Back out previous change for now -- it needs more work.
This commit is contained in:
parent
f694ad9267
commit
f57f7ac072
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: rtld.c,v 1.91 2003/04/23 17:40:25 mycroft Exp $ */
|
/* $NetBSD: rtld.c,v 1.92 2003/04/24 16:55:29 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 1996 John D. Polstra.
|
* Copyright 1996 John D. Polstra.
|
||||||
|
@ -367,6 +367,8 @@ _rtld(sp, relocbase)
|
||||||
_rtld_objmain->pathlen = strlen(_rtld_objmain->path);
|
_rtld_objmain->pathlen = strlen(_rtld_objmain->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_rtld_objmain->mainprog = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the actual dynamic linker pathname from the executable if
|
* Get the actual dynamic linker pathname from the executable if
|
||||||
* possible. (It should always be possible.) That ensures that
|
* possible. (It should always be possible.) That ensures that
|
||||||
|
@ -671,10 +673,19 @@ _rtld_dlsym(handle, name)
|
||||||
const char *name;
|
const char *name;
|
||||||
{
|
{
|
||||||
const Obj_Entry *obj;
|
const Obj_Entry *obj;
|
||||||
|
unsigned long hash;
|
||||||
const Elf_Sym *def;
|
const Elf_Sym *def;
|
||||||
const Obj_Entry *defobj;
|
const Obj_Entry *defobj;
|
||||||
|
|
||||||
if (handle == NULL) {
|
hash = _rtld_elf_hash(name);
|
||||||
|
def = NULL;
|
||||||
|
defobj = NULL;
|
||||||
|
|
||||||
|
if (handle == NULL
|
||||||
|
#if 0
|
||||||
|
|| handle == RTLD_NEXT
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
void *retaddr;
|
void *retaddr;
|
||||||
|
|
||||||
retaddr = __builtin_return_address(0); /* __GNUC__ only */
|
retaddr = __builtin_return_address(0); /* __GNUC__ only */
|
||||||
|
@ -682,14 +693,33 @@ _rtld_dlsym(handle, name)
|
||||||
_rtld_error("Cannot determine caller's shared object");
|
_rtld_error("Cannot determine caller's shared object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (handle == NULL) { /* Just the caller's shared object. */
|
||||||
|
def = _rtld_symlook_obj(name, hash, obj, false);
|
||||||
|
defobj = obj;
|
||||||
|
} else { /* All the shared objects after the caller's */
|
||||||
|
while ((obj = obj->next) != NULL) {
|
||||||
|
if ((def = _rtld_symlook_obj(name, hash, obj, false)) != NULL) {
|
||||||
|
defobj = obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((obj = _rtld_dlcheck(handle)) == NULL) {
|
if ((obj = _rtld_dlcheck(handle)) == NULL)
|
||||||
_rtld_error("Handle not found");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (obj->mainprog) {
|
||||||
|
/* Search main program and all libraries loaded by it. */
|
||||||
|
def = _rtld_symlook_list(name, hash, &_rtld_list_main, &defobj, false);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* XXX - This isn't correct. The search should include the whole
|
||||||
|
* DAG rooted at the given object.
|
||||||
|
*/
|
||||||
|
def = _rtld_symlook_obj(name, hash, obj, false);
|
||||||
|
defobj = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def = _rtld_find_symname(name, obj, &defobj, false);
|
|
||||||
|
|
||||||
if (def != NULL) {
|
if (def != NULL) {
|
||||||
#ifdef __HAVE_FUNCTION_DESCRIPTORS
|
#ifdef __HAVE_FUNCTION_DESCRIPTORS
|
||||||
|
@ -698,10 +728,10 @@ _rtld_dlsym(handle, name)
|
||||||
def, 0);
|
def, 0);
|
||||||
#endif /* __HAVE_FUNCTION_DESCRIPTORS */
|
#endif /* __HAVE_FUNCTION_DESCRIPTORS */
|
||||||
return defobj->relocbase + def->st_value;
|
return defobj->relocbase + def->st_value;
|
||||||
} else {
|
|
||||||
_rtld_error("Undefined symbol \"%s\"", name);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_rtld_error("Undefined symbol \"%s\"", name);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: rtld.h,v 1.66 2003/04/23 17:40:25 mycroft Exp $ */
|
/* $NetBSD: rtld.h,v 1.67 2003/04/24 16:55:30 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 1996 John D. Polstra.
|
* Copyright 1996 John D. Polstra.
|
||||||
|
@ -176,7 +176,8 @@ typedef struct Struct_Obj_Entry {
|
||||||
int (*dlclose) __P((void *));
|
int (*dlclose) __P((void *));
|
||||||
int (*dladdr) __P((const void *, Dl_info *));
|
int (*dladdr) __P((const void *, Dl_info *));
|
||||||
|
|
||||||
u_int32_t rtld:1, /* True if this is the dynamic linker */
|
u_int32_t mainprog:1, /* True if this is the main program */
|
||||||
|
rtld:1, /* True if this is the dynamic linker */
|
||||||
textrel:1, /* True if there are relocations to
|
textrel:1, /* True if there are relocations to
|
||||||
* text seg */
|
* text seg */
|
||||||
symbolic:1, /* True if generated with
|
symbolic:1, /* True if generated with
|
||||||
|
@ -255,8 +256,6 @@ Obj_Entry *_rtld_load_library __P((const char *, const Obj_Entry *, int));
|
||||||
unsigned long _rtld_elf_hash __P((const char *));
|
unsigned long _rtld_elf_hash __P((const char *));
|
||||||
const Elf_Sym *_rtld_symlook_obj __P((const char *, unsigned long,
|
const Elf_Sym *_rtld_symlook_obj __P((const char *, unsigned long,
|
||||||
const Obj_Entry *, bool));
|
const Obj_Entry *, bool));
|
||||||
const Elf_Sym *_rtld_find_symname __P((const char *, const Obj_Entry *,
|
|
||||||
const Obj_Entry **, bool));
|
|
||||||
const Elf_Sym *_rtld_find_symdef __P((unsigned long, const Obj_Entry *,
|
const Elf_Sym *_rtld_find_symdef __P((unsigned long, const Obj_Entry *,
|
||||||
const Obj_Entry **, bool));
|
const Obj_Entry **, bool));
|
||||||
const Elf_Sym *_rtld_symlook_list(const char *, unsigned long,
|
const Elf_Sym *_rtld_symlook_list(const char *, unsigned long,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: symbol.c,v 1.26 2003/04/23 17:40:25 mycroft Exp $ */
|
/* $NetBSD: symbol.c,v 1.27 2003/04/24 16:55:30 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 1996 John D. Polstra.
|
* Copyright 1996 John D. Polstra.
|
||||||
|
@ -83,9 +83,11 @@ _rtld_symlook_list(const char *name, unsigned long hash, const Objlist *objlist,
|
||||||
{
|
{
|
||||||
const Elf_Sym *symp;
|
const Elf_Sym *symp;
|
||||||
const Elf_Sym *def;
|
const Elf_Sym *def;
|
||||||
|
const Obj_Entry *defobj;
|
||||||
const Objlist_Entry *elm;
|
const Objlist_Entry *elm;
|
||||||
|
|
||||||
def = NULL;
|
def = NULL;
|
||||||
|
defobj = NULL;
|
||||||
SIMPLEQ_FOREACH(elm, objlist, link) {
|
SIMPLEQ_FOREACH(elm, objlist, link) {
|
||||||
rdbg(("search object %p (%s)", elm->obj, elm->obj->path));
|
rdbg(("search object %p (%s)", elm->obj, elm->obj->path));
|
||||||
if ((symp = _rtld_symlook_obj(name, hash, elm->obj, in_plt))
|
if ((symp = _rtld_symlook_obj(name, hash, elm->obj, in_plt))
|
||||||
|
@ -93,12 +95,14 @@ _rtld_symlook_list(const char *name, unsigned long hash, const Objlist *objlist,
|
||||||
if ((def == NULL) ||
|
if ((def == NULL) ||
|
||||||
(ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
(ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||||
def = symp;
|
def = symp;
|
||||||
*defobj_out = elm->obj;
|
defobj = elm->obj;
|
||||||
if (ELF_ST_BIND(def->st_info) != STB_WEAK)
|
if (ELF_ST_BIND(def->st_info) != STB_WEAK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (def != NULL)
|
||||||
|
*defobj_out = defobj;
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,26 +166,33 @@ _rtld_symlook_obj(name, hash, obj, in_plt)
|
||||||
* defining object via the reference parameter DEFOBJ_OUT.
|
* defining object via the reference parameter DEFOBJ_OUT.
|
||||||
*/
|
*/
|
||||||
const Elf_Sym *
|
const Elf_Sym *
|
||||||
_rtld_find_symname(name, refobj, defobj_out, in_plt)
|
_rtld_find_symdef(symnum, refobj, defobj_out, in_plt)
|
||||||
const char *name;
|
unsigned long symnum;
|
||||||
const Obj_Entry *refobj;
|
const Obj_Entry *refobj;
|
||||||
const Obj_Entry **defobj_out;
|
const Obj_Entry **defobj_out;
|
||||||
bool in_plt;
|
bool in_plt;
|
||||||
{
|
{
|
||||||
|
const Elf_Sym *ref;
|
||||||
const Elf_Sym *def;
|
const Elf_Sym *def;
|
||||||
const Elf_Sym *symp;
|
const Elf_Sym *symp;
|
||||||
const Obj_Entry *obj;
|
const Obj_Entry *obj;
|
||||||
|
const Obj_Entry *defobj;
|
||||||
const Objlist_Entry *elm;
|
const Objlist_Entry *elm;
|
||||||
|
const char *name;
|
||||||
unsigned long hash;
|
unsigned long hash;
|
||||||
|
|
||||||
|
ref = refobj->symtab + symnum;
|
||||||
|
name = refobj->strtab + ref->st_name;
|
||||||
|
|
||||||
hash = _rtld_elf_hash(name);
|
hash = _rtld_elf_hash(name);
|
||||||
def = NULL;
|
def = NULL;
|
||||||
|
defobj = NULL;
|
||||||
|
|
||||||
if (refobj->symbolic) { /* Look first in the referencing object */
|
if (refobj->symbolic) { /* Look first in the referencing object */
|
||||||
symp = _rtld_symlook_obj(name, hash, refobj, in_plt);
|
symp = _rtld_symlook_obj(name, hash, refobj, in_plt);
|
||||||
if (symp != NULL) {
|
if (symp != NULL) {
|
||||||
def = symp;
|
def = symp;
|
||||||
*defobj_out = refobj;
|
defobj = refobj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +203,7 @@ _rtld_find_symname(name, refobj, defobj_out, in_plt)
|
||||||
if (symp != NULL &&
|
if (symp != NULL &&
|
||||||
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||||
def = symp;
|
def = symp;
|
||||||
*defobj_out = obj;
|
defobj = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +216,7 @@ _rtld_find_symname(name, refobj, defobj_out, in_plt)
|
||||||
if (symp != NULL &&
|
if (symp != NULL &&
|
||||||
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||||
def = symp;
|
def = symp;
|
||||||
*defobj_out = obj;
|
defobj = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,41 +227,26 @@ _rtld_find_symname(name, refobj, defobj_out, in_plt)
|
||||||
if (symp != NULL &&
|
if (symp != NULL &&
|
||||||
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||||
def = symp;
|
def = symp;
|
||||||
*defobj_out = obj;
|
defobj = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we found no definition and the reference is weak, treat the
|
||||||
|
* symbol as having the value zero.
|
||||||
|
*/
|
||||||
|
if (def == NULL && ELF_ST_BIND(ref->st_info) == STB_WEAK) {
|
||||||
|
rdbg((" returning _rtld_sym_zero@_rtld_objmain"));
|
||||||
|
def = &_rtld_sym_zero;
|
||||||
|
defobj = _rtld_objmain;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def != NULL)
|
||||||
|
*defobj_out = defobj;
|
||||||
|
else {
|
||||||
|
rdbg(("lookup failed"));
|
||||||
|
_rtld_error("%s: Undefined %ssymbol \"%s\" (symnum = %ld)",
|
||||||
|
refobj->path, in_plt ? "PLT " : "", name, symnum);
|
||||||
|
}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Elf_Sym *
|
|
||||||
_rtld_find_symdef(symnum, refobj, defobj_out, in_plt)
|
|
||||||
unsigned long symnum;
|
|
||||||
const Obj_Entry *refobj;
|
|
||||||
const Obj_Entry **defobj_out;
|
|
||||||
bool in_plt;
|
|
||||||
{
|
|
||||||
const Elf_Sym *ref, *def;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
ref = refobj->symtab + symnum;
|
|
||||||
name = refobj->strtab + ref->st_name;
|
|
||||||
|
|
||||||
def = _rtld_find_symname(name, refobj, defobj_out, in_plt);
|
|
||||||
if (def == NULL) {
|
|
||||||
if (ELF_ST_BIND(ref->st_info) == STB_WEAK) {
|
|
||||||
/*
|
|
||||||
* If we found no definition and the reference is weak,
|
|
||||||
* treat the symbol as having the value zero.
|
|
||||||
*/
|
|
||||||
rdbg((" returning _rtld_sym_zero@_rtld_objmain"));
|
|
||||||
def = &_rtld_sym_zero;
|
|
||||||
*defobj_out = _rtld_objmain;
|
|
||||||
} else {
|
|
||||||
rdbg(("lookup failed"));
|
|
||||||
_rtld_error("%s: Undefined %ssymbol \"%s\" (symnum = %ld)",
|
|
||||||
refobj->path, in_plt ? "PLT " : "", name, symnum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (def);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue