* sysdeps/generic/libc-tls.c (__libc_setup_tls): Cope with zero ALIGN.

* malloc/hooks.c [_LIBC && (USE___THREAD || (USE_TLS && !SHARED))]
	(malloc_starter, memalign_starter, free_starter): Don't define these.
	* malloc/malloc.c [_LIBC && (USE___THREAD || (USE_TLS && !SHARED))]:
	Don't declare them either.
	* malloc/arena.c (ptmalloc_init) [_LIBC && USE_TLS]: Don't call
	__pthread_initialize, so no need to set hooks to *_starter.
	(ptmalloc_init_minimal): New function, broken out of ptmalloc_init.
	[_LIBC && SHARED && USE_TLS && !USE___THREAD]
	(__libc_malloc_pthread_startup): New function.
	* malloc/Versions (libc: GLIBC_PRIVATE): New set, add that function.

	* malloc/hooks.c (memalign_starter): New function.
	* malloc/malloc.c: Declare it.
	* malloc/arena.c (save_memalign_hook): New variable.
	(ptmalloc_init): Set __memalign_hook to memalign_starter.

	* elf/dl-minimal.c (free): Clear the memory.
	(calloc): Just call malloc, knowing all memory it returns is cleared.

	* sysdeps/generic/dl-tls.c (allocate_dtv): Use calloc instead of
	malloc and memset; calloc can avoid the zeroing when redundant.
	(_dl_tls_setup): Likewise.
	* elf/dl-load.c (decompose_rpath): Likewise.
	* sysdeps/generic/libc-tls.c (__libc_setup_tls): Comment out memset
	call, since memory from sbrk at startup is already zero.

	* elf/rtld.c (_dl_start, dl_main): TLS_INIT_TP macro now returns an
	error string for failure, null for success.  Update callers.
	* sysdeps/generic/libc-tls.c (__libc_setup_tls): Likewise.
	* elf/dl-load.c (_dl_map_object_from_fd): Likewise.
This commit is contained in:
Roland McGrath 2002-12-06 11:15:07 +00:00
parent d58847f952
commit fde89ad009
19 changed files with 296 additions and 68 deletions

View File

@ -1,3 +1,38 @@
2002-12-06 Roland McGrath <roland@redhat.com>
* sysdeps/generic/libc-tls.c (__libc_setup_tls): Cope with zero ALIGN.
* malloc/hooks.c [_LIBC && (USE___THREAD || (USE_TLS && !SHARED))]
(malloc_starter, memalign_starter, free_starter): Don't define these.
* malloc/malloc.c [_LIBC && (USE___THREAD || (USE_TLS && !SHARED))]:
Don't declare them either.
* malloc/arena.c (ptmalloc_init) [_LIBC && USE_TLS]: Don't call
__pthread_initialize, so no need to set hooks to *_starter.
(ptmalloc_init_minimal): New function, broken out of ptmalloc_init.
[_LIBC && SHARED && USE_TLS && !USE___THREAD]
(__libc_malloc_pthread_startup): New function.
* malloc/Versions (libc: GLIBC_PRIVATE): New set, add that function.
* malloc/hooks.c (memalign_starter): New function.
* malloc/malloc.c: Declare it.
* malloc/arena.c (save_memalign_hook): New variable.
(ptmalloc_init): Set __memalign_hook to memalign_starter.
* elf/dl-minimal.c (free): Clear the memory.
(calloc): Just call malloc, knowing all memory it returns is cleared.
* sysdeps/generic/dl-tls.c (allocate_dtv): Use calloc instead of
malloc and memset; calloc can avoid the zeroing when redundant.
(_dl_tls_setup): Likewise.
* elf/dl-load.c (decompose_rpath): Likewise.
* sysdeps/generic/libc-tls.c (__libc_setup_tls): Comment out memset
call, since memory from sbrk at startup is already zero.
* elf/rtld.c (_dl_start, dl_main): TLS_INIT_TP macro now returns an
error string for failure, null for success. Update callers.
* sysdeps/generic/libc-tls.c (__libc_setup_tls): Likewise.
* elf/dl-load.c (_dl_map_object_from_fd): Likewise.
2002-12-05 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/x86_64/syscalls.list (sendfile): Change

