diff --git a/manticore/core/cpu/arm.py b/manticore/core/cpu/arm.py index 26e28fa..9b09aaa 100644 --- a/manticore/core/cpu/arm.py +++ b/manticore/core/cpu/arm.py @@ -335,9 +335,18 @@ class Armv7Cpu(Cpu): self._at_symbolic_conditional = state['at_symbolic_conditional'] def _set_mode(self, new_mode): - assert new_mode in (CS_MODE_ARM, CS_MODE_THUMB) - self.mode = new_mode - self._md.mode = new_mode + assert new_mode in (CS_MODE_ARM, CS_MODE_THUMB) + self.mode = new_mode + self._md.mode = new_mode + + def _swap_mode(self): + #swap from arm to thumb or back + assert self.mode in (CS_MODE_ARM, CS_MODE_THUMB) + if self.mode == CS_MODE_ARM: + self._set_mode(CS_MODE_THUMB) + else: + self._set_mode(CS_MODE_ARM) + # Flags that are the result of arithmetic instructions. Unconditionally # set, but conditionally committed. @@ -755,9 +764,12 @@ class Armv7Cpu(Cpu): def B(cpu, dest): cpu.PC = dest.read() - # XXX How should we deal with switching Thumb modes? @instruction def BX(cpu, dest): + if dest.read() & 0x1: + cpu._set_mode(CS_MODE_THUMB) + else: + cpu._set_mode(CS_MODE_ARM) cpu.PC = dest.read() & ~1 @instruction @@ -771,25 +783,21 @@ class Armv7Cpu(Cpu): cpu.regfile.write('LR', next_instr_addr) cpu.regfile.write('PC', label.read()) - @instruction def BLX(cpu, dest): - ## XXX: Technically, this should use the values that are commented (sub - ## 2 and LSB of LR set, but we currently do not distinguish between - ## THUMB and regular modes, so we use the addresses as is. TODO: Handle - ## thumb correctly and fix this address = cpu.PC target = dest.read() - next_instr_addr = cpu.regfile.read('PC') #- 2 - cpu.regfile.write('LR', next_instr_addr) # | 1) + next_instr_addr = cpu.regfile.read('PC') + cpu.regfile.write('LR', next_instr_addr) cpu.regfile.write('PC', target & ~1) - ## The `blx