Source-Changes-HG archive

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

[src/matt-nb6-plus]: src/libexec/ld.elf_so Pullup from HEAD:



details:   https://anonhg.NetBSD.org/src/rev/b8d128b820cd
branches:  matt-nb6-plus
changeset: 774537:b8d128b820cd
user:      matt <matt%NetBSD.org@localhost>
date:      Tue Jan 22 21:47:27 2013 +0000

description:
Pullup from HEAD:
Add .init_array/.fini_array support (conditionalized on HAVE_INITFINI_ARRAY).

diffstat:

 libexec/ld.elf_so/Makefile              |    8 +-
 libexec/ld.elf_so/arch/arm/Makefile.inc |    5 +-
 libexec/ld.elf_so/arch/arm/rtld_start.S |   11 +-
 libexec/ld.elf_so/headers.c             |   26 ++++-
 libexec/ld.elf_so/rtld.c                |  164 +++++++++++++++++++------------
 libexec/ld.elf_so/rtld.h                |   15 ++-
 libexec/ld.elf_so/symbol.c              |    6 +-
 7 files changed, 149 insertions(+), 86 deletions(-)

diffs (truncated from 446 to 300 lines):

diff -r 8306254e0f76 -r b8d128b820cd libexec/ld.elf_so/Makefile
--- a/libexec/ld.elf_so/Makefile        Thu Jan 17 01:33:34 2013 +0000
+++ b/libexec/ld.elf_so/Makefile        Tue Jan 22 21:47:27 2013 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.110 2011/10/07 09:15:21 mrg Exp $
+#      $NetBSD: Makefile,v 1.110.6.1 2013/01/22 21:47:27 matt Exp $
 #
 # NOTE: when changing ld.so, ensure that ldd still compiles.
 #
@@ -43,7 +43,7 @@
 LDFLAGS+=      -Wl,-static
 LDFLAGS+=      -Wl,--warn-shared-textrel
 
-CFLAGS+=       -fvisibility=hidden
+COPTS+=                -fvisibility=hidden
 
 # Adds SRCS, CPPFLAGS, LDFLAGS, etc.  Must go first so MD startup source
 # is first.
@@ -92,10 +92,10 @@
 #CPPFLAGS+=    -DRTLD_DEBUG
 #CPPFLAGS+=    -DRTLD_DEBUG_RELOC
 #DBG=          -g
-DBG=           -O3 -fomit-frame-pointer
+COPTS=         -O3 -fomit-frame-pointer
 
 .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64"
-DBG+=          -mno-3dnow -mno-mmx -mno-sse -mno-sse2 -mno-sse3
+COPTS+=                -mno-3dnow -mno-mmx -mno-sse -mno-sse2 -mno-sse3
 .endif
 
 
diff -r 8306254e0f76 -r b8d128b820cd libexec/ld.elf_so/arch/arm/Makefile.inc
--- a/libexec/ld.elf_so/arch/arm/Makefile.inc   Thu Jan 17 01:33:34 2013 +0000
+++ b/libexec/ld.elf_so/arch/arm/Makefile.inc   Tue Jan 22 21:47:27 2013 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile.inc,v 1.11 2005/06/04 16:17:17 lukem Exp $
+#      $NetBSD: Makefile.inc,v 1.11.46.1 2013/01/22 21:47:28 matt Exp $
 
 SRCS+=         rtld_start.S mdreloc.c
 
@@ -6,5 +6,8 @@
 CPPFLAGS+=     -fpic
 
 CPPFLAGS+=     -DELFSIZE=32
+.if ${MACHINE_ARCH} == "earm" || ${MACHINE_ARCH} == "earmeb"
+CPPFLAGS+=     -DHAVE_INITFINI_ARRAY
+.endif
 
 LDFLAGS+=      -Wl,-e,_rtld_start
diff -r 8306254e0f76 -r b8d128b820cd libexec/ld.elf_so/arch/arm/rtld_start.S
--- a/libexec/ld.elf_so/arch/arm/rtld_start.S   Thu Jan 17 01:33:34 2013 +0000
+++ b/libexec/ld.elf_so/arch/arm/rtld_start.S   Tue Jan 22 21:47:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld_start.S,v 1.10 2009/11/11 14:15:41 skrll Exp $    */
+/*     $NetBSD: rtld_start.S,v 1.10.10.1 2013/01/22 21:47:28 matt Exp $        */
 
 /*-
  * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <machine/asm.h>
 
-RCSID("$NetBSD: rtld_start.S,v 1.10 2009/11/11 14:15:41 skrll Exp $")
+RCSID("$NetBSD: rtld_start.S,v 1.10.10.1 2013/01/22 21:47:28 matt Exp $")
 
        .text
        .align  0
@@ -58,9 +58,8 @@
        bl      _rtld                   /* call the shared loader */
        mov     r3, r0                  /* save entry point */
 