View File

@ -513,8 +513,7 @@ decompose_rpath (struct r_search_path_struct *sps,
{
/* This object is on the list of objects for which the
RUNPATH and RPATH must not be used. */
result = (struct r_search_path_elem **)
malloc (sizeof (*result));
result = calloc (1, sizeof *result);
if (result == NULL)
{
signal_error_cache:
@ -523,8 +522,6 @@ decompose_rpath (struct r_search_path_struct *sps,
INTUSE(_dl_signal_error) (ENOMEM, NULL, NULL, errstring);
}
result[0] = NULL;
sps->dirs = result;
sps->malloced = 1;
@ -994,7 +991,8 @@ cannot allocate TLS data structures for initial thread");
}
/* Now we install the TCB in the thread register. */
if (__builtin_expect (TLS_INIT_TP (tcb, 0), 0) != -1)
errstring = TLS_INIT_TP (tcb, 0);
if (__builtin_expect (errstring == NULL, 1))
{
/* Now we are all good. */
l->l_tls_modid = ++GL(dl_tls_max_dtv_idx);
@ -1002,7 +1000,9 @@ cannot allocate TLS data structures for initial thread");
}
/* The kernel is too old or somesuch. */
errval = 0;
_dl_deallocate_tls (tcb, 1);
goto call_lose;
}
#endif

View File

@ -104,9 +104,10 @@ malloc (size_t n)
void * weak_function
calloc (size_t nmemb, size_t size)
{
size_t total = nmemb * size;
void *result = malloc (total);
return memset (result, '\0', total);
/* New memory from the trivial malloc above is always already cleared.
(We make sure that's true in the rare occasion it might not be,
by clearing memory in free, below.) */
return malloc (nmemb * size);
}
/* This will rarely be called. */
@ -115,7 +116,12 @@ free (void *ptr)
{
/* We can free only the last block allocated. */
if (ptr == alloc_last_block)
alloc_ptr = alloc_last_block;
{
/* Since this is rare, we clear the freed block here
so that calloc can presume malloc returns cleared memory. */
memset (alloc_last_block, '\0', alloc_ptr - alloc_last_block);
alloc_ptr = alloc_last_block;
}
}
/* This is only called with the most recent block returned by malloc. */

View File

@ -404,16 +404,17 @@ _dl_start (void *arg)
INSTALL_DTV ((char *) tlsblock + bootstrap_map.l_tls_offset,
initdtv);
if (TLS_INIT_TP ((char *) tlsblock + bootstrap_map.l_tls_offset, 0)
!= 0)
_dl_fatal_printf ("cannot setup thread-local storage\n");
const char *lossage = TLS_INIT_TP ((char *) tlsblock
+ bootstrap_map.l_tls_offset, 0);
# elif TLS_DTV_AT_TP
INSTALL_DTV (tlsblock, initdtv);
if (TLS_INIT_TP (tlsblock, 0) != 0)
_dl_fatal_printf ("cannot setup thread-local storage\n");
const char *lossage = TLS_INIT_TP (tlsblock, 0);
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
if (__builtin_expect (lossage != NULL, 0))
_dl_fatal_printf ("cannot set up thread-local storage: %s\n",
lossage);
/* So far this is module number one. */
bootstrap_map.l_tls_modid = 1;
@ -1564,7 +1565,9 @@ cannot allocate TLS data structures for initial thread");
/* And finally install it for the main thread. If ld.so itself uses
TLS we know the thread pointer was initialized earlier. */
TLS_INIT_TP (tcbp, USE___THREAD);
const char *lossage = TLS_INIT_TP (tcbp, USE___THREAD);
if (__builtin_expect (lossage != NULL, 0))
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
}
#endif

View File

