tech-userlevel archive

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

ld.elf_so locking



Hi all,
attached patch adds a reader/writer lock to ld.elf_so. This should fix
all the basic race conditions for ld.elf_so in multi-threaded programs.
There are currently two situations left where a recursion would currently
result in a dead lock: a signal handler or constructor using __tls_get_addr
requiring memory allocation when already in ld.elf_so and a signal
handler occuring during exclusively locked calls like dlopen trying to
access a shared lock e.g. to lazily resolve a relocation.

The second can be mostly be adressed by using sigprocmask in the
exclusive lock. The former would require either splitting the exclusive
lock into two (one for malloc and one for the rest) or annotating
globally whether malloc is currently safe and allowing exclusive lock
recursion in that case. Comments?

Joerg
Index: libexec/ld.elf_so/rtld.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/rtld.c,v
retrieving revision 1.140
diff -u -p -r1.140 rtld.c
--- libexec/ld.elf_so/rtld.c    13 Mar 2011 21:08:45 -0000      1.140
+++ libexec/ld.elf_so/rtld.c    14 Mar 2011 15:21:22 -0000
@@ -43,16 +43,18 @@
 __RCSID("$NetBSD: rtld.c,v 1.140 2011/03/13 21:08:45 joerg Exp $");
 #endif /* not lint */
 
+#include <sys/param.h>
+#include <sys/atomic.h>
+#include <sys/mman.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <lwp.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/param.h>
-#include <sys/mman.h>
 #include <dirent.h>
 
 #include <ctype.h>
@@ -107,6 +109,8 @@ Library_Xform  *_rtld_xforms;
 char           *__progname;
 char          **environ;
 
+static volatile bool _rtld_mutex_may_recurse;
+
 #if defined(RTLD_DEBUG)
 #ifndef __sh__
 extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
@@ -153,7 +157,10 @@ _rtld_call_fini_functions(int force)
                dbg (("calling fini function %s at %p",  obj->path,
                    (void *)obj->fini));
                obj->fini_called = 1;
+               /* XXXlocking: exit point */
+               _rtld_mutex_may_recurse = true;
                (*obj->fini)();
+               _rtld_mutex_may_recurse = false;
        }
 
        /* Second pass: objects marked with DF_1_INITFIRST. */
@@ -168,7 +175,10 @@ _rtld_call_fini_functions(int force)
                dbg (("calling fini function %s at %p (DF_1_INITFIRST)",
                    obj->path, (void *)obj->fini));
                obj->fini_called = 1;
+               /* XXXlocking: exit point */
+               _rtld_mutex_may_recurse = true;
                (*obj->fini)();
+               _rtld_mutex_may_recurse = false;
        }
 
         _rtld_objlist_clear(&finilist);
@@ -194,7 +204,10 @@ _rtld_call_init_functions()
                dbg (("calling init function %s at %p (DF_1_INITFIRST)",
                    obj->path, (void *)obj->init));
                obj->init_called = 1;
+               /* XXXlocking: exit point */
+               _rtld_mutex_may_recurse = true;
                (*obj->init)();
+               _rtld_mutex_may_recurse = false;
        }
 
        /* Second pass: all other objects. */
@@ -206,7 +219,10 @@ _rtld_call_init_functions()
                dbg (("calling init function %s at %p",  obj->path,
                    (void *)obj->init));
                obj->init_called = 1;
+               /* XXXlocking: exit point */
+               _rtld_mutex_may_recurse = true;
                (*obj->init)();
+               _rtld_mutex_may_recurse = false;
        }
 
         _rtld_objlist_clear(&initlist);
@@ -619,12 +635,16 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
        if (real___mainprog_obj)
                *real___mainprog_obj = _rtld_objmain;
 
+       _rtld_exclusive_enter();
+
        dbg(("calling _init functions"));
        _rtld_call_init_functions();
 
        dbg(("control at program entry point = %p, obj = %p, exit = %p",
             _rtld_objmain->entry, _rtld_objmain, _rtld_exit));
 
