[lld] a520324 - [ELF] Avoid make<PhdrEntry>
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 19 22:38:20 PST 2024
Author: Fangrui Song
Date: 2024-11-19T22:38:14-08:00
New Revision: a52032448efb5d24af9c57418580206f17931401
URL: https://github.com/llvm/llvm-project/commit/a52032448efb5d24af9c57418580206f17931401
DIFF: https://github.com/llvm/llvm-project/commit/a52032448efb5d24af9c57418580206f17931401.diff
LOG: [ELF] Avoid make<PhdrEntry>
Store them in Partition::phdrs instead.
Added:
Modified:
lld/ELF/LinkerScript.cpp
lld/ELF/LinkerScript.h
lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 3f962e1a3129a3..d8aa2c46cfa5b3 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1440,17 +1440,17 @@ void LinkerScript::adjustSectionsAfterSorting() {
// We check if the headers fit below the first allocated section. If there isn't
// enough space for these sections, we'll remove them from the PT_LOAD segment,
// and we'll also remove the PT_PHDR segment.
-void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
+void LinkerScript::allocateHeaders(
+ SmallVector<std::unique_ptr<PhdrEntry>, 0> &phdrs) {
uint64_t min = std::numeric_limits<uint64_t>::max();
for (OutputSection *sec : ctx.outputSections)
if (sec->flags & SHF_ALLOC)
min = std::min<uint64_t>(min, sec->addr);
- auto it = llvm::find_if(
- phdrs, [](const PhdrEntry *e) { return e->p_type == PT_LOAD; });
+ auto it = llvm::find_if(phdrs, [](auto &e) { return e->p_type == PT_LOAD; });
if (it == phdrs.end())
return;
- PhdrEntry *firstPTLoad = *it;
+ PhdrEntry *firstPTLoad = it->get();
bool hasExplicitHeaders =
llvm::any_of(phdrsCommands, [](const PhdrsCommand &cmd) {
@@ -1479,8 +1479,7 @@ void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
ctx.out.programHeaders->ptLoad = nullptr;
firstPTLoad->firstSec = findFirstSection(ctx, firstPTLoad);
- llvm::erase_if(phdrs,
- [](const PhdrEntry *e) { return e->p_type == PT_PHDR; });
+ llvm::erase_if(phdrs, [](auto &e) { return e->p_type == PT_PHDR; });
}
LinkerScript::AddressState::AddressState(const LinkerScript &script) {
@@ -1643,13 +1642,14 @@ void LinkerScript::erasePotentialSpillSections() {
}
// Creates program headers as instructed by PHDRS linker script command.
-SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
- SmallVector<PhdrEntry *, 0> ret;
+SmallVector<std::unique_ptr<PhdrEntry>, 0> LinkerScript::createPhdrs() {
+ SmallVector<std::unique_ptr<PhdrEntry>, 0> ret;
// Process PHDRS and FILEHDR keywords because they are not
// real output sections and cannot be added in the following loop.
for (const PhdrsCommand &cmd : phdrsCommands) {
- PhdrEntry *phdr = make<PhdrEntry>(ctx, cmd.type, cmd.flags.value_or(PF_R));
+ auto phdr =
+ std::make_unique<PhdrEntry>(ctx, cmd.type, cmd.flags.value_or(PF_R));
if (cmd.hasFilehdr)
phdr->add(ctx.out.elfHeader.get());
@@ -1660,7 +1660,7 @@ SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
phdr->p_paddr = cmd.lmaExpr().getValue();
phdr->hasLMA = true;
}
- ret.push_back(phdr);
+ ret.push_back(std::move(phdr));
}
// Add output sections to program headers.
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 445bb2b1d7d23c..f5408b4ba3037e 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -356,14 +356,14 @@ class LinkerScript final {
void adjustOutputSections();
void adjustSectionsAfterSorting();
- SmallVector<PhdrEntry *, 0> createPhdrs();
+ SmallVector<std::unique_ptr<PhdrEntry>, 0> createPhdrs();
bool needsInterpSection();
bool shouldKeep(InputSectionBase *s);
std::pair<const OutputSection *, const Defined *> assignAddresses();
bool spillSections();
void erasePotentialSpillSections();
- void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
+ void allocateHeaders(SmallVector<std::unique_ptr<PhdrEntry>, 0> &phdrs);
void processSectionCommands();
void processSymbolAssignments();
void declareSymbols();
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 10372248bc8733..7e5e713513c473 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -4427,7 +4427,7 @@ void elf::writeEhdr(Ctx &ctx, uint8_t *buf, Partition &part) {
template <typename ELFT> void elf::writePhdrs(uint8_t *buf, Partition &part) {
// Write the program header table.
auto *hBuf = reinterpret_cast<typename ELFT::Phdr *>(buf);
- for (PhdrEntry *p : part.phdrs) {
+ for (std::unique_ptr<PhdrEntry> &p : part.phdrs) {
hBuf->p_type = p->p_type;
hBuf->p_flags = p->p_flags;
hBuf->p_offset = p->p_offset;
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index bfe318fb10d297..163a4950a0983f 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1472,7 +1472,7 @@ struct Partition {
std::unique_ptr<SyntheticSection> elfHeader;
std::unique_ptr<SyntheticSection> programHeaders;
- SmallVector<PhdrEntry *, 0> phdrs;
+ SmallVector<std::unique_ptr<PhdrEntry>, 0> phdrs;
std::unique_ptr<ARMExidxSyntheticSection> armExidx;
std::unique_ptr<BuildIdSection> buildId;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index d698479c9707fb..26887d11a397a6 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -65,7 +65,7 @@ template <class ELFT> class Writer {
void checkExecuteOnly();
void setReservedSymbolSections();
- SmallVector<PhdrEntry *, 0> createPhdrs(Partition &part);
+ SmallVector<std::unique_ptr<PhdrEntry>, 0> createPhdrs(Partition &part);
void addPhdrForSection(Partition &part, unsigned shType, unsigned pType,
unsigned pFlags);
void assignFileOffsets();
@@ -96,20 +96,22 @@ template <class ELFT> void elf::writeResult(Ctx &ctx) {
Writer<ELFT>(ctx).run();
}
-static void removeEmptyPTLoad(Ctx &ctx, SmallVector<PhdrEntry *, 0> &phdrs) {
- auto it = std::stable_partition(
- phdrs.begin(), phdrs.end(), [&](const PhdrEntry *p) {
- if (p->p_type != PT_LOAD)
- return true;
- if (!p->firstSec)
- return false;
- uint64_t size = p->lastSec->addr + p->lastSec->size - p->firstSec->addr;
- return size != 0;
- });
+static void
+removeEmptyPTLoad(Ctx &ctx, SmallVector<std::unique_ptr<PhdrEntry>, 0> &phdrs) {
+ auto it = std::stable_partition(phdrs.begin(), phdrs.end(), [&](auto &p) {
+ if (p->p_type != PT_LOAD)
+ return true;
+ if (!p->firstSec)
+ return false;
+ uint64_t size = p->lastSec->addr + p->lastSec->size - p->firstSec->addr;
+ return size != 0;
+ });
// Clear OutputSection::ptLoad for sections contained in removed
// segments.
- DenseSet<PhdrEntry *> removed(it, phdrs.end());
+ DenseSet<PhdrEntry *> removed;
+ for (auto it2 = it; it2 != phdrs.end(); ++it2)
+ removed.insert(it2->get());
for (OutputSection *sec : ctx.outputSections)
if (removed.count(sec->ptLoad))
sec->ptLoad = nullptr;
@@ -853,10 +855,10 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
return ctx.arg.emachine == EM_X86_64 && osec->flags & SHF_X86_64_LARGE;
};
for (Partition &part : ctx.partitions) {
- for (PhdrEntry *p : part.phdrs) {
+ for (auto &p : part.phdrs) {
if (p->p_type != PT_LOAD)
continue;
- last = p;
+ last = p.get();
if (!(p->p_flags & PF_W) && p->lastSec && !isLarge(p->lastSec))
lastRO = p->lastSec;
}
@@ -1978,9 +1980,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Android relocation packing can look up TLS symbol addresses. We only need
// to care about the main partition here because all TLS symbols were moved
// to the main partition (see MarkLive.cpp).
- for (PhdrEntry *p : ctx.mainPart->phdrs)
+ for (auto &p : ctx.mainPart->phdrs)
if (p->p_type == PT_TLS)
- ctx.tlsPhdr = p;
+ ctx.tlsPhdr = p.get();
}
// Some symbols are defined in term of program headers. Now that we
@@ -2190,11 +2192,12 @@ static uint64_t computeFlags(Ctx &ctx, uint64_t flags) {
// Decide which program headers to create and which sections to include in each
// one.
template <class ELFT>
-SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
- SmallVector<PhdrEntry *, 0> ret;
+SmallVector<std::unique_ptr<PhdrEntry>, 0>
+Writer<ELFT>::createPhdrs(Partition &part) {
+ SmallVector<std::unique_ptr<PhdrEntry>, 0> ret;
auto addHdr = [&, &ctx = ctx](unsigned type, unsigned flags) -> PhdrEntry * {
- ret.push_back(make<PhdrEntry>(ctx, type, flags));
- return ret.back();
+ ret.push_back(std::make_unique<PhdrEntry>(ctx, type, flags));
+ return ret.back().get();
};
unsigned partNo = part.getNumber(ctx);
@@ -2232,7 +2235,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
// read-only by dynamic linker after processing relocations.
// Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
// an error message if more than one PT_GNU_RELRO PHDR is required.
- PhdrEntry *relRo = make<PhdrEntry>(ctx, PT_GNU_RELRO, PF_R);
+ auto relRo = std::make_unique<PhdrEntry>(ctx, PT_GNU_RELRO, PF_R);
bool inRelroPhdr = false;
OutputSection *relroEnd = nullptr;
for (OutputSection *sec : ctx.outputSections) {
@@ -2309,19 +2312,19 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
}
// Add a TLS segment if any.
- PhdrEntry *tlsHdr = make<PhdrEntry>(ctx, PT_TLS, PF_R);
+ auto tlsHdr = std::make_unique<PhdrEntry>(ctx, PT_TLS, PF_R);
for (OutputSection *sec : ctx.outputSections)
if (sec->partition == partNo && sec->flags & SHF_TLS)
tlsHdr->add(sec);
if (tlsHdr->firstSec)
- ret.push_back(tlsHdr);
+ ret.push_back(std::move(tlsHdr));
// Add an entry for .dynamic.
if (OutputSection *sec = part.dynamic->getParent())
addHdr(PT_DYNAMIC, sec->getPhdrFlags())->add(sec);
if (relRo->firstSec)
- ret.push_back(relRo);
+ ret.push_back(std::move(relRo));
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
if (part.ehFrame->isNeeded() && part.ehFrameHdr &&
@@ -2394,9 +2397,9 @@ void Writer<ELFT>::addPhdrForSection(Partition &part, unsigned shType,
if (i == ctx.outputSections.end())
return;
- PhdrEntry *entry = make<PhdrEntry>(ctx, pType, pFlags);
+ auto entry = std::make_unique<PhdrEntry>(ctx, pType, pFlags);
entry->add(*i);
- part.phdrs.push_back(entry);
+ part.phdrs.push_back(std::move(entry));
}
// Place the first section of each PT_LOAD to a
diff erent page (of maxPageSize).
@@ -2459,10 +2462,10 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
for (Partition &part : ctx.partitions) {
prev = nullptr;
- for (const PhdrEntry *p : part.phdrs)
+ for (auto &p : part.phdrs)
if (p->p_type == PT_LOAD && p->firstSec) {
- pageAlign(p);
- prev = p;
+ pageAlign(p.get());
+ prev = p.get();
}
}
}
@@ -2524,9 +2527,9 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
PhdrEntry *lastRX = nullptr;
for (Partition &part : ctx.partitions)
- for (PhdrEntry *p : part.phdrs)
+ for (auto &p : part.phdrs)
if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
- lastRX = p;
+ lastRX = p.get();
// Layout SHF_ALLOC sections before non-SHF_ALLOC sections. A non-SHF_ALLOC
// will not occupy file offsets contained by a PT_LOAD.
@@ -2579,7 +2582,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
// Finalize the program headers. We call this function after we assign
// file offsets and VAs to all sections.
template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &part) {
- for (PhdrEntry *p : part.phdrs) {
+ for (std::unique_ptr<PhdrEntry> &p : part.phdrs) {
OutputSection *first = p->firstSec;
OutputSection *last = p->lastSec;
@@ -2838,7 +2841,7 @@ static void fillTrap(std::array<uint8_t, 4> trapInstr, uint8_t *i,
template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
for (Partition &part : ctx.partitions) {
// Fill the last page.
- for (PhdrEntry *p : part.phdrs)
+ for (std::unique_ptr<PhdrEntry> &p : part.phdrs)
if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
fillTrap(
ctx.target->trapInstr,
@@ -2850,9 +2853,9 @@ template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
// an executable segment to ensure that other tools don't accidentally
// trim the instruction padding (e.g. when stripping the file).
PhdrEntry *last = nullptr;
- for (PhdrEntry *p : part.phdrs)
+ for (std::unique_ptr<PhdrEntry> &p : part.phdrs)
if (p->p_type == PT_LOAD)
- last = p;
+ last = p.get();
if (last && (last->p_flags & PF_X))
last->p_memsz = last->p_filesz =
More information about the llvm-commits
mailing list