mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
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.
This commit is contained in:
parent
778cddad17
commit
b1f6875087
@ -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.
|
||||||
|
@ -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
|
||||||
|
125
elf/dl-fini.c
125
elf/dl-fini.c
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user