about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--elf/dl-close.c13
-rw-r--r--elf/dl-debug.c25
-rw-r--r--elf/dl-load.c7
-rw-r--r--elf/dl-open.c18
-rw-r--r--elf/rtld.c5
-rw-r--r--sysdeps/generic/ldsodefs.h4
7 files changed, 58 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 562dd67d0e..bd563f9aa4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.  */