[PATCH] elf: Remove the GET_ADDR_ARGS and related macros from the TLS code

Frank Scheiner frank.scheiner@web.de
Sat Dec 28 12:00:59 GMT 2024


Dear Florian,

On 23.12.24 15:32, Florian Weimer wrote:
> This was used to manage an IA-64 ABI divergence is no longere needed
> after the IA-64 removal.
>
> (It should be possible to encode all the required information in
> one machine word, so the pointer indirection is really unnecessary.
> Technically, none of this is part of the ABI, so perhaps it's
> possible to do this retroactively.  See bug 27404.)

So this breaks our toolchain builds for ia64 ([1]) - as expected.

[1]: https://github.com/linux-ia64/glibc-ia64/issues/7

I am trying to "fix" that in a way that keeps the changes active for
architectures other than ia64 but at the same time keeps the builds for
ia64 working.

I also looked at [2] but I don't know if ia64 can be switched over to
using the "generic" __tls_get_addr() with single tls_index struct instead
of two arguments. I guess not, otherwise it would have been implemented
differently from the start maybe.

[2]: https://sourceware.org/pipermail/libc-alpha/2024-December/163165.html

So I came up with a partial revert ([3]) instead that masks out
tls_get_addr_tail() and update_get_addr() (both not used on ia64 - IIUC)
depending on the definition of DONT_USE_TLS_INDEX, which is the case for
ia64 as it doesn't have a tls_index type (yet) as per
`sysdeps/ia64/dl-tls.h`.

[3]: https://github.com/linux-ia64/glibc-ia64/commit/828e8c109719b48e83df34930231e089ad5d97a8

I would have also masked out "__tls_get_addr (tls_index *ti)" - assuming
it also wouldn't be needed on ia64, as it has its own implementation -
but this leads to a build error:

```
In file included from <command-line>:
./../include/libc-symbols.h:463:33: error: '__EI___tls_get_addr' aliased to undefined symbol '__GI___tls_get_addr'
  463 |   extern thread __typeof (name) __EI_##name \
      |                                 ^~~~~
./../include/libc-symbols.h:459:3: note: in expansion of macro '__hidden_ver2'
  459 |   __hidden_ver2 (, local, internal, name)
      |   ^~~~~~~~~~~~~
./../include/libc-symbols.h:467:41: note: in expansion of macro '__hidden_ver1'
  467 | #  define hidden_def(name)              __hidden_ver1(__GI_##name, name, name);
      |                                         ^~~~~~~~~~~~~
./../include/libc-symbols.h:571:32: note: in expansion of macro 'hidden_def'
  571 | # define rtld_hidden_def(name) hidden_def (name)
      |                                ^~~~~~~~~~
dl-tls.c:996:1: note: in expansion of macro 'rtld_hidden_def'
  996 | rtld_hidden_def (__tls_get_addr)
      | ^~~~~~~~~~~~~~~
```

So I instead define __tls_get_addr (GET_ADDR_ARGS) with an empty body
when DONT_USE_TLS_INDEX is defined.

Maybe just defining the tls_index type for ia64 to allow those three
functions - which are assumingly not used on ia64 - to be defined as
is, would be the less intrusive change. But I don't know.

****

I still wonder why a separate "implementation" for __tls_get_addr() is
needed for the ia64 build to succeed, as it has it's own implementation in
`sysdeps/ia64/libc-tls.c` with the required number of arguments:

```
void *
__tls_get_addr (size_t m, size_t offset)
{
  dtv_t *dtv = THREAD_DTV ();
  return (char *) dtv[1].pointer.val + offset;
}
```

...which is IIUC also referenced by:

```
#ifndef __tls_get_addr
extern void * __tls_get_addr (GET_ADDR_ARGS);
rtld_hidden_proto (__tls_get_addr)
rtld_hidden_def (__tls_get_addr)
#endif
```

...in `elf/dl-tls.c`.

Cheers,
Frank


More information about the Libc-alpha mailing list