mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 11:43:34 +08:00
4c533566c2
* elf/dl-close.c (_dl_close): Check for it. * elf/dl-reloc.c (CHECK_STATIC_TLS): Likewise. (_dl_allocate_static_tls): Likewise. * elf/dl-tls.c (_dl_allocate_tls_init): Likewise. (__tls_get_addr): Protect from race conditions in setting l_tls_offset to it. * elf/tst-tls16.c: New file. * elf/tst-tlsmod16a.c: New file. * elf/tst-tlsmod16b.c: New file. * elf/Makefile: Add rules to build and run tst-tls16.
53 lines
1.3 KiB
C
53 lines
1.3 KiB
C
#include <dlfcn.h>
|
|
#include <stdio.h>
|
|
|
|
static int
|
|
do_test (void)
|
|
{
|
|
void *h = dlopen ("tst-tlsmod16a.so", RTLD_LAZY | RTLD_GLOBAL);
|
|
if (h == NULL)
|
|
{
|
|
puts ("unexpectedly failed to open tst-tlsmod16a.so");
|
|
exit (1);
|
|
}
|
|
|
|
void *p = dlsym (h, "tlsvar");
|
|
|
|
/* This dlopen should indeed fail, because tlsvar was assigned to
|
|
dynamic TLS, and the new module requests it to be in static TLS.
|
|
However, there's a possibility that dlopen succeeds if the
|
|
variable is, for whatever reason, assigned to static TLS, or if
|
|
the module fails to require static TLS, or even if TLS is not
|
|
supported. */
|
|
h = dlopen ("tst-tlsmod16b.so", RTLD_NOW | RTLD_GLOBAL);
|
|
if (h == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
puts ("unexpectedly succeeded to open tst-tlsmod16b.so");
|
|
|
|
|
|
void *(*fp) (void) = (void *(*) (void)) dlsym (h, "in_dso");
|
|
if (fp == NULL)
|
|
{
|
|
puts ("cannot find in_dso");
|
|
exit (1);
|
|
}
|
|
|
|
/* If the dlopen passes, at least make sure the address returned by
|
|
dlsym is the same as that returned by the initial-exec access.
|
|
If the variable was assigned to dynamic TLS during dlsym, this
|
|
portion will fail. */
|
|
if (fp () != p)
|
|
{
|
|
puts ("returned values do not match");
|
|
exit (1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define TEST_FUNCTION do_test ()
|
|
#include "../test-skeleton.c"
|