[lld] [lld][ELF] Add range extension thunks for x86-64 (PR #180266)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 11 00:15:04 PST 2026


================
@@ -1396,6 +1406,50 @@ void RetpolineZNow::writePlt(uint8_t *buf, const Symbol &sym,
   write32le(buf + 8, ctx.in.plt->getVA() - pltEntryAddr - 12);
 }
 
+// For x86-64, thunks are needed when the displacement between the branch
+// instruction and its target exceeds the 32-bit signed range (2GiB).
+// This can happen in very large binaries where .text exceeds 2GiB.
+bool X86_64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
+                        uint64_t branchAddr, const Symbol &s,
+                        int64_t a) const {
+  // Only branch relocations need thunks.
+  // R_X86_64_PLT32 is used for call/jmp instructions and always needs thunks.
+  // R_X86_64_PC32 is more general and can be used for both branches and data
+  // accesses (lea, mov). We only create thunks for function symbols.
+  if (type != R_X86_64_PLT32 && (type != R_X86_64_PC32 || !s.isFunc()))
----------------
MaskRay wrote:

I agree that we should not handle R_X86_64_PC32, and we should return R_PLT_PC for PC32 by "disassembling" the instruction (which might not be an instruction). This means  that we cannot handle GNU Assembler generated calls like the following (see https://sourceware.org/pipermail/binutils/2026-February/148179.html )

```
call .text1 # sigh, R_X86_64_PC32 in gas due to https://sourceware.org/bugzilla/show_bug.cgi?id=26263
call foo # R_X86_64_PC32
.section .text1,"ax"
foo:
```

https://github.com/llvm/llvm-project/pull/180266


More information about the llvm-commits mailing list