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.
This commit is contained in:
Ulrich Drepper 2005-01-09 08:29:25 +00:00
parent 4e2d549137
commit 29f976542b
7 changed files with 58 additions and 30 deletions

View file

@ -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

View file

@ -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. */

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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 ();

View file

@ -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. */