From f0dac63b69736577785b29ff318d490f638e67a4 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 16 Jan 2016 18:05:32 -0500 Subject: [PATCH] In response to issue #364, a unit test case has been created for exercising proper flushing of the instruction translation cache. --- tests/unit/Makefile | 5 +- tests/unit/test_tb_x86.c | 301 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test_tb_x86.c diff --git a/tests/unit/Makefile b/tests/unit/Makefile index e70c8071..b261da4d 100644 --- a/tests/unit/Makefile +++ b/tests/unit/Makefile @@ -4,7 +4,8 @@ CFLAGS += -L ../../ CFLAGS += -lcmocka -lunicorn CFLAGS += -I ../../include -ALL_TESTS = test_sanity test_x86 test_mem_map test_mem_high test_mem_map_ptr +ALL_TESTS = test_sanity test_x86 test_mem_map test_mem_high test_mem_map_ptr \ + test_tb_x86 .PHONY: all all: ${ALL_TESTS} @@ -21,12 +22,14 @@ test: ${ALL_TESTS} ./test_mem_map ./test_mem_map_ptr ./test_mem_high + ./test_tb_x86 test_sanity: test_sanity.c test_x86: test_x86.c test_mem_map: test_mem_map.c test_mem_map_ptr: test_mem_map_ptr.c test_mem_high: test_mem_high.c +test_tb_x86: test_tb_x86.c ${ALL_TESTS}: ${CC} ${CFLAGS} -o $@ $^ diff --git a/tests/unit/test_tb_x86.c b/tests/unit/test_tb_x86.c new file mode 100644 index 00000000..ce5eb75e --- /dev/null +++ b/tests/unit/test_tb_x86.c @@ -0,0 +1,301 @@ +/** + * Unicorn x86_32 self-modifying unit test + * + * This test demonstrates the flushing of instruction translation cache + * after a self-modification of Intel's x8's "IMUL Gv,Ev,Ib" instruction. + */ +#include "unicorn_test.h" +#include +#include +#include + + +// Demostration of a self-modifying "IMUL eax,mem,Ib" opcode +// And the QEMU's ability to flush the translation buffer properly + +#define MIN(a, b) (a < b? a: b) + +#define CODE_SPACE (2 * 1024 * 1024) +#define PHY_STACK_REGION (0x60000000) + +#define X86_CODE32_ALPHA_MIXED \ + "\x89\xe1\xd9\xcd\xd9\x71\xf4\x5d\x55\x59\x49\x49\x49\x49\x49\x49" \ + "\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a\x41\x58" \ + "\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30" \ + "\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x51\x51\x51\x52" \ + "\x47\x33\x47\x34\x51\x55\x51\x56\x50\x47\x47\x38\x47\x39\x50\x4a" \ + "\x50\x4b\x50\x4c\x50\x4d\x50\x4e\x50\x4f\x50\x50\x50\x31\x47\x42" \ + "\x47\x42\x50\x34\x50\x5a\x50\x45\x51\x52\x46\x32\x47\x31\x50\x4d" \ + "\x51\x51\x50\x4e\x41\x41" + + +/* Called before every test to set up a new instance */ +static int setup(void **state) +{ + uc_engine *uc; + + uc_assert_success(uc_open(UC_ARCH_X86, UC_MODE_64, &uc)); + + *state = uc; + return 0; +} + + +/* Called after every test to clean up */ +static int teardown(void **state) +{ + uc_engine *uc = *state; + + uc_assert_success(uc_close(uc)); + + *state = NULL; + return 0; +} + + + +static void dump_stack_mem(uc_engine *uc) +{ + uint8_t tmp[256]; + uint32_t size; + + size = sizeof(X86_CODE32_ALPHA_MIXED); + if (size > 255) size = 255; + if (!uc_mem_read(uc, PHY_STACK_REGION, tmp, size)) + { + uint32_t i; + + printf("Stack region dump"); + for (i=0; i