aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--elf/Versions1
-rw-r--r--sysdeps/generic/dl-tls.c64
-rw-r--r--sysdeps/generic/ldsodefs.h10
4 files changed, 66 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 21164f2ff5..bfd9a2d281 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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. */