This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: providing __tls_get_addr on s390?
- From: Stefan Liebler <stli at linux dot ibm dot com>
- To: "Carlos O'Donell" <carlos at redhat dot com>, libc-alpha at sourceware dot org
- Cc: Florian Weimer <fweimer at redhat dot com>, Robin Dapp <rdapp at de dot ibm dot com>, Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- Date: Mon, 2 Sep 2019 14:24:08 +0200
- Subject: Re: providing __tls_get_addr on s390?
- References: <20190831141030.GA6914@aurel32.net> <862fbffd-f0cc-bc79-4d16-11a5a31108ec@redhat.com>
On 8/31/19 4:28 PM, Carlos O'Donell wrote:
On 8/31/19 10:10 AM, Aurelien Jarno wrote:
Dear all,
I have noticed that GCC recently started to use the
__tls_get_addr_internal symbol on s390 [1]. This is probably a bad
idea to use an internal libc symbol outside of the libc as it can be
modified or removed at anytime.
That said, I also noticed that s390 is (one of the) only architectures
which doesn't provide __tls_get_addr. Is there a reason for that? Is it
something that we should fix?
Stefan,
Is there any reason s390 doesn't implement __tls_get_addr like other arches?
It's always easier if all the machines support the same generic infrastructure.
The lack of __tls_get_addr on s390 forces the D language runtime to have
Z Series specific code to handle TLS calculations :-(
According to the s390 specific "ELF Handling for Thread-Local-Storage"
parts:
The s390 ABI is defined to use the __tls_get_offset function instead of
the __tls_get_addr function used in other ABIs. The prototype is:
unsigned long int __tls_get_offset (unsigned long int offset);
The function has a second, hidden parameter. The caller needs to set up
the GOT register %r12 to contain the address of the global offset table
of the caller’s module. The offset parameter, when added to the value of
the GOT register, yields the address of a tls_index structure located in
the caller’s global offset table.
The return value of __tls_get_offset is an offset to the thread pointer.
To get the address of the requested variable the thread pointer needs to
be added to the return value. The use of __tls_get_offset might seem
more complicated than the standard __tls_get_addr but for s390 the use
of tls get offset allows for better code sequences.
The D-language runtime should be fixed and use __tls_get_offset instead
of __tls_get_addr_internal@GLIBC_PRIVATE on s390x/s390.
__tls_get_offset internally computes the address of the tls_index struct
and then calls the not exported __tls_get_addr function.
But as __tls_get_offset assumes that the tls_index struct is located in
the GOT of the caller, it just adds r12 (=GOT-pointer) to the provided
offset in order to get the address to tls_index struct.
As Florian Weimer has already mentioned in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91628#c6 the offset could
be prepared.
Usually r12 is setup by the compiler for cross-module calls. It is a
call-saved register and is not modified by the PLT code.
Aurelien,
The D-language runtime encodes a ton of TLS-specific implementation details
and one of them is accessing TLS details.
This can be seen as a failing of glibc to provide a generic low-level TLS
interface for language runtimes. There aren't enough details spelled out
to make it easy to provide TLS details to the runtime.
Either way, *no* language runtime should be using GLIBC_PRIVATE symbols.
Could you please file a bug for that? If they need access they should do
so through the appropriate API e.g. __tls_get_addr which is a standard
API with specified semantics.