+       _rtld_exclusive_exit();
+
        /*
         * Return with the entry point and the exit procedure in at the top
         * of stack.
@@ -856,6 +876,8 @@ dlopen(const char *name, int mode)
        bool nodelete;
        bool now;
 
+       _rtld_exclusive_enter();
+
        flags |= (mode & RTLD_GLOBAL) ? _RTLD_GLOBAL : 0;
        flags |= (mode & RTLD_NOLOAD) ? _RTLD_NOLOAD : 0;
        
@@ -899,6 +921,8 @@ dlopen(const char *name, int mode)
        _rtld_debug.r_state = RT_CONSISTENT;
        _rtld_debug_state();
 
+       _rtld_exclusive_exit();
+
        return obj;
 }
 
@@ -933,6 +957,14 @@ hackish_return_address(void)
 }
 #endif
 
+#ifdef __HAVE_FUNCTION_DESCRIPTORS
+#define        lookup_mutex_enter()    _rtld_exclusive_enter()
+#define        lookup_mutex_exit()     _rtld_exclusive_exit()
+#else
+#define        lookup_mutex_enter()    _rtld_shared_enter()
+#define        lookup_mutex_exit()     _rtld_shared_exit()
+#endif
+
 __strong_alias(__dlsym,dlsym)
 void *
 dlsym(void *handle, const char *name)
@@ -943,7 +975,9 @@ dlsym(void *handle, const char *name)
        const Obj_Entry *defobj;
        void *retaddr;
        DoneList donelist; 
-       
+
+       lookup_mutex_enter();
+
        hash = _rtld_elf_hash(name);
        def = NULL;
        defobj = NULL;
@@ -960,6 +994,7 @@ dlsym(void *handle, const char *name)
 #endif
                if ((obj = _rtld_obj_from_addr(retaddr)) == NULL) {
                        _rtld_error("Cannot determine caller's shared object");
+                       lookup_mutex_exit();
                        return NULL;
                }
 
@@ -994,9 +1029,11 @@ dlsym(void *handle, const char *name)
                break;
 
        default:
-               if ((obj = _rtld_dlcheck(handle)) == NULL)
+               if ((obj = _rtld_dlcheck(handle)) == NULL) {
+                       lookup_mutex_exit();
                        return NULL;
-               
+               }
+
                _rtld_donelist_init(&donelist);
 
                if (obj->mainprog) {
@@ -1021,15 +1058,20 @@ dlsym(void *handle, const char *name)
        }
        
        if (def != NULL) {
+               void *p;
 #ifdef __HAVE_FUNCTION_DESCRIPTORS
-               if (ELF_ST_TYPE(def->st_info) == STT_FUNC)
-                       return (void *)_rtld_function_descriptor_alloc(defobj, 
-                           def, 0);
+               if (ELF_ST_TYPE(def->st_info) == STT_FUNC) {
+                       lookup_mutex_exit();
+                       return p;
+               }
 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
-               return defobj->relocbase + def->st_value;
+               p = defobj->relocbase + def->st_value;
+               lookup_mutex_exit();
+               return p;
        }
        
        _rtld_error("Undefined symbol \"%s\"", name);
+       lookup_mutex_exit();
        return NULL;
 }
 
@@ -1041,7 +1083,9 @@ dladdr(const void *addr, Dl_info *info)
        const Elf_Sym *def, *best_def;
        void *symbol_addr;
        unsigned long symoffset;
-       
+
+       lookup_mutex_enter();
+
 #ifdef __HAVE_FUNCTION_DESCRIPTORS
        addr = _rtld_function_descriptor_function(addr);
 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
@@ -1049,6 +1093,7 @@ dladdr(const void *addr, Dl_info *info)
        obj = _rtld_obj_from_addr(addr);
        if (obj == NULL) {
                _rtld_error("No shared object contains address");
+               lookup_mutex_enter();
                return 0;
        }
        info->dli_fname = obj->path;
@@ -1096,6 +1141,7 @@ dladdr(const void *addr, Dl_info *info)
                    best_def, 0);
 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
 
+       lookup_mutex_exit();
        return 1;
 }
 
@@ -1106,6 +1152,8 @@ dlinfo(void *handle, int req, void *v)
        const Obj_Entry *obj;
        void *retaddr;
 
+       _rtld_shared_enter();
+
        if (handle == RTLD_SELF) {
 #ifdef __powerpc__
                retaddr = hackish_return_address();
@@ -1114,11 +1162,13 @@ dlinfo(void *handle, int req, void *v)
 #endif
                if ((obj = _rtld_obj_from_addr(retaddr)) == NULL) {
                        _rtld_error("Cannot determine caller's shared object");
+                       _rtld_shared_exit();
                        return -1;
                }
        } else {
                if ((obj = _rtld_dlcheck(handle)) == NULL) {
                        _rtld_error("Invalid handle");
+                       _rtld_shared_exit();
                        return -1;
                }
        }
@@ -1134,9 +1184,11 @@ dlinfo(void *handle, int req, void *v)
 
        default:
                _rtld_error("Invalid request");
+               _rtld_shared_exit();
                return -1;
        }
 
+       _rtld_shared_exit();
        return 0;
 }
 
@@ -1148,6 +1200,8 @@ dl_iterate_phdr(int (*callback)(struct d
        const Obj_Entry *obj;
        int error = 0;
 
+       _rtld_shared_enter();
+
        for (obj = _rtld_objlist;  obj != NULL;  obj = obj->next) {
                phdr_info.dlpi_addr = (Elf_Addr)obj->relocbase;
                phdr_info.dlpi_name = STAILQ_FIRST(&obj->names) ?
@@ -1164,11 +1218,13 @@ dl_iterate_phdr(int (*callback)(struct d
                phdr_info.dlpi_adds = _rtld_objloads;
                phdr_info.dlpi_subs = _rtld_objloads - _rtld_objcount;
 
+               /* XXXlocking: exit point */
                error = callback(&phdr_info, sizeof(phdr_info), param);
                if (error)
                        break;
        }
 
