TLS does not support 64bit relocations

14 views
Skip to first unread message

Farid Zakaria

unread,
Jul 27, 2026, 11:58:20 AM (8 days ago) Jul 27
to X86-64 System V Application Binary Interface
Hi,

I decided to breakout part of
https://groups.google.com/g/x86-64-abi/c/iEwXPVq48i4/m/1qns04tICAAJ
into it's own topic, specificaly about TLS relocation overflows.

Here is an example of a relocation overflow I've run into:

ld.lld: error: ...libgen_patch_client_config-cpp2-types...o:
relocation R_X86_64_PLT32 out of range: 2636113542 is not in
[-2147483648, 2147483647];
references '__tls_get_addr'
>>> defined in fbcode/third-party-buck/platform010/build/glibc/lib/ld-linux-x86-64.so.2
RELOCATION: R_X86_64_TLSGD ... offset in output section .ltext ... 2.04 GiB
TARGET: folly::SharedMutexImpl<...>::tls_lastTokenlessSlot()::tl (.tbss)
output section .tbss address 0xd1a7c6a0 (~3.52 GB)

I will admit my knowledge about TLS is relatively minimal especially
when it comes to relocations.

I decided to do a somewhat deep-dive into it and wrote-up the
following to describe the failure mode:
https://fzakaria.com/2026/07/26/seriously-what-is-the-large-code-model-even-for
Knowledge about TLS online is varied and sparse. I tried to root it in
the ABI and what clang/gcc emits.)

tl;dr;
Looks like the ABI for TLS code-sequences always rely on 32-bit offsets.
- local-exec: Uses R_X86_64_TPOFF32 which is 32-bit
- initial-exec: Uses GOTTPOFF which is 32 bit
- general-dynamic: Uses R_X86_64_TLSGD which is 32 bit

The easiest to fix seems initial-exec since we can replace GOTTPOFF
with GOTPC64/GOT64 equivalent. We can/should probably also expand the
ABI to include a code sequence for R_X86_64_TPOFF64 with
mcmodel=large.

Florian Weimer

unread,
Jul 28, 2026, 6:11:54 AM (7 days ago) Jul 28
to 'Farid Zakaria' via X86-64 System V Application Binary Interface, Farid Zakaria
* via:

> Looks like the ABI for TLS code-sequences always rely on 32-bit offsets.
> - local-exec: Uses R_X86_64_TPOFF32 which is 32-bit

This offset is relative to the thread pointer. 32 bits are enough for
now.

Do you need support for large shared objects?

> - initial-exec: Uses GOTTPOFF which is 32 bit
> - general-dynamic: Uses R_X86_64_TLSGD which is 32 bit

Initial-exec TLS is not general enough for shared objects.

The support data for both types of TLS can be duplicated by the link
editor as needed because the address is not significant. I dont't think
new relocations are required.

Thanks,
Florian

Farid Zakaria

unread,
Jul 28, 2026, 1:19:00 PM (7 days ago) Jul 28
to Florian Weimer, 'Farid Zakaria' via X86-64 System V Application Binary Interface, John Porto, Rafael Auler
Hi Florian,

On Tue, Jul 28, 2026 at 3:11 AM Florian Weimer <fwe...@redhat.com> wrote:
>
> >
> * via:
>
> > Looks like the ABI for TLS code-sequences always rely on 32-bit offsets.
> > - local-exec: Uses R_X86_64_TPOFF32 which is 32-bit
>
> This offset is relative to the thread pointer. 32 bits are enough for
> now.

Yes, I met with my colleague John and Rafael and that was one thing we
discussed.
I audited all our binaries and sure-enough the TLS block is < 32bits.
I misunderstood that it was a pointer from the base of the TLS block;
I though it was from the instruction.

>
> Do you need support for large shared objects?
>
> > - initial-exec: Uses GOTTPOFF which is 32 bit
> > - general-dynamic: Uses R_X86_64_TLSGD which is 32 bit
>
> Initial-exec TLS is not general enough for shared objects.
>
> The support data for both types of TLS can be duplicated by the link
> editor as needed because the address is not significant. I dont't think
> new relocations are required.

Yes our large-objects still use shared-objects; and they are mixed code-models.
(We also support PIC & non-PIC)

I saw errors with R_X86_64_TLSGD in our local testing:

ld.lld: error: ...libgen_patch_client_config-cpp2-types...o:
relocation R_X86_64_PLT32 out of range: 2636113542 is not in
[-2147483648, 2147483647];
references '__tls_get_addr'
>>> defined in fbcode/third-party-buck/platform010/build/glibc/lib/ld-linux-x86-64.so.2
RELOCATION: R_X86_64_TLSGD ... offset in output section .ltext ... 2.04 GiB
TARGET: folly::SharedMutexImpl<...>::tls_lastTokenlessSlot()::tl (.tbss)
output section .tbss address 0xd1a7c6a0 (~3.52 GB)

Does R_X86_64_TLSGD need a 64 bit variant as it's a GOT-like offset?

>
> Thanks,
> Florian
>

Florian Weimer

unread,
Jul 28, 2026, 1:46:01 PM (7 days ago) Jul 28
to Farid Zakaria, 'Farid Zakaria' via X86-64 System V Application Binary Interface, John Porto, Rafael Auler
* Farid Zakaria:

> Does R_X86_64_TLSGD need a 64 bit variant as it's a GOT-like offset?

I think linkers need to emit local versions of the relocation
information at a convenient office, otherwise you'll end up with
triple-indirection or worse, which is very bad for performance.

Thanks,
Florian

Farid Zakaria

unread,
Jul 29, 2026, 4:16:48 PM (5 days ago) Jul 29
to Florian Weimer, 'Farid Zakaria' via X86-64 System V Application Binary Interface, John Porto, Rafael Auler, Arthur Eubanks
This sounds similar to multiple-GOT effectively right?
We have a proposal for that in the RFC Athur and I are working towards
however that is a lot harder.

I was wondering whether there is a shorter-term solution: introduce a
relocation and code sequence that materializes the full-width
address of a TLSGD GOT entry, analogous to how the large code model
accesses ordinary GOT entries.

> Thanks,
> Florian
>

Florian Weimer

unread,
Jul 30, 2026, 2:05:58 AM (5 days ago) Jul 30
to Farid Zakaria, 'Farid Zakaria' via X86-64 System V Application Binary Interface, John Porto, Rafael Auler, Arthur Eubanks
* Farid Zakaria:

> On Tue, Jul 28, 2026 at 10:46 AM Florian Weimer <fwe...@redhat.com> wrote:
>>
>> >
>> * Farid Zakaria:
>>
>> > Does R_X86_64_TLSGD need a 64 bit variant as it's a GOT-like offset?
>>
>> I think linkers need to emit local versions of the relocation
>> information at a convenient office, otherwise you'll end up with
>> triple-indirection or worse, which is very bad for performance.
>>
>
> This sounds similar to multiple-GOT effectively right?

No, these are not GOT entries. The dynamic linker does not enforce that
the TLS metadata is located in a specific position in the executable, or
that it is continuous.

However, new executables should use R_X86_64_TLSDESC, which should be
covered by RELRO, so multi-RELRO support would be recommended for this.

Thanks,
Florian

Reply all
Reply to author
Forward
0 new messages