You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a large operating system implementation using Unicorn 1. I am looking to upgrade, but although it appears to start correctly for simple things, I have found a problem with the support for UND32 -> SVC32 transitions (possibly others, but this fails early in module initialisation whilst the floating point emulator code is initialising).
Source environment
I built unicorn on the dev branch at sha 87a391d549a339b5d8109c10c6b16bd95130a923.
This has been tested on OSX system on Intel hardware (10.14.6)
Failure mode
The failure appears to be that on return from UND32 to SVC32 (via a MOVS pc, lr, with SPSR set to the SVC32 mode) the mode changes, but the stack pointer is corrupted - it becomes 0.
What are we testing here?
We want to know that the change back from UND32 to SVC32 restores the banked
registers.
Our state at the start of execution:
CPSR = UND32 mode
SPSR = SVC32 mode
sp_und = 0xDEAD0000
sp_svc = 0x12345678
lr-> code to execute in SVC mode (a MVN r0,#0 as a dummy instruction)
pc-> code to execute in UND mode (a MVN dummy instruction, then MOVS pc, lr)
What we observe is that:
the first two instructions execute fine in UND32 mode
we return to SVC32 mode after the MOVS pc, lr instruction
we begin execution at 0x12000, the expected address
BUT sp has been set to 0.
This is a serious fault and makes handling of undefined instructions impossible.
Why is this a problem?
My OS implementation (https://pyromaniac.riscos.online/) is reliant on the UND mode
behaviour in order to emulate FPA instructions. This worked under Unicorn 1,
but does not under Unicorn 2 as built here.
Test code
Test code which exhibits this problem here:
#!/usr/bin/env python# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com># Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>from __future__ importprint_functionfromunicornimport*fromunicorn.arm_constimport*# code to be emulatedARM_CODE_UND= [b"\x00\x00\xe0\xe3", # MVN r0, #0b"\x0e\xf0\xb0\xe1", # MOVS pc, lrb"\x00\x00\xe0\xe3", # MVN r0, #0
]
ARM_CODE_SVC= [b"\x00\x00\xe0\xe3", # MVN r0, #0
]
# memory address where emulation startsADDRESS_UND=0x10000ADDRESS_SVC=0x12000MAPPED_UND=4096MAPPED_SVC=4096# callback for tracing instructionsdefhook_code(uc, address, size, user_data):
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x"%(address, size))
print(" CPSR = 0x{:08x}".format(uc.reg_read(UC_ARM_REG_CPSR)))
print(" SPSR = 0x{:08x}".format(uc.reg_read(UC_ARM_REG_SPSR)))
print(" SP = 0x{:08x}".format(uc.reg_read(UC_ARM_REG_R13)))
print(" PC = 0x{:08x}".format(uc.reg_read(UC_ARM_REG_R15)))
# Test ARMdeftest_arm():
print("Testing under Unicorn : {!r}".format(uc_version()))
print("Header version: {!r}".format((UC_VERSION_MAJOR, UC_VERSION_MINOR, UC_VERSION_EXTRA)))
print("Emulate ARM code")
try:
# Initialize emulator in ARM modemu=Uc(UC_ARCH_ARM, UC_MODE_ARM)
# map some memory for each blockmu.mem_map(ADDRESS_UND, MAPPED_UND)
mu.mem_map(ADDRESS_SVC, MAPPED_SVC)
# write machine code to be emulated to memorycode=b''.join(ARM_CODE_UND)
mu.mem_write(ADDRESS_UND, code)
code=b''.join(ARM_CODE_SVC)
mu.mem_write(ADDRESS_SVC, code)
# initialize machine registers in different modesmu.reg_write(UC_ARM_REG_CPSR, 0x40000093) # Current mode = SVC32 modemu.reg_write(UC_ARM_REG_R13, 0x12345678) # SVC stack valuemu.reg_write(UC_ARM_REG_CPSR, 0x4000009b) # Current mode = UND32 modemu.reg_write(UC_ARM_REG_SPSR, 0x40000093) # Saved mode = SVC32 modemu.reg_write(UC_ARM_REG_R13, 0xDEAD0000) # UND stack valuemu.reg_write(UC_ARM_REG_R14, ADDRESS_SVC) # return address for the UND vector# tracing one instruction at ADDRESS with customized callbackmu.hook_add(UC_HOOK_CODE, hook_code)
# What are we testing here?# We want to know that the change back from UND32 to SVC32 restores the banked# registers.# Our state at the start of execution:# CPSR = UND32 mode# SPSR = SVC32 mode# sp_und = &DEAD0000# sp_svc = &12345678# lr-> code to execute in SVC mode (a MVN r0,#0 as a dummy instruction)# pc-> code to execute in UND mode (a MVN dummy instruction, then MOVS pc, lr)# What we observe is that:# the first two instructions execute fine in UND32 mode# we return to SVC32 mode after the MOVS pc, lr instruction# we begin execution at 0x12000, the expected address# BUT sp has been set to 0.# This is a serious fault and makes handling of undefined instructions impossible.# Why is this a problem?# My OS implementation (pyromaniac.riscos.online) is reliant on the UND mode# behaviour in order to emulate FPA instructions. This worked under Unicorn 1,# but does not under Unicorn 2.# emulate machine code in infinite timemu.emu_start(ADDRESS_UND, ADDRESS_SVC+len(code))
# now print out some registersprint(">>> Emulation done. Below is the CPU context")
print(" CPSR = 0x{:08x}".format(mu.reg_read(UC_ARM_REG_CPSR)))
print(" SPSR = 0x{:08x}".format(mu.reg_read(UC_ARM_REG_SPSR)))
print(" SP = 0x{:08x}".format(mu.reg_read(UC_ARM_REG_R13)))
print(" PC = 0x{:08x}".format(mu.reg_read(UC_ARM_REG_R15)))
exceptUcErrorase:
print("ERROR: %s"%e)
if__name__=='__main__':
test_arm()
Failing output (Unicorn 2)
This produces the following output on Unicorn 2 (failing output):
Testing under Unicorn : (2, 0, 262656L)
Header version: (2, 0, 0)
Emulate ARM code
>>> Tracing instruction at 0x10000, instruction size = 0x4
CPSR = 0x4000009b
SPSR = 0x40000093
SP = 0xdead0000
PC = 0x00010000
>>> Tracing instruction at 0x10004, instruction size = 0x4
CPSR = 0x4000009b
SPSR = 0x40000093
SP = 0xdead0000
PC = 0x00010004
>>> Tracing instruction at 0x12000, instruction size = 0x4
CPSR = 0x40000093
SPSR = 0x00000000
SP = 0x00000000
PC = 0x00012000
>>> Emulation done. Below is the CPU context
CPSR = 0x40000093
SPSR = 0x00000000
SP = 0x00000000
PC = 0x00012004
The 3rd traced instruction should have SP =0x12345678
Successful output (Unicorn 1)
Testing under Unicorn : (1, 0, 256L)
Header version: (1, 0, 2)
Emulate ARM code
>>> Tracing instruction at 0x10000, instruction size = 0x4
CPSR = 0x4000009b
SPSR = 0x40000093
SP = 0xdead0000
PC = 0x00010000
>>> Tracing instruction at 0x10004, instruction size = 0x4
CPSR = 0x4000009b
SPSR = 0x40000093
SP = 0xdead0000
PC = 0x00010004
>>> Tracing instruction at 0x12000, instruction size = 0x4
CPSR = 0x40000093
SPSR = 0x00000000
SP = 0x12345678
PC = 0x00012000
>>> Emulation done. Below is the CPU context
CPSR = 0x40000093
SPSR = 0x00000000
SP = 0x12345678
PC = 0x00012000
The text was updated successfully, but these errors were encountered:
I have a large operating system implementation using Unicorn 1. I am looking to upgrade, but although it appears to start correctly for simple things, I have found a problem with the support for UND32 -> SVC32 transitions (possibly others, but this fails early in module initialisation whilst the floating point emulator code is initialising).
Source environment
I built unicorn on the dev branch at sha
87a391d549a339b5d8109c10c6b16bd95130a923
.This has been tested on OSX system on Intel hardware (10.14.6)
Failure mode
The failure appears to be that on return from UND32 to SVC32 (via a
MOVS pc, lr
, with SPSR set to the SVC32 mode) the mode changes, but the stack pointer is corrupted - it becomes 0.What are we testing here?
We want to know that the change back from UND32 to SVC32 restores the banked
registers.
Our state at the start of execution:
CPSR
= UND32 modeSPSR
= SVC32 modesp_und
=0xDEAD0000
sp_svc
=0x12345678
lr
-> code to execute in SVC mode (aMVN r0,#0
as a dummy instruction)pc
-> code to execute in UND mode (aMVN
dummy instruction, thenMOVS pc, lr
)What we observe is that:
MOVS pc, lr
instruction0x12000
, the expected addresssp
has been set to 0.Why is this a problem?
behaviour in order to emulate FPA instructions. This worked under Unicorn 1,
but does not under Unicorn 2 as built here.
Test code
Test code which exhibits this problem here:
Failing output (Unicorn 2)
This produces the following output on Unicorn 2 (failing output):
The 3rd traced instruction should have
SP
=0x12345678
Successful output (Unicorn 1)
The text was updated successfully, but these errors were encountered: