[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:37:06 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:
Hm, seems handleTlsIe already exists; why not use that? enableIeToLe = false and ieExpr = R_GOT_PC should trivially be optimised to this, but avoid the duplication and lack of abstraction.
https://github.com/llvm/llvm-project/pull/181332
More information about the llvm-commits
mailing list