From: Roland McGrath Date: Wed, 6 Apr 2005 02:50:11 +0000 (+0000) Subject: 2005-03-18 Ulrich Drepper X-Git-Tag: cvs/glibc-2_3_5~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83973e6aa379621135d5c5e7a5f87eac08d2c0f8;p=thirdparty%2Fglibc.git 2005-03-18 Ulrich Drepper [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. --- diff --git a/elf/circleload1.c b/elf/circleload1.c index 7ac101a799c..1fb885cf507 100644 --- a/elf/circleload1.c +++ b/elf/circleload1.c @@ -27,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, count = %d\n", lm->l_name, (int) lm->l_opencount); + printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount); if (lm->l_type == lt_loaded && lm->l_name) { int match = 0; diff --git a/elf/dl-deps.c b/elf/dl-deps.c index a1c16d73106..acc8fc3a072 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -566,8 +566,6 @@ Filters not supported with LD_TRACE_PRELINKING")); { /* A direct or transitive dependency is also on the list of relocation dependencies. Remove the latter. */ - --map->l_reldeps[i]->l_opencount; - for (j = i + 1; j < map->l_reldepsact; ++j) map->l_reldeps[j - 1] = map->l_reldeps[j]; diff --git a/elf/dl-load.c b/elf/dl-load.c index 17b90ae8b86..85e03720c6e 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -841,7 +841,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, /* Look again to see if the real name matched another already loaded. */ for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next) - if (l->l_ino == st.st_ino && l->l_dev == st.st_dev) + if (l->l_removed == 0 && l->l_ino == st.st_ino && l->l_dev == st.st_dev) { /* The object is already loaded. Just bump its reference count and return it. */ @@ -1826,7 +1826,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, /* 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. */ - if (__builtin_expect (l->l_faked, 0) != 0) + if (__builtin_expect (l->l_faked, 0) != 0 + || __builtin_expect (l->l_removed, 0) != 0) continue; if (!_dl_name_match_p (name, l)) { diff --git a/elf/do-lookup.h b/elf/do-lookup.h index e57d9df26da..88de3fe26f2 100644 --- a/elf/do-lookup.h +++ b/elf/do-lookup.h @@ -52,6 +52,10 @@ do_lookup_x (const char *undef_name, unsigned long int hash, if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable) continue; + /* Do not look into objects which are going to be removed. */ + if (map->l_removed) + continue; + /* Print some debugging info if wanted. */ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0)) _dl_debug_printf ("symbol=%s; lookup in file=%s\n", diff --git a/elf/loadtest.c b/elf/loadtest.c index 6b8f4bb7d08..ee106ea1523 100644 --- a/elf/loadtest.c +++ b/elf/loadtest.c @@ -73,8 +73,8 @@ static const struct #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); \ + printf ("name = \"%s\", direct_opencount = %d\n", \ + map->l_name, (int) map->l_direct_opencount); \ fflush (stdout) @@ -183,8 +183,8 @@ main (int argc, char *argv[]) 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); + printf ("name = \"%s\", direct_opencount = %d\n", + map->l_name, (int) map->l_direct_opencount); result = 1; } diff --git a/elf/neededtest.c b/elf/neededtest.c index e6e99bfc6db..6c7a952066c 100644 --- a/elf/neededtest.c +++ b/elf/neededtest.c @@ -27,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, count = %d\n", lm->l_name, (int) lm->l_opencount); + printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount); if (lm->l_type == lt_loaded && lm->l_name) { int match = 0; diff --git a/elf/neededtest2.c b/elf/neededtest2.c index cf111bc303d..b682f15792b 100644 --- a/elf/neededtest2.c +++ b/elf/neededtest2.c @@ -27,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, count = %d\n", lm->l_name, (int) lm->l_opencount); + printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount); if (lm->l_type == lt_loaded && lm->l_name) { int match = 0; diff --git a/elf/neededtest3.c b/elf/neededtest3.c index 38b3c6c6b71..ea1dcf47949 100644 --- a/elf/neededtest3.c +++ b/elf/neededtest3.c @@ -27,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, count = %d\n", lm->l_name, (int) lm->l_opencount); + printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount); if (lm->l_type == lt_loaded && lm->l_name) { int match = 0; diff --git a/elf/neededtest4.c b/elf/neededtest4.c index 04ab10e4c9b..7514bed4990 100644 --- a/elf/neededtest4.c +++ b/elf/neededtest4.c @@ -27,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, count = %d\n", lm->l_name, (int) lm->l_opencount); + printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount); if (lm->l_type == lt_loaded && lm->l_name) { int match = 0; diff --git a/elf/unload.c b/elf/unload.c index 4fd82b7e3a2..ffb33482c0d 100644 --- a/elf/unload.c +++ b/elf/unload.c @@ -12,8 +12,8 @@ #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); \ + printf ("name = \"%s\", direct_opencount = %d\n", \ + map->l_name, (int) map->l_direct_opencount); \ fflush (stdout) typedef struct diff --git a/elf/unload2.c b/elf/unload2.c index 7a380534338..e14c6f06afd 100644 --- a/elf/unload2.c +++ b/elf/unload2.c @@ -9,8 +9,8 @@ #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); \ + printf ("name = \"%s\", direct_opencount = %d\n", \ + map->l_name, (int) map->l_direct_opencount); \ fflush (stdout) int diff --git a/include/link.h b/include/link.h index 3078b72a87c..7c801e94ee5 100644 --- a/include/link.h +++ b/include/link.h @@ -177,7 +177,7 @@ struct link_map Elf_Symndx l_nbuckets; const Elf_Symndx *l_buckets, *l_chain; - unsigned int l_opencount; /* Counter for direct and indirect usage. */ + unsigned int l_dummy_opencount; /* Used to be l_opencount, now unused. */ unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose. */ enum /* Where this object came from. */ { @@ -199,6 +199,8 @@ struct link_map should be called on this link map when relocation finishes. */ unsigned int l_used:1; /* Nonzero if the DSO is used. */ + unsigned int l_removed:1; /* Nozero if the object cannot be used anymore + since it is removed. */ /* Array with version names. */ unsigned int l_nversions; struct r_found_version *l_versions; @@ -255,7 +257,7 @@ struct link_map ElfW(Word) l_flags; /* Temporarily used in `dl_close'. */ - unsigned int l_idx; + int l_idx; struct link_map_machine l_mach;