diff options
author | Fangrui Song <i@maskray.me> | 2024-10-11 18:35:02 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2024-10-11 18:35:02 -0700 |
commit | 1c28f3113377da218d67dc76aa0876b6250ceb6a (patch) | |
tree | 54a310b9bb92c4bf0be5cc0ff43c5a797f758ba2 | |
parent | 24ac6cf4f7fe0dd4358614066e6159130f7f11e7 (diff) | |
download | llvm-1c28f3113377da218d67dc76aa0876b6250ceb6a.zip llvm-1c28f3113377da218d67dc76aa0876b6250ceb6a.tar.gz llvm-1c28f3113377da218d67dc76aa0876b6250ceb6a.tar.bz2 |
[ELF] Pass Ctx &
-rw-r--r-- | lld/ELF/Arch/AArch64.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/CallGraphSort.cpp | 15 | ||||
-rw-r--r-- | lld/ELF/CallGraphSort.h | 7 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/InputFiles.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/InputSection.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/MapFile.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 26 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 6 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 2 |
10 files changed, 44 insertions, 33 deletions
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index f595504..51d2f19c 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 e73fe12..537e065 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 1b54f2b..5f9987c 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 019388c..504c099 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 39a78a6..a88fcd0 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 082fdb9..291b210 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 3495cdb..6bbc1ec 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 ee0e9c5..e35bc7a 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 421ef76..50ae06d 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 f9a21b6..bd34c5f 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; |