[lld] [LLD][COFF] Store reference to SymbolTable instead of COFFLinkerContext in InputFile (NFC) (PR #119296)

Jacek Caban via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 15 03:41:41 PST 2024


https://github.com/cjacek updated https://github.com/llvm/llvm-project/pull/119296

>From f71f70def53f486d5bbd57bcd95a43bd045df9fa Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Tue, 3 Dec 2024 23:30:29 +0100
Subject: [PATCH] [LLD][COFF] Store reference to SymbolTable instead of
 COFFLinkerContext in InputFile (NFC)

This change prepares for the introduction of separate hybrid namespaces. Hybrid images will
require two SymbolTable instances, making it necessary to associate InputFile objects with
the relevant one.
---
 lld/COFF/Chunks.cpp      |  29 +++---
 lld/COFF/DLL.cpp         |   5 +-
 lld/COFF/Driver.cpp      |   2 +-
 lld/COFF/InputFiles.cpp  | 192 ++++++++++++++++++++-------------------
 lld/COFF/InputFiles.h    |  15 +--
 lld/COFF/PDB.cpp         |   2 +-
 lld/COFF/SymbolTable.cpp |   6 +-
 lld/COFF/SymbolTable.h   |   4 +-
 lld/COFF/Symbols.cpp     |   4 +-
 9 files changed, 135 insertions(+), 124 deletions(-)

diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index c3a8b2f91999bc..ec0fdf0b67b38b 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -56,7 +56,7 @@ SectionChunk::SectionChunk(ObjFile *f, const coff_section *h, Kind k)
   // files will be built with -ffunction-sections or /Gy, so most things worth
   // stripping will be in a comdat.
   if (file)
-    live = !file->ctx.config.doGC || !isCOMDAT();
+    live = !file->symtab.ctx.config.doGC || !isCOMDAT();
   else
     live = true;
 }
