add @model argument to uc_open() to enable selection of CPU model. this fixes the issue #117

This commit is contained in:
Nguyen Anh Quynh 2015-10-26 23:15:59 +08:00
parent 24a7036a87
commit a11265521a
29 changed files with 67 additions and 56 deletions

View file

@ -92,7 +92,7 @@ uc_hook_h = ctypes.c_size_t
_setup_prototype(_uc, "uc_version", ctypes.c_uint, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
_setup_prototype(_uc, "uc_arch_supported", ctypes.c_bool, ctypes.c_int)
_setup_prototype(_uc, "uc_open", ucerr, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(uc_engine))
_setup_prototype(_uc, "uc_open", ucerr, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(uc_engine))
_setup_prototype(_uc, "uc_close", ucerr, uc_engine)
_setup_prototype(_uc, "uc_strerror", ctypes.c_char_p, ucerr)
_setup_prototype(_uc, "uc_errno", ucerr, uc_engine)
@ -151,7 +151,7 @@ def uc_arch_supported(query):
class Uc(object):
def __init__(self, arch, mode):
def __init__(self, arch, mode, model=None):
# verify version compatibility with the core before doing anything
(major, minor, _combined) = uc_version()
if major != UC_API_MAJOR or minor != UC_API_MINOR:
@ -161,7 +161,7 @@ class Uc(object):
self._arch, self._mode = arch, mode
self._uch = ctypes.c_void_p()
status = _uc.uc_open(arch, mode, ctypes.byref(self._uch))
status = _uc.uc_open(arch, mode, model, ctypes.byref(self._uch))
if status != UC_ERR_OK:
self._uch = None
raise UcError(status)

View file

@ -71,6 +71,7 @@ struct hook_struct {
struct uc_struct {
uc_arch arch;
uc_mode mode;
char model[32]; // CPU model, or empty ('') for default model
QemuMutex qemu_global_mutex; // qemu/cpus.c
QemuCond qemu_cpu_cond; // qemu/cpus.c
QemuThread *tcg_cpu_thread; // qemu/cpus.c

View file

@ -252,13 +252,14 @@ bool uc_arch_supported(uc_arch arch);
@arch: architecture type (UC_ARCH_*)
@mode: hardware mode. This is combined of UC_MODE_*
@model: CPU model in string, or NULL for default model.
@uc: pointer to uc_engine, which will be updated at return time
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **uc);
uc_err uc_open(uc_arch arch, uc_mode mode, char *model, uc_engine **uc);
/*
Close UC instance: MUST do to release the handle when it is not used anymore.

View file

@ -19,8 +19,13 @@
static void tosa_init(struct uc_struct *uc, MachineState *machine)
{
//cpu_arm_init(uc, "pxa255");
cpu_arm_init(uc, "cortex-a15"); // FIXME
const char *cpu_model = uc->model;
if (cpu_model[0] == '\0') {
cpu_model = "cortex-a15";
}
cpu_arm_init(uc, cpu_model);
}
void tosa_machine_init(struct uc_struct *uc)

View file

@ -38,10 +38,10 @@
static void machvirt_init(struct uc_struct *uc, MachineState *machine)
{
const char *cpu_model = machine->cpu_model;
const char *cpu_model = uc->model;
int n;
if (!cpu_model) {
if (cpu_model[0] == '\0') {
cpu_model = "cortex-a57"; // ARM64
}

View file

@ -110,7 +110,7 @@ static void do_nx_demo(bool cause_fault)
printf("# Example of marking memory NX (%s)\n", cause_fault ? "faulting" : "non-faulting");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok - Failed on uc_open() with error returned: %u\n", err);
return;
@ -193,7 +193,7 @@ static void do_perms_demo(bool change_perms)
printf("# Example of manipulating memory permissions\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok - Failed on uc_open() with error returned: %u\n", err);
return;
@ -271,7 +271,7 @@ static void do_unmap_demo(bool do_unmap)
printf("# Example of unmapping memory\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok - Failed on uc_open() with error returned: %u\n", err);
return;

View file

@ -39,7 +39,7 @@ static void test_arm(void)
printf("Emulate ARM code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -92,7 +92,7 @@ static void test_thumb(void)
printf("Emulate THUMB code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc);
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));

View file

@ -37,7 +37,7 @@ static void test_arm64(void)
printf("Emulate ARM64 code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc);
err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));

View file

@ -52,7 +52,7 @@ static void test_m68k(void)
printf("Emulate M68K code\n");
// Initialize emulator in M68K mode
err = uc_open(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN, &uc);
err = uc_open(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));

View file

@ -36,7 +36,7 @@ static void test_mips_eb(void)
printf("Emulate MIPS code (big-endian)\n");
// Initialize emulator in MIPS mode
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN, &uc);
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -86,7 +86,7 @@ static void test_mips_el(void)
printf("Emulate MIPS code (little-endian)\n");
// Initialize emulator in MIPS mode
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &uc);
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));

View file

@ -38,7 +38,7 @@ static void test_sparc(void)
printf("Emulate SPARC code\n");
// Initialize emulator in Sparc mode
err = uc_open(UC_ARCH_SPARC, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_SPARC, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));

View file

@ -179,7 +179,7 @@ static void test_i386(void)
printf("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -238,7 +238,7 @@ static void test_i386_jump(void)
printf("Emulate i386 code with jump\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -285,7 +285,7 @@ static void test_i386_loop(void)
printf("Emulate i386 code that loop forever\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -337,7 +337,7 @@ static void test_i386_invalid_mem_read(void)
printf("Emulate i386 code that read from invalid memory\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -395,7 +395,7 @@ static void test_i386_invalid_mem_write(void)
printf("Emulate i386 code that write to invalid memory\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -466,7 +466,7 @@ static void test_i386_jump_invalid(void)
printf("Emulate i386 code that jumps to invalid memory\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -522,7 +522,7 @@ static void test_i386_inout(void)
printf("Emulate i386 code with IN/OUT instructions\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -597,7 +597,7 @@ static void test_x86_64(void)
printf("Emulate x86_64 code\n");
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_64, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -698,7 +698,7 @@ static void test_x86_64_syscall(void)
printf("Emulate x86_64 code with 'syscall' instruction\n");
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_64, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
@ -750,7 +750,7 @@ static void test_x86_16(void)
printf("Emulate x86 16-bit code\n");
// Initialize emulator in X86-16bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_16, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;

View file

@ -96,7 +96,7 @@ static void test_i386(void)
printf("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;

View file

@ -33,7 +33,7 @@ int main() {
fprintf(stderr, "# basic block callback test\n");
fprintf(stderr, "# there are only two basic blocks 0x1000000-0x10001ff and 0x1000200-0x10003ff\n");
uc_err err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
uc_err err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);

View file

@ -11,7 +11,7 @@ int main()
int size;
uint8_t *buf;
uc_engine *uc;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, NULL, &uc);
if (err) {
fprintf (stderr, "Cannot initialize unicorn\n");
return 1;

View file

@ -13,7 +13,7 @@ int main()
int i;
uc_err err;
err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
err = uc_open (UC_ARCH_X86, UC_MODE_64, NULL, &uc);
if (err) {
printf ("uc_open %d\n", err);
return 1;

View file

@ -15,7 +15,7 @@ int main(int argc, char **argv, char **envp)
uc_err err;
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok - Failed on uc_open() with error returned: %u\n", err);
return -1;

View file

@ -159,7 +159,7 @@ int main(int argc, char **argv, char **envp)
printf("# Memory protect test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;

View file

@ -177,7 +177,7 @@ int main(int argc, char **argv, char **envp)
printf("# Memory protect test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;

View file

@ -172,7 +172,7 @@ int main(int argc, char **argv, char **envp)
printf("# Memory unmapping test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;

View file

@ -62,7 +62,7 @@ int main(int argc, char **argv, char **envp)
printf("Memory protections test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return 1;

View file

@ -99,7 +99,7 @@ int main(int argc, char **argv, char **envp)
memset(buf1, 'A', 20);
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;

View file

@ -109,7 +109,7 @@ int main(int argc, char **argv, char **envp)
printf("Memory mapping test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return 1;

View file

@ -22,7 +22,7 @@ int main()
uint8_t *buf;
uc_engine *uc;
uc_hook uh_trap;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, NULL, &uc);
if (err) {
fprintf (stderr, "Cannot initialize unicorn\n");
return 1;

View file

@ -12,7 +12,7 @@ int main()
uint8_t *buf;
uc_engine *uc;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, NULL, &uc);
if (err) {
fprintf (stderr, "Cannot initialize unicorn\n");
return 1;

View file

@ -48,7 +48,7 @@ static void test_arm(void)
printf("Emulate ARM code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -101,7 +101,7 @@ static void test_thumb(void)
printf("Emulate THUMB code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc);
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, NULL, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));

View file

@ -13,7 +13,7 @@ static int setup(void **state)
{
uc_engine *uc;
uc_assert_success(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
uc_assert_success(uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc));
*state = uc;
return 0;

View file

@ -8,7 +8,7 @@ static int setup32(void **state)
{
uc_engine *uc;
OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
OK(uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc));
*state = uc;
return 0;
@ -126,7 +126,7 @@ static void test_i386(void **state)
int r_edx = 0x7890; // EDX register
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -182,7 +182,7 @@ static void test_i386_jump(void **state)
const uint64_t address = 0x1000000;
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -284,7 +284,7 @@ static void test_i386_inout(void **state)
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -349,7 +349,7 @@ static void test_i386_loop(void **state)
};
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -395,7 +395,7 @@ static void test_i386_invalid_mem_read(void **state)
};
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -425,7 +425,7 @@ static void test_i386_invalid_mem_write(void **state)
};
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -456,7 +456,7 @@ static void test_i386_jump_invalid(void **state)
};
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_32, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -536,7 +536,7 @@ static void test_x86_64(void **state)
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_64, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -650,7 +650,7 @@ static void test_x86_64_syscall(void **state)
int64_t rax = 0x100;
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_64, NULL, &uc);
uc_assert_success(err);
// map 2MB memory for this emulation
@ -699,7 +699,7 @@ static void test_x86_16(void **state)
int32_t esi = 6;
// Initialize emulator in X86-16bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
err = uc_open(UC_ARCH_X86, UC_MODE_16, NULL, &uc);
uc_assert_success(err);
// map 8KB memory for this emulation

6
uc.c
View file

@ -134,7 +134,7 @@ bool uc_arch_supported(uc_arch arch)
UNICORN_EXPORT
uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
uc_err uc_open(uc_arch arch, uc_mode mode, char *model, uc_engine **result)
{
struct uc_struct *uc;
@ -148,6 +148,10 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
uc->errnum = UC_ERR_OK;
uc->arch = arch;
uc->mode = mode;
if (model) {
// uc->model[] is already filled with zeros.
strncpy(uc->model, model, sizeof(uc->model) - 1);
}
// uc->cpus = QTAILQ_HEAD_INITIALIZER(uc->cpus);
uc->cpus.tqh_first = NULL;