[lld] [ELF] Add target-specific relocation scanning for RISC-V (PR #181332)
Jessica Clarke via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 5 06:14:45 PST 2026
================
@@ -356,29 +320,154 @@ void RISCV::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
// Many relocations end up in sec.relocations.
sec.relocations.reserve(rels.size());
- StringRef rvVendor;
+ StringRef vendor;
for (auto it = rels.begin(); it != rels.end(); ++it) {
RelType type = it->getType(false);
uint32_t symIndex = it->getSymbol(false);
Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIndex);
- const uint8_t *loc = sec.content().data() + it->r_offset;
+ uint64_t offset = it->r_offset;
+ if (sym.isUndefined() && symIndex != 0 &&
+ rs.maybeReportUndefined(cast<Undefined>(sym), offset))
+ continue;
+ int64_t addend = rs.getAddend<ELFT>(*it, type);
+ RelExpr expr;
+ // Relocation types that only need a RelExpr set `expr` and break out of
+ // the switch to reach rs.process(). Types that need special handling
+ // (fast-path helpers, TLS) call a handler and use `continue`.
+ switch (type) {
+ case R_RISCV_NONE:
+ continue;
- if (type == R_RISCV_VENDOR) {
- if (!rvVendor.empty())
- Err(ctx) << getErrorLoc(ctx, loc)
- << "malformed consecutive R_RISCV_VENDOR relocations";
- rvVendor = sym.getName();
+ // Absolute relocations:
+ case R_RISCV_32:
+ case R_RISCV_64:
+ case R_RISCV_HI20:
+ case R_RISCV_LO12_I:
+ case R_RISCV_LO12_S:
+ expr = R_ABS;
+ break;
+
+ // PC-relative relocations:
+ case R_RISCV_JAL:
+ case R_RISCV_BRANCH:
+ case R_RISCV_PCREL_HI20:
+ case R_RISCV_RVC_BRANCH:
+ case R_RISCV_RVC_JUMP:
+ case R_RISCV_32_PCREL:
+ rs.processR_PC(type, offset, addend, sym);
continue;
- } else if (!rvVendor.empty()) {
- Err(ctx) << getErrorLoc(ctx, loc)
- << "unknown vendor-specific relocation (" << type.v
- << ") in namespace '" << rvVendor << "' against symbol '" << &sym
- << "'";
- rvVendor = "";
+ case R_RISCV_PCREL_LO12_I:
+ case R_RISCV_PCREL_LO12_S:
+ expr = RE_RISCV_PC_INDIRECT;
+ break;
+
+ // PLT-generating relocations:
+ case R_RISCV_CALL:
+ case R_RISCV_CALL_PLT:
+ case R_RISCV_PLT32:
+ rs.processR_PLT_PC(type, offset, addend, sym);
continue;
- }
- rs.scan<ELFT, RelTy>(it, type, rs.getAddend<ELFT>(*it, type));
+ // GOT-generating relocations:
+ case R_RISCV_GOT_HI20:
+ case R_RISCV_GOT32_PCREL:
+ expr = R_GOT_PC;
+ break;
+
+ // TLS relocations:
+ case R_RISCV_TPREL_HI20:
+ case R_RISCV_TPREL_LO12_I:
+ case R_RISCV_TPREL_LO12_S:
+ if (rs.checkTlsLe(offset, sym, type))
+ continue;
+ expr = R_TPREL;
+ break;
+ case R_RISCV_TLS_GOT_HI20:
+ // There is no IE to LE optimization.
+ sym.setFlags(NEEDS_TLSIE);
+ sec.addReloc({R_GOT_PC, type, offset, addend, &sym});
----------------
jrtc27 wrote:
It would be nice if some of these were handled by simple implementations in headers rather than duplicating it for every target. Especially the flags handling, abstracting that makes changing it easier.
https://github.com/llvm/llvm-project/pull/181332
More information about the llvm-commits
mailing list