stab.c revision 7257d1b4d25bfac0c802847390e98a464fd787ac
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file contains all functions relating to stab processing. The
* stab table is compressed by eliminating duplicate include file entries.
*/
#include <stdio.h>
#include <string.h>
#include <stab.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <libintl.h>
#include "libld.h"
#include "msg.h"
/*
* With the 5.x compiler, stab.h changed struct nlist into
* struct stab and got rid of it's embeded unions.
*/
#else
#endif
/*
* Data structure that holds persistent data that sbfocus_symbol & sbfocus_close
* needs. Passing in a pointer to this struct makes them re-entrant.
*/
typedef struct sbld_tag {
int failed;
extern Half out_e_type;
extern void sbfocus_symbol(Sbld, const char *, const char *,
const char *);
#if !defined(_ELF64)
/*
* holds information needed by sbfocus_symbol and sbfocus_close.
*/
/*
* holds information out the output file being created.
*/
/*
* Signal handler is called when a SIGPIPE is encountered. This would
* happen in case `sbfocus' did not exist and `ld' is writing down a
* pipe with no reader. Trap signal and set failed field so that no
* more subsequent writes occur.
*/
static void
{
}
/*
* sbfocus_symbol() will write one symbol to a pipe that has the program
* "sbfocus" at the receiving end. If the program has not been started yet,
* it is started, and the pipe established. "sbfocus" is started with the
* function arguments "type" and "name" as its arguments, in that order.
*
* sbfocus_symbol() should be called with four arguments:
* data Pointer to a Sbld struct that the caller has allocated in
* permanent storage. It must be the same struct for all related
* calls to sbfocus_symbol().
* name This is the string name of the library/executable being built.
* type A string, should be one of:
* "-x": Building an executable or shared object
* "-r": Concatenating object files
* symbol The string that should be written to "sbfocus". If this
* argument is NULL "sbfocus" is started, but no symbol is
* written to it.
*/
void
const char *symbol)
{
return;
}
switch (fork()) {
case -1:
return;
/*
* Child process
*/
case 0:
exit(-1);
/*
* Parent process
*/
default:
break;
}
}
}
}
#endif /* !defined(_ELF64) */
static Xword
{
size_t i;
size_t str_offset = 0;
/*
* The processing of the stab table happens in two passes.
*
* first pass: calculate if any change is needed and if so, how much
* the string table needs to be expanded by.
*/
for (i = 0; i < num_elem; i++) {
char *str;
case 0:
if (last)
break;
case N_OBJ:
/*
* This is a 'CWD' N_OBJ
*
* we only record the 'cwd' once in each
* stringtable. so - we only need to add
* it's length once to the new_size
*/
if (any_obj == 0) {
any_obj++;
} /* if */
first_object = 0;
} /* if */
else if (*str == '\0') {
/*
* This is a 'object_name' N_OBJ
*/
first_object = 1;
} /* else if */
break;
default:
/* no-op */
break;
} /* switch */
} /* for */
/*LINTED*/
} /* pass1_stabindex */
static int
{
size_t i;
size_t str_offset = 0;
/*
* The processing of the stab table happens in two passes.
*
* first pass: calculate if any change is needed and if so, how much
* the string table needs to be expanded by.
*/
for (i = 0; i < num_elem; i++) {
char *str;
case 0:
if (last)
break;
case N_OBJ:
/*
* This is a 'CWD' N_OBJ
*
* We point it at the CWD entry that we've
* already placed in the new string_table.
*/
/*LINTED*/
first_object = 0;
} /* if */
else if (*str == '\0') {
/*
* This is a 'object_name' N_OBJ.
*
* Append the object name to the string table
* and set the elem->n_un.n_strx to point
* to it.
*/
/*LINTED*/
first_object = 1;
} /* if */
break;
default:
break;
} /* switch */
} /* for */
/*LINTED*/
return (1);
} /* pass2_stabindex() */
/*
* find_scn()
*
* Find a section in elf that matches the supplied section name,
* type, and flags.
*
* Returns:
* section number if found
* 0 - if no matching section found
* -1 - if error
*
* If shdr is a non-null pointer it will be set to the section header
* that was found.
*/
static size_t
{
return ((size_t)-1);
/*
* we've got a match
*/
return ((size_t)-1);
if (ret_scn)
return (scn_ndx);
} /* if */
} /* while */
/*
* no match found
*/
return (0);
} /* find_scn() */
static Elf_Data *
{
/*
* The stab's string table can be found through the
* shdr->sh_link value.
*/
/*
* Normally the sh_link field should point to the
* required strtab. But if it's not filled in (which
* means something goofed somewhere) we will try to look
* it up from the elf file itself.
*/
if (strscn_ndx == 0) {
in_fname);
in_fname);
}
} else {
in_fname, elf_errmsg(0));
}
}
elf_errmsg(0));
}
return (str_data);
}
/*
* We examine all the stab's looking for pairs of N_OBJ's who's
* string pointers (elem->n_un.n_strx) points to a null string.
* When we find a pair we set the first string pointing to the
* CWD and we set the second string to the file object name (*name).
*
* The stab's string table will have to be expanded to hold
* these new enties.
*/
static void
{
return;
return;
}
}
if (new_size == 0)
/* no changes are needed */
return;
/*
* The .stab.index data buffer must be updated so a new copy is
* allocated. The original is read-only.
*/
return;
/*
* Allocate a new .stab.indexstr that is big enough to hold the new
* entries that we will need to place into it.
*
* Then append the 'cwd' onto the end of the current data.
*/
return;
}
static void
{
return;
for (i = 0; i < num_elem; i++) {
case 0:
if (last)
break;
case N_BROWS:
else
break;
default:
/* no-op */
break;
}
}
}
/* ARGSUSED2 */
void
#if defined(_ELF64)
#else
#endif
{
out_e_type = etype;
}
/* ARGSUSED1 */
void
#if defined(_ELF64)
#else
#endif
{
}
/*
* ld_section()
*
* Args:
* name - pointer to name of current section being processed.
* shdr - pointer to Section Header of current in-file being
* processed.
* s_data - pointer to Section Data structure of current in-file
* being processed.
* elf - pointer to elf structure for current in-file being
* processed
*/
/* ARGSUSED2 */
void
#if defined(_ELF64)
#else
#endif
{
char *strtab;
/*
* this is a minor optimization for speed. If it's not a
* stab string we aren't going to strcmp() it.
*/
/*
* If 'extended sections' are in use, then
* e_shstrndx == Shdr[0].sh_link
*/
} else
/*
* Process .stab
*/
MSG_ORIG(MSG_SCN_STABINDEX)) == 0) {
/*
* Process .stab.index
*/
s_data);
MSG_ORIG(MSG_SCN_STABSBFOCUS)) == 0) {
/*
* Process .stab.sbfocus
*/
}
}
}
}
/*
* Null atexit() routine, causes dlsym() to pass and thus no dlerror() message
* generation.
*/
/* ARGSUSED */
void
#if defined(_ELF64)
ld_atexit64(int status)
#else
#endif
{
}
#if !defined(_ELF64)
/*
* Messaging support - funnel everything through dgettext().
*/
const char *
{
}
#endif