* elf/dl-close.c: Decrement opencount for all dependencies which can
	be removed even if the object is not yet unloaded.
	* elf/dl-deps.c (_dl_map_object_deps): If dependency is already in
	the list decrement opencount of all dependencies.
	* elf/dl-load.c (_dl_map_object_from_fd): Increment object of object
	and all dependencies.
	(_dl_map_object): Likewise.
	* elf/dl-lookup.c (add_dependency): Likewise.

	* elf/loadtest.c: Add debug when with more output.
This commit is contained in:
Ulrich Drepper 2000-10-21 06:02:49 +00:00
parent f6de2239e2
commit 8699e7b1da
8 changed files with 71 additions and 18 deletions

View File

@ -1,5 +1,16 @@
2000-10-20 Ulrich Drepper <drepper@redhat.com>
* elf/dl-close.c: Decrement opencount for all dependencies which can
be removed even if the object is not yet unloaded.
* elf/dl-deps.c (_dl_map_object_deps): If dependency is already in
the list decrement opencount of all dependencies.
* elf/dl-load.c (_dl_map_object_from_fd): Increment object of object
and all dependencies.
(_dl_map_object): Likewise.
* elf/dl-lookup.c (add_dependency): Likewise.
* elf/loadtest.c: Add debug when with more output.
* elf/Makefile: Add rules to build and run unload2.
* elf/unload2.c: New file.
* elf/unload2mod.c: New file.

View File

@ -61,6 +61,9 @@ _dl_close (void *_map)
/* Acquire the lock. */
__libc_lock_lock (_dl_load_lock);
list = map->l_searchlist.r_list;
nsearchlist = map->l_searchlist.r_nlist;
/* Decrement the reference count. */
if (map->l_opencount > 1 || map->l_type != lt_loaded)
{
@ -78,14 +81,14 @@ _dl_close (void *_map)
"\n", NULL);
}
--map->l_opencount;
for (i = 0; i < nsearchlist; ++i)
if (! (list[i]->l_flags_1 & DF_1_NODELETE))
--list[i]->l_opencount;
__libc_lock_unlock (_dl_load_lock);
return;
}
list = map->l_searchlist.r_list;
nsearchlist = map->l_searchlist.r_nlist;
rellist = map->l_reldeps;
nrellist = map->l_reldepsact;

View File

@ -244,11 +244,16 @@ _dl_map_object_deps (struct link_map *map,
++nduplist;
if (dep->l_reserved)
{
/* This object is already in the search list we are
building. Don't add a duplicate pointer.
Release the reference just added by
_dl_map_object. */
if (dep->l_initfini != NULL)
for (i = 1; dep->l_initfini[i] != NULL; ++i)
--dep->l_initfini[i]->l_opencount;
--dep->l_opencount;
}
else
{
/* Append DEP to the unique list. */
@ -360,6 +365,9 @@ _dl_map_object_deps (struct link_map *map,
are building. Don't add a duplicate pointer.
Release the reference just added by
_dl_map_object. */
if (args.aux->l_initfini != NULL)
for (i = 1; args.aux->l_initfini[i] != NULL; ++i)
--args.aux->l_initfini[i]->l_opencount;
--args.aux->l_opencount;
for (late = newp; late->unique; late = late->unique)

View File

@ -777,6 +777,8 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
for (l = _dl_loaded; l; l = l->l_next)
if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)
{
unsigned int i;
/* The object is already loaded.
Just bump its reference count and return it. */
__close (fd);
@ -785,6 +787,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
it. */
free (realname);
add_name_to_object (l, name);
if (l->l_initfini != NULL)
for (i = 1; l->l_initfini[i] != NULL; ++i)
++l->l_initfini[i]->l_opencount;
++l->l_opencount;
return l;
}
@ -1396,6 +1402,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
/* Look for this name among those already loaded. */
for (l = _dl_loaded; l; l = l->l_next)
{
unsigned int i;
/* If the requested name matches the soname of a loaded object,
use that object. Elide this check for names that have not
yet been opened. */
@ -1408,7 +1416,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
if (l->l_info[DT_SONAME] == NULL)
continue;
soname = (const void *) (D_PTR (l, l_info[DT_STRTAB])
soname = ((const char *) D_PTR (l, l_info[DT_STRTAB])
+ l->l_info[DT_SONAME]->d_un.d_val);
if (strcmp (name, soname) != 0)
continue;
@ -1418,6 +1426,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
}
/* We have a match -- bump the reference count and return it. */
if (l->l_initfini != NULL)
for (i = 1; l->l_initfini[i] != NULL; ++i)
++l->l_initfini[i]->l_opencount;
++l->l_opencount;
return l;
}

View File

@ -129,6 +129,8 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
if (runp != NULL)
{
unsigned int j;
/* The object is still available. Add the reference now. */
if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
{
@ -158,7 +160,11 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
/* And increment the counter in the referenced object. */
/* And increment the counter in the referenced object
and its dependencies. */
if (map->l_initfini != NULL)
for (j = 1; map->l_initfini[j] != NULL; ++j)
++map->l_initfini[j]->l_opencount;
++map->l_opencount;
/* Display information if we are debugging. */

View File

@ -69,10 +69,18 @@ static const struct
#include <include/link.h>
#define OUT \
for (map = _r_debug.r_map; map != NULL; map = map->l_next) \
if (map->l_type == lt_loaded) \
printf ("name = \"%s\", opencount = %d\n", \
map->l_name, (int) map->l_opencount); \
fflush (stdout)
int
main (void)
main (int argc, char *argv[])
{
int debug = argc > 1 && argv[1][0] != '\0';
int count = TEST_ROUNDS;
int result = 0;
@ -85,6 +93,7 @@ main (void)
{
int nr = random () % NTESTS;
int index = tests[nr].index;
struct link_map *map;
printf ("%4d: %4d: ", count + 1, nr);
fflush (stdout);
@ -125,6 +134,9 @@ main (void)
testobjs[index].handle = NULL;
}
if (debug)
OUT;
}
/* Unload all loaded modules. */

View File

@ -1,8 +1,9 @@
#include <dlfcn.h>
#include <libintl.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <link.h>
static int
check_loaded_objects (const char **loaded)
@ -26,7 +27,7 @@ check_loaded_objects (const char **loaded)
for (lm = _r_debug.r_map; lm; lm = lm->l_next)
{
if (lm->l_name && lm->l_name[0])
printf(" %s\n", lm->l_name);
printf(" %s, count = %d\n", lm->l_name, (int) lm->l_opencount);
if (lm->l_type == lt_loaded && lm->l_name)
{
int match = 0;
@ -99,6 +100,6 @@ main (void)
loaded[0] = NULL;
errors += check_loaded_objects (loaded);
if (errors != 0)
printf ("%d errorss found\n", errors);
printf ("%d errors found\n", errors);
return errors;
}

View File

@ -10,7 +10,8 @@
for (map = _r_debug.r_map; map != NULL; map = map->l_next) \
if (map->l_type == lt_loaded) \
printf ("name = \"%s\", opencount = %d\n", \
map->l_name, (int) map->l_opencount)
map->l_name, (int) map->l_opencount); \
fflush (stdout)
int
main (void)