]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 13 Feb 2002 09:38:39 +0000 (09:38 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 13 Feb 2002 09:38:39 +0000 (09:38 +0000)
2002-02-13  Ulrich Drepper  <drepper@redhat.com>

* elf/dl-close.c (_dl_close): Implement freeing entries in the
slotinfo array.
(free_mem): Free memory for the slotinfo array if possible.

ChangeLog
csu/gmon-start.c
elf/dl-close.c

index 99727733ebd3f1eb36ff9ba837dba5581246482f..bcc868fff832a999f4b4401ab485e11f6e4fbbc0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2002-02-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-close.c (_dl_close): Implement freeing entries in the
+       slotinfo array.
+       (free_mem): Free memory for the slotinfo array if possible.
+
 2002-02-12  Andreas Schwab  <schwab@suse.de>
 
        * csu/gmon-start.c (__gmon_start__): Remove '&' from ENTRY_POINT.
index 1aaeefcf7fac6e00cd3c694c5b71596ca044f53d..9ee722aa0f9c2c538be7114b62b994550193fe02 100644 (file)
@@ -1,5 +1,5 @@
 /* Code to enable profiling at program startup.
-   Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1995,1996,1997,2000,2001,2002 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
@@ -63,7 +63,11 @@ __gmon_start__ (void)
 #endif
 
   /* Start keeping profiling records.  */
+#ifdef ENTRY_POINT_DECL
   __monstartup ((u_long) ENTRY_POINT, (u_long) &etext);
+#else
+  __monstartup ((u_long) &ENTRY_POINT, (u_long) &etext);
+#endif
 
   /* Call _mcleanup before exiting; it will write out gmon.out from the
      collected data.  */
index 65de9e7809b0dd993807bb3d2059aed3beec0106..5c7e5dad3837507ce9254ef5acf64dbaa8567ecd 100644 (file)
@@ -46,6 +46,9 @@ _dl_close (void *_map)
   struct link_map *map = _map;
   unsigned int i;
   unsigned int *new_opencount;
+#ifdef USE_TLS
+  bool any_tls = false;
+#endif
 
   /* First see whether we can remove the object at all.  */
   if (__builtin_expect (map->l_flags_1 & DF_1_NODELETE, 0)
@@ -206,6 +209,28 @@ _dl_close (void *_map)
              --GL(dl_main_searchlist)->r_nlist;
            }
 
+#ifdef USE_TLS
+         /* Remove the object from the dtv slotinfo array if it uses
+            TLS.  */
+         if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
+           {
+             /* Locate the entry in the slotinfo array.  */
+             size_t idx = imap->l_tls_modid;
+             struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
+
+             while (idx >= listp->len)
+               {
+                 idx -= listp->len;
+                 listp = listp->next;
+               }
+
+             listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
+             listp->slotinfo[idx].map = NULL;
+
+             any_tls = true;
+           }
+#endif
+
          /* We can unmap all the maps at once.  We determined the
             start address and length when we loaded the object and
             the `munmap' call does the rest.  */
@@ -279,6 +304,12 @@ _dl_close (void *_map)
        }
     }
 
+#ifdef USE_TLS
+  /* If we removed any object which uses TLS bumnp the generation
+     counter.  */
+  ++GL(dl_tls_generation);
+#endif
+
   /* Notify the debugger those objects are finalized and gone.  */
   _r_debug.r_state = RT_CONSISTENT;
   _dl_debug_state ();
@@ -302,6 +333,30 @@ _dl_close (void *_map)
 }
 
 
+static bool
+free_slotinfo (struct dtv_slotinfo_list *elemp)
+{
+  size_t cnt;
+
+  if (elemp->next != NULL && !free_slotinfo (elemp->next))
+    /* We cannot free the entry.  */
+    return false;
+
+  /* The least we could do is remove next element (if there was any).  */
+  elemp->next = NULL;
+
+  for (cnt = 0; cnt < elemp->len; ++cnt)
+    if (elemp->slotinfo[cnt].map != NULL)
+      /* Still used.  */
+      return false;
+
+  /* We can remove the list element.  */
+  free (elemp);
+
+  return true;
+}
+
+
 static void
 free_mem (void)
 {
@@ -320,5 +375,15 @@ free_mem (void)
       /* Now free the old map.  */
       free (old);
     }
+
+#ifdef USE_TLS
+  /* Free the memory allocated for the dtv slotinfo array.  We can do
+     this only if all modules which used this memory are unloaded.
+     Also, the first element of the list does not have to be
+     deallocated.  It was allocated in the dynamic linker (i.e., with
+     a different malloc).  */
+  if (free_slotinfo (GL(dl_tls_dtv_slotinfo_list)->next))
+    GL(dl_tls_dtv_slotinfo_list)->next = NULL;
+#endif
 }
 text_set_element (__libc_subfreeres, free_mem);