Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/ld.elf_so Attempt to give dlsym() the same symbol-se...



details:   https://anonhg.NetBSD.org/src/rev/27506a509af0
branches:  trunk
changeset: 546242:27506a509af0
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Wed Apr 23 17:40:25 2003 +0000

description:
Attempt to give dlsym() the same symbol-searching semantics as _rtld_bind().
Tested in a handful of cases.
Reviewed by: a dead silence

diffstat:

 libexec/ld.elf_so/rtld.c   |  48 +++++-----------------------
 libexec/ld.elf_so/rtld.h   |   7 ++-
 libexec/ld.elf_so/symbol.c |  76 ++++++++++++++++++++++++---------------------
 3 files changed, 53 insertions(+), 78 deletions(-)

diffs (271 lines):

diff -r 30feb3237293 -r 27506a509af0 libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c  Wed Apr 23 17:32:09 2003 +0000
+++ b/libexec/ld.elf_so/rtld.c  Wed Apr 23 17:40:25 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.c,v 1.90 2002/12/14 15:37:57 junyoung Exp $        */
+/*     $NetBSD: rtld.c,v 1.91 2003/04/23 17:40:25 mycroft Exp $         */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -367,8 +367,6 @@
                _rtld_objmain->pathlen = strlen(_rtld_objmain->path);
        }
 
-       _rtld_objmain->mainprog = true;
-       
        /*
         * Get the actual dynamic linker pathname from the executable if
         * possible.  (It should always be possible.)  That ensures that
@@ -673,19 +671,10 @@
        const char *name;
 {
        const Obj_Entry *obj;
-       unsigned long hash;
        const Elf_Sym *def;
        const Obj_Entry *defobj;
        
-       hash = _rtld_elf_hash(name);
-       def = NULL;
-       defobj = NULL;
-       
-       if (handle == NULL
-#if 0
-           || handle == RTLD_NEXT
-#endif
-       ) {
+       if (handle == NULL) {
                void *retaddr;
 
                retaddr = __builtin_return_address(0); /* __GNUC__ only */
@@ -693,33 +682,14 @@
                        _rtld_error("Cannot determine caller's shared object");
                        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 {
-               if ((obj = _rtld_dlcheck(handle)) == NULL)
+               if ((obj = _rtld_dlcheck(handle)) == NULL) {
+                       _rtld_error("Handle not found");
                        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) {
 #ifdef __HAVE_FUNCTION_DESCRIPTORS
@@ -728,10 +698,10 @@
                            def, 0);
 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
                return defobj->relocbase + def->st_value;
+       } else {
+               _rtld_error("Undefined symbol \"%s\"", name);
+               return NULL;
        }
-       
-       _rtld_error("Undefined symbol \"%s\"", name);
-       return NULL;
 }
 
 int
diff -r 30feb3237293 -r 27506a509af0 libexec/ld.elf_so/rtld.h
--- a/libexec/ld.elf_so/rtld.h  Wed Apr 23 17:32:09 2003 +0000
+++ b/libexec/ld.elf_so/rtld.h  Wed Apr 23 17:40:25 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.h,v 1.65 2002/12/05 04:56:57 junyoung Exp $        */
+/*     $NetBSD: rtld.h,v 1.66 2003/04/23 17:40:25 mycroft Exp $         */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -176,8 +176,7 @@
        int             (*dlclose) __P((void *));
        int             (*dladdr) __P((const void *, Dl_info *));
 
-       u_int32_t       mainprog:1,     /* True if this is the main program */
-                       rtld:1,         /* True if this is the dynamic linker */
+       u_int32_t       rtld:1,         /* True if this is the dynamic linker */
                        textrel:1,      /* True if there are relocations to
                                         * text seg */
                        symbolic:1,     /* True if generated with
@@ -256,6 +255,8 @@
 unsigned long _rtld_elf_hash __P((const char *));
 const Elf_Sym *_rtld_symlook_obj __P((const char *, unsigned long,
     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 Obj_Entry **, bool));
 const Elf_Sym *_rtld_symlook_list(const char *, unsigned long,
diff -r 30feb3237293 -r 27506a509af0 libexec/ld.elf_so/symbol.c
--- a/libexec/ld.elf_so/symbol.c        Wed Apr 23 17:32:09 2003 +0000
+++ b/libexec/ld.elf_so/symbol.c        Wed Apr 23 17:40:25 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: symbol.c,v 1.25 2002/10/05 11:59:04 mycroft Exp $       */
+/*     $NetBSD: symbol.c,v 1.26 2003/04/23 17:40:25 mycroft Exp $       */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -83,11 +83,9 @@
 {
        const Elf_Sym *symp;
        const Elf_Sym *def;
-       const Obj_Entry *defobj;
        const Objlist_Entry *elm;
        
        def = NULL;
-       defobj = NULL;
        SIMPLEQ_FOREACH(elm, objlist, link) {
                rdbg(("search object %p (%s)", elm->obj, elm->obj->path));
                if ((symp = _rtld_symlook_obj(name, hash, elm->obj, in_plt))
@@ -95,14 +93,12 @@
                        if ((def == NULL) ||
                            (ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
                                def = symp;
-                               defobj = elm->obj;
+                               *defobj_out = elm->obj;
                                if (ELF_ST_BIND(def->st_info) != STB_WEAK)
                                        break;
                        }
                }
        }
-       if (def != NULL)
-               *defobj_out = defobj;
        return def;
 }
 
@@ -166,33 +162,26 @@
  * defining object via the reference parameter DEFOBJ_OUT.
  */
 const Elf_Sym *
-_rtld_find_symdef(symnum, refobj, defobj_out, in_plt)
-       unsigned long symnum;
+_rtld_find_symname(name, refobj, defobj_out, in_plt)
+       const char *name;
        const Obj_Entry *refobj;
        const Obj_Entry **defobj_out;
        bool in_plt;
 {
-       const Elf_Sym  *ref;
        const Elf_Sym  *def;
        const Elf_Sym  *symp;
        const Obj_Entry *obj;
-       const Obj_Entry *defobj;
        const Objlist_Entry *elm;
-       const char     *name;
        unsigned long   hash;
 
-       ref = refobj->symtab + symnum;
-       name = refobj->strtab + ref->st_name;
-
        hash = _rtld_elf_hash(name);
        def = NULL;
-       defobj = NULL;
        
        if (refobj->symbolic) { /* Look first in the referencing object */
                symp = _rtld_symlook_obj(name, hash, refobj, in_plt);
                if (symp != NULL) {
                        def = symp;
-                       defobj = refobj;
+                       *defobj_out = refobj;
                }
        }
        
@@ -203,7 +192,7 @@
                if (symp != NULL &&
                    (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
                        def = symp;
-                       defobj = obj;
+                       *defobj_out = obj;
                }
        }
        
@@ -216,7 +205,7 @@
                if (symp != NULL &&
                    (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
                        def = symp;
-                       defobj = obj;
+                       *defobj_out = obj;
                }
        }
        
@@ -227,26 +216,41 @@
                if (symp != NULL &&
                    (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
                        def = symp;
-                       defobj = obj;
+                       *defobj_out = 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;
 }
+
+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);
+}



Home | Main Index | Thread Index | Old Index