Update.
[glibc.git] / elf / dl-close.c
blob7e7547de9953d42f099b1f2dcd2e31a3e05513b9
1 /* Close a shared object opened by `_dl_open'.
2 Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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. */
20 #include <assert.h>
21 #include <dlfcn.h>
22 #include <libintl.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <bits/libc-lock.h>
26 #include <ldsodefs.h>
27 #include <sys/types.h>
28 #include <sys/mman.h>
31 /* Type of the constructor functions. */
32 typedef void (*fini_t) (void);
35 void
36 internal_function
37 _dl_close (void *_map)
39 struct reldep_list
41 struct link_map **rellist;
42 unsigned int nrellist;
43 struct reldep_list *next;
44 } *reldeps = NULL;
45 struct link_map **list;
46 struct link_map *map = _map;
47 unsigned int i;
48 unsigned int *new_opencount;
49 #ifdef USE_TLS
50 bool any_tls = false;
51 #endif
53 /* First see whether we can remove the object at all. */
54 if (__builtin_expect (map->l_flags_1 & DF_1_NODELETE, 0)
55 && map->l_init_called)
56 /* Nope. Do nothing. */
57 return;
59 if (__builtin_expect (map->l_opencount, 1) == 0)
60 _dl_signal_error (0, map->l_name, NULL, N_("shared object not open"));
62 /* Acquire the lock. */
63 __libc_lock_lock_recursive (GL(dl_load_lock));
65 /* Decrement the reference count. */
66 if (map->l_opencount > 1 || map->l_type != lt_loaded)
68 /* There are still references to this object. Do nothing more. */
69 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))
70 _dl_debug_printf ("\nclosing file=%s; opencount == %u\n",
71 map->l_name, map->l_opencount);
73 /* One decrement the object itself, not the dependencies. */
74 --map->l_opencount;
76 __libc_lock_unlock_recursive (GL(dl_load_lock));
77 return;
80 list = map->l_initfini;
82 /* Compute the new l_opencount values. */
83 i = map->l_searchlist.r_nlist;
84 if (__builtin_expect (i == 0, 0))
85 /* This can happen if we handle relocation dependencies for an
86 object which wasn't loaded directly. */
87 for (i = 1; list[i] != NULL; ++i)
90 new_opencount = (unsigned int *) alloca (i * sizeof (unsigned int));
92 for (i = 0; list[i] != NULL; ++i)
94 list[i]->l_idx = i;
95 new_opencount[i] = list[i]->l_opencount;
97 --new_opencount[0];
98 for (i = 1; list[i] != NULL; ++i)
99 if ((! (list[i]->l_flags_1 & DF_1_NODELETE) || ! list[i]->l_init_called)
100 /* Decrement counter. */
101 && --new_opencount[i] == 0
102 /* Test whether this object was also loaded directly. */
103 && list[i]->l_searchlist.r_list != NULL)
105 /* In this case we have the decrement all the dependencies of
106 this object. They are all in MAP's dependency list. */
107 unsigned int j;
108 struct link_map **dep_list = list[i]->l_searchlist.r_list;
110 for (j = 1; j < list[i]->l_searchlist.r_nlist; ++j)
111 if (! (dep_list[j]->l_flags_1 & DF_1_NODELETE)
112 || ! dep_list[j]->l_init_called)
114 assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
115 --new_opencount[dep_list[j]->l_idx];
118 assert (new_opencount[0] == 0);
120 /* Call all termination functions at once. */
121 for (i = 0; list[i] != NULL; ++i)
123 struct link_map *imap = list[i];
124 if (new_opencount[i] == 0 && imap->l_type == lt_loaded
125 && (imap->l_info[DT_FINI] || imap->l_info[DT_FINI_ARRAY])
126 && (! (imap->l_flags_1 & DF_1_NODELETE) || ! imap->l_init_called)
127 /* Skip any half-cooked objects that were never initialized. */
128 && imap->l_init_called)
130 /* When debugging print a message first. */
131 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
132 _dl_debug_printf ("\ncalling fini: %s\n\n", imap->l_name);
134 /* Call its termination function. */
135 if (imap->l_info[DT_FINI_ARRAY] != NULL)
137 ElfW(Addr) *array =
138 (ElfW(Addr) *) (imap->l_addr
139 + imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
140 unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
141 / sizeof (ElfW(Addr)));
142 unsigned int cnt;
144 for (cnt = 0; cnt < sz; ++cnt)
145 ((fini_t) (imap->l_addr + array[cnt])) ();
148 /* Next try the old-style destructor. */
149 if (imap->l_info[DT_FINI] != NULL)
150 (*(void (*) (void)) DL_DT_FINI_ADDRESS
151 (imap, (void *) imap->l_addr
152 + imap->l_info[DT_FINI]->d_un.d_ptr)) ();
154 else if (new_opencount[i] != 0 && imap->l_type == lt_loaded)
156 /* The object is still used. But the object we are unloading
157 right now is responsible for loading it and therefore we
158 have the search list of the current object in its scope.
159 Remove it. */
160 struct r_scope_elem **runp = imap->l_scope;
162 while (*runp != NULL)
163 if (*runp == &map->l_searchlist)
165 /* Copy all later elements. */
166 while ((runp[0] = runp[1]) != NULL)
167 ++runp;
168 break;
170 else
171 ++runp;
174 /* Store the new l_opencount value. */
175 imap->l_opencount = new_opencount[i];
176 /* Just a sanity check. */
177 assert (imap->l_type == lt_loaded || imap->l_opencount > 0);
180 /* Notify the debugger we are about to remove some loaded objects. */
181 _r_debug.r_state = RT_DELETE;
182 _dl_debug_state ();
184 /* Check each element of the search list to see if all references to
185 it are gone. */
186 for (i = 0; list[i] != NULL; ++i)
188 struct link_map *imap = list[i];
189 if (imap->l_opencount == 0 && imap->l_type == lt_loaded)
191 struct libname_list *lnp;
193 /* That was the last reference, and this was a dlopen-loaded
194 object. We can unmap it. */
195 if (__builtin_expect (imap->l_global, 0))
197 /* This object is in the global scope list. Remove it. */
198 unsigned int cnt = GL(dl_main_searchlist)->r_nlist;
201 --cnt;
202 while (GL(dl_main_searchlist)->r_list[cnt] != imap);
204 /* The object was already correctly registered. */
205 while (++cnt < GL(dl_main_searchlist)->r_nlist)
206 GL(dl_main_searchlist)->r_list[cnt - 1]
207 = GL(dl_main_searchlist)->r_list[cnt];
209 --GL(dl_main_searchlist)->r_nlist;
212 #ifdef USE_TLS
213 /* Remove the object from the dtv slotinfo array if it uses
214 TLS. */
215 if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
217 /* Locate the entry in the slotinfo array. */
218 size_t idx = imap->l_tls_modid;
219 struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
221 while (idx >= listp->len)
223 idx -= listp->len;
224 listp = listp->next;
227 listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
228 listp->slotinfo[idx].map = NULL;
230 any_tls = true;
232 if (imap->l_tls_modid == GL(dl_tls_max_dtv_idx))
233 --GL(dl_tls_max_dtv_idx);
234 else
235 GL(dl_tls_dtv_gaps) = true;
237 #endif
239 /* We can unmap all the maps at once. We determined the
240 start address and length when we loaded the object and
241 the `munmap' call does the rest. */
242 DL_UNMAP (imap);
244 /* Finally, unlink the data structure and free it. */
245 #ifdef SHARED
246 /* We will unlink the first object only if this is a statically
247 linked program. */
248 assert (imap->l_prev != NULL);
249 imap->l_prev->l_next = imap->l_next;
250 #else
251 if (imap->l_prev != NULL)
252 imap->l_prev->l_next = imap->l_next;
253 else
254 GL(dl_loaded) = imap->l_next;
255 #endif
256 --GL(dl_nloaded);
257 if (imap->l_next)
258 imap->l_next->l_prev = imap->l_prev;
260 if (imap->l_versions != NULL)
261 free (imap->l_versions);
262 if (imap->l_origin != NULL && imap->l_origin != (char *) -1)
263 free ((char *) imap->l_origin);
265 /* If the object has relocation dependencies save this
266 information for latter. */
267 if (__builtin_expect (imap->l_reldeps != NULL, 0))
269 struct reldep_list *newrel;
271 newrel = (struct reldep_list *) alloca (sizeof (*reldeps));
272 newrel->rellist = imap->l_reldeps;
273 newrel->nrellist = imap->l_reldepsact;
274 newrel->next = reldeps;
276 reldeps = newrel;
279 /* This name always is allocated. */
280 free (imap->l_name);
281 /* Remove the list with all the names of the shared object. */
282 lnp = imap->l_libname;
285 struct libname_list *this = lnp;
286 lnp = lnp->next;
287 if (!this->dont_free)
288 free (this);
290 while (lnp != NULL);
292 /* Remove the searchlists. */
293 if (imap != map)
294 free (imap->l_initfini);
296 /* Remove the scope array if we allocated it. */
297 if (imap->l_scope != imap->l_scope_mem)
298 free (imap->l_scope);
300 if (imap->l_phdr_allocated)
301 free ((void *) imap->l_phdr);
303 if (imap->l_rpath_dirs.dirs != (void *) -1)
304 free (imap->l_rpath_dirs.dirs);
305 if (imap->l_runpath_dirs.dirs != (void *) -1)
306 free (imap->l_runpath_dirs.dirs);
308 free (imap);
312 #ifdef USE_TLS
313 /* If we removed any object which uses TLS bumnp the generation
314 counter. */
315 if (any_tls)
316 ++GL(dl_tls_generation);
317 #endif
319 /* Notify the debugger those objects are finalized and gone. */
320 _r_debug.r_state = RT_CONSISTENT;
321 _dl_debug_state ();
323 /* Now we can perhaps also remove the modules for which we had
324 dependencies because of symbol lookup. */
325 while (__builtin_expect (reldeps != NULL, 0))
327 while (reldeps->nrellist-- > 0)
328 _dl_close (reldeps->rellist[reldeps->nrellist]);
330 free (reldeps->rellist);
332 reldeps = reldeps->next;
335 free (list);
337 /* Release the lock. */
338 __libc_lock_unlock_recursive (GL(dl_load_lock));
342 #ifdef USE_TLS
343 static bool
344 free_slotinfo (struct dtv_slotinfo_list *elemp)
346 size_t cnt;
348 if (elemp->next != NULL && !free_slotinfo (elemp->next))
349 /* We cannot free the entry. */
350 return false;
352 /* The least we could do is remove next element (if there was any). */
353 elemp->next = NULL;
355 for (cnt = 0; cnt < elemp->len; ++cnt)
356 if (elemp->slotinfo[cnt].map != NULL)
357 /* Still used. */
358 return false;
360 /* We can remove the list element. */
361 free (elemp);
363 return true;
365 #endif
368 static void
369 free_mem (void)
371 if (__builtin_expect (GL(dl_global_scope_alloc), 0) != 0
372 && GL(dl_main_searchlist)->r_nlist == GL(dl_initial_searchlist).r_nlist)
374 /* All object dynamically loaded by the program are unloaded. Free
375 the memory allocated for the global scope variable. */
376 struct link_map **old = GL(dl_main_searchlist)->r_list;
378 /* Put the old map in. */
379 GL(dl_main_searchlist)->r_list = GL(dl_initial_searchlist).r_list;
380 /* Signal that the original map is used. */
381 GL(dl_global_scope_alloc) = 0;
383 /* Now free the old map. */
384 free (old);
387 #ifdef USE_TLS
388 /* Free the memory allocated for the dtv slotinfo array. We can do
389 this only if all modules which used this memory are unloaded.
390 Also, the first element of the list does not have to be
391 deallocated. It was allocated in the dynamic linker (i.e., with
392 a different malloc). */
393 if (free_slotinfo (GL(dl_tls_dtv_slotinfo_list)->next))
394 GL(dl_tls_dtv_slotinfo_list)->next = NULL;
395 #endif
397 text_set_element (__libc_subfreeres, free_mem);