Module Name: src Committed By: joerg Date: Tue Mar 29 20:56:35 UTC 2011
Modified Files: src/libexec/ld.elf_so: rtld.c rtld.h tls.c src/usr.bin/ldd: ldd.c Log Message: Block signals when using the exclusive lock. To generate a diff of this commit: cvs rdiff -u -r1.147 -r1.148 src/libexec/ld.elf_so/rtld.c cvs rdiff -u -r1.104 -r1.105 src/libexec/ld.elf_so/rtld.h cvs rdiff -u -r1.4 -r1.5 src/libexec/ld.elf_so/tls.c cvs rdiff -u -r1.17 -r1.18 src/usr.bin/ldd/ldd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/ld.elf_so/rtld.c diff -u src/libexec/ld.elf_so/rtld.c:1.147 src/libexec/ld.elf_so/rtld.c:1.148 --- src/libexec/ld.elf_so/rtld.c:1.147 Mon Mar 28 00:37:40 2011 +++ src/libexec/ld.elf_so/rtld.c Tue Mar 29 20:56:35 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.c,v 1.147 2011/03/28 00:37:40 joerg Exp $ */ +/* $NetBSD: rtld.c,v 1.148 2011/03/29 20:56:35 joerg Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -40,7 +40,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: rtld.c,v 1.147 2011/03/28 00:37:40 joerg Exp $"); +__RCSID("$NetBSD: rtld.c,v 1.148 2011/03/29 20:56:35 joerg Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -121,8 +121,8 @@ #endif /* RTLD_DEBUG */ extern Elf_Dyn _DYNAMIC; -static void _rtld_call_fini_functions(int); -static void _rtld_call_init_functions(void); +static void _rtld_call_fini_functions(sigset_t *, int); +static void _rtld_call_init_functions(sigset_t *); static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int); static void _rtld_initlist_tsort(Objlist *, int); static Obj_Entry *_rtld_dlcheck(void *); @@ -130,12 +130,12 @@ static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *); static void _rtld_objlist_remove(Objlist *, Obj_Entry *); static void _rtld_objlist_clear(Objlist *); -static void _rtld_unload_object(Obj_Entry *, bool); +static void _rtld_unload_object(sigset_t *, Obj_Entry *, bool); static void _rtld_unref_dag(Obj_Entry *); static Obj_Entry *_rtld_obj_from_addr(const void *); static void -_rtld_call_fini_functions(int force) +_rtld_call_fini_functions(sigset_t *mask, int force) { Objlist_Entry *elm; Objlist finilist; @@ -168,9 +168,9 @@ * XXX the fini() call is done. */ fini = obj->fini; - _rtld_exclusive_exit(); + _rtld_exclusive_exit(mask); (*fini)(); - _rtld_exclusive_enter(); + _rtld_exclusive_enter(mask); if (_rtld_objgen != cur_objgen) { dbg(("restarting fini iteration")); _rtld_objlist_clear(&finilist); @@ -192,9 +192,9 @@ obj->fini_called = 1; /* XXX See above for the race condition here */ fini = obj->fini; - _rtld_exclusive_exit(); + _rtld_exclusive_exit(mask); (*fini)(); - _rtld_exclusive_enter(); + _rtld_exclusive_enter(mask); if (_rtld_objgen != cur_objgen) { dbg(("restarting fini iteration")); _rtld_objlist_clear(&finilist); @@ -206,7 +206,7 @@ } static void -_rtld_call_init_functions() +_rtld_call_init_functions(sigset_t *mask) { Objlist_Entry *elm; Objlist initlist; @@ -231,9 +231,9 @@ obj->path, (void *)obj->init)); obj->init_called = 1; init = obj->init; - _rtld_exclusive_exit(); + _rtld_exclusive_exit(mask); (*init)(); - _rtld_exclusive_enter(); + _rtld_exclusive_enter(mask); if (_rtld_objgen != cur_objgen) { dbg(("restarting init iteration")); _rtld_objlist_clear(&initlist); @@ -251,9 +251,9 @@ (void *)obj->init)); obj->init_called = 1; init = obj->init; - _rtld_exclusive_exit(); + _rtld_exclusive_exit(mask); (*init)(); - _rtld_exclusive_enter(); + _rtld_exclusive_enter(mask); if (_rtld_objgen != cur_objgen) { dbg(("restarting init iteration")); _rtld_objlist_clear(&initlist); @@ -338,13 +338,15 @@ static void _rtld_exit(void) { + sigset_t mask; + dbg(("rtld_exit()")); - _rtld_exclusive_enter(); + _rtld_exclusive_enter(&mask); - _rtld_call_fini_functions(1); + _rtld_call_fini_functions(&mask, 1); - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); } /* @@ -383,6 +385,7 @@ const char **real___progname; const Obj_Entry **real___mainprog_obj; char ***real_environ; + sigset_t mask; #ifdef DEBUG const char *ld_debug; #endif @@ -675,15 +678,15 @@ if (real___mainprog_obj) *real___mainprog_obj = _rtld_objmain; - _rtld_exclusive_enter(); + _rtld_exclusive_enter(&mask); dbg(("calling _init functions")); - _rtld_call_init_functions(); + _rtld_call_init_functions(&mask); dbg(("control at program entry point = %p, obj = %p, exit = %p", _rtld_objmain->entry, _rtld_objmain, _rtld_exit)); - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); /* * Return with the entry point and the exit procedure in at the top @@ -792,7 +795,7 @@ * Note, this is called only for objects loaded by dlopen(). */ static void -_rtld_unload_object(Obj_Entry *root, bool do_fini_funcs) +_rtld_unload_object(sigset_t *mask, Obj_Entry *root, bool do_fini_funcs) { _rtld_unref_dag(root); @@ -803,7 +806,7 @@ /* Finalize objects that are about to be unmapped. */ if (do_fini_funcs) - _rtld_call_fini_functions(0); + _rtld_call_fini_functions(mask, 0); /* Remove the DAG from all objects' DAG lists. */ SIMPLEQ_FOREACH(elm, &root->dagmembers, link) @@ -880,15 +883,16 @@ dlclose(void *handle) { Obj_Entry *root; + sigset_t mask; dbg(("dlclose of %p", handle)); - _rtld_exclusive_enter(); + _rtld_exclusive_enter(&mask); root = _rtld_dlcheck(handle); if (root == NULL) { - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); return -1; } @@ -896,12 +900,12 @@ _rtld_debug_state(); --root->dl_refcount; - _rtld_unload_object(root, true); + _rtld_unload_object(&mask, root, true); _rtld_debug.r_state = RT_CONSISTENT; _rtld_debug_state(); - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); return 0; } @@ -925,10 +929,11 @@ int flags = _RTLD_DLOPEN; bool nodelete; bool now; + sigset_t mask; dbg(("dlopen of %s %d", name, mode)); - _rtld_exclusive_enter(); + _rtld_exclusive_enter(&mask); flags |= (mode & RTLD_GLOBAL) ? _RTLD_GLOBAL : 0; flags |= (mode & RTLD_NOLOAD) ? _RTLD_NOLOAD : 0; @@ -955,11 +960,11 @@ (_rtld_init_dag(obj), _rtld_relocate_objects(obj, (now || obj->z_now))) == -1) { - _rtld_unload_object(obj, false); + _rtld_unload_object(&mask, obj, false); obj->dl_refcount--; obj = NULL; } else { - _rtld_call_init_functions(); + _rtld_call_init_functions(&mask); } } if (obj != NULL) { @@ -973,7 +978,7 @@ _rtld_debug.r_state = RT_CONSISTENT; _rtld_debug_state(); - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); return obj; } @@ -1010,8 +1015,8 @@ #endif #ifdef __HAVE_FUNCTION_DESCRIPTORS -#define lookup_mutex_enter() _rtld_exclusive_enter() -#define lookup_mutex_exit() _rtld_exclusive_exit() +#define lookup_mutex_enter() _rtld_exclusive_enter(&mask) +#define lookup_mutex_exit() _rtld_exclusive_exit(&mask) #else #define lookup_mutex_enter() _rtld_shared_enter() #define lookup_mutex_exit() _rtld_shared_exit() @@ -1026,7 +1031,10 @@ const Elf_Sym *def; const Obj_Entry *defobj; void *retaddr; - DoneList donelist; + DoneList donelist; +#ifdef __HAVE_FUNCTION_DESCRIPTORS + sigset_t mask; +#endif dbg(("dlsym of %s in %p", name, handle)); @@ -1471,11 +1479,15 @@ } void -_rtld_exclusive_enter(void) +_rtld_exclusive_enter(sigset_t *mask) { lwpid_t waiter, self = _lwp_self(); unsigned int locked_value = (unsigned int)self | RTLD_EXCLUSIVE_MASK; unsigned int cur; + sigset_t blockmask; + + sigfillset(&blockmask); + sigprocmask(SIG_BLOCK, &blockmask, mask); membar_enter(); @@ -1497,7 +1509,7 @@ } void -_rtld_exclusive_exit(void) +_rtld_exclusive_exit(sigset_t *mask) { lwpid_t waiter; @@ -1509,4 +1521,5 @@ _lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex)); membar_exit(); + sigprocmask(SIG_SETMASK, mask, NULL); } Index: src/libexec/ld.elf_so/rtld.h diff -u src/libexec/ld.elf_so/rtld.h:1.104 src/libexec/ld.elf_so/rtld.h:1.105 --- src/libexec/ld.elf_so/rtld.h:1.104 Fri Mar 25 18:07:04 2011 +++ src/libexec/ld.elf_so/rtld.h Tue Mar 29 20:56:35 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.h,v 1.104 2011/03/25 18:07:04 joerg Exp $ */ +/* $NetBSD: rtld.h,v 1.105 2011/03/29 20:56:35 joerg Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -35,6 +35,7 @@ #define RTLD_H #include <dlfcn.h> +#include <signal.h> #include <stdbool.h> #include <stddef.h> #include <sys/param.h> @@ -314,8 +315,8 @@ void _rtld_shared_enter(void); void _rtld_shared_exit(void); -void _rtld_exclusive_enter(void); -void _rtld_exclusive_exit(void); +void _rtld_exclusive_enter(sigset_t *); +void _rtld_exclusive_exit(sigset_t *); /* expand.c */ size_t _rtld_expand_path(char *, size_t, const char *, const char *,\ Index: src/libexec/ld.elf_so/tls.c diff -u src/libexec/ld.elf_so/tls.c:1.4 src/libexec/ld.elf_so/tls.c:1.5 --- src/libexec/ld.elf_so/tls.c:1.4 Fri Mar 25 18:07:04 2011 +++ src/libexec/ld.elf_so/tls.c Tue Mar 29 20:56:35 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: tls.c,v 1.4 2011/03/25 18:07:04 joerg Exp $ */ +/* $NetBSD: tls.c,v 1.5 2011/03/29 20:56:35 joerg Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: tls.c,v 1.4 2011/03/25 18:07:04 joerg Exp $"); +__RCSID("$NetBSD: tls.c,v 1.5 2011/03/29 20:56:35 joerg Exp $"); #include <sys/param.h> #include <sys/ucontext.h> @@ -60,8 +60,9 @@ { struct tls_tcb *tcb = tls; void **dtv, **new_dtv; + sigset_t mask; - _rtld_exclusive_enter(); + _rtld_exclusive_enter(&mask); dtv = tcb->tcb_dtv; @@ -82,7 +83,7 @@ if (__predict_false(dtv[idx] == NULL)) dtv[idx] = _rtld_tls_module_allocate(idx); - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); return (uint8_t *)dtv[idx] + offset; } @@ -148,10 +149,11 @@ _rtld_tls_allocate(void) { struct tls_tcb *tcb; + sigset_t mask; - _rtld_exclusive_enter(); + _rtld_exclusive_enter(&mask); tcb = _rtld_tls_allocate_locked(); - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); return tcb; } @@ -161,8 +163,9 @@ { size_t i, max_index; uint8_t *p; + sigset_t mask; - _rtld_exclusive_enter(); + _rtld_exclusive_enter(&mask); max_index = DTV_MAX_INDEX(tcb->tcb_dtv); for (i = 1; i <= max_index; ++i) @@ -176,7 +179,7 @@ #endif xfree(p); - _rtld_exclusive_exit(); + _rtld_exclusive_exit(&mask); } void * Index: src/usr.bin/ldd/ldd.c diff -u src/usr.bin/ldd/ldd.c:1.17 src/usr.bin/ldd/ldd.c:1.18 --- src/usr.bin/ldd/ldd.c:1.17 Fri Mar 25 18:07:07 2011 +++ src/usr.bin/ldd/ldd.c Tue Mar 29 20:56:35 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ldd.c,v 1.17 2011/03/25 18:07:07 joerg Exp $ */ +/* $NetBSD: ldd.c,v 1.18 2011/03/29 20:56:35 joerg Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ldd.c,v 1.17 2011/03/25 18:07:07 joerg Exp $"); +__RCSID("$NetBSD: ldd.c,v 1.18 2011/03/29 20:56:35 joerg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -325,11 +325,11 @@ } void -_rtld_exclusive_enter(void) +_rtld_exclusive_enter(sigset_t *mask) { } void -_rtld_exclusive_exit(void) +_rtld_exclusive_exit(sigset_t *mask) { }