mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-10-30 04:20:35 +00:00 
			
		
		
		
	* 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
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			98 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);
 | |
| }
 |