@ -1,3 +1,21 @@
2002-12-05 Roland McGrath <roland@redhat.com>
* pthread.c (__pthread_initialize_minimal)
[USE_TLS && SHARED && !USE___THREAD]: Initialize TLS and set up the
TCB if the dynamic linker didn't do it at startup.
* sysdeps/i386/tls.h (TLS_INIT_TP): Make it return zero or an error
string.
(TLS_DO_SET_THREAD_AREA, TLS_DO_MODIFY_LDT, TLS_SETUP_GS_SEGMENT):
Submacros updated.
* sysdeps/x86_64/tls.h (TLS_INIT_TP): Likewise.
* sysdeps/alpha/tls.h (TLS_INIT_TP): Likewise (always zero).
2002-12-03 Roland McGrath <roland@redhat.com>
* pthread.c (pthread_initialize) [SHARED]: Copy dl_error_tsd value
from dynamic linker internal cell to new libc cell.
2002-11-28 Roland McGrath <roland@redhat.com>
* tst-context.c: #define IS_IN_libpthread around #include <tls.h>

View File

@ -317,6 +317,49 @@ __pthread_initialize_minimal(void)
/* Unlike in the dynamically linked case the dynamic linker has not
taken care of initializing the TLS data structures. */
__libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN);
# elif !USE___THREAD
if (__builtin_expect (GL(dl_tls_max_dtv_idx) == 0, 0))
{
/* There is no actual TLS being used, so the thread register
was not initialized in the dynamic linker. */
/* We need to install special hooks so that the malloc and memalign
calls in _dl_tls_setup and _dl_allocate_tls won't cause full
malloc initialization that will try to set up its thread state. */
extern void __libc_malloc_pthread_startup (bool first_time);
__libc_malloc_pthread_startup (true);
if (__builtin_expect (_dl_tls_setup (), 0)
|| __builtin_expect ((self = _dl_allocate_tls (NULL)) == NULL, 0))
{
static const char msg[] = "\
cannot allocate TLS data structures for initial thread\n";
TEMP_FAILURE_RETRY (__libc_write (STDERR_FILENO,
msg, sizeof msg - 1));
abort ();
}
const char *lossage = TLS_INIT_TP (self, 0);
if (__builtin_expect (lossage != NULL, 0))
{
static const char msg[] = "cannot set up thread-local storage: ";
const char nl = '\n';
TEMP_FAILURE_RETRY (__libc_write (STDERR_FILENO,
msg, sizeof msg - 1));
TEMP_FAILURE_RETRY (__libc_write (STDERR_FILENO,
lossage, strlen (lossage)));
TEMP_FAILURE_RETRY (__libc_write (STDERR_FILENO, &nl, 1));
}
/* Though it was allocated with libc's malloc, that was done without
the user's __malloc_hook installed. A later realloc that uses
the hooks might not work with that block from the plain malloc.
So we record this block as unfreeable just as the dynamic linker
does when it allocates the DTV before the libc malloc exists. */
GL(dl_initial_dtv) = GET_DTV (self);
__libc_malloc_pthread_startup (false);
}
# endif
self = THREAD_SELF;
@ -344,7 +387,9 @@ __pthread_initialize_minimal(void)
/* And fill in the pointer the the thread __pthread_handles array. */
__pthread_handles[0].h_descr = self;
#else
#else /* USE_TLS */
/* First of all init __pthread_handles[0] and [1]. */
# if __LT_SPINLOCK_INIT != 0
__pthread_handles[0].h_lock = __LOCK_INITIALIZER;
@ -513,6 +558,8 @@ static void pthread_initialize(void)
__pthread_smp_kernel = is_smp_system ();
#ifdef SHARED
/* Transfer the old value from the dynamic linker's internal location. */
*__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
#endif
}

View File

@ -92,6 +92,7 @@ typedef struct
register tcbhead_t *__self = (void *)(descr); \
__self->tcb = __self; \
__builtin_set_thread_pointer(__self); \
0; \
})
/* Return the address of the dtv for the current thread. */

View File

