[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