Skip to content

Commit 1527677

Browse files
committed
[aarch64] Add support for ARM64_RELOC_BRANCH26, ARM64_RELOC_GOT_LOAD_PAGE21, ARM64_RELOC_GOT_LOAD_PAGEOFF12
1 parent 64f0668 commit 1527677

1 file changed

Lines changed: 23 additions & 7 deletions

File tree

arch/arm64/arch_arm64.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,7 +2899,21 @@ class Arm64MachoRelocationHandler : public RelocationHandler
28992899
{ // Magic number defined in MachOView.cpp for chained fixups
29002900
*(uint64_t*)dest = info.target + info.addend;
29012901
}
2902-
else if (info.nativeType == ARM64_RELOC_PAGE21)
2902+
else if (info.nativeType == ARM64_RELOC_BRANCH26)
2903+
{
2904+
// B/BL: OP=X|00101|IMM26=XXXXXXXXXXXXXXXXXXXXXXXXXX
2905+
// imm26 is signed number of 4-byte instructions
2906+
int64_t delta = (int64_t)reloc->GetTarget() - (int64_t)reloc->GetAddress();
2907+
if (delta < -(1LL << 27) || delta >= (1LL << 27) || (delta & 3))
2908+
{
2909+
// Relocation can't apply bc the delta is out of range or not 4-byte aligned
2910+
return false;
2911+
}
2912+
// Keep the opcode, shift the delta bc the encoding is in terms of 4-byte instructions
2913+
insword = (insword & 0xFC000000) | ((uint32_t)(delta >> 2) & 0x03FFFFFF);
2914+
*(uint32_t*)dest = insword;
2915+
}
2916+
else if (info.nativeType == ARM64_RELOC_PAGE21 || info.nativeType == ARM64_RELOC_GOT_LOAD_PAGE21)
29032917
{
29042918
// 21 bits across IMMHI:IMMLO
29052919
// OP=1|IMMLO=XX|10000|IMMHI=XXXXXXXXXXXXXXXXXXX|RD=XXXXX
@@ -2909,7 +2923,7 @@ class Arm64MachoRelocationHandler : public RelocationHandler
29092923
insword = insword | ((page_delta >> 2) << 5); // IMMHI
29102924
*(uint32_t*)dest = insword;
29112925
}
2912-
else if (info.nativeType == ARM64_RELOC_PAGEOFF12)
2926+
else if (info.nativeType == ARM64_RELOC_PAGEOFF12 || info.nativeType == ARM64_RELOC_GOT_LOAD_PAGEOFF12)
29132927
{
29142928
/* verify relocation point to qualifying instructions */
29152929
if ((insword & 0x3B000000) != 0x39000000 && (insword & 0x11C00000) != 0x11000000)
@@ -2985,17 +2999,19 @@ class Arm64MachoRelocationHandler : public RelocationHandler
29852999
result[i].hasSign = false;
29863000
break;
29873001
case ARM64_RELOC_PAGE21:
3002+
case ARM64_RELOC_GOT_LOAD_PAGE21:
29883003
// eg: the number of pages to get to <addr> in "adrp x1, <addr>"
2989-
// printf("GetRelocationInfo(): ARM64_RELOC_PAGE21 .address=0x%llX\n", result[i].address);
3004+
// GOT_LOAD: the page of the GOT slot
29903005
break;
29913006
case ARM64_RELOC_PAGEOFF12:
3007+
case ARM64_RELOC_GOT_LOAD_PAGEOFF12:
29923008
// eg: the 12-bit <immediate> in "add x8, x8, #<immediate>"
2993-
// printf("GetRelocationInfo(): ARM64_RELOC_PAGEOFF12 .address=0x%llX\n",
2994-
// result[i].address);
3009+
// GOT_LOAD: 12-bit offset in the GOT slot page (usually used with ARM64_RELOC_GOT_LOAD_PAGE21)
29953010
break;
29963011
case ARM64_RELOC_BRANCH26:
2997-
case ARM64_RELOC_GOT_LOAD_PAGE21:
2998-
case ARM64_RELOC_GOT_LOAD_PAGEOFF12:
3012+
// 26-bit immediate for branch instrs
3013+
result[i].pcRelative = true;
3014+
break;
29993015
case ARM64_RELOC_TLVP_LOAD_PAGE21:
30003016
case ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
30013017
case ARM64_RELOC_ADDEND:

0 commit comments

Comments
 (0)