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)
{
}