@@ -208,28 +208,28 @@ RelType ARM::getDynRel(RelType type) const {
208
208
}
209
209
210
210
void ARM::writeGotPlt (uint8_t *buf, const Symbol &) const {
211
- write32 (buf, ctx.in .plt ->getVA ());
211
+ write32 (ctx, buf, ctx.in .plt ->getVA ());
212
212
}
213
213
214
214
void ARM::writeIgotPlt (uint8_t *buf, const Symbol &s) const {
215
215
// An ARM entry is the address of the ifunc resolver function.
216
- write32 (buf, s.getVA ());
216
+ write32 (ctx, buf, s.getVA ());
217
217
}
218
218
219
219
// Long form PLT Header that does not have any restrictions on the displacement
220
220
// of the .plt from the .got.plt.
221
221
static void writePltHeaderLong (Ctx &ctx, uint8_t *buf) {
222
- write32 (buf + 0 , 0xe52de004 ); // str lr, [sp,#-4]!
223
- write32 (buf + 4 , 0xe59fe004 ); // ldr lr, L2
224
- write32 (buf + 8 , 0xe08fe00e ); // L1: add lr, pc, lr
225
- write32 (buf + 12 , 0xe5bef008 ); // ldr pc, [lr, #8]
226
- write32 (buf + 16 , 0x00000000 ); // L2: .word &(.got.plt) - L1 - 8
227
- write32 (buf + 20 , 0xd4d4d4d4 ); // Pad to 32-byte boundary
228
- write32 (buf + 24 , 0xd4d4d4d4 ); // Pad to 32-byte boundary
229
- write32 (buf + 28 , 0xd4d4d4d4 );
222
+ write32 (ctx, buf + 0 , 0xe52de004 ); // str lr, [sp,#-4]!
223
+ write32 (ctx, buf + 4 , 0xe59fe004 ); // ldr lr, L2
224
+ write32 (ctx, buf + 8 , 0xe08fe00e ); // L1: add lr, pc, lr
225
+ write32 (ctx, buf + 12 , 0xe5bef008 ); // ldr pc, [lr, #8]
226
+ write32 (ctx, buf + 16 , 0x00000000 ); // L2: .word &(.got.plt) - L1 - 8
227
+ write32 (ctx, buf + 20 , 0xd4d4d4d4 ); // Pad to 32-byte boundary
228
+ write32 (ctx, buf + 24 , 0xd4d4d4d4 ); // Pad to 32-byte boundary
229
+ write32 (ctx, buf + 28 , 0xd4d4d4d4 );
230
230
uint64_t gotPlt = ctx.in .gotPlt ->getVA ();
231
231
uint64_t l1 = ctx.in .plt ->getVA () + 8 ;
232
- write32 (buf + 16 , gotPlt - l1 - 8 );
232
+ write32 (ctx, buf + 16 , gotPlt - l1 - 8 );
233
233
}
234
234
235
235
// True if we should use Thumb PLTs, which currently require Thumb2, and are
@@ -263,7 +263,7 @@ void ARM::writePltHeader(uint8_t *buf) const {
263
263
// Split into two halves to support endianness correctly.
264
264
write16 (buf + 8 , 0xf85e );
265
265
write16 (buf + 10 , 0xff08 );
266
- write32 (buf + 12 , offset);
266
+ write32 (ctx, buf + 12 , offset);
267
267
268
268
memcpy (buf + 16 , trapInstr.data (), 4 ); // Pad to 32-byte boundary
269
269
memcpy (buf + 20 , trapInstr.data (), 4 );
@@ -287,10 +287,10 @@ void ARM::writePltHeader(uint8_t *buf) const {
287
287
writePltHeaderLong (ctx, buf);
288
288
return ;
289
289
}
290
- write32 (buf + 0 , pltData[0 ]);
291
- write32 (buf + 4 , pltData[1 ] | ((offset >> 20 ) & 0xff ));
292
- write32 (buf + 8 , pltData[2 ] | ((offset >> 12 ) & 0xff ));
293
- write32 (buf + 12 , pltData[3 ] | (offset & 0xfff ));
290
+ write32 (ctx, buf + 0 , pltData[0 ]);
291
+ write32 (ctx, buf + 4 , pltData[1 ] | ((offset >> 20 ) & 0xff ));
292
+ write32 (ctx, buf + 8 , pltData[2 ] | ((offset >> 12 ) & 0xff ));
293
+ write32 (ctx, buf + 12 , pltData[3 ] | (offset & 0xfff ));
294
294
memcpy (buf + 16 , trapInstr.data (), 4 ); // Pad to 32-byte boundary
295
295
memcpy (buf + 20 , trapInstr.data (), 4 );
296
296
memcpy (buf + 24 , trapInstr.data (), 4 );
@@ -312,12 +312,12 @@ void ARM::addPltHeaderSymbols(InputSection &isec) const {
312
312
// of the .plt from the .got.plt.
313
313
static void writePltLong (uint8_t *buf, uint64_t gotPltEntryAddr,
314
314
uint64_t pltEntryAddr) {
315
- write32 (buf + 0 , 0xe59fc004 ); // ldr ip, L2
316
- write32 (buf + 4 , 0xe08cc00f ); // L1: add ip, ip, pc
317
- write32 (buf + 8 , 0xe59cf000 ); // ldr pc, [ip]
318
- write32 (buf + 12 , 0x00000000 ); // L2: .word Offset(&(.got.plt) - L1 - 8
315
+ write32 (ctx, buf + 0 , 0xe59fc004 ); // ldr ip, L2
316
+ write32 (ctx, buf + 4 , 0xe08cc00f ); // L1: add ip, ip, pc
317
+ write32 (ctx, buf + 8 , 0xe59cf000 ); // ldr pc, [ip]
318
+ write32 (ctx, buf + 12 , 0x00000000 ); // L2: .word Offset(&(.got.plt) - L1 - 8
319
319
uint64_t l1 = pltEntryAddr + 4 ;
320
- write32 (buf + 12 , gotPltEntryAddr - l1 - 8 );
320
+ write32 (ctx, buf + 12 , gotPltEntryAddr - l1 - 8 );
321
321
}
322
322
323
323
// 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,
342
342
writePltLong (buf, sym.getGotPltVA (ctx), pltEntryAddr);
343
343
return ;
344
344
}
345
- write32 (buf + 0 , pltData[0 ] | ((offset >> 20 ) & 0xff ));
346
- write32 (buf + 4 , pltData[1 ] | ((offset >> 12 ) & 0xff ));
347
- write32 (buf + 8 , pltData[2 ] | (offset & 0xfff ));
345
+ write32 (ctx, buf + 0 , pltData[0 ] | ((offset >> 20 ) & 0xff ));
346
+ write32 (ctx, buf + 4 , pltData[1 ] | ((offset >> 12 ) & 0xff ));
347
+ write32 (ctx, buf + 8 , pltData[2 ] | (offset & 0xfff ));
348
348
memcpy (buf + 12 , trapInstr.data (), 4 ); // Pad to 16-byte boundary
349
349
} else {
350
350
uint64_t offset = sym.getGotPltVA (ctx) - pltEntryAddr - 12 ;
@@ -558,7 +558,8 @@ void ARM::encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
558
558
if (check && imm > 0xff )
559
559
error (getErrorLoc (ctx, loc) + " unencodeable immediate " + Twine (val).str () +
560
560
" for relocation " + toString (rel.type ));
561
- write32 (loc, (read32 (loc) & 0xff3ff000 ) | opcode | rot | (imm & 0xff ));
561
+ write32 (ctx, loc,
562
+ (read32 (ctx, loc) & 0xff3ff000 ) | opcode | rot | (imm & 0xff ));
562
563
}
563
564
564
565
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,
576
577
}
577
578
uint32_t imm = getRemAndLZForGroup (group, val).first ;
578
579
checkUInt (loc, imm, 12 , rel);
579
- write32 (loc, (read32 (loc) & 0xff7ff000 ) | opcode | imm);
580
+ write32 (ctx, loc, (read32 (ctx, loc) & 0xff7ff000 ) | opcode | imm);
580
581
}
581
582
582
583
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,
594
595
}
595
596
uint32_t imm = getRemAndLZForGroup (group, val).first ;
596
597
checkUInt (loc, imm, 8 , rel);
597
- write32 (loc, (read32 (loc) & 0xff7ff0f0 ) | opcode | ((imm & 0xf0 ) << 4 ) |
598
- (imm & 0xf ));
598
+ write32 (ctx, loc,
599
+ (read32 (ctx, loc) & 0xff7ff0f0 ) | opcode | ((imm & 0xf0 ) << 4 ) |
600
+ (imm & 0xf ));
599
601
}
600
602
601
603
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 {
617
619
case R_ARM_TLS_LE32:
618
620
case R_ARM_TLS_TPOFF32:
619
621
case R_ARM_TLS_DTPOFF32:
620
- write32 (loc, val);
622
+ write32 (ctx, loc, val);
621
623
break ;
622
624
case R_ARM_PREL31:
623
625
checkInt (loc, val, 31 , rel);
624
- write32 (loc, (read32 (loc) & 0x80000000 ) | (val & ~0x80000000 ));
626
+ write32 (ctx, loc, (read32 (ctx, loc) & 0x80000000 ) | (val & ~0x80000000 ));
625
627
break ;
626
628
case R_ARM_CALL: {
627
629
// R_ARM_CALL is used for BL and BLX instructions, for symbols of type
@@ -630,40 +632,42 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
630
632
// not of type STT_FUNC then we must preserve the original instruction.
631
633
assert (rel.sym ); // R_ARM_CALL is always reached via relocate().
632
634
bool bit0Thumb = val & 1 ;
633
- bool isBlx = (read32 (loc) & 0xfe000000 ) == 0xfa000000 ;
635
+ bool isBlx = (read32 (ctx, loc) & 0xfe000000 ) == 0xfa000000 ;
634
636
// lld 10.0 and before always used bit0Thumb when deciding to write a BLX
635
637
// even when type not STT_FUNC.
636
638
if (!rel.sym ->isFunc () && isBlx != bit0Thumb)
637
639
stateChangeWarning (ctx, loc, rel.type , *rel.sym );
638
640
if (rel.sym ->isFunc () ? bit0Thumb : isBlx) {
639
641
// The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
640
642
checkInt (loc, val, 26 , rel);
641
- write32 (loc, 0xfa000000 | // opcode
642
- ((val & 2 ) << 23 ) | // H
643
- ((val >> 2 ) & 0x00ffffff )); // imm24
643
+ write32 (ctx, loc,
644
+ 0xfa000000 | // opcode
645
+ ((val & 2 ) << 23 ) | // H
646
+ ((val >> 2 ) & 0x00ffffff )); // imm24
644
647
break ;
645
648
}
646
649
// BLX (always unconditional) instruction to an ARM Target, select an
647
650
// unconditional BL.
648
- write32 (loc, 0xeb000000 | (read32 (loc) & 0x00ffffff ));
651
+ write32 (ctx, loc, 0xeb000000 | (read32 (ctx, loc) & 0x00ffffff ));
649
652
// fall through as BL encoding is shared with B
650
653
}
651
654
[[fallthrough]];
652
655
case R_ARM_JUMP24:
653
656
case R_ARM_PC24:
654
657
case R_ARM_PLT32:
655
658
checkInt (loc, val, 26 , rel);
656
- write32 (loc, (read32 (loc) & ~0x00ffffff ) | ((val >> 2 ) & 0x00ffffff ));
659
+ write32 (ctx, loc,
660
+ (read32 (ctx, loc) & ~0x00ffffff ) | ((val >> 2 ) & 0x00ffffff ));
657
661
break ;
658
662
case R_ARM_THM_JUMP8:
659
663
// We do a 9 bit check because val is right-shifted by 1 bit.
660
664
checkInt (loc, val, 9 , rel);
661
- write16 (loc, (read32 (loc) & 0xff00 ) | ((val >> 1 ) & 0x00ff ));
665
+ write16 (loc, (read32 (ctx, loc) & 0xff00 ) | ((val >> 1 ) & 0x00ff ));
662
666
break ;
663
667
case R_ARM_THM_JUMP11:
664
668
// We do a 12 bit check because val is right-shifted by 1 bit.
665
669
checkInt (loc, val, 12 , rel);
666
- write16 (loc, (read32 (loc) & 0xf800 ) | ((val >> 1 ) & 0x07ff ));
670
+ write16 (loc, (read32 (ctx, loc) & 0xf800 ) | ((val >> 1 ) & 0x07ff ));
667
671
break ;
668
672
case R_ARM_THM_JUMP19:
669
673
// 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 {
733
737
case R_ARM_MOVW_ABS_NC:
734
738
case R_ARM_MOVW_PREL_NC:
735
739
case R_ARM_MOVW_BREL_NC:
736
- write32 (loc, (read32 (loc) & ~0x000f0fff ) | ((val & 0xf000 ) << 4 ) |
737
- (val & 0x0fff ));
740
+ write32 (ctx, loc,
741
+ (read32 (ctx, loc) & ~0x000f0fff ) | ((val & 0xf000 ) << 4 ) |
742
+ (val & 0x0fff ));
738
743
break ;
739
744
case R_ARM_MOVT_ABS:
740
745
case R_ARM_MOVT_PREL:
741
746
case R_ARM_MOVT_BREL:
742
- write32 (loc, (read32 (loc) & ~0x000f0fff ) |
743
- (((val >> 16 ) & 0xf000 ) << 4 ) | ((val >> 16 ) & 0xfff ));
747
+ write32 (ctx, loc,
748
+ (read32 (ctx, loc) & ~0x000f0fff ) | (((val >> 16 ) & 0xf000 ) << 4 ) |
749
+ ((val >> 16 ) & 0xfff ));
744
750
break ;
745
751
case R_ARM_THM_MOVT_ABS:
746
752
case R_ARM_THM_MOVT_PREL:
@@ -890,14 +896,14 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
890
896
case R_ARM_TLS_LE32:
891
897
case R_ARM_TLS_LDO32:
892
898
case R_ARM_TLS_TPOFF32:
893
- return SignExtend64<32 >(read32 (buf));
899
+ return SignExtend64<32 >(read32 (ctx, buf));
894
900
case R_ARM_PREL31:
895
- return SignExtend64<31 >(read32 (buf));
901
+ return SignExtend64<31 >(read32 (ctx, buf));
896
902
case R_ARM_CALL:
897
903
case R_ARM_JUMP24:
898
904
case R_ARM_PC24:
899
905
case R_ARM_PLT32:
900
- return SignExtend64<26 >(read32 (buf) << 2 );
906
+ return SignExtend64<26 >(read32 (ctx, buf) << 2 );
901
907
case R_ARM_THM_JUMP8:
902
908
return SignExtend64<9 >(read16 (buf) << 1 );
903
909
case R_ARM_THM_JUMP11:
@@ -942,7 +948,7 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
942
948
case R_ARM_MOVT_PREL:
943
949
case R_ARM_MOVW_BREL_NC:
944
950
case R_ARM_MOVT_BREL: {
945
- uint64_t val = read32 (buf) & 0x000f0fff ;
951
+ uint64_t val = read32 (ctx, buf) & 0x000f0fff ;
946
952
return SignExtend64<16 >(((val & 0x000f0000 ) >> 4 ) | (val & 0x00fff ));
947
953
}
948
954
case R_ARM_THM_MOVW_ABS_NC:
@@ -973,7 +979,7 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
973
979
// right rotation and 8-bit constant. After the rotation the value
974
980
// is zero-extended. When bit 23 is set the instruction is an add, when
975
981
// bit 22 is set it is a sub.
976
- uint32_t instr = read32 (buf);
982
+ uint32_t instr = read32 (ctx, buf);
977
983
uint32_t val = rotr32 (instr & 0xff , ((instr & 0xf00 ) >> 8 ) * 2 );
978
984
return (instr & 0x00400000 ) ? -val : val;
979
985
}
@@ -982,15 +988,15 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
982
988
case R_ARM_LDR_PC_G2: {
983
989
// ADR (literal) add = bit23, sub = bit22
984
990
// LDR (literal) u = bit23 unsigned imm12
985
- bool u = read32 (buf) & 0x00800000 ;
986
- uint32_t imm12 = read32 (buf) & 0xfff ;
991
+ bool u = read32 (ctx, buf) & 0x00800000 ;
992
+ uint32_t imm12 = read32 (ctx, buf) & 0xfff ;
987
993
return u ? imm12 : -imm12;
988
994
}
989
995
case R_ARM_LDRS_PC_G0:
990
996
case R_ARM_LDRS_PC_G1:
991
997
case R_ARM_LDRS_PC_G2: {
992
998
// LDRD/LDRH/LDRSB/LDRSH (literal) u = bit23 unsigned imm8
993
- uint32_t opcode = read32 (buf);
999
+ uint32_t opcode = read32 (ctx, buf);
994
1000
bool u = opcode & 0x00800000 ;
995
1001
uint32_t imm4l = opcode & 0xf ;
996
1002
uint32_t imm4h = (opcode & 0xf00 ) >> 4 ;
@@ -1089,7 +1095,7 @@ static void toLittleEndianInstructions(uint8_t *buf, uint64_t start,
1089
1095
CodeState curState = static_cast <CodeState>(width);
1090
1096
if (curState == CodeState::Arm)
1091
1097
for (uint64_t i = start; i < end; i += width)
1092
- write32le (buf + i, read32 (buf + i));
1098
+ write32le (buf + i, read32 (ctx, buf + i));
1093
1099
1094
1100
if (curState == CodeState::Thumb)
1095
1101
for (uint64_t i = start; i < end; i += width)
0 commit comments