FreeBSD/libexec/rtld-elf/rtld.c
/*
 * Given a symbol number in a referencing object, find the corresponding
 * definition of the symbol.  Returns a pointer to the symbol, or NULL if
 * no definition was found.  Returns a pointer to the Obj_Entry of the
 * defining object via the reference parameter DEFOBJ_OUT.
 */
Given a symbol number in a referencing object, find the corresponding
definition of the symbol.  Returns a pointer to the symbol, or NULL if
no definition was found.  Returns a pointer to the Obj_Entry of the
defining object via the reference parameter DEFOBJ_OUT.
Given a symbol number in a referencing object find the corresponding definition of the symbol . Returns a pointer to the symbol or NULL if no definition was found . Returns a pointer to the Obj_Entry of the defining object via the reference parameter DEFOBJ_OUT .
const Elf_Sym *
find_symdef(unsigned long symnum, const Obj_Entry *refobj,
    const Obj_Entry **defobj_out, int flags, SymCache *cache,
    RtldLockState *lockstate)
{
    const Elf_Sym *ref;
    const Elf_Sym *def;
    const Obj_Entry *defobj;
    SymLook req;
    const char *name;
    int res;
    if (symnum >= refobj->dynsymcount)
	return NULL;	
    if (cache != NULL && cache[symnum].sym != NULL) {
	*defobj_out = cache[symnum].obj;
	return cache[symnum].sym;
    }
    ref = refobj->symtab + symnum;
    name = refobj->strtab + ref->st_name;
    def = NULL;
    defobj = NULL;
    if (ELF_ST_BIND(ref->st_info) != STB_LOCAL) {
	if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) {
	    _rtld_error("%s: Bogus symbol table entry %lu", refobj->path,
		symnum);
	}
	symlook_init(&req, name);
	req.flags = flags;
	req.ventry = fetch_ventry(refobj, symnum);
	req.lockstate = lockstate;
	res = symlook_default(&req, refobj);
	if (res == 0) {
	    def = req.sym_out;
	    defobj = req.defobj_out;
	}
    } else {
	def = ref;
	defobj = refobj;
    }
    if (def == NULL && ELF_ST_BIND(ref->st_info) == STB_WEAK) {
	def = &sym_zero;
	defobj = obj_main;
    }
    if (def != NULL) {
	*defobj_out = defobj;
	if (cache != NULL) {
	    cache[symnum].sym = def;
	    cache[symnum].obj = defobj;
	}
    } else {
	if (refobj != &obj_rtld)
	    _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name);
    }
    return def;
}
const Elf_Sym * find_symdef ( unsigned long symnum , const Obj_Entry * refobj , const Obj_Entry * * defobj_out , int flags , SymCache * cache , RtldLockState * lockstate ) { const Elf_Sym * ref ; const Elf_Sym * def ; const Obj_Entry * defobj ; SymLook req ; const char * name ; int res ; if ( symnum >= refobj -> dynsymcount ) return NULL ; if ( cache != NULL && cache [ symnum ] . sym != NULL ) { * defobj_out = cache [ symnum ] . obj ; return cache [ symnum ] . sym ; } ref = refobj -> symtab + symnum ; name = refobj -> strtab + ref -> st_name ; def = NULL ; defobj = NULL ; if ( ELF_ST_BIND ( ref -> st_info ) != STB_LOCAL ) { if ( ELF_ST_TYPE ( ref -> st_info ) == STT_SECTION ) { _rtld_error ( " " , refobj -> path , symnum ) ; } symlook_init ( & req , name ) ; req . flags = flags ; req . ventry = fetch_ventry ( refobj , symnum ) ; req . lockstate = lockstate ; res = symlook_default ( & req , refobj ) ; if ( res == 0 ) { def = req . sym_out ; defobj = req . defobj_out ; } } else { def = ref ; defobj = refobj ; } if ( def == NULL && ELF_ST_BIND ( ref -> st_info ) == STB_WEAK ) { def = & sym_zero ; defobj = obj_main ; } if ( def != NULL ) { * defobj_out = defobj ; if ( cache != NULL ) { cache [ symnum ] . sym = def ; cache [ symnum ] . obj = defobj ; } } else { if ( refobj != & obj_rtld ) _rtld_error ( " \" \" " , refobj -> path , name ) ; } return def ; }
Given a symbol number in a referencing object, find the corresponding
 definition of the symbol.
Given a symbol number in a referencing object find the corresponding definition of the symbol .
/*
     * If we have already found this symbol, get the information from
     * the cache.
     */ /* Bad object */ /*
     * We don't have to do a full scale lookup if the symbol is local.
     * We know it will bind to the instance in this load module; to
     * which we already have a pointer (ie ref). By not doing a lookup,
     * we not only improve performance, but it also avoids unresolvable
     * symbols when local symbols are not in the hash table. This has
     * been seen with the ia64 toolchain.
     */ /*
     * If we found no definition and the reference is weak, treat the
     * symbol as having the value zero.
     */ /* Record the information in the cache to avoid subsequent lookups. */