Skip to content

Commit 4745338

Browse files
jeremyd2019nobu
authored andcommitted
[win32] fix arm64 instruction decoding
Two minor fixes to arm64 instruction decoding when looking for __pioinfo: 1. add_mask was shifted by one bit, it was intended to be 0x7f800000. However, since the mask was already excluding matching the 'sh' bit, and since the purpose of the add following the adrp is to add in the lower 12 bits, I opted to set the mask to 0x7fc00000 and simply remove the handling for the 12 bit shift option which is now required to be disabled in order to match. 2. adrp's immediate was supposed to be sign extended. So far, I have not seen cases where the global variable ends up before the code in memory, but it's a possibility, so handle the sign extension.
1 parent 8149f4d commit 4745338

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

win32/win32.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2580,7 +2580,7 @@ set_pioinfo_extra(void)
25802580
const uint32_t adrp_id = 0x90000000;
25812581
const uint32_t adrp_mask = 0x9f000000;
25822582
const uint32_t add_id = 0x11000000;
2583-
const uint32_t add_mask = 0x3fc00000;
2583+
const uint32_t add_mask = 0x7fc00000;
25842584
for(; pc > start; pc--) {
25852585
if (IS_INSN(pc, adrp) && IS_INSN(pc + 1, add)) {
25862586
break;
@@ -2600,17 +2600,14 @@ set_pioinfo_extra(void)
26002600
const uint32_t adrp_insn = *pc;
26012601
const uint32_t adrp_immhi = (adrp_insn & 0x00ffffe0) >> 5;
26022602
const uint32_t adrp_immlo = (adrp_insn & 0x60000000) >> (5 + 19 + 5);
2603-
/* imm = immhi:immlo:Zeros(12), 64 */
2604-
const uint64_t adrp_imm = ((adrp_immhi << 2) | adrp_immlo) << 12;
2603+
const int64_t adrp_sign = (adrp_insn & 0x00800000) ? ~0x001fffff : 0;
2604+
/* imm = SignExtend(immhi:immlo:Zeros(12), 64) */
2605+
const int64_t adrp_imm = (adrp_sign | (adrp_immhi << 2) | adrp_immlo) << 12;
26052606
/* base = PC64<63:12>:Zeros(12) */
26062607
const uint64_t adrp_base = (uint64_t)pc & 0xfffffffffffff000;
26072608

26082609
const uint32_t add_insn = *(pc + 1);
2609-
const uint32_t add_sh = (add_insn & 0x400000) >> (12 + 5 + 5);
2610-
/* case sh of
2611-
when '0' imm = ZeroExtend(imm12, datasize);
2612-
when '1' imm = ZeroExtend(imm12:Zeros(12), datasize); */
2613-
const uint64_t add_imm = ((add_insn & 0x3ffc00) >> (5 + 5)) << (add_sh ? 12 : 0);
2610+
const uint64_t add_imm = (add_insn & 0x3ffc00) >> (5 + 5);
26142611

26152612
__pioinfo = (ioinfo**)(adrp_base + adrp_imm + add_imm);
26162613
#else /* _M_ARM64 */

0 commit comments

Comments
 (0)