@@ -129,7 +129,7 @@ void SectionChunk::applyRelX64(uint8_t *off, uint16_t type, OutputSection *os,
   case IMAGE_REL_AMD64_REL32_4:  add32(off, s - p - 8); break;
   case IMAGE_REL_AMD64_REL32_5:  add32(off, s - p - 9); break;
   case IMAGE_REL_AMD64_SECTION:
-    applySecIdx(off, os, file->ctx.outputSections.size());
+    applySecIdx(off, os, file->symtab.ctx.outputSections.size());
     break;
   case IMAGE_REL_AMD64_SECREL:   applySecRel(this, off, os, s); break;
   default:
@@ -149,7 +149,7 @@ void SectionChunk::applyRelX86(uint8_t *off, uint16_t type, OutputSection *os,
   case IMAGE_REL_I386_DIR32NB:  add32(off, s); break;
   case IMAGE_REL_I386_REL32:    add32(off, s - p - 4); break;
   case IMAGE_REL_I386_SECTION:
-    applySecIdx(off, os, file->ctx.outputSections.size());
+    applySecIdx(off, os, file->symtab.ctx.outputSections.size());
     break;
   case IMAGE_REL_I386_SECREL:   applySecRel(this, off, os, s); break;
   default:
@@ -225,7 +225,7 @@ void SectionChunk::applyRelARM(uint8_t *off, uint16_t type, OutputSection *os,
   case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(off, sx - p - 4); break;
   case IMAGE_REL_ARM_BLX23T:    applyBranch24T(off, sx - p - 4); break;
   case IMAGE_REL_ARM_SECTION:
-    applySecIdx(off, os, file->ctx.outputSections.size());
+    applySecIdx(off, os, file->symtab.ctx.outputSections.size());
     break;
   case IMAGE_REL_ARM_SECREL:    applySecRel(this, off, os, s); break;
   case IMAGE_REL_ARM_REL32:     add32(off, sx - p - 4); break;
@@ -346,7 +346,7 @@ void SectionChunk::applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os,
   case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, off, os, s); break;
   case IMAGE_REL_ARM64_SECREL_LOW12L:  applySecRelLdr(this, off, os, s); break;
   case IMAGE_REL_ARM64_SECTION:
-    applySecIdx(off, os, file->ctx.outputSections.size());
+    applySecIdx(off, os, file->symtab.ctx.outputSections.size());
     break;
   case IMAGE_REL_ARM64_REL32:          add32(off, s - p - 4); break;
   default:
@@ -371,12 +371,12 @@ static void maybeReportRelocationToDiscarded(const SectionChunk *fromChunk,
   ObjFile *file = fromChunk->file;
   std::string name;
   if (sym) {
-    name = toString(file->ctx, *sym);
+    name = toString(file->symtab.ctx, *sym);
   } else {
     COFFSymbolRef coffSym =
         check(file->getCOFFObj()->getSymbol(rel.SymbolTableIndex));
     name = maybeDemangleSymbol(
-        file->ctx, check(file->getCOFFObj()->getSymbolName(coffSym)));
+        file->symtab.ctx, check(file->getCOFFObj()->getSymbolName(coffSym)));
   }
 
   std::vector<std::string> symbolLocations =
@@ -428,7 +428,8 @@ void SectionChunk::applyRelocation(uint8_t *off,
   // section is needed to compute SECREL and SECTION relocations used in debug
   // info.
   Chunk *c = sym ? sym->getChunk() : nullptr;
-  OutputSection *os = c ? file->ctx.getOutputSection(c) : nullptr;
+  COFFLinkerContext &ctx = file->symtab.ctx;
+  OutputSection *os = c ? ctx.getOutputSection(c) : nullptr;
 
   // Skip the relocation if it refers to a discarded section, and diagnose it
   // as an error if appropriate. If a symbol was discarded early, it may be
@@ -436,7 +437,7 @@ void SectionChunk::applyRelocation(uint8_t *off,
   // it was an absolute or synthetic symbol.
   if (!sym ||
       (!os && !isa<DefinedAbsolute>(sym) && !isa<DefinedSynthetic>(sym))) {
-    maybeReportRelocationToDiscarded(this, sym, rel, file->ctx.config.mingw);
+    maybeReportRelocationToDiscarded(this, sym, rel, ctx.config.mingw);
     return;
   }
 
@@ -444,7 +445,7 @@ void SectionChunk::applyRelocation(uint8_t *off,
 
   // Compute the RVA of the relocation for relative relocations.
   uint64_t p = rva + rel.VirtualAddress;
-  uint64_t imageBase = file->ctx.config.imageBase;
+  uint64_t imageBase = ctx.config.imageBase;
   switch (getArch()) {
   case Triple::x86_64:
     applyRelX64(off, rel.Type, os, s, p, imageBase);
@@ -670,7 +671,7 @@ void SectionChunk::getRuntimePseudoRelocs(
             toString(file));
       continue;
     }
-    int addressSizeInBits = file->ctx.config.is64() ? 64 : 32;
+    int addressSizeInBits = file->symtab.ctx.config.is64() ? 64 : 32;
     if (sizeInBits < addressSizeInBits) {
       warn("runtime pseudo relocation in " + toString(file) + " against " +
            "symbol " + target->getName() + " is too narrow (only " +
@@ -1099,7 +1100,7 @@ void CHPERedirectionChunk::writeTo(uint8_t *buf) const {
 }
 
 ImportThunkChunkARM64EC::ImportThunkChunkARM64EC(ImportFile *file)
-    : ImportThunkChunk(file->ctx, file->impSym), file(file) {}
+    : ImportThunkChunk(file->symtab.ctx, file->impSym), file(file) {}
 
 size_t ImportThunkChunkARM64EC::getSize() const {
   if (!extended)
@@ -1123,7 +1124,7 @@ void ImportThunkChunkARM64EC::writeTo(uint8_t *buf) const {
   applyArm64Addr(buf + 8, exitThunkRVA, rva + 8, 12);
   applyArm64Imm(buf + 12, exitThunkRVA & 0xfff, 0);
 
-  Defined *helper = cast<Defined>(file->ctx.config.arm64ECIcallHelper);
+  Defined *helper = cast<Defined>(file->symtab.ctx.config.arm64ECIcallHelper);
   if (extended) {
     // Replace last instruction with an inline range extension thunk.
     memcpy(buf + 16, arm64Thunk, sizeof(arm64Thunk));
@@ -1137,7 +1138,7 @@ void ImportThunkChunkARM64EC::writeTo(uint8_t *buf) const {
 bool ImportThunkChunkARM64EC::verifyRanges() {
   if (extended)
     return true;
-  auto helper = cast<Defined>(file->ctx.config.arm64ECIcallHelper);
+  auto helper = cast<Defined>(file->symtab.ctx.config.arm64ECIcallHelper);
   return isInt<28>(helper->getRVA() - rva - 16);
 }
 
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index 0f6a40a41ca00f..3d6ed5a9ddeae9 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -160,13 +160,14 @@ class AuxImportChunk : public NonSectionChunk {
   void writeTo(uint8_t *buf) const override {
     uint64_t impchkVA = 0;
     if (file->impchkThunk)
-      impchkVA = file->impchkThunk->getRVA() + file->ctx.config.imageBase;
+      impchkVA =
+          file->impchkThunk->getRVA() + file->symtab.ctx.config.imageBase;
     write64le(buf, impchkVA);
   }
 
   void getBaserels(std::vector<Baserel> *res) override {
     if (file->impchkThunk)
-      res->emplace_back(rva, file->ctx.config.machine);
+      res->emplace_back(rva, file->symtab.ctx.config.machine);
   }
 
 private:
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 714de67e88b065..b47b3ffec0a908 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -241,7 +241,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
     break;
   case file_magic::pecoff_executable:
     if (ctx.config.mingw) {
-      ctx.symtab.addFile(make<DLLFile>(ctx, mbref));
+      ctx.symtab.addFile(make<DLLFile>(ctx.symtab, mbref));
       break;
     }
     if (filename.ends_with_insensitive(".dll")) {
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index f32bc5bbbc35f1..42c1a9aa90a0f8 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -78,7 +78,7 @@ const COFFSyncStream &coff::operator<<(const COFFSyncStream &s,
 /// Checks that Source is compatible with being a weak alias to Target.
 /// If Source is Undefined and has no weak alias set, makes it a weak
 /// alias to Target.
-static void checkAndSetWeakAlias(COFFLinkerContext &ctx, InputFile *f,
+static void checkAndSetWeakAlias(SymbolTable &symtab, InputFile *f,
                                  Symbol *source, Symbol *target,
                                  bool isAntiDep) {
   if (auto *u = dyn_cast<Undefined>(source)) {
@@ -92,9 +92,9 @@ static void checkAndSetWeakAlias(COFFLinkerContext &ctx, InputFile *f,
         // of another symbol emitted near the weak symbol.
         // Just use the definition from the first object file that defined
         // this weak symbol.
-        if (ctx.config.allowDuplicateWeak)
+        if (symtab.ctx.config.allowDuplicateWeak)
           return;
-        ctx.symtab.reportDuplicate(source, f);
+        symtab.reportDuplicate(source, f);
       }
     }
     u->setWeakAlias(target, isAntiDep);
@@ -106,9 +106,10 @@ static bool ignoredSymbolName(StringRef name) {
 }
 
 ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)
-    : InputFile(ctx, ArchiveKind, m) {}
+    : InputFile(ctx.symtab, ArchiveKind, m) {}
 
 void ArchiveFile::parse() {
+  COFFLinkerContext &ctx = symtab.ctx;
   // Parse a MemoryBufferRef as an archive file.
   file = CHECK(Archive::create(mb), this);
 
@@ -134,14 +135,14 @@ void ArchiveFile::parse() {
 // Returns a buffer pointing to a member file containing a given symbol.
 void ArchiveFile::addMember(const Archive::Symbol &sym) {
   const Archive::Child &c =
-      CHECK(sym.getMember(),
-            "could not get the member for symbol " + toCOFFString(ctx, sym));
+      CHECK(sym.getMember(), "could not get the member for symbol " +
+                                 toCOFFString(symtab.ctx, sym));
 
   // Return an empty buffer if we have already returned the same buffer.
   if (!seen.insert(c.getChildOffset()).second)
     return;
 
-  ctx.driver.enqueueArchiveMember(c, sym, getName());
+  symtab.ctx.driver.enqueueArchiveMember(c, sym, getName());
 }
 
 std::vector<MemoryBufferRef>
@@ -161,6 +162,9 @@ lld::coff::getArchiveMembers(COFFLinkerContext &ctx, Archive *file) {
   return v;
 }
 
+ObjFile::ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy)
+    : InputFile(ctx.symtab, ObjectKind, m, lazy) {}
+
 void ObjFile::parseLazy() {
   // Native object file.
   std::unique_ptr<Binary> coffObjPtr = CHECK(createBinary(mb), this);
@@ -174,7 +178,7 @@ void ObjFile::parseLazy() {
     StringRef name = check(coffObj->getSymbolName(coffSym));
     if (coffSym.isAbsolute() && ignoredSymbolName(name))
       continue;
-    ctx.symtab.addLazyObject(this, name);
+    symtab.addLazyObject(this, name);
     i += coffSym.getNumberOfAuxSymbols();
   }
 }
@@ -188,7 +192,8 @@ struct ECMapEntry {
 void ObjFile::initializeECThunks() {
   for (SectionChunk *chunk : hybmpChunks) {
     if (chunk->getContents().size() % sizeof(ECMapEntry)) {
-      Err(ctx) << "Invalid .hybmp chunk size " << chunk->getContents().size();
+      Err(symtab.ctx) << "Invalid .hybmp chunk size "
+                      << chunk->getContents().size();
       continue;
     }
 
@@ -199,15 +204,15 @@ void ObjFile::initializeECThunks() {
       auto entry = reinterpret_cast<const ECMapEntry *>(iter);
       switch (entry->type) {
       case Arm64ECThunkType::Entry:
-        ctx.symtab.addEntryThunk(getSymbol(entry->src), getSymbol(entry->dst));
+        symtab.addEntryThunk(getSymbol(entry->src), getSymbol(entry->dst));
         break;
       case Arm64ECThunkType::Exit:
-        ctx.symtab.addExitThunk(getSymbol(entry->src), getSymbol(entry->dst));
+        symtab.addExitThunk(getSymbol(entry->src), getSymbol(entry->dst));
         break;
       case Arm64ECThunkType::GuestExit:
         break;
       default:
-        Warn(ctx) << "Ignoring unknown EC thunk type " << entry->type;
+        Warn(symtab.ctx) << "Ignoring unknown EC thunk type " << entry->type;
       }
     }
   }
@@ -221,7 +226,7 @@ void ObjFile::parse() {
     bin.release();
     coffObj.reset(obj);
   } else {
-    Fatal(ctx) << toString(this) << " is not a COFF file";
+    Fatal(symtab.ctx) << toString(this) << " is not a COFF file";
   }
 
   // Read section and symbol tables.
@@ -235,7 +240,7 @@ void ObjFile::parse() {
 const coff_section *ObjFile::getSection(uint32_t i) {
   auto sec = coffObj->getSection(i);
   if (!sec)
-    Fatal(ctx) << "getSection failed: #" << i << ": " << sec.takeError();
+    Fatal(symtab.ctx) << "getSection failed: #" << i << ": " << sec.takeError();
   return *sec;
 }
 
@@ -268,8 +273,8 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
   if (Expected<StringRef> e = coffObj->getSectionName(sec))
     name = *e;
   else
-    Fatal(ctx) << "getSectionName failed: #" << sectionNumber << ": "
-               << e.takeError();
+    Fatal(symtab.ctx) << "getSectionName failed: #" << sectionNumber << ": "
+                      << e.takeError();
 
   if (name == ".drectve") {
     ArrayRef<uint8_t> data;
@@ -299,7 +304,7 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
   // and then write it to a separate .pdb file.
 
   // Ignore DWARF debug info unless requested to be included.
-  if (!ctx.config.includeDwarfChunks && name.starts_with(".debug_"))
+  if (!symtab.ctx.config.includeDwarfChunks && name.starts_with(".debug_"))
     return nullptr;
 
   if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
@@ -328,12 +333,12 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
     sxDataChunks.push_back(c);
   else if (isArm64EC(getMachineType()) && name == ".hybmp$x")
     hybmpChunks.push_back(c);
-  else if (ctx.config.tailMerge && sec->NumberOfRelocations == 0 &&
+  else if (symtab.ctx.config.tailMerge && sec->NumberOfRelocations == 0 &&
            name == ".rdata" && leaderName.starts_with("??_C@"))
     // COFF sections that look like string literal sections (i.e. no
     // relocations, in .rdata, leader symbol name matches the MSVC name mangling
     // for string literals) are subject to string tail merging.
-    MergeChunk::addSection(ctx, c);
+    MergeChunk::addSection(symtab.ctx, c);
   else if (name == ".rsrc" || name.starts_with(".rsrc$"))
     resourceChunks.push_back(c);
   else
@@ -364,9 +369,10 @@ void ObjFile::readAssociativeDefinition(COFFSymbolRef sym,
     const coff_section *parentSec = getSection(parentIndex);
     if (Expected<StringRef> e = coffObj->getSectionName(parentSec))
       parentName = *e;
-    Err(ctx) << toString(this) << ": associative comdat " << name << " (sec "
-             << sectionNumber << ") has invalid reference to section "
-             << parentName << " (sec " << parentIndex << ")";
+    Err(symtab.ctx) << toString(this) << ": associative comdat " << name
+                    << " (sec " << sectionNumber
+                    << ") has invalid reference to section " << parentName
+                    << " (sec " << parentIndex << ")";
   };
 
   if (parent == pendingComdat) {
@@ -427,16 +433,16 @@ Symbol *ObjFile::createRegular(COFFSymbolRef sym) {
   if (sym.isExternal()) {
     StringRef name = check(coffObj->getSymbolName(sym));
     if (sc)
-      return ctx.symtab.addRegular(this, name, sym.getGeneric(), sc,
-                                   sym.getValue());
+      return symtab.addRegular(this, name, sym.getGeneric(), sc,
+                               sym.getValue());
     // For MinGW symbols named .weak.* that point to a discarded section,
     // don't create an Undefined symbol. If nothing ever refers to the symbol,
     // everything should be fine. If something actually refers to the symbol
     // (e.g. the undefined weak alias), linking will fail due to undefined
     // references at the end.
-    if (ctx.config.mingw && name.starts_with(".weak."))
+    if (symtab.ctx.config.mingw && name.starts_with(".weak."))
       return nullptr;
-    return ctx.symtab.addUndefined(name, this, false);
+    return symtab.addUndefined(name, this, false);
   }
   if (sc)
     return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
@@ -456,6 +462,7 @@ void ObjFile::initializeSymbols() {
   DenseMap<StringRef, uint32_t> prevailingSectionMap;
   std::vector<const coff_aux_section_definition *> comdatDefs(
       coffObj->getNumberOfSections() + 1);
+  COFFLinkerContext &ctx = symtab.ctx;
 
   for (uint32_t i = 0; i < numSymbols; ++i) {
     COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
@@ -529,7 +536,7 @@ void ObjFile::initializeSymbols() {
   for (auto &kv : weakAliases) {
     Symbol *sym = kv.first;
     const coff_aux_weak_external *aux = kv.second;
-    checkAndSetWeakAlias(ctx, this, sym, symbols[aux->TagIndex],
+    checkAndSetWeakAlias(symtab, this, sym, symbols[aux->TagIndex],
                          aux->Characteristics ==
                              IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY);
   }
@@ -540,17 +547,17 @@ void ObjFile::initializeSymbols() {
 
 Symbol *ObjFile::createUndefined(COFFSymbolRef sym, bool overrideLazy) {
   StringRef name = check(coffObj->getSymbolName(sym));
-  Symbol *s = ctx.symtab.addUndefined(name, this, overrideLazy);
+  Symbol *s = symtab.addUndefined(name, this, overrideLazy);
 
   // Add an anti-dependency alias for undefined AMD64 symbols on the ARM64EC
   // target.
-  if (isArm64EC(ctx.config.machine) && getMachineType() == AMD64) {
+  if (isArm64EC(symtab.ctx.config.machine) && getMachineType() == AMD64) {
     auto u = dyn_cast<Undefined>(s);
     if (u && !u->weakAlias) {
       if (std::optional<std::string> mangledName =
               getArm64ECMangledFunctionName(name)) {
-        Symbol *m = ctx.symtab.addUndefined(saver().save(*mangledName), this,
-                                            /*overrideLazy=*/false);
+        Symbol *m = symtab.addUndefined(saver().save(*mangledName), this,
+                                        /*overrideLazy=*/false);
         u->setWeakAlias(m, /*antiDep=*/true);
       }
     }
@@ -584,6 +591,7 @@ void ObjFile::handleComdatSelection(
 
   SectionChunk *leaderChunk = leader->getChunk();
   COMDATType leaderSelection = leaderChunk->selection;
+  COFFLinkerContext &ctx = symtab.ctx;
 
   assert(leader->data && "Comdat leader without SectionChunk?");
   if (isa<BitcodeFile>(leader->file)) {
@@ -624,13 +632,13 @@ void ObjFile::handleComdatSelection(
     Log(ctx) << "conflicting comdat type for " << leader << ": "
              << (int)leaderSelection << " in " << leader->getFile() << " and "
              << (int)selection << " in " << this;
-    ctx.symtab.reportDuplicate(leader, this);
+    symtab.reportDuplicate(leader, this);
     return;
   }
 
   switch (selection) {
   case IMAGE_COMDAT_SELECT_NODUPLICATES:
-    ctx.symtab.reportDuplicate(leader, this);
+    symtab.reportDuplicate(leader, this);
     break;
 
   case IMAGE_COMDAT_SELECT_ANY:
@@ -640,14 +648,14 @@ void ObjFile::handleComdatSelection(
   case IMAGE_COMDAT_SELECT_SAME_SIZE:
     if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) {
       if (!ctx.config.mingw) {
-        ctx.symtab.reportDuplicate(leader, this);
+        symtab.reportDuplicate(leader, this);
       } else {
         const coff_aux_section_definition *leaderDef = nullptr;
         if (leaderChunk->file)
           leaderDef = findSectionDef(leaderChunk->file->getCOFFObj(),
                                      leaderChunk->getSectionNumber());
         if (!leaderDef || leaderDef->Length != def->Length)
-          ctx.symtab.reportDuplicate(leader, this);
+          symtab.reportDuplicate(leader, this);
       }
     }
     break;
@@ -658,7 +666,7 @@ void ObjFile::handleComdatSelection(
     // if the two comdat sections have e.g. different alignment.
     // Match that.
     if (leaderChunk->getContents() != newChunk.getContents())
-      ctx.symtab.reportDuplicate(leader, this, &newChunk, sym.getValue());
+      symtab.reportDuplicate(leader, this, &newChunk, sym.getValue());
     break;
   }
 
@@ -701,10 +709,11 @@ std::optional<Symbol *> ObjFile::createDefined(
   if (sym.isCommon()) {
     auto *c = make<CommonChunk>(sym);
     chunks.push_back(c);
-    return ctx.symtab.addCommon(this, getName(), sym.getValue(),
-                                sym.getGeneric(), c);
+    return symtab.addCommon(this, getName(), sym.getValue(), sym.getGeneric(),
+                            c);
   }
 
+  COFFLinkerContext &ctx = symtab.ctx;
   if (sym.isAbsolute()) {
     StringRef name = getName();
 
@@ -715,7 +724,7 @@ std::optional<Symbol *> ObjFile::createDefined(
       return nullptr;
 
     if (sym.isExternal())
-      return ctx.symtab.addAbsolute(name, sym);
+      return symtab.addAbsolute(name, sym);
     return make<DefinedAbsolute>(ctx, name, sym);
   }
 
@@ -750,7 +759,7 @@ std::optional<Symbol *> ObjFile::createDefined(
 
     if (sym.isExternal()) {
       std::tie(leader, prevailing) =
-          ctx.symtab.addComdat(this, getName(), sym.getGeneric());
+          symtab.addComdat(this, getName(), sym.getGeneric());
     } else {
       leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
                                     /*IsExternal*/ false, sym.getGeneric());
@@ -865,6 +874,7 @@ void ObjFile::initializeFlags() {
 // DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular
 // output even with /Yc and /Yu and with /Zi.
 void ObjFile::initializeDependencies() {
+  COFFLinkerContext &ctx = symtab.ctx;
   if (!ctx.config.debug)
     return;
 
@@ -975,7 +985,7 @@ findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputPath) {
 }
 
 PDBInputFile::PDBInputFile(COFFLinkerContext &ctx, MemoryBufferRef m)
-    : InputFile(ctx, PDBKind, m) {}
+    : InputFile(ctx.symtab, PDBKind, m) {}
 
 PDBInputFile::~PDBInputFile() = default;
 
@@ -992,7 +1002,7 @@ PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,
 }
 
 void PDBInputFile::parse() {
-  ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this;
+  symtab.ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this;
 
   std::unique_ptr<pdb::IPDBSession> thisSession;
   Error E = pdb::NativeSession::createFromPdb(
@@ -1012,7 +1022,7 @@ void PDBInputFile::parse() {
     loadErrorStr.emplace(toString(expectedInfo.takeError()));
     return;
   }
-  debugTypesObj = makeTypeServerSource(ctx, this);
+  debugTypesObj = makeTypeServerSource(symtab.ctx, this);
 }
 
 // Used only for DWARF debug info, which is not common (except in MinGW
@@ -1025,7 +1035,7 @@ ObjFile::getVariableLocation(StringRef var) {
     if (!dwarf)
       return std::nullopt;
   }
-  if (ctx.config.machine == I386)
+  if (symtab.ctx.config.machine == I386)
     var.consume_front("_");
   std::optional<std::pair<std::string, unsigned>> ret =
       dwarf->getVariableLoc(var);
@@ -1048,17 +1058,17 @@ std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,
 }
 
 void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
-  auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
+  auto p = findPdbPath(path.str(), fromFile, symtab.ctx.config.outputFile);
   if (!p)
     return;
-  auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr);
+  auto it = symtab.ctx.pdbInputFileInstances.emplace(*p, nullptr);
   if (!it.second)
     return; // already scheduled for load
-  ctx.driver.enqueuePDB(*p);
+  symtab.ctx.driver.enqueuePDB(*p);
 }
 
 ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)
-    : InputFile(ctx, ImportKind, m), live(!ctx.config.doGC) {}
+    : InputFile(ctx.symtab, ImportKind, m), live(!ctx.config.doGC) {}
 
 MachineTypes ImportFile::getMachineType() const {
   uint16_t machine =
@@ -1070,13 +1080,13 @@ MachineTypes ImportFile::getMachineType() const {
 ImportThunkChunk *ImportFile::makeImportThunk() {
   switch (hdr->Machine) {
   case AMD64:
-    return make<ImportThunkChunkX64>(ctx, impSym);
+    return make<ImportThunkChunkX64>(symtab.ctx, impSym);
   case I386:
-    return make<ImportThunkChunkX86>(ctx, impSym);
+    return make<ImportThunkChunkX86>(symtab.ctx, impSym);
   case ARM64:
-    return make<ImportThunkChunkARM64>(ctx, impSym, ARM64);
+    return make<ImportThunkChunkARM64>(symtab.ctx, impSym, ARM64);
   case ARMNT:
-    return make<ImportThunkChunkARM>(ctx, impSym);
+    return make<ImportThunkChunkARM>(symtab.ctx, impSym);
   }
   llvm_unreachable("unknown machine type");
 }
@@ -1088,7 +1098,7 @@ void ImportFile::parse() {
   // Check if the total size is valid.
   if (mb.getBufferSize() < sizeof(*hdr) ||
       mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)
-    Fatal(ctx) << "broken import library";
+    Fatal(symtab.ctx) << "broken import library";
 
   // Read names and create an __imp_ symbol.
   StringRef buf = mb.getBuffer().substr(sizeof(*hdr));
@@ -1129,8 +1139,8 @@ void ImportFile::parse() {
 
   bool isCode = hdr->getType() == llvm::COFF::IMPORT_CODE;
 
-  if (ctx.config.machine != ARM64EC) {
-    impSym = ctx.symtab.addImportData(impName, this, location);
+  if (symtab.ctx.config.machine != ARM64EC) {
+    impSym = symtab.addImportData(impName, this, location);
   } else {
     // In addition to the regular IAT, ARM64EC also contains an auxiliary IAT,
     // which holds addresses that are guaranteed to be callable directly from
@@ -1139,18 +1149,17 @@ void ImportFile::parse() {
     // data imports, the naming is reversed.
     StringRef auxImpName = saver().save("__imp_aux_" + name);
     if (isCode) {
-      impSym = ctx.symtab.addImportData(auxImpName, this, location);
-      impECSym = ctx.symtab.addImportData(impName, this, auxLocation);
+      impSym = symtab.addImportData(auxImpName, this, location);
+      impECSym = symtab.addImportData(impName, this, auxLocation);
     } else {
-      impSym = ctx.symtab.addImportData(impName, this, location);
-      impECSym = ctx.symtab.addImportData(auxImpName, this, auxLocation);
+      impSym = symtab.addImportData(impName, this, location);
+      impECSym = symtab.addImportData(auxImpName, this, auxLocation);
     }
     if (!impECSym)
       return;
 
     StringRef auxImpCopyName = saver().save("__auximpcopy_" + name);
-    auxImpCopySym =
-        ctx.symtab.addImportData(auxImpCopyName, this, auxCopyLocation);
+    auxImpCopySym = symtab.addImportData(auxImpCopyName, this, auxCopyLocation);
     if (!auxImpCopySym)
       return;
   }
@@ -1160,31 +1169,30 @@ void ImportFile::parse() {
     return;
 
   if (hdr->getType() == llvm::COFF::IMPORT_CONST)
-    static_cast<void>(ctx.symtab.addImportData(name, this, location));
+    static_cast<void>(symtab.addImportData(name, this, location));
 
   // If type is function, we need to create a thunk which jump to an
   // address pointed by the __imp_ symbol. (This allows you to call
   // DLL functions just like regular non-DLL functions.)
   if (isCode) {
-    if (ctx.config.machine != ARM64EC) {
-      thunkSym = ctx.symtab.addImportThunk(name, impSym, makeImportThunk());
+    if (symtab.ctx.config.machine != ARM64EC) {
+      thunkSym = symtab.addImportThunk(name, impSym, makeImportThunk());
     } else {
-      thunkSym = ctx.symtab.addImportThunk(
-          name, impSym, make<ImportThunkChunkX64>(ctx, impSym));
+      thunkSym = symtab.addImportThunk(
+          name, impSym, make<ImportThunkChunkX64>(symtab.ctx, impSym));
 
       if (std::optional<std::string> mangledName =
               getArm64ECMangledFunctionName(name)) {
         StringRef auxThunkName = saver().save(*mangledName);
-        auxThunkSym = ctx.symtab.addImportThunk(
+        auxThunkSym = symtab.addImportThunk(
             auxThunkName, impECSym,
-            make<ImportThunkChunkARM64>(ctx, impECSym, ARM64EC));
+            make<ImportThunkChunkARM64>(symtab.ctx, impECSym, ARM64EC));
       }
 
       StringRef impChkName = saver().save("__impchk_" + name);
       impchkThunk = make<ImportThunkChunkARM64EC>(this);
-      impchkThunk->sym =
-          ctx.symtab.addImportThunk(impChkName, impSym, impchkThunk);
-      ctx.driver.pullArm64ECIcallHelper();
+      impchkThunk->sym = symtab.addImportThunk(impChkName, impSym, impchkThunk);
+      symtab.ctx.driver.pullArm64ECIcallHelper();
     }
   }
 }
@@ -1192,7 +1200,7 @@ void ImportFile::parse() {
 BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
                          StringRef archiveName, uint64_t offsetInArchive,
                          bool lazy)
-    : InputFile(ctx, BitcodeKind, mb, lazy) {
+    : InputFile(ctx.symtab, BitcodeKind, mb, lazy) {
   std::string path = mb.getBufferIdentifier().str();
   if (ctx.config.thinLTOIndexOnly)
     path = replaceThinLTOSuffix(mb.getBufferIdentifier(),
@@ -1224,18 +1232,18 @@ void BitcodeFile::parse() {
   for (size_t i = 0; i != obj->getComdatTable().size(); ++i)
     // FIXME: Check nodeduplicate
     comdat[i] =
-        ctx.symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first));
+        symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first));
   for (const lto::InputFile::Symbol &objSym : obj->symbols()) {
     StringRef symName = saver.save(objSym.getName());
     int comdatIndex = objSym.getComdatIndex();
     Symbol *sym;
     SectionChunk *fakeSC = nullptr;
     if (objSym.isExecutable())
-      fakeSC = &ctx.ltoTextSectionChunk.chunk;
+      fakeSC = &symtab.ctx.ltoTextSectionChunk.chunk;
     else
-      fakeSC = &ctx.ltoDataSectionChunk.chunk;
+      fakeSC = &symtab.ctx.ltoDataSectionChunk.chunk;
     if (objSym.isUndefined()) {
-      sym = ctx.symtab.addUndefined(symName, this, false);
+      sym = symtab.addUndefined(symName, this, false);
       if (objSym.isWeak())
         sym->deferUndefined = true;
       // If one LTO object file references (i.e. has an undefined reference to)
@@ -1252,30 +1260,30 @@ void BitcodeFile::parse() {
       if (symName.starts_with("__imp_"))
         sym->isUsedInRegularObj = true;
     } else if (objSym.isCommon()) {
-      sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize());
+      sym = symtab.addCommon(this, symName, objSym.getCommonSize());
     } else if (objSym.isWeak() && objSym.isIndirect()) {
       // Weak external.
-      sym = ctx.symtab.addUndefined(symName, this, true);
+      sym = symtab.addUndefined(symName, this, true);
       std::string fallback = std::string(objSym.getCOFFWeakExternalFallback());
-      Symbol *alias = ctx.symtab.addUndefined(saver.save(fallback));
-      checkAndSetWeakAlias(ctx, this, sym, alias, false);
+      Symbol *alias = symtab.addUndefined(saver.save(fallback));
+      checkAndSetWeakAlias(symtab, this, sym, alias, false);
     } else if (comdatIndex != -1) {
       if (symName == obj->getComdatTable()[comdatIndex].first) {
         sym = comdat[comdatIndex].first;
         if (cast<DefinedRegular>(sym)->data == nullptr)
           cast<DefinedRegular>(sym)->data = &fakeSC->repl;
       } else if (comdat[comdatIndex].second) {
-        sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC);
+        sym = symtab.addRegular(this, symName, nullptr, fakeSC);
       } else {
-        sym = ctx.symtab.addUndefined(symName, this, false);
+        sym = symtab.addUndefined(symName, this, false);
       }
     } else {
-      sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC, 0,
-                                  objSym.isWeak());
+      sym =
+          symtab.addRegular(this, symName, nullptr, fakeSC, 0, objSym.isWeak());
     }
     symbols.push_back(sym);
     if (objSym.isUsed())
-      ctx.config.gcroot.push_back(sym);
+      symtab.ctx.config.gcroot.push_back(sym);
   }
   directives = saver.save(obj->getCOFFLinkerOpts());
 }
@@ -1283,7 +1291,7 @@ void BitcodeFile::parse() {
 void BitcodeFile::parseLazy() {
   for (const lto::InputFile::Symbol &sym : obj->symbols())
     if (!sym.isUndefined())
-      ctx.symtab.addLazyObject(this, sym.getName());
+      symtab.addLazyObject(this, sym.getName());
 }
 
 MachineTypes BitcodeFile::getMachineType() const {
@@ -1329,12 +1337,12 @@ void DLLFile::parse() {
     bin.release();
     coffObj.reset(obj);
   } else {
-    Err(ctx) << toString(this) << " is not a COFF file";
+    Err(symtab.ctx) << toString(this) << " is not a COFF file";
     return;
   }
 
   if (!coffObj->getPE32Header() && !coffObj->getPE32PlusHeader()) {
-    Err(ctx) << toString(this) << " is not a PE-COFF executable";
+    Err(symtab.ctx) << toString(this) << " is not a PE-COFF executable";
     return;
   }
 
@@ -1362,9 +1370,9 @@ void DLLFile::parse() {
     }
 
     StringRef impName = saver().save("__imp_" + symbolName);
-    ctx.symtab.addLazyDLLSymbol(this, s, impName);
+    symtab.addLazyDLLSymbol(this, s, impName);
     if (code)
-      ctx.symtab.addLazyDLLSymbol(this, s, symbolName);
+      symtab.addLazyDLLSymbol(this, s, symbolName);
   }
 }
 
@@ -1396,6 +1404,6 @@ void DLLFile::makeImport(DLLFile::Symbol *s) {
   p += s->symbolName.size() + 1;
   memcpy(p, s->dllName.data(), s->dllName.size());
   MemoryBufferRef mbref = MemoryBufferRef(StringRef(buf, size), s->dllName);
-  ImportFile *impFile = make<ImportFile>(ctx, mbref);
-  ctx.symtab.addFile(impFile);
+  ImportFile *impFile = make<ImportFile>(symtab.ctx, mbref);
+  symtab.addFile(impFile);
 }
diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
index 3c48e778ac5b5d..fd2e409ada30f4 100644
--- a/lld/COFF/InputFiles.h
+++ b/lld/COFF/InputFiles.h
@@ -62,6 +62,7 @@ class ImportThunkChunk;
 class ImportThunkChunkARM64EC;
 class SectionChunk;
 class Symbol;
+class SymbolTable;
 class Undefined;
 class TpiSource;
 
@@ -99,11 +100,11 @@ class InputFile {
   // Returns .drectve section contents if exist.
   StringRef getDirectives() { return directives; }
 
-  COFFLinkerContext &ctx;
+  SymbolTable &symtab;
 
 protected:
-  InputFile(COFFLinkerContext &c, Kind k, MemoryBufferRef m, bool lazy = false)
-      : mb(m), ctx(c), fileKind(k), lazy(lazy) {}
+  InputFile(SymbolTable &s, Kind k, MemoryBufferRef m, bool lazy = false)
+      : mb(m), symtab(s), fileKind(k), lazy(lazy) {}
 
   StringRef directives;
 
@@ -135,8 +136,8 @@ class ArchiveFile : public InputFile {
 // .obj or .o file. This may be a member of an archive file.
 class ObjFile : public InputFile {
 public:
-  explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy = false)
-      : InputFile(ctx, ObjectKind, m, lazy) {}
+  explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m,
+                   bool lazy = false);
   static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
   void parse() override;
   void parseLazy();
@@ -403,8 +404,8 @@ class BitcodeFile : public InputFile {
 // .dll file. MinGW only.
 class DLLFile : public InputFile {
 public:
-  explicit DLLFile(COFFLinkerContext &ctx, MemoryBufferRef m)
-      : InputFile(ctx, DLLKind, m) {}
+  explicit DLLFile(SymbolTable &symtab, MemoryBufferRef m)
+      : InputFile(symtab, DLLKind, m) {}
   static bool classof(const InputFile *f) { return f->kind() == DLLKind; }
   void parse() override;
   MachineTypes getMachineType() const override;
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 6dcab906b35bf7..21475033b0ae84 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1012,7 +1012,7 @@ static void warnUnusable(InputFile *f, Error e, bool shouldWarn) {
     consumeError(std::move(e));
     return;
   }
-  auto diag = Warn(f->ctx);
+  auto diag = Warn(f->symtab.ctx);
   diag << "Cannot use debug info for '" << f << "' [LNK4099]";
   if (e)
     diag << "\n>>> failed to load reference " << std::move(e);
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 26ace0e75c4931..942e7ceda1ebe3 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -117,7 +117,7 @@ static void forceLazy(Symbol *s) {
   }
   case Symbol::Kind::LazyObjectKind: {
     InputFile *file = cast<LazyObject>(s)->file;
-    file->ctx.symtab.addFile(file);
+    file->symtab.ctx.symtab.addFile(file);
     break;
   }
   case Symbol::Kind::LazyDLLSymbolKind: {
@@ -177,7 +177,7 @@ getFileLine(const SectionChunk *c, uint32_t addr) {
   std::optional<std::pair<StringRef, uint32_t>> fileLine =
       getFileLineCodeView(c, addr);
   // If codeview didn't yield any result, check dwarf in MinGW mode.
-  if (!fileLine && c->file->ctx.config.mingw)
+  if (!fileLine && c->file->symtab.ctx.config.mingw)
     fileLine = getFileLineDwarf(c, addr);
   return fileLine;
 }
@@ -235,7 +235,7 @@ getSymbolLocations(ObjFile *file, uint32_t symIndex, size_t maxStrings) {
          << "\n>>>               ";
     os << toString(file);
     if (loc.sym)
-      os << ":(" << toString(file->ctx, *loc.sym) << ')';
+      os << ":(" << toString(file->symtab.ctx, *loc.sym) << ')';
   }
   return std::make_pair(symbolLocations, numLocations);
 }
diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h
index 1d9e908b8b9918..92e94671ce8130 100644
--- a/lld/COFF/SymbolTable.h
+++ b/lld/COFF/SymbolTable.h
@@ -119,6 +119,8 @@ class SymbolTable {
                        SectionChunk *newSc = nullptr,
                        uint32_t newSectionOffset = 0);
 
+  COFFLinkerContext &ctx;
+
   // A list of chunks which to be added to .rdata.
   std::vector<Chunk *> localImportChunks;
 
@@ -147,8 +149,6 @@ class SymbolTable {
   bool ltoCompilationDone = false;
   std::vector<std::pair<Symbol *, Symbol *>> entryThunks;
   llvm::DenseMap<Symbol *, Symbol *> exitThunks;
-
-  COFFLinkerContext &ctx;
 };
 
 std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex);
diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp
index 35c421d599ff55..148822fdb68ffa 100644
--- a/lld/COFF/Symbols.cpp
+++ b/lld/COFF/Symbols.cpp
@@ -166,10 +166,10 @@ bool Undefined::resolveWeakAlias() {
 MemoryBufferRef LazyArchive::getMemberBuffer() {
   Archive::Child c =
       CHECK(sym.getMember(), "could not get the member for symbol " +
-                                 toCOFFString(file->ctx, sym));
+                                 toCOFFString(file->symtab.ctx, sym));
   return CHECK(c.getMemoryBufferRef(),
                "could not get the buffer for the member defining symbol " +
-                   toCOFFString(file->ctx, sym));
+                   toCOFFString(file->symtab.ctx, sym));
 }
 } // namespace coff
 } // namespace lld



More information about the llvm-commits mailing list