summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2005-09-16 23:19:44 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2005-09-16 23:19:44 +0000
commitaf3616ed51f4eb0fd16d93f503c40bc80f7f50c3 (patch)
tree2580ab1dca2725647349467a20e61a10d25295e0 /libexec
parent9d9cb5a7061046352d3c2131dcc90e03844265fc (diff)
Rework symbol lookup to more closely match sun's documentation, now
treats dlopens as load groups. ok kurt@
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.so/Makefile4
-rw-r--r--libexec/ld.so/alpha/rtld_machine.c41
-rw-r--r--libexec/ld.so/amd64/rtld_machine.c27
-rw-r--r--libexec/ld.so/arm/rtld_machine.c28
-rw-r--r--libexec/ld.so/dlfcn.c60
-rw-r--r--libexec/ld.so/hppa/archdep.h8
-rw-r--r--libexec/ld.so/hppa/rtld_machine.c27
-rw-r--r--libexec/ld.so/i386/rtld_machine.c29
-rw-r--r--libexec/ld.so/library.c7
-rw-r--r--libexec/ld.so/library_mquery.c8
-rw-r--r--libexec/ld.so/library_subr.c112
-rw-r--r--libexec/ld.so/loader.c51
-rw-r--r--libexec/ld.so/mips64/rtld_machine.c41
-rw-r--r--libexec/ld.so/powerpc/rtld_machine.c54
-rw-r--r--libexec/ld.so/resolve.c138
-rw-r--r--libexec/ld.so/resolve.h69
-rw-r--r--libexec/ld.so/sparc/rtld_machine.c38
-rw-r--r--libexec/ld.so/sparc64/rtld_machine.c38
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;