[lld] 6d03a69 - [ELF] Pass Ctx & to Arch/

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 6 00:14:18 PDT 2024


Author: Fangrui Song
Date: 2024-10-06T00:14:12-07:00
New Revision: 6d03a69034edb7805a4ba00334a1275cef39dd72

URL: https://github.com/llvm/llvm-project/commit/6d03a69034edb7805a4ba00334a1275cef39dd72
DIFF: https://github.com/llvm/llvm-project/commit/6d03a69034edb7805a4ba00334a1275cef39dd72.diff

LOG: [ELF] Pass Ctx & to Arch/

Added: 
    

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/ELF/Arch/ARM.cpp
    lld/ELF/Arch/LoongArch.cpp
    lld/ELF/Arch/Mips.cpp
    lld/ELF/Arch/MipsArchTree.cpp
    lld/ELF/Arch/PPC.cpp
    lld/ELF/Arch/PPC64.cpp
    lld/ELF/Arch/RISCV.cpp
    lld/ELF/Driver.cpp
    lld/ELF/InputFiles.cpp
    lld/ELF/InputSection.cpp
    lld/ELF/Relocations.cpp
    lld/ELF/SyntheticSections.cpp
    lld/ELF/SyntheticSections.h
    lld/ELF/Target.h
    lld/ELF/Thunks.cpp
    lld/ELF/Writer.cpp
    lld/ELF/Writer.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 45d429c915a6ee..a576fe38ea99f0 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -91,9 +91,10 @@ class AArch64 : public TargetInfo {
 };
 
 struct AArch64Relaxer {
+  Ctx &ctx;
   bool safeToRelaxAdrpLdr = false;
 
-  AArch64Relaxer(ArrayRef<Relocation> relocs);
+  AArch64Relaxer(Ctx &ctx, ArrayRef<Relocation> relocs);
   bool tryRelaxAdrpAdd(const Relocation &adrpRel, const Relocation &addRel,
                        uint64_t secAddr, uint8_t *buf) const;
   bool tryRelaxAdrpLdr(const Relocation &adrpRel, const Relocation &ldrRel,
@@ -750,7 +751,8 @@ void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
   llvm_unreachable("invalid relocation for TLS IE to LE relaxation");
 }
 
-AArch64Relaxer::AArch64Relaxer(ArrayRef<Relocation> relocs) {
+AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef<Relocation> relocs)
+    : ctx(ctx) {
   if (!ctx.arg.relax)
     return;
   // Check if R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC
@@ -909,7 +911,7 @@ void AArch64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
     secAddr += s->outSecOff;
   else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
     secAddr += ehIn->getParent()->outSecOff;
-  AArch64Relaxer relaxer(sec.relocs());
+  AArch64Relaxer relaxer(ctx, sec.relocs());
   for (size_t i = 0, size = sec.relocs().size(); i != size; ++i) {
     const Relocation &rel = sec.relocs()[i];
     uint8_t *loc = buf + rel.offset;
@@ -1149,13 +1151,13 @@ addTaggedSymbolReferences(InputSectionBase &sec,
 // Ideally, this isn't a problem, as any TU that imports or exports tagged
 // symbols should also be built with tagging. But, to handle these cases, we
 // demote the symbol to be untagged.
-void lld::elf::createTaggedSymbols(const SmallVector<ELFFileBase *, 0> &files) {
+void elf::createTaggedSymbols(Ctx &ctx) {
   assert(hasMemtag());
 
   // First, collect all symbols that are marked as tagged, and count how many
   // times they're marked as tagged.
   DenseMap<Symbol *, unsigned> taggedSymbolReferenceCount;
-  for (InputFile* file : files) {
+  for (InputFile *file : ctx.objectFiles) {
     if (file->kind() != InputFile::ObjKind)
       continue;
     for (InputSectionBase *section : file->getSections()) {
@@ -1171,7 +1173,7 @@ void lld::elf::createTaggedSymbols(const SmallVector<ELFFileBase *, 0> &files) {
   // definitions to a symbol exceeds the amount of times they're marked as
   // tagged, it means we have an objfile that uses the untagged variant of the
   // symbol.
-  for (InputFile *file : files) {
+  for (InputFile *file : ctx.objectFiles) {
     if (file->kind() != InputFile::BinaryKind &&
         file->kind() != InputFile::ObjKind)
       continue;

diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index d22ac540c92a1e..7f2f8129a6dce2 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -214,7 +214,7 @@ void ARM::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
 
 // Long form PLT Header that does not have any restrictions on the displacement
 // of the .plt from the .got.plt.
-static void writePltHeaderLong(uint8_t *buf) {
+static void writePltHeaderLong(Ctx &ctx, uint8_t *buf) {
   write32(buf + 0, 0xe52de004);   //     str lr, [sp,#-4]!
   write32(buf + 4, 0xe59fe004);   //     ldr lr, L2
   write32(buf + 8, 0xe08fe00e);   // L1: add lr, pc, lr
@@ -280,7 +280,7 @@ void ARM::writePltHeader(uint8_t *buf) const {
     uint64_t offset = ctx.in.gotPlt->getVA() - ctx.in.plt->getVA() - 4;
     if (!llvm::isUInt<27>(offset)) {
       // We cannot encode the Offset, use the long form.
-      writePltHeaderLong(buf);
+      writePltHeaderLong(ctx, buf);
       return;
     }
     write32(buf + 0, pltData[0]);
@@ -1048,7 +1048,7 @@ void elf::sortArmMappingSymbols() {
   }
 }
 
-void elf::addArmInputSectionMappingSymbols() {
+void elf::addArmInputSectionMappingSymbols(Ctx &ctx) {
   // Collect mapping symbols for every executable input sections.
   // The linker generated mapping symbols for all the synthetic
   // sections are adding into the sectionmap through the function
@@ -1327,7 +1327,7 @@ class elf::ArmCmseSGVeneer {
   const std::optional<uint64_t> entAddr;
 };
 
-ArmCmseSGSection::ArmCmseSGSection()
+ArmCmseSGSection::ArmCmseSGSection(Ctx &ctx)
     : SyntheticSection(llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
                        llvm::ELF::SHT_PROGBITS,
                        /*alignment=*/32, ".gnu.sgstubs") {
@@ -1440,7 +1440,7 @@ void ArmCmseSGSection::finalizeContents(Ctx &) {
 // in the executable output by this link.
 // See ArmĀ® v8-M Security Extensions: Requirements on Development Tools
 // https://developer.arm.com/documentation/ecm0359818/latest
-template <typename ELFT> void elf::writeARMCmseImportLib() {
+template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
   StringTableSection *shstrtab =
       make<StringTableSection>(".shstrtab", /*dynamic=*/false);
   StringTableSection *strtab =
@@ -1538,10 +1538,10 @@ TargetInfo *elf::getARMTargetInfo(Ctx &ctx) {
   return ⌖
 }
 
-template void elf::writeARMCmseImportLib<ELF32LE>();
-template void elf::writeARMCmseImportLib<ELF32BE>();
-template void elf::writeARMCmseImportLib<ELF64LE>();
-template void elf::writeARMCmseImportLib<ELF64BE>();
+template void elf::writeARMCmseImportLib<ELF32LE>(Ctx &);
+template void elf::writeARMCmseImportLib<ELF32BE>(Ctx &);
+template void elf::writeARMCmseImportLib<ELF64LE>(Ctx &);
+template void elf::writeARMCmseImportLib<ELF64BE>(Ctx &);
 
 template void ObjFile<ELF32LE>::importCmseSymbols();
 template void ObjFile<ELF32BE>::importCmseSymbols();

diff  --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 3e86488063f0e4..ebbd203a05368c 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -212,7 +212,7 @@ LoongArch::LoongArch(Ctx &ctx) : TargetInfo(ctx) {
   ipltEntrySize = 16;
 }
 
-static uint32_t getEFlags(const InputFile *f) {
+static uint32_t getEFlags(Ctx &ctx, const InputFile *f) {
   if (ctx.arg.is64)
     return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader().e_flags;
   return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader().e_flags;
@@ -242,7 +242,7 @@ uint32_t LoongArch::calcEFlags() const {
       continue;
 
     // Take the first non-zero e_flags as the reference.
-    uint32_t flags = getEFlags(f);
+    uint32_t flags = getEFlags(ctx, f);
     if (target == 0 && flags != 0) {
       target = flags;
       targetFile = f;
@@ -825,7 +825,7 @@ bool LoongArch::relaxOnce(int pass) const {
     return false;
 
   if (pass == 0)
-    initSymbolAnchors();
+    initSymbolAnchors(ctx);
 
   SmallVector<InputSection *, 0> storage;
   bool changed = false;

diff  --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index 0e65df347031ef..6eedc4c6eb8f2c 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -70,7 +70,7 @@ template <class ELFT> MIPS<ELFT>::MIPS(Ctx &ctx) : TargetInfo(ctx) {
 }
 
 template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
-  return calcMipsEFlags<ELFT>();
+  return calcMipsEFlags<ELFT>(ctx);
 }
 
 template <class ELFT>
@@ -262,14 +262,14 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
     // Overwrite trap instructions written by Writer::writeTrapInstr.
     memset(buf, 0, pltHeaderSize);
 
-    write16(buf, isMipsR6() ? 0x7860 : 0x7980);  // addiupc v1, (GOTPLT) - .
+    write16(buf, isMipsR6(ctx) ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
     write16(buf + 4, 0xff23);    // lw      $25, 0($3)
     write16(buf + 8, 0x0535);    // subu16  $2,  $2, $3
     write16(buf + 10, 0x2525);   // srl16   $2,  $2, 2
     write16(buf + 12, 0x3302);   // addiu   $24, $2, -2
     write16(buf + 14, 0xfffe);
     write16(buf + 16, 0x0dff);   // move    $15, $31
-    if (isMipsR6()) {
+    if (isMipsR6(ctx)) {
       write16(buf + 18, 0x0f83); // move    $28, $3
       write16(buf + 20, 0x472b); // jalrc   $25
       write16(buf + 22, 0x0c00); // nop
@@ -324,7 +324,7 @@ void MIPS<ELFT>::writePlt(uint8_t *buf, const Symbol &sym,
     // Overwrite trap instructions written by Writer::writeTrapInstr.
     memset(buf, 0, pltEntrySize);
 
-    if (isMipsR6()) {
+    if (isMipsR6(ctx)) {
       write16(buf, 0x7840);      // addiupc $2, (GOTPLT) - .
       write16(buf + 4, 0xff22);  // lw $25, 0($2)
       write16(buf + 8, 0x0f02);  // move $24, $2
@@ -341,8 +341,9 @@ void MIPS<ELFT>::writePlt(uint8_t *buf, const Symbol &sym,
   }
 
   uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
-  uint32_t jrInst = isMipsR6() ? (ctx.arg.zHazardplt ? 0x03200409 : 0x03200009)
-                               : (ctx.arg.zHazardplt ? 0x03200408 : 0x03200008);
+  uint32_t jrInst = isMipsR6(ctx)
+                        ? (ctx.arg.zHazardplt ? 0x03200409 : 0x03200009)
+                        : (ctx.arg.zHazardplt ? 0x03200408 : 0x03200008);
   uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
 
   write32(buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)

diff  --git a/lld/ELF/Arch/MipsArchTree.cpp b/lld/ELF/Arch/MipsArchTree.cpp
index c958ba9032fa35..bb0577b73fa118 100644
--- a/lld/ELF/Arch/MipsArchTree.cpp
+++ b/lld/ELF/Arch/MipsArchTree.cpp
@@ -62,7 +62,7 @@ static StringRef getNanName(bool isNan2008) {
 
 static StringRef getFpName(bool isFp64) { return isFp64 ? "64" : "32"; }
 
-static void checkFlags(ArrayRef<FileFlags> files) {
+static void checkFlags(Ctx &ctx, ArrayRef<FileFlags> files) {
   assert(!files.empty() && "expected non-empty file list");
 
   uint32_t abi = files[0].flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
@@ -293,7 +293,7 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> files) {
   return ret;
 }
 
-template <class ELFT> uint32_t elf::calcMipsEFlags() {
+template <class ELFT> uint32_t elf::calcMipsEFlags(Ctx &ctx) {
   std::vector<FileFlags> v;
   for (InputFile *f : ctx.objectFiles)
     v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader().e_flags});
@@ -305,7 +305,7 @@ template <class ELFT> uint32_t elf::calcMipsEFlags() {
       return 0;
     return ctx.arg.mipsN32Abi ? EF_MIPS_ABI2 : EF_MIPS_ABI_O32;
   }
-  checkFlags(v);
+  checkFlags(ctx, v);
   return getMiscFlags(v) | getPicFlags(v) | getArchFlags(v);
 }
 
@@ -360,13 +360,13 @@ uint8_t elf::getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
   return oldFlag;
 }
 
-template <class ELFT> static bool isN32Abi(const InputFile *f) {
-  if (auto *ef = dyn_cast<ELFFileBase>(f))
+template <class ELFT> static bool isN32Abi(const InputFile &f) {
+  if (auto *ef = dyn_cast<ELFFileBase>(&f))
     return ef->template getObj<ELFT>().getHeader().e_flags & EF_MIPS_ABI2;
   return false;
 }
 
-bool elf::isMipsN32Abi(const InputFile *f) {
+bool elf::isMipsN32Abi(Ctx &ctx, const InputFile &f) {
   switch (ctx.arg.ekind) {
   case ELF32LEKind:
     return isN32Abi<ELF32LE>(f);
@@ -383,12 +383,12 @@ bool elf::isMipsN32Abi(const InputFile *f) {
 
 bool elf::isMicroMips() { return ctx.arg.eflags & EF_MIPS_MICROMIPS; }
 
-bool elf::isMipsR6() {
+bool elf::isMipsR6(Ctx &ctx) {
   uint32_t arch = ctx.arg.eflags & EF_MIPS_ARCH;
   return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6;
 }
 
-template uint32_t elf::calcMipsEFlags<ELF32LE>();
-template uint32_t elf::calcMipsEFlags<ELF32BE>();
-template uint32_t elf::calcMipsEFlags<ELF64LE>();
-template uint32_t elf::calcMipsEFlags<ELF64BE>();
+template uint32_t elf::calcMipsEFlags<ELF32LE>(Ctx &);
+template uint32_t elf::calcMipsEFlags<ELF32BE>(Ctx &);
+template uint32_t elf::calcMipsEFlags<ELF64LE>(Ctx &);
+template uint32_t elf::calcMipsEFlags<ELF64BE>(Ctx &);

diff  --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index 2d6355fac13e63..22e7f5c996e3d8 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -64,15 +64,15 @@ class PPC final : public TargetInfo {
 static uint16_t lo(uint32_t v) { return v; }
 static uint16_t ha(uint32_t v) { return (v + 0x8000) >> 16; }
 
-static uint32_t readFromHalf16(const uint8_t *loc) {
+static uint32_t readFromHalf16(Ctx &ctx, const uint8_t *loc) {
   return read32(ctx.arg.isLE ? loc : loc - 2);
 }
 
-static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
+static void writeFromHalf16(Ctx &ctx, uint8_t *loc, uint32_t insn) {
   write32(ctx.arg.isLE ? loc : loc - 2, insn);
 }
 
-void elf::writePPC32GlinkSection(uint8_t *buf, size_t numEntries) {
+void elf::writePPC32GlinkSection(Ctx &ctx, uint8_t *buf, size_t numEntries) {
   // Create canonical PLT entries for non-PIE code. Compilers don't generate
   // non-GOT-non-PLT relocations referencing external functions for -fpie/-fPIE.
   uint32_t glink = ctx.in.plt->getVA(); // VA of .glink
@@ -412,8 +412,8 @@ void PPC::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
   switch (rel.type) {
   case R_PPC_GOT_TLSGD16: {
     // addi rT, rA, x at got@tlsgd --> lwz rT, x at got@tprel(rA)
-    uint32_t insn = readFromHalf16(loc);
-    writeFromHalf16(loc, 0x80000000 | (insn & 0x03ff0000));
+    uint32_t insn = readFromHalf16(ctx, loc);
+    writeFromHalf16(ctx, loc, 0x80000000 | (insn & 0x03ff0000));
     relocateNoSym(loc, R_PPC_GOT_TPREL16, val);
     break;
   }
@@ -431,7 +431,7 @@ void PPC::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
   switch (rel.type) {
   case R_PPC_GOT_TLSGD16:
     // addi r3, r31, x at got@tlsgd --> addis r3, r2, x at tprel@ha
-    writeFromHalf16(loc, 0x3c620000 | ha(val));
+    writeFromHalf16(ctx, loc, 0x3c620000 | ha(val));
     break;
   case R_PPC_TLSGD:
     // bl __tls_get_addr(x at tldgd) --> add r3, r3, x at tprel@l
@@ -447,7 +447,7 @@ void PPC::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
   switch (rel.type) {
   case R_PPC_GOT_TLSLD16:
     // addi r3, rA, x at got@tlsgd --> addis r3, r2, 0
-    writeFromHalf16(loc, 0x3c620000);
+    writeFromHalf16(ctx, loc, 0x3c620000);
     break;
   case R_PPC_TLSLD:
     // r3+x at dtprel computes r3+x-0x8000, while we want it to compute r3+x at tprel
@@ -471,8 +471,8 @@ void PPC::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
   switch (rel.type) {
   case R_PPC_GOT_TPREL16: {
     // lwz rT, x at got@tprel(rA) --> addis rT, r2, x at tprel@ha
-    uint32_t rt = readFromHalf16(loc) & 0x03e00000;
-    writeFromHalf16(loc, 0x3c020000 | rt | ha(val));
+    uint32_t rt = readFromHalf16(ctx, loc) & 0x03e00000;
+    writeFromHalf16(ctx, loc, 0x3c020000 | rt | ha(val));
     break;
   }
   case R_PPC_TLS: {

diff  --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index da2a5aeed43b06..f1aa108c163943 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -205,7 +205,7 @@ class PPC64 final : public TargetInfo {
 };
 } // namespace
 
-uint64_t elf::getPPC64TocBase() {
+uint64_t elf::getPPC64TocBase(Ctx &ctx) {
   // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
   // TOC starts where the first of these sections starts. We always create a
   // .got when we see a relocation that uses it, so for us the start is always
@@ -244,12 +244,12 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
   return 0;
 }
 
-void elf::writePrefixedInstruction(uint8_t *loc, uint64_t insn) {
+void elf::writePrefixedInst(Ctx &ctx, uint8_t *loc, uint64_t insn) {
   insn = ctx.arg.isLE ? insn << 32 | insn >> 32 : insn;
   write64(loc, insn);
 }
 
-static bool addOptional(StringRef name, uint64_t value,
+static bool addOptional(Ctx &ctx, StringRef name, uint64_t value,
                         std::vector<Defined *> &defined) {
   Symbol *sym = ctx.symtab->find(name);
   if (!sym || sym->isDefined())
@@ -264,8 +264,8 @@ static bool addOptional(StringRef name, uint64_t value,
 // If from is 14, write ${prefix}14: firstInsn; ${prefix}15:
 // firstInsn+0x200008; ...; ${prefix}31: firstInsn+(31-14)*0x200008; $tail
 // The labels are defined only if they exist in the symbol table.
-static void writeSequence(MutableArrayRef<uint32_t> buf, const char *prefix,
-                          int from, uint32_t firstInsn,
+static void writeSequence(Ctx &ctx, MutableArrayRef<uint32_t> buf,
+                          const char *prefix, int from, uint32_t firstInsn,
                           ArrayRef<uint32_t> tail) {
   std::vector<Defined *> defined;
   char name[16];
@@ -273,7 +273,7 @@ static void writeSequence(MutableArrayRef<uint32_t> buf, const char *prefix,
   uint32_t *ptr = buf.data();
   for (int r = from; r < 32; ++r) {
     format("%s%d", prefix, r).snprint(name, sizeof(name));
-    if (addOptional(name, 4 * (r - from), defined) && defined.size() == 1)
+    if (addOptional(ctx, name, 4 * (r - from), defined) && defined.size() == 1)
       first = r - from;
     write32(ptr++, firstInsn + 0x200008 * (r - from));
   }
@@ -308,23 +308,23 @@ static void writeSequence(MutableArrayRef<uint32_t> buf, const char *prefix,
 // avoid long branch thunks. However, we don't consider the advantage
 // significant enough to complicate our trunk implementation, so we take the
 // simple approach and synthesize .text sections providing the implementation.
-void elf::addPPC64SaveRestore() {
+void elf::addPPC64SaveRestore(Ctx &ctx) {
   static uint32_t savegpr0[20], restgpr0[21], savegpr1[19], restgpr1[19];
   constexpr uint32_t blr = 0x4e800020, mtlr_0 = 0x7c0803a6;
 
   // _restgpr0_14: ld 14, -144(1); _restgpr0_15: ld 15, -136(1); ...
   // Tail: ld 0, 16(1); mtlr 0; blr
-  writeSequence(restgpr0, "_restgpr0_", 14, 0xe9c1ff70,
+  writeSequence(ctx, restgpr0, "_restgpr0_", 14, 0xe9c1ff70,
                 {0xe8010010, mtlr_0, blr});
   // _restgpr1_14: ld 14, -144(12); _restgpr1_15: ld 15, -136(12); ...
   // Tail: blr
-  writeSequence(restgpr1, "_restgpr1_", 14, 0xe9ccff70, {blr});
+  writeSequence(ctx, restgpr1, "_restgpr1_", 14, 0xe9ccff70, {blr});
   // _savegpr0_14: std 14, -144(1); _savegpr0_15: std 15, -136(1); ...
   // Tail: std 0, 16(1); blr
-  writeSequence(savegpr0, "_savegpr0_", 14, 0xf9c1ff70, {0xf8010010, blr});
+  writeSequence(ctx, savegpr0, "_savegpr0_", 14, 0xf9c1ff70, {0xf8010010, blr});
   // _savegpr1_14: std 14, -144(12); _savegpr1_15: std 15, -136(12); ...
   // Tail: blr
-  writeSequence(savegpr1, "_savegpr1_", 14, 0xf9ccff70, {blr});
+  writeSequence(ctx, savegpr1, "_savegpr1_", 14, 0xf9ccff70, {blr});
 }
 
 // Find the R_PPC64_ADDR64 in .rela.toc with matching offset.
@@ -377,7 +377,7 @@ getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) {
 //   ld/lwa 3, 0(3)           # load the value from the address
 //
 // Returns true if the relaxation is performed.
-static bool tryRelaxPPC64TocIndirection(const Relocation &rel,
+static bool tryRelaxPPC64TocIndirection(Ctx &ctx, const Relocation &rel,
                                         uint8_t *bufLoc) {
   assert(ctx.arg.tocOptimize);
   if (rel.addend < 0)
@@ -404,7 +404,7 @@ static bool tryRelaxPPC64TocIndirection(const Relocation &rel,
   assert(!d->isGnuIFunc());
 
   // Two instructions can materialize a 32-bit signed offset from the toc base.
-  uint64_t tocRelative = d->getVA(addend) - getPPC64TocBase();
+  uint64_t tocRelative = d->getVA(addend) - getPPC64TocBase(ctx);
   if (!isInt<32>(tocRelative))
     return false;
 
@@ -565,15 +565,15 @@ static int64_t getTotalDisp(uint64_t prefixedInsn, uint32_t accessInsn) {
 // pointer is pointing into the middle of the word we want to extract, and on
 // little-endian it is pointing to the start of the word. These 2 helpers are to
 // simplify reading and writing in that context.
-static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
+static void writeFromHalf16(Ctx &ctx, uint8_t *loc, uint32_t insn) {
   write32(ctx.arg.isLE ? loc : loc - 2, insn);
 }
 
-static uint32_t readFromHalf16(const uint8_t *loc) {
+static uint32_t readFromHalf16(Ctx &ctx, const uint8_t *loc) {
   return read32(ctx.arg.isLE ? loc : loc - 2);
 }
 
-static uint64_t readPrefixedInstruction(const uint8_t *loc) {
+static uint64_t readPrefixedInst(Ctx &ctx, const uint8_t *loc) {
   uint64_t fullInstr = read64(loc);
   return ctx.arg.isLE ? (fullInstr << 32 | fullInstr >> 32) : fullInstr;
 }
@@ -658,24 +658,24 @@ void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC64_TOC16_LO_DS: {
     // Convert "ld reg, .LC0 at toc@l(reg)" to "addi reg, reg, var at toc@l" or
     // "addi reg, 2, var at toc".
-    uint32_t insn = readFromHalf16(loc);
+    uint32_t insn = readFromHalf16(ctx, loc);
     if (getPrimaryOpCode(insn) != LD)
       error("expected a 'ld' for got-indirect to toc-relative relaxing");
-    writeFromHalf16(loc, (insn & 0x03ffffff) | 0x38000000);
+    writeFromHalf16(ctx, loc, (insn & 0x03ffffff) | 0x38000000);
     relocateNoSym(loc, R_PPC64_TOC16_LO, val);
     break;
   }
   case R_PPC64_GOT_PCREL34: {
     // Clear the first 8 bits of the prefix and the first 6 bits of the
     // instruction (the primary opcode).
-    uint64_t insn = readPrefixedInstruction(loc);
+    uint64_t insn = readPrefixedInst(ctx, loc);
     if ((insn & 0xfc000000) != 0xe4000000)
       error("expected a 'pld' for got-indirect to pc-relative relaxing");
     insn &= ~0xff000000fc000000;
 
     // Replace the cleared bits with the values for PADDI (0x600000038000000);
     insn |= 0x600000038000000;
-    writePrefixedInstruction(loc, insn);
+    writePrefixedInst(ctx, loc, insn);
     relocate(loc, rel, val);
     break;
   }
@@ -683,7 +683,7 @@ void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     // We can only relax this if the R_PPC64_GOT_PCREL34 at this offset can
     // be relaxed. The eligibility for the relaxation needs to be determined
     // on that relocation since this one does not relocate a symbol.
-    uint64_t insn = readPrefixedInstruction(loc);
+    uint64_t insn = readPrefixedInst(ctx, loc);
     uint32_t accessInsn = read32(loc + rel.addend);
     uint64_t pcRelInsn = getPCRelativeForm(accessInsn);
 
@@ -702,9 +702,9 @@ void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
       break; // Displacement doesn't fit.
     // Convert the PADDI to the prefixed version of accessInsn and convert
     // accessInsn to a nop.
-    writePrefixedInstruction(loc, pcRelInsn |
-                                      ((totalDisp & 0x3ffff0000) << 16) |
-                                      (totalDisp & 0xffff));
+    writePrefixedInst(ctx, loc,
+                      pcRelInsn | ((totalDisp & 0x3ffff0000) << 16) |
+                          (totalDisp & 0xffff));
     write32(loc + rel.addend, NOP); // nop accessInsn.
     break;
   }
@@ -732,17 +732,17 @@ void PPC64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
 
   switch (rel.type) {
   case R_PPC64_GOT_TLSGD16_HA:
-    writeFromHalf16(loc, NOP);
+    writeFromHalf16(ctx, loc, NOP);
     break;
   case R_PPC64_GOT_TLSGD16:
   case R_PPC64_GOT_TLSGD16_LO:
-    writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13
+    writeFromHalf16(ctx, loc, 0x3c6d0000); // addis r3, r13
     relocateNoSym(loc, R_PPC64_TPREL16_HA, val);
     break;
   case R_PPC64_GOT_TLSGD_PCREL34:
     // Relax from paddi r3, 0, x at got@tlsgd at pcrel, 1 to
     //            paddi r3, r13, x at tprel, 0
-    writePrefixedInstruction(loc, 0x06000000386d0000);
+    writePrefixedInst(ctx, loc, 0x06000000386d0000);
     relocateNoSym(loc, R_PPC64_TPREL34, val);
     break;
   case R_PPC64_TLSGD: {
@@ -795,15 +795,15 @@ void PPC64::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
 
   switch (rel.type) {
   case R_PPC64_GOT_TLSLD16_HA:
-    writeFromHalf16(loc, NOP);
+    writeFromHalf16(ctx, loc, NOP);
     break;
   case R_PPC64_GOT_TLSLD16_LO:
-    writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13, 0
+    writeFromHalf16(ctx, loc, 0x3c6d0000); // addis r3, r13, 0
     break;
   case R_PPC64_GOT_TLSLD_PCREL34:
     // Relax from paddi r3, 0, x1 at got@tlsld at pcrel, 1 to
     //            paddi r3, r13, 0x1000, 0
-    writePrefixedInstruction(loc, 0x06000000386d1000);
+    writePrefixedInst(ctx, loc, 0x06000000386d1000);
     break;
   case R_PPC64_TLSLD: {
     // PC Relative Relaxation:
@@ -922,9 +922,9 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
     break;
   }
   case R_PPC64_GOT_TPREL_PCREL34: {
-    const uint64_t pldRT = readPrefixedInstruction(loc) & 0x0000000003e00000;
+    const uint64_t pldRT = readPrefixedInst(ctx, loc) & 0x0000000003e00000;
     // paddi RT(from pld), r13, symbol at tprel, 0
-    writePrefixedInstruction(loc, 0x06000000380d0000 | pldRT);
+    writePrefixedInst(ctx, loc, 0x06000000380d0000 | pldRT);
     relocateNoSym(loc, R_PPC64_TPREL34, val);
     break;
   }
@@ -1133,7 +1133,7 @@ int64_t PPC64::getImplicitAddend(const uint8_t *buf, RelType type) const {
 }
 
 void PPC64::writeGotHeader(uint8_t *buf) const {
-  write64(buf, getPPC64TocBase());
+  write64(buf, getPPC64TocBase(ctx));
 }
 
 void PPC64::writePltHeader(uint8_t *buf) const {
@@ -1168,7 +1168,7 @@ void PPC64::writePlt(uint8_t *buf, const Symbol &sym,
 
 void PPC64::writeIplt(uint8_t *buf, const Symbol &sym,
                       uint64_t /*pltEntryAddr*/) const {
-  writePPC64LoadAndBranch(buf, sym.getGotPltVA() - getPPC64TocBase());
+  writePPC64LoadAndBranch(buf, sym.getGotPltVA() - getPPC64TocBase(ctx));
 }
 
 static std::pair<RelType, uint64_t> toAddr16Rel(RelType type, uint64_t val) {
@@ -1284,7 +1284,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     checkInt(loc, val, 16, rel);
     // DQ-form instructions use bits 28-31 as part of the instruction encoding
     // DS-form instructions only use bits 30-31.
-    uint16_t mask = isDQFormInstruction(readFromHalf16(loc)) ? 0xf : 0x3;
+    uint16_t mask = isDQFormInstruction(readFromHalf16(ctx, loc)) ? 0xf : 0x3;
     checkAlignment(loc, lo(val), mask + 1, rel);
     write16(loc, (read16(loc) & mask) | lo(val));
   } break;
@@ -1292,7 +1292,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC64_REL16_HA:
   case R_PPC64_TPREL16_HA:
     if (ctx.arg.tocOptimize && shouldTocOptimize && ha(val) == 0)
-      writeFromHalf16(loc, NOP);
+      writeFromHalf16(ctx, loc, NOP);
     else {
       checkInt(loc, val + 0x8000, 32, rel);
       write16(loc, ha(val));
@@ -1330,12 +1330,12 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     // changed into a nop. The lo part then needs to be updated to use the
     // toc-pointer register r2, as the base register.
     if (ctx.arg.tocOptimize && shouldTocOptimize && ha(val) == 0) {
-      uint32_t insn = readFromHalf16(loc);
+      uint32_t insn = readFromHalf16(ctx, loc);
       if (isInstructionUpdateForm(insn))
         error(getErrorLocation(loc) +
               "can't toc-optimize an update instruction: 0x" +
               utohexstr(insn));
-      writeFromHalf16(loc, (insn & 0xffe00000) | 0x00020000 | lo(val));
+      writeFromHalf16(ctx, loc, (insn & 0xffe00000) | 0x00020000 | lo(val));
     } else {
       write16(loc, lo(val));
     }
@@ -1344,7 +1344,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC64_TPREL16_LO_DS: {
     // DQ-form instructions use bits 28-31 as part of the instruction encoding
     // DS-form instructions only use bits 30-31.
-    uint32_t insn = readFromHalf16(loc);
+    uint32_t insn = readFromHalf16(ctx, loc);
     uint16_t mask = isDQFormInstruction(insn) ? 0xf : 0x3;
     checkAlignment(loc, lo(val), mask + 1, rel);
     if (ctx.arg.tocOptimize && shouldTocOptimize && ha(val) == 0) {
@@ -1356,7 +1356,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
               "Can't toc-optimize an update instruction: 0x" +
               Twine::utohexstr(insn));
       insn &= 0xffe00000 | mask;
-      writeFromHalf16(loc, insn | 0x00020000 | lo(val));
+      writeFromHalf16(ctx, loc, insn | 0x00020000 | lo(val));
     } else {
       write16(loc, (read16(loc) & mask) | lo(val));
     }
@@ -1409,9 +1409,9 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     const uint64_t fullMask = 0x0003ffff0000ffff;
     checkInt(loc, val, 34, rel);
 
-    uint64_t instr = readPrefixedInstruction(loc) & ~fullMask;
-    writePrefixedInstruction(loc, instr | ((val & si0Mask) << 16) |
-                             (val & si1Mask));
+    uint64_t instr = readPrefixedInst(ctx, loc) & ~fullMask;
+    writePrefixedInst(ctx, loc,
+                      instr | ((val & si0Mask) << 16) | (val & si1Mask));
     break;
   }
   // If we encounter a PCREL_OPT relocation that we won't optimize.
@@ -1486,7 +1486,7 @@ RelExpr PPC64::adjustGotPcExpr(RelType type, int64_t addend,
       ctx.arg.pcRelOptimize) {
     // It only makes sense to optimize pld since paddi means that the address
     // of the object in the GOT is required rather than the object itself.
-    if ((readPrefixedInstruction(loc) & 0xfc000000) == 0xe4000000)
+    if ((readPrefixedInst(ctx, loc) & 0xfc000000) == 0xe4000000)
       return R_PPC64_RELAX_GOT_PC;
   }
   return R_GOT_PC;
@@ -1521,15 +1521,15 @@ void PPC64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
   case R_PPC64_GOT_TLSGD16_LO: {
     // Relax from addi  r3, rA, sym at got@tlsgd at l to
     //            ld r3, sym at got@tprel at l(rA)
-    uint32_t ra = (readFromHalf16(loc) & (0x1f << 16));
-    writeFromHalf16(loc, 0xe8600000 | ra);
+    uint32_t ra = (readFromHalf16(ctx, loc) & (0x1f << 16));
+    writeFromHalf16(ctx, loc, 0xe8600000 | ra);
     relocateNoSym(loc, R_PPC64_GOT_TPREL16_LO_DS, val);
     return;
   }
   case R_PPC64_GOT_TLSGD_PCREL34: {
     // Relax from paddi r3, 0, sym at got@tlsgd at pcrel, 1 to
     //            pld r3, sym at got@tprel at pcrel
-    writePrefixedInstruction(loc, 0x04100000e4600000);
+    writePrefixedInst(ctx, loc, 0x04100000e4600000);
     relocateNoSym(loc, R_PPC64_GOT_TPREL_PCREL34, val);
     return;
   }
@@ -1594,7 +1594,7 @@ void PPC64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
       // R_PPC64_TOC16_LO_DS. Don't relax. This loses some relaxation
       // opportunities but is safe.
       if (ctx.ppc64noTocRelax.count({rel.sym, rel.addend}) ||
-          !tryRelaxPPC64TocIndirection(rel, loc))
+          !tryRelaxPPC64TocIndirection(ctx, rel, loc))
         relocate(loc, rel, val);
       break;
     case R_PPC64_CALL:

diff  --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index f13000fcadec2b..052d39ed43c4f1 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -137,7 +137,7 @@ RISCV::RISCV(Ctx &ctx) : TargetInfo(ctx) {
   ipltEntrySize = 16;
 }
 
-static uint32_t getEFlags(InputFile *f) {
+static uint32_t getEFlags(Ctx &ctx, InputFile *f) {
   if (ctx.arg.is64)
     return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader().e_flags;
   return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader().e_flags;
@@ -149,10 +149,9 @@ uint32_t RISCV::calcEFlags() const {
   if (ctx.objectFiles.empty())
     return 0;
 
-  uint32_t target = getEFlags(ctx.objectFiles.front());
-
+  uint32_t target = getEFlags(ctx, ctx.objectFiles.front());
   for (InputFile *f : ctx.objectFiles) {
-    uint32_t eflags = getEFlags(f);
+    uint32_t eflags = getEFlags(ctx, f);
     if (eflags & EF_RISCV_RVC)
       target |= EF_RISCV_RVC;
 
@@ -547,7 +546,8 @@ static bool relaxable(ArrayRef<Relocation> relocs, size_t i) {
   return i + 1 != relocs.size() && relocs[i + 1].type == R_RISCV_RELAX;
 }
 
-static void tlsdescToIe(uint8_t *loc, const Relocation &rel, uint64_t val) {
+static void tlsdescToIe(Ctx &ctx, uint8_t *loc, const Relocation &rel,
+                        uint64_t val) {
   switch (rel.type) {
   case R_RISCV_TLSDESC_HI20:
   case R_RISCV_TLSDESC_LOAD_LO12:
@@ -627,7 +627,7 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
       isToLe = false;
       tlsdescRelax = relaxable(relocs, i);
       if (!tlsdescRelax)
-        tlsdescToIe(loc, rel, val);
+        tlsdescToIe(ctx, loc, rel, val);
       continue;
     case R_RELAX_TLS_GD_TO_LE:
       // See the comment in handleTlsRelocation. For TLSDESC=>IE,
@@ -652,7 +652,7 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
       if (isToLe)
         tlsdescToLe(loc, rel, val);
       else
-        tlsdescToIe(loc, rel, val);
+        tlsdescToIe(ctx, loc, rel, val);
       continue;
     case R_RISCV_LEB128:
       if (i + 1 < size) {
@@ -678,7 +678,7 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
   }
 }
 
-void elf::initSymbolAnchors() {
+void elf::initSymbolAnchors(Ctx &ctx) {
   SmallVector<InputSection *, 0> storage;
   for (OutputSection *osec : ctx.outputSections) {
     if (!(osec->flags & SHF_EXECINSTR))
@@ -732,9 +732,9 @@ void elf::initSymbolAnchors() {
 }
 
 // Relax R_RISCV_CALL/R_RISCV_CALL_PLT auipc+jalr to c.j, c.jal, or jal.
-static void relaxCall(const InputSection &sec, size_t i, uint64_t loc,
+static void relaxCall(Ctx &ctx, const InputSection &sec, size_t i, uint64_t loc,
                       Relocation &r, uint32_t &remove) {
-  const bool rvc = getEFlags(sec.file) & EF_RISCV_RVC;
+  const bool rvc = getEFlags(ctx, sec.file) & EF_RISCV_RVC;
   const Symbol &sym = *r.sym;
   const uint64_t insnPair = read64le(sec.content().data() + r.offset);
   const uint32_t rd = extractBits(insnPair, 32 + 11, 32 + 7);
@@ -787,8 +787,8 @@ static void relaxTlsLe(const InputSection &sec, size_t i, uint64_t loc,
   }
 }
 
-static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
-                          Relocation &r, uint32_t &remove) {
+static void relaxHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
+                          uint64_t loc, Relocation &r, uint32_t &remove) {
   const Defined *gp = ctx.sym.riscvGlobalPointer;
   if (!gp)
     return;
@@ -811,7 +811,7 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
   }
 }
 
-static bool relax(InputSection &sec) {
+static bool relax(Ctx &ctx, InputSection &sec) {
   const uint64_t secAddr = sec.getVA();
   const MutableArrayRef<Relocation> relocs = sec.relocs();
   auto &aux = *sec.relaxAux;
@@ -844,7 +844,7 @@ static bool relax(InputSection &sec) {
     case R_RISCV_CALL:
     case R_RISCV_CALL_PLT:
       if (relaxable(relocs, i))
-        relaxCall(sec, i, loc, r, remove);
+        relaxCall(ctx, sec, i, loc, r, remove);
       break;
     case R_RISCV_TPREL_HI20:
     case R_RISCV_TPREL_ADD:
@@ -857,7 +857,7 @@ static bool relax(InputSection &sec) {
     case R_RISCV_LO12_I:
     case R_RISCV_LO12_S:
       if (relaxable(relocs, i))
-        relaxHi20Lo12(sec, i, loc, r, remove);
+        relaxHi20Lo12(ctx, sec, i, loc, r, remove);
       break;
     case R_RISCV_TLSDESC_HI20:
       // For TLSDESC=>LE, we can use the short form if hi20 is zero.
@@ -918,7 +918,7 @@ bool RISCV::relaxOnce(int pass) const {
     return false;
 
   if (pass == 0)
-    initSymbolAnchors();
+    initSymbolAnchors(ctx);
 
   SmallVector<InputSection *, 0> storage;
   bool changed = false;
@@ -926,7 +926,7 @@ bool RISCV::relaxOnce(int pass) const {
     if (!(osec->flags & SHF_EXECINSTR))
       continue;
     for (InputSection *sec : getInputSections(*osec, storage))
-      changed |= relax(*sec);
+      changed |= relax(ctx, *sec);
   }
   return changed;
 }
@@ -1170,7 +1170,8 @@ static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it,
 }
 
 static RISCVAttributesSection *
-mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
+mergeAttributesSection(Ctx &ctx,
+                       const SmallVector<InputSectionBase *, 0> &sections) {
   using RISCVAttrs::RISCVAtomicAbiTag;
   RISCVISAUtils::OrderedExtensionMap exts;
   const InputSectionBase *firstStackAlign = nullptr;
@@ -1305,7 +1306,7 @@ void RISCVAttributesSection::writeTo(Ctx &ctx, uint8_t *buf) {
   }
 }
 
-void elf::mergeRISCVAttributesSections(Ctx &) {
+void elf::mergeRISCVAttributesSections(Ctx &ctx) {
   // Find the first input SHT_RISCV_ATTRIBUTES; return if not found.
   size_t place =
       llvm::find_if(ctx.inputSections,
@@ -1325,7 +1326,7 @@ void elf::mergeRISCVAttributesSections(Ctx &) {
 
   // Add the merged section.
   ctx.inputSections.insert(ctx.inputSections.begin() + place,
-                           mergeAttributesSection(sections));
+                           mergeAttributesSection(ctx, sections));
 }
 
 TargetInfo *elf::getRISCVTargetInfo(Ctx &ctx) {

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 373505a9e965b7..9f084ed774921a 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2059,7 +2059,7 @@ void LinkerDriver::inferMachineType() {
       inferred = true;
       ctx.arg.ekind = f->ekind;
       ctx.arg.emachine = f->emachine;
-      ctx.arg.mipsN32Abi = ctx.arg.emachine == EM_MIPS && isMipsN32Abi(f);
+      ctx.arg.mipsN32Abi = ctx.arg.emachine == EM_MIPS && isMipsN32Abi(ctx, *f);
     }
     ctx.arg.osabi = f->osabi;
     if (f->osabi != ELFOSABI_NONE)
@@ -3155,7 +3155,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
 
   if (canHaveMemtagGlobals()) {
     llvm::TimeTraceScope timeScope("Process memory tagged symbols");
-    createTaggedSymbols(ctx.objectFiles);
+    createTaggedSymbols(ctx);
   }
 
   // Create synthesized sections such as .got and .plt. This is called before

diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 3f5d2fbb5cbae5..7841cae6e8ffd5 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -272,7 +272,7 @@ static bool isCompatible(Ctx &ctx, InputFile *file) {
   if (file->ekind == ctx.arg.ekind && file->emachine == ctx.arg.emachine) {
     if (ctx.arg.emachine != EM_MIPS)
       return true;
-    if (isMipsN32Abi(file) == ctx.arg.mipsN32Abi)
+    if (isMipsN32Abi(ctx, *file) == ctx.arg.mipsN32Abi)
       return true;
   }
 

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index eb6de90a02f661..09267a515d0900 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -893,7 +893,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
     return symVA - p + getPPC64GlobalEntryToLocalEntryOffset(sym.stOther);
   }
   case R_PPC64_TOCBASE:
-    return getPPC64TocBase() + a;
+    return getPPC64TocBase(ctx) + a;
   case R_RELAX_GOT_PC:
   case R_PPC64_RELAX_GOT_PC:
     return sym.getVA(a) - p;

diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 12c4b69bee57e4..a70d26fb418d6e 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1480,7 +1480,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
   if (LLVM_UNLIKELY(ctx.arg.emachine == EM_MIPS))
     addend += computeMipsAddend<ELFT>(rel, expr, sym.isLocal());
   else if (ctx.arg.emachine == EM_PPC64 && ctx.arg.isPic && type == R_PPC64_TOC)
-    addend += getPPC64TocBase();
+    addend += getPPC64TocBase(ctx);
 
   // Ignore R_*_NONE and other marker relocations.
   if (expr == R_NONE)

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index bc0da5da755b84..f5609ab56b355c 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2645,7 +2645,7 @@ PPC32GlinkSection::PPC32GlinkSection() {
 }
 
 void PPC32GlinkSection::writeTo(Ctx &ctx, uint8_t *buf) {
-  writePPC32GlinkSection(buf, entries.size());
+  writePPC32GlinkSection(ctx, buf, entries.size());
 }
 
 size_t PPC32GlinkSection::getSize(Ctx &ctx) const {
@@ -4870,7 +4870,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
   }
 
   if (ctx.arg.emachine == EM_ARM) {
-    ctx.in.armCmseSGSection = std::make_unique<ArmCmseSGSection>();
+    ctx.in.armCmseSGSection = std::make_unique<ArmCmseSGSection>(ctx);
     add(*ctx.in.armCmseSGSection);
   }
 

diff  --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 37724d783162c5..12a4db8262707d 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1311,7 +1311,7 @@ class ArmCmseSGVeneer;
 
 class ArmCmseSGSection final : public SyntheticSection {
 public:
-  ArmCmseSGSection();
+  ArmCmseSGSection(Ctx &ctx);
   bool isNeeded() const override { return !entries.empty(); }
   size_t getSize(Ctx &) const override;
   void writeTo(Ctx &, uint8_t *buf) override;

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index f18770dfc424de..fbf6a0df4f2aed 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -210,7 +210,7 @@ static inline std::string getErrorLocation(const uint8_t *loc) {
 
 void processArmCmseSymbols(Ctx &);
 
-void writePPC32GlinkSection(uint8_t *buf, size_t numEntries);
+void writePPC32GlinkSection(Ctx &, uint8_t *buf, size_t numEntries);
 
 unsigned getPPCDFormOp(unsigned secondaryOp);
 unsigned getPPCDSFormOp(unsigned secondaryOp);
@@ -227,22 +227,22 @@ unsigned getPPC64GlobalEntryToLocalEntryOffset(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
 // lower memory than the instruction.
-void writePrefixedInstruction(uint8_t *loc, uint64_t insn);
+void writePrefixedInst(Ctx &, uint8_t *loc, uint64_t insn);
 
-void addPPC64SaveRestore();
-uint64_t getPPC64TocBase();
+void addPPC64SaveRestore(Ctx &);
+uint64_t getPPC64TocBase(Ctx &ctx);
 uint64_t getAArch64Page(uint64_t expr);
 bool isAArch64BTILandingPad(Symbol &s, int64_t a);
-template <typename ELFT> void writeARMCmseImportLib();
+template <typename ELFT> void writeARMCmseImportLib(Ctx &);
 uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type);
 void riscvFinalizeRelax(int passes);
 void mergeRISCVAttributesSections(Ctx &);
-void addArmInputSectionMappingSymbols();
+void addArmInputSectionMappingSymbols(Ctx &);
 void addArmSyntheticSectionMappingSymbol(Defined *);
 void sortArmMappingSymbols();
 void convertArmInstructionstoBE8(InputSection *sec, uint8_t *buf);
-void createTaggedSymbols(const SmallVector<ELFFileBase *, 0> &files);
-void initSymbolAnchors();
+void createTaggedSymbols(Ctx &);
+void initSymbolAnchors(Ctx &);
 
 TargetInfo *getTarget(Ctx &);
 

diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 1a01c3f6b3e581..629ef994773229 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -1231,7 +1231,7 @@ void elf::writePPC64LoadAndBranch(uint8_t *buf, int64_t offset) {
 }
 
 void PPC64PltCallStub::writeTo(uint8_t *buf) {
-  int64_t offset = destination.getGotPltVA() - getPPC64TocBase();
+  int64_t offset = destination.getGotPltVA() - getPPC64TocBase(ctx);
   // Save the TOC pointer to the save-slot reserved in the call frame.
   write32(buf + 0, 0xf8410018); // std     r2,24(r1)
   writePPC64LoadAndBranch(buf + 4, offset);
@@ -1257,7 +1257,7 @@ void PPC64R2SaveStub::writeTo(uint8_t *buf) {
     write32(buf + 4, 0x48000000 | (offset & 0x03fffffc)); // b    <offset>
   } else if (isInt<34>(offset)) {
     int nextInstOffset;
-    uint64_t tocOffset = destination.getVA() - getPPC64TocBase();
+    uint64_t tocOffset = destination.getVA() - getPPC64TocBase(ctx);
     if (tocOffset >> 16 > 0) {
       const uint64_t addi = ADDI_R12_TO_R12_NO_DISP | (tocOffset & 0xffff);
       const uint64_t addis =
@@ -1276,7 +1276,7 @@ void PPC64R2SaveStub::writeTo(uint8_t *buf) {
     ctx.in.ppc64LongBranchTarget->addEntry(&destination, addend);
     const int64_t offsetFromTOC =
         ctx.in.ppc64LongBranchTarget->getEntryVA(&destination, addend) -
-        getPPC64TocBase();
+        getPPC64TocBase(ctx);
     writePPC64LoadAndBranch(buf + 4, offsetFromTOC);
   }
 }
@@ -1303,8 +1303,8 @@ void PPC64R12SetupStub::writeTo(uint8_t *buf) {
   if (ctx.arg.power10Stubs) {
     const uint64_t imm = (((offset >> 16) & 0x3ffff) << 32) | (offset & 0xffff);
     // pld 12, func at plt@pcrel or  paddi r12, 0, func at pcrel
-    writePrefixedInstruction(
-        buf, (gotPlt ? PLD_R12_NO_DISP : PADDI_R12_NO_DISP) | imm);
+    writePrefixedInst(ctx, buf,
+                      (gotPlt ? PLD_R12_NO_DISP : PADDI_R12_NO_DISP) | imm);
     nextInstOffset = 8;
   } else {
     uint32_t off = offset - 8;
@@ -1338,7 +1338,7 @@ bool PPC64R12SetupStub::isCompatibleWith(const InputSection &isec,
 void PPC64LongBranchThunk::writeTo(uint8_t *buf) {
   int64_t offset =
       ctx.in.ppc64LongBranchTarget->getEntryVA(&destination, addend) -
-      getPPC64TocBase();
+      getPPC64TocBase(ctx);
   writePPC64LoadAndBranch(buf, offset);
 }
 
@@ -1514,7 +1514,7 @@ static Thunk *addThunkAVR(Ctx &ctx, RelType type, Symbol &s, int64_t a) {
 }
 
 static Thunk *addThunkMips(Ctx &ctx, RelType type, Symbol &s) {
-  if ((s.stOther & STO_MIPS_MICROMIPS) && isMipsR6())
+  if ((s.stOther & STO_MIPS_MICROMIPS) && isMipsR6(ctx))
     return make<MicroMipsR6Thunk>(ctx, s);
   if (s.stOther & STO_MIPS_MICROMIPS)
     return make<MicroMipsThunk>(ctx, s);

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index c922d0366ae660..a6c3a0f5b9ce0d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -186,7 +186,7 @@ void elf::addReservedSymbols(Ctx &ctx) {
     // support Small Data Area, define it arbitrarily as 0.
     addOptionalRegular(ctx, "_SDA_BASE_", nullptr, 0, STV_HIDDEN);
   } else if (ctx.arg.emachine == EM_PPC64) {
-    addPPC64SaveRestore();
+    addPPC64SaveRestore(ctx);
   }
 
   // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which
@@ -377,7 +377,7 @@ template <class ELFT> void Writer<ELFT>::run() {
             "': " + toString(std::move(e)));
 
     if (!ctx.arg.cmseOutputLib.empty())
-      writeARMCmseImportLib<ELFT>();
+      writeARMCmseImportLib<ELFT>(ctx);
   }
 }
 
@@ -2082,7 +2082,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   ctx.script->checkFinalScriptConditions();
 
   if (ctx.arg.emachine == EM_ARM && !ctx.arg.isLE && ctx.arg.armBe8) {
-    addArmInputSectionMappingSymbols();
+    addArmInputSectionMappingSymbols(ctx);
     sortArmMappingSymbols();
   }
 }

diff  --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h
index 3a82a4bb5f8bf0..33e40dbfb1c4c4 100644
--- a/lld/ELF/Writer.h
+++ b/lld/ELF/Writer.h
@@ -48,14 +48,14 @@ void addReservedSymbols(Ctx &ctx);
 bool includeInSymtab(const Symbol &b);
 unsigned getSectionRank(Ctx &, OutputSection &osec);
 
-template <class ELFT> uint32_t calcMipsEFlags();
+template <class ELFT> uint32_t calcMipsEFlags(Ctx &);
 
 uint8_t getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
                          llvm::StringRef fileName);
 
-bool isMipsN32Abi(const InputFile *f);
+bool isMipsN32Abi(Ctx &, const InputFile &f);
 bool isMicroMips();
-bool isMipsR6();
+bool isMipsR6(Ctx &);
 
 } // namespace lld::elf
 


        


More information about the llvm-commits mailing list