@ -106,20 +106,18 @@ typedef struct
# endif
# if __ASSUME_LDT_WORKS > 0
# define TLS_DO_MODIFY_LDT_KERNEL_CHECK /* Nothing to do. */
# define TLS_DO_MODIFY_LDT_KERNEL_CHECK(doit) (doit) /* Nothing to check. */
# else
# include "useldt.h" /* For the structure. */
# define TLS_DO_MODIFY_LDT_KERNEL_CHECK \
if (__builtin_expect (GL(dl_osversion) < 131939, 0)) \
_dl_fatal_printf ("kernel %u.%u.%u cannot support thread-local storage\n",\
(GL(dl_osversion) >> 16) & 0xff, \
(GL(dl_osversion) >> 8) & 0xff, \
(GL(dl_osversion) >> 0) & 0xff);
# define TLS_DO_MODIFY_LDT_KERNEL_CHECK(doit) \
(__builtin_expect (GL(dl_osversion) < 131939, 0) \
? "kernel too old for thread-local storage support" \
: (doit))
# endif
# define TLS_DO_MODIFY_LDT(descr, nr) \
TLS_DO_MODIFY_LDT_KERNEL_CHECK( \
({ \
TLS_DO_MODIFY_LDT_KERNEL_CHECK \
struct modify_ldt_ldt_s ldt_entry = \
{ nr, (unsigned long int) (descr), 0xfffff /* 4GB in pages */, \
1, 0, 0, 1, 0, 1, 0 }; \
@ -134,8 +132,10 @@ typedef struct
here. */ \
"m" (ldt_entry), TLS_EBX_ARG (1), "c" (&ldt_entry), \
"d" (sizeof (ldt_entry))); \
__builtin_expect (result, 0) != 0 ? -1 : nr * 8 + 7; \
})
__builtin_expect (result, 0) == 0 \
? ({ asm ("movw %w0, %%gs" : : "q" ((nr) * 8 + 7)); NULL; }) \
: "cannot set up LDT for thread-local storage"; \
}))
# define TLS_DO_SET_THREAD_AREA(descr, secondcall) \
({ \
@ -156,41 +156,40 @@ typedef struct
to let the compiler know that we are accessing LDT_ENTRY \
here. */ \
TLS_EBX_ARG (&ldt_entry), "m" (ldt_entry)); \
__builtin_expect (result, 0) == 0 ? ldt_entry.entry_number * 8 + 3 : -1; \
if (__builtin_expect (result, 0) == 0) \
asm ("movw %w0, %%gs" : : "q" (ldt_entry.entry_number * 8 + 3)); \
result; \
})
# ifdef __ASSUME_SET_THREAD_AREA_SYSCALL
# define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
TLS_DO_SET_THREAD_AREA (descr, firstcall)
# define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
(TLS_DO_SET_THREAD_AREA (descr, firstcall) \
? "set_thread_area failed when setting up thread-local storage" : NULL)
# elif defined __NR_set_thread_area
# define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
({ int __seg = TLS_DO_SET_THREAD_AREA (descr, secondcall); \
__seg == -1 ? TLS_DO_MODIFY_LDT (descr, 0) : __seg; })
(TLS_DO_SET_THREAD_AREA (descr, secondcall) \
? TLS_DO_MODIFY_LDT (descr, 0) : NULL)
# else
# define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
TLS_DO_MODIFY_LDT ((descr), 0)
# endif
/* Code to initially initialize the thread pointer. This might need
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.
The value of this macro is null if successful, or an error string. */
# define TLS_INIT_TP(descr, secondcall) \
({ \
void *_descr = (descr); \
tcbhead_t *head = _descr; \
int __gs; \
\
head->tcb = _descr; \
/* For now the thread descriptor is at the same address. */ \
head->self = _descr; \
\
__gs = TLS_SETUP_GS_SEGMENT (_descr, secondcall); \
if (__builtin_expect (__gs, 7) != -1) \
{ \
asm ("movw %w0, %%gs" : : "q" (__gs)); \
__gs = 0; \
} \
__gs; \
TLS_SETUP_GS_SEGMENT (_descr, secondcall); \
})

View File

