mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 01:33:36 +08:00
Update.
2000-08-19 Ulrich Drepper <drepper@redhat.com> * elf/Versions [ld] (GLIBC_2.2): Export _dl_check_map_versions. * elf/dl-deps.c (_dl_map_object_deps): If object was dependency of a dynamically loaded object remove old l_initfini list. * elf/dl-libc.c (free_mem): Used as __libc_subfreeres callback to remove some dynamically allocated memory blocks in the dynamic loading data structures. * elf/dl-load.c (add_name_to_object): Initialize dont_free to 0. * elf/dl-open.c (dl_open_workder): Don't call _dl_check_all_versions. Instead call _dl_check_map_versions only for the dependencies. * elf/rtld.c: Avoid unneccessary initializations. Mark l_libname information of initial objects as not free-able. * sysdeps/generic/ldsodefs.h (struct libname_list): Add dont_free element. * elf/filter.c: Call mtrace. * elf/restest1.c: Likewise. Close the objects. * elf/loadtest.c: Call mtrace. Check result of dlclose. Print more debug information. * elf/constload1.c: Add comment explaining not freed memory.
This commit is contained in:
parent
003715fa0d
commit
752a2a50d4
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
||||
2000-08-19 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/Versions [ld] (GLIBC_2.2): Export _dl_check_map_versions.
|
||||
* elf/dl-deps.c (_dl_map_object_deps): If object was dependency of
|
||||
a dynamically loaded object remove old l_initfini list.
|
||||
* elf/dl-libc.c (free_mem): Used as __libc_subfreeres callback to
|
||||
remove some dynamically allocated memory blocks in the dynamic
|
||||
loading data structures.
|
||||
* elf/dl-load.c (add_name_to_object): Initialize dont_free to 0.
|
||||
* elf/dl-open.c (dl_open_workder): Don't call _dl_check_all_versions.
|
||||
Instead call _dl_check_map_versions only for the dependencies.
|
||||
* elf/rtld.c: Avoid unneccessary initializations. Mark l_libname
|
||||
information of initial objects as not free-able.
|
||||
* sysdeps/generic/ldsodefs.h (struct libname_list): Add dont_free
|
||||
element.
|
||||
|
||||
* elf/filter.c: Call mtrace.
|
||||
* elf/restest1.c: Likewise. Close the objects.
|
||||
* elf/loadtest.c: Call mtrace. Check result of dlclose. Print more
|
||||
debug information.
|
||||
|
||||
* elf/constload1.c: Add comment explaining not freed memory.
|
||||
|
||||
2000-08-18 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/mips/bits/stat.h: Add pads to show
|
||||
|
@ -18,6 +18,10 @@ main (void)
|
||||
error (EXIT_FAILURE, errno, "cannot load module \"constload2.so\"");
|
||||
foo = dlsym (h, "foo");
|
||||
ret = foo ();
|
||||
/* Note that the following dlclose() call cannot unload the objects.
|
||||
Due to the introduced relocation dependency constload2.so depends
|
||||
on constload3.so and the dependencies of constload2.so on constload3.so
|
||||
is not visible to ld.so since it's done using dlopen(). */
|
||||
if (dlclose (h) != 0)
|
||||
{
|
||||
puts ("failed to close");
|
||||
|
@ -467,6 +467,14 @@ _dl_map_object_deps (struct link_map *map,
|
||||
while (runp != NULL && runp->done);
|
||||
}
|
||||
|
||||
if (map->l_initfini != NULL && map->l_type == lt_loaded)
|
||||
{
|
||||
/* This object was previously loaded as a dependency and we have
|
||||
a separate l_initfini list. We don't need it anymore. */
|
||||
assert (map->l_searchlist.r_list == NULL);
|
||||
free (map->l_initfini);
|
||||
}
|
||||
|
||||
/* Store the search list we built in the object. It will be used for
|
||||
searches in the scope of this object. */
|
||||
map->l_searchlist.r_list = malloc ((2 * nlist + 1
|
||||
|
@ -120,3 +120,27 @@ __libc_dlclose (void *__map)
|
||||
{
|
||||
return dlerror_run (do_dlclose, __map);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_mem (void)
|
||||
{
|
||||
struct link_map *l;
|
||||
|
||||
/* Remove all additional names added to the objects. */
|
||||
for (l = _dl_loaded; l != NULL; l = l->l_next)
|
||||
{
|
||||
struct libname_list *lnp = l->l_libname->next;
|
||||
|
||||
l->l_libname->next = NULL;
|
||||
|
||||
while (lnp != NULL)
|
||||
{
|
||||
struct libname_list *old = lnp;
|
||||
lnp = lnp->next;
|
||||
if (! old->dont_free)
|
||||
free (old);
|
||||
}
|
||||
}
|
||||
}
|
||||
text_set_element (__libc_subfreeres, free_mem);
|
||||
|
@ -322,6 +322,7 @@ add_name_to_object (struct link_map *l, const char *name)
|
||||
|
||||
newname->name = memcpy (newname + 1, name, name_len);
|
||||
newname->next = NULL;
|
||||
newname->dont_free = 0;
|
||||
lastp->next = newname;
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ dl_open_worker (void *a)
|
||||
struct link_map *new, *l;
|
||||
const char *dst;
|
||||
int lazy;
|
||||
unsigned int i;
|
||||
|
||||
/* Maybe we have to expand a DST. */
|
||||
dst = strchr (file, '$');
|
||||
@ -163,7 +164,9 @@ dl_open_worker (void *a)
|
||||
_dl_map_object_deps (new, NULL, 0, 0);
|
||||
|
||||
/* So far, so good. Now check the versions. */
|
||||
(void) _dl_check_all_versions (new, 0, 0);
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
if (new->l_searchlist.r_list[i]->l_versions == NULL)
|
||||
(void) _dl_check_map_versions (new->l_searchlist.r_list[i], 0, 0);
|
||||
|
||||
#ifdef SCOPE_DEBUG
|
||||
show_scope (new);
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <mcheck.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -6,7 +7,11 @@ extern const char *foo (void);
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
const char *s = foo ();
|
||||
const char *s;
|
||||
|
||||
mtrace ();
|
||||
|
||||
s = foo ();
|
||||
|
||||
printf ("called `foo' from `%s'\n", s);
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <mcheck.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -66,10 +67,16 @@ static const struct
|
||||
#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||
|
||||
|
||||
#include <include/link.h>
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int count = TEST_ROUNDS;
|
||||
int result = 0;
|
||||
|
||||
mtrace ();
|
||||
|
||||
/* Just a seed. */
|
||||
srandom (TEST_ROUNDS);
|
||||
@ -102,23 +109,38 @@ main (void)
|
||||
|
||||
fct (10);
|
||||
|
||||
printf ("successfully loaded `%s'\n", testobjs[index].name);
|
||||
printf ("successfully loaded `%s', handle %p\n",
|
||||
testobjs[index].name, testobjs[index].handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
dlclose (testobjs[index].handle);
|
||||
testobjs[index].handle = NULL;
|
||||
if (dlclose (testobjs[index].handle) != 0)
|
||||
{
|
||||
printf ("failed to close %s\n", testobjs[index].name);
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
printf ("successfully unloaded `%s', handle %p\n",
|
||||
testobjs[index].name, testobjs[index].handle);
|
||||
|
||||
printf ("successfully unloaded `%s'\n", testobjs[index].name);
|
||||
testobjs[index].handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unload all loaded modules. */
|
||||
for (count = 0; count < NOBJS; ++count)
|
||||
if (testobjs[count].handle != NULL)
|
||||
dlclose (testobjs[count].handle);
|
||||
{ printf ("\nclose: %s: l_initfini = %p, l_versions = %p\n",
|
||||
testobjs[count].name,
|
||||
((struct link_map*)testobjs[count].handle)->l_initfini,
|
||||
((struct link_map*)testobjs[count].handle)->l_versions);
|
||||
if (dlclose (testobjs[count].handle) != 0)
|
||||
{
|
||||
printf ("failed to close %s\n", testobjs[count].name);
|
||||
result = 1;
|
||||
} }
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <dlfcn.h>
|
||||
#include <error.h>
|
||||
#include <mcheck.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -13,6 +14,8 @@ main (void)
|
||||
int res1;
|
||||
int res2;
|
||||
|
||||
mtrace ();
|
||||
|
||||
h1 = dlopen ("testobj1.so", RTLD_LAZY);
|
||||
if (h1 == NULL)
|
||||
error (EXIT_FAILURE, 0, "while loading `%s': %s", "testobj1.so",
|
||||
@ -37,6 +40,11 @@ main (void)
|
||||
res2 = fp2 (10);
|
||||
printf ("fp1(10) = %d\nfp2(10) = %d\n", res1, res2);
|
||||
|
||||
if (dlclose (h1) != 0)
|
||||
error (EXIT_FAILURE, 0, "cannot close testobj1.so: %s\n", dlerror ());
|
||||
if (dlclose (h2) != 0)
|
||||
error (EXIT_FAILURE, 0, "cannot close testobj1_1.so: %s\n", dlerror ());
|
||||
|
||||
return res1 != 42 || res2 != 72;
|
||||
}
|
||||
|
||||
|
17
elf/rtld.c
17
elf/rtld.c
@ -590,7 +590,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
the shared object is already loaded. */
|
||||
_dl_rtld_libname.name = ((const char *) _dl_loaded->l_addr
|
||||
+ ph->p_vaddr);
|
||||
_dl_rtld_libname.next = NULL;
|
||||
/* _dl_rtld_libname.next = NULL; Already zero. */
|
||||
_dl_rtld_map.l_libname = &_dl_rtld_libname;
|
||||
|
||||
/* Ordinarilly, we would get additional names for the loader from
|
||||
@ -604,7 +604,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
if (p)
|
||||
{
|
||||
_dl_rtld_libname2.name = p+1;
|
||||
_dl_rtld_libname2.next = NULL;
|
||||
/* _dl_rtld_libname2.next = NULL; Already zero. */
|
||||
_dl_rtld_libname.next = &_dl_rtld_libname2;
|
||||
}
|
||||
}
|
||||
@ -626,7 +626,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
/* We were invoked directly, so the program might not have a
|
||||
PT_INTERP. */
|
||||
_dl_rtld_libname.name = _dl_rtld_map.l_name;
|
||||
_dl_rtld_libname.next = NULL;
|
||||
/* _dl_rtld_libname.next = NULL; Alread zero. */
|
||||
_dl_rtld_map.l_libname = &_dl_rtld_libname;
|
||||
}
|
||||
else
|
||||
@ -1059,6 +1059,17 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
HP_TIMING_NOW (start);
|
||||
do
|
||||
{
|
||||
/* While we are at it, help the memory handling a bit. We have to
|
||||
mark some data structures as allocated with the fake malloc()
|
||||
implementation in ld.so. */
|
||||
struct libname_list *lnp = l->l_libname->next;
|
||||
|
||||
while (__builtin_expect (lnp != NULL, 0))
|
||||
{
|
||||
lnp->dont_free = 1;
|
||||
lnp = lnp->next;
|
||||
}
|
||||
|
||||
if (l != &_dl_rtld_map)
|
||||
_dl_relocate_object (l, l->l_scope, _dl_lazy, consider_profiling);
|
||||
|
||||
|
@ -115,6 +115,8 @@ struct libname_list
|
||||
{
|
||||
const char *name; /* Name requested (before search). */
|
||||
struct libname_list *next; /* Link to next name for this object. */
|
||||
int dont_free; /* Flag whether this element should be freed
|
||||
if the object is not entirely unloaded. */
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user