Several small changes that shave 7-8% off the simple-exec-loop test:

* Rename _rtld_find_library() to _rtld_load_library().  It now calls
  _rtld_load_object() if necessary to actually load the object, rather
  than having the caller do it.  To do this, it also takes the `mode'
  argument that gets passed to _rtld_load_object().

* On a related note, remove _rtld_check_library(), and instead call
  _rtld_load_object() to instead try actually loading the object.  We
  save two extra namei's and a bunch of redundant work (almost
  literally the same code) this way.

* In _rtld_map_object(), mmap(2) the first page read-only, rather than
  read(2)ing it.

* In _rtld_symlook_obj(), compare the *second* character of the symbol
  name before calling strcmp().  (This first character is too
  frequently `_', and turns out to not be helpful, in libc.)

* Also in _rtld_symlook_obj(), remove the bogus STT_FUNC special case
  -- this also allows removing the `in_plt' argument to
  _rtld_symlook_list() and _rtld_symlook_obj().

Also:

* In _rtld_obj_from_addr(), rather than trying to look up `_end' in
  the each object, instead use obj->mapsize as the upper bound.
This commit is contained in:
mycroft 2002-09-23 23:56:46 +00:00
parent f0efca630a
commit 86103e2f0e
7 changed files with 116 additions and 186 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: load.c,v 1.18 2002/09/12 22:56:28 mycroft Exp $ */
/* $NetBSD: load.c,v 1.19 2002/09/23 23:56:46 mycroft Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -101,9 +101,9 @@ _rtld_load_object(filepath, mode)
int fd = -1;
struct stat sb;
for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next)
if (strcmp(obj->path, filepath) == 0)
break;
for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next)
if (!strcmp(obj->path, filepath))
break;
/*
* If we didn't find a match by pathname, open the file and check
@ -138,7 +138,6 @@ _rtld_load_object(filepath, mode)
free(filepath);
return NULL;
}
obj->path = filepath;
_rtld_digest_dynamic(obj);
*_rtld_objtail = obj;
@ -170,7 +169,6 @@ _rtld_load_by_name(name, obj, needed, mode)
Library_Xform *x = _rtld_xforms;
Obj_Entry *o = NULL;
size_t i, j;
char *libpath;
bool got = false;
union {
int i;
@ -219,16 +217,13 @@ _rtld_load_by_name(name, obj, needed, mode)
* what we loaded in the needed objects */
for (j = 0; j < RTLD_MAX_LIBRARY &&
x->entry[i].library[j] != NULL; j++) {
libpath = _rtld_find_library(
x->entry[i].library[j], obj);
if (libpath == NULL) {
o = _rtld_load_library(x->entry[i].library[j], obj,
mode);
if (o == NULL) {
xwarnx("could not load %s for %s",
x->entry[i].library[j], name);
continue;
}
o = _rtld_load_object(libpath, mode);
if (o == NULL)
continue;
got = true;
if (j == 0)
(*needed)->obj = o;
@ -249,10 +244,7 @@ _rtld_load_by_name(name, obj, needed, mode)
if (got)
return true;
libpath = _rtld_find_library(name, obj);
if (libpath == NULL)
return false;
return ((*needed)->obj = _rtld_load_object(libpath, mode)) != NULL;
return ((*needed)->obj = _rtld_load_library(name, obj, mode)) != NULL;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: map_object.c,v 1.15 2002/09/13 03:12:40 mycroft Exp $ */
/* $NetBSD: map_object.c,v 1.16 2002/09/23 23:56:47 mycroft Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -53,7 +53,7 @@ static int protflags __P((int)); /* Elf flags -> mmap protection */
*/
Obj_Entry *
_rtld_map_object(path, fd, sb)
const char *path;
char *path;
int fd;
const struct stat *sb;
{
@ -61,8 +61,7 @@ _rtld_map_object(path, fd, sb)
union {
Elf_Ehdr hdr;
char buf[PAGESIZE];
} u;
int nbytes;
} *u;
Elf_Phdr *phdr;
Elf_Phdr *phlimit;
Elf_Phdr *segs[2];
@ -89,33 +88,34 @@ _rtld_map_object(path, fd, sb)
size_t nclear;
#endif
if ((nbytes = read(fd, u.buf, PAGESIZE)) == -1) {
u = mmap(NULL, PAGESIZE, PROT_READ, MAP_FILE | MAP_SHARED, fd,
(off_t)0);
if (u == MAP_FAILED) {
_rtld_error("%s: read error: %s", path, xstrerror(errno));
return NULL;
}
/* Make sure the file is valid */
if (nbytes < sizeof(Elf_Ehdr) ||
memcmp(ELFMAG, u.hdr.e_ident, SELFMAG) != 0 ||
u.hdr.e_ident[EI_CLASS] != ELFCLASS) {
if (memcmp(ELFMAG, u->hdr.e_ident, SELFMAG) != 0 ||
u->hdr.e_ident[EI_CLASS] != ELFCLASS) {
_rtld_error("%s: unrecognized file format", path);
return NULL;
goto bad;
}
/* Elf_e_ident includes class */
if (u.hdr.e_ident[EI_VERSION] != EV_CURRENT ||
u.hdr.e_version != EV_CURRENT ||
u.hdr.e_ident[EI_DATA] != ELFDEFNNAME(MACHDEP_ENDIANNESS)) {
_rtld_error("%s: Unsupported file version", path);
return NULL;
if (u->hdr.e_ident[EI_VERSION] != EV_CURRENT ||
u->hdr.e_version != EV_CURRENT ||
u->hdr.e_ident[EI_DATA] != ELFDEFNNAME(MACHDEP_ENDIANNESS)) {
_rtld_error("%s: unsupported file version", path);
goto bad;
}
if (u.hdr.e_type != ET_EXEC && u.hdr.e_type != ET_DYN) {
_rtld_error("%s: Unsupported file type", path);
return NULL;
if (u->hdr.e_type != ET_EXEC && u->hdr.e_type != ET_DYN) {
_rtld_error("%s: unsupported file type", path);
goto bad;
}
switch (u.hdr.e_machine) {
switch (u->hdr.e_machine) {
ELFDEFNNAME(MACHDEP_ID_CASES)
default:
_rtld_error("%s: Unsupported machine", path);
return NULL;
_rtld_error("%s: unsupported machine", path);
goto bad;
}
/*
@ -123,9 +123,8 @@ _rtld_map_object(path, fd, sb)
* not strictly required by the ABI specification, but it seems to
* always true in practice. And, it simplifies things considerably.
*/
assert(u.hdr.e_phentsize == sizeof(Elf_Phdr));
assert(u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) <= PAGESIZE);
assert(u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) <= nbytes);
assert(u->hdr.e_phentsize == sizeof(Elf_Phdr));
assert(u->hdr.e_phoff + u->hdr.e_phnum * sizeof(Elf_Phdr) <= PAGESIZE);
/*
* Scan the program header entries, and save key information.
@ -133,8 +132,8 @@ _rtld_map_object(path, fd, sb)
* We rely on there being exactly two load segments, text and data,
* in that order.
*/
phdr = (Elf_Phdr *) (u.buf + u.hdr.e_phoff);
phlimit = phdr + u.hdr.e_phnum;
phdr = (Elf_Phdr *) (u->buf + u->hdr.e_phoff);
phlimit = phdr + u->hdr.e_phnum;
nsegs = 0;
phdyn = phphdr = phinterp = NULL;
while (phdr < phlimit) {
@ -162,12 +161,12 @@ _rtld_map_object(path, fd, sb)
}
if (phdyn == NULL) {
_rtld_error("%s: not dynamically linked", path);
return NULL;
goto bad;
}
if (nsegs != 2) {
_rtld_error("%s: wrong number of segments (%d != 2)", path,
nsegs);
return NULL;
goto bad;
}
/*
@ -189,7 +188,7 @@ _rtld_map_object(path, fd, sb)
mapsize = base_vlimit - base_vaddr;
#ifdef RTLD_LOADER
base_addr = u.hdr.e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
base_addr = u->hdr.e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
#else
base_addr = NULL;
#endif
@ -199,7 +198,7 @@ _rtld_map_object(path, fd, sb)
if (mapbase == MAP_FAILED) {
_rtld_error("mmap of entire address space failed: %s",
xstrerror(errno));
return NULL;
goto bad;
}
base_addr = mapbase;
@ -215,7 +214,7 @@ _rtld_map_object(path, fd, sb)
== MAP_FAILED) {
_rtld_error("mmap of data failed: %s", xstrerror(errno));
munmap(mapbase, mapsize);
return NULL;
goto bad;
}
/* Overlay the bss segment onto the proper region. */
@ -225,7 +224,7 @@ _rtld_map_object(path, fd, sb)
== MAP_FAILED) {
_rtld_error("mmap of bss failed: %s", xstrerror(errno));
munmap(mapbase, mapsize);
return NULL;
goto bad;
}
/* Unmap the gap between the text and data. */
@ -235,7 +234,7 @@ _rtld_map_object(path, fd, sb)
_rtld_error("munmap of text -> data gap failed: %s",
xstrerror(errno));
munmap(mapbase, mapsize);
return NULL;
goto bad;
}
#ifdef RTLD_LOADER
@ -249,6 +248,7 @@ _rtld_map_object(path, fd, sb)
#endif
obj = _rtld_obj_new();
obj->path = path;
if (sb != NULL) {
obj->dev = sb->st_dev;
obj->ino = sb->st_ino;
@ -260,8 +260,8 @@ _rtld_map_object(path, fd, sb)
obj->vaddrbase = base_vaddr;
obj->relocbase = mapbase - base_vaddr;
obj->dynamic = (Elf_Dyn *)(obj->relocbase + phdyn->p_vaddr);
if (u.hdr.e_entry != 0)
obj->entry = (caddr_t)(obj->relocbase + u.hdr.e_entry);
if (u->hdr.e_entry != 0)
obj->entry = (caddr_t)(obj->relocbase + u->hdr.e_entry);
if (phphdr != NULL) {
obj->phdr = (const Elf_Phdr *)
(obj->relocbase + phphdr->p_vaddr);
@ -269,9 +269,13 @@ _rtld_map_object(path, fd, sb)
}
if (phinterp != NULL)
obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr);
obj->isdynamic = u.hdr.e_type == ET_DYN;
obj->isdynamic = u->hdr.e_type == ET_DYN;
return obj;
bad:
munmap(u, PAGESIZE);
return NULL;
}
void

View File

@ -1,4 +1,4 @@
/* $NetBSD: reloc.c,v 1.68 2002/09/17 07:29:46 junyoung Exp $ */
/* $NetBSD: reloc.c,v 1.69 2002/09/23 23:56:47 mycroft Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -79,8 +79,7 @@ _rtld_do_copy_relocation(dstobj, rela)
Obj_Entry *srcobj;
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next)
if ((srcsym = _rtld_symlook_obj(name, hash, srcobj,
false)) != NULL)
if ((srcsym = _rtld_symlook_obj(name, hash, srcobj)) != NULL)
break;
if (srcobj == NULL) {
@ -236,6 +235,7 @@ _rtld_relocate_objects(first, bind_now, self)
return -1;
}
}
dbg(("a\n"));
if (_rtld_relocate_nonplt_objects(obj, self) < 0)
ok = 0;
if (obj->textrel) { /* Re-protected the text segment. */
@ -246,6 +246,7 @@ _rtld_relocate_objects(first, bind_now, self)
return -1;
}
}
dbg(("b\n"));
if (_rtld_relocate_plt_lazy(obj) < 0)
ok = 0;
#if defined(__i386__)
@ -268,6 +269,7 @@ _rtld_relocate_objects(first, bind_now, self)
obj->dlclose = _rtld_dlclose;
obj->dladdr = _rtld_dladdr;
dbg(("c\n"));
/* Set the special PLTGOT entries. */
if (obj->pltgot != NULL)
_rtld_setup_pltgot(obj);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.c,v 1.66 2002/09/21 05:24:17 junyoung Exp $ */
/* $NetBSD: rtld.c,v 1.67 2002/09/23 23:56:48 mycroft Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -418,7 +418,8 @@ _rtld(sp, relocbase)
if (pAUX_execfd != NULL) { /* Load the main program. */
int fd = pAUX_execfd->a_v;
dbg(("loading main program"));
_rtld_objmain = _rtld_map_object(argv[0], fd, NULL);
_rtld_objmain = _rtld_map_object(argv[0] ? xstrdup(argv[0]) :
xstrdup("main program"), fd, NULL);
close(fd);
if (_rtld_objmain == NULL)
_rtld_die();
@ -439,10 +440,6 @@ _rtld(sp, relocbase)
_rtld_objmain = _rtld_digest_phdr(phdr, phnum, entry);
}
if (argv[0] != NULL)
_rtld_objmain->path = xstrdup(argv[0]);
else
_rtld_objmain->path = xstrdup("main program");
_rtld_objmain->mainprog = true;
/*
@ -690,11 +687,8 @@ _rtld_dlopen(name, mode)
if (name == NULL) {
obj = _rtld_objmain;
obj->refcount++;
} else {
char *path = _rtld_find_library(name, _rtld_objmain);
if (path != NULL)
obj = _rtld_load_object(path, mode);
}
} else
obj = _rtld_load_library(name, _rtld_objmain, mode);
if (obj != NULL) {
++obj->dl_refcount;
@ -732,7 +726,7 @@ _rtld_objmain_sym(name)
hash = _rtld_elf_hash(name);
obj = _rtld_objmain;
def = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj, true);
def = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj);
if (def != NULL)
return obj->relocbase + def->st_value;
@ -766,11 +760,11 @@ _rtld_dlsym(handle, name)
return NULL;
}
if (handle == NULL) { /* Just the caller's shared object. */
def = _rtld_symlook_obj(name, hash, obj, true);
def = _rtld_symlook_obj(name, hash, obj);
defobj = obj;
} else { /* All the shared objects after the caller's */
while ((obj = obj->next) != NULL) {
if ((def = _rtld_symlook_obj(name, hash, obj, true)) != NULL) {
if ((def = _rtld_symlook_obj(name, hash, obj)) != NULL) {
defobj = obj;
break;
}
@ -782,13 +776,13 @@ _rtld_dlsym(handle, name)
if (obj->mainprog) {
/* Search main program and all libraries loaded by it. */
def = _rtld_symlook_list(name, hash, &_rtld_list_main, &defobj, true);
def = _rtld_symlook_list(name, hash, &_rtld_list_main, &defobj);
} else {
/*
* XXX - This isn't correct. The search should include the whole
* DAG rooted at the given object.
*/
def = _rtld_symlook_obj(name, hash, obj, true);
def = _rtld_symlook_obj(name, hash, obj);
defobj = obj;
}
}
@ -943,18 +937,12 @@ _rtld_linkmap_delete(obj)
static Obj_Entry *
_rtld_obj_from_addr(const void *addr)
{
unsigned long endhash;
Obj_Entry *obj;
endhash = _rtld_elf_hash(END_SYM);
for (obj = _rtld_objlist; obj != NULL; obj = obj->next) {
const Elf_Sym *endsym;
if (addr < (void *) obj->mapbase)
continue;
if ((endsym = _rtld_symlook_obj(END_SYM, endhash, obj, true)) == NULL)
continue; /* No "end" symbol?! */
if (addr < (void *) (obj->relocbase + endsym->st_value))
if (addr < (void *) (obj->mapbase + obj->mapsize))
return obj;
}
return NULL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.h,v 1.52 2002/09/19 14:05:37 junyoung Exp $ */
/* $NetBSD: rtld.h,v 1.53 2002/09/23 23:56:49 mycroft Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -269,19 +269,19 @@ int _rtld_relocate_plt_objects __P((const Obj_Entry *));
void _rtld_setup_pltgot __P((const Obj_Entry *));
/* search.c */
char *_rtld_find_library __P((const char *, const Obj_Entry *));
Obj_Entry *_rtld_load_library __P((const char *, const Obj_Entry *, int));
/* symbol.c */
unsigned long _rtld_elf_hash __P((const char *));
const Elf_Sym *_rtld_symlook_obj __P((const char *, unsigned long,
const Obj_Entry *, bool));
const Obj_Entry *));
const Elf_Sym *_rtld_find_symdef __P((unsigned long, const Obj_Entry *,
const Obj_Entry **, bool));
const Elf_Sym *_rtld_symlook_list(const char *, unsigned long,
Objlist *, const Obj_Entry **, bool in_plt);
Objlist *, const Obj_Entry **);
/* map_object.c */
Obj_Entry *_rtld_map_object __P((const char *, int, const struct stat *));
Obj_Entry *_rtld_map_object __P((char *, int, const struct stat *));
void _rtld_obj_free(Obj_Entry *);
Obj_Entry *_rtld_obj_new(void);