+       _rtld_shared_exit();
        return error;
 }
 
@@ -1278,3 +1334,117 @@ _rtld_objlist_remove(Objlist *list, Obj_
                xfree(elm);
        }
 }
+
+#define        RTLD_EXCLUSIVE_MASK     0x80000000U
+static volatile unsigned int _rtld_mutex;
+static volatile unsigned int _rtld_waiter_exclusive;
+static volatile unsigned int _rtld_waiter_shared;
+
+void
+_rtld_shared_enter(void)
+{
+       unsigned int cur;
+       lwpid_t waiter, self = 0;
+
+       membar_enter();
+
+       for (;;) {
+               cur = _rtld_mutex;
+               /*
+                * First check if we are currently not exclusively locked.
+                */
+               if ((cur & RTLD_EXCLUSIVE_MASK) == 0) {
+                       /* Yes, so increment use counter */
+                       if (atomic_cas_uint(&_rtld_mutex, cur, cur + 1) != cur)
+                               continue;
+                       return;
+               }
+               /*
+                * Someone has an exclusive lock.  Puts us on the waiter list.
+                */
+               if (!self)
+                       self = _lwp_self();
+               if (cur == (self | RTLD_EXCLUSIVE_MASK)) {
+                       if (_rtld_mutex_may_recurse)
+                               return;
+                       _rtld_error("dead lock detected");
+                       _rtld_die();
+               }
+               waiter = atomic_swap_uint(&_rtld_waiter_shared, self);
+               /*
+                * Check for race against _rtld_exclusive_exit before sleeping.
+                */
+               if ((_rtld_mutex & RTLD_EXCLUSIVE_MASK) ||
+                   _rtld_waiter_exclusive)
+                       _lwp_park(NULL, -1, __UNVOLATILE(&_rtld_mutex), NULL);
+               /* Try to remove us from the waiter list. */
+               atomic_cas_uint(&_rtld_waiter_shared, self, 0);
+               if (waiter)
+                       _lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
+       }
+}
+
+void
+_rtld_shared_exit(void)
+{
+       lwpid_t waiter;
+
+       /*
+        * Shared lock taken after an exclusive lock.
+        * Just assume this is a partial recursion.
+        */
+       if (_rtld_mutex & RTLD_EXCLUSIVE_MASK)
+               return;
+
+       /*
+        * Wakeup LWPs waiting for an exclusive lock if this is the last
+        * LWP on the shared lock.
+        */
+       if (atomic_dec_uint_nv(&_rtld_mutex))
+               return;
+       if ((waiter = _rtld_waiter_exclusive) != 0)
+               _lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
+
+       membar_exit();
+}
+
+void
+_rtld_exclusive_enter(void)
+{
+       lwpid_t waiter, self = _lwp_self();
+       unsigned int locked_value = (unsigned int)self | RTLD_EXCLUSIVE_MASK;
+       unsigned int cur;
+
+       membar_enter();
+
+       for (;;) {
+               if (atomic_cas_uint(&_rtld_mutex, 0, locked_value) == 0)
+                       break;
+               waiter = atomic_swap_uint(&_rtld_waiter_exclusive, self);
+               cur = _rtld_mutex;
+               if (cur == locked_value) {
+                       _rtld_error("dead lock detected");
+                       _rtld_die();
+               }
+               if (cur)
+                       _lwp_park(NULL, -1, __UNVOLATILE(&_rtld_mutex), NULL);
+               atomic_cas_uint(&_rtld_waiter_exclusive, self, 0);
+               if (waiter)
+                       _lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
+       }
+}
+
+void
+_rtld_exclusive_exit(void)
+{
+       lwpid_t waiter;
+
+       _rtld_mutex = 0;
+       if ((waiter = _rtld_waiter_exclusive) != 0)
+               _lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
+
+       if ((waiter = _rtld_waiter_shared) != 0)
+               _lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
+
+       membar_exit();
+}
Index: libexec/ld.elf_so/rtld.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/rtld.h,v
retrieving revision 1.103
diff -u -p -r1.103 rtld.h
--- libexec/ld.elf_so/rtld.h    12 Mar 2011 22:54:36 -0000      1.103
+++ libexec/ld.elf_so/rtld.h    13 Mar 2011 18:23:20 -0000
@@ -312,6 +312,11 @@ void _rtld_objlist_push_tail(Objlist *, 
 Objlist_Entry *_rtld_objlist_find(Objlist *, const Obj_Entry *);
 void _rtld_ref_dag(Obj_Entry *);
 
+void _rtld_shared_enter(void);
+void _rtld_shared_exit(void);
+void _rtld_exclusive_enter(void);
+void _rtld_exclusive_exit(void);
+
 /* expand.c */
 size_t _rtld_expand_path(char *, size_t, const char *, const char *,\
     const char *);
Index: libexec/ld.elf_so/tls.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/tls.c,v
retrieving revision 1.3
diff -u -p -r1.3 tls.c
--- libexec/ld.elf_so/tls.c     12 Mar 2011 07:43:53 -0000      1.3
+++ libexec/ld.elf_so/tls.c     13 Mar 2011 21:01:15 -0000
@@ -39,6 +39,8 @@ __RCSID("$NetBSD: tls.c,v 1.3 2011/03/12
 
 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
 
+static struct tls_tcb *_rtld_tls_allocate_locked(void);
+
 #ifndef TLS_DTV_OFFSET
 #define        TLS_DTV_OFFSET  0
 #endif
@@ -59,6 +61,8 @@ _rtld_tls_get_addr(void *tls, size_t idx
        struct tls_tcb *tcb = tls;
        void **dtv, **new_dtv;
 
+       _rtld_exclusive_enter();
+
        dtv = tcb->tcb_dtv;
 
        if (__predict_false(DTV_GENERATION(dtv) != _rtld_tls_dtv_generation)) {
@@ -78,6 +82,8 @@ _rtld_tls_get_addr(void *tls, size_t idx
        if (__predict_false(dtv[idx] == NULL))
                dtv[idx] = _rtld_tls_module_allocate(idx);
 
+       _rtld_exclusive_exit();
+
        return (uint8_t *)dtv[idx] + offset;
 }
 
@@ -94,7 +100,7 @@ _rtld_tls_initial_allocation(void)
            sizeof(void *));
 #endif
 
-       tcb = _rtld_tls_allocate();
+       tcb = _rtld_tls_allocate_locked();
 #ifdef __HAVE___LWP_SETTCB
        __lwp_settcb(tcb);
 #else
@@ -102,8 +108,8 @@ _rtld_tls_initial_allocation(void)
 #endif
 }
 
-struct tls_tcb *
-_rtld_tls_allocate(void)
+static struct tls_tcb *
+_rtld_tls_allocate_locked(void)
 {
        Obj_Entry *obj;
        struct tls_tcb *tcb;
@@ -138,12 +144,26 @@ _rtld_tls_allocate(void)
        return tcb;
 }
 
+struct tls_tcb *
+_rtld_tls_allocate(void)
+{
+       struct tls_tcb *tcb;
+
+       _rtld_exclusive_enter();
+       tcb = _rtld_tls_allocate_locked();
+       _rtld_exclusive_exit();
+
+       return tcb;
+}
+
 void
 _rtld_tls_free(struct tls_tcb *tcb)
 {
        size_t i, max_index;
        uint8_t *p;
 
+       _rtld_exclusive_enter();
+
        max_index = DTV_MAX_INDEX(tcb->tcb_dtv);
        for (i = 1; i <= max_index; ++i)
                xfree(tcb->tcb_dtv[i]);
@@ -155,6 +175,8 @@ _rtld_tls_free(struct tls_tcb *tcb)
        p = (uint8_t *)tcb - _rtld_tls_static_space;
 #endif
        xfree(p);
+
+       _rtld_exclusive_exit();
 }
 
 void *
Index: libexec/ld.elf_so/arch/alpha/alpha_reloc.c
===================================================================
RCS file: 
/home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/alpha/alpha_reloc.c,v
retrieving revision 1.38
diff -u -p -r1.38 alpha_reloc.c
--- libexec/ld.elf_so/arch/alpha/alpha_reloc.c  30 Sep 2010 09:11:18 -0000      
1.38
+++ libexec/ld.elf_so/arch/alpha/alpha_reloc.c  13 Mar 2011 18:37:05 -0000
@@ -483,9 +483,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Add
        Elf_Addr result = 0; /* XXX gcc */
        int err;
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, &result);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)result;
 }
