[ELF] Pass Ctx & to OutputSection
This commit is contained in:
parent
6dd773b650
commit
9bf2e20b17
@ -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 {
|
||||
@ -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();
|
||||
|
||||
@ -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)
|
||||
@ -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.
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -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) {
|
||||
@ -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();
|
||||
@ -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);
|
||||
@ -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.
|
||||
@ -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();
|
||||
@ -685,7 +689,7 @@ 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;
|
||||
@ -693,11 +697,13 @@ template <bool is64> void OutputSection::finalizeNonAllocCrel(Ctx &ctx) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
@ -44,6 +44,7 @@ public:
|
||||
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;
|
||||
|
||||
@ -74,8 +75,8 @@ public:
|
||||
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;
|
||||
@ -135,8 +136,8 @@ private:
|
||||
|
||||
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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user