summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2003-09-02 15:17:53 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2003-09-02 15:17:53 +0000
commit4418bcd8245d1be69f59c3508fac853c9ad5e38b (patch)
tree30ba7368f7462d65a290542718c610719da5d3e9 /libexec
parent2bf9849879f2b7cde901a0c55c2f0984c74ddecb (diff)
Fix PR 3371, symbol lookup in dlopen()ed objects is not correct. Correct
behavior for RTLD_GLOBAL/RTLD_LOCAL is now supported. ok espie@
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.so/alpha/rtld_machine.c19
-rw-r--r--libexec/ld.so/dlfcn.c11
-rw-r--r--libexec/ld.so/i386/rtld_machine.c12
-rw-r--r--libexec/ld.so/library.c7
-rw-r--r--libexec/ld.so/library_mquery.c7
-rw-r--r--libexec/ld.so/loader.c11
-rw-r--r--libexec/ld.so/mips/rtld_machine.c16
-rw-r--r--libexec/ld.so/powerpc/rtld_machine.c17
-rw-r--r--libexec/ld.so/resolve.c165
-rw-r--r--libexec/ld.so/resolve.h8
-rw-r--r--libexec/ld.so/sparc/rtld_machine.c16
-rw-r--r--libexec/ld.so/sparc64/rtld_machine.c16
12 files changed, 176 insertions, 129 deletions
diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c
index 8705cc97a4e..8a2c61b9230 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.25 2003/07/28 03:11:00 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.26 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -109,7 +109,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
case R_TYPE(REFQUAD):
ooff = _dl_find_symbol(symn, _dl_objects, &this,
SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT,
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (this == NULL)
goto resolve_failed;
*r_addr += ooff + this->st_value + relas->r_addend;
@@ -134,7 +134,7 @@ _dl_printf("unaligned RELATIVE: %p type: %d %s 0x%lx -> 0x%lx\n", r_addr,
case R_TYPE(JMP_SLOT):
ooff = _dl_find_symbol(symn, _dl_objects, &this,
SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT,
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (this == NULL)
goto resolve_failed;
*r_addr = ooff + this->st_value + relas->r_addend;
@@ -142,7 +142,7 @@ _dl_printf("unaligned RELATIVE: %p type: %d %s 0x%lx -> 0x%lx\n", r_addr,
case R_TYPE(GLOB_DAT):
ooff = _dl_find_symbol(symn, _dl_objects, &this,
SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT,
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (this == NULL)
goto resolve_failed;
*r_addr = ooff + this->st_value + relas->r_addend;
@@ -196,8 +196,7 @@ _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,
- SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size,
- object->load_name);
+ SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object);
if (this == NULL) {
_dl_printf("lazy binding failed!\n");
*((int *)0) = 0; /* XXX */
@@ -241,13 +240,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__got_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
@@ -255,13 +254,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->plt_size = 0;
this = NULL;
ooff = _dl_find_symbol("__plt_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
plt_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__plt_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->plt_size = ooff + this->st_value - plt_addr;
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c
index f7d51e18607..b1e03fcca79 100644
--- a/libexec/ld.so/dlfcn.c
+++ b/libexec/ld.so/dlfcn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dlfcn.c,v 1.29 2003/06/26 07:53:27 deraadt Exp $ */
+/* $OpenBSD: dlfcn.c,v 1.30 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -47,7 +47,7 @@ static void _dl_thread_kern_go(void);
static void (*_dl_thread_fnc)(int) = NULL;
void *
-dlopen(const char *libname, int how)
+dlopen(const char *libname, int flags)
{
elf_object_t *object, *dynobj;
Elf_Dyn *dynp;
@@ -58,7 +58,7 @@ dlopen(const char *libname, int how)
DL_DEB(("dlopen: loading: %s\n", libname));
_dl_thread_kern_stop();
- object = _dl_load_shlib(libname, _dl_objects, OBJTYPE_DLO);
+ object = _dl_load_shlib(libname, _dl_objects, OBJTYPE_DLO, flags);
/* this add_object should not be here, XXX */
if (object == 0) {
_dl_thread_kern_go();
@@ -91,7 +91,8 @@ dlopen(const char *libname, int how)
libname = dynobj->dyn.strtab + dynp->d_un.d_val;
_dl_thread_kern_stop();
- depobj = _dl_load_shlib(libname, dynobj, OBJTYPE_LIB);
+ depobj = _dl_load_shlib(libname, dynobj, OBJTYPE_LIB,
+ flags|RTLD_GLOBAL);
if (!depobj)
_dl_exit(4);
/* this add_object should not be here, XXX */
@@ -137,7 +138,7 @@ dlsym(void *handle, const char *name)
}
retval = (void *)_dl_find_symbol(name, object, &sym,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_NOTPLT, 0, "");
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_NOTPLT, 0, object);
if (sym != NULL)
retval += sym->st_value;
else
diff --git a/libexec/ld.so/i386/rtld_machine.c b/libexec/ld.so/i386/rtld_machine.c
index 1f501216e46..971c1a9ea3e 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.10 2003/07/28 03:11:00 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.11 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -241,7 +241,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
&this, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|
((type == R_TYPE(JUMP_SLOT))?
SYM_PLT:SYM_NOTPLT),
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (this == NULL) {
resolve_failed:
_dl_printf("%s: %s: can't resolve "
@@ -270,7 +270,7 @@ resolve_failed:
soff = _dl_find_symbol(symn, object->next, &srcsym,
SYM_SEARCH_ALL|SYM_WARNNOTFOUND|
((type == R_TYPE(JUMP_SLOT)) ? SYM_PLT:SYM_NOTPLT),
- size, object->load_name);
+ size, object);
if (srcsym == NULL)
goto resolve_failed;
@@ -367,7 +367,7 @@ _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,
- SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, 0, object->load_name);
+ SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object);
if (this == NULL) {
_dl_printf("lazy binding failed!\n");
*((int *)0) = 0; /* XXX */
@@ -417,13 +417,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__got_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
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 731ae183252..d2c7e2d1504 100644
--- a/libexec/ld.so/library.c
+++ b/libexec/ld.so/library.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: library.c,v 1.32 2003/07/18 14:09:02 drahn Exp $ */
+/* $OpenBSD: library.c,v 1.33 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -236,7 +236,7 @@ nohints:
*/
elf_object_t *
-_dl_load_shlib(const char *libname, elf_object_t *parent, int type)
+_dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags)
{
int try_any_minor, ignore_hints;
struct sod sod, req_sod;
@@ -270,6 +270,7 @@ again:
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
_dl_free((char *)sod.sod_name);
+ object->obj_flags = flags;
return (object);
}
}
@@ -291,6 +292,7 @@ again:
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
_dl_free((char *)sod.sod_name);
+ object->obj_flags = flags;
return (object);
}
}
@@ -308,6 +310,7 @@ again:
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
_dl_free((char *)sod.sod_name);
+ object->obj_flags = flags;
return(object);
}
}
diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c
index 17f04c4d5e3..97691a42311 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.12 2003/07/18 14:09:02 drahn Exp $ */
+/* $OpenBSD: library_mquery.c,v 1.13 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -236,7 +236,7 @@ nohints:
*/
elf_object_t *
-_dl_load_shlib(const char *libname, elf_object_t *parent, int type)
+_dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags)
{
int try_any_minor, ignore_hints;
struct sod sod, req_sod;
@@ -270,6 +270,7 @@ again:
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
_dl_free((char *)sod.sod_name);
+ object->obj_flags = flags;
return (object);
}
}
@@ -291,6 +292,7 @@ again:
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
_dl_free((char *)sod.sod_name);
+ object->obj_flags = flags;
return (object);
}
}
@@ -308,6 +310,7 @@ again:
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
_dl_free((char *)sod.sod_name);
+ object->obj_flags = flags;
return(object);
}
}
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index 2299ad6027c..a6d77780a1f 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: loader.c,v 1.66 2003/07/09 21:01:10 drahn Exp $ */
+/* $OpenBSD: loader.c,v 1.67 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -36,6 +36,7 @@
#include <nlist.h>
#include <string.h>
#include <link.h>
+#include <dlfcn.h>
#include "syscall.h"
#include "archdep.h"
@@ -109,7 +110,8 @@ _dl_dopreload(char *paths)
}
while ((cp = _dl_strsep(&dp, ":")) != NULL) {
- shlib = _dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB);
+ shlib = _dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB,
+ DL_LAZY|RTLD_GLOBAL);
if (shlib == NULL) {
_dl_printf("%s: can't load library '%s'\n",
_dl_progname, cp);
@@ -304,7 +306,7 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data)
liblist[randomlist[i]].dynp->d_un.d_val;
DL_DEB(("needs: '%s'\n", libname));
depobj = _dl_load_shlib(libname, dynobj,
- OBJTYPE_LIB);
+ OBJTYPE_LIB, DL_LAZY|RTLD_GLOBAL);
if (depobj == 0) {
_dl_printf(
"%s: can't load library '%s'\n",
@@ -361,7 +363,7 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data)
sym = NULL;
ooff = _dl_find_symbol("atexit", _dl_objects, &sym,
- SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, 0, "");
+ SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, 0, dyn_obj);
if (sym == NULL)
_dl_printf("cannot find atexit, destructors will not be run!\n");
else
@@ -407,6 +409,7 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data)
_dl_exit(0);
DL_DEB(("entry point: 0x%lx\n", dl_data[AUX_entry]));
+
/*
* Return the entry point.
*/
diff --git a/libexec/ld.so/mips/rtld_machine.c b/libexec/ld.so/mips/rtld_machine.c
index eaca0b86c0e..15a5356239f 100644
--- a/libexec/ld.so/mips/rtld_machine.c
+++ b/libexec/ld.so/mips/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.13 2003/07/28 03:11:00 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.14 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 1998-2002 Opsycon AB, Sweden.
@@ -72,7 +72,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
ELF32_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
ooff = _dl_find_symbol(symn, _dl_objects, &this,
SYM_SEARCH_ALL | SYM_NOWARNNOTFOUND | SYM_PLT,
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (!this && ELF32_ST_BIND(sym->st_info) == STB_GLOBAL) {
_dl_printf("%s: can't resolve reference '%s'\n",
_dl_progname, symn);
@@ -158,25 +158,25 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__got_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
this = NULL;
ooff = _dl_find_symbol("__plt_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->plt_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__plt_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->plt_size = ooff + this->st_value - object->plt_addr;
@@ -193,7 +193,7 @@ DL_DEB(("got: '%s' = %x\n", strt + symp->st_name, symp->st_value));
ooff = _dl_find_symbol(strt + symp->st_name,
_dl_objects, &this,
SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT,
- symp->st_size, object->load_name);
+ symp->st_size, object);
if (this)
*gotp = this->st_value + ooff;
} else
@@ -204,7 +204,7 @@ DL_DEB(("got: '%s' = %x\n", strt + symp->st_name, symp->st_value));
ooff = _dl_find_symbol(strt + symp->st_name,
_dl_objects, &this,
SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT,
- symp->st_size, object->load_name);
+ symp->st_size, object);
if (this)
*gotp = this->st_value + ooff;
} else if (ELF32_ST_TYPE(symp->st_info) == STT_FUNC) {
diff --git a/libexec/ld.so/powerpc/rtld_machine.c b/libexec/ld.so/powerpc/rtld_machine.c
index 648b49efbad..bd4f2040e94 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.29 2003/08/19 04:15:54 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.30 2003/09/02 15:17:52 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -70,6 +70,7 @@ void _dl_syncicache(char *from, size_t len);
((((x) & 0xfe000000) == 0x00000000) || (((x) & 0xfe000000) == 0xfe000000))
void _dl_bind_start(void); /* XXX */
+Elf_Addr _dl_bind(elf_object_t *object, int reloff);
void
_dl_bcopy(const void *src, void *dest, int size)
@@ -206,7 +207,7 @@ _dl_printf("object relocation size %x, numrela %x\n",
ooff = _dl_find_symbol(symn, _dl_objects, &this,
SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|
((type == RELOC_JMP_SLOT) ? SYM_PLT:SYM_NOTPLT),
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (!this && ELF32_ST_BIND(sym->st_info) == STB_GLOBAL) {
_dl_printf("%s: %s :can't resolve reference '%s'\n",
@@ -397,7 +398,7 @@ _dl_printf(" symn [%s] val 0x%x\n", symn, val);
SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|
((type == RELOC_JMP_SLOT) ?
SYM_PLT : SYM_NOTPLT),
- sym->st_size, object->load_name);
+ sym->st_size, object);
}
}
if (cpysrc == NULL) {
@@ -467,13 +468,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__got_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
@@ -481,13 +482,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->plt_size = 0;
this = NULL;
ooff = _dl_find_symbol("__plt_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
plt_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__plt_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->plt_size = ooff + this->st_value - plt_addr;
@@ -569,7 +570,7 @@ _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,
- SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, 0, object->load_name);
+ SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object);
if (this == NULL) {
_dl_printf("lazy binding failed!\n");
*((int *)0) = 0; /* XXX */
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index 852c38aeadf..07b464ff2cf 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.19 2003/06/22 21:39:01 drahn Exp $ */
+/* $OpenBSD: resolve.c,v 1.20 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -184,17 +184,20 @@ _dl_lookup_object(const char *name)
return(0);
}
+int find_symbol_obj(elf_object_t *object, const char *name, unsigned long hash,
+ int flags, const Elf_Sym **ref, const Elf_Sym **weak_sym,
+ elf_object_t **weak_object);
Elf_Addr
_dl_find_symbol(const char *name, elf_object_t *startlook,
- const Elf_Sym **ref, int flags, int req_size, const char *module_name)
+ const Elf_Sym **ref, int flags, int req_size, elf_object_t *req_obj)
{
const Elf_Sym *weak_sym = NULL;
- const char *weak_symn = NULL; /* remove warning */
- Elf_Addr weak_offs = 0;
unsigned long h = 0;
const char *p = name;
elf_object_t *object, *weak_object = NULL;
+ int found = 0;
+ int lastchance = 0;
while (*p) {
unsigned long g;
@@ -204,76 +207,108 @@ _dl_find_symbol(const char *name, elf_object_t *startlook,
h &= ~g;
}
+ if (req_obj->dyn.symbolic)
+ if (find_symbol_obj(req_obj, name, h, flags, ref, &weak_sym,
+ &weak_object)) {
+ object = req_obj;
+ found = 1;
+ goto found;
+ }
+
+retry_nonglobal_dlo:
for (object = startlook; object;
object = ((flags & SYM_SEARCH_SELF) ? 0 : object->next)) {
- const Elf_Sym *symt = object->dyn.symtab;
- const char *strt = object->dyn.strtab;
- long si;
- const char *symn;
- for (si = object->buckets[h % object->nbuckets];
- si != STN_UNDEF; si = object->chains[si]) {
- const Elf_Sym *sym = symt + si;
+ if ((lastchance == 0) &&
+ ((object->obj_flags & RTLD_GLOBAL) == 0) &&
+ (object->obj_type == OBJTYPE_DLO) &&
+ (object != req_obj))
+ continue;
- if (sym->st_value == 0)
- continue;
+ if (find_symbol_obj(object, name, h, flags, ref, &weak_sym,
+ &weak_object)) {
+ found = 1;
+ break;
+ }
+ }
- if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE &&
- ELF_ST_TYPE(sym->st_info) != STT_OBJECT &&
- ELF_ST_TYPE(sym->st_info) != STT_FUNC)
- continue;
+found:
+ if (weak_object != NULL && found == 0) {
+ object=weak_object;
+ *ref = weak_sym;
+ found = 1;
+ }
- symn = strt + sym->st_name;
- if (sym != *ref && _dl_strcmp(symn, name))
- continue;
+ if (found == 0) {
+ if (lastchance == 0) {
+ lastchance = 1;
+ goto retry_nonglobal_dlo;
+ }
+ if (flags & SYM_WARNNOTFOUND)
+ _dl_printf("%s:%s: undefined symbol '%s'\n",
+ _dl_progname, req_obj->load_name, name);
+ return (0);
+ }
- /* allow this symbol if we are referring to a function
- * which has a value, even if section is UNDEF.
- * this allows &func to refer to PLT as per the
- * ELF spec. st_value is checked above.
- * if flags has SYM_PLT set, we must have actual
- * symbol, so this symbol is skipped.
- */
- if (sym->st_shndx == SHN_UNDEF) {
- if ((flags & SYM_PLT) || sym->st_value == 0 ||
- ELF_ST_TYPE(sym->st_info) != STT_FUNC)
- continue;
- }
+ if (req_size != (*ref)->st_size && req_size != 0 &&
+ (ELF_ST_TYPE((*ref)->st_info) != STT_FUNC)) {
+ _dl_printf("%s:%s: %s : WARNING: "
+ "symbol(%s) size mismatch, relink your program\n",
+ _dl_progname, req_obj->load_name,
+ object->load_name, name);
+ }
+
+ return (object->load_offs);
+}
- if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) {
- *ref = sym;
- if (req_size != sym->st_size &&
- req_size != 0 &&
- (ELF_ST_TYPE(sym->st_info) != STT_FUNC)) {
- _dl_printf("%s: %s : WARNING: "
- "symbol(%s) size mismatch ",
- _dl_progname, object->load_name,
- symn);
- _dl_printf("relink your program\n");
- }
- return(object->load_offs);
- } else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
- if (!weak_sym) {
- weak_sym = sym;
- weak_symn = symn;
- weak_offs = object->load_offs;
- weak_object = object;
- }
+int
+find_symbol_obj(elf_object_t *object, const char *name, unsigned long hash,
+ int flags, const Elf_Sym **ref, const Elf_Sym **weak_sym,
+ elf_object_t **weak_object)
+{
+ const Elf_Sym *symt = object->dyn.symtab;
+ const char *strt = object->dyn.strtab;
+ long si;
+ const char *symn;
+
+ for (si = object->buckets[hash % object->nbuckets];
+ si != STN_UNDEF; si = object->chains[si]) {
+ const Elf_Sym *sym = symt + si;
+
+ if (sym->st_value == 0)
+ continue;
+
+ if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE &&
+ ELF_ST_TYPE(sym->st_info) != STT_OBJECT &&
+ ELF_ST_TYPE(sym->st_info) != STT_FUNC)
+ continue;
+
+ symn = strt + sym->st_name;
+ if (sym != *ref && _dl_strcmp(symn, name))
+ continue;
+
+ /* allow this symbol if we are referring to a function
+ * which has a value, even if section is UNDEF.
+ * this allows &func to refer to PLT as per the
+ * ELF spec. st_value is checked above.
+ * if flags has SYM_PLT set, we must have actual
+ * symbol, so this symbol is skipped.
+ */
+ if (sym->st_shndx == SHN_UNDEF) {
+ if ((flags & SYM_PLT) || sym->st_value == 0 ||
+ ELF_ST_TYPE(sym->st_info) != STT_FUNC)
+ continue;
+ }
+
+ if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) {
+ *ref = sym;
+ return 1;
+ } else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
+ if (!*weak_sym) {
+ *weak_sym = sym;
+ *weak_object = object;
}
}
}
- if (flags & SYM_WARNNOTFOUND && weak_sym == NULL) {
- _dl_printf("%s:%s: undefined symbol '%s'\n",
- _dl_progname, module_name, name);
- }
- *ref = weak_sym;
- if (weak_sym != NULL && req_size != weak_sym->st_size &&
- req_size != 0 && (ELF_ST_TYPE(weak_sym->st_info) != STT_FUNC)) {
- _dl_printf("%s:%s: %s : WARNING: "
- "symbol(%s) size mismatch ",
- _dl_progname, module_name, weak_object->load_name,
- weak_symn);
- _dl_printf("relink your program\n");
- }
- return (weak_offs);
+ return 0;
}
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index b2ce3c5e556..e5b31ae562b 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.h,v 1.27 2003/07/06 20:03:57 deraadt Exp $ */
+/* $OpenBSD: resolve.h,v 1.28 2003/09/02 15:17:51 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -30,6 +30,7 @@
#define _RESOLVE_H_
#include <link.h>
+#include <dlfcn.h>
struct load_list {
struct load_list *next;
@@ -111,6 +112,7 @@ typedef struct elf_object {
#define OBJTYPE_EXE 2
#define OBJTYPE_LIB 3
#define OBJTYPE_DLO 4
+ int obj_flags;
Elf_Word *buckets;
u_int32_t nbuckets;
@@ -135,14 +137,14 @@ extern elf_object_t *_dl_finalize_object(const char *objname, Elf_Dyn *dynp,
extern 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);
+extern elf_object_t *_dl_load_shlib(const char *, elf_object_t *, int, int);
extern void _dl_unload_shlib(elf_object_t *object);
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);
Elf_Addr _dl_find_symbol(const char *name, elf_object_t *startlook,
- const Elf_Sym **ref, int flags, int sym_size, const char *module_name);
+ const Elf_Sym **ref, int flags, int sym_size, elf_object_t *object);
/*
* defines for _dl_find_symbol() flag field, three bits of meaning
* myself - clear: search all objects, set: search only this object
diff --git a/libexec/ld.so/sparc/rtld_machine.c b/libexec/ld.so/sparc/rtld_machine.c
index af60b9cf25e..c39b6886ed2 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.17 2003/07/28 03:11:00 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.18 2003/09/02 15:17:52 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -256,7 +256,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
SYM_SEARCH_ALL|SYM_WARNNOTFOUND|
((type == R_TYPE(JMP_SLOT)) ?
SYM_PLT : SYM_NOTPLT),
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (this == NULL) {
resolve_failed:
_dl_printf("%s: %s: can't resolve "
@@ -281,7 +281,7 @@ resolve_failed:
soff = _dl_find_symbol(symn, object->next, &srcsym,
SYM_SEARCH_ALL|SYM_WARNNOTFOUND|
((type == R_TYPE(JMP_SLOT)) ? SYM_PLT : SYM_NOTPLT),
- size, object->load_name);
+ size, object);
if (srcsym == NULL)
goto resolve_failed;
@@ -341,7 +341,7 @@ _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,
- SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, 0, object->load_name);
+ SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object);
if (this == NULL) {
_dl_printf("lazy binding failed!\n");
*((int *)0) = 0; /* XXX */
@@ -413,13 +413,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__got_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
@@ -427,13 +427,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->plt_size = 0;
this = NULL;
ooff = _dl_find_symbol("__plt_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
plt_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__plt_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
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 3dea5af724c..dbdf035323c 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.28 2003/07/28 03:11:00 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.29 2003/09/02 15:17:52 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -276,7 +276,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
&this, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|
((type == R_TYPE(JMP_SLOT))?
SYM_PLT:SYM_NOTPLT),
- sym->st_size, object->load_name);
+ sym->st_size, object);
if (this == NULL) {
resolve_failed:
_dl_printf("%s: %s: can't resolve "
@@ -304,7 +304,7 @@ resolve_failed:
soff = _dl_find_symbol(symn, object->next, &srcsym,
SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_NOTPLT,
- size, object->load_name);
+ size, object);
if (srcsym == NULL)
goto resolve_failed;
@@ -632,7 +632,7 @@ _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,
- SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, 0, object->load_name);
+ SYM_SEARCH_ALL|SYM_WARNNOTFOUND|SYM_PLT, sym->st_size, object);
if (this == NULL) {
_dl_printf("lazy binding failed!\n");
*((int *)0) = 0; /* XXX */
@@ -705,13 +705,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__got_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
@@ -719,13 +719,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->plt_size = 0;
this = NULL;
ooff = _dl_find_symbol("__plt_start", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
plt_addr = ooff + this->st_value;
this = NULL;
ooff = _dl_find_symbol("__plt_end", object, &this,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, NULL);
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
object->plt_size = ooff + this->st_value - plt_addr;