Index: libexec/ld.elf_so/arch/arm/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/arm/mdreloc.c,v
retrieving revision 1.34
diff -u -p -r1.34 mdreloc.c
--- libexec/ld.elf_so/arch/arm/mdreloc.c        6 Aug 2010 16:33:17 -0000       
1.34
+++ libexec/ld.elf_so/arch/arm/mdreloc.c        13 Mar 2011 18:37:19 -0000
@@ -254,9 +254,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
        Elf_Addr new_value = 0; /* XXX gcc */
        int err;
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rel, &new_value);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)new_value;
 }
Index: libexec/ld.elf_so/arch/hppa/hppa_reloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/hppa/hppa_reloc.c,v
retrieving revision 1.35
diff -u -p -r1.35 hppa_reloc.c
--- libexec/ld.elf_so/arch/hppa/hppa_reloc.c    10 Mar 2011 12:53:42 -0000      
1.35
+++ libexec/ld.elf_so/arch/hppa/hppa_reloc.c    13 Mar 2011 18:37:35 -0000
@@ -597,9 +597,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
        
        assert(ELF_R_SYM(rela->r_info) != 0);
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, &new_value); 
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)new_value;
 }
Index: libexec/ld.elf_so/arch/i386/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/i386/mdreloc.c,v
retrieving revision 1.33
diff -u -p -r1.33 mdreloc.c
--- libexec/ld.elf_so/arch/i386/mdreloc.c       12 Mar 2011 22:54:36 -0000      
1.33
+++ libexec/ld.elf_so/arch/i386/mdreloc.c       13 Mar 2011 18:37:48 -0000
@@ -236,9 +236,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 
        new_value = 0;  /* XXX gcc */
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rel, &new_value);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)new_value;
 }