@ -105,7 +105,8 @@ typedef struct
"D" ((unsigned long int) ARCH_SET_FS), \
"S" (_descr) \
: "memory", "cc", "r11", "cx"); \
_result ? -1 : 0; \
\
_result ? "cannot set %fs base address for thread-local storage" : 0; \
})
/* Return the address of the dtv for the current thread. */

View File

@ -136,6 +136,11 @@ int __malloc_initialized = -1;
static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size,
__const __malloc_ptr_t));
# if !defined _LIBC || !defined USE_TLS || (defined SHARED && !USE___THREAD)
static __malloc_ptr_t (*save_memalign_hook) __MALLOC_P ((size_t __align,
size_t __size,
__const __malloc_ptr_t));
# endif
static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
__const __malloc_ptr_t));
static Void_t* save_arena;
@ -322,6 +327,51 @@ next_env_entry (char ***position)
}
#endif /* _LIBC */
/* Set up basic state so that _int_malloc et al can work. */
static void
ptmalloc_init_minimal __MALLOC_P((void))
{
#if DEFAULT_TOP_PAD != 0
mp_.top_pad = DEFAULT_TOP_PAD;
#endif
mp_.n_mmaps_max = DEFAULT_MMAP_MAX;
mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
mp_.pagesize = malloc_getpagesize;
}
#ifdef _LIBC
# if defined SHARED && defined USE_TLS && !USE___THREAD
# include <stdbool.h>
/* This is called by __pthread_initialize_minimal when it needs to use
malloc to set up the TLS state. We cannot do the full work of
ptmalloc_init (below) until __pthread_initialize_minimal has finished,
so it has to switch to using the special startup-time hooks while doing
those allocations. */
void
__libc_malloc_pthread_startup (bool first_time)
{
if (first_time)
{
ptmalloc_init_minimal ();
save_malloc_hook = __malloc_hook;
save_memalign_hook = __memalign_hook;
save_free_hook = __free_hook;
__malloc_hook = malloc_starter;
__memalign_hook = memalign_starter;
__free_hook = free_starter;
}
else
{
__malloc_hook = save_malloc_hook;
__memalign_hook = save_memalign_hook;
__free_hook = save_free_hook;
}
}
# endif
#endif
static void
ptmalloc_init __MALLOC_P((void))
{
@ -335,25 +385,37 @@ ptmalloc_init __MALLOC_P((void))
if(__malloc_initialized >= 0) return;
__malloc_initialized = 0;
mp_.top_pad = DEFAULT_TOP_PAD;
mp_.n_mmaps_max = DEFAULT_MMAP_MAX;
mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
mp_.pagesize = malloc_getpagesize;
#ifdef _LIBC
# if defined SHARED && defined USE_TLS && !USE___THREAD
/* ptmalloc_init_minimal may already have been called via
__libc_malloc_pthread_startup, above. */
if (mp_.pagesize == 0)
# endif
#endif
ptmalloc_init_minimal();
#ifndef NO_THREADS
# if defined _LIBC && defined USE_TLS
/* We know __pthread_initialize_minimal has already been called,
and that is enough. */
# define NO_STARTER
# endif
# ifndef NO_STARTER
/* With some threads implementations, creating thread-specific data
or initializing a mutex may call malloc() itself. Provide a
simple starter version (realloc() won't work). */
save_malloc_hook = __malloc_hook;
save_memalign_hook = __memalign_hook;
save_free_hook = __free_hook;
__malloc_hook = malloc_starter;
__memalign_hook = memalign_starter;
__free_hook = free_starter;
#ifdef _LIBC
# ifdef _LIBC
/* Initialize the pthreads interface. */
if (__pthread_initialize != NULL)
__pthread_initialize();
#endif
# endif /* !defined _LIBC */
# endif /* !defined NO_STARTER */
#endif /* !defined NO_THREADS */
mutex_init(&main_arena.mutex);
main_arena.next = &main_arena;
@ -363,8 +425,13 @@ ptmalloc_init __MALLOC_P((void))
tsd_setspecific(arena_key, (Void_t *)&main_arena);
thread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2);
#ifndef NO_THREADS
# ifndef NO_STARTER
__malloc_hook = save_malloc_hook;
__memalign_hook = save_memalign_hook;
__free_hook = save_free_hook;
# else
# undef NO_STARTER
# endif
#endif
#ifdef _LIBC
secure = __libc_enable_secure;

