Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Ulrich Drepper committed Aug 19, 2000
1 parent 003715f commit 752a2a5
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 11 deletions.
23 changes: 23 additions & 0 deletions 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
Expand Down
4 changes: 4 additions & 0 deletions elf/constload1.c
Expand Up @@ -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");
Expand Down
8 changes: 8 additions & 0 deletions elf/dl-deps.c
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions elf/dl-libc.c
Expand Up @@ -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);
1 change: 1 addition & 0 deletions elf/dl-load.c
Expand Up @@ -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;
}

Expand Down
5 changes: 4 additions & 1 deletion elf/dl-open.c
Expand Up @@ -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, '$');
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion elf/filter.c
@@ -1,3 +1,4 @@
#include <mcheck.h>
#include <stdio.h>
#include <string.h>

Expand All @@ -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);

Expand Down
34 changes: 28 additions & 6 deletions elf/loadtest.c
Expand Up @@ -2,6 +2,7 @@
#include <dlfcn.h>
#include <errno.h>
#include <error.h>
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}


Expand Down
8 changes: 8 additions & 0 deletions elf/restest1.c
@@ -1,5 +1,6 @@
#include <dlfcn.h>
#include <error.h>
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>

Expand All @@ -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",
Expand All @@ -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;
}

Expand Down
17 changes: 14 additions & 3 deletions elf/rtld.c
Expand Up @@ -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
Expand All @@ -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;
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions sysdeps/generic/ldsodefs.h
Expand Up @@ -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. */
};


Expand Down

0 comments on commit 752a2a5

Please sign in to comment.