[lld] 3590068 - [ELF] Pass Ctx & to OutputSections
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 3 20:07:04 PDT 2024
Author: Fangrui Song
Date: 2024-10-03T20:06:58-07:00
New Revision: 359006895004c588efe615ae2422b3e068ceff1a
URL: https://github.com/llvm/llvm-project/commit/359006895004c588efe615ae2422b3e068ceff1a
DIFF: https://github.com/llvm/llvm-project/commit/359006895004c588efe615ae2422b3e068ceff1a.diff
LOG: [ELF] Pass Ctx & to OutputSections
Added:
Modified:
lld/ELF/Arch/ARM.cpp
lld/ELF/Driver.cpp
lld/ELF/LinkerScript.cpp
lld/ELF/OutputSections.cpp
lld/ELF/OutputSections.h
lld/ELF/Relocations.cpp
lld/ELF/ScriptParser.cpp
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 77bdd656dd8cd6..368b72e687a4ca 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -1469,7 +1469,7 @@ template <typename ELFT> void elf::writeARMCmseImportLib() {
for (auto &[osec, isec] : osIsPairs) {
osec->sectionIndex = ++idx;
osec->recordSection(isec);
- osec->finalizeInputSections();
+ osec->finalizeInputSections(ctx);
osec->shName = shstrtab->addString(osec->name);
osec->size = isec->getSize();
isec->finalizeContents();
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 94cd060b697d25..373505a9e965b7 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -3194,7 +3194,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// sectionBases.
for (SectionCommand *cmd : ctx.script->sectionCommands)
if (auto *osd = dyn_cast<OutputDesc>(cmd))
- osd->osec.finalizeInputSections(ctx.script);
+ osd->osec.finalizeInputSections(ctx);
}
// Two input sections with
diff erent output sections should not be folded.
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index cce584ae4d8679..2852c90fb57ef0 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1442,7 +1442,7 @@ void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
return cmd.hasPhdrs || cmd.hasFilehdr;
});
bool paged = !ctx.arg.omagic && !ctx.arg.nmagic;
- uint64_t headerSize = getHeaderSize();
+ uint64_t headerSize = getHeaderSize(ctx);
uint64_t base = 0;
// If SECTIONS is present and the linkerscript is not explicit about program
@@ -1491,7 +1491,7 @@ LinkerScript::assignAddresses() {
dot = ctx.target->getImageBase();
ctx.out.elfHeader->addr = dot;
ctx.out.programHeaders->addr = dot + ctx.out.elfHeader->size;
- dot += getHeaderSize();
+ dot += getHeaderSize(ctx);
}
OutputSection *changedOsec = nullptr;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index b775eed9af2bf0..e65ed110e098d7 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -78,7 +78,7 @@ OutputSection::OutputSection(StringRef name, uint32_t type, uint64_t flags)
//
// NOTE: clang since rL252300 emits SHT_X86_64_UNWIND .eh_frame sections. Allow
// them to be merged into SHT_PROGBITS .eh_frame (GNU as .cfi_*).
-static bool canMergeToProgbits(unsigned type) {
+static bool canMergeToProgbits(Ctx &ctx, unsigned type) {
return type == SHT_NOBITS || type == SHT_PROGBITS || type == SHT_INIT_ARRAY ||
type == SHT_PREINIT_ARRAY || type == SHT_FINI_ARRAY ||
type == SHT_NOTE ||
@@ -105,7 +105,7 @@ void OutputSection::recordSection(InputSectionBase *isec) {
// Update fields (type, flags, alignment, etc) according to the InputSection
// isec. Also check whether the InputSection flags and type are consistent with
// other InputSections.
-void OutputSection::commitSection(InputSection *isec) {
+void OutputSection::commitSection(Ctx &ctx, InputSection *isec) {
if (LLVM_UNLIKELY(type != isec->type)) {
if (!hasInputSections && !typeIsSet) {
type = isec->type;
@@ -120,8 +120,8 @@ void OutputSection::commitSection(InputSection *isec) {
name = saver().save(".crel" + name);
}
} else {
- if (typeIsSet || !canMergeToProgbits(type) ||
- !canMergeToProgbits(isec->type)) {
+ if (typeIsSet || !canMergeToProgbits(ctx, type) ||
+ !canMergeToProgbits(ctx, isec->type)) {
// The (NOLOAD) changes the section type to SHT_NOBITS, the intention is
// that the contents at that address is provided by some other means.
// Some projects (e.g.
@@ -172,7 +172,7 @@ void OutputSection::commitSection(InputSection *isec) {
entsize = 0;
}
-static MergeSyntheticSection *createMergeSynthetic(StringRef name,
+static MergeSyntheticSection *createMergeSynthetic(Ctx &ctx, StringRef name,
uint32_t type,
uint64_t flags,
uint32_t addralign) {
@@ -188,7 +188,8 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef name,
// new synthetic sections at the location of the first input section
// that it replaces. It then finalizes each synthetic section in order
// to compute an output offset for each piece of each input section.
-void OutputSection::finalizeInputSections(LinkerScript *script) {
+void OutputSection::finalizeInputSections(Ctx &ctx) {
+ auto *script = ctx.script;
std::vector<MergeSyntheticSection *> mergeSections;
for (SectionCommand *cmd : commands) {
auto *isd = dyn_cast<InputSectionDescription>(cmd);
@@ -222,8 +223,8 @@ void OutputSection::finalizeInputSections(LinkerScript *script) {
(sec->addralign == ms->addralign || !(sec->flags & SHF_STRINGS));
});
if (i == mergeSections.end()) {
- MergeSyntheticSection *syn =
- createMergeSynthetic(s->name, ms->type, ms->flags, ms->addralign);
+ MergeSyntheticSection *syn = createMergeSynthetic(
+ ctx, s->name, ms->type, ms->flags, ms->addralign);
mergeSections.push_back(syn);
i = std::prev(mergeSections.end());
syn->entsize = ms->entsize;
@@ -243,7 +244,7 @@ void OutputSection::finalizeInputSections(LinkerScript *script) {
// Some input sections may be removed from the list after ICF.
for (InputSection *s : isd->sections)
- commitSection(s);
+ commitSection(ctx, s);
}
for (auto *ms : mergeSections)
ms->finalizeContents();
@@ -260,7 +261,7 @@ static void sortByOrder(MutableArrayRef<InputSection *> in,
in[i] = v[i].second;
}
-uint64_t elf::getHeaderSize() {
+uint64_t elf::getHeaderSize(Ctx &ctx) {
if (ctx.arg.oFormatBinary)
return 0;
return ctx.out.elfHeader->size + ctx.out.programHeaders->size;
@@ -273,7 +274,7 @@ void OutputSection::sort(llvm::function_ref<int(InputSectionBase *s)> order) {
sortByOrder(isd->sections, order);
}
-static void nopInstrFill(uint8_t *buf, size_t size) {
+static void nopInstrFill(Ctx &ctx, uint8_t *buf, size_t size) {
if (size == 0)
return;
unsigned i = 0;
@@ -341,7 +342,7 @@ static SmallVector<uint8_t, 0> deflateShard(ArrayRef<uint8_t> in, int level,
//
// * (if --compress-debug-sections is specified) non-empty .debug_* sections
// * (if --compress-sections is specified) matched sections
-template <class ELFT> void OutputSection::maybeCompress() {
+template <class ELFT> void OutputSection::maybeCompress(Ctx &ctx) {
using Elf_Chdr = typename ELFT::Chdr;
(void)sizeof(Elf_Chdr);
@@ -507,7 +508,7 @@ void OutputSection::writeTo(uint8_t *buf, parallel::TaskGroup &tg) {
// Write leading padding.
ArrayRef<InputSection *> sections = getInputSections(*this, storage);
- std::array<uint8_t, 4> filler = getFiller();
+ std::array<uint8_t, 4> filler = getFiller(ctx);
bool nonZeroFiller = read32(filler.data()) != 0;
if (nonZeroFiller)
fill(buf, sections.empty() ? size : sections[0]->outSecOff, filler);
@@ -543,7 +544,7 @@ void OutputSection::writeTo(uint8_t *buf, parallel::TaskGroup &tg) {
end = buf + sections[i + 1]->outSecOff;
if (isec->nopFiller) {
assert(ctx.target->nopInstrs);
- nopInstrFill(start, end - start);
+ nopInstrFill(ctx, start, end - start);
} else
fill(start, end - start, filler);
}
@@ -582,7 +583,8 @@ void OutputSection::writeTo(uint8_t *buf, parallel::TaskGroup &tg) {
}
}
-static void finalizeShtGroup(OutputSection *os, InputSection *section) {
+static void finalizeShtGroup(Ctx &ctx, OutputSection *os,
+ InputSection *section) {
// sh_link field for SHT_GROUP sections should contain the section index of
// the symbol table.
os->link = ctx.in.symTab->getParent()->sectionIndex;
@@ -668,7 +670,7 @@ static size_t relToCrel(raw_svector_ostream &os, Elf_Crel<ELFT::Is64Bits> &out,
// Compute the content of a non-alloc CREL section due to -r or --emit-relocs.
// Input CREL sections are decoded while REL[A] need to be converted.
-template <bool is64> void OutputSection::finalizeNonAllocCrel() {
+template <bool is64> void OutputSection::finalizeNonAllocCrel(Ctx &ctx) {
using uint = typename Elf_Crel_Impl<is64>::uint;
raw_svector_ostream os(crelBody);
uint64_t totalCount = 0;
@@ -702,7 +704,7 @@ template <bool is64> void OutputSection::finalizeNonAllocCrel() {
size = getULEB128Size(crelHeader) + crelBody.size();
}
-void OutputSection::finalize() {
+void OutputSection::finalize(Ctx &ctx) {
InputSection *first = getFirstInputSection(this);
if (flags & SHF_LINK_ORDER) {
@@ -718,7 +720,7 @@ void OutputSection::finalize() {
}
if (type == SHT_GROUP) {
- finalizeShtGroup(this, first);
+ finalizeShtGroup(ctx, this, first);
return;
}
@@ -741,9 +743,9 @@ void OutputSection::finalize() {
// Finalize the content of non-alloc CREL.
if (type == SHT_CREL) {
if (ctx.arg.is64)
- finalizeNonAllocCrel<true>();
+ finalizeNonAllocCrel<true>(ctx);
else
- finalizeNonAllocCrel<false>();
+ finalizeNonAllocCrel<false>(ctx);
}
}
@@ -854,7 +856,7 @@ void OutputSection::sortInitFini() {
sort([](InputSectionBase *s) { return getPriority(s->name); });
}
-std::array<uint8_t, 4> OutputSection::getFiller() {
+std::array<uint8_t, 4> OutputSection::getFiller(Ctx &ctx) {
if (filler)
return *filler;
if (flags & SHF_EXECINSTR)
@@ -862,7 +864,7 @@ std::array<uint8_t, 4> OutputSection::getFiller() {
return {0, 0, 0, 0};
}
-void OutputSection::checkDynRelAddends(const uint8_t *bufStart) {
+void OutputSection::checkDynRelAddends(Ctx &ctx) {
assert(ctx.arg.writeAddends && ctx.arg.checkDynamicRelocs);
assert(isStaticRelSecType(type));
SmallVector<InputSection *, 0> storage;
@@ -885,8 +887,8 @@ void OutputSection::checkDynRelAddends(const uint8_t *bufStart) {
(rel.inputSec == ctx.in.ppc64LongBranchTarget.get() ||
rel.inputSec == ctx.in.igotPlt.get()))
continue;
- const uint8_t *relocTarget =
- bufStart + relOsec->offset + rel.inputSec->getOffset(rel.offsetInSec);
+ const uint8_t *relocTarget = ctx.bufferStart + relOsec->offset +
+ rel.inputSec->getOffset(rel.offsetInSec);
// For SHT_NOBITS the written addend is always zero.
int64_t writtenAddend =
relOsec->type == SHT_NOBITS
@@ -918,7 +920,7 @@ template void OutputSection::writeTo<ELF64LE>(uint8_t *,
template void OutputSection::writeTo<ELF64BE>(uint8_t *,
llvm::parallel::TaskGroup &);
-template void OutputSection::maybeCompress<ELF32LE>();
-template void OutputSection::maybeCompress<ELF32BE>();
-template void OutputSection::maybeCompress<ELF64LE>();
-template void OutputSection::maybeCompress<ELF64BE>();
+template void OutputSection::maybeCompress<ELF32LE>(Ctx &);
+template void OutputSection::maybeCompress<ELF32BE>(Ctx &);
+template void OutputSection::maybeCompress<ELF64LE>(Ctx &);
+template void OutputSection::maybeCompress<ELF64BE>(Ctx &);
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 909b284a75a2ef..10363127918dfb 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -74,8 +74,8 @@ class OutputSection final : public SectionBase {
uint32_t shName = 0;
void recordSection(InputSectionBase *isec);
- void commitSection(InputSection *isec);
- void finalizeInputSections(LinkerScript *script = nullptr);
+ void commitSection(Ctx &ctx, InputSection *isec);
+ void finalizeInputSections(Ctx &ctx);
// The following members are normally only used in linker scripts.
MemoryRegion *memRegion = nullptr;
@@ -111,13 +111,13 @@ class OutputSection final : public SectionBase {
// DATA_RELRO_END.
bool relro = false;
- template <bool is64> void finalizeNonAllocCrel();
- void finalize();
+ template <bool is64> void finalizeNonAllocCrel(Ctx &);
+ void finalize(Ctx &);
template <class ELFT>
void writeTo(uint8_t *buf, llvm::parallel::TaskGroup &tg);
// Check that the addends for dynamic relocations were written correctly.
- void checkDynRelAddends(const uint8_t *bufStart);
- template <class ELFT> void maybeCompress();
+ void checkDynRelAddends(Ctx &);
+ template <class ELFT> void maybeCompress(Ctx &);
void sort(llvm::function_ref<int(InputSectionBase *s)> order);
void sortInitFini();
@@ -130,7 +130,7 @@ class OutputSection final : public SectionBase {
private:
SmallVector<InputSection *, 0> storage;
- std::array<uint8_t, 4> getFiller();
+ std::array<uint8_t, 4> getFiller(Ctx &);
};
struct OutputDesc final : SectionCommand {
@@ -169,7 +169,7 @@ llvm::ArrayRef<InputSection *>
getInputSections(const OutputSection &os,
SmallVector<InputSection *, 0> &storage);
-uint64_t getHeaderSize();
+uint64_t getHeaderSize(Ctx &);
} // namespace lld::elf
#endif
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 078166e0d3f037..01bb2e6b718126 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -392,7 +392,7 @@ template <class ELFT> static void addCopyRelSymbol(Ctx &ctx, SharedSymbol &ss) {
osec->commands.push_back(make<InputSectionDescription>(""));
auto *isd = cast<InputSectionDescription>(osec->commands.back());
isd->sections.push_back(sec);
- osec->commitSection(sec);
+ osec->commitSection(ctx, sec);
// Look through the DSO's dynamic symbol table for aliases and create a
// dynamic symbol for each one. This causes the copy relocation to correctly
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index b16b2e56473adc..3282551c441d12 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1647,7 +1647,7 @@ Expr ScriptParser::readPrimary() {
return [=] { return cmd->size; };
}
if (tok == "SIZEOF_HEADERS")
- return [=] { return elf::getHeaderSize(); };
+ return [=, &ctx = ctx] { return elf::getHeaderSize(ctx); };
// Tok is the dot.
if (tok == ".")
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 2ad7de7324a845..4c28f3e2d1845b 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -315,7 +315,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// If --compressed-debug-sections is specified, compress .debug_* sections.
// Do it right now because it changes the size of output sections.
for (OutputSection *sec : ctx.outputSections)
- sec->maybeCompress<ELFT>();
+ sec->maybeCompress<ELFT>(ctx);
if (ctx.script->hasSectionsCommand)
ctx.script->allocateHeaders(ctx.mainPart->phdrs);
@@ -2077,7 +2077,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// at the end because some tags like RELSZ depend on result
// of finalizing other sections.
for (OutputSection *sec : ctx.outputSections)
- sec->finalize();
+ sec->finalize(ctx);
ctx.script->checkFinalScriptConditions();
@@ -2870,7 +2870,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
if (ctx.arg.checkDynamicRelocs && ctx.arg.writeAddends) {
for (OutputSection *sec : ctx.outputSections)
if (isStaticRelSecType(sec->type))
- sec->checkDynRelAddends(ctx.bufferStart);
+ sec->checkDynRelAddends(ctx);
}
}
More information about the llvm-commits
mailing list