View File

@ -395,6 +395,17 @@ memalign_check(alignment, bytes, caller)
#ifndef NO_THREADS
# ifdef _LIBC
# if USE___THREAD || (defined USE_TLS && !defined SHARED)
/* These routines are never needed in this configuration. */
# define NO_STARTER
# endif
# endif
# ifdef NO_STARTER
# undef NO_STARTER
# else
/* The following hooks are used when the global initialization in
ptmalloc_init() hasn't completed yet. */
@ -412,6 +423,20 @@ malloc_starter(sz, caller) size_t sz; const Void_t *caller;
return victim ? BOUNDED_N(victim, sz) : 0;
}
static Void_t*
#if __STD_C
memalign_starter(size_t align, size_t sz, const Void_t *caller)
#else
memalign_starter(align, sz, caller) size_t align, sz; const Void_t *caller;
#endif
{
Void_t* victim;
victim = _int_memalign(&main_arena, align, sz);
return victim ? BOUNDED_N(victim, sz) : 0;
}
static void
#if __STD_C
free_starter(Void_t* mem, const Void_t *caller)
@ -432,6 +457,7 @@ free_starter(mem, caller) Void_t* mem; const Void_t *caller;
_int_free(&main_arena, mem);
}
# endif /* !defiend NO_STARTER */
#endif /* NO_THREADS */

View File

@ -1498,8 +1498,19 @@ static Void_t* realloc_check(Void_t* oldmem, size_t bytes,
static Void_t* memalign_check(size_t alignment, size_t bytes,
const Void_t *caller);
#ifndef NO_THREADS
# ifdef _LIBC
# if USE___THREAD || (defined USE_TLS && !defined SHARED)
/* These routines are never needed in this configuration. */
# define NO_STARTER
# endif
# endif
# ifdef NO_STARTER
# undef NO_STARTER
# else
static Void_t* malloc_starter(size_t sz, const Void_t *caller);
static Void_t* memalign_starter(size_t aln, size_t sz, const Void_t *caller);
static void free_starter(Void_t* mem, const Void_t *caller);
# endif
static Void_t* malloc_atfork(size_t sz, const Void_t *caller);
static void free_atfork(Void_t* mem, const Void_t *caller);
#endif

View File

@ -1,5 +1,14 @@
2002-12-06 Roland McGrath <roland@redhat.com>
* allocatestack.c (__stack_user): Use uninitialized defn.
* init.c (__pthread_initialize_minimal): Initialize it here.
2002-12-05 Roland McGrath <roland@redhat.com>
* sysdeps/i386/tls.h (TLS_INIT_TP): Make it return zero or an error
string.
* sysdeps/x86_64/tls.h (TLS_INIT_TP): Likewise.
* sysdeps/unix/sysv/linux/i386/createthread.c (create_thread): Add
missing & here too.

View File

@ -68,8 +68,9 @@ static LIST_HEAD (stack_cache);
/* List of the stacks in use. */
static LIST_HEAD (stack_used);
/* List of the threads with user provided stacks in use. */
LIST_HEAD (__stack_user);
/* List of the threads with user provided stacks in use. No need to
initialize this, since it's done in __pthread_initialize_minimal. */
list_t __stack_user __attribute__ ((nocommon));
hidden_def (__stack_user)
/* Number of threads running. */

View File

@ -123,8 +123,8 @@ __pthread_initialize_minimal (void)
THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
#endif
/* Add the main thread to the list of all running threads. No need
to get the lock we are alone so far. */
/* Initialize the list of all running threads with the main thread. */
INIT_LIST_HEAD (__stack_user);
list_add (&pd->header.data.list, &__stack_user);

View File

@ -204,7 +204,8 @@ union user_desc_init
which is necessary since we have changed it. */ \
TLS_SET_GS (_segdescr.desc.entry_number * 8 + 3); \
\
_result; })
_result == 0 ? NULL \
: "set_thread_area failed when setting up thread-local storage"; })
/* Return the address of the dtv for the current thread. */

