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

Farid Zakaria via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 15:55:20 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()))
----------------
fzakaria wrote:

Older compilers seem to generate PC32 https://godbolt.org/z/e39cEM4dj
We can support it by augmenting the PC32 to PLT depending on the opcode

```
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -399,9 +399,16 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
     return R_PLT_PC;
   case R_X86_64_PC8:
   case R_X86_64_PC16:
-  case R_X86_64_PC32:
   case R_X86_64_PC64:
     return R_PC;
+  case R_X86_64_PC32:
+    // Old compilers (pre-2017 binutils) may use R_X86_64_PC32 for call/jmp
+    // instructions. Check the opcode byte to promote branches to R_PLT_PC
+    // so they are eligible for thunking and PLT optimization, while keeping
+    // data references (lea, mov) as plain R_PC.
+    if (loc[-1] == 0xe8 || loc[-1] == 0xe9)
+      return R_PLT_PC;
+    return R_PC;
   case R_X86_64_GOT32:
   case R_X86_64_GOT64:
     return R_GOTPLT;
```

I will see if we can test this.

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


More information about the llvm-commits mailing list