summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-10-21 06:02:49 +0000
committerUlrich Drepper <drepper@redhat.com>2000-10-21 06:02:49 +0000
commit8699e7b1daa5d250b8bc69e1ecffae80170277e5 (patch)
tree6ee2841f9875e4bf2d1f73f1539b0ad3bd9b5406
parentf6de2239e2cb1af87b36dbd8712bd27f42ae7d54 (diff)
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.
-rw-r--r--ChangeLog11
-rw-r--r--elf/dl-close.c11
-rw-r--r--elf/dl-deps.c18
-rw-r--r--elf/dl-load.c15
-rw-r--r--elf/dl-lookup.c8
-rw-r--r--elf/loadtest.c14
-rw-r--r--elf/neededtest.c9
-rw-r--r--elf/unload2.c3
8 files changed, 71 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index a42615d10e..ba79bf8855 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 8426e73ec9..cb6b6fc381 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 44838d6208..566073eb7a 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 b2f5ad7a1c..55725c3cb3 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 581c6a6c2b..d9476817c3 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 80f99607ec..4a3c4c08be 100644
--- a/elf/loadtest.c
+++ b/elf/loadtest.c
@@ -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. */
diff --git a/elf/neededtest.c b/elf/neededtest.c
index 053d5528aa..98f69a3185 100644
--- a/elf/neededtest.c
+++ b/elf/neededtest.c
@@ -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;
}
diff --git a/elf/unload2.c b/elf/unload2.c
index b544e794c8..7a38053433 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)