Index: libexec/ld.elf_so/arch/m68k/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/m68k/mdreloc.c,v
retrieving revision 1.27
diff -u -p -r1.27 mdreloc.c
--- libexec/ld.elf_so/arch/m68k/mdreloc.c       6 Aug 2010 16:33:18 -0000       
1.27
+++ libexec/ld.elf_so/arch/m68k/mdreloc.c       13 Mar 2011 18:38:28 -0000
@@ -204,9 +204,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 
        result = 0;     /* XXX gcc */
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, &result);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)result;
 }
Index: libexec/ld.elf_so/arch/mips/mips_reloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/mips/mips_reloc.c,v
retrieving revision 1.60
diff -u -p -r1.60 mips_reloc.c
--- libexec/ld.elf_so/arch/mips/mips_reloc.c    24 Sep 2010 15:20:52 -0000      
1.60
+++ libexec/ld.elf_so/arch/mips/mips_reloc.c    13 Mar 2011 18:38:40 -0000
@@ -431,9 +431,11 @@ _rtld_bind(Elf_Word a0, Elf_Addr a1, Elf
        Elf_Addr new_value = 0; /* XXX gcc */
        int err;
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, a0, &new_value);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)new_value;
 }
Index: libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
===================================================================
RCS file: 
/home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c,v
retrieving revision 1.48
diff -u -p -r1.48 ppc_reloc.c
--- libexec/ld.elf_so/arch/powerpc/ppc_reloc.c  12 Mar 2011 07:43:53 -0000      
1.48
+++ libexec/ld.elf_so/arch/powerpc/ppc_reloc.c  13 Mar 2011 18:38:53 -0000
@@ -397,9 +397,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 
        new_value = 0;  /* XXX gcc */
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, reloff, &new_value); 
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)new_value;
 }
