mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-22 19:15:36 +00:00
armeb: Add support for ARM big endian.
This commit is contained in:
parent
ee89c4a421
commit
d8fe34a2e8
5
Makefile
5
Makefile
|
@ -26,8 +26,11 @@ ifneq (,$(findstring x86,$(UNICORN_ARCHS)))
|
|||
endif
|
||||
ifneq (,$(findstring arm,$(UNICORN_ARCHS)))
|
||||
UC_TARGET_OBJ += $(call GENOBJ,arm-softmmu)
|
||||
UC_TARGET_OBJ += $(call GENOBJ,armeb-softmmu)
|
||||
UNICORN_CFLAGS += -DUNICORN_HAS_ARM
|
||||
UNICORN_CFLAGS += -DUNICORN_HAS_ARMEB
|
||||
UNICORN_TARGETS += arm-softmmu,
|
||||
UNICORN_TARGETS += armeb-softmmu,
|
||||
endif
|
||||
ifneq (,$(findstring m68k,$(UNICORN_ARCHS)))
|
||||
UC_TARGET_OBJ += $(call GENOBJ,m68k-softmmu)
|
||||
|
@ -297,7 +300,7 @@ dist:
|
|||
|
||||
# run "make header" whenever qemu/header_gen.py is modified
|
||||
header:
|
||||
$(eval TARGETS := m68k arm aarch64 mips mipsel mips64 mips64el\
|
||||
$(eval TARGETS := m68k arm armeb aarch64 mips mipsel mips64 mips64el\
|
||||
powerpc sparc sparc64 x86_64)
|
||||
$(foreach var,$(TARGETS),\
|
||||
$(shell python qemu/header_gen.py $(var) > qemu/$(var).h;))
|
||||
|
|
105
bindings/python/sample_armeb.py
Executable file
105
bindings/python/sample_armeb.py
Executable file
|
@ -0,0 +1,105 @@
|
|||
#!/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__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm_const import *
|
||||
|
||||
|
||||
# code to be emulated
|
||||
ARM_CODE = b"\xe3\xa0\x00\x37\xe0\x42\x10\x03" # mov r0, #0x37; sub r1, r2, r3
|
||||
THUMB_CODE = b"\xb0\x83" # sub sp, #0xc
|
||||
# memory address where emulation starts
|
||||
ADDRESS = 0x10000
|
||||
|
||||
|
||||
# callback for tracing basic blocks
|
||||
def hook_block(uc, address, size, user_data):
|
||||
print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
|
||||
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc, address, size, user_data):
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
|
||||
|
||||
|
||||
# Test ARM
|
||||
def test_arm():
|
||||
print("Emulate ARM code")
|
||||
try:
|
||||
# Initialize emulator in ARM mode
|
||||
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM | UC_MODE_BIG_ENDIAN)
|
||||
|
||||
# map 2MB memory for this emulation
|
||||
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(ADDRESS, ARM_CODE)
|
||||
|
||||
# initialize machine registers
|
||||
mu.reg_write(UC_ARM_REG_R0, 0x1234)
|
||||
mu.reg_write(UC_ARM_REG_R2, 0x6789)
|
||||
mu.reg_write(UC_ARM_REG_R3, 0x3333)
|
||||
mu.reg_write(UC_ARM_REG_APSR, 0xFFFFFFFF) #All application flags turned on
|
||||
|
||||
# tracing all basic blocks with customized callback
|
||||
mu.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
|
||||
# tracing one instruction at ADDRESS with customized callback
|
||||
mu.hook_add(UC_HOOK_CODE, hook_code, begin=ADDRESS, end=ADDRESS)
|
||||
|
||||
# emulate machine code in infinite time
|
||||
mu.emu_start(ADDRESS, ADDRESS + len(ARM_CODE))
|
||||
|
||||
# now print out some registers
|
||||
print(">>> Emulation done. Below is the CPU context")
|
||||
|
||||
r0 = mu.reg_read(UC_ARM_REG_R0)
|
||||
r1 = mu.reg_read(UC_ARM_REG_R1)
|
||||
print(">>> R0 = 0x%x" %r0)
|
||||
print(">>> R1 = 0x%x" %r1)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
def test_thumb():
|
||||
print("Emulate THUMB code")
|
||||
try:
|
||||
# Initialize emulator in thumb mode
|
||||
mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_BIG_ENDIAN)
|
||||
|
||||
# map 2MB memory for this emulation
|
||||
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(ADDRESS, THUMB_CODE)
|
||||
|
||||
# initialize machine registers
|
||||
mu.reg_write(UC_ARM_REG_SP, 0x1234)
|
||||
|
||||
# tracing all basic blocks with customized callback
|
||||
mu.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
|
||||
# tracing all instructions with customized callback
|
||||
mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||
|
||||
# emulate machine code in infinite time
|
||||
# Note we start at ADDRESS | 1 to indicate THUMB mode.
|
||||
mu.emu_start(ADDRESS | 1, ADDRESS + len(THUMB_CODE))
|
||||
|
||||
# now print out some registers
|
||||
print(">>> Emulation done. Below is the CPU context")
|
||||
|
||||
sp = mu.reg_read(UC_ARM_REG_SP)
|
||||
print(">>> SP = 0x%x" %sp)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_arm()
|
||||
print("=" * 26)
|
||||
test_thumb()
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
// These are masks of supported modes for each cpu/arch.
|
||||
// They should be updated when changes are made to the uc_mode enum typedef.
|
||||
#define UC_MODE_ARM_MASK (UC_MODE_ARM|UC_MODE_THUMB|UC_MODE_LITTLE_ENDIAN|UC_MODE_MCLASS)
|
||||
#define UC_MODE_ARM_MASK (UC_MODE_ARM|UC_MODE_THUMB|UC_MODE_LITTLE_ENDIAN|UC_MODE_MCLASS|UC_MODE_BIG_ENDIAN)
|
||||
#define UC_MODE_MIPS_MASK (UC_MODE_MIPS32|UC_MODE_MIPS64|UC_MODE_LITTLE_ENDIAN|UC_MODE_BIG_ENDIAN)
|
||||
#define UC_MODE_X86_MASK (UC_MODE_16|UC_MODE_32|UC_MODE_64|UC_MODE_LITTLE_ENDIAN)
|
||||
#define UC_MODE_PPC_MASK (UC_MODE_PPC64|UC_MODE_BIG_ENDIAN)
|
||||
|
|
3020
qemu/armeb.h
Normal file
3020
qemu/armeb.h
Normal file
File diff suppressed because it is too large
Load diff
0
qemu/default-configs/armeb-softmmu.mak
Normal file
0
qemu/default-configs/armeb-softmmu.mak
Normal file
|
@ -15,6 +15,7 @@ void arm64_reg_reset(struct uc_struct *uc);
|
|||
|
||||
__attribute__ ((visibility ("default")))
|
||||
void arm_uc_init(struct uc_struct* uc);
|
||||
void armeb_uc_init(struct uc_struct* uc);
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
void arm64_uc_init(struct uc_struct* uc);
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
#include "unicorn_common.h"
|
||||
#include "uc_priv.h"
|
||||
|
||||
|
||||
#ifndef TARGET_WORDS_BIGENDIAN
|
||||
const int ARM_REGS_STORAGE_SIZE = offsetof(CPUARMState, tlb_table);
|
||||
#endif
|
||||
|
||||
static void arm_set_pc(struct uc_struct *uc, uint64_t address)
|
||||
{
|
||||
|
@ -181,7 +182,11 @@ static uc_err arm_query(struct uc_struct *uc, uc_query_type type, size_t *result
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
void armeb_uc_init(struct uc_struct* uc)
|
||||
#else
|
||||
void arm_uc_init(struct uc_struct* uc)
|
||||
#endif
|
||||
{
|
||||
register_accel_types(uc);
|
||||
arm_cpu_register_types(uc);
|
||||
|
|
|
@ -64,6 +64,7 @@ UNICORN_ARCHS := $(shell if [ -e ../config.log ]; then cat ../config.log;\
|
|||
SOURCES =
|
||||
ifneq (,$(findstring arm,$(UNICORN_ARCHS)))
|
||||
SOURCES += sample_arm.c
|
||||
SOURCES += sample_armeb.c
|
||||
endif
|
||||
ifneq (,$(findstring aarch64,$(UNICORN_ARCHS)))
|
||||
SOURCES += sample_arm64.c
|
||||
|
|
9
uc.c
9
uc.c
|
@ -188,12 +188,15 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
|
|||
#endif
|
||||
#ifdef UNICORN_HAS_ARM
|
||||
case UC_ARCH_ARM:
|
||||
if ((mode & ~UC_MODE_ARM_MASK) ||
|
||||
(mode & UC_MODE_BIG_ENDIAN)) {
|
||||
if ((mode & ~UC_MODE_ARM_MASK)) {
|
||||
free(uc);
|
||||
return UC_ERR_MODE;
|
||||
}
|
||||
uc->init_arch = arm_uc_init;
|
||||
if (mode & UC_MODE_BIG_ENDIAN) {
|
||||
uc->init_arch = armeb_uc_init;
|
||||
} else {
|
||||
uc->init_arch = arm_uc_init;
|
||||
}
|
||||
|
||||
if (mode & UC_MODE_THUMB)
|
||||
uc->thumb = 1;
|
||||
|
|
Loading…
Reference in a new issue