[lld] 3be67c7 - [ELF] Add target-specific relocation scanning for SPARCV9 (#206284)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 5 12:01:31 PDT 2026


Author: Fangrui Song
Date: 2026-07-05T12:01:27-07:00
New Revision: 3be67c72f5d5b9f459c0b11fce2c92c2cac5a984

URL: https://github.com/llvm/llvm-project/commit/3be67c72f5d5b9f459c0b11fce2c92c2cac5a984
DIFF: https://github.com/llvm/llvm-project/commit/3be67c72f5d5b9f459c0b11fce2c92c2cac5a984.diff

LOG: [ELF] Add target-specific relocation scanning for SPARCV9 (#206284)

Implement SPARCV9::scanSectionImpl, following the pattern established
for x86 and other targets. This merges the getRelExpr and TLS handling
for SHF_ALLOC sections into the target-specific scanner, enabling
devirtualization and eliminating abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC for PC-relative relocations and processR_PLT_PC for
  PLT relocations.
- Handle TLS LE relocations directly with checkTlsLe.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc and preprocessRelocs.

Added: 
    

Modified: 
    lld/ELF/Arch/SPARCV9.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/SPARCV9.cpp b/lld/ELF/Arch/SPARCV9.cpp
index 86668c50d3c78..405be69a8f572 100644
--- a/lld/ELF/Arch/SPARCV9.cpp
+++ b/lld/ELF/Arch/SPARCV9.cpp
@@ -6,12 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "RelocScan.h"
 #include "Symbols.h"
 #include "SyntheticSections.h"
 #include "Target.h"
 #include "llvm/Support/Endian.h"
 
 using namespace llvm;
+using namespace llvm::object;
 using namespace llvm::support::endian;
 using namespace llvm::ELF;
 using namespace lld;
@@ -25,6 +27,11 @@ class SPARCV9 final : public TargetInfo {
                      const uint8_t *loc) const override;
   void writePlt(uint8_t *buf, const Symbol &sym,
                 uint64_t pltEntryAddr) const override;
+  template <class ELFT, class RelTy>
+  void scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels);
+  void scanSection(InputSectionBase &sec) override {
+    elf::scanSection1<SPARCV9, ELF64BE>(*this, sec);
+  }
   void relocate(uint8_t *loc, const Relocation &rel,
                 uint64_t val) const override;
 };
@@ -44,6 +51,8 @@ SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {
   defaultImageBase = 0x100000;
 }
 
+// Only needed to support relocations used by relocateNonAlloc and
+// preprocessRelocs.
 RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,
                             const uint8_t *loc) const {
   switch (type) {
@@ -51,31 +60,11 @@ RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,
   case R_SPARC_UA32:
   case R_SPARC_64:
   case R_SPARC_UA64:
-  case R_SPARC_H44:
-  case R_SPARC_M44:
-  case R_SPARC_L44:
-  case R_SPARC_HH22:
-  case R_SPARC_HM10:
-  case R_SPARC_LM22:
-  case R_SPARC_HI22:
-  case R_SPARC_LO10:
     return R_ABS;
-  case R_SPARC_PC10:
-  case R_SPARC_PC22:
   case R_SPARC_DISP32:
-  case R_SPARC_WDISP30:
     return R_PC;
-  case R_SPARC_GOT10:
-    return R_GOT_OFF;
-  case R_SPARC_GOT22:
-    return R_GOT_OFF;
-  case R_SPARC_WPLT30:
-    return R_PLT_PC;
   case R_SPARC_NONE:
     return R_NONE;
-  case R_SPARC_TLS_LE_HIX22:
-  case R_SPARC_TLS_LE_LOX10:
-    return R_TPREL;
   default:
     Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v
              << ") against symbol " << &s;
@@ -83,6 +72,78 @@ RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,
   }
 }
 
+template <class ELFT, class RelTy>
+void SPARCV9::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
+  RelocScan rs(ctx, &sec);
+  sec.relocations.reserve(rels.size());
+  for (auto it = rels.begin(); it != rels.end(); ++it) {
+    const RelTy &rel = *it;
+    uint32_t symIdx = rel.getSymbol(false);
+    Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIdx);
+    uint64_t offset = rel.r_offset;
+    RelType type = rel.getType(false);
+    if (sym.isUndefined() && symIdx != 0 &&
+        rs.maybeReportUndefined(cast<Undefined>(sym), offset))
+      continue;
+    int64_t addend = rs.getAddend<ELFT>(rel, type);
+    RelExpr expr;
+    switch (type) {
+    case R_SPARC_NONE:
+      continue;
+
+    // Absolute relocations:
+    case R_SPARC_32:
+    case R_SPARC_UA32:
+    case R_SPARC_64:
+    case R_SPARC_UA64:
+    case R_SPARC_H44:
+    case R_SPARC_M44:
+    case R_SPARC_L44:
+    case R_SPARC_HH22:
+    case R_SPARC_HM10:
+    case R_SPARC_LM22:
+    case R_SPARC_HI22:
+    case R_SPARC_LO10:
+      expr = R_ABS;
+      break;
+
+    // PLT-generating relocations:
+    case R_SPARC_WPLT30:
+      rs.processR_PLT_PC(type, offset, addend, sym);
+      continue;
+
+    // PC-relative relocations:
+    case R_SPARC_PC10:
+    case R_SPARC_PC22:
+    case R_SPARC_DISP32:
+    case R_SPARC_WDISP30:
+      rs.processR_PC(type, offset, addend, sym);
+      continue;
+
+    // GOT relocations:
+    case R_SPARC_GOT10:
+    case R_SPARC_GOT22:
+      expr = R_GOT_OFF;
+      break;
+
+    // TLS LE relocations:
+    case R_SPARC_TLS_LE_HIX22:
+    case R_SPARC_TLS_LE_LOX10:
+      if (rs.checkTlsLe(offset, sym, type))
+        continue;
+      expr = R_TPREL;
+      break;
+
+    default:
+      Err(ctx) << getErrorLoc(ctx, sec.content().data() + offset)
+               << "unknown relocation (" << type.v << ") against symbol "
+               << &sym;
+      continue;
+    }
+    rs.process(expr, type, offset, sym, addend);
+  }
+}
+
 void SPARCV9::relocate(uint8_t *loc, const Relocation &rel,
                        uint64_t val) const {
   switch (rel.type) {


        


More information about the llvm-commits mailing list