Skip to content

Commit

Permalink
[ELF] Pass Ctx & to OutputSection
Browse files Browse the repository at this point in the history
  • Loading branch information
MaskRay authored and bricknerb committed Oct 17, 2024
1 parent 474b765 commit 4f5b4e4
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 32 deletions.
10 changes: 6 additions & 4 deletions lld/ELF/Arch/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1452,9 +1452,11 @@ template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
make<SymbolTableSection<ELFT>>(ctx, *strtab);

SmallVector<std::pair<OutputSection *, SyntheticSection *>, 0> osIsPairs;
osIsPairs.emplace_back(make<OutputSection>(strtab->name, 0, 0), strtab);
osIsPairs.emplace_back(make<OutputSection>(impSymTab->name, 0, 0), impSymTab);
osIsPairs.emplace_back(make<OutputSection>(shstrtab->name, 0, 0), shstrtab);
osIsPairs.emplace_back(make<OutputSection>(ctx, strtab->name, 0, 0), strtab);
osIsPairs.emplace_back(make<OutputSection>(ctx, impSymTab->name, 0, 0),
impSymTab);
osIsPairs.emplace_back(make<OutputSection>(ctx, shstrtab->name, 0, 0),
shstrtab);

std::sort(ctx.symtab->cmseSymMap.begin(), ctx.symtab->cmseSymMap.end(),
[](const auto &a, const auto &b) -> bool {
Expand All @@ -1473,7 +1475,7 @@ template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
for (auto &[osec, isec] : osIsPairs) {
osec->sectionIndex = ++idx;
osec->recordSection(isec);
osec->finalizeInputSections(ctx);
osec->finalizeInputSections();
osec->shName = shstrtab->addString(osec->name);
osec->size = isec->getSize();
isec->finalizeContents();
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2975,7 +2975,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {

// Create elfHeader early. We need a dummy section in
// addReservedSymbols to mark the created symbols as not absolute.
ctx.out.elfHeader = make<OutputSection>("", 0, SHF_ALLOC);
ctx.out.elfHeader = make<OutputSection>(ctx, "", 0, SHF_ALLOC);

// We need to create some reserved symbols such as _end. Create them.
if (!ctx.arg.relocatable)
Expand Down Expand Up @@ -3200,7 +3200,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);
osd->osec.finalizeInputSections();
}

// Two input sections with different output sections should not be folded.
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1389,7 +1389,7 @@ static size_t findNull(StringRef s, size_t entSize) {
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(StringRef s, size_t entSize) {
const bool live = !(flags & SHF_ALLOC) || !ctx.arg.gcSections;
const bool live = !(flags & SHF_ALLOC) || !getCtx().arg.gcSections;
const char *p = s.data(), *end = s.data() + s.size();
if (!std::all_of(end - entSize, end, [](char c) { return c == 0; }))
fatal(toString(this) + ": string is not null terminated");
Expand Down
6 changes: 3 additions & 3 deletions lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ OutputDesc *LinkerScript::createOutputSection(StringRef name,
// There was a forward reference.
sec = secRef;
} else {
sec = make<OutputDesc>(name, SHT_PROGBITS, 0);
sec = make<OutputDesc>(ctx, name, SHT_PROGBITS, 0);
if (!secRef)
secRef = sec;
}
Expand All @@ -151,7 +151,7 @@ OutputDesc *LinkerScript::createOutputSection(StringRef name,
OutputDesc *LinkerScript::getOrCreateOutputSection(StringRef name) {
OutputDesc *&cmdRef = nameToOutputSection[CachedHashStringRef(name)];
if (!cmdRef)
cmdRef = make<OutputDesc>(name, SHT_PROGBITS, 0);
cmdRef = make<OutputDesc>(ctx, name, SHT_PROGBITS, 0);
return cmdRef;
}

Expand Down Expand Up @@ -830,7 +830,7 @@ void LinkerScript::processSymbolAssignments() {
// sh_shndx should not be SHN_UNDEF or SHN_ABS. Create a dummy aether section
// that fills the void outside a section. It has an index of one, which is
// indistinguishable from any other regular section index.
aether = make<OutputSection>("", 0, SHF_ALLOC);
aether = make<OutputSection>(ctx, "", 0, SHF_ALLOC);
aether->sectionIndex = 1;

// `st` captures the local AddressState and makes it accessible deliberately.
Expand Down
36 changes: 21 additions & 15 deletions lld/ELF/OutputSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ void OutputSection::writeHeaderTo(typename ELFT::Shdr *shdr) {
shdr->sh_name = shName;
}

OutputSection::OutputSection(StringRef name, uint32_t type, uint64_t flags)
OutputSection::OutputSection(Ctx &ctx, StringRef name, uint32_t type,
uint64_t flags)
: SectionBase(Output, ctx.internalFile, name, flags, /*entsize=*/0,
/*addralign=*/1, type,
/*info=*/0, /*link=*/0) {}
/*info=*/0, /*link=*/0),
ctx(ctx) {}

// We allow sections of types listed below to merged into a
// single progbits section. This is typically done by linker
Expand Down Expand Up @@ -106,7 +108,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(Ctx &ctx, InputSection *isec) {
void OutputSection::commitSection(InputSection *isec) {
if (LLVM_UNLIKELY(type != isec->type)) {
if (!hasInputSections && !typeIsSet) {
type = isec->type;
Expand Down Expand Up @@ -189,7 +191,7 @@ static MergeSyntheticSection *createMergeSynthetic(Ctx &ctx, 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(Ctx &ctx) {
void OutputSection::finalizeInputSections() {
auto *script = ctx.script;
std::vector<MergeSyntheticSection *> mergeSections;
for (SectionCommand *cmd : commands) {
Expand Down Expand Up @@ -245,7 +247,7 @@ void OutputSection::finalizeInputSections(Ctx &ctx) {

// Some input sections may be removed from the list after ICF.
for (InputSection *s : isd->sections)
commitSection(ctx, s);
commitSection(s);
}
for (auto *ms : mergeSections)
ms->finalizeContents();
Expand Down Expand Up @@ -610,8 +612,9 @@ static void finalizeShtGroup(Ctx &ctx, OutputSection *os,

template <class uint>
LLVM_ATTRIBUTE_ALWAYS_INLINE static void
encodeOneCrel(raw_svector_ostream &os, Elf_Crel<sizeof(uint) == 8> &out,
uint offset, const Symbol &sym, uint32_t type, uint addend) {
encodeOneCrel(Ctx &ctx, raw_svector_ostream &os,
Elf_Crel<sizeof(uint) == 8> &out, uint offset, const Symbol &sym,
uint32_t type, uint addend) {
const auto deltaOffset = static_cast<uint64_t>(offset - out.r_offset);
out.r_offset = offset;
int64_t symidx = ctx.in.symTab->getSymbolIndex(sym);
Expand Down Expand Up @@ -652,8 +655,9 @@ encodeOneCrel(raw_svector_ostream &os, Elf_Crel<sizeof(uint) == 8> &out,
}

template <class ELFT>
static size_t relToCrel(raw_svector_ostream &os, Elf_Crel<ELFT::Is64Bits> &out,
InputSection *relSec, InputSectionBase *sec) {
static size_t relToCrel(Ctx &ctx, raw_svector_ostream &os,
Elf_Crel<ELFT::Is64Bits> &out, InputSection *relSec,
InputSectionBase *sec) {
const auto &file = *cast<ELFFileBase>(relSec->file);
if (relSec->type == SHT_REL) {
// REL conversion is complex and unsupported yet.
Expand All @@ -663,7 +667,7 @@ static size_t relToCrel(raw_svector_ostream &os, Elf_Crel<ELFT::Is64Bits> &out,
auto rels = relSec->getDataAs<typename ELFT::Rela>();
for (auto rel : rels) {
encodeOneCrel<typename ELFT::uint>(
os, out, sec->getVA(rel.r_offset), file.getRelocTargetSym(rel),
ctx, os, out, sec->getVA(rel.r_offset), file.getRelocTargetSym(rel),
rel.getType(ctx.arg.isMips64EL), getAddend<ELFT>(rel));
}
return rels.size();
Expand All @@ -685,19 +689,21 @@ template <bool is64> void OutputSection::finalizeNonAllocCrel(Ctx &ctx) {
RelocsCrel<is64> entries(relSec->content_);
totalCount += entries.size();
for (Elf_Crel_Impl<is64> r : entries) {
encodeOneCrel<uint>(os, out, uint(sec->getVA(r.r_offset)),
encodeOneCrel<uint>(ctx, os, out, uint(sec->getVA(r.r_offset)),
file.getSymbol(r.r_symidx), r.r_type, r.r_addend);
}
continue;
}

// Convert REL[A] to CREL.
if constexpr (is64) {
totalCount += ctx.arg.isLE ? relToCrel<ELF64LE>(os, out, relSec, sec)
: relToCrel<ELF64BE>(os, out, relSec, sec);
totalCount += ctx.arg.isLE
? relToCrel<ELF64LE>(ctx, os, out, relSec, sec)
: relToCrel<ELF64BE>(ctx, os, out, relSec, sec);
} else {
totalCount += ctx.arg.isLE ? relToCrel<ELF32LE>(os, out, relSec, sec)
: relToCrel<ELF32BE>(os, out, relSec, sec);
totalCount += ctx.arg.isLE
? relToCrel<ELF32LE>(ctx, os, out, relSec, sec)
: relToCrel<ELF32BE>(ctx, os, out, relSec, sec);
}
}

Expand Down
11 changes: 6 additions & 5 deletions lld/ELF/OutputSections.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct CompressedData {
// non-overlapping file offsets and VAs.
class OutputSection final : public SectionBase {
public:
OutputSection(StringRef name, uint32_t type, uint64_t flags);
OutputSection(Ctx &, StringRef name, uint32_t type, uint64_t flags);

static bool classof(const SectionBase *s) {
return s->kind() == SectionBase::Output;
Expand All @@ -44,6 +44,7 @@ class OutputSection final : public SectionBase {
uint64_t getLMA() const { return ptLoad ? addr + ptLoad->lmaOffset : addr; }
template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *sHdr);

Ctx &ctx;
uint32_t sectionIndex = UINT32_MAX;
unsigned sortRank;

Expand Down Expand Up @@ -74,8 +75,8 @@ class OutputSection final : public SectionBase {
uint32_t shName = 0;

void recordSection(InputSectionBase *isec);
void commitSection(Ctx &ctx, InputSection *isec);
void finalizeInputSections(Ctx &ctx);
void commitSection(InputSection *isec);
void finalizeInputSections();

// The following members are normally only used in linker scripts.
MemoryRegion *memRegion = nullptr;
Expand Down Expand Up @@ -135,8 +136,8 @@ class OutputSection final : public SectionBase {

struct OutputDesc final : SectionCommand {
OutputSection osec;
OutputDesc(StringRef name, uint32_t type, uint64_t flags)
: SectionCommand(OutputSectionKind), osec(name, type, flags) {}
OutputDesc(Ctx &ctx, StringRef name, uint32_t type, uint64_t flags)
: SectionCommand(OutputSectionKind), osec(ctx, name, type, flags) {}

static bool classof(const SectionCommand *c) {
return c->kind == OutputSectionKind;
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(ctx, sec);
osec->commitSection(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
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4692,7 +4692,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
ctx.in.shStrTab =
std::make_unique<StringTableSection>(ctx, ".shstrtab", false);

ctx.out.programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
ctx.out.programHeaders = make<OutputSection>(ctx, "", 0, SHF_ALLOC);
ctx.out.programHeaders->addralign = ctx.arg.wordsize;

if (ctx.arg.strip != StripPolicy::All) {
Expand Down

0 comments on commit 4f5b4e4

Please sign in to comment.