1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-12-24 17:51:17 +03:00

Tue Jun 4 02:25:44 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>

* elf/linux-compat.c (_init): Pass reloc_addr arg to _dl_lookup_symbol.

	* elf/dl-lookup.c (_dl_lookup_symbol): Use l_searchlist.

	* elf/dl-deps.c: New file.
	* elf/Makefile (rtld-routines): Add dl-deps.
	* elf/link.h: Declare _dl_map_object_deps, _dl_open.
	* elf/rtld.c (dl_main): Use _dl_map_object_deps.
	* elf/dlopen.c: Use _dl_open.

	* elf/rtld.c (dl_main): Remove BEFORE_RTLD variable and list
	frobnication based on its value.  Detach RTLD_MAP from the chain if
	its l_opencount is zero after loading deps.

	* elf/dlfcn.h (RTLD_BINDING_MASK): New macro.

	* elf/link.h (struct link_map): Replace l_deps_loaded flag member with
	`struct link_map **l_searchlist' and `unsigned int l_nsearchlist'.
	* elf/dl-lookup.c (_dl_lookup_symbol): Make SYMBOL_SCOPE arg an array
	of two link_map ptrs.  Search the maps in the l_searchlist of each
	elt that is not null.
	* elf/dl-reloc.c (_dl_relocate_object): Pass proper SCOPE array.
	* elf/dl-runtime.c: Likewise.
	* elf/dlsym.c: Likewise.
	* elf/rtld.c (dl_main): Likewise.

	* elf/dl-minimal.c (realloc): Support realloc of the block most
	recently returned by the minimal malloc.

	* intl/localealias.c, intl/dcgettext.c [_LIBC]: Define HAVE_ALLOCA.
This commit is contained in:
Roland McGrath
1996-06-04 05:18:15 +00:00
parent b25ae9c6a4
commit efec1d0c47
13 changed files with 253 additions and 162 deletions

View File

@@ -29,77 +29,84 @@ Cambridge, MA 02139, USA. */
Elf32_Addr
_dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
struct link_map *symbol_scope,
struct link_map *symbol_scope[2],
const char *reference_name,
Elf32_Addr reloc_addr,
int noplt)
{
unsigned long int hash = elf_hash (undef_name);
struct link_map *map;
struct
{
Elf32_Addr a;
const Elf32_Sym *s;
} weak_value = { 0, NULL };
size_t i;
struct link_map **scope, *map;
/* Search the relevant loaded objects for a definition. */
for (map = symbol_scope; map; map = map->l_next)
{
const Elf32_Sym *symtab;
const char *strtab;
Elf32_Word symidx;
symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
/* Search the appropriate hash bucket in this object's symbol table
for a definition for the same symbol name. */
for (symidx = map->l_buckets[hash % map->l_nbuckets];
symidx != STN_UNDEF;
symidx = map->l_chain[symidx])
for (scope = symbol_scope; scope < &symbol_scope[2]; ++scope)
if (*scope)
for (i = 0; i < (*scope)->l_nsearchlist; ++i)
{
const Elf32_Sym *sym = &symtab[symidx];
const Elf32_Sym *symtab;
const char *strtab;
Elf32_Word symidx;
if (sym->st_value == 0 || /* No value. */
reloc_addr == map->l_addr + sym->st_value || /* Self ref. */
(noplt && sym->st_shndx == SHN_UNDEF)) /* Unwanted PLT entry. */
continue;
map = (*scope)->l_searchlist[i];
switch (ELF32_ST_TYPE (sym->st_info))
symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
/* Search the appropriate hash bucket in this object's symbol table
for a definition for the same symbol name. */
for (symidx = map->l_buckets[hash % map->l_nbuckets];
symidx != STN_UNDEF;
symidx = map->l_chain[symidx])
{
case STT_NOTYPE:
case STT_FUNC:
case STT_OBJECT:
break;
default:
/* Not a code/data definition. */
continue;
}
const Elf32_Sym *sym = &symtab[symidx];
if (sym != *ref && strcmp (strtab + sym->st_name, undef_name))
/* Not the symbol we are looking for. */
continue;
if (sym->st_value == 0 || /* No value. */
/* Cannot resolve to the location being filled in. */
reloc_addr == map->l_addr + sym->st_value ||
(noplt && sym->st_shndx == SHN_UNDEF)) /* Reject PLT. */
continue;
switch (ELF32_ST_BIND (sym->st_info))
{
case STB_GLOBAL:
/* Global definition. Just what we need. */
*ref = sym;
return map->l_addr;
case STB_WEAK:
/* Weak definition. Use this value if we don't find another. */
if (! weak_value.s)
switch (ELF32_ST_TYPE (sym->st_info))
{
weak_value.s = sym;
weak_value.a = map->l_addr;
case STT_NOTYPE:
case STT_FUNC:
case STT_OBJECT:
break;
default:
/* Not a code/data definition. */
continue;
}
if (sym != *ref && strcmp (strtab + sym->st_name, undef_name))
/* Not the symbol we are looking for. */
continue;
switch (ELF32_ST_BIND (sym->st_info))
{
case STB_GLOBAL:
/* Global definition. Just what we need. */
*ref = sym;
return map->l_addr;
case STB_WEAK:
/* Weak definition. Use this value if we don't find
another. */
if (! weak_value.s)
{
weak_value.s = sym;
weak_value.a = map->l_addr;
}
break;
default:
/* Local symbols are ignored. */
break;
}
break;
default:
/* Local symbols are ignored. */
break;
}
}
}
if (weak_value.s == NULL && ELF32_ST_BIND ((*ref)->st_info) != STB_WEAK)
{