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
|
endif
|
||||||
ifneq (,$(findstring arm,$(UNICORN_ARCHS)))
|
ifneq (,$(findstring arm,$(UNICORN_ARCHS)))
|
||||||
UC_TARGET_OBJ += $(call GENOBJ,arm-softmmu)
|
UC_TARGET_OBJ += $(call GENOBJ,arm-softmmu)
|
||||||
|
UC_TARGET_OBJ += $(call GENOBJ,armeb-softmmu)
|
||||||
UNICORN_CFLAGS += -DUNICORN_HAS_ARM
|
UNICORN_CFLAGS += -DUNICORN_HAS_ARM
|
||||||
|
UNICORN_CFLAGS += -DUNICORN_HAS_ARMEB
|
||||||
UNICORN_TARGETS += arm-softmmu,
|
UNICORN_TARGETS += arm-softmmu,
|
||||||
|
UNICORN_TARGETS += armeb-softmmu,
|
||||||
endif
|
endif
|
||||||
ifneq (,$(findstring m68k,$(UNICORN_ARCHS)))
|
ifneq (,$(findstring m68k,$(UNICORN_ARCHS)))
|
||||||
UC_TARGET_OBJ += $(call GENOBJ,m68k-softmmu)
|
UC_TARGET_OBJ += $(call GENOBJ,m68k-softmmu)
|
||||||
|
@ -297,7 +300,7 @@ dist:
|
||||||
|
|
||||||
# run "make header" whenever qemu/header_gen.py is modified
|
# run "make header" whenever qemu/header_gen.py is modified
|
||||||
header:
|
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)
|
powerpc sparc sparc64 x86_64)
|
||||||
$(foreach var,$(TARGETS),\
|
$(foreach var,$(TARGETS),\
|
||||||
$(shell python qemu/header_gen.py $(var) > qemu/$(var).h;))
|
$(shell python qemu/header_gen.py $(var) > qemu/$(var).h;))
|
||||||
|
|
|
@ -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.
|
// These are masks of supported modes for each cpu/arch.
|
||||||
// They should be updated when changes are made to the uc_mode enum typedef.
|
// 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_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_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)
|
#define UC_MODE_PPC_MASK (UC_MODE_PPC64|UC_MODE_BIG_ENDIAN)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,7 @@ void arm64_reg_reset(struct uc_struct *uc);
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
__attribute__ ((visibility ("default")))
|
||||||
void arm_uc_init(struct uc_struct* uc);
|
void arm_uc_init(struct uc_struct* uc);
|
||||||
|
void armeb_uc_init(struct uc_struct* uc);
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
__attribute__ ((visibility ("default")))
|
||||||
void arm64_uc_init(struct uc_struct* uc);
|
void arm64_uc_init(struct uc_struct* uc);
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
#include "unicorn_common.h"
|
#include "unicorn_common.h"
|
||||||
#include "uc_priv.h"
|
#include "uc_priv.h"
|
||||||
|
|
||||||
|
#ifndef TARGET_WORDS_BIGENDIAN
|
||||||
const int ARM_REGS_STORAGE_SIZE = offsetof(CPUARMState, tlb_table);
|
const int ARM_REGS_STORAGE_SIZE = offsetof(CPUARMState, tlb_table);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void arm_set_pc(struct uc_struct *uc, uint64_t address)
|
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)
|
void arm_uc_init(struct uc_struct* uc)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
register_accel_types(uc);
|
register_accel_types(uc);
|
||||||
arm_cpu_register_types(uc);
|
arm_cpu_register_types(uc);
|
||||||
|
|
|
@ -64,6 +64,7 @@ UNICORN_ARCHS := $(shell if [ -e ../config.log ]; then cat ../config.log;\
|
||||||
SOURCES =
|
SOURCES =
|
||||||
ifneq (,$(findstring arm,$(UNICORN_ARCHS)))
|
ifneq (,$(findstring arm,$(UNICORN_ARCHS)))
|
||||||
SOURCES += sample_arm.c
|
SOURCES += sample_arm.c
|
||||||
|
SOURCES += sample_armeb.c
|
||||||
endif
|
endif
|
||||||
ifneq (,$(findstring aarch64,$(UNICORN_ARCHS)))
|
ifneq (,$(findstring aarch64,$(UNICORN_ARCHS)))
|
||||||
SOURCES += sample_arm64.c
|
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
|
#endif
|
||||||
#ifdef UNICORN_HAS_ARM
|
#ifdef UNICORN_HAS_ARM
|
||||||
case UC_ARCH_ARM:
|
case UC_ARCH_ARM:
|
||||||
if ((mode & ~UC_MODE_ARM_MASK) ||
|
if ((mode & ~UC_MODE_ARM_MASK)) {
|
||||||
(mode & UC_MODE_BIG_ENDIAN)) {
|
|
||||||
free(uc);
|
free(uc);
|
||||||
return UC_ERR_MODE;
|
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)
|
if (mode & UC_MODE_THUMB)
|
||||||
uc->thumb = 1;
|
uc->thumb = 1;
|
||||||
|
|
Loading…
Reference in New Issue