mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
Update.
2002-02-08 Ulrich Drepper <drepper@redhat.com> * elf/rtld.c (_dl_start_final): Install DTV explicitly. (dl_main): Move dtv/static TLS handling before relocation. Unconditionally call _dl_tlsoffset. Call _dl_allocate_tls and TLS_INIT_TP to allocate and install the dtv/static TLS block. * sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): If no object so far uses TLS initialize GL(dl_tls_static_size) and GL(dl_tls_static_align) to account for the TCB. (_dl_allocate_tls): New function. * sysdeps/generic/ldsodefs.h (rtld_global): Add _dl_initial_dtv_malloced. * configure.in: Test for __builtin_memset more realistically. * csu/version.c (banner): If TLS support available say so.
This commit is contained in:
parent
013aafb7d0
commit
a52d15621f
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
2002-02-08 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* elf/rtld.c (_dl_start_final): Install DTV explicitly.
|
||||||
|
(dl_main): Move dtv/static TLS handling before relocation.
|
||||||
|
Unconditionally call _dl_tlsoffset. Call _dl_allocate_tls and
|
||||||
|
TLS_INIT_TP to allocate and install the dtv/static TLS block.
|
||||||
|
* sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): If no object
|
||||||
|
so far uses TLS initialize GL(dl_tls_static_size) and
|
||||||
|
GL(dl_tls_static_align) to account for the TCB.
|
||||||
|
(_dl_allocate_tls): New function.
|
||||||
|
* sysdeps/generic/ldsodefs.h (rtld_global): Add
|
||||||
|
_dl_initial_dtv_malloced.
|
||||||
|
|
||||||
|
* configure.in: Test for __builtin_memset more realistically.
|
||||||
|
|
||||||
|
* csu/version.c (banner): If TLS support available say so.
|
||||||
|
|
||||||
2002-02-04 H.J. Lu <hjl@gnu.org>
|
2002-02-04 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
* sysdeps/mips/dl-machine.h (elf_machine_matches_host): Use
|
* sysdeps/mips/dl-machine.h (elf_machine_matches_host): Use
|
||||||
|
2
configure
vendored
2
configure
vendored
@ -3396,7 +3396,7 @@ else
|
|||||||
cat > conftest.c <<\EOF
|
cat > conftest.c <<\EOF
|
||||||
void zero (void *x)
|
void zero (void *x)
|
||||||
{
|
{
|
||||||
__builtin_memset (x, 0, 4);
|
__builtin_memset (x, 0, 1000);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
if { ac_try='${CC-cc} -O3 -S conftest.c -o - | fgrep "memset" > /dev/null'; { (eval echo configure:3403: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
if { ac_try='${CC-cc} -O3 -S conftest.c -o - | fgrep "memset" > /dev/null'; { (eval echo configure:3403: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||||
|
@ -1403,7 +1403,7 @@ AC_CACHE_CHECK(for __builtin_memset, libc_cv_gcc_builtin_memset, [dnl
|
|||||||
cat > conftest.c <<\EOF
|
cat > conftest.c <<\EOF
|
||||||
void zero (void *x)
|
void zero (void *x)
|
||||||
{
|
{
|
||||||
__builtin_memset (x, 0, 4);
|
__builtin_memset (x, 0, 1000);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
dnl
|
dnl
|
||||||
|
101
elf/rtld.c
101
elf/rtld.c
@ -309,14 +309,20 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
|
|||||||
'\0', (GL(dl_rtld_map).l_tls_blocksize
|
'\0', (GL(dl_rtld_map).l_tls_blocksize
|
||||||
- GL(dl_rtld_map).l_tls_initimage_size));
|
- GL(dl_rtld_map).l_tls_initimage_size));
|
||||||
|
|
||||||
|
/* Install the pointer to the dtv. */
|
||||||
|
|
||||||
/* Initialize the thread pointer. */
|
/* Initialize the thread pointer. */
|
||||||
# if TLS_TCB_AT_TP
|
# if TLS_TCB_AT_TP
|
||||||
GL(dl_rtld_map).l_tls_offset
|
GL(dl_rtld_map).l_tls_offset
|
||||||
= roundup (GL(dl_rtld_map).l_tls_blocksize, TLS_INIT_TCB_ALIGN);
|
= roundup (GL(dl_rtld_map).l_tls_blocksize, TLS_INIT_TCB_ALIGN);
|
||||||
TLS_INIT_TP ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset,
|
|
||||||
|
INSTALL_DTV ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset,
|
||||||
initdtv);
|
initdtv);
|
||||||
|
|
||||||
|
TLS_INIT_TP ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset);
|
||||||
# elif TLS_DTV_AT_TP
|
# elif TLS_DTV_AT_TP
|
||||||
TLS_INIT_TP (tlsblock, initdtv);
|
INSTALL_DTV (tlsblock, initdtv);
|
||||||
|
TLS_INIT_TP (tlsblock);
|
||||||
# else
|
# else
|
||||||
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||||
# endif
|
# endif
|
||||||
@ -477,6 +483,9 @@ dl_main (const ElfW(Phdr) *phdr,
|
|||||||
hp_timing_t stop;
|
hp_timing_t stop;
|
||||||
hp_timing_t diff;
|
hp_timing_t diff;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_TLS
|
||||||
|
void *tcbp;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Process the environment variable which control the behaviour. */
|
/* Process the environment variable which control the behaviour. */
|
||||||
process_envvars (&mode);
|
process_envvars (&mode);
|
||||||
@ -1169,6 +1178,53 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
_exit (0);
|
_exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_TLS
|
||||||
|
/* Now it is time to determine the layout of the static TLS block
|
||||||
|
and allocate it for the initial thread. Note that we always
|
||||||
|
allocate the static block, we never defer it even if no
|
||||||
|
DF_STATIC_TLS bit is set. The reason is that we know glibc will
|
||||||
|
use the static model. First add the dynamic linker to the list
|
||||||
|
if it also uses TLS. */
|
||||||
|
if (GL(dl_rtld_map).l_tls_blocksize != 0)
|
||||||
|
{
|
||||||
|
/* At to the list. */
|
||||||
|
if (GL(dl_initimage_list) == NULL)
|
||||||
|
GL(dl_initimage_list) = GL(dl_rtld_map).l_tls_nextimage
|
||||||
|
= GL(dl_rtld_map).l_tls_previmage = &GL(dl_rtld_map);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL(dl_rtld_map).l_tls_nextimage
|
||||||
|
= GL(dl_initimage_list)->l_tls_nextimage;
|
||||||
|
GL(dl_rtld_map).l_tls_nextimage->l_tls_previmage
|
||||||
|
= &GL(dl_rtld_map);
|
||||||
|
GL(dl_rtld_map).l_tls_previmage = GL(dl_initimage_list);
|
||||||
|
GL(dl_rtld_map).l_tls_previmage->l_tls_nextimage
|
||||||
|
= &GL(dl_rtld_map);
|
||||||
|
GL(dl_initimage_list) = &GL(dl_rtld_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign a module ID. */
|
||||||
|
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computer the TLS offsets for the various blocks. We call this
|
||||||
|
function even if none of the modules available at startup time
|
||||||
|
uses TLS to initialize some variables. */
|
||||||
|
_dl_determine_tlsoffset (GL(dl_initimage_list));
|
||||||
|
|
||||||
|
/* Construct the static TLS block and the dtv for the initial
|
||||||
|
thread. For some platforms this will include allocating memory
|
||||||
|
for the thread descriptor. The memory for the TLS block will
|
||||||
|
never be freed. It should be allocated accordingly. The dtv
|
||||||
|
array can be changed if dynamic loading requires it. */
|
||||||
|
tcbp = _dl_allocate_tls ();
|
||||||
|
if (tcbp == NULL)
|
||||||
|
_dl_fatal_printf ("cannot allocate TLS data structures for inital thread");
|
||||||
|
|
||||||
|
/* And finally install it for the main thread. */
|
||||||
|
TLS_INIT_TP (tcbp);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]
|
if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]
|
||||||
&& ! __builtin_expect (GL(dl_profile) != NULL, 0))
|
&& ! __builtin_expect (GL(dl_profile) != NULL, 0))
|
||||||
{
|
{
|
||||||
@ -1333,47 +1389,6 @@ of this helper program; chances are you did not intend to run this program.\n\
|
|||||||
we need it in the memory handling later. */
|
we need it in the memory handling later. */
|
||||||
GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
|
GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
|
||||||
|
|
||||||
#ifdef USE_TLS
|
|
||||||
/* Now it is time to determine the layout of the static TLS block
|
|
||||||
and allocate it for the initial thread. Note that we always
|
|
||||||
allocate the static block, we never defer it even if no
|
|
||||||
DF_STATIC_TLS bit is set. The reason is that we know glibc will
|
|
||||||
use the static model. First add the dynamic linker to the list
|
|
||||||
if it also uses TLS. */
|
|
||||||
if (GL(dl_rtld_map).l_tls_blocksize != 0)
|
|
||||||
{
|
|
||||||
/* At to the list. */
|
|
||||||
if (GL(dl_initimage_list) == NULL)
|
|
||||||
GL(dl_initimage_list) = GL(dl_rtld_map).l_tls_nextimage
|
|
||||||
= GL(dl_rtld_map).l_tls_previmage = &GL(dl_rtld_map);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GL(dl_rtld_map).l_tls_nextimage
|
|
||||||
= GL(dl_initimage_list)->l_tls_nextimage;
|
|
||||||
GL(dl_rtld_map).l_tls_nextimage->l_tls_previmage
|
|
||||||
= &GL(dl_rtld_map);
|
|
||||||
GL(dl_rtld_map).l_tls_previmage = GL(dl_initimage_list);
|
|
||||||
GL(dl_rtld_map).l_tls_previmage->l_tls_nextimage
|
|
||||||
= &GL(dl_rtld_map);
|
|
||||||
GL(dl_initimage_list) = &GL(dl_rtld_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign a module ID. */
|
|
||||||
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GL(dl_initimage_list) != NULL)
|
|
||||||
/* This means we actually have some modules which use TLS.
|
|
||||||
Computer the TLS offsets for the various blocks. */
|
|
||||||
_dl_determine_tlsoffset (GL(dl_initimage_list)->l_tls_nextimage);
|
|
||||||
|
|
||||||
/* Construct the static TLS block and the dtv for the initial
|
|
||||||
thread. For some platforms this will include allocating memory
|
|
||||||
for the thread descriptor. The memory for the TLS block will
|
|
||||||
never be freed. It should be allocated accordingly. The dtv
|
|
||||||
array can be changed if dynamic loading requires it. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Initialize _r_debug. */
|
/* Initialize _r_debug. */
|
||||||
struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr);
|
struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr);
|
||||||
|
@ -42,7 +42,7 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
/* We can support TLS only if the floating-stack support is available. */
|
/* We can support TLS only if the floating-stack support is available. */
|
||||||
#ifdef HAVE_TLS_SUPPORT
|
#if defined FLOATING_STACKS && defined HAVE_TLS_SUPPORT
|
||||||
|
|
||||||
/* Get system call information. */
|
/* Get system call information. */
|
||||||
# include <sysdep.h>
|
# include <sysdep.h>
|
||||||
@ -66,10 +66,15 @@ typedef struct
|
|||||||
thread pointer points to is unspecified. Allocate the TCB there. */
|
thread pointer points to is unspecified. Allocate the TCB there. */
|
||||||
# define TLS_TCB_AT_TP 1
|
# define TLS_TCB_AT_TP 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Install the dtv pointer. */
|
||||||
|
# define INSTALL_DTV(descr, dtvp) \
|
||||||
|
((tcbhead_t *) descr)->dtv = dtvp
|
||||||
|
|
||||||
/* Code to initially initialize the thread pointer. This might need
|
/* Code to initially initialize the thread pointer. This might need
|
||||||
special attention since 'errno' is not yet available and if the
|
special attention since 'errno' is not yet available and if the
|
||||||
operation can cause a failure 'errno' must not be touched. */
|
operation can cause a failure 'errno' must not be touched. */
|
||||||
# define TLS_INIT_TP(descr, dtvp) \
|
# define TLS_INIT_TP(descr) \
|
||||||
do { \
|
do { \
|
||||||
void *_descr = (descr); \
|
void *_descr = (descr); \
|
||||||
struct modify_ldt_ldt_s ldt_entry = \
|
struct modify_ldt_ldt_s ldt_entry = \
|
||||||
@ -78,7 +83,6 @@ typedef struct
|
|||||||
tcbhead_t *head = _descr; \
|
tcbhead_t *head = _descr; \
|
||||||
\
|
\
|
||||||
head->tcb = _descr; \
|
head->tcb = _descr; \
|
||||||
head->dtv = dtvp; \
|
|
||||||
\
|
\
|
||||||
asm ("pushl %%ebx\n\t" \
|
asm ("pushl %%ebx\n\t" \
|
||||||
"movl $1, %%ebx\n\t" \
|
"movl $1, %%ebx\n\t" \
|
||||||
@ -94,16 +98,10 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
/* Return the address of the dtv for the current thread. */
|
/* Return the address of the dtv for the current thread. */
|
||||||
# if FLOATING_STACKS
|
# define THREAD_DTV() \
|
||||||
# define THREAD_DTV() \
|
|
||||||
({ struct _pthread_descr_struct *__descr; \
|
({ struct _pthread_descr_struct *__descr; \
|
||||||
THREAD_GETMEM (__descr, p_header.data.dtvp); })
|
THREAD_GETMEM (__descr, p_header.data.dtvp); })
|
||||||
# else
|
|
||||||
# define THREAD_DTV() \
|
|
||||||
({ struct _pthread_descr_struct *__descr = thread_self (); \
|
|
||||||
THREAD_GETMEM (__descr, p_header.data.dtvp); })
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif /* HAVE_TLS_SUPPORT */
|
#endif /* FLOATING_STACKS && HAVE_TLS_SUPPORT */
|
||||||
|
|
||||||
#endif /* tls.h */
|
#endif /* tls.h */
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
02111-1307 USA. */
|
02111-1307 USA. */
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
|
|
||||||
@ -84,6 +85,16 @@ _dl_determine_tlsoffset (struct link_map *firstp)
|
|||||||
size_t max_align = 0;
|
size_t max_align = 0;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
|
||||||
|
if (GL(dl_initimage_list) == NULL)
|
||||||
|
{
|
||||||
|
/* None of the objects used at startup time uses TLS. We still
|
||||||
|
have to allocate the TCB adn dtv. */
|
||||||
|
GL(dl_tls_static_size) = TLS_TCB_SIZE;
|
||||||
|
GL(dl_tls_static_align) = TLS_TCB_ALIGN;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
# if TLS_TCB_AT_TP
|
# if TLS_TCB_AT_TP
|
||||||
/* We simply start with zero. */
|
/* We simply start with zero. */
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@ -149,6 +160,79 @@ _dl_determine_tlsoffset (struct link_map *firstp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *
|
||||||
|
internal_function
|
||||||
|
_dl_allocate_tls (void)
|
||||||
|
{
|
||||||
|
void *result;
|
||||||
|
dtv_t *dtv;
|
||||||
|
|
||||||
|
/* Allocate a correctly aligned chunk of memory. */
|
||||||
|
/* XXX For now */
|
||||||
|
assert (GL(dl_tls_static_align) <= GL(dl_pagesize));
|
||||||
|
#ifdef MAP_ANON
|
||||||
|
# define _dl_zerofd (-1)
|
||||||
|
#else
|
||||||
|
# define _dl_zerofd GL(dl_zerofd)
|
||||||
|
if ((dl_zerofd) == -1)
|
||||||
|
GL(dl_zerofd) = _dl_sysdep_open_zero_fill ();
|
||||||
|
# define MAP_ANON 0
|
||||||
|
#endif
|
||||||
|
result = __mmap (0, GL(dl_tls_static_size), PROT_READ|PROT_WRITE,
|
||||||
|
MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0);
|
||||||
|
|
||||||
|
dtv = (dtv_t *) malloc ((GL(dl_tls_max_dtv_idx) + 1) * sizeof (dtv_t));
|
||||||
|
if (result != MAP_FAILED && dtv != NULL)
|
||||||
|
{
|
||||||
|
struct link_map *runp;
|
||||||
|
|
||||||
|
# if TLS_TCB_AT_TP
|
||||||
|
/* The TCB follows the TLS blocks. */
|
||||||
|
result = (char *) result + GL(dl_tls_static_size) - TLS_TCB_SIZE;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* XXX Fill in an correct generation number. */
|
||||||
|
dtv[0].counter = 0;
|
||||||
|
|
||||||
|
/* Initialize the memory from the initialization image list and clear
|
||||||
|
the BSS parts. */
|
||||||
|
if (GL(dl_initimage_list) != NULL)
|
||||||
|
{
|
||||||
|
runp = GL(dl_initimage_list)->l_tls_nextimage;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
assert (runp->l_tls_modid > 0);
|
||||||
|
assert (runp->l_tls_modid <= GL(dl_tls_max_dtv_idx));
|
||||||
|
# if TLS_TCB_AT_TP
|
||||||
|
dtv[runp->l_tls_modid].pointer = result - runp->l_tls_offset;
|
||||||
|
# elif TLS_DTV_AT_TP
|
||||||
|
dtv[runp->l_tls_modid].pointer = result + runp->l_tls_offset;
|
||||||
|
# else
|
||||||
|
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
memset (__mempcpy (dtv[runp->l_tls_modid].pointer,
|
||||||
|
runp->l_tls_initimage,
|
||||||
|
runp->l_tls_initimage_size),
|
||||||
|
'\0',
|
||||||
|
runp->l_tls_blocksize - runp->l_tls_initimage_size);
|
||||||
|
}
|
||||||
|
while ((runp = runp->l_tls_nextimage) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the dtv to the thread data structures. */
|
||||||
|
INSTALL_DTV (result, dtv);
|
||||||
|
}
|
||||||
|
else if (result != NULL)
|
||||||
|
{
|
||||||
|
free (result);
|
||||||
|
result = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The __tls_get_addr function has two basic forms which differ in the
|
/* The __tls_get_addr function has two basic forms which differ in the
|
||||||
arguments. The IA-64 form takes two parameters, the module ID and
|
arguments. The IA-64 form takes two parameters, the module ID and
|
||||||
offset. The form used, among others, on IA-32 takes a reference to
|
offset. The form used, among others, on IA-32 takes a reference to
|
||||||
|
@ -303,6 +303,9 @@ struct rtld_global
|
|||||||
EXTERN size_t _dl_tls_static_size;
|
EXTERN size_t _dl_tls_static_size;
|
||||||
/* Alignment requirement of the static TLS block. */
|
/* Alignment requirement of the static TLS block. */
|
||||||
EXTERN size_t _dl_tls_static_align;
|
EXTERN size_t _dl_tls_static_align;
|
||||||
|
|
||||||
|
/* True if the dtv for the initial thread was malloc()ed. */
|
||||||
|
EXTERN bool _dl_initial_dtv_malloced;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Name of the shared object to be profiled (if any). */
|
/* Name of the shared object to be profiled (if any). */
|
||||||
@ -666,6 +669,8 @@ extern size_t _dl_next_tls_modid (void) internal_function;
|
|||||||
extern void _dl_determine_tlsoffset (struct link_map *firstp)
|
extern void _dl_determine_tlsoffset (struct link_map *firstp)
|
||||||
internal_function;
|
internal_function;
|
||||||
|
|
||||||
|
/* Allocate memory for static TLS block and dtv. */
|
||||||
|
extern void *_dl_allocate_tls (void) internal_function;
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user