View File

@ -165,7 +165,8 @@ union user_desc_init
"S" (_descr) \
: "memory", "cc", "r11", "cx"); \
\
_result ? -1 : 0; })
_result ? "cannot set %fs base address for thread-local storage" : 0; \
})
/* Return the address of the dtv for the current thread. */

View File

@ -217,16 +217,13 @@ _dl_tls_setup (void)
const size_t nelem = 2 + TLS_SLOTINFO_SURPLUS;
GL(dl_tls_dtv_slotinfo_list) =
malloc (sizeof (struct dtv_slotinfo_list)
+ nelem * sizeof (struct dtv_slotinfo));
GL(dl_tls_dtv_slotinfo_list)
= calloc (1, (sizeof (struct dtv_slotinfo_list)
+ nelem * sizeof (struct dtv_slotinfo)));
if (GL(dl_tls_dtv_slotinfo_list) == NULL)
return -1;
memset (GL(dl_tls_dtv_slotinfo_list)->slotinfo, '\0',
nelem * sizeof (struct dtv_slotinfo));
GL(dl_tls_dtv_slotinfo_list)->len = nelem;
GL(dl_tls_dtv_slotinfo_list)->next = NULL;
/* Number of elements in the static TLS block. It can't be zero
because of various assumptions. The one element is null. */
@ -251,14 +248,14 @@ allocate_dtv (void *result)
initial set of modules. This should avoid in most cases expansions
of the dtv. */
dtv_length = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
dtv = (dtv_t *) malloc ((dtv_length + 2) * sizeof (dtv_t));
dtv = calloc (dtv_length + 2, sizeof (dtv_t));
if (dtv != NULL)
{
/* This is the initial length of the dtv. */
dtv[0].counter = dtv_length;
/* Initialize all of the rest of the dtv (including the
generation counter) with zero to indicate nothing there. */
memset (dtv + 1, '\0', (dtv_length + 1) * sizeof (dtv_t));
/* The rest of the dtv (including the generation counter) is
Initialize with zero to indicate nothing there. */
/* Add the dtv to the thread data structures. */
INSTALL_DTV (result, dtv);

View File

@ -21,6 +21,7 @@
#include <ldsodefs.h>
#include <tls.h>
#include <unistd.h>
#include <stdio.h>
#ifdef SHARED
#error makefile bug, this file is for static only
@ -168,8 +169,8 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
/* Initialize the TLS block. */
# if TLS_TCB_AT_TP
static_dtv[2].pointer = ((char *) tlsblock + tcb_offset
- roundup (memsz, align));
static_map.l_tls_offset = roundup (memsz, align);
- roundup (memsz, align ?: 1));
static_map.l_tls_offset = roundup (memsz, align ?: 1);
# elif TLS_DTV_AT_TP
tcb_offset = roundup (tcbsize, align);
static_dtv[2].pointer = (char *) tlsblock + tcb_offset;
@ -177,8 +178,10 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
/* sbrk gives us zero'd memory, so we don't need this.
memset (__mempcpy (static_dtv[2].pointer, initimage, filesz),
'\0', memsz - filesz);
*/
/* Install the pointer to the dtv. */
@ -186,13 +189,15 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
# if TLS_TCB_AT_TP
INSTALL_DTV ((char *) tlsblock + tcb_offset, static_dtv);
TLS_INIT_TP ((char *) tlsblock + tcb_offset, 0);
const char *lossage = TLS_INIT_TP ((char *) tlsblock + tcb_offset, 0);
# elif TLS_DTV_AT_TP
INSTALL_DTV (tlsblock, static_dtv);
TLS_INIT_TP (tlsblock, 0);
const char *lossage = TLS_INIT_TP (tlsblock, 0);
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
if (__builtin_expect (lossage != NULL, 0))
__libc_fatal (lossage);
/* We have to create a fake link map which normally would be created
by the dynamic linker. It just has to have enough information to