From 4a62409949c68f36248bd4ece3a47aa30286f7bf Mon Sep 17 00:00:00 2001 From: zhangwm Date: Thu, 4 May 2017 20:00:48 +0800 Subject: [PATCH] arm64eb: arm64 big endian also using little endian instructions. (#816) * arm64eb: arm64 big endian also using little endian instructions. * arm64: using another example that depends on endians. example: 1. store a word: 0x12345678 2. load a byte: * little endian : 0x78 * big endian : 0x12 --- bindings/python/sample_arm64.py | 13 +++++++------ bindings/python/sample_arm64eb.py | 13 +++++++------ qemu/target-arm/translate-a64.c | 4 ++++ samples/sample_arm64.c | 13 +++++++------ samples/sample_arm64eb.c | 14 +++++++------- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/bindings/python/sample_arm64.py b/bindings/python/sample_arm64.py index 0270a401..41bd9c34 100755 --- a/bindings/python/sample_arm64.py +++ b/bindings/python/sample_arm64.py @@ -8,7 +8,7 @@ from unicorn.arm64_const import * # code to be emulated -ARM64_CODE = b"\xab\x01\x0f\x8b" #add x11, x13, x15 +ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13] # memory address where emulation starts ADDRESS = 0x10000 @@ -38,26 +38,27 @@ def test_arm64(): mu.mem_write(ADDRESS, ARM64_CODE) # initialize machine registers - mu.reg_write(UC_ARM64_REG_X11, 0x1234) - mu.reg_write(UC_ARM64_REG_X13, 0x6789) - mu.reg_write(UC_ARM64_REG_X15, 0x3333) + mu.reg_write(UC_ARM64_REG_X11, 0x12345678) + mu.reg_write(UC_ARM64_REG_X13, 0x10008) + mu.reg_write(UC_ARM64_REG_X15, 0x33) # 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) + mu.hook_add(UC_HOOK_CODE, hook_code, begin=ADDRESS, end=ADDRESS) # emulate machine code in infinite time mu.emu_start(ADDRESS, ADDRESS + len(ARM64_CODE)) # now print out some registers print(">>> Emulation done. Below is the CPU context") + print(">>> As little endian, X15 should be 0x78:"); x11 = mu.reg_read(UC_ARM64_REG_X11) x13 = mu.reg_read(UC_ARM64_REG_X13) x15 = mu.reg_read(UC_ARM64_REG_X15) - print(">>> X11 = 0x%x" %x11) + print(">>> X15 = 0x%x" %x15) except UcError as e: print("ERROR: %s" % e) diff --git a/bindings/python/sample_arm64eb.py b/bindings/python/sample_arm64eb.py index 1dc177da..6d46fb5e 100755 --- a/bindings/python/sample_arm64eb.py +++ b/bindings/python/sample_arm64eb.py @@ -9,7 +9,7 @@ from unicorn.arm64_const import * # code to be emulated -ARM64_CODE = b"\x8b\x0f\x01\xab" #add x11, x13, x15 +ARM64_CODE = b"\xab\x05\x00\xb8\xaf\x05\x40\x38" # str x11, [x13]; ldrb x15, [x13] # memory address where emulation starts ADDRESS = 0x10000 @@ -39,26 +39,27 @@ def test_arm64(): mu.mem_write(ADDRESS, ARM64_CODE) # initialize machine registers - mu.reg_write(UC_ARM64_REG_X11, 0x1234) - mu.reg_write(UC_ARM64_REG_X13, 0x6789) - mu.reg_write(UC_ARM64_REG_X15, 0x3333) + mu.reg_write(UC_ARM64_REG_X11, 0x12345678) + mu.reg_write(UC_ARM64_REG_X13, 0x10008) + mu.reg_write(UC_ARM64_REG_X15, 0x33) # 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) + mu.hook_add(UC_HOOK_CODE, hook_code, begin=ADDRESS, end=ADDRESS) # emulate machine code in infinite time mu.emu_start(ADDRESS, ADDRESS + len(ARM64_CODE)) # now print out some registers print(">>> Emulation done. Below is the CPU context") + print(">>> As big endian, X15 should be 0x12:"); x11 = mu.reg_read(UC_ARM64_REG_X11) x13 = mu.reg_read(UC_ARM64_REG_X13) x15 = mu.reg_read(UC_ARM64_REG_X15) - print(">>> X11 = 0x%x" %x11) + print(">>> X15 = 0x%x" %x15) except UcError as e: print("ERROR: %s" % e) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 2953165b..1afaf3d2 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -11059,7 +11059,11 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, dc->aarch64 = 1; dc->thumb = 0; +#if defined(TARGET_WORDS_BIGENDIAN) + dc->bswap_code = 1; +#else dc->bswap_code = 0; +#endif dc->condexec_mask = 0; dc->condexec_cond = 0; #if !defined(CONFIG_USER_ONLY) diff --git a/samples/sample_arm64.c b/samples/sample_arm64.c index 149928ac..537df068 100644 --- a/samples/sample_arm64.c +++ b/samples/sample_arm64.c @@ -8,7 +8,7 @@ // code to be emulated -#define ARM_CODE "\xab\x01\x0f\x8b" // add x11, x13, x15 +#define ARM_CODE "\xab\x05\x00\xb8\xaf\x05\x40\x38" // str x11, [x13]; ldrb x15, [x13] // memory address where emulation starts #define ADDRESS 0x10000 @@ -29,9 +29,9 @@ static void test_arm64(void) uc_err err; uc_hook trace1, trace2; - int64_t x11 = 0x1234; // X11 register - int64_t x13 = 0x6789; // X13 register - int64_t x15 = 0x3333; // X15 register + int64_t x11 = 0x12345678; // X11 register + int64_t x13 = 0x10000 + 0x8; // X13 register + int64_t x15 = 0x33; // X15 register printf("Emulate ARM64 code\n"); @@ -69,9 +69,10 @@ static void test_arm64(void) // now print out some registers printf(">>> Emulation done. Below is the CPU context\n"); + printf(">>> As little endian, X15 should be 0x78:\n"); - uc_reg_read(uc, UC_ARM64_REG_X11, &x11); - printf(">>> X11 = 0x%" PRIx64 "\n", x11); + uc_reg_read(uc, UC_ARM64_REG_X15, &x15); + printf(">>> X15 = 0x%" PRIx64 "\n", x15); uc_close(uc); } diff --git a/samples/sample_arm64eb.c b/samples/sample_arm64eb.c index b09cc22f..1644ebbd 100644 --- a/samples/sample_arm64eb.c +++ b/samples/sample_arm64eb.c @@ -7,9 +7,8 @@ #include #include - // code to be emulated -#define ARM_CODE "\x8b\x0f\x01\xab" // add x11, x13, x15 +#define ARM_CODE "\xab\x05\x00\xb8\xaf\x05\x40\x38" // str x11, [x13]; ldrb x15, [x13] // memory address where emulation starts #define ADDRESS 0x10000 @@ -30,9 +29,9 @@ static void test_arm64(void) uc_err err; uc_hook trace1, trace2; - int64_t x11 = 0x1234; // X11 register - int64_t x13 = 0x6789; // X13 register - int64_t x15 = 0x3333; // X15 register + int64_t x11 = 0x12345678; // X11 register + int64_t x13 = 0x10000 + 0x8; // X13 register + int64_t x15 = 0x33; // X15 register printf("Emulate ARM64 Big-Endian code\n"); @@ -70,9 +69,10 @@ static void test_arm64(void) // now print out some registers printf(">>> Emulation done. Below is the CPU context\n"); + printf(">>> As big endian, X15 should be 0x12:\n"); - uc_reg_read(uc, UC_ARM64_REG_X11, &x11); - printf(">>> X11 = 0x%" PRIx64 "\n", x11); + uc_reg_read(uc, UC_ARM64_REG_X15, &x15); + printf(">>> X15 = 0x%" PRIx64 "\n", x15); uc_close(uc); }