diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | elf/dl-close.c | 13 | ||||
-rw-r--r-- | elf/dl-debug.c | 25 | ||||
-rw-r--r-- | elf/dl-load.c | 7 | ||||
-rw-r--r-- | elf/dl-open.c | 18 | ||||
-rw-r--r-- | elf/rtld.c | 5 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 4 |
7 files changed, 58 insertions, 30 deletions
@@ -1,3 +1,19 @@ +2005-01-09 Ulrich Drepper <drepper@redhat.com> + + * elf/dl-debug.c (_dl_debug_initialize): Take extra parameter and + use it to select the r_debug structure for that namespace. + * elf/dl-close.c (_dl_close): Adjust call to _dl_debug_initialize. + * elf/dl-load.c (_dl_map_object_from_fd): Likewise. + * elf/dl-open.c (_dl_open): Likewise. + * elf/rtld.c (dl_main): Likewise. + * sysdeps/generic/ldsodefs.h (struct link_namespaces): Add _ns_debug + member. + (_dl_debug_initialize): Add new parameter in declaration. + + * elf/dl-close.c (_dl_close): Make sure auditing callbacks are not + called for the auditing objects themselves. + * elf/dl-load.c (_dl_map_object_from_fd): Likewise. + 2005-01-07 Ulrich Drepper <drepper@redhat.com> * sysdeps/powerpc/powerpc64/dl-machine.h diff --git a/elf/dl-close.c b/elf/dl-close.c index cf926ae566..eb5e805dd4 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -1,5 +1,5 @@ /* Close a shared object opened by `_dl_open'. - Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -266,6 +266,9 @@ _dl_close (void *_map) assert (new_opencount[0] == 0); /* Call all termination functions at once. */ +#ifdef SHARED + bool do_audit = GLRO(dl_naudit) > 0 && !GL(dl_ns)[ns]._ns_loaded->l_auditing; +#endif for (i = 0; list[i] != NULL; ++i) { struct link_map *imap = list[i]; @@ -306,7 +309,7 @@ _dl_close (void *_map) #ifdef SHARED /* Auditing checkpoint: we have a new object. */ - if (__builtin_expect (GLRO(dl_naudit) > 0, 0)) + if (__builtin_expect (do_audit, 0)) { struct audit_ifaces *afct = GLRO(dl_audit); for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) @@ -388,7 +391,7 @@ _dl_close (void *_map) #ifdef SHARED /* Auditing checkpoint: we will start deleting objects. */ - if (__builtin_expect (GLRO(dl_naudit) > 0, 0)) + if (__builtin_expect (do_audit, 0)) { struct link_map *head = GL(dl_ns)[ns]._ns_loaded; struct audit_ifaces *afct = GLRO(dl_audit); @@ -407,7 +410,7 @@ _dl_close (void *_map) #endif /* Notify the debugger we are about to remove some loaded objects. */ - struct r_debug *r = _dl_debug_initialize (0); + struct r_debug *r = _dl_debug_initialize (0, ns); r->r_state = RT_DELETE; _dl_debug_state (); @@ -629,7 +632,7 @@ _dl_close (void *_map) #ifdef SHARED /* Auditing checkpoint: we have deleted all objects. */ - if (__builtin_expect (GLRO(dl_naudit) > 0, 0)) + if (__builtin_expect (do_audit, 0)) { struct link_map *head = GL(dl_ns)[ns]._ns_loaded; /* Do not call the functions for any auditing object. */ diff --git a/elf/dl-debug.c b/elf/dl-debug.c index 39234720b0..bc7d793435 100644 --- a/elf/dl-debug.c +++ b/elf/dl-debug.c @@ -1,5 +1,5 @@ /* Communicate dynamic linker state to the debugger at runtime. - Copyright (C) 1996, 1998, 2000, 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1996, 1998,2000,2002,2004,2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,20 +32,25 @@ struct r_debug _r_debug; struct r_debug * internal_function -_dl_debug_initialize (ElfW(Addr) ldbase) +_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) { - if (_r_debug.r_brk == 0 || ldbase != 0) + struct r_debug *r; + + if (ns == LM_ID_BASE) + r = &_r_debug; + else + r = &GL(dl_ns)[ns]._ns_debug; + + if (r->r_brk == 0 || ldbase != 0) { /* Tell the debugger where to find the map of loaded objects. */ - _r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; - _r_debug.r_ldbase = ldbase; - // XXX This is problematic. It means we cannot tell the debugger - // XXX about namespaces other than the main one. - _r_debug.r_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state; + r->r_version = 1 /* R_DEBUG_VERSION XXX */; + r->r_ldbase = ldbase ?: _r_debug.r_ldbase; + r->r_map = GL(dl_ns)[ns]._ns_loaded; + r->r_brk = (ElfW(Addr)) &_dl_debug_state; } - return &_r_debug; + return r; } diff --git a/elf/dl-load.c b/elf/dl-load.c index 7f11b62bf4..363f77bcdf 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1,5 +1,5 @@ /* Map in a shared object's segments from the file. - Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -827,7 +827,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, /* Initialize to keep the compiler happy. */ const char *errstring = NULL; int errval = 0; - struct r_debug *r = _dl_debug_initialize (0); + struct r_debug *r = _dl_debug_initialize (0, nsid); bool make_consistent = false; /* Get file information. */ @@ -1467,7 +1467,8 @@ cannot enable executable stack as shared object requires"); #ifdef SHARED /* Auditing checkpoint: we have a new object. */ - if (__builtin_expect (GLRO(dl_naudit) > 0, 0)) + if (__builtin_expect (GLRO(dl_naudit) > 0, 0) + && !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) { struct audit_ifaces *afct = GLRO(dl_audit); for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) diff --git a/elf/dl-open.c b/elf/dl-open.c index 9da7523dc1..c2cf1dbf13 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -1,5 +1,5 @@ /* Load a shared object at runtime, relocate it, and run its initializer. - Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1996-2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -174,8 +174,6 @@ dl_open_worker (void *a) #endif struct link_map *call_map = NULL; - assert (_dl_debug_initialize (0)->r_state == RT_CONSISTENT); - /* Check whether _dl_open() has been called from a valid DSO. */ if (__check_caller (args->caller_dl_open, allow_libc|allow_libdl|allow_ldso) != 0) @@ -220,6 +218,8 @@ dl_open_worker (void *a) } } + assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + /* Maybe we have to expand a DST. */ if (__builtin_expect (dst != NULL, 0)) { @@ -298,7 +298,7 @@ dl_open_worker (void *a) /* Increment just the reference counter of the object. */ ++new->l_opencount; - assert (_dl_debug_initialize (0)->r_state == RT_CONSISTENT); + assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); return; } @@ -338,7 +338,7 @@ dl_open_worker (void *a) #endif /* Notify the debugger all new objects are now ready to go. */ - struct r_debug *r = _dl_debug_initialize (0); + struct r_debug *r = _dl_debug_initialize (0, args->nsid); r->r_state = RT_CONSISTENT; _dl_debug_state (); @@ -525,8 +525,6 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, /* Make sure we are alone. */ __rtld_lock_lock_recursive (GL(dl_load_lock)); - assert (_dl_debug_initialize (0)->r_state == RT_CONSISTENT); - if (nsid == LM_ID_NEWLM) { /* Find a new namespace. */ @@ -542,6 +540,8 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, _dl_signal_error (EINVAL, file, NULL, N_("\ no more namespaces available for dlmopen()")); } + + _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT; } /* Never allow loading a DSO in a namespace which is empty. Such direct placements is only causing problems. Also don't allow @@ -621,13 +621,13 @@ no more namespaces available for dlmopen()")); if (errstring != INTUSE(_dl_out_of_memory)) free ((char *) errstring); - assert (_dl_debug_initialize (0)->r_state == RT_CONSISTENT); + assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); /* Reraise the error. */ _dl_signal_error (errcode, objname, NULL, local_errstring); } - assert (_dl_debug_initialize (0)->r_state == RT_CONSISTENT); + assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); #ifndef SHARED DL_STATIC_INIT (args.map); diff --git a/elf/rtld.c b/elf/rtld.c index c9ed64a7a8..77903bfd09 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1208,7 +1208,8 @@ ld.so does not support TLS, but program uses it!\n"); _dl_init_paths (library_path); /* Initialize _r_debug. */ - struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr); + struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr, + LM_ID_BASE); r->r_state = RT_CONSISTENT; /* Put the link_map for ourselves on the chain so it can be found by @@ -2257,7 +2258,7 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n", /* Notify the debugger all new objects are now ready to go. We must re-get the address since by now the variable might be in another object. */ - r = _dl_debug_initialize (0); + r = _dl_debug_initialize (0, LM_ID_BASE); r->r_state = RT_CONSISTENT; _dl_debug_state (); diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 909f309e7f..7364f321de 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -296,6 +296,8 @@ struct rtld_global allocated by rtld. Later it keeps the size of the map. It might be reset if in _dl_close if the last global object is removed. */ size_t _ns_global_scope_alloc; + /* Keep track of changes to each namespace' list. */ + struct r_debug _ns_debug; } _dl_ns[DL_NNS]; /* During the program run we must not modify the global data of @@ -844,7 +846,7 @@ rtld_hidden_proto (_dl_debug_state) /* Initialize `struct r_debug' if it has not already been done. The argument is the run-time load address of the dynamic linker, to be put in the `r_ldbase' member. Returns the address of the structure. */ -extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase) +extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) internal_function; /* Initialize the basic data structure for the search paths. */ |