diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | elf/Versions | 1 | ||||
-rw-r--r-- | sysdeps/generic/dl-tls.c | 64 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 10 |
4 files changed, 66 insertions, 22 deletions
@@ -1,3 +1,16 @@ +2002-08-20 Ulrich Drepper <drepper@redhat.com> + + * elf/Versions [ld] (GLIBC_PRIVATE): Add _dl_get_tls_static_info. + * sysdeps/generic/dl-tls.c (_dl_allocate_tls_storage): Move dtv + memory allocation to... + (allocate_dtv): ...here. New function. + (_dl_allocate_tls): Change to take parameter. If parameter is non-NULL + call allocate_dtv instead of _dl_allocate_tls_storage. + (_dl_deallocate_tls): New parameter. Deallocate TCB only if true. + (_dl_get_tls_static_info): New function. + * sysdeps/generic/ldsodefs.h: Adjust prototypes of _dl_allocate_tls + and _dl_deallocate_tls. Add prototype for _dl_get_tls_static_info. + 2002-08-19 Ulrich Drepper <drepper@redhat.com> * sysdeps/generic/dl-tls.c (_dl_allocate_tls_init): Return diff --git a/elf/Versions b/elf/Versions index 4f924e6df5..a49ecbf7de 100644 --- a/elf/Versions +++ b/elf/Versions @@ -50,6 +50,7 @@ ld { _dl_relocate_object; _dl_signal_error; _dl_start_profile; _dl_starting_up; _dl_unload_cache; _rtld_global; _dl_tls_symaddr; _dl_allocate_tls; _dl_deallocate_tls; + _dl_get_tls_static_info; _dl_get_origin; } } diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c index 2b47195c96..38f40ac8ae 100644 --- a/sysdeps/generic/dl-tls.c +++ b/sysdeps/generic/dl-tls.c @@ -196,19 +196,13 @@ _dl_determine_tlsoffset (void) } -void * +static void * internal_function -_dl_allocate_tls_storage (void) +allocate_dtv (void *result) { - void *result; dtv_t *dtv; size_t dtv_length; - /* Allocate a correctly aligned chunk of memory. */ - result = __libc_memalign (GL(dl_tls_static_align), GL(dl_tls_static_size)); - if (__builtin_expect (result == NULL, 0)) - return result; - /* We allocate a few more elements in the dtv than are needed for the initial set of modules. This should avoid in most cases expansions of the dtv. */ @@ -216,11 +210,6 @@ _dl_allocate_tls_storage (void) dtv = (dtv_t *) malloc ((dtv_length + 2) * sizeof (dtv_t)); if (dtv != NULL) { -# if TLS_TCB_AT_TP - /* The TCB follows the TLS blocks. */ - result = (char *) result + GL(dl_tls_static_size) - TLS_TCB_SIZE; -# endif - /* This is the initial length of the dtv. */ dtv[0].counter = dtv_length; /* Fill in the generation number. */ @@ -233,9 +222,43 @@ _dl_allocate_tls_storage (void) INSTALL_DTV (result, dtv); } else + result = NULL; + + return result; +} + + +/* Get size and alignment requirements of the static TLS block. */ +void +internal_function +_dl_get_tls_static_info (size_t *sizep, size_t *alignp) +{ + *sizep = GL(dl_tls_static_size); + *alignp = GL(dl_tls_static_align); +} + + +void * +internal_function +_dl_allocate_tls_storage (void) +{ + void *result; + + /* Allocate a correctly aligned chunk of memory. */ + result = __libc_memalign (GL(dl_tls_static_align), GL(dl_tls_static_size)); + if (__builtin_expect (result != NULL, 0)) { - free (result); - result = NULL; + /* Allocate the DTV. */ + void *allocated = result; + +# if TLS_TCB_AT_TP + /* The TCB follows the TLS blocks. */ + result = (char *) result + GL(dl_tls_static_size) - TLS_TCB_SIZE; +# endif + + result = allocate_dtv (result); + if (result == NULL) + free (allocated); } return result; @@ -315,23 +338,26 @@ _dl_allocate_tls_init (void *result) void * internal_function -_dl_allocate_tls (void) +_dl_allocate_tls (void *mem) { - return _dl_allocate_tls_init (_dl_allocate_tls_storage ()); + return _dl_allocate_tls_init (mem == NULL + ? _dl_allocate_tls_storage () + : allocate_dtv (mem)); } INTDEF(_dl_allocate_tls) void internal_function -_dl_deallocate_tls (void *tcb) +_dl_deallocate_tls (void *tcb, bool dealloc_tcb) { dtv_t *dtv = GET_DTV (tcb); /* The array starts with dtv[-1]. */ free (dtv - 1); - free (tcb); + if (dealloc_tcb) + free (tcb); } diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index cd499f61b7..361cb0b72d 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -724,8 +724,12 @@ extern size_t _dl_next_tls_modid (void) internal_function; /* Calculate offset of the TLS blocks in the static TLS block. */ extern void _dl_determine_tlsoffset (void) internal_function; -/* Allocate memory for static TLS block and dtv. */ -extern void *_dl_allocate_tls (void) internal_function; +/* Allocate memory for static TLS block (unless MEM is nonzero) and dtv. */ +extern void *_dl_allocate_tls (void *mem) internal_function; + +/* Get size and alignment requirements of the static TLS block. */ +extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp) + internal_function; /* These are internal entry points to the two halves of _dl_allocate_tls, only used within rtld.c itself at startup time. */ @@ -735,7 +739,7 @@ extern void *_dl_allocate_tls_init (void *) internal_function attribute_hidden; /* Deallocate memory allocated with _dl_allocate_tls. */ -extern void _dl_deallocate_tls (void *tcb) internal_function; +extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function; /* Return the symbol address given the map of the module it is in and the symbol record. */ |