diff options
author | Fangrui Song <i@maskray.me> | 2024-11-14 22:30:29 -0800 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2024-11-14 22:30:29 -0800 |
commit | d69cc05bcfeaf43853a509ec47ec742464fd60a0 (patch) | |
tree | 56a6d6e479075be6ff9be2f2097214704aeaa80d | |
parent | 2de1e067360055b5fb17568dc474fbfd7c4b1ffb (diff) | |
download | llvm-d69cc05bcfeaf43853a509ec47ec742464fd60a0.zip llvm-d69cc05bcfeaf43853a509ec47ec742464fd60a0.tar.gz llvm-d69cc05bcfeaf43853a509ec47ec742464fd60a0.tar.bz2 |
[ELF] Migrate away from global ctx
-rw-r--r-- | lld/ELF/Arch/AArch64.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/Arch/Hexagon.cpp | 17 | ||||
-rw-r--r-- | lld/ELF/Arch/PPC64.cpp | 10 | ||||
-rw-r--r-- | lld/ELF/Arch/RISCV.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 29 | ||||
-rw-r--r-- | lld/ELF/InputSection.cpp | 7 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 11 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 2 | ||||
-rw-r--r-- | lld/ELF/Target.h | 2 | ||||
-rw-r--r-- | lld/ELF/Thunks.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 9 |
11 files changed, 54 insertions, 51 deletions
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 025672d..c4334a6 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -1107,7 +1107,7 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym, template <class ELFT> static void -addTaggedSymbolReferences(InputSectionBase &sec, +addTaggedSymbolReferences(Ctx &ctx, InputSectionBase &sec, DenseMap<Symbol *, unsigned> &referenceCount) { assert(sec.type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC); @@ -1163,7 +1163,7 @@ void elf::createTaggedSymbols(Ctx &ctx) { if (!section || section->type != SHT_AARCH64_MEMTAG_GLOBALS_STATIC || section == &InputSection::discarded) continue; - invokeELFT(addTaggedSymbolReferences, *section, + invokeELFT(addTaggedSymbolReferences, ctx, *section, taggedSymbolReferenceCount); } } diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp index b648b3b..84b1bfb 100644 --- a/lld/ELF/Arch/Hexagon.cpp +++ b/lld/ELF/Arch/Hexagon.cpp @@ -190,7 +190,7 @@ static bool isDuplex(uint32_t insn) { return (instParsePacketEnd & insn) == 0; } -static uint32_t findMaskR6(uint32_t insn) { +static uint32_t findMaskR6(Ctx &ctx, uint32_t insn) { if (isDuplex(insn)) return 0x03f00000; @@ -198,8 +198,8 @@ static uint32_t findMaskR6(uint32_t insn) { if ((0xff000000 & insn) == i.cmpMask) return i.relocMask; - ErrAlways(ctx) << "unrecognized instruction for 6_X relocation: 0x" - << utohexstr(insn); + Err(ctx) << "unrecognized instruction for 6_X relocation: 0x" + << utohexstr(insn); return 0; } @@ -217,7 +217,7 @@ static uint32_t findMaskR11(uint32_t insn) { return 0x06003fe0; } -static uint32_t findMaskR16(uint32_t insn) { +static uint32_t findMaskR16(Ctx &ctx, uint32_t insn) { if (isDuplex(insn)) return 0x03f00000; @@ -246,8 +246,7 @@ static uint32_t findMaskR16(uint32_t insn) { if ((0xff000000 & insn) == i.cmpMask) return i.relocMask; - ErrAlways(ctx) << "unrecognized instruction for 16_X type: 0x" - << utohexstr(insn); + Err(ctx) << "unrecognized instruction for 16_X type: 0x" << utohexstr(insn); return 0; } @@ -260,7 +259,7 @@ void Hexagon::relocate(uint8_t *loc, const Relocation &rel, break; case R_HEX_6_PCREL_X: case R_HEX_6_X: - or32le(loc, applyMask(findMaskR6(read32le(loc)), val)); + or32le(loc, applyMask(findMaskR6(ctx, read32le(loc)), val)); break; case R_HEX_8_X: or32le(loc, applyMask(findMaskR8(read32le(loc)), val)); @@ -289,10 +288,10 @@ void Hexagon::relocate(uint8_t *loc, const Relocation &rel, case R_HEX_GOT_16_X: case R_HEX_GOTREL_16_X: case R_HEX_TPREL_16_X: - or32le(loc, applyMask(findMaskR16(read32le(loc)), val & 0x3f)); + or32le(loc, applyMask(findMaskR16(ctx, read32le(loc)), val & 0x3f)); break; case R_HEX_TPREL_16: - or32le(loc, applyMask(findMaskR16(read32le(loc)), val & 0xffff)); + or32le(loc, applyMask(findMaskR16(ctx, read32le(loc)), val & 0xffff)); break; case R_HEX_32: case R_HEX_32_PCREL: diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 21790fb..a7188e2 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -219,7 +219,7 @@ uint64_t elf::getPPC64TocBase(Ctx &ctx) { return tocVA + ppc64TocOffset; } -unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) { +unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(Ctx &ctx, uint8_t stOther) { // The offset is encoded into the 3 most significant bits of the st_other // field, with some special values described in section 3.4.1 of the ABI: // 0 --> Zero offset between the GEP and LEP, and the function does NOT use @@ -1455,9 +1455,9 @@ bool PPC64::needsThunk(RelExpr expr, RelType type, const InputFile *file, // If the offset exceeds the range of the branch type then it will need // a range-extending thunk. // See the comment in getRelocTargetVA() about R_PPC64_CALL. - return !inBranchRange(type, branchAddr, - s.getVA(ctx, a) + - getPPC64GlobalEntryToLocalEntryOffset(s.stOther)); + return !inBranchRange( + type, branchAddr, + s.getVA(ctx, a) + getPPC64GlobalEntryToLocalEntryOffset(ctx, s.stOther)); } uint32_t PPC64::getThunkSectionSpacing() const { @@ -1678,7 +1678,7 @@ bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end, uint8_t stOther) const { // If the caller has a global entry point adjust the buffer past it. The start // of the split-stack prologue will be at the local entry point. - loc += getPPC64GlobalEntryToLocalEntryOffset(stOther); + loc += getPPC64GlobalEntryToLocalEntryOffset(ctx, stOther); // At the very least we expect to see a load of some split-stack data from the // tcb, and 2 instructions that calculate the ending stack address this diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index 72d5db0..ca3a8f9 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -1059,7 +1059,7 @@ public: }; } // namespace -static void mergeArch(RISCVISAUtils::OrderedExtensionMap &mergedExts, +static void mergeArch(Ctx &ctx, RISCVISAUtils::OrderedExtensionMap &mergedExts, unsigned &mergedXlen, const InputSectionBase *sec, StringRef s) { auto maybeInfo = RISCVISAInfo::parseNormalizedArchString(s); @@ -1086,7 +1086,7 @@ static void mergeArch(RISCVISAUtils::OrderedExtensionMap &mergedExts, } } -static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it, +static void mergeAtomic(Ctx &ctx, DenseMap<unsigned, unsigned>::iterator it, const InputSectionBase *oldSection, const InputSectionBase *newSection, RISCVAttrs::RISCVAtomicAbiTag oldTag, @@ -1104,8 +1104,8 @@ static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it, << ": atomic_abi=" << Twine(static_cast<unsigned>(newTag)); }; - auto reportUnknownAbiError = [](const InputSectionBase *section, - RISCVAtomicAbiTag tag) { + auto reportUnknownAbiError = [&](const InputSectionBase *section, + RISCVAtomicAbiTag tag) { switch (tag) { case RISCVAtomicAbiTag::UNKNOWN: case RISCVAtomicAbiTag::A6C: @@ -1214,7 +1214,7 @@ mergeAttributesSection(Ctx &ctx, case RISCVAttrs::ARCH: if (auto s = parser.getAttributeString(tag.attr)) { hasArch = true; - mergeArch(exts, xlen, sec, *s); + mergeArch(ctx, exts, xlen, sec, *s); } continue; @@ -1230,7 +1230,7 @@ mergeAttributesSection(Ctx &ctx, if (r.second) firstAtomicAbi = sec; else - mergeAtomic(r.first, firstAtomicAbi, sec, + mergeAtomic(ctx, r.first, firstAtomicAbi, sec, static_cast<RISCVAtomicAbiTag>(r.first->getSecond()), static_cast<RISCVAtomicAbiTag>(*i)); } diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 429e5fa..a812b53 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -197,7 +197,8 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, } // namespace lld // Parses a linker -m option. -static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) { +static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(Ctx &ctx, + StringRef emul) { uint8_t osabi = 0; StringRef s = emul; if (s.ends_with("_fbsd")) { @@ -578,7 +579,7 @@ static GnuStackKind getZGnuStack(opt::InputArgList &args) { return ret; } -static uint8_t getZStartStopVisibility(opt::InputArgList &args) { +static uint8_t getZStartStopVisibility(Ctx &ctx, opt::InputArgList &args) { uint8_t ret = STV_PROTECTED; for (auto *arg : args.filtered(OPT_z)) { std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('='); @@ -1556,7 +1557,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) { ctx.arg.zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0); ctx.arg.zStartStopGC = getZFlag(args, "start-stop-gc", "nostart-stop-gc", true); - ctx.arg.zStartStopVisibility = getZStartStopVisibility(args); + ctx.arg.zStartStopVisibility = getZStartStopVisibility(ctx, args); ctx.arg.zText = getZFlag(args, "text", "notext", true); ctx.arg.zWxneeded = hasZOption(args, "wxneeded"); setUnresolvedSymbolPolicy(ctx, args); @@ -1759,7 +1760,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) { if (auto *arg = args.getLastArg(OPT_m)) { StringRef s = arg->getValue(); std::tie(ctx.arg.ekind, ctx.arg.emachine, ctx.arg.osabi) = - parseEmulation(s); + parseEmulation(ctx, s); ctx.arg.mipsN32Abi = (s.starts_with("elf32btsmipn32") || s.starts_with("elf32ltsmipn32")); ctx.arg.emulation = s; @@ -2756,17 +2757,19 @@ static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) { ctx.symtab->wrap(w.sym, w.real, w.wrap); } -static void reportMissingFeature(StringRef config, const Twine &report) { +static void reportMissingFeature(Ctx &ctx, StringRef config, + const Twine &report) { if (config == "error") ErrAlways(ctx) << report; else if (config == "warning") Warn(ctx) << report; } -static void checkAndReportMissingFeature(StringRef config, uint32_t features, - uint32_t mask, const Twine &report) { +static void checkAndReportMissingFeature(Ctx &ctx, StringRef config, + uint32_t features, uint32_t mask, + const Twine &report) { if (!(features & mask)) - reportMissingFeature(config, report); + reportMissingFeature(ctx, config, report); } // To enable CET (x86's hardware-assisted control flow enforcement), each @@ -2805,22 +2808,22 @@ static void readSecurityNotes(Ctx &ctx) { uint32_t features = f->andFeatures; checkAndReportMissingFeature( - ctx.arg.zBtiReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_BTI, + ctx, ctx.arg.zBtiReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_BTI, toString(f) + ": -z bti-report: file does not have " "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property"); checkAndReportMissingFeature( - ctx.arg.zGcsReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_GCS, + ctx, ctx.arg.zGcsReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_GCS, toString(f) + ": -z gcs-report: file does not have " "GNU_PROPERTY_AARCH64_FEATURE_1_GCS property"); checkAndReportMissingFeature( - ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_IBT, + ctx, ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_IBT, toString(f) + ": -z cet-report: file does not have " "GNU_PROPERTY_X86_FEATURE_1_IBT property"); checkAndReportMissingFeature( - ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_SHSTK, + ctx, ctx.arg.zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_SHSTK, toString(f) + ": -z cet-report: file does not have " "GNU_PROPERTY_X86_FEATURE_1_SHSTK property"); @@ -2852,7 +2855,7 @@ static void readSecurityNotes(Ctx &ctx) { continue; if (f->aarch64PauthAbiCoreInfo.empty()) { - reportMissingFeature(ctx.arg.zPauthReport, + reportMissingFeature(ctx, ctx.arg.zPauthReport, toString(f) + ": -z pauth-report: file does not have AArch64 " "PAuth core info while '" + diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index d246c64..48e59ad 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -113,7 +113,7 @@ size_t InputSectionBase::getSize() const { } template <class ELFT> -static void decompressAux(const InputSectionBase &sec, uint8_t *out, +static void decompressAux(Ctx &ctx, const InputSectionBase &sec, uint8_t *out, size_t size) { auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(sec.content_); auto compressed = ArrayRef<uint8_t>(sec.content_, sec.compressedSize) @@ -134,7 +134,7 @@ void InputSectionBase::decompress() const { uncompressedBuf = bAlloc().Allocate<uint8_t>(size); } - invokeELFT(decompressAux, *this, uncompressedBuf, size); + invokeELFT(decompressAux, ctx, *this, uncompressedBuf, size); content_ = uncompressedBuf; compressed = false; } @@ -914,7 +914,8 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r, // the callee. For local calls the caller and callee share the same // TOC base and so the TOC pointer initialization code should be skipped by // branching to the local entry point. - return symVA - p + getPPC64GlobalEntryToLocalEntryOffset(r.sym->stOther); + return symVA - p + + getPPC64GlobalEntryToLocalEntryOffset(ctx, r.sym->stOther); } case R_PPC64_TOCBASE: return getPPC64TocBase(ctx) + a; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 55ce1ab..ba77fbf 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2856,13 +2856,12 @@ readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni, } void DebugNamesBaseSection::parseDebugNames( - InputChunk &inputChunk, OutputChunk &chunk, + Ctx &ctx, InputChunk &inputChunk, OutputChunk &chunk, DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor, function_ref<SmallVector<uint32_t, 0>( uint32_t numCus, const DWARFDebugNames::Header &, const DWARFDebugNames::DWARFDebugNamesOffsets &)> readOffsets) { - Ctx &ctx = elf::ctx; const LLDDWARFSection &namesSec = inputChunk.section; DenseMap<uint32_t, IndexEntry *> offsetMap; // Number of CUs seen in previous NameIndex sections within current chunk. @@ -3216,7 +3215,7 @@ DebugNamesSection<ELFT>::DebugNamesSection(Ctx &ctx) Err(ctx) << dobj.getNamesSection().sec << Twine(": ") << std::move(e); } parseDebugNames( - inputChunk, chunk, namesExtractor, strExtractor, + ctx, inputChunk, chunk, namesExtractor, strExtractor, [&chunk, namesData = dobj.getNamesSection().Data.data()]( uint32_t numCus, const DWARFDebugNames::Header &hdr, const DWARFDebugNames::DWARFDebugNamesOffsets &locs) { @@ -3376,7 +3375,7 @@ readCuList(DWARFContext &dwarf) { } static SmallVector<GdbIndexSection::AddressEntry, 0> -readAddressAreas(DWARFContext &dwarf, InputSection *sec) { +readAddressAreas(Ctx &ctx, DWARFContext &dwarf, InputSection *sec) { SmallVector<GdbIndexSection::AddressEntry, 0> ret; uint32_t cuIdx = 0; @@ -3564,7 +3563,7 @@ std::unique_ptr<GdbIndexSection> GdbIndexSection::create(Ctx &ctx) { // this only picks the last one. Other address ranges are lost. chunks[i].sec = dobj.getInfoSection(); chunks[i].compilationUnits = readCuList(dwarf); - chunks[i].addressAreas = readAddressAreas(dwarf, chunks[i].sec); + chunks[i].addressAreas = readAddressAreas(ctx, dwarf, chunks[i].sec); nameAttrs[i] = readPubNamesAndTypes<ELFT>(ctx, dobj, chunks[i].compilationUnits); }); @@ -4366,7 +4365,7 @@ void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) { // must be a local-call. write64(ctx, buf, sym->getVA(ctx, addend) + - getPPC64GlobalEntryToLocalEntryOffset(sym->stOther)); + getPPC64GlobalEntryToLocalEntryOffset(ctx, sym->stOther)); buf += 8; } } diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 3573767..9f78bd3 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -871,7 +871,7 @@ public: protected: void init(llvm::function_ref<void(InputFile *, InputChunk &, OutputChunk &)>); static void - parseDebugNames(InputChunk &inputChunk, OutputChunk &chunk, + parseDebugNames(Ctx &, InputChunk &inputChunk, OutputChunk &chunk, llvm::DWARFDataExtractor &namesExtractor, llvm::DataExtractor &strExtractor, llvm::function_ref<SmallVector<uint32_t, 0>( diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index d4919ff..baf4f48 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -229,7 +229,7 @@ unsigned getPPCDSFormOp(unsigned secondaryOp); // offset between GEP and LEP is encoded in a function's st_other flags. // This function will return the offset (in bytes) from the global entry-point // to the local entry-point. -unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther); +unsigned getPPC64GlobalEntryToLocalEntryOffset(Ctx &, uint8_t stOther); // Write a prefixed instruction, which is a 4-byte prefix followed by a 4-byte // instruction (regardless of endianness). Therefore, the prefix is always in diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp index 7ae5d34..e4c78cb 100644 --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -519,7 +519,7 @@ public: ctx.mainPart->relaDyn->addRelativeReloc( ctx.target->relativeRel, *ctx.in.ppc64LongBranchTarget, *index * UINT64_C(8), dest, - addend + getPPC64GlobalEntryToLocalEntryOffset(dest.stOther), + addend + getPPC64GlobalEntryToLocalEntryOffset(ctx, dest.stOther), ctx.target->symbolicRel, R_ABS); } } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 4a20084..82b4491 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2625,7 +2625,8 @@ struct SectionOffset { // Check whether sections overlap for a specific address range (file offsets, // load and virtual addresses). -static void checkOverlap(StringRef name, std::vector<SectionOffset> §ions, +static void checkOverlap(Ctx &ctx, StringRef name, + std::vector<SectionOffset> §ions, bool isVirtualAddr) { llvm::sort(sections, [=](const SectionOffset &a, const SectionOffset &b) { return a.offset < b.offset; @@ -2676,7 +2677,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() { if (sec->size > 0 && sec->type != SHT_NOBITS && (!ctx.arg.oFormatBinary || (sec->flags & SHF_ALLOC))) fileOffs.push_back({sec, sec->offset}); - checkOverlap("file", fileOffs, false); + checkOverlap(ctx, "file", fileOffs, false); // When linking with -r there is no need to check for overlapping virtual/load // addresses since those addresses will only be assigned when the final @@ -2693,7 +2694,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() { for (OutputSection *sec : ctx.outputSections) if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS)) vmas.push_back({sec, sec->addr}); - checkOverlap("virtual address", vmas, true); + checkOverlap(ctx, "virtual address", vmas, true); // Finally, check that the load addresses don't overlap. This will usually be // the same as the virtual addresses but can be different when using a linker @@ -2702,7 +2703,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() { for (OutputSection *sec : ctx.outputSections) if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS)) lmas.push_back({sec, sec->getLMA()}); - checkOverlap("load address", lmas, false); + checkOverlap(ctx, "load address", lmas, false); } // The entry point address is chosen in the following ways. |