mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
Update.
2003-07-30 Jakub Jelinek <jakub@redhat.com> * elf/dl-reloc.c (_dl_allocate_static_tls): Don't return any value, call dl_signal_error directly. If already relocated, call GL(dl_init_static_tls) directly, otherwise queue it for later. (CHECK_STATIC_TLS): Undo 2003-07-24 change. * elf/rtld.c (dl_main): Initialize GL(dl_init_static_tls). * elf/dl-open.c (dl_open_worker): Call GL_dl_init_static_tls for all static TLS initializations delayed in _dl_allocate_static_tls. * elf/dl-support.c (_dl_init_static_tls): New variable. * include/link.h (struct link_map): Add l_need_tls_init. * sysdeps/generic/ldsodefs.h (_rtld_global): Add _dl_init_static_tls. (_dl_nothread_init_static_tls): New prototype. (_dl_allocate_static_tls): Adjust prototype. * elf/tls-macros.h (VAR_INT_DEF): Add alignment directive. elf_machine_rela_relative): Adjust. (CHECK_STATIC_TLS): _dl_allocate_static_tls can fail now.
This commit is contained in:
parent
9722e6f3e2
commit
adc12574e5
21
ChangeLog
21
ChangeLog
@ -1,3 +1,20 @@
|
||||
2003-07-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/dl-reloc.c (_dl_allocate_static_tls): Don't return any value,
|
||||
call dl_signal_error directly. If already relocated, call
|
||||
GL(dl_init_static_tls) directly, otherwise queue it for later.
|
||||
(CHECK_STATIC_TLS): Undo 2003-07-24 change.
|
||||
* elf/rtld.c (dl_main): Initialize GL(dl_init_static_tls).
|
||||
* elf/dl-open.c (dl_open_worker): Call GL_dl_init_static_tls
|
||||
for all static TLS initializations delayed in _dl_allocate_static_tls.
|
||||
* elf/dl-support.c (_dl_init_static_tls): New variable.
|
||||
* include/link.h (struct link_map): Add l_need_tls_init.
|
||||
* sysdeps/generic/ldsodefs.h (_rtld_global): Add _dl_init_static_tls.
|
||||
(_dl_nothread_init_static_tls): New prototype.
|
||||
(_dl_allocate_static_tls): Adjust prototype.
|
||||
|
||||
* elf/tls-macros.h (VAR_INT_DEF): Add alignment directive.
|
||||
|
||||
2003-07-31 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* elf/dynamic-link.h (elf_machine_rel, elf_machine_rela,
|
||||
@ -26,7 +43,7 @@
|
||||
* sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela,
|
||||
elf_machine_rela_relative): Adjust.
|
||||
* sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela,
|
||||
elf_machine_rela_relative):
|
||||
elf_machine_rela_relative): Adjust.
|
||||
* sysdeps/sh/dl-machine.h (elf_machine_rela,
|
||||
elf_machine_rela_relative): Adjust.
|
||||
* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela,
|
||||
@ -123,7 +140,7 @@
|
||||
* elf/rtld.c (_dl_start_final, _dl_start, dl_main): Likewise.
|
||||
* elf/dl-reloc.c (_dl_allocate_static_tls): Change return type to int.
|
||||
Take l_tls_firstbyte_offset information into account.
|
||||
(CHECK_STATIS_TLS): _dl_allocate_static_tls can fail now.
|
||||
(CHECK_STATIC_TLS): _dl_allocate_static_tls can fail now.
|
||||
* sysdeps/generic/ldsodefs.h: Adjust _dl_allocate_static_tls prototype.
|
||||
* elf/Makefile: Add rules to build and run tst-tls14.
|
||||
* elf/tst-tls14.c: New file.
|
||||
|
@ -303,6 +303,16 @@ dl_open_worker (void *a)
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
/* Do static TLS initialization now if it has been delayed because
|
||||
the TLS template might not be fully relocated at _dl_allocate_static_tls
|
||||
time. */
|
||||
for (l = new; l; l = l->l_next)
|
||||
if (l->l_need_tls_init)
|
||||
{
|
||||
l->l_need_tls_init = 0;
|
||||
GL(dl_init_static_tls) (l);
|
||||
}
|
||||
|
||||
/* We normally don't bump the TLS generation counter. There must be
|
||||
actually a need to do this. */
|
||||
any_tls = false;
|
||||
|
@ -98,6 +98,10 @@ int _dl_starting_up = 1;
|
||||
hp_timing_t _dl_cpuclock_offset;
|
||||
#endif
|
||||
|
||||
#ifdef USE_TLS
|
||||
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
|
||||
#endif
|
||||
|
||||
/* This is zero at program start to signal that the global scope map is
|
||||
allocated by rtld. Later it keeps the size of the map. It might be
|
||||
reset if in _dl_close if the last global object is removed. */
|
||||
|
@ -622,6 +622,10 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||
GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd;
|
||||
#endif
|
||||
|
||||
#ifdef USE_TLS
|
||||
GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
|
||||
#endif
|
||||
|
||||
/* Process the environment variable which control the behaviour. */
|
||||
process_envvars (&mode);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define VAR_INT_DEF(x) \
|
||||
asm (".section .tdata\n\t" \
|
||||
".globl " #x "\n" \
|
||||
".balign 4\n" \
|
||||
#x ":\t.long 0\n\t" \
|
||||
".size " #x ",4\n\t" \
|
||||
".previous")
|
||||
|
@ -186,7 +186,9 @@ struct link_map
|
||||
the l_libname list. */
|
||||
unsigned int l_faked:1; /* Nonzero if this is a faked descriptor
|
||||
without associated file. */
|
||||
|
||||
unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls)
|
||||
should be called on this link map
|
||||
when relocation finishes. */
|
||||
/* Array with version names. */
|
||||
unsigned int l_nversions;
|
||||
struct r_found_version *l_versions;
|
||||
|
@ -1,3 +1,9 @@
|
||||
2003-07-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* pthread.c (init_one_static_tls, __pthread_init_static_tls): New
|
||||
functions.
|
||||
(pthread_initialize): Initialize GL(dl_init_static_tls).
|
||||
|
||||
2003-06-19 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* sysdeps/pthread/timer_create.c (timer_create): Call timer_delref
|
||||
|
@ -462,6 +462,44 @@ __libc_dl_error_tsd (void)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_TLS
|
||||
static inline void __attribute__((always_inline))
|
||||
init_one_static_tls (pthread_descr descr, struct link_map *map)
|
||||
{
|
||||
# if TLS_TCB_AT_TP
|
||||
dtv_t *dtv = GET_DTV (descr);
|
||||
void *dest = (char *) descr - map->l_tls_offset;
|
||||
# elif TLS_DTV_AT_TP
|
||||
dtv_t *dtv = GET_DTV ((pthread_descr) ((char *) descr + TLS_PRE_TCB_SIZE));
|
||||
void *dest = (char *) descr + map->l_tls_offset + TLS_PRE_TCB_SIZE;
|
||||
# else
|
||||
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||
# endif
|
||||
|
||||
/* Fill in the DTV slot so that a later LD/GD access will find it. */
|
||||
dtv[map->l_tls_modid].pointer = dest;
|
||||
|
||||
/* Initialize the memory. */
|
||||
memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
|
||||
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
|
||||
}
|
||||
|
||||
static void
|
||||
__pthread_init_static_tls (struct link_map *map)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < PTHREAD_THREADS_MAX; ++i)
|
||||
if (__pthread_handles[i].h_descr != NULL && i != 1)
|
||||
{
|
||||
__pthread_lock (&__pthread_handles[i].h_lock, NULL);
|
||||
if (__pthread_handles[i].h_descr != NULL)
|
||||
init_one_static_tls (__pthread_handles[i].h_descr, map);
|
||||
__pthread_unlock (&__pthread_handles[i].h_lock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void pthread_initialize(void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
@ -551,6 +589,10 @@ static void pthread_initialize(void)
|
||||
*__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
|
||||
GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
|
||||
#endif
|
||||
|
||||
#ifdef USE_TLS
|
||||
GL(dl_init_static_tls) = &__pthread_init_static_tls;
|
||||
#endif
|
||||
}
|
||||
|
||||
void __pthread_initialize(void)
|
||||
|
@ -1,3 +1,19 @@
|
||||
2003-07-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* init.c (__pthread_initialize_minimal_internal): Initialize
|
||||
GL(dl_init_static_tls).
|
||||
* pthreadP.h (__pthread_init_static_tls): New prototype.
|
||||
* allocatestack.c (init_one_static_tls, __pthread_init_static_tls):
|
||||
New functions.
|
||||
* Makefile (tests): Add tst-tls4.
|
||||
(modules-names): Add tst-tls4moda and tst-tls4modb.
|
||||
($(objpfx)tst-tls4): Link against libdl and libpthread.
|
||||
($(objpfx)tst-tls4.out): Depend on tst-tls4moda.so and
|
||||
tst-tls4modb.so.
|
||||
* tst-tls4.c: New file.
|
||||
* tst-tls4moda.c: New file.
|
||||
* tst-tls4modb.c: New file.
|
||||
|
||||
2003-06-19 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* sysdeps/pthread/timer_create.c (timer_create): Call timer_delref
|
||||
|
@ -251,10 +251,11 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
|
||||
tst-oncex3 tst-oncex4
|
||||
endif
|
||||
ifeq ($(build-shared),yes)
|
||||
tests += tst-atfork2 tst-tls3 tst-_res1
|
||||
tests += tst-atfork2 tst-tls3 tst-tls4 tst-_res1
|
||||
endif
|
||||
|
||||
modules-names = tst-atfork2mod tst-tls3mod tst-_res1mod1 tst-_res1mod2
|
||||
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
|
||||
tst-_res1mod1 tst-_res1mod2
|
||||
extra-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||
test-extras += $(modules-names)
|
||||
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
|
||||
@ -395,6 +396,9 @@ LDFLAGS-tst-tls3 = -rdynamic
|
||||
$(objpfx)tst-tls3.out: $(objpfx)tst-tls3mod.so
|
||||
$(objpfx)tst-tls3mod.so: $(shared-thread-library)
|
||||
|
||||
$(objpfx)tst-tls4: $(libdl) $(shared-thread-library)
|
||||
$(objpfx)tst-tls4.out: $(objpfx)tst-tls4moda.so $(objpfx)tst-tls4modb.so
|
||||
|
||||
$(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library)
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
|
@ -710,3 +710,41 @@ __find_thread_by_id (pid_t tid)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void __attribute__((always_inline))
|
||||
init_one_static_tls (struct pthread *curp, struct link_map *map)
|
||||
{
|
||||
dtv_t *dtv = GET_DTV (TLS_TPADJ (curp));
|
||||
# if TLS_TCB_AT_TP
|
||||
void *dest = (char *) curp - map->l_tls_offset;
|
||||
# elif TLS_DTV_AT_TP
|
||||
void *dest = (char *) curp + map->l_tls_offset + TLS_PRE_TCB_SIZE;
|
||||
# else
|
||||
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||
# endif
|
||||
|
||||
/* Fill in the DTV slot so that a later LD/GD access will find it. */
|
||||
dtv[map->l_tls_modid].pointer = dest;
|
||||
|
||||
/* Initialize the memory. */
|
||||
memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
|
||||
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
|
||||
}
|
||||
|
||||
void
|
||||
attribute_hidden
|
||||
__pthread_init_static_tls (struct link_map *map)
|
||||
{
|
||||
lll_lock (stack_cache_lock);
|
||||
|
||||
/* Iterate over the list with system-allocated threads first. */
|
||||
list_t *runp;
|
||||
list_for_each (runp, &stack_used)
|
||||
init_one_static_tls (list_entry (runp, struct pthread, list), map);
|
||||
|
||||
/* Now the list with threads using user-allocated stacks. */
|
||||
list_for_each (runp, &__stack_user)
|
||||
init_one_static_tls (list_entry (runp, struct pthread, list), map);
|
||||
|
||||
lll_unlock (stack_cache_lock);
|
||||
}
|
||||
|
@ -272,6 +272,8 @@ __pthread_initialize_minimal_internal (void)
|
||||
GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
|
||||
#endif
|
||||
|
||||
GL(dl_init_static_tls) = &__pthread_init_static_tls;
|
||||
|
||||
/* Register the fork generation counter with the libc. */
|
||||
#ifndef TLS_MULTIPLE_THREADS_IN_TCB
|
||||
__libc_multiple_threads_ptr =
|
||||
|
@ -257,6 +257,8 @@ extern int *__libc_multiple_threads_ptr attribute_hidden;
|
||||
/* Find a thread given its TID. */
|
||||
extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden;
|
||||
|
||||
extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
|
||||
|
||||
|
||||
/* Namespace save aliases. */
|
||||
extern int __pthread_getschedparam (pthread_t thread_id, int *policy,
|
||||
|
191
nptl/tst-tls4.c
Normal file
191
nptl/tst-tls4.c
Normal file
@ -0,0 +1,191 @@
|
||||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <tls.h>
|
||||
|
||||
#if HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE
|
||||
|
||||
#define N 3
|
||||
|
||||
void (*test1) (void), (*test2) (void);
|
||||
|
||||
pthread_barrier_t b2, b3;
|
||||
|
||||
static void *
|
||||
tf (void *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= (uintptr_t) arg; ++i)
|
||||
{
|
||||
int r = pthread_barrier_wait (&b3);
|
||||
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
{
|
||||
puts ("tf: barrier_wait failed");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
test1 ();
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
int r = pthread_barrier_wait (&b3);
|
||||
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
{
|
||||
puts ("tf: barrier_wait failed");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
test2 ();
|
||||
|
||||
for (i = 0; i < 3 - (uintptr_t) arg; ++i)
|
||||
{
|
||||
int r = pthread_barrier_wait (&b3);
|
||||
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
{
|
||||
puts ("tf: barrier_wait failed");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
tf2 (void *arg)
|
||||
{
|
||||
int r = pthread_barrier_wait (&b2);
|
||||
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
{
|
||||
puts ("tf2: barrier_wait failed");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < N; ++i)
|
||||
tf (arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
do_test (void)
|
||||
{
|
||||
pthread_t th[2];
|
||||
const char *modules[N]
|
||||
= { "tst-tls4moda.so", "tst-tls4moda.so", "tst-tls4modb.so" };
|
||||
|
||||
if (pthread_barrier_init (&b2, NULL, 2) != 0)
|
||||
{
|
||||
puts ("barrier_init failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pthread_barrier_init (&b3, NULL, 3) != 0)
|
||||
{
|
||||
puts ("barrier_init failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pthread_create (&th[0], NULL, tf2, (void *) (uintptr_t) 1))
|
||||
{
|
||||
puts ("pthread_create failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int r = pthread_barrier_wait (&b2);
|
||||
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
{
|
||||
puts ("barrier_wait failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
void *h = dlopen (modules[i], RTLD_LAZY);
|
||||
if (h == NULL)
|
||||
{
|
||||
printf ("dlopen failed %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
test1 = dlsym (h, "test1");
|
||||
if (test1 == NULL)
|
||||
{
|
||||
printf ("dlsym for test1 failed %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
test2 = dlsym (h, "test2");
|
||||
if (test2 == NULL)
|
||||
{
|
||||
printf ("dlsym for test2 failed %s\n", dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pthread_create (&th[1], NULL, tf, (void *) (uintptr_t) 2))
|
||||
{
|
||||
puts ("pthread_create failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
tf ((void *) (uintptr_t) 0);
|
||||
|
||||
if (pthread_join (th[1], NULL) != 0)
|
||||
{
|
||||
puts ("join failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dlclose (h))
|
||||
{
|
||||
puts ("dlclose failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("test %d with %s succeeded\n", i, modules[i]);
|
||||
}
|
||||
|
||||
if (pthread_join (th[0], NULL) != 0)
|
||||
{
|
||||
puts ("join failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TIMEOUT 5
|
||||
#define TEST_FUNCTION do_test ()
|
||||
|
||||
#else
|
||||
|
||||
#define TEST_FUNCTION 0
|
||||
|
||||
#endif
|
||||
|
||||
#include "../test-skeleton.c"
|
56
nptl/tst-tls4moda.c
Normal file
56
nptl/tst-tls4moda.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <tls.h>
|
||||
|
||||
#if HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE
|
||||
|
||||
static __thread unsigned char foo [32]
|
||||
__attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *))));
|
||||
|
||||
void
|
||||
test1 (void)
|
||||
{
|
||||
size_t s;
|
||||
|
||||
for (s = 0; s < sizeof (foo); ++s)
|
||||
{
|
||||
if (foo [s])
|
||||
abort ();
|
||||
foo [s] = s;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test2 (void)
|
||||
{
|
||||
size_t s;
|
||||
|
||||
for (s = 0; s < sizeof (foo); ++s)
|
||||
{
|
||||
if (foo [s] != s)
|
||||
abort ();
|
||||
foo [s] = sizeof (foo) - s;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
65
nptl/tst-tls4modb.c
Normal file
65
nptl/tst-tls4modb.c
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <tls.h>
|
||||
|
||||
#if HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE
|
||||
|
||||
static int i;
|
||||
int bar;
|
||||
|
||||
static __thread void *foo [32 / sizeof (void *)]
|
||||
__attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *))))
|
||||
= { &i, &bar };
|
||||
|
||||
void
|
||||
test1 (void)
|
||||
{
|
||||
size_t s;
|
||||
|
||||
if (foo [0] != &i || foo [1] != &bar)
|
||||
abort ();
|
||||
|
||||
foo [0] = NULL;
|
||||
foo [1] = NULL;
|
||||
for (s = 0; s < sizeof (foo) / sizeof (void *); ++s)
|
||||
{
|
||||
if (foo [s])
|
||||
abort ();
|
||||
foo [s] = &foo[s];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test2 (void)
|
||||
{
|
||||
size_t s;
|
||||
|
||||
for (s = 0; s < sizeof (foo) / sizeof (void *); ++s)
|
||||
{
|
||||
if (foo [s] != &foo [s])
|
||||
abort ();
|
||||
foo [s] = &foo [s ^ 1];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -390,6 +390,8 @@ struct rtld_global
|
||||
EXTERN void *_dl_initial_dtv;
|
||||
/* Generation counter for the dtv. */
|
||||
EXTERN size_t _dl_tls_generation;
|
||||
|
||||
EXTERN void (*_dl_init_static_tls) (struct link_map *);
|
||||
#endif
|
||||
|
||||
#ifdef NEED_DL_SYSINFO
|
||||
@ -797,7 +799,7 @@ rtld_hidden_proto (_dl_allocate_tls)
|
||||
extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
|
||||
internal_function;
|
||||
|
||||
extern int _dl_allocate_static_tls (struct link_map *map)
|
||||
extern void _dl_allocate_static_tls (struct link_map *map)
|
||||
internal_function attribute_hidden;
|
||||
|
||||
/* These are internal entry points to the two halves of _dl_allocate_tls,
|
||||
@ -816,6 +818,10 @@ rtld_hidden_proto (_dl_deallocate_tls)
|
||||
extern void *_dl_tls_symaddr (struct link_map *map, const ElfW(Sym) *ref)
|
||||
internal_function;
|
||||
|
||||
#if defined USE_TLS
|
||||
extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden;
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* ldsodefs.h */
|
||||
|
Loading…
Reference in New Issue
Block a user