mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-24 23:08:17 +00:00
da21bd0589
* Move assembly to S files * more assembly files * osx compilation change * makefile mistake * add objcopy from crosstool * use gobjcopy on osx * start cmocka install cleanup * move wget to directory option * move back to cd * fix copy * First cut * free allocated memory * bad idea too much switching between python and c * add debug * cleanup bad size
97 lines
2.3 KiB
C
97 lines
2.3 KiB
C
// Test PC change during the callback. by Nguyen Anh Quynh, 2016
|
|
#include "unicorn_test.h"
|
|
#include "unicorn/unicorn.h"
|
|
#include "sys/stat.h"
|
|
|
|
#define OK(x) uc_assert_success(x)
|
|
|
|
/* Called before every test to set up a new instance */
|
|
static int setup32(void **state)
|
|
{
|
|
uc_engine *uc;
|
|
|
|
OK(uc_open(UC_ARCH_X86, UC_MODE_32, &uc));
|
|
|
|
*state = uc;
|
|
return 0;
|
|
}
|
|
|
|
/* Called after every test to clean up */
|
|
static int teardown(void **state)
|
|
{
|
|
uc_engine *uc = *state;
|
|
|
|
OK(uc_close(uc));
|
|
|
|
*state = NULL;
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
static void test_code_hook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
|
|
{
|
|
uint8_t tmp[256];
|
|
int32_t r_eip = 0x1000006;
|
|
printf("instruction at 0x%"PRIx64": ", address);
|
|
|
|
if (!uc_mem_read(uc, address, tmp, size)) {
|
|
uint32_t i;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
printf("0x%x ", tmp[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
if (address == 0x1000003) {
|
|
// change the PC to "inc EDX"
|
|
uc_reg_write(uc, UC_X86_REG_EIP, &r_eip);
|
|
}
|
|
}
|
|
|
|
static void test_pc_change(void **state)
|
|
{
|
|
uc_engine *uc = *state;
|
|
uc_hook trace1;
|
|
int32_t r_ecx = 3, r_edx = 15;
|
|
struct stat info;
|
|
char *code = read_file("pc_change.bin", &info);
|
|
|
|
#define BASEADDR 0x1000000
|
|
|
|
uint64_t address = BASEADDR;
|
|
|
|
#undef BASEADDR
|
|
|
|
// map 2MB memory for this emulation
|
|
OK(uc_mem_map(uc, address, 2 * 1024 * 1024, UC_PROT_ALL));
|
|
|
|
// write machine code to be emulated to memory
|
|
OK(uc_mem_write(uc, address, code, info.st_size));
|
|
|
|
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
|
|
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
|
printf("ECX = %u, EDX = %u\n", r_ecx, r_edx);
|
|
|
|
// trace all instructions
|
|
OK(uc_hook_add(uc, &trace1, UC_HOOK_CODE, test_code_hook, NULL, 1, 0));
|
|
|
|
OK(uc_emu_start(uc, address, address+info.st_size, 0, 0));
|
|
|
|
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
|
|
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
|
|
|
|
printf("ECX = %u, EDX = %u\n", r_ecx, r_edx);
|
|
assert_int_equal(r_ecx, 6);
|
|
assert_int_equal(r_edx, 17);
|
|
free(code);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
const struct CMUnitTest tests[] = {
|
|
cmocka_unit_test_setup_teardown(test_pc_change, setup32, teardown),
|
|
};
|
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
|
}
|