[lld] 38dfcd9 - [ELF] Pass Ctx & to read32/write32
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 13 10:37:54 PDT 2024
Author: Fangrui Song
Date: 2024-10-13T10:37:47-07:00
New Revision: 38dfcd9ac9cceaebc86fc3d08bdc29ecef82c874
URL: https://github.com/llvm/llvm-project/commit/38dfcd9ac9cceaebc86fc3d08bdc29ecef82c874
DIFF: https://github.com/llvm/llvm-project/commit/38dfcd9ac9cceaebc86fc3d08bdc29ecef82c874.diff
LOG: [ELF] Pass Ctx & to read32/write32
Added:
Modified:
lld/ELF/Arch/AArch64.cpp
lld/ELF/Arch/ARM.cpp
lld/ELF/Arch/Hexagon.cpp
lld/ELF/Arch/Mips.cpp
lld/ELF/Arch/PPC.cpp
lld/ELF/Arch/PPC64.cpp
lld/ELF/Arch/RISCV.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 51d2f19c6f9296..e1b06240493635 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -265,7 +265,7 @@ int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
return SignExtend64<16>(read16(buf));
case R_AARCH64_ABS32:
case R_AARCH64_PREL32:
- return SignExtend64<32>(read32(buf));
+ return SignExtend64<32>(read32(ctx, buf));
case R_AARCH64_ABS64:
case R_AARCH64_PREL64:
case R_AARCH64_RELATIVE:
@@ -490,12 +490,12 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
case R_AARCH64_ABS32:
case R_AARCH64_PREL32:
checkIntUInt(loc, val, 32, rel);
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_AARCH64_PLT32:
case R_AARCH64_GOTPCREL32:
checkInt(loc, val, 32, rel);
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_AARCH64_ABS64:
// AArch64 relocations to tagged symbols have extended semantics, as
@@ -526,7 +526,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
// finalizeAddressDependentContent(). Writing the value is harmless
// because dynamic linking ignores it.
if (isInt<32>(val))
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_AARCH64_ADD_ABS_LO12_NC:
write32Imm12(loc, val);
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 2219d2d6ce0c41..d6fbea13e8d725 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -208,28 +208,28 @@ RelType ARM::getDynRel(RelType type) const {
}
void ARM::writeGotPlt(uint8_t *buf, const Symbol &) const {
- write32(buf, ctx.in.plt->getVA());
+ write32(ctx, buf, ctx.in.plt->getVA());
}
void ARM::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
// An ARM entry is the address of the ifunc resolver function.
- write32(buf, s.getVA());
+ write32(ctx, buf, s.getVA());
}
// Long form PLT Header that does not have any restrictions on the displacement
// of the .plt from the .got.plt.
static void writePltHeaderLong(Ctx &ctx, uint8_t *buf) {
- write32(buf + 0, 0xe52de004); // str lr, [sp,#-4]!
- write32(buf + 4, 0xe59fe004); // ldr lr, L2
- write32(buf + 8, 0xe08fe00e); // L1: add lr, pc, lr
- write32(buf + 12, 0xe5bef008); // ldr pc, [lr, #8]
- write32(buf + 16, 0x00000000); // L2: .word &(.got.plt) - L1 - 8
- write32(buf + 20, 0xd4d4d4d4); // Pad to 32-byte boundary
- write32(buf + 24, 0xd4d4d4d4); // Pad to 32-byte boundary
- write32(buf + 28, 0xd4d4d4d4);
+ write32(ctx, buf + 0, 0xe52de004); // str lr, [sp,#-4]!
+ write32(ctx, buf + 4, 0xe59fe004); // ldr lr, L2
+ write32(ctx, buf + 8, 0xe08fe00e); // L1: add lr, pc, lr
+ write32(ctx, buf + 12, 0xe5bef008); // ldr pc, [lr, #8]
+ write32(ctx, buf + 16, 0x00000000); // L2: .word &(.got.plt) - L1 - 8
+ write32(ctx, buf + 20, 0xd4d4d4d4); // Pad to 32-byte boundary
+ write32(ctx, buf + 24, 0xd4d4d4d4); // Pad to 32-byte boundary
+ write32(ctx, buf + 28, 0xd4d4d4d4);
uint64_t gotPlt = ctx.in.gotPlt->getVA();
uint64_t l1 = ctx.in.plt->getVA() + 8;
- write32(buf + 16, gotPlt - l1 - 8);
+ write32(ctx, buf + 16, gotPlt - l1 - 8);
}
// True if we should use Thumb PLTs, which currently require Thumb2, and are
@@ -263,7 +263,7 @@ void ARM::writePltHeader(uint8_t *buf) const {
// Split into two halves to support endianness correctly.
write16(buf + 8, 0xf85e);
write16(buf + 10, 0xff08);
- write32(buf + 12, offset);
+ write32(ctx, buf + 12, offset);
memcpy(buf + 16, trapInstr.data(), 4); // Pad to 32-byte boundary
memcpy(buf + 20, trapInstr.data(), 4);
@@ -287,10 +287,10 @@ void ARM::writePltHeader(uint8_t *buf) const {
writePltHeaderLong(ctx, buf);
return;
}
- write32(buf + 0, pltData[0]);
- write32(buf + 4, pltData[1] | ((offset >> 20) & 0xff));
- write32(buf + 8, pltData[2] | ((offset >> 12) & 0xff));
- write32(buf + 12, pltData[3] | (offset & 0xfff));
+ write32(ctx, buf + 0, pltData[0]);
+ write32(ctx, buf + 4, pltData[1] | ((offset >> 20) & 0xff));
+ write32(ctx, buf + 8, pltData[2] | ((offset >> 12) & 0xff));
+ write32(ctx, buf + 12, pltData[3] | (offset & 0xfff));
memcpy(buf + 16, trapInstr.data(), 4); // Pad to 32-byte boundary
memcpy(buf + 20, trapInstr.data(), 4);
memcpy(buf + 24, trapInstr.data(), 4);
@@ -312,12 +312,12 @@ void ARM::addPltHeaderSymbols(InputSection &isec) const {
// of the .plt from the .got.plt.
static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr,
uint64_t pltEntryAddr) {
- write32(buf + 0, 0xe59fc004); // ldr ip, L2
- write32(buf + 4, 0xe08cc00f); // L1: add ip, ip, pc
- write32(buf + 8, 0xe59cf000); // ldr pc, [ip]
- write32(buf + 12, 0x00000000); // L2: .word Offset(&(.got.plt) - L1 - 8
+ write32(ctx, buf + 0, 0xe59fc004); // ldr ip, L2
+ write32(ctx, buf + 4, 0xe08cc00f); // L1: add ip, ip, pc
+ write32(ctx, buf + 8, 0xe59cf000); // ldr pc, [ip]
+ write32(ctx, buf + 12, 0x00000000); // L2: .word Offset(&(.got.plt) - L1 - 8
uint64_t l1 = pltEntryAddr + 4;
- write32(buf + 12, gotPltEntryAddr - l1 - 8);
+ write32(ctx, buf + 12, gotPltEntryAddr - l1 - 8);
}
// The default PLT entries require the .got.plt to be within 128 Mb of the
@@ -342,9 +342,9 @@ void ARM::writePlt(uint8_t *buf, const Symbol &sym,
writePltLong(buf, sym.getGotPltVA(ctx), pltEntryAddr);
return;
}
- write32(buf + 0, pltData[0] | ((offset >> 20) & 0xff));
- write32(buf + 4, pltData[1] | ((offset >> 12) & 0xff));
- write32(buf + 8, pltData[2] | (offset & 0xfff));
+ write32(ctx, buf + 0, pltData[0] | ((offset >> 20) & 0xff));
+ write32(ctx, buf + 4, pltData[1] | ((offset >> 12) & 0xff));
+ write32(ctx, buf + 8, pltData[2] | (offset & 0xfff));
memcpy(buf + 12, trapInstr.data(), 4); // Pad to 16-byte boundary
} else {
uint64_t offset = sym.getGotPltVA(ctx) - pltEntryAddr - 12;
@@ -558,7 +558,8 @@ void ARM::encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
if (check && imm > 0xff)
error(getErrorLoc(ctx, loc) + "unencodeable immediate " + Twine(val).str() +
" for relocation " + toString(rel.type));
- write32(loc, (read32(loc) & 0xff3ff000) | opcode | rot | (imm & 0xff));
+ write32(ctx, loc,
+ (read32(ctx, loc) & 0xff3ff000) | opcode | rot | (imm & 0xff));
}
static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
@@ -576,7 +577,7 @@ static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
}
uint32_t imm = getRemAndLZForGroup(group, val).first;
checkUInt(loc, imm, 12, rel);
- write32(loc, (read32(loc) & 0xff7ff000) | opcode | imm);
+ write32(ctx, loc, (read32(ctx, loc) & 0xff7ff000) | opcode | imm);
}
static void encodeLdrsGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
@@ -594,8 +595,9 @@ static void encodeLdrsGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
}
uint32_t imm = getRemAndLZForGroup(group, val).first;
checkUInt(loc, imm, 8, rel);
- write32(loc, (read32(loc) & 0xff7ff0f0) | opcode | ((imm & 0xf0) << 4) |
- (imm & 0xf));
+ write32(ctx, loc,
+ (read32(ctx, loc) & 0xff7ff0f0) | opcode | ((imm & 0xf0) << 4) |
+ (imm & 0xf));
}
void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
@@ -617,11 +619,11 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_ARM_TLS_LE32:
case R_ARM_TLS_TPOFF32:
case R_ARM_TLS_DTPOFF32:
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_ARM_PREL31:
checkInt(loc, val, 31, rel);
- write32(loc, (read32(loc) & 0x80000000) | (val & ~0x80000000));
+ write32(ctx, loc, (read32(ctx, loc) & 0x80000000) | (val & ~0x80000000));
break;
case R_ARM_CALL: {
// R_ARM_CALL is used for BL and BLX instructions, for symbols of type
@@ -630,7 +632,7 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
// not of type STT_FUNC then we must preserve the original instruction.
assert(rel.sym); // R_ARM_CALL is always reached via relocate().
bool bit0Thumb = val & 1;
- bool isBlx = (read32(loc) & 0xfe000000) == 0xfa000000;
+ bool isBlx = (read32(ctx, loc) & 0xfe000000) == 0xfa000000;
// lld 10.0 and before always used bit0Thumb when deciding to write a BLX
// even when type not STT_FUNC.
if (!rel.sym->isFunc() && isBlx != bit0Thumb)
@@ -638,14 +640,15 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
if (rel.sym->isFunc() ? bit0Thumb : isBlx) {
// The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
checkInt(loc, val, 26, rel);
- write32(loc, 0xfa000000 | // opcode
- ((val & 2) << 23) | // H
- ((val >> 2) & 0x00ffffff)); // imm24
+ write32(ctx, loc,
+ 0xfa000000 | // opcode
+ ((val & 2) << 23) | // H
+ ((val >> 2) & 0x00ffffff)); // imm24
break;
}
// BLX (always unconditional) instruction to an ARM Target, select an
// unconditional BL.
- write32(loc, 0xeb000000 | (read32(loc) & 0x00ffffff));
+ write32(ctx, loc, 0xeb000000 | (read32(ctx, loc) & 0x00ffffff));
// fall through as BL encoding is shared with B
}
[[fallthrough]];
@@ -653,17 +656,18 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_ARM_PC24:
case R_ARM_PLT32:
checkInt(loc, val, 26, rel);
- write32(loc, (read32(loc) & ~0x00ffffff) | ((val >> 2) & 0x00ffffff));
+ write32(ctx, loc,
+ (read32(ctx, loc) & ~0x00ffffff) | ((val >> 2) & 0x00ffffff));
break;
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(loc) & 0xff00) | ((val >> 1) & 0x00ff));
+ write16(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(loc) & 0xf800) | ((val >> 1) & 0x07ff));
+ write16(loc, (read32(ctx, loc) & 0xf800) | ((val >> 1) & 0x07ff));
break;
case R_ARM_THM_JUMP19:
// Encoding T3: Val = S:J2:J1:imm6:imm11:0
@@ -733,14 +737,16 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVW_BREL_NC:
- write32(loc, (read32(loc) & ~0x000f0fff) | ((val & 0xf000) << 4) |
- (val & 0x0fff));
+ write32(ctx, loc,
+ (read32(ctx, loc) & ~0x000f0fff) | ((val & 0xf000) << 4) |
+ (val & 0x0fff));
break;
case R_ARM_MOVT_ABS:
case R_ARM_MOVT_PREL:
case R_ARM_MOVT_BREL:
- write32(loc, (read32(loc) & ~0x000f0fff) |
- (((val >> 16) & 0xf000) << 4) | ((val >> 16) & 0xfff));
+ write32(ctx, loc,
+ (read32(ctx, loc) & ~0x000f0fff) | (((val >> 16) & 0xf000) << 4) |
+ ((val >> 16) & 0xfff));
break;
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVT_PREL:
@@ -890,14 +896,14 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_ARM_TLS_LE32:
case R_ARM_TLS_LDO32:
case R_ARM_TLS_TPOFF32:
- return SignExtend64<32>(read32(buf));
+ return SignExtend64<32>(read32(ctx, buf));
case R_ARM_PREL31:
- return SignExtend64<31>(read32(buf));
+ return SignExtend64<31>(read32(ctx, buf));
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PC24:
case R_ARM_PLT32:
- return SignExtend64<26>(read32(buf) << 2);
+ return SignExtend64<26>(read32(ctx, buf) << 2);
case R_ARM_THM_JUMP8:
return SignExtend64<9>(read16(buf) << 1);
case R_ARM_THM_JUMP11:
@@ -942,7 +948,7 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_ARM_MOVT_PREL:
case R_ARM_MOVW_BREL_NC:
case R_ARM_MOVT_BREL: {
- uint64_t val = read32(buf) & 0x000f0fff;
+ uint64_t val = read32(ctx, buf) & 0x000f0fff;
return SignExtend64<16>(((val & 0x000f0000) >> 4) | (val & 0x00fff));
}
case R_ARM_THM_MOVW_ABS_NC:
@@ -973,7 +979,7 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
// right rotation and 8-bit constant. After the rotation the value
// is zero-extended. When bit 23 is set the instruction is an add, when
// bit 22 is set it is a sub.
- uint32_t instr = read32(buf);
+ uint32_t instr = read32(ctx, buf);
uint32_t val = rotr32(instr & 0xff, ((instr & 0xf00) >> 8) * 2);
return (instr & 0x00400000) ? -val : val;
}
@@ -982,15 +988,15 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_ARM_LDR_PC_G2: {
// ADR (literal) add = bit23, sub = bit22
// LDR (literal) u = bit23 unsigned imm12
- bool u = read32(buf) & 0x00800000;
- uint32_t imm12 = read32(buf) & 0xfff;
+ bool u = read32(ctx, buf) & 0x00800000;
+ uint32_t imm12 = read32(ctx, buf) & 0xfff;
return u ? imm12 : -imm12;
}
case R_ARM_LDRS_PC_G0:
case R_ARM_LDRS_PC_G1:
case R_ARM_LDRS_PC_G2: {
// LDRD/LDRH/LDRSB/LDRSH (literal) u = bit23 unsigned imm8
- uint32_t opcode = read32(buf);
+ uint32_t opcode = read32(ctx, buf);
bool u = opcode & 0x00800000;
uint32_t imm4l = opcode & 0xf;
uint32_t imm4h = (opcode & 0xf00) >> 4;
@@ -1089,7 +1095,7 @@ 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(buf + i));
+ write32le(buf + i, read32(ctx, buf + i));
if (curState == CodeState::Thumb)
for (uint64_t i = start; i < end; i += width)
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index 8c2d3126a3cc73..4f4d466ca75040 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -410,7 +410,7 @@ int64_t Hexagon::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_HEX_DTPMOD_32:
case R_HEX_DTPREL_32:
case R_HEX_TPREL_32:
- return SignExtend64<32>(read32(buf));
+ return SignExtend64<32>(read32(ctx, buf));
default:
internalLinkerError(getErrorLoc(ctx, buf),
"cannot read addend for relocation " + toString(type));
diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index 6313ac8ca4fb9a..8736b2cc734410 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -52,7 +52,7 @@ template <class ELFT> MIPS<ELFT>::MIPS(Ctx &ctx) : TargetInfo(ctx) {
needsThunks = true;
// Set `sigrie 1` as a trap instruction.
- write32(trapInstr.data(), 0x04170001);
+ write32(ctx, trapInstr.data(), 0x04170001);
if (ELFT::Is64Bits) {
relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
@@ -208,7 +208,7 @@ void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
uint64_t va = ctx.in.plt->getVA();
if (isMicroMips(ctx))
va |= 1;
- write32(buf, va);
+ write32(ctx, buf, va);
}
template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
@@ -218,7 +218,7 @@ template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
// as early as possible. To do so, little-endian binaries keep 16-bit
// words in a big-endian order. That is why we have to swap these
// words to get a correct value.
- uint32_t v = read32(loc);
+ uint32_t v = read32(ctx, loc);
if (E == llvm::endianness::little)
return (v << 16) | (v >> 16);
return v;
@@ -226,10 +226,10 @@ template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
static void writeValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
uint8_t shift) {
- uint32_t instr = read32(loc);
+ uint32_t instr = read32(ctx, loc);
uint32_t mask = 0xffffffff >> (32 - bitsSize);
uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
- write32(loc, data);
+ write32(ctx, loc, data);
}
template <endianness E>
@@ -284,31 +284,31 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
}
if (ctx.arg.mipsN32Abi) {
- write32(buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
- write32(buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
- write32(buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
- write32(buf + 12, 0x030ec023); // subu $24, $24, $14
- write32(buf + 16, 0x03e07825); // move $15, $31
- write32(buf + 20, 0x0018c082); // srl $24, $24, 2
+ write32(ctx, buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
+ write32(ctx, buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
+ write32(ctx, buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
+ write32(ctx, buf + 12, 0x030ec023); // subu $24, $24, $14
+ write32(ctx, buf + 16, 0x03e07825); // move $15, $31
+ write32(ctx, buf + 20, 0x0018c082); // srl $24, $24, 2
} else if (ELFT::Is64Bits) {
- write32(buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
- write32(buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
- write32(buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
- write32(buf + 12, 0x030ec023); // subu $24, $24, $14
- write32(buf + 16, 0x03e07825); // move $15, $31
- write32(buf + 20, 0x0018c0c2); // srl $24, $24, 3
+ write32(ctx, buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
+ write32(ctx, buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
+ write32(ctx, buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
+ write32(ctx, buf + 12, 0x030ec023); // subu $24, $24, $14
+ write32(ctx, buf + 16, 0x03e07825); // move $15, $31
+ write32(ctx, buf + 20, 0x0018c0c2); // srl $24, $24, 3
} else {
- write32(buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
- write32(buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
- write32(buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
- write32(buf + 12, 0x031cc023); // subu $24, $24, $28
- write32(buf + 16, 0x03e07825); // move $15, $31
- write32(buf + 20, 0x0018c082); // srl $24, $24, 2
+ write32(ctx, buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
+ write32(ctx, buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
+ write32(ctx, buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
+ write32(ctx, buf + 12, 0x031cc023); // subu $24, $24, $28
+ write32(ctx, buf + 16, 0x03e07825); // move $15, $31
+ write32(ctx, buf + 20, 0x0018c082); // srl $24, $24, 2
}
uint32_t jalrInst = ctx.arg.zHazardplt ? 0x0320fc09 : 0x0320f809;
- write32(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
- write32(buf + 28, 0x2718fffe); // subu $24, $24, 2
+ write32(ctx, buf + 24, jalrInst); // jalr.hb $25 or jalr $25
+ write32(ctx, buf + 28, 0x2718fffe); // subu $24, $24, 2
uint64_t gotPlt = ctx.in.gotPlt->getVA();
writeValue(buf, gotPlt + 0x8000, 16, 16);
@@ -346,10 +346,10 @@ void MIPS<ELFT>::writePlt(uint8_t *buf, const Symbol &sym,
: (ctx.arg.zHazardplt ? 0x03200408 : 0x03200008);
uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
- write32(buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
- write32(buf + 4, loadInst); // l[wd] $25, %lo(.got.plt entry)($15)
- write32(buf + 8, jrInst); // jr $25 / jr.hb $25
- write32(buf + 12, addInst); // [d]addiu $24, $15, %lo(.got.plt entry)
+ write32(ctx, buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
+ write32(ctx, buf + 4, loadInst); // l[wd] $25, %lo(.got.plt entry)($15)
+ write32(ctx, buf + 8, jrInst); // jr $25 / jr.hb $25
+ write32(ctx, buf + 12, addInst); // [d]addiu $24, $15, %lo(.got.plt entry)
writeValue(buf, gotPltEntryAddr + 0x8000, 16, 16);
writeValue(buf + 4, gotPltEntryAddr, 16, 0);
writeValue(buf + 12, gotPltEntryAddr, 16, 0);
@@ -389,18 +389,18 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_MIPS_TLS_DTPREL32:
case R_MIPS_TLS_DTPMOD32:
case R_MIPS_TLS_TPREL32:
- return SignExtend64<32>(read32(buf));
+ return SignExtend64<32>(read32(ctx, buf));
case R_MIPS_26:
// FIXME (simon): If the relocation target symbol is not a PLT entry
// we should use another expression for calculation:
// ((A << 2) | (P & 0xf0000000)) >> 2
- return SignExtend64<28>(read32(buf) << 2);
+ return SignExtend64<28>(read32(ctx, buf) << 2);
case R_MIPS_CALL_HI16:
case R_MIPS_GOT16:
case R_MIPS_GOT_HI16:
case R_MIPS_HI16:
case R_MIPS_PCHI16:
- return SignExtend64<16>(read32(buf)) << 16;
+ return SignExtend64<16>(read32(ctx, buf)) << 16;
case R_MIPS_CALL16:
case R_MIPS_CALL_LO16:
case R_MIPS_GOT_LO16:
@@ -414,7 +414,7 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_MIPS_TLS_LDM:
case R_MIPS_TLS_TPREL_HI16:
case R_MIPS_TLS_TPREL_LO16:
- return SignExtend64<16>(read32(buf));
+ return SignExtend64<16>(read32(ctx, buf));
case R_MICROMIPS_GOT16:
case R_MICROMIPS_HI16:
return SignExtend64<16>(readShuffle<e>(buf)) << 16;
@@ -432,15 +432,15 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_MICROMIPS_GPREL7_S2:
return SignExtend64<9>(readShuffle<e>(buf) << 2);
case R_MIPS_PC16:
- return SignExtend64<18>(read32(buf) << 2);
+ return SignExtend64<18>(read32(ctx, buf) << 2);
case R_MIPS_PC19_S2:
- return SignExtend64<21>(read32(buf) << 2);
+ return SignExtend64<21>(read32(ctx, buf) << 2);
case R_MIPS_PC21_S2:
- return SignExtend64<23>(read32(buf) << 2);
+ return SignExtend64<23>(read32(ctx, buf) << 2);
case R_MIPS_PC26_S2:
- return SignExtend64<28>(read32(buf) << 2);
+ return SignExtend64<28>(read32(ctx, buf) << 2);
case R_MIPS_PC32:
- return SignExtend64<32>(read32(buf));
+ return SignExtend64<32>(read32(ctx, buf));
case R_MICROMIPS_26_S1:
return SignExtend64<27>(readShuffle<e>(buf) << 1);
case R_MICROMIPS_PC7_S1:
@@ -466,7 +466,7 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
case (R_MIPS_64 << 8) | R_MIPS_REL32:
return read64(buf);
case R_MIPS_COPY:
- return ctx.arg.is64 ? read64(buf) : read32(buf);
+ return ctx.arg.is64 ? read64(buf) : read32(ctx, buf);
case R_MIPS_NONE:
case R_MIPS_JUMP_SLOT:
case R_MIPS_JALR:
@@ -531,7 +531,7 @@ static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
switch (type) {
case R_MIPS_26: {
- uint32_t inst = read32(loc) >> 26;
+ uint32_t inst = read32(ctx, loc) >> 26;
if (inst == 0x3 || inst == 0x1d) { // JAL or JALX
writeValue(loc, 0x1d << 26, 32, 0);
return val;
@@ -591,7 +591,7 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
case R_MIPS_GPREL32:
case R_MIPS_TLS_DTPREL32:
case R_MIPS_TLS_TPREL32:
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_MIPS_64:
case R_MIPS_TLS_DTPREL64:
@@ -682,12 +682,12 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
// Replace jalr/jr instructions by bal/b if the target
// offset fits into the 18-bit range.
if (isInt<18>(val)) {
- switch (read32(loc)) {
+ switch (read32(ctx, loc)) {
case 0x0320f809: // jalr $25 => bal sym
- write32(loc, 0x04110000 | ((val >> 2) & 0xffff));
+ write32(ctx, loc, 0x04110000 | ((val >> 2) & 0xffff));
break;
case 0x03200008: // jr $25 => b sym
- write32(loc, 0x10000000 | ((val >> 2) & 0xffff));
+ write32(ctx, loc, 0x10000000 | ((val >> 2) & 0xffff));
break;
}
}
diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index fa1b2a6c39d494..79962d06e5553b 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -65,11 +65,11 @@ static uint16_t lo(uint32_t v) { return v; }
static uint16_t ha(uint32_t v) { return (v + 0x8000) >> 16; }
static uint32_t readFromHalf16(Ctx &ctx, const uint8_t *loc) {
- return read32(ctx.arg.isLE ? loc : loc - 2);
+ return read32(ctx, ctx.arg.isLE ? loc : loc - 2);
}
static void writeFromHalf16(Ctx &ctx, uint8_t *loc, uint32_t insn) {
- write32(ctx.arg.isLE ? loc : loc - 2, insn);
+ write32(ctx, ctx.arg.isLE ? loc : loc - 2, insn);
}
void elf::writePPC32GlinkSection(Ctx &ctx, uint8_t *buf, size_t numEntries) {
@@ -96,7 +96,7 @@ void elf::writePPC32GlinkSection(Ctx &ctx, uint8_t *buf, size_t numEntries) {
// Write N `b PLTresolve` first.
for (size_t i = 0; i != numEntries; ++i)
- write32(buf + 4 * i, 0x48000000 | 4 * (numEntries - i));
+ write32(ctx, buf + 4 * i, 0x48000000 | 4 * (numEntries - i));
buf += 4 * numEntries;
// Then write PLTresolve(), which has two forms: PIC and non-PIC. PLTresolve()
@@ -107,49 +107,53 @@ void elf::writePPC32GlinkSection(Ctx &ctx, uint8_t *buf, size_t numEntries) {
if (ctx.arg.isPic) {
uint32_t afterBcl = 4 * ctx.in.plt->getNumEntries() + 12;
uint32_t gotBcl = got + 4 - (glink + afterBcl);
- write32(buf + 0, 0x3d6b0000 | ha(afterBcl)); // addis r11,r11,1f-glink at ha
- write32(buf + 4, 0x7c0802a6); // mflr r0
- write32(buf + 8, 0x429f0005); // bcl 20,30,.+4
- write32(buf + 12, 0x396b0000 | lo(afterBcl)); // 1: addi r11,r11,1b-glink at l
- write32(buf + 16, 0x7d8802a6); // mflr r12
- write32(buf + 20, 0x7c0803a6); // mtlr r0
- write32(buf + 24, 0x7d6c5850); // sub r11,r11,r12
- write32(buf + 28, 0x3d8c0000 | ha(gotBcl)); // addis 12,12,GOT+4-1b at ha
+ write32(ctx, buf + 0,
+ 0x3d6b0000 | ha(afterBcl)); // addis r11,r11,1f-glink at ha
+ write32(ctx, buf + 4, 0x7c0802a6); // mflr r0
+ write32(ctx, buf + 8, 0x429f0005); // bcl 20,30,.+4
+ write32(ctx, buf + 12,
+ 0x396b0000 | lo(afterBcl)); // 1: addi r11,r11,1b-glink at l
+ write32(ctx, buf + 16, 0x7d8802a6); // mflr r12
+ write32(ctx, buf + 20, 0x7c0803a6); // mtlr r0
+ write32(ctx, buf + 24, 0x7d6c5850); // sub r11,r11,r12
+ write32(ctx, buf + 28, 0x3d8c0000 | ha(gotBcl)); // addis 12,12,GOT+4-1b at ha
if (ha(gotBcl) == ha(gotBcl + 4)) {
- write32(buf + 32, 0x800c0000 | lo(gotBcl)); // lwz r0,r12,GOT+4-1b at l(r12)
- write32(buf + 36,
- 0x818c0000 | lo(gotBcl + 4)); // lwz r12,r12,GOT+8-1b at l(r12)
+ write32(ctx, buf + 32,
+ 0x800c0000 | lo(gotBcl)); // lwz r0,r12,GOT+4-1b at l(r12)
+ write32(ctx, buf + 36,
+ 0x818c0000 | lo(gotBcl + 4)); // lwz r12,r12,GOT+8-1b at l(r12)
} else {
- write32(buf + 32, 0x840c0000 | lo(gotBcl)); // lwzu r0,r12,GOT+4-1b at l(r12)
- write32(buf + 36, 0x818c0000 | 4); // lwz r12,r12,4(r12)
+ write32(ctx, buf + 32,
+ 0x840c0000 | lo(gotBcl)); // lwzu r0,r12,GOT+4-1b at l(r12)
+ write32(ctx, buf + 36, 0x818c0000 | 4); // lwz r12,r12,4(r12)
}
- write32(buf + 40, 0x7c0903a6); // mtctr 0
- write32(buf + 44, 0x7c0b5a14); // add r0,11,11
- write32(buf + 48, 0x7d605a14); // add r11,0,11
- write32(buf + 52, 0x4e800420); // bctr
+ write32(ctx, buf + 40, 0x7c0903a6); // mtctr 0
+ write32(ctx, buf + 44, 0x7c0b5a14); // add r0,11,11
+ write32(ctx, buf + 48, 0x7d605a14); // add r11,0,11
+ write32(ctx, buf + 52, 0x4e800420); // bctr
buf += 56;
} else {
- write32(buf + 0, 0x3d800000 | ha(got + 4)); // lis r12,GOT+4 at ha
- write32(buf + 4, 0x3d6b0000 | ha(-glink)); // addis r11,r11,-glink at ha
+ write32(ctx, buf + 0, 0x3d800000 | ha(got + 4)); // lis r12,GOT+4 at ha
+ write32(ctx, buf + 4, 0x3d6b0000 | ha(-glink)); // addis r11,r11,-glink at ha
if (ha(got + 4) == ha(got + 8))
- write32(buf + 8, 0x800c0000 | lo(got + 4)); // lwz r0,GOT+4 at l(r12)
+ write32(ctx, buf + 8, 0x800c0000 | lo(got + 4)); // lwz r0,GOT+4 at l(r12)
else
- write32(buf + 8, 0x840c0000 | lo(got + 4)); // lwzu r0,GOT+4 at l(r12)
- write32(buf + 12, 0x396b0000 | lo(-glink)); // addi r11,r11,-glink at l
- write32(buf + 16, 0x7c0903a6); // mtctr r0
- write32(buf + 20, 0x7c0b5a14); // add r0,r11,r11
+ write32(ctx, buf + 8, 0x840c0000 | lo(got + 4)); // lwzu r0,GOT+4 at l(r12)
+ write32(ctx, buf + 12, 0x396b0000 | lo(-glink)); // addi r11,r11,-glink at l
+ write32(ctx, buf + 16, 0x7c0903a6); // mtctr r0
+ write32(ctx, buf + 20, 0x7c0b5a14); // add r0,r11,r11
if (ha(got + 4) == ha(got + 8))
- write32(buf + 24, 0x818c0000 | lo(got + 8)); // lwz r12,GOT+8 at l(r12)
+ write32(ctx, buf + 24, 0x818c0000 | lo(got + 8)); // lwz r12,GOT+8 at l(r12)
else
- write32(buf + 24, 0x818c0000 | 4); // lwz r12,4(r12)
- write32(buf + 28, 0x7d605a14); // add r11,r0,r11
- write32(buf + 32, 0x4e800420); // bctr
+ write32(ctx, buf + 24, 0x818c0000 | 4); // lwz r12,4(r12)
+ write32(ctx, buf + 28, 0x7d605a14); // add r11,r0,r11
+ write32(ctx, buf + 32, 0x4e800420); // bctr
buf += 36;
}
// Pad with nop. They should not be executed.
for (; buf < end; buf += 4)
- write32(buf, 0x60000000);
+ write32(ctx, buf, 0x60000000);
}
PPC::PPC(Ctx &ctx) : TargetInfo(ctx) {
@@ -174,7 +178,7 @@ PPC::PPC(Ctx &ctx) : TargetInfo(ctx) {
defaultMaxPageSize = 65536;
defaultImageBase = 0x10000000;
- write32(trapInstr.data(), 0x7fe00008);
+ write32(ctx, trapInstr.data(), 0x7fe00008);
}
void PPC::writeIplt(uint8_t *buf, const Symbol &sym,
@@ -188,12 +192,12 @@ void PPC::writeGotHeader(uint8_t *buf) const {
// _GLOBAL_OFFSET_TABLE_[0] = _DYNAMIC
// glibc stores _dl_runtime_resolve in _GLOBAL_OFFSET_TABLE_[1],
// link_map in _GLOBAL_OFFSET_TABLE_[2].
- write32(buf, ctx.mainPart->dynamic->getVA());
+ write32(ctx, buf, ctx.mainPart->dynamic->getVA());
}
void PPC::writeGotPlt(uint8_t *buf, const Symbol &s) const {
// Address of the symbol resolver stub in .glink .
- write32(buf,
+ write32(ctx, buf,
ctx.in.plt->getVA() + ctx.in.plt->headerSize + 4 * s.getPltIdx(ctx));
}
@@ -290,7 +294,7 @@ int64_t PPC::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_PPC_DTPMOD32:
case R_PPC_DTPREL32:
case R_PPC_TPREL32:
- return SignExtend64<32>(read32(buf));
+ return SignExtend64<32>(read32(ctx, buf));
default:
internalLinkerError(getErrorLoc(ctx, buf),
"cannot read addend for relocation " + toString(type));
@@ -361,13 +365,13 @@ void PPC::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
break;
case R_PPC_ADDR32:
case R_PPC_REL32:
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_PPC_REL14: {
uint32_t mask = 0x0000FFFC;
checkInt(loc, val, 16, rel);
checkAlignment(loc, val, 4, rel);
- write32(loc, (read32(loc) & ~mask) | (val & mask));
+ write32(ctx, loc, (read32(ctx, loc) & ~mask) | (val & mask));
break;
}
case R_PPC_ADDR24:
@@ -377,7 +381,7 @@ void PPC::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
uint32_t mask = 0x03FFFFFC;
checkInt(loc, val, 26, rel);
checkAlignment(loc, val, 4, rel);
- write32(loc, (read32(loc) & ~mask) | (val & mask));
+ write32(ctx, loc, (read32(ctx, loc) & ~mask) | (val & mask));
break;
}
default:
@@ -419,7 +423,7 @@ void PPC::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
}
case R_PPC_TLSGD:
// bl __tls_get_addr(x at tldgd) --> add r3, r3, r2
- write32(loc, 0x7c631214);
+ write32(ctx, loc, 0x7c631214);
break;
default:
llvm_unreachable("unsupported relocation for TLS GD to IE relaxation");
@@ -435,7 +439,7 @@ void PPC::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
break;
case R_PPC_TLSGD:
// bl __tls_get_addr(x at tldgd) --> add r3, r3, x at tprel@l
- write32(loc, 0x38630000 | lo(val));
+ write32(ctx, loc, 0x38630000 | lo(val));
break;
default:
llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
@@ -453,7 +457,7 @@ void PPC::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
// r3+x at dtprel computes r3+x-0x8000, while we want it to compute r3+x at tprel
// = r3+x-0x7000, so add 4096 to r3.
// bl __tls_get_addr(x at tlsld) --> addi r3, r3, 4096
- write32(loc, 0x38631000);
+ write32(ctx, loc, 0x38631000);
break;
case R_PPC_DTPREL16:
case R_PPC_DTPREL16_HA:
@@ -476,18 +480,18 @@ void PPC::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
break;
}
case R_PPC_TLS: {
- uint32_t insn = read32(loc);
+ uint32_t insn = read32(ctx, loc);
if (insn >> 26 != 31)
error("unrecognized instruction for IE to LE R_PPC_TLS");
// addi rT, rT, x at tls --> addi rT, rT, x at tprel@l
- unsigned secondaryOp = (read32(loc) & 0x000007fe) >> 1;
+ unsigned secondaryOp = (read32(ctx, loc) & 0x000007fe) >> 1;
uint32_t dFormOp = getPPCDFormOp(secondaryOp);
if (dFormOp == 0) { // Expecting a DS-Form instruction.
dFormOp = getPPCDSFormOp(secondaryOp);
if (dFormOp == 0)
error("unrecognized instruction for IE to LE R_PPC_TLS");
}
- write32(loc, (dFormOp | (insn & 0x03ff0000) | lo(val)));
+ write32(ctx, loc, (dFormOp | (insn & 0x03ff0000) | lo(val)));
break;
}
default:
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index 6948ae0263aab9..647954106322e8 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -275,10 +275,10 @@ static void writeSequence(Ctx &ctx, MutableArrayRef<uint32_t> buf,
format("%s%d", prefix, r).snprint(name, sizeof(name));
if (addOptional(ctx, name, 4 * (r - from), defined) && defined.size() == 1)
first = r - from;
- write32(ptr++, firstInsn + 0x200008 * (r - from));
+ write32(ctx, ptr++, firstInsn + 0x200008 * (r - from));
}
for (uint32_t insn : tail)
- write32(ptr++, insn);
+ write32(ctx, ptr++, insn);
assert(ptr == &*buf.end());
if (defined.empty())
@@ -566,11 +566,11 @@ static int64_t getTotalDisp(uint64_t prefixedInsn, uint32_t accessInsn) {
// little-endian it is pointing to the start of the word. These 2 helpers are to
// simplify reading and writing in that context.
static void writeFromHalf16(Ctx &ctx, uint8_t *loc, uint32_t insn) {
- write32(ctx.arg.isLE ? loc : loc - 2, insn);
+ write32(ctx, ctx.arg.isLE ? loc : loc - 2, insn);
}
static uint32_t readFromHalf16(Ctx &ctx, const uint8_t *loc) {
- return read32(ctx.arg.isLE ? loc : loc - 2);
+ return read32(ctx, ctx.arg.isLE ? loc : loc - 2);
}
static uint64_t readPrefixedInst(Ctx &ctx, const uint8_t *loc) {
@@ -613,7 +613,7 @@ PPC64::PPC64(Ctx &ctx) : TargetInfo(ctx) {
// use 0x10000000 as the starting address.
defaultImageBase = 0x10000000;
- write32(trapInstr.data(), 0x7fe00008);
+ write32(ctx, trapInstr.data(), 0x7fe00008);
}
int PPC64::getTlsGdRelaxSkip(RelType type) const {
@@ -684,7 +684,7 @@ void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
// be relaxed. The eligibility for the relaxation needs to be determined
// on that relocation since this one does not relocate a symbol.
uint64_t insn = readPrefixedInst(ctx, loc);
- uint32_t accessInsn = read32(loc + rel.addend);
+ uint32_t accessInsn = read32(ctx, loc + rel.addend);
uint64_t pcRelInsn = getPCRelativeForm(accessInsn);
// This error is not necessary for correctness but is emitted for now
@@ -705,7 +705,7 @@ void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
writePrefixedInst(ctx, loc,
pcRelInsn | ((totalDisp & 0x3ffff0000) << 16) |
(totalDisp & 0xffff));
- write32(loc + rel.addend, NOP); // nop accessInsn.
+ write32(ctx, loc + rel.addend, NOP); // nop accessInsn.
break;
}
default:
@@ -757,15 +757,15 @@ void PPC64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
// addi r3, r3, x at tprel@l
const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
if (locAsInt % 4 == 0) {
- write32(loc, NOP); // nop
- write32(loc + 4, 0x38630000); // addi r3, r3
+ write32(ctx, loc, NOP); // nop
+ write32(ctx, loc + 4, 0x38630000); // addi r3, r3
// Since we are relocating a half16 type relocation and Loc + 4 points to
// the start of an instruction we need to advance the buffer by an extra
// 2 bytes on BE.
relocateNoSym(loc + 4 + (ctx.arg.ekind == ELF64BEKind ? 2 : 0),
R_PPC64_TPREL16_LO, val);
} else if (locAsInt % 4 == 1) {
- write32(loc - 1, NOP);
+ write32(ctx, loc - 1, NOP);
} else {
errorOrWarn("R_PPC64_TLSGD has unexpected byte alignment");
}
@@ -818,10 +818,10 @@ void PPC64::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
// addi r3, r3, 4096
const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
if (locAsInt % 4 == 0) {
- write32(loc, NOP);
- write32(loc + 4, 0x38631000); // addi r3, r3, 4096
+ write32(ctx, loc, NOP);
+ write32(ctx, loc + 4, 0x38631000); // addi r3, r3, 4096
} else if (locAsInt % 4 == 1) {
- write32(loc - 1, NOP);
+ write32(ctx, loc - 1, NOP);
} else {
errorOrWarn("R_PPC64_TLSLD has unexpected byte alignment");
}
@@ -912,12 +912,12 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
unsigned offset = (ctx.arg.ekind == ELF64BEKind) ? 2 : 0;
switch (rel.type) {
case R_PPC64_GOT_TPREL16_HA:
- write32(loc - offset, NOP);
+ write32(ctx, loc - offset, NOP);
break;
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_DS: {
- uint32_t regNo = read32(loc - offset) & 0x03E00000; // bits 6-10
- write32(loc - offset, 0x3C0D0000 | regNo); // addis RegNo, r13
+ uint32_t regNo = read32(ctx, loc - offset) & 0x03e00000; // bits 6-10
+ write32(ctx, loc - offset, 0x3c0d0000 | regNo); // addis RegNo, r13
relocateNoSym(loc, R_PPC64_TPREL16_HA, val);
break;
}
@@ -931,10 +931,10 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
case R_PPC64_TLS: {
const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
if (locAsInt % 4 == 0) {
- uint32_t primaryOp = getPrimaryOpCode(read32(loc));
+ uint32_t primaryOp = getPrimaryOpCode(read32(ctx, loc));
if (primaryOp != 31)
error("unrecognized instruction for IE to LE R_PPC64_TLS");
- uint32_t secondaryOp = (read32(loc) & 0x000007FE) >> 1; // bits 21-30
+ uint32_t secondaryOp = (read32(ctx, loc) & 0x000007fe) >> 1; // bits 21-30
uint32_t dFormOp = getPPCDFormOp(secondaryOp);
uint32_t finalReloc;
if (dFormOp == 0) { // Expecting a DS-Form instruction.
@@ -944,13 +944,13 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
finalReloc = R_PPC64_TPREL16_LO_DS;
} else
finalReloc = R_PPC64_TPREL16_LO;
- write32(loc, dFormOp | (read32(loc) & 0x03ff0000));
+ write32(ctx, loc, dFormOp | (read32(ctx, loc) & 0x03ff0000));
relocateNoSym(loc + offset, finalReloc, val);
} else if (locAsInt % 4 == 1) {
// If the offset is not 4 byte aligned then we have a PCRel type reloc.
// This version of the relocation is offset by one byte from the
// instruction it references.
- uint32_t tlsInstr = read32(loc - 1);
+ uint32_t tlsInstr = read32(ctx, loc - 1);
uint32_t primaryOp = getPrimaryOpCode(tlsInstr);
if (primaryOp != 31)
errorOrWarn("unrecognized instruction for IE to LE R_PPC64_TLS");
@@ -963,10 +963,11 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
uint32_t rt = (tlsInstr & 0x03E00000) >> 21; // bits 6-10
uint32_t ra = (tlsInstr & 0x001F0000) >> 16; // bits 11-15
if (ra == rt) {
- write32(loc - 1, NOP);
+ write32(ctx, loc - 1, NOP);
} else {
// mr rt, ra
- write32(loc - 1, 0x7C000378 | (rt << 16) | (ra << 21) | (ra << 11));
+ write32(ctx, loc - 1,
+ 0x7C000378 | (rt << 16) | (ra << 21) | (ra << 11));
}
} else {
uint32_t dFormOp = getPPCDFormOp(secondaryOp);
@@ -975,7 +976,7 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
if (dFormOp == 0)
errorOrWarn("unrecognized instruction for IE to LE R_PPC64_TLS");
}
- write32(loc - 1, (dFormOp | (tlsInstr & 0x03ff0000)));
+ write32(ctx, loc - 1, (dFormOp | (tlsInstr & 0x03ff0000)));
}
} else {
errorOrWarn("R_PPC64_TLS must be either 4 byte aligned or one byte "
@@ -1116,7 +1117,7 @@ int64_t PPC64::getImplicitAddend(const uint8_t *buf, RelType type) const {
case R_PPC64_JMP_SLOT:
return 0;
case R_PPC64_REL32:
- return SignExtend64<32>(read32(buf));
+ return SignExtend64<32>(read32(ctx, buf));
case R_PPC64_ADDR64:
case R_PPC64_REL64:
case R_PPC64_RELATIVE:
@@ -1138,19 +1139,19 @@ void PPC64::writeGotHeader(uint8_t *buf) const {
void PPC64::writePltHeader(uint8_t *buf) const {
// The generic resolver stub goes first.
- write32(buf + 0, 0x7c0802a6); // mflr r0
- write32(buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8>
- write32(buf + 8, 0x7d6802a6); // mflr r11
- write32(buf + 12, 0x7c0803a6); // mtlr r0
- write32(buf + 16, 0x7d8b6050); // subf r12, r11, r12
- write32(buf + 20, 0x380cffcc); // subi r0,r12,52
- write32(buf + 24, 0x7800f082); // srdi r0,r0,62,2
- write32(buf + 28, 0xe98b002c); // ld r12,44(r11)
- write32(buf + 32, 0x7d6c5a14); // add r11,r12,r11
- write32(buf + 36, 0xe98b0000); // ld r12,0(r11)
- write32(buf + 40, 0xe96b0008); // ld r11,8(r11)
- write32(buf + 44, 0x7d8903a6); // mtctr r12
- write32(buf + 48, 0x4e800420); // bctr
+ write32(ctx, buf + 0, 0x7c0802a6); // mflr r0
+ write32(ctx, buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8>
+ write32(ctx, buf + 8, 0x7d6802a6); // mflr r11
+ write32(ctx, buf + 12, 0x7c0803a6); // mtlr r0
+ write32(ctx, buf + 16, 0x7d8b6050); // subf r12, r11, r12
+ write32(ctx, buf + 20, 0x380cffcc); // subi r0,r12,52
+ write32(ctx, buf + 24, 0x7800f082); // srdi r0,r0,62,2
+ write32(ctx, buf + 28, 0xe98b002c); // ld r12,44(r11)
+ write32(ctx, buf + 32, 0x7d6c5a14); // add r11,r12,r11
+ write32(ctx, buf + 36, 0xe98b0000); // ld r12,0(r11)
+ write32(ctx, buf + 40, 0xe96b0008); // ld r11,8(r11)
+ write32(ctx, buf + 44, 0x7d8903a6); // mtctr r12
+ write32(ctx, buf + 48, 0x4e800420); // bctr
// The 'bcl' instruction will set the link register to the address of the
// following instruction ('mflr r11'). Here we store the offset from that
@@ -1163,7 +1164,7 @@ void PPC64::writePlt(uint8_t *buf, const Symbol &sym,
uint64_t /*pltEntryAddr*/) const {
int32_t offset = pltHeaderSize + sym.getPltIdx(ctx) * pltEntrySize;
// bl __glink_PLTresolve
- write32(buf, 0x48000000 | ((-offset) & 0x03FFFFFc));
+ write32(ctx, buf, 0x48000000 | ((-offset) & 0x03fffffc));
}
void PPC64::writeIplt(uint8_t *buf, const Symbol &sym,
@@ -1277,7 +1278,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
break;
case R_PPC64_ADDR32:
checkIntUInt(loc, val, 32, rel);
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_PPC64_ADDR16_DS:
case R_PPC64_TPREL16_DS: {
@@ -1366,7 +1367,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
break;
case R_PPC64_REL32:
checkInt(loc, val, 32, rel);
- write32(loc, val);
+ write32(ctx, loc, val);
break;
case R_PPC64_ADDR64:
case R_PPC64_REL64:
@@ -1377,7 +1378,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
uint32_t mask = 0x0000FFFC;
checkInt(loc, val, 16, rel);
checkAlignment(loc, val, 4, rel);
- write32(loc, (read32(loc) & ~mask) | (val & mask));
+ write32(ctx, loc, (read32(ctx, loc) & ~mask) | (val & mask));
break;
}
case R_PPC64_REL24:
@@ -1385,7 +1386,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
uint32_t mask = 0x03FFFFFC;
checkInt(loc, val, 26, rel);
checkAlignment(loc, val, 4, rel);
- write32(loc, (read32(loc) & ~mask) | (val & mask));
+ write32(ctx, loc, (read32(ctx, loc) & ~mask) | (val & mask));
break;
}
case R_PPC64_DTPREL64:
@@ -1544,11 +1545,11 @@ void PPC64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
// add r3, r3, r13
const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
if (locAsInt % 4 == 0) {
- write32(loc, NOP); // bl __tls_get_addr(sym at tlsgd) --> nop
- write32(loc + 4, 0x7c636A14); // nop --> add r3, r3, r13
+ write32(ctx, loc, NOP); // bl __tls_get_addr(sym at tlsgd) --> nop
+ write32(ctx, loc + 4, 0x7c636a14); // nop --> add r3, r3, r13
} else if (locAsInt % 4 == 1) {
// bl __tls_get_addr(sym at tlsgd) --> add r3, r3, r13
- write32(loc - 1, 0x7c636a14);
+ write32(ctx, loc - 1, 0x7c636a14);
} else {
errorOrWarn("R_PPC64_TLSGD has unexpected byte alignment");
}
@@ -1598,7 +1599,7 @@ void PPC64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
// If this is a call to __tls_get_addr, it may be part of a TLS
// sequence that has been relaxed and turned into a nop. In this
// case, we don't want to handle it as a call.
- if (read32(loc) == 0x60000000) // nop
+ if (read32(ctx, loc) == 0x60000000) // nop
break;
// Patch a nop (0x60000000) to a ld.
@@ -1608,7 +1609,7 @@ void PPC64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
// wrong in the common case where the function is not preempted at
// runtime. Just ignore.
if ((rel.offset + 8 > sec.content().size() ||
- read32(loc + 4) != 0x60000000) &&
+ read32(ctx, loc + 4) != 0x60000000) &&
rel.sym->file != sec.file) {
// Use substr(6) to remove the "__plt_" prefix.
errorOrWarn(getErrorLoc(ctx, loc) + "call to " +
@@ -1616,7 +1617,7 @@ void PPC64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
" lacks nop, can't restore toc");
break;
}
- write32(loc + 4, 0xe8410018); // ld %r2, 24(%r1)
+ write32(ctx, loc + 4, 0xe8410018); // ld %r2, 24(%r1)
}
relocate(loc, rel, val);
break;
@@ -1682,14 +1683,14 @@ bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
return false;
// First instruction must be `ld r0, -0x7000-64(r13)`
- if (read32(loc) != 0xe80d8fc0)
+ if (read32(ctx, loc) != 0xe80d8fc0)
return false;
int16_t hiImm = 0;
int16_t loImm = 0;
// First instruction can be either an addis if the frame size is larger then
// 32K, or an addi if the size is less then 32K.
- int32_t firstInstr = read32(loc + 4);
+ int32_t firstInstr = read32(ctx, loc + 4);
if (getPrimaryOpCode(firstInstr) == 15) {
hiImm = firstInstr & 0xFFFF;
} else if (getPrimaryOpCode(firstInstr) == 14) {
@@ -1700,7 +1701,7 @@ bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
// Second instruction is either an addi or a nop. If the first instruction was
// an addi then LoImm is set and the second instruction must be a nop.
- uint32_t secondInstr = read32(loc + 8);
+ uint32_t secondInstr = read32(ctx, loc + 8);
if (!loImm && getPrimaryOpCode(secondInstr) == 14) {
loImm = secondInstr & 0xFFFF;
} else if (secondInstr != NOP) {
@@ -1734,14 +1735,14 @@ bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
loImm = adjustedStackFrameSize & 0xFFFF;
hiImm = (adjustedStackFrameSize + 0x8000) >> 16;
if (hiImm) {
- write32(loc + 4, 0x3D810000 | (uint16_t)hiImm);
+ write32(ctx, loc + 4, 0x3d810000 | (uint16_t)hiImm);
// If the low immediate is zero the second instruction will be a nop.
secondInstr = loImm ? 0x398C0000 | (uint16_t)loImm : NOP;
- write32(loc + 8, secondInstr);
+ write32(ctx, loc + 8, secondInstr);
} else {
// addi r12, r1, imm
- write32(loc + 4, (0x39810000) | (uint16_t)loImm);
- write32(loc + 8, NOP);
+ write32(ctx, loc + 4, (0x39810000) | (uint16_t)loImm);
+ write32(ctx, loc + 8, NOP);
}
return true;
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index d65467f10378be..cbbda83c7f848e 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -1282,14 +1282,14 @@ void RISCVAttributesSection::writeTo(uint8_t *buf) {
const size_t size = getSize();
uint8_t *const end = buf + size;
*buf = ELFAttrs::Format_Version;
- write32(buf + 1, size - 1);
+ write32(ctx, buf + 1, size - 1);
buf += 5;
memcpy(buf, vendor.data(), vendor.size());
buf += vendor.size() + 1;
*buf = ELFAttrs::File;
- write32(buf + 1, end - buf);
+ write32(ctx, buf + 1, end - buf);
buf += 5;
for (auto &attr : intAttr) {
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index d6abb6184f3619..0b9daef951b216 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -464,7 +464,7 @@ static void writeInt(uint8_t *buf, uint64_t data, uint64_t size) {
else if (size == 2)
write16(buf, data);
else if (size == 4)
- write32(buf, data);
+ write32(ctx, buf, data);
else if (size == 8)
write64(buf, data);
else
@@ -512,7 +512,7 @@ void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
// Write leading padding.
ArrayRef<InputSection *> sections = getInputSections(*this, storage);
std::array<uint8_t, 4> filler = getFiller(ctx);
- bool nonZeroFiller = read32(filler.data()) != 0;
+ bool nonZeroFiller = read32(ctx, filler.data()) != 0;
if (nonZeroFiller)
fill(buf, sections.empty() ? size : sections[0]->outSecOff, filler);
@@ -605,7 +605,7 @@ static void finalizeShtGroup(Ctx &ctx, OutputSection *os,
DenseSet<uint32_t> seen;
ArrayRef<InputSectionBase *> sections = section->file->getSections();
for (const uint32_t &idx : section->getDataAs<uint32_t>().slice(1))
- if (OutputSection *osec = sections[read32(&idx)]->getOutputSection())
+ if (OutputSection *osec = sections[read32(ctx, &idx)]->getOutputSection())
seen.insert(osec->sectionIndex);
os->size = (1 + seen.size()) * sizeof(uint32_t);
}
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index b44b87f8276e94..01a7e9a7866c36 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -60,14 +60,14 @@ 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(buf);
+ return ctx.arg.is64 ? read64(buf) : read32(ctx, buf);
}
static void writeUint(Ctx &ctx, uint8_t *buf, uint64_t val) {
if (ctx.arg.is64)
write64(buf, val);
else
- write32(buf, val);
+ write32(ctx, buf, val);
}
// Returns an LLD version string.
@@ -323,9 +323,9 @@ GnuPropertySection::GnuPropertySection(Ctx &ctx)
ctx.arg.wordsize, ".note.gnu.property") {}
void GnuPropertySection::writeTo(uint8_t *buf) {
- write32(buf, 4); // Name size
- write32(buf + 4, getSize() - 16); // Content size
- write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
+ write32(ctx, buf, 4); // Name size
+ write32(ctx, buf + 4, getSize() - 16); // Content size
+ write32(ctx, buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
memcpy(buf + 12, "GNU", 4); // Name string
uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
@@ -334,17 +334,17 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
unsigned offset = 16;
if (ctx.arg.andFeatures != 0) {
- write32(buf + offset + 0, featureAndType); // Feature type
- write32(buf + offset + 4, 4); // Feature size
- write32(buf + offset + 8, ctx.arg.andFeatures); // Feature flags
+ write32(ctx, buf + offset + 0, featureAndType); // Feature type
+ write32(ctx, buf + offset + 4, 4); // Feature size
+ write32(ctx, buf + offset + 8, ctx.arg.andFeatures); // Feature flags
if (ctx.arg.is64)
- write32(buf + offset + 12, 0); // Padding
+ write32(ctx, buf + offset + 12, 0); // Padding
offset += 16;
}
if (!ctx.aarch64PauthAbiCoreInfo.empty()) {
- write32(buf + offset + 0, GNU_PROPERTY_AARCH64_FEATURE_PAUTH);
- write32(buf + offset + 4, ctx.aarch64PauthAbiCoreInfo.size());
+ write32(ctx, buf + offset + 0, GNU_PROPERTY_AARCH64_FEATURE_PAUTH);
+ write32(ctx, buf + offset + 4, ctx.aarch64PauthAbiCoreInfo.size());
memcpy(buf + offset + 8, ctx.aarch64PauthAbiCoreInfo.data(),
ctx.aarch64PauthAbiCoreInfo.size());
}
@@ -365,9 +365,9 @@ BuildIdSection::BuildIdSection(Ctx &ctx)
hashSize(getHashSize(ctx)) {}
void BuildIdSection::writeTo(uint8_t *buf) {
- write32(buf, 4); // Name size
- write32(buf + 4, hashSize); // Content size
- write32(buf + 8, NT_GNU_BUILD_ID); // Type
+ write32(ctx, buf, 4); // Name size
+ write32(ctx, buf + 4, hashSize); // Content size
+ write32(ctx, buf + 8, NT_GNU_BUILD_ID); // Type
memcpy(buf + 12, "GNU", 4); // Name string
hashBuf = buf + 16;
}
@@ -509,7 +509,7 @@ void EhFrameSection::iterateFDEWithLSDA(
static void writeCieFde(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(buf, d.size() - 4);
+ write32(ctx, buf, d.size() - 4);
}
void EhFrameSection::finalizeContents() {
@@ -600,9 +600,9 @@ static uint64_t readFdeAddr(Ctx &ctx, uint8_t *buf, int size) {
case DW_EH_PE_sdata2:
return (int16_t)read16(buf);
case DW_EH_PE_udata4:
- return read32(buf);
+ return read32(ctx, buf);
case DW_EH_PE_sdata4:
- return (int32_t)read32(buf);
+ return (int32_t)read32(ctx, buf);
case DW_EH_PE_udata8:
case DW_EH_PE_sdata8:
return read64(buf);
@@ -640,7 +640,7 @@ void EhFrameSection::writeTo(uint8_t *buf) {
// FDE's second word should have the offset to an associated CIE.
// Write it.
- write32(buf + off + 4, off + 4 - cieOffset);
+ write32(ctx, buf + off + 4, off + 4 - cieOffset);
}
}
@@ -2355,7 +2355,7 @@ void SymtabShndxSection::writeTo(uint8_t *buf) {
for (const SymbolTableEntry &entry : ctx.in.symTab->getSymbols()) {
if (!getCommonSec(relocatable, entry.sym) &&
getSymSectionIndex(entry.sym) == SHN_XINDEX)
- write32(buf, entry.sym->getOutputSection()->sectionIndex);
+ write32(ctx, buf, entry.sym->getOutputSection()->sectionIndex);
buf += 4;
}
}
@@ -2436,10 +2436,11 @@ void GnuHashTableSection::finalizeContents() {
void GnuHashTableSection::writeTo(uint8_t *buf) {
// Write a header.
- write32(buf, nBuckets);
- write32(buf + 4, getPartition().dynSymTab->getNumSymbols() - symbols.size());
- write32(buf + 8, maskWords);
- write32(buf + 12, Shift2);
+ write32(ctx, buf, nBuckets);
+ write32(ctx, buf + 4,
+ getPartition().dynSymTab->getNumSymbols() - symbols.size());
+ write32(ctx, buf + 8, maskWords);
+ write32(ctx, buf + 12, Shift2);
buf += 16;
// Write the 2-bit bloom filter.
@@ -2466,13 +2467,13 @@ void GnuHashTableSection::writeTo(uint8_t *buf) {
uint32_t hash = i->hash;
bool isLastInChain = (i + 1) == e || i->bucketIdx != (i + 1)->bucketIdx;
hash = isLastInChain ? hash | 1 : hash & ~1;
- write32(values++, hash);
+ write32(ctx, values++, hash);
if (i->bucketIdx == oldBucket)
continue;
// Write a hash bucket. Hash buckets contain indices in the following hash
// value table.
- write32(buckets + i->bucketIdx,
+ write32(ctx, buckets + i->bucketIdx,
getPartition().dynSymTab->getSymbolIndex(*i->sym));
oldBucket = i->bucketIdx;
}
@@ -2544,8 +2545,8 @@ void HashTableSection::writeTo(uint8_t *buf) {
unsigned numSymbols = symTab->getNumSymbols();
uint32_t *p = reinterpret_cast<uint32_t *>(buf);
- write32(p++, numSymbols); // nbucket
- write32(p++, numSymbols); // nchain
+ write32(ctx, p++, numSymbols); // nbucket
+ write32(ctx, p++, numSymbols); // nchain
uint32_t *buckets = p;
uint32_t *chains = p + numSymbols;
@@ -2556,7 +2557,7 @@ void HashTableSection::writeTo(uint8_t *buf) {
unsigned i = sym->dynsymIndex;
uint32_t hash = hashSysV(name) % numSymbols;
chains[i] = buckets[hash];
- write32(buckets + hash, i);
+ write32(ctx, buckets + hash, i);
}
}
@@ -3672,14 +3673,14 @@ void EhFrameHeader::write() {
buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
buf[2] = DW_EH_PE_udata4;
buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
- write32(buf + 4,
+ write32(ctx, buf + 4,
getPartition().ehFrame->getParent()->addr - this->getVA() - 4);
- write32(buf + 8, fdes.size());
+ write32(ctx, buf + 8, fdes.size());
buf += 12;
for (FdeData &fde : fdes) {
- write32(buf, fde.pcRel);
- write32(buf + 4, fde.fdeVARel);
+ write32(ctx, buf, fde.pcRel);
+ write32(ctx, buf + 4, fde.fdeVARel);
buf += 8;
}
}
@@ -3728,13 +3729,13 @@ void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
write16(buf + 2, flags); // vd_flags
write16(buf + 4, index); // vd_ndx
write16(buf + 6, 1); // vd_cnt
- write32(buf + 8, hashSysV(name)); // vd_hash
- write32(buf + 12, 20); // vd_aux
- write32(buf + 16, 28); // vd_next
+ write32(ctx, buf + 8, hashSysV(name)); // vd_hash
+ write32(ctx, buf + 12, 20); // vd_aux
+ write32(ctx, buf + 16, 28); // vd_next
// Write a veraux.
- write32(buf + 20, nameOff); // vda_name
- write32(buf + 24, 0); // vda_next
+ write32(ctx, buf + 20, nameOff); // vda_name
+ write32(ctx, buf + 24, 0); // vda_next
}
void VersionDefinitionSection::writeTo(uint8_t *buf) {
@@ -3747,7 +3748,7 @@ void VersionDefinitionSection::writeTo(uint8_t *buf) {
}
// Need to terminate the last version definition.
- write32(buf + 16, 0); // vd_next
+ write32(ctx, buf + 16, 0); // vd_next
}
size_t VersionDefinitionSection::getSize() const {
@@ -4081,7 +4082,8 @@ static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
// nullptr then it will be a synthesized EXIDX_CANTUNWIND entry.
uint32_t prevUnwind = 1;
if (prev)
- prevUnwind = read32(prev->content().data() + prev->content().size() - 4);
+ prevUnwind =
+ read32(ctx, prev->content().data() + prev->content().size() - 4);
if (isExtabRef(prevUnwind))
return false;
@@ -4098,7 +4100,7 @@ static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
return prevUnwind == 1;
for (uint32_t offset = 4; offset < (uint32_t)cur->content().size(); offset +=8) {
- uint32_t curUnwind = read32(cur->content().data() + offset);
+ uint32_t curUnwind = read32(ctx, cur->content().data() + offset);
if (isExtabRef(curUnwind) || curUnwind != prevUnwind)
return false;
}
@@ -4211,8 +4213,8 @@ void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
if (InputSection *d = findExidxSection(isec)) {
for (int dataOffset = 0; dataOffset != (int)d->content().size();
dataOffset += 4)
- write32(buf + offset + dataOffset,
- read32(d->content().data() + dataOffset));
+ write32(ctx, buf + offset + dataOffset,
+ read32(ctx, d->content().data() + dataOffset));
// Recalculate outSecOff as finalizeAddressDependentContent()
// may have altered syntheticSection outSecOff.
d->outSecOff = offset + outSecOff;
@@ -4220,8 +4222,8 @@ void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
offset += d->getSize();
} else {
// A Linker generated CANTUNWIND section.
- write32(buf + offset + 0, 0x0);
- write32(buf + offset + 4, 0x1);
+ write32(ctx, buf + offset + 0, 0x0);
+ write32(ctx, buf + offset + 4, 0x1);
uint64_t s = isec->getVA();
uint64_t p = getVA() + offset;
ctx.target->relocateNoSym(buf + offset, R_ARM_PREL31, s - p);
@@ -4229,8 +4231,8 @@ void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
}
}
// Write Sentinel CANTUNWIND entry.
- write32(buf + offset + 0, 0x0);
- write32(buf + offset + 4, 0x1);
+ write32(ctx, buf + offset + 0, 0x0);
+ write32(ctx, buf + offset + 4, 0x1);
uint64_t s = sentinel->getVA(sentinel->getSize());
uint64_t p = getVA() + offset;
ctx.target->relocateNoSym(buf + offset, R_ARM_PREL31, s - p);
@@ -4480,14 +4482,15 @@ void PartitionIndexSection::finalizeContents() {
void PartitionIndexSection::writeTo(uint8_t *buf) {
uint64_t va = getVA();
for (size_t i = 1; i != ctx.partitions.size(); ++i) {
- write32(buf, ctx.mainPart->dynStrTab->getVA() +
- ctx.partitions[i].nameStrTab - va);
- write32(buf + 4, ctx.partitions[i].elfHeader->getVA() - (va + 4));
+ write32(ctx, buf,
+ ctx.mainPart->dynStrTab->getVA() + ctx.partitions[i].nameStrTab -
+ va);
+ write32(ctx, buf + 4, ctx.partitions[i].elfHeader->getVA() - (va + 4));
SyntheticSection *next = i == ctx.partitions.size() - 1
? ctx.in.partEnd.get()
: ctx.partitions[i + 1].elfHeader.get();
- write32(buf + 8, next->getVA() - ctx.partitions[i].elfHeader->getVA());
+ write32(ctx, buf + 8, next->getVA() - ctx.partitions[i].elfHeader->getVA());
va += 12;
buf += 12;
@@ -4553,9 +4556,9 @@ void MemtagAndroidNote::writeTo(uint8_t *buf) {
"Android 11 & 12 have an ABI that the note name is 8 bytes long. Keep it "
"that way for backwards compatibility.");
- write32(buf, sizeof(kMemtagAndroidNoteName));
- write32(buf + 4, sizeof(uint32_t));
- write32(buf + 8, ELF::NT_ANDROID_TYPE_MEMTAG);
+ write32(ctx, buf, sizeof(kMemtagAndroidNoteName));
+ write32(ctx, buf + 4, sizeof(uint32_t));
+ write32(ctx, buf + 8, ELF::NT_ANDROID_TYPE_MEMTAG);
memcpy(buf + 12, kMemtagAndroidNoteName, sizeof(kMemtagAndroidNoteName));
buf += 12 + alignTo(sizeof(kMemtagAndroidNoteName), 4);
@@ -4567,7 +4570,7 @@ void MemtagAndroidNote::writeTo(uint8_t *buf) {
// binary on Android 11 or 12 will result in a checkfail in the loader.
if (ctx.arg.androidMemtagStack)
value |= ELF::NT_MEMTAG_STACK;
- write32(buf, value); // note value
+ write32(ctx, buf, value); // note value
}
size_t MemtagAndroidNote::getSize() const {
@@ -4577,9 +4580,9 @@ size_t MemtagAndroidNote::getSize() const {
}
void PackageMetadataNote::writeTo(uint8_t *buf) {
- write32(buf, 4);
- write32(buf + 4, ctx.arg.packageMetadata.size() + 1);
- write32(buf + 8, FDO_PACKAGING_METADATA);
+ write32(ctx, buf, 4);
+ write32(ctx, buf + 4, ctx.arg.packageMetadata.size() + 1);
+ write32(ctx, buf + 8, FDO_PACKAGING_METADATA);
memcpy(buf + 12, "FDO", 4);
memcpy(buf + 16, ctx.arg.packageMetadata.data(),
ctx.arg.packageMetadata.size());
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 8a415c84cb5742..f94d3cf0552a84 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -296,7 +296,7 @@ inline uint16_t read16(const void *p) {
return llvm::support::endian::read16(p, ctx.arg.endianness);
}
-inline uint32_t read32(const void *p) {
+inline uint32_t read32(Ctx &ctx, const void *p) {
return llvm::support::endian::read32(p, ctx.arg.endianness);
}
@@ -308,7 +308,7 @@ inline void write16(void *p, uint16_t v) {
llvm::support::endian::write16(p, v, ctx.arg.endianness);
}
-inline void write32(void *p, uint32_t v) {
+inline void write32(Ctx &ctx, void *p, uint32_t v) {
llvm::support::endian::write32(p, v, ctx.arg.endianness);
}
diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index f239fda758b6fe..16066926c860d5 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -570,7 +570,7 @@ void AArch64Thunk::writeTo(uint8_t *buf) {
}
uint64_t s = getAArch64ThunkDestVA(ctx, destination, addend);
uint64_t p = getThunkTargetSym()->getVA();
- write32(buf, 0x14000000); // b S
+ write32(ctx, buf, 0x14000000); // b S
ctx.target->relocateNoSym(buf, R_AARCH64_CALL26, s - p);
}
@@ -647,7 +647,7 @@ void AArch64BTILandingPadThunk::writeTo(uint8_t *buf) {
writeLong(buf);
return;
}
- write32(buf, 0xd503245f); // BTI c
+ write32(ctx, buf, 0xd503245f); // BTI c
// Control falls through to target in following section.
}
@@ -672,8 +672,8 @@ bool AArch64BTILandingPadThunk::getMayUseShortThunk() {
void AArch64BTILandingPadThunk::writeLong(uint8_t *buf) {
uint64_t s = destination.getVA(addend);
uint64_t p = getThunkTargetSym()->getVA() + 4;
- write32(buf, 0xd503245f); // BTI c
- write32(buf + 4, 0x14000000); // B S
+ write32(ctx, buf, 0xd503245f); // BTI c
+ write32(ctx, buf + 4, 0x14000000); // B S
ctx.target->relocateNoSym(buf + 4, R_AARCH64_CALL26, s - p);
}
@@ -708,7 +708,7 @@ void ARMThunk::writeTo(uint8_t *buf) {
uint64_t s = getARMThunkDestVA(ctx, destination);
uint64_t p = getThunkTargetSym()->getVA();
int64_t offset = s - p - 8;
- write32(buf, 0xea000000); // b S
+ write32(ctx, buf, 0xea000000); // b S
ctx.target->relocateNoSym(buf, R_ARM_JUMP24, offset);
}
@@ -767,9 +767,9 @@ bool ThumbThunk::isCompatibleWith(const InputSection &isec,
}
void ARMV7ABSLongThunk::writeLong(uint8_t *buf) {
- write32(buf + 0, 0xe300c000); // movw ip,:lower16:S
- write32(buf + 4, 0xe340c000); // movt ip,:upper16:S
- write32(buf + 8, 0xe12fff1c); // bx ip
+ write32(ctx, buf + 0, 0xe300c000); // movw ip,:lower16:S
+ write32(ctx, buf + 4, 0xe340c000); // movt ip,:upper16:S
+ write32(ctx, buf + 8, 0xe12fff1c); // bx ip
uint64_t s = getARMThunkDestVA(ctx, destination);
ctx.target->relocateNoSym(buf, R_ARM_MOVW_ABS_NC, s);
ctx.target->relocateNoSym(buf + 4, R_ARM_MOVT_ABS, s);
@@ -799,10 +799,12 @@ void ThumbV7ABSLongThunk::addSymbols(ThunkSection &isec) {
}
void ARMV7PILongThunk::writeLong(uint8_t *buf) {
- write32(buf + 0, 0xe30fcff0); // P: movw ip,:lower16:S - (P + (L1-P) + 8)
- write32(buf + 4, 0xe340c000); // movt ip,:upper16:S - (P + (L1-P) + 8)
- write32(buf + 8, 0xe08cc00f); // L1: add ip, ip, pc
- write32(buf + 12, 0xe12fff1c); // bx ip
+ write32(ctx, buf + 0,
+ 0xe30fcff0); // P: movw ip,:lower16:S - (P + (L1-P) + 8)
+ write32(ctx, buf + 4,
+ 0xe340c000); // movt ip,:upper16:S - (P + (L1-P) + 8)
+ write32(ctx, buf + 8, 0xe08cc00f); // L1: add ip, ip, pc
+ write32(ctx, buf + 12, 0xe12fff1c); // bx ip
uint64_t s = getARMThunkDestVA(ctx, destination);
uint64_t p = getThunkTargetSym()->getVA();
int64_t offset = s - p - 16;
@@ -845,7 +847,7 @@ void ThumbV6MABSLongThunk::writeLong(uint8_t *buf) {
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
- write32(buf + 8, 0x00000000); // L1: .word S
+ write32(ctx, buf + 8, 0x00000000); // L1: .word S
uint64_t s = getARMThunkDestVA(ctx, destination);
ctx.target->relocateNoSym(buf + 8, R_ARM_ABS32, s);
}
@@ -896,7 +898,7 @@ void ThumbV6MPILongThunk::writeLong(uint8_t *buf) {
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
- write32(buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 4)
+ write32(ctx, buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 4)
uint64_t s = getARMThunkDestVA(ctx, destination);
uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
ctx.target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 12);
@@ -911,8 +913,8 @@ void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
}
void ARMV5LongLdrPcThunk::writeLong(uint8_t *buf) {
- write32(buf + 0, 0xe51ff004); // ldr pc, [pc,#-4] ; L1
- write32(buf + 4, 0x00000000); // L1: .word S
+ write32(ctx, buf + 0, 0xe51ff004); // ldr pc, [pc,#-4] ; L1
+ write32(ctx, buf + 4, 0x00000000); // L1: .word S
ctx.target->relocateNoSym(buf + 4, R_ARM_ABS32,
getARMThunkDestVA(ctx, destination));
}
@@ -926,9 +928,9 @@ void ARMV5LongLdrPcThunk::addSymbols(ThunkSection &isec) {
}
void ARMV4ABSLongBXThunk::writeLong(uint8_t *buf) {
- write32(buf + 0, 0xe59fc000); // ldr r12, [pc] ; L1
- write32(buf + 4, 0xe12fff1c); // bx r12
- write32(buf + 8, 0x00000000); // L1: .word S
+ write32(ctx, buf + 0, 0xe59fc000); // ldr r12, [pc] ; L1
+ write32(ctx, buf + 4, 0xe12fff1c); // bx r12
+ write32(ctx, buf + 8, 0x00000000); // L1: .word S
ctx.target->relocateNoSym(buf + 8, R_ARM_ABS32,
getARMThunkDestVA(ctx, destination));
}
@@ -944,8 +946,8 @@ 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
- write32(buf + 4, 0xe51ff004); // ldr pc, [pc, #-4] ; L1
- write32(buf + 8, 0x00000000); // L1: .word S
+ 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,
getARMThunkDestVA(ctx, destination));
}
@@ -962,9 +964,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
- write32(buf + 4, 0xe59fc000); // ldr r12, [pc] ; L1
- write32(buf + 8, 0xe12fff1c); // bx r12
- write32(buf + 12, 0x00000000); // L1: .word S
+ write32(ctx, buf + 4, 0xe59fc000); // ldr r12, [pc] ; L1
+ write32(ctx, buf + 8, 0xe12fff1c); // bx r12
+ write32(ctx, buf + 12, 0x00000000); // L1: .word S
ctx.target->relocateNoSym(buf + 12, R_ARM_ABS32,
getARMThunkDestVA(ctx, destination));
}
@@ -979,10 +981,10 @@ void ThumbV4ABSLongThunk::addSymbols(ThunkSection &isec) {
}
void ARMV4PILongBXThunk::writeLong(uint8_t *buf) {
- write32(buf + 0, 0xe59fc004); // P: ldr ip, [pc,#4] ; L2
- write32(buf + 4, 0xe08fc00c); // L1: add ip, pc, ip
- write32(buf + 8, 0xe12fff1c); // bx ip
- write32(buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
+ write32(ctx, buf + 0, 0xe59fc004); // P: ldr ip, [pc,#4] ; L2
+ write32(ctx, buf + 4, 0xe08fc00c); // L1: add ip, pc, ip
+ write32(ctx, buf + 8, 0xe12fff1c); // bx ip
+ write32(ctx, buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
uint64_t s = getARMThunkDestVA(ctx, destination);
uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
ctx.target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 12);
@@ -997,9 +999,9 @@ void ARMV4PILongBXThunk::addSymbols(ThunkSection &isec) {
}
void ARMV4PILongThunk::writeLong(uint8_t *buf) {
- write32(buf + 0, 0xe59fc000); // P: ldr ip, [pc] ; L2
- write32(buf + 4, 0xe08ff00c); // L1: add pc, pc, r12
- write32(buf + 8, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
+ write32(ctx, buf + 0, 0xe59fc000); // P: ldr ip, [pc] ; L2
+ write32(ctx, buf + 4, 0xe08ff00c); // L1: add pc, pc, r12
+ write32(ctx, buf + 8, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
uint64_t s = getARMThunkDestVA(ctx, destination);
uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
ctx.target->relocateNoSym(buf + 8, R_ARM_REL32, s - p - 12);
@@ -1016,9 +1018,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
- write32(buf + 4, 0xe59fc000); // ldr r12, [pc] ; L2
- write32(buf + 8, 0xe08cf00f); // L1: add pc, r12, pc
- write32(buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
+ 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)
uint64_t s = getARMThunkDestVA(ctx, destination);
uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
ctx.target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 16);
@@ -1036,10 +1038,10 @@ 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
- write32(buf + 4, 0xe59fc004); // ldr ip, [pc,#4] ; L2
- write32(buf + 8, 0xe08fc00c); // L1: add ip, pc, ip
- write32(buf + 12, 0xe12fff1c); // bx ip
- write32(buf + 16, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
+ 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
+ write32(ctx, buf + 16, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
uint64_t s = getARMThunkDestVA(ctx, destination);
uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
ctx.target->relocateNoSym(buf + 16, R_ARM_REL32, s - p - 16);
@@ -1056,7 +1058,7 @@ void ThumbV4PILongThunk::addSymbols(ThunkSection &isec) {
// Use the long jump which covers a range up to 8MiB.
void AVRThunk::writeTo(uint8_t *buf) {
- write32(buf, 0x940c); // jmp func
+ write32(ctx, buf, 0x940c); // jmp func
ctx.target->relocateNoSym(buf, R_AVR_CALL, destination.getVA());
}
@@ -1068,10 +1070,10 @@ void AVRThunk::addSymbols(ThunkSection &isec) {
// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
void MipsThunk::writeTo(uint8_t *buf) {
uint64_t s = destination.getVA();
- write32(buf, 0x3c190000); // lui $25, %hi(func)
- write32(buf + 4, 0x08000000 | (s >> 2)); // j func
- write32(buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
- write32(buf + 12, 0x00000000); // nop
+ write32(ctx, buf, 0x3c190000); // lui $25, %hi(func)
+ write32(ctx, buf + 4, 0x08000000 | (s >> 2)); // j func
+ write32(ctx, buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
+ write32(ctx, buf + 12, 0x00000000); // nop
ctx.target->relocateNoSym(buf, R_MIPS_HI16, s);
ctx.target->relocateNoSym(buf + 8, R_MIPS_LO16, s);
}
@@ -1139,10 +1141,10 @@ InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
void elf::writePPC32PltCallStub(Ctx &ctx, uint8_t *buf, uint64_t gotPltVA,
const InputFile *file, int64_t addend) {
if (!ctx.arg.isPic) {
- write32(buf + 0, 0x3d600000 | (gotPltVA + 0x8000) >> 16); // lis r11,ha
- write32(buf + 4, 0x816b0000 | (uint16_t)gotPltVA); // lwz r11,l(r11)
- write32(buf + 8, 0x7d6903a6); // mtctr r11
- write32(buf + 12, 0x4e800420); // bctr
+ write32(ctx, buf + 0, 0x3d600000 | (gotPltVA + 0x8000) >> 16); // lis r11,ha
+ write32(ctx, buf + 4, 0x816b0000 | (uint16_t)gotPltVA); // lwz r11,l(r11)
+ write32(ctx, buf + 8, 0x7d6903a6); // mtctr r11
+ write32(ctx, buf + 12, 0x4e800420); // bctr
return;
}
uint32_t offset;
@@ -1160,15 +1162,15 @@ void elf::writePPC32PltCallStub(Ctx &ctx, uint8_t *buf, uint64_t gotPltVA,
}
uint16_t ha = (offset + 0x8000) >> 16, l = (uint16_t)offset;
if (ha == 0) {
- write32(buf + 0, 0x817e0000 | l); // lwz r11,l(r30)
- write32(buf + 4, 0x7d6903a6); // mtctr r11
- write32(buf + 8, 0x4e800420); // bctr
- write32(buf + 12, 0x60000000); // nop
+ write32(ctx, buf + 0, 0x817e0000 | l); // lwz r11,l(r30)
+ write32(ctx, buf + 4, 0x7d6903a6); // mtctr r11
+ write32(ctx, buf + 8, 0x4e800420); // bctr
+ write32(ctx, buf + 12, 0x60000000); // nop
} else {
- write32(buf + 0, 0x3d7e0000 | ha); // addis r11,r30,ha
- write32(buf + 4, 0x816b0000 | l); // lwz r11,l(r11)
- write32(buf + 8, 0x7d6903a6); // mtctr r11
- write32(buf + 12, 0x4e800420); // bctr
+ write32(ctx, buf + 0, 0x3d7e0000 | ha); // addis r11,r30,ha
+ write32(ctx, buf + 4, 0x816b0000 | l); // lwz r11,l(r11)
+ write32(ctx, buf + 8, 0x7d6903a6); // mtctr r11
+ write32(ctx, buf + 12, 0x4e800420); // bctr
}
}
@@ -1206,36 +1208,36 @@ void PPC32LongThunk::writeTo(uint8_t *buf) {
uint32_t d = destination.getVA(addend);
if (ctx.arg.isPic) {
uint32_t off = d - (getThunkTargetSym()->getVA() + 8);
- write32(buf + 0, 0x7c0802a6); // mflr r12,0
- write32(buf + 4, 0x429f0005); // bcl r20,r31,.+4
- write32(buf + 8, 0x7d8802a6); // mtctr r12
- write32(buf + 12, 0x3d8c0000 | ha(off)); // addis r12,r12,off at ha
- write32(buf + 16, 0x398c0000 | lo(off)); // addi r12,r12,off at l
- write32(buf + 20, 0x7c0803a6); // mtlr r0
+ write32(ctx, buf + 0, 0x7c0802a6); // mflr r12,0
+ write32(ctx, buf + 4, 0x429f0005); // bcl r20,r31,.+4
+ write32(ctx, buf + 8, 0x7d8802a6); // mtctr r12
+ write32(ctx, buf + 12, 0x3d8c0000 | ha(off)); // addis r12,r12,off at ha
+ write32(ctx, buf + 16, 0x398c0000 | lo(off)); // addi r12,r12,off at l
+ write32(ctx, buf + 20, 0x7c0803a6); // mtlr r0
buf += 24;
} else {
- write32(buf + 0, 0x3d800000 | ha(d)); // lis r12,d at ha
- write32(buf + 4, 0x398c0000 | lo(d)); // addi r12,r12,d at l
+ write32(ctx, buf + 0, 0x3d800000 | ha(d)); // lis r12,d at ha
+ write32(ctx, buf + 4, 0x398c0000 | lo(d)); // addi r12,r12,d at l
buf += 8;
}
- write32(buf + 0, 0x7d8903a6); // mtctr r12
- write32(buf + 4, 0x4e800420); // bctr
+ write32(ctx, buf + 0, 0x7d8903a6); // mtctr r12
+ write32(ctx, buf + 4, 0x4e800420); // bctr
}
void elf::writePPC64LoadAndBranch(uint8_t *buf, int64_t offset) {
uint16_t offHa = (offset + 0x8000) >> 16;
uint16_t offLo = offset & 0xffff;
- write32(buf + 0, 0x3d820000 | offHa); // addis r12, r2, OffHa
- write32(buf + 4, 0xe98c0000 | offLo); // ld r12, OffLo(r12)
- write32(buf + 8, 0x7d8903a6); // mtctr r12
- write32(buf + 12, 0x4e800420); // bctr
+ write32(ctx, buf + 0, 0x3d820000 | offHa); // addis r12, r2, OffHa
+ write32(ctx, buf + 4, 0xe98c0000 | offLo); // ld r12, OffLo(r12)
+ write32(ctx, buf + 8, 0x7d8903a6); // mtctr r12
+ write32(ctx, buf + 12, 0x4e800420); // bctr
}
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(buf + 0, 0xf8410018); // std r2,24(r1)
+ write32(ctx, buf + 0, 0xf8410018); // std r2,24(r1)
writePPC64LoadAndBranch(buf + 4, offset);
}
@@ -1253,10 +1255,10 @@ bool PPC64PltCallStub::isCompatibleWith(const InputSection &isec,
void PPC64R2SaveStub::writeTo(uint8_t *buf) {
const int64_t offset = computeOffset();
- write32(buf + 0, 0xf8410018); // std r2,24(r1)
+ write32(ctx, buf + 0, 0xf8410018); // std r2,24(r1)
// The branch offset needs to fit in 26 bits.
if (getMayUseShortThunk()) {
- write32(buf + 4, 0x48000000 | (offset & 0x03fffffc)); // b <offset>
+ write32(ctx, buf + 4, 0x48000000 | (offset & 0x03fffffc)); // b <offset>
} else if (isInt<34>(offset)) {
int nextInstOffset;
uint64_t tocOffset = destination.getVA() - getPPC64TocBase(ctx);
@@ -1264,16 +1266,16 @@ void PPC64R2SaveStub::writeTo(uint8_t *buf) {
const uint64_t addi = ADDI_R12_TO_R12_NO_DISP | (tocOffset & 0xffff);
const uint64_t addis =
ADDIS_R12_TO_R2_NO_DISP | ((tocOffset >> 16) & 0xffff);
- write32(buf + 4, addis); // addis r12, r2 , top of offset
- write32(buf + 8, addi); // addi r12, r12, bottom of offset
+ write32(ctx, buf + 4, addis); // addis r12, r2 , top of offset
+ write32(ctx, buf + 8, addi); // addi r12, r12, bottom of offset
nextInstOffset = 12;
} else {
const uint64_t addi = ADDI_R12_TO_R2_NO_DISP | (tocOffset & 0xffff);
- write32(buf + 4, addi); // addi r12, r2, offset
+ write32(ctx, buf + 4, addi); // addi r12, r2, offset
nextInstOffset = 8;
}
- write32(buf + nextInstOffset, MTCTR_R12); // mtctr r12
- write32(buf + nextInstOffset + 4, BCTR); // bctr
+ write32(ctx, buf + nextInstOffset, MTCTR_R12); // mtctr r12
+ write32(ctx, buf + nextInstOffset + 4, BCTR); // bctr
} else {
ctx.in.ppc64LongBranchTarget->addEntry(&destination, addend);
const int64_t offsetFromTOC =
@@ -1311,20 +1313,20 @@ void PPC64R12SetupStub::writeTo(uint8_t *buf) {
nextInstOffset = 8;
} else {
uint32_t off = offset - 8;
- write32(buf + 0, 0x7d8802a6); // mflr 12
- write32(buf + 4, 0x429f0005); // bcl 20,31,.+4
- write32(buf + 8, 0x7d6802a6); // mflr 11
- write32(buf + 12, 0x7d8803a6); // mtlr 12
- write32(buf + 16,
- 0x3d8b0000 | ((off + 0x8000) >> 16)); // addis 12,11,off at ha
+ write32(ctx, buf + 0, 0x7d8802a6); // mflr 12
+ write32(ctx, buf + 4, 0x429f0005); // bcl 20,31,.+4
+ write32(ctx, buf + 8, 0x7d6802a6); // mflr 11
+ write32(ctx, buf + 12, 0x7d8803a6); // mtlr 12
+ write32(ctx, buf + 16,
+ 0x3d8b0000 | ((off + 0x8000) >> 16)); // addis 12,11,off at ha
if (gotPlt)
- write32(buf + 20, 0xe98c0000 | (off & 0xffff)); // ld 12, off at l(12)
+ write32(ctx, buf + 20, 0xe98c0000 | (off & 0xffff)); // ld 12, off at l(12)
else
- write32(buf + 20, 0x398c0000 | (off & 0xffff)); // addi 12,12,off at l
+ write32(ctx, buf + 20, 0x398c0000 | (off & 0xffff)); // addi 12,12,off at l
nextInstOffset = 24;
}
- write32(buf + nextInstOffset, MTCTR_R12); // mtctr r12
- write32(buf + nextInstOffset + 4, BCTR); // bctr
+ write32(ctx, buf + nextInstOffset, MTCTR_R12); // mtctr r12
+ write32(ctx, buf + nextInstOffset + 4, BCTR); // bctr
}
void PPC64R12SetupStub::addSymbols(ThunkSection &isec) {
More information about the llvm-commits
mailing list