diff options
author | Ulrich Drepper <drepper@redhat.com> | 2001-09-07 07:57:11 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2001-09-07 07:57:11 +0000 |
commit | 5a21d307c518c911f81848b6c0056fcc39e3ddcd (patch) | |
tree | 9b2c8e176909392cb03b76cf2eb5d29e61c55d40 /elf/dl-open.c | |
parent | b98e518f5627b95c79bf75d178ae41527c333886 (diff) | |
download | glibc-5a21d307c518c911f81848b6c0056fcc39e3ddcd.tar glibc-5a21d307c518c911f81848b6c0056fcc39e3ddcd.tar.gz glibc-5a21d307c518c911f81848b6c0056fcc39e3ddcd.tar.bz2 glibc-5a21d307c518c911f81848b6c0056fcc39e3ddcd.zip |
Update.
2001-09-07 Ulrich Drepper <drepper@redhat.com>
* include/link.h (struct link_map): Add l_scope_mem and l_scope_max
elements. Change l_scope to be a pointer only.
* elf/dl-object.c (_dl_new_ojbect): Initialize l_scope and l_scope_max.
* elf/dl-open.c (dl_open_worker): If dependency wasn't just opened
here add searchlist of newly open file to the dependency's scope.
* elf/dl-close.c (_dl_close): If dependency is used otherwise remove
only searchlist from its scope. Free own scope array if necessary.
* elf/Makefile (tests): Add dblload and dblunload now.
Diffstat (limited to 'elf/dl-open.c')
-rw-r--r-- | elf/dl-open.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c index ec88c79a27..f79c317da8 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -295,9 +295,55 @@ dl_open_worker (void *a) l = l->l_prev; } - /* Increment the open count for all dependencies. */ + /* 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. */ for (i = 0; i < new->l_searchlist.r_nlist; ++i) - ++new->l_searchlist.r_list[i]->l_opencount; + if (++new->l_searchlist.r_list[i]->l_opencount > 1 + && new->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) + { + ++cnt; + ++runp; + } + + 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 * imap->l_scope_max); + } + 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[cnt++] = &new->l_searchlist; + imap->l_scope[cnt] = NULL; + } + } /* Run the initializer functions of new objects. */ _dl_init (new, __libc_argc, __libc_argv, __environ); |