about summary refs log tree commit diff
path: root/elf/dl-fini.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-01-06 22:40:27 +0000
committerUlrich Drepper <drepper@redhat.com>2005-01-06 22:40:27 +0000
commit9dcafc559763e339d4a79580c333127033e39c11 (patch)
tree342441fed429693bc69d95addc588e10a7d021c4 /elf/dl-fini.c
parentf14038f2e295e7994e2317127cdea1cb26db6be1 (diff)
downloadglibc-9dcafc559763e339d4a79580c333127033e39c11.tar.gz
glibc-9dcafc559763e339d4a79580c333127033e39c11.tar.xz
glibc-9dcafc559763e339d4a79580c333127033e39c11.zip
* csu/elf-init.c (__libc_csu_fini): Don't do anything here.
* sysdeps/generic/libc-start.c: Don't register program destructor here.
	* dlfcn/Makefile: Add rules to build dlfcn.c.
	(LDFLAGS-dl.so): Removed.
	* dlfcn/dlclose.c: _dl_close is now in ld.so, use function pointer
	table.
	* dlfcn/dlmopen.c: Likewise for _dl_open.
	* dlfcn/dlopen.c: Likewise.
	* dlfcn/dlopenold.c: Likewise.
	* elf/dl-libc.c: Likewise for _dl_open and _dl_close.
	* elf/Makefile (routines): Remove dl-open and dl-close.
	(dl-routines): Add dl-open, dl-close, and dl-trampoline.
	Add rules to build and run tst-audit1.
	* elf/tst-audit1.c: New file.
	* elf/tst-auditmod1.c: New file.
	* elf/Versions [libc]: Remove _dl_open and _dl_close.
	* elf/dl-close.c: Change for use inside ld.so instead of libc.so.
	* elf/dl-open.c: Likewise.
	* elf/dl-debug.c (_dl_debug_initialize): Allow reinitialization,
	signaled by nonzero parameter.
	* elf/dl-init.c: Fix use of r_state.
	* elf/dl-load.c: Likewise.

	* elf/dl-close.c: Add auditing checkpoints.
	* elf/dl-open.c: Likewise.
	* elf/dl-fini.c: Likewise.
	* elf/dl-load.c: Likewise.
	* elf/dl-sym.c: Likewise.
	* sysdeps/generic/libc-start.c: Likewise.
	* elf/dl-object.c: Allocate memory for auditing information.
	* elf/dl-reloc.c: Remove RESOLV.  We now always need the map.
	Correctly initialize slotinfo.
	* elf/dynamic-link.h: Adjust after removal of RESOLV.
	* sysdeps/hppa/dl-lookupcfg.h: Likewise.
	* sysdeps/ia64/dl-lookupcfg.h: Likewise.
	* sysdeps/powerpc/powerpc64/dl-lookupcfg.h: Removed.
	* elf/dl-runtime.c (_dl_fixup): Little cleanup.
	(_dl_profile_fixup): New parameters to point to register struct and
	variable for frame size.
	Add auditing checkpoints.
	(_dl_call_pltexit): New function.
	Don't define trampoline code here.
	* elf/rtld.c: Recognize LD_AUDIT.  Load modules on startup.
	Remove all the functions from _rtld_global_ro which only _dl_open
	and _dl_close needed.
	Add auditing checkpoints.
	* elf/link.h: Define symbols for auditing interfaces.
	* include/link.h: Likewise.
	* include/dlfcn.h: Define __RTLD_AUDIT.
	Remove prototypes for _dl_open and _dl_close.
	Adjust access to argc and argv in libdl.
	* dlfcn/dlfcn.c: New file.
	* sysdeps/generic/dl-lookupcfg.h: Remove all content now that RESOLVE
	is gone.
	* sysdeps/generic/ldsodefs.h: Add definitions for auditing interfaces.
	* sysdeps/generic/unsecvars.h: Add LD_AUDIT.
	* sysdeps/i386/dl-machine.h: Remove trampoline code here.
	Adjust for removal of RESOLVE.
	* sysdeps/x86_64/dl-machine.h: Likewise.
	* sysdeps/generic/dl-trampoline.c: New file.
	* sysdeps/i386/dl-trampoline.c: New file.
	* sysdeps/x86_64/dl-trampoline.c: New file.

	* sysdeps/generic/dl-tls.c: Cleanups.  Fixup for dtv_t change.
	Fix updating of DTV.
	* sysdeps/generic/libc-tls.c: Likewise.

	* sysdeps/arm/bits/link.h: Renamed to ...
	* sysdeps/arm/buts/linkmap.h: ...this.
	* sysdeps/generic/bits/link.h: Renamed to...
	* sysdeps/generic/bits/linkmap.h: ...this.
	* sysdeps/hppa/bits/link.h: Renamed to...
	* sysdeps/hppa/bits/linkmap.h: ...this.
	* sysdeps/hppa/i386/link.h: Renamed to...
	* sysdeps/hppa/i386/linkmap.h: ...this.
	* sysdeps/hppa/ia64/link.h: Renamed to...
	* sysdeps/hppa/ia64/linkmap.h: ...this.
	* sysdeps/hppa/s390/link.h: Renamed to...
	* sysdeps/hppa/s390/linkmap.h: ...this.
	* sysdeps/hppa/sh/link.h: Renamed to...
	* sysdeps/hppa/sh/linkmap.h: ...this.
	* sysdeps/hppa/x86_64/link.h: Renamed to...
	* sysdeps/hppa/x86_64/linkmap.h: ...this.
