[lld] 0dbc85a - [ELF] Pass Ctx & to Arch-specific code

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 13 11:08:12 PDT 2024


Author: Fangrui Song
Date: 2024-10-13T11:08:06-07:00
New Revision: 0dbc85a59f556736133019f655e7110fc7ae8847

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

LOG: [ELF] Pass Ctx & to Arch-specific code

Added: 
    

Modified: 
    lld/ELF/Arch/ARM.cpp
    lld/ELF/Arch/LoongArch.cpp
    lld/ELF/Arch/Mips.cpp
    lld/ELF/Arch/PPC64.cpp
    lld/ELF/OutputSections.cpp
    lld/ELF/SyntheticSections.cpp
    lld/ELF/Thunks.cpp
    lld/ELF/Thunks.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 0b09a083ce2b0d..b1685fe0723833 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -310,7 +310,7 @@ void ARM::addPltHeaderSymbols(InputSection &isec) const {
 
 // Long form PLT entries that do not have any restrictions on the displacement
 // of the .plt from the .got.plt.
-static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr,
+static void writePltLong(Ctx &ctx, uint8_t *buf, uint64_t gotPltEntryAddr,
                          uint64_t pltEntryAddr) {
   write32(ctx, buf + 0, 0xe59fc004);  //     ldr ip, L2
   write32(ctx, buf + 4, 0xe08cc00f);  // L1: add ip, ip, pc
@@ -339,7 +339,7 @@ void ARM::writePlt(uint8_t *buf, const Symbol &sym,
     };
     if (!llvm::isUInt<27>(offset)) {
       // We cannot encode the Offset, use the long form.
-      writePltLong(buf, sym.getGotPltVA(ctx), pltEntryAddr);
+      writePltLong(ctx, buf, sym.getGotPltVA(ctx), pltEntryAddr);
       return;
     }
     write32(ctx, buf + 0, pltData[0] | ((offset >> 20) & 0xff));
@@ -562,8 +562,8 @@ void ARM::encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
           (read32(ctx, loc) & 0xff3ff000) | opcode | rot | (imm & 0xff));
 }
 
-static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
-                           int group) {
+static void encodeLdrGroup(Ctx &ctx, uint8_t *loc, const Relocation &rel,
+                           uint64_t val, int group) {
   // R_ARM_LDR_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a
   // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
   // bottom bit to recover S + A - P.
@@ -580,8 +580,8 @@ static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
   write32(ctx, loc, (read32(ctx, loc) & 0xff7ff000) | opcode | imm);
 }
 
-static void encodeLdrsGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
-                            int group) {
+static void encodeLdrsGroup(Ctx &ctx, uint8_t *loc, const Relocation &rel,
+                            uint64_t val, int group) {
   // R_ARM_LDRS_PC_Gn is S + A - P, we have ((S + A) | T) - P, if S is a
   // function then addr is 0 (modulo 2) and Pa is 0 (modulo 4) so we can clear
   // bottom bit to recover S + A - P.
@@ -804,22 +804,22 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     encodeAluGroup(loc, rel, val, 2, true);
     break;
   case R_ARM_LDR_PC_G0:
-    encodeLdrGroup(loc, rel, val, 0);
+    encodeLdrGroup(ctx, loc, rel, val, 0);
     break;
   case R_ARM_LDR_PC_G1:
-    encodeLdrGroup(loc, rel, val, 1);
+    encodeLdrGroup(ctx, loc, rel, val, 1);
     break;
   case R_ARM_LDR_PC_G2:
-    encodeLdrGroup(loc, rel, val, 2);
+    encodeLdrGroup(ctx, loc, rel, val, 2);
     break;
   case R_ARM_LDRS_PC_G0:
-    encodeLdrsGroup(loc, rel, val, 0);
+    encodeLdrsGroup(ctx, loc, rel, val, 0);
     break;
   case R_ARM_LDRS_PC_G1:
-    encodeLdrsGroup(loc, rel, val, 1);
+    encodeLdrsGroup(ctx, loc, rel, val, 1);
     break;
   case R_ARM_LDRS_PC_G2:
-    encodeLdrsGroup(loc, rel, val, 2);
+    encodeLdrsGroup(ctx, loc, rel, val, 2);
     break;
   case R_ARM_THM_ALU_PREL_11_0: {
     // ADR encoding T2 (sub), T3 (add) i:imm3:imm8
@@ -1096,11 +1096,11 @@ static void toLittleEndianInstructions(uint8_t *buf, uint64_t start,
   CodeState curState = static_cast<CodeState>(width);
   if (curState == CodeState::Arm)
     for (uint64_t i = start; i < end; i += width)
-      write32le(buf + i, read32(ctx, buf + i));
+      write32le(buf + i, read32be(buf + i));
 
   if (curState == CodeState::Thumb)
     for (uint64_t i = start; i < end; i += width)
-      write16le(buf + i, read16(ctx, buf + i));
+      write16le(buf + i, read16be(buf + i));
 }
 
 // Arm BE8 big endian format requires instructions to be little endian, with

diff  --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index f16f8f0c8d5ce4..638e0cfd02414f 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -744,7 +744,7 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
   }
 }
 
-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;
@@ -833,7 +833,7 @@ bool LoongArch::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;
 }

