summaryrefslogtreecommitdiff
path: root/arch/armv7
diff options
context:
space:
mode:
authorGalen Williamson <galen@vector35.com>2024-03-12 13:26:16 -0400
committergalenbwill <galenbwill@users.noreply.github.com>2024-03-12 13:49:08 -0400
commit45a674447579e350cf380dbacba5c5f6360c5ac1 (patch)
treebc6daa4644a5c78caa7d834740b70f3bf3550230 /arch/armv7
parentc924e7f746f7f81fab1f35d8adc936dfba706b58 (diff)
moved over from https://github.com/Vector35/arch-armv7/pull/81
Diffstat (limited to 'arch/armv7')
-rw-r--r--arch/armv7/il.cpp16
-rwxr-xr-xarch/armv7/test_lift.py26
2 files changed, 39 insertions, 3 deletions
diff --git a/arch/armv7/il.cpp b/arch/armv7/il.cpp
index d946e77c..5fbbb729 100644
--- a/arch/armv7/il.cpp
+++ b/arch/armv7/il.cpp
@@ -312,8 +312,20 @@ static void Load(
memValue = il.ZeroExtend(dstSize, memValue);
}
- il.AddInstruction(SetRegisterOrBranch(il, dst.reg, memValue));
- il.AddInstruction(SetRegisterOrBranch(il, src.reg, value));
+ if (dst.reg == REG_PC)
+ {
+ // don't update Rd, update Rs, jump to pre-updated Rs
+ il.AddInstruction(il.SetRegister(4, LLIL_TEMP(0), memValue));
+ il.AddInstruction(SetRegisterOrBranch(il, src.reg, value));
+ il.AddInstruction(il.Jump(il.Register(4, LLIL_TEMP(0))));
+ }
+ else
+ {
+ // set Rd, update Rs, don't jump
+ il.AddInstruction(il.SetRegister(get_register_size(dst.reg), dst.reg, memValue));
+ il.AddInstruction(SetRegisterOrBranch(il, src.reg, value));
+ }
+
break;
case MEM_IMM:
case LABEL:
diff --git a/arch/armv7/test_lift.py b/arch/armv7/test_lift.py
index 2e12dbe4..ab97d1d9 100755
--- a/arch/armv7/test_lift.py
+++ b/arch/armv7/test_lift.py
@@ -2,6 +2,27 @@
test_cases = \
[
+ # Post-Indexed addressing (normal)
+ # with register offset
+ # ldr r0, [r1], r2
+ ('A', b'\x02\x00\x91\xe6', 'LLIL_SET_REG.d(r0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_REG.d(r2)))'),
+ # with immediate offset
+ # ldr r0, [r1], #4
+ ('A', b'\x04\x00\x91\xe4', 'LLIL_SET_REG.d(r0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_CONST.d(0x4)))'),
+ # with register and shift
+ # ldr r0, [r1], r2, lsl #2
+ ('A', b'\x02\x01\x91\xe6', 'LLIL_SET_REG.d(r0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_LSL.d(LLIL_REG.d(r2),LLIL_CONST.b(0x2))))'),
+
+ # Post-Indexed addressing (to pc)
+ # ldr pc, [r1], r2
+ ('A', b'\x02\xf0\x91\xe6', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_REG.d(r2))); LLIL_JUMP(LLIL_REG.d(temp0))'),
+ # ldr pc, [r1], #4
+ ('A', b'\x04\xf0\x91\xe4', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_CONST.d(0x4))); LLIL_JUMP(LLIL_REG.d(temp0))'),
+ # ldr pc, [r1], r2, lsl #2
+ ('A', b'\x02\xf1\x91\xe6', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(r1))); LLIL_SET_REG.d(r1,LLIL_ADD.d(LLIL_REG.d(r1),LLIL_LSL.d(LLIL_REG.d(r2),LLIL_CONST.b(0x2)))); LLIL_JUMP(LLIL_REG.d(temp0))'),
+ # from " Armv7: POP(PC) lifted as LDR without writeback #3982"
+ ('A', b'\x04\xf0\x9d\xe4', 'LLIL_SET_REG.d(temp0,LLIL_LOAD.d(LLIL_REG.d(sp))); LLIL_SET_REG.d(sp,LLIL_ADD.d(LLIL_REG.d(sp),LLIL_CONST.d(0x4))); LLIL_JUMP(LLIL_REG.d(temp0))'),
+
# umaal r0, r1, r2, r3
('A', b'\x92\x03\x41\xe0', 'LLIL_SET_REG_SPLIT.d(r1,r0,LLIL_ADD.q(LLIL_MULU_DP.d(LLIL_REG.d(r3),LLIL_REG.d(r2)),LLIL_ADD.q(LLIL_REG.d(r1),LLIL_REG.d(r0))))'),
# umlal r0, r1, r2, r3
@@ -100,7 +121,8 @@ test_cases = \
# sbfx r0, r1, 1, 2 (starting at b1, width 2, so extract b2b1)
('T', b'\x41\xf3\x41\x00', 'LLIL_SET_REG.d(r0,LLIL_ASR.d(LLIL_LSL.d(LLIL_REG.d(r1),LLIL_CONST.b(0x1D)),LLIL_CONST.b(0x1E)))'),
# sbfx r0, r1, 20, 30 (starting at b20, width 30... gets clamped, so b31b30...b20
- ('T', b'\x41\xf3\x1d\x50', 'LLIL_SET_REG.d(r0,LLIL_ASR.d(LLIL_LSL.d(LLIL_REG.d(r1),LLIL_CONST.b(0x0)),LLIL_CONST.b(0x14)))')
+ # just r0 = r1 >> 20, no left shift required
+ ('T', b'\x41\xf3\x1d\x50', 'LLIL_SET_REG.d(r0,LLIL_ASR.d(LLIL_REG.d(r1),LLIL_CONST.b(0x14)))')
]
import re
@@ -126,6 +148,8 @@ def il2str(il):
return '%s%s%s(%s)' % (il.operation.name, size_code, flags_code, ','.join([il2str(o) for o in il.operands]))
elif isinstance(il, list):
return '[' + ','.join([il2str(x) for x in il]) + ']'
+ elif type(il) == lowlevelil.LowLevelILFlagCondition:
+ return f'LowLevelILFlagCondition.{il.name}'
else:
return str(il)