[lld] 002ca63 - [ELF] Pass Ctx & to (read|write)(16|64)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 13 10:47:33 PDT 2024


Author: Fangrui Song
Date: 2024-10-13T10:47:18-07:00
New Revision: 002ca63b3f1cb660b831a78d29abdfe33eaffbb4

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

LOG: [ELF] Pass Ctx & to (read|write)(16|64)

Added: 
    

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/ELF/Arch/AMDGPU.cpp
    lld/ELF/Arch/ARM.cpp
    lld/ELF/Arch/Mips.cpp
    lld/ELF/Arch/PPC.cpp
    lld/ELF/Arch/PPC64.cpp
    lld/ELF/OutputSections.cpp
    lld/ELF/SyntheticSections.cpp
    lld/ELF/Target.h
    lld/ELF/Thunks.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index e1b06240493635..ae03fde21c7993 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -255,14 +255,14 @@ RelType AArch64::getDynRel(RelType type) const {
 int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
   switch (type) {
   case R_AARCH64_TLSDESC:
-    return read64(buf + 8);
+    return read64(ctx, buf + 8);
   case R_AARCH64_NONE:
   case R_AARCH64_GLOB_DAT:
   case R_AARCH64_JUMP_SLOT:
     return 0;
   case R_AARCH64_ABS16:
   case R_AARCH64_PREL16:
-    return SignExtend64<16>(read16(buf));
+    return SignExtend64<16>(read16(ctx, buf));
   case R_AARCH64_ABS32:
   case R_AARCH64_PREL32:
     return SignExtend64<32>(read32(ctx, buf));
@@ -271,7 +271,7 @@ int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_AARCH64_RELATIVE:
   case R_AARCH64_IRELATIVE:
   case R_AARCH64_TLS_TPREL64:
-    return read64(buf);
+    return read64(ctx, buf);
 
     // The following relocation types all point at instructions, and
     // relocate an immediate field in the instruction.
@@ -355,12 +355,12 @@ int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
 }
 
 void AArch64::writeGotPlt(uint8_t *buf, const Symbol &) const {
-  write64(buf, ctx.in.plt->getVA());
+  write64(ctx, buf, ctx.in.plt->getVA());
 }
 
 void AArch64::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
   if (ctx.arg.writeAddends)
-    write64(buf, s.getVA());
+    write64(ctx, buf, s.getVA());
 }
 
 void AArch64::writePltHeader(uint8_t *buf) const {
@@ -485,7 +485,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
   case R_AARCH64_ABS16:
   case R_AARCH64_PREL16:
     checkIntUInt(loc, val, 16, rel);
-    write16(loc, val);
+    write16(ctx, loc, val);
     break;
   case R_AARCH64_ABS32:
   case R_AARCH64_PREL32:
@@ -508,12 +508,12 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     if (rel.sym && rel.sym->isTagged() &&
         (rel.addend < 0 ||
          rel.addend >= static_cast<int64_t>(rel.sym->getSize())))
-      write64(loc, -rel.addend);
+      write64(ctx, loc, -rel.addend);
     else
-      write64(loc, val);
+      write64(ctx, loc, val);
     break;
   case R_AARCH64_PREL64:
-    write64(loc, val);
+    write64(ctx, loc, val);
     break;
   case R_AARCH64_AUTH_ABS64:
     // If val is wider than 32 bits, the relocation must have been moved from
@@ -662,7 +662,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     break;
   case R_AARCH64_TLSDESC:
     // For R_AARCH64_TLSDESC the addend is stored in the second 64-bit word.
-    write64(loc + 8, val);
+    write64(ctx, loc + 8, val);
     break;
   default:
     llvm_unreachable("unknown relocation");

diff  --git a/lld/ELF/Arch/AMDGPU.cpp b/lld/ELF/Arch/AMDGPU.cpp
index 130da19d0e210d..ce37d0adc5fbb8 100644
--- a/lld/ELF/Arch/AMDGPU.cpp
+++ b/lld/ELF/Arch/AMDGPU.cpp
@@ -211,7 +211,7 @@ int64_t AMDGPU::getImplicitAddend(const uint8_t *buf, RelType type) const {
     return 0;
   case R_AMDGPU_ABS64:
   case R_AMDGPU_RELATIVE64:
-    return read64(buf);
+    return read64(ctx, buf);
   default:
     internalLinkerError(getErrorLoc(ctx, buf),
                         "cannot read addend for relocation " + toString(type));

diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index d6fbea13e8d725..0b09a083ce2b0d 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -255,14 +255,14 @@ void ARM::writePltHeader(uint8_t *buf) const {
     //
     uint64_t offset = ctx.in.gotPlt->getVA() - ctx.in.plt->getVA() - 16;
     assert(llvm::isUInt<32>(offset) && "This should always fit into a 32-bit offset");
-    write16(buf + 0, 0xb500);
+    write16(ctx, buf + 0, 0xb500);
     // Split into two halves to support endianness correctly.
-    write16(buf + 2, 0xf8df);
-    write16(buf + 4, 0xe008);
-    write16(buf + 6, 0x44fe);
+    write16(ctx, buf + 2, 0xf8df);
+    write16(ctx, buf + 4, 0xe008);
+    write16(ctx, buf + 6, 0x44fe);
     // Split into two halves to support endianness correctly.
-    write16(buf + 8, 0xf85e);
-    write16(buf + 10, 0xff08);
+    write16(ctx, buf + 8, 0xf85e);
+    write16(ctx, buf + 10, 0xff08);
     write32(ctx, buf + 12, offset);
 
     memcpy(buf + 16, trapInstr.data(), 4);  // Pad to 32-byte boundary
@@ -361,17 +361,17 @@ void ARM::writePlt(uint8_t *buf, const Symbol &sym,
     // where ip = r12 = 0xc
 
     // movw ip, #<lower 16 bits>
-    write16(buf + 2, 0x0c00); // use `ip`
+    write16(ctx, buf + 2, 0x0c00); // use `ip`
     relocateNoSym(buf, R_ARM_THM_MOVW_ABS_NC, offset);
 
     // movt ip, #<upper 16 bits>
-    write16(buf + 6, 0x0c00); // use `ip`
+    write16(ctx, buf + 6, 0x0c00); // use `ip`
     relocateNoSym(buf + 4, R_ARM_THM_MOVT_ABS, offset);
 
-    write16(buf + 8, 0x44fc);       // add ip, pc
-    write16(buf + 10, 0xf8dc);      // ldr.w   pc, [ip] (bottom half)
-    write16(buf + 12, 0xf000);      // ldr.w   pc, [ip] (upper half)
-    write16(buf + 14, 0xe7fc);      // Branch to previous instruction
+    write16(ctx, buf + 8, 0x44fc);  // add ip, pc
+    write16(ctx, buf + 10, 0xf8dc); // ldr.w   pc, [ip] (bottom half)
+    write16(ctx, buf + 12, 0xf000); // ldr.w   pc, [ip] (upper half)
+    write16(ctx, buf + 14, 0xe7fc); // Branch to previous instruction
   }
 }
 
@@ -662,25 +662,25 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_ARM_THM_JUMP8:
     // We do a 9 bit check because val is right-shifted by 1 bit.
     checkInt(loc, val, 9, rel);
-    write16(loc, (read32(ctx, loc) & 0xff00) | ((val >> 1) & 0x00ff));
+    write16(ctx, loc, (read32(ctx, loc) & 0xff00) | ((val >> 1) & 0x00ff));
     break;
   case R_ARM_THM_JUMP11:
     // We do a 12 bit check because val is right-shifted by 1 bit.
     checkInt(loc, val, 12, rel);
-    write16(loc, (read32(ctx, loc) & 0xf800) | ((val >> 1) & 0x07ff));
+    write16(ctx, loc, (read32(ctx, loc) & 0xf800) | ((val >> 1) & 0x07ff));
     break;
   case R_ARM_THM_JUMP19:
     // Encoding T3: Val = S:J2:J1:imm6:imm11:0
     checkInt(loc, val, 21, rel);
-    write16(loc,
-              (read16(loc) & 0xfbc0) |   // opcode cond
-                  ((val >> 10) & 0x0400) | // S
-                  ((val >> 12) & 0x003f)); // imm6
-    write16(loc + 2,
-              0x8000 |                    // opcode
-                  ((val >> 8) & 0x0800) | // J2
-                  ((val >> 5) & 0x2000) | // J1
-                  ((val >> 1) & 0x07ff)); // imm11
+    write16(ctx, loc,
+            (read16(ctx, loc) & 0xfbc0) | // opcode cond
+                ((val >> 10) & 0x0400) |  // S
+                ((val >> 12) & 0x003f));  // imm6
+    write16(ctx, loc + 2,
+            0x8000 |                    // opcode
+                ((val >> 8) & 0x0800) | // J2
+                ((val >> 5) & 0x2000) | // J1
+                ((val >> 1) & 0x07ff)); // imm11
     break;
   case R_ARM_THM_CALL: {
     // R_ARM_THM_CALL is used for BL and BLX instructions, for symbols of type
@@ -691,7 +691,7 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     assert(rel.sym); // R_ARM_THM_CALL is always reached via relocate().
     bool bit0Thumb = val & 1;
     bool useThumb = bit0Thumb || useThumbPLTs(ctx);
-    bool isBlx = (read16(loc + 2) & 0x1000) == 0;
+    bool isBlx = (read16(ctx, loc + 2) & 0x1000) == 0;
     // lld 10.0 and before always used bit0Thumb when deciding to write a BLX
     // even when type not STT_FUNC.
     if (!rel.sym->isFunc() && !rel.sym->isInPlt(ctx) && isBlx == useThumb)
@@ -701,21 +701,21 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
       // the BLX instruction may only be two byte aligned. This must be done
       // before overflow check.
       val = alignTo(val, 4);
-      write16(loc + 2, read16(loc + 2) & ~0x1000);
+      write16(ctx, loc + 2, read16(ctx, loc + 2) & ~0x1000);
     } else {
-      write16(loc + 2, (read16(loc + 2) & ~0x1000) | 1 << 12);
+      write16(ctx, loc + 2, (read16(ctx, loc + 2) & ~0x1000) | 1 << 12);
     }
     if (!ctx.arg.armJ1J2BranchEncoding) {
       // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
       // 
diff erent encoding rules and range due to J1 and J2 always being 1.
       checkInt(loc, val, 23, rel);
-      write16(loc,
-                0xf000 |                     // opcode
-                    ((val >> 12) & 0x07ff)); // imm11
-      write16(loc + 2,
-                (read16(loc + 2) & 0xd000) | // opcode
-                    0x2800 |                   // J1 == J2 == 1
-                    ((val >> 1) & 0x07ff));    // imm11
+      write16(ctx, loc,
+              0xf000 |                     // opcode
+                  ((val >> 12) & 0x07ff)); // imm11
+      write16(ctx, loc + 2,
+              (read16(ctx, loc + 2) & 0xd000) | // opcode
+                  0x2800 |                      // J1 == J2 == 1
+                  ((val >> 1) & 0x07ff));       // imm11
       break;
     }
   }
@@ -724,15 +724,15 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_ARM_THM_JUMP24:
     // Encoding B  T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
     checkInt(loc, val, 25, rel);
-    write16(loc,
-              0xf000 |                     // opcode
-                  ((val >> 14) & 0x0400) | // S
-                  ((val >> 12) & 0x03ff)); // imm10
-    write16(loc + 2,
-              (read16(loc + 2) & 0xd000) |                  // opcode
-                  (((~(val >> 10)) ^ (val >> 11)) & 0x2000) | // J1
-                  (((~(val >> 11)) ^ (val >> 13)) & 0x0800) | // J2
-                  ((val >> 1) & 0x07ff));                     // imm11
+    write16(ctx, loc,
+            0xf000 |                     // opcode
+                ((val >> 14) & 0x0400) | // S
+                ((val >> 12) & 0x03ff)); // imm10
+    write16(ctx, loc + 2,
+            (read16(ctx, loc + 2) & 0xd000) |               // opcode
+                (((~(val >> 10)) ^ (val >> 11)) & 0x2000) | // J1
+                (((~(val >> 11)) ^ (val >> 13)) & 0x0800) | // J2
+                ((val >> 1) & 0x07ff));                     // imm11
     break;
   case R_ARM_MOVW_ABS_NC:
   case R_ARM_MOVW_PREL_NC:
@@ -753,40 +753,40 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_ARM_THM_MOVT_BREL:
     // Encoding T1: A = imm4:i:imm3:imm8
 
-    write16(loc,
+    write16(ctx, loc,
             0xf2c0 |                     // opcode
                 ((val >> 17) & 0x0400) | // i
                 ((val >> 28) & 0x000f)); // imm4
 
-    write16(loc + 2,
-              (read16(loc + 2) & 0x8f00) | // opcode
-                  ((val >> 12) & 0x7000) |   // imm3
-                  ((val >> 16) & 0x00ff));   // imm8
+    write16(ctx, loc + 2,
+            (read16(ctx, loc + 2) & 0x8f00) | // opcode
+                ((val >> 12) & 0x7000) |      // imm3
+                ((val >> 16) & 0x00ff));      // imm8
     break;
   case R_ARM_THM_MOVW_ABS_NC:
   case R_ARM_THM_MOVW_PREL_NC:
   case R_ARM_THM_MOVW_BREL_NC:
     // Encoding T3: A = imm4:i:imm3:imm8
-    write16(loc,
-              0xf240 |                     // opcode
-                  ((val >> 1) & 0x0400) |  // i
-                  ((val >> 12) & 0x000f)); // imm4
-    write16(loc + 2,
-              (read16(loc + 2) & 0x8f00) | // opcode
-                  ((val << 4) & 0x7000) |    // imm3
-                  (val & 0x00ff));           // imm8
+    write16(ctx, loc,
+            0xf240 |                     // opcode
+                ((val >> 1) & 0x0400) |  // i
+                ((val >> 12) & 0x000f)); // imm4
+    write16(ctx, loc + 2,
+            (read16(ctx, loc + 2) & 0x8f00) | // opcode
+                ((val << 4) & 0x7000) |       // imm3
+                (val & 0x00ff));              // imm8
     break;
   case R_ARM_THM_ALU_ABS_G3:
-    write16(loc, (read16(loc) &~ 0x00ff) | ((val >> 24) & 0x00ff));
+    write16(ctx, loc, (read16(ctx, loc) & ~0x00ff) | ((val >> 24) & 0x00ff));
     break;
   case R_ARM_THM_ALU_ABS_G2_NC:
-    write16(loc, (read16(loc) &~ 0x00ff) | ((val >> 16) & 0x00ff));
+    write16(ctx, loc, (read16(ctx, loc) & ~0x00ff) | ((val >> 16) & 0x00ff));
     break;
   case R_ARM_THM_ALU_ABS_G1_NC:
-    write16(loc, (read16(loc) &~ 0x00ff) | ((val >> 8) & 0x00ff));
+    write16(ctx, loc, (read16(ctx, loc) & ~0x00ff) | ((val >> 8) & 0x00ff));
     break;
   case R_ARM_THM_ALU_ABS_G0_NC:
-    write16(loc, (read16(loc) &~ 0x00ff) | (val & 0x00ff));
+    write16(ctx, loc, (read16(ctx, loc) & ~0x00ff) | (val & 0x00ff));
     break;
   case R_ARM_ALU_PC_G0:
     encodeAluGroup(loc, rel, val, 0, true);
@@ -830,9 +830,10 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
       sub = 0x00a0;
     }
     checkUInt(loc, imm, 12, rel);
-    write16(loc, (read16(loc) & 0xfb0f) | sub | (imm & 0x800) >> 1);
-    write16(loc + 2,
-              (read16(loc + 2) & 0x8f00) | (imm & 0x700) << 4 | (imm & 0xff));
+    write16(ctx, loc, (read16(ctx, loc) & 0xfb0f) | sub | (imm & 0x800) >> 1);
+    write16(ctx, loc + 2,
+            (read16(ctx, loc + 2) & 0x8f00) | (imm & 0x700) << 4 |
+                (imm & 0xff));
     break;
   }
   case R_ARM_THM_PC8:
