tech-userlevel archive

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

Proper interface for finding the ELF auxilary vector



Hi all,
attached patch adds a new function _dlauxinfo() to obtain a pointer to
the ELF auxilary vector. The function returns void * to allow changing
the vector. Consider passing the initial seed for __guard_setup() to
avoid one system call per exec(2), in which case it is useful to whipe
the entry after consuming it. The patch fixes a non-trivial init order
issue. __libc_init is called twice for dynamically linked programs --
once as constructor by ld.elf_so, once by crt0.o. Only the second call
has access to __ps_strings though. The new callback into ld.elf_so
addresses that issue.

Joerg
Index: include/dlfcn.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/include/dlfcn.h,v
retrieving revision 1.23
diff -u -p -r1.23 dlfcn.h
--- include/dlfcn.h     25 Jun 2011 05:45:11 -0000      1.23
+++ include/dlfcn.h     14 Feb 2012 22:45:30 -0000
@@ -48,6 +48,8 @@ typedef struct _dl_info {
  * User interface to the run-time linker.
  */
 __BEGIN_DECLS
+void *_dlauxinfo(void) __pure;
+
 void   *dlopen(const char *, int);
 int    dlclose(void *);
 void   *dlsym(void * __restrict, const char * __restrict);
Index: lib/libc/dlfcn/dlfcn_elf.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/dlfcn/dlfcn_elf.c,v
retrieving revision 1.10
diff -u -p -r1.10 dlfcn_elf.c
--- lib/libc/dlfcn/dlfcn_elf.c  25 Jun 2011 05:45:11 -0000      1.10
+++ lib/libc/dlfcn/dlfcn_elf.c  14 Feb 2012 17:03:28 -0000
@@ -149,21 +149,14 @@ static Elf_Addr dlpi_addr;
 static const Elf_Phdr *dlpi_phdr;
 static Elf_Half dlpi_phnum;
 
-/*
- * Declare as common symbol to allow new libc with older binaries to
- * not trigger an undefined reference.
- */
-extern __dso_hidden void *__auxinfo;
-
 static void
 dl_iterate_phdr_setup(void)
 {
        const AuxInfo *aux;
 
-       if (__auxinfo == NULL)
-               return;
+       _DIAGASSERT(_dlauxinfo() != NULL);
 
-       for (aux = __auxinfo; aux->a_type != AT_NULL; ++aux) {
+       for (aux = _dlauxinfo(); aux->a_type != AT_NULL; ++aux) {
                switch (aux->a_type) {
                case AT_BASE:
                        dlpi_addr = aux->a_v;
@@ -189,9 +182,6 @@ dl_iterate_phdr(int (*callback)(struct d
        static bool setup_done;
        struct dl_phdr_info phdr_info;
 
-       if (__auxinfo == NULL)
-               return EOPNOTSUPP;
-
        if (!setup_done) {
                /*
                 * This can race on the first call to dl_iterate_phdr.
Index: lib/libc/misc/initfini.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/misc/initfini.c,v
retrieving revision 1.9
diff -u -p -r1.9 initfini.c
--- lib/libc/misc/initfini.c    9 Mar 2011 23:10:06 -0000       1.9
+++ lib/libc/misc/initfini.c    14 Feb 2012 22:45:49 -0000
@@ -53,11 +53,27 @@ void        __libc_env_init(void);
 __dso_hidden void      __libc_static_tls_setup(void);
 #endif
 
+#ifdef __weak_alias
+__weak_alias(_dlauxinfo,___dlauxinfo)
+static void *__libc_dlauxinfo;
+
+void *___dlauxinfo(void) __pure;
+
+void *
+___dlauxinfo(void)
+{
+       return __libc_dlauxinfo;
+}
+#endif
+
 static bool libc_initialised;
 
 void _libc_init(void);
 
-__dso_hidden void      *__auxinfo;
+/*
+ * Declare as common symbol to allow new libc with older binaries to
+ * not trigger an undefined reference.
+ */
 struct ps_strings *__ps_strings;
 
 /*
@@ -74,7 +90,7 @@ _libc_init(void)
        libc_initialised = 1;
 
        if (__ps_strings != NULL)
-               __auxinfo = __ps_strings->ps_argvstr +
+               __libc_dlauxinfo = __ps_strings->ps_argvstr +
                    __ps_strings->ps_nargvstr + __ps_strings->ps_nenvstr + 2;
 
        /* For -fstack-protector */
Index: libexec/ld.elf_so/rtld.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/rtld.c,v
retrieving revision 1.155
diff -u -p -r1.155 rtld.c
--- libexec/ld.elf_so/rtld.c    25 Nov 2011 21:27:15 -0000      1.155
+++ libexec/ld.elf_so/rtld.c    14 Feb 2012 22:55:21 -0000
@@ -103,6 +103,7 @@ Search_Path    *_rtld_default_paths;
 Search_Path    *_rtld_paths;
 
 Library_Xform  *_rtld_xforms;
+static void    *auxinfo;
 
 /*
  * Global declarations normally provided by crt0.
@@ -349,6 +350,12 @@ _rtld_exit(void)
        _rtld_exclusive_exit(&mask);
 }
 
+__dso_public void *
+_dlauxinfo(void)
+{
+       return auxinfo;
+}
+
 /*
  * Main entry point for dynamic linking.  The argument is the stack
  * pointer.  The stack is expected to be laid out as described in the
@@ -371,7 +378,6 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
                       *pAUX_ruid, *pAUX_rgid;
        const AuxInfo  *pAUX_pagesz;
        char          **env, **oenvp;
-       const AuxInfo  *aux;
        const AuxInfo  *auxp;
        Obj_Entry      *obj;
        Elf_Addr       *const osp = sp;
@@ -421,7 +427,7 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
                dbg(("env[%d] = %p %s", i++, (void *)sp[-1], (char *)sp[-1]));
 #endif
        }
-       aux = (const AuxInfo *) sp;
+       auxinfo = (AuxInfo *) sp;
 
        pAUX_base = pAUX_entry = pAUX_execfd = NULL;
        pAUX_phdr = pAUX_phent = pAUX_phnum = NULL;
@@ -431,7 +437,7 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
        execname = NULL;
 
        /* Digest the auxiliary vector. */
-       for (auxp = aux; auxp->a_type != AT_NULL; ++auxp) {
+       for (auxp = auxinfo; auxp->a_type != AT_NULL; ++auxp) {
                switch (auxp->a_type) {
                case AT_BASE:
                        pAUX_base = auxp;
Index: libexec/ld.elf_so/rtld.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/rtld.h,v
retrieving revision 1.107
diff -u -p -r1.107 rtld.h
--- libexec/ld.elf_so/rtld.h    2 Dec 2011 09:06:49 -0000       1.107
+++ libexec/ld.elf_so/rtld.h    14 Feb 2012 22:46:16 -0000
@@ -331,6 +331,8 @@ __dso_public int dlinfo(void *, int, voi
 __dso_public int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void 
*),
     void *);
 
+__dso_public void *_dlauxinfo(void) __pure;
+
 /* These aren't exported */
 void _rtld_error(const char *, ...)
      __attribute__((__format__(__printf__,1,2)));
Index: libexec/ld.elf_so/symbol.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/symbol.c,v
retrieving revision 1.59
diff -u -p -r1.59 symbol.c
--- libexec/ld.elf_so/symbol.c  25 Nov 2011 14:39:02 -0000      1.59
+++ libexec/ld.elf_so/symbol.c  14 Feb 2012 17:01:35 -0000
@@ -94,6 +94,7 @@ _rtld_is_exported(const Elf_Sym *def)
                (fptr_t)dladdr,
                (fptr_t)dlinfo,
                (fptr_t)dl_iterate_phdr,
+               (fptr_t)_dlauxinfo,
 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
                (fptr_t)_rtld_tls_allocate,
                (fptr_t)_rtld_tls_free,


Home | Main Index | Thread Index | Old Index