[lld] 1c28f31 - [ELF] Pass Ctx &
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 11 18:35:08 PDT 2024
Author: Fangrui Song
Date: 2024-10-11T18:35:02-07:00
New Revision: 1c28f3113377da218d67dc76aa0876b6250ceb6a
URL: https://github.com/llvm/llvm-project/commit/1c28f3113377da218d67dc76aa0876b6250ceb6a
DIFF: https://github.com/llvm/llvm-project/commit/1c28f3113377da218d67dc76aa0876b6250ceb6a.diff
LOG: [ELF] Pass Ctx &
Added:
Modified:
lld/ELF/Arch/AArch64.cpp
lld/ELF/CallGraphSort.cpp
lld/ELF/CallGraphSort.h
lld/ELF/Driver.cpp
lld/ELF/InputFiles.cpp
lld/ELF/InputSection.cpp
lld/ELF/MapFile.cpp
lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index f595504e621181..51d2f19c6f9296 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -1150,7 +1150,7 @@ addTaggedSymbolReferences(InputSectionBase &sec,
// symbols should also be built with tagging. But, to handle these cases, we
// demote the symbol to be untagged.
void elf::createTaggedSymbols(Ctx &ctx) {
- assert(hasMemtag());
+ assert(hasMemtag(ctx));
// First, collect all symbols that are marked as tagged, and count how many
// times they're marked as tagged.
diff --git a/lld/ELF/CallGraphSort.cpp b/lld/ELF/CallGraphSort.cpp
index e73fe12317bd76..537e065081f3fc 100644
--- a/lld/ELF/CallGraphSort.cpp
+++ b/lld/ELF/CallGraphSort.cpp
@@ -88,11 +88,12 @@ struct Cluster {
/// * Sort non-empty clusters by density
class CallGraphSort {
public:
- CallGraphSort();
+ CallGraphSort(Ctx &);
DenseMap<const InputSectionBase *, int> run();
private:
+ Ctx &ctx;
std::vector<Cluster> clusters;
std::vector<const InputSectionBase *> sections;
};
@@ -111,7 +112,7 @@ using SectionPair =
// Take the edge list in ctx.arg.callGraphProfile, resolve symbol names to
// Symbols, and generate a graph between InputSections with the provided
// weights.
-CallGraphSort::CallGraphSort() {
+CallGraphSort::CallGraphSort(Ctx &ctx) : ctx(ctx) {
MapVector<SectionPair, uint64_t> &profile = ctx.arg.callGraphProfile;
DenseMap<const InputSectionBase *, int> secToCluster;
@@ -274,7 +275,8 @@ DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
// Sort sections by the profile data using the Cache-Directed Sort algorithm.
// The placement is done by optimizing the locality by co-locating frequently
// executed code sections together.
-DenseMap<const InputSectionBase *, int> elf::computeCacheDirectedSortOrder() {
+DenseMap<const InputSectionBase *, int>
+elf::computeCacheDirectedSortOrder(Ctx &ctx) {
SmallVector<uint64_t, 0> funcSizes;
SmallVector<uint64_t, 0> funcCounts;
SmallVector<codelayout::EdgeCount, 0> callCounts;
@@ -336,8 +338,9 @@ DenseMap<const InputSectionBase *, int> elf::computeCacheDirectedSortOrder() {
//
// This first builds a call graph based on the profile data then merges sections
// according either to the C³ or Cache-Directed-Sort ordering algorithm.
-DenseMap<const InputSectionBase *, int> elf::computeCallGraphProfileOrder() {
+DenseMap<const InputSectionBase *, int>
+elf::computeCallGraphProfileOrder(Ctx &ctx) {
if (ctx.arg.callGraphProfileSort == CGProfileSortKind::Cdsort)
- return computeCacheDirectedSortOrder();
- return CallGraphSort().run();
+ return computeCacheDirectedSortOrder(ctx);
+ return CallGraphSort(ctx).run();
}
diff --git a/lld/ELF/CallGraphSort.h b/lld/ELF/CallGraphSort.h
index 1b54f2b6248228..5f9987ce097357 100644
--- a/lld/ELF/CallGraphSort.h
+++ b/lld/ELF/CallGraphSort.h
@@ -12,11 +12,14 @@
#include "llvm/ADT/DenseMap.h"
namespace lld::elf {
+struct Ctx;
class InputSectionBase;
-llvm::DenseMap<const InputSectionBase *, int> computeCacheDirectedSortOrder();
+llvm::DenseMap<const InputSectionBase *, int>
+computeCacheDirectedSortOrder(Ctx &);
-llvm::DenseMap<const InputSectionBase *, int> computeCallGraphProfileOrder();
+llvm::DenseMap<const InputSectionBase *, int>
+computeCallGraphProfileOrder(Ctx &);
} // namespace lld::elf
#endif
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 019388c9bd2e2c..504c09943f4658 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -155,8 +155,9 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
context->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
context->e.cleanupCallback = []() {
- elf::ctx.reset();
- elf::ctx.partitions.emplace_back();
+ Ctx &ctx = elf::ctx;
+ ctx.reset();
+ ctx.partitions.emplace_back(ctx);
SharedFile::vernauxNum = 0;
};
@@ -165,13 +166,14 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
"too many errors emitted, stopping now (use "
"--error-limit=0 to see all errors)";
+ Ctx &ctx = elf::ctx;
LinkerScript script(ctx);
ctx.script = &script;
ctx.symAux.emplace_back();
ctx.symtab = std::make_unique<SymbolTable>(ctx);
ctx.partitions.clear();
- ctx.partitions.emplace_back();
+ ctx.partitions.emplace_back(ctx);
ctx.arg.progName = args[0];
@@ -2495,7 +2497,7 @@ static void readSymbolPartitionSection(Ctx &ctx, InputSectionBase *s) {
if (ctx.partitions.size() == 254)
fatal("may not have more than 254 partitions");
- ctx.partitions.emplace_back();
+ ctx.partitions.emplace_back(ctx);
Partition &newPart = ctx.partitions.back();
newPart.name = partName;
sym->partition = newPart.getNumber();
@@ -3157,7 +3159,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// partition.
copySectionsIntoPartitions(ctx);
- if (canHaveMemtagGlobals()) {
+ if (canHaveMemtagGlobals(ctx)) {
llvm::TimeTraceScope timeScope("Process memory tagged symbols");
createTaggedSymbols(ctx);
}
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 39a78a65bd7cd6..a88fcd08d98c1b 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -649,7 +649,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
// medatada, and we don't want them to end up in the output file for static
// executables.
if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
- !canHaveMemtagGlobals()) {
+ !canHaveMemtagGlobals(ctx)) {
this->sections[i] = &InputSection::discarded;
continue;
}
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 082fdb9f5c9ac4..291b210c46b0b1 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -119,6 +119,7 @@ static void decompressAux(const InputSectionBase &sec, uint8_t *out,
}
void InputSectionBase::decompress() const {
+ Ctx &ctx = getCtx();
uint8_t *uncompressedBuf;
{
static std::mutex mu;
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 3495cdb0bc6663..6bbc1ecc646fdd 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -53,7 +53,7 @@ static void writeHeader(Ctx &ctx, raw_ostream &os, uint64_t vma, uint64_t lma,
}
// Returns a list of all symbols that we want to print out.
-static std::vector<Defined *> getSymbols() {
+static std::vector<Defined *> getSymbols(Ctx &ctx) {
std::vector<Defined *> v;
for (ELFFileBase *file : ctx.objectFiles)
for (Symbol *b : file->getSymbols())
@@ -148,7 +148,7 @@ static void printEhFrame(Ctx &ctx, raw_ostream &os, const EhFrameSection *sec) {
static void writeMapFile(Ctx &ctx, raw_fd_ostream &os) {
// Collect symbol info that we want to print out.
- std::vector<Defined *> syms = getSymbols();
+ std::vector<Defined *> syms = getSymbols(ctx);
SymbolMapTy sectionSyms = getSectionSyms(syms);
DenseMap<Symbol *, std::string> symStr = getSymbolStrings(ctx, syms);
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index ee0e9c513740ac..e35bc7a42b66e7 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -592,7 +592,7 @@ SmallVector<EhFrameSection::FdeData, 0> EhFrameSection::getFdeData() const {
return ret;
}
-static uint64_t readFdeAddr(uint8_t *buf, int size) {
+static uint64_t readFdeAddr(Ctx &ctx, uint8_t *buf, int size) {
switch (size) {
case DW_EH_PE_udata2:
return read16(buf);
@@ -619,7 +619,7 @@ uint64_t EhFrameSection::getFdePc(uint8_t *buf, size_t fdeOff,
// stored at FDE + 8 byte. And this offset is within
// the .eh_frame section.
size_t off = fdeOff + 8;
- uint64_t addr = readFdeAddr(buf + off, enc & 0xf);
+ uint64_t addr = readFdeAddr(ctx, buf + off, enc & 0xf);
if ((enc & 0x70) == DW_EH_PE_absptr)
return ctx.arg.is64 ? addr : uint32_t(addr);
if ((enc & 0x70) == DW_EH_PE_pcrel)
@@ -1478,7 +1478,7 @@ DynamicSection<ELFT>::computeContents() {
if (ctx.arg.zPacPlt)
addInt(DT_AARCH64_PAC_PLT, 0);
- if (hasMemtag()) {
+ if (hasMemtag(ctx)) {
addInt(DT_AARCH64_MEMTAG_MODE, ctx.arg.androidMemtagMode == NT_MEMTAG_LEVEL_ASYNC);
addInt(DT_AARCH64_MEMTAG_HEAP, ctx.arg.androidMemtagHeap);
addInt(DT_AARCH64_MEMTAG_STACK, ctx.arg.androidMemtagStack);
@@ -4359,7 +4359,7 @@ bool PPC64LongBranchTargetSection::isNeeded() const {
return !finalized || !entries.empty();
}
-static uint8_t getAbiVersion() {
+static uint8_t getAbiVersion(Ctx &ctx) {
// MIPS non-PIC executable gets ABI version 1.
if (ctx.arg.emachine == EM_MIPS) {
if (!ctx.arg.isPic && !ctx.arg.relocatable &&
@@ -4388,7 +4388,7 @@ template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) {
ELFT::Endianness == endianness::little ? ELFDATA2LSB : ELFDATA2MSB;
eHdr->e_ident[EI_VERSION] = EV_CURRENT;
eHdr->e_ident[EI_OSABI] = ctx.arg.osabi;
- eHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
+ eHdr->e_ident[EI_ABIVERSION] = getAbiVersion(ctx);
eHdr->e_machine = ctx.arg.emachine;
eHdr->e_version = EV_CURRENT;
eHdr->e_flags = ctx.arg.eflags;
@@ -4516,7 +4516,7 @@ static bool needsInterpSection(Ctx &ctx) {
!ctx.arg.dynamicLinker.empty() && ctx.script->needsInterpSection();
}
-bool elf::hasMemtag() {
+bool elf::hasMemtag(Ctx &ctx) {
return ctx.arg.emachine == EM_AARCH64 &&
ctx.arg.androidMemtagMode != ELF::NT_MEMTAG_LEVEL_NONE;
}
@@ -4527,8 +4527,8 @@ bool elf::hasMemtag() {
// - Dynamic entries.
// This restriction could be removed in future by re-using some of the ideas
// that ifuncs use in fully static executables.
-bool elf::canHaveMemtagGlobals() {
- return hasMemtag() &&
+bool elf::canHaveMemtagGlobals(Ctx &ctx) {
+ return hasMemtag(ctx) &&
(ctx.arg.relocatable || ctx.arg.shared || needsInterpSection(ctx));
}
@@ -4656,7 +4656,7 @@ static OutputSection *findSection(StringRef name) {
return nullptr;
}
-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())
@@ -4757,10 +4757,10 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
continue;
part.dynamic = std::make_unique<DynamicSection<ELFT>>(ctx);
- if (hasMemtag()) {
+ if (hasMemtag(ctx)) {
part.memtagAndroidNote = std::make_unique<MemtagAndroidNote>(ctx);
add(*part.memtagAndroidNote);
- if (canHaveMemtagGlobals()) {
+ if (canHaveMemtagGlobals(ctx)) {
part.memtagGlobalDescriptors =
std::make_unique<MemtagGlobalDescriptors>(ctx);
add(*part.memtagGlobalDescriptors);
@@ -4840,8 +4840,8 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
add(*ctx.in.partEnd);
ctx.in.partIndex = std::make_unique<PartitionIndexSection>(ctx);
- addOptionalRegular("__part_index_begin", ctx.in.partIndex.get(), 0);
- addOptionalRegular("__part_index_end", ctx.in.partIndex.get(),
+ addOptionalRegular(ctx, "__part_index_begin", ctx.in.partIndex.get(), 0);
+ addOptionalRegular(ctx, "__part_index_end", ctx.in.partIndex.get(),
ctx.in.partIndex->getSize());
add(*ctx.in.partIndex);
}
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 421ef760ef4a09..50ae06d6773936 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1433,8 +1433,8 @@ MergeInputSection *createCommentSection();
template <class ELFT> void splitSections(Ctx &);
void combineEhSections(Ctx &);
-bool hasMemtag();
-bool canHaveMemtagGlobals();
+bool hasMemtag(Ctx &);
+bool canHaveMemtagGlobals(Ctx &);
template <typename ELFT> void writeEhdr(uint8_t *buf, Partition &part);
template <typename ELFT> void writePhdrs(uint8_t *buf, Partition &part);
@@ -1446,6 +1446,7 @@ void addVerneed(Symbol *ss);
// Linker generated per-partition sections.
struct Partition {
+ Ctx &ctx;
StringRef name;
uint64_t nameStrTab;
@@ -1472,6 +1473,7 @@ struct Partition {
std::unique_ptr<SyntheticSection> verNeed;
std::unique_ptr<VersionTableSection> verSym;
+ Partition(Ctx &ctx) : ctx(ctx) {}
unsigned getNumber() const { return this - &ctx.partitions[0] + 1; }
};
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index f9a21b6745fdd1..bd34c5fa97269b 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1072,7 +1072,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder(Ctx &ctx) {
DenseMap<const InputSectionBase *, int> sectionOrder;
// Use the rarely used option --call-graph-ordering-file to sort sections.
if (!ctx.arg.callGraphProfile.empty())
- return computeCallGraphProfileOrder();
+ return computeCallGraphProfileOrder(ctx);
if (ctx.arg.symbolOrderingFile.empty())
return sectionOrder;
More information about the llvm-commits
mailing list