mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 08:11:08 +00:00
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.
This commit is contained in:
parent
f6de2239e2
commit
8699e7b1da
11
ChangeLog
11
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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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. */
|
||||
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)
|
||||
|
@ -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,7 +1416,7 @@ _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])
|
||||
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;
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user