@@ -310,14 +310,12 @@ class Patcher : public RelocActions {
310
310
ptrdiff_t offset = target - insn_addr;
311
311
instructions = 2 ;
312
312
precond (inner != nullptr );
313
- uintptr_t dest = (uintptr_t )target;
313
+ // Give the inner reloc a chance to modify the target.
314
+ address adjusted_target = target;
315
+ instructions = (*inner)(insn_addr, adjusted_target);
314
316
uintptr_t pc_page = (uintptr_t )insn_addr >> 12 ;
315
- uintptr_t adr_page = (uintptr_t )target >> 12 ;
317
+ uintptr_t adr_page = (uintptr_t )adjusted_target >> 12 ;
316
318
offset = adr_page - pc_page;
317
- instructions = (*inner)(insn_addr, target);
318
- // Now we extract the lower 21 bits of the signed offset field for
319
- // the ADRP.
320
- offset = offset << (64 -21 ) >> (64 -21 );
321
319
int offset_lo = offset & 3 ;
322
320
offset >>= 2 ;
323
321
Instruction_aarch64::spatch (insn_addr, 23 , 5 , offset);
@@ -340,8 +338,10 @@ class Patcher : public RelocActions {
340
338
return 2 ;
341
339
}
342
340
static int adrpMovk_impl (address insn_addr, address &target) {
343
- uintptr_t dest = ( uintptr_t ) target;
341
+ uintptr_t dest = uintptr_t ( target) ;
344
342
Instruction_aarch64::patch (insn_addr + sizeof (uint32_t ), 20 , 5 , (uintptr_t )target >> 32 );
343
+ dest = (dest & 0xffffffffULL ) | (uintptr_t (insn_addr) & 0xffff00000000ULL );
344
+ target = address (dest);
345
345
return 2 ;
346
346
}
347
347
virtual int immediate (address insn_addr, address &target) {
@@ -457,7 +457,7 @@ class Decoder : public RelocActions {
457
457
static int adrpMovk_impl (address insn_addr, address &target) {
458
458
uint32_t insn2 = insn_at (insn_addr, 1 );
459
459
uint64_t dest = uint64_t (target);
460
- dest = (dest & 0xffffffff ) |
460
+ dest = (dest & 0xffff0000ffffffff ) |
461
461
((uint64_t )Instruction_aarch64::extract (insn2, 20 , 5 ) << 32 );
462
462
target = address (dest);
463
463
0 commit comments