diff --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp index f61a9269d6a41..ae473284ef0b4 100644 --- a/lld/ELF/AArch64ErrataFix.cpp +++ b/lld/ELF/AArch64ErrataFix.cpp @@ -439,7 +439,7 @@ void AArch64Err843419Patcher::init() { }; // Collect mapping symbols for every executable InputSection. - for (ELFFileBase *file : ctx->objectFiles) { + for (ELFFileBase *file : ctx.objectFiles) { for (Symbol *b : file->getLocalSymbols()) { auto *def = dyn_cast(b); if (!def) diff --git a/lld/ELF/ARMErrataFix.cpp b/lld/ELF/ARMErrataFix.cpp index 1cebbba55b4a6..375d138da6255 100644 --- a/lld/ELF/ARMErrataFix.cpp +++ b/lld/ELF/ARMErrataFix.cpp @@ -327,7 +327,7 @@ void ARMErr657417Patcher::init() { }; // Collect mapping symbols for every executable InputSection. - for (ELFFileBase *file : ctx->objectFiles) { + for (ELFFileBase *file : ctx.objectFiles) { for (Symbol *s : file->getLocalSymbols()) { auto *def = dyn_cast(s); if (!def) diff --git a/lld/ELF/Arch/AMDGPU.cpp b/lld/ELF/Arch/AMDGPU.cpp index 0368f82c6a653..461f320173621 100644 --- a/lld/ELF/Arch/AMDGPU.cpp +++ b/lld/ELF/Arch/AMDGPU.cpp @@ -48,10 +48,10 @@ static uint32_t getEFlags(InputFile *file) { } uint32_t AMDGPU::calcEFlagsV3() const { - uint32_t ret = getEFlags(ctx->objectFiles[0]); + uint32_t ret = getEFlags(ctx.objectFiles[0]); // Verify that all input files have the same e_flags. - for (InputFile *f : makeArrayRef(ctx->objectFiles).slice(1)) { + for (InputFile *f : makeArrayRef(ctx.objectFiles).slice(1)) { if (ret == getEFlags(f)) continue; error("incompatible e_flags: " + toString(f)); @@ -61,15 +61,15 @@ uint32_t AMDGPU::calcEFlagsV3() const { } uint32_t AMDGPU::calcEFlagsV4() const { - uint32_t retMach = getEFlags(ctx->objectFiles[0]) & EF_AMDGPU_MACH; + uint32_t retMach = getEFlags(ctx.objectFiles[0]) & EF_AMDGPU_MACH; uint32_t retXnack = - getEFlags(ctx->objectFiles[0]) & EF_AMDGPU_FEATURE_XNACK_V4; + getEFlags(ctx.objectFiles[0]) & EF_AMDGPU_FEATURE_XNACK_V4; uint32_t retSramEcc = - getEFlags(ctx->objectFiles[0]) & EF_AMDGPU_FEATURE_SRAMECC_V4; + getEFlags(ctx.objectFiles[0]) & EF_AMDGPU_FEATURE_SRAMECC_V4; // Verify that all input files have compatible e_flags (same mach, all // features in the same category are either ANY, ANY and ON, or ANY and OFF). - for (InputFile *f : makeArrayRef(ctx->objectFiles).slice(1)) { + for (InputFile *f : makeArrayRef(ctx.objectFiles).slice(1)) { if (retMach != (getEFlags(f) & EF_AMDGPU_MACH)) { error("incompatible mach: " + toString(f)); return 0; @@ -106,10 +106,10 @@ uint32_t AMDGPU::calcEFlagsV4() const { } uint32_t AMDGPU::calcEFlags() const { - if (ctx->objectFiles.empty()) + if (ctx.objectFiles.empty()) return 0; - uint8_t abiVersion = cast>(ctx->objectFiles[0]) + uint8_t abiVersion = cast>(ctx.objectFiles[0]) ->getObj() .getHeader() .e_ident[EI_ABIVERSION]; diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp index d972f8e8fdea8..ae01ebc0ea5c9 100644 --- a/lld/ELF/Arch/AVR.cpp +++ b/lld/ELF/Arch/AVR.cpp @@ -226,12 +226,12 @@ static uint32_t getEFlags(InputFile *file) { } uint32_t AVR::calcEFlags() const { - assert(!ctx->objectFiles.empty()); + assert(!ctx.objectFiles.empty()); - uint32_t flags = getEFlags(ctx->objectFiles[0]); + uint32_t flags = getEFlags(ctx.objectFiles[0]); bool hasLinkRelaxFlag = flags & EF_AVR_LINKRELAX_PREPARED; - for (InputFile *f : makeArrayRef(ctx->objectFiles).slice(1)) { + for (InputFile *f : makeArrayRef(ctx.objectFiles).slice(1)) { uint32_t objFlags = getEFlags(f); if ((objFlags & EF_AVR_ARCH_MASK) != (flags & EF_AVR_ARCH_MASK)) error(toString(f) + diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp index 6bca4070629ec..567ef0b4370ba 100644 --- a/lld/ELF/Arch/Hexagon.cpp +++ b/lld/ELF/Arch/Hexagon.cpp @@ -59,12 +59,12 @@ Hexagon::Hexagon() { } uint32_t Hexagon::calcEFlags() const { - assert(!ctx->objectFiles.empty()); + assert(!ctx.objectFiles.empty()); // The architecture revision must always be equal to or greater than // greatest revision in the list of inputs. uint32_t ret = 0; - for (InputFile *f : ctx->objectFiles) { + for (InputFile *f : ctx.objectFiles) { uint32_t eflags = cast>(f)->getObj().getHeader().e_flags; if (eflags > ret) ret = eflags; diff --git a/lld/ELF/Arch/MipsArchTree.cpp b/lld/ELF/Arch/MipsArchTree.cpp index f1fcf1610cb10..44661731a3e2f 100644 --- a/lld/ELF/Arch/MipsArchTree.cpp +++ b/lld/ELF/Arch/MipsArchTree.cpp @@ -295,7 +295,7 @@ static uint32_t getArchFlags(ArrayRef files) { template uint32_t elf::calcMipsEFlags() { std::vector v; - for (InputFile *f : ctx->objectFiles) + for (InputFile *f : ctx.objectFiles) v.push_back({f, cast>(f)->getObj().getHeader().e_flags}); if (v.empty()) { // If we don't have any input files, we'll have to rely on the information diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 1b4a7bac5655f..febcbe6bb2457 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -622,7 +622,7 @@ static uint32_t getEFlags(InputFile *file) { // This file implements v2 ABI. This function makes sure that all // object files have v2 or an unspecified version as an ABI version. uint32_t PPC64::calcEFlags() const { - for (InputFile *f : ctx->objectFiles) { + for (InputFile *f : ctx.objectFiles) { uint32_t flag = getEFlags(f); if (flag == 1) error(toString(f) + ": ABI version 1 is not supported"); diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index 95e4b3a629887..347784bb080df 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -128,12 +128,12 @@ static uint32_t getEFlags(InputFile *f) { uint32_t RISCV::calcEFlags() const { // If there are only binary input files (from -b binary), use a // value of 0 for the ELF header flags. - if (ctx->objectFiles.empty()) + if (ctx.objectFiles.empty()) return 0; - uint32_t target = getEFlags(ctx->objectFiles.front()); + uint32_t target = getEFlags(ctx.objectFiles.front()); - for (InputFile *f : ctx->objectFiles) { + for (InputFile *f : ctx.objectFiles) { uint32_t eflags = getEFlags(f); if (eflags & EF_RISCV_RVC) target |= EF_RISCV_RVC; @@ -142,7 +142,7 @@ uint32_t RISCV::calcEFlags() const { error( toString(f) + ": cannot link object files with different floating-point ABI from " + - toString(ctx->objectFiles[0])); + toString(ctx.objectFiles[0])); if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE)) error(toString(f) + @@ -524,7 +524,7 @@ static void initSymbolAnchors() { } // Store anchors (st_value and st_value+st_size) for symbols relative to text // sections. - for (InputFile *file : ctx->objectFiles) + for (InputFile *file : ctx.objectFiles) for (Symbol *sym : file->getSymbols()) { auto *d = dyn_cast(sym); if (!d || d->file != file) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index ac25fc677c664..9b84669922269 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -395,10 +395,6 @@ struct Ctx { // Symbols in a non-prevailing COMDAT group which should be changed to an // Undefined. SmallVector, 0> nonPrevailingSyms; - // True if SHT_LLVM_SYMPART is used. - std::atomic hasSympart{false}; - // True if we need to reserve two .got entries for local-dynamic TLS model. - std::atomic needsTlsLd{false}; // A tuple of (reference, extractedFile, sym). Used by --why-extract=. SmallVector, 0> whyExtractRecords; @@ -407,10 +403,15 @@ struct Ctx { llvm::DenseMap> backwardReferences; + // True if SHT_LLVM_SYMPART is used. + std::atomic hasSympart{false}; + // True if we need to reserve two .got entries for local-dynamic TLS model. + std::atomic needsTlsLd{false}; + + void reset(); }; -// The only instance of Ctx struct. -extern std::unique_ptr ctx; +LLVM_LIBRARY_VISIBILITY extern Ctx ctx; // The first two elements of versionDefinitions represent VER_NDX_LOCAL and // VER_NDX_GLOBAL. This helper returns other elements. diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 3b9d457f4a73e..904c0004d066b 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -74,7 +74,7 @@ using namespace lld; using namespace lld::elf; ConfigWrapper elf::config; -std::unique_ptr elf::ctx; +Ctx elf::ctx; std::unique_ptr elf::driver; static void setConfigs(opt::InputArgList &args); @@ -87,6 +87,21 @@ void elf::errorOrWarn(const Twine &msg) { error(msg); } +void Ctx::reset() { + memoryBuffers.clear(); + objectFiles.clear(); + sharedFiles.clear(); + binaryFiles.clear(); + bitcodeFiles.clear(); + lazyBitcodeFiles.clear(); + duplicates.clear(); + nonPrevailingSyms.clear(); + whyExtractRecords.clear(); + backwardReferences.clear(); + hasSympart.store(false, std::memory_order_relaxed); + needsTlsLd.store(false, std::memory_order_relaxed); +} + bool elf::link(ArrayRef args, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) { @@ -95,6 +110,8 @@ bool elf::link(ArrayRef args, llvm::raw_ostream &stdoutOS, ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput); ctx->e.cleanupCallback = []() { + elf::ctx.reset(); + inputSections.clear(); ehInputSections.clear(); outputSections.clear(); @@ -113,7 +130,6 @@ bool elf::link(ArrayRef args, llvm::raw_ostream &stdoutOS, "--error-limit=0 to see all errors)"; config = ConfigWrapper(); - elf::ctx = std::make_unique(); driver = std::make_unique(); script = std::make_unique(); symtab = std::make_unique(); @@ -195,7 +211,7 @@ std::vector> static getArchiveMembers( // Take ownership of memory buffers created for members of thin archives. std::vector> mbs = file->takeThinBuffers(); - std::move(mbs.begin(), mbs.end(), std::back_inserter(ctx->memoryBuffers)); + std::move(mbs.begin(), mbs.end(), std::back_inserter(ctx.memoryBuffers)); return v; } @@ -845,7 +861,7 @@ static std::pair getPackDynRelocs(opt::InputArgList &args) { static void readCallGraph(MemoryBufferRef mb) { // Build a map from symbol name to section DenseMap map; - for (ELFFileBase *file : ctx->objectFiles) + for (ELFFileBase *file : ctx.objectFiles) for (Symbol *sym : file->getSymbols()) map[sym->getName()] = sym; @@ -924,7 +940,7 @@ processCallGraphRelocations(SmallVector &symbolIndices, template static void readCallGraphsFromObjectFiles() { SmallVector symbolIndices; ArrayRef cgProfile; - for (auto file : ctx->objectFiles) { + for (auto file : ctx.objectFiles) { auto *obj = cast>(file); if (!processCallGraphRelocations(symbolIndices, cgProfile, obj)) continue; @@ -1788,10 +1804,10 @@ static void excludeLibs(opt::InputArgList &args) { sym->versionId = VER_NDX_LOCAL; }; - for (ELFFileBase *file : ctx->objectFiles) + for (ELFFileBase *file : ctx.objectFiles) visit(file); - for (BitcodeFile *file : ctx->bitcodeFiles) + for (BitcodeFile *file : ctx.bitcodeFiles) visit(file); } @@ -1805,7 +1821,7 @@ static void handleUndefined(Symbol *sym, const char *option) { return; sym->extract(); if (!config->whyExtract.empty()) - ctx->whyExtractRecords.emplace_back(option, sym->file, *sym); + ctx.whyExtractRecords.emplace_back(option, sym->file, *sym); } // As an extension to GNU linkers, lld supports a variant of `-u` @@ -1857,10 +1873,10 @@ static void writeArchiveStats() { SmallVector archives; DenseMap all, extracted; - for (ELFFileBase *file : ctx->objectFiles) + for (ELFFileBase *file : ctx.objectFiles) if (file->archiveName.size()) ++extracted[CachedHashStringRef(file->archiveName)]; - for (BitcodeFile *file : ctx->bitcodeFiles) + for (BitcodeFile *file : ctx.bitcodeFiles) if (file->archiveName.size()) ++extracted[CachedHashStringRef(file->archiveName)]; for (std::pair f : driver->archiveFiles) { @@ -1884,14 +1900,14 @@ static void writeWhyExtract() { } os << "reference\textracted\tsymbol\n"; - for (auto &entry : ctx->whyExtractRecords) { + for (auto &entry : ctx.whyExtractRecords) { os << std::get<0>(entry) << '\t' << toString(std::get<1>(entry)) << '\t' << toString(std::get<2>(entry)) << '\n'; } } static void reportBackrefs() { - for (auto &ref : ctx->backwardReferences) { + for (auto &ref : ctx.backwardReferences) { const Symbol &sym = *ref.first; std::string to = toString(ref.second.second); // Some libraries have known problems and can cause noise. Filter them out @@ -1984,7 +2000,7 @@ static void writeDependencyFile() { // symbols of type CommonSymbol. static void replaceCommonSymbols() { llvm::TimeTraceScope timeScope("Replace common symbols"); - for (ELFFileBase *file : ctx->objectFiles) { + for (ELFFileBase *file : ctx.objectFiles) { if (!file->hasCommonSyms) continue; for (Symbol *sym : file->getGlobalSymbols()) { @@ -2059,7 +2075,7 @@ static void findKeepUniqueSections(opt::InputArgList &args) { // Visit the address-significance table in each object file and mark each // referenced symbol as address-significant. - for (InputFile *f : ctx->objectFiles) { + for (InputFile *f : ctx.objectFiles) { auto *obj = cast>(f); ArrayRef syms = obj->getSymbols(); if (obj->addrsigSec) { @@ -2145,18 +2161,18 @@ static void markBuffersAsDontNeed(bool skipLinkedOutput) { // buffers as MADV_DONTNEED so that these pages can be reused by the expensive // thin link, saving memory. if (skipLinkedOutput) { - for (MemoryBuffer &mb : llvm::make_pointee_range(ctx->memoryBuffers)) + for (MemoryBuffer &mb : llvm::make_pointee_range(ctx.memoryBuffers)) mb.dontNeedIfMmap(); return; } // Otherwise, just mark MemoryBuffers backing BitcodeFiles. DenseSet bufs; - for (BitcodeFile *file : ctx->bitcodeFiles) + for (BitcodeFile *file : ctx.bitcodeFiles) bufs.insert(file->mb.getBufferStart()); - for (BitcodeFile *file : ctx->lazyBitcodeFiles) + for (BitcodeFile *file : ctx.lazyBitcodeFiles) bufs.insert(file->mb.getBufferStart()); - for (MemoryBuffer &mb : llvm::make_pointee_range(ctx->memoryBuffers)) + for (MemoryBuffer &mb : llvm::make_pointee_range(ctx.memoryBuffers)) if (bufs.count(mb.getBufferStart())) mb.dontNeedIfMmap(); } @@ -2173,10 +2189,10 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) { llvm::TimeTraceScope timeScope("LTO"); // Compile bitcode files and replace bitcode symbols. lto.reset(new BitcodeCompiler); - for (BitcodeFile *file : ctx->bitcodeFiles) + for (BitcodeFile *file : ctx.bitcodeFiles) lto->add(*file); - if (!ctx->bitcodeFiles.empty()) + if (!ctx.bitcodeFiles.empty()) markBuffersAsDontNeed(skipLinkedOutput); for (InputFile *file : lto->compile()) { @@ -2188,7 +2204,7 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) { for (Symbol *sym : obj->getGlobalSymbols()) if (sym->hasVersionSuffix) sym->parseSymbolVersion(); - ctx->objectFiles.push_back(obj); + ctx.objectFiles.push_back(obj); } } @@ -2324,7 +2340,7 @@ static void redirectSymbols(ArrayRef wrapped) { return; // Update pointers in input files. - parallelForEach(ctx->objectFiles, [&](ELFFileBase *file) { + parallelForEach(ctx.objectFiles, [&](ELFFileBase *file) { for (Symbol *&sym : file->getMutableGlobalSymbols()) if (Symbol *s = map.lookup(sym)) sym = s; @@ -2359,7 +2375,7 @@ static uint32_t getAndFeatures() { return 0; uint32_t ret = -1; - for (ELFFileBase *f : ctx->objectFiles) { + for (ELFFileBase *f : ctx.objectFiles) { uint32_t features = f->andFeatures; checkAndReportMissingFeature( @@ -2512,7 +2528,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // We also need one if any shared libraries are used and for pie executables // (probably because the dynamic linker needs it). config->hasDynSymTab = - !ctx->sharedFiles.empty() || config->isPic || config->exportDynamic; + !ctx.sharedFiles.empty() || config->isPic || config->exportDynamic; // Some symbols (such as __ehdr_start) are defined lazily only when there // are undefined symbols for them, so we add these to trigger that logic. @@ -2558,7 +2574,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // to, i.e. if the symbol's definition is in bitcode. Any other required // libcall symbols will be added to the link after LTO when we add the LTO // object file to the link. - if (!ctx->bitcodeFiles.empty()) + if (!ctx.bitcodeFiles.empty()) for (auto *s : lto::LTO::getRuntimeLibcallSymbols()) handleLibcall(s); @@ -2567,23 +2583,23 @@ void LinkerDriver::link(opt::InputArgList &args) { // No more lazy bitcode can be extracted at this point. Do post parse work // like checking duplicate symbols. - parallelForEach(ctx->objectFiles, [](ELFFileBase *file) { + parallelForEach(ctx.objectFiles, [](ELFFileBase *file) { initSectionsAndLocalSyms(file, /*ignoreComdats=*/false); }); - parallelForEach(ctx->objectFiles, postParseObjectFile); - parallelForEach(ctx->bitcodeFiles, + parallelForEach(ctx.objectFiles, postParseObjectFile); + parallelForEach(ctx.bitcodeFiles, [](BitcodeFile *file) { file->postParse(); }); - for (auto &it : ctx->nonPrevailingSyms) { + for (auto &it : ctx.nonPrevailingSyms) { Symbol &sym = *it.first; Undefined(sym.file, sym.getName(), sym.binding, sym.stOther, sym.type, it.second) .overwrite(sym); cast(sym).nonPrevailing = true; } - ctx->nonPrevailingSyms.clear(); - for (const DuplicateSymbol &d : ctx->duplicates) + ctx.nonPrevailingSyms.clear(); + for (const DuplicateSymbol &d : ctx.duplicates) reportDuplicate(*d.sym, d.file, d.section, d.value); - ctx->duplicates.clear(); + ctx.duplicates.clear(); // Return if there were name resolution errors. if (errorCount()) @@ -2636,7 +2652,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // // With this the symbol table should be complete. After this, no new names // except a few linker-synthesized ones will be added to the symbol table. - const size_t numObjsBeforeLTO = ctx->objectFiles.size(); + const size_t numObjsBeforeLTO = ctx.objectFiles.size(); invokeELFT(compileBitcodeFiles, skipLinkedOutput); // Symbol resolution finished. Report backward reference problems, @@ -2653,12 +2669,12 @@ void LinkerDriver::link(opt::InputArgList &args) { // compileBitcodeFiles may have produced lto.tmp object files. After this, no // more file will be added. - auto newObjectFiles = makeArrayRef(ctx->objectFiles).slice(numObjsBeforeLTO); + auto newObjectFiles = makeArrayRef(ctx.objectFiles).slice(numObjsBeforeLTO); parallelForEach(newObjectFiles, [](ELFFileBase *file) { initSectionsAndLocalSyms(file, /*ignoreComdats=*/true); }); parallelForEach(newObjectFiles, postParseObjectFile); - for (const DuplicateSymbol &d : ctx->duplicates) + for (const DuplicateSymbol &d : ctx.duplicates) reportDuplicate(*d.sym, d.file, d.section, d.value); // Handle --exclude-libs again because lto.tmp may reference additional @@ -2678,7 +2694,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // Now that we have a complete list of input files. // Beyond this point, no new files are added. // Aggregate all input sections into one place. - for (InputFile *f : ctx->objectFiles) { + for (InputFile *f : ctx.objectFiles) { for (InputSectionBase *s : f->getSections()) { if (!s || s == &InputSection::discarded) continue; @@ -2688,14 +2704,14 @@ void LinkerDriver::link(opt::InputArgList &args) { inputSections.push_back(s); } } - for (BinaryFile *f : ctx->binaryFiles) + for (BinaryFile *f : ctx.binaryFiles) for (InputSectionBase *s : f->getSections()) inputSections.push_back(cast(s)); } { llvm::TimeTraceScope timeScope("Strip sections"); - if (ctx->hasSympart.load(std::memory_order_relaxed)) { + if (ctx.hasSympart.load(std::memory_order_relaxed)) { llvm::erase_if(inputSections, [](InputSectionBase *s) { if (s->type != SHT_LLVM_SYMPART) return false; diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index 5cd399f4f3161..84c890f21b3ec 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -560,7 +560,7 @@ template void ICF::run() { }; for (Symbol *sym : symtab->getSymbols()) fold(sym); - parallelForEach(ctx->objectFiles, [&](ELFFileBase *file) { + parallelForEach(ctx.objectFiles, [&](ELFFileBase *file) { for (Symbol *sym : file->getLocalSymbols()) fold(sym); }); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index d5faefe64fde6..1c9003d51283b 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -206,7 +206,7 @@ Optional elf::readFile(StringRef path) { } MemoryBufferRef mbref = (*mbOrErr)->getMemBufferRef(); - ctx->memoryBuffers.push_back(std::move(*mbOrErr)); // take MB ownership + ctx.memoryBuffers.push_back(std::move(*mbOrErr)); // take MB ownership if (tar) tar->append(relativeToRoot(path), mbref.getBuffer()); @@ -235,12 +235,12 @@ static bool isCompatible(InputFile *file) { } InputFile *existing = nullptr; - if (!ctx->objectFiles.empty()) - existing = ctx->objectFiles[0]; - else if (!ctx->sharedFiles.empty()) - existing = ctx->sharedFiles[0]; - else if (!ctx->bitcodeFiles.empty()) - existing = ctx->bitcodeFiles[0]; + if (!ctx.objectFiles.empty()) + existing = ctx.objectFiles[0]; + else if (!ctx.sharedFiles.empty()) + existing = ctx.sharedFiles[0]; + else if (!ctx.bitcodeFiles.empty()) + existing = ctx.bitcodeFiles[0]; std::string with; if (existing) with = " with " + toString(existing); @@ -254,7 +254,7 @@ template static void doParseFile(InputFile *file) { // Binary file if (auto *f = dyn_cast(file)) { - ctx->binaryFiles.push_back(f); + ctx.binaryFiles.push_back(f); f->parse(); return; } @@ -262,7 +262,7 @@ template static void doParseFile(InputFile *file) { // Lazy object file if (file->lazy) { if (auto *f = dyn_cast(file)) { - ctx->lazyBitcodeFiles.push_back(f); + ctx.lazyBitcodeFiles.push_back(f); f->parseLazy(); } else { cast>(file)->parseLazy(); @@ -281,13 +281,13 @@ template static void doParseFile(InputFile *file) { // LLVM bitcode file if (auto *f = dyn_cast(file)) { - ctx->bitcodeFiles.push_back(f); + ctx.bitcodeFiles.push_back(f); f->parse(); return; } // Regular object file - ctx->objectFiles.push_back(cast(file)); + ctx.objectFiles.push_back(cast(file)); cast>(file)->parse(); } @@ -769,7 +769,7 @@ void ObjFile::initializeSections(bool ignoreComdats, case SHT_NULL: break; case SHT_LLVM_SYMPART: - ctx->hasSympart.store(true, std::memory_order_relaxed); + ctx.hasSympart.store(true, std::memory_order_relaxed); [[fallthrough]]; default: this->sections[i] = @@ -1179,7 +1179,7 @@ template void ObjFile::postParse() { } if (sym.file == this) { std::lock_guard lock(mu); - ctx->nonPrevailingSyms.emplace_back(&sym, secIdx); + ctx.nonPrevailingSyms.emplace_back(&sym, secIdx); } continue; } @@ -1192,7 +1192,7 @@ template void ObjFile::postParse() { if (binding == STB_WEAK) continue; std::lock_guard lock(mu); - ctx->duplicates.push_back({&sym, this, sec, eSym.st_value}); + ctx.duplicates.push_back({&sym, this, sec, eSym.st_value}); } } @@ -1422,7 +1422,7 @@ template void SharedFile::parse() { if (!wasInserted) return; - ctx->sharedFiles.push_back(this); + ctx.sharedFiles.push_back(this); verdefs = parseVerdefs(obj.base(), verdefSec); std::vector verneeds = parseVerneed(obj, verneedSec); diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index d10c0495db8e9..1e18b43201108 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -211,7 +211,7 @@ BitcodeCompiler::BitcodeCompiler() { config->ltoPartitions); // Initialize usedStartStop. - if (ctx->bitcodeFiles.empty()) + if (ctx.bitcodeFiles.empty()) return; for (Symbol *sym : symtab->getSymbols()) { if (sym->isPlaceholder()) @@ -293,10 +293,10 @@ void BitcodeCompiler::add(BitcodeFile &f) { // distributed build system that depends on that behavior. static void thinLTOCreateEmptyIndexFiles() { DenseSet linkedBitCodeFiles; - for (BitcodeFile *f : ctx->bitcodeFiles) + for (BitcodeFile *f : ctx.bitcodeFiles) linkedBitCodeFiles.insert(f->getName()); - for (BitcodeFile *f : ctx->lazyBitcodeFiles) { + for (BitcodeFile *f : ctx.lazyBitcodeFiles) { if (!f->lazy) continue; if (linkedBitCodeFiles.contains(f->getName())) @@ -332,7 +332,7 @@ std::vector BitcodeCompiler::compile() { files[task] = std::move(mb); })); - if (!ctx->bitcodeFiles.empty()) + if (!ctx.bitcodeFiles.empty()) checkError(ltoObj->run( [&](size_t task) { return std::make_unique( diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index ec1c90ee89949..03150881b9abf 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -55,7 +55,7 @@ static void writeHeader(raw_ostream &os, uint64_t vma, uint64_t lma, // Returns a list of all symbols that we want to print out. static std::vector getSymbols() { std::vector v; - for (ELFFileBase *file : ctx->objectFiles) + for (ELFFileBase *file : ctx.objectFiles) for (Symbol *b : file->getSymbols()) if (auto *dr = dyn_cast(b)) if (!dr->isSection() && dr->section && dr->section->isLive() && @@ -224,7 +224,7 @@ static void writeMapFile(raw_fd_ostream &os) { static void writeCref(raw_fd_ostream &os) { // Collect symbols and files. MapVector> map; - for (ELFFileBase *file : ctx->objectFiles) { + for (ELFFileBase *file : ctx.objectFiles) { for (Symbol *sym : file->getSymbols()) { if (isa(sym)) map[sym].insert(file); diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index d042f33dc2b61..80f0473d1f0fa 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -328,7 +328,7 @@ template void MarkLive::mark() { // to from __start_/__stop_ symbols because there will only be one set of // symbols for the whole program. template void MarkLive::moveToMain() { - for (ELFFileBase *file : ctx->objectFiles) + for (ELFFileBase *file : ctx.objectFiles) for (Symbol *s : file->getSymbols()) if (auto *d = dyn_cast(s)) if ((d->type == STT_GNU_IFUNC || d->type == STT_TLS) && d->section && diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 6c79d1a16337d..7bd0c17599699 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1237,7 +1237,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym, } if (expr == R_TLSLD_HINT) return 1; - ctx->needsTlsLd.store(true, std::memory_order_relaxed); + ctx.needsTlsLd.store(true, std::memory_order_relaxed); c.relocations.push_back({expr, type, offset, addend, &sym}); return 1; } @@ -1544,7 +1544,7 @@ template void elf::scanRelocations() { bool serial = !config->zCombreloc || config->emachine == EM_MIPS || config->emachine == EM_PPC64; parallel::TaskGroup tg; - for (ELFFileBase *f : ctx->objectFiles) { + for (ELFFileBase *f : ctx.objectFiles) { auto fn = [f]() { RelocationScanner scanner; for (InputSectionBase *s : f->getSections()) { @@ -1737,8 +1737,7 @@ void elf::postScanRelocations() { addTpOffsetGotEntry(sym); }; - if (ctx->needsTlsLd.load(std::memory_order_relaxed) && - in.got->addTlsIndex()) { + if (ctx.needsTlsLd.load(std::memory_order_relaxed) && in.got->addTlsIndex()) { static Undefined dummy(nullptr, "", STB_LOCAL, 0, 0); if (config->shared) mainPart->relaDyn->addReloc( @@ -1754,7 +1753,7 @@ void elf::postScanRelocations() { // Local symbols may need the aforementioned non-preemptible ifunc and GOT // handling. They don't need regular PLT. - for (ELFFileBase *file : ctx->objectFiles) + for (ELFFileBase *file : ctx.objectFiles) for (Symbol *sym : file->getLocalSymbols()) fn(*sym); } diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 90ce5048ea720..b5a62649528b6 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -304,7 +304,7 @@ void elf::printTraceSymbol(const Symbol &sym, StringRef name) { static void recordWhyExtract(const InputFile *reference, const InputFile &extracted, const Symbol &sym) { - ctx->whyExtractRecords.emplace_back(toString(reference), &extracted, sym); + ctx.whyExtractRecords.emplace_back(toString(reference), &extracted, sym); } void elf::maybeWarnUnorderableSymbol(const Symbol *sym) { @@ -477,8 +477,8 @@ void Symbol::resolve(const Undefined &other) { // definition. this->file needs to be saved because in the case of LTO it // may be reset to nullptr or be replaced with a file named lto.tmp. if (backref && !isWeak()) - ctx->backwardReferences.try_emplace(this, - std::make_pair(other.file, file)); + ctx.backwardReferences.try_emplace(this, + std::make_pair(other.file, file)); return; } @@ -622,7 +622,7 @@ void Symbol::resolve(const LazyObject &other) { // should be extracted as the canonical definition instead. if (LLVM_UNLIKELY(isCommon()) && elf::config->fortranCommon && other.file->shouldExtractForCommon(getName())) { - ctx->backwardReferences.erase(this); + ctx.backwardReferences.erase(this); other.overwrite(*this); other.extract(); return; @@ -631,7 +631,7 @@ void Symbol::resolve(const LazyObject &other) { if (!isUndefined()) { // See the comment in resolveUndefined(). if (isDefined()) - ctx->backwardReferences.erase(this); + ctx.backwardReferences.erase(this); return; } diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 24336fd50b51a..38cd166f2264e 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1306,7 +1306,7 @@ DynamicSection::computeContents() { addInt(config->enableNewDtags ? DT_RUNPATH : DT_RPATH, part.dynStrTab->addString(config->rpath)); - for (SharedFile *file : ctx->sharedFiles) + for (SharedFile *file : ctx.sharedFiles) if (file->isNeeded) addInt(DT_NEEDED, part.dynStrTab->addString(file->soName)); @@ -1475,7 +1475,7 @@ DynamicSection::computeContents() { if (part.verNeed && part.verNeed->isNeeded()) { addInSec(DT_VERNEED, *part.verNeed); unsigned needNum = 0; - for (SharedFile *f : ctx->sharedFiles) + for (SharedFile *f : ctx.sharedFiles) if (!f->vernauxs.empty()) ++needNum; addInt(DT_VERNEEDNUM, needNum); @@ -3127,7 +3127,7 @@ VersionNeedSection::VersionNeedSection() ".gnu.version_r") {} template void VersionNeedSection::finalizeContents() { - for (SharedFile *f : ctx->sharedFiles) { + for (SharedFile *f : ctx.sharedFiles) { if (f->vernauxs.empty()) continue; verneeds.emplace_back(); @@ -3295,7 +3295,7 @@ template void elf::splitSections() { llvm::TimeTraceScope timeScope("Split sections"); // splitIntoPieces needs to be called on each MergeInputSection // before calling finalizeContents(). - parallelForEach(ctx->objectFiles, [](ELFFileBase *file) { + parallelForEach(ctx.objectFiles, [](ELFFileBase *file) { for (InputSectionBase *sec : file->getSections()) { if (!sec) continue; @@ -3686,9 +3686,9 @@ static uint8_t getAbiVersion() { return 0; } - if (config->emachine == EM_AMDGPU && !ctx->objectFiles.empty()) { - uint8_t ver = ctx->objectFiles[0]->abiVersion; - for (InputFile *file : makeArrayRef(ctx->objectFiles).slice(1)) + if (config->emachine == EM_AMDGPU && !ctx.objectFiles.empty()) { + uint8_t ver = ctx.objectFiles[0]->abiVersion; + for (InputFile *file : makeArrayRef(ctx.objectFiles).slice(1)) if (file->abiVersion != ver) error("incompatible ABI version: " + toString(file)); return ver; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 57e0369e17d87..8428691ecebc0 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -611,7 +611,7 @@ template static void markUsedLocalSymbols() { // See MarkLive::resolveReloc(). if (config->gcSections) return; - for (ELFFileBase *file : ctx->objectFiles) { + for (ELFFileBase *file : ctx.objectFiles) { ObjFile *f = cast>(file); for (InputSectionBase *s : f->getSections()) { InputSection *isec = dyn_cast_or_null(s); @@ -682,7 +682,7 @@ template void Writer::copyLocalSymbols() { llvm::TimeTraceScope timeScope("Add local symbols"); if (config->copyRelocs && config->discard != DiscardPolicy::None) markUsedLocalSymbols(); - for (ELFFileBase *file : ctx->objectFiles) { + for (ELFFileBase *file : ctx.objectFiles) { for (Symbol *b : file->getLocalSymbols()) { assert(b->isLocal() && "should have been caught in initializeSymbols()"); auto *dr = dyn_cast(b); @@ -1281,7 +1281,7 @@ static DenseMap buildSectionOrder() { for (Symbol *sym : symtab->getSymbols()) addSym(*sym); - for (ELFFileBase *file : ctx->objectFiles) + for (ELFFileBase *file : ctx.objectFiles) for (Symbol *sym : file->getLocalSymbols()) addSym(*sym); @@ -1697,7 +1697,7 @@ template void Writer::finalizeAddressDependentContent() { // block sections, input sections can shrink when the jump instructions at // the end of the section are relaxed. static void fixSymbolsAfterShrinking() { - for (InputFile *File : ctx->objectFiles) { + for (InputFile *File : ctx.objectFiles) { parallelForEach(File->getSymbols(), [&](Symbol *Sym) { auto *def = dyn_cast(Sym); if (!def) @@ -1934,7 +1934,7 @@ template void Writer::finalizeSections() { // ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to // catch more cases. That is too much for us. Our approach resembles the one // used in ld.gold, achieves a good balance to be useful but not too smart. - for (SharedFile *file : ctx->sharedFiles) { + for (SharedFile *file : ctx.sharedFiles) { bool allNeededIsKnown = llvm::all_of(file->dtNeeded, [&](StringRef needed) { return symtab->soNames.count(CachedHashStringRef(needed));