[ELF] Make elfHeader/programHeaders unique_ptr
This removes some SpecificAlloc instantiations, makes lld smaller, and drops the small memory waste due to the separate BumpPtrAllocator.
This commit is contained in:
parent
53dc4e7600
commit
5b1b6a62b8
@ -1466,12 +1466,14 @@ template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
|
||||
SymbolTableBaseSection *impSymTab =
|
||||
make<SymbolTableSection<ELFT>>(ctx, *strtab);
|
||||
|
||||
SmallVector<std::pair<OutputSection *, SyntheticSection *>, 0> osIsPairs;
|
||||
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);
|
||||
SmallVector<std::pair<std::unique_ptr<OutputSection>, SyntheticSection *>, 0>
|
||||
osIsPairs;
|
||||
osIsPairs.emplace_back(
|
||||
std::make_unique<OutputSection>(ctx, strtab->name, 0, 0), strtab);
|
||||
osIsPairs.emplace_back(
|
||||
std::make_unique<OutputSection>(ctx, impSymTab->name, 0, 0), impSymTab);
|
||||
osIsPairs.emplace_back(
|
||||
std::make_unique<OutputSection>(ctx, shstrtab->name, 0, 0), shstrtab);
|
||||
|
||||
llvm::sort(ctx.symtab->cmseSymMap, [&](const auto &a, const auto &b) {
|
||||
return a.second.sym->getVA(ctx) < b.second.sym->getVA(ctx);
|
||||
|
@ -565,8 +565,8 @@ struct Ctx : CommonLinkerContext {
|
||||
Partition *mainPart = nullptr;
|
||||
PhdrEntry *tlsPhdr = nullptr;
|
||||
struct OutSections {
|
||||
OutputSection *elfHeader;
|
||||
OutputSection *programHeaders;
|
||||
std::unique_ptr<OutputSection> elfHeader;
|
||||
std::unique_ptr<OutputSection> programHeaders;
|
||||
OutputSection *preinitArray;
|
||||
OutputSection *initArray;
|
||||
OutputSection *finiArray;
|
||||
|
@ -2973,7 +2973,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>(ctx, "", 0, SHF_ALLOC);
|
||||
ctx.out.elfHeader = std::make_unique<OutputSection>(ctx, "", 0, SHF_ALLOC);
|
||||
|
||||
// We need to create some reserved symbols such as _end. Create them.
|
||||
if (!ctx.arg.relocatable)
|
||||
|
@ -133,6 +133,10 @@ uint64_t ExprValue::getSectionOffset() const {
|
||||
return getValue() - getSecAddr();
|
||||
}
|
||||
|
||||
// std::unique_ptr<OutputSection> may be incomplete type.
|
||||
LinkerScript::LinkerScript(Ctx &ctx) : ctx(ctx) {}
|
||||
LinkerScript::~LinkerScript() {}
|
||||
|
||||
OutputDesc *LinkerScript::createOutputSection(StringRef name,
|
||||
StringRef location) {
|
||||
OutputDesc *&secRef = nameToOutputSection[CachedHashStringRef(name)];
|
||||
@ -832,7 +836,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>(ctx, "", 0, SHF_ALLOC);
|
||||
aether = std::make_unique<OutputSection>(ctx, "", 0, SHF_ALLOC);
|
||||
aether->sectionIndex = 1;
|
||||
|
||||
// `st` captures the local AddressState and makes it accessible deliberately.
|
||||
@ -840,7 +844,7 @@ void LinkerScript::processSymbolAssignments() {
|
||||
// current state through to a lambda function created by the script parser.
|
||||
AddressState st(*this);
|
||||
state = &st;
|
||||
st.outSec = aether;
|
||||
st.outSec = aether.get();
|
||||
|
||||
for (SectionCommand *cmd : sectionCommands) {
|
||||
if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
|
||||
@ -1509,7 +1513,7 @@ LinkerScript::assignAddresses() {
|
||||
AddressState st(*this);
|
||||
state = &st;
|
||||
errorOnMissingSection = true;
|
||||
st.outSec = aether;
|
||||
st.outSec = aether.get();
|
||||
recordedErrors.clear();
|
||||
|
||||
SymbolAssignmentMap oldValues = getSymbolAssignmentValues(sectionCommands);
|
||||
@ -1648,9 +1652,9 @@ SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
|
||||
PhdrEntry *phdr = make<PhdrEntry>(ctx, cmd.type, cmd.flags.value_or(PF_R));
|
||||
|
||||
if (cmd.hasFilehdr)
|
||||
phdr->add(ctx.out.elfHeader);
|
||||
phdr->add(ctx.out.elfHeader.get());
|
||||
if (cmd.hasPhdrs)
|
||||
phdr->add(ctx.out.programHeaders);
|
||||
phdr->add(ctx.out.programHeaders.get());
|
||||
|
||||
if (cmd.lmaExpr) {
|
||||
phdr->p_paddr = cmd.lmaExpr().getValue();
|
||||
|
@ -332,12 +332,15 @@ class LinkerScript final {
|
||||
// LinkerScript.
|
||||
AddressState *state = nullptr;
|
||||
|
||||
OutputSection *aether;
|
||||
std::unique_ptr<OutputSection> aether;
|
||||
|
||||
uint64_t dot = 0;
|
||||
|
||||
public:
|
||||
LinkerScript(Ctx &ctx) : ctx(ctx) {}
|
||||
// OutputSection may be incomplete. Avoid inline ctor/dtor.
|
||||
LinkerScript(Ctx &ctx);
|
||||
~LinkerScript();
|
||||
|
||||
OutputDesc *createOutputSection(StringRef name, StringRef location);
|
||||
OutputDesc *getOrCreateOutputSection(StringRef name);
|
||||
|
||||
|
@ -4679,7 +4679,8 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
|
||||
ctx.in.shStrTab =
|
||||
std::make_unique<StringTableSection>(ctx, ".shstrtab", false);
|
||||
|
||||
ctx.out.programHeaders = make<OutputSection>(ctx, "", 0, SHF_ALLOC);
|
||||
ctx.out.programHeaders =
|
||||
std::make_unique<OutputSection>(ctx, "", 0, SHF_ALLOC);
|
||||
ctx.out.programHeaders->addralign = ctx.arg.wordsize;
|
||||
|
||||
if (ctx.arg.strip != StripPolicy::All) {
|
||||
|
@ -213,7 +213,7 @@ void elf::addReservedSymbols(Ctx &ctx) {
|
||||
|
||||
s->resolve(ctx, Defined{ctx, ctx.internalFile, StringRef(), STB_GLOBAL,
|
||||
STV_HIDDEN, STT_NOTYPE, gotOff, /*size=*/0,
|
||||
ctx.out.elfHeader});
|
||||
ctx.out.elfHeader.get()});
|
||||
ctx.sym.globalOffsetTable = cast<Defined>(s);
|
||||
}
|
||||
|
||||
@ -221,24 +221,27 @@ void elf::addReservedSymbols(Ctx &ctx) {
|
||||
// this symbol unconditionally even when using a linker script, which
|
||||
// differs from the behavior implemented by GNU linker which only define
|
||||
// this symbol if ELF headers are in the memory mapped segment.
|
||||
addOptionalRegular(ctx, "__ehdr_start", ctx.out.elfHeader, 0, STV_HIDDEN);
|
||||
addOptionalRegular(ctx, "__ehdr_start", ctx.out.elfHeader.get(), 0,
|
||||
STV_HIDDEN);
|
||||
|
||||
// __executable_start is not documented, but the expectation of at
|
||||
// least the Android libc is that it points to the ELF header.
|
||||
addOptionalRegular(ctx, "__executable_start", ctx.out.elfHeader, 0,
|
||||
addOptionalRegular(ctx, "__executable_start", ctx.out.elfHeader.get(), 0,
|
||||
STV_HIDDEN);
|
||||
|
||||
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
|
||||
// each DSO. The address of the symbol doesn't matter as long as they are
|
||||
// different in different DSOs, so we chose the start address of the DSO.
|
||||
addOptionalRegular(ctx, "__dso_handle", ctx.out.elfHeader, 0, STV_HIDDEN);
|
||||
addOptionalRegular(ctx, "__dso_handle", ctx.out.elfHeader.get(), 0,
|
||||
STV_HIDDEN);
|
||||
|
||||
// If linker script do layout we do not need to create any standard symbols.
|
||||
if (ctx.script->hasSectionsCommand)
|
||||
return;
|
||||
|
||||
auto add = [&](StringRef s, int64_t pos) {
|
||||
return addOptionalRegular(ctx, s, ctx.out.elfHeader, pos, STV_DEFAULT);
|
||||
return addOptionalRegular(ctx, s, ctx.out.elfHeader.get(), pos,
|
||||
STV_DEFAULT);
|
||||
};
|
||||
|
||||
ctx.sym.bss = add("__bss_start", 0);
|
||||
@ -815,10 +818,10 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
|
||||
// .rela.dyn will be present in the output.
|
||||
std::string name = ctx.arg.isRela ? "__rela_iplt_start" : "__rel_iplt_start";
|
||||
ctx.sym.relaIpltStart =
|
||||
addOptionalRegular(ctx, name, ctx.out.elfHeader, 0, STV_HIDDEN);
|
||||
addOptionalRegular(ctx, name, ctx.out.elfHeader.get(), 0, STV_HIDDEN);
|
||||
name.replace(name.size() - 5, 5, "end");
|
||||
ctx.sym.relaIpltEnd =
|
||||
addOptionalRegular(ctx, name, ctx.out.elfHeader, 0, STV_HIDDEN);
|
||||
addOptionalRegular(ctx, name, ctx.out.elfHeader.get(), 0, STV_HIDDEN);
|
||||
}
|
||||
|
||||
// This function generates assignments for predefined symbols (e.g. _end or
|
||||
@ -1751,7 +1754,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||
if (!ctx.arg.shared) {
|
||||
OutputSection *sec = findSection(ctx, ".sdata");
|
||||
addOptionalRegular(ctx, "__global_pointer$",
|
||||
sec ? sec : ctx.out.elfHeader, 0x800, STV_DEFAULT);
|
||||
sec ? sec : ctx.out.elfHeader.get(), 0x800,
|
||||
STV_DEFAULT);
|
||||
// Set riscvGlobalPointer to be used by the optional global pointer
|
||||
// relaxation.
|
||||
if (ctx.arg.relaxGP) {
|
||||
@ -2128,8 +2132,8 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
|
||||
if (startSym || stopSym)
|
||||
os->usedInExpression = true;
|
||||
} else {
|
||||
addOptionalRegular(ctx, start, ctx.out.elfHeader, 0);
|
||||
addOptionalRegular(ctx, end, ctx.out.elfHeader, 0);
|
||||
addOptionalRegular(ctx, start, ctx.out.elfHeader.get(), 0);
|
||||
addOptionalRegular(ctx, end, ctx.out.elfHeader.get(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2206,7 +2210,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
|
||||
// The first phdr entry is PT_PHDR which describes the program header
|
||||
// itself.
|
||||
if (isMain)
|
||||
addHdr(PT_PHDR, PF_R)->add(ctx.out.programHeaders);
|
||||
addHdr(PT_PHDR, PF_R)->add(ctx.out.programHeaders.get());
|
||||
else
|
||||
addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent());
|
||||
|
||||
@ -2219,8 +2223,8 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
|
||||
// need to be added here.
|
||||
if (isMain) {
|
||||
load = addHdr(PT_LOAD, flags);
|
||||
load->add(ctx.out.elfHeader);
|
||||
load->add(ctx.out.programHeaders);
|
||||
load->add(ctx.out.elfHeader.get());
|
||||
load->add(ctx.out.programHeaders.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2292,7 +2296,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
|
||||
load && !sec->lmaExpr && sec->lmaRegion == load->firstSec->lmaRegion;
|
||||
if (load && sec != relroEnd &&
|
||||
sec->memRegion == load->firstSec->memRegion &&
|
||||
(sameLMARegion || load->lastSec == ctx.out.programHeaders) &&
|
||||
(sameLMARegion || load->lastSec == ctx.out.programHeaders.get()) &&
|
||||
(ctx.script->hasSectionsCommand || sec->type == SHT_NOBITS ||
|
||||
load->lastSec->type != SHT_NOBITS)) {
|
||||
load->p_flags |= newFlags;
|
||||
|
Loading…
x
Reference in New Issue
Block a user