View File

@ -1,4 +1,4 @@
/* $NetBSD: search.c,v 1.10 2000/07/27 10:44:39 kleink Exp $ */
/* $NetBSD: search.c,v 1.11 2002/09/23 23:56:49 mycroft Exp $ */
/*
* Copyright 1996 Matt Thomas <matt@3am-software.com>
@ -55,61 +55,19 @@
/*
* Data declarations.
*/
static bool _rtld_check_library __P((const char *));
static char *_rtld_search_library_path __P((const char *, size_t, const char *,
size_t));
static Obj_Entry *_rtld_search_library_path __P((const char *, size_t,
const char *, size_t, int));
static bool
_rtld_check_library(pathname)
const char *pathname;
{
struct stat mystat;
Elf_Ehdr ehdr;
int fd;
if (stat(pathname, &mystat) == -1 || !S_ISREG(mystat.st_mode))
return false;
if ((fd = open(pathname, O_RDONLY)) == -1)
return false;
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
goto lose;
/* ELF_Ehdr.e_ident includes class */
if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
ehdr.e_ident[EI_CLASS] != ELFCLASS)
goto lose;
switch (ehdr.e_machine) {
ELFDEFNNAME(MACHDEP_ID_CASES)
default:
goto lose;
}
if (ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
ehdr.e_version != EV_CURRENT ||
ehdr.e_ident[EI_DATA] != ELFDEFNNAME(MACHDEP_ENDIANNESS) ||
ehdr.e_type != ET_DYN)
goto lose;
close(fd);
return true;
lose:
close(fd);
return false;
}
static char *
_rtld_search_library_path(name, namelen, dir, dirlen)
static Obj_Entry *
_rtld_search_library_path(name, namelen, dir, dirlen, mode)
const char *name;
size_t namelen;
const char *dir;
size_t dirlen;
int mode;
{
char *pathname;
Obj_Entry *obj;
pathname = xmalloc(dirlen + 1 + namelen + 1);
(void)strncpy(pathname, dir, dirlen);
@ -117,11 +75,10 @@ _rtld_search_library_path(name, namelen, dir, dirlen)
strcpy(pathname + dirlen + 1, name);
dbg((" Trying \"%s\"", pathname));
if (_rtld_check_library(pathname)) /* We found it */
return pathname;
free(pathname);
return NULL;
obj = _rtld_load_object(pathname, mode);
if (obj == NULL)
free(pathname);
return obj;
}
/*
@ -132,14 +89,16 @@ _rtld_search_library_path(name, namelen, dir, dirlen)
* If the second argument is non-NULL, then it refers to an already-
* loaded shared object, whose library search path will be searched.
*/
char *
_rtld_find_library(name, refobj)
Obj_Entry *
_rtld_load_library(name, refobj, mode)
const char *name;
const Obj_Entry *refobj;
int mode;
{
Search_Path *sp;
char *pathname;
int namelen;
Obj_Entry *obj;
if (strchr(name, '/') != NULL) { /* Hard coded pathname */
if (name[0] != '/' && !_rtld_trust) {
@ -160,45 +119,39 @@ _rtld_find_library(name, refobj)
(void)strcpy(pathname, LIBDIR);
(void)strcpy(pathname + LIBDIRLEN, name +
SVR4_LIBDIRLEN);
return pathname;
goto found2;
}
#endif /* SVR4_LIBDIR */
return xstrdup(name);
pathname = xstrdup(name);
goto found2;
}
dbg((" Searching for \"%s\" (%p)", name, refobj));
namelen = strlen(name);
for (sp = _rtld_paths; sp != NULL; sp = sp->sp_next)
if ((pathname = _rtld_search_library_path(name, namelen,
sp->sp_path, sp->sp_pathlen)) != NULL)
return (pathname);
if ((obj = _rtld_search_library_path(name, namelen,
sp->sp_path, sp->sp_pathlen, mode)) != NULL)
goto found;
if (refobj != NULL)
for (sp = refobj->rpaths; sp != NULL; sp = sp->sp_next)
if ((pathname = _rtld_search_library_path(name,
namelen, sp->sp_path, sp->sp_pathlen)) != NULL)
return (pathname);
if ((obj = _rtld_search_library_path(name,
namelen, sp->sp_path, sp->sp_pathlen, mode)) != NULL)
goto found;
for (sp = _rtld_default_paths; sp != NULL; sp = sp->sp_next)
if ((pathname = _rtld_search_library_path(name, namelen,
sp->sp_path, sp->sp_pathlen)) != NULL)
return (pathname);
#if 0
if ((refobj != NULL &&
(pathname = _rtld_search_library_path(name,
refobj->rpath)) != NULL) ||
(pathname = _rtld_search_library_path(name,
ld_library_path)) != NULL
#ifdef SVR4_LIBDIR
LOSE !
||(pathname = _rtld_search_library_path(name, SVR4_LIBDIR)) != NULL
#endif
)
return pathname;
#endif
if ((obj = _rtld_search_library_path(name, namelen,
sp->sp_path, sp->sp_pathlen, mode)) != NULL)
goto found;
_rtld_error("Shared object \"%s\" not found", name);
return NULL;
found2:
obj = _rtld_load_object(pathname, mode);
if (obj == NULL)
free(pathname);
found:
return obj;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: symbol.c,v 1.19 2002/09/13 03:40:40 mycroft Exp $ */
/* $NetBSD: symbol.c,v 1.20 2002/09/23 23:56:49 mycroft Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -75,7 +75,7 @@ _rtld_elf_hash(name)
const Elf_Sym *
_rtld_symlook_list(const char *name, unsigned long hash, Objlist *objlist,
const Obj_Entry **defobj_out, bool in_plt)
const Obj_Entry **defobj_out)
{
const Elf_Sym *symp;
const Elf_Sym *def;
@ -85,7 +85,7 @@ _rtld_symlook_list(const char *name, unsigned long hash, Objlist *objlist,
def = NULL;
defobj = NULL;
SIMPLEQ_FOREACH(elm, objlist, link) {
if ((symp = _rtld_symlook_obj(name, hash, elm->obj, in_plt))
if ((symp = _rtld_symlook_obj(name, hash, elm->obj))
!= NULL) {
if ((def == NULL) ||
(ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
@ -110,36 +110,28 @@ _rtld_symlook_list(const char *name, unsigned long hash, Objlist *objlist,
* eliminates many recomputations of the hash value.
*/
const Elf_Sym *
_rtld_symlook_obj(name, hash, obj, in_plt)
_rtld_symlook_obj(name, hash, obj)
const char *name;
unsigned long hash;
const Obj_Entry *obj;
bool in_plt;
{
unsigned long symnum = obj->buckets[hash % obj->nbuckets];
unsigned long symnum;
while (symnum != ELF_SYM_UNDEFINED) {
for (symnum = obj->buckets[hash % obj->nbuckets];
symnum != ELF_SYM_UNDEFINED;
symnum = obj->chains[symnum]) {
const Elf_Sym *symp;
const char *strp;
assert(symnum < obj->nchains);
symp = obj->symtab + symnum;
strp = obj->strtab + symp->st_name;
#if 0
assert(symp->st_name != 0);
#endif
if (strcmp(name, strp) == 0) {
if (symp->st_shndx != SHN_UNDEF
#if !defined(__mips__) /* Following doesn't work on MIPS? mhitch */
|| (!in_plt && symp->st_value != 0 &&
ELF_ST_TYPE(symp->st_info) == STT_FUNC)
#endif
)
if (name[1] == strp[1] && !strcmp(name, strp)) {
if (symp->st_shndx != SHN_UNDEF)
return symp;
else
return NULL;
}
symnum = obj->chains[symnum];
}
return NULL;
@ -175,7 +167,7 @@ _rtld_find_symdef(symnum, refobj, defobj_out, in_plt)
defobj = NULL;
if (refobj->symbolic) { /* Look first in the referencing object */
symp = _rtld_symlook_obj(name, hash, refobj, in_plt);
symp = _rtld_symlook_obj(name, hash, refobj);
if (symp != NULL) {
def = symp;
defobj = refobj;
@ -184,7 +176,7 @@ _rtld_find_symdef(symnum, refobj, defobj_out, in_plt)
/* Search all objects loaded at program start up. */
if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
symp = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj, in_plt);
symp = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj);
if (symp != NULL &&
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
def = symp;
@ -196,8 +188,7 @@ _rtld_find_symdef(symnum, refobj, defobj_out, in_plt)
SIMPLEQ_FOREACH(elm, &refobj->dldags, link) {
if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
break;
symp = _rtld_symlook_list(name, hash, &elm->obj->dagmembers, &obj,
in_plt);
symp = _rtld_symlook_list(name, hash, &elm->obj->dagmembers, &obj);
if (symp != NULL &&
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
def = symp;
@ -207,7 +198,7 @@ _rtld_find_symdef(symnum, refobj, defobj_out, in_plt)
/* Search all RTLD_GLOBAL objects. */
if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
symp = _rtld_symlook_list(name, hash, &_rtld_list_global, &obj, in_plt);
symp = _rtld_symlook_list(name, hash, &_rtld_list_global, &obj);
if (symp != NULL &&
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
def = symp;