[lld] [ELF] Add target-specific relocation scanning for x86 (PR #178846)

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 9 04:08:40 PDT 2026


================
@@ -66,8 +66,112 @@ class RelocScan {
                                 uint64_t relOff) const;
   void process(RelExpr expr, RelType type, uint64_t offset, Symbol &sym,
                int64_t addend) const;
+  // Process relocation after needsGot/needsPlt flags are already handled.
+  void processAux(RelExpr expr, RelType type, uint64_t offset, Symbol &sym,
+                  int64_t addend) const;
   unsigned handleTlsRelocation(RelExpr expr, RelType type, uint64_t offset,
                                Symbol &sym, int64_t addend);
+
+  // Process R_PC relocations. These are the most common relocation type, so we
+  // inline the isStaticLinkTimeConstant check.
+  void processR_PC(RelType type, uint64_t offset, int64_t addend, Symbol &sym) {
+    if (LLVM_UNLIKELY(sym.isGnuIFunc()))
+      sym.setFlags(HAS_DIRECT_RELOC);
+    if (sym.isPreemptible || (isAbsolute(sym) && ctx.arg.isPic))
+      processAux(R_PC, type, offset, sym, addend);
+    else
+      sec->addReloc({R_PC, type, offset, addend, &sym});
+  }
+
+  // Process R_PLT_PC relocations. These are very common (calls), so we inline
+  // the isStaticLinkTimeConstant check. Non-preemptible symbols are optimized
+  // to R_PC (direct call).
+  void processR_PLT_PC(RelType type, uint64_t offset, int64_t addend,
+                       Symbol &sym) {
+    if (LLVM_UNLIKELY(sym.isGnuIFunc())) {
+      process(R_PLT_PC, type, offset, sym, addend);
+      return;
+    }
+    if (sym.isPreemptible) {
+      sym.setFlags(NEEDS_PLT);
+      sec->addReloc({R_PLT_PC, type, offset, addend, &sym});
+    } else if (!(isAbsolute(sym) && ctx.arg.isPic)) {
+      sec->addReloc({R_PC, type, offset, addend, &sym});
+    } else {
+      processAux(R_PC, type, offset, sym, addend);
+    }
+  }
+
+  // Handle TLS Initial-Exec relocation.
+  void handleTlsIe(RelExpr ieExpr, RelType type, uint64_t offset,
+                   int64_t addend, Symbol &sym) {
+    if (!ctx.arg.shared && !sym.isPreemptible) {
+      // Optimize to Local Exec.
+      sec->addReloc({R_TPREL, type, offset, addend, &sym});
+    } else {
+      ctx.hasTlsIe.store(true, std::memory_order_relaxed);
+      sym.setFlags(NEEDS_TLSIE);
----------------
smithp35 wrote:

Yes. If you are able to debug the example then checking what happens in `void elf::postScanRelocations(Ctx &ctx)` (https://github.com/llvm/llvm-project/blob/main/lld/ELF/Relocations.cpp#L1403) for the symbol in question, will help.

It is possible that there's some combination of options, perhaps more than one TLS flag has been set on the symbol, or there's an early exit (can't immediately see how from the code) that causes the GOT entry not to be created.





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


More information about the llvm-commits mailing list