Index: libexec/ld.elf_so/arch/sh3/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/sh3/mdreloc.c,v
retrieving revision 1.29
diff -u -p -r1.29 mdreloc.c
--- libexec/ld.elf_so/arch/sh3/mdreloc.c        12 Mar 2011 22:54:36 -0000      
1.29
+++ libexec/ld.elf_so/arch/sh3/mdreloc.c        13 Mar 2011 18:39:03 -0000
@@ -244,9 +244,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 
        new_value = 0;  /* XXX gcc */
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, &new_value);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)new_value;
 }
Index: libexec/ld.elf_so/arch/sparc/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/sparc/mdreloc.c,v
retrieving revision 1.44
diff -u -p -r1.44 mdreloc.c
--- libexec/ld.elf_so/arch/sparc/mdreloc.c      6 Aug 2010 16:33:18 -0000       
1.44
+++ libexec/ld.elf_so/arch/sparc/mdreloc.c      13 Mar 2011 18:39:12 -0000
@@ -325,9 +325,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 
        value = 0;      /* XXX gcc */
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, &value);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)value;
 }
Index: libexec/ld.elf_so/arch/sparc64/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/sparc64/mdreloc.c,v
retrieving revision 1.50
diff -u -p -r1.50 mdreloc.c
--- libexec/ld.elf_so/arch/sparc64/mdreloc.c    24 Sep 2010 12:00:10 -0000      
1.50
+++ libexec/ld.elf_so/arch/sparc64/mdreloc.c    13 Mar 2011 18:39:40 -0000
@@ -471,9 +471,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
                rela -= 4;
        }
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, &result);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)result;
 }
