(_dl_close_worker): Renamed from _dl_close and split out locking and
[kopensolaris-gnu/glibc.git] / elf / dl-close.c
1 /* Close a shared object opened by `_dl_open'.
2    Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <assert.h>
21 #include <dlfcn.h>
22 #include <errno.h>
23 #include <libintl.h>
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <bits/libc-lock.h>
30 #include <ldsodefs.h>
31 #include <sys/types.h>
32 #include <sys/mman.h>
33 #include <sysdep-cancel.h>
34
35
36 /* Type of the constructor functions.  */
37 typedef void (*fini_t) (void);
38
39
40 /* Special l_idx value used to indicate which objects remain loaded.  */
41 #define IDX_STILL_USED -1
42
43
44 #ifdef USE_TLS
45 /* Returns true we an non-empty was found.  */
46 static bool
47 remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
48                  bool should_be_there)
49 {
50   if (idx - disp >= listp->len)
51     {
52       if (listp->next == NULL)
53         {
54           /* The index is not actually valid in the slotinfo list,
55              because this object was closed before it was fully set
56              up due to some error.  */
57           assert (! should_be_there);
58         }
59       else
60         {
61           if (remove_slotinfo (idx, listp->next, disp + listp->len,
62                                should_be_there))
63             return true;
64
65           /* No non-empty entry.  Search from the end of this element's
66              slotinfo array.  */
67           idx = disp + listp->len;
68         }
69     }
70   else
71     {
72       struct link_map *old_map = listp->slotinfo[idx - disp].map;
73
74       /* The entry might still be in its unused state if we are closing an
75          object that wasn't fully set up.  */
76       if (__builtin_expect (old_map != NULL, 1))
77         {
78           assert (old_map->l_tls_modid == idx);
79
80           /* Mark the entry as unused. */
81           listp->slotinfo[idx - disp].gen = GL(dl_tls_generation) + 1;
82           listp->slotinfo[idx - disp].map = NULL;
83         }
84
85       /* If this is not the last currently used entry no need to look
86          further.  */
87       if (idx != GL(dl_tls_max_dtv_idx))
88         return true;
89     }
90
91   while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0))
92     {
93       --idx;
94
95       if (listp->slotinfo[idx - disp].map != NULL)
96         {
97           /* Found a new last used index.  */
98           GL(dl_tls_max_dtv_idx) = idx;
99           return true;
100         }
101     }
102
103   /* No non-entry in this list element.  */
104   return false;
105 }
106 #endif
107
108
109 void
110 _dl_close_worker (struct link_map *map)
111 {
112   Lmid_t ns = map->l_ns;
113   unsigned int i;
114
115   /* Acquire the lock.  */
116   __rtld_lock_lock_recursive (GL(dl_load_lock));
117
118   /* One less direct use.  */
119   --map->l_direct_opencount;
120
121   /* If _dl_close is called recursively (some destructor call dlclose),
122      just record that the parent _dl_close will need to do garbage collection
123      again and return.  */
124   static enum { not_pending, pending, rerun } dl_close_state;
125
126   if (map->l_direct_opencount > 0 || map->l_type != lt_loaded
127       || dl_close_state != not_pending)
128     {
129       if (map->l_direct_opencount == 0 && map->l_type == lt_loaded)
130         dl_close_state = rerun;
131
132       /* There are still references to this object.  Do nothing more.  */
133       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
134         _dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
135                           map->l_name, map->l_direct_opencount);
136
137       return;
138     }
139
140  retry:
141   dl_close_state = pending;
142
143 #ifdef USE_TLS
144   bool any_tls = false;
145 #endif
146   const unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded;
147   char used[nloaded];
148   char done[nloaded];
149   struct link_map *maps[nloaded];
150
151   /* Run over the list and assign indexes to the link maps and enter
152      them into the MAPS array.  */
153   int idx = 0;
154   for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
155     {
156       l->l_idx = idx;
157       maps[idx] = l;
158       ++idx;
159     }
160   assert (idx == nloaded);
161
162   /* Prepare the bitmaps.  */
163   memset (used, '\0', sizeof (used));
164   memset (done, '\0', sizeof (done));
165
166   /* Keep track of the lowest index link map we have covered already.  */
167   int done_index = -1;
168   while (++done_index < nloaded)
169     {
170       struct link_map *l = maps[done_index];
171
172       if (done[done_index])
173         /* Already handled.  */
174         continue;
175
176       /* Check whether this object is still used.  */
177       if (l->l_type == lt_loaded
178           && l->l_direct_opencount == 0
179           && (l->l_flags_1 & DF_1_NODELETE) == 0
180           && !used[done_index])
181         continue;
182
183       /* We need this object and we handle it now.  */
184       done[done_index] = 1;
185       used[done_index] = 1;
186       /* Signal the object is still needed.  */
187       l->l_idx = IDX_STILL_USED;
188
189       /* Mark all dependencies as used.  */
190       if (l->l_initfini != NULL)
191         {
192           struct link_map **lp = &l->l_initfini[1];
193           while (*lp != NULL)
194             {
195               if ((*lp)->l_idx != IDX_STILL_USED)
196                 {
197                   assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded);
198
199                   if (!used[(*lp)->l_idx])
200                     {
201                       used[(*lp)->l_idx] = 1;
202                       if ((*lp)->l_idx - 1 < done_index)
203                         done_index = (*lp)->l_idx - 1;
204                     }
205                 }
206
207               ++lp;
208             }
209         }
210       /* And the same for relocation dependencies.  */
211       if (l->l_reldeps != NULL)
212         for (unsigned int j = 0; j < l->l_reldepsact; ++j)
213           {
214             struct link_map *jmap = l->l_reldeps[j];
215
216             if (jmap->l_idx != IDX_STILL_USED)
217               {
218                 assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded);
219
220                 if (!used[jmap->l_idx])
221                   {
222                     used[jmap->l_idx] = 1;
223                     if (jmap->l_idx - 1 < done_index)
224                       done_index = jmap->l_idx - 1;
225                   }
226               }
227           }
228     }
229
230   /* Sort the entries.  */
231   _dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nloaded, used, ns);
232
233   /* Call all termination functions at once.  */
234 #ifdef SHARED
235   bool do_audit = GLRO(dl_naudit) > 0 && !GL(dl_ns)[ns]._ns_loaded->l_auditing;
236 #endif
237   bool unload_any = false;
238   unsigned int first_loaded = ~0;
239   for (i = 0; i < nloaded; ++i)
240     {
241       struct link_map *imap = maps[i];
242
243       /* All elements must be in the same namespace.  */
244       assert (imap->l_ns == ns);
245
246       if (!used[i])
247         {
248           assert (imap->l_type == lt_loaded
249                   && (imap->l_flags_1 & DF_1_NODELETE) == 0);
250
251           /* Call its termination function.  Do not do it for
252              half-cooked objects.  */
253           if (imap->l_init_called)
254             {
255               /* When debugging print a message first.  */
256               if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
257                                     0))
258                 _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
259                                   imap->l_name, ns);
260
261               if (imap->l_info[DT_FINI_ARRAY] != NULL)
262                 {
263                   ElfW(Addr) *array =
264                     (ElfW(Addr) *) (imap->l_addr
265                                     + imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
266                   unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
267                                      / sizeof (ElfW(Addr)));
268
269                   while (sz-- > 0)
270                     ((fini_t) array[sz]) ();
271                 }
272
273               /* Next try the old-style destructor.  */
274               if (imap->l_info[DT_FINI] != NULL)
275                 (*(void (*) (void)) DL_DT_FINI_ADDRESS
276                  (imap, ((void *) imap->l_addr
277                          + imap->l_info[DT_FINI]->d_un.d_ptr))) ();
278             }
279
280 #ifdef SHARED
281           /* Auditing checkpoint: we have a new object.  */
282           if (__builtin_expect (do_audit, 0))
283             {
284               struct audit_ifaces *afct = GLRO(dl_audit);
285               for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
286                 {
287                   if (afct->objclose != NULL)
288                     /* Return value is ignored.  */
289                     (void) afct->objclose (&imap->l_audit[cnt].cookie);
290
291                   afct = afct->next;
292                 }
293             }
294 #endif
295
296           /* This object must not be used anymore.  */
297           imap->l_removed = 1;
298
299           /* We indeed have an object to remove.  */
300           unload_any = true;
301
302           /* Remember where the first dynamically loaded object is.  */
303           if (i < first_loaded)
304             first_loaded = i;
305         }
306       /* Else used[i].  */
307       else if (imap->l_type == lt_loaded)
308         {
309           struct r_scope_elem *new_list = NULL;
310
311           if (imap->l_searchlist.r_list == NULL && imap->l_initfini != NULL)
312             {
313               /* The object is still used.  But one of the objects we are
314                  unloading right now is responsible for loading it.  If
315                  the current object does not have it's own scope yet we
316                  have to create one.  This has to be done before running
317                  the finalizers.
318
319                  To do this count the number of dependencies.  */
320               unsigned int cnt;
321               for (cnt = 1; imap->l_initfini[cnt] != NULL; ++cnt)
322                 ;
323
324               /* We simply reuse the l_initfini list.  */
325               imap->l_searchlist.r_list = &imap->l_initfini[cnt + 1];
326               imap->l_searchlist.r_nlist = cnt;
327
328               new_list = &imap->l_searchlist;
329             }
330
331           /* Count the number of scopes which remain after the unload.
332              When we add the local search list count it.  Always add
333              one for the terminating NULL pointer.  */
334           size_t remain = (new_list != NULL) + 1;
335           bool removed_any = false;
336           for (size_t cnt = 0; imap->l_scope[cnt] != NULL; ++cnt)
337             /* This relies on l_scope[] entries being always set either
338                to its own l_symbolic_searchlist address, or some map's
339                l_searchlist address.  */
340             if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
341               {
342                 struct link_map *tmap = (struct link_map *)
343                   ((char *) imap->l_scope[cnt]
344                    - offsetof (struct link_map, l_searchlist));
345                 assert (tmap->l_ns == ns);
346                 if (tmap->l_idx == IDX_STILL_USED)
347                   ++remain;
348                 else
349                   removed_any = true;
350               }
351             else
352               ++remain;
353
354           if (removed_any)
355             {
356               /* Always allocate a new array for the scope.  This is
357                  necessary since we must be able to determine the last
358                  user of the current array.  If possible use the link map's
359                  memory.  */
360               size_t new_size;
361               struct r_scope_elem **newp;
362
363 #define SCOPE_ELEMS(imap) \
364   (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))
365
366               if (imap->l_scope != imap->l_scope_mem
367                   && remain < SCOPE_ELEMS (imap))
368                 {
369                   new_size = SCOPE_ELEMS (imap);
370                   newp = imap->l_scope_mem;
371                 }
372               else
373                 {
374                   new_size = imap->l_scope_max;
375                   newp = (struct r_scope_elem **)
376                     malloc (new_size * sizeof (struct r_scope_elem *));
377                   if (newp == NULL)
378                     _dl_signal_error (ENOMEM, "dlclose", NULL,
379                                       N_("cannot create scope list"));
380                 }
381
382               /* Copy over the remaining scope elements.  */
383               remain = 0;
384               for (size_t cnt = 0; imap->l_scope[cnt] != NULL; ++cnt)
385                 {
386                   if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
387                     {
388                       struct link_map *tmap = (struct link_map *)
389                         ((char *) imap->l_scope[cnt]
390                          - offsetof (struct link_map, l_searchlist));
391                       if (tmap->l_idx != IDX_STILL_USED)
392                         {
393                           /* Remove the scope.  Or replace with own map's
394                              scope.  */
395                           if (new_list != NULL)
396                             {
397                               newp[remain++] = new_list;
398                               new_list = NULL;
399                             }
400                           continue;
401                         }
402                     }
403
404                   newp[remain++] = imap->l_scope[cnt];
405                 }
406               newp[remain] = NULL;
407
408               struct r_scope_elem **old = imap->l_scope;
409
410               if (SINGLE_THREAD_P)
411                 imap->l_scope = newp;
412               else
413                 {
414                   __rtld_mrlock_change (imap->l_scope_lock);
415                   imap->l_scope = newp;
416                   __rtld_mrlock_done (imap->l_scope_lock);
417                 }
418
419               /* No user anymore, we can free it now.  */
420               if (old != imap->l_scope_mem)
421                 free (old);
422
423               imap->l_scope_max = new_size;
424             }
425
426           /* The loader is gone, so mark the object as not having one.
427              Note: l_idx != IDX_STILL_USED -> object will be removed.  */
428           if (imap->l_loader != NULL
429               && imap->l_loader->l_idx != IDX_STILL_USED)
430             imap->l_loader = NULL;
431
432           /* Remember where the first dynamically loaded object is.  */
433           if (i < first_loaded)
434             first_loaded = i;
435         }
436     }
437
438   /* If there are no objects to unload, do nothing further.  */
439   if (!unload_any)
440     goto out;
441
442 #ifdef SHARED
443   /* Auditing checkpoint: we will start deleting objects.  */
444   if (__builtin_expect (do_audit, 0))
445     {
446       struct link_map *head = GL(dl_ns)[ns]._ns_loaded;
447       struct audit_ifaces *afct = GLRO(dl_audit);
448       /* Do not call the functions for any auditing object.  */
449       if (head->l_auditing == 0)
450         {
451           for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
452             {
453               if (afct->activity != NULL)
454                 afct->activity (&head->l_audit[cnt].cookie, LA_ACT_DELETE);
455
456               afct = afct->next;
457             }
458         }
459     }
460 #endif
461
462   /* Notify the debugger we are about to remove some loaded objects.  */
463   struct r_debug *r = _dl_debug_initialize (0, ns);
464   r->r_state = RT_DELETE;
465   _dl_debug_state ();
466
467 #ifdef USE_TLS
468   size_t tls_free_start;
469   size_t tls_free_end;
470   tls_free_start = tls_free_end = NO_TLS_OFFSET;
471 #endif
472
473   /* Check each element of the search list to see if all references to
474      it are gone.  */
475   for (i = first_loaded; i < nloaded; ++i)
476     {
477       struct link_map *imap = maps[i];
478       if (!used[i])
479         {
480           assert (imap->l_type == lt_loaded);
481
482           /* That was the last reference, and this was a dlopen-loaded
483              object.  We can unmap it.  */
484           if (__builtin_expect (imap->l_global, 0))
485             {
486               /* This object is in the global scope list.  Remove it.  */
487               unsigned int cnt = GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
488
489               do
490                 --cnt;
491               while (GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt] != imap);
492
493               /* The object was already correctly registered.  */
494               while (++cnt
495                      < GL(dl_ns)[ns]._ns_main_searchlist->r_nlist)
496                 GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt - 1]
497                   = GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt];
498
499               --GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
500             }
501
502 #ifdef USE_TLS
503           /* Remove the object from the dtv slotinfo array if it uses TLS.  */
504           if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
505             {
506               any_tls = true;
507
508               if (GL(dl_tls_dtv_slotinfo_list) != NULL
509                   && ! remove_slotinfo (imap->l_tls_modid,
510                                         GL(dl_tls_dtv_slotinfo_list), 0,
511                                         imap->l_init_called))
512                 /* All dynamically loaded modules with TLS are unloaded.  */
513                 GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
514
515               if (imap->l_tls_offset != NO_TLS_OFFSET)
516                 {
517                   /* Collect a contiguous chunk built from the objects in
518                      this search list, going in either direction.  When the
519                      whole chunk is at the end of the used area then we can
520                      reclaim it.  */
521 # if TLS_TCB_AT_TP
522                   if (tls_free_start == NO_TLS_OFFSET
523                       || (size_t) imap->l_tls_offset == tls_free_start)
524                     {
525                       /* Extend the contiguous chunk being reclaimed.  */
526                       tls_free_start
527                         = imap->l_tls_offset - imap->l_tls_blocksize;
528
529                       if (tls_free_end == NO_TLS_OFFSET)
530                         tls_free_end = imap->l_tls_offset;
531                     }
532                   else if (imap->l_tls_offset - imap->l_tls_blocksize
533                            == tls_free_end)
534                     /* Extend the chunk backwards.  */
535                     tls_free_end = imap->l_tls_offset;
536                   else
537                     {
538                       /* This isn't contiguous with the last chunk freed.
539                          One of them will be leaked unless we can free
540                          one block right away.  */
541                       if (tls_free_end == GL(dl_tls_static_used))
542                         {
543                           GL(dl_tls_static_used) = tls_free_start;
544                           tls_free_end = imap->l_tls_offset;
545                           tls_free_start
546                             = tls_free_end - imap->l_tls_blocksize;
547                         }
548                       else if ((size_t) imap->l_tls_offset
549                                == GL(dl_tls_static_used))
550                         GL(dl_tls_static_used)
551                           = imap->l_tls_offset - imap->l_tls_blocksize;
552                       else if (tls_free_end < (size_t) imap->l_tls_offset)
553                         {
554                           /* We pick the later block.  It has a chance to
555                              be freed.  */
556                           tls_free_end = imap->l_tls_offset;
557                           tls_free_start
558                             = tls_free_end - imap->l_tls_blocksize;
559                         }
560                     }
561 # elif TLS_DTV_AT_TP
562                   if ((size_t) imap->l_tls_offset == tls_free_end)
563                     /* Extend the contiguous chunk being reclaimed.  */
564                     tls_free_end -= imap->l_tls_blocksize;
565                   else if (imap->l_tls_offset + imap->l_tls_blocksize
566                            == tls_free_start)
567                     /* Extend the chunk backwards.  */
568                     tls_free_start = imap->l_tls_offset;
569                   else
570                     {
571                       /* This isn't contiguous with the last chunk freed.
572                          One of them will be leaked.  */
573                       if (tls_free_end == GL(dl_tls_static_used))
574                         GL(dl_tls_static_used) = tls_free_start;
575                       tls_free_start = imap->l_tls_offset;
576                       tls_free_end = tls_free_start + imap->l_tls_blocksize;
577                     }
578 # else
579 #  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
580 # endif
581                 }
582             }
583 #endif
584
585           /* We can unmap all the maps at once.  We determined the
586              start address and length when we loaded the object and
587              the `munmap' call does the rest.  */
588           DL_UNMAP (imap);
589
590           /* Finally, unlink the data structure and free it.  */
591           if (imap->l_prev != NULL)
592             imap->l_prev->l_next = imap->l_next;
593           else
594             {
595 #ifdef SHARED
596               assert (ns != LM_ID_BASE);
597 #endif
598               GL(dl_ns)[ns]._ns_loaded = imap->l_next;
599             }
600
601           --GL(dl_ns)[ns]._ns_nloaded;
602           if (imap->l_next != NULL)
603             imap->l_next->l_prev = imap->l_prev;
604
605           free (imap->l_versions);
606           if (imap->l_origin != (char *) -1)
607             free ((char *) imap->l_origin);
608
609           free (imap->l_reldeps);
610
611           /* Print debugging message.  */
612           if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
613             _dl_debug_printf ("\nfile=%s [%lu];  destroying link map\n",
614                               imap->l_name, imap->l_ns);
615
616           /* This name always is allocated.  */
617           free (imap->l_name);
618           /* Remove the list with all the names of the shared object.  */
619
620           struct libname_list *lnp = imap->l_libname;
621           do
622             {
623               struct libname_list *this = lnp;
624               lnp = lnp->next;
625               if (!this->dont_free)
626                 free (this);
627             }
628           while (lnp != NULL);
629
630           /* Remove the searchlists.  */
631           free (imap->l_initfini);
632
633           /* Remove the scope array if we allocated it.  */
634           if (imap->l_scope != imap->l_scope_mem)
635             free (imap->l_scope);
636
637           if (imap->l_phdr_allocated)
638             free ((void *) imap->l_phdr);
639
640           if (imap->l_rpath_dirs.dirs != (void *) -1)
641             free (imap->l_rpath_dirs.dirs);
642           if (imap->l_runpath_dirs.dirs != (void *) -1)
643             free (imap->l_runpath_dirs.dirs);
644
645           free (imap);
646         }
647     }
648
649 #ifdef USE_TLS
650   /* If we removed any object which uses TLS bump the generation counter.  */
651   if (any_tls)
652     {
653       if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
654         _dl_fatal_printf ("TLS generation counter wrapped!  Please report as described in <http://www.gnu.org/software/libc/bugs.html>.\n");
655
656       if (tls_free_end == GL(dl_tls_static_used))
657         GL(dl_tls_static_used) = tls_free_start;
658     }
659 #endif
660
661 #ifdef SHARED
662   /* Auditing checkpoint: we have deleted all objects.  */
663   if (__builtin_expect (do_audit, 0))
664     {
665       struct link_map *head = GL(dl_ns)[ns]._ns_loaded;
666       /* Do not call the functions for any auditing object.  */
667       if (head->l_auditing == 0)
668         {
669           struct audit_ifaces *afct = GLRO(dl_audit);
670           for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
671             {
672               if (afct->activity != NULL)
673                 afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
674
675               afct = afct->next;
676             }
677         }
678     }
679 #endif
680
681   /* Notify the debugger those objects are finalized and gone.  */
682   r->r_state = RT_CONSISTENT;
683   _dl_debug_state ();
684
685   /* Recheck if we need to retry, release the lock.  */
686  out:
687   if (dl_close_state == rerun)
688     goto retry;
689
690   dl_close_state = not_pending;
691 }
692
693
694 void
695 _dl_close (void *_map)
696 {
697   struct link_map *map = _map;
698
699   /* First see whether we can remove the object at all.  */
700   if (__builtin_expect (map->l_flags_1 & DF_1_NODELETE, 0))
701     {
702       assert (map->l_init_called);
703       /* Nope.  Do nothing.  */
704       return;
705     }
706
707   if (__builtin_expect (map->l_direct_opencount, 1) == 0)
708     GLRO(dl_signal_error) (0, map->l_name, NULL, N_("shared object not open"));
709
710   /* Acquire the lock.  */
711   __rtld_lock_lock_recursive (GL(dl_load_lock));
712
713   _dl_close_worker (map);
714
715   __rtld_lock_unlock_recursive (GL(dl_load_lock));
716 }
717
718
719 #ifdef USE_TLS
720 static bool __libc_freeres_fn_section
721 free_slotinfo (struct dtv_slotinfo_list **elemp)
722 {
723   size_t cnt;
724
725   if (*elemp == NULL)
726     /* Nothing here, all is removed (or there never was anything).  */
727     return true;
728
729   if (!free_slotinfo (&(*elemp)->next))
730     /* We cannot free the entry.  */
731     return false;
732
733   /* That cleared our next pointer for us.  */
734
735   for (cnt = 0; cnt < (*elemp)->len; ++cnt)
736     if ((*elemp)->slotinfo[cnt].map != NULL)
737       /* Still used.  */
738       return false;
739
740   /* We can remove the list element.  */
741   free (*elemp);
742   *elemp = NULL;
743
744   return true;
745 }
746 #endif
747
748
749 libc_freeres_fn (free_mem)
750 {
751   for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
752     if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
753         && (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist
754             // XXX Check whether we need NS-specific initial_searchlist
755             == GLRO(dl_initial_searchlist).r_nlist))
756       {
757         /* All object dynamically loaded by the program are unloaded.  Free
758            the memory allocated for the global scope variable.  */
759         struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
760
761         /* Put the old map in.  */
762         GL(dl_ns)[ns]._ns_main_searchlist->r_list
763           // XXX Check whether we need NS-specific initial_searchlist
764           = GLRO(dl_initial_searchlist).r_list;
765         /* Signal that the original map is used.  */
766         GL(dl_ns)[ns]._ns_global_scope_alloc = 0;
767
768         /* Now free the old map.  */
769         free (old);
770       }
771
772 #ifdef USE_TLS
773   if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL)
774     {
775       /* Free the memory allocated for the dtv slotinfo array.  We can do
776          this only if all modules which used this memory are unloaded.  */
777 # ifdef SHARED
778       if (GL(dl_initial_dtv) == NULL)
779         /* There was no initial TLS setup, it was set up later when
780            it used the normal malloc.  */
781         free_slotinfo (&GL(dl_tls_dtv_slotinfo_list));
782       else
783 # endif
784         /* The first element of the list does not have to be deallocated.
785            It was allocated in the dynamic linker (i.e., with a different
786            malloc), and in the static library it's in .bss space.  */
787         free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next);
788     }
789 #endif
790 }