-       ldr     r2, [sp, #0]            /* r2 = cleanup */
-       ldr     r1, [sp, #4]            /* r1 = obj_main */
-       add     sp, sp, #8              /* restore stack */
+       ldr     r2, [sp], #4            /* pop r2 = cleanup */
+       ldr     r1, [sp], #4            /* pop r1 = obj_main */
        mov     r0, r4                  /* restore ps_strings */
 #ifdef _ARM_ARCH_4T
        bx      r3                      /* jump to the entry point */
@@ -81,7 +80,7 @@
  *     lr = &GOT[2]
  */
 _rtld_bind_start:
-       stmdb   sp!,{r0-r4,sl,fp}
+       stmdb   sp!,{r0-r4,sl,fp}       /* 8 byte aligned (lr already saved) */
 
        sub     r1, ip, lr              /* r1 = 4 * (n + 1) */
        sub     r1, r1, #4              /* r1 = 4 * n */
diff -r 8306254e0f76 -r b8d128b820cd libexec/ld.elf_so/headers.c
--- a/libexec/ld.elf_so/headers.c       Thu Jan 17 01:33:34 2013 +0000
+++ b/libexec/ld.elf_so/headers.c       Tue Jan 22 21:47:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: headers.c,v 1.41.4.1 2012/08/08 06:24:51 jdc Exp $      */
+/*     $NetBSD: headers.c,v 1.41.4.1.2.1 2013/01/22 21:47:27 matt Exp $         */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.41.4.1 2012/08/08 06:24:51 jdc Exp $");
+__RCSID("$NetBSD: headers.c,v 1.41.4.1.2.1 2013/01/22 21:47:27 matt Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -227,10 +227,32 @@
                        init = dynp->d_un.d_ptr;
                        break;
 
+#ifdef HAVE_INITFINI_ARRAY
+               case DT_INIT_ARRAY:
+                       obj->init_array =
+                           (fptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
+                       break;
+
+               case DT_INIT_ARRAYSZ:
+                       obj->init_arraysz = dynp->d_un.d_val / sizeof(fptr_t);
+                       break;
+#endif
+
                case DT_FINI:
                        fini = dynp->d_un.d_ptr;
                        break;
 
+#ifdef HAVE_INITFINI_ARRAY
+               case DT_FINI_ARRAY:
+                       obj->fini_array =
+                           (fptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
+                       break;
+
+               case DT_FINI_ARRAYSZ:
+                       obj->fini_arraysz = dynp->d_un.d_val / sizeof(fptr_t); 
+                       break;
+#endif
+
                /*
                 * Don't process DT_DEBUG on MIPS as the dynamic section
                 * is mapped read-only. DT_MIPS_RLD_MAP is used instead.
diff -r 8306254e0f76 -r b8d128b820cd libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c  Thu Jan 17 01:33:34 2013 +0000
+++ b/libexec/ld.elf_so/rtld.c  Tue Jan 22 21:47:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.c,v 1.155 2011/11/25 21:27:15 joerg Exp $  */
+/*     $NetBSD: rtld.c,v 1.155.4.1 2013/01/22 21:47:28 matt Exp $       */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.155 2011/11/25 21:27:15 joerg Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.155.4.1 2013/01/22 21:47:28 matt Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -134,13 +134,50 @@
 static void _rtld_unref_dag(Obj_Entry *);
 static Obj_Entry *_rtld_obj_from_addr(const void *);
 
+static inline void
+_rtld_call_initfini_function(fptr_t func, sigset_t *mask)
+{
+       _rtld_exclusive_exit(mask);
+       (*func)();
+       _rtld_exclusive_enter(mask);
+}
+
+static void
+_rtld_call_fini_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
+{
+       if (obj->fini_arraysz == 0 && (obj->fini == NULL || obj->fini_called)) {
+                       return;
+       }
+       if (obj->fini != NULL && !obj->fini_called) {
+               dbg (("calling fini function %s at %p%s", obj->path,
+                   (void *)obj->fini,
+                   obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
+               obj->fini_called = 1; 
+               _rtld_call_initfini_function(obj->fini, mask);
+       }
+#ifdef HAVE_INITFINI_ARRAY
+       /*
+        * Now process the fini_array if it exists.  Simply go from
+        * start to end.  We need to make restartable so just advance
+        * the array pointer and decrement the size each time through
+        * the loop.
+        */
+       while (obj->fini_arraysz > 0 && _rtld_objgen == cur_objgen) {
+               fptr_t fini = *obj->fini_array++;
+               obj->fini_arraysz--;
+               dbg (("calling fini array function %s at %p%s", obj->path,
+                   (void *)fini,
+                   obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
+               _rtld_call_initfini_function(fini, mask);
+       }
+#endif /* HAVE_INITFINI_ARRAY */
+}
+
 static void
 _rtld_call_fini_functions(sigset_t *mask, int force)
 {
        Objlist_Entry *elm;
        Objlist finilist;
-       Obj_Entry *obj;
-       void (*fini)(void);
        u_int cur_objgen;
 
        dbg(("_rtld_call_fini_functions(%d)", force));
@@ -152,49 +189,33 @@
 
        /* First pass: objects _not_ marked with DF_1_INITFIRST. */
        SIMPLEQ_FOREACH(elm, &finilist, link) {
-               obj = elm->obj;
-               if (obj->refcount > 0 && !force) {
-                       continue;
-               }
-               if (obj->fini == NULL || obj->fini_called || obj->z_initfirst) {
-                       continue;
+               Obj_Entry * const obj = elm->obj;
+               if (!obj->z_initfirst) {
+                       if (obj->refcount > 0 && !force) {
+                               continue;
+                       }
+                       /*
+                        * XXX This can race against a concurrent dlclose().
+                        * XXX In that case, the object could be unmapped before
+                        * XXX the fini() call or the fini_array has completed.
+                        */
+                       _rtld_call_fini_function(obj, mask, cur_objgen);
+                       if (_rtld_objgen != cur_objgen) {
+                               dbg(("restarting fini iteration"));
+                               _rtld_objlist_clear(&finilist);
+                               goto restart;
                }
-               dbg (("calling fini function %s at %p",  obj->path,
-                   (void *)obj->fini));
-               obj->fini_called = 1;
-               /*
-                * XXX This can race against a concurrent dlclose().
-                * XXX In that case, the object could be unmapped before
-                * XXX the fini() call is done.
-                */
-               fini = obj->fini;
-               _rtld_exclusive_exit(mask);
-               (*fini)();
-               _rtld_exclusive_enter(mask);
-               if (_rtld_objgen != cur_objgen) {
-                       dbg(("restarting fini iteration"));
-                       _rtld_objlist_clear(&finilist);
-                       goto restart;
                }
        }
 
        /* Second pass: objects marked with DF_1_INITFIRST. */
        SIMPLEQ_FOREACH(elm, &finilist, link) {
-               obj = elm->obj;
+               Obj_Entry * const obj = elm->obj;
                if (obj->refcount > 0 && !force) {
                        continue;
                }
-               if (obj->fini == NULL || obj->fini_called) {
-                       continue;
-               }
-               dbg (("calling fini function %s at %p (DF_1_INITFIRST)",
-                   obj->path, (void *)obj->fini));
-               obj->fini_called = 1;
                /* XXX See above for the race condition here */
-               fini = obj->fini;
-               _rtld_exclusive_exit(mask);
-               (*fini)();
-               _rtld_exclusive_enter(mask);
+               _rtld_call_fini_function(obj, mask, cur_objgen);
                if (_rtld_objgen != cur_objgen) {
                        dbg(("restarting fini iteration"));
                        _rtld_objlist_clear(&finilist);
@@ -206,12 +227,42 @@
 }
 
 static void
+_rtld_call_init_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
+{
+       if (obj->init_arraysz == 0 && (obj->init_called || obj->init == NULL)) {
+               return;
+       }
+       if (!obj->init_called && obj->init != NULL) {
+               dbg (("calling init function %s at %p%s",
+                   obj->path, (void *)obj->init,
+                   obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
+               obj->init_called = 1;
+               _rtld_call_initfini_function(obj->init, mask);
+       }
+
+#ifdef HAVE_INITFINI_ARRAY
+       /*
+        * Now process the init_array if it exists.  Simply go from
+        * start to end.  We need to make restartable so just advance
+        * the array pointer and decrement the size each time through
+        * the loop.



Home | Main Index | Thread Index | Old Index