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.
This commit is contained in:
Ulrich Drepper 2001-09-07 07:57:11 +00:00
parent b98e518f56
commit 5a21d307c5
5 changed files with 89 additions and 3 deletions

View file

@ -1,3 +1,14 @@
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.
2001-09-06 Andreas Jaeger <aj@suse.de>
* sysdeps/ieee754/ldbl-128/e_lgammal_r.c: New file, contributed

View file

@ -106,7 +106,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \
$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
neededtest3 neededtest4 unload2 lateglobal initfirst global \
restest2 next #dblload dblunload
restest2 next dblload dblunload
test-srcs = tst-pathopt
tests-vis-yes = vismain
tests-nodelete-yes = nodelete

View file

@ -146,6 +146,25 @@ _dl_close (void *_map)
(imap, (void *) imap->l_addr
+ imap->l_info[DT_FINI]->d_un.d_ptr)) ();
}
else if (new_opencount[i] != 0 && imap->l_type == lt_loaded)
{
/* The object is still used. But the object we are unloading
right now is responsible for loading it and therefore we
have the search list of the current object in its scope.
Remove it. */
struct r_scope_elem **runp = imap->l_scope;
while (*runp != NULL)
if (*runp == &map->l_searchlist)
{
/* Copy all later elements. */
while ((runp[0] = runp[1]) != NULL)
++runp;
break;
}
else
++runp;
}
/* Store the new l_opencount value. */
imap->l_opencount = new_opencount[i];
@ -241,6 +260,10 @@ _dl_close (void *_map)
if (imap != map)
free (imap->l_initfini);
/* Remove the scope array if we allocated it. */
if (imap->l_scope != imap->l_scope_mem)
free (imap->l_scope);
if (imap->l_phdr_allocated)
free ((void *) imap->l_phdr);

View file

@ -50,6 +50,12 @@ _dl_new_object (char *realname, const char *libname, int type,
new->l_loader = loader;
/* new->l_global = 0; We use calloc therefore not necessary. */
/* Use the 'l_scope_mem' array by default for the the 'l_scope'
information. If we need more entries we will allocate a large
array dynamically. */
new->l_scope = new->l_scope_mem;
new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
/* Counter for the scopes we have to handle. */
idx = 0;

View file

@ -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);