Skip to content

Commit 5b1b6a6

Browse files
committed
[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.
1 parent 53dc4e7 commit 5b1b6a6

File tree

7 files changed

+45
-31
lines changed

7 files changed

+45
-31
lines changed

lld/ELF/Arch/ARM.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,12 +1466,14 @@ template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
14661466
SymbolTableBaseSection *impSymTab =
14671467
make<SymbolTableSection<ELFT>>(ctx, *strtab);
14681468

1469-
SmallVector<std::pair<OutputSection *, SyntheticSection *>, 0> osIsPairs;
1470-
osIsPairs.emplace_back(make<OutputSection>(ctx, strtab->name, 0, 0), strtab);
1471-
osIsPairs.emplace_back(make<OutputSection>(ctx, impSymTab->name, 0, 0),
1472-
impSymTab);
1473-
osIsPairs.emplace_back(make<OutputSection>(ctx, shstrtab->name, 0, 0),
1474-
shstrtab);
1469+
SmallVector<std::pair<std::unique_ptr<OutputSection>, SyntheticSection *>, 0>
1470+
osIsPairs;
1471+
osIsPairs.emplace_back(
1472+
std::make_unique<OutputSection>(ctx, strtab->name, 0, 0), strtab);
1473+
osIsPairs.emplace_back(
1474+
std::make_unique<OutputSection>(ctx, impSymTab->name, 0, 0), impSymTab);
1475+
osIsPairs.emplace_back(
1476+
std::make_unique<OutputSection>(ctx, shstrtab->name, 0, 0), shstrtab);
14751477

14761478
llvm::sort(ctx.symtab->cmseSymMap, [&](const auto &a, const auto &b) {
14771479
return a.second.sym->getVA(ctx) < b.second.sym->getVA(ctx);

lld/ELF/Config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,8 @@ struct Ctx : CommonLinkerContext {
565565
Partition *mainPart = nullptr;
566566
PhdrEntry *tlsPhdr = nullptr;
567567
struct OutSections {
568-
OutputSection *elfHeader;
569-
OutputSection *programHeaders;
568+
std::unique_ptr<OutputSection> elfHeader;
569+
std::unique_ptr<OutputSection> programHeaders;
570570
OutputSection *preinitArray;
571571
OutputSection *initArray;
572572
OutputSection *finiArray;

lld/ELF/Driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2973,7 +2973,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
29732973

29742974
// Create elfHeader early. We need a dummy section in
29752975
// addReservedSymbols to mark the created symbols as not absolute.
2976-
ctx.out.elfHeader = make<OutputSection>(ctx, "", 0, SHF_ALLOC);
2976+
ctx.out.elfHeader = std::make_unique<OutputSection>(ctx, "", 0, SHF_ALLOC);
29772977

29782978
// We need to create some reserved symbols such as _end. Create them.
29792979
if (!ctx.arg.relocatable)

lld/ELF/LinkerScript.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ uint64_t ExprValue::getSectionOffset() const {
133133
return getValue() - getSecAddr();
134134
}
135135

136+
// std::unique_ptr<OutputSection> may be incomplete type.
137+
LinkerScript::LinkerScript(Ctx &ctx) : ctx(ctx) {}
138+
LinkerScript::~LinkerScript() {}
139+
136140
OutputDesc *LinkerScript::createOutputSection(StringRef name,
137141
StringRef location) {
138142
OutputDesc *&secRef = nameToOutputSection[CachedHashStringRef(name)];
@@ -832,15 +836,15 @@ void LinkerScript::processSymbolAssignments() {
832836
// sh_shndx should not be SHN_UNDEF or SHN_ABS. Create a dummy aether section
833837
// that fills the void outside a section. It has an index of one, which is
834838
// indistinguishable from any other regular section index.
835-
aether = make<OutputSection>(ctx, "", 0, SHF_ALLOC);
839+
aether = std::make_unique<OutputSection>(ctx, "", 0, SHF_ALLOC);
836840
aether->sectionIndex = 1;
837841

838842
// `st` captures the local AddressState and makes it accessible deliberately.
839843
// This is needed as there are some cases where we cannot just thread the
840844
// current state through to a lambda function created by the script parser.
841845
AddressState st(*this);
842846
state = &st;
843-
st.outSec = aether;
847+
st.outSec = aether.get();
844848

845849
for (SectionCommand *cmd : sectionCommands) {
846850
if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
@@ -1509,7 +1513,7 @@ LinkerScript::assignAddresses() {
15091513
AddressState st(*this);
15101514
state = &st;
15111515
errorOnMissingSection = true;
1512-
st.outSec = aether;
1516+
st.outSec = aether.get();
15131517
recordedErrors.clear();
15141518

15151519
SymbolAssignmentMap oldValues = getSymbolAssignmentValues(sectionCommands);
@@ -1648,9 +1652,9 @@ SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
16481652
PhdrEntry *phdr = make<PhdrEntry>(ctx, cmd.type, cmd.flags.value_or(PF_R));
16491653

16501654
if (cmd.hasFilehdr)
1651-
phdr->add(ctx.out.elfHeader);
1655+
phdr->add(ctx.out.elfHeader.get());
16521656
if (cmd.hasPhdrs)
1653-
phdr->add(ctx.out.programHeaders);
1657+
phdr->add(ctx.out.programHeaders.get());
16541658

16551659
if (cmd.lmaExpr) {
16561660
phdr->p_paddr = cmd.lmaExpr().getValue();

lld/ELF/LinkerScript.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,15 @@ class LinkerScript final {
332332
// LinkerScript.
333333
AddressState *state = nullptr;
334334

335-
OutputSection *aether;
335+
std::unique_ptr<OutputSection> aether;
336336

337337
uint64_t dot = 0;
338338

339339
public:
340-
LinkerScript(Ctx &ctx) : ctx(ctx) {}
340+
// OutputSection may be incomplete. Avoid inline ctor/dtor.
341+
LinkerScript(Ctx &ctx);
342+
~LinkerScript();
343+
341344
OutputDesc *createOutputSection(StringRef name, StringRef location);
342345
OutputDesc *getOrCreateOutputSection(StringRef name);
343346

lld/ELF/SyntheticSections.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4679,7 +4679,8 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
46794679
ctx.in.shStrTab =
46804680
std::make_unique<StringTableSection>(ctx, ".shstrtab", false);
46814681

4682-
ctx.out.programHeaders = make<OutputSection>(ctx, "", 0, SHF_ALLOC);
4682+
ctx.out.programHeaders =
4683+
std::make_unique<OutputSection>(ctx, "", 0, SHF_ALLOC);
46834684
ctx.out.programHeaders->addralign = ctx.arg.wordsize;
46844685

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

lld/ELF/Writer.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,32 +213,35 @@ void elf::addReservedSymbols(Ctx &ctx) {
213213

214214
s->resolve(ctx, Defined{ctx, ctx.internalFile, StringRef(), STB_GLOBAL,
215215
STV_HIDDEN, STT_NOTYPE, gotOff, /*size=*/0,
216-
ctx.out.elfHeader});
216+
ctx.out.elfHeader.get()});
217217
ctx.sym.globalOffsetTable = cast<Defined>(s);
218218
}
219219

220220
// __ehdr_start is the location of ELF file headers. Note that we define
221221
// this symbol unconditionally even when using a linker script, which
222222
// differs from the behavior implemented by GNU linker which only define
223223
// this symbol if ELF headers are in the memory mapped segment.
224-
addOptionalRegular(ctx, "__ehdr_start", ctx.out.elfHeader, 0, STV_HIDDEN);
224+
addOptionalRegular(ctx, "__ehdr_start", ctx.out.elfHeader.get(), 0,
225+
STV_HIDDEN);
225226

226227
// __executable_start is not documented, but the expectation of at
227228
// least the Android libc is that it points to the ELF header.
228-
addOptionalRegular(ctx, "__executable_start", ctx.out.elfHeader, 0,
229+
addOptionalRegular(ctx, "__executable_start", ctx.out.elfHeader.get(), 0,
229230
STV_HIDDEN);
230231

231232
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
232233
// each DSO. The address of the symbol doesn't matter as long as they are
233234
// different in different DSOs, so we chose the start address of the DSO.
234-
addOptionalRegular(ctx, "__dso_handle", ctx.out.elfHeader, 0, STV_HIDDEN);
235+
addOptionalRegular(ctx, "__dso_handle", ctx.out.elfHeader.get(), 0,
236+
STV_HIDDEN);
235237

236238
// If linker script do layout we do not need to create any standard symbols.
237239
if (ctx.script->hasSectionsCommand)
238240
return;
239241

240242
auto add = [&](StringRef s, int64_t pos) {
241-
return addOptionalRegular(ctx, s, ctx.out.elfHeader, pos, STV_DEFAULT);
243+
return addOptionalRegular(ctx, s, ctx.out.elfHeader.get(), pos,
244+
STV_DEFAULT);
242245
};
243246

244247
ctx.sym.bss = add("__bss_start", 0);
@@ -815,10 +818,10 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
815818
// .rela.dyn will be present in the output.
816819
std::string name = ctx.arg.isRela ? "__rela_iplt_start" : "__rel_iplt_start";
817820
ctx.sym.relaIpltStart =
818-
addOptionalRegular(ctx, name, ctx.out.elfHeader, 0, STV_HIDDEN);
821+
addOptionalRegular(ctx, name, ctx.out.elfHeader.get(), 0, STV_HIDDEN);
819822
name.replace(name.size() - 5, 5, "end");
820823
ctx.sym.relaIpltEnd =
821-
addOptionalRegular(ctx, name, ctx.out.elfHeader, 0, STV_HIDDEN);
824+
addOptionalRegular(ctx, name, ctx.out.elfHeader.get(), 0, STV_HIDDEN);
822825
}
823826

824827
// This function generates assignments for predefined symbols (e.g. _end or
@@ -1751,7 +1754,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
17511754
if (!ctx.arg.shared) {
17521755
OutputSection *sec = findSection(ctx, ".sdata");
17531756
addOptionalRegular(ctx, "__global_pointer$",
1754-
sec ? sec : ctx.out.elfHeader, 0x800, STV_DEFAULT);
1757+
sec ? sec : ctx.out.elfHeader.get(), 0x800,
1758+
STV_DEFAULT);
17551759
// Set riscvGlobalPointer to be used by the optional global pointer
17561760
// relaxation.
17571761
if (ctx.arg.relaxGP) {
@@ -2128,8 +2132,8 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
21282132
if (startSym || stopSym)
21292133
os->usedInExpression = true;
21302134
} else {
2131-
addOptionalRegular(ctx, start, ctx.out.elfHeader, 0);
2132-
addOptionalRegular(ctx, end, ctx.out.elfHeader, 0);
2135+
addOptionalRegular(ctx, start, ctx.out.elfHeader.get(), 0);
2136+
addOptionalRegular(ctx, end, ctx.out.elfHeader.get(), 0);
21332137
}
21342138
};
21352139

@@ -2206,7 +2210,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
22062210
// The first phdr entry is PT_PHDR which describes the program header
22072211
// itself.
22082212
if (isMain)
2209-
addHdr(PT_PHDR, PF_R)->add(ctx.out.programHeaders);
2213+
addHdr(PT_PHDR, PF_R)->add(ctx.out.programHeaders.get());
22102214
else
22112215
addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent());
22122216

@@ -2219,8 +2223,8 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
22192223
// need to be added here.
22202224
if (isMain) {
22212225
load = addHdr(PT_LOAD, flags);
2222-
load->add(ctx.out.elfHeader);
2223-
load->add(ctx.out.programHeaders);
2226+
load->add(ctx.out.elfHeader.get());
2227+
load->add(ctx.out.programHeaders.get());
22242228
}
22252229
}
22262230

@@ -2292,7 +2296,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
22922296
load && !sec->lmaExpr && sec->lmaRegion == load->firstSec->lmaRegion;
22932297
if (load && sec != relroEnd &&
22942298
sec->memRegion == load->firstSec->memRegion &&
2295-
(sameLMARegion || load->lastSec == ctx.out.programHeaders) &&
2299+
(sameLMARegion || load->lastSec == ctx.out.programHeaders.get()) &&
22962300
(ctx.script->hasSectionsCommand || sec->type == SHT_NOBITS ||
22972301
load->lastSec->type != SHT_NOBITS)) {
22982302
load->p_flags |= newFlags;

0 commit comments

Comments
 (0)