diff  --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index 9e1241924b444d..3fb18a892d2d7b 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -248,8 +248,8 @@ static void writeShuffle(Ctx &ctx, uint8_t *loc, uint64_t v, uint8_t bitsSize,
 }
 
 template <endianness E>
-static void writeMicroRelocation16(uint8_t *loc, uint64_t v, uint8_t bitsSize,
-                                   uint8_t shift) {
+static void writeMicroRelocation16(Ctx &ctx, uint8_t *loc, uint64_t v,
+                                   uint8_t bitsSize, uint8_t shift) {
   uint16_t instr = read16(ctx, loc);
   uint16_t mask = 0xffff >> (16 - bitsSize);
   uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
@@ -519,7 +519,8 @@ static bool isMicroBranchReloc(RelType type) {
 }
 
 template <class ELFT>
-static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
+static uint64_t fixupCrossModeJump(Ctx &ctx, uint8_t *loc, RelType type,
+                                   uint64_t val) {
   // Here we need to detect jump/branch from regular MIPS code
   // to a microMIPS target and vice versa. In that cases jump
   // instructions need to be replaced by their "cross-mode"
@@ -577,7 +578,7 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
     std::tie(type, val) = calculateMipsRelChain(ctx, loc, type, val);
 
   // Detect cross-mode jump/branch and fix instruction.
-  val = fixupCrossModeJump<ELFT>(loc, type, val);
+  val = fixupCrossModeJump<ELFT>(ctx, loc, type, val);
 
   // Thread pointer and DRP offsets from the start of TLS data area.
   // https://www.linux-mips.org/wiki/NPTL
@@ -727,11 +728,11 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
     break;
   case R_MICROMIPS_PC7_S1:
     checkInt(loc, val, 8, rel);
-    writeMicroRelocation16<e>(loc, val, 7, 1);
+    writeMicroRelocation16<e>(ctx, loc, val, 7, 1);
     break;
   case R_MICROMIPS_PC10_S1:
     checkInt(loc, val, 11, rel);
-    writeMicroRelocation16<e>(loc, val, 10, 1);
+    writeMicroRelocation16<e>(ctx, loc, val, 10, 1);
     break;
   case R_MICROMIPS_PC16_S1:
     checkInt(loc, val, 17, rel);

diff  --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index f25ff53fccd8eb..1c4f1c64390e33 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -1169,7 +1169,8 @@ 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(ctx) - getPPC64TocBase(ctx));
+  writePPC64LoadAndBranch(ctx, buf,
+                          sym.getGotPltVA(ctx) - getPPC64TocBase(ctx));
 }
 
 static std::pair<RelType, uint64_t> toAddr16Rel(RelType type, uint64_t val) {

diff  --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 372f7a3b9d7b02..309039fe7e204a 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -458,7 +458,7 @@ template <class ELFT> void OutputSection::maybeCompress(Ctx &ctx) {
   flags |= SHF_COMPRESSED;
 }
 
-static void writeInt(uint8_t *buf, uint64_t data, uint64_t size) {
+static void writeInt(Ctx &ctx, uint8_t *buf, uint64_t data, uint64_t size) {
   if (size == 1)
     *buf = data;
   else if (size == 2)
@@ -563,7 +563,8 @@ void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
     if (auto *data = dyn_cast<ByteCommand>(cmd)) {
       if (!std::exchange(written, true))
         fn(0, numSections);
-      writeInt(buf + data->offset, data->expression().getValue(), data->size);
+      writeInt(ctx, buf + data->offset, data->expression().getValue(),
+               data->size);
     }
   if (written || !numSections)
     return;

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 1288126328b4d2..d99aeac50ca5ce 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -506,7 +506,7 @@ void EhFrameSection::iterateFDEWithLSDA(
   }
 }
 
-static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) {
+static void writeCieFde(Ctx &ctx, uint8_t *buf, ArrayRef<uint8_t> d) {
   memcpy(buf, d.data(), d.size());
   // Fix the size field. -4 since size does not include the size field itself.
   write32(ctx, buf, d.size() - 4);
@@ -632,11 +632,11 @@ void EhFrameSection::writeTo(uint8_t *buf) {
   // Write CIE and FDE records.
   for (CieRecord *rec : cieRecords) {
     size_t cieOffset = rec->cie->outputOff;
-    writeCieFde(buf + cieOffset, rec->cie->data());
+    writeCieFde(ctx, buf + cieOffset, rec->cie->data());
 
     for (EhSectionPiece *fde : rec->fdes) {
       size_t off = fde->outputOff;
-      writeCieFde(buf + off, fde->data());
+      writeCieFde(ctx, buf + off, fde->data());
 
       // FDE's second word should have the offset to an associated CIE.
       // Write it.
@@ -4077,7 +4077,8 @@ static bool isExtabRef(uint32_t unwind) {
 // unwinding instructions in Cur are identical to Prev. Linker generated
 // EXIDX_CANTUNWIND entries are represented by nullptr as they do not have an
 // InputSection.
-static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
+static bool isDuplicateArmExidxSec(Ctx &ctx, InputSection *prev,
+                                   InputSection *cur) {
   // Get the last table Entry from the previous .ARM.exidx section. If Prev is
   // nullptr then it will be a synthesized EXIDX_CANTUNWIND entry.
   uint32_t prevUnwind = 1;
@@ -4166,7 +4167,7 @@ void ARMExidxSyntheticSection::finalizeContents() {
     for (size_t i = 1; i < executableSections.size(); ++i) {
       InputSection *ex1 = findExidxSection(executableSections[prev]);
       InputSection *ex2 = findExidxSection(executableSections[i]);
-      if (!isDuplicateArmExidxSec(ex1, ex2)) {
+      if (!isDuplicateArmExidxSec(ctx, ex1, ex2)) {
         selectedSections.push_back(executableSections[i]);
         prev = i;
       }

diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 611b632f826979..971b2724b3e26f 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -1232,7 +1232,7 @@ void PPC32LongThunk::writeTo(uint8_t *buf) {
   write32(ctx, buf + 4, 0x4e800420); // bctr
 }
 
-void elf::writePPC64LoadAndBranch(uint8_t *buf, int64_t offset) {
+void elf::writePPC64LoadAndBranch(Ctx &ctx, uint8_t *buf, int64_t offset) {
   uint16_t offHa = (offset + 0x8000) >> 16;
   uint16_t offLo = offset & 0xffff;
 
@@ -1246,7 +1246,7 @@ void PPC64PltCallStub::writeTo(uint8_t *buf) {
   int64_t offset = destination.getGotPltVA(ctx) - getPPC64TocBase(ctx);
   // Save the TOC pointer to the save-slot reserved in the call frame.
   write32(ctx, buf + 0, 0xf8410018); // std     r2,24(r1)
-  writePPC64LoadAndBranch(buf + 4, offset);
+  writePPC64LoadAndBranch(ctx, buf + 4, offset);
 }
 
 void PPC64PltCallStub::addSymbols(ThunkSection &isec) {
@@ -1289,7 +1289,7 @@ void PPC64R2SaveStub::writeTo(uint8_t *buf) {
     const int64_t offsetFromTOC =
         ctx.in.ppc64LongBranchTarget->getEntryVA(&destination, addend) -
         getPPC64TocBase(ctx);
-    writePPC64LoadAndBranch(buf + 4, offsetFromTOC);
+    writePPC64LoadAndBranch(ctx, buf + 4, offsetFromTOC);
   }
 }
 
@@ -1352,7 +1352,7 @@ void PPC64LongBranchThunk::writeTo(uint8_t *buf) {
   int64_t offset =
       ctx.in.ppc64LongBranchTarget->getEntryVA(&destination, addend) -
       getPPC64TocBase(ctx);
-  writePPC64LoadAndBranch(buf, offset);
+  writePPC64LoadAndBranch(ctx, buf, offset);
 }
 
 void PPC64LongBranchThunk::addSymbols(ThunkSection &isec) {

diff  --git a/lld/ELF/Thunks.h b/lld/ELF/Thunks.h
index 3929aa0aee8114..247b500580325e 100644
--- a/lld/ELF/Thunks.h
+++ b/lld/ELF/Thunks.h
@@ -84,7 +84,7 @@ Thunk *addLandingPadThunk(Ctx &, Symbol &s, int64_t a);
 
 void writePPC32PltCallStub(Ctx &, uint8_t *buf, uint64_t gotPltVA,
                            const InputFile *file, int64_t addend);
-void writePPC64LoadAndBranch(uint8_t *buf, int64_t offset);
+void writePPC64LoadAndBranch(Ctx &, uint8_t *buf, int64_t offset);
 
 } // namespace lld::elf
 


        


More information about the llvm-commits mailing list