FreeBSD/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
/*
 * Process the symbol table of the output file, associating each symbol
 * with a type description if possible, and sorting them into functions
 * and data, maintaining symbol table order.
 */
Process the symbol table of the output file, associating each symbol
with a type description if possible, and sorting them into functions
and data, maintaining symbol table order.
Process the symbol table of the output file associating each symbol with a type description if possible and sorting them into functions and data maintaining symbol table order .
static iiburst_t *
sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
    int dynsym)
{
	iiburst_t *iiburst;
	Elf_Scn *scn;
	GElf_Shdr shdr;
	Elf_Data *data, *strdata;
	int i, stidx;
	int nent;
	iidesc_match_t match;
	match.iim_fuzzy = fuzzymatch;
	match.iim_file = NULL;
	if ((stidx = findelfsecidx(elf, file,
	    dynsym ? ".dynsym" : ".symtab")) < 0)
		terminate("%s: Can't open symbol table\n", file);
	scn = elf_getscn(elf, stidx);
	data = elf_getdata(scn, NULL);
	gelf_getshdr(scn, &shdr);
	nent = shdr.sh_size / shdr.sh_entsize;
	scn = elf_getscn(elf, shdr.sh_link);
	strdata = elf_getdata(scn, NULL);
	iiburst = iiburst_new(td, nent);
	for (i = 0; i < nent; i++) {
		GElf_Sym sym;
		char *bname;
		iidesc_t **tolist;
		GElf_Sym ssym;
		iidesc_match_t smatch;
		int *curr;
		iidesc_t *iidesc;
		if (gelf_getsym(data, i, &sym) == NULL)
			elfterminate(file, "Couldn't read symbol %d", i);
		match.iim_name = (char *)strdata->d_buf + sym.st_name;
		match.iim_bind = GELF_ST_BIND(sym.st_info);
		switch (GELF_ST_TYPE(sym.st_info)) {
		case STT_FILE:
			bname = strrchr(match.iim_name, '/');
			match.iim_file = bname == NULL ? match.iim_name : bname + 1;
			continue;
		case STT_OBJECT:
			tolist = iiburst->iib_objts;
			curr = &iiburst->iib_nobjts;
			break;
		case STT_FUNC:
			tolist = iiburst->iib_funcs;
			curr = &iiburst->iib_nfuncs;
			break;
		default:
			continue;
		}
		if (ignore_symbol(&sym, match.iim_name))
			continue;
		iidesc = find_iidesc(td, &match);
		if (iidesc != NULL) {
			tolist[*curr] = iidesc;
			iidesc->ii_flags |= IIDESC_F_USED;
			(*curr)++;
			continue;
		}
		if (!check_for_weak(&sym, match.iim_file, data, nent, strdata,
		    &ssym, &smatch.iim_file)) {
			(*curr)++;
			continue;
		}
		smatch.iim_fuzzy = fuzzymatch;
		smatch.iim_name = (char *)strdata->d_buf + ssym.st_name;
		smatch.iim_bind = GELF_ST_BIND(ssym.st_info);
		debug(3, "Weak symbol %s resolved to %s\n", match.iim_name,
		    smatch.iim_name);
		iidesc = find_iidesc(td, &smatch);
		if (iidesc != NULL) {
			tolist[*curr] = copy_from_strong(td, &sym,
			    iidesc, match.iim_name, match.iim_file);
			tolist[*curr]->ii_flags |= IIDESC_F_USED;
		}
		(*curr)++;
	}
	iiburst_types(iiburst);
	tdata_label_newmax(td, iiburst->iib_maxtypeid);
	return (iiburst);
}
static iiburst_t * sort_iidescs ( Elf * elf , const char * file , tdata_t * td , int fuzzymatch , int dynsym ) { iiburst_t * iiburst ; Elf_Scn * scn ; GElf_Shdr shdr ; Elf_Data * data , * strdata ; int i , stidx ; int nent ; iidesc_match_t match ; match . iim_fuzzy = fuzzymatch ; match . iim_file = NULL ; if ( ( stidx = findelfsecidx ( elf , file , dynsym ? " " : " " ) ) < 0 ) terminate ( " \n " , file ) ; scn = elf_getscn ( elf , stidx ) ; data = elf_getdata ( scn , NULL ) ; gelf_getshdr ( scn , & shdr ) ; nent = shdr . sh_size / shdr . sh_entsize ; scn = elf_getscn ( elf , shdr . sh_link ) ; strdata = elf_getdata ( scn , NULL ) ; iiburst = iiburst_new ( td , nent ) ; for ( i = 0 ; i < nent ; i ++ ) { GElf_Sym sym ; char * bname ; iidesc_t * * tolist ; GElf_Sym ssym ; iidesc_match_t smatch ; int * curr ; iidesc_t * iidesc ; if ( gelf_getsym ( data , i , & sym ) == NULL ) elfterminate ( file , " " , i ) ; match . iim_name = ( char * ) strdata -> d_buf + sym . st_name ; match . iim_bind = GELF_ST_BIND ( sym . st_info ) ; switch ( GELF_ST_TYPE ( sym . st_info ) ) { case STT_FILE : bname = strrchr ( match . iim_name , ' ' ) ; match . iim_file = bname == NULL ? match . iim_name : bname + 1 ; continue ; case STT_OBJECT : tolist = iiburst -> iib_objts ; curr = & iiburst -> iib_nobjts ; break ; case STT_FUNC : tolist = iiburst -> iib_funcs ; curr = & iiburst -> iib_nfuncs ; break ; default : continue ; } if ( ignore_symbol ( & sym , match . iim_name ) ) continue ; iidesc = find_iidesc ( td , & match ) ; if ( iidesc != NULL ) { tolist [ * curr ] = iidesc ; iidesc -> ii_flags |= IIDESC_F_USED ; ( * curr ) ++ ; continue ; } if ( ! check_for_weak ( & sym , match . iim_file , data , nent , strdata , & ssym , & smatch . iim_file ) ) { ( * curr ) ++ ; continue ; } smatch . iim_fuzzy = fuzzymatch ; smatch . iim_name = ( char * ) strdata -> d_buf + ssym . st_name ; smatch . iim_bind = GELF_ST_BIND ( ssym . st_info ) ; debug ( 3 , " \n " , match . iim_name , smatch . iim_name ) ; iidesc = find_iidesc ( td , & smatch ) ; if ( iidesc != NULL ) { tolist [ * curr ] = copy_from_strong ( td , & sym , iidesc , match . iim_name , match . iim_file ) ; tolist [ * curr ] -> ii_flags |= IIDESC_F_USED ; } ( * curr ) ++ ; } iiburst_types ( iiburst ) ; tdata_label_newmax ( td , iiburst -> iib_maxtypeid ) ; return ( iiburst ) ; }
Process the symbol table of the output file, associating each symbol
 with a type description if possible, and sorting them into functions
 and data, maintaining symbol table order.
Process the symbol table of the output file associating each symbol with a type description if possible and sorting them into functions and data maintaining symbol table order .
/*
	 * Stabs are generated for every function declared in a given C source
	 * file.  When converting an object file, we may encounter a stab that
	 * has no symbol table entry because the optimizer has decided to omit
	 * that item (for example, an unreferenced static function).  We may
	 * see iidescs that do not have an associated symtab entry, and so
	 * we do not write records for those functions into the CTF data.
	 * All others get marked as a root by this function.
	 */ /*
	 * By not adding some of the functions and/or objects, we may have
	 * caused some types that were referenced solely by those
	 * functions/objects to be suppressed.  This could cause a label,
	 * generated prior to the evisceration, to be incorrect.  Find the
	 * highest type index, and change the label indicies to be no higher
	 * than this value.
	 */