[lld] 6f7483b - Reland "[LLD] Remove global state in lld/COFF" after fixing asan and msan test failures
Amy Huang via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 17 17:41:49 PDT 2021
Whoops, I'll fix that.
On Fri, Sep 17, 2021 at 5:40 PM Geoffrey Martin-Noble <gcmn at google.com>
wrote:
> I'm seeing diagnostic failures that appear to be coming from this commit
>
> llvm-project/lld/Common/Timer.cpp:29:38: error: field 'name' will be
> initialized after field 'total' [-Werror,-Wreorder-ctor]
> Timer::Timer(llvm::StringRef name) : name(std::string(name)), total(0) {}
>
> Could you take a look?
>
> On Fri, Sep 17, 2021 at 5:19 PM Amy Huang via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>>
>> Author: Amy Huang
>> Date: 2021-09-17T17:18:42-07:00
>> New Revision: 6f7483b1ece4747f2aafe4baa05fc07e7dc9ed9d
>>
>> URL:
>> https://github.com/llvm/llvm-project/commit/6f7483b1ece4747f2aafe4baa05fc07e7dc9ed9d
>> DIFF:
>> https://github.com/llvm/llvm-project/commit/6f7483b1ece4747f2aafe4baa05fc07e7dc9ed9d.diff
>>
>> LOG: Reland "[LLD] Remove global state in lld/COFF" after fixing asan and
>> msan test failures
>>
>> Original commit description:
>>
>> [LLD] Remove global state in lld/COFF
>>
>> This patch removes globals from the lldCOFF library, by moving globals
>> into a context class (COFFLinkingContext) and passing it around wherever
>> it's needed.
>>
>> See https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html for
>> context about removing globals from LLD.
>>
>> I also haven't moved the `driver` or `config` variables yet.
>>
>> Differential Revision: https://reviews.llvm.org/D109634
>>
>> This reverts commit a2fd05ada9030eab2258fff25e77a05adccae128.
>>
>> Original commits were b4fa71eed34d967195514fe9b0a5211fca2bc5bc
>> and e03c7e367adb8f228332e3c2ef8f45484597b719.
>>
>> Added:
>> lld/COFF/COFFLinkerContext.cpp
>> lld/COFF/COFFLinkerContext.h
>> lld/test/COFF/timers.ll
>>
>> Modified:
>> lld/COFF/CMakeLists.txt
>> lld/COFF/CallGraphSort.cpp
>> lld/COFF/CallGraphSort.h
>> lld/COFF/Chunks.cpp
>> lld/COFF/Chunks.h
>> lld/COFF/DLL.cpp
>> lld/COFF/DLL.h
>> lld/COFF/DebugTypes.cpp
>> lld/COFF/DebugTypes.h
>> lld/COFF/Driver.cpp
>> lld/COFF/Driver.h
>> lld/COFF/ICF.cpp
>> lld/COFF/ICF.h
>> lld/COFF/InputFiles.cpp
>> lld/COFF/InputFiles.h
>> lld/COFF/LLDMapFile.cpp
>> lld/COFF/LLDMapFile.h
>> lld/COFF/LTO.cpp
>> lld/COFF/LTO.h
>> lld/COFF/MapFile.cpp
>> lld/COFF/MapFile.h
>> lld/COFF/MarkLive.cpp
>> lld/COFF/MarkLive.h
>> lld/COFF/MinGW.cpp
>> lld/COFF/MinGW.h
>> lld/COFF/PDB.cpp
>> lld/COFF/PDB.h
>> lld/COFF/SymbolTable.cpp
>> lld/COFF/SymbolTable.h
>> lld/COFF/TypeMerger.h
>> lld/COFF/Writer.cpp
>> lld/COFF/Writer.h
>> lld/Common/Timer.cpp
>> lld/include/lld/Common/Timer.h
>> llvm/utils/gn/secondary/lld/COFF/BUILD.gn
>>
>> Removed:
>>
>>
>>
>>
>> ################################################################################
>> diff --git a/lld/COFF/CMakeLists.txt b/lld/COFF/CMakeLists.txt
>> index bbcd337b210f3..b32b9cfcff04e 100644
>> --- a/lld/COFF/CMakeLists.txt
>> +++ b/lld/COFF/CMakeLists.txt
>> @@ -5,6 +5,7 @@ add_public_tablegen_target(COFFOptionsTableGen)
>> add_lld_library(lldCOFF
>> CallGraphSort.cpp
>> Chunks.cpp
>> + COFFLinkerContext.cpp
>> DebugTypes.cpp
>> DLL.cpp
>> Driver.cpp
>>
>> diff --git a/lld/COFF/COFFLinkerContext.cpp
>> b/lld/COFF/COFFLinkerContext.cpp
>> new file mode 100644
>> index 0000000000000..a280cacb932e2
>> --- /dev/null
>> +++ b/lld/COFF/COFFLinkerContext.cpp
>> @@ -0,0 +1,40 @@
>> +//===- COFFContext.cpp
>> ----------------------------------------------------===//
>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>> Exceptions.
>> +// See https://llvm.org/LICENSE.txt for license information.
>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +//
>> +// Description
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +#include "COFFLinkerContext.h"
>> +#include "lld/Common/Memory.h"
>> +#include "llvm/DebugInfo/CodeView/TypeHashing.h"
>> +
>> +namespace lld {
>> +namespace coff {
>> +
>> +COFFLinkerContext::COFFLinkerContext()
>> + : symtab(*this), rootTimer("Total Linking Time"),
>> + inputFileTimer("Input File Reading", rootTimer),
>> + ltoTimer("LTO", rootTimer), gcTimer("GC", rootTimer),
>> + icfTimer("ICF", rootTimer), codeLayoutTimer("Code Layout",
>> rootTimer),
>> + outputCommitTimer("Commit Output File", rootTimer),
>> + totalMapTimer("MAP Emission (Cumulative)", rootTimer),
>> + symbolGatherTimer("Gather Symbols", totalMapTimer),
>> + symbolStringsTimer("Build Symbol Strings", totalMapTimer),
>> + writeTimer("Write to File", totalMapTimer),
>> + totalPdbLinkTimer("PDB Emission (Cumulative)", rootTimer),
>> + addObjectsTimer("Add Objects", totalPdbLinkTimer),
>> + typeMergingTimer("Type Merging", addObjectsTimer),
>> + loadGHashTimer("Global Type Hashing", addObjectsTimer),
>> + mergeGHashTimer("GHash Type Merging", addObjectsTimer),
>> + symbolMergingTimer("Symbol Merging", addObjectsTimer),
>> + publicsLayoutTimer("Publics Stream Layout", totalPdbLinkTimer),
>> + tpiStreamLayoutTimer("TPI Stream Layout", totalPdbLinkTimer),
>> + diskCommitTimer("Commit to Disk", totalPdbLinkTimer) {}
>> +
>> +} // namespace coff
>> +} // namespace lld
>>
>> diff --git a/lld/COFF/COFFLinkerContext.h b/lld/COFF/COFFLinkerContext.h
>> new file mode 100644
>> index 0000000000000..e5223da86ef83
>> --- /dev/null
>> +++ b/lld/COFF/COFFLinkerContext.h
>> @@ -0,0 +1,85 @@
>> +//===- COFFLinkerContext.h --------------------------------------*- C++
>> -*-===//
>> +//
>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>> Exceptions.
>> +// See https://llvm.org/LICENSE.txt for license information.
>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +#ifndef LLD_COFF_COFFLinkerContext_H
>> +#define LLD_COFF_COFFLinkerContext_H
>> +
>> +#include "Chunks.h"
>> +#include "Config.h"
>> +#include "DebugTypes.h"
>> +#include "InputFiles.h"
>> +#include "SymbolTable.h"
>> +#include "Writer.h"
>> +#include "lld/Common/Timer.h"
>> +
>> +namespace lld {
>> +namespace coff {
>> +
>> +class COFFLinkerContext {
>> +public:
>> + COFFLinkerContext();
>> + COFFLinkerContext(const COFFLinkerContext &) = delete;
>> + COFFLinkerContext &operator=(const COFFLinkerContext &) = delete;
>> + ~COFFLinkerContext() = default;
>> +
>> + void addTpiSource(TpiSource *tpi) { tpiSourceList.push_back(tpi); }
>> +
>> + SymbolTable symtab;
>> +
>> + std::vector<ObjFile *> objFileInstances;
>> + std::map<std::string, PDBInputFile *> pdbInputFileInstances;
>> + std::vector<ImportFile *> importFileInstances;
>> + std::vector<BitcodeFile *> bitcodeFileInstances;
>> +
>> + MergeChunk *mergeChunkInstances[Log2MaxSectionAlignment + 1] = {};
>> +
>> + /// All sources of type information in the program.
>> + std::vector<TpiSource *> tpiSourceList;
>> +
>> + std::map<llvm::codeview::GUID, TpiSource *> typeServerSourceMappings;
>> + std::map<uint32_t, TpiSource *> precompSourceMappings;
>> +
>> + /// List of all output sections. After output sections are finalized,
>> this
>> + /// can be indexed by getOutputSection.
>> + std::vector<OutputSection *> outputSections;
>> +
>> + OutputSection *getOutputSection(const Chunk *c) const {
>> + return c->osidx == 0 ? nullptr : outputSections[c->osidx - 1];
>> + }
>> +
>> + // All timers used in the COFF linker.
>> + Timer rootTimer;
>> + Timer inputFileTimer;
>> + Timer ltoTimer;
>> + Timer gcTimer;
>> + Timer icfTimer;
>> +
>> + // Writer timers.
>> + Timer codeLayoutTimer;
>> + Timer outputCommitTimer;
>> + Timer totalMapTimer;
>> + Timer symbolGatherTimer;
>> + Timer symbolStringsTimer;
>> + Timer writeTimer;
>> +
>> + // PDB timers.
>> + Timer totalPdbLinkTimer;
>> + Timer addObjectsTimer;
>> + Timer typeMergingTimer;
>> + Timer loadGHashTimer;
>> + Timer mergeGHashTimer;
>> + Timer symbolMergingTimer;
>> + Timer publicsLayoutTimer;
>> + Timer tpiStreamLayoutTimer;
>> + Timer diskCommitTimer;
>> +};
>> +
>> +} // namespace coff
>> +} // namespace lld
>> +
>> +#endif
>>
>> diff --git a/lld/COFF/CallGraphSort.cpp b/lld/COFF/CallGraphSort.cpp
>> index d3e5312ce7fdd..709e69b24914b 100644
>> --- a/lld/COFF/CallGraphSort.cpp
>> +++ b/lld/COFF/CallGraphSort.cpp
>> @@ -12,6 +12,7 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "CallGraphSort.h"
>> +#include "COFFLinkerContext.h"
>> #include "InputFiles.h"
>> #include "SymbolTable.h"
>> #include "Symbols.h"
>> @@ -48,7 +49,7 @@ struct Cluster {
>>
>> class CallGraphSort {
>> public:
>> - CallGraphSort();
>> + CallGraphSort(const COFFLinkerContext &ctx);
>>
>> DenseMap<const SectionChunk *, int> run();
>>
>> @@ -70,7 +71,7 @@ using SectionPair = std::pair<const SectionChunk *,
>> const SectionChunk *>;
>> // Take the edge list in Config->CallGraphProfile, resolve symbol names
>> to
>> // Symbols, and generate a graph between InputSections with the provided
>> // weights.
>> -CallGraphSort::CallGraphSort() {
>> +CallGraphSort::CallGraphSort(const COFFLinkerContext &ctx) {
>> MapVector<SectionPair, uint64_t> &profile = config->callGraphProfile;
>> DenseMap<const SectionChunk *, int> secToCluster;
>>
>> @@ -95,7 +96,7 @@ CallGraphSort::CallGraphSort() {
>> // output. This messes with the cluster size and density
>> calculations. We
>> // would also end up moving input sections in other output sections
>> without
>> // moving them closer to what calls them.
>> - if (fromSec->getOutputSection() != toSec->getOutputSection())
>> + if (ctx.getOutputSection(fromSec) != ctx.getOutputSection(toSec))
>> continue;
>>
>> int from = getOrCreateNode(fromSec);
>> @@ -240,6 +241,7 @@ DenseMap<const SectionChunk *, int>
>> CallGraphSort::run() {
>> // This first builds a call graph based on the profile data then merges
>> sections
>> // according to the C³ heuristic. All clusters are then sorted by a
>> density
>> // metric to further improve locality.
>> -DenseMap<const SectionChunk *, int> coff::computeCallGraphProfileOrder()
>> {
>> - return CallGraphSort().run();
>> +DenseMap<const SectionChunk *, int>
>> +coff::computeCallGraphProfileOrder(const COFFLinkerContext &ctx) {
>> + return CallGraphSort(ctx).run();
>> }
>>
>> diff --git a/lld/COFF/CallGraphSort.h b/lld/COFF/CallGraphSort.h
>> index e4f372137448c..99f35d6b62762 100644
>> --- a/lld/COFF/CallGraphSort.h
>> +++ b/lld/COFF/CallGraphSort.h
>> @@ -14,8 +14,10 @@
>> namespace lld {
>> namespace coff {
>> class SectionChunk;
>> +class COFFLinkerContext;
>>
>> -llvm::DenseMap<const SectionChunk *, int> computeCallGraphProfileOrder();
>> +llvm::DenseMap<const SectionChunk *, int>
>> +computeCallGraphProfileOrder(const COFFLinkerContext &ctx);
>> } // namespace coff
>> } // namespace lld
>>
>>
>> diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
>> index 36d5f371326fe..9f6dbd1725096 100644
>> --- a/lld/COFF/Chunks.cpp
>> +++ b/lld/COFF/Chunks.cpp
>> @@ -7,10 +7,11 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "Chunks.h"
>> +#include "COFFLinkerContext.h"
>> #include "InputFiles.h"
>> +#include "SymbolTable.h"
>> #include "Symbols.h"
>> #include "Writer.h"
>> -#include "SymbolTable.h"
>> #include "lld/Common/ErrorHandler.h"
>> #include "llvm/ADT/Twine.h"
>> #include "llvm/BinaryFormat/COFF.h"
>> @@ -385,7 +386,7 @@ 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 ? c->getOutputSection() : nullptr;
>> + OutputSection *os = c ? file->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
>> @@ -938,18 +939,16 @@ uint8_t Baserel::getDefaultType() {
>> }
>> }
>>
>> -MergeChunk *MergeChunk::instances[Log2MaxSectionAlignment + 1] = {};
>> -
>> MergeChunk::MergeChunk(uint32_t alignment)
>> : builder(StringTableBuilder::RAW, alignment) {
>> setAlignment(alignment);
>> }
>>
>> -void MergeChunk::addSection(SectionChunk *c) {
>> +void MergeChunk::addSection(COFFLinkerContext &ctx, SectionChunk *c) {
>> assert(isPowerOf2_32(c->getAlignment()));
>> uint8_t p2Align = llvm::Log2_32(c->getAlignment());
>> - assert(p2Align < array_lengthof(instances));
>> - auto *&mc = instances[p2Align];
>> + assert(p2Align < array_lengthof(ctx.mergeChunkInstances));
>> + auto *&mc = ctx.mergeChunkInstances[p2Align];
>> if (!mc)
>> mc = make<MergeChunk>(c->getAlignment());
>> mc->sections.push_back(c);
>>
>> diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
>> index bdd3faa179a8a..daaa043ffaceb 100644
>> --- a/lld/COFF/Chunks.h
>> +++ b/lld/COFF/Chunks.h
>> @@ -101,7 +101,6 @@ class Chunk {
>> // chunk has a back pointer to an output section.
>> void setOutputSectionIdx(uint16_t o) { osidx = o; }
>> uint16_t getOutputSectionIdx() const { return osidx; }
>> - OutputSection *getOutputSection() const;
>>
>> // Windows-specific.
>> // Collect all locations that contain absolute addresses for base
>> relocations.
>> @@ -415,7 +414,7 @@ inline StringRef Chunk::getDebugName() const {
>> class MergeChunk : public NonSectionChunk {
>> public:
>> MergeChunk(uint32_t alignment);
>> - static void addSection(SectionChunk *c);
>> + static void addSection(COFFLinkerContext &ctx, SectionChunk *c);
>> void finalizeContents();
>> void assignSubsectionRVAs();
>>
>> @@ -424,7 +423,6 @@ class MergeChunk : public NonSectionChunk {
>> size_t getSize() const override;
>> void writeTo(uint8_t *buf) const override;
>>
>> - static MergeChunk *instances[Log2MaxSectionAlignment + 1];
>> std::vector<SectionChunk *> sections;
>>
>> private:
>>
>> diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
>> index b9e12ef4b34dd..6fec9df5617db 100644
>> --- a/lld/COFF/DLL.cpp
>> +++ b/lld/COFF/DLL.cpp
>> @@ -18,6 +18,7 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "DLL.h"
>> +#include "COFFLinkerContext.h"
>> #include "Chunks.h"
>> #include "SymbolTable.h"
>> #include "llvm/Object/COFF.h"
>> @@ -631,7 +632,7 @@ uint64_t DelayLoadContents::getDirSize() {
>> return dirs.size() * sizeof(delay_import_directory_table_entry);
>> }
>>
>> -void DelayLoadContents::create(Defined *h) {
>> +void DelayLoadContents::create(COFFLinkerContext &ctx, Defined *h) {
>> helper = h;
>> std::vector<std::vector<DefinedImportData *>> v = binImports(imports);
>>
>> @@ -660,13 +661,13 @@ void DelayLoadContents::create(Defined *h) {
>> // call targets for Control Flow Guard.
>> StringRef symName = saver.save("__imp_load_" + extName);
>> s->loadThunkSym =
>> - cast<DefinedSynthetic>(symtab->addSynthetic(symName, t));
>> + cast<DefinedSynthetic>(ctx.symtab.addSynthetic(symName, t));
>> }
>> }
>> thunks.push_back(tm);
>> StringRef tmName =
>> saver.save("__tailMerge_" + syms[0]->getDLLName().lower());
>> - symtab->addSynthetic(tmName, tm);
>> + ctx.symtab.addSynthetic(tmName, tm);
>> // Terminate with null values.
>> addresses.push_back(make<NullChunk>(8));
>> names.push_back(make<NullChunk>(8));
>>
>> diff --git a/lld/COFF/DLL.h b/lld/COFF/DLL.h
>> index ce0ee01c4a3df..0d594e675bd23 100644
>> --- a/lld/COFF/DLL.h
>> +++ b/lld/COFF/DLL.h
>> @@ -40,7 +40,7 @@ class DelayLoadContents {
>> public:
>> void add(DefinedImportData *sym) { imports.push_back(sym); }
>> bool empty() { return imports.empty(); }
>> - void create(Defined *helper);
>> + void create(COFFLinkerContext &ctx, Defined *helper);
>> std::vector<Chunk *> getChunks();
>> std::vector<Chunk *> getDataChunks();
>> ArrayRef<Chunk *> getCodeChunks() { return thunks; }
>>
>> diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp
>> index 97be5bc79ac34..115b66c34332d 100644
>> --- a/lld/COFF/DebugTypes.cpp
>> +++ b/lld/COFF/DebugTypes.cpp
>> @@ -7,6 +7,7 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "DebugTypes.h"
>> +#include "COFFLinkerContext.h"
>> #include "Chunks.h"
>> #include "Driver.h"
>> #include "InputFiles.h"
>> @@ -14,7 +15,6 @@
>> #include "TypeMerger.h"
>> #include "lld/Common/ErrorHandler.h"
>> #include "lld/Common/Memory.h"
>> -#include "lld/Common/Timer.h"
>> #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
>> #include "llvm/DebugInfo/CodeView/TypeRecord.h"
>> #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
>> @@ -46,8 +46,8 @@ class TypeServerIpiSource;
>> // before any dependent OBJ.
>> class TypeServerSource : public TpiSource {
>> public:
>> - explicit TypeServerSource(PDBInputFile *f)
>> - : TpiSource(PDB, nullptr), pdbInputFile(f) {
>> + explicit TypeServerSource(COFFLinkerContext &ctx, PDBInputFile *f)
>> + : TpiSource(ctx, PDB, nullptr), pdbInputFile(f) {
>> if (f->loadErr && *f->loadErr)
>> return;
>> pdb::PDBFile &file = f->session->getPDBFile();
>> @@ -55,7 +55,7 @@ class TypeServerSource : public TpiSource {
>> if (!expectedInfo)
>> return;
>> Guid = expectedInfo->getGuid();
>> - auto it = mappings.emplace(Guid, this);
>> + auto it = ctx.typeServerSourceMappings.emplace(Guid, this);
>> assert(it.second);
>> (void)it;
>> }
>> @@ -74,8 +74,6 @@ class TypeServerSource : public TpiSource {
>>
>> // The PDB signature GUID.
>> codeview::GUID Guid;
>> -
>> - static std::map<codeview::GUID, TypeServerSource *> mappings;
>> };
>>
>> // Companion to TypeServerSource. Stores the index map for the IPI
>> stream in the
>> @@ -83,7 +81,8 @@ class TypeServerSource : public TpiSource {
>> // invariant of one type index space per source.
>> class TypeServerIpiSource : public TpiSource {
>> public:
>> - explicit TypeServerIpiSource() : TpiSource(PDBIpi, nullptr) {}
>> + explicit TypeServerIpiSource(COFFLinkerContext &ctx)
>> + : TpiSource(ctx, PDBIpi, nullptr) {}
>>
>> friend class TypeServerSource;
>>
>> @@ -101,8 +100,8 @@ class UseTypeServerSource : public TpiSource {
>> Expected<TypeServerSource *> getTypeServerSource();
>>
>> public:
>> - UseTypeServerSource(ObjFile *f, TypeServer2Record ts)
>> - : TpiSource(UsingPDB, f), typeServerDependency(ts) {}
>> + UseTypeServerSource(COFFLinkerContext &ctx, ObjFile *f,
>> TypeServer2Record ts)
>> + : TpiSource(ctx, UsingPDB, f), typeServerDependency(ts) {}
>>
>> Error mergeDebugT(TypeMerger *m) override;
>>
>> @@ -121,11 +120,11 @@ class UseTypeServerSource : public TpiSource {
>> // such files, clang does not.
>> class PrecompSource : public TpiSource {
>> public:
>> - PrecompSource(ObjFile *f) : TpiSource(PCH, f) {
>> + PrecompSource(COFFLinkerContext &ctx, ObjFile *f) : TpiSource(ctx,
>> PCH, f) {
>> if (!f->pchSignature || !*f->pchSignature)
>> fatal(toString(f) +
>> " claims to be a PCH object, but does not have a valid
>> signature");
>> - auto it = mappings.emplace(*f->pchSignature, this);
>> + auto it = ctx.precompSourceMappings.emplace(*f->pchSignature, this);
>> if (!it.second)
>> fatal("a PCH object with the same signature has already been
>> provided (" +
>> toString(it.first->second->file) + " and " + toString(file)
>> + ")");
>> @@ -134,16 +133,14 @@ class PrecompSource : public TpiSource {
>> void loadGHashes() override;
>>
>> bool isDependency() const override { return true; }
>> -
>> - static std::map<uint32_t, PrecompSource *> mappings;
>> };
>>
>> // This class represents the debug type stream of an OBJ file that
>> depends on a
>> // Microsoft precompiled headers OBJ (see PrecompSource).
>> class UsePrecompSource : public TpiSource {
>> public:
>> - UsePrecompSource(ObjFile *f, PrecompRecord precomp)
>> - : TpiSource(UsingPCH, f), precompDependency(precomp) {}
>> + UsePrecompSource(COFFLinkerContext &ctx, ObjFile *f, PrecompRecord
>> precomp)
>> + : TpiSource(ctx, UsingPCH, f), precompDependency(precomp) {}
>>
>> Error mergeDebugT(TypeMerger *m) override;
>>
>> @@ -153,6 +150,10 @@ class UsePrecompSource : public TpiSource {
>> private:
>> Error mergeInPrecompHeaderObj();
>>
>> + PrecompSource *findObjByName(StringRef fileNameOnly);
>> + PrecompSource *findPrecompSource(ObjFile *file, PrecompRecord &pr);
>> + Expected<PrecompSource *> findPrecompMap(ObjFile *file, PrecompRecord
>> &pr);
>> +
>> public:
>> // Information about the Precomp OBJ dependency, that needs to be
>> loaded in
>> // before merging this OBJ.
>> @@ -160,13 +161,9 @@ class UsePrecompSource : public TpiSource {
>> };
>> } // namespace
>>
>> -std::vector<TpiSource *> TpiSource::instances;
>> -ArrayRef<TpiSource *> TpiSource::dependencySources;
>> -ArrayRef<TpiSource *> TpiSource::objectSources;
>> -
>> -TpiSource::TpiSource(TpiKind k, ObjFile *f)
>> - : kind(k), tpiSrcIdx(instances.size()), file(f) {
>> - instances.push_back(this);
>> +TpiSource::TpiSource(COFFLinkerContext &ctx, TpiKind k, ObjFile *f)
>> + : ctx(ctx), kind(k), tpiSrcIdx(ctx.tpiSourceList.size()), file(f) {
>> + ctx.addTpiSource(this);
>> }
>>
>> // Vtable key method.
>> @@ -175,52 +172,35 @@ TpiSource::~TpiSource() {
>> consumeError(std::move(typeMergingError));
>> }
>>
>> -void TpiSource::sortDependencies() {
>> - // Order dependencies first, but preserve the existing order.
>> - std::vector<TpiSource *> deps;
>> - std::vector<TpiSource *> objs;
>> - for (TpiSource *s : instances)
>> - (s->isDependency() ? deps : objs).push_back(s);
>> - uint32_t numDeps = deps.size();
>> - uint32_t numObjs = objs.size();
>> - instances = std::move(deps);
>> - instances.insert(instances.end(), objs.begin(), objs.end());
>> - for (uint32_t i = 0, e = instances.size(); i < e; ++i)
>> - instances[i]->tpiSrcIdx = i;
>> - dependencySources = makeArrayRef(instances.data(), numDeps);
>> - objectSources = makeArrayRef(instances.data() + numDeps, numObjs);
>> -}
>> -
>> -TpiSource *lld::coff::makeTpiSource(ObjFile *file) {
>> - return make<TpiSource>(TpiSource::Regular, file);
>> +TpiSource *lld::coff::makeTpiSource(COFFLinkerContext &ctx, ObjFile
>> *file) {
>> + return make<TpiSource>(ctx, TpiSource::Regular, file);
>> }
>>
>> -TpiSource *lld::coff::makeTypeServerSource(PDBInputFile *pdbInputFile) {
>> +TpiSource *lld::coff::makeTypeServerSource(COFFLinkerContext &ctx,
>> + PDBInputFile *pdbInputFile) {
>> // Type server sources come in pairs: the TPI stream, and the IPI
>> stream.
>> - auto *tpiSource = make<TypeServerSource>(pdbInputFile);
>> + auto *tpiSource = make<TypeServerSource>(ctx, pdbInputFile);
>> if (pdbInputFile->session->getPDBFile().hasPDBIpiStream())
>> - tpiSource->ipiSrc = make<TypeServerIpiSource>();
>> + tpiSource->ipiSrc = make<TypeServerIpiSource>(ctx);
>> return tpiSource;
>> }
>>
>> -TpiSource *lld::coff::makeUseTypeServerSource(ObjFile *file,
>> +TpiSource *lld::coff::makeUseTypeServerSource(COFFLinkerContext &ctx,
>> + ObjFile *file,
>> TypeServer2Record ts) {
>> - return make<UseTypeServerSource>(file, ts);
>> + return make<UseTypeServerSource>(ctx, file, ts);
>> }
>>
>> -TpiSource *lld::coff::makePrecompSource(ObjFile *file) {
>> - return make<PrecompSource>(file);
>> +TpiSource *lld::coff::makePrecompSource(COFFLinkerContext &ctx, ObjFile
>> *file) {
>> + return make<PrecompSource>(ctx, file);
>> }
>>
>> -TpiSource *lld::coff::makeUsePrecompSource(ObjFile *file,
>> +TpiSource *lld::coff::makeUsePrecompSource(COFFLinkerContext &ctx,
>> + ObjFile *file,
>> PrecompRecord precomp) {
>> - return make<UsePrecompSource>(file, precomp);
>> + return make<UsePrecompSource>(ctx, file, precomp);
>> }
>>
>> -std::map<codeview::GUID, TypeServerSource *> TypeServerSource::mappings;
>> -
>> -std::map<uint32_t, PrecompSource *> PrecompSource::mappings;
>> -
>> bool TpiSource::remapTypeIndex(TypeIndex &ti, TiRefKind refKind) const {
>> if (ti.isSimple())
>> return true;
>> @@ -419,12 +399,12 @@ Expected<TypeServerSource *>
>> UseTypeServerSource::getTypeServerSource() {
>> StringRef tsPath = typeServerDependency.getName();
>>
>> TypeServerSource *tsSrc;
>> - auto it = TypeServerSource::mappings.find(tsId);
>> - if (it != TypeServerSource::mappings.end()) {
>> - tsSrc = it->second;
>> + auto it = ctx.typeServerSourceMappings.find(tsId);
>> + if (it != ctx.typeServerSourceMappings.end()) {
>> + tsSrc = (TypeServerSource *)it->second;
>> } else {
>> // The file failed to load, lookup by name
>> - PDBInputFile *pdb = PDBInputFile::findFromRecordPath(tsPath, file);
>> + PDBInputFile *pdb = PDBInputFile::findFromRecordPath(ctx, tsPath,
>> file);
>> if (!pdb)
>> return createFileError(tsPath, errorCodeToError(std::error_code(
>> ENOENT,
>> std::generic_category())));
>> @@ -471,36 +451,37 @@ static bool equalsPath(StringRef path1, StringRef
>> path2) {
>> }
>>
>> // Find by name an OBJ provided on the command line
>> -static PrecompSource *findObjByName(StringRef fileNameOnly) {
>> +PrecompSource *UsePrecompSource::findObjByName(StringRef fileNameOnly) {
>> SmallString<128> currentPath;
>> - for (auto kv : PrecompSource::mappings) {
>> + for (auto kv : ctx.precompSourceMappings) {
>> StringRef currentFileName =
>> sys::path::filename(kv.second->file->getName(),
>>
>> sys::path::Style::windows);
>>
>> // Compare based solely on the file name (link.exe behavior)
>> if (equalsPath(currentFileName, fileNameOnly))
>> - return kv.second;
>> + return (PrecompSource *)kv.second;
>> }
>> return nullptr;
>> }
>>
>> -static PrecompSource *findPrecompSource(ObjFile *file, PrecompRecord
>> &pr) {
>> +PrecompSource *UsePrecompSource::findPrecompSource(ObjFile *file,
>> + PrecompRecord &pr) {
>> // Cross-compile warning: given that Clang doesn't generate LF_PRECOMP
>> // records, we assume the OBJ comes from a Windows build of cl.exe.
>> Thusly,
>> // the paths embedded in the OBJs are in the Windows format.
>> SmallString<128> prFileName =
>> sys::path::filename(pr.getPrecompFilePath(),
>> sys::path::Style::windows);
>>
>> - auto it = PrecompSource::mappings.find(pr.getSignature());
>> - if (it != PrecompSource::mappings.end()) {
>> - return it->second;
>> + auto it = ctx.precompSourceMappings.find(pr.getSignature());
>> + if (it != ctx.precompSourceMappings.end()) {
>> + return (PrecompSource *)it->second;
>> }
>> // Lookup by name
>> return findObjByName(prFileName);
>> }
>>
>> -static Expected<PrecompSource *> findPrecompMap(ObjFile *file,
>> - PrecompRecord &pr) {
>> +Expected<PrecompSource *> UsePrecompSource::findPrecompMap(ObjFile *file,
>> + PrecompRecord
>> &pr) {
>> PrecompSource *precomp = findPrecompSource(file, pr);
>>
>> if (!precomp)
>> @@ -555,22 +536,6 @@ Error UsePrecompSource::mergeDebugT(TypeMerger *m) {
>> return TpiSource::mergeDebugT(m);
>> }
>>
>> -uint32_t TpiSource::countTypeServerPDBs() {
>> - return TypeServerSource::mappings.size();
>> -}
>> -
>> -uint32_t TpiSource::countPrecompObjs() {
>> - return PrecompSource::mappings.size();
>> -}
>> -
>> -void TpiSource::clear() {
>> - // Clean up any owned ghash allocations.
>> - clearGHashes();
>> - TpiSource::instances.clear();
>> - TypeServerSource::mappings.clear();
>> - PrecompSource::mappings.clear();
>> -}
>> -
>>
>> //===----------------------------------------------------------------------===//
>> // Parellel GHash type merging implementation.
>>
>> //===----------------------------------------------------------------------===//
>> @@ -926,7 +891,8 @@ struct GHashTable {
>> /// Insert the cell with the given ghash into the table. Return the
>> insertion
>> /// position in the table. It is safe for the caller to store the
>> insertion
>> /// position because the table cannot be resized.
>> - uint32_t insert(GloballyHashedType ghash, GHashCell newCell);
>> + uint32_t insert(COFFLinkerContext &ctx, GloballyHashedType ghash,
>> + GHashCell newCell);
>> };
>>
>> /// A ghash table cell for deduplicating types from TpiSources.
>> @@ -965,8 +931,8 @@ class GHashCell {
>> bool isItem() const { return data & (1ULL << 63U); }
>>
>> /// Get the ghash key for this cell.
>> - GloballyHashedType getGHash() const {
>> - return TpiSource::instances[getTpiSrcIdx()]->ghashes[getGHashIdx()];
>> + GloballyHashedType getGHash(const COFFLinkerContext &ctx) const {
>> + return ctx.tpiSourceList[getTpiSrcIdx()]->ghashes[getGHashIdx()];
>> }
>>
>> /// The priority function for the cell. The data is stored such that
>> lower
>> @@ -996,7 +962,8 @@ void GHashTable::init(uint32_t newTableSize) {
>> tableSize = newTableSize;
>> }
>>
>> -uint32_t GHashTable::insert(GloballyHashedType ghash, GHashCell newCell)
>> {
>> +uint32_t GHashTable::insert(COFFLinkerContext &ctx, GloballyHashedType
>> ghash,
>> + GHashCell newCell) {
>> assert(!newCell.isEmpty() && "cannot insert empty cell value");
>>
>> // FIXME: The low bytes of SHA1 have low entropy for short records,
>> which
>> @@ -1015,7 +982,7 @@ uint32_t GHashTable::insert(GloballyHashedType
>> ghash, GHashCell newCell) {
>> // - cell has non-matching key: hash collision, probe next cell
>> auto *cellPtr = reinterpret_cast<std::atomic<GHashCell>
>> *>(&table[idx]);
>> GHashCell oldCell(cellPtr->load());
>> - while (oldCell.isEmpty() || oldCell.getGHash() == ghash) {
>> + while (oldCell.isEmpty() || oldCell.getGHash(ctx) == ghash) {
>> // Check if there is an existing ghash entry with a higher priority
>> // (earlier ordering). If so, this is a duplicate, we are done.
>> if (!oldCell.isEmpty() && oldCell < newCell)
>> @@ -1040,22 +1007,22 @@ uint32_t GHashTable::insert(GloballyHashedType
>> ghash, GHashCell newCell) {
>> llvm_unreachable("left infloop");
>> }
>>
>> -TypeMerger::TypeMerger(llvm::BumpPtrAllocator &alloc)
>> - : typeTable(alloc), idTable(alloc) {}
>> +TypeMerger::TypeMerger(COFFLinkerContext &c, llvm::BumpPtrAllocator
>> &alloc)
>> + : typeTable(alloc), idTable(alloc), ctx(c) {}
>>
>> TypeMerger::~TypeMerger() = default;
>>
>> void TypeMerger::mergeTypesWithGHash() {
>> // Load ghashes. Do type servers and PCH objects first.
>> {
>> - ScopedTimer t1(loadGHashTimer);
>> - parallelForEach(TpiSource::dependencySources,
>> + ScopedTimer t1(ctx.loadGHashTimer);
>> + parallelForEach(dependencySources,
>> [&](TpiSource *source) { source->loadGHashes(); });
>> - parallelForEach(TpiSource::objectSources,
>> + parallelForEach(objectSources,
>> [&](TpiSource *source) { source->loadGHashes(); });
>> }
>>
>> - ScopedTimer t2(mergeGHashTimer);
>> + ScopedTimer t2(ctx.mergeGHashTimer);
>> GHashState ghashState;
>>
>> // Estimate the size of hash table needed to deduplicate ghashes. This
>> *must*
>> @@ -1066,7 +1033,7 @@ void TypeMerger::mergeTypesWithGHash() {
>> // small compared to total memory usage, at eight bytes per input type
>> record,
>> // and most input type records are larger than eight bytes.
>> size_t tableSize = 0;
>> - for (TpiSource *source : TpiSource::instances)
>> + for (TpiSource *source : ctx.tpiSourceList)
>> tableSize += source->ghashes.size();
>>
>> // Cap the table size so that we can use 32-bit cell indices. Type
>> indices are
>> @@ -1080,8 +1047,8 @@ void TypeMerger::mergeTypesWithGHash() {
>> // position. Because the table does not rehash, the position will not
>> change
>> // under insertion. After insertion is done, the value of the cell can
>> be read
>> // to retrieve the final PDB type index.
>> - parallelForEachN(0, TpiSource::instances.size(), [&](size_t tpiSrcIdx)
>> {
>> - TpiSource *source = TpiSource::instances[tpiSrcIdx];
>> + parallelForEachN(0, ctx.tpiSourceList.size(), [&](size_t tpiSrcIdx) {
>> + TpiSource *source = ctx.tpiSourceList[tpiSrcIdx];
>> source->indexMapStorage.resize(source->ghashes.size());
>> for (uint32_t i = 0, e = source->ghashes.size(); i < e; i++) {
>> if (source->shouldOmitFromPdb(i)) {
>> @@ -1091,7 +1058,7 @@ void TypeMerger::mergeTypesWithGHash() {
>> GloballyHashedType ghash = source->ghashes[i];
>> bool isItem = source->isItemIndex.test(i);
>> uint32_t cellIdx =
>> - ghashState.table.insert(ghash, GHashCell(isItem, tpiSrcIdx,
>> i));
>> + ghashState.table.insert(ctx, ghash, GHashCell(isItem,
>> tpiSrcIdx, i));
>>
>> // Store the ghash cell index as a type index in indexMapStorage.
>> Later
>> // we will replace it with the PDB type index.
>> @@ -1137,7 +1104,7 @@ void TypeMerger::mergeTypesWithGHash() {
>> for (uint32_t i = 0, e = entries.size(); i < e; ++i) {
>> auto &cell = entries[i];
>> uint32_t tpiSrcIdx = cell.getTpiSrcIdx();
>> - TpiSource *source = TpiSource::instances[tpiSrcIdx];
>> + TpiSource *source = ctx.tpiSourceList[tpiSrcIdx];
>> source->uniqueTypes.push_back(cell.getGHashIdx());
>>
>> // Update the ghash table to store the destination PDB type index in
>> the
>> @@ -1150,21 +1117,37 @@ void TypeMerger::mergeTypesWithGHash() {
>> }
>>
>> // In parallel, remap all types.
>> - for_each(TpiSource::dependencySources, [&](TpiSource *source) {
>> + for_each(dependencySources, [&](TpiSource *source) {
>> source->remapTpiWithGHashes(&ghashState);
>> });
>> - parallelForEach(TpiSource::objectSources, [&](TpiSource *source) {
>> + parallelForEach(objectSources, [&](TpiSource *source) {
>> source->remapTpiWithGHashes(&ghashState);
>> });
>>
>> // Build a global map of from function ID to function type.
>> - for (TpiSource *source : TpiSource::instances) {
>> + for (TpiSource *source : ctx.tpiSourceList) {
>> for (auto idToType : source->funcIdToType)
>> funcIdToType.insert(idToType);
>> source->funcIdToType.clear();
>> }
>>
>> - TpiSource::clearGHashes();
>> + clearGHashes();
>> +}
>> +
>> +void TypeMerger::sortDependencies() {
>> + // Order dependencies first, but preserve the existing order.
>> + std::vector<TpiSource *> deps;
>> + std::vector<TpiSource *> objs;
>> + for (TpiSource *s : ctx.tpiSourceList)
>> + (s->isDependency() ? deps : objs).push_back(s);
>> + uint32_t numDeps = deps.size();
>> + uint32_t numObjs = objs.size();
>> + ctx.tpiSourceList = std::move(deps);
>> + ctx.tpiSourceList.insert(ctx.tpiSourceList.end(), objs.begin(),
>> objs.end());
>> + for (uint32_t i = 0, e = ctx.tpiSourceList.size(); i < e; ++i)
>> + ctx.tpiSourceList[i]->tpiSrcIdx = i;
>> + dependencySources = makeArrayRef(ctx.tpiSourceList.data(), numDeps);
>> + objectSources = makeArrayRef(ctx.tpiSourceList.data() + numDeps,
>> numObjs);
>> }
>>
>> /// Given the index into the ghash table for a particular type, return
>> the type
>> @@ -1175,6 +1158,17 @@ static TypeIndex
>> loadPdbTypeIndexFromCell(GHashState *g,
>> return TypeIndex::fromArrayIndex(cell.getGHashIdx());
>> }
>>
>> +/// Free heap allocated ghashes.
>> +void TypeMerger::clearGHashes() {
>> + for (TpiSource *src : ctx.tpiSourceList) {
>> + if (src->ownedGHashes)
>> + delete[] src->ghashes.data();
>> + src->ghashes = {};
>> + src->isItemIndex.clear();
>> + src->uniqueTypes.clear();
>> + }
>> +}
>> +
>> // Fill in a TPI or IPI index map using ghashes. For each source type,
>> use its
>> // ghash to lookup its final type index in the PDB, and store that in
>> the map.
>> void TpiSource::fillMapFromGHashes(GHashState *g) {
>> @@ -1187,13 +1181,3 @@ void TpiSource::fillMapFromGHashes(GHashState *g) {
>> loadPdbTypeIndexFromCell(g, fakeCellIndex.toArrayIndex());
>> }
>> }
>> -
>> -void TpiSource::clearGHashes() {
>> - for (TpiSource *src : TpiSource::instances) {
>> - if (src->ownedGHashes)
>> - delete[] src->ghashes.data();
>> - src->ghashes = {};
>> - src->isItemIndex.clear();
>> - src->uniqueTypes.clear();
>> - }
>> -}
>>
>> diff --git a/lld/COFF/DebugTypes.h b/lld/COFF/DebugTypes.h
>> index faad30b141e92..b02b5b884cf7e 100644
>> --- a/lld/COFF/DebugTypes.h
>> +++ b/lld/COFF/DebugTypes.h
>> @@ -37,12 +37,13 @@ class ObjFile;
>> class PDBInputFile;
>> class TypeMerger;
>> struct GHashState;
>> +class COFFLinkerContext;
>>
>> class TpiSource {
>> public:
>> enum TpiKind : uint8_t { Regular, PCH, UsingPCH, PDB, PDBIpi, UsingPDB
>> };
>>
>> - TpiSource(TpiKind k, ObjFile *f);
>> + TpiSource(COFFLinkerContext &ctx, TpiKind k, ObjFile *f);
>> virtual ~TpiSource();
>>
>> /// Produce a mapping from the type and item indices used in the object
>> @@ -93,6 +94,8 @@ class TpiSource {
>> // Walk over file->debugTypes and fill in the isItemIndex bit vector.
>> void fillIsItemIndexFromDebugT();
>>
>> + COFFLinkerContext &ctx;
>> +
>> public:
>> bool remapTypesInSymbolRecord(MutableArrayRef<uint8_t> rec);
>>
>> @@ -109,29 +112,6 @@ class TpiSource {
>> return ghashIdx == endPrecompGHashIdx;
>> }
>>
>> - /// All sources of type information in the program.
>> - static std::vector<TpiSource *> instances;
>> -
>> - /// Dependency type sources, such as type servers or PCH object files.
>> These
>> - /// must be processed before objects that rely on them. Set by
>> - /// TpiSources::sortDependencies.
>> - static ArrayRef<TpiSource *> dependencySources;
>> -
>> - /// Object file sources. These must be processed after
>> dependencySources.
>> - static ArrayRef<TpiSource *> objectSources;
>> -
>> - /// Sorts the dependencies and reassigns TpiSource indices.
>> - static void sortDependencies();
>> -
>> - static uint32_t countTypeServerPDBs();
>> - static uint32_t countPrecompObjs();
>> -
>> - /// Free heap allocated ghashes.
>> - static void clearGHashes();
>> -
>> - /// Clear global data structures for TpiSources.
>> - static void clear();
>> -
>> const TpiKind kind;
>> bool ownedGHashes = true;
>> uint32_t tpiSrcIdx = 0;
>> @@ -186,12 +166,13 @@ class TpiSource {
>> uint64_t nbTypeRecordsBytes = 0;
>> };
>>
>> -TpiSource *makeTpiSource(ObjFile *file);
>> -TpiSource *makeTypeServerSource(PDBInputFile *pdbInputFile);
>> -TpiSource *makeUseTypeServerSource(ObjFile *file,
>> +TpiSource *makeTpiSource(COFFLinkerContext &ctx, ObjFile *f);
>> +TpiSource *makeTypeServerSource(COFFLinkerContext &ctx,
>> + PDBInputFile *pdbInputFile);
>> +TpiSource *makeUseTypeServerSource(COFFLinkerContext &ctx, ObjFile *file,
>> llvm::codeview::TypeServer2Record ts);
>> -TpiSource *makePrecompSource(ObjFile *file);
>> -TpiSource *makeUsePrecompSource(ObjFile *file,
>> +TpiSource *makePrecompSource(COFFLinkerContext &ctx, ObjFile *file);
>> +TpiSource *makeUsePrecompSource(COFFLinkerContext &ctx, ObjFile *file,
>> llvm::codeview::PrecompRecord ts);
>>
>> } // namespace coff
>>
>> diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
>> index fd9ae7f47bf87..9ebd1c336c594 100644
>> --- a/lld/COFF/Driver.cpp
>> +++ b/lld/COFF/Driver.cpp
>> @@ -7,6 +7,7 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "Driver.h"
>> +#include "COFFLinkerContext.h"
>> #include "Config.h"
>> #include "DebugTypes.h"
>> #include "ICF.h"
>> @@ -59,8 +60,6 @@ using namespace llvm::sys;
>> namespace lld {
>> namespace coff {
>>
>> -static Timer inputFileTimer("Input File Reading", Timer::root());
>> -
>> Configuration *config;
>> LinkerDriver *driver;
>>
>> @@ -70,14 +69,7 @@ bool link(ArrayRef<const char *> args, bool
>> canExitEarly, raw_ostream &stdoutOS,
>> lld::stderrOS = &stderrOS;
>>
>> errorHandler().cleanupCallback = []() {
>> - TpiSource::clear();
>> freeArena();
>> - ObjFile::instances.clear();
>> - PDBInputFile::instances.clear();
>> - ImportFile::instances.clear();
>> - BitcodeFile::instances.clear();
>> - memset(MergeChunk::instances, 0, sizeof(MergeChunk::instances));
>> - OutputSection::clear();
>> };
>>
>> errorHandler().logName = args::getFilenameWithoutExe(args[0]);
>> @@ -87,9 +79,9 @@ bool link(ArrayRef<const char *> args, bool
>> canExitEarly, raw_ostream &stdoutOS,
>> errorHandler().exitEarly = canExitEarly;
>> stderrOS.enable_colors(stderrOS.has_colors());
>>
>> + COFFLinkerContext ctx;
>> config = make<Configuration>();
>> - symtab = make<SymbolTable>();
>> - driver = make<LinkerDriver>();
>> + driver = make<LinkerDriver>(ctx);
>>
>> driver->linkerMain(args);
>>
>> @@ -174,8 +166,8 @@ static StringRef mangle(StringRef sym) {
>> return sym;
>> }
>>
>> -static bool findUnderscoreMangle(StringRef sym) {
>> - Symbol *s = symtab->findMangle(mangle(sym));
>> +bool LinkerDriver::findUnderscoreMangle(StringRef sym) {
>> + Symbol *s = ctx.symtab.findMangle(mangle(sym));
>> return s && !isa<Undefined>(s);
>> }
>>
>> @@ -213,30 +205,30 @@ void
>> LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
>> addArchiveBuffer(m, "<whole-archive>", filename, memberIndex++);
>> return;
>> }
>> - symtab->addFile(make<ArchiveFile>(mbref));
>> + ctx.symtab.addFile(make<ArchiveFile>(ctx, mbref));
>> break;
>> case file_magic::bitcode:
>> if (lazy)
>> - symtab->addFile(make<LazyObjFile>(mbref));
>> + ctx.symtab.addFile(make<LazyObjFile>(ctx, mbref));
>> else
>> - symtab->addFile(make<BitcodeFile>(mbref, "", 0));
>> + ctx.symtab.addFile(make<BitcodeFile>(ctx, mbref, "", 0));
>> break;
>> case file_magic::coff_object:
>> case file_magic::coff_import_library:
>> if (lazy)
>> - symtab->addFile(make<LazyObjFile>(mbref));
>> + ctx.symtab.addFile(make<LazyObjFile>(ctx, mbref));
>> else
>> - symtab->addFile(make<ObjFile>(mbref));
>> + ctx.symtab.addFile(make<ObjFile>(ctx, mbref));
>> break;
>> case file_magic::pdb:
>> - symtab->addFile(make<PDBInputFile>(mbref));
>> + ctx.symtab.addFile(make<PDBInputFile>(ctx, mbref));
>> break;
>> case file_magic::coff_cl_gl_object:
>> error(filename + ": is not a native COFF file. Recompile without
>> /GL");
>> break;
>> case file_magic::pecoff_executable:
>> if (config->mingw) {
>> - symtab->addFile(make<DLLFile>(mbref));
>> + ctx.symtab.addFile(make<DLLFile>(ctx, mbref));
>> break;
>> }
>> if (filename.endswith_insensitive(".dll")) {
>> @@ -280,24 +272,24 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef
>> mb, StringRef symName,
>> uint64_t offsetInArchive) {
>> file_magic magic = identify_magic(mb.getBuffer());
>> if (magic == file_magic::coff_import_library) {
>> - InputFile *imp = make<ImportFile>(mb);
>> + InputFile *imp = make<ImportFile>(ctx, mb);
>> imp->parentName = parentName;
>> - symtab->addFile(imp);
>> + ctx.symtab.addFile(imp);
>> return;
>> }
>>
>> InputFile *obj;
>> if (magic == file_magic::coff_object) {
>> - obj = make<ObjFile>(mb);
>> + obj = make<ObjFile>(ctx, mb);
>> } else if (magic == file_magic::bitcode) {
>> - obj = make<BitcodeFile>(mb, parentName, offsetInArchive);
>> + obj = make<BitcodeFile>(ctx, mb, parentName, offsetInArchive);
>> } else {
>> error("unknown file type: " + mb.getBufferIdentifier());
>> return;
>> }
>>
>> obj->parentName = parentName;
>> - symtab->addFile(obj);
>> + ctx.symtab.addFile(obj);
>> log("Loaded " + toString(obj) + " for " + symName);
>> }
>>
>> @@ -547,7 +539,7 @@ void LinkerDriver::addLibSearchPaths() {
>> }
>>
>> Symbol *LinkerDriver::addUndefined(StringRef name) {
>> - Symbol *b = symtab->addUndefined(name);
>> + Symbol *b = ctx.symtab.addUndefined(name);
>> if (!b->isGCRoot) {
>> b->isGCRoot = true;
>> config->gcroot.push_back(b);
>> @@ -562,14 +554,14 @@ StringRef LinkerDriver::mangleMaybe(Symbol *s) {
>> return "";
>>
>> // Otherwise, see if a similar, mangled symbol exists in the symbol
>> table.
>> - Symbol *mangled = symtab->findMangle(unmangled->getName());
>> + Symbol *mangled = ctx.symtab.findMangle(unmangled->getName());
>> if (!mangled)
>> return "";
>>
>> // If we find a similar mangled symbol, make this an alias to it and
>> return
>> // its name.
>> log(unmangled->getName() + " aliased to " + mangled->getName());
>> - unmangled->weakAlias = symtab->addUndefined(mangled->getName());
>> + unmangled->weakAlias = ctx.symtab.addUndefined(mangled->getName());
>> return mangled->getName();
>> }
>>
>> @@ -939,7 +931,7 @@ void LinkerDriver::enqueueTask(std::function<void()>
>> task) {
>> }
>>
>> bool LinkerDriver::run() {
>> - ScopedTimer t(inputFileTimer);
>> + ScopedTimer t(ctx.inputFileTimer);
>>
>> bool didWork = !taskQueue.empty();
>> while (!taskQueue.empty()) {
>> @@ -952,7 +944,7 @@ bool LinkerDriver::run() {
>> // Parse an /order file. If an option is given, the linker places
>> // COMDAT sections in the same order as their names appear in the
>> // given file.
>> -static void parseOrderFile(StringRef arg) {
>> +static void parseOrderFile(COFFLinkerContext &ctx, StringRef arg) {
>> // For some reason, the MSVC linker requires a filename to be
>> // preceded by "@".
>> if (!arg.startswith("@")) {
>> @@ -962,7 +954,7 @@ static void parseOrderFile(StringRef arg) {
>>
>> // Get a list of all comdat sections for error checking.
>> DenseSet<StringRef> set;
>> - for (Chunk *c : symtab->getChunks())
>> + for (Chunk *c : ctx.symtab.getChunks())
>> if (auto *sec = dyn_cast<SectionChunk>(c))
>> if (sec->sym)
>> set.insert(sec->sym->getName());
>> @@ -996,7 +988,7 @@ static void parseOrderFile(StringRef arg) {
>> driver->takeBuffer(std::move(mb));
>> }
>>
>> -static void parseCallGraphFile(StringRef path) {
>> +static void parseCallGraphFile(COFFLinkerContext &ctx, StringRef path) {
>> std::unique_ptr<MemoryBuffer> mb =
>> CHECK(MemoryBuffer::getFile(path, /*IsText=*/false,
>> /*RequiresNullTerminator=*/false,
>> @@ -1005,7 +997,7 @@ static void parseCallGraphFile(StringRef path) {
>>
>> // Build a map from symbol name to section.
>> DenseMap<StringRef, Symbol *> map;
>> - for (ObjFile *file : ObjFile::instances)
>> + for (ObjFile *file : ctx.objFileInstances)
>> for (Symbol *sym : file->getSymbols())
>> if (sym)
>> map[sym->getName()] = sym;
>> @@ -1042,8 +1034,8 @@ static void parseCallGraphFile(StringRef path) {
>> driver->takeBuffer(std::move(mb));
>> }
>>
>> -static void readCallGraphsFromObjectFiles() {
>> - for (ObjFile *obj : ObjFile::instances) {
>> +static void readCallGraphsFromObjectFiles(COFFLinkerContext &ctx) {
>> + for (ObjFile *obj : ctx.objFileInstances) {
>> if (obj->callgraphSec) {
>> ArrayRef<uint8_t> contents;
>> cantFail(
>> @@ -1077,7 +1069,7 @@ static void markAddrsig(Symbol *s) {
>> c->keepUnique = true;
>> }
>>
>> -static void findKeepUniqueSections() {
>> +static void findKeepUniqueSections(COFFLinkerContext &ctx) {
>> // Exported symbols could be address-significant in other executables
>> or DSOs,
>> // so we conservatively mark them as address-significant.
>> for (Export &r : config->exports)
>> @@ -1085,7 +1077,7 @@ static void findKeepUniqueSections() {
>>
>> // Visit the address-significance table in each object file and mark
>> each
>> // referenced symbol as address-significant.
>> - for (ObjFile *obj : ObjFile::instances) {
>> + for (ObjFile *obj : ctx.objFileInstances) {
>> ArrayRef<Symbol *> syms = obj->getSymbols();
>> if (obj->addrsigSec) {
>> ArrayRef<uint8_t> contents;
>> @@ -1169,7 +1161,7 @@ static void parsePDBAltPath(StringRef altPath) {
>> void LinkerDriver::convertResources() {
>> std::vector<ObjFile *> resourceObjFiles;
>>
>> - for (ObjFile *f : ObjFile::instances) {
>> + for (ObjFile *f : ctx.objFileInstances) {
>> if (f->isResourceObjFile())
>> resourceObjFiles.push_back(f);
>> }
>> @@ -1191,8 +1183,9 @@ void LinkerDriver::convertResources() {
>> f->includeResourceChunks();
>> return;
>> }
>> - ObjFile *f = make<ObjFile>(convertResToCOFF(resources,
>> resourceObjFiles));
>> - symtab->addFile(f);
>> + ObjFile *f =
>> + make<ObjFile>(ctx, convertResToCOFF(resources, resourceObjFiles));
>> + ctx.symtab.addFile(f);
>> f->includeResourceChunks();
>> }
>>
>> @@ -1219,9 +1212,9 @@ void LinkerDriver::maybeExportMinGWSymbols(const
>> opt::InputArgList &args) {
>> if (Optional<StringRef> path = doFindFile(arg->getValue()))
>> exporter.addWholeArchive(*path);
>>
>> - symtab->forEachSymbol([&](Symbol *s) {
>> + ctx.symtab.forEachSymbol([&](Symbol *s) {
>> auto *def = dyn_cast<Defined>(s);
>> - if (!exporter.shouldExport(def))
>> + if (!exporter.shouldExport(ctx, def))
>> return;
>>
>> if (!def->isGCRoot) {
>> @@ -1266,7 +1259,7 @@ Optional<std::string> getReproduceFile(const
>> opt::InputArgList &args) {
>> }
>>
>> void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
>> - ScopedTimer rootTimer(Timer::root());
>> + ScopedTimer rootTimer(ctx.rootTimer);
>>
>> // Needed for LTO.
>> InitializeAllTargetInfos();
>> @@ -2018,32 +2011,32 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> if (config->imageBase == uint64_t(-1))
>> config->imageBase = getDefaultImageBase();
>>
>> - symtab->addSynthetic(mangle("__ImageBase"), nullptr);
>> + ctx.symtab.addSynthetic(mangle("__ImageBase"), nullptr);
>> if (config->machine == I386) {
>> - symtab->addAbsolute("___safe_se_handler_table", 0);
>> - symtab->addAbsolute("___safe_se_handler_count", 0);
>> + ctx.symtab.addAbsolute("___safe_se_handler_table", 0);
>> + ctx.symtab.addAbsolute("___safe_se_handler_count", 0);
>> }
>>
>> - symtab->addAbsolute(mangle("__guard_fids_count"), 0);
>> - symtab->addAbsolute(mangle("__guard_fids_table"), 0);
>> - symtab->addAbsolute(mangle("__guard_flags"), 0);
>> - symtab->addAbsolute(mangle("__guard_iat_count"), 0);
>> - symtab->addAbsolute(mangle("__guard_iat_table"), 0);
>> - symtab->addAbsolute(mangle("__guard_longjmp_count"), 0);
>> - symtab->addAbsolute(mangle("__guard_longjmp_table"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_fids_count"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_fids_table"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_flags"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_iat_count"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_iat_table"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_longjmp_count"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_longjmp_table"), 0);
>> // Needed for MSVC 2017 15.5 CRT.
>> - symtab->addAbsolute(mangle("__enclave_config"), 0);
>> + ctx.symtab.addAbsolute(mangle("__enclave_config"), 0);
>> // Needed for MSVC 2019 16.8 CRT.
>> - symtab->addAbsolute(mangle("__guard_eh_cont_count"), 0);
>> - symtab->addAbsolute(mangle("__guard_eh_cont_table"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_eh_cont_count"), 0);
>> + ctx.symtab.addAbsolute(mangle("__guard_eh_cont_table"), 0);
>>
>> if (config->pseudoRelocs) {
>> - symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
>> - symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
>> + ctx.symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
>> + ctx.symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"),
>> 0);
>> }
>> if (config->mingw) {
>> - symtab->addAbsolute(mangle("__CTOR_LIST__"), 0);
>> - symtab->addAbsolute(mangle("__DTOR_LIST__"), 0);
>> + ctx.symtab.addAbsolute(mangle("__CTOR_LIST__"), 0);
>> + ctx.symtab.addAbsolute(mangle("__DTOR_LIST__"), 0);
>> }
>>
>> // This code may add new undefined symbols to the link, which may
>> enqueue more
>> @@ -2069,12 +2062,12 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> for (auto pair : config->alternateNames) {
>> StringRef from = pair.first;
>> StringRef to = pair.second;
>> - Symbol *sym = symtab->find(from);
>> + Symbol *sym = ctx.symtab.find(from);
>> if (!sym)
>> continue;
>> if (auto *u = dyn_cast<Undefined>(sym))
>> if (!u->weakAlias)
>> - u->weakAlias = symtab->addUndefined(to);
>> + u->weakAlias = ctx.symtab.addUndefined(to);
>> }
>>
>> // If any inputs are bitcode files, the LTO code generator may create
>> @@ -2082,25 +2075,25 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> // file's symbol table. If any of those library functions are
>> defined in a
>> // bitcode file in an archive member, we need to arrange to use LTO
>> to
>> // compile those archive members by adding them to the link
>> beforehand.
>> - if (!BitcodeFile::instances.empty())
>> + if (!ctx.bitcodeFileInstances.empty())
>> for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
>> - symtab->addLibcall(s);
>> + ctx.symtab.addLibcall(s);
>>
>> // Windows specific -- if __load_config_used can be resolved,
>> resolve it.
>> - if (symtab->findUnderscore("_load_config_used"))
>> + if (ctx.symtab.findUnderscore("_load_config_used"))
>> addUndefined(mangle("_load_config_used"));
>> } while (run());
>>
>> if (args.hasArg(OPT_include_optional)) {
>> // Handle /includeoptional
>> for (auto *arg : args.filtered(OPT_include_optional))
>> - if (dyn_cast_or_null<LazyArchive>(symtab->find(arg->getValue())))
>> + if
>> (dyn_cast_or_null<LazyArchive>(ctx.symtab.find(arg->getValue())))
>> addUndefined(arg->getValue());
>> while (run());
>> }
>>
>> // Create wrapped symbols for -wrap option.
>> - std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
>> + std::vector<WrappedSymbol> wrapped = addWrappedSymbols(ctx, args);
>> // Load more object files that might be needed for wrapped symbols.
>> if (!wrapped.empty())
>> while (run());
>> @@ -2126,7 +2119,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> // If it ends up pulling in more object files from static libraries,
>> // (and maybe doing more stdcall fixups along the way), this would
>> need
>> // to loop these two calls.
>> - symtab->loadMinGWSymbols();
>> + ctx.symtab.loadMinGWSymbols();
>> run();
>> }
>>
>> @@ -2134,8 +2127,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> // If we are going to do codegen for link-time optimization, check for
>> // unresolvable symbols first, so we don't spend time generating code
>> that
>> // will fail to link anyway.
>> - if (!BitcodeFile::instances.empty() && !config->forceUnresolved)
>> - symtab->reportUnresolvable();
>> + if (!ctx.bitcodeFileInstances.empty() && !config->forceUnresolved)
>> + ctx.symtab.reportUnresolvable();
>> if (errorCount())
>> return;
>>
>> @@ -2149,7 +2142,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> // Do LTO by compiling bitcode input files to a set of native COFF
>> files then
>> // link those files (unless -thinlto-index-only was given, in which
>> case we
>> // resolve symbols and write indices, but don't generate native code
>> or link).
>> - symtab->addCombinedLTOObjects();
>> + ctx.symtab.addCombinedLTOObjects();
>>
>> // If -thinlto-index-only is given, we should create only "index
>> // files" and not object files. Index file creation is already done
>> @@ -2163,10 +2156,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>>
>> // Apply symbol renames for -wrap.
>> if (!wrapped.empty())
>> - wrapSymbols(wrapped);
>> + wrapSymbols(ctx, wrapped);
>>
>> // Resolve remaining undefined symbols and warn about imported locals.
>> - symtab->resolveRemainingUndefines();
>> + ctx.symtab.resolveRemainingUndefines();
>> if (errorCount())
>> return;
>>
>> @@ -2177,12 +2170,12 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> // order provided on the command line, while lld will pull in needed
>> // files from static libraries only after the last object file on the
>> // command line.
>> - for (auto i = ObjFile::instances.begin(), e =
>> ObjFile::instances.end();
>> + for (auto i = ctx.objFileInstances.begin(), e =
>> ctx.objFileInstances.end();
>> i != e; i++) {
>> ObjFile *file = *i;
>> if (isCrtend(file->getName())) {
>> - ObjFile::instances.erase(i);
>> - ObjFile::instances.push_back(file);
>> + ctx.objFileInstances.erase(i);
>> + ctx.objFileInstances.push_back(file);
>> break;
>> }
>> }
>> @@ -2207,7 +2200,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> StringRef name = pair.first;
>> uint32_t alignment = pair.second;
>>
>> - Symbol *sym = symtab->find(name);
>> + Symbol *sym = ctx.symtab.find(name);
>> if (!sym) {
>> warn("/aligncomm symbol " + name + " not found");
>> continue;
>> @@ -2239,16 +2232,16 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> if (auto *arg = args.getLastArg(OPT_order)) {
>> if (args.hasArg(OPT_call_graph_ordering_file))
>> error("/order and /call-graph-order-file may not be used
>> together");
>> - parseOrderFile(arg->getValue());
>> + parseOrderFile(ctx, arg->getValue());
>> config->callGraphProfileSort = false;
>> }
>>
>> // Handle /call-graph-ordering-file and /call-graph-profile-sort
>> (default on).
>> if (config->callGraphProfileSort) {
>> if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file)) {
>> - parseCallGraphFile(arg->getValue());
>> + parseCallGraphFile(ctx, arg->getValue());
>> }
>> - readCallGraphsFromObjectFiles();
>> + readCallGraphsFromObjectFiles(ctx);
>> }
>>
>> // Handle /print-symbol-order.
>> @@ -2265,7 +2258,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> // functions. This doesn't bring in more object files, but only
>> marks
>> // functions that already have been included to be retained.
>> for (const char *n : {"__gxx_personality_v0",
>> "__gcc_personality_v0"}) {
>> - Defined *d =
>> dyn_cast_or_null<Defined>(symtab->findUnderscore(n));
>> + Defined *d =
>> dyn_cast_or_null<Defined>(ctx.symtab.findUnderscore(n));
>> if (d && !d->isGCRoot) {
>> d->isGCRoot = true;
>> config->gcroot.push_back(d);
>> @@ -2273,7 +2266,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>> }
>> }
>>
>> - markLive(symtab->getChunks());
>> + markLive(ctx);
>> }
>>
>> // Needs to happen after the last call to addFile().
>> @@ -2281,17 +2274,17 @@ void LinkerDriver::linkerMain(ArrayRef<const char
>> *> argsArr) {
>>
>> // Identify identical COMDAT sections to merge them.
>> if (config->doICF != ICFLevel::None) {
>> - findKeepUniqueSections();
>> - doICF(symtab->getChunks(), config->doICF);
>> + findKeepUniqueSections(ctx);
>> + doICF(ctx, config->doICF);
>> }
>>
>> // Write the result.
>> - writeResult();
>> + writeResult(ctx);
>>
>> // Stop early so we can print the results.
>> rootTimer.stop();
>> if (config->showTiming)
>> - Timer::root().print();
>> + ctx.rootTimer.print();
>> }
>>
>> } // namespace coff
>>
>> diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
>> index 5729bed69528b..7c2fbe3c7d64c 100644
>> --- a/lld/COFF/Driver.h
>> +++ b/lld/COFF/Driver.h
>> @@ -9,6 +9,7 @@
>> #ifndef LLD_COFF_DRIVER_H
>> #define LLD_COFF_DRIVER_H
>>
>> +#include "COFFLinkerContext.h"
>> #include "Config.h"
>> #include "SymbolTable.h"
>> #include "lld/Common/LLVM.h"
>> @@ -78,6 +79,8 @@ class ArgParser {
>>
>> class LinkerDriver {
>> public:
>> + LinkerDriver(COFFLinkerContext &c) : ctx(c) {}
>> +
>> void linkerMain(llvm::ArrayRef<const char *> args);
>>
>> // Used by the resolver to parse .drectve section contents.
>> @@ -103,6 +106,8 @@ class LinkerDriver {
>> StringRef doFindLib(StringRef filename);
>> StringRef doFindLibMinGW(StringRef filename);
>>
>> + bool findUnderscoreMangle(StringRef sym);
>> +
>> // Parses LIB environment which contains a list of search paths.
>> void addLibSearchPaths();
>>
>> @@ -148,6 +153,8 @@ class LinkerDriver {
>> std::vector<MemoryBufferRef> resources;
>>
>> llvm::StringSet<> directivesExports;
>> +
>> + COFFLinkerContext &ctx;
>> };
>>
>> // Functions below this line are defined in DriverUtils.cpp.
>>
>> diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp
>> index 7326469672968..8323626623948 100644
>> --- a/lld/COFF/ICF.cpp
>> +++ b/lld/COFF/ICF.cpp
>> @@ -18,6 +18,7 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "ICF.h"
>> +#include "COFFLinkerContext.h"
>> #include "Chunks.h"
>> #include "Symbols.h"
>> #include "lld/Common/ErrorHandler.h"
>> @@ -36,12 +37,10 @@ using namespace llvm;
>> namespace lld {
>> namespace coff {
>>
>> -static Timer icfTimer("ICF", Timer::root());
>> -
>> class ICF {
>> public:
>> - ICF(ICFLevel icfLevel) : icfLevel(icfLevel){};
>> - void run(ArrayRef<Chunk *> v);
>> + ICF(COFFLinkerContext &c, ICFLevel icfLevel) : icfLevel(icfLevel),
>> ctx(c){};
>> + void run();
>>
>> private:
>> void segregate(size_t begin, size_t end, bool constant);
>> @@ -64,6 +63,8 @@ class ICF {
>> int cnt = 0;
>> std::atomic<bool> repeat = {false};
>> ICFLevel icfLevel = ICFLevel::All;
>> +
>> + COFFLinkerContext &ctx;
>> };
>>
>> // Returns true if section S is subject of ICF.
>> @@ -246,12 +247,12 @@ void ICF::forEachClass(std::function<void(size_t,
>> size_t)> fn) {
>> // Merge identical COMDAT sections.
>> // Two sections are considered the same if their section headers,
>> // contents and relocations are all the same.
>> -void ICF::run(ArrayRef<Chunk *> vec) {
>> - ScopedTimer t(icfTimer);
>> +void ICF::run() {
>> + ScopedTimer t(ctx.icfTimer);
>>
>> // Collect only mergeable sections and group by hash value.
>> uint32_t nextId = 1;
>> - for (Chunk *c : vec) {
>> + for (Chunk *c : ctx.symtab.getChunks()) {
>> if (auto *sc = dyn_cast<SectionChunk>(c)) {
>> if (isEligible(sc))
>> chunks.push_back(sc);
>> @@ -262,7 +263,7 @@ void ICF::run(ArrayRef<Chunk *> vec) {
>>
>> // Make sure that ICF doesn't merge sections that are being handled by
>> string
>> // tail merging.
>> - for (MergeChunk *mc : MergeChunk::instances)
>> + for (MergeChunk *mc : ctx.mergeChunkInstances)
>> if (mc)
>> for (SectionChunk *sc : mc->sections)
>> sc->eqClass[0] = nextId++;
>> @@ -317,8 +318,8 @@ void ICF::run(ArrayRef<Chunk *> vec) {
>> }
>>
>> // Entry point to ICF.
>> -void doICF(ArrayRef<Chunk *> chunks, ICFLevel icfLevel) {
>> - ICF(icfLevel).run(chunks);
>> +void doICF(COFFLinkerContext &ctx, ICFLevel icfLevel) {
>> + ICF(ctx, icfLevel).run();
>> }
>>
>> } // namespace coff
>>
>> diff --git a/lld/COFF/ICF.h b/lld/COFF/ICF.h
>> index f8cc8071f9eb7..10e6792a5418f 100644
>> --- a/lld/COFF/ICF.h
>> +++ b/lld/COFF/ICF.h
>> @@ -17,8 +17,9 @@ namespace lld {
>> namespace coff {
>>
>> class Chunk;
>> +class COFFLinkerContext;
>>
>> -void doICF(ArrayRef<Chunk *> chunks, ICFLevel);
>> +void doICF(COFFLinkerContext &ctx, ICFLevel);
>>
>> } // namespace coff
>> } // namespace lld
>>
>> diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
>> index f32353ca4f94a..4b38e3d1a99bc 100644
>> --- a/lld/COFF/InputFiles.cpp
>> +++ b/lld/COFF/InputFiles.cpp
>> @@ -7,6 +7,7 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "InputFiles.h"
>> +#include "COFFLinkerContext.h"
>> #include "Chunks.h"
>> #include "Config.h"
>> #include "DebugTypes.h"
>> @@ -69,11 +70,6 @@ std::string lld::toString(const coff::InputFile *file)
>> {
>> .str();
>> }
>>
>> -std::vector<ObjFile *> ObjFile::instances;
>> -std::map<std::string, PDBInputFile *> PDBInputFile::instances;
>> -std::vector<ImportFile *> ImportFile::instances;
>> -std::vector<BitcodeFile *> BitcodeFile::instances;
>> -
>> /// 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.
>> @@ -98,7 +94,8 @@ static bool ignoredSymbolName(StringRef name) {
>> return name == "@feat.00" || name == "@comp.id";
>> }
>>
>> -ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m)
>> {}
>> +ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)
>> + : InputFile(ctx, ArchiveKind, m) {}
>>
>> void ArchiveFile::parse() {
>> // Parse a MemoryBufferRef as an archive file.
>> @@ -106,7 +103,7 @@ void ArchiveFile::parse() {
>>
>> // Read the symbol table to construct Lazy objects.
>> for (const Archive::Symbol &sym : file->symbols())
>> - symtab->addLazyArchive(this, sym);
>> + ctx.symtab.addLazyArchive(this, sym);
>> }
>>
>> // Returns a buffer pointing to a member file containing a given symbol.
>> @@ -144,11 +141,11 @@ void LazyObjFile::fetch() {
>>
>> InputFile *file;
>> if (isBitcode(mb))
>> - file = make<BitcodeFile>(mb, "", 0, std::move(symbols));
>> + file = make<BitcodeFile>(ctx, mb, "", 0, std::move(symbols));
>> else
>> - file = make<ObjFile>(mb, std::move(symbols));
>> + file = make<ObjFile>(ctx, mb, std::move(symbols));
>> mb = {};
>> - symtab->addFile(file);
>> + ctx.symtab.addFile(file);
>> }
>>
>> void LazyObjFile::parse() {
>> @@ -158,7 +155,7 @@ void LazyObjFile::parse() {
>> CHECK(lto::InputFile::create(this->mb), this);
>> for (const lto::InputFile::Symbol &sym : obj->symbols()) {
>> if (!sym.isUndefined())
>> - symtab->addLazyObject(this, sym.getName());
>> + ctx.symtab.addLazyObject(this, sym.getName());
>> }
>> return;
>> }
>> @@ -175,7 +172,7 @@ void LazyObjFile::parse() {
>> StringRef name = check(coffObj->getSymbolName(coffSym));
>> if (coffSym.isAbsolute() && ignoredSymbolName(name))
>> continue;
>> - symtab->addLazyObject(this, name);
>> + ctx.symtab.addLazyObject(this, name);
>> i += coffSym.getNumberOfAuxSymbols();
>> }
>> }
>> @@ -293,7 +290,7 @@ SectionChunk *ObjFile::readSection(uint32_t
>> sectionNumber,
>> // 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(c);
>> + MergeChunk::addSection(ctx, c);
>> else if (name == ".rsrc" || name.startswith(".rsrc$"))
>> resourceChunks.push_back(c);
>> else
>> @@ -387,8 +384,8 @@ Symbol *ObjFile::createRegular(COFFSymbolRef sym) {
>> if (sym.isExternal()) {
>> StringRef name = check(coffObj->getSymbolName(sym));
>> if (sc)
>> - return symtab->addRegular(this, name, sym.getGeneric(), sc,
>> - sym.getValue());
>> + return ctx.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
>> @@ -396,7 +393,7 @@ Symbol *ObjFile::createRegular(COFFSymbolRef sym) {
>> // references at the end.
>> if (config->mingw && name.startswith(".weak."))
>> return nullptr;
>> - return symtab->addUndefined(name, this, false);
>> + return ctx.symtab.addUndefined(name, this, false);
>> }
>> if (sc)
>> return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
>> @@ -464,7 +461,7 @@ void ObjFile::initializeSymbols() {
>> for (auto &kv : weakAliases) {
>> Symbol *sym = kv.first;
>> uint32_t idx = kv.second;
>> - checkAndSetWeakAlias(symtab, this, sym, symbols[idx]);
>> + checkAndSetWeakAlias(&ctx.symtab, this, sym, symbols[idx]);
>> }
>>
>> // Free the memory used by sparseChunks now that symbol loading is
>> finished.
>> @@ -473,7 +470,7 @@ void ObjFile::initializeSymbols() {
>>
>> Symbol *ObjFile::createUndefined(COFFSymbolRef sym) {
>> StringRef name = check(coffObj->getSymbolName(sym));
>> - return symtab->addUndefined(name, this, sym.isWeakExternal());
>> + return ctx.symtab.addUndefined(name, this, sym.isWeakExternal());
>> }
>>
>> static const coff_aux_section_definition *findSectionDef(COFFObjectFile
>> *obj,
>> @@ -543,13 +540,13 @@ void ObjFile::handleComdatSelection(
>> Twine((int)leaderSelection) + " in " +
>> toString(leader->getFile()) +
>> " and " + Twine((int)selection) + " in " + toString(this))
>> .str());
>> - symtab->reportDuplicate(leader, this);
>> + ctx.symtab.reportDuplicate(leader, this);
>> return;
>> }
>>
>> switch (selection) {
>> case IMAGE_COMDAT_SELECT_NODUPLICATES:
>> - symtab->reportDuplicate(leader, this);
>> + ctx.symtab.reportDuplicate(leader, this);
>> break;
>>
>> case IMAGE_COMDAT_SELECT_ANY:
>> @@ -559,14 +556,14 @@ void ObjFile::handleComdatSelection(
>> case IMAGE_COMDAT_SELECT_SAME_SIZE:
>> if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) {
>> if (!config->mingw) {
>> - symtab->reportDuplicate(leader, this);
>> + ctx.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)
>> - symtab->reportDuplicate(leader, this);
>> + ctx.symtab.reportDuplicate(leader, this);
>> }
>> }
>> break;
>> @@ -577,7 +574,7 @@ void ObjFile::handleComdatSelection(
>> // if the two comdat sections have e.g.
>> diff erent alignment.
>> // Match that.
>> if (leaderChunk->getContents() != newChunk.getContents())
>> - symtab->reportDuplicate(leader, this, &newChunk, sym.getValue());
>> + ctx.symtab.reportDuplicate(leader, this, &newChunk,
>> sym.getValue());
>> break;
>> }
>>
>> @@ -620,8 +617,8 @@ Optional<Symbol *> ObjFile::createDefined(
>> if (sym.isCommon()) {
>> auto *c = make<CommonChunk>(sym);
>> chunks.push_back(c);
>> - return symtab->addCommon(this, getName(), sym.getValue(),
>> sym.getGeneric(),
>> - c);
>> + return ctx.symtab.addCommon(this, getName(), sym.getValue(),
>> + sym.getGeneric(), c);
>> }
>>
>> if (sym.isAbsolute()) {
>> @@ -634,7 +631,7 @@ Optional<Symbol *> ObjFile::createDefined(
>> return nullptr;
>>
>> if (sym.isExternal())
>> - return symtab->addAbsolute(name, sym);
>> + return ctx.symtab.addAbsolute(name, sym);
>> return make<DefinedAbsolute>(name, sym);
>> }
>>
>> @@ -667,7 +664,7 @@ Optional<Symbol *> ObjFile::createDefined(
>>
>> if (sym.isExternal()) {
>> std::tie(leader, prevailing) =
>> - symtab->addComdat(this, getName(), sym.getGeneric());
>> + ctx.symtab.addComdat(this, getName(), sym.getGeneric());
>> } else {
>> leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/
>> false,
>> /*IsExternal*/ false,
>> sym.getGeneric());
>> @@ -789,12 +786,11 @@ void ObjFile::initializeDependencies() {
>> else
>> data = getDebugSection(".debug$T");
>>
>> - // Don't make a TpiSource for objects with no debug info. If the
>> object has
>> // symbols but no types, make a plain, empty TpiSource anyway, because
>> it
>> // simplifies adding the symbols later.
>> if (data.empty()) {
>> if (!debugChunks.empty())
>> - debugTypesObj = makeTpiSource(this);
>> + debugTypesObj = makeTpiSource(ctx, this);
>> return;
>> }
>>
>> @@ -812,7 +808,7 @@ void ObjFile::initializeDependencies() {
>>
>> // This object file is a PCH file that others will depend on.
>> if (isPCH) {
>> - debugTypesObj = makePrecompSource(this);
>> + debugTypesObj = makePrecompSource(ctx, this);
>> return;
>> }
>>
>> @@ -820,8 +816,8 @@ void ObjFile::initializeDependencies() {
>> if (firstType->kind() == LF_TYPESERVER2) {
>> TypeServer2Record ts = cantFail(
>>
>> TypeDeserializer::deserializeAs<TypeServer2Record>(firstType->data()));
>> - debugTypesObj = makeUseTypeServerSource(this, ts);
>> - PDBInputFile::enqueue(ts.getName(), this);
>> + debugTypesObj = makeUseTypeServerSource(ctx, this, ts);
>> + enqueuePdbFile(ts.getName(), this);
>> return;
>> }
>>
>> @@ -830,14 +826,14 @@ void ObjFile::initializeDependencies() {
>> if (firstType->kind() == LF_PRECOMP) {
>> PrecompRecord precomp = cantFail(
>>
>> TypeDeserializer::deserializeAs<PrecompRecord>(firstType->data()));
>> - debugTypesObj = makeUsePrecompSource(this, precomp);
>> + debugTypesObj = makeUsePrecompSource(ctx, this, precomp);
>> // Drop the LF_PRECOMP record from the input stream.
>> debugTypes = debugTypes.drop_front(firstType->RecordData.size());
>> return;
>> }
>>
>> // This is a plain old object file.
>> - debugTypesObj = makeTpiSource(this);
>> + debugTypesObj = makeTpiSource(ctx, this);
>> }
>>
>> // Make a PDB path assuming the PDB is in the same folder as the OBJ
>> @@ -855,7 +851,7 @@ static std::string getPdbBaseName(ObjFile *file,
>> StringRef tSPath) {
>>
>> // The casing of the PDB path stamped in the OBJ can
>> diff er from the actual path
>> // on disk. With this, we ensure to always use lowercase as a key for the
>> -// PDBInputFile::instances map, at least on Windows.
>> +// pdbInputFileInstances map, at least on Windows.
>> static std::string normalizePdbPath(StringRef path) {
>> #if defined(_WIN32)
>> return path.lower();
>> @@ -879,33 +875,25 @@ static Optional<std::string> findPdbPath(StringRef
>> pdbPath,
>> return None;
>> }
>>
>> -PDBInputFile::PDBInputFile(MemoryBufferRef m) : InputFile(PDBKind, m) {}
>> +PDBInputFile::PDBInputFile(COFFLinkerContext &ctx, MemoryBufferRef m)
>> + : InputFile(ctx, PDBKind, m) {}
>>
>> PDBInputFile::~PDBInputFile() = default;
>>
>> -PDBInputFile *PDBInputFile::findFromRecordPath(StringRef path,
>> +PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext
>> &ctx,
>> + StringRef path,
>> ObjFile *fromFile) {
>> auto p = findPdbPath(path.str(), fromFile);
>> if (!p)
>> return nullptr;
>> - auto it = PDBInputFile::instances.find(*p);
>> - if (it != PDBInputFile::instances.end())
>> + auto it = ctx.pdbInputFileInstances.find(*p);
>> + if (it != ctx.pdbInputFileInstances.end())
>> return it->second;
>> return nullptr;
>> }
>>
>> -void PDBInputFile::enqueue(StringRef path, ObjFile *fromFile) {
>> - auto p = findPdbPath(path.str(), fromFile);
>> - if (!p)
>> - return;
>> - auto it = PDBInputFile::instances.emplace(*p, nullptr);
>> - if (!it.second)
>> - return; // already scheduled for load
>> - driver->enqueuePDB(*p);
>> -}
>> -
>> void PDBInputFile::parse() {
>> - PDBInputFile::instances[mb.getBufferIdentifier().str()] = this;
>> + ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this;
>>
>> std::unique_ptr<pdb::IPDBSession> thisSession;
>> loadErr.emplace(pdb::NativeSession::createFromPdb(
>> @@ -923,7 +911,7 @@ void PDBInputFile::parse() {
>> loadErr.emplace(expectedInfo.takeError());
>> return;
>> }
>> - debugTypesObj = makeTypeServerSource(this);
>> + debugTypesObj = makeTypeServerSource(ctx, this);
>> }
>>
>> // Used only for DWARF debug info, which is not common (except in MinGW
>> @@ -957,6 +945,16 @@ Optional<DILineInfo> ObjFile::getDILineInfo(uint32_t
>> offset,
>> return dwarf->getDILineInfo(offset, sectionIndex);
>> }
>>
>> +void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
>> + auto p = findPdbPath(path.str(), fromFile);
>> + if (!p)
>> + return;
>> + auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr);
>> + if (!it.second)
>> + return; // already scheduled for load
>> + driver->enqueuePDB(*p);
>> +}
>> +
>> void ImportFile::parse() {
>> const char *buf = mb.getBufferStart();
>> const auto *hdr = reinterpret_cast<const coff_import_header *>(buf);
>> @@ -990,31 +988,31 @@ void ImportFile::parse() {
>> this->hdr = hdr;
>> externalName = extName;
>>
>> - impSym = symtab->addImportData(impName, this);
>> + impSym = ctx.symtab.addImportData(impName, this);
>> // If this was a duplicate, we logged an error but may continue;
>> // in this case, impSym is nullptr.
>> if (!impSym)
>> return;
>>
>> if (hdr->getType() == llvm::COFF::IMPORT_CONST)
>> - static_cast<void>(symtab->addImportData(name, this));
>> + static_cast<void>(ctx.symtab.addImportData(name, this));
>>
>> // 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 (hdr->getType() == llvm::COFF::IMPORT_CODE)
>> - thunkSym = symtab->addImportThunk(
>> + thunkSym = ctx.symtab.addImportThunk(
>> name, cast_or_null<DefinedImportData>(impSym), hdr->Machine);
>> }
>>
>> -BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
>> - uint64_t offsetInArchive)
>> - : BitcodeFile(mb, archiveName, offsetInArchive, {}) {}
>> +BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
>> + StringRef archiveName, uint64_t offsetInArchive)
>> + : BitcodeFile(ctx, mb, archiveName, offsetInArchive, {}) {}
>>
>> -BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
>> - uint64_t offsetInArchive,
>> +BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
>> + StringRef archiveName, uint64_t offsetInArchive,
>> std::vector<Symbol *> &&symbols)
>> - : InputFile(BitcodeKind, mb), symbols(std::move(symbols)) {
>> + : InputFile(ctx, BitcodeKind, mb), symbols(std::move(symbols)) {
>> std::string path = mb.getBufferIdentifier().str();
>> if (config->thinLTOIndexOnly)
>> path = replaceThinLTOSuffix(mb.getBufferIdentifier());
>> @@ -1069,7 +1067,7 @@ void BitcodeFile::parse() {
>> for (size_t i = 0; i != obj->getComdatTable().size(); ++i)
>> // FIXME: Check nodeduplicate
>> comdat[i] =
>> - symtab->addComdat(this,
>> saver.save(obj->getComdatTable()[i].first));
>> + ctx.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();
>> @@ -1080,27 +1078,27 @@ void BitcodeFile::parse() {
>> else
>> fakeSC = <oDataSectionChunk.chunk;
>> if (objSym.isUndefined()) {
>> - sym = symtab->addUndefined(symName, this, false);
>> + sym = ctx.symtab.addUndefined(symName, this, false);
>> } else if (objSym.isCommon()) {
>> - sym = symtab->addCommon(this, symName, objSym.getCommonSize());
>> + sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize());
>> } else if (objSym.isWeak() && objSym.isIndirect()) {
>> // Weak external.
>> - sym = symtab->addUndefined(symName, this, true);
>> + sym = ctx.symtab.addUndefined(symName, this, true);
>> std::string fallback =
>> std::string(objSym.getCOFFWeakExternalFallback());
>> - Symbol *alias = symtab->addUndefined(saver.save(fallback));
>> - checkAndSetWeakAlias(symtab, this, sym, alias);
>> + Symbol *alias = ctx.symtab.addUndefined(saver.save(fallback));
>> + checkAndSetWeakAlias(&ctx.symtab, this, sym, alias);
>> } 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 = symtab->addRegular(this, symName, nullptr, fakeSC);
>> + sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC);
>> } else {
>> - sym = symtab->addUndefined(symName, this, false);
>> + sym = ctx.symtab.addUndefined(symName, this, false);
>> }
>> } else {
>> - sym = symtab->addRegular(this, symName, nullptr, fakeSC);
>> + sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC);
>> }
>> symbols.push_back(sym);
>> if (objSym.isUsed())
>> @@ -1185,9 +1183,9 @@ void DLLFile::parse() {
>> }
>>
>> StringRef impName = saver.save("__imp_" + symbolName);
>> - symtab->addLazyDLLSymbol(this, s, impName);
>> + ctx.symtab.addLazyDLLSymbol(this, s, impName);
>> if (code)
>> - symtab->addLazyDLLSymbol(this, s, symbolName);
>> + ctx.symtab.addLazyDLLSymbol(this, s, symbolName);
>> }
>> }
>>
>> @@ -1219,6 +1217,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>(mbref);
>> - symtab->addFile(impFile);
>> + ImportFile *impFile = make<ImportFile>(ctx, mbref);
>> + ctx.symtab.addFile(impFile);
>> }
>>
>> diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
>> index 47b5c588c5af7..801c668d3ae45 100644
>> --- a/lld/COFF/InputFiles.h
>> +++ b/lld/COFF/InputFiles.h
>> @@ -38,6 +38,7 @@ namespace lld {
>> class DWARFCache;
>>
>> namespace coff {
>> +class COFFLinkerContext;
>>
>> std::vector<MemoryBufferRef> getArchiveMembers(llvm::object::Archive
>> *file);
>>
>> @@ -91,8 +92,11 @@ class InputFile {
>> // Returns .drectve section contents if exist.
>> StringRef getDirectives() { return directives; }
>>
>> + COFFLinkerContext &ctx;
>> +
>> protected:
>> - InputFile(Kind k, MemoryBufferRef m) : mb(m), fileKind(k) {}
>> + InputFile(COFFLinkerContext &c, Kind k, MemoryBufferRef m)
>> + : mb(m), ctx(c), fileKind(k) {}
>>
>> StringRef directives;
>>
>> @@ -103,7 +107,7 @@ class InputFile {
>> // .lib or .a file.
>> class ArchiveFile : public InputFile {
>> public:
>> - explicit ArchiveFile(MemoryBufferRef m);
>> + explicit ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m);
>> static bool classof(const InputFile *f) { return f->kind() ==
>> ArchiveKind; }
>> void parse() override;
>>
>> @@ -120,7 +124,8 @@ class ArchiveFile : public InputFile {
>> // .obj or .o file between -start-lib and -end-lib.
>> class LazyObjFile : public InputFile {
>> public:
>> - explicit LazyObjFile(MemoryBufferRef m) : InputFile(LazyObjectKind, m)
>> {}
>> + explicit LazyObjFile(COFFLinkerContext &ctx, MemoryBufferRef m)
>> + : InputFile(ctx, LazyObjectKind, m) {}
>> static bool classof(const InputFile *f) {
>> return f->kind() == LazyObjectKind;
>> }
>> @@ -136,9 +141,11 @@ class LazyObjFile : public InputFile {
>> // .obj or .o file. This may be a member of an archive file.
>> class ObjFile : public InputFile {
>> public:
>> - explicit ObjFile(MemoryBufferRef m) : InputFile(ObjectKind, m) {}
>> - explicit ObjFile(MemoryBufferRef m, std::vector<Symbol *> &&symbols)
>> - : InputFile(ObjectKind, m), symbols(std::move(symbols)) {}
>> + explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m)
>> + : InputFile(ctx, ObjectKind, m) {}
>> + explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m,
>> + std::vector<Symbol *> &&symbols)
>> + : InputFile(ctx, ObjectKind, m), symbols(std::move(symbols)) {}
>> static bool classof(const InputFile *f) { return f->kind() ==
>> ObjectKind; }
>> void parse() override;
>> MachineTypes getMachineType() override;
>> @@ -175,8 +182,6 @@ class ObjFile : public InputFile {
>>
>> bool isResourceObjFile() const { return !resourceChunks.empty(); }
>>
>> - static std::vector<ObjFile *> instances;
>> -
>> // Flags in the absolute @feat.00 symbol if it is present. These
>> usually
>> // indicate if an object was compiled with certain security features
>> enabled
>> // like stack guard, safeseh, /guard:cf, or other things.
>> @@ -228,6 +233,8 @@ class ObjFile : public InputFile {
>> return getSection(sym.getSectionNumber());
>> }
>>
>> + void enqueuePdbFile(StringRef path, ObjFile *fromFile);
>> +
>> void initializeChunks();
>> void initializeSymbols();
>> void initializeFlags();
>> @@ -318,16 +325,13 @@ class ObjFile : public InputFile {
>> // stream.
>> class PDBInputFile : public InputFile {
>> public:
>> - explicit PDBInputFile(MemoryBufferRef m);
>> + explicit PDBInputFile(COFFLinkerContext &ctx, MemoryBufferRef m);
>> ~PDBInputFile();
>> static bool classof(const InputFile *f) { return f->kind() == PDBKind;
>> }
>> void parse() override;
>>
>> - static void enqueue(StringRef path, ObjFile *fromFile);
>> -
>> - static PDBInputFile *findFromRecordPath(StringRef path, ObjFile
>> *fromFile);
>> -
>> - static std::map<std::string, PDBInputFile *> instances;
>> + static PDBInputFile *findFromRecordPath(const COFFLinkerContext &ctx,
>> + StringRef path, ObjFile
>> *fromFile);
>>
>> // Record possible errors while opening the PDB file
>> llvm::Optional<Error> loadErr;
>> @@ -344,12 +348,11 @@ class PDBInputFile : public InputFile {
>> // for details about the format.
>> class ImportFile : public InputFile {
>> public:
>> - explicit ImportFile(MemoryBufferRef m) : InputFile(ImportKind, m) {}
>> + explicit ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)
>> + : InputFile(ctx, ImportKind, m) {}
>>
>> static bool classof(const InputFile *f) { return f->kind() ==
>> ImportKind; }
>>
>> - static std::vector<ImportFile *> instances;
>> -
>> Symbol *impSym = nullptr;
>> Symbol *thunkSym = nullptr;
>> std::string dllName;
>> @@ -377,16 +380,15 @@ class ImportFile : public InputFile {
>> // Used for LTO.
>> class BitcodeFile : public InputFile {
>> public:
>> - BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
>> + BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb, StringRef
>> archiveName,
>> uint64_t offsetInArchive);
>> - explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName,
>> - uint64_t offsetInArchive,
>> + explicit BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef m,
>> + StringRef archiveName, uint64_t offsetInArchive,
>> std::vector<Symbol *> &&symbols);
>> ~BitcodeFile();
>> static bool classof(const InputFile *f) { return f->kind() ==
>> BitcodeKind; }
>> ArrayRef<Symbol *> getSymbols() { return symbols; }
>> MachineTypes getMachineType() override;
>> - static std::vector<BitcodeFile *> instances;
>> std::unique_ptr<llvm::lto::InputFile> obj;
>>
>> private:
>> @@ -398,7 +400,8 @@ class BitcodeFile : public InputFile {
>> // .dll file. MinGW only.
>> class DLLFile : public InputFile {
>> public:
>> - explicit DLLFile(MemoryBufferRef m) : InputFile(DLLKind, m) {}
>> + explicit DLLFile(COFFLinkerContext &ctx, MemoryBufferRef m)
>> + : InputFile(ctx, DLLKind, m) {}
>> static bool classof(const InputFile *f) { return f->kind() == DLLKind;
>> }
>> void parse() override;
>> MachineTypes getMachineType() override;
>>
>> diff --git a/lld/COFF/LLDMapFile.cpp b/lld/COFF/LLDMapFile.cpp
>> index 79df33a3535fd..639b186dbb6f9 100644
>> --- a/lld/COFF/LLDMapFile.cpp
>> +++ b/lld/COFF/LLDMapFile.cpp
>> @@ -19,6 +19,7 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "LLDMapFile.h"
>> +#include "COFFLinkerContext.h"
>> #include "SymbolTable.h"
>> #include "Symbols.h"
>> #include "Writer.h"
>> @@ -44,9 +45,9 @@ static void writeHeader(raw_ostream &os, uint64_t addr,
>> uint64_t size,
>> }
>>
>> // Returns a list of all symbols that we want to print out.
>> -static std::vector<DefinedRegular *> getSymbols() {
>> +static std::vector<DefinedRegular *> getSymbols(const COFFLinkerContext
>> &ctx) {
>> std::vector<DefinedRegular *> v;
>> - for (ObjFile *file : ObjFile::instances)
>> + for (ObjFile *file : ctx.objFileInstances)
>> for (Symbol *b : file->getSymbols())
>> if (auto *sym = dyn_cast_or_null<DefinedRegular>(b))
>> if (sym && !sym->getCOFFSymbol().isSectionDefinition())
>> @@ -86,7 +87,7 @@ getSymbolStrings(ArrayRef<DefinedRegular *> syms) {
>> return ret;
>> }
>>
>> -void lld::coff::writeLLDMapFile(ArrayRef<OutputSection *>
>> outputSections) {
>> +void lld::coff::writeLLDMapFile(const COFFLinkerContext &ctx) {
>> if (config->lldmapFile.empty())
>> return;
>>
>> @@ -96,7 +97,7 @@ void lld::coff::writeLLDMapFile(ArrayRef<OutputSection
>> *> outputSections) {
>> fatal("cannot open " + config->lldmapFile + ": " + ec.message());
>>
>> // Collect symbol info that we want to print out.
>> - std::vector<DefinedRegular *> syms = getSymbols();
>> + std::vector<DefinedRegular *> syms = getSymbols(ctx);
>> SymbolMapTy sectionSyms = getSectionSyms(syms);
>> DenseMap<DefinedRegular *, std::string> symStr =
>> getSymbolStrings(syms);
>>
>> @@ -104,7 +105,7 @@ void
>> lld::coff::writeLLDMapFile(ArrayRef<OutputSection *> outputSections) {
>> os << "Address Size Align Out In Symbol\n";
>>
>> // Print out file contents.
>> - for (OutputSection *sec : outputSections) {
>> + for (OutputSection *sec : ctx.outputSections) {
>> writeHeader(os, sec->getRVA(), sec->getVirtualSize(),
>> /*align=*/pageSize);
>> os << sec->name << '\n';
>>
>>
>> diff --git a/lld/COFF/LLDMapFile.h b/lld/COFF/LLDMapFile.h
>> index b731293a8625d..72e999a61900a 100644
>> --- a/lld/COFF/LLDMapFile.h
>> +++ b/lld/COFF/LLDMapFile.h
>> @@ -9,12 +9,10 @@
>> #ifndef LLD_COFF_LLDMAPFILE_H
>> #define LLD_COFF_LLDMAPFILE_H
>>
>> -#include "llvm/ADT/ArrayRef.h"
>> -
>> namespace lld {
>> namespace coff {
>> -class OutputSection;
>> -void writeLLDMapFile(llvm::ArrayRef<OutputSection *> outputSections);
>> +class COFFLinkerContext;
>> +void writeLLDMapFile(const COFFLinkerContext &ctx);
>> }
>> }
>>
>>
>> diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
>> index 6e38f53f21362..ce9c4fd0d51b2 100644
>> --- a/lld/COFF/LTO.cpp
>> +++ b/lld/COFF/LTO.cpp
>> @@ -156,7 +156,7 @@ void BitcodeCompiler::add(BitcodeFile &f) {
>>
>> // Merge all the bitcode files we have seen, codegen the
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210917/5784f33c/attachment-0001.html>
More information about the llvm-commits
mailing list