FreeBSD/sys/kern/link_elf_obj.c
/*
 * Symbol lookup function that can be used when the symbol index is known (ie
 * in relocations). It uses the symbol index instead of doing a fully fledged
 * hash table based lookup when such is valid. For example for local symbols.
 * This is not only more efficient, it's also more correct. It's not always
 * the case that the symbol can be found through the hash table.
 */
Symbol lookup function that can be used when the symbol index is known . It uses the symbol index instead of doing a fully fledged
hash table based lookup when such is valid. For example for local symbols.
This is not only more efficient, it's also more correct. It's not always
the case that the symbol can be found through the hash table.
Symbol lookup function that can be used when the symbol index is known . It uses the symbol index instead of doing a fully fledged hash table based lookup when such is valid . For example for local symbols . This is not only more efficient it ' s also more correct . It ' s not always the case that the symbol can be found through the hash table .
static int
elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res)
{
	elf_file_t ef = (elf_file_t)lf;
	Elf_Sym *sym;
	const char *symbol;
	Elf_Addr res1;
	if (symidx >= ef->ddbsymcnt) {
		*res = 0;
		return (EINVAL);
	}
	sym = ef->ddbsymtab + symidx;
	if (sym->st_shndx != SHN_UNDEF) {
		*res = sym->st_value;
		return (0);
	}
	switch (ELF_ST_BIND(sym->st_info)) {
	case STB_LOCAL:
		*res = 0;
		return (EINVAL);
	case STB_GLOBAL:
	case STB_WEAK:
		symbol = ef->ddbstrtab + sym->st_name;
		if (*symbol == 0) {
			*res = 0;
			return (EINVAL);
		}
		res1 = (Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps);
		if (res1 != 0) {
			sym->st_shndx = SHN_FBSD_CACHED;
			sym->st_value = res1;
			*res = res1;
			return (0);
		} else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
			sym->st_value = 0;
			*res = 0;
			return (0);
		}
		return (EINVAL);
	default:
		return (EINVAL);
	}
}
static int elf_obj_lookup ( linker_file_t lf , Elf_Size symidx , int deps , Elf_Addr * res ) { elf_file_t ef = ( elf_file_t ) lf ; Elf_Sym * sym ; const char * symbol ; Elf_Addr res1 ; if ( symidx >= ef -> ddbsymcnt ) { * res = 0 ; return ( EINVAL ) ; } sym = ef -> ddbsymtab + symidx ; if ( sym -> st_shndx != SHN_UNDEF ) { * res = sym -> st_value ; return ( 0 ) ; } switch ( ELF_ST_BIND ( sym -> st_info ) ) { case STB_LOCAL : * res = 0 ; return ( EINVAL ) ; case STB_GLOBAL : case STB_WEAK : symbol = ef -> ddbstrtab + sym -> st_name ; if ( * symbol == 0 ) { * res = 0 ; return ( EINVAL ) ; } res1 = ( Elf_Addr ) linker_file_lookup_symbol ( lf , symbol , deps ) ; if ( res1 != 0 ) { sym -> st_shndx = SHN_FBSD_CACHED ; sym -> st_value = res1 ; * res = res1 ; return ( 0 ) ; } else if ( ELF_ST_BIND ( sym -> st_info ) == STB_WEAK ) { sym -> st_value = 0 ; * res = 0 ; return ( 0 ) ; } return ( EINVAL ) ; default : return ( EINVAL ) ; } }
Symbol lookup function that can be used when the symbol index is known (ie
 in relocations).
Symbol lookup function that can be used when the symbol index is known ( ie in relocations ) .
/* Don't even try to lookup the symbol if the index is bogus. */ /* Quick answer if there is a definition included. */ /* If we get here, then it is undefined and needs a lookup. */ /* Local, but undefined? huh? */ /* Relative to Data or Function name */ /* Force a lookup failure if the symbol name is bogus. */ /*
		 * Cache global lookups during module relocation. The failure
		 * case is particularly expensive for callers, who must scan
		 * through the entire globals table doing strcmp(). Cache to
		 * avoid doing such work repeatedly.
		 *
		 * After relocation is complete, undefined globals will be
		 * restored to SHN_UNDEF in elf_obj_cleanup_globals_cache(),
		 * above.
		 */