[lld] 5b1b6a6 - [ELF] Make elfHeader/programHeaders unique_ptr
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 17 00:25:48 PST 2024
Author: Fangrui Song
Date: 2024-11-17T00:25:42-08:00
New Revision: 5b1b6a62b8bd986adc711d0c0be5b6a8182be263
URL: https://github.com/llvm/llvm-project/commit/5b1b6a62b8bd986adc711d0c0be5b6a8182be263
DIFF: https://github.com/llvm/llvm-project/commit/5b1b6a62b8bd986adc711d0c0be5b6a8182be263.diff
LOG: [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.
Added:
Modified:
lld/ELF/Arch/ARM.cpp
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/LinkerScript.cpp
lld/ELF/LinkerScript.h
lld/ELF/SyntheticSections.cpp
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index c8fbc77e308251..100db445446810 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -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);
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 1e83104db773c7..2cca0a0bf71859 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -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;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 2592877203bfa0..10c52d7206b805 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -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)
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index d3a9302249dad0..3f962e1a3129a3 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -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();
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 33c526f59bfc41..445bb2b1d7d23c 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -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);
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 00149aa270f19a..10372248bc8733 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -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) {
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 69a22229792f5f..5865ead0ff88bb 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -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
//
diff ers 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
//
diff erent in
diff erent 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;
More information about the llvm-commits
mailing list