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.
This commit is contained in:
Ulrich Drepper 2004-10-27 20:27:40 +00:00
parent 778cddad17
commit b1f6875087
4 changed files with 93 additions and 66 deletions

View File

@ -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> 2004-10-27 Jakub Jelinek <jakub@redhat.com>
* sysdeps/generic/glob.c (globfree): Clear gl_pathv after freeing it. * sysdeps/generic/glob.c (globfree): Clear gl_pathv after freeing it.

View File

@ -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 \ 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 \ tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount \ $(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 # reldep9
test-srcs = tst-pathopt test-srcs = tst-pathopt
tests-vis-yes = vismain tests-vis-yes = vismain
@ -770,3 +770,6 @@ $(objpfx)tst-dlmopen1.out: $(objpfx)tst-dlmopen1mod.so
$(objpfx)tst-dlmopen2: $(libdl) $(objpfx)tst-dlmopen2: $(libdl)
$(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so $(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so
$(objpfx)tst-dlmopen3: $(libdl)
$(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so

View File

@ -42,23 +42,18 @@ _dl_fini (void)
using `dlopen' there are possibly several other modules with its using `dlopen' there are possibly several other modules with its
dependencies to be taken into account. Therefore we have to start dependencies to be taken into account. Therefore we have to start
determining the order of the modules once again from the beginning. */ 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; struct link_map **maps = NULL;
size_t maps_size = 0; size_t maps_size = 0;
/* We First run the destructors of the main namespaces, then the /* We run the destructors of the main namespaces last. As for the
other ones. The order should not matter since the namespace other namespaces, we pick run the destructors in them in reverse
content is supposed to be independent. But we can have auditing order of the namespace ID. */
code in a auxiliaty namespace and we want it to monitor the for (Lmid_t cnt = DL_NNS - 1; cnt >= 0; --cnt)
destructors. */
for (Lmid_t cnt = 0; cnt < DL_NNS; ++cnt)
{ {
/* Protect against concurrent loads and unloads. */ /* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock)); __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 /* XXX Could it be (in static binaries) that there is no object
loaded? */ loaded? */
@ -79,20 +74,20 @@ _dl_fini (void)
nloaded * sizeof (struct link_map *)); 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) for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
{ /* Do not handle ld.so in secondary namespaces. */
assert (i < nloaded); if (l == l->l_real)
{
assert (i < nloaded);
/* Do not handle ld.so in secondary namespaces. */ maps[i++] = l;
if (l == l->l_real)
{
maps[i++] = l;
/* Bump l_opencount of all objects so that they are not /* Bump l_opencount of all objects so that they are not
dlclose()ed from underneath us. */ dlclose()ed from underneath us. */
++l->l_opencount; ++l->l_opencount;
} }
}
assert (cnt != LM_ID_BASE || i == nloaded); assert (cnt != LM_ID_BASE || i == nloaded);
assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1); assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
unsigned int nmaps = i; unsigned int nmaps = i;
@ -105,46 +100,23 @@ _dl_fini (void)
/* The main executable always comes first. */ /* The main executable always comes first. */
l = l->l_next; l = l->l_next;
for (; l != NULL; l = l->l_next) for (; l != NULL; l = l->l_next)
{ /* Do not handle ld.so in secondary namespaces. */
unsigned int j; if (l == l->l_real)
unsigned int k; {
/* 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 the place in the 'maps' array. */ /* Find all object for which the current one is a dependency
for (j = 1; maps[j] != l; ++j) and move the found object (if necessary) in front. */
; for (unsigned int k = j + 1; k < nmaps; ++k)
{
/* Find all object for which the current one is a dependency and struct link_map **runp = maps[k]->l_initfini;
move the found object (if necessary) in front. */ if (runp != NULL)
for (k = j + 1; k < nmaps; ++k) {
{ while (*runp != NULL)
struct link_map **runp = maps[k]->l_initfini; if (*runp == l)
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)
{ {
struct link_map *here = maps[k]; struct link_map *here = maps[k];
@ -152,14 +124,37 @@ _dl_fini (void)
memmove (&maps[j] + 1, memmove (&maps[j] + 1,
&maps[j], &maps[j],
(k - j) * sizeof (struct link_map *)); (k - j) * sizeof (struct link_map *));
maps[j] = here; maps[j++] = here;
break; 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 /* We do not rely on the linked list of loaded object anymore from

View File

@ -3,6 +3,16 @@
#include <gnu/lib-names.h> #include <gnu/lib-names.h>
static int cnt;
static void
__attribute ((constructor))
constr (void)
{
++cnt;
}
int int
foo (Lmid_t ns2) foo (Lmid_t ns2)
{ {
@ -34,5 +44,16 @@ foo (Lmid_t ns2)
return 1; 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; return 0;
} }