rtld: Sync 7/7 - Use symbol versioning instead of exports mapping
authorJohn Marino <draco@marino.st>
Thu, 13 Jun 2013 07:19:29 +0000 (09:19 +0200)
committerJohn Marino <draco@marino.st>
Thu, 13 Jun 2013 11:12:08 +0000 (13:12 +0200)
Now that DragonFly has the symbol versioning framework in place, rtld
can leverage it by offloading the symbol export duties to it.  This
further reduces differences between FreeBSD and DragonFly linkers.
Keeping the exports table up to date after FreeBSD removed it was extra
work.

libexec/rtld-elf/Makefile
libexec/rtld-elf/Symbol.map [new file with mode: 0644]
libexec/rtld-elf/i386/Symbol.map [new file with mode: 0644]
libexec/rtld-elf/rtld.c

index 2017433..259eb5a 100644 (file)
@@ -23,6 +23,19 @@ MLINKS=              rtld.1 ld-elf.so.1.1
 MLINKS+=       rtld.1 ld-elf.so.2.1
 MLINKS+=       rtld.1 _rtld_functrace.3
 
+.if !defined(NO_SYMVER)
+VERSION_DEF=   ${.CURDIR}/../../lib/libc/Versions.def
+SYMBOL_MAPS=   ${.CURDIR}/Symbol.map
+VERSION_MAP=   Version.map
+LDFLAGS+=      -Wl,--version-script=${VERSION_MAP}
+
+rtld.c:                ${VERSION_MAP}
+
+.if exists(${.CURDIR}/${MACHINE_ARCH}/Symbol.map)
+SYMBOL_MAPS+=  ${.CURDIR}/${MACHINE_ARCH}/Symbol.map
+.endif
+.endif
+
 .if exists(${.CURDIR}/${MACHINE_ARCH}/Makefile.inc)
 .include "${.CURDIR}/${MACHINE_ARCH}/Makefile.inc"
 .endif
@@ -38,4 +51,5 @@ CFLAGS+=      -DDEBUG
 
 .PATH: ${.CURDIR}/${MACHINE_ARCH}
 
+.include <bsd.symver.mk>
 .include <bsd.prog.mk>
diff --git a/libexec/rtld-elf/Symbol.map b/libexec/rtld-elf/Symbol.map
new file mode 100644 (file)
index 0000000..7f4a67e
--- /dev/null
@@ -0,0 +1,24 @@
+DF306.0 {
+    _rtld_error;
+    dlclose;
+    dlerror;
+    dlopen;
+    dlsym;
+    dlfunc;
+    dlvsym;
+    dladdr;
+    dlinfo;
+    dl_iterate_phdr;
+    __tls_get_addr;
+    __tls_get_addr_tcb;
+    fdlopen;
+};
+
+DFprivate_1.0 {
+    _rtld_allocate_tls;
+    _rtld_free_tls;
+    _rtld_call_init;
+    _rtld_thread_init;
+    _rtld_addr_phdr;
+    _rtld_get_stack_prot;
+};
diff --git a/libexec/rtld-elf/i386/Symbol.map b/libexec/rtld-elf/i386/Symbol.map
new file mode 100644 (file)
index 0000000..6e671c7
--- /dev/null
@@ -0,0 +1,3 @@
+DF306.0 {
+    ___tls_get_addr;
+};
index edb856c..ee54394 100644 (file)
@@ -100,7 +100,6 @@ static void init_dag(Obj_Entry *);
 static void init_rtld(caddr_t, Elf_Auxinfo **);
 static void initlist_add_neededs(Needed_Entry *, Objlist *);
 static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *);
-static bool is_exported(const Elf_Sym *);
 static void linkmap_add(Obj_Entry *);
 static void linkmap_delete(Obj_Entry *);
 static void load_filtees(Obj_Entry *, int flags, RtldLockState *);
@@ -225,37 +224,6 @@ static int stack_prot = PROT_READ | PROT_WRITE | RTLD_DEFAULT_STACK_EXEC;
 static int max_stack_flags;
 
 /*
- * These are the functions the dynamic linker exports to application
- * programs.  They are the only symbols the dynamic linker is willing
- * to export from itself.
- */
-static func_ptr_type exports[] = {
-    (func_ptr_type) &_rtld_error,
-    (func_ptr_type) &dlclose,
-    (func_ptr_type) &dlerror,
-    (func_ptr_type) &dlopen,
-    (func_ptr_type) &fdlopen,
-    (func_ptr_type) &dlfunc,
-    (func_ptr_type) &dlsym,
-    (func_ptr_type) &dlvsym,
-    (func_ptr_type) &dladdr,
-    (func_ptr_type) &dlinfo,
-    (func_ptr_type) &dl_iterate_phdr,
-#ifdef __i386__
-    (func_ptr_type) &___tls_get_addr,
-#endif
-    (func_ptr_type) &__tls_get_addr,
-    (func_ptr_type) &__tls_get_addr_tcb,
-    (func_ptr_type) &_rtld_allocate_tls,
-    (func_ptr_type) &_rtld_free_tls,
-    (func_ptr_type) &_rtld_call_init,
-    (func_ptr_type) &_rtld_thread_init,
-    (func_ptr_type) &_rtld_addr_phdr,
-    (func_ptr_type) &_rtld_get_stack_prot,
-    NULL
-};
-
-/*
  * Global declarations normally provided by crt1.  The dynamic linker is
  * not built with crt1, so we have to provide them ourselves.
  */
@@ -1973,19 +1941,6 @@ initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, Objlist *list)
 #define FPTR_TARGET(f) ((Elf_Addr) (f))
 #endif
 
-static bool
-is_exported(const Elf_Sym *def)
-{
-    Elf_Addr value;
-    const func_ptr_type *p;
-
-    value = (Elf_Addr)(obj_rtld.relocbase + def->st_value);
-    for (p = exports;  *p != NULL;  p++)
-       if (FPTR_TARGET(*p) == value)
-           return true;
-    return false;
-}
-
 static void
 free_needed_filtees(Needed_Entry *n)
 {
@@ -3080,7 +3035,7 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve,
             */
            if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
                res = symlook_obj(&req, &obj_rtld);
-               if (res == 0 && is_exported(req.sym_out)) {
+               if (res == 0) {
                    def = req.sym_out;
                    defobj = req.defobj_out;
                }
@@ -3735,13 +3690,12 @@ symlook_default(SymLook *req, const Obj_Entry *refobj)
     /*
      * Search the dynamic linker itself, and possibly resolve the
      * symbol from there.  This is how the application links to
-     * dynamic linker services such as dlopen.  Only the values listed
-     * in the "exports" array can be resolved from the dynamic linker.
+     * dynamic linker services such as dlopen.
      */
     if (req->sym_out == NULL ||
       ELF_ST_BIND(req->sym_out->st_info) == STB_WEAK) {
        res = symlook_obj(&req1, &obj_rtld);
-       if (res == 0 && is_exported(req1.sym_out)) {
+       if (res == 0) {
            req->sym_out = req1.sym_out;
            req->defobj_out = req1.defobj_out;
            assert(req->defobj_out != NULL);