elf: Improve diagnostics for static TLS exhaustion

Message ID 20260528113329.1255380-1-fberat@redhat.com (mailing list archive)
State Superseded
Headers
Series 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

Frédéric Bérat May 28, 2026, 11:33 a.m. UTC
  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

Adhemerval Zanella Netto May 29, 2026, 6:06 p.m. UTC | #1
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
  

Patch

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)
+	{
+	  _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"));
     }
 }
 
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.  */