[lld] fd5d7c5 - ELF: Split relocateAlloc to relocateAlloc and relocateEh. NFC
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 22 09:08:18 PDT 2025
Author: Fangrui Song
Date: 2025-09-22T09:08:12-07:00
New Revision: fd5d7c5048501c3cf2f71ab7b1544ebe5c6816b7
URL: https://github.com/llvm/llvm-project/commit/fd5d7c5048501c3cf2f71ab7b1544ebe5c6816b7
DIFF: https://github.com/llvm/llvm-project/commit/fd5d7c5048501c3cf2f71ab7b1544ebe5c6816b7.diff
LOG: ELF: Split relocateAlloc to relocateAlloc and relocateEh. NFC
relocateAlloc can be called with either InputSection (including
SyntheticSection like GotSection) or EhInputSection.
Introduce relocateEh so that we can remove some boilerplate and replace
relocateAlloc's parameter type with `InputSection`.
Pull Request: https://github.com/llvm/llvm-project/pull/160031
Added:
Modified:
lld/ELF/Arch/AArch64.cpp
lld/ELF/Arch/LoongArch.cpp
lld/ELF/Arch/PPC.cpp
lld/ELF/Arch/PPC64.cpp
lld/ELF/Arch/RISCV.cpp
lld/ELF/Arch/X86.cpp
lld/ELF/Arch/X86_64.cpp
lld/ELF/InputSection.cpp
lld/ELF/InputSection.h
lld/ELF/Relocations.cpp
lld/ELF/SyntheticSections.cpp
lld/ELF/Target.cpp
lld/ELF/Target.h
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 27e77e943c197..2a97df4785ecb 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -82,7 +82,7 @@ class AArch64 : public TargetInfo {
void relocate(uint8_t *loc, const Relocation &rel,
uint64_t val) const override;
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
- void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
+ void relocateAlloc(InputSection &sec, uint8_t *buf) const override;
void applyBranchToBranchOpt() const override;
private:
@@ -939,12 +939,8 @@ static bool needsGotForMemtag(const Relocation &rel) {
return rel.sym->isTagged() && needsGot(rel.expr);
}
-void AArch64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
- else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
- secAddr += ehIn->getParent()->outSecOff;
+void AArch64::relocateAlloc(InputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
AArch64Relaxer relaxer(ctx, sec.relocs());
for (size_t i = 0, size = sec.relocs().size(); i != size; ++i) {
const Relocation &rel = sec.relocs()[i];
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index db2c71c3b42b9..c6cdf05547d3f 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -41,7 +41,7 @@ class LoongArch final : public TargetInfo {
bool relaxOnce(int pass) const override;
bool synthesizeAlign(uint64_t &dot, InputSection *sec) override;
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
- void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
+ void relocateAlloc(InputSection &sec, uint8_t *buf) const override;
void finalizeRelax(int passes) const override;
private:
@@ -1395,13 +1395,9 @@ static bool pairForGotRels(ArrayRef<Relocation> relocs) {
return i == size;
}
-void LoongArch::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
+void LoongArch::relocateAlloc(InputSection &sec, uint8_t *buf) const {
const unsigned bits = ctx.arg.is64 ? 64 : 32;
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
- else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
- secAddr += ehIn->getParent()->outSecOff;
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
bool isExtreme = false, isRelax = false;
const MutableArrayRef<Relocation> relocs = sec.relocs();
const bool isPairForGotRels = pairForGotRels(relocs);
diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index 60a0a38d5f23a..5972698b34a2c 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -49,7 +49,7 @@ class PPC final : public TargetInfo {
uint64_t val) const override;
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
int getTlsGdRelaxSkip(RelType type) const override;
- void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
+ void relocateAlloc(InputSection &sec, uint8_t *buf) const override;
private:
void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
@@ -496,10 +496,8 @@ void PPC::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
}
}
-void PPC::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
+void PPC::relocateAlloc(InputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val =
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index 3cd4a6294e2a8..550c091624bb5 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -190,7 +190,7 @@ class PPC64 final : public TargetInfo {
RelExpr adjustGotPcExpr(RelType type, int64_t addend,
const uint8_t *loc) const override;
void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const;
- void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
+ void relocateAlloc(InputSection &sec, uint8_t *buf) const override;
bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
uint8_t stOther) const override;
@@ -1561,12 +1561,8 @@ void PPC64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
}
}
-void PPC64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
- else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
- secAddr += ehIn->getParent()->outSecOff;
+void PPC64::relocateAlloc(InputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
uint64_t lastPPCRelaxedRelocOff = -1;
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 7f2bfefa5578a..dc2ab97e9d9be 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -43,7 +43,7 @@ class RISCV final : public TargetInfo {
const uint8_t *loc) const override;
void relocate(uint8_t *loc, const Relocation &rel,
uint64_t val) const override;
- void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
+ void relocateAlloc(InputSection &sec, uint8_t *buf) const override;
bool relaxOnce(int pass) const override;
template <class ELFT, class RelTy>
bool synthesizeAlignForInput(uint64_t &dot, InputSection *sec,
@@ -603,12 +603,8 @@ static void tlsdescToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
}
}
-void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
- else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
- secAddr += ehIn->getParent()->outSecOff;
+void RISCV::relocateAlloc(InputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
uint64_t tlsdescVal = 0;
bool tlsdescRelax = false, isToLe = false;
const ArrayRef<Relocation> relocs = sec.relocs();
diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp
index c1980d6e0538f..904741fd72b0a 100644
--- a/lld/ELF/Arch/X86.cpp
+++ b/lld/ELF/Arch/X86.cpp
@@ -37,7 +37,7 @@ class X86 : public TargetInfo {
uint64_t val) const override;
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
- void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
+ void relocateAlloc(InputSection &sec, uint8_t *buf) const override;
private:
void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
@@ -491,10 +491,8 @@ void X86::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
memcpy(loc - 2, inst, sizeof(inst));
}
-void X86::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
+void X86::relocateAlloc(InputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val =
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 488f4803b2cb4..9083b5b9ff250 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -44,7 +44,7 @@ class X86_64 : public TargetInfo {
unsigned size) const override;
RelExpr adjustGotPcExpr(RelType type, int64_t addend,
const uint8_t *loc) const override;
- void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
+ void relocateAlloc(InputSection &sec, uint8_t *buf) const override;
bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
uint8_t stOther) const override;
bool deleteFallThruJmpInsn(InputSection &is, InputFile *file,
@@ -1146,12 +1146,8 @@ bool X86_64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
return false;
}
-void X86_64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
- else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
- secAddr += ehIn->getParent()->outSecOff;
+void X86_64::relocateAlloc(InputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
for (const Relocation &rel : sec.relocs()) {
if (rel.expr == R_NONE) // See deleteFallThruJmpInsn
continue;
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index ea6bcc5bb272b..98267d1e081db 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -1171,7 +1171,7 @@ void InputSection::relocateNonAlloc(Ctx &ctx, uint8_t *buf,
}
template <class ELFT>
-void InputSectionBase::relocate(Ctx &ctx, uint8_t *buf, uint8_t *bufEnd) {
+void InputSection::relocate(Ctx &ctx, uint8_t *buf, uint8_t *bufEnd) {
if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
adjustSplitStackFunctionPrologues<ELFT>(ctx, buf, bufEnd);
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 98e7d5d4ff0cd..8462f03bdb77e 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -262,10 +262,6 @@ class InputSectionBase : public SectionBase {
return {*this, sym, offset};
}
- // Each section knows how to relocate itself. These functions apply
- // relocations, assuming that Buf points to this section's copy in
- // the mmap'ed output buffer.
- template <class ELFT> void relocate(Ctx &, uint8_t *buf, uint8_t *bufEnd);
uint64_t getRelocTargetVA(Ctx &, const Relocation &r, uint64_t p) const;
// The native ELF reloc data type is not very convenient to handle.
@@ -443,8 +439,12 @@ class InputSection : public InputSectionBase {
InputSectionBase *getRelocatedSection() const;
+ // Each section knows how to relocate itself. These functions apply
+ // relocations, assuming that `buf` points to this section's copy in
+ // the mmap'ed output buffer.
template <class ELFT, class RelTy>
void relocateNonAlloc(Ctx &, uint8_t *buf, Relocs<RelTy> rels);
+ template <class ELFT> void relocate(Ctx &, uint8_t *buf, uint8_t *bufEnd);
// Points to the canonical section. If ICF folds two sections, repl pointer of
// one section points to the other.
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 6f55bac2ecf16..bd96c051d160d 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1549,7 +1549,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
sec->file->ppc64SmallCodeModelTocRelocs = true;
// Record the TOC entry (.toc + addend) as not relaxable. See the comment in
- // InputSectionBase::relocateAlloc().
+ // PPC64::relocateAlloc().
if (type == R_PPC64_TOC16_LO && sym.isSection() && isa<Defined>(sym) &&
cast<Defined>(sym).section->name == ".toc")
ctx.ppc64noTocRelax.insert({&sym, addend});
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 0d87f9a66071a..0e96e37ecb9c1 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -662,7 +662,7 @@ void EhFrameSection::writeTo(uint8_t *buf) {
// in the output buffer, but relocateAlloc() still works because
// getOffset() takes care of discontiguous section pieces.
for (EhInputSection *s : sections)
- ctx.target->relocateAlloc(*s, buf);
+ ctx.target->relocateEh(*s, buf);
if (getPartition(ctx).ehFrameHdr && getPartition(ctx).ehFrameHdr->getParent())
getPartition(ctx).ehFrameHdr->write();
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 4946484074d05..fb79ee911273a 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -148,22 +148,30 @@ RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
return R_GOT_PC;
}
-void TargetInfo::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
+static void relocateImpl(const TargetInfo &target, InputSectionBase &sec,
+ uint64_t secAddr, uint8_t *buf) {
+ auto &ctx = target.ctx;
const unsigned bits = ctx.arg.is64 ? 64 : 32;
- uint64_t secAddr = sec.getOutputSection()->addr;
- if (auto *s = dyn_cast<InputSection>(&sec))
- secAddr += s->outSecOff;
- else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
- secAddr += ehIn->getParent()->outSecOff;
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val = SignExtend64(
sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset), bits);
if (rel.expr != R_RELAX_HINT)
- relocate(loc, rel, val);
+ target.relocate(loc, rel, val);
}
}
+void TargetInfo::relocateAlloc(InputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
+ relocateImpl(*this, sec, secAddr, buf);
+}
+
+// A variant of relocateAlloc that processes an EhInputSection.
+void TargetInfo::relocateEh(EhInputSection &sec, uint8_t *buf) const {
+ uint64_t secAddr = sec.getOutputSection()->addr + sec.getParent()->outSecOff;
+ relocateImpl(*this, sec, secAddr, buf);
+}
+
uint64_t TargetInfo::getImageBase() const {
// Use --image-base if set. Fall back to the target default if not.
if (ctx.arg.imageBase)
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index bb8c24f052aa2..9f0605138a4fb 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -92,7 +92,8 @@ class TargetInfo {
void relocateNoSym(uint8_t *loc, RelType type, uint64_t val) const {
relocate(loc, Relocation{R_NONE, type, 0, 0, nullptr}, val);
}
- virtual void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const;
+ virtual void relocateAlloc(InputSection &sec, uint8_t *buf) const;
+ void relocateEh(EhInputSection &sec, uint8_t *buf) const;
// Do a linker relaxation pass and return true if we changed something.
virtual bool relaxOnce(int pass) const { return false; }
More information about the llvm-commits
mailing list