[lld] c331332 - [ELF] Pass Ctx & to InputSection

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 11 20:39:59 PDT 2024


Author: Fangrui Song
Date: 2024-10-11T20:39:53-07:00
New Revision: c33133279bc25ec6e25ddd5fd13ca173bf716f3e

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

LOG: [ELF] Pass Ctx & to InputSection

Added: 
    

Modified: 
    lld/ELF/InputSection.cpp
    lld/ELF/InputSection.h
    lld/ELF/OutputSections.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index fe4a6e2e5366a8..bca395eb5ea950 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -400,18 +400,20 @@ InputSectionBase *InputSection::getRelocatedSection() const {
 }
 
 template <class ELFT, class RelTy>
-void InputSection::copyRelocations(uint8_t *buf) {
+void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf) {
   if (ctx.arg.relax && !ctx.arg.relocatable &&
       (ctx.arg.emachine == EM_RISCV || ctx.arg.emachine == EM_LOONGARCH)) {
     // On LoongArch and RISC-V, relaxation might change relocations: copy
     // from internal ones that are updated by relaxation.
     InputSectionBase *sec = getRelocatedSection();
-    copyRelocations<ELFT, RelTy>(buf, llvm::make_range(sec->relocations.begin(),
-                                                       sec->relocations.end()));
+    copyRelocations<ELFT, RelTy>(
+        ctx, buf,
+        llvm::make_range(sec->relocations.begin(), sec->relocations.end()));
   } else {
     // Convert the raw relocations in the input section into Relocation objects
     // suitable to be used by copyRelocations below.
     struct MapRel {
+      Ctx &ctx;
       const ObjFile<ELFT> &file;
       Relocation operator()(const RelTy &rel) const {
         // RelExpr is not used so set to a dummy value.
@@ -423,11 +425,11 @@ void InputSection::copyRelocations(uint8_t *buf) {
     using RawRels = ArrayRef<RelTy>;
     using MapRelIter =
         llvm::mapped_iterator<typename RawRels::iterator, MapRel>;
-    auto mapRel = MapRel{*getFile<ELFT>()};
+    auto mapRel = MapRel{ctx, *getFile<ELFT>()};
     RawRels rawRels = getDataAs<RelTy>();
     auto rels = llvm::make_range(MapRelIter(rawRels.begin(), mapRel),
                                  MapRelIter(rawRels.end(), mapRel));
-    copyRelocations<ELFT, RelTy>(buf, rels);
+    copyRelocations<ELFT, RelTy>(ctx, buf, rels);
   }
 }
 
@@ -435,9 +437,8 @@ void InputSection::copyRelocations(uint8_t *buf) {
 // relocations because we need to update symbol table offset and section index
 // for each relocation. So we copy relocations one by one.
 template <class ELFT, class RelTy, class RelIt>
-void InputSection::copyRelocations(uint8_t *buf,
+void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf,
                                    llvm::iterator_range<RelIt> rels) {
-  Ctx &ctx = getCtx();
   const TargetInfo &target = *ctx.target;
   InputSectionBase *sec = getRelocatedSection();
   (void)sec->contentMaybeDecompress(); // uncompress if needed
@@ -973,9 +974,10 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
 // So, we handle relocations for non-alloc sections directly in this
 // function as a performance optimization.
 template <class ELFT, class RelTy>
-void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
+void InputSection::relocateNonAlloc(Ctx &ctx, uint8_t *buf,
+                                    Relocs<RelTy> rels) {
   const unsigned bits = sizeof(typename ELFT::uint) * 8;
-  const TargetInfo &target = *elf::ctx.target;
+  const TargetInfo &target = *ctx.target;
   const auto emachine = ctx.arg.emachine;
   const bool isDebug = isDebugSection(*this);
   const bool isDebugLine = isDebug && name == ".debug_line";
@@ -1123,9 +1125,9 @@ void InputSection::relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels) {
 }
 
 template <class ELFT>
-void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
+void InputSectionBase::relocate(Ctx &ctx, uint8_t *buf, uint8_t *bufEnd) {
   if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
-    adjustSplitStackFunctionPrologues<ELFT>(buf, bufEnd);
+    adjustSplitStackFunctionPrologues<ELFT>(ctx, buf, bufEnd);
 
   if (flags & SHF_ALLOC) {
     ctx.target->relocateAlloc(*this, buf);
@@ -1135,13 +1137,13 @@ void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
   auto *sec = cast<InputSection>(this);
   // For a relocatable link, also call relocateNonAlloc() to rewrite applicable
   // locations with tombstone values.
-  invokeOnRelocs(*sec, sec->relocateNonAlloc<ELFT>, buf);
+  invokeOnRelocs(*sec, sec->relocateNonAlloc<ELFT>, ctx, buf);
 }
 
 // For each function-defining prologue, find any calls to __morestack,
 // and replace them with calls to __morestack_non_split.
 static void switchMorestackCallsToMorestackNonSplit(
-    DenseSet<Defined *> &prologues,
+    Ctx &ctx, DenseSet<Defined *> &prologues,
     SmallVector<Relocation *, 0> &morestackCalls) {
 
   // If the target adjusted a function's prologue, all calls to
@@ -1189,7 +1191,7 @@ static bool enclosingPrologueAttempted(uint64_t offset,
 // adjusted to ensure that the called function will have enough stack
 // available. Find those functions, and adjust their prologues.
 template <class ELFT>
-void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
+void InputSectionBase::adjustSplitStackFunctionPrologues(Ctx &ctx, uint8_t *buf,
                                                          uint8_t *end) {
   DenseSet<Defined *> prologues;
   SmallVector<Relocation *, 0> morestackCalls;
@@ -1234,20 +1236,20 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
   }
 
   if (ctx.target->needsMoreStackNonSplit)
-    switchMorestackCallsToMorestackNonSplit(prologues, morestackCalls);
+    switchMorestackCallsToMorestackNonSplit(ctx, prologues, morestackCalls);
 }
 
-template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
+template <class ELFT> void InputSection::writeTo(Ctx &ctx, uint8_t *buf) {
   if (LLVM_UNLIKELY(type == SHT_NOBITS))
     return;
   // If -r or --emit-relocs is given, then an InputSection
   // may be a relocation section.
   if (LLVM_UNLIKELY(type == SHT_RELA)) {
-    copyRelocations<ELFT, typename ELFT::Rela>(buf);
+    copyRelocations<ELFT, typename ELFT::Rela>(ctx, buf);
     return;
   }
   if (LLVM_UNLIKELY(type == SHT_REL)) {
-    copyRelocations<ELFT, typename ELFT::Rel>(buf);
+    copyRelocations<ELFT, typename ELFT::Rel>(ctx, buf);
     return;
   }
 
@@ -1270,14 +1272,14 @@ template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
       fatal(toString(this) +
             ": decompress failed: " + llvm::toString(std::move(e)));
     uint8_t *bufEnd = buf + size;
-    relocate<ELFT>(buf, bufEnd);
+    relocate<ELFT>(ctx, buf, bufEnd);
     return;
   }
 
   // Copy section contents from source object file to output file
   // and then apply relocations.
   memcpy(buf, content().data(), content().size());
-  relocate<ELFT>(buf, buf + content().size());
+  relocate<ELFT>(ctx, buf, buf + content().size());
 }
 
 void InputSection::replace(InputSection *other) {
@@ -1415,7 +1417,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> data,
                                         size_t entSize) {
   size_t size = data.size();
   assert((size % entSize) == 0);
-  const bool live = !(flags & SHF_ALLOC) || !ctx.arg.gcSections;
+  const bool live = !(flags & SHF_ALLOC) || !getCtx().arg.gcSections;
 
   pieces.resize_for_overwrite(size / entSize);
   for (size_t i = 0, j = 0; i != size; i += entSize, j++)
@@ -1471,10 +1473,10 @@ template InputSection::InputSection(ObjFile<ELF64LE> &, const ELF64LE::Shdr &,
 template InputSection::InputSection(ObjFile<ELF64BE> &, const ELF64BE::Shdr &,
                                     StringRef);
 
-template void InputSection::writeTo<ELF32LE>(uint8_t *);
-template void InputSection::writeTo<ELF32BE>(uint8_t *);
-template void InputSection::writeTo<ELF64LE>(uint8_t *);
-template void InputSection::writeTo<ELF64BE>(uint8_t *);
+template void InputSection::writeTo<ELF32LE>(Ctx &, uint8_t *);
+template void InputSection::writeTo<ELF32BE>(Ctx &, uint8_t *);
+template void InputSection::writeTo<ELF64LE>(Ctx &, uint8_t *);
+template void InputSection::writeTo<ELF64BE>(Ctx &, uint8_t *);
 
 template RelsOrRelas<ELF32LE>
 InputSectionBase::relsOrRelas<ELF32LE>(bool) const;

diff  --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 2b34047bc0682a..c25ff143fd3434 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -245,7 +245,7 @@ class InputSectionBase : public SectionBase {
   // Each section knows how to relocate itself. These functions apply
   // relocations, assuming that Buf points to this section's copy in
   // the mmap'ed output buffer.
-  template <class ELFT> void relocate(uint8_t *buf, uint8_t *bufEnd);
+  template <class ELFT> void relocate(Ctx &, uint8_t *buf, uint8_t *bufEnd);
   uint64_t getRelocTargetVA(Ctx &, const Relocation &r, uint64_t p) const;
 
   // The native ELF reloc data type is not very convenient to handle.
@@ -278,8 +278,7 @@ class InputSectionBase : public SectionBase {
   // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
   // information.
   template <typename ELFT>
-  void adjustSplitStackFunctionPrologues(uint8_t *buf, uint8_t *end);
-
+  void adjustSplitStackFunctionPrologues(Ctx &, uint8_t *buf, uint8_t *end);
 
   template <typename T> llvm::ArrayRef<T> getDataAs() const {
     size_t s = content().size();
@@ -410,7 +409,7 @@ class InputSection : public InputSectionBase {
 
   // Write this section to a mmap'ed file, assuming Buf is pointing to
   // beginning of the output section.
-  template <class ELFT> void writeTo(uint8_t *buf);
+  template <class ELFT> void writeTo(Ctx &, uint8_t *buf);
 
   OutputSection *getParent() const {
     return reinterpret_cast<OutputSection *>(parent);
@@ -425,7 +424,7 @@ class InputSection : public InputSectionBase {
   InputSectionBase *getRelocatedSection() const;
 
   template <class ELFT, class RelTy>
-  void relocateNonAlloc(uint8_t *buf, Relocs<RelTy> rels);
+  void relocateNonAlloc(Ctx &, uint8_t *buf, Relocs<RelTy> rels);
 
   // Points to the canonical section. If ICF folds two sections, repl pointer of
   // one section points to the other.
@@ -440,10 +439,10 @@ class InputSection : public InputSectionBase {
   static InputSection discarded;
 
 private:
-  template <class ELFT, class RelTy> void copyRelocations(uint8_t *buf);
+  template <class ELFT, class RelTy> void copyRelocations(Ctx &, uint8_t *buf);
 
   template <class ELFT, class RelTy, class RelIt>
-  void copyRelocations(uint8_t *buf, llvm::iterator_range<RelIt> rels);
+  void copyRelocations(Ctx &, uint8_t *buf, llvm::iterator_range<RelIt> rels);
 
   template <class ELFT> void copyShtGroup(uint8_t *buf);
 };

diff  --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index ca0a7718fa0cc4..d6abb6184f3619 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -529,7 +529,7 @@ void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
       if (auto *s = dyn_cast<SyntheticSection>(isec))
         s->writeTo(buf + isec->outSecOff);
       else
-        isec->writeTo<ELFT>(buf + isec->outSecOff);
+        isec->writeTo<ELFT>(ctx, buf + isec->outSecOff);
 
       // When in Arm BE8 mode, the linker has to convert the big-endian
       // instructions to little-endian, leaving the data big-endian.


        


More information about the llvm-commits mailing list