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.
/* 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)
{
"\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;
++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. */
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)
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);
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;
}
/* 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. */
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;
}
/* 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;
}
if (runp != NULL)
{
+ unsigned int j;
+
/* The object is still available. Add the reference now. */
if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
{
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. */
#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;
{
int nr = random () % NTESTS;
int index = tests[nr].index;
+ struct link_map *map;
printf ("%4d: %4d: ", count + 1, nr);
fflush (stdout);
testobjs[index].handle = NULL;
}
+
+ if (debug)
+ OUT;
}
/* Unload all loaded modules. */
+#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)
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;
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;
}
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)