[lld] [ELF] Add target-specific relocation scanning for x86 (PR #178846)
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 6 04:16:24 PST 2026
================
@@ -66,8 +66,106 @@ 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) {
+ ctx.hasTlsIe.store(true, std::memory_order_relaxed);
+ if (!ctx.arg.shared && !sym.isPreemptible) {
+ sec->addReloc({R_TPREL, type, offset, addend, &sym});
+ } else {
+ sym.setFlags(NEEDS_TLSIE);
+ // R_GOT (absolute GOT address) needs a RELATIVE dynamic relocation in
+ // PIC. This is used by R_386_TLS_IE.
+ if (ieExpr == R_GOT && ctx.arg.isPic)
+ sec->getPartition(ctx).relaDyn->addRelativeReloc(
+ ctx.target->relativeRel, *sec, offset, sym, addend, type, ieExpr);
+ else
+ sec->addReloc({ieExpr, type, offset, addend, &sym});
+ }
+ }
+
+ // Handle TLS Local-Dynamic relocation. Returns true if the __tls_get_addr
+ // call should be skipped (i.e., caller should ++it).
+ bool handleTlsLd(RelExpr sharedExpr, RelType type, uint64_t offset,
+ int64_t addend, Symbol &sym) {
+ if (ctx.arg.shared) {
+ ctx.needsTlsLd.store(true, std::memory_order_relaxed);
+ sec->addReloc({sharedExpr, type, offset, addend, &sym});
+ return false;
+ }
+ sec->addReloc({R_TPREL, type, offset, addend, &sym});
+ return true;
+ }
+
+ // Handle TLS General-Dynamic relocation. Returns true if the __tls_get_addr
+ // call should be skipped (i.e., caller should ++it).
+ bool handleTlsGd(RelExpr sharedExpr, RelExpr ieExpr, RelExpr leExpr,
+ RelType type, uint64_t offset, int64_t addend, Symbol &sym) {
+ if (ctx.arg.shared) {
+ sym.setFlags(NEEDS_TLSGD);
+ sec->addReloc({sharedExpr, type, offset, addend, &sym});
+ return false;
+ }
+ if (sym.isPreemptible) {
+ ctx.hasTlsIe.store(true, std::memory_order_relaxed);
+ sym.setFlags(NEEDS_TLSIE);
+ sec->addReloc({ieExpr, type, offset, addend, &sym});
+ } else {
+ sec->addReloc({leExpr, type, offset, addend, &sym});
+ }
+ return true;
+ }
+
+ // Handle TLSDESC relocation.
+ void handleTlsDesc(RelExpr sharedExpr, RelExpr ieExpr, RelType type,
+ uint64_t offset, int64_t addend, Symbol &sym) {
+ if (ctx.arg.shared) {
+ sym.setFlags(NEEDS_TLSDESC);
+ sec->addReloc({sharedExpr, type, offset, addend, &sym});
+ } else if (sym.isPreemptible) {
+ ctx.hasTlsIe.store(true, std::memory_order_relaxed);
+ sym.setFlags(NEEDS_TLSIE);
+ sec->addReloc({ieExpr, type, offset, addend, &sym});
+ } else {
+ sec->addReloc({R_TPREL, type, offset, addend, &sym});
----------------
smithp35 wrote:
Suggest we add a comment
```
// Relax to Local Exec.
```
https://github.com/llvm/llvm-project/pull/178846
More information about the llvm-commits
mailing list