aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-open.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-03-18 11:11:42 +0000
committerUlrich Drepper <drepper@redhat.com>2005-03-18 11:11:42 +0000
commit20fe49b93a8807b7e91732d5a1b21a2d99472793 (patch)
tree03326dfe9fea0cad1bbb77d4f546584de6c60b5d /elf/dl-open.c
parent193af754dc157708224817fb8ff8914f2fc5e6e1 (diff)
downloadglibc-20fe49b93a8807b7e91732d5a1b21a2d99472793.tar
glibc-20fe49b93a8807b7e91732d5a1b21a2d99472793.tar.gz
glibc-20fe49b93a8807b7e91732d5a1b21a2d99472793.tar.bz2
glibc-20fe49b93a8807b7e91732d5a1b21a2d99472793.zip
* include/link.h (struct link_map): Remove l_opencount. Add l_removed.
Change type of l_idx to int. * elf/dl-close.c: Basically rewrite. Do not use l_opencount to determine whether a DSO has to be unloaded. Instead compute this in this function. * elf/dl-deps.c: No need to manipulate l_opencount anymore. * elf/dl-lookup.c: Likewise. * elf/rtld.c: Likewise * elf/dl-open.c: Likewise. Use l_init_called to determine whether object was just loaded. * elf/dl-fini.c: Bump l_direct_opencount instead of l_opencount. * elf/dl-load.c (_dl_map_object_from_fd): Do not recognize DSO which is about to be unloaded as a match. (_dl_map_object): Likewise. * elf/do-lookup.h (do_lookup_x): Do not look into DSO which is about to be unloaded. * elf/circleload1.c: Don't use l_opencount anymore. * elf/neededtest.c: Likewise. * elf/neededtest2.c: Likewise. * elf/neededtest3.c: Likewise. * elf/neededtest4.c: Likewise. * elf/unload.c: Likewise. * elf/unload2.c: Likewise. * elf/loadtest.c: Likewise. * elf/rtld.c: Preloading errors are now never fatal. 2005-03-08 Jakub Jelinek <jakub@redhat.com> * elf/Makefile: Add rules to build and run unload5 test. * elf/unload5.c: New file. 2005-03-08 Jakub Jelinek <jakub@redhat.com> * elf/Makefile: Add rules to build and run unload4 test. * elf/unload4.c: New file. * elf/unload4mod1.c: New file. * elf/unload4mod2.c: New file. * elf/unload4mod3.c: New file. * elf/unload4mod4.c: New file.
Diffstat (limited to 'elf/dl-open.c')
-rw-r--r--elf/dl-open.c185
1 files changed, 84 insertions, 101 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 0e06ca15d5..199c75553e 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -281,23 +281,14 @@ dl_open_worker (void *a)
{
/* Let the user know about the opencount. */
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
- _dl_debug_printf ("opening file=%s [%lu]; opencount=%u\n\n",
- new->l_name, new->l_ns, new->l_opencount + 1);
+ _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ new->l_name, new->l_ns, new->l_direct_opencount + 1);
/* If the user requested the object to be in the global namespace
but it is not so far, add it now. */
if ((mode & RTLD_GLOBAL) && new->l_global == 0)
(void) add_to_global (new);
- if (new->l_direct_opencount == 1)
- /* This is the only direct reference. Increment all the
- dependencies' reference counter. */
- for (i = 0; i < new->l_searchlist.r_nlist; ++i)
- ++new->l_searchlist.r_list[i]->l_opencount;
- else
- /* Increment just the reference counter of the object. */
- ++new->l_opencount;
-
assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
return;
@@ -386,94 +377,92 @@ dl_open_worker (void *a)
l = l->l_prev;
}
- /* Increment the open count for all dependencies. If the file is
- not loaded as a dependency here add the search list of the newly
- loaded object to the scope. */
+ /* If the file is not loaded now as a dependency, add the search
+ list of the newly loaded object to the scope. */
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
- if (++new->l_searchlist.r_list[i]->l_opencount > 1
- && new->l_real->l_searchlist.r_list[i]->l_type == lt_loaded)
- {
- struct link_map *imap = new->l_searchlist.r_list[i];
- struct r_scope_elem **runp = imap->l_scope;
- size_t cnt = 0;
-
- while (*runp != NULL)
- {
- /* This can happen if imap was just loaded, but during
- relocation had l_opencount bumped because of relocation
- dependency. Avoid duplicates in l_scope. */
- if (__builtin_expect (*runp == &new->l_searchlist, 0))
- break;
-
- ++cnt;
- ++runp;
- }
-
- if (*runp != NULL)
- /* Avoid duplicates. */
- continue;
-
- if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
- {
- /* The 'r_scope' array is too small. Allocate a new one
- dynamically. */
- struct r_scope_elem **newp;
- size_t new_size = imap->l_scope_max * 2;
-
- if (imap->l_scope == imap->l_scope_mem)
- {
- newp = (struct r_scope_elem **)
- malloc (new_size * sizeof (struct r_scope_elem *));
- if (newp == NULL)
- _dl_signal_error (ENOMEM, "dlopen", NULL,
- N_("cannot create scope list"));
- imap->l_scope = memcpy (newp, imap->l_scope,
- cnt * sizeof (imap->l_scope[0]));
- }
- else
- {
- newp = (struct r_scope_elem **)
- realloc (imap->l_scope,
- new_size * sizeof (struct r_scope_elem *));
- if (newp == NULL)
- _dl_signal_error (ENOMEM, "dlopen", NULL,
- N_("cannot create scope list"));
- imap->l_scope = newp;
- }
-
- imap->l_scope_max = new_size;
- }
-
- imap->l_scope[cnt++] = &new->l_searchlist;
- imap->l_scope[cnt] = NULL;
- }
+ {
+ struct link_map *imap = new->l_searchlist.r_list[i];
+
+ /* If the initializer has been called already, the object has
+ not been loaded here and now. */
+ if (imap->l_init_called && imap->l_type == lt_loaded)
+ {
+ struct r_scope_elem **runp = imap->l_scope;
+ size_t cnt = 0;
+
+ while (*runp != NULL)
+ {
+ ++cnt;
+ ++runp;
+ }
+
+ if (*runp != NULL)
+ /* Avoid duplicates. */
+ continue;
+
+ if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
+ {
+ /* The 'r_scope' array is too small. Allocate a new one
+ dynamically. */
+ struct r_scope_elem **newp;
+ size_t new_size = imap->l_scope_max * 2;
+
+ if (imap->l_scope == imap->l_scope_mem)
+ {
+ newp = (struct r_scope_elem **)
+ malloc (new_size * sizeof (struct r_scope_elem *));
+ if (newp == NULL)
+ _dl_signal_error (ENOMEM, "dlopen", NULL,
+ N_("cannot create scope list"));
+ imap->l_scope = memcpy (newp, imap->l_scope,
+ cnt * sizeof (imap->l_scope[0]));
+ }
+ else
+ {
+ newp = (struct r_scope_elem **)
+ realloc (imap->l_scope,
+ new_size * sizeof (struct r_scope_elem *));
+ if (newp == NULL)
+ _dl_signal_error (ENOMEM, "dlopen", NULL,
+ N_("cannot create scope list"));
+ imap->l_scope = newp;
+ }
+
+ imap->l_scope_max = new_size;
+ }
+
+ imap->l_scope[cnt++] = &new->l_searchlist;
+ imap->l_scope[cnt] = NULL;
+ }
#if USE_TLS
- else if (new->l_searchlist.r_list[i]->l_opencount == 1
- /* Only if the module defines thread local data. */
- && __builtin_expect (new->l_searchlist.r_list[i]->l_tls_blocksize
- > 0, 0))
- {
- /* Now that we know the object is loaded successfully add
- modules containing TLS data to the slot info table. We
- might have to increase its size. */
- _dl_add_to_slotinfo (new->l_searchlist.r_list[i]);
-
- if (new->l_searchlist.r_list[i]->l_need_tls_init)
- {
- new->l_searchlist.r_list[i]->l_need_tls_init = 0;
+ /* Only add TLS memory if this object is loaded now and
+ therefore is not yet initialized. */
+ else if (! imap->l_init_called
+ /* Only if the module defines thread local data. */
+ && __builtin_expect (imap->l_tls_blocksize > 0, 0))
+ {
+ /* Now that we know the object is loaded successfully add
+ modules containing TLS data to the slot info table. We
+ might have to increase its size. */
+ _dl_add_to_slotinfo (imap);
+
+ if (imap->l_need_tls_init)
+ {
+ imap->l_need_tls_init = 0;
# ifdef SHARED
- /* Update the slot information data for at least the
- generation of the DSO we are allocating data for. */
- _dl_update_slotinfo (new->l_searchlist.r_list[i]->l_tls_modid);
+ /* Update the slot information data for at least the
+ generation of the DSO we are allocating data for. */
+ _dl_update_slotinfo (imap->l_tls_modid);
# endif
- GL(dl_init_static_tls) (new->l_searchlist.r_list[i]);
- assert (new->l_searchlist.r_list[i]->l_need_tls_init == 0);
- }
+ GL(dl_init_static_tls) (imap);
+ assert (imap->l_need_tls_init == 0);
+ }
- /* We have to bump the generation counter. */
- any_tls = true;
- }
+ /* We have to bump the generation counter. */
+ any_tls = true;
+ }
+ }
/* Bump the generation number if necessary. */
if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0))
@@ -504,8 +493,8 @@ TLS generation counter wrapped! Please report this."));
/* Let the user know about the opencount. */
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
- _dl_debug_printf ("opening file=%s [%lu]; opencount=%u\n\n",
- new->l_name, new->l_ns, new->l_opencount);
+ _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ new->l_name, new->l_ns, new->l_direct_opencount);
}
@@ -581,12 +570,6 @@ no more namespaces available for dlmopen()"));
state if relocation failed, for example. */
if (args.map)
{
- /* Increment open counters for all objects since this
- sometimes has not happened yet. */
- if (args.map->l_searchlist.r_list[0]->l_opencount == 0)
- for (unsigned int i = 0; i < args.map->l_searchlist.r_nlist; ++i)
- ++args.map->l_searchlist.r_list[i]->l_opencount;
-
#ifdef USE_TLS
/* Maybe some of the modules which were loaded use TLS.
Since it will be removed in the following _dl_close call