diff options
-rw-r--r-- | libexec/ld.so/Makefile | 4 | ||||
-rw-r--r-- | libexec/ld.so/alpha/rtld_machine.c | 41 | ||||
-rw-r--r-- | libexec/ld.so/amd64/rtld_machine.c | 27 | ||||
-rw-r--r-- | libexec/ld.so/arm/rtld_machine.c | 28 | ||||
-rw-r--r-- | libexec/ld.so/dlfcn.c | 60 | ||||
-rw-r--r-- | libexec/ld.so/hppa/archdep.h | 8 | ||||
-rw-r--r-- | libexec/ld.so/hppa/rtld_machine.c | 27 | ||||
-rw-r--r-- | libexec/ld.so/i386/rtld_machine.c | 29 | ||||
-rw-r--r-- | libexec/ld.so/library.c | 7 | ||||
-rw-r--r-- | libexec/ld.so/library_mquery.c | 8 | ||||
-rw-r--r-- | libexec/ld.so/library_subr.c | 112 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 51 | ||||
-rw-r--r-- | libexec/ld.so/mips64/rtld_machine.c | 41 | ||||
-rw-r--r-- | libexec/ld.so/powerpc/rtld_machine.c | 54 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 138 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 69 | ||||
-rw-r--r-- | libexec/ld.so/sparc/rtld_machine.c | 38 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/rtld_machine.c | 38 |
18 files changed, 457 insertions, 323 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile index c65b116284b..73a0c71454d 100644 --- a/libexec/ld.so/Makefile +++ b/libexec/ld.so/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.25 2005/03/23 19:48:05 drahn Exp $ +# $OpenBSD: Makefile,v 1.26 2005/09/16 23:19:41 drahn Exp $ SUBDIR=ldconfig ldd VPATH=${.CURDIR}/../../lib/libc/string @@ -17,12 +17,14 @@ MAN= ld.so.1 .include "${.CURDIR}/${MACHINE_ARCH}/Makefile.inc" .PATH: ${.CURDIR}/${MACHINE_ARCH} +CFLAGS += -g CFLAGS += -Wall CFLAGS += -I${.CURDIR} -I${.CURDIR}/${MACHINE_ARCH} \ -Dstrsep=_dl_strsep INSTALL_STRIP= ELF_LDFLAGS+=--shared -Bsymbolic +ELF_LDFLAGS+=-g $(PROG): $(LD) -x -e _dl_start $(ELF_LDFLAGS) -o $(PROG) $(OBJS) $(LDADD) diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c index b8e90399d8d..d64b1fd89cb 100644 --- a/libexec/ld.so/alpha/rtld_machine.c +++ b/libexec/ld.so/alpha/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.31 2004/05/25 21:42:47 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.32 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -96,9 +96,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) switch (ELF64_R_TYPE(relas->r_info)) { case R_TYPE(REFQUAD): ooff = _dl_find_symbol_bysym(object, - ELF64_R_SYM(relas->r_info), _dl_objects, &this, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, - sym->st_size); + ELF64_R_SYM(relas->r_info), &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, + sym->st_size, NULL); if (this == NULL) goto resolve_failed; *r_addr += ooff + this->st_value + relas->r_addend; @@ -121,18 +121,18 @@ _dl_printf("unaligned RELATIVE: %p type: %d %s 0x%lx -> 0x%lx\n", r_addr, *r_addr += loff; break; case R_TYPE(JMP_SLOT): - ooff = _dl_find_symbol(symn, _dl_objects, &this, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, - sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, + sym->st_size, object, NULL); if (this == NULL) goto resolve_failed; *r_addr = ooff + this->st_value + relas->r_addend; break; case R_TYPE(GLOB_DAT): ooff = _dl_find_symbol_bysym(object, - ELF64_R_SYM(relas->r_info), _dl_objects, &this, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, - sym->st_size); + ELF64_R_SYM(relas->r_info), &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, + sym->st_size, NULL); if (this == NULL) goto resolve_failed; *r_addr = ooff + this->st_value + relas->r_addend; @@ -185,8 +185,9 @@ _dl_bind(elf_object_t *object, int reloff) addr = (Elf_Addr *)(object->load_offs + rela->r_offset); this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, NULL); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ @@ -229,28 +230,28 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; plt_addr = NULL; object->plt_size = 0; this = NULL; - ooff = _dl_find_symbol("__plt_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL); if (this != NULL) plt_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__plt_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL); if (this != NULL) object->plt_size = ooff + this->st_value - plt_addr; diff --git a/libexec/ld.so/amd64/rtld_machine.c b/libexec/ld.so/amd64/rtld_machine.c index d482f52c300..2dd82c91183 100644 --- a/libexec/ld.so/amd64/rtld_machine.c +++ b/libexec/ld.so/amd64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.7 2004/05/25 21:42:47 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.8 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 2002,2004 Dale Rahn @@ -234,11 +234,11 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) } else { this = NULL; ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), _dl_objects, - &this,NULL,SYM_SEARCH_ALL|SYM_WARNNOTFOUND| + ELF_R_SYM(rels->r_info), &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT))? SYM_PLT:SYM_NOTPLT), - sym->st_size); + sym->st_size, NULL); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " @@ -264,10 +264,10 @@ resolve_failed: size_t size = dstsym->st_size; Elf_Addr soff; - soff = _dl_find_symbol(symn, object->next, &srcsym, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| + soff = _dl_find_symbol(symn, &srcsym, + SYM_SEARCH_OTHER|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT)) ? SYM_PLT:SYM_NOTPLT), - size, object); + size, object, NULL); if (srcsym == NULL) goto resolve_failed; @@ -353,8 +353,9 @@ _dl_bind(elf_object_t *object, int index) addr = (Elf_Word *)(object->load_offs + rel->r_offset); this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, NULL); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ @@ -404,14 +405,14 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; diff --git a/libexec/ld.so/arm/rtld_machine.c b/libexec/ld.so/arm/rtld_machine.c index e6dc6160732..15d91736abf 100644 --- a/libexec/ld.so/arm/rtld_machine.c +++ b/libexec/ld.so/arm/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.6 2004/05/25 21:42:48 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.7 2005/09/16 23:19:42 drahn Exp $ */ /* * Copyright (c) 2004 Dale Rahn @@ -235,12 +235,11 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) } else { this = NULL; ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), - _dl_objects, &this, NULL, + ELF_R_SYM(rels->r_info), &this, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT)) ? SYM_PLT : SYM_NOTPLT), - sym->st_size); + sym->st_size, NULL); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " @@ -269,9 +268,9 @@ resolve_failed: size_t size = dstsym->st_size; Elf_Addr soff; - soff = _dl_find_symbol(symn, object->next, &srcsym, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, - size, object); + soff = _dl_find_symbol(symn, &srcsym, + SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, + size, object, NULL); if (srcsym == NULL) goto resolve_failed; @@ -347,14 +346,16 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; @@ -408,8 +409,9 @@ _dl_bind(elf_object_t *object, int relidx) sym += ELF_R_SYM(rel->r_info); symn = object->dyn.strtab + sym->st_name; - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, NULL); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c index 0095023b1c1..c7e6a5e65b7 100644 --- a/libexec/ld.so/dlfcn.c +++ b/libexec/ld.so/dlfcn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dlfcn.c,v 1.49 2005/09/13 03:32:15 drahn Exp $ */ +/* $OpenBSD: dlfcn.c,v 1.50 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -49,6 +49,7 @@ dlopen(const char *libname, int flags) { elf_object_t *object, *dynobj; Elf_Dyn *dynp; + struct dep_node *n; if (libname == NULL) return _dl_objects; @@ -56,18 +57,28 @@ dlopen(const char *libname, int flags) DL_DEB(("dlopen: loading: %s\n", libname)); _dl_thread_kern_stop(); + object = _dl_load_shlib(libname, _dl_objects, OBJTYPE_DLO, flags); if (object == 0) { _dl_thread_kern_go(); return((void *)0); } + if (object->refcount > 1) + return((void *)object); /* Already loaded */ + /* this add_object should not be here, XXX */ _dl_add_object(object); - _dl_link_sub(object, _dl_objects); - _dl_thread_kern_go(); - if (object->refcount > 1) - return((void *)object); /* Already loaded */ + DL_DEB(("head [%s]\n", object->load_name )); + object->load_object = object; + _dl_loading_object = object; + + n = _dl_malloc(sizeof *n); + if (n == NULL) + _dl_exit(5); + n->data = object; + TAILQ_INSERT_TAIL(&object->dload_list, n, next_sib); + /* * Check for 'needed' objects. For each 'needed' object we @@ -90,7 +101,6 @@ dlopen(const char *libname, int flags) deplibname = dynobj->dyn.strtab + dynp->d_un.d_val; DL_DEB(("dlopen: loading: %s required by %s\n", deplibname, libname)); - _dl_thread_kern_stop(); depobj = _dl_load_shlib(deplibname, dynobj, OBJTYPE_LIB, flags|RTLD_GLOBAL); if (!depobj) @@ -98,7 +108,6 @@ dlopen(const char *libname, int flags) /* this add_object should not be here, XXX */ _dl_add_object(depobj); _dl_link_sub(depobj, dynobj); - _dl_thread_kern_go(); tmpobj->dep_next = _dl_malloc(sizeof(elf_object_t)); tmpobj->dep_next->next = depobj; @@ -107,11 +116,13 @@ dlopen(const char *libname, int flags) dynobj = dynobj->next; } + _dl_link_dlopen(object); _dl_rtld(object); _dl_call_init(object); - _dl_link_dlopen(object); + _dl_loading_object = NULL; + DL_DEB(("tail %s\n", object->load_name )); if (_dl_debug_map->r_brk) { _dl_debug_map->r_state = RT_ADD; @@ -120,6 +131,8 @@ dlopen(const char *libname, int flags) (*((void (*)(void))_dl_debug_map->r_brk))(); } + _dl_thread_kern_go(); + DL_DEB(("dlopen: %s: done.\n", libname)); return((void *)object); @@ -132,7 +145,7 @@ dlsym(void *handle, const char *name) elf_object_t *dynobj; void *retval; const Elf_Sym *sym = NULL; - int flags; + int flags; if (handle == NULL || handle == RTLD_NEXT || handle == RTLD_SELF) { @@ -145,25 +158,19 @@ dlsym(void *handle, const char *name) return(0); } - if (handle == RTLD_NEXT) { - object = object->next; - if (object == NULL) { - _dl_errno = DL_NO_SYMBOL; - return(0); - } - } - - if (handle == NULL) + if (handle == RTLD_NEXT) + flags = SYM_SEARCH_NEXT|SYM_PLT; + else if (handle == RTLD_SELF) flags = SYM_SEARCH_SELF|SYM_PLT; else - flags = SYM_SEARCH_ALL|SYM_PLT; + flags = SYM_DLSYM|SYM_PLT; } else if (handle == RTLD_DEFAULT) { object = _dl_objects; flags = SYM_SEARCH_ALL|SYM_PLT; } else { object = (elf_object_t *)handle; - flags = SYM_SEARCH_SELF|SYM_NOTPLT; + flags = SYM_DLSYM|SYM_PLT; dynobj = _dl_objects; while (dynobj && dynobj != object) @@ -175,8 +182,8 @@ dlsym(void *handle, const char *name) } } - retval = (void *)_dl_find_symbol(name, object, &sym, NULL, - flags|SYM_NOWARNNOTFOUND, 0, object); + retval = (void *)_dl_find_symbol(name, &sym, + flags|SYM_NOWARNNOTFOUND, 0, object, NULL); if (sym != NULL) { retval += sym->st_value; @@ -219,8 +226,12 @@ dlclose(void *handle) if (handle == _dl_objects) return 0; + _dl_thread_kern_stop(); + retval = _dl_real_close(handle); + _dl_thread_kern_go(); + if (_dl_debug_map->r_brk) { _dl_debug_map->r_state = RT_DELETE; (*((void (*)(void))_dl_debug_map->r_brk))(); @@ -246,9 +257,10 @@ _dl_real_close(void *handle) return (1); } - _dl_unlink_dlopen(object); + _dl_notify_unload_shlib(object); _dl_run_all_dtors(); + _dl_unlink_dlopen(object); _dl_unload_shlib(object); return (0); } @@ -307,8 +319,6 @@ dlerror(void) void _dl_show_objects(void) { - extern int _dl_symcachestat_hits; - extern int _dl_symcachestat_lookups; elf_object_t *object; char *objtypename; int outputfd; diff --git a/libexec/ld.so/hppa/archdep.h b/libexec/ld.so/hppa/archdep.h index a5008bb9f74..94e56079b42 100644 --- a/libexec/ld.so/hppa/archdep.h +++ b/libexec/ld.so/hppa/archdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: archdep.h,v 1.2 2004/06/07 15:18:19 mickey Exp $ */ +/* $OpenBSD: archdep.h,v 1.3 2005/09/16 23:19:42 drahn Exp $ */ /* * Copyright (c) 2004 Michael Shalayeff @@ -67,6 +67,12 @@ RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v) _dl_exit(20); } +/* + * !!!!! WARNING: THIS CODE CANNOT HANDLE ld.so RELOCATIONS OF THE FORM + * 0000bde8 R_PARISC_DIR32 .data+0x00000048 + * these can be caused by static intialization foo = &bar; + * prepare to code around this problem, or fix it here. + */ static inline void RELOC_RELA(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v) { diff --git a/libexec/ld.so/hppa/rtld_machine.c b/libexec/ld.so/hppa/rtld_machine.c index 48f677b895d..a7005d41e05 100644 --- a/libexec/ld.so/hppa/rtld_machine.c +++ b/libexec/ld.so/hppa/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.7 2005/01/09 17:57:40 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.8 2005/09/16 23:19:42 drahn Exp $ */ /* * Copyright (c) 2004 Michael Shalayeff @@ -160,10 +160,10 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) ooff = 0; if (ELF_R_SYM(rela->r_info) && sym->st_name) { ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rela->r_info), _dl_objects, - &this, &sobj, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND| + ELF_R_SYM(rela->r_info), &this, + SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND| ((type == RELOC_DIR32) ? SYM_NOTPLT : SYM_PLT), - sym->st_size); + sym->st_size, &sobj); if (!this) { _dl_printf("%s: %s: can't resolve reference '%s'\n", _dl_progname, object->load_name, symn); @@ -235,9 +235,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) case RELOC_COPY: size = sym->st_size; - ooff = _dl_find_symbol(symn, object->next, &sym, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, - size, object); + ooff = _dl_find_symbol(symn, &sym, + SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, + size, object, NULL); if (sym) { _dl_bcopy((void *)(ooff + sym->st_value), pt, sym->st_size); @@ -277,14 +277,14 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL ); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; @@ -343,8 +343,9 @@ _dl_bind(elf_object_t *object, int reloff) addr = (Elf_Addr *)(object->load_offs + rela->r_offset); this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, &this, &sobj, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, &sobj); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ diff --git a/libexec/ld.so/i386/rtld_machine.c b/libexec/ld.so/i386/rtld_machine.c index 06aca82d00b..6c891593490 100644 --- a/libexec/ld.so/i386/rtld_machine.c +++ b/libexec/ld.so/i386/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.16 2004/05/25 21:42:48 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.17 2005/09/16 23:19:42 drahn Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -227,11 +227,11 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) } else { this = NULL; ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(rels->r_info), _dl_objects, - &this,NULL,SYM_SEARCH_ALL|SYM_WARNNOTFOUND| + ELF_R_SYM(rels->r_info), &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT))? SYM_PLT:SYM_NOTPLT), - sym->st_size); + sym->st_size, NULL); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " @@ -257,10 +257,10 @@ resolve_failed: size_t size = dstsym->st_size; Elf_Addr soff; - soff = _dl_find_symbol(symn, object->next, &srcsym, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| + soff = _dl_find_symbol(symn, &srcsym, + SYM_SEARCH_OTHER|SYM_WARNNOTFOUND| ((type == R_TYPE(JUMP_SLOT)) ? SYM_PLT:SYM_NOTPLT), - size, object); + size, object, NULL); if (srcsym == NULL) goto resolve_failed; @@ -356,8 +356,9 @@ _dl_bind(elf_object_t *object, int index) addr = (Elf_Word *)(object->load_offs + rel->r_offset); this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, NULL); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ @@ -406,14 +407,16 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c index 37b5eed57f0..5a53c8bce31 100644 --- a/libexec/ld.so/library.c +++ b/libexec/ld.so/library.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library.c,v 1.40 2005/05/23 19:22:11 drahn Exp $ */ +/* $OpenBSD: library.c,v 1.41 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -66,7 +66,7 @@ _dl_unload_shlib(elf_object_t *object) elf_object_t * -_dl_tryload_shlib(const char *libname, int type) +_dl_tryload_shlib(const char *libname, int type, int flags) { int libfile, i, align = _dl_pagesz - 1; struct load_list *next_load, *load_list = NULL; @@ -85,6 +85,7 @@ _dl_tryload_shlib(const char *libname, int type) object = _dl_lookup_object(libname); if (object) { object->refcount++; + object->load_object->obj_flags |= flags & RTLD_GLOBAL; return(object); /* Already loaded */ } @@ -102,6 +103,7 @@ _dl_tryload_shlib(const char *libname, int type) for (object = _dl_objects; object != NULL; object = object->next) { if (object->dev == sb.st_dev && object->inode == sb.st_ino) { + object->load_object->obj_flags |= flags & RTLD_GLOBAL; _dl_close(libfile); return(object); } @@ -223,6 +225,7 @@ _dl_tryload_shlib(const char *libname, int type) /* set inode, dev from stat info */ object->dev = sb.st_dev; object->inode = sb.st_ino; + object->obj_flags = flags; } else { /* XXX not possible. object cannot come back NULL */ _dl_munmap((void *)libaddr, maxva - minva); diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c index 91dd295d43f..c7f41df99ff 100644 --- a/libexec/ld.so/library_mquery.c +++ b/libexec/ld.so/library_mquery.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library_mquery.c,v 1.22 2005/05/31 14:31:36 drahn Exp $ */ +/* $OpenBSD: library_mquery.c,v 1.23 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -70,7 +70,7 @@ _dl_unload_shlib(elf_object_t *object) elf_object_t * -_dl_tryload_shlib(const char *libname, int type) +_dl_tryload_shlib(const char *libname, int type, int flags) { int libfile, i, align = _dl_pagesz - 1; struct load_list *ld, *lowld = NULL; @@ -90,6 +90,7 @@ _dl_tryload_shlib(const char *libname, int type) object = _dl_lookup_object(libname); if (object) { object->refcount++; + object->load_object->obj_flags |= flags & RTLD_GLOBAL; return(object); /* Already loaded */ } @@ -107,6 +108,7 @@ _dl_tryload_shlib(const char *libname, int type) for (object = _dl_objects; object != NULL; object = object->next) { if (object->dev == sb.st_dev && object->inode == sb.st_ino) { + object->load_object->obj_flags |= flags & RTLD_GLOBAL; _dl_close(libfile); return(object); } @@ -261,6 +263,8 @@ retry: /* set inode, dev from stat info */ object->dev = sb.st_dev; object->inode = sb.st_ino; + object->obj_flags = flags; + } else { /* XXX no point. object is never returned NULL */ _dl_load_list_free(lowld); diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c index c2e7d8f8e81..6ffdbb9a41e 100644 --- a/libexec/ld.so/library_subr.c +++ b/libexec/ld.so/library_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library_subr.c,v 1.5 2005/05/23 19:22:11 drahn Exp $ */ +/* $OpenBSD: library_subr.c,v 1.6 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -32,6 +32,7 @@ #include <sys/types.h> #include <sys/syslimits.h> #include <sys/param.h> +#include <sys/queue.h> #include <dirent.h> #include "archdep.h" @@ -41,11 +42,11 @@ #define DEFAULT_PATH "/usr/lib" -static void _dl_unload_dlopen_recurse(struct dep_node *node); /* STATIC DATA */ -static struct dep_node *_dlopened_first_child; -static struct dep_node *_dlopened_last_child; +struct dlochld _dlopened_child_list; + + /* * _dl_match_file() @@ -254,7 +255,7 @@ _dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags) ignore_hints = 0; if (_dl_strchr(libname, '/')) { - object = _dl_tryload_shlib(libname, type); + object = _dl_tryload_shlib(libname, type, flags); return(object); } @@ -274,10 +275,9 @@ again: "using it anyway\n", sod.sod_name, sod.sod_major, req_sod.sod_minor, sod.sod_minor); - object = _dl_tryload_shlib(hint, type); + object = _dl_tryload_shlib(hint, type, flags); if (object != NULL) { _dl_free((char *)sod.sod_name); - object->obj_flags = flags; return (object); } } @@ -296,10 +296,9 @@ again: "using it anyway\n", sod.sod_name, sod.sod_major, req_sod.sod_minor, sod.sod_minor); - object = _dl_tryload_shlib(hint, type); + object = _dl_tryload_shlib(hint, type, flags); if (object != NULL) { _dl_free((char *)sod.sod_name); - object->obj_flags = flags; return (object); } } @@ -314,10 +313,9 @@ again: "using it anyway\n", sod.sod_name, sod.sod_major, req_sod.sod_minor, sod.sod_minor); - object = _dl_tryload_shlib(hint, type); + object = _dl_tryload_shlib(hint, type, flags); if (object != NULL) { _dl_free((char *)sod.sod_name); - object->obj_flags = flags; return(object); } } @@ -344,12 +342,7 @@ _dl_link_dlopen(elf_object_t *dep) _dl_exit(5); n->data = dep; - n->next_sibling = NULL; - if (_dlopened_first_child) { - _dlopened_last_child->next_sibling = n; - _dlopened_last_child = n; - } else - _dlopened_first_child = _dlopened_last_child = n; + TAILQ_INSERT_TAIL(&_dlopened_child_list, n, next_sib); DL_DEB(("linking %s as dlopen()ed\n", dep->load_name)); } @@ -357,34 +350,19 @@ _dl_link_dlopen(elf_object_t *dep) void _dl_unlink_dlopen(elf_object_t *dep) { - struct dep_node **dnode; - struct dep_node *pnode; - struct dep_node *next; - dnode = &_dlopened_first_child; + struct dep_node *dnode; - if (_dlopened_first_child == NULL) - return; + TAILQ_FOREACH(dnode, &_dlopened_child_list, next_sib) + if (dnode->data == dep) + break; - if (_dlopened_first_child->data == dep) { - next = _dlopened_first_child->next_sibling; - _dl_free(_dlopened_first_child); - _dlopened_first_child = next; + if (dnode == NULL) /* XXX - not found? */ return; - } - pnode = _dlopened_first_child; - - while (pnode->next_sibling != NULL) { - if (pnode->next_sibling->data == dep) { - next = pnode->next_sibling->next_sibling; - if (pnode->next_sibling == _dlopened_last_child) - _dlopened_last_child = pnode; - _dl_free(pnode->next_sibling); - pnode->next_sibling = next; - break; - } - pnode = pnode->next_sibling; - } + + TAILQ_REMOVE(&_dlopened_child_list, dnode, next_sib); + + _dl_free(dnode); } void @@ -393,34 +371,26 @@ _dl_notify_unload_shlib(elf_object_t *object) struct dep_node *n; if (--object->refcount == 0) - for (n = object->first_child; n; n = n->next_sibling) + TAILQ_FOREACH(n, &object->child_list, next_sib) _dl_notify_unload_shlib(n->data); } void _dl_unload_dlopen(void) { - if (_dlopened_first_child != NULL) - _dl_unload_dlopen_recurse(_dlopened_first_child); -} + struct dep_node *node; -/* - * is recursion here a good thing? - */ -void -_dl_unload_dlopen_recurse(struct dep_node *node) -{ - if (node->next_sibling != NULL) { - _dl_unload_dlopen_recurse(node->next_sibling); + TAILQ_FOREACH_REVERSE(node, &_dlopened_child_list, dlochld, next_sib) { + _dl_notify_unload_shlib(node->data); + _dl_run_all_dtors(); + if (_dl_exiting == 0) + _dl_unload_shlib(node->data); + + TAILQ_REMOVE(&_dlopened_child_list, node, next_sib); + _dl_free(node); } - _dl_notify_unload_shlib(node->data); - _dl_run_all_dtors(); - if (_dl_exiting == 0) - _dl_unload_shlib(node->data); - _dl_free(node); } - void _dl_link_sub(elf_object_t *dep, elf_object_t *p) { @@ -428,14 +398,24 @@ _dl_link_sub(elf_object_t *dep, elf_object_t *p) n = _dl_malloc(sizeof *n); if (n == NULL) - _dl_exit(5); + _dl_exit(7); + n->data = dep; + TAILQ_INSERT_TAIL(&p->child_list, n, next_sib); + + /* + * because two child libraries can refer to the same library + * and we only want to deal with each one once, check for dups + * before adding new, dup libs will have the same dep pointer. + */ + TAILQ_FOREACH(n, &_dl_loading_object->dload_list, next_sib) + if (n->data == dep) + return; /* found, dont bother adding */ + + n = _dl_malloc(sizeof *n); + if (n == NULL) + _dl_exit(8); n->data = dep; - n->next_sibling = NULL; - if (p->first_child) { - p->last_child->next_sibling = n; - p->last_child = n; - } else - p->first_child = p->last_child = n; + TAILQ_INSERT_TAIL(&_dl_loading_object->dload_list, n, next_sib); DL_DEB(("linking dep %s as child of %s\n", dep->load_name, p->load_name)); diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index fd3b73542e1..55049a35744 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.86 2005/05/10 03:36:07 drahn Exp $ */ +/* $OpenBSD: loader.c,v 1.87 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -112,9 +112,8 @@ _dl_run_all_dtors() (node->refcount == 0) && (node->status & STAT_INIT_DONE) && ((node->status & STAT_FINI_DONE) == 0)) - for (dnode = node->first_child; - dnode != NULL; - dnode = dnode->next_sibling) + TAILQ_FOREACH(dnode, &node->child_list, + next_sib) dnode->data->status &= ~STAT_FINI_READY; } @@ -141,16 +140,11 @@ _dl_run_dtors(elf_object_t *object) { struct dep_node *n; - for (n = object->first_child; n; n = n->next_sibling) { + TAILQ_FOREACH(n, &object->child_list, next_sib) _dl_notify_unload_shlib(n->data); - } _dl_run_all_dtors(); - - if (_dl_exiting == 0) - for (n = object->first_child; n; n = n->next_sibling) - _dl_unload_shlib(n->data); } /* @@ -271,6 +265,7 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) char *us = ""; unsigned int i; int libcnt = 0; + struct dep_node *n; _dl_setup_env(envp); @@ -308,6 +303,9 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) DL_DEB(("rtld loading: '%s'\n", _dl_progname)); + /* init this in runtime, not statically */ + TAILQ_INIT(&_dlopened_child_list); + exe_obj = NULL; /* * Examine the user application and set up object information. @@ -324,6 +322,15 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) } phdp++; } + exe_obj->load_object = exe_obj; + TAILQ_INIT(&exe_obj->dload_list); + + n = _dl_malloc(sizeof *n); + if (n == NULL) + _dl_exit(9); + n->data = exe_obj; + TAILQ_INSERT_TAIL(&exe_obj->dload_list, n, next_sib); + if (_dl_preload != NULL) _dl_dopreload(_dl_preload); @@ -356,12 +363,10 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) for (dynp = dynobj->load_dyn, i = 0; dynp->d_tag; - dynp++) { - if (dynp->d_tag == DT_NEEDED) { + dynp++) + if (dynp->d_tag == DT_NEEDED) liblist[i++].dynp = dynp; - } - } /* Randomize these */ for (i = 0; i < libcnt; i++) randomlist[i] = i; @@ -414,6 +419,13 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) dyn_obj = _dl_finalize_object(us, dynp, 0, OBJTYPE_LDR, dl_data[AUX_base], loff); _dl_add_object(dyn_obj); + + n = _dl_malloc(sizeof *n); + if (n == NULL) + _dl_exit(5); + n->data = dyn_obj; + TAILQ_INSERT_TAIL(&exe_obj->dload_list, n, next_sib); + dyn_obj->status |= STAT_RELOC_DONE; /* @@ -486,8 +498,9 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) Elf_Addr ooff; sym = NULL; - ooff = _dl_find_symbol("atexit", _dl_objects, &sym, &sobj, - SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, 0, dyn_obj); + ooff = _dl_find_symbol("atexit", &sym, + SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, + 0, dyn_obj, &sobj); if (sym == NULL) _dl_printf("cannot find atexit, destructors will not be run!\n"); else @@ -743,7 +756,7 @@ _dl_call_init(elf_object_t *object) { struct dep_node *n; - for (n = object->first_child; n; n = n->next_sibling) { + TAILQ_FOREACH(n, &object->child_list, next_sib) { if (n->data->status & STAT_INIT_DONE) continue; _dl_call_init(n->data); @@ -820,8 +833,8 @@ _dl_fixup_user_env(void) dummy_obj.load_name = "ld.so"; sym = NULL; - ooff = _dl_find_symbol("environ", _dl_objects, &sym, NULL, - SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, 0, &dummy_obj); + ooff = _dl_find_symbol("environ", &sym, + SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, 0, &dummy_obj, NULL); if (sym != NULL) *((char ***)(sym->st_value + ooff)) = _dl_so_envp; } diff --git a/libexec/ld.so/mips64/rtld_machine.c b/libexec/ld.so/mips64/rtld_machine.c index ccc6ab05b95..fde75a0bb4f 100644 --- a/libexec/ld.so/mips64/rtld_machine.c +++ b/libexec/ld.so/mips64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.5 2004/10/01 22:10:37 pefo Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.6 2005/09/16 23:19:42 drahn Exp $ */ /* * Copyright (c) 1998-2004 Opsycon AB, Sweden. @@ -74,14 +74,15 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) this = NULL; got_start = 0; got_end = 0; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) got_start = ooff + this->st_value; - this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) got_end = ooff + this->st_value; @@ -104,9 +105,9 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz) if (ELF64_R_SYM(relocs->r_info) && !(ELF64_ST_BIND(sym->st_info) == STB_LOCAL && ELF64_ST_TYPE (sym->st_info) == STT_NOTYPE)) { - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, + ooff = _dl_find_symbol(symn, &this, SYM_SEARCH_ALL | SYM_NOWARNNOTFOUND | SYM_PLT, - sym->st_size, object); + sym->st_size, object, NULL); if (!this && ELF64_ST_BIND(sym->st_info) == STB_GLOBAL) { _dl_printf("%s: can't resolve reference '%s'\n", _dl_progname, symn); @@ -213,14 +214,16 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) this = NULL; object->plt_size = 0; object->got_size = 0; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_start = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_start; @@ -234,9 +237,9 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) if (symp->st_value == 0 || !lazy) { this = 0; ooff = _dl_find_symbol(strt + symp->st_name, - _dl_objects, &this, NULL, + &this, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, - symp->st_size, object); + symp->st_size, object, NULL); if (this) *gotp = this->st_value + ooff; } else @@ -244,10 +247,9 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) } else if (symp->st_shndx == SHN_COMMON || symp->st_shndx == SHN_UNDEF) { this = 0; - ooff = _dl_find_symbol(strt + symp->st_name, - _dl_objects, &this, NULL, + ooff = _dl_find_symbol(strt + symp->st_name, &this, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, - symp->st_size, object); + symp->st_size, object, NULL); if (this) *gotp = this->st_value + ooff; } else if (ELF64_ST_TYPE(symp->st_info) == STT_FUNC && @@ -255,10 +257,9 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) *gotp += loff; } else { /* Resolve all others immediatly */ this = 0; - ooff = _dl_find_symbol(strt + symp->st_name, - _dl_objects, &this, NULL, + ooff = _dl_find_symbol(strt + symp->st_name, &this, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, - symp->st_size, object); + symp->st_size, object, NULL); if (this) *gotp = this->st_value + ooff; else diff --git a/libexec/ld.so/powerpc/rtld_machine.c b/libexec/ld.so/powerpc/rtld_machine.c index eb0361d5acd..bb8d7eab9c1 100644 --- a/libexec/ld.so/powerpc/rtld_machine.c +++ b/libexec/ld.so/powerpc/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.35 2004/05/25 21:42:48 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.36 2005/09/16 23:19:42 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -194,10 +194,10 @@ _dl_printf("object relocation size %x, numrela %x\n", !(ELF32_ST_BIND(sym->st_info) == STB_LOCAL && ELF32_ST_TYPE (sym->st_info) == STT_NOTYPE)) { ooff = _dl_find_symbol_bysym(object, - ELF32_R_SYM(relas->r_info), _dl_objects, - &this, NULL, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND| + ELF32_R_SYM(relas->r_info), &this, + SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND| ((type == RELOC_JMP_SLOT) ? SYM_PLT:SYM_NOTPLT), - sym->st_size); + sym->st_size, NULL); if (!this && ELF32_ST_BIND(sym->st_info) == STB_GLOBAL) { _dl_printf("%s: %s :can't resolve reference '%s'\n", @@ -360,38 +360,27 @@ _dl_printf(" symn [%s] val 0x%x\n", symn, val); } break; case RELOC_COPY: + { #ifdef DL_PRINTF_DEBUG _dl_printf("copy r_addr %x, sym %x [%s] size %d val %x\n", r_addr, sym, symn, sym->st_size, (ooff + this->st_value+ relas->r_addend)); #endif - { /* * we need to find a symbol, that is not in the current * object, start looking at the beginning of the list, * searching all objects but _not_ the current object, * first one found wins. */ - elf_object_t *cobj; const Elf32_Sym *cpysrc = NULL; Elf32_Addr src_loff; int size; src_loff = 0; - for (cobj = _dl_objects; cobj != NULL && cpysrc == NULL; - cobj = cobj->next) { - if (object != cobj) { - /* only look in this object */ - src_loff = _dl_find_symbol_bysym(object, - ELF32_R_SYM(relas->r_info), - cobj, &cpysrc, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND| - ((type == RELOC_JMP_SLOT) ? - SYM_PLT : SYM_NOTPLT), - sym->st_size); - } - } + src_loff = _dl_find_symbol(symn, &cpysrc, + SYM_SEARCH_OTHER|SYM_NOWARNNOTFOUND| SYM_NOTPLT, + sym->st_size, object, NULL); if (cpysrc == NULL) { _dl_printf("symbol not found [%s] \n", symn); } else { @@ -458,28 +447,32 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT|SYM_DLSYM, 0, + object, NULL); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT|SYM_DLSYM, 0, + object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; plt_addr = 0; object->plt_size = 0; this = NULL; - ooff = _dl_find_symbol("__plt_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT|SYM_DLSYM, 0, + object, NULL); if (this != NULL) plt_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__plt_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT|SYM_DLSYM, 0, + object, NULL); if (this != NULL) object->plt_size = ooff + this->st_value - plt_addr; @@ -562,8 +555,9 @@ _dl_bind(elf_object_t *object, int reloff) r_addr = (Elf_Addr *)(object->load_offs + relas->r_offset); this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, NULL); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ @@ -620,7 +614,7 @@ _dl_bind(elf_object_t *object, int reloff) _dl_dcbf(&r_addr[0]); } - /* if PLT is (to be protected, change back to RO/X */ + /* if PLT is to be protected, change back to RO/X */ if (object->plt_size != 0) { _dl_mprotect((void*)object->plt_start, object->plt_size, PROT_READ|PROT_EXEC); /* only PPC is PROT_EXE */ diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index a1d643926f6..a2043fe6145 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.27 2005/05/10 03:36:07 drahn Exp $ */ +/* $OpenBSD: resolve.c,v 1.28 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -38,6 +38,7 @@ elf_object_t *_dl_objects; elf_object_t *_dl_last_object; +elf_object_t *_dl_loading_object; /* * Add a new dynamic object to the object list. @@ -68,7 +69,7 @@ _dl_add_object(elf_object_t *object) * Initialize a new dynamic object. */ elf_object_t * -_dl_finalize_object(const char *objname, Elf_Dyn *dynp, const u_long *dl_data, +_dl_finalize_object(const char *objname, Elf_Dyn *dynp, const long *dl_data, const int objtype, const long laddr, const long loff) { elf_object_t *object; @@ -140,12 +141,24 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, const u_long *dl_data, object->load_addr = laddr; object->load_offs = loff; object->load_name = _dl_strdup(objname); + if (_dl_loading_object == NULL) { + /* + * no loading object, object is the loading object, + * as it is either executable, or dlopened() + */ + _dl_loading_object = object->load_object = object; + DL_DEB(("head %s\n", object->load_name )); + } else { + object->load_object = _dl_loading_object; + } + DL_DEB(("obj %s has %s as head\n", object->load_name, + _dl_loading_object->load_name )); object->refcount = 1; - object->first_child = NULL; - object->last_child = NULL; + TAILQ_INIT(&object->child_list); /* default dev, inode for dlopen-able objects. */ object->dev = 0; object->inode = 0; + TAILQ_INIT(&object->dload_list); return(object); } @@ -198,8 +211,7 @@ int _dl_symcachestat_lookups; Elf_Addr _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, - elf_object_t *startlook, const Elf_Sym **ref, const elf_object_t **pobj, - int flags, int req_size) + const Elf_Sym **ref, int flags, int req_size, const elf_object_t **pobj) { Elf_Addr ret; const Elf_Sym *sym; @@ -225,8 +237,7 @@ _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, sym += symidx; symn = req_obj->dyn.strtab + sym->st_name; - ret = _dl_find_symbol(symn, startlook, ref, &sobj, - flags, req_size, req_obj); + ret = _dl_find_symbol(symn, ref, flags, req_size, req_obj, &sobj); if (pobj) *pobj = sobj; @@ -242,16 +253,16 @@ _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, } Elf_Addr -_dl_find_symbol(const char *name, elf_object_t *startlook, - const Elf_Sym **ref, const elf_object_t **pobj, - int flags, int req_size, elf_object_t *req_obj) +_dl_find_symbol(const char *name, const Elf_Sym **ref, + int flags, int req_size, elf_object_t *req_obj, const elf_object_t **pobj) { const Elf_Sym *weak_sym = NULL; unsigned long h = 0; const char *p = name; - elf_object_t *object, *weak_object = NULL; - int found = 0; - int lastchance = 0; + elf_object_t *object = NULL, *weak_object = NULL; + int found = 0, lastchance = 0; + struct dep_node *n, *m; + while (*p) { unsigned long g; @@ -269,20 +280,96 @@ _dl_find_symbol(const char *name, elf_object_t *startlook, goto found; } + retry_nonglobal_dlo: - for (object = startlook; object; - object = ((flags & SYM_SEARCH_SELF) ? 0 : object->next)) { + if (flags & SYM_SEARCH_OBJ) { + if (_dl_find_symbol_obj(req_obj, name, h, flags, ref, + &weak_sym, &weak_object)) { + object = req_obj; + found = 1; + } + } else if ((flags & SYM_SEARCH_SELF) || (flags & SYM_SEARCH_NEXT)) { + /* search after req_obj in the objects's load group */ + int skip = 1; - if ((lastchance == 0) && - ((object->obj_flags & RTLD_GLOBAL) == 0) && - (object->obj_type == OBJTYPE_DLO) && - (object != req_obj)) - continue; + TAILQ_FOREACH(n, &req_obj->load_object->dload_list, next_sib) { - if (_dl_find_symbol_obj(object, name, h, flags, ref, &weak_sym, - &weak_object)) { + if (n->data == req_obj && skip == 1) { + skip = 0; + if (flags & SYM_SEARCH_NEXT) + continue; + } + if (skip == 1) + continue; + if (_dl_find_symbol_obj(n->data, name, h, flags, ref, + &weak_sym, &weak_object)) { + object = n->data; + found = 1; + break; + } + } + } else if (flags & SYM_DLSYM) { + if (_dl_find_symbol_obj(req_obj, name, h, flags, ref, + &weak_sym, &weak_object)) { + object = req_obj; + found = 1; + } + if (weak_object != NULL && found == 0) { + object=weak_object; + *ref = weak_sym; found = 1; - break; + } + /* search dlopened obj and all children */ + + if (found == 0) { + TAILQ_FOREACH(n, &req_obj->load_object->dload_list, + next_sib) { + if (_dl_find_symbol_obj(n->data, name, h, + flags, ref, + &weak_sym, &weak_object)) { + object = n->data; + found = 1; + break; + } + } + } + } else { + /* search main program and it's libs */ + TAILQ_FOREACH(n, &_dl_objects->dload_list, next_sib) { + if ((flags & SYM_SEARCH_OTHER) && + (n->data == req_obj)) { + continue; + } + + if (_dl_find_symbol_obj(n->data, name, h, flags, + ref, &weak_sym, &weak_object)) { + object = n->data; + found = 1; + goto found; + } + } + + /* + * search dlopened objects: global or req_obj == dlopened_obj + * and and it's children + */ + TAILQ_FOREACH(n, &_dlopened_child_list, next_sib) { + if ((lastchance == 0) && + ((n->data->obj_flags & RTLD_GLOBAL) == 0) && + (n->data != req_obj->load_object)) + continue; + + TAILQ_FOREACH(m, &n->data->dload_list, next_sib) { + if ((flags & SYM_SEARCH_OTHER) && + (m->data == req_obj)) + continue; + if (_dl_find_symbol_obj(m->data, name, h, flags, + ref, &weak_sym, &weak_object)) { + object = m->data; + found = 1; + break; + } + } } } @@ -293,11 +380,14 @@ found: found = 1; } + if (found == 0) { +#if 1 if (lastchance == 0) { lastchance = 1; goto retry_nonglobal_dlo; } +#endif if (flags & SYM_WARNNOTFOUND) _dl_printf("%s:%s: undefined symbol '%s'\n", _dl_progname, req_obj->load_name, name); diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h index fd60b1444a3..94445ccf595 100644 --- a/libexec/ld.so/resolve.h +++ b/libexec/ld.so/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.36 2005/05/10 03:36:07 drahn Exp $ */ +/* $OpenBSD: resolve.h,v 1.37 2005/09/16 23:19:41 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -29,6 +29,7 @@ #ifndef _RESOLVE_H_ #define _RESOLVE_H_ +#include <sys/queue.h> #include <link.h> #include <dlfcn.h> @@ -46,7 +47,8 @@ struct load_list { * The head of this struct must be compatible * with struct link_map in sys/link.h */ -typedef struct elf_object { +typedef struct elf_object elf_object_t; +struct elf_object { Elf_Addr load_addr; /* Real load address */ char *load_name; /* Pointer to object name */ Elf_Dyn *load_dyn; /* Pointer to object dynamic data */ @@ -122,40 +124,40 @@ typedef struct elf_object { u_int32_t nchains; Elf_Dyn *dynamic; - struct dep_node *first_child; - struct dep_node *last_child; + TAILQ_HEAD(,dep_node) child_list; + TAILQ_HEAD(,dep_node) dload_list; + + /* object that caused this module to be loaded, used in symbol lookup */ + elf_object_t *load_object; /* for object confirmation */ dev_t dev; ino_t inode; -} elf_object_t; +}; struct dep_node { - struct dep_node *next_sibling; + TAILQ_ENTRY(dep_node) next_sib; elf_object_t *data; }; -extern void _dl_rt_resolve(void); +void _dl_rt_resolve(void); void _dl_add_object(elf_object_t *object); -extern elf_object_t *_dl_finalize_object(const char *objname, Elf_Dyn *dynp, - const u_long *, const int objtype, const long laddr, const long loff); -extern void _dl_remove_object(elf_object_t *object); +elf_object_t *_dl_finalize_object(const char *objname, Elf_Dyn *dynp, + const long *, const int objtype, const long laddr, const long loff); +void _dl_remove_object(elf_object_t *object); -extern elf_object_t *_dl_lookup_object(const char *objname); -extern elf_object_t *_dl_load_shlib(const char *, elf_object_t *, int, int); -extern void _dl_unload_shlib(elf_object_t *object); -elf_object_t *_dl_tryload_shlib(const char *libname, int type); +elf_object_t *_dl_lookup_object(const char *objname); +elf_object_t *_dl_load_shlib(const char *, elf_object_t *, int, int); +elf_object_t *_dl_tryload_shlib(const char *libname, int type, int flags); -extern int _dl_md_reloc(elf_object_t *object, int rel, int relsz); -extern void _dl_md_reloc_got(elf_object_t *object, int lazy); +int _dl_md_reloc(elf_object_t *object, int rel, int relsz); +void _dl_md_reloc_got(elf_object_t *object, int lazy); -Elf_Addr _dl_find_symbol(const char *name, elf_object_t *startlook, - const Elf_Sym **ref, const elf_object_t **pobj, - int flags, int sym_size, elf_object_t *object); +Elf_Addr _dl_find_symbol(const char *name, const Elf_Sym **ref, + int flags, int sym_size, elf_object_t *object, const elf_object_t **pobj); Elf_Addr _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, - elf_object_t *startlook, const Elf_Sym **ref, const elf_object_t **pobj, - int flags, int req_size); + const Elf_Sym **ref, int flags, int req_size, const elf_object_t **pobj); /* * defines for _dl_find_symbol() flag field, three bits of meaning * myself - clear: search all objects, set: search only this object @@ -170,14 +172,19 @@ Elf_Addr _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, * the 'real' function address is necessary, not the possible PLT address. */ /* myself */ -#define SYM_SEARCH_ALL 0 -#define SYM_SEARCH_SELF 1 +#define SYM_SEARCH_ALL 0x00 +#define SYM_SEARCH_SELF 0x01 +#define SYM_SEARCH_OTHER 0x02 +#define SYM_SEARCH_NEXT 0x04 +#define SYM_SEARCH_OBJ 0x08 /* warnnotfound */ -#define SYM_NOWARNNOTFOUND 0 -#define SYM_WARNNOTFOUND 2 +#define SYM_NOWARNNOTFOUND 0x00 +#define SYM_WARNNOTFOUND 0x10 /* inplt */ -#define SYM_NOTPLT 0 -#define SYM_PLT 4 +#define SYM_NOTPLT 0x00 +#define SYM_PLT 0x20 + +#define SYM_DLSYM 0x40 void _dl_rtld(elf_object_t *object); void _dl_call_init(elf_object_t *object); @@ -185,6 +192,7 @@ void _dl_link_sub(elf_object_t *dep, elf_object_t *p); void _dl_link_dlopen(elf_object_t *dep); void _dl_unlink_dlopen(elf_object_t *dep); void _dl_notify_unload_shlib(elf_object_t *object); +void _dl_unload_shlib(elf_object_t *object); void _dl_unload_dlopen(void); void _dl_run_dtors(elf_object_t *object); @@ -202,6 +210,8 @@ void _dl_thread_kern_stop(void); extern elf_object_t *_dl_objects; extern elf_object_t *_dl_last_object; +extern elf_object_t *_dl_loading_object; + extern const char *_dl_progname; extern struct r_debug *_dl_debug_map; @@ -239,5 +249,10 @@ typedef struct sym_cache { } sym_cache; extern sym_cache *_dl_symcache; +extern int _dl_symcachestat_hits; +extern int _dl_symcachestat_lookups; +TAILQ_HEAD(dlochld, dep_node); +extern struct dlochld _dlopened_child_list; + #endif /* _RESOLVE_H_ */ diff --git a/libexec/ld.so/sparc/rtld_machine.c b/libexec/ld.so/sparc/rtld_machine.c index 4d99fed3058..713fcc86289 100644 --- a/libexec/ld.so/sparc/rtld_machine.c +++ b/libexec/ld.so/sparc/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.23 2004/05/25 21:42:48 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.24 2005/09/16 23:19:43 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -241,12 +241,11 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } else { this = NULL; ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(relas->r_info), - _dl_objects, &this, NULL, + ELF_R_SYM(relas->r_info), &this, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JMP_SLOT)) ? SYM_PLT : SYM_NOTPLT), - sym->st_size); + sym->st_size, NULL); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " @@ -268,10 +267,10 @@ resolve_failed: size_t size = dstsym->st_size; Elf_Addr soff; - soff = _dl_find_symbol(symn, object->next, &srcsym, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| + soff = _dl_find_symbol(symn, &srcsym, + SYM_SEARCH_OTHER|SYM_WARNNOTFOUND| ((type == R_TYPE(JMP_SLOT)) ? SYM_PLT : SYM_NOTPLT), - size, object); + size, object, NULL); if (srcsym == NULL) goto resolve_failed; @@ -330,8 +329,9 @@ _dl_bind(elf_object_t *object, int reloff) addr = (Elf_Addr *)(object->load_offs + rela->r_offset); this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, NULL); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ @@ -402,28 +402,32 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; plt_addr = 0; object->plt_size = 0; this = NULL; - ooff = _dl_find_symbol("__plt_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) plt_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__plt_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->plt_size = ooff + this->st_value - plt_addr; diff --git a/libexec/ld.so/sparc64/rtld_machine.c b/libexec/ld.so/sparc64/rtld_machine.c index 5b45eb44dd9..92c92db08ac 100644 --- a/libexec/ld.so/sparc64/rtld_machine.c +++ b/libexec/ld.so/sparc64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.34 2004/05/25 21:42:48 mickey Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.35 2005/09/16 23:19:43 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -262,12 +262,11 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } else { this = NULL; ooff = _dl_find_symbol_bysym(object, - ELF_R_SYM(relas->r_info), - _dl_objects, &this, NULL, + ELF_R_SYM(relas->r_info), &this, SYM_SEARCH_ALL|SYM_WARNNOTFOUND| ((type == R_TYPE(JMP_SLOT)) ? SYM_PLT : SYM_NOTPLT), - sym->st_size); + sym->st_size, NULL); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " @@ -293,9 +292,9 @@ resolve_failed: size_t size = dstsym->st_size; Elf_Addr soff; - soff = _dl_find_symbol(symn, object->next, &srcsym, - NULL, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT, - size, object); + soff = _dl_find_symbol(symn, &srcsym, + SYM_SEARCH_OTHER|SYM_WARNNOTFOUND|SYM_NOTPLT, + size, object, NULL); if (srcsym == NULL) goto resolve_failed; @@ -622,8 +621,9 @@ _dl_bind(elf_object_t *object, int index) addr = (Elf_Word *)(object->load_offs + rela->r_offset); this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, &this, NULL, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object); + ooff = _dl_find_symbol(symn, &this, + SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, + object, NULL); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ @@ -695,28 +695,32 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_addr = NULL; object->got_size = 0; this = NULL; - ooff = _dl_find_symbol("__got_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__got_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__got_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; plt_addr = 0; object->plt_size = 0; this = NULL; - ooff = _dl_find_symbol("__plt_start", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_start", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) plt_addr = ooff + this->st_value; this = NULL; - ooff = _dl_find_symbol("__plt_end", object, &this, NULL, - SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object); + ooff = _dl_find_symbol("__plt_end", &this, + SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, 0, + object, NULL); if (this != NULL) object->plt_size = ooff + this->st_value - plt_addr; |