[lld] 7a5b9ef - [ELF] Pass Ctx & to SyntheticSection::writeTo

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 3 20:56:14 PDT 2024


Author: Fangrui Song
Date: 2024-10-03T20:56:09-07:00
New Revision: 7a5b9ef54eb96abd8415fd893576c42e51fd95db

URL: https://github.com/llvm/llvm-project/commit/7a5b9ef54eb96abd8415fd893576c42e51fd95db
DIFF: https://github.com/llvm/llvm-project/commit/7a5b9ef54eb96abd8415fd893576c42e51fd95db.diff

LOG: [ELF] Pass Ctx & to SyntheticSection::writeTo

Added: 
    

Modified: 
    lld/ELF/AArch64ErrataFix.cpp
    lld/ELF/ARMErrataFix.cpp
    lld/ELF/Arch/ARM.cpp
    lld/ELF/Arch/RISCV.cpp
    lld/ELF/InputSection.h
    lld/ELF/OutputSections.cpp
    lld/ELF/OutputSections.h
    lld/ELF/SyntheticSections.cpp
    lld/ELF/SyntheticSections.h
    lld/ELF/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp
index 7a1477ebb79ad0..789711983140bb 100644
--- a/lld/ELF/AArch64ErrataFix.cpp
+++ b/lld/ELF/AArch64ErrataFix.cpp
@@ -374,7 +374,7 @@ class elf::Patch843419Section final : public SyntheticSection {
 public:
   Patch843419Section(InputSection *p, uint64_t off);
 
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
   size_t getSize() const override { return 8; }
 
@@ -407,7 +407,7 @@ uint64_t Patch843419Section::getLDSTAddr() const {
   return patchee->getVA(patcheeOffset);
 }
 
-void Patch843419Section::writeTo(uint8_t *buf) {
+void Patch843419Section::writeTo(Ctx &ctx, uint8_t *buf) {
   // Copy the instruction that we will be replacing with a branch in the
   // patchee Section.
   write32le(buf, read32le(patchee->content().begin() + patcheeOffset));

diff  --git a/lld/ELF/ARMErrataFix.cpp b/lld/ELF/ARMErrataFix.cpp
index 7068344a73b955..ebc79bb33af3ef 100644
--- a/lld/ELF/ARMErrataFix.cpp
+++ b/lld/ELF/ARMErrataFix.cpp
@@ -72,7 +72,7 @@ class elf::Patch657417Section final : public SyntheticSection {
 public:
   Patch657417Section(InputSection *p, uint64_t off, uint32_t instr, bool isARM);
 
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
   size_t getSize() const override { return 4; }
 
@@ -174,7 +174,7 @@ static uint64_t getThumbDestAddr(uint64_t sourceAddr, uint32_t instr) {
   return sourceAddr + offset + 4;
 }
 
-void Patch657417Section::writeTo(uint8_t *buf) {
+void Patch657417Section::writeTo(Ctx &ctx, uint8_t *buf) {
   // The base instruction of the patch is always a 32-bit unconditional branch.
   if (isARM)
     write32le(buf, 0xea000000);

diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index bd24e423841ac8..6969a9cab7e7b5 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -1380,7 +1380,7 @@ void ArmCmseSGSection::addSGVeneer(Symbol *acleSeSym, Symbol *sym) {
   sgVeneers.emplace_back(ss);
 }
 
-void ArmCmseSGSection::writeTo(uint8_t *buf) {
+void ArmCmseSGSection::writeTo(Ctx &ctx, uint8_t *buf) {
   for (ArmCmseSGVeneer *s : sgVeneers) {
     uint8_t *p = buf + s->offset;
     write16(p + 0, 0xe97f); // SG
@@ -1525,7 +1525,7 @@ template <typename ELFT> void elf::writeARMCmseImportLib() {
   {
     parallel::TaskGroup tg;
     for (auto &[osec, _] : osIsPairs)
-      osec->template writeTo<ELFT>(buf + osec->offset, tg);
+      osec->template writeTo<ELFT>(ctx, buf + osec->offset, tg);
   }
 
   if (auto e = buffer->commit())

diff  --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index f776ac8ede1bd7..ea20613070097f 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -1048,7 +1048,7 @@ class RISCVAttributesSection final : public SyntheticSection {
       : SyntheticSection(0, SHT_RISCV_ATTRIBUTES, 1, ".riscv.attributes") {}
 
   size_t getSize() const override { return size; }
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
   static constexpr StringRef vendor = "riscv";
   DenseMap<unsigned, unsigned> intAttr;
@@ -1276,7 +1276,7 @@ mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
   return &merged;
 }
 
-void RISCVAttributesSection::writeTo(uint8_t *buf) {
+void RISCVAttributesSection::writeTo(Ctx &ctx, uint8_t *buf) {
   const size_t size = getSize();
   uint8_t *const end = buf + size;
   *buf = ELFAttrs::Format_Version;

diff  --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 4d022ee1e44def..5e5457812c275d 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -484,7 +484,7 @@ class SyntheticSection : public InputSection {
   // thunks are added, update the section size.
   virtual bool isNeeded() const { return true; }
   virtual void finalizeContents(Ctx &) {}
-  virtual void writeTo(uint8_t *buf) = 0;
+  virtual void writeTo(Ctx &, uint8_t *buf) = 0;
 
   static bool classof(const SectionBase *sec) {
     return sec->kind() == InputSectionBase::Synthetic;

diff  --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index ac07af1649e918..3468420b3bb0bb 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -368,7 +368,7 @@ template <class ELFT> void OutputSection::maybeCompress(Ctx &ctx) {
   // Write uncompressed data to a temporary zero-initialized buffer.
   {
     parallel::TaskGroup tg;
-    writeTo<ELFT>(buf.get(), tg);
+    writeTo<ELFT>(ctx, buf.get(), tg);
   }
   // The generic ABI specifies "The sh_size and sh_addralign fields of the
   // section header for a compressed section reflect the requirements of the
@@ -469,7 +469,7 @@ static void writeInt(uint8_t *buf, uint64_t data, uint64_t size) {
 }
 
 template <class ELFT>
-void OutputSection::writeTo(uint8_t *buf, parallel::TaskGroup &tg) {
+void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
   llvm::TimeTraceScope timeScope("Write sections", name);
   if (type == SHT_NOBITS)
     return;
@@ -519,12 +519,12 @@ void OutputSection::writeTo(uint8_t *buf, parallel::TaskGroup &tg) {
     return;
   }
 
-  auto fn = [=](size_t begin, size_t end) {
+  auto fn = [=, &ctx](size_t begin, size_t end) {
     size_t numSections = sections.size();
     for (size_t i = begin; i != end; ++i) {
       InputSection *isec = sections[i];
       if (auto *s = dyn_cast<SyntheticSection>(isec))
-        s->writeTo(buf + isec->outSecOff);
+        s->writeTo(ctx, buf + isec->outSecOff);
       else
         isec->writeTo<ELFT>(buf + isec->outSecOff);
 
@@ -911,13 +911,13 @@ template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
 template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
 template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
 
-template void OutputSection::writeTo<ELF32LE>(uint8_t *,
+template void OutputSection::writeTo<ELF32LE>(Ctx &, uint8_t *,
                                               llvm::parallel::TaskGroup &);
-template void OutputSection::writeTo<ELF32BE>(uint8_t *,
+template void OutputSection::writeTo<ELF32BE>(Ctx &, uint8_t *,
                                               llvm::parallel::TaskGroup &);
-template void OutputSection::writeTo<ELF64LE>(uint8_t *,
+template void OutputSection::writeTo<ELF64LE>(Ctx &, uint8_t *,
                                               llvm::parallel::TaskGroup &);
-template void OutputSection::writeTo<ELF64BE>(uint8_t *,
+template void OutputSection::writeTo<ELF64BE>(Ctx &, uint8_t *,
                                               llvm::parallel::TaskGroup &);
 
 template void OutputSection::maybeCompress<ELF32LE>(Ctx &);

diff  --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 10363127918dfb..904206b20bc1cb 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -114,7 +114,7 @@ class OutputSection final : public SectionBase {
   template <bool is64> void finalizeNonAllocCrel(Ctx &);
   void finalize(Ctx &);
   template <class ELFT>
-  void writeTo(uint8_t *buf, llvm::parallel::TaskGroup &tg);
+  void writeTo(Ctx &, uint8_t *buf, llvm::parallel::TaskGroup &tg);
   // Check that the addends for dynamic relocations were written correctly.
   void checkDynRelAddends(Ctx &);
   template <class ELFT> void maybeCompress(Ctx &);

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index cddd5ccddfea6f..1c34adff724b25 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -102,7 +102,8 @@ MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags flags)
   this->entsize = sizeof(Elf_Mips_ABIFlags);
 }
 
-template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void MipsAbiFlagsSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   memcpy(buf, &flags, sizeof(flags));
 }
 
@@ -162,7 +163,8 @@ MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo reginfo)
   this->entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
 }
 
-template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void MipsOptionsSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   auto *options = reinterpret_cast<Elf_Mips_Options *>(buf);
   options->kind = ODK_REGINFO;
   options->size = getSize();
@@ -223,7 +225,8 @@ MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo reginfo)
   this->entsize = sizeof(Elf_Mips_RegInfo);
 }
 
-template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void MipsReginfoSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   if (!ctx.arg.relocatable)
     reginfo.ri_gp_value = ctx.in.mipsGot->getGp();
   memcpy(buf, &reginfo, sizeof(reginfo));
@@ -317,7 +320,7 @@ GnuPropertySection::GnuPropertySection()
     : SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE,
                        ctx.arg.wordsize, ".note.gnu.property") {}
 
-void GnuPropertySection::writeTo(uint8_t *buf) {
+void GnuPropertySection::writeTo(Ctx &ctx, uint8_t *buf) {
   write32(buf, 4);                          // Name size
   write32(buf + 4, getSize() - 16);         // Content size
   write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
@@ -359,7 +362,7 @@ BuildIdSection::BuildIdSection()
     : SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
       hashSize(getHashSize()) {}
 
-void BuildIdSection::writeTo(uint8_t *buf) {
+void BuildIdSection::writeTo(Ctx &ctx, uint8_t *buf) {
   write32(buf, 4);                      // Name size
   write32(buf + 4, hashSize);           // Content size
   write32(buf + 8, NT_GNU_BUILD_ID);    // Type
@@ -621,7 +624,7 @@ uint64_t EhFrameSection::getFdePc(uint8_t *buf, size_t fdeOff,
   fatal("unknown FDE size relative encoding");
 }
 
-void EhFrameSection::writeTo(uint8_t *buf) {
+void EhFrameSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // Write CIE and FDE records.
   for (CieRecord *rec : cieRecords) {
     size_t cieOffset = rec->cie->outputOff;
@@ -715,7 +718,7 @@ bool GotSection::isNeeded() const {
   return hasGotOffRel || numEntries > ctx.target->gotHeaderEntriesNum;
 }
 
-void GotSection::writeTo(uint8_t *buf) {
+void GotSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // On PPC64 .got may be needed but empty. Skip the write.
   if (size == 0)
     return;
@@ -1096,7 +1099,7 @@ uint64_t MipsGotSection::getGp(const InputFile *f) const {
   return getVA() + gots[f->mipsGotIndex].startIndex * ctx.arg.wordsize + 0x7ff0;
 }
 
-void MipsGotSection::writeTo(uint8_t *buf) {
+void MipsGotSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // Set the MSB of the second GOT slot. This is not required by any
   // MIPS ABI documentation, though.
   //
@@ -1185,7 +1188,7 @@ size_t GotPltSection::getSize() const {
          ctx.target->gotEntrySize;
 }
 
-void GotPltSection::writeTo(uint8_t *buf) {
+void GotPltSection::writeTo(Ctx &ctx, uint8_t *buf) {
   ctx.target->writeGotPltHeader(buf);
   buf += ctx.target->gotPltHeaderEntriesNum * ctx.target->gotEntrySize;
   for (const Symbol *b : entries) {
@@ -1229,7 +1232,7 @@ size_t IgotPltSection::getSize() const {
   return entries.size() * ctx.target->gotEntrySize;
 }
 
-void IgotPltSection::writeTo(uint8_t *buf) {
+void IgotPltSection::writeTo(Ctx &ctx, uint8_t *buf) {
   for (const Symbol *b : entries) {
     ctx.target->writeIgotPlt(buf, *b);
     buf += ctx.target->gotEntrySize;
@@ -1263,7 +1266,7 @@ unsigned StringTableSection::addString(StringRef s, bool hashIt) {
   return ret;
 }
 
-void StringTableSection::writeTo(uint8_t *buf) {
+void StringTableSection::writeTo(Ctx &ctx, uint8_t *buf) {
   for (StringRef s : strings) {
     memcpy(buf, s.data(), s.size());
     buf[s.size()] = '\0';
@@ -1580,7 +1583,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents(Ctx &) {
   this->size = computeContents().size() * this->entsize;
 }
 
-template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void DynamicSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   auto *p = reinterpret_cast<Elf_Dyn *>(buf);
 
   for (std::pair<int32_t, uint64_t> kv : computeContents()) {
@@ -1732,7 +1736,8 @@ RelocationSection<ELFT>::RelocationSection(StringRef name, bool combreloc,
   this->entsize = ctx.arg.isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
 }
 
-template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void RelocationSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   computeRels();
   for (const DynamicReloc &rel : relocs) {
     auto *p = reinterpret_cast<Elf_Rela *>(buf);
@@ -2243,7 +2248,8 @@ static uint32_t getSymSectionIndex(Symbol *sym) {
 }
 
 // Write the internal symbol table contents to the output symbol table.
-template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void SymbolTableSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   // The first entry is a null entry as per the ELF spec.
   buf += sizeof(Elf_Sym);
 
@@ -2325,7 +2331,7 @@ SymtabShndxSection::SymtabShndxSection()
   this->entsize = 4;
 }
 
-void SymtabShndxSection::writeTo(uint8_t *buf) {
+void SymtabShndxSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // We write an array of 32 bit values, where each value has 1:1 association
   // with an entry in ctx.in.symTab if the corresponding entry contains
   // SHN_XINDEX, we need to write actual index, otherwise, we must write
@@ -2412,7 +2418,7 @@ void GnuHashTableSection::finalizeContents(Ctx &) {
   size += symbols.size() * 4;           // Hash values
 }
 
-void GnuHashTableSection::writeTo(uint8_t *buf) {
+void GnuHashTableSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // Write a header.
   write32(buf, nBuckets);
   write32(buf + 4, getPartition().dynSymTab->getNumSymbols() - symbols.size());
@@ -2517,7 +2523,7 @@ void HashTableSection::finalizeContents(Ctx &) {
   this->size = numEntries * 4;
 }
 
-void HashTableSection::writeTo(uint8_t *buf) {
+void HashTableSection::writeTo(Ctx &ctx, uint8_t *buf) {
   SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
   unsigned numSymbols = symTab->getNumSymbols();
 
@@ -2559,7 +2565,7 @@ PltSection::PltSection()
     this->flags |= SHF_WRITE;
 }
 
-void PltSection::writeTo(uint8_t *buf) {
+void PltSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // At beginning of PLT, we have code to call the dynamic
   // linker to resolve dynsyms at runtime. Write such code.
   ctx.target->writePltHeader(buf);
@@ -2606,7 +2612,7 @@ IpltSection::IpltSection()
   }
 }
 
-void IpltSection::writeTo(uint8_t *buf) {
+void IpltSection::writeTo(Ctx &ctx, uint8_t *buf) {
   uint32_t off = 0;
   for (const Symbol *sym : entries) {
     ctx.target->writeIplt(buf + off, *sym, getVA() + off);
@@ -2638,7 +2644,7 @@ PPC32GlinkSection::PPC32GlinkSection() {
   addralign = 4;
 }
 
-void PPC32GlinkSection::writeTo(uint8_t *buf) {
+void PPC32GlinkSection::writeTo(Ctx &ctx, uint8_t *buf) {
   writePPC32GlinkSection(buf, entries.size());
 }
 
@@ -2707,7 +2713,7 @@ size_t PPC32GlinkSection::getSize() const {
 IBTPltSection::IBTPltSection()
     : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt") {}
 
-void IBTPltSection::writeTo(uint8_t *buf) {
+void IBTPltSection::writeTo(Ctx &ctx, uint8_t *buf) {
   ctx.target->writeIBTPlt(buf, ctx.in.plt->getNumEntries());
 }
 
@@ -3237,7 +3243,8 @@ template <class ELFT> void DebugNamesSection<ELFT>::finalizeContents(Ctx &) {
   });
 }
 
-template <class ELFT> void DebugNamesSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void DebugNamesSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   [[maybe_unused]] const uint8_t *const beginBuf = buf;
   // Write the header.
   endian::writeNext<uint32_t, ELFT::Endianness>(buf, hdr.UnitLength);
@@ -3548,7 +3555,7 @@ std::unique_ptr<GdbIndexSection> GdbIndexSection::create() {
   return ret;
 }
 
-void GdbIndexSection::writeTo(uint8_t *buf) {
+void GdbIndexSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // Write the header.
   auto *hdr = reinterpret_cast<GdbIndexHeader *>(buf);
   uint8_t *start = buf;
@@ -3622,7 +3629,7 @@ bool GdbIndexSection::isNeeded() const { return !chunks.empty(); }
 EhFrameHeader::EhFrameHeader()
     : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}
 
-void EhFrameHeader::writeTo(uint8_t *buf) {
+void EhFrameHeader::writeTo(Ctx &ctx, uint8_t *buf) {
   // Unlike most sections, the EhFrameHeader section is written while writing
   // another section, namely EhFrameSection, which calls the write() function
   // below from its writeTo() function. This is necessary because the contents
@@ -3708,7 +3715,7 @@ void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
   write32(buf + 24, 0);       // vda_next
 }
 
-void VersionDefinitionSection::writeTo(uint8_t *buf) {
+void VersionDefinitionSection::writeTo(Ctx &ctx, uint8_t *buf) {
   writeOne(buf, 1, getFileDefName(), fileDefNameOff);
 
   auto nameOffIt = verDefNameOffs.begin();
@@ -3742,7 +3749,7 @@ size_t VersionTableSection::getSize() const {
   return (getPartition().dynSymTab->getSymbols().size() + 1) * 2;
 }
 
-void VersionTableSection::writeTo(uint8_t *buf) {
+void VersionTableSection::writeTo(Ctx &ctx, uint8_t *buf) {
   buf += 2;
   for (const SymbolTableEntry &s : getPartition().dynSymTab->getSymbols()) {
     // For an unextracted lazy symbol (undefined weak), it must have been
@@ -3814,7 +3821,8 @@ template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents(Ctx &) {
   getParent()->info = verneeds.size();
 }
 
-template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *buf) {
+template <class ELFT>
+void VersionNeedSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   // The Elf_Verneeds need to appear first, followed by the Elf_Vernauxs.
   auto *verneed = reinterpret_cast<Elf_Verneed *>(buf);
   auto *vernaux = reinterpret_cast<Elf_Vernaux *>(verneed + verneeds.size());
@@ -3867,7 +3875,7 @@ MergeTailSection::MergeTailSection(StringRef name, uint32_t type,
 
 size_t MergeTailSection::getSize() const { return builder.getSize(); }
 
-void MergeTailSection::writeTo(uint8_t *buf) { builder.write(buf); }
+void MergeTailSection::writeTo(Ctx &ctx, uint8_t *buf) { builder.write(buf); }
 
 void MergeTailSection::finalizeContents(Ctx &) {
   // Add all string pieces to the string table builder to create section
@@ -3889,7 +3897,7 @@ void MergeTailSection::finalizeContents(Ctx &) {
         sec->pieces[i].outputOff = builder.getOffset(sec->getData(i));
 }
 
-void MergeNoTailSection::writeTo(uint8_t *buf) {
+void MergeNoTailSection::writeTo(Ctx &ctx, uint8_t *buf) {
   parallelFor(0, numShards,
               [&](size_t i) { shards[i].write(buf + shardOffsets[i]); });
 }
@@ -4171,7 +4179,7 @@ InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const {
 //     section is to terminate the address range of the previous entry.
 // 3.) A trailing EXIDX_CANTUNWIND sentinel section is required at the end of
 //     the table to terminate the address range of the final entry.
-void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
+void ARMExidxSyntheticSection::writeTo(Ctx &ctx, uint8_t *buf) {
 
   // A linker generated CANTUNWIND entry is made up of two words:
   // 0x0 with R_ARM_PREL31 relocation to target.
@@ -4231,7 +4239,7 @@ void ThunkSection::addThunk(Thunk *t) {
   t->addSymbols(*this);
 }
 
-void ThunkSection::writeTo(uint8_t *buf) {
+void ThunkSection::writeTo(Ctx &ctx, uint8_t *buf) {
   for (Thunk *t : thunks)
     t->writeTo(buf + t->offset);
 }
@@ -4314,7 +4322,7 @@ size_t PPC64LongBranchTargetSection::getSize() const {
   return entries.size() * 8;
 }
 
-void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
+void PPC64LongBranchTargetSection::writeTo(Ctx &ctx, uint8_t *buf) {
   // If linking non-pic we have the final addresses of the targets and they get
   // written to the table directly. For pic the dynamic linker will allocate
   // the section and fill it.
@@ -4412,7 +4420,7 @@ size_t PartitionElfHeaderSection<ELFT>::getSize() const {
 }
 
 template <typename ELFT>
-void PartitionElfHeaderSection<ELFT>::writeTo(uint8_t *buf) {
+void PartitionElfHeaderSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   writeEhdr<ELFT>(buf, getPartition());
 
   // Loadable partitions are always ET_DYN.
@@ -4430,7 +4438,7 @@ size_t PartitionProgramHeadersSection<ELFT>::getSize() const {
 }
 
 template <typename ELFT>
-void PartitionProgramHeadersSection<ELFT>::writeTo(uint8_t *buf) {
+void PartitionProgramHeadersSection<ELFT>::writeTo(Ctx &ctx, uint8_t *buf) {
   writePhdrs<ELFT>(buf, getPartition());
 }
 
@@ -4447,7 +4455,7 @@ void PartitionIndexSection::finalizeContents(Ctx &) {
         ctx.mainPart->dynStrTab->addString(ctx.partitions[i].name);
 }
 
-void PartitionIndexSection::writeTo(uint8_t *buf) {
+void PartitionIndexSection::writeTo(Ctx &ctx, uint8_t *buf) {
   uint64_t va = getVA();
   for (size_t i = 1; i != ctx.partitions.size(); ++i) {
     write32(buf, ctx.mainPart->dynStrTab->getVA() +
@@ -4517,7 +4525,7 @@ bool elf::canHaveMemtagGlobals() {
 }
 
 constexpr char kMemtagAndroidNoteName[] = "Android";
-void MemtagAndroidNote::writeTo(uint8_t *buf) {
+void MemtagAndroidNote::writeTo(Ctx &ctx, uint8_t *buf) {
   static_assert(
       sizeof(kMemtagAndroidNoteName) == 8,
       "Android 11 & 12 have an ABI that the note name is 8 bytes long. Keep it "
@@ -4546,7 +4554,7 @@ size_t MemtagAndroidNote::getSize() const {
          /*descsz=*/sizeof(uint32_t);
 }
 
-void PackageMetadataNote::writeTo(uint8_t *buf) {
+void PackageMetadataNote::writeTo(Ctx &ctx, uint8_t *buf) {
   write32(buf, 4);
   write32(buf + 4, ctx.arg.packageMetadata.size() + 1);
   write32(buf + 8, FDO_PACKAGING_METADATA);
@@ -4623,7 +4631,7 @@ bool MemtagGlobalDescriptors::updateAllocSize() {
   return oldSize != getSize();
 }
 
-void MemtagGlobalDescriptors::writeTo(uint8_t *buf) {
+void MemtagGlobalDescriptors::writeTo(Ctx &ctx, uint8_t *buf) {
   createMemtagGlobalDescriptors(symbols, buf);
 }
 

diff  --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 2fc78759b62ec0..12417da80b7b4d 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -51,7 +51,7 @@ struct CieRecord {
 class EhFrameSection final : public SyntheticSection {
 public:
   EhFrameSection();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   void finalizeContents(Ctx &) override;
   bool isNeeded() const override { return !sections.empty(); }
   size_t getSize() const override { return size; }
@@ -108,7 +108,7 @@ class GotSection final : public SyntheticSection {
   size_t getSize() const override { return size; }
   void finalizeContents(Ctx &) override;
   bool isNeeded() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
   void addConstant(const Relocation &r);
   void addEntry(const Symbol &sym);
@@ -138,14 +138,14 @@ class GnuStackSection : public SyntheticSection {
 public:
   GnuStackSection()
       : SyntheticSection(0, llvm::ELF::SHT_PROGBITS, 1, ".note.GNU-stack") {}
-  void writeTo(uint8_t *buf) override {}
+  void writeTo(Ctx &, uint8_t *buf) override {}
   size_t getSize() const override { return 0; }
 };
 
 class GnuPropertySection final : public SyntheticSection {
 public:
   GnuPropertySection();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
 };
 
@@ -157,7 +157,7 @@ class BuildIdSection : public SyntheticSection {
 public:
   const size_t hashSize;
   BuildIdSection();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override { return headerSize + hashSize; }
   void writeBuildId(llvm::ArrayRef<uint8_t> buf);
 
@@ -172,7 +172,7 @@ class BuildIdSection : public SyntheticSection {
 class BssSection final : public SyntheticSection {
 public:
   BssSection(StringRef name, uint64_t size, uint32_t addralign);
-  void writeTo(uint8_t *) override {}
+  void writeTo(Ctx &, uint8_t *) override {}
   bool isNeeded() const override { return size != 0; }
   size_t getSize() const override { return size; }
 
@@ -183,7 +183,7 @@ class BssSection final : public SyntheticSection {
 class MipsGotSection final : public SyntheticSection {
 public:
   MipsGotSection();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override { return size; }
   bool updateAllocSize() override;
   void finalizeContents(Ctx &) override;
@@ -362,7 +362,7 @@ class GotPltSection final : public SyntheticSection {
   GotPltSection();
   void addEntry(Symbol &sym);
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   bool isNeeded() const override;
 
   // Flag to force GotPlt to be in output if we have relocations
@@ -382,7 +382,7 @@ class IgotPltSection final : public SyntheticSection {
   IgotPltSection();
   void addEntry(Symbol &sym);
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   bool isNeeded() const override { return !entries.empty(); }
 
 private:
@@ -393,7 +393,7 @@ class StringTableSection final : public SyntheticSection {
 public:
   StringTableSection(StringRef name, bool dynamic);
   unsigned addString(StringRef s, bool hashIt = true);
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override { return size; }
   bool isDynamic() const { return dynamic; }
 
@@ -485,7 +485,7 @@ template <class ELFT> class DynamicSection final : public SyntheticSection {
 public:
   DynamicSection();
   void finalizeContents(Ctx &) override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override { return size; }
 
 private:
@@ -577,7 +577,7 @@ class RelocationSection final : public RelocationBaseSection {
 
 public:
   RelocationSection(StringRef name, bool combreloc, unsigned concurrency);
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 };
 
 template <class ELFT>
@@ -590,7 +590,7 @@ class AndroidPackedRelocationSection final : public RelocationBaseSection {
 
   bool updateAllocSize() override;
   size_t getSize() const override { return relocData.size(); }
-  void writeTo(uint8_t *buf) override {
+  void writeTo(Ctx &, uint8_t *buf) override {
     memcpy(buf, relocData.data(), relocData.size());
   }
 
@@ -631,7 +631,7 @@ template <class ELFT> class RelrSection final : public RelrBaseSection {
 
   bool updateAllocSize() override;
   size_t getSize() const override { return relrRelocs.size() * this->entsize; }
-  void writeTo(uint8_t *buf) override {
+  void writeTo(Ctx &, uint8_t *buf) override {
     memcpy(buf, relrRelocs.data(), getSize());
   }
 
@@ -673,14 +673,14 @@ class SymbolTableSection final : public SymbolTableBaseSection {
 
 public:
   SymbolTableSection(StringTableSection &strTabSec);
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 };
 
 class SymtabShndxSection final : public SyntheticSection {
 public:
   SymtabShndxSection();
 
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
   bool isNeeded() const override;
   void finalizeContents(Ctx &) override;
@@ -692,7 +692,7 @@ class GnuHashTableSection final : public SyntheticSection {
 public:
   GnuHashTableSection();
   void finalizeContents(Ctx &) override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override { return size; }
 
   // Adds symbols to the hash table.
@@ -720,7 +720,7 @@ class HashTableSection final : public SyntheticSection {
 public:
   HashTableSection();
   void finalizeContents(Ctx &) override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override { return size; }
 
 private:
@@ -741,7 +741,7 @@ class HashTableSection final : public SyntheticSection {
 class PltSection : public SyntheticSection {
 public:
   PltSection();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
   bool isNeeded() const override;
   void addSymbols();
@@ -762,7 +762,7 @@ class IpltSection final : public SyntheticSection {
 
 public:
   IpltSection();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
   bool isNeeded() const override { return !entries.empty(); }
   void addSymbols();
@@ -772,7 +772,7 @@ class IpltSection final : public SyntheticSection {
 class PPC32GlinkSection : public PltSection {
 public:
   PPC32GlinkSection();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
 
   SmallVector<const Symbol *, 0> canonical_plts;
@@ -783,7 +783,7 @@ class PPC32GlinkSection : public PltSection {
 class IBTPltSection : public SyntheticSection {
 public:
   IBTPltSection();
-  void writeTo(uint8_t *Buf) override;
+  void writeTo(Ctx &, uint8_t *Buf) override;
   bool isNeeded() const override;
   size_t getSize() const override;
 };
@@ -795,7 +795,7 @@ class RelroPaddingSection final : public SyntheticSection {
 public:
   RelroPaddingSection();
   size_t getSize() const override { return 0; }
-  void writeTo(uint8_t *buf) override {}
+  void writeTo(Ctx &, uint8_t *buf) override {}
 };
 
 // Used by the merged DWARF32 .debug_names (a per-module index). If we
@@ -914,7 +914,7 @@ class DebugNamesSection final : public DebugNamesBaseSection {
 public:
   DebugNamesSection();
   void finalizeContents(Ctx &) override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
   template <class RelTy>
   void getNameRelocs(const InputFile &file,
@@ -961,7 +961,7 @@ class GdbIndexSection final : public SyntheticSection {
 
   GdbIndexSection();
   template <typename ELFT> static std::unique_ptr<GdbIndexSection> create();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override { return size; }
   bool isNeeded() const override;
 
@@ -1000,7 +1000,7 @@ class EhFrameHeader final : public SyntheticSection {
 public:
   EhFrameHeader();
   void write();
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
   bool isNeeded() const override;
 };
@@ -1018,7 +1018,7 @@ class VersionDefinitionSection final : public SyntheticSection {
   VersionDefinitionSection();
   void finalizeContents(Ctx &) override;
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
 private:
   enum { EntrySize = 28 };
@@ -1040,7 +1040,7 @@ class VersionTableSection final : public SyntheticSection {
   VersionTableSection();
   void finalizeContents(Ctx &) override;
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   bool isNeeded() const override;
 };
 
@@ -1070,7 +1070,7 @@ class VersionNeedSection final : public SyntheticSection {
 public:
   VersionNeedSection();
   void finalizeContents(Ctx &) override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
   bool isNeeded() const override;
 };
@@ -1096,7 +1096,7 @@ class MergeTailSection final : public MergeSyntheticSection {
                    uint32_t addralign);
 
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   void finalizeContents(Ctx &) override;
 
 private:
@@ -1110,7 +1110,7 @@ class MergeNoTailSection final : public MergeSyntheticSection {
       : MergeSyntheticSection(name, type, flags, addralign) {}
 
   size_t getSize() const override { return size; }
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   void finalizeContents(Ctx &) override;
 
 private:
@@ -1143,7 +1143,7 @@ class MipsAbiFlagsSection final : public SyntheticSection {
 
   MipsAbiFlagsSection(Elf_Mips_ABIFlags flags);
   size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
 private:
   Elf_Mips_ABIFlags flags;
@@ -1158,7 +1158,7 @@ template <class ELFT> class MipsOptionsSection final : public SyntheticSection {
   static std::unique_ptr<MipsOptionsSection<ELFT>> create();
 
   MipsOptionsSection(Elf_Mips_RegInfo reginfo);
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
   size_t getSize() const override {
     return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
@@ -1177,7 +1177,7 @@ template <class ELFT> class MipsReginfoSection final : public SyntheticSection {
 
   MipsReginfoSection(Elf_Mips_RegInfo reginfo);
   size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 
 private:
   Elf_Mips_RegInfo reginfo;
@@ -1191,7 +1191,7 @@ class MipsRldMapSection final : public SyntheticSection {
 public:
   MipsRldMapSection();
   size_t getSize() const override { return ctx.arg.wordsize; }
-  void writeTo(uint8_t *buf) override {}
+  void writeTo(Ctx &, uint8_t *buf) override {}
 };
 
 // Representation of the combined .ARM.Exidx input sections. We process these
@@ -1237,7 +1237,7 @@ class ARMExidxSyntheticSection : public SyntheticSection {
   bool addSection(InputSection *isec);
 
   size_t getSize() const override { return size; }
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   bool isNeeded() const override;
   // Sort and remove duplicate entries.
   void finalizeContents(Ctx &) override;
@@ -1285,7 +1285,7 @@ class ThunkSection final : public SyntheticSection {
   // of a relocation
   void addThunk(Thunk *t);
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   InputSection *getTargetInputSection() const;
   bool assignOffsets();
 
@@ -1310,7 +1310,7 @@ class ArmCmseSGSection final : public SyntheticSection {
   ArmCmseSGSection();
   bool isNeeded() const override { return !entries.empty(); }
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   void addSGVeneer(Symbol *sym, Symbol *ext_sym);
   void addMappingSymbol();
   void finalizeContents(Ctx &) override;
@@ -1331,7 +1331,7 @@ class PPC32Got2Section final : public SyntheticSection {
   size_t getSize() const override { return 0; }
   bool isNeeded() const override;
   void finalizeContents(Ctx &) override;
-  void writeTo(uint8_t *buf) override {}
+  void writeTo(Ctx &, uint8_t *buf) override {}
 };
 
 // This section is used to store the addresses of functions that are called
@@ -1345,7 +1345,7 @@ class PPC64LongBranchTargetSection final : public SyntheticSection {
   uint64_t getEntryVA(const Symbol *sym, int64_t addend);
   std::optional<uint32_t> addEntry(const Symbol *sym, int64_t addend);
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   bool isNeeded() const override;
   void finalizeContents(Ctx &) override { finalized = true; }
 
@@ -1360,7 +1360,7 @@ class PartitionElfHeaderSection final : public SyntheticSection {
 public:
   PartitionElfHeaderSection();
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 };
 
 template <typename ELFT>
@@ -1368,7 +1368,7 @@ class PartitionProgramHeadersSection final : public SyntheticSection {
 public:
   PartitionProgramHeadersSection();
   size_t getSize() const override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 };
 
 class PartitionIndexSection final : public SyntheticSection {
@@ -1376,7 +1376,7 @@ class PartitionIndexSection final : public SyntheticSection {
   PartitionIndexSection();
   size_t getSize() const override;
   void finalizeContents(Ctx &) override;
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
 };
 
 // See the following link for the Android-specific loader code that operates on
@@ -1387,7 +1387,7 @@ class MemtagAndroidNote final : public SyntheticSection {
   MemtagAndroidNote()
       : SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE,
                          /*alignment=*/4, ".note.android.memtag") {}
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
 };
 
@@ -1396,7 +1396,7 @@ class PackageMetadataNote final : public SyntheticSection {
   PackageMetadataNote()
       : SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE,
                          /*alignment=*/4, ".note.package") {}
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   size_t getSize() const override;
 };
 
@@ -1406,7 +1406,7 @@ class MemtagGlobalDescriptors final : public SyntheticSection {
       : SyntheticSection(llvm::ELF::SHF_ALLOC,
                          llvm::ELF::SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC,
                          /*alignment=*/4, ".memtag.globals.dynamic") {}
-  void writeTo(uint8_t *buf) override;
+  void writeTo(Ctx &, uint8_t *buf) override;
   // The size of the section is non-computable until all addresses are
   // synthetized, because the section's contents contain a sorted
   // varint-compressed list of pointers to global variables. We only know the

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a1ce347a92009d..f909e026a91ffc 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2806,7 +2806,7 @@ template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
   parallel::TaskGroup tg;
   for (OutputSection *sec : ctx.outputSections)
     if (sec->flags & SHF_ALLOC)
-      sec->writeTo<ELFT>(ctx.bufferStart + sec->offset, tg);
+      sec->writeTo<ELFT>(ctx, ctx.bufferStart + sec->offset, tg);
 }
 
 static void fillTrap(std::array<uint8_t, 4> trapInstr, uint8_t *i,
@@ -2857,13 +2857,13 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
     parallel::TaskGroup tg;
     for (OutputSection *sec : ctx.outputSections)
       if (isStaticRelSecType(sec->type))
-        sec->writeTo<ELFT>(ctx.bufferStart + sec->offset, tg);
+        sec->writeTo<ELFT>(ctx, ctx.bufferStart + sec->offset, tg);
   }
   {
     parallel::TaskGroup tg;
     for (OutputSection *sec : ctx.outputSections)
       if (!isStaticRelSecType(sec->type))
-        sec->writeTo<ELFT>(ctx.bufferStart + sec->offset, tg);
+        sec->writeTo<ELFT>(ctx, ctx.bufferStart + sec->offset, tg);
   }
 
   // Finally, check that all dynamic relocation addends were written correctly.


        


More information about the llvm-commits mailing list