[lld] c331332 - [ELF] Pass Ctx & to InputSection
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 11 20:39:59 PDT 2024
Author: Fangrui Song
Date: 2024-10-11T20:39:53-07:00
New Revision: c33133279bc25ec6e25ddd5fd13ca173bf716f3e
URL: https://github.com/llvm/llvm-project/commit/c33133279bc25ec6e25ddd5fd13ca173bf716f3e
DIFF: https://github.com/llvm/llvm-project/commit/c33133279bc25ec6e25ddd5fd13ca173bf716f3e.diff
LOG: [ELF] Pass Ctx & to InputSection
Added:
Modified:
lld/ELF/InputSection.cpp
lld/ELF/InputSection.h
lld/ELF/OutputSections.cpp
Removed:
################################################################################
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index fe4a6e2e5366a8..bca395eb5ea950 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -400,18 +400,20 @@ InputSectionBase *InputSection::getRelocatedSection() const {
}
template <class ELFT, class RelTy>
-void InputSection::copyRelocations(uint8_t *buf) {
+void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf) {
if (ctx.arg.relax && !ctx.arg.relocatable &&
(ctx.arg.emachine == EM_RISCV || ctx.arg.emachine == EM_LOONGARCH)) {
// On LoongArch and RISC-V, relaxation might change relocations: copy
// from internal ones that are updated by relaxation.
InputSectionBase *sec = getRelocatedSection();
- copyRelocations<ELFT, RelTy>(buf, llvm::make_range(sec->relocations.begin(),
- sec->relocations.end()));
+ copyRelocations<ELFT, RelTy>(
+ ctx, buf,
+ llvm::make_range(sec->relocations.begin(), sec->relocations.end()));
} else {
// Convert the raw relocations in the input section into Relocation objects
// suitable to be used by copyRelocations below.
struct MapRel {
+ Ctx &ctx;
const ObjFile<ELFT> &file;
Relocation operator()(const RelTy &rel) const {
// RelExpr is not used so set to a dummy value.
@@ -423,11 +425,11 @@ void InputSection::copyRelocations(uint8_t *buf) {
using RawRels = ArrayRef<RelTy>;
using MapRelIter =
llvm::mapped_iterator<typename RawRels::iterator, MapRel>;
- auto mapRel = MapRel{*getFile<ELFT>()};
+ auto mapRel = MapRel{ctx, *getFile<ELFT>()};
RawRels rawRels = getDataAs<RelTy>();
auto rels = llvm::make_range(MapRelIter(rawRels.begin(), mapRel),
MapRelIter(rawRels.end(), mapRel));
- copyRelocations<ELFT, RelTy>(buf, rels);
+ copyRelocations<ELFT, RelTy>(ctx, buf, rels);
}
}
@@ -435,9 +437,8 @@ void InputSection::copyRelocations(uint8_t *buf) {
// relocations because we need to update symbol table offset and section index
// for each relocation. So we copy relocations one by one.
template <class ELFT, class RelTy, class RelIt>
-void InputSection::copyRelocations(uint8_t *buf,
+void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf,
llvm::iterator_range<RelIt> rels) {
- Ctx &ctx = getCtx();
const TargetInfo &target = *ctx.target;
InputSectionBase *sec = getRelocatedSection();
(void)sec->contentMaybeDecompress(); // uncompress if needed
@@ -973,9 +974,10 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
// So, we handle relocations for non-alloc sections directly in this
// function as a performance optimization.
template <class ELFT, class RelTy>
-void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
+void InputSection::relocateNonAlloc(Ctx &ctx, uint8_t *buf,
+ Relocs<RelTy> rels) {
const unsigned bits = sizeof(typename ELFT::uint) * 8;
- const TargetInfo &target = *elf::ctx.target;
+ const TargetInfo &target = *ctx.target;
const auto emachine = ctx.arg.emachine;
const bool isDebug = isDebugSection(*this);
const bool isDebugLine = isDebug && name == ".debug_line";
@@ -1123,9 +1125,9 @@ void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
}
template <class ELFT>
-void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
+void InputSectionBase::relocate(Ctx &ctx, uint8_t *buf, uint8_t *bufEnd) {
if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
- adjustSplitStackFunctionPrologues<ELFT>(buf, bufEnd);
+ adjustSplitStackFunctionPrologues<ELFT>(ctx, buf, bufEnd);
if (flags & SHF_ALLOC) {
ctx.target->relocateAlloc(*this, buf);
@@ -1135,13 +1137,13 @@ void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
auto *sec = cast<InputSection>(this);
// For a relocatable link, also call relocateNonAlloc() to rewrite applicable
// locations with tombstone values.
- invokeOnRelocs(*sec, sec->relocateNonAlloc<ELFT>, buf);
+ invokeOnRelocs(*sec, sec->relocateNonAlloc<ELFT>, ctx, buf);
}
// For each function-defining prologue, find any calls to __morestack,
// and replace them with calls to __morestack_non_split.
static void switchMorestackCallsToMorestackNonSplit(
- DenseSet<Defined *> &prologues,
+ Ctx &ctx, DenseSet<Defined *> &prologues,
SmallVector<Relocation *, 0> &morestackCalls) {
// If the target adjusted a function's prologue, all calls to
@@ -1189,7 +1191,7 @@ static bool enclosingPrologueAttempted(uint64_t offset,
// adjusted to ensure that the called function will have enough stack
// available. Find those functions, and adjust their prologues.
template <class ELFT>
-void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
+void InputSectionBase::adjustSplitStackFunctionPrologues(Ctx &ctx, uint8_t *buf,
uint8_t *end) {
DenseSet<Defined *> prologues;
SmallVector<Relocation *, 0> morestackCalls;
@@ -1234,20 +1236,20 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
}
if (ctx.target->needsMoreStackNonSplit)
- switchMorestackCallsToMorestackNonSplit(prologues, morestackCalls);
+ switchMorestackCallsToMorestackNonSplit(ctx, prologues, morestackCalls);
}
-template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
+template <class ELFT> void InputSection::writeTo(Ctx &ctx, uint8_t *buf) {
if (LLVM_UNLIKELY(type == SHT_NOBITS))
return;
// If -r or --emit-relocs is given, then an InputSection
// may be a relocation section.
if (LLVM_UNLIKELY(type == SHT_RELA)) {
- copyRelocations<ELFT, typename ELFT::Rela>(buf);
+ copyRelocations<ELFT, typename ELFT::Rela>(ctx, buf);
return;
}
if (LLVM_UNLIKELY(type == SHT_REL)) {
- copyRelocations<ELFT, typename ELFT::Rel>(buf);
+ copyRelocations<ELFT, typename ELFT::Rel>(ctx, buf);
return;
}
@@ -1270,14 +1272,14 @@ template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
fatal(toString(this) +
": decompress failed: " + llvm::toString(std::move(e)));
uint8_t *bufEnd = buf + size;
- relocate<ELFT>(buf, bufEnd);
+ relocate<ELFT>(ctx, buf, bufEnd);
return;
}
// Copy section contents from source object file to output file
// and then apply relocations.
memcpy(buf, content().data(), content().size());
- relocate<ELFT>(buf, buf + content().size());
+ relocate<ELFT>(ctx, buf, buf + content().size());
}
void InputSection::replace(InputSection *other) {
@@ -1415,7 +1417,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> data,
size_t entSize) {
size_t size = data.size();
assert((size % entSize) == 0);
- const bool live = !(flags & SHF_ALLOC) || !ctx.arg.gcSections;
+ const bool live = !(flags & SHF_ALLOC) || !getCtx().arg.gcSections;
pieces.resize_for_overwrite(size / entSize);
for (size_t i = 0, j = 0; i != size; i += entSize, j++)
@@ -1471,10 +1473,10 @@ template InputSection::InputSection(ObjFile<ELF64LE> &, const ELF64LE::Shdr &,
template InputSection::InputSection(ObjFile<ELF64BE> &, const ELF64BE::Shdr &,
StringRef);
-template void InputSection::writeTo<ELF32LE>(uint8_t *);
-template void InputSection::writeTo<ELF32BE>(uint8_t *);
-template void InputSection::writeTo<ELF64LE>(uint8_t *);
-template void InputSection::writeTo<ELF64BE>(uint8_t *);
+template void InputSection::writeTo<ELF32LE>(Ctx &, uint8_t *);
+template void InputSection::writeTo<ELF32BE>(Ctx &, uint8_t *);
+template void InputSection::writeTo<ELF64LE>(Ctx &, uint8_t *);
+template void InputSection::writeTo<ELF64BE>(Ctx &, uint8_t *);
template RelsOrRelas<ELF32LE>
InputSectionBase::relsOrRelas<ELF32LE>(bool) const;
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 2b34047bc0682a..c25ff143fd3434 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -245,7 +245,7 @@ class InputSectionBase : public SectionBase {
// 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(uint8_t *buf, uint8_t *bufEnd);
+ 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.
@@ -278,8 +278,7 @@ class InputSectionBase : public SectionBase {
// to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
// information.
template <typename ELFT>
- void adjustSplitStackFunctionPrologues(uint8_t *buf, uint8_t *end);
-
+ void adjustSplitStackFunctionPrologues(Ctx &, uint8_t *buf, uint8_t *end);
template <typename T> llvm::ArrayRef<T> getDataAs() const {
size_t s = content().size();
@@ -410,7 +409,7 @@ class InputSection : public InputSectionBase {
// Write this section to a mmap'ed file, assuming Buf is pointing to
// beginning of the output section.
- template <class ELFT> void writeTo(uint8_t *buf);
+ template <class ELFT> void writeTo(Ctx &, uint8_t *buf);
OutputSection *getParent() const {
return reinterpret_cast<OutputSection *>(parent);
@@ -425,7 +424,7 @@ class InputSection : public InputSectionBase {
InputSectionBase *getRelocatedSection() const;
template <class ELFT, class RelTy>
- void relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels);
+ void relocateNonAlloc(Ctx &, uint8_t *buf, Relocs<RelTy> rels);
// Points to the canonical section. If ICF folds two sections, repl pointer of
// one section points to the other.
@@ -440,10 +439,10 @@ class InputSection : public InputSectionBase {
static InputSection discarded;
private:
- template <class ELFT, class RelTy> void copyRelocations(uint8_t *buf);
+ template <class ELFT, class RelTy> void copyRelocations(Ctx &, uint8_t *buf);
template <class ELFT, class RelTy, class RelIt>
- void copyRelocations(uint8_t *buf, llvm::iterator_range<RelIt> rels);
+ void copyRelocations(Ctx &, uint8_t *buf, llvm::iterator_range<RelIt> rels);
template <class ELFT> void copyShtGroup(uint8_t *buf);
};
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index ca0a7718fa0cc4..d6abb6184f3619 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -529,7 +529,7 @@ void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
if (auto *s = dyn_cast<SyntheticSection>(isec))
s->writeTo(buf + isec->outSecOff);
else
- isec->writeTo<ELFT>(buf + isec->outSecOff);
+ isec->writeTo<ELFT>(ctx, buf + isec->outSecOff);
// When in Arm BE8 mode, the linker has to convert the big-endian
// instructions to little-endian, leaving the data big-endian.
More information about the llvm-commits
mailing list