2005-01-06  Ulrich Drepper  <drepper@redhat.com>

	* allocatestack.c (init_one_static_tls): Adjust initialization of DTV
	entry for static tls deallocation fix.
	* sysdeps/alpha/tls.h (dtv_t): Change pointer type to be struct which
	also contains information whether the memory pointed to is static
	TLS or not.
	* sysdeps/i386/tls.h: Likewise.
	* sysdeps/ia64/tls.h: Likewise.
	* sysdeps/powerpc/tls.h: Likewise.
	* sysdeps/s390/tls.h: Likewise.
	* sysdeps/sh/tls.h: Likewise.
	* sysdeps/sparc/tls.h: Likewise.
	* sysdeps/x86_64/tls.h: Likewise.
Diffstat (limited to 'elf/dl-fini.c')
-rw-r--r--elf/dl-fini.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index f43f4a00ed..8fc5dbf123 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -53,7 +53,12 @@ _dl_fini (void)
       /* Protect against concurrent loads and unloads.  */
       __rtld_lock_lock_recursive (GL(dl_load_lock));
 
+      unsigned int nmaps = 0;
       unsigned int nloaded = GL(dl_ns)[cnt]._ns_nloaded;
+      /* No need to do anything for empty namespaces or those used for
+	 auditing DSOs.  */
+      if (nloaded == 0 || GL(dl_ns)[cnt]._ns_loaded->l_auditing)
+	goto out;
 
       /* XXX Could it be (in static binaries) that there is no object
 	 loaded?  */
@@ -76,6 +81,7 @@ _dl_fini (void)
 
       unsigned int i;
       struct link_map *l;
+      assert (nloaded != 0 || GL(dl_ns)[cnt]._ns_loaded == NULL);
       for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
 	/* Do not handle ld.so in secondary namespaces.  */
 	if (l == l->l_real)
@@ -90,7 +96,7 @@ _dl_fini (void)
 	  }
       assert (cnt != LM_ID_BASE || i == nloaded);
       assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
-      unsigned int nmaps = i;
+      nmaps = i;
 
       if (nmaps != 0)
 	{
@@ -163,6 +169,7 @@ _dl_fini (void)
 	 high and will be decremented in this loop.  So we release the
 	 lock so that some code which might be called from a destructor
 	 can directly or indirectly access the lock.  */
+    out:
       __rtld_lock_unlock_recursive (GL(dl_load_lock));
 
       /* 'maps' now contains the objects in the right order.  Now call the
@@ -176,38 +183,49 @@ _dl_fini (void)
 	      /* Make sure nothing happens if we are called twice.  */
 	      l->l_init_called = 0;
 
-	      /* Don't call the destructors for objects we are not
-		 supposed to.  */
-	      if (l->l_name[0] == '\0' && l->l_type == lt_executable)
-		continue;
-
 	      /* Is there a destructor function?  */
-	      if (l->l_info[DT_FINI_ARRAY] == NULL
-		  && l->l_info[DT_FINI] == NULL)
-		continue;
-
-	      /* When debugging print a message first.  */
-	      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
-				    0))
-		_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
-				  l->l_name[0] ? l->l_name : rtld_progname,
-				  cnt);
-
-	      /* First see whether an array is given.  */
-	      if (l->l_info[DT_FINI_ARRAY] != NULL)
+	      if (l->l_info[DT_FINI_ARRAY] != NULL
+		  || l->l_info[DT_FINI] != NULL)
 		{
-		  ElfW(Addr) *array =
-		    (ElfW(Addr) *) (l->l_addr
-				    + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
-		  unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
-				    / sizeof (ElfW(Addr)));
-		  while (i-- > 0)
-		    ((fini_t) array[i]) ();
+		  /* When debugging print a message first.  */
+		  if (__builtin_expect (GLRO(dl_debug_mask)
+					& DL_DEBUG_IMPCALLS, 0))
+		    _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+				      l->l_name[0] ? l->l_name : rtld_progname,
+				      cnt);
+
+		  /* First see whether an array is given.  */
+		  if (l->l_info[DT_FINI_ARRAY] != NULL)
+		    {
+		      ElfW(Addr) *array =
+			(ElfW(Addr) *) (l->l_addr
+					+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
+		      unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
+					/ sizeof (ElfW(Addr)));
+		      while (i-- > 0)
+			((fini_t) array[i]) ();
+		    }
+
+		  /* Next try the old-style destructor.  */
+		  if (l->l_info[DT_FINI] != NULL)
+		    ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
 		}
 
-	      /* Next try the old-style destructor.  */
-	      if (l->l_info[DT_FINI] != NULL)
-		((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
+#ifdef SHARED
+	      /* Auditing checkpoint: another object closed.  */
+	      if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+		{
+		  struct audit_ifaces *afct = GLRO(dl_audit);
+		  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+		    {
+		      if (afct->objclose != NULL)
+			/* Return value is ignored.  */
+			(void) afct->objclose (&l->l_audit[cnt].cookie);
+
+		      afct = afct->next;
+		    }
+		}
+#endif
 	    }
 
 	  /* Correct the previous increment.  */