diff --git a/Makefile b/Makefile index 4d7e4e73..c4cb31c7 100644 --- a/Makefile +++ b/Makefile @@ -222,7 +222,7 @@ else endif compile_lib: config qemu/config-host.h-timestamp - rm -rf lib$(LIBNAME)* $(LIBNAME)*.lib $(LIBNAME)*.dll cyg$(LIBNAME)*.dll && cd qemu && $(MAKE) -j 8 + rm -rf lib$(LIBNAME)* $(LIBNAME)*.lib $(LIBNAME)*.dll cyg$(LIBNAME)*.dll && cd qemu && $(MAKE) -j 4 $(MAKE) unicorn cd samples && $(MAKE) clean diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 2deac84f..af24351f 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_AARCH64_H #define UNICORN_AUTOGEN_AARCH64_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_aarch64 +#define tcg_target_deposit_valid tcg_target_deposit_valid_aarch64 #define helper_power_down helper_power_down_aarch64 #define check_exit_request check_exit_request_aarch64 #define address_space_unregister address_space_unregister_aarch64 @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_aarch64 #define tb_reset_jump tb_reset_jump_aarch64 #define tb_set_jmp_target tb_set_jmp_target_aarch64 -#define tb_set_jmp_target1 tb_set_jmp_target1_aarch64 #define tcg_accel_class_init tcg_accel_class_init_aarch64 #define tcg_accel_type tcg_accel_type_aarch64 #define tcg_add_param_i32 tcg_add_param_i32_aarch64 diff --git a/qemu/arm.h b/qemu/arm.h index a5ae3a38..ad95d316 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_ARM_H #define UNICORN_AUTOGEN_ARM_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_arm +#define tcg_target_deposit_valid tcg_target_deposit_valid_arm #define helper_power_down helper_power_down_arm #define check_exit_request check_exit_request_arm #define address_space_unregister address_space_unregister_arm @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_arm #define tb_reset_jump tb_reset_jump_arm #define tb_set_jmp_target tb_set_jmp_target_arm -#define tb_set_jmp_target1 tb_set_jmp_target1_arm #define tcg_accel_class_init tcg_accel_class_init_arm #define tcg_accel_type tcg_accel_type_arm #define tcg_add_param_i32 tcg_add_param_i32_arm diff --git a/qemu/configure b/qemu/configure index 7f6d9164..65d09a3b 100755 --- a/qemu/configure +++ b/qemu/configure @@ -1520,8 +1520,6 @@ echo "PIE $pie" config_host_mak="config-host.mak" -echo "# Automatically generated by configure - do not modify" >config-all-disas.mak - echo "# Automatically generated by configure - do not modify" > $config_host_mak echo >> $config_host_mak @@ -1905,7 +1903,6 @@ ldflags="" if test "$tcg_interpreter" = "yes" ; then echo "CONFIG_TCI_DIS=y" >> $config_target_mak - echo "CONFIG_TCI_DIS=y" >> config-all-disas.mak fi case "$ARCH" in diff --git a/qemu/header_gen.py b/qemu/header_gen.py index d889247d..e9442ecb 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -7,6 +7,8 @@ import sys symbols = ( + 'use_idiv_instructions_rt', + 'tcg_target_deposit_valid', 'helper_power_down', 'check_exit_request', 'address_space_unregister', @@ -2814,7 +2816,6 @@ symbols = ( 'tb_phys_invalidate', 'tb_reset_jump', 'tb_set_jmp_target', - 'tb_set_jmp_target1', 'tcg_accel_class_init', 'tcg_accel_type', 'tcg_add_param_i32', diff --git a/qemu/m68k.h b/qemu/m68k.h index f1a6712f..47420bd2 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_M68K_H #define UNICORN_AUTOGEN_M68K_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_m68k +#define tcg_target_deposit_valid tcg_target_deposit_valid_m68k #define helper_power_down helper_power_down_m68k #define check_exit_request check_exit_request_m68k #define address_space_unregister address_space_unregister_m68k @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_m68k #define tb_reset_jump tb_reset_jump_m68k #define tb_set_jmp_target tb_set_jmp_target_m68k -#define tb_set_jmp_target1 tb_set_jmp_target1_m68k #define tcg_accel_class_init tcg_accel_class_init_m68k #define tcg_accel_type tcg_accel_type_m68k #define tcg_add_param_i32 tcg_add_param_i32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index ed7e86d1..b3c31bbb 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_MIPS_H #define UNICORN_AUTOGEN_MIPS_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_mips +#define tcg_target_deposit_valid tcg_target_deposit_valid_mips #define helper_power_down helper_power_down_mips #define check_exit_request check_exit_request_mips #define address_space_unregister address_space_unregister_mips @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_mips #define tb_reset_jump tb_reset_jump_mips #define tb_set_jmp_target tb_set_jmp_target_mips -#define tb_set_jmp_target1 tb_set_jmp_target1_mips #define tcg_accel_class_init tcg_accel_class_init_mips #define tcg_accel_type tcg_accel_type_mips #define tcg_add_param_i32 tcg_add_param_i32_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 96ff3baa..d3938116 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_MIPS64_H #define UNICORN_AUTOGEN_MIPS64_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64 +#define tcg_target_deposit_valid tcg_target_deposit_valid_mips64 #define helper_power_down helper_power_down_mips64 #define check_exit_request check_exit_request_mips64 #define address_space_unregister address_space_unregister_mips64 @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_mips64 #define tb_reset_jump tb_reset_jump_mips64 #define tb_set_jmp_target tb_set_jmp_target_mips64 -#define tb_set_jmp_target1 tb_set_jmp_target1_mips64 #define tcg_accel_class_init tcg_accel_class_init_mips64 #define tcg_accel_type tcg_accel_type_mips64 #define tcg_add_param_i32 tcg_add_param_i32_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 60315919..362bb30d 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_MIPS64EL_H #define UNICORN_AUTOGEN_MIPS64EL_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64el +#define tcg_target_deposit_valid tcg_target_deposit_valid_mips64el #define helper_power_down helper_power_down_mips64el #define check_exit_request check_exit_request_mips64el #define address_space_unregister address_space_unregister_mips64el @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_mips64el #define tb_reset_jump tb_reset_jump_mips64el #define tb_set_jmp_target tb_set_jmp_target_mips64el -#define tb_set_jmp_target1 tb_set_jmp_target1_mips64el #define tcg_accel_class_init tcg_accel_class_init_mips64el #define tcg_accel_type tcg_accel_type_mips64el #define tcg_add_param_i32 tcg_add_param_i32_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 54c454f8..5e71bef9 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_MIPSEL_H #define UNICORN_AUTOGEN_MIPSEL_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_mipsel +#define tcg_target_deposit_valid tcg_target_deposit_valid_mipsel #define helper_power_down helper_power_down_mipsel #define check_exit_request check_exit_request_mipsel #define address_space_unregister address_space_unregister_mipsel @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_mipsel #define tb_reset_jump tb_reset_jump_mipsel #define tb_set_jmp_target tb_set_jmp_target_mipsel -#define tb_set_jmp_target1 tb_set_jmp_target1_mipsel #define tcg_accel_class_init tcg_accel_class_init_mipsel #define tcg_accel_type tcg_accel_type_mipsel #define tcg_add_param_i32 tcg_add_param_i32_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 7cd2c00d..22dad739 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_POWERPC_H #define UNICORN_AUTOGEN_POWERPC_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_powerpc +#define tcg_target_deposit_valid tcg_target_deposit_valid_powerpc #define helper_power_down helper_power_down_powerpc #define check_exit_request check_exit_request_powerpc #define address_space_unregister address_space_unregister_powerpc @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_powerpc #define tb_reset_jump tb_reset_jump_powerpc #define tb_set_jmp_target tb_set_jmp_target_powerpc -#define tb_set_jmp_target1 tb_set_jmp_target1_powerpc #define tcg_accel_class_init tcg_accel_class_init_powerpc #define tcg_accel_type tcg_accel_type_powerpc #define tcg_add_param_i32 tcg_add_param_i32_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index c30dd375..7c78c2e2 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_SPARC_H #define UNICORN_AUTOGEN_SPARC_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc +#define tcg_target_deposit_valid tcg_target_deposit_valid_sparc #define helper_power_down helper_power_down_sparc #define check_exit_request check_exit_request_sparc #define address_space_unregister address_space_unregister_sparc @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_sparc #define tb_reset_jump tb_reset_jump_sparc #define tb_set_jmp_target tb_set_jmp_target_sparc -#define tb_set_jmp_target1 tb_set_jmp_target1_sparc #define tcg_accel_class_init tcg_accel_class_init_sparc #define tcg_accel_type tcg_accel_type_sparc #define tcg_add_param_i32 tcg_add_param_i32_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index c7824ebf..681a7086 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_SPARC64_H #define UNICORN_AUTOGEN_SPARC64_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc64 +#define tcg_target_deposit_valid tcg_target_deposit_valid_sparc64 #define helper_power_down helper_power_down_sparc64 #define check_exit_request check_exit_request_sparc64 #define address_space_unregister address_space_unregister_sparc64 @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_sparc64 #define tb_reset_jump tb_reset_jump_sparc64 #define tb_set_jmp_target tb_set_jmp_target_sparc64 -#define tb_set_jmp_target1 tb_set_jmp_target1_sparc64 #define tcg_accel_class_init tcg_accel_class_init_sparc64 #define tcg_accel_type tcg_accel_type_sparc64 #define tcg_add_param_i32 tcg_add_param_i32_sparc64 diff --git a/qemu/tcg/aarch64/tcg-target.c b/qemu/tcg/aarch64/tcg-target.c index 6dff1756..ce8360f6 100644 --- a/qemu/tcg/aarch64/tcg-target.c +++ b/qemu/tcg/aarch64/tcg-target.c @@ -1241,7 +1241,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, { /* 99% of the time, we can signal the use of extension registers by looking to see if the opcode handles 64-bit data. */ - TCGType ext = (tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0; + TCGType ext = (s->tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0; /* Hoist the loads of the most common arguments. */ TCGArg a0 = args[0]; diff --git a/qemu/tcg/arm/tcg-target.c b/qemu/tcg/arm/tcg-target.c index cabbd1f1..17289d92 100644 --- a/qemu/tcg/arm/tcg-target.c +++ b/qemu/tcg/arm/tcg-target.c @@ -56,8 +56,8 @@ static int arm_arch = __ARM_ARCH; #define use_armv6_instructions (__ARM_ARCH >= 6 || arm_arch >= 6) #define use_armv7_instructions (__ARM_ARCH >= 7 || arm_arch >= 7) -#ifndef use_idiv_instructions -bool use_idiv_instructions; +#ifndef __ARM_ARCH_EXT_IDIV__ +bool use_idiv_instructions_rt; #endif /* ??? Ought to think about changing CONFIG_SOFTMMU to always defined. */ @@ -1981,10 +1981,10 @@ static void tcg_target_init(TCGContext *s) { /* Only probe for the platform and capabilities if we havn't already determined maximum values at compile time. */ -#ifndef use_idiv_instructions +#ifndef __ARM_ARCH_EXT_IDIV__ { unsigned long hwcap = qemu_getauxval(AT_HWCAP); - use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0; + use_idiv_instructions_rt = (hwcap & HWCAP_ARM_IDIVA) != 0; } #endif if (__ARM_ARCH < 7) { diff --git a/qemu/tcg/arm/tcg-target.h b/qemu/tcg/arm/tcg-target.h index 1c719e28..a6ea9763 100644 --- a/qemu/tcg/arm/tcg-target.h +++ b/qemu/tcg/arm/tcg-target.h @@ -52,7 +52,8 @@ typedef enum { #ifdef __ARM_ARCH_EXT_IDIV__ #define use_idiv_instructions 1 #else -extern bool use_idiv_instructions; +extern bool use_idiv_instructions_rt; +#define use_idiv_instructions use_idiv_instructions_rt #endif diff --git a/qemu/util/Makefile.objs b/qemu/util/Makefile.objs index 25e6bf34..9f4021b9 100644 --- a/qemu/util/Makefile.objs +++ b/qemu/util/Makefile.objs @@ -8,3 +8,4 @@ util-obj-y += aes.o util-obj-y += qemu-option.o util-obj-y += crc32c.o util-obj-y += host-utils.o +util-obj-y += getauxval.o diff --git a/qemu/util/getauxval.c b/qemu/util/getauxval.c new file mode 100644 index 00000000..208bfa39 --- /dev/null +++ b/qemu/util/getauxval.c @@ -0,0 +1,109 @@ +/* + * QEMU access to the auxiliary vector + * + * Copyright (C) 2013 Red Hat, Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu-common.h" +#include "qemu/osdep.h" + +#ifdef CONFIG_GETAUXVAL +/* Don't inline this in qemu/osdep.h, because pulling in for + the system declaration of getauxval pulls in the system , which + conflicts with qemu's version. */ + +#include + +unsigned long qemu_getauxval(unsigned long key) +{ + return getauxval(key); +} +#elif defined(__linux__) +#include "elf.h" + +/* Our elf.h doesn't contain Elf32_auxv_t and Elf64_auxv_t, which is ok because + that just makes it easier to define it properly for the host here. */ +typedef struct { + unsigned long a_type; + unsigned long a_val; +} ElfW_auxv_t; + +static const ElfW_auxv_t *auxv; + +static const ElfW_auxv_t *qemu_init_auxval(void) +{ + ElfW_auxv_t *a; + ssize_t size = 512, r, ofs; + int fd; + + /* Allocate some initial storage. Make sure the first entry is set + to end-of-list, so that we've got a valid list in case of error. */ + auxv = a = g_malloc(size); + a[0].a_type = 0; + a[0].a_val = 0; + + fd = open("/proc/self/auxv", O_RDONLY); + if (fd < 0) { + return a; + } + + /* Read the first SIZE bytes. Hopefully, this covers everything. */ + r = read(fd, a, size); + + if (r == size) { + /* Continue to expand until we do get a partial read. */ + do { + ofs = size; + size *= 2; + auxv = a = g_realloc(a, size); + r = read(fd, (char *)a + ofs, ofs); + } while (r == ofs); +} + + close(fd); + return a; +} + +unsigned long qemu_getauxval(unsigned long type) +{ + const ElfW_auxv_t *a = auxv; + + if (unlikely(a == NULL)) { + a = qemu_init_auxval(); + } + + for (; a->a_type != 0; a++) { + if (a->a_type == type) { + return a->a_val; + } + } + + return 0; +} + +#else + +unsigned long qemu_getauxval(unsigned long type) +{ + return 0; +} + +#endif diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 340e4e08..7f00e8b4 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1,6 +1,8 @@ /* Autogen header for Unicorn Engine - DONOT MODIFY */ #ifndef UNICORN_AUTOGEN_X86_64_H #define UNICORN_AUTOGEN_X86_64_H +#define use_idiv_instructions_rt use_idiv_instructions_rt_x86_64 +#define tcg_target_deposit_valid tcg_target_deposit_valid_x86_64 #define helper_power_down helper_power_down_x86_64 #define check_exit_request check_exit_request_x86_64 #define address_space_unregister address_space_unregister_x86_64 @@ -2808,7 +2810,6 @@ #define tb_phys_invalidate tb_phys_invalidate_x86_64 #define tb_reset_jump tb_reset_jump_x86_64 #define tb_set_jmp_target tb_set_jmp_target_x86_64 -#define tb_set_jmp_target1 tb_set_jmp_target1_x86_64 #define tcg_accel_class_init tcg_accel_class_init_x86_64 #define tcg_accel_type tcg_accel_type_x86_64 #define tcg_add_param_i32 tcg_add_param_i32_x86_64 diff --git a/samples/Makefile b/samples/Makefile index 0904512a..02a1f66d 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -27,7 +27,7 @@ LIBDIR = $(BUILDDIR) endif CFLAGS += -Wall -I$(INCDIR) -LDFLAGS += -L$(LIBDIR) -l$(LIBNAME) +LDFLAGS += -lpthread -L$(LIBDIR) -l$(LIBNAME) LDFLAGS_STATIC += $(UNICORN_DEP_LIBS_STATIC) ifeq ($(CROSS),) diff --git a/tests/unit/test_tb_x86.c b/tests/unit/test_tb_x86.c index ce5eb75e..7b51d71a 100644 --- a/tests/unit/test_tb_x86.c +++ b/tests/unit/test_tb_x86.c @@ -8,6 +8,7 @@ #include #include #include +#include // Demostration of a self-modifying "IMUL eax,mem,Ib" opcode @@ -110,7 +111,7 @@ static void hook_code32(uc_engine *uc, uint32_t tmp4[1]; uint32_t ecx; - printf("\nhook_code32: Address: %lx, Opcode Size: %d\n", address, size); + printf("\nhook_code32: Address: %"PRIx64", Opcode Size: %d\n", address, size); size = MIN(sizeof(tmp), size); if (!uc_mem_read(uc, address, tmp, size)) { @@ -202,7 +203,7 @@ static void hook_mem32(uc_engine *uc, ctype = '?'; if (type == 16) ctype = 'R'; if (type == 17) ctype = 'W'; - printf("hook_mem32(%c): Address: 0x%lx, Size: %d, Value:0x%lx\n", ctype, address, size, value); + printf("hook_mem32(%c): Address: 0x%"PRIx64", Size: %d, Value:0x%"PRIx64"\n", ctype, address, size, value); // if (!uc_mem_read(uc, 0x6000003a, tmp, 4)) // { diff --git a/uc.c b/uc.c index b354a5fa..ee7d5549 100644 --- a/uc.c +++ b/uc.c @@ -184,7 +184,8 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) uc->init_arch = arm_uc_init; // verify mode - if (mode != UC_MODE_ARM && mode != UC_MODE_THUMB) { + // TODO: support Big endian, MCLASS & V8 + if (mode & (~(UC_MODE_ARM | UC_MODE_THUMB | UC_MODE_BIG_ENDIAN | UC_MODE_LITTLE_ENDIAN))) { free(uc); return UC_ERR_MODE; }