From 8699e7b1daa5d250b8bc69e1ecffae80170277e5 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 21 Oct 2000 06:02:49 +0000 Subject: [PATCH] Update. * 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. --- ChangeLog | 11 +++++++++++ elf/dl-close.c | 11 +++++++---- elf/dl-deps.c | 18 +++++++++++++----- elf/dl-load.c | 15 +++++++++++++-- elf/dl-lookup.c | 8 +++++++- elf/loadtest.c | 14 +++++++++++++- elf/neededtest.c | 9 +++++---- elf/unload2.c | 3 ++- 8 files changed, 71 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index a42615d..ba79bf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2000-10-20 Ulrich Drepper + * 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. diff --git a/elf/dl-close.c b/elf/dl-close.c index 8426e73..cb6b6fc 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -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; diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 44838d6..566073e 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -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. */ - --dep->l_opencount; + { + /* 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) diff --git a/elf/dl-load.c b/elf/dl-load.c index b2f5ad7..55725c3 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -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,8 +1416,8 @@ _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]) - + l->l_info[DT_SONAME]->d_un.d_val); + 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; } diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 581c6a6..d947681 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -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. */ diff --git a/elf/loadtest.c b/elf/loadtest.c index 80f9960..4a3c4c0 100644 --- a/elf/loadtest.c +++ b/elf/loadtest.c @@ -69,10 +69,18 @@ static const struct #include +#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. */ diff --git a/elf/neededtest.c b/elf/neededtest.c index 053d552..98f69a3 100644 --- a/elf/neededtest.c +++ b/elf/neededtest.c @@ -1,8 +1,9 @@ +#include +#include +#include #include #include #include -#include -#include 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; } diff --git a/elf/unload2.c b/elf/unload2.c index b544e79..7a38053 100644 --- a/elf/unload2.c +++ b/elf/unload2.c @@ -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) -- 2.7.4