Index: libexec/ld.elf_so/arch/vax/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/vax/mdreloc.c,v
retrieving revision 1.27
diff -u -p -r1.27 mdreloc.c
--- libexec/ld.elf_so/arch/vax/mdreloc.c        6 Aug 2010 16:33:19 -0000       
1.27
+++ libexec/ld.elf_so/arch/vax/mdreloc.c        13 Mar 2011 18:39:51 -0000
@@ -187,9 +187,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 
        result = 0;     /* XXX gcc */
 
+       _rtld_shared_enter();
        err = _rtld_relocate_plt_object(obj, rela, &result);
        if (err)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)result;
 }
Index: libexec/ld.elf_so/arch/x86_64/mdreloc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/arch/x86_64/mdreloc.c,v
retrieving revision 1.39
diff -u -p -r1.39 mdreloc.c
--- libexec/ld.elf_so/arch/x86_64/mdreloc.c     12 Mar 2011 22:54:36 -0000      
1.39
+++ libexec/ld.elf_so/arch/x86_64/mdreloc.c     13 Mar 2011 18:40:02 -0000
@@ -335,9 +335,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Wor
 
        new_value = 0; /* XXX GCC4 */
 
+       _rtld_shared_enter();
        error = _rtld_relocate_plt_object(obj, rela, &new_value);
        if (error)
                _rtld_die();
+       _rtld_shared_exit();
 
        return (caddr_t)new_value;
 }
Index: rescue/list.ldd
===================================================================
RCS file: /home/joerg/repo/netbsd/src/rescue/list.ldd,v
retrieving revision 1.5
diff -u -p -r1.5 list.ldd
--- rescue/list.ldd     9 Mar 2011 23:10:07 -0000       1.5
+++ rescue/list.ldd     13 Mar 2011 18:41:43 -0000
@@ -10,4 +10,7 @@ SPECIAL ldd   keepsymbols     _rtld_default_pa
 SPECIAL ldd    keepsymbols     _rtld_xforms _rtld_objmain
 SPECIAL ldd    keepsymbols     _rtld_objtail _rtld_objlist
 SPECIAL ldd    keepsymbols     _rtld_objcount _rtld_objloads
+SPECIAL ldd    keepsymbols     _rtld_shared_enter _rtld_shared_exit
+SPECIAL ldd    keepsymbols     _rtld_exclusive_enter _rtld_exclusive_exit
+
 SPECIAL ldd    keepsymbols     print_needed main_local main_progname
Index: usr.bin/ldd/ldd.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/usr.bin/ldd/ldd.c,v
retrieving revision 1.16
diff -u -p -r1.16 ldd.c
--- usr.bin/ldd/ldd.c   9 Mar 2011 23:10:08 -0000       1.16
+++ usr.bin/ldd/ldd.c   13 Mar 2011 18:41:59 -0000
@@ -313,3 +313,23 @@ _rtld_die(void)
                msg = "Fatal error";
        xerrx(1, "%s", msg);
 }
+
+void
+_rtld_shared_enter(void)
+{
+}
+
+void
+_rtld_shared_exit(void)
+{
+}
+
+void
+_rtld_exclusive_enter(void)
+{
+}
+
+void
+_rtld_exclusive_exit(void)
+{
+}


Home | Main Index | Thread Index | Old Index