mirror of git://sourceware.org/git/glibc.git
Update.
* elf/dl-close.c (remove_slotinfo): New function. Handles everything for removing reference of module in slotinfo list. (_dl_close): Use remove_slotinfo. * sysdeps/generic/dl-tls.c: General pretty printing. (oom): Define only if SHARED. (_dl_next_tls_modid): Correct starting point for the case we assume there is a gap. Add missing instruction grouping (doh!). Correct tests for reaching maximum index. * elf/Makefile: Add rules to build and run tst-tls7. * elf/tst-tls7.c: New file. * elf/tst-tlsmod3.c: New file. * elf/tst-tlsmod1.c: Move #include "tls-macros.h" instead #ifdef USE_TLS. * elf/tst-tlsmod2.c: Likewise.
This commit is contained in:
parent
bb4cb25213
commit
fc093be160
16
ChangeLog
16
ChangeLog
|
|
@ -1,5 +1,21 @@
|
||||||
2002-02-13 Ulrich Drepper <drepper@redhat.com>
|
2002-02-13 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* elf/dl-close.c (remove_slotinfo): New function. Handles everything
|
||||||
|
for removing reference of module in slotinfo list.
|
||||||
|
(_dl_close): Use remove_slotinfo.
|
||||||
|
* sysdeps/generic/dl-tls.c: General pretty printing.
|
||||||
|
(oom): Define only if SHARED.
|
||||||
|
(_dl_next_tls_modid): Correct starting point for the case we assume
|
||||||
|
there is a gap. Add missing instruction grouping (doh!). Correct
|
||||||
|
tests for reaching maximum index.
|
||||||
|
* elf/Makefile: Add rules to build and run tst-tls7.
|
||||||
|
* elf/tst-tls7.c: New file.
|
||||||
|
* elf/tst-tlsmod3.c: New file.
|
||||||
|
|
||||||
|
* elf/tst-tlsmod1.c: Move #include "tls-macros.h" instead #ifdef
|
||||||
|
USE_TLS.
|
||||||
|
* elf/tst-tlsmod2.c: Likewise.
|
||||||
|
|
||||||
* elf/dl-close.c (_dl_close): When closing an object using TLS
|
* elf/dl-close.c (_dl_close): When closing an object using TLS
|
||||||
either decrement dl_tls_max_dtv_idx or set dl_tls_dtv_gaps to
|
either decrement dl_tls_max_dtv_idx or set dl_tls_dtv_gaps to
|
||||||
true. Increment dl_tls_generation only if we closed any TLS-using
|
true. Increment dl_tls_generation only if we closed any TLS-using
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
|
$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
|
||||||
neededtest3 neededtest4 unload2 lateglobal initfirst global \
|
neededtest3 neededtest4 unload2 lateglobal initfirst global \
|
||||||
restest2 next dblload dblunload reldep5 reldep6 tst-tls1 tst-tls2 \
|
restest2 next dblload dblunload reldep5 reldep6 tst-tls1 tst-tls2 \
|
||||||
tst-tls3 tst-tls4 tst-tls5 tst-tls6
|
tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7
|
||||||
test-srcs = tst-pathopt
|
test-srcs = tst-pathopt
|
||||||
tests-vis-yes = vismain
|
tests-vis-yes = vismain
|
||||||
tests-nodelete-yes = nodelete
|
tests-nodelete-yes = nodelete
|
||||||
|
|
@ -137,7 +137,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \
|
unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \
|
||||||
dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \
|
dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \
|
||||||
reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \
|
reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \
|
||||||
tst-tlsmod1 tst-tlsmod2
|
tst-tlsmod1 tst-tlsmod2 tst-tlsmod3
|
||||||
modules-vis-yes = vismod1 vismod2 vismod3
|
modules-vis-yes = vismod1 vismod2 vismod3
|
||||||
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
|
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
|
||||||
modules-nodlopen-yes = nodlopenmod nodlopenmod2
|
modules-nodlopen-yes = nodlopenmod nodlopenmod2
|
||||||
|
|
@ -292,6 +292,7 @@ $(objpfx)reldep6mod1.so: $(objpfx)reldep6mod0.so
|
||||||
$(objpfx)reldep6mod2.so: $(objpfx)reldep6mod1.so
|
$(objpfx)reldep6mod2.so: $(objpfx)reldep6mod1.so
|
||||||
$(objpfx)reldep6mod3.so: $(objpfx)reldep6mod2.so
|
$(objpfx)reldep6mod3.so: $(objpfx)reldep6mod2.so
|
||||||
$(objpfx)reldep6mod4.so: $(objpfx)reldep6mod1.so
|
$(objpfx)reldep6mod4.so: $(objpfx)reldep6mod1.so
|
||||||
|
$(objpfx)tst-tlsmod3.so: $(objpfx)tst-tlsmod2.so
|
||||||
|
|
||||||
# filtmod1.so has a special rule
|
# filtmod1.so has a special rule
|
||||||
$(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os
|
$(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os
|
||||||
|
|
@ -451,3 +452,6 @@ $(objpfx)tst-tls5.out: $(objpfx)tst-tlsmod2.so
|
||||||
|
|
||||||
$(objpfx)tst-tls6: $(libdl)
|
$(objpfx)tst-tls6: $(libdl)
|
||||||
$(objpfx)tst-tls6.out: $(objpfx)tst-tlsmod2.so
|
$(objpfx)tst-tls6.out: $(objpfx)tst-tlsmod2.so
|
||||||
|
|
||||||
|
$(objpfx)tst-tls7: $(libdl)
|
||||||
|
$(objpfx)tst-tls7.out: $(objpfx)tst-tlsmod3.so
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,58 @@
|
||||||
typedef void (*fini_t) (void);
|
typedef void (*fini_t) (void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_TLS
|
||||||
|
/* Returns true we an non-empty was found. */
|
||||||
|
static bool
|
||||||
|
remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp)
|
||||||
|
{
|
||||||
|
if (idx - disp >= listp->len)
|
||||||
|
{
|
||||||
|
/* There must be a next entry. Otherwise would the index be wrong. */
|
||||||
|
assert (listp->next != NULL);
|
||||||
|
|
||||||
|
if (remove_slotinfo (idx, listp->next, disp + listp->len))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* No non-empty entry. Search from the end of this elements
|
||||||
|
slotinfo array. */
|
||||||
|
idx = disp + listp->len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct link_map *old_map = listp->slotinfo[idx - disp].map;
|
||||||
|
assert (old_map != NULL);
|
||||||
|
|
||||||
|
/* Mark the entry as unused. */
|
||||||
|
listp->slotinfo[idx - disp].gen = GL(dl_tls_generation) + 1;
|
||||||
|
listp->slotinfo[idx - disp].map = NULL;
|
||||||
|
|
||||||
|
/* If this is not the last currently used entry no need to look
|
||||||
|
further. */
|
||||||
|
if (old_map->l_tls_modid != GL(dl_tls_max_dtv_idx))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
assert (old_map->l_tls_modid == GL(dl_tls_max_dtv_idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (idx - disp > disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0)
|
||||||
|
{
|
||||||
|
--idx;
|
||||||
|
|
||||||
|
if (listp->slotinfo[idx - disp].map != NULL)
|
||||||
|
{
|
||||||
|
/* Found a new last used index. */
|
||||||
|
GL(dl_tls_max_dtv_idx) = idx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No non-entry in this list element. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
internal_function
|
internal_function
|
||||||
_dl_close (void *_map)
|
_dl_close (void *_map)
|
||||||
|
|
@ -214,25 +266,12 @@ _dl_close (void *_map)
|
||||||
TLS. */
|
TLS. */
|
||||||
if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
|
if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
|
||||||
{
|
{
|
||||||
/* Locate the entry in the slotinfo array. */
|
|
||||||
size_t idx = imap->l_tls_modid;
|
|
||||||
struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
|
|
||||||
|
|
||||||
while (idx >= listp->len)
|
|
||||||
{
|
|
||||||
idx -= listp->len;
|
|
||||||
listp = listp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
|
|
||||||
listp->slotinfo[idx].map = NULL;
|
|
||||||
|
|
||||||
any_tls = true;
|
any_tls = true;
|
||||||
|
|
||||||
if (imap->l_tls_modid == GL(dl_tls_max_dtv_idx))
|
if (! remove_slotinfo (imap->l_tls_modid,
|
||||||
--GL(dl_tls_max_dtv_idx);
|
GL(dl_tls_dtv_slotinfo_list), 0))
|
||||||
else
|
/* All dynamically loaded modules with TLS are unloaded. */
|
||||||
GL(dl_tls_dtv_gaps) = true;
|
GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <link.h>
|
||||||
|
#include <tls.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define TEST_FUNCTION do_test ()
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
#ifdef USE_TLS
|
||||||
|
static const char modname[] = "tst-tlsmod3.so";
|
||||||
|
int result = 0;
|
||||||
|
int (*fp) (void);
|
||||||
|
void *h;
|
||||||
|
int i;
|
||||||
|
int modid = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
h = dlopen (modname, RTLD_LAZY);
|
||||||
|
if (h == NULL)
|
||||||
|
{
|
||||||
|
printf ("cannot open '%s': %s\n", modname, dlerror ());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dirty test code here: we peek into a private data structure.
|
||||||
|
We make sure that the module gets assigned the same ID every
|
||||||
|
time. The value of the first round is used. */
|
||||||
|
if (modid == -1)
|
||||||
|
modid = ((struct link_map *) h)->l_tls_modid;
|
||||||
|
else if (((struct link_map *) h)->l_tls_modid != modid)
|
||||||
|
{
|
||||||
|
printf ("round %d: modid now %d, initially %d\n",
|
||||||
|
i, ((struct link_map *) h)->l_tls_modid, modid);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = dlsym (h, "in_dso2");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
printf ("cannot get symbol 'in_dso2': %s\n", dlerror ());
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
result |= fp ();
|
||||||
|
|
||||||
|
dlclose (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "../test-skeleton.c"
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
|
|
||||||
|
#ifdef USE_TLS
|
||||||
#include "tls-macros.h"
|
#include "tls-macros.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TLS
|
|
||||||
/* One define int variable, two externs. */
|
/* One define int variable, two externs. */
|
||||||
COMMON_INT_DEF(foo);
|
COMMON_INT_DEF(foo);
|
||||||
VAR_INT_DEF(bar);
|
VAR_INT_DEF(bar);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#include "tls-macros.h"
|
|
||||||
|
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
|
#include "tls-macros.h"
|
||||||
|
|
||||||
|
|
||||||
COMMON_INT_DEF(foo);
|
COMMON_INT_DEF(foo);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <tls.h>
|
||||||
|
#include "tls-macros.h"
|
||||||
|
|
||||||
|
#ifdef USE_TLS
|
||||||
|
extern int in_dso (int n, int *caller_foop);
|
||||||
|
|
||||||
|
COMMON_INT_DEF(comm_n);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
in_dso2 (void)
|
||||||
|
{
|
||||||
|
int *foop = TLS_GD (foo);
|
||||||
|
int result = 0;
|
||||||
|
static int n;
|
||||||
|
int *np = TLS_GD (comm_n);
|
||||||
|
|
||||||
|
if (n != *np)
|
||||||
|
{
|
||||||
|
printf ("n = %d != comm_n = %d\n", n, *np);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result |= in_dso (*foop = 42 + n++, foop);
|
||||||
|
|
||||||
|
*foop = 16;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -29,14 +29,15 @@
|
||||||
/* We don't need any of this if TLS is not supported. */
|
/* We don't need any of this if TLS is not supported. */
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
|
|
||||||
#include <dl-tls.h>
|
# include <dl-tls.h>
|
||||||
#include <ldsodefs.h>
|
# include <ldsodefs.h>
|
||||||
|
|
||||||
/* Value used for dtv entries for which the allocation is delayed. */
|
/* Value used for dtv entries for which the allocation is delayed. */
|
||||||
# define TLS_DTV_UNALLOCATED ((void *) -1l)
|
# define TLS_DTV_UNALLOCATED ((void *) -1l)
|
||||||
|
|
||||||
|
|
||||||
/* Out-of-memory handler. */
|
/* Out-of-memory handler. */
|
||||||
|
# ifdef SHARED
|
||||||
static void
|
static void
|
||||||
__attribute__ ((__noreturn__))
|
__attribute__ ((__noreturn__))
|
||||||
oom (void)
|
oom (void)
|
||||||
|
|
@ -57,6 +58,7 @@ cannot allocate memory for thread-local data: ABORT\n";
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -75,16 +77,20 @@ _dl_next_tls_modid (void)
|
||||||
start since there are no gaps at that time. Therefore it
|
start since there are no gaps at that time. Therefore it
|
||||||
does not matter that the dl_tls_dtv_slotinfo is not allocated
|
does not matter that the dl_tls_dtv_slotinfo is not allocated
|
||||||
yet when the function is called for the first times. */
|
yet when the function is called for the first times. */
|
||||||
result = GL(dl_tls_static_nelem);
|
result = GL(dl_tls_static_nelem) + 1;
|
||||||
assert (result < GL(dl_tls_max_dtv_idx));
|
/* If the following would not be true we mustn't have assumed
|
||||||
|
there is a gap. */
|
||||||
|
assert (result <= GL(dl_tls_max_dtv_idx));
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (result - disp < runp->len)
|
while (result - disp < runp->len)
|
||||||
|
{
|
||||||
if (runp->slotinfo[result - disp].map == NULL)
|
if (runp->slotinfo[result - disp].map == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
++result;
|
++result;
|
||||||
assert (result <= GL(dl_tls_max_dtv_idx) + 1);
|
assert (result <= GL(dl_tls_max_dtv_idx) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (result - disp < runp->len)
|
if (result - disp < runp->len)
|
||||||
break;
|
break;
|
||||||
|
|
@ -93,11 +99,11 @@ _dl_next_tls_modid (void)
|
||||||
}
|
}
|
||||||
while ((runp = runp->next) != NULL);
|
while ((runp = runp->next) != NULL);
|
||||||
|
|
||||||
if (result >= GL(dl_tls_max_dtv_idx) + 1)
|
if (result >= GL(dl_tls_max_dtv_idx))
|
||||||
{
|
{
|
||||||
/* The new index must indeed be exactly one higher than the
|
/* The new index must indeed be exactly one higher than the
|
||||||
previous high. */
|
previous high. */
|
||||||
assert (result == GL(dl_tls_max_dtv_idx) + 1);
|
assert (result == GL(dl_tls_max_dtv_idx));
|
||||||
|
|
||||||
/* There is no gap anymore. */
|
/* There is no gap anymore. */
|
||||||
GL(dl_tls_dtv_gaps) = false;
|
GL(dl_tls_dtv_gaps) = false;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue