Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update.
2004-10-27  Ulrich Drepper  <drepper@redhat.com>

	* elf/dl-fini.c (_dl_fini): Fix search for map in maps array.
	Reverse order of namespaces.
	* elf/Makefile: Add rules to build and run tst-dlmopen3.
	* elf/tst-dlmopen3.c: New file.
	* elf/tst-dlmopen1mod.c: Add check whether constructor runs.
  • Loading branch information
Ulrich Drepper committed Oct 27, 2004
1 parent 778cdda commit b1f6875
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 67 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
@@ -1,3 +1,11 @@
2004-10-27 Ulrich Drepper <drepper@redhat.com>

* elf/dl-fini.c (_dl_fini): Fix search for map in maps array.
Reverse order of namespaces.
* elf/Makefile: Add rules to build and run tst-dlmopen3.
* elf/tst-dlmopen3.c: New file.
* elf/tst-dlmopen1mod.c: Add check whether constructor runs.

2004-10-27 Jakub Jelinek <jakub@redhat.com>

* sysdeps/generic/glob.c (globfree): Clear gl_pathv after freeing it.
Expand Down
5 changes: 4 additions & 1 deletion elf/Makefile
Expand Up @@ -154,7 +154,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2
tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3
# reldep9
test-srcs = tst-pathopt
tests-vis-yes = vismain
Expand Down Expand Up @@ -770,3 +770,6 @@ $(objpfx)tst-dlmopen1.out: $(objpfx)tst-dlmopen1mod.so

$(objpfx)tst-dlmopen2: $(libdl)
$(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so

$(objpfx)tst-dlmopen3: $(libdl)
$(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
127 changes: 61 additions & 66 deletions elf/dl-fini.c
Expand Up @@ -42,23 +42,18 @@ _dl_fini (void)
using `dlopen' there are possibly several other modules with its
dependencies to be taken into account. Therefore we have to start
determining the order of the modules once again from the beginning. */
unsigned int i;
unsigned int nloaded;
struct link_map *l;
struct link_map **maps = NULL;
size_t maps_size = 0;

/* We First run the destructors of the main namespaces, then the
other ones. The order should not matter since the namespace
content is supposed to be independent. But we can have auditing
code in a auxiliaty namespace and we want it to monitor the
destructors. */
for (Lmid_t cnt = 0; cnt < DL_NNS; ++cnt)
/* We run the destructors of the main namespaces last. As for the
other namespaces, we pick run the destructors in them in reverse
order of the namespace ID. */
for (Lmid_t cnt = DL_NNS - 1; cnt >= 0; --cnt)
{
/* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock));

nloaded = GL(dl_ns)[cnt]._ns_nloaded;
unsigned int nloaded = GL(dl_ns)[cnt]._ns_nloaded;

/* XXX Could it be (in static binaries) that there is no object
loaded? */
Expand All @@ -79,20 +74,20 @@ _dl_fini (void)
nloaded * sizeof (struct link_map *));
}

unsigned int i;
struct link_map *l;
for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
{
assert (i < nloaded);
/* Do not handle ld.so in secondary namespaces. */
if (l == l->l_real)
{
assert (i < nloaded);

/* Do not handle ld.so in secondary namespaces. */
if (l == l->l_real)
{
maps[i++] = l;
maps[i++] = l;

/* Bump l_opencount of all objects so that they are not
dlclose()ed from underneath us. */
++l->l_opencount;
}
}
/* Bump l_opencount of all objects so that they are not
dlclose()ed from underneath us. */
++l->l_opencount;
}
assert (cnt != LM_ID_BASE || i == nloaded);
assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
unsigned int nmaps = i;
Expand All @@ -105,61 +100,61 @@ _dl_fini (void)
/* The main executable always comes first. */
l = l->l_next;
for (; l != NULL; l = l->l_next)
{
unsigned int j;
unsigned int k;

/* Find the place in the 'maps' array. */
for (j = 1; maps[j] != l; ++j)
;

/* Find all object for which the current one is a dependency and
move the found object (if necessary) in front. */
for (k = j + 1; k < nmaps; ++k)
{
struct link_map **runp = maps[k]->l_initfini;
if (runp != NULL)
{
while (*runp != NULL)
if (*runp == l)
{
struct link_map *here = maps[k];

/* Move it now. */
memmove (&maps[j] + 1,
&maps[j],
(k - j) * sizeof (struct link_map *));
maps[j++] = here;

break;
}
else
++runp;
}

if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
{
unsigned int m = maps[k]->l_reldepsact;
struct link_map **relmaps = maps[k]->l_reldeps;

while (m-- > 0)
{
if (relmaps[m] == l)
/* Do not handle ld.so in secondary namespaces. */
if (l == l->l_real)
{
/* Find the place in the 'maps' array. */
unsigned int j;
for (j = cnt == LM_ID_BASE ? 1 : 0; maps[j] != l; ++j)
assert (j < nmaps);

/* Find all object for which the current one is a dependency
and move the found object (if necessary) in front. */
for (unsigned int k = j + 1; k < nmaps; ++k)
{
struct link_map **runp = maps[k]->l_initfini;
if (runp != NULL)
{
while (*runp != NULL)
if (*runp == l)
{
struct link_map *here = maps[k];

/* Move it now. */
memmove (&maps[j] + 1,
&maps[j],
(k - j) * sizeof (struct link_map *));
maps[j] = here;
maps[j++] = here;

break;
}
}
}
}
}
else
++runp;
}

if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
{
unsigned int m = maps[k]->l_reldepsact;
struct link_map **relmaps = maps[k]->l_reldeps;

while (m-- > 0)
{
if (relmaps[m] == l)
{
struct link_map *here = maps[k];

/* Move it now. */
memmove (&maps[j] + 1,
&maps[j],
(k - j) * sizeof (struct link_map *));
maps[j] = here;

break;
}
}
}
}
}
}

/* We do not rely on the linked list of loaded object anymore from
Expand Down
21 changes: 21 additions & 0 deletions elf/tst-dlmopen1mod.c
Expand Up @@ -3,6 +3,16 @@
#include <gnu/lib-names.h>


static int cnt;

static void
__attribute ((constructor))
constr (void)
{
++cnt;
}


int
foo (Lmid_t ns2)
{
Expand Down Expand Up @@ -34,5 +44,16 @@ foo (Lmid_t ns2)
return 1;
}

if (cnt == 0)
{
puts ("constructor did not run");
return 1;
}
else if (cnt != 1)
{
puts ("constructor did not run exactly once");
return 1;
}

return 0;
}

0 comments on commit b1f6875

Please sign in to comment.