@@ -844,7 +845,7 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
       val &= ~0x1;
     checkUInt(loc, val, 10, rel);
     checkAlignment(loc, val, 4, rel);
-    write16(loc, (read16(loc) & 0xff00) | (val & 0x3fc) >> 2);
+    write16(ctx, loc, (read16(ctx, loc) & 0xff00) | (val & 0x3fc) >> 2);
     break;
   case R_ARM_THM_PC12: {
     // LDR (literal) encoding T2, add = (U == '1') imm12
@@ -861,8 +862,8 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
       u = 0;
     }
     checkUInt(loc, imm12, 12, rel);
-    write16(loc, read16(loc) | u);
-    write16(loc + 2, (read16(loc + 2) & 0xf000) | imm12);
+    write16(ctx, loc, read16(ctx, loc) | u);
+    write16(ctx, loc + 2, (read16(ctx, loc + 2) & 0xf000) | imm12);
     break;
   }
   default:
@@ -905,13 +906,13 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_ARM_PLT32:
     return SignExtend64<26>(read32(ctx, buf) << 2);
   case R_ARM_THM_JUMP8:
-    return SignExtend64<9>(read16(buf) << 1);
+    return SignExtend64<9>(read16(ctx, buf) << 1);
   case R_ARM_THM_JUMP11:
-    return SignExtend64<12>(read16(buf) << 1);
+    return SignExtend64<12>(read16(ctx, buf) << 1);
   case R_ARM_THM_JUMP19: {
     // Encoding T3: A = S:J2:J1:imm10:imm6:0
-    uint16_t hi = read16(buf);
-    uint16_t lo = read16(buf + 2);
+    uint16_t hi = read16(ctx, buf);
+    uint16_t lo = read16(ctx, buf + 2);
     return SignExtend64<20>(((hi & 0x0400) << 10) | // S
                             ((lo & 0x0800) << 8) |  // J2
                             ((lo & 0x2000) << 5) |  // J1
@@ -922,8 +923,8 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
     if (!ctx.arg.armJ1J2BranchEncoding) {
       // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
       // 
diff erent encoding rules and range due to J1 and J2 always being 1.
-      uint16_t hi = read16(buf);
-      uint16_t lo = read16(buf + 2);
+      uint16_t hi = read16(ctx, buf);
+      uint16_t lo = read16(ctx, buf + 2);
       return SignExtend64<22>(((hi & 0x7ff) << 12) | // imm11
                               ((lo & 0x7ff) << 1));  // imm11:0
       break;
@@ -932,8 +933,8 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_ARM_THM_JUMP24: {
     // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
     // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
-    uint16_t hi = read16(buf);
-    uint16_t lo = read16(buf + 2);
+    uint16_t hi = read16(ctx, buf);
+    uint16_t lo = read16(ctx, buf + 2);
     return SignExtend64<24>(((hi & 0x0400) << 14) |                    // S
                             (~((lo ^ (hi << 3)) << 10) & 0x00800000) | // I1
                             (~((lo ^ (hi << 1)) << 11) & 0x00400000) | // I2
@@ -958,8 +959,8 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_ARM_THM_MOVW_BREL_NC:
   case R_ARM_THM_MOVT_BREL: {
     // Encoding T3: A = imm4:i:imm3:imm8
-    uint16_t hi = read16(buf);
-    uint16_t lo = read16(buf + 2);
+    uint16_t hi = read16(ctx, buf);
+    uint16_t lo = read16(ctx, buf + 2);
     return SignExtend64<16>(((hi & 0x000f) << 12) | // imm4
                             ((hi & 0x0400) << 1) |  // i
                             ((lo & 0x7000) >> 4) |  // imm3
@@ -969,7 +970,7 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_ARM_THM_ALU_ABS_G1_NC:
   case R_ARM_THM_ALU_ABS_G2_NC:
   case R_ARM_THM_ALU_ABS_G3:
-    return read16(buf) & 0xff;
+    return read16(ctx, buf) & 0xff;
   case R_ARM_ALU_PC_G0:
   case R_ARM_ALU_PC_G0_NC:
   case R_ARM_ALU_PC_G1:
@@ -1006,8 +1007,8 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
     // Thumb2 ADR, which is an alias for a sub or add instruction with an
     // unsigned immediate.
     // ADR encoding T2 (sub), T3 (add) i:imm3:imm8
-    uint16_t hi = read16(buf);
-    uint16_t lo = read16(buf + 2);
+    uint16_t hi = read16(ctx, buf);
+    uint16_t lo = read16(ctx, buf + 2);
     uint64_t imm = (hi & 0x0400) << 1 | // i
                    (lo & 0x7000) >> 4 | // imm3
                    (lo & 0x00ff);       // imm8
@@ -1019,11 +1020,11 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
     // From ELF for the ARM Architecture the initial signed addend is formed
     // from an unsigned field using expression (((imm8:00 + 4) & 0x3ff) – 4)
     // this trick permits the PC bias of -4 to be encoded using imm8 = 0xff
-    return ((((read16(buf) & 0xff) << 2) + 4) & 0x3ff) - 4;
+    return ((((read16(ctx, buf) & 0xff) << 2) + 4) & 0x3ff) - 4;
   case R_ARM_THM_PC12: {
     // LDR (literal) encoding T2, add = (U == '1') imm12
-    bool u = read16(buf) & 0x0080;
-    uint64_t imm12 = read16(buf + 2) & 0x0fff;
+    bool u = read16(ctx, buf) & 0x0080;
+    uint64_t imm12 = read16(ctx, buf + 2) & 0x0fff;
     return u ? imm12 : -imm12;
   }
   case R_ARM_NONE:
@@ -1099,7 +1100,7 @@ static void toLittleEndianInstructions(uint8_t *buf, uint64_t start,
 
   if (curState == CodeState::Thumb)
     for (uint64_t i = start; i < end; i += width)
-      write16le(buf + i, read16(buf + i));
+      write16le(buf + i, read16(ctx, buf + i));
 }
 
 // Arm BE8 big endian format requires instructions to be little endian, with
@@ -1393,10 +1394,10 @@ void ArmCmseSGSection::addSGVeneer(Symbol *acleSeSym, Symbol *sym) {
 void ArmCmseSGSection::writeTo(uint8_t *buf) {
   for (ArmCmseSGVeneer *s : sgVeneers) {
     uint8_t *p = buf + s->offset;
-    write16(p + 0, 0xe97f); // SG
-    write16(p + 2, 0xe97f);
-    write16(p + 4, 0xf000); // B.W S
-    write16(p + 6, 0xb000);
+    write16(ctx, p + 0, 0xe97f); // SG
+    write16(ctx, p + 2, 0xe97f);
+    write16(ctx, p + 4, 0xf000); // B.W S
+    write16(ctx, p + 6, 0xb000);
     ctx.target->relocateNoSym(p + 4, R_ARM_THM_JUMP24,
                               s->acleSeSym->getVA() -
                                   (getVA() + s->offset + s->size));

diff  --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index 8736b2cc734410..d5b63497625cba 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -249,10 +249,10 @@ static void writeShuffleValue(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) {
-  uint16_t instr = read16(loc);
+  uint16_t instr = read16(ctx, loc);
   uint16_t mask = 0xffff >> (16 - bitsSize);
   uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
-  write16(loc, data);
+  write16(ctx, loc, data);
 }
 
 template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
@@ -262,22 +262,23 @@ 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(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
+    write16(ctx, buf,
+            isMipsR6(ctx) ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
+    write16(ctx, buf + 4, 0xff23);            // lw      $25, 0($3)
+    write16(ctx, buf + 8, 0x0535);            // subu16  $2,  $2, $3
+    write16(ctx, buf + 10, 0x2525);           // srl16   $2,  $2, 2
+    write16(ctx, buf + 12, 0x3302);           // addiu   $24, $2, -2
+    write16(ctx, buf + 14, 0xfffe);
+    write16(ctx, buf + 16, 0x0dff); // move    $15, $31
     if (isMipsR6(ctx)) {
-      write16(buf + 18, 0x0f83); // move    $28, $3
-      write16(buf + 20, 0x472b); // jalrc   $25
-      write16(buf + 22, 0x0c00); // nop
+      write16(ctx, buf + 18, 0x0f83); // move    $28, $3
+      write16(ctx, buf + 20, 0x472b); // jalrc   $25
+      write16(ctx, buf + 22, 0x0c00); // nop
       relocateNoSym(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
     } else {
-      write16(buf + 18, 0x45f9); // jalrc   $25
-      write16(buf + 20, 0x0f83); // move    $28, $3
-      write16(buf + 22, 0x0c00); // nop
+      write16(ctx, buf + 18, 0x45f9); // jalrc   $25
+      write16(ctx, buf + 20, 0x0f83); // move    $28, $3
+      write16(ctx, buf + 22, 0x0c00); // nop
       relocateNoSym(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
     }
     return;
@@ -325,16 +326,16 @@ void MIPS<ELFT>::writePlt(uint8_t *buf, const Symbol &sym,
     memset(buf, 0, pltEntrySize);
 
     if (isMipsR6(ctx)) {
-      write16(buf, 0x7840);      // addiupc $2, (GOTPLT) - .
-      write16(buf + 4, 0xff22);  // lw $25, 0($2)
-      write16(buf + 8, 0x0f02);  // move $24, $2
-      write16(buf + 10, 0x4723); // jrc $25 / jr16 $25
+      write16(ctx, buf, 0x7840);      // addiupc $2, (GOTPLT) - .
+      write16(ctx, buf + 4, 0xff22);  // lw $25, 0($2)
+      write16(ctx, buf + 8, 0x0f02);  // move $24, $2
+      write16(ctx, buf + 10, 0x4723); // jrc $25 / jr16 $25
       relocateNoSym(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
     } else {
-      write16(buf, 0x7900);      // addiupc $2, (GOTPLT) - .
-      write16(buf + 4, 0xff22);  // lw $25, 0($2)
-      write16(buf + 8, 0x4599);  // jrc $25 / jr16 $25
-      write16(buf + 10, 0x0f02); // move $24, $2
+      write16(ctx, buf, 0x7900);      // addiupc $2, (GOTPLT) - .
+      write16(ctx, buf + 4, 0xff22);  // lw $25, 0($2)
+      write16(ctx, buf + 8, 0x4599);  // jrc $25 / jr16 $25
+      write16(ctx, buf + 10, 0x0f02); // move $24, $2
       relocateNoSym(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
     }
     return;
@@ -444,9 +445,9 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_MICROMIPS_26_S1:
     return SignExtend64<27>(readShuffle<e>(buf) << 1);
   case R_MICROMIPS_PC7_S1:
-    return SignExtend64<8>(read16(buf) << 1);
+    return SignExtend64<8>(read16(ctx, buf) << 1);
   case R_MICROMIPS_PC10_S1:
-    return SignExtend64<11>(read16(buf) << 1);
+    return SignExtend64<11>(read16(ctx, buf) << 1);
   case R_MICROMIPS_PC16_S1:
     return SignExtend64<17>(readShuffle<e>(buf) << 1);
   case R_MICROMIPS_PC18_S3:
@@ -464,9 +465,9 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_MIPS_TLS_DTPREL64:
   case R_MIPS_TLS_TPREL64:
   case (R_MIPS_64 << 8) | R_MIPS_REL32:
-    return read64(buf);
+    return read64(ctx, buf);
   case R_MIPS_COPY:
-    return ctx.arg.is64 ? read64(buf) : read32(ctx, buf);
+    return ctx.arg.is64 ? read64(ctx, buf) : read32(ctx, buf);
   case R_MIPS_NONE:
   case R_MIPS_JUMP_SLOT:
   case R_MIPS_JALR:
@@ -596,7 +597,7 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
   case R_MIPS_64:
   case R_MIPS_TLS_DTPREL64:
   case R_MIPS_TLS_TPREL64:
-    write64(loc, val);
+    write64(ctx, loc, val);
     break;
   case R_MIPS_26:
     writeValue(loc, val, 26, 2);

diff  --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index 79962d06e5553b..e9bd3ecdbdd523 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -326,7 +326,7 @@ void PPC::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   switch (newType) {
   case R_PPC_ADDR16:
     checkIntUInt(loc, val, 16, rel);
-    write16(loc, val);
+    write16(ctx, loc, val);
     break;
   case R_PPC_GOT16:
   case R_PPC_GOT_TLSGD16:
@@ -334,7 +334,7 @@ void PPC::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC_GOT_TPREL16:
   case R_PPC_TPREL16:
     checkInt(loc, val, 16, rel);
-    write16(loc, val);
+    write16(ctx, loc, val);
     break;
   case R_PPC_ADDR16_HA:
   case R_PPC_DTPREL16_HA:
@@ -343,7 +343,7 @@ void PPC::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC_GOT_TPREL16_HA:
   case R_PPC_REL16_HA:
   case R_PPC_TPREL16_HA:
-    write16(loc, ha(val));
+    write16(ctx, loc, ha(val));
     break;
   case R_PPC_ADDR16_HI:
   case R_PPC_DTPREL16_HI:
@@ -352,7 +352,7 @@ void PPC::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC_GOT_TPREL16_HI:
   case R_PPC_REL16_HI:
   case R_PPC_TPREL16_HI:
-    write16(loc, val >> 16);
+    write16(ctx, loc, val >> 16);
     break;
   case R_PPC_ADDR16_LO:
   case R_PPC_DTPREL16_LO:
@@ -361,7 +361,7 @@ void PPC::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC_GOT_TPREL16_LO:
   case R_PPC_REL16_LO:
   case R_PPC_TPREL16_LO:
-    write16(loc, val);
+    write16(ctx, loc, val);
     break;
   case R_PPC_ADDR32:
   case R_PPC_REL32:

diff  --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index 647954106322e8..f25ff53fccd8eb 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -246,7 +246,7 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
 
 void elf::writePrefixedInst(Ctx &ctx, uint8_t *loc, uint64_t insn) {
   insn = ctx.arg.isLE ? insn << 32 | insn >> 32 : insn;
-  write64(loc, insn);
+  write64(ctx, loc, insn);
 }
 
 static bool addOptional(Ctx &ctx, StringRef name, uint64_t value,
@@ -574,7 +574,7 @@ static uint32_t readFromHalf16(Ctx &ctx, const uint8_t *loc) {
 }
 
 static uint64_t readPrefixedInst(Ctx &ctx, const uint8_t *loc) {
-  uint64_t fullInstr = read64(loc);
+  uint64_t fullInstr = read64(ctx, loc);
   return ctx.arg.isLE ? (fullInstr << 32 | fullInstr >> 32) : fullInstr;
 }
 
@@ -1125,7 +1125,7 @@ int64_t PPC64::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_PPC64_DTPMOD64:
   case R_PPC64_DTPREL64:
   case R_PPC64_TPREL64:
-    return read64(buf);
+    return read64(ctx, buf);
   default:
     internalLinkerError(getErrorLoc(ctx, buf),
                         "cannot read addend for relocation " + toString(type));
@@ -1134,7 +1134,7 @@ int64_t PPC64::getImplicitAddend(const uint8_t *buf, RelType type) const {
 }
 
 void PPC64::writeGotHeader(uint8_t *buf) const {
-  write64(buf, getPPC64TocBase(ctx));
+  write64(ctx, buf, getPPC64TocBase(ctx));
 }
 
 void PPC64::writePltHeader(uint8_t *buf) const {
@@ -1157,7 +1157,7 @@ void PPC64::writePltHeader(uint8_t *buf) const {
   // following instruction ('mflr r11'). Here we store the offset from that
   // instruction  to the first entry in the GotPlt section.
   int64_t gotPltOffset = ctx.in.gotPlt->getVA() - (ctx.in.plt->getVA() + 8);
-  write64(buf + 52, gotPltOffset);
+  write64(ctx, buf + 52, gotPltOffset);
 }
 
 void PPC64::writePlt(uint8_t *buf, const Symbol &sym,
@@ -1269,12 +1269,12 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     checkAlignment(loc, val, 4, rel);
     // Preserve the AA/LK bits in the branch instruction
     uint8_t aalk = loc[3];
-    write16(loc + 2, (aalk & 3) | (val & 0xfffc));
+    write16(ctx, loc + 2, (aalk & 3) | (val & 0xfffc));
     break;
   }
   case R_PPC64_ADDR16:
     checkIntUInt(loc, val, 16, rel);
-    write16(loc, val);
+    write16(ctx, loc, val);
     break;
   case R_PPC64_ADDR32:
     checkIntUInt(loc, val, 32, rel);
@@ -1287,7 +1287,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     // DS-form instructions only use bits 30-31.
     uint16_t mask = isDQFormInstruction(readFromHalf16(ctx, loc)) ? 0xf : 0x3;
     checkAlignment(loc, lo(val), mask + 1, rel);
-    write16(loc, (read16(loc) & mask) | lo(val));
+    write16(ctx, loc, (read16(ctx, loc) & mask) | lo(val));
   } break;
   case R_PPC64_ADDR16_HA:
   case R_PPC64_REL16_HA:
@@ -1296,33 +1296,33 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
       writeFromHalf16(ctx, loc, NOP);
     else {
       checkInt(loc, val + 0x8000, 32, rel);
-      write16(loc, ha(val));
+      write16(ctx, loc, ha(val));
     }
     break;
   case R_PPC64_ADDR16_HI:
   case R_PPC64_REL16_HI:
   case R_PPC64_TPREL16_HI:
     checkInt(loc, val, 32, rel);
-    write16(loc, hi(val));
+    write16(ctx, loc, hi(val));
     break;
   case R_PPC64_ADDR16_HIGH:
-    write16(loc, hi(val));
+    write16(ctx, loc, hi(val));
     break;
   case R_PPC64_ADDR16_HIGHER:
   case R_PPC64_TPREL16_HIGHER:
-    write16(loc, higher(val));
+    write16(ctx, loc, higher(val));
     break;
   case R_PPC64_ADDR16_HIGHERA:
   case R_PPC64_TPREL16_HIGHERA:
-    write16(loc, highera(val));
+    write16(ctx, loc, highera(val));
     break;
   case R_PPC64_ADDR16_HIGHEST:
   case R_PPC64_TPREL16_HIGHEST:
-    write16(loc, highest(val));
+    write16(ctx, loc, highest(val));
     break;
   case R_PPC64_ADDR16_HIGHESTA:
   case R_PPC64_TPREL16_HIGHESTA:
-    write16(loc, highesta(val));
+    write16(ctx, loc, highesta(val));
     break;
   case R_PPC64_ADDR16_LO:
   case R_PPC64_REL16_LO:
@@ -1337,7 +1337,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
               "can't toc-optimize an update instruction: 0x" + utohexstr(insn));
       writeFromHalf16(ctx, loc, (insn & 0xffe00000) | 0x00020000 | lo(val));
     } else {
-      write16(loc, lo(val));
+      write16(ctx, loc, lo(val));
     }
     break;
   case R_PPC64_ADDR16_LO_DS:
@@ -1358,12 +1358,12 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
       insn &= 0xffe00000 | mask;
       writeFromHalf16(ctx, loc, insn | 0x00020000 | lo(val));
     } else {
-      write16(loc, (read16(loc) & mask) | lo(val));
+      write16(ctx, loc, (read16(ctx, loc) & mask) | lo(val));
     }
   } break;
   case R_PPC64_TPREL16:
     checkInt(loc, val, 16, rel);
-    write16(loc, val);
+    write16(ctx, loc, val);
     break;
   case R_PPC64_REL32:
     checkInt(loc, val, 32, rel);
@@ -1372,7 +1372,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_PPC64_ADDR64:
   case R_PPC64_REL64:
   case R_PPC64_TOC:
-    write64(loc, val);
+    write64(ctx, loc, val);
     break;
   case R_PPC64_REL14: {
     uint32_t mask = 0x0000FFFC;
@@ -1390,7 +1390,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     break;
   }
   case R_PPC64_DTPREL64:
-    write64(loc, val - dynamicThreadPointerOffset);
+    write64(ctx, loc, val - dynamicThreadPointerOffset);
     break;
   case R_PPC64_DTPREL34:
     // The Dynamic Thread Vector actually points 0x8000 bytes past the start

diff  --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 0b9daef951b216..372f7a3b9d7b02 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -462,11 +462,11 @@ static void writeInt(uint8_t *buf, uint64_t data, uint64_t size) {
   if (size == 1)
     *buf = data;
   else if (size == 2)
-    write16(buf, data);
+    write16(ctx, buf, data);
   else if (size == 4)
     write32(ctx, buf, data);
   else if (size == 8)
-    write64(buf, data);
+    write64(ctx, buf, data);
   else
     llvm_unreachable("unsupported Size argument");
 }

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 01a7e9a7866c36..1288126328b4d2 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -60,12 +60,12 @@ using llvm::support::endian::write64le;
 constexpr size_t MergeNoTailSection::numShards;
 
 static uint64_t readUint(Ctx &ctx, uint8_t *buf) {
-  return ctx.arg.is64 ? read64(buf) : read32(ctx, buf);
+  return ctx.arg.is64 ? read64(ctx, buf) : read32(ctx, buf);
 }
 
 static void writeUint(Ctx &ctx, uint8_t *buf, uint64_t val) {
   if (ctx.arg.is64)
-    write64(buf, val);
+    write64(ctx, buf, val);
   else
     write32(ctx, buf, val);
 }
@@ -596,16 +596,16 @@ SmallVector<EhFrameSection::FdeData, 0> EhFrameSection::getFdeData() const {
 static uint64_t readFdeAddr(Ctx &ctx, uint8_t *buf, int size) {
   switch (size) {
   case DW_EH_PE_udata2:
-    return read16(buf);
+    return read16(ctx, buf);
   case DW_EH_PE_sdata2:
-    return (int16_t)read16(buf);
+    return (int16_t)read16(ctx, buf);
   case DW_EH_PE_udata4:
     return read32(ctx, buf);
   case DW_EH_PE_sdata4:
     return (int32_t)read32(ctx, buf);
   case DW_EH_PE_udata8:
   case DW_EH_PE_sdata8:
-    return read64(buf);
+    return read64(ctx, buf);
   case DW_EH_PE_absptr:
     return readUint(ctx, buf);
   }
@@ -3725,10 +3725,10 @@ void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
   uint16_t flags = index == 1 ? VER_FLG_BASE : 0;
 
   // Write a verdef.
-  write16(buf, 1);                  // vd_version
-  write16(buf + 2, flags);          // vd_flags
-  write16(buf + 4, index);          // vd_ndx
-  write16(buf + 6, 1);              // vd_cnt
+  write16(ctx, buf, 1);                  // vd_version
+  write16(ctx, buf + 2, flags);          // vd_flags
+  write16(ctx, buf + 4, index);          // vd_ndx
+  write16(ctx, buf + 6, 1);              // vd_cnt
   write32(ctx, buf + 8, hashSysV(name)); // vd_hash
   write32(ctx, buf + 12, 20);            // vd_aux
   write32(ctx, buf + 16, 28);            // vd_next
@@ -3778,7 +3778,7 @@ void VersionTableSection::writeTo(uint8_t *buf) {
     // For an unextracted lazy symbol (undefined weak), it must have been
     // converted to Undefined and have VER_NDX_GLOBAL version here.
     assert(!s.sym->isLazy());
-    write16(buf, s.sym->versionId);
+    write16(ctx, buf, s.sym->versionId);
     buf += 2;
   }
 }
@@ -4358,8 +4358,9 @@ void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
     assert(sym->getVA());
     // Need calls to branch to the local entry-point since a long-branch
     // must be a local-call.
-    write64(buf, sym->getVA(addend) +
-                     getPPC64GlobalEntryToLocalEntryOffset(sym->stOther));
+    write64(ctx, buf,
+            sym->getVA(addend) +
+                getPPC64GlobalEntryToLocalEntryOffset(sym->stOther));
     buf += 8;
   }
 }

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index f94d3cf0552a84..bdf5bae80f42b2 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -292,7 +292,7 @@ inline void checkAlignment(uint8_t *loc, uint64_t v, int n,
 }
 
 // Endianness-aware read/write.
-inline uint16_t read16(const void *p) {
+inline uint16_t read16(Ctx &ctx, const void *p) {
   return llvm::support::endian::read16(p, ctx.arg.endianness);
 }
 
@@ -300,11 +300,11 @@ inline uint32_t read32(Ctx &ctx, const void *p) {
   return llvm::support::endian::read32(p, ctx.arg.endianness);
 }
 
-inline uint64_t read64(const void *p) {
+inline uint64_t read64(Ctx &ctx, const void *p) {
   return llvm::support::endian::read64(p, ctx.arg.endianness);
 }
 
-inline void write16(void *p, uint16_t v) {
+inline void write16(Ctx &ctx, void *p, uint16_t v) {
   llvm::support::endian::write16(p, v, ctx.arg.endianness);
 }
 
@@ -312,7 +312,7 @@ inline void write32(Ctx &ctx, void *p, uint32_t v) {
   llvm::support::endian::write32(p, v, ctx.arg.endianness);
 }
 
-inline void write64(void *p, uint64_t v) {
+inline void write64(Ctx &ctx, void *p, uint64_t v) {
   llvm::support::endian::write64(p, v, ctx.arg.endianness);
 }
 

diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 16066926c860d5..611b632f826979 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -751,8 +751,8 @@ void ThumbThunk::writeTo(uint8_t *buf) {
   uint64_t s = getARMThunkDestVA(ctx, destination);
   uint64_t p = getThunkTargetSym()->getVA();
   int64_t offset = s - p - 4;
-  write16(buf + 0, 0xf000); // b.w S
-  write16(buf + 2, 0xb000);
+  write16(ctx, buf + 0, 0xf000); // b.w S
+  write16(ctx, buf + 2, 0xb000);
   ctx.target->relocateNoSym(buf, R_ARM_THM_JUMP24, offset);
 }
 
@@ -782,11 +782,11 @@ void ARMV7ABSLongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV7ABSLongThunk::writeLong(uint8_t *buf) {
-  write16(buf + 0, 0xf240); // movw ip, :lower16:S
-  write16(buf + 2, 0x0c00);
-  write16(buf + 4, 0xf2c0); // movt ip, :upper16:S
-  write16(buf + 6, 0x0c00);
-  write16(buf + 8, 0x4760); // bx   ip
+  write16(ctx, buf + 0, 0xf240); // movw ip, :lower16:S
+  write16(ctx, buf + 2, 0x0c00);
+  write16(ctx, buf + 4, 0xf2c0); // movt ip, :upper16:S
+  write16(ctx, buf + 6, 0x0c00);
+  write16(ctx, buf + 8, 0x4760); // bx   ip
   uint64_t s = getARMThunkDestVA(ctx, destination);
   ctx.target->relocateNoSym(buf, R_ARM_THM_MOVW_ABS_NC, s);
   ctx.target->relocateNoSym(buf + 4, R_ARM_THM_MOVT_ABS, s);
@@ -819,12 +819,12 @@ void ARMV7PILongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV7PILongThunk::writeLong(uint8_t *buf) {
-  write16(buf + 0, 0xf64f);   // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
-  write16(buf + 2, 0x7cf4);
-  write16(buf + 4, 0xf2c0);   //     movt ip,:upper16:S - (P + (L1-P) + 4)
-  write16(buf + 6, 0x0c00);
-  write16(buf + 8, 0x44fc);   // L1: add  ip, pc
-  write16(buf + 10, 0x4760);  //     bx   ip
+  write16(ctx, buf + 0, 0xf64f); // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
+  write16(ctx, buf + 2, 0x7cf4);
+  write16(ctx, buf + 4, 0xf2c0); //     movt ip,:upper16:S - (P + (L1-P) + 4)
+  write16(ctx, buf + 6, 0x0c00);
+  write16(ctx, buf + 8, 0x44fc);  // L1: add  ip, pc
+  write16(ctx, buf + 10, 0x4760); //     bx   ip
   uint64_t s = getARMThunkDestVA(ctx, destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
   int64_t offset = s - p - 12;
@@ -843,10 +843,10 @@ void ThumbV6MABSLongThunk::writeLong(uint8_t *buf) {
   // only register we can corrupt is r12 we must instead spill a low register
   // to the stack to use as a scratch register. We push r1 even though we
   // don't need to get some space to use for the return address.
-  write16(buf + 0, 0xb403);   // push {r0, r1} ; Obtain scratch registers
-  write16(buf + 2, 0x4801);   // ldr r0, [pc, #4] ; L1
-  write16(buf + 4, 0x9001);   // str r0, [sp, #4] ; SP + 4 = S
-  write16(buf + 6, 0xbd01);   // pop {r0, pc} ; restore r0 and branch to dest
+  write16(ctx, buf + 0, 0xb403); // push {r0, r1} ; Obtain scratch registers
+  write16(ctx, buf + 2, 0x4801); // ldr r0, [pc, #4] ; L1
+  write16(ctx, buf + 4, 0x9001); // str r0, [sp, #4] ; SP + 4 = S
+  write16(ctx, buf + 6, 0xbd01); // pop {r0, pc} ; restore r0 and branch to dest
   write32(ctx, buf + 8, 0x00000000); // L1: .word S
   uint64_t s = getARMThunkDestVA(ctx, destination);
   ctx.target->relocateNoSym(buf + 8, R_ARM_ABS32, s);
@@ -865,16 +865,17 @@ void ThumbV6MABSXOLongThunk::writeLong(uint8_t *buf) {
   // only register we can corrupt is r12 we must instead spill a low register
   // to the stack to use as a scratch register. We push r1 even though we
   // don't need to get some space to use for the return address.
-  write16(buf + 0, 0xb403);  // push {r0, r1} ; Obtain scratch registers
-  write16(buf + 2, 0x2000);  // movs r0, :upper8_15:S
-  write16(buf + 4, 0x0200);  // lsls r0, r0, #8
-  write16(buf + 6, 0x3000);  // adds r0, :upper0_7:S
-  write16(buf + 8, 0x0200);  // lsls r0, r0, #8
-  write16(buf + 10, 0x3000); // adds r0, :lower8_15:S
-  write16(buf + 12, 0x0200); // lsls r0, r0, #8
-  write16(buf + 14, 0x3000); // adds r0, :lower0_7:S
-  write16(buf + 16, 0x9001); // str r0, [sp, #4] ; SP + 4 = S
-  write16(buf + 18, 0xbd01); // pop {r0, pc} ; restore r0 and branch to dest
+  write16(ctx, buf + 0, 0xb403);  // push {r0, r1} ; Obtain scratch registers
+  write16(ctx, buf + 2, 0x2000);  // movs r0, :upper8_15:S
+  write16(ctx, buf + 4, 0x0200);  // lsls r0, r0, #8
+  write16(ctx, buf + 6, 0x3000);  // adds r0, :upper0_7:S
+  write16(ctx, buf + 8, 0x0200);  // lsls r0, r0, #8
+  write16(ctx, buf + 10, 0x3000); // adds r0, :lower8_15:S
+  write16(ctx, buf + 12, 0x0200); // lsls r0, r0, #8
+  write16(ctx, buf + 14, 0x3000); // adds r0, :lower0_7:S
+  write16(ctx, buf + 16, 0x9001); // str r0, [sp, #4] ; SP + 4 = S
+  write16(ctx, buf + 18,
+          0xbd01); // pop {r0, pc} ; restore r0 and branch to dest
   uint64_t s = getARMThunkDestVA(ctx, destination);
   ctx.target->relocateNoSym(buf + 2, R_ARM_THM_ALU_ABS_G3, s);
   ctx.target->relocateNoSym(buf + 6, R_ARM_THM_ALU_ABS_G2_NC, s);
@@ -892,12 +893,15 @@ void ThumbV6MPILongThunk::writeLong(uint8_t *buf) {
   // Most Thumb instructions cannot access the high registers r8 - r15. As the
   // only register we can corrupt is ip (r12) we must instead spill a low
   // register to the stack to use as a scratch register.
-  write16(buf + 0, 0xb401);   // P:  push {r0}        ; Obtain scratch register
-  write16(buf + 2, 0x4802);   //     ldr r0, [pc, #8] ; L2
-  write16(buf + 4, 0x4684);   //     mov ip, r0       ; high to low register
-  write16(buf + 6, 0xbc01);   //     pop {r0}         ; restore scratch register
-  write16(buf + 8, 0x44e7);   // L1: add pc, ip       ; transfer control
-  write16(buf + 10, 0x46c0);  //     nop              ; pad to 4-byte boundary
+  write16(ctx, buf + 0,
+          0xb401); // P:  push {r0}        ; Obtain scratch register
+  write16(ctx, buf + 2, 0x4802); //     ldr r0, [pc, #8] ; L2
+  write16(ctx, buf + 4, 0x4684); //     mov ip, r0       ; high to low register
+  write16(ctx, buf + 6,
+          0xbc01); //     pop {r0}         ; restore scratch register
+  write16(ctx, buf + 8, 0x44e7); // L1: add pc, ip       ; transfer control
+  write16(ctx, buf + 10,
+          0x46c0); //     nop              ; pad to 4-byte boundary
   write32(ctx, buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 4)
   uint64_t s = getARMThunkDestVA(ctx, destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
@@ -944,8 +948,9 @@ void ARMV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4ABSLongBXThunk::writeLong(uint8_t *buf) {
-  write16(buf + 0, 0x4778); // bx pc
-  write16(buf + 2, 0xe7fd); // b #-6 ; Arm recommended sequence to follow bx pc
+  write16(ctx, buf + 0, 0x4778); // bx pc
+  write16(ctx, buf + 2,
+          0xe7fd); // b #-6 ; Arm recommended sequence to follow bx pc
   write32(ctx, buf + 4, 0xe51ff004); // ldr pc, [pc, #-4] ; L1
   write32(ctx, buf + 8, 0x00000000); // L1: .word S
   ctx.target->relocateNoSym(buf + 8, R_ARM_ABS32,
@@ -962,8 +967,9 @@ void ThumbV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4ABSLongThunk::writeLong(uint8_t *buf) {
-  write16(buf + 0, 0x4778); // bx pc
-  write16(buf + 2, 0xe7fd); // b #-6 ; Arm recommended sequence to follow bx pc
+  write16(ctx, buf + 0, 0x4778); // bx pc
+  write16(ctx, buf + 2,
+          0xe7fd); // b #-6 ; Arm recommended sequence to follow bx pc
   write32(ctx, buf + 4, 0xe59fc000);  // ldr r12, [pc] ; L1
   write32(ctx, buf + 8, 0xe12fff1c);  // bx r12
   write32(ctx, buf + 12, 0x00000000); // L1: .word S
@@ -1016,8 +1022,9 @@ void ARMV4PILongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4PILongBXThunk::writeLong(uint8_t *buf) {
-  write16(buf + 0, 0x4778); // P:  bx pc
-  write16(buf + 2, 0xe7fd); //     b #-6 ; Arm recommended sequence to follow bx pc
+  write16(ctx, buf + 0, 0x4778); // P:  bx pc
+  write16(ctx, buf + 2,
+          0xe7fd); //     b #-6 ; Arm recommended sequence to follow bx pc
   write32(ctx, buf + 4, 0xe59fc000);  //     ldr r12, [pc] ; L2
   write32(ctx, buf + 8, 0xe08cf00f);  // L1: add pc, r12, pc
   write32(ctx, buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
@@ -1036,8 +1043,9 @@ void ThumbV4PILongBXThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4PILongThunk::writeLong(uint8_t *buf) {
-  write16(buf + 0, 0x4778); // P:  bx pc
-  write16(buf + 2, 0xe7fd); //     b #-6 ; Arm recommended sequence to follow bx pc
+  write16(ctx, buf + 0, 0x4778); // P:  bx pc
+  write16(ctx, buf + 2,
+          0xe7fd); //     b #-6 ; Arm recommended sequence to follow bx pc
   write32(ctx, buf + 4, 0xe59fc004);  //     ldr ip, [pc,#4] ; L2
   write32(ctx, buf + 8, 0xe08fc00c);  // L1: add ip, pc, ip
   write32(ctx, buf + 12, 0xe12fff1c); //     bx ip
@@ -1092,10 +1100,10 @@ InputSection *MipsThunk::getTargetInputSection() const {
 // to call PIC function from the non-PIC one.
 void MicroMipsThunk::writeTo(uint8_t *buf) {
   uint64_t s = destination.getVA();
-  write16(buf, 0x41b9);       // lui   $25, %hi(func)
-  write16(buf + 4, 0xd400);   // j     func
-  write16(buf + 8, 0x3339);   // addiu $25, $25, %lo(func)
-  write16(buf + 12, 0x0c00);  // nop
+  write16(ctx, buf, 0x41b9);      // lui   $25, %hi(func)
+  write16(ctx, buf + 4, 0xd400);  // j     func
+  write16(ctx, buf + 8, 0x3339);  // addiu $25, $25, %lo(func)
+  write16(ctx, buf + 12, 0x0c00); // nop
   ctx.target->relocateNoSym(buf, R_MICROMIPS_HI16, s);
   ctx.target->relocateNoSym(buf + 4, R_MICROMIPS_26_S1, s);
   ctx.target->relocateNoSym(buf + 8, R_MICROMIPS_LO16, s);
@@ -1118,9 +1126,9 @@ InputSection *MicroMipsThunk::getTargetInputSection() const {
 void MicroMipsR6Thunk::writeTo(uint8_t *buf) {
   uint64_t s = destination.getVA();
   uint64_t p = getThunkTargetSym()->getVA();
-  write16(buf, 0x1320);       // lui   $25, %hi(func)
-  write16(buf + 4, 0x3339);   // addiu $25, $25, %lo(func)
-  write16(buf + 8, 0x9400);   // bc    func
+  write16(ctx, buf, 0x1320);     // lui   $25, %hi(func)
+  write16(ctx, buf + 4, 0x3339); // addiu $25, $25, %lo(func)
+  write16(ctx, buf + 8, 0x9400); // bc    func
   ctx.target->relocateNoSym(buf, R_MICROMIPS_HI16, s);
   ctx.target->relocateNoSym(buf + 4, R_MICROMIPS_LO16, s);
   ctx.target->relocateNoSym(buf + 8, R_MICROMIPS_PC26_S1, s - p - 12);


        


More information about the llvm-commits mailing list