elf: Improve diagnostics for static TLS exhaustion
Checks
| Context |
Check |
Description |
| redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
| linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
| redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
| linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Test passed
|
Commit Message
Improve the error diagnostics printed when static TLS allocation fails
during dlopen.
The CHECK_STATIC_TLS macro is updated to pass the fully resolved sym and
the referencing map over to _dl_allocate_static_tls, modifying its
signature.
When _dl_allocate_static_tls is called, it now attempts to reconstruct
what failed using _dl_exception_create_format. It displays:
* The name of the symbol that triggers this.
* Whether this is due to static TLS space being exhausted, or if the
symbol has previously been used as global-dynamic and is now being
tried to use as initial-exec.
* If the symbol-defining map is different from the referencing map, it
includes its name as well.
* If static TLS is exhausted, includes requested size and available
size.
The change cascades through all architecture variants modifying their
dl-machine calls to CHECK_STATIC_TLS to conform to the new prototype.
---
elf/dl-reloc.c | 51 +++++++++++++++++++++++---
elf/dl-static-tls.h | 4 +-
sysdeps/aarch64/dl-machine.h | 4 +-
sysdeps/alpha/dl-machine.h | 2 +-
sysdeps/arc/dl-machine.h | 2 +-
sysdeps/arm/dl-machine.h | 4 +-
sysdeps/csky/dl-machine.h | 2 +-
sysdeps/generic/ldsodefs.h | 4 +-
sysdeps/hppa/dl-machine.h | 2 +-
sysdeps/i386/dl-machine.h | 6 +--
sysdeps/loongarch/dl-machine.h | 4 +-
sysdeps/m68k/dl-machine.h | 2 +-
sysdeps/microblaze/dl-machine.h | 2 +-
sysdeps/mips/dl-machine.h | 2 +-
sysdeps/or1k/dl-machine.h | 2 +-
sysdeps/powerpc/powerpc32/dl-machine.c | 2 +-
sysdeps/powerpc/powerpc32/dl-machine.h | 4 +-
sysdeps/powerpc/powerpc64/dl-machine.h | 4 +-
sysdeps/riscv/dl-machine.h | 2 +-
sysdeps/s390/dl-machine.h | 2 +-
sysdeps/sh/dl-machine.h | 2 +-
sysdeps/sparc/sparc32/dl-machine.h | 4 +-
sysdeps/sparc/sparc64/dl-machine.h | 4 +-
sysdeps/x86_64/dl-machine.h | 4 +-
24 files changed, 82 insertions(+), 39 deletions(-)
base-commit: b20b94006c79d65d75e5bd3a8d14fbcf9cd5bee6
Comments
On 28/05/26 08:33, Frédéric Bérat wrote:
> Improve the error diagnostics printed when static TLS allocation fails
> during dlopen.
>
> The CHECK_STATIC_TLS macro is updated to pass the fully resolved sym and
> the referencing map over to _dl_allocate_static_tls, modifying its
> signature.
>
> When _dl_allocate_static_tls is called, it now attempts to reconstruct
> what failed using _dl_exception_create_format. It displays:
> * The name of the symbol that triggers this.
> * Whether this is due to static TLS space being exhausted, or if the
> symbol has previously been used as global-dynamic and is now being
> tried to use as initial-exec.
> * If the symbol-defining map is different from the referencing map, it
> includes its name as well.
> * If static TLS is exhausted, includes requested size and available
> size.
>
> The change cascades through all architecture variants modifying their
> dl-machine calls to CHECK_STATIC_TLS to conform to the new prototype.
Looks good in general, some comments below.
> ---
> elf/dl-reloc.c | 51 +++++++++++++++++++++++---
> elf/dl-static-tls.h | 4 +-
> sysdeps/aarch64/dl-machine.h | 4 +-
> sysdeps/alpha/dl-machine.h | 2 +-
> sysdeps/arc/dl-machine.h | 2 +-
> sysdeps/arm/dl-machine.h | 4 +-
> sysdeps/csky/dl-machine.h | 2 +-
> sysdeps/generic/ldsodefs.h | 4 +-
> sysdeps/hppa/dl-machine.h | 2 +-
> sysdeps/i386/dl-machine.h | 6 +--
> sysdeps/loongarch/dl-machine.h | 4 +-
> sysdeps/m68k/dl-machine.h | 2 +-
> sysdeps/microblaze/dl-machine.h | 2 +-
> sysdeps/mips/dl-machine.h | 2 +-
> sysdeps/or1k/dl-machine.h | 2 +-
> sysdeps/powerpc/powerpc32/dl-machine.c | 2 +-
> sysdeps/powerpc/powerpc32/dl-machine.h | 4 +-
> sysdeps/powerpc/powerpc64/dl-machine.h | 4 +-
> sysdeps/riscv/dl-machine.h | 2 +-
> sysdeps/s390/dl-machine.h | 2 +-
> sysdeps/sh/dl-machine.h | 2 +-
> sysdeps/sparc/sparc32/dl-machine.h | 4 +-
> sysdeps/sparc/sparc64/dl-machine.h | 4 +-
> sysdeps/x86_64/dl-machine.h | 4 +-
> 24 files changed, 82 insertions(+), 39 deletions(-)
>
> diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
> index 15a6a4cffe..093a0eda1d 100644
> --- a/elf/dl-reloc.c
> +++ b/elf/dl-reloc.c
> @@ -131,13 +131,54 @@ _dl_try_allocate_static_tls (struct link_map *map, bool optional)
> not be inlined as much as possible. */
> void
> __attribute_noinline__
> -_dl_allocate_static_tls (struct link_map *map)
> +_dl_allocate_static_tls (struct link_map *map, struct link_map *sym_map,
> + const ElfW(Sym) *sym)
> {
> - if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
> - || _dl_try_allocate_static_tls (map, false))
> + if (sym_map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
> + || _dl_try_allocate_static_tls (sym_map, false))
> {
> - _dl_signal_error (0, map->l_name, NULL, N_("\
> -cannot allocate memory in static TLS block"));
> + const char *symname = "unknown";
> + const char *def_map_info = "";
> + const char *def_map_name = "";
> + struct dl_exception exception;
> +
> + if (sym != NULL)
> + {
> + const char *strtab
> + = (const char *) D_PTR (sym_map, l_info[DT_STRTAB]);
> + symname = strtab + sym->st_name;
> + if (symname[0] == '\0')
> + symname = "unknown";
> + }
> +
> + if (sym_map != map)
> + {
> + def_map_info = " defined in ";
> + def_map_name = DSO_FILENAME (sym_map->l_name);
> + }
> +
> + if (sym_map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET)
> + {
Maybe add a '/* XXX We cannot translate the message. */', similar on
dl-version.c.
> + _dl_exception_create_format (
> + &exception, DSO_FILENAME (map->l_name),
> + "cannot allocate memory in static TLS block: "
> + "%s%s%s: previously used as global-dynamic",
> + symname, def_map_info, def_map_name);
> + }
> + else
> + {
> + size_t requested = sym_map->l_tls_blocksize;
Should we considere l_tls_firstbyte_offset/l_tls_align here?
> + size_t available
> + = (GLRO (dl_tls_static_size) - GL (dl_tls_static_used));
Style nit: GL/GLRO definition is not really a macro/function call,
but a variable access - so no space.
> +
> + _dl_exception_create_format (
> + &exception, DSO_FILENAME (map->l_name),
> + "cannot allocate memory in static TLS block: "
> + "%s%s%s: requested %zx, available %zx",
> + symname, def_map_info, def_map_name, requested, available);
> + }
> +
> + _dl_signal_exception (0, &exception, N_ ("TLS allocation error"));
Same here.
> }
> }
>
> diff --git a/elf/dl-static-tls.h b/elf/dl-static-tls.h
> index 5bc5dbe0c3..b3cd6299f8 100644
> --- a/elf/dl-static-tls.h
> +++ b/elf/dl-static-tls.h
> @@ -33,10 +33,10 @@
> && ((sym_map)->l_tls_offset \
> != FORCED_DYNAMIC_TLS_OFFSET), 1))
>
> -#define CHECK_STATIC_TLS(map, sym_map) \
> +#define CHECK_STATIC_TLS(map, sym_map, sym) \
> do { \
> if (!HAVE_STATIC_TLS (map, sym_map)) \
> - _dl_allocate_static_tls (sym_map); \
> + _dl_allocate_static_tls (map, sym_map, sym); \
> } while (0)
>
> #define TRY_STATIC_TLS(map, sym_map) \
> diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
> index 15651c62f3..7605b760b8 100644
> --- a/sysdeps/aarch64/dl-machine.h
> +++ b/sysdeps/aarch64/dl-machine.h
> @@ -237,7 +237,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> else
> {
> # ifndef SHARED
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> # else
> if (!TRY_STATIC_TLS (map, sym_map))
> {
> @@ -271,7 +271,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case R_AARCH64_TLS_TPREL:
> if (sym)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr =
> sym->st_value + reloc->r_addend + sym_map->l_tls_offset;
> }
> diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
> index 77686c728e..7c500ea850 100644
> --- a/sysdeps/alpha/dl-machine.h
> +++ b/sysdeps/alpha/dl-machine.h
> @@ -405,7 +405,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> # else
> if (sym_map)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = sym_raw_value + sym_map->l_tls_offset;
> }
> # endif
> diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h
> index 50c9e877ae..7bb1b7be98 100644
> --- a/sysdeps/arc/dl-machine.h
> +++ b/sysdeps/arc/dl-machine.h
> @@ -283,7 +283,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case R_ARC_TLS_TPOFF:
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = sym_map->l_tls_offset + sym->st_value + reloc->r_addend;
> }
> break;
> diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
> index 15cced693e..8b1b0dc035 100644
> --- a/sysdeps/arm/dl-machine.h
> +++ b/sysdeps/arm/dl-machine.h
> @@ -383,7 +383,7 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
>
> # ifndef RTLD_BOOTSTRAP
> # ifndef SHARED
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> # else
> if (!TRY_STATIC_TLS (map, sym_map))
> {
> @@ -424,7 +424,7 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
> case R_ARM_TLS_TPOFF32:
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr += sym->st_value + sym_map->l_tls_offset;
> }
> break;
> diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h
> index 57444f4cce..a5804af4df 100644
> --- a/sysdeps/csky/dl-machine.h
> +++ b/sysdeps/csky/dl-machine.h
> @@ -301,7 +301,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case R_CKCORE_TLS_TPOFF32:
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = (sym->st_value + sym_map->l_tls_offset
> + reloc->r_addend);
> }
> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
> index 24529db8a1..54e92b08b7 100644
> --- a/sysdeps/generic/ldsodefs.h
> +++ b/sysdeps/generic/ldsodefs.h
> @@ -1228,7 +1228,9 @@ rtld_hidden_proto (_dl_allocate_tls)
> /* Get size and alignment requirements of the static TLS block. */
> extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp);
>
> -extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
> +extern void _dl_allocate_static_tls (struct link_map *map,
> + struct link_map *sym_map,
> + const ElfW(Sym) *sym) attribute_hidden;
>
> extern void *_dl_allocate_tls_storage (void) attribute_hidden;
> extern void *_dl_allocate_tls_init (void *result, bool main_thread);
> diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
> index f931087869..9bdbd85b6b 100644
> --- a/sysdeps/hppa/dl-machine.h
> +++ b/sysdeps/hppa/dl-machine.h
> @@ -714,7 +714,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> /* The offset is negative, forward from the thread pointer */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> value = sym_map->l_tls_offset + sym->st_value + reloc->r_addend;
> }
> break;
> diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
> index dd49079d75..b074c40dbf 100644
> --- a/sysdeps/i386/dl-machine.h
> +++ b/sysdeps/i386/dl-machine.h
> @@ -342,7 +342,7 @@ and creates an unsatisfiable circular dependency.\n",
> {
> # ifndef RTLD_BOOTSTRAP
> # ifndef SHARED
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> # else
> if (!TRY_STATIC_TLS (map, sym_map))
> {
> @@ -372,7 +372,7 @@ and creates an unsatisfiable circular dependency.\n",
> block we subtract the offset from that of the TLS block. */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr += sym_map->l_tls_offset - sym->st_value;
> }
> # endif
> @@ -387,7 +387,7 @@ and creates an unsatisfiable circular dependency.\n",
> thread pointer. */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr += sym->st_value - sym_map->l_tls_offset;
> }
> # endif
> diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
> index e8ee50b810..ae295264ae 100644
> --- a/sysdeps/loongarch/dl-machine.h
> +++ b/sysdeps/loongarch/dl-machine.h
> @@ -205,7 +205,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> break;
>
> case __WORDSIZE == 64 ? R_LARCH_TLS_TPREL64 : R_LARCH_TLS_TPREL32:
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend;
> break;
>
> @@ -220,7 +220,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> else
> {
> # ifndef SHARED
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> # else
> if (!TRY_STATIC_TLS (map, sym_map))
> {
> diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
> index e61dd27f5f..48b7705d71 100644
> --- a/sysdeps/m68k/dl-machine.h
> +++ b/sysdeps/m68k/dl-machine.h
> @@ -283,7 +283,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case R_68K_TLS_TPREL32:
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
> }
> break;
> diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h
> index 62031a589c..da59c00bea 100644
> --- a/sysdeps/microblaze/dl-machine.h
> +++ b/sysdeps/microblaze/dl-machine.h
> @@ -261,7 +261,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> {
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = sym->st_value + sym_map->l_tls_offset + reloc->r_addend;
> }
> }
> diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
> index 79d0df82c7..75cb5b10bb 100644
> --- a/sysdeps/mips/dl-machine.h
> +++ b/sysdeps/mips/dl-machine.h
> @@ -474,7 +474,7 @@ elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
> case R_MIPS_TLS_TPREL64:
> if (sym)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> if (inplace_p)
> r_addend = *addr_field;
> *addr_field = r_addend + TLS_TPREL_VALUE (sym_map, sym);
> diff --git a/sysdeps/or1k/dl-machine.h b/sysdeps/or1k/dl-machine.h
> index e6d88aabd9..b06da7c7c4 100644
> --- a/sysdeps/or1k/dl-machine.h
> +++ b/sysdeps/or1k/dl-machine.h
> @@ -254,7 +254,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> # else
> if (sym_map != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = sym->st_value + reloc->r_addend +
> sym_map->l_tls_offset - TLS_TCB_SIZE;
> }
> diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
> index 7127ebc32c..ebdfc63a47 100644
> --- a/sysdeps/powerpc/powerpc32/dl-machine.c
> +++ b/sysdeps/powerpc/powerpc32/dl-machine.c
> @@ -566,7 +566,7 @@ __process_machine_rela (struct link_map *map,
> case R_PPC_TPREL##suffix: \
> if (sym_map != NULL) \
> { \
> - CHECK_STATIC_TLS (map, sym_map); \
> + CHECK_STATIC_TLS (map, sym_map, sym); \
> do_reloc##suffix ("R_PPC_TPREL"#suffix, \
> TLS_TPREL_VALUE (sym_map, sym, reloc)); \
> } \
> diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
> index e07a44a5a5..e42f6fd399 100644
> --- a/sysdeps/powerpc/powerpc32/dl-machine.h
> +++ b/sysdeps/powerpc/powerpc32/dl-machine.h
> @@ -362,7 +362,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> else if (sym_map != NULL)
> {
> #ifndef SHARED
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> #else
> if (TRY_STATIC_TLS (map, sym_map))
> #endif
> @@ -415,7 +415,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> if (!NOT_BOOTSTRAP || sym_map != NULL)
> {
> if (NOT_BOOTSTRAP)
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
> }
> break;
> diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
> index 1f5d7a0170..cd4b3ab2f3 100644
> --- a/sysdeps/powerpc/powerpc64/dl-machine.h
> +++ b/sysdeps/powerpc/powerpc64/dl-machine.h
> @@ -628,7 +628,7 @@ elf_machine_tprel (struct link_map *map,
> #ifndef RTLD_BOOTSTRAP
> if (sym_map)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> #endif
> return TLS_TPREL_VALUE (sym_map, sym, reloc);
> #ifndef RTLD_BOOTSTRAP
> @@ -741,7 +741,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> if (sym_map != NULL)
> {
> # ifndef SHARED
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> # else
> if (TRY_STATIC_TLS (map, sym_map))
> # endif
> diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
> index babb52af20..3e3e51f82e 100644
> --- a/sysdeps/riscv/dl-machine.h
> +++ b/sysdeps/riscv/dl-machine.h
> @@ -215,7 +215,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case __WORDSIZE == 64 ? R_RISCV_TLS_TPREL64 : R_RISCV_TLS_TPREL32:
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend;
> }
> break;
> diff --git a/sysdeps/s390/dl-machine.h b/sysdeps/s390/dl-machine.h
> index ac27644b05..b8c7c54a3b 100644
> --- a/sysdeps/s390/dl-machine.h
> +++ b/sysdeps/s390/dl-machine.h
> @@ -327,7 +327,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> thread pointer. */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = (sym->st_value + reloc->r_addend
> - sym_map->l_tls_offset);
> }
> diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
> index 79d9aa65cc..e0b68dde8e 100644
> --- a/sysdeps/sh/dl-machine.h
> +++ b/sysdeps/sh/dl-machine.h
> @@ -371,7 +371,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> we add the offset from that of the TLS block. */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = sym_map->l_tls_offset + sym->st_value
> + reloc->r_addend;
> }
> diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
> index 3771339a04..946c68c7e4 100644
> --- a/sysdeps/sparc/sparc32/dl-machine.h
> +++ b/sysdeps/sparc/sparc32/dl-machine.h
> @@ -371,7 +371,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> thread pointer. */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = sym->st_value - sym_map->l_tls_offset
> + reloc->r_addend;
> }
> @@ -381,7 +381,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case R_SPARC_TLS_LE_LOX10:
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> value = sym->st_value - sym_map->l_tls_offset
> + reloc->r_addend;
> if (r_type == R_SPARC_TLS_LE_HIX22)
> diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
> index 8a1a38d170..c4eefe11d2 100644
> --- a/sysdeps/sparc/sparc64/dl-machine.h
> +++ b/sysdeps/sparc/sparc64/dl-machine.h
> @@ -387,7 +387,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> thread pointer. */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> *reloc_addr = sym->st_value - sym_map->l_tls_offset
> + reloc->r_addend;
> }
> @@ -397,7 +397,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> case R_SPARC_TLS_LE_LOX10:
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> value = sym->st_value - sym_map->l_tls_offset
> + reloc->r_addend;
> if (r_type == R_SPARC_TLS_LE_HIX22)
> diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
> index a94cb1a8af..f36e55b602 100644
> --- a/sysdeps/x86_64/dl-machine.h
> +++ b/sysdeps/x86_64/dl-machine.h
> @@ -372,7 +372,7 @@ and creates an unsatisfiable circular dependency.\n",
> else
> {
> # ifndef SHARED
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> # else
> if (!TRY_STATIC_TLS (map, sym_map))
> {
> @@ -394,7 +394,7 @@ and creates an unsatisfiable circular dependency.\n",
> /* The offset is negative, forward from the thread pointer. */
> if (sym != NULL)
> {
> - CHECK_STATIC_TLS (map, sym_map);
> + CHECK_STATIC_TLS (map, sym_map, sym);
> /* We know the offset of the object the symbol is contained in.
> It is a negative value which will be added to the
> thread pointer. */
>
> base-commit: b20b94006c79d65d75e5bd3a8d14fbcf9cd5bee6
@@ -131,13 +131,54 @@ _dl_try_allocate_static_tls (struct link_map *map, bool optional)
not be inlined as much as possible. */
void
__attribute_noinline__
-_dl_allocate_static_tls (struct link_map *map)
+_dl_allocate_static_tls (struct link_map *map, struct link_map *sym_map,
+ const ElfW(Sym) *sym)
{
- if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
- || _dl_try_allocate_static_tls (map, false))
+ if (sym_map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
+ || _dl_try_allocate_static_tls (sym_map, false))
{
- _dl_signal_error (0, map->l_name, NULL, N_("\
-cannot allocate memory in static TLS block"));
+ const char *symname = "unknown";
+ const char *def_map_info = "";
+ const char *def_map_name = "";
+ struct dl_exception exception;
+
+ if (sym != NULL)
+ {
+ const char *strtab
+ = (const char *) D_PTR (sym_map, l_info[DT_STRTAB]);
+ symname = strtab + sym->st_name;
+ if (symname[0] == '\0')
+ symname = "unknown";
+ }
+
+ if (sym_map != map)
+ {
+ def_map_info = " defined in ";
+ def_map_name = DSO_FILENAME (sym_map->l_name);
+ }
+
+ if (sym_map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET)
+ {
+ _dl_exception_create_format (
+ &exception, DSO_FILENAME (map->l_name),
+ "cannot allocate memory in static TLS block: "
+ "%s%s%s: previously used as global-dynamic",
+ symname, def_map_info, def_map_name);
+ }
+ else
+ {
+ size_t requested = sym_map->l_tls_blocksize;
+ size_t available
+ = (GLRO (dl_tls_static_size) - GL (dl_tls_static_used));
+
+ _dl_exception_create_format (
+ &exception, DSO_FILENAME (map->l_name),
+ "cannot allocate memory in static TLS block: "
+ "%s%s%s: requested %zx, available %zx",
+ symname, def_map_info, def_map_name, requested, available);
+ }
+
+ _dl_signal_exception (0, &exception, N_ ("TLS allocation error"));
}
}
@@ -33,10 +33,10 @@
&& ((sym_map)->l_tls_offset \
!= FORCED_DYNAMIC_TLS_OFFSET), 1))
-#define CHECK_STATIC_TLS(map, sym_map) \
+#define CHECK_STATIC_TLS(map, sym_map, sym) \
do { \
if (!HAVE_STATIC_TLS (map, sym_map)) \
- _dl_allocate_static_tls (sym_map); \
+ _dl_allocate_static_tls (map, sym_map, sym); \
} while (0)
#define TRY_STATIC_TLS(map, sym_map) \
@@ -237,7 +237,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
else
{
# ifndef SHARED
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
# else
if (!TRY_STATIC_TLS (map, sym_map))
{
@@ -271,7 +271,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_AARCH64_TLS_TPREL:
if (sym)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr =
sym->st_value + reloc->r_addend + sym_map->l_tls_offset;
}
@@ -405,7 +405,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
# else
if (sym_map)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = sym_raw_value + sym_map->l_tls_offset;
}
# endif
@@ -283,7 +283,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_ARC_TLS_TPOFF:
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = sym_map->l_tls_offset + sym->st_value + reloc->r_addend;
}
break;
@@ -383,7 +383,7 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
# ifndef RTLD_BOOTSTRAP
# ifndef SHARED
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
# else
if (!TRY_STATIC_TLS (map, sym_map))
{
@@ -424,7 +424,7 @@ elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
case R_ARM_TLS_TPOFF32:
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr += sym->st_value + sym_map->l_tls_offset;
}
break;
@@ -301,7 +301,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_CKCORE_TLS_TPOFF32:
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = (sym->st_value + sym_map->l_tls_offset
+ reloc->r_addend);
}
@@ -1228,7 +1228,9 @@ rtld_hidden_proto (_dl_allocate_tls)
/* Get size and alignment requirements of the static TLS block. */
extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp);
-extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
+extern void _dl_allocate_static_tls (struct link_map *map,
+ struct link_map *sym_map,
+ const ElfW(Sym) *sym) attribute_hidden;
extern void *_dl_allocate_tls_storage (void) attribute_hidden;
extern void *_dl_allocate_tls_init (void *result, bool main_thread);
@@ -714,7 +714,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
/* The offset is negative, forward from the thread pointer */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
value = sym_map->l_tls_offset + sym->st_value + reloc->r_addend;
}
break;
@@ -342,7 +342,7 @@ and creates an unsatisfiable circular dependency.\n",
{
# ifndef RTLD_BOOTSTRAP
# ifndef SHARED
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
# else
if (!TRY_STATIC_TLS (map, sym_map))
{
@@ -372,7 +372,7 @@ and creates an unsatisfiable circular dependency.\n",
block we subtract the offset from that of the TLS block. */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr += sym_map->l_tls_offset - sym->st_value;
}
# endif
@@ -387,7 +387,7 @@ and creates an unsatisfiable circular dependency.\n",
thread pointer. */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr += sym->st_value - sym_map->l_tls_offset;
}
# endif
@@ -205,7 +205,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
break;
case __WORDSIZE == 64 ? R_LARCH_TLS_TPREL64 : R_LARCH_TLS_TPREL32:
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend;
break;
@@ -220,7 +220,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
else
{
# ifndef SHARED
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
# else
if (!TRY_STATIC_TLS (map, sym_map))
{
@@ -283,7 +283,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_68K_TLS_TPREL32:
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
}
break;
@@ -261,7 +261,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
{
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = sym->st_value + sym_map->l_tls_offset + reloc->r_addend;
}
}
@@ -474,7 +474,7 @@ elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
case R_MIPS_TLS_TPREL64:
if (sym)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
if (inplace_p)
r_addend = *addr_field;
*addr_field = r_addend + TLS_TPREL_VALUE (sym_map, sym);
@@ -254,7 +254,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
# else
if (sym_map != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = sym->st_value + reloc->r_addend +
sym_map->l_tls_offset - TLS_TCB_SIZE;
}
@@ -566,7 +566,7 @@ __process_machine_rela (struct link_map *map,
case R_PPC_TPREL##suffix: \
if (sym_map != NULL) \
{ \
- CHECK_STATIC_TLS (map, sym_map); \
+ CHECK_STATIC_TLS (map, sym_map, sym); \
do_reloc##suffix ("R_PPC_TPREL"#suffix, \
TLS_TPREL_VALUE (sym_map, sym, reloc)); \
} \
@@ -362,7 +362,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
else if (sym_map != NULL)
{
#ifndef SHARED
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
#else
if (TRY_STATIC_TLS (map, sym_map))
#endif
@@ -415,7 +415,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
if (!NOT_BOOTSTRAP || sym_map != NULL)
{
if (NOT_BOOTSTRAP)
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
}
break;
@@ -628,7 +628,7 @@ elf_machine_tprel (struct link_map *map,
#ifndef RTLD_BOOTSTRAP
if (sym_map)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
#endif
return TLS_TPREL_VALUE (sym_map, sym, reloc);
#ifndef RTLD_BOOTSTRAP
@@ -741,7 +741,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
if (sym_map != NULL)
{
# ifndef SHARED
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
# else
if (TRY_STATIC_TLS (map, sym_map))
# endif
@@ -215,7 +215,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case __WORDSIZE == 64 ? R_RISCV_TLS_TPREL64 : R_RISCV_TLS_TPREL32:
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend;
}
break;
@@ -327,7 +327,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
thread pointer. */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = (sym->st_value + reloc->r_addend
- sym_map->l_tls_offset);
}
@@ -371,7 +371,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
we add the offset from that of the TLS block. */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = sym_map->l_tls_offset + sym->st_value
+ reloc->r_addend;
}
@@ -371,7 +371,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
thread pointer. */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend;
}
@@ -381,7 +381,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_SPARC_TLS_LE_LOX10:
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
value = sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend;
if (r_type == R_SPARC_TLS_LE_HIX22)
@@ -387,7 +387,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
thread pointer. */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
*reloc_addr = sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend;
}
@@ -397,7 +397,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
case R_SPARC_TLS_LE_LOX10:
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
value = sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend;
if (r_type == R_SPARC_TLS_LE_HIX22)
@@ -372,7 +372,7 @@ and creates an unsatisfiable circular dependency.\n",
else
{
# ifndef SHARED
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
# else
if (!TRY_STATIC_TLS (map, sym_map))
{
@@ -394,7 +394,7 @@ and creates an unsatisfiable circular dependency.\n",
/* The offset is negative, forward from the thread pointer. */
if (sym != NULL)
{
- CHECK_STATIC_TLS (map, sym_map);
+ CHECK_STATIC_TLS (map, sym_map, sym);
/* We know the offset of the object the symbol is contained in.
It is a negative value which will be added to the
thread pointer. */