aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2005-04-06 02:50:11 +0000
committerRoland McGrath <roland@gnu.org>2005-04-06 02:50:11 +0000
commit83973e6aa379621135d5c5e7a5f87eac08d2c0f8 (patch)
tree65c71927e5ffad21eaab2e282f98e283d428a472
parentcd107adf8b6084891dc7f8909abf12060f3ca112 (diff)
downloadglibc-83973e6aa379621135d5c5e7a5f87eac08d2c0f8.tar
glibc-83973e6aa379621135d5c5e7a5f87eac08d2c0f8.tar.gz
glibc-83973e6aa379621135d5c5e7a5f87eac08d2c0f8.tar.bz2
glibc-83973e6aa379621135d5c5e7a5f87eac08d2c0f8.zip
2005-03-18 Ulrich Drepper <drepper@redhat.com>
[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.
-rw-r--r--elf/circleload1.c2
-rw-r--r--elf/dl-deps.c2
-rw-r--r--elf/dl-load.c5
-rw-r--r--elf/do-lookup.h4
-rw-r--r--elf/loadtest.c8
-rw-r--r--elf/neededtest.c2
-rw-r--r--elf/neededtest2.c2
-rw-r--r--elf/neededtest3.c2
-rw-r--r--elf/neededtest4.c2
-rw-r--r--elf/unload.c4
-rw-r--r--elf/unload2.c4
-rw-r--r--include/link.h6
12 files changed, 24 insertions, 19 deletions
diff --git a/elf/circleload1.c b/elf/circleload1.c
index 7ac101a799..1fb885cf50 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 a1c16d7310..acc8fc3a07 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 17b90ae8b8..85e03720c6 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 e57d9df26d..88de3fe26f 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 6b8f4bb7d0..ee106ea152 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 e6e99bfc6d..6c7a952066 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 cf111bc303..b682f15792 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 38b3c6c6b7..ea1dcf4794 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 04ab10e4c9..7514bed499 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 4fd82b7e3a..ffb33482c0 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 7a38053433..e14c6f06af 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 3078b72a87..7c801e94ee 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;