diff options
author | Roland McGrath <roland@gnu.org> | 2005-04-06 02:50:03 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2005-04-06 02:50:03 +0000 |
commit | cd107adf8b6084891dc7f8909abf12060f3ca112 (patch) | |
tree | 29ea1e3cc5dbb2c3175ba21ec057a09864e8d0d5 /elf | |
parent | 0330a08d8a0a3e4ab29573f045138f9754d0cda4 (diff) |
2005-03-19 Jakub Jelinek <jakub@redhat.com>
[BZ #821]
* elf/dl-open.c (dl_open_worker): Print exact l_direct_opencount value,
it has been incremented before.
2005-03-18 Ulrich Drepper <drepper@redhat.com>
[BZ #821]
* 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.
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-open.c | 277 |
1 files changed, 129 insertions, 148 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c index 7e890ad7f7..dc4a9736ee 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -279,23 +279,14 @@ dl_open_worker (void *a) { /* Let the user know about the opencount. */ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)) - GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n", - new->l_name, new->l_ns, new->l_opencount); + GLRO(dl_debug_printf) ("opening file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); /* 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; - return; } @@ -373,135 +364,133 @@ dl_open_worker (void *a) any_tls = false; #endif - /* 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) - GLRO(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) - GLRO(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) + GLRO(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) + GLRO(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 dtv info table. We - might have to increase its size. */ - struct dtv_slotinfo_list *listp; - struct dtv_slotinfo_list *prevp; - size_t idx = new->l_searchlist.r_list[i]->l_tls_modid; - - assert (new->l_searchlist.r_list[i]->l_type == lt_loaded); - - /* Find the place in the dtv slotinfo list. */ - listp = GL(dl_tls_dtv_slotinfo_list); - prevp = NULL; /* Needed to shut up gcc. */ - do - { - /* Does it fit in the array of this list element? */ - if (idx < listp->len) - break; - idx -= listp->len; - prevp = listp; - listp = listp->next; - } - while (listp != NULL); - - if (listp == NULL) - { - /* When we come here it means we have to add a new element - to the slotinfo list. And the new module must be in - the first slot. */ - assert (idx == 0); - - listp = prevp->next = (struct dtv_slotinfo_list *) - malloc (sizeof (struct dtv_slotinfo_list) - + TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo)); - if (listp == NULL) - { - /* We ran out of memory. We will simply fail this - call but don't undo anything we did so far. The - application will crash or be terminated anyway very - soon. */ - - /* We have to do this since some entries in the dtv - slotinfo array might already point to this - generation. */ - ++GL(dl_tls_generation); - - GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL, N_("\ -cannot create TLS data structures")); - } - - listp->len = TLS_SLOTINFO_SURPLUS; - listp->next = NULL; - memset (listp->slotinfo, '\0', - TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo)); - } - - /* Add the information into the slotinfo data structure. */ - listp->slotinfo[idx].map = new->l_searchlist.r_list[i]; - listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; - - /* We have to bump the generation counter. */ - any_tls = true; - } + /* 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 dtv info table. We + might have to increase its size. */ + struct dtv_slotinfo_list *listp; + struct dtv_slotinfo_list *prevp; + size_t idx = imap->l_tls_modid; + + assert (imap->l_type == lt_loaded); + + /* Find the place in the dtv slotinfo list. */ + listp = GL(dl_tls_dtv_slotinfo_list); + prevp = NULL; /* Needed to shut up gcc. */ + do + { + /* Does it fit in the array of this list element? */ + if (idx < listp->len) + break; + idx -= listp->len; + prevp = listp; + listp = listp->next; + } + while (listp != NULL); + + if (listp == NULL) + { + /* When we come here it means we have to add a new element + to the slotinfo list. And the new module must be in + the first slot. */ + assert (idx == 0); + + listp = prevp->next = (struct dtv_slotinfo_list *) + malloc (sizeof (struct dtv_slotinfo_list) + + TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo)); + if (listp == NULL) + { + /* We ran out of memory. We will simply fail this + call but don't undo anything we did so far. The + application will crash or be terminated anyway very + soon. */ + + /* We have to do this since some entries in the dtv + slotinfo array might already point to this + generation. */ + ++GL(dl_tls_generation); + + GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL, N_("\ + cannot create TLS data structures")); + } + + listp->len = TLS_SLOTINFO_SURPLUS; + listp->next = NULL; + memset (listp->slotinfo, '\0', + TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo)); + } + + /* Add the information into the slotinfo data structure. */ + listp->slotinfo[idx].map = imap; + listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; + + /* We have to bump the generation counter. */ + any_tls = true; + } + } /* Bump the generation number if necessary. */ if (any_tls) @@ -532,8 +521,8 @@ cannot create TLS data structures")); /* Let the user know about the opencount. */ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)) - GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n", - new->l_name, new->l_ns, new->l_opencount); + GLRO(dl_debug_printf) ("opening file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); } @@ -603,14 +592,6 @@ no more namespaces available for dlmopen()")); state if relocation failed, for example. */ if (args.map) { - unsigned int i; - - /* 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 (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 uses TLS. Since it will be removed in the following _dl_close call |