[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