Skip to content

LLVM uses R_X86_64_TPOFF32 relocations for large code model (-mcmodel=large), resulting in 'relocation truncated to fit' error #77128

@nmosier

Description

@nmosier
Contributor

LLVM appears to generate R_X86_64_TPOFF32 relocations for accesses to thread-local variables, even when the large code model is enabled with the clang flag -mcmodel=large. This results in a linker error for programs that require >4GB thread-local data sections (.tdata and .tbss).

Here is an example program that fails to compile:

#define BUFSIZE (1024UL * 1024UL * 1024UL * 5UL)
_Thread_local char buf[BUFSIZE];
int main() {
  buf[BUFSIZE-1] = 0;
}

Compile as follows: clang -mcmodel=large test.c
Produces following error:

/tmp/user/20498/large-633e12.o: in function `main':
large.c:(.text+0xf): relocation truncated to fit: R_X86_64_TPOFF32 against symbol `buf' defined in .tbss section in /tmp/user/20498/large-633e12.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Activity

llvmbot

llvmbot commented on Jan 23, 2024

@llvmbot
Member

@llvm/issue-subscribers-backend-x86

Author: Nicholas Mosier (nmosier)

LLVM appears to generate R_X86_64_TPOFF32 relocations for accesses to thread-local variables, even when the large code model is enabled with the clang flag `-mcmodel=large`. This results in a linker error for programs that require >4GB thread-local data sections (.tdata and .tbss).

Here is an example program that fails to compile:

#define BUFSIZE (1024UL * 1024UL * 1024UL * 5UL)
_Thread_local char buf[BUFSIZE];
int main() {
  buf[BUFSIZE-1] = 0;
}

Compile as follows: clang -mcmodel=large test.c
Produces following error:

/tmp/user/20498/large-633e12.o: in function `main':
large.c:(.text+0xf): relocation truncated to fit: R_X86_64_TPOFF32 against symbol `buf' defined in .tbss section in /tmp/user/20498/large-633e12.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
MaskRay

MaskRay commented on Jan 25, 2024

@MaskRay
Member

LLVM appears to generate R_X86_64_TPOFF32 relocations for accesses to thread-local variables, even when the large code model is enabled with the clang flag -mcmodel=large. This results in a linker error for programs that require >4GB thread-local data sections (.tdata and .tbss).

The large code model is for code and data. There is no requirement that a large code model needs to support >4GB TLS.
I'd consider this a wont-change, as using a longer code sequence is going to pessimize every large code model user without tangible benefits. In addition, GCC generates R_X86_64_TPOFF32. There is no hard requirement that we must match it, but we should make careful judgement.

aeubanks

aeubanks commented on Jan 25, 2024

@aeubanks
Contributor

The large code model is already extremely slow, I doubt TLS performance is a concern.

IMO making the large code model work with large TLS data seems fine if many people request it. Is this something you actually hit in real binaries, or just a theoretical thing? 4GB TLS does seems like a lot.

MaskRay

MaskRay commented on Jan 26, 2024

@MaskRay
Member

Note: a 2GiB static TLS block almost assuredly won't work. It means that the dynamic loader needs to allocate 2GiB thread stack upfront for each new thread. No lazy allocation is possible. The memory use is just not affordable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @MaskRay@aeubanks@dtcxzyw@nmosier@llvmbot

        Issue actions

          LLVM uses R_X86_64_TPOFF32 relocations for large code model (-mcmodel=large), resulting in 'relocation truncated to fit' error · Issue #77128 · llvm/llvm-project