diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 8f43fc996a8cbe..418f689cee2167 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -196,17 +196,17 @@ void LinkerScript::setDot(Expr e, const Twine &loc, bool inSec) { // Used for handling linker symbol assignments, for both finalizing // their values and doing early declarations. Returns true if symbol // should be defined from linker script. -static bool shouldDefineSym(SymbolAssignment *cmd) { +static bool shouldDefineSym(Ctx &ctx, SymbolAssignment *cmd) { if (cmd->name == ".") return false; - return !cmd->provide || LinkerScript::shouldAddProvideSym(cmd->name); + return !cmd->provide || LinkerScript::shouldAddProvideSym(ctx, cmd->name); } // Called by processSymbolAssignments() to assign definitions to // linker-script-defined symbols. void LinkerScript::addSymbol(SymbolAssignment *cmd) { - if (!shouldDefineSym(cmd)) + if (!shouldDefineSym(ctx, cmd)) return; // Define a symbol. @@ -240,7 +240,7 @@ void LinkerScript::addSymbol(SymbolAssignment *cmd) { // This function is called from LinkerScript::declareSymbols. // It creates a placeholder symbol if needed. void LinkerScript::declareSymbol(SymbolAssignment *cmd) { - if (!shouldDefineSym(cmd)) + if (!shouldDefineSym(ctx, cmd)) return; uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT; @@ -1798,7 +1798,7 @@ void LinkerScript::addScriptReferencedSymbolsToSymTable() { DenseSet added; SmallVector *, 0> symRefsVec; for (const auto &[name, symRefs] : provideMap) - if (LinkerScript::shouldAddProvideSym(name) && added.insert(name).second) + if (shouldAddProvideSym(ctx, name) && added.insert(name).second) symRefsVec.push_back(&symRefs); while (symRefsVec.size()) { for (StringRef name : *symRefsVec.pop_back_val()) { @@ -1806,7 +1806,7 @@ void LinkerScript::addScriptReferencedSymbolsToSymTable() { // Prevent the symbol from being discarded by --gc-sections. referencedSymbols.push_back(name); auto it = provideMap.find(name); - if (it != provideMap.end() && shouldAddProvideSym(name) && + if (it != provideMap.end() && shouldAddProvideSym(ctx, name) && added.insert(name).second) { symRefsVec.push_back(&it->second); } @@ -1814,14 +1814,14 @@ void LinkerScript::addScriptReferencedSymbolsToSymTable() { } } -bool LinkerScript::shouldAddProvideSym(StringRef symName) { +bool LinkerScript::shouldAddProvideSym(Ctx &ctx, StringRef symName) { // This function is called before and after garbage collection. To prevent // undefined references from the RHS, the result of this function for a // symbol must be the same for each call. We use isUsedInRegularObj to not // change the return value of a demoted symbol. The exportDynamic condition, // while not so accurate, allows PROVIDE to define a symbol referenced by a // DSO. - Symbol *sym = elf::ctx.symtab->find(symName); + Symbol *sym = ctx.symtab->find(symName); return sym && !sym->isDefined() && !sym->isCommon() && (sym->isUsedInRegularObj || sym->exportDynamic); } diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 4aa030a37fc0f4..eda152dd3582ab 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -389,7 +389,7 @@ class LinkerScript final { // Returns true if the PROVIDE symbol should be added to the link. // A PROVIDE symbol is added to the link only if it satisfies an // undefined reference. - static bool shouldAddProvideSym(StringRef symName); + static bool shouldAddProvideSym(Ctx &, StringRef symName); // SECTIONS command list. SmallVector sectionCommands; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 4865bf3ab8477a..73c19c8385a824 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -917,7 +917,7 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, } template -static void addPltEntry(PltSection &plt, GotPltSection &gotPlt, +static void addPltEntry(Ctx &ctx, PltSection &plt, GotPltSection &gotPlt, RelocationBaseSection &rel, RelType type, Symbol &sym) { plt.addEntry(sym); gotPlt.addEntry(sym); @@ -1756,7 +1756,7 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) { directSym->allocateAux(ctx); auto &dyn = ctx.arg.androidPackDynRelocs ? *ctx.in.relaPlt : *ctx.mainPart->relaDyn; - addPltEntry(*ctx.in.iplt, *ctx.in.igotPlt, dyn, ctx.target->iRelativeRel, + addPltEntry(ctx, *ctx.in.iplt, *ctx.in.igotPlt, dyn, ctx.target->iRelativeRel, *directSym); sym.allocateAux(ctx); ctx.symAux.back().pltIdx = ctx.symAux[directSym->auxIdx].pltIdx; @@ -1796,7 +1796,7 @@ void elf::postScanRelocations(Ctx &ctx) { if (flags & NEEDS_GOT) addGotEntry(ctx, sym); if (flags & NEEDS_PLT) - addPltEntry(*ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt, + addPltEntry(ctx, *ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt, ctx.target->pltRel, sym); if (flags & NEEDS_COPY) { if (sym.isObject()) { @@ -2427,7 +2427,7 @@ void elf::hexagonTLSSymbolUpdate(Ctx &ctx) { if (rel.sym->type == llvm::ELF::STT_TLS && rel.expr == R_PLT_PC) { if (needEntry) { sym->allocateAux(ctx); - addPltEntry(*ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt, + addPltEntry(ctx, *ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt, ctx.target->pltRel, *sym); needEntry = false; } diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 001f1efe383248..b44b87f8276e94 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -290,7 +290,7 @@ Defined *elf::addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type, return s; } -static size_t getHashSize() { +static size_t getHashSize(Ctx &ctx) { switch (ctx.arg.buildId) { case BuildIdKind::Fast: return 8; @@ -362,7 +362,7 @@ size_t GnuPropertySection::getSize() const { BuildIdSection::BuildIdSection(Ctx &ctx) : SyntheticSection(ctx, SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"), - hashSize(getHashSize()) {} + hashSize(getHashSize(ctx)) {} void BuildIdSection::writeTo(uint8_t *buf) { write32(buf, 4); // Name size @@ -1208,7 +1208,7 @@ bool GotPltSection::isNeeded() const { return !entries.empty() || hasGotPltOffRel; } -static StringRef getIgotPltName() { +static StringRef getIgotPltName(Ctx &ctx) { // On ARM the IgotPltSection is part of the GotSection. if (ctx.arg.emachine == EM_ARM) return ".got"; @@ -1226,7 +1226,7 @@ static StringRef getIgotPltName() { IgotPltSection::IgotPltSection(Ctx &ctx) : SyntheticSection(ctx, SHF_ALLOC | SHF_WRITE, ctx.arg.emachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS, - ctx.target->gotEntrySize, getIgotPltName()) {} + ctx.target->gotEntrySize, getIgotPltName(ctx)) {} void IgotPltSection::addEntry(Symbol &sym) { assert(ctx.symAux.back().pltIdx == entries.size()); @@ -1605,7 +1605,7 @@ uint64_t DynamicReloc::getOffset() const { return inputSec->getVA(offsetInSec); } -int64_t DynamicReloc::computeAddend() const { +int64_t DynamicReloc::computeAddend(Ctx &ctx) const { switch (kind) { case AddendOnly: assert(sym == nullptr); @@ -1704,17 +1704,18 @@ void RelocationBaseSection::finalizeContents() { } } -void DynamicReloc::computeRaw(SymbolTableBaseSection *symt) { +void DynamicReloc::computeRaw(Ctx &ctx, SymbolTableBaseSection *symt) { r_offset = getOffset(); r_sym = getSymIndex(symt); - addend = computeAddend(); + addend = computeAddend(ctx); kind = AddendOnly; // Catch errors } void RelocationBaseSection::computeRels() { SymbolTableBaseSection *symTab = getPartition().dynSymTab.get(); - parallelForEach(relocs, - [symTab](DynamicReloc &rel) { rel.computeRaw(symTab); }); + parallelForEach(relocs, [&ctx = ctx, symTab](DynamicReloc &rel) { + rel.computeRaw(ctx, symTab); + }); auto irelative = std::stable_partition( relocs.begin() + numRelativeRelocs, relocs.end(), @@ -1853,7 +1854,7 @@ bool AndroidPackedRelocationSection::updateAllocSize(Ctx &ctx) { r.r_offset = rel.getOffset(); r.setSymbolAndType(rel.getSymIndex(getPartition().dynSymTab.get()), rel.type, false); - r.r_addend = ctx.arg.isRela ? rel.computeAddend() : 0; + r.r_addend = ctx.arg.isRela ? rel.computeAddend(ctx) : 0; if (r.getType(ctx.arg.isMips64EL) == ctx.target->relativeRel) relatives.push_back(r); @@ -3438,6 +3439,7 @@ readPubNamesAndTypes(const LLDDwarfObj &obj, // by uniquifying them by name. static std::pair, size_t> createSymbols( + Ctx &ctx, ArrayRef> nameAttrs, const SmallVector &chunks) { using GdbSymbol = GdbIndexSection::GdbSymbol; @@ -3563,7 +3565,8 @@ std::unique_ptr GdbIndexSection::create(Ctx &ctx) { auto ret = std::make_unique(ctx); ret->chunks = std::move(chunks); - std::tie(ret->symbols, ret->size) = createSymbols(nameAttrs, ret->chunks); + std::tie(ret->symbols, ret->size) = + createSymbols(ctx, nameAttrs, ret->chunks); // Count the areas other than the constant pool. ret->size += sizeof(GdbIndexHeader) + ret->computeSymtabSize() * 8; @@ -3784,9 +3787,9 @@ bool VersionTableSection::isNeeded() const { (getPartition().verDef || getPartition().verNeed->isNeeded()); } -void elf::addVerneed(Symbol *ss) { - auto &file = cast(*ss->file); - if (ss->versionId == VER_NDX_GLOBAL) +void elf::addVerneed(Ctx &ctx, Symbol &ss) { + auto &file = cast(*ss.file); + if (ss.versionId == VER_NDX_GLOBAL) return; if (file.vernauxs.empty()) @@ -3796,10 +3799,10 @@ void elf::addVerneed(Symbol *ss) { // already allocated one. The verdef identifiers cover the range // [1..getVerDefNum(ctx)]; this causes the vernaux identifiers to start from // getVerDefNum(ctx)+1. - if (file.vernauxs[ss->versionId] == 0) - file.vernauxs[ss->versionId] = ++SharedFile::vernauxNum + getVerDefNum(ctx); + if (file.vernauxs[ss.versionId] == 0) + file.vernauxs[ss.versionId] = ++SharedFile::vernauxNum + getVerDefNum(ctx); - ss->versionId = file.vernauxs[ss->versionId]; + ss.versionId = file.vernauxs[ss.versionId]; } template @@ -4659,7 +4662,7 @@ size_t MemtagGlobalDescriptors::getSize() const { return createMemtagGlobalDescriptors(ctx, symbols); } -static OutputSection *findSection(StringRef name) { +static OutputSection *findSection(Ctx &ctx, StringRef name) { for (SectionCommand *cmd : ctx.script->sectionCommands) if (auto *osd = dyn_cast(cmd)) if (osd->osec.name == name) @@ -4715,7 +4718,7 @@ template void elf::createSyntheticSections(Ctx &ctx) { // .data.rel.ro.bss so that we match in the .data.rel.ro output section. // This makes sure our relro is contiguous. bool hasDataRelRo = - ctx.script->hasSectionsCommand && findSection(".data.rel.ro"); + ctx.script->hasSectionsCommand && findSection(ctx, ".data.rel.ro"); ctx.in.bssRelRo = std::make_unique( ctx, hasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1); add(*ctx.in.bssRelRo); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 3ef3e04b5d1570..7ddbaff5573fdb 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -411,14 +411,14 @@ class DynamicReloc { public: enum Kind { /// The resulting dynamic relocation does not reference a symbol (#sym must - /// be nullptr) and uses #addend as the result of computeAddend(). + /// be nullptr) and uses #addend as the result of computeAddend(ctx). AddendOnly, /// The resulting dynamic relocation will not reference a symbol: #sym is /// only used to compute the addend with InputSection::getRelocTargetVA(). /// Useful for various relative and TLS relocations (e.g. R_X86_64_TPOFF64). AddendOnlyWithTargetVA, /// The resulting dynamic relocation references symbol #sym from the dynamic - /// symbol table and uses #addend as the value of computeAddend(). + /// symbol table and uses #addend as the value of computeAddend(ctx). AgainstSymbol, /// The resulting dynamic relocation references symbol #sym from the dynamic /// symbol table and uses InputSection::getRelocTargetVA() + #addend for the @@ -458,9 +458,9 @@ class DynamicReloc { /// Computes the addend of the dynamic relocation. Note that this is not the /// same as the #addend member variable as it may also include the symbol /// address/the address of the corresponding GOT entry/etc. - int64_t computeAddend() const; + int64_t computeAddend(Ctx &) const; - void computeRaw(SymbolTableBaseSection *symt); + void computeRaw(Ctx &, SymbolTableBaseSection *symt); Symbol *sym; const OutputSection *outputSec = nullptr; @@ -1443,7 +1443,7 @@ Defined *addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type, uint64_t value, uint64_t size, InputSectionBase §ion); -void addVerneed(Symbol *ss); +void addVerneed(Ctx &, Symbol &ss); // Linker generated per-partition sections. struct Partition { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 02c45d5e573711..49b6ab4a48b55a 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1879,7 +1879,7 @@ template void Writer::finalizeSections() { ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym); if (auto *file = dyn_cast_or_null(sym->file)) if (file->isNeeded && !sym->isUndefined()) - addVerneed(sym); + addVerneed(ctx, *sym); } }