[lld] 0206181 - [ELF] Pass Ctx & to Driver and Writer
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 23 21:28:19 PDT 2024
Author: Fangrui Song
Date: 2024-09-23T21:28:14-07:00
New Revision: 0206181ada4b39f0324dfe977442c65c1693f0b1
URL: https://github.com/llvm/llvm-project/commit/0206181ada4b39f0324dfe977442c65c1693f0b1
DIFF: https://github.com/llvm/llvm-project/commit/0206181ada4b39f0324dfe977442c65c1693f0b1.diff
LOG: [ELF] Pass Ctx & to Driver and Writer
Added:
Modified:
lld/ELF/Driver.cpp
lld/ELF/Writer.cpp
lld/ELF/Writer.h
Removed:
################################################################################
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index dab0fbe3f5bda5..343fc4989fa4c7 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2726,7 +2726,7 @@ static void checkAndReportMissingFeature(StringRef config, uint32_t features,
// For AArch64 PAuth-enabled object files, the core info of all of them must
// match. Missing info for some object files with matching info for remaining
// ones can be allowed (see -z pauth-report).
-static void readSecurityNotes() {
+static void readSecurityNotes(Ctx &ctx) {
if (ctx.arg.emachine != EM_386 && ctx.arg.emachine != EM_X86_64 &&
ctx.arg.emachine != EM_AARCH64)
return;
@@ -2969,7 +2969,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// We need to create some reserved symbols such as _end. Create them.
if (!ctx.arg.relocatable)
- addReservedSymbols();
+ addReservedSymbols(ctx);
// Apply version scripts.
//
@@ -3113,7 +3113,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Read .note.gnu.property sections from input object files which
// contain a hint to tweak linker's and loader's behaviors.
- readSecurityNotes();
+ readSecurityNotes(ctx);
// The Target instance handles target-specific stuff, such as applying
// relocations or writing a PLT section. It also contains target-dependent
@@ -3147,7 +3147,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Make copies of any input sections that need to be copied into each
// partition.
- copySectionsIntoPartitions();
+ copySectionsIntoPartitions(ctx);
if (canHaveMemtagGlobals()) {
llvm::TimeTraceScope timeScope("Process memory tagged symbols");
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 90c8d081b702fa..ce7cbc25d7eb08 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -96,7 +96,7 @@ template <class ELFT> void elf::writeResult(Ctx &ctx) {
Writer<ELFT>(ctx).run();
}
-static void removeEmptyPTLoad(SmallVector<PhdrEntry *, 0> &phdrs) {
+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)
@@ -116,7 +116,7 @@ static void removeEmptyPTLoad(SmallVector<PhdrEntry *, 0> &phdrs) {
phdrs.erase(it, phdrs.end());
}
-void elf::copySectionsIntoPartitions() {
+void elf::copySectionsIntoPartitions(Ctx &ctx) {
SmallVector<InputSectionBase *, 0> newSections;
const size_t ehSize = ctx.ehInputSections.size();
for (unsigned part = 2; part != ctx.partitions.size() + 1; ++part) {
@@ -139,7 +139,7 @@ void elf::copySectionsIntoPartitions() {
newSections.end());
}
-static Defined *addOptionalRegular(StringRef name, SectionBase *sec,
+static Defined *addOptionalRegular(Ctx &ctx, StringRef name, SectionBase *sec,
uint64_t val, uint8_t stOther = STV_HIDDEN) {
Symbol *s = ctx.symtab->find(name);
if (!s || s->isDefined() || s->isCommon())
@@ -154,9 +154,9 @@ static Defined *addOptionalRegular(StringRef name, SectionBase *sec,
// The linker is expected to define some symbols depending on
// the linking result. This function defines such symbols.
-void elf::addReservedSymbols() {
+void elf::addReservedSymbols(Ctx &ctx) {
if (ctx.arg.emachine == EM_MIPS) {
- auto addAbsolute = [](StringRef name) {
+ auto addAbsolute = [&](StringRef name) {
Symbol *sym =
ctx.symtab->addSymbol(Defined{ctx.internalFile, name, STB_GLOBAL,
STV_HIDDEN, STT_NOTYPE, 0, 0, nullptr});
@@ -184,7 +184,7 @@ void elf::addReservedSymbols() {
} else if (ctx.arg.emachine == EM_PPC) {
// glibc *crt1.o has a undefined reference to _SDA_BASE_. Since we don't
// support Small Data Area, define it arbitrarily as 0.
- addOptionalRegular("_SDA_BASE_", nullptr, 0, STV_HIDDEN);
+ addOptionalRegular(ctx, "_SDA_BASE_", nullptr, 0, STV_HIDDEN);
} else if (ctx.arg.emachine == EM_PPC64) {
addPPC64SaveRestore();
}
@@ -220,23 +220,24 @@ void elf::addReservedSymbols() {
// 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("__ehdr_start", ctx.out.elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular(ctx, "__ehdr_start", ctx.out.elfHeader, 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("__executable_start", ctx.out.elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular(ctx, "__executable_start", ctx.out.elfHeader, 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("__dso_handle", ctx.out.elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular(ctx, "__dso_handle", ctx.out.elfHeader, 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(s, ctx.out.elfHeader, pos, STV_DEFAULT);
+ auto add = [&](StringRef s, int64_t pos) {
+ return addOptionalRegular(ctx, s, ctx.out.elfHeader, pos, STV_DEFAULT);
};
ctx.sym.bss = add("__bss_start", 0);
@@ -270,7 +271,7 @@ static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
//
// In addition, demote symbols defined in discarded sections, so that
// references to /DISCARD/ discarded symbols will lead to errors.
-static void demoteSymbolsAndComputeIsPreemptible() {
+static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
llvm::TimeTraceScope timeScope("Demote symbols");
DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
for (Symbol *sym : ctx.symtab->getSymbols()) {
@@ -322,7 +323,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// 0 sized region. This has to be done late since only after assignAddresses
// we know the size of the sections.
for (Partition &part : ctx.partitions)
- removeEmptyPTLoad(part.phdrs);
+ removeEmptyPTLoad(ctx, part.phdrs);
if (!ctx.arg.oFormatBinary)
assignFileOffsets();
@@ -391,7 +392,7 @@ static void markUsedLocalSymbolsImpl(ObjFile<ELFT> *file,
// The function ensures that the "used" field of local symbols reflects the fact
// that the symbol is used in a relocation from a live section.
-template <class ELFT> static void markUsedLocalSymbols() {
+template <class ELFT> static void markUsedLocalSymbols(Ctx &ctx) {
// With --gc-sections, the field is already filled.
// See MarkLive<ELFT>::resolveReloc().
if (ctx.arg.gcSections)
@@ -419,7 +420,7 @@ template <class ELFT> static void markUsedLocalSymbols() {
}
}
-static bool shouldKeepInSymtab(const Defined &sym) {
+static bool shouldKeepInSymtab(Ctx &ctx, const Defined &sym) {
if (sym.isSection())
return false;
@@ -474,7 +475,7 @@ bool lld::elf::includeInSymtab(const Symbol &b) {
// - demote symbols defined relative to /DISCARD/ discarded input sections so
// that relocations referencing them will lead to errors.
// - copy eligible symbols to .symTab
-static void demoteAndCopyLocalSymbols() {
+static void demoteAndCopyLocalSymbols(Ctx &ctx) {
llvm::TimeTraceScope timeScope("Add local symbols");
for (ELFFileBase *file : ctx.objectFiles) {
DenseMap<SectionBase *, size_t> sectionIndexMap;
@@ -486,7 +487,8 @@ static void demoteAndCopyLocalSymbols() {
if (dr->section && !dr->section->isLive())
demoteDefined(*dr, sectionIndexMap);
- else if (ctx.in.symTab && includeInSymtab(*b) && shouldKeepInSymtab(*dr))
+ else if (ctx.in.symTab && includeInSymtab(*b) &&
+ shouldKeepInSymtab(ctx, *dr))
ctx.in.symTab->addSymbol(b);
}
}
@@ -811,10 +813,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(name, ctx.out.elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular(ctx, name, ctx.out.elfHeader, 0, STV_HIDDEN);
name.replace(name.size() - 5, 5, "end");
ctx.sym.relaIpltEnd =
- addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
+ addOptionalRegular(ctx, name, ctx.out.elfHeader, 0, STV_HIDDEN);
}
// This function generates assignments for predefined symbols (e.g. _end or
@@ -1661,7 +1663,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
// To deal with the above problem, this function is called after
// scanRelocations is called to remove synthetic sections that turn
// out to be empty.
-static void removeUnusedSyntheticSections() {
+static void removeUnusedSyntheticSections(Ctx &ctx) {
// All input synthetic sections that can be empty are placed after
// all regular ones. Reverse iterate to find the first synthetic section
// after a non-synthetic one which will be our starting point.
@@ -1740,8 +1742,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (ctx.arg.emachine == EM_RISCV) {
if (!ctx.arg.shared) {
OutputSection *sec = findSection(".sdata");
- addOptionalRegular("__global_pointer$", sec ? sec : ctx.out.elfHeader,
- 0x800, STV_DEFAULT);
+ addOptionalRegular(ctx, "__global_pointer$",
+ sec ? sec : ctx.out.elfHeader, 0x800, STV_DEFAULT);
// Set riscvGlobalPointer to be used by the optional global pointer
// relaxation.
if (ctx.arg.relaxGP) {
@@ -1783,11 +1785,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
}
}
- demoteSymbolsAndComputeIsPreemptible();
+ demoteSymbolsAndComputeIsPreemptible(ctx);
if (ctx.arg.copyRelocs && ctx.arg.discard != DiscardPolicy::None)
- markUsedLocalSymbols<ELFT>();
- demoteAndCopyLocalSymbols();
+ markUsedLocalSymbols<ELFT>(ctx);
+ demoteAndCopyLocalSymbols(ctx);
if (ctx.arg.copyRelocs)
addSectionSymbols();
@@ -1890,7 +1892,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (ctx.in.mipsGot)
ctx.in.mipsGot->build();
- removeUnusedSyntheticSections();
+ removeUnusedSyntheticSections(ctx);
ctx.script->diagnoseOrphanHandling();
ctx.script->diagnoseMissingSGSectionAddress();
@@ -2111,13 +2113,13 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
// correct.
auto define = [=](StringRef start, StringRef end, OutputSection *os) {
if (os) {
- Defined *startSym = addOptionalRegular(start, os, 0);
- Defined *stopSym = addOptionalRegular(end, os, -1);
+ Defined *startSym = addOptionalRegular(ctx, start, os, 0);
+ Defined *stopSym = addOptionalRegular(ctx, end, os, -1);
if (startSym || stopSym)
os->usedInExpression = true;
} else {
- addOptionalRegular(start, ctx.out.elfHeader, 0);
- addOptionalRegular(end, ctx.out.elfHeader, 0);
+ addOptionalRegular(ctx, start, ctx.out.elfHeader, 0);
+ addOptionalRegular(ctx, end, ctx.out.elfHeader, 0);
}
};
@@ -2141,10 +2143,11 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection &osec) {
StringRef s = osec.name;
if (!isValidCIdentifier(s))
return;
- Defined *startSym = addOptionalRegular(saver().save("__start_" + s), &osec, 0,
- ctx.arg.zStartStopVisibility);
- Defined *stopSym = addOptionalRegular(saver().save("__stop_" + s), &osec, -1,
- ctx.arg.zStartStopVisibility);
+ Defined *startSym =
+ addOptionalRegular(ctx, saver().save("__start_" + s), &osec, 0,
+ ctx.arg.zStartStopVisibility);
+ Defined *stopSym = addOptionalRegular(ctx, saver().save("__stop_" + s), &osec,
+ -1, ctx.arg.zStartStopVisibility);
if (startSym || stopSym)
osec.usedInExpression = true;
}
@@ -2162,7 +2165,7 @@ static bool needsPtLoad(OutputSection *sec) {
}
// Adjust phdr flags according to certain options.
-static uint64_t computeFlags(uint64_t flags) {
+static uint64_t computeFlags(Ctx &ctx, uint64_t flags) {
if (ctx.arg.omagic)
return PF_R | PF_W | PF_X;
if (ctx.arg.executeOnly && (flags & PF_X))
@@ -2184,7 +2187,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
bool isMain = partNo == 1;
// Add the first PT_LOAD segment for regular output sections.
- uint64_t flags = computeFlags(PF_R);
+ uint64_t flags = computeFlags(ctx, PF_R);
PhdrEntry *load = nullptr;
// nmagic or omagic output does not have PT_PHDR, PT_INTERP, or the readonly
@@ -2247,7 +2250,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
// partitions.
if (sec->partition != partNo) {
if (isMain && sec->partition == 255)
- addHdr(PT_LOAD, computeFlags(sec->getPhdrFlags()))->add(sec);
+ addHdr(PT_LOAD, computeFlags(ctx, sec->getPhdrFlags()))->add(sec);
continue;
}
@@ -2267,7 +2270,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
// supposed-to-be-NOBITS section to the output file. (However, we cannot do
// so when hasSectionsCommand, since we cannot introduce the extra alignment
// needed to create a new LOAD)
- uint64_t newFlags = computeFlags(sec->getPhdrFlags());
+ uint64_t newFlags = computeFlags(ctx, sec->getPhdrFlags());
// When --no-rosegment is specified, RO and RX sections are compatible.
uint32_t incompatible = flags ^ newFlags;
if (ctx.arg.singleRoRx && !(newFlags & PF_W))
diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h
index 7644b620bbffcd..bf4783cc52f6b9 100644
--- a/lld/ELF/Writer.h
+++ b/lld/ELF/Writer.h
@@ -16,7 +16,7 @@
namespace lld::elf {
class InputFile;
class OutputSection;
-void copySectionsIntoPartitions();
+void copySectionsIntoPartitions(Ctx &ctx);
template <class ELFT> void writeResult(Ctx &ctx);
// This describes a program header entry.
@@ -44,7 +44,7 @@ struct PhdrEntry {
uint64_t lmaOffset = 0;
};
-void addReservedSymbols();
+void addReservedSymbols(Ctx &ctx);
bool includeInSymtab(const Symbol &b);
unsigned getSectionRank(OutputSection &osec);
More information about the llvm-commits
mailing list