diff --git a/include/uc_priv.h b/include/uc_priv.h index d1a3dab2..a65664a4 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -403,7 +403,7 @@ struct uc_struct { uint32_t tcg_buffer_size; // The buffer size we are going to use #ifdef WIN32 PVOID seh_handle; - void* seh_closure; + void *seh_closure; #endif }; diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index f44f6ed9..e7d9d4d1 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -264,13 +264,15 @@ typedef enum uc_mem_type { @vaddr: virtuall address for lookup @rw: the access mode - @result: result entry, contains physical address (paddr) and permitted access type (perms) for the entry + @result: result entry, contains physical address (paddr) and permitted access + type (perms) for the entry @return: return true if the entry was found. If a callback is present but no one returns true a pagefault is generated. */ -typedef bool (*uc_cb_tlbevent_t)(uc_engine *uc, uint64_t vaddr, uc_mem_type type, - uc_tlb_entry *result, void *user_data); +typedef bool (*uc_cb_tlbevent_t)(uc_engine *uc, uint64_t vaddr, + uc_mem_type type, uc_tlb_entry *result, + void *user_data); // Represent a TranslationBlock. typedef struct uc_tb { @@ -510,11 +512,12 @@ typedef enum uc_query_type { // unicorn tlb type selection typedef enum uc_tlb_type { - // The default unicorn virtuall TLB implementation. + // The default unicorn virtuall TLB implementation. // The tlb implementation of the CPU, best to use for full system emulation. UC_TLB_CPU = 0, // This tlb defaults to virtuall address == physical address - // Also a hook is availible to override the tlb entries (see uc_cb_tlbevent_t). + // Also a hook is availible to override the tlb entries (see + // uc_cb_tlbevent_t). UC_TLB_VIRTUAL } uc_tlb_type; @@ -652,7 +655,8 @@ See sample_ctl.c for a detailed example. uc_ctl(uc, UC_CTL_READ_WRITE(UC_CTL_TB_REQUEST_CACHE, 2), (address), (tb)) #define uc_ctl_flush_tb(uc) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TB_FLUSH, 0)) #define uc_ctl_flush_tlb(uc) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TLB_FLUSH, 0)) -#define uc_ctl_tlb_mode(uc, mode) uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TLB_TYPE, 1), (mode)) +#define uc_ctl_tlb_mode(uc, mode) \ + uc_ctl(uc, UC_CTL_WRITE(UC_CTL_TLB_TYPE, 1), (mode)) #define uc_ctl_get_tcg_buffer_size(uc, size) \ uc_ctl(uc, UC_CTL_READ(UC_CTL_TCG_BUFFER_SIZE, 1), (size)) #define uc_ctl_set_tcg_buffer_size(uc, size) \ diff --git a/msvc/config-host.h b/msvc/config-host.h index d07f74ac..943d8593 100644 --- a/msvc/config-host.h +++ b/msvc/config-host.h @@ -6,4 +6,4 @@ // #define CONFIG_INT128 1 #define CONFIG_CMPXCHG128 1 // #define CONFIG_ATOMIC64 1 -#define CONFIG_PLUGIN 1 \ No newline at end of file +#define CONFIG_PLUGIN 1 diff --git a/qemu/target/i386/unicorn.c b/qemu/target/i386/unicorn.c index a7a93628..540ebd96 100644 --- a/qemu/target/i386/unicorn.c +++ b/qemu/target/i386/unicorn.c @@ -986,7 +986,7 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value, goto write_cr; case UC_X86_REG_CR4: cpu_x86_update_cr4(env, *(uint32_t *)value); -write_cr: + write_cr: env->cr[regid - UC_X86_REG_CR0] = *(uint32_t *)value; break; case UC_X86_REG_DR0: @@ -1169,16 +1169,16 @@ write_cr: default: break; case UC_X86_REG_CR0: - cpu_x86_update_cr0(env, *(uint32_t *) value); + cpu_x86_update_cr0(env, *(uint32_t *)value); goto write_cr64; case UC_X86_REG_CR1: case UC_X86_REG_CR2: case UC_X86_REG_CR3: - cpu_x86_update_cr3(env, *(uint32_t *) value); + cpu_x86_update_cr3(env, *(uint32_t *)value); goto write_cr64; case UC_X86_REG_CR4: - cpu_x86_update_cr4(env, *(uint32_t *) value); -write_cr64: + cpu_x86_update_cr4(env, *(uint32_t *)value); + write_cr64: env->cr[regid - UC_X86_REG_CR0] = *(uint64_t *)value; break; case UC_X86_REG_DR0: diff --git a/samples/sample_arm64.c b/samples/sample_arm64.c index 11f4ca63..84f32c29 100644 --- a/samples/sample_arm64.c +++ b/samples/sample_arm64.c @@ -10,8 +10,8 @@ #define ARM64_CODE \ "\xab\x05\x00\xb8\xaf\x05\x40\x38" // str w11, [x13], #0; ldrb w15, [x13], // #0 -//#define ARM64_CODE_EB "\xb8\x00\x05\xab\x38\x40\x05\xaf" // str w11, [x13]; -// ldrb w15, [x13] +// #define ARM64_CODE_EB "\xb8\x00\x05\xab\x38\x40\x05\xaf" // str w11, [x13]; +// ldrb w15, [x13] #define ARM64_CODE_EB ARM64_CODE // mrs x2, tpidrro_el0 diff --git a/samples/sample_mmu.c b/samples/sample_mmu.c index 84baa2a0..96c526bd 100644 --- a/samples/sample_mmu.c +++ b/samples/sample_mmu.c @@ -18,25 +18,30 @@ * mov rax, 60 * syscall */ -char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05"; +char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00" + "\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00" + "\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05"; -static void mmu_write_callback(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) +static void mmu_write_callback(uc_engine *uc, uc_mem_type type, + uint64_t address, int size, int64_t value, + void *user_data) { printf("write at 0x%lx: 0x%lx\n", address, value); } -static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base) +static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, + uint64_t tlb_base) { uc_err err; uint64_t cr0; uint64_t cr4; uc_x86_msr msr = {.rid = 0xC0000080, .value = 0}; - uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39)*8; - uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30)*8; - uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21)*8; + uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39) * 8; + uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30) * 8; + uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21) * 8; uint64_t pml4e = (tlb_base + 0x1000) | 1 | (1 << 2); - uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2); - uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2); + uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2); + uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2); err = uc_mem_write(uc, tlb_base + pml4o, &pml4e, sizeof(pml4o)); if (err) { printf("failed to write pml4e\n"); @@ -73,10 +78,10 @@ static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base exit(1); } - cr0 |= 1; //enable protected mode - cr0 |= 1l << 31; //enable paging - cr4 |= 1l << 5; //enable physical address extension - msr.value |= 1l << 8; //enable long mode + cr0 |= 1; // enable protected mode + cr0 |= 1l << 31; // enable paging + cr4 |= 1l << 5; // enable physical address extension + msr.value |= 1l << 8; // enable long mode err = uc_reg_write(uc, UC_X86_REG_CR0, &cr0); if (err) { @@ -95,10 +100,11 @@ static void x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base } } -static void x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr, uint64_t tlb_base) +static void x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr, + uint64_t tlb_base) { - uint64_t pto = ((vaddr & 0x000000001ff000) >> 12)*8; - uint32_t pte = (paddr) | 1 | (1 << 2); + uint64_t pto = ((vaddr & 0x000000001ff000) >> 12) * 8; + uint32_t pte = (paddr) | 1 | (1 << 2); uc_mem_write(uc, tlb_base + 0x3000 + pto, &pte, sizeof(pte)); } @@ -162,20 +168,23 @@ void cpu_tlb(void) exit(1); } - err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL); + err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback, + &parrent_done, 1, 0, UC_X86_INS_SYSCALL); if (err) { printf("Failed on uc_hook_add() with error returned: %u\n", err); exit(1); } - // Memory hooks are called after the mmu translation, so hook the physicall addresses - err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL, 0x1000, 0x3000); + // Memory hooks are called after the mmu translation, so hook the physicall + // addresses + err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL, + 0x1000, 0x3000); if (err) { printf("Faled on uc_hook_add() with error returned: %u\n", err); } printf("map code\n"); - err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); //Code + err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); // Code if (err) { printf("Failed on uc_mem_map() with error return: %u\n", err); exit(1); @@ -186,25 +195,24 @@ void cpu_tlb(void) exit(1); } printf("map parrent memory\n"); - err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); //Parrent + err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); // Parrent if (err) { printf("Failed on uc_mem_map() with error return: %u\n", err); exit(1); } printf("map child memory\n"); - err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); //Child + err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); // Child if (err) { printf("failed to map child memory\n"); exit(1); } printf("map tlb memory\n"); - err = uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL); //TLB + err = uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL); // TLB if (err) { printf("failed to map memory for tlb\n"); exit(1); } - printf("set up the tlb\n"); x86_mmu_prepare_tlb(uc, 0x0, tlb_base); x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base); @@ -277,7 +285,8 @@ void cpu_tlb(void) uc_close(uc); } -static bool virtual_tlb_callback(uc_engine *uc, uint64_t addr, uc_mem_type type, uc_tlb_entry *result, void *user_data) +static bool virtual_tlb_callback(uc_engine *uc, uint64_t addr, uc_mem_type type, + uc_tlb_entry *result, void *user_data) { bool *parrent_done = user_data; printf("tlb lookup for address: 0x%lX\n", addr); @@ -324,20 +333,23 @@ void virtual_tlb(void) exit(1); } - err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL); + err = uc_hook_add(uc, &h1, UC_HOOK_INSN, &x86_mmu_syscall_callback, + &parrent_done, 1, 0, UC_X86_INS_SYSCALL); if (err) { printf("Failed on uc_hook_add() with error returned: %u\n", err); exit(1); } - // Memory hooks are called after the mmu translation, so hook the physicall addresses - err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL, 0x1000, 0x3000); + // Memory hooks are called after the mmu translation, so hook the physicall + // addresses + err = uc_hook_add(uc, &h2, UC_HOOK_MEM_WRITE, &mmu_write_callback, NULL, + 0x1000, 0x3000); if (err) { printf("Faled on uc_hook_add() with error returned: %u\n", err); } printf("map code\n"); - err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); //Code + err = uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL); // Code if (err) { printf("Failed on uc_mem_map() with error return: %u\n", err); exit(1); @@ -348,19 +360,20 @@ void virtual_tlb(void) exit(1); } printf("map parrent memory\n"); - err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); //Parrent + err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); // Parrent if (err) { printf("Failed on uc_mem_map() with error return: %u\n", err); exit(1); } printf("map child memory\n"); - err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); //Child + err = uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL); // Child if (err) { printf("failed to map child memory\n"); exit(1); } - err = uc_hook_add(uc, &h3, UC_HOOK_TLB_FILL, virtual_tlb_callback, &parrent_done, 1, 0); + err = uc_hook_add(uc, &h3, UC_HOOK_TLB_FILL, virtual_tlb_callback, + &parrent_done, 1, 0); printf("run the parrent\n"); err = uc_emu_start(uc, 0x2000, 0x0, 0, 0); diff --git a/samples/sample_riscv.c b/samples/sample_riscv.c index 6e36f53a..4096d83b 100644 --- a/samples/sample_riscv.c +++ b/samples/sample_riscv.c @@ -11,7 +11,7 @@ $ cstool riscv64 1305100093850502 0 13 05 10 00 addi a0, zero, 1 4 93 85 05 02 addi a1, a1, 0x20 #endif -//#define RISCV_CODE "\x13\x05\x10\x00\x93\x85\x05\x02\x93\x85\x05\x02" +// #define RISCV_CODE "\x13\x05\x10\x00\x93\x85\x05\x02\x93\x85\x05\x02" #define RISCV_CODE "\x13\x05\x10\x00\x93\x85\x05\x02" // memory address where emulation starts diff --git a/samples/sample_sparc.c b/samples/sample_sparc.c index f7609282..dd847142 100644 --- a/samples/sample_sparc.c +++ b/samples/sample_sparc.c @@ -8,7 +8,7 @@ // code to be emulated #define SPARC_CODE "\x86\x00\x40\x02" // add %g1, %g2, %g3; -//#define SPARC_CODE "\xbb\x70\x00\x00" // illegal code +// #define SPARC_CODE "\xbb\x70\x00\x00" // illegal code // memory address where emulation starts #define ADDRESS 0x10000 diff --git a/samples/sample_x86.c b/samples/sample_x86.c index d8500cc4..735a9985 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -13,7 +13,7 @@ "\xeb\x02\x90\x90\x90\x90\x90\x90" // jmp 4; nop; nop; nop; nop; nop; nop // #define X86_CODE32_SELF // "\xeb\x1c\x5a\x89\xd6\x8b\x02\x66\x3d\xca\x7d\x75\x06\x66\x05\x03\x03\x89\x02\xfe\xc2\x3d\x41\x41\x41\x41\x75\xe9\xff\xe6\xe8\xdf\xff\xff\xff\x31\xd2\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xca\x7d\x41\x41\x41\x41" -//#define X86_CODE32 "\x51\x51\x51\x51" // PUSH ecx; +// #define X86_CODE32 "\x51\x51\x51\x51" // PUSH ecx; #define X86_CODE32_LOOP "\x41\x4a\xeb\xfe" // INC ecx; DEC edx; JMP self-loop #define X86_CODE32_MEM_WRITE \ "\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" // mov [0xaaaaaaaa], ecx; INC ecx; DEC @@ -30,7 +30,7 @@ // AL; INC ebx #define X86_CODE32_INC "\x40" // INC eax -//#define X86_CODE64 "\x41\xBC\x3B\xB0\x28\x2A \x49\x0F\xC9 \x90 +// #define X86_CODE64 "\x41\xBC\x3B\xB0\x28\x2A \x49\x0F\xC9 \x90 //\x4D\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9" // //<== still crash #define X86_CODE64 //"\x41\xBC\x3B\xB0\x28\x2A\x49\x0F\xC9\x90\x4D\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9" diff --git a/tests/unit/acutest.h b/tests/unit/acutest.h index fbe55bc2..8ec7d989 100644 --- a/tests/unit/acutest.h +++ b/tests/unit/acutest.h @@ -270,7 +270,8 @@ #include #include -#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) || defined(__HAIKU__) +#if defined(unix) || defined(__unix__) || defined(__unix) || \ + defined(__APPLE__) || defined(__HAIKU__) #define ACUTEST_UNIX_ 1 #include #include diff --git a/tests/unit/endian.h b/tests/unit/endian.h index a028be75..b42da241 100644 --- a/tests/unit/endian.h +++ b/tests/unit/endian.h @@ -32,53 +32,47 @@ // GNU libc offers the helpful header which defines // __BYTE_ORDER -#if defined (__GLIBC__) -# include -# if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define BOOST_LITTLE_ENDIAN -# elif (__BYTE_ORDER == __BIG_ENDIAN) -# define BOOST_BIG_ENDIAN -# elif (__BYTE_ORDER == __PDP_ENDIAN) -# define BOOST_PDP_ENDIAN -# else +#if defined(__GLIBC__) +#include +#if (__BYTE_ORDER == __LITTLE_ENDIAN) +#define BOOST_LITTLE_ENDIAN +#elif (__BYTE_ORDER == __BIG_ENDIAN) +#define BOOST_BIG_ENDIAN +#elif (__BYTE_ORDER == __PDP_ENDIAN) +#define BOOST_PDP_ENDIAN +#else // Failsafe -# define BOOST_LITTLE_ENDIAN -# endif -# define BOOST_BYTE_ORDER __BYTE_ORDER +#define BOOST_LITTLE_ENDIAN +#endif +#define BOOST_BYTE_ORDER __BYTE_ORDER #elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) -# define BOOST_BIG_ENDIAN -# define BOOST_BYTE_ORDER 4321 +#define BOOST_BIG_ENDIAN +#define BOOST_BYTE_ORDER 4321 #elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) -# define BOOST_LITTLE_ENDIAN -# define BOOST_BYTE_ORDER 1234 +#define BOOST_LITTLE_ENDIAN +#define BOOST_BYTE_ORDER 1234 // https://developer.arm.com/documentation/dui0491/i/Compiler-specific-Features/Predefined-macros -#elif defined(__sparc) || defined(__sparc__) \ - || defined(_POWER) || defined(__powerpc__) \ - || defined(__ppc__) || defined(__hpux) || defined(__hppa) \ - || defined(_MIPSEB) || defined(_POWER) \ - || defined(__s390__) \ - || defined(__ARMEB__) || defined(__AARCH64EB__) \ - || defined(__BIG_ENDIAN) || defined(__ARM_BIG_ENDIAN) -# define BOOST_BIG_ENDIAN -# define BOOST_BYTE_ORDER 4321 -#elif defined(__i386__) || defined(__alpha__) \ - || defined(__ia64) || defined(__ia64__) \ - || defined(_M_IX86) || defined(_M_IA64) \ - || defined(_M_ALPHA) || defined(__amd64) \ - || defined(__amd64__) || defined(_M_AMD64) \ - || defined(__x86_64) || defined(__x86_64__) \ - || defined(_M_X64) || defined(__bfin__) \ - || defined(__ARMEL__) || defined(__AARCH64EL__) \ - || defined(__arm64__) || defined(__arm__) -# define BOOST_LITTLE_ENDIAN -# define BOOST_BYTE_ORDER 1234 +#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || \ + defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || \ + defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || \ + defined(__s390__) || defined(__ARMEB__) || defined(__AARCH64EB__) || \ + defined(__BIG_ENDIAN) || defined(__ARM_BIG_ENDIAN) +#define BOOST_BIG_ENDIAN +#define BOOST_BYTE_ORDER 4321 +#elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || \ + defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || \ + defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || \ + defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_X64) || defined(__bfin__) || defined(__ARMEL__) || \ + defined(__AARCH64EL__) || defined(__arm64__) || defined(__arm__) +#define BOOST_LITTLE_ENDIAN +#define BOOST_BYTE_ORDER 1234 #else // Failsafe -# define BOOST_LITTLE_ENDIAN -# define BOOST_BYTE_ORDER 1234 +#define BOOST_LITTLE_ENDIAN +#define BOOST_BYTE_ORDER 1234 #endif - #endif diff --git a/tests/unit/test_arm64.c b/tests/unit/test_arm64.c index 44f0ad9c..e016dc82 100644 --- a/tests/unit/test_arm64.c +++ b/tests/unit/test_arm64.c @@ -380,7 +380,8 @@ static void test_arm64_mmu(void) char tlbe[8]; uint64_t x0, x1, x2; /* - * Not exact the binary, but aarch64-linux-gnu-as generate this code and reference sometimes data after ttb0_base. + * Not exact the binary, but aarch64-linux-gnu-as generate this code and + reference sometimes data after ttb0_base. * // Read data from physical address * ldr X0, =0x40000000 * ldr X1, [X0] @@ -402,16 +403,21 @@ static void test_arm64_mmu(void) * orr X0, X0, #0x1 // The M bit (MMU). * msr SCTLR_EL1, X0 * dsb SY - * isb + * isb * // Read the same memory area through virtual address * ldr X0, =0x80000000 * ldr X2, [X0] * * // Stop - * b . + * b . */ - char code[] = "\x00\x81\x00\x58\x01\x00\x40\xf9\x00\x81\x00\x58\x40\x20\x18\xd5\x00\x81\x00\x58\x00\xa2\x18\xd5\x40\x7f\x00\x10\x00\x20\x18\xd5\x00\x10\x38\xd5\x00\x00\x7e\xb2\x00\x00\x74\xb2\x00\x00\x40\xb2\x00\x10\x18\xd5\x9f\x3f\x03\xd5\xdf\x3f\x03\xd5\xe0\x7f\x00\x58\x02\x00\x40\xf9\x00\x00\x00\x14\x1f\x20\x03\xd5\x1f\x20\x03\xd5\x1F\x20\x03\xD5\x1F\x20\x03\xD5"; + char code[] = "\x00\x81\x00\x58\x01\x00\x40\xf9\x00\x81\x00\x58\x40\x20\x18" + "\xd5\x00\x81\x00\x58\x00\xa2\x18\xd5\x40\x7f\x00\x10\x00\x20" + "\x18\xd5\x00\x10\x38\xd5\x00\x00\x7e\xb2\x00\x00\x74\xb2\x00" + "\x00\x40\xb2\x00\x10\x18\xd5\x9f\x3f\x03\xd5\xdf\x3f\x03\xd5" + "\xe0\x7f\x00\x58\x02\x00\x40\xf9\x00\x00\x00\x14\x1f\x20\x03" + "\xd5\x1f\x20\x03\xd5\x1F\x20\x03\xD5\x1F\x20\x03\xD5"; data = malloc(0x1000); TEST_CHECK(data != NULL); @@ -436,7 +442,7 @@ static void test_arm64_mmu(void) OK(uc_mem_write(uc, 0x1010, tlbe, sizeof(tlbe))); OK(uc_mem_write(uc, 0x1018, tlbe, sizeof(tlbe))); - //mentioned data referenced by the asm generated my aarch64-linux-gnu-as + // mentioned data referenced by the asm generated my aarch64-linux-gnu-as tlbe[0] = 0; tlbe[1] = 0; OK(uc_mem_write(uc, 0x1020, tlbe, sizeof(tlbe))); @@ -484,7 +490,7 @@ static void test_arm64_pc_wrap(void) uint64_t x0, x1, x2, x3; uint64_t pc = 0xFFFFFFFFFFFFFFFCULL; uint64_t page = 0xFFFFFFFFFFFFF000ULL; - + OK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); OK(uc_mem_map(uc, page, 4096, UC_PROT_READ | UC_PROT_EXEC)); OK(uc_mem_write(uc, pc, add_x1_x2, sizeof(add_x1_x2) - 1)); @@ -500,7 +506,7 @@ static void test_arm64_pc_wrap(void) OK(uc_reg_read(uc, UC_ARM64_REG_X0, &x0)); - TEST_CHECK( (x0 == 1 + 2) ); + TEST_CHECK((x0 == 1 + 2)); OK(uc_mem_map(uc, page, 4096, UC_PROT_READ | UC_PROT_EXEC)); OK(uc_mem_write(uc, pc, add_x1_x3, sizeof(add_x1_x3) - 1)); @@ -518,7 +524,7 @@ static void test_arm64_pc_wrap(void) OK(uc_reg_read(uc, UC_ARM64_REG_X0, &x0)); - TEST_CHECK( (x0 == 5 + 5) ); + TEST_CHECK((x0 == 5 + 5)); OK(uc_close(uc)); } @@ -536,6 +542,6 @@ TEST_LIST = {{"test_arm64_until", test_arm64_until}, {"test_arm64_block_sync_pc", test_arm64_block_sync_pc}, {"test_arm64_block_invalid_mem_read_write_sync", test_arm64_block_invalid_mem_read_write_sync}, - {"test_arm64_mmu", test_arm64_mmu}, - {"test_arm64_pc_wrap", test_arm64_pc_wrap}, + {"test_arm64_mmu", test_arm64_mmu}, + {"test_arm64_pc_wrap", test_arm64_pc_wrap}, {NULL, NULL}}; diff --git a/tests/unit/test_ctl.c b/tests/unit/test_ctl.c index 9cfcd7dd..795d0fe9 100644 --- a/tests/unit/test_ctl.c +++ b/tests/unit/test_ctl.c @@ -304,7 +304,8 @@ static void test_uc_hook_cached_uaf(void) #endif } -static void test_uc_emu_stop_set_ip_callback(uc_engine *uc, uint64_t address, uint32_t size, void *userdata) +static void test_uc_emu_stop_set_ip_callback(uc_engine *uc, uint64_t address, + uint32_t size, void *userdata) { uint64_t rip = code_start + 0xb; @@ -320,27 +321,31 @@ static void test_uc_emu_stop_set_ip(void) uc_hook h; uint64_t rip; - char code[] = "\x48\x31\xc0" // 0x0 xor rax, rax : rax = 0 - "\x90" // 0x3 nop : - "\x48\xff\xc0" // 0x4 inc rax : rax++ - "\x90" // 0x7 nop : <-- going to stop here - "\x48\xff\xc0" // 0x8 inc rax : rax++ - "\x90" // 0xb nop : - "\x0f\x0b" // 0xc ud2 : <-- will raise UC_ERR_INSN_INVALID, but should not never be reached - "\x90" // 0xe nop : - "\x90"; // 0xf nop : + char code[] = + "\x48\x31\xc0" // 0x0 xor rax, rax : rax = 0 + "\x90" // 0x3 nop : + "\x48\xff\xc0" // 0x4 inc rax : rax++ + "\x90" // 0x7 nop : <-- going to stop here + "\x48\xff\xc0" // 0x8 inc rax : rax++ + "\x90" // 0xb nop : + "\x0f\x0b" // 0xc ud2 : <-- will raise + // UC_ERR_INSN_INVALID, but should not never be reached + "\x90" // 0xe nop : + "\x90"; // 0xf nop : uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1); - OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_uc_emu_stop_set_ip_callback, NULL, 1, 0)); + OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_uc_emu_stop_set_ip_callback, NULL, + 1, 0)); OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); OK(uc_reg_read(uc, UC_X86_REG_RIP, &rip)); TEST_CHECK(rip == code_start + 0xb); OK(uc_close(uc)); } -static bool test_tlb_clear_tlb(uc_engine *uc, uint64_t addr, uc_mem_type type, uc_tlb_entry *result, void *user_data) +static bool test_tlb_clear_tlb(uc_engine *uc, uint64_t addr, uc_mem_type type, + uc_tlb_entry *result, void *user_data) { - size_t *tlbcount = (size_t*)user_data; + size_t *tlbcount = (size_t *)user_data; *tlbcount += 1; result->paddr = addr; result->perms = UC_PROT_ALL; @@ -357,14 +362,19 @@ static void test_tlb_clear(void) uc_engine *uc; uc_hook hook1, hook2; size_t tlbcount = 0; - char code[] = "\xa3\x00\x00\x20\x00\x00\x00\x00\x00\x0f\x05\xa3\x00\x00\x20\x00\x00\x00\x00\x00"; //movabs dword ptr [0x200000], eax; syscall; movabs dword ptr [0x200000], eax + char code[] = + "\xa3\x00\x00\x20\x00\x00\x00\x00\x00\x0f\x05\xa3\x00\x00\x20\x00\x00" + "\x00\x00\x00"; // movabs dword ptr [0x200000], eax; syscall; movabs + // dword ptr [0x200000], eax uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1); OK(uc_mem_map(uc, 0x200000, 0x1000, UC_PROT_ALL)); OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL)); - OK(uc_hook_add(uc, &hook1, UC_HOOK_TLB_FILL, test_tlb_clear_tlb, &tlbcount, 1, 0)); - OK(uc_hook_add(uc, &hook2, UC_HOOK_INSN, test_tlb_clear_syscall, NULL, 1, 0, UC_X86_INS_SYSCALL)); + OK(uc_hook_add(uc, &hook1, UC_HOOK_TLB_FILL, test_tlb_clear_tlb, &tlbcount, + 1, 0)); + OK(uc_hook_add(uc, &hook2, UC_HOOK_INSN, test_tlb_clear_syscall, NULL, 1, 0, + UC_X86_INS_SYSCALL)); OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); @@ -373,7 +383,6 @@ static void test_tlb_clear(void) OK(uc_close(uc)); } - TEST_LIST = {{"test_uc_ctl_mode", test_uc_ctl_mode}, {"test_uc_ctl_page_size", test_uc_ctl_page_size}, {"test_uc_ctl_arch", test_uc_ctl_arch}, diff --git a/tests/unit/test_riscv.c b/tests/unit/test_riscv.c index 7c66f89d..cf8b8fbe 100644 --- a/tests/unit/test_riscv.c +++ b/tests/unit/test_riscv.c @@ -634,12 +634,13 @@ static void test_riscv_correct_address_in_long_jump_hook(void) OK(uc_close(uc)); } -static void test_riscv_mmu_prepare_tlb(uc_engine *uc, uint32_t data_address, uint32_t code_address) +static void test_riscv_mmu_prepare_tlb(uc_engine *uc, uint32_t data_address, + uint32_t code_address) { uint64_t tlbe; uint32_t sptbr = 0x2000; - OK(uc_mem_map(uc, sptbr, 0x3000, UC_PROT_ALL)); //tlb base + OK(uc_mem_map(uc, sptbr, 0x3000, UC_PROT_ALL)); // tlb base tlbe = ((sptbr + 0x1000) >> 2) | 1; OK(uc_mem_write(uc, sptbr, &tlbe, sizeof(tlbe))); @@ -647,13 +648,14 @@ static void test_riscv_mmu_prepare_tlb(uc_engine *uc, uint32_t data_address, uin OK(uc_mem_write(uc, sptbr + 0x1000, &tlbe, sizeof(tlbe))); tlbe = (code_address >> 2) | (7 << 1) | 1; - OK(uc_mem_write(uc, sptbr + 0x2000 + 0x15*8, &tlbe, sizeof(tlbe))); + OK(uc_mem_write(uc, sptbr + 0x2000 + 0x15 * 8, &tlbe, sizeof(tlbe))); tlbe = (data_address >> 2) | (7 << 1) | 1; - OK(uc_mem_write(uc, sptbr + 0x2000 + 0x16*8, &tlbe, sizeof(tlbe))); + OK(uc_mem_write(uc, sptbr + 0x2000 + 0x16 * 8, &tlbe, sizeof(tlbe))); } -static void test_riscv_mmu_hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *userdata) +static void test_riscv_mmu_hook_code(uc_engine *uc, uint64_t address, + uint32_t size, void *userdata) { if (address == 0x15010) { OK(uc_emu_stop(uc)); @@ -678,7 +680,16 @@ static void test_riscv_mmu(void) csrw mepc, t1 mret */ - char code_m[] = "\x1b\x0e\xf0\xff" "\x13\x1e\xfe\x03" "\x13\x0e\x2e\x00" "\x73\x10\x0e\x18" "\xb7\x12\x00\x00" "\x9b\x82\x02\x82" "\x73\x90\x02\x30" "\x37\x53\x01\x00" "\x73\x10\x13\x34" "\x73\x00\x20\x30"; + char code_m[] = "\x1b\x0e\xf0\xff" + "\x13\x1e\xfe\x03" + "\x13\x0e\x2e\x00" + "\x73\x10\x0e\x18" + "\xb7\x12\x00\x00" + "\x9b\x82\x02\x82" + "\x73\x90\x02\x30" + "\x37\x53\x01\x00" + "\x73\x10\x13\x34" + "\x73\x00\x20\x30"; /* li t0, 0x41414141 @@ -686,7 +697,11 @@ static void test_riscv_mmu(void) sw t0, 0(t1) nop */ - char code_s[] = "\xb7\x42\x41\x41" "\x9b\x82\x12\x14" "\x37\x63\x01\x00" "\x23\x20\x53\x00" "\x13\x00\x00\x00"; + char code_s[] = "\xb7\x42\x41\x41" + "\x9b\x82\x12\x14" + "\x37\x63\x01\x00" + "\x23\x20\x53\x00" + "\x13\x00\x00\x00"; OK(uc_open(UC_ARCH_RISCV, UC_MODE_RISCV64, &uc)); OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU)); diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index 61625e82..c55b9e36 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -1125,8 +1125,8 @@ static void test_x86_invalid_vex_l(void) OK(uc_close(uc)); } -// AARCH64 inline the read while s390x won't split the access. Though not tested on other hosts -// but we restrict a bit more. +// AARCH64 inline the read while s390x won't split the access. Though not tested +// on other hosts but we restrict a bit more. #if !defined(TARGET_READ_INLINED) && defined(BOOST_LITTLE_ENDIAN) struct writelog_t { @@ -1230,7 +1230,8 @@ static void test_x86_lazy_mapping(void) OK(uc_close(uc)); } -static void test_x86_16_incorrect_ip_cb(uc_engine *uc, uint64_t address, uint32_t size, void* data) +static void test_x86_16_incorrect_ip_cb(uc_engine *uc, uint64_t address, + uint32_t size, void *data) { uint16_t cs, ip; @@ -1250,27 +1251,30 @@ static void test_x86_16_incorrect_ip(void) uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_16, code, sizeof(code) - 1); - OK(uc_hook_add(uc, &hk1, UC_HOOK_BLOCK, test_x86_16_incorrect_ip_cb, NULL, 1, 0)); - OK(uc_hook_add(uc, &hk2, UC_HOOK_CODE, test_x86_16_incorrect_ip_cb, NULL, 1, 0)); - + OK(uc_hook_add(uc, &hk1, UC_HOOK_BLOCK, test_x86_16_incorrect_ip_cb, NULL, + 1, 0)); + OK(uc_hook_add(uc, &hk2, UC_HOOK_CODE, test_x86_16_incorrect_ip_cb, NULL, 1, + 0)); + OK(uc_reg_write(uc, UC_X86_REG_CS, &cs)); - + OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); OK(uc_close(uc)); } -static void test_x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb_base) +static void test_x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, + uint64_t tlb_base) { uint64_t cr0; uint64_t cr4; uc_x86_msr msr = {.rid = 0x0c0000080, .value = 0}; - uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39)*8; - uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30)*8; - uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21)*8; + uint64_t pml4o = ((vaddr & 0x00ff8000000000) >> 39) * 8; + uint64_t pdpo = ((vaddr & 0x00007fc0000000) >> 30) * 8; + uint64_t pdo = ((vaddr & 0x0000003fe00000) >> 21) * 8; uint64_t pml4e = (tlb_base + 0x1000) | 1 | (1 << 2); - uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2); - uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2); + uint64_t pdpe = (tlb_base + 0x2000) | 1 | (1 << 2); + uint64_t pde = (tlb_base + 0x3000) | 1 | (1 << 2); OK(uc_mem_write(uc, tlb_base + pml4o, &pml4e, sizeof(pml4o))); OK(uc_mem_write(uc, tlb_base + 0x1000 + pdpo, &pdpe, sizeof(pdpe))); OK(uc_mem_write(uc, tlb_base + 0x2000 + pdo, &pde, sizeof(pde))); @@ -1287,10 +1291,11 @@ static void test_x86_mmu_prepare_tlb(uc_engine *uc, uint64_t vaddr, uint64_t tlb OK(uc_reg_write(uc, UC_X86_REG_MSR, &msr)); } -static void test_x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr, uint64_t tlb_base) +static void test_x86_mmu_pt_set(uc_engine *uc, uint64_t vaddr, uint64_t paddr, + uint64_t tlb_base) { - uint64_t pto = ((vaddr & 0x000000001ff000) >> 12)*8; - uint32_t pte = (paddr) | 1 | (1 << 2); + uint64_t pto = ((vaddr & 0x000000001ff000) >> 12) * 8; + uint32_t pte = (paddr) | 1 | (1 << 2); uc_mem_write(uc, tlb_base + 0x3000 + pto, &pte, sizeof(pte)); } @@ -1346,18 +1351,22 @@ static void test_x86_mmu(void) * mov rax, 60 * syscall */ - char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05"; + char code[] = + "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00" + "\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89" + "\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05"; OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc)); OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU)); - OK(uc_hook_add(uc, &h1, UC_HOOK_INSN, &test_x86_mmu_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL)); + OK(uc_hook_add(uc, &h1, UC_HOOK_INSN, &test_x86_mmu_callback, &parrent_done, + 1, 0, UC_X86_INS_SYSCALL)); OK(uc_context_alloc(uc, &context)); - OK(uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL)); //Code + OK(uc_mem_map(uc, 0x0, 0x1000, UC_PROT_ALL)); // Code OK(uc_mem_write(uc, 0x0, code, sizeof(code) - 1)); - OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL)); //Parrent - OK(uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL)); //Child - OK(uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL)); //TLB + OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL)); // Parrent + OK(uc_mem_map(uc, 0x2000, 0x1000, UC_PROT_ALL)); // Child + OK(uc_mem_map(uc, tlb_base, 0x4000, UC_PROT_ALL)); // TLB test_x86_mmu_prepare_tlb(uc, 0x0, tlb_base); test_x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base); @@ -1386,7 +1395,9 @@ static void test_x86_mmu(void) TEST_CHECK(child == 42); } -static bool test_x86_vtlb_callback(uc_engine *uc, uint64_t addr, uc_mem_type type, uc_tlb_entry *result, void *user_data) +static bool test_x86_vtlb_callback(uc_engine *uc, uint64_t addr, + uc_mem_type type, uc_tlb_entry *result, + void *user_data) { result->paddr = addr; result->perms = UC_PROT_ALL; @@ -1404,7 +1415,8 @@ static void test_x86_vtlb(void) uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1); OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL)); - OK(uc_hook_add(uc, &hook, UC_HOOK_TLB_FILL, test_x86_vtlb_callback, NULL, 1, 0)); + OK(uc_hook_add(uc, &hook, UC_HOOK_TLB_FILL, test_x86_vtlb_callback, NULL, 1, + 0)); OK(uc_emu_start(uc, code_start, code_start + 4, 0, 0)); @@ -1419,14 +1431,13 @@ static void test_x86_segmentation() { uc_engine *uc; uint64_t fs = 0x53; - uc_x86_mmr gdtr = { 0, 0xfffff8076d962000, 0x57, 0 }; + uc_x86_mmr gdtr = {0, 0xfffff8076d962000, 0x57, 0}; OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc)); OK(uc_reg_write(uc, UC_X86_REG_GDTR, &gdtr)); uc_assert_err(UC_ERR_EXCEPTION, uc_reg_write(uc, UC_X86_REG_FS, &fs)); } - TEST_LIST = { {"test_x86_in", test_x86_in}, {"test_x86_out", test_x86_out}, diff --git a/tests/unit/unicorn_test.h b/tests/unit/unicorn_test.h index dbc17a27..86fe24a6 100644 --- a/tests/unit/unicorn_test.h +++ b/tests/unit/unicorn_test.h @@ -10,20 +10,19 @@ // Copied from glibc-2.29 /* Swap bytes in 32 bit value. */ -#define bswap_32(x) \ - ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \ - (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24)) +#define bswap_32(x) \ + ((((x)&0xff000000u) >> 24) | (((x)&0x00ff0000u) >> 8) | \ + (((x)&0x0000ff00u) << 8) | (((x)&0x000000ffu) << 24)) /* Swap bytes in 64 bit value. */ -#define bswap_64(x) \ - ((((x) & 0xff00000000000000ull) >> 56) \ - | (((x) & 0x00ff000000000000ull) >> 40) \ - | (((x) & 0x0000ff0000000000ull) >> 24) \ - | (((x) & 0x000000ff00000000ull) >> 8) \ - | (((x) & 0x00000000ff000000ull) << 8) \ - | (((x) & 0x0000000000ff0000ull) << 24) \ - | (((x) & 0x000000000000ff00ull) << 40) \ - | (((x) & 0x00000000000000ffull) << 56)) +#define bswap_64(x) \ + ((((x)&0xff00000000000000ull) >> 56) | \ + (((x)&0x00ff000000000000ull) >> 40) | \ + (((x)&0x0000ff0000000000ull) >> 24) | \ + (((x)&0x000000ff00000000ull) >> 8) | (((x)&0x00000000ff000000ull) << 8) | \ + (((x)&0x0000000000ff0000ull) << 24) | \ + (((x)&0x000000000000ff00ull) << 40) | \ + (((x)&0x00000000000000ffull) << 56)) /** * Assert that err matches expect diff --git a/uc.c b/uc.c index a07ff789..81a89861 100644 --- a/uc.c +++ b/uc.c @@ -1495,16 +1495,14 @@ MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) // try with the cache index first i = uc->mapped_block_cache_index; - if (i < uc->mapped_block_count && - address >= uc->mapped_blocks[i]->addr && + if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && address <= uc->mapped_blocks[i]->end - 1) { return uc->mapped_blocks[i]; } i = bsearch_mapped_blocks(uc, address); - if (i < uc->mapped_block_count && - address >= uc->mapped_blocks[i]->addr && + if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && address <= uc->mapped_blocks[i]->end - 1) { uc->mapped_block_cache_index = i; return uc->mapped_blocks[i];