diff --git a/CMakeLists.txt b/CMakeLists.txt index c4650c60571..57b9a845d8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,12 +208,16 @@ endif () # The target architecture. # For cross-compilation this should still work as you're supposed to set this var. -if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") +set(TARGET_ARCH "${CMAKE_SYSTEM_PROCESSOR}" CACHE STRING "Target architecture") +if (TARGET_ARCH MATCHES "^arm") set(ARM 1) # This means AArch32. -elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") + message(STATUS "Building for ARM") +elseif (TARGET_ARCH MATCHES "^aarch64") set(AARCH64 1) + message(STATUS "Building for AArch64") else () set(X86 1) # This means IA-32 or AMD64 + message(STATUS "Building for x86") endif () if (X86) @@ -233,6 +237,33 @@ else () set(ARCH_NAME_SHARED ${ARCH_NAME}) endif () +# The execution architecture, which might differ from the target for building +# an AArch64 decoder to execute on x86 machines (i#1684). +if (NOT "${TARGET_ARCH}" STREQUAL "${CMAKE_SYSTEM_PROCESSOR}") + set(DR_HOST_NOT_TARGET 1) +endif () +if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") + set(DR_HOST_ARM 1) # This means AArch32. + set(DR_HOST_ARCH_NAME "arm") + set(DR_HOST_AARCHXX 1) + set(DR_HOST_ARCH_NAME_SHARED aarchxx) +elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") + set(DR_HOST_AARCH64 1) + set(DR_HOST_ARCH_NAME "aarch64") + set(DR_HOST_AARCHXX 1) + set(DR_HOST_ARCH_NAME_SHARED aarchxx) + set(DR_HOST_X64 1) +elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_32") + set(DR_HOST_X86 1) + set(DR_HOST_ARCH_NAME "x86") + set(DR_HOST_ARCH_NAME_SHARED ${DR_HOST_ARCH_NAME}) +else () + set(DR_HOST_X86 1) + set(DR_HOST_ARCH_NAME "x86") + set(DR_HOST_ARCH_NAME_SHARED ${DR_HOST_ARCH_NAME}) + set(DR_HOST_X64 1) +endif () + # The plan is to use X64 to mean 64-bit generically, whether AMD64 or AARCH64. # Whether 64-bit is expected to be selected by user setting up compiler # prior to invoking CMake: it has to be that way for Windows, and for diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d4c814bd354..9043bf3dca6 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -70,10 +70,10 @@ endif () set(asm_deps "${PROJECT_SOURCE_DIR}/core/arch/asm_defines.asm" "${PROJECT_BINARY_DIR}/configure.h") -add_asm_target(arch/${ARCH_NAME}/${ARCH_NAME}.asm arch_core_asm_src arch_core_asm_tgt - "_core" "" "${asm_deps}") -if (NOT "${ARCH_NAME}" STREQUAL "${ARCH_NAME_SHARED}") - add_asm_target(arch/${ARCH_NAME_SHARED}/${ARCH_NAME_SHARED}.asm +add_asm_target(arch/${DR_HOST_ARCH_NAME}/${DR_HOST_ARCH_NAME}.asm + arch_core_asm_src arch_core_asm_tgt "_core" "" "${asm_deps}") +if (NOT "${DR_HOST_ARCH_NAME}" STREQUAL "${DR_HOST_ARCH_NAME_SHARED}") + add_asm_target(arch/${DR_HOST_ARCH_NAME_SHARED}/${DR_HOST_ARCH_NAME_SHARED}.asm archshared_core_asm_src archshared_core_asm_tgt "_core" "" "${asm_deps}") endif () @@ -86,7 +86,7 @@ if (UNIX) # our auxiliary tools (i#1504), but we do *not* want our own memcpy and # memset for static-lib DR core. Thus we separate them out. The i#1504 # glibc versioning is only an issue on x86. - add_asm_target(arch/${ARCH_NAME}/memfuncs.asm memfuncs_asm_src memfuncs_asm_tgt + add_asm_target(arch/${DR_HOST_ARCH_NAME}/memfuncs.asm memfuncs_asm_src memfuncs_asm_tgt "_memfuncs" "" "${asm_deps}") add_library(drmemfuncs STATIC ${memfuncs_asm_src} lib/memmove.c) add_gen_events_deps(drmemfuncs) @@ -98,7 +98,7 @@ endif () # i#1409: to share core libc-ish code with non-core, we use the "drlibc" library. add_asm_target(drlibc/drlibc_xarch.asm drlibc_xarch_asm_src drlibc_xarch_asm_tgt "_core" "" "${asm_deps}") -add_asm_target(drlibc/drlibc_${ARCH_NAME}.asm drlibc_arch_asm_src +add_asm_target(drlibc/drlibc_${DR_HOST_ARCH_NAME}.asm drlibc_arch_asm_src drlibc_arch_asm_tgt "" "" "${asm_deps}") set(DRLIBC_SRCS @@ -1050,7 +1050,7 @@ endif () ########################################################################### # Unit tests -if (BUILD_TESTS) +if (BUILD_TESTS AND NOT DR_HOST_NOT_TARGET) add_executable(unit_tests unit_tests.c # These unit tests have been moved from the x86_code module into a new x86_code # test module that gets its own clang/gcc options for testing (-mno-vzeroupper). @@ -1124,7 +1124,7 @@ if (BUILD_TESTS) set_tests_properties(unit_tests PROPERTIES LABELS OSX) endif () copy_target_to_device(unit_tests "${location_suffix}") -endif (BUILD_TESTS) +endif () ########################################################################### diff --git a/core/arch/aarchxx/mangle.c b/core/arch/aarchxx/mangle.c index 3c6acb22269..5847fdf1036 100644 --- a/core/arch/aarchxx/mangle.c +++ b/core/arch/aarchxx/mangle.c @@ -2853,8 +2853,10 @@ mangle_icache_op(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr, opnd_create_base_disp(dr_reg_stolen, DR_REG_NULL, 0, 16, OPSZ_16), opnd_create_reg(xt == dr_reg_stolen ? DR_REG_X0 : xt), opnd_create_reg(DR_REG_X30))); +# ifndef DR_HOST_NOT_TARGET insert_mov_immed_arch(dcontext, NULL, NULL, (ptr_int_t)icache_op_ic_ivau_asm, opnd_create_reg(DR_REG_X30), ilist, instr, NULL, NULL); +# endif PRE(ilist, instr, /* mov x0, x28 */ XINST_CREATE_move(dcontext, opnd_create_reg(DR_REG_X0), opnd_create_reg(dr_reg_stolen))); @@ -2887,8 +2889,10 @@ mangle_icache_op(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr, dcontext, opnd_create_base_disp(dr_reg_stolen, DR_REG_NULL, 0, 8, OPSZ_16), opnd_create_reg(DR_REG_X1), opnd_create_reg(DR_REG_X2))); +# ifndef DR_HOST_NOT_TARGET insert_mov_immed_arch(dcontext, NULL, NULL, (ptr_int_t)icache_op_isb_asm, opnd_create_reg(DR_REG_X2), ilist, instr, NULL, NULL); +# endif insert_mov_immed_arch(dcontext, NULL, NULL, (ptr_int_t)pc, opnd_create_reg(DR_REG_X1), ilist, instr, NULL, NULL); PRE(ilist, instr, /* mov x0, x28 */ diff --git a/core/arch/arch_exports.h b/core/arch/arch_exports.h index 9e7aec749fd..7465dc90ac3 100644 --- a/core/arch/arch_exports.h +++ b/core/arch/arch_exports.h @@ -468,7 +468,7 @@ atomic_add_exchange_int64(volatile int64 *var, int64 value) # define atomic_add_exchange atomic_add_exchange_int #else /* UNIX */ -# ifdef X86 +# ifdef DR_HOST_X86 /* IA-32 vol 3 7.1.4: processor will internally suppress the bus lock * if target is within cache line. */ @@ -632,7 +632,7 @@ atomic_add_exchange_int64(volatile int64 *var, int64 value) # define SET_IF_NOT_ZERO(flag) SET_FLAG(nz, flag) # define SET_IF_NOT_LESS(flag) SET_FLAG(nl, flag) -# elif defined(AARCH64) +# elif defined(DR_HOST_AARCH64) # define ATOMIC_1BYTE_WRITE(target, value, hot_patch) \ do { \ @@ -817,7 +817,7 @@ atomic_dec_becomes_zero(volatile int *var) return atomic_add_exchange_int(var, -1) == 0; } -# elif defined(ARM) +# elif defined(DR_HOST_ARM) # define ATOMIC_1BYTE_WRITE(target, value, hot_patch) \ do { \ @@ -979,7 +979,7 @@ proc_get_timestamp(void); # define ATOMIC_COMPARE_EXCHANGE_PTR ATOMIC_COMPARE_EXCHANGE # endif -# ifndef AARCH64 +# ifndef DR_HOST_AARCH64 /* Atomically increments *var by 1 * Returns true if the resulting value is zero, otherwise returns false */ diff --git a/core/arch/asm_defines.asm b/core/arch/asm_defines.asm index a4773e32edc..e3338103208 100644 --- a/core/arch/asm_defines.asm +++ b/core/arch/asm_defines.asm @@ -61,6 +61,11 @@ # define AARCHXX #endif +//NOCHECK +#define X86 +#undef AARCH64 +#undef AARCHXX + #if (defined(ARM) && defined(X64)) || (defined(AARCH64) && !defined(X64)) # error ARM is only 32-bit; AARCH64 is 64-bit #endif diff --git a/core/arch/x86_code_test.c b/core/arch/x86_code_test.c index 6d060a1e595..b5409392f45 100644 --- a/core/arch/x86_code_test.c +++ b/core/arch/x86_code_test.c @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2013-2019 Google, Inc. All rights reserved. + * Copyright (c) 2013-2020 Google, Inc. All rights reserved. * Copyright (c) 2001-2010 VMware, Inc. All rights reserved. * **********************************************************/ @@ -105,7 +105,7 @@ test_cpuid() # endif } -# ifdef __AVX__ +# if !defined(DR_HOST_NOT_TARGET) && defined(__AVX__) static void unit_test_get_ymm_caller_saved() @@ -393,7 +393,7 @@ unit_test_asm(dcontext_t *dc) print_file(STDERR, "testing asm\n"); test_call_switch_stack(dc); test_cpuid(); -# ifdef UNIX +# if defined(UNIX) && !defined(DR_HOST_NOT_TARGET) # ifdef __AVX__ unit_test_get_ymm_caller_saved(); # endif diff --git a/core/drlibc/drlibc.c b/core/drlibc/drlibc.c index 6d65ba77b03..37f8420e9f7 100644 --- a/core/drlibc/drlibc.c +++ b/core/drlibc/drlibc.c @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2015-2019 Google, Inc. All rights reserved. + * Copyright (c) 2015-2020 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -117,6 +117,9 @@ kernel_is_64bit(void) void clear_icache(void *beg, void *end) { +# ifdef DR_HOST_NOT_TARGET + ASSERT_NOT_REACHED(); +# else static size_t cache_info = 0; size_t dcache_line_size; size_t icache_line_size; @@ -159,6 +162,7 @@ clear_icache(void *beg, void *end) /* Instruction Synchronization Barrier */ __asm__ __volatile__("isb" : : : "memory"); +# endif } #endif diff --git a/core/drlibc/drlibc_module_elf.c b/core/drlibc/drlibc_module_elf.c index 5aa516c6fa0..f3748db3a60 100644 --- a/core/drlibc/drlibc_module_elf.c +++ b/core/drlibc/drlibc_module_elf.c @@ -108,9 +108,14 @@ is_elf_so_header_common(app_pc base, size_t size, bool memory) if ((elf_header.e_version != 1) || (memory && elf_header.e_ehsize != sizeof(ELF_HEADER_TYPE)) || (memory && +# ifdef DR_HOST_NOT_TARGET + false +# else elf_header.e_machine != - IF_X86_ELSE(IF_X64_ELSE(EM_X86_64, EM_386), - IF_X64_ELSE(EM_AARCH64, EM_ARM)))) + IF_HOST_X86_ELSE(IF_HOST_X64_ELSE(EM_X86_64, EM_386), + IF_HOST_X64_ELSE(EM_AARCH64, EM_ARM)) +# endif + )) return false; #endif /* FIXME - should we add any of these to the check? For real @@ -119,10 +124,12 @@ is_elf_so_header_common(app_pc base, size_t size, bool memory) ASSERT_CURIOSITY(!memory || elf_header.e_ehsize == sizeof(ELF_HEADER_TYPE)); ASSERT_CURIOSITY(elf_header.e_ident[EI_OSABI] == ELFOSABI_SYSV || elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX); +#ifndef DR_HOST_NOT_TARGET ASSERT_CURIOSITY(!memory || elf_header.e_machine == - IF_X86_ELSE(IF_X64_ELSE(EM_X86_64, EM_386), - IF_X64_ELSE(EM_AARCH64, EM_ARM))); + IF_HOST_X86_ELSE(IF_HOST_X64_ELSE(EM_X86_64, EM_386), + IF_HOST_X64_ELSE(EM_AARCH64, EM_ARM))); +#endif return true; } return false; diff --git a/core/lib/globals_shared.h b/core/lib/globals_shared.h index 2f4152292c4..f4a875d4a65 100644 --- a/core/lib/globals_shared.h +++ b/core/lib/globals_shared.h @@ -796,6 +796,17 @@ typedef struct _instr_t instr_t; #endif /* DR_API EXPORT END */ +#ifdef DR_HOST_X86 +# define IF_HOST_X86_ELSE(x, y) x +#else +# define IF_HOST_X86_ELSE(x, y) y +#endif +#ifdef DR_HOST_X64 +# define IF_HOST_X64_ELSE(x, y) x +#else +# define IF_HOST_X64_ELSE(x, y) y +#endif + typedef enum { SYSLOG_INFORMATION = 0x1, SYSLOG_WARNING = 0x2, diff --git a/core/unix/include/sigcontext.h b/core/unix/include/sigcontext.h index 9e0c1062777..31efe39c3f5 100644 --- a/core/unix/include/sigcontext.h +++ b/core/unix/include/sigcontext.h @@ -63,7 +63,7 @@ typedef struct _kernel_fpx_sw_bytes_t { __u32 padding[7]; /* for future use. */ } kernel_fpx_sw_bytes_t; -#ifdef __i386__ +#ifdef X86_32 /* * As documented in the iBCS2 standard.. * @@ -161,7 +161,7 @@ typedef struct _kernel_sigcontext_t { unsigned long cr2; } kernel_sigcontext_t; -#elif defined(__amd64__) +#elif defined(X86_64) /* FXSAVE frame */ /* Note: reserved1/2 may someday contain valuable data. Always save/restore @@ -220,9 +220,9 @@ typedef struct _kernel_sigcontext_t { unsigned long reserved1[8]; } kernel_sigcontext_t; -#endif /* !__i386__ */ +#endif -#if defined(__i386__) || defined(__amd64__) +#if defined(X86_32) || defined(X86_64) typedef struct _kernel_xsave_hdr_t { __u64 xstate_bv; __u64 reserved1[2]; @@ -246,9 +246,9 @@ typedef struct _kernel_xstate_t { kernel_ymmh_state_t ymmh; /* new processor state extensions go here */ } kernel_xstate_t; -#endif /* __i386__ || __amd64__ */ +#endif -#ifdef __arm__ +#ifdef ARM /* * Signal context structure - contains all info to do with the state * before the signal handler was invoked. Note: only add new entries @@ -314,9 +314,9 @@ typedef struct _kernel_iwmmxt_sigframe_t { /* Dummy padding block: a block with this magic should be skipped. */ # define DUMMY_MAGIC 0xb0d9ed01 -#endif /* __arm__ */ +#endif -#ifdef __aarch64__ +#ifdef AARCH64 typedef struct _kernel_sigcontext_t { unsigned long long fault_address; @@ -328,6 +328,26 @@ typedef struct _kernel_sigcontext_t { unsigned char __reserved[4096] __attribute__((__aligned__(16))); } kernel_sigcontext_t; -#endif /* __aarch64__ */ +/* + * Header to be used at the beginning of structures extending the user + * context. Such structures must be placed after the rt_sigframe on the stack + * and be 16-byte aligned. The last structure must be a dummy one with the + * magic and size set to 0. + */ +struct _aarch64_ctx { + __u32 magic; + __u32 size; +}; + +# define FPSIMD_MAGIC 0x46508001 + +struct fpsimd_context { + struct _aarch64_ctx head; + __u32 fpsr; + __u32 fpcr; + __uint128_t vregs[32]; +}; + +#endif #endif /* _SIGCONTEXT_H_ */ diff --git a/core/unix/include/syscall.h b/core/unix/include/syscall.h index 61d62446ecb..6cb28c4dfc0 100644 --- a/core/unix/include/syscall.h +++ b/core/unix/include/syscall.h @@ -18,12 +18,14 @@ # error Only use this file on Linux #endif -#ifdef X86 +#ifdef DR_HOST_X86 # include "syscall_linux_x86.h" -#elif defined(ARM) +#elif defined(DR_HOST_ARM) # include "syscall_linux_arm.h" -#elif defined(AARCH64) +#elif defined(DR_HOST_AARCH64) # include "syscall_linux_uapi.h" +#else +# error Unknown platform. #endif #endif /* _SYSCALL_H_ */ diff --git a/core/unix/injector.c b/core/unix/injector.c index 6b965093b25..2f0243b90f8 100644 --- a/core/unix/injector.c +++ b/core/unix/injector.c @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2012-2019 Google, Inc. All rights reserved. + * Copyright (c) 2012-2020 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -821,12 +821,12 @@ dr_inject_process_exit(void *data, bool terminate) enum { MAX_SHELL_CODE = 4096 }; -# ifdef X86 +# ifdef DR_HOST_X86 # define USER_REGS_TYPE user_regs_struct # define REG_PC_FIELD IF_X64_ELSE(rip, eip) # define REG_SP_FIELD IF_X64_ELSE(rsp, esp) # define REG_RETVAL_FIELD IF_X64_ELSE(rax, eax) -# elif defined(ARM) +# elif defined(DR_HOST_ARM) /* On AArch32, glibc uses user_regs instead of user_regs_struct. * struct user_regs { * unsigned long int uregs[18]; @@ -840,7 +840,7 @@ enum { MAX_SHELL_CODE = 4096 }; # define REG_SP_FIELD uregs[13] /* r13 in user_regs */ /* On ARM, all reg args are also reg retvals. */ # define REG_RETVAL_FIELD uregs[0] /* r0 in user_regs */ -# elif defined(AARCH64) +# elif defined(DR_HOST_AARCH64) # define USER_REGS_TYPE user_pt_regs # define REG_PC_FIELD pc # define REG_SP_FIELD sp @@ -876,7 +876,7 @@ static const enum_name_pair_t pt_req_map[] = { { PTRACE_TRACEME, "PTRACE_TRACEME { PTRACE_CONT, "PTRACE_CONT" }, { PTRACE_KILL, "PTRACE_KILL" }, { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" }, -# ifndef AARCH64 +# ifndef DR_HOST_AARCH64 { PTRACE_GETREGS, "PTRACE_GETREGS" }, { PTRACE_SETREGS, "PTRACE_SETREGS" }, { PTRACE_GETFPREGS, "PTRACE_GETFPREGS" }, diff --git a/core/unix/loader.c b/core/unix/loader.c index 83c35306f55..a464150e902 100644 --- a/core/unix/loader.c +++ b/core/unix/loader.c @@ -1637,10 +1637,13 @@ privload_mem_is_elf_so_header(byte *mem) /* libdynamorio should be ET_DYN */ if (elf_hdr->e_type != ET_DYN) return false; - /* ARM or X86 */ + /* ARM or X86 */ +# ifndef DR_HOST_NOT_TARGET if (elf_hdr->e_machine != - IF_X86_ELSE(IF_X64_ELSE(EM_X86_64, EM_386), IF_X64_ELSE(EM_AARCH64, EM_ARM))) + IF_HOST_X86_ELSE(IF_HOST_X64_ELSE(EM_X86_64, EM_386), + IF_HOST_X64_ELSE(EM_AARCH64, EM_ARM))) return false; +# endif if (elf_hdr->e_ehsize != sizeof(ELF_HEADER_TYPE)) return false; return true; diff --git a/core/unix/loader_linux.c b/core/unix/loader_linux.c index 6837b982a2d..8d59216ea03 100644 --- a/core/unix/loader_linux.c +++ b/core/unix/loader_linux.c @@ -411,7 +411,10 @@ redirect____tls_get_addr() /* XXX: in some version of ___tls_get_addr, ti is passed via xax * How can I generalize it? */ -#ifdef X86 +#ifdef DR_HOST_NOT_TARGET + ti = NULL; + ASSERT_NOT_REACHED(); +#elif defined(X86) asm("mov %%" ASM_XAX ", %0" : "=m"((ti)) : : ASM_XAX); #elif defined(AARCH64) /* FIXME i#1569: NYI */ diff --git a/core/unix/module_elf.c b/core/unix/module_elf.c index 8a3607a13a0..9491491fa84 100644 --- a/core/unix/module_elf.c +++ b/core/unix/module_elf.c @@ -1401,7 +1401,7 @@ dr_symbol_export_iterator_stop(dr_symbol_export_iterator_t *dr_iter) #ifndef ANDROID -# ifdef AARCH64 +# if defined(AARCH64) && !defined(DR_HOST_NOT_TARGET) /* Defined in aarch64.asm. */ ptr_int_t tlsdesc_resolver(struct tlsdesc_t *); diff --git a/core/unix/os.c b/core/unix/os.c index 23b734ad62f..b9ed9e68c5e 100644 --- a/core/unix/os.c +++ b/core/unix/os.c @@ -129,13 +129,13 @@ typedef struct rlimit64 rlimit64_t; * values in xdx:xax. */ #define MCXT_SYSCALL_RES(mc) ((mc)->IF_X86_ELSE(xax, r0)) -#if defined(AARCH64) +#if defined(DR_HOST_AARCH64) # define ASM_R2 "x2" # define ASM_R3 "x3" # define READ_TP_TO_R3_DISP_IN_R2 \ "mrs " ASM_R3 ", tpidr_el0\n\t" \ "ldr " ASM_R3 ", [" ASM_R3 ", " ASM_R2 "] \n\t" -#elif defined(ARM) +#elif defined(DR_HOST_ARM) # define ASM_R2 "r2" # define ASM_R3 "r3" # define READ_TP_TO_R3_DISP_IN_R2 \ @@ -1457,7 +1457,14 @@ os_timeout(int time_in_milliseconds) * precise constraint, then the compiler would be able to optimize better. See * glibc comments on THREAD_SELF. */ -#ifdef MACOS64 +#ifdef DR_HOST_NOT_TARGET +# define WRITE_TLS_SLOT_IMM(imm, var) var = 0, ASSERT_NOT_REACHED() +# define READ_TLS_SLOT_IMM(imm, var) var = 0, ASSERT_NOT_REACHED() +# define WRITE_TLS_INT_SLOT_IMM(imm, var) var = 0, ASSERT_NOT_REACHED() +# define READ_TLS_INT_SLOT_IMM(imm, var) var = 0, ASSERT_NOT_REACHED() +# define WRITE_TLS_SLOT(offs, var) offs = var ? 0 : 1, ASSERT_NOT_REACHED() +# define READ_TLS_SLOT(offs, var) var = (void *)(ptr_uint_t)offs, ASSERT_NOT_REACHED() +#elif defined(MACOS64) /* For now we have both a directly-addressable os_local_state_t and a pointer to * it in slot 6. If we settle on always doing the full os_local_state_t in slots, * we would probably get rid of the indirection here and directly access slot fields. diff --git a/core/unix/os_exports.h b/core/unix/os_exports.h index f3d7ed36f88..baff1f63b45 100644 --- a/core/unix/os_exports.h +++ b/core/unix/os_exports.h @@ -285,11 +285,11 @@ disable_env(const char *name); asm(".section __DATA," name); \ asm(".align 12"); /* 2^12 */ #else -# ifdef X86 +# ifdef DR_HOST_X86 # define DECLARE_DATA_SECTION(name, wx) \ asm(".section " name ", \"a" wx "\", @progbits"); \ asm(".align 0x1000"); -# elif defined(AARCHXX) +# elif defined(DR_HOST_AARCHXX) # define DECLARE_DATA_SECTION(name, wx) \ asm(".section " name ", \"a" wx "\""); \ asm(".align 12"); /* 2^12 */ @@ -308,12 +308,12 @@ disable_env(const char *name); asm(".align 12"); \ asm(".text"); #else -# ifdef X86 +# ifdef DR_HOST_X86 # define END_DATA_SECTION_DECLARATIONS() \ asm(".section .data"); \ asm(".align 0x1000"); \ asm(".text"); -# elif defined(AARCHXX) +# elif defined(DR_HOST_AARCHXX) # define END_DATA_SECTION_DECLARATIONS() \ asm(".section .data"); \ asm(".align 12"); \ diff --git a/core/unix/signal.c b/core/unix/signal.c index 34304b3293e..14ca7b8b32d 100644 --- a/core/unix/signal.c +++ b/core/unix/signal.c @@ -7206,7 +7206,9 @@ notify_and_jmp_without_stack(KSYNCH_TYPE *notify_var, byte *continuation, byte * #ifdef MACOS ASSERT(sizeof(notify_var->sem) == 4); #endif -#ifdef X86 +#ifdef DR_HOST_NOT_TARGET + ASSERT_NOT_REACHED(); +#elif defined(X86) # ifndef MACOS /* i#2632: recent clang for 32-bit annoyingly won't do the right thing for * "jmp dynamorio_condvar_wake_and_jmp" and leaves relocs so we ensure it's PIC. @@ -7234,7 +7236,9 @@ notify_and_jmp_without_stack(KSYNCH_TYPE *notify_var, byte *continuation, byte * #endif } else { ksynch_set_value(notify_var, 1); -#ifdef X86 +#ifdef DR_HOST_NOT_TARGET + ASSERT_NOT_REACHED(); +#elif defined(X86) asm("mov %0, %%" ASM_XSP : : "m"(xsp)); asm("mov %0, %%" ASM_XAX : : "m"(continuation)); asm("jmp *%" ASM_XAX); diff --git a/core/unix/tls.h b/core/unix/tls.h index 00e27145608..313ad91d48f 100644 --- a/core/unix/tls.h +++ b/core/unix/tls.h @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2011-2019 Google, Inc. All rights reserved. + * Copyright (c) 2011-2020 Google, Inc. All rights reserved. * Copyright (c) 2008-2010 VMware, Inc. All rights reserved. * **********************************************************/ @@ -129,7 +129,10 @@ typedef struct _our_modify_ldt_t { static inline ptr_uint_t read_thread_register(reg_id_t reg) { -#if defined(MACOS64) +#ifdef DR_HOST_NOT_TARGET + ptr_uint_t sel = 0; + ASSERT_NOT_REACHED(); +#elif defined(MACOS64) ptr_uint_t sel; if (reg == SEG_GS) { asm volatile("mov %%gs:%1, %0" : "=r"(sel) : "m"(*(void **)0)); @@ -191,7 +194,10 @@ read_thread_register(reg_id_t reg) static inline bool write_thread_register(void *val) { -# ifdef AARCH64 +# ifdef DR_HOST_NOT_TARGET + ASSERT_NOT_REACHED(); + return false; +# elif defined(AARCH64) asm volatile("msr tpidr_el0, %0" : : "r"(val)); return true; # else diff --git a/ext/drsyms/CMakeLists.txt b/ext/drsyms/CMakeLists.txt index 933cf7869b1..96461e1b13b 100644 --- a/ext/drsyms/CMakeLists.txt +++ b/ext/drsyms/CMakeLists.txt @@ -132,11 +132,11 @@ elseif (UNIX) else (APPLE) set(srcs ${srcs} drsyms_elf.c) set(dwarf_libpath - "${PROJECT_SOURCE_DIR}/ext/drsyms/libelftc${ARCH}/lib${BITS}/libdwarf.a") + "${PROJECT_SOURCE_DIR}/ext/drsyms/libelftc${DR_HOST_ARCH}/lib${BITS}/libdwarf.a") set(elftc_libpath - "${PROJECT_SOURCE_DIR}/ext/drsyms/libelftc${ARCH}/lib${BITS}/libelftc.a") + "${PROJECT_SOURCE_DIR}/ext/drsyms/libelftc${DR_HOST_ARCH}/lib${BITS}/libelftc.a") set(elf_libpath - "${PROJECT_SOURCE_DIR}/ext/drsyms/libelftc${ARCH}/lib${BITS}/libelf.a") + "${PROJECT_SOURCE_DIR}/ext/drsyms/libelftc${DR_HOST_ARCH}/lib${BITS}/libelf.a") endif (APPLE) set(srcs_static ${srcs}) endif (WIN32) diff --git a/ext/drwrap/CMakeLists.txt b/ext/drwrap/CMakeLists.txt index 57aad8c0631..2bb30c7d5bf 100644 --- a/ext/drwrap/CMakeLists.txt +++ b/ext/drwrap/CMakeLists.txt @@ -1,5 +1,5 @@ # ********************************************************** -# Copyright (c) 2010-2016 Google, Inc. All rights reserved. +# Copyright (c) 2010-2020 Google, Inc. All rights reserved. # ********************************************************** # drwrap: DynamoRIO Function Wrapping and Replacing Extension @@ -52,9 +52,9 @@ get_DynamoRIO_defines(DR_DEFINES OFF) string(REPLACE " " ";" DR_DEFINES "${DR_DEFINES}") set(asm_flags ${asm_defs} ${DR_DEFINES} -I "${DynamoRIO_DIR}") set(asm_deps "${DynamoRIO_DIR}/cpp2asm_defines.h") -if (ARM) +if (DR_HOST_ARM) set(asm_file "drwrap_asm_arm.asm") -elseif (AARCH64) +elseif (DR_HOST_AARCH64) set(asm_file "drwrap_asm_aarch64.asm") else () set(asm_file "drwrap_asm_x86.asm") diff --git a/make/DynamoRIOConfig.cmake.in b/make/DynamoRIOConfig.cmake.in index 8d0da6a96de..e37d54ce3a9 100755 --- a/make/DynamoRIOConfig.cmake.in +++ b/make/DynamoRIOConfig.cmake.in @@ -295,12 +295,23 @@ if (NOT DEFINED DynamoRIO_USE_LIBC) set(DynamoRIO_USE_LIBC ON) endif () -if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") - set(ARM 1) # This means AArch32. -elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") - set(AARCH64 1) -else () - set(X86 1) # This means IA-32 or AMD64 +if (NOT DEFINED ARM AND NOT DEFINED AARCH64 AND NOT DEFINED X86) + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") + set(ARM 1) # This means AArch32. + elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") + set(AARCH64 1) + else () + set(X86 1) # This means IA-32 or AMD64 + endif () +endif () +if (NOT DEFINED DR_HOST_ARM AND NOT DEFINED DR_HOST_AARCH64 AND NOT DEFINED DR_HOST_X86) + if (ARM) + set(DR_HOST_ARM 1) + elseif (AARCH64) + set(DR_HOST_AARCH64 1) + else () + set(DR_HOST_X86 1) + endif () endif () if (WIN32 OR ANDROID) @@ -578,6 +589,15 @@ function (DynamoRIO_extra_cflags flags_out extra_cflags tgt_cxx) else (UNIX) set(extra_cflags "${extra_cflags} -DWINDOWS") endif (UNIX) + if (DynamoRIO_INTERNAL) + if (DR_HOST_ARM) + set(extra_cflags "${extra_cflags} -DDR_HOST_ARM") + elseif (DR_HOST_AARCH64) + set(extra_cflags "${extra_cflags} -DDR_HOST_AARCH64") + elseif (DR_HOST_X86) + set(extra_cflags "${extra_cflags} -DDR_HOST_X86") + endif () + endif () if (DynamoRIO_REG_COMPATIBILITY) set(extra_cflags "${extra_cflags} -DDR_REG_ENUM_COMPATIBILITY") @@ -941,11 +961,11 @@ function (configure_DynamoRIO_client target) set(LD_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/${target}.ldscript) # We do NOT add ${LD_SCRIPT} as an ADDITIONAL_MAKE_CLEAN_FILES since it's # configure-time built not make-time built - if (X86) + if (DR_HOST_X86) set(LD_FLAGS "-melf_x86_64") - elseif (ARM) + elseif (DR_HOST_ARM) set(LD_FLAGS "-marmelf_linux_eabi") - elseif (AARCH64) + elseif (DR_HOST_AARCH64) set(LD_FLAGS "-maarch64linux") endif () diff --git a/make/configure.cmake.h b/make/configure.cmake.h index 7dc58f3b398..2e7288b0181 100644 --- a/make/configure.cmake.h +++ b/make/configure.cmake.h @@ -63,6 +63,14 @@ # define MACOS64 #endif +/* host, when different */ +#cmakedefine DR_HOST_X86 +#cmakedefine DR_HOST_ARM +#cmakedefine DR_HOST_AARCH64 +#cmakedefine DR_HOST_AARCHXX +#cmakedefine DR_HOST_X64 +#cmakedefine DR_HOST_NOT_TARGET + /* set by high-level VMAP/VMSAFE/VPS configurations */ #cmakedefine PROGRAM_SHEPHERDING #cmakedefine CLIENT_INTERFACE diff --git a/make/cpp2asm_support.cmake b/make/cpp2asm_support.cmake index 082211f6acb..3ba5f9eb1d7 100644 --- a/make/cpp2asm_support.cmake +++ b/make/cpp2asm_support.cmake @@ -1,5 +1,5 @@ # ********************************************************** -# Copyright (c) 2010-2015 Google, Inc. All rights reserved. +# Copyright (c) 2010-2020 Google, Inc. All rights reserved. # Copyright (c) 2009-2010 VMware, Inc. All rights reserved. # ********************************************************** @@ -208,7 +208,7 @@ if (APPLE) set(ASM_FLAGS "${ASM_FLAGS} -g") endif (DEBUG) elseif (UNIX) - if (X86) + if (DR_HOST_X86) set(ASM_FLAGS "-mmnemonic=intel -msyntax=intel -mnaked-reg") if (X64) set(ASM_FLAGS "${ASM_FLAGS} --64") @@ -216,7 +216,7 @@ elseif (UNIX) # putting --32 last so we fail on -mmnemonic=intel on older as, not --32 set(ASM_FLAGS "${ASM_FLAGS} --32") endif (X64) - elseif (ARM) + elseif (DR_HOST_ARM) # No 64-bit support yet. # Some tests and libgcc/arm use deprecated instructions, disable warnings. set(ASM_FLAGS "${ASM_FLAGS} -mfpu=neon -mno-warn-deprecated") diff --git a/suite/runsuite.cmake b/suite/runsuite.cmake index 531bd23f68a..eef556fae4b 100644 --- a/suite/runsuite.cmake +++ b/suite/runsuite.cmake @@ -520,6 +520,19 @@ if (UNIX AND ARCH_IS_X86) set(ARCH_IS_X86 ON) endif (UNIX AND ARCH_IS_X86) +#NOCHECK test Windows +#NOCHECK test runsuite here +#NOCHECK limit this to Windows master: only Linux PR's? Separate Travis job there? +if (ARCH_IS_X86) + # Test decoding and analyzing aarch64 traces on x86 machines. + testbuild_ex("aarch64-on-x86" ON " + TARGET_ARCH:STRING=aarch64 + DEBUG:BOOL=ON + INTERNAL:BOOL=ON + ${build_tests} + " OFF ${arg_package} "") +endif () + # XXX: do we still care about these builds? ## defines we don't want to break -- no runs though since we don't currently use these # "BUILD::NOSHORT::ADD_DEFINES=\"${D}DGC_DIAGNOSTICS\"", diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index 6f90201ad46..bad96924aa1 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -546,6 +546,10 @@ function(add_exe test source) # Some files use asm code, which must be separate for x64, but it's much # more convenient to have it in the same source file and auto-split. if ("${srccode}" MATCHES "ifndef ASM_CODE_ONLY") + if (DR_HOST_NOT_TARGET) + # We just don't support such tests. + message(FATAL_ERROR "No asm-containing tests supported for host!=target") + endif () # we rely on the asm rule doing preprocessing for us, so we just make # a copy and set the ASM_CODE_ONLY define get_filename_component(source_abs "${source}" ABSOLUTE) @@ -743,6 +747,9 @@ function(configure_app_api_build_flags test decoder use_static_DR) string(REGEX REPLACE "-DCLANG" "" prop_cflags "${prop_cflags}") string(REGEX REPLACE "-DANDROID" "" prop_cflags "${prop_cflags}") string(REGEX REPLACE "-DDR_APP_EXPORTS" "" prop_cflags "${prop_cflags}") + string(REGEX REPLACE "-DDR_HOST_ARM" "" prop_cflags "${prop_cflags}") + string(REGEX REPLACE "-DDR_HOST_AARCH64" "" prop_cflags "${prop_cflags}") + string(REGEX REPLACE "-DDR_HOST_X86" "" prop_cflags "${prop_cflags}") # FIXME: apparently moving cflags to a target property makes it show up # in the cpp run for asm targets, where it doesn't if in global var. # This causes compilation failure. Removing -g3 manually as a workaround. @@ -1662,6 +1669,66 @@ endfunction(optimize) # This step takes a while so we provide a status message: message(STATUS "Processing tests and generating expected output patterns") +# Tests enabled when DR_HOST_NOT_TARGET go first: +if (DR_HOST_NOT_TARGET) + if (CLIENT_INTERFACE) + if (ARM) + set(sfx "arm") + elseif (AARCH64) + set(sfx "aarch64") + else () + set(sfx "x86") + endif () + if (NOT ANDROID) + # XXX i#1874: get working on Android + tobuild_api(api.ir api/ir_${sfx}.c "" "" OFF OFF) + # XXX i#1686: add ARM's headers too once they are all created + if (NOT ARM AND NOT AARCH64 AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") + # CMake's Unix Makefiles dependence analysis doesn't run the preprocessor + # and so doesn't find headers named via macros + # (http://www.cmake.org/Bug/view.php?id=13718) + set(api_ir_headers # must be full paths: + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_0args.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_1args.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args_mm.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_4args.h + # The following headers are x86 specific. + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args_avx512_evex.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args_avx512_vex.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx512_evex.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx512_evex_mask.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx512_vex.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_4args_avx512_evex_mask_A.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_4args_avx512_evex_mask_B.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_5args_avx512_evex_mask.h) + append_property_string(SOURCE api/ir_${sfx}.c OBJECT_DEPENDS "${api_ir_headers}") + endif () + + if (AARCH64) + tobuild_api(api.ir_negative api/ir_aarch64_negative.c "" "" OFF OFF) + endif (AARCH64) + endif () + + # test static decoder library + tobuild_api(api.ir-static api/ir_${sfx}.c "" "" ON OFF) + + if (ARM) + if (NOT ANDROID) # XXX i#1874: get working on Android + tobuild_api(api.drdecode api/drdecode_arm.c "" "" ON OFF) + endif () + elseif (AARCH64) + tobuild_api(api.drdecode api/drdecode_aarch64.c "" "" ON OFF) + else () + tobuild_api(api.drdecode api/drdecode_x86.c "" "" ON OFF) + endif () + endif () + +else (DR_HOST_NOT_TARGET) +#NOCHECK not yet willing to indent the world (and manually deal w/ long lines) until we're sure there's no simpler way: move the code at the bottom into a function up higher we can call here and at bottom, and then return() here?? + # Make sure we test running a path with spaces (to avoid regressions like i#2538). set(common.broadfun_outname "common.broadfun spaces") tobuild(common.broadfun common/broadfun.c) @@ -1780,7 +1847,8 @@ endif () #tobuild(common.ops common/ops.c) #tobuild(common.recurse common/recurse.c) -if (ARM AND NOT ANDROID) # XXX i#1874: Android loader won't run our static asm apps +# XXX i#1874: Android loader won't run our static asm apps +if (DR_HOST_ARM AND NOT ANDROID) tobuild_ops(common.allasm_thumb common/allasm_thumb.asm # set small -max_bb_instrs to test bb_safe_to_stop() "-early_inject -max_bb_instrs 6" "") @@ -1793,7 +1861,7 @@ if (ARM AND NOT ANDROID) # XXX i#1874: Android loader won't run our static asm a append_link_flags(common.allasm_arm "-nostartfiles -nodefaultlibs -static") endif () -if (AARCH64) +if (DR_HOST_AARCH64) tobuild_ops(common.allasm_aarch64_isa common/allasm_aarch64_isa.asm "-early_inject" "") # FIXME i#1569: -enable_traces here set_target_properties(common.allasm_aarch64_isa PROPERTIES LINKER_LANGUAGE C) @@ -2451,46 +2519,6 @@ if (CLIENT_INTERFACE) tobuild_api(api.it api/it_arm.c "" "" OFF OFF) endif(ARM AND NOT ANDROID) - if (ARM) - set(sfx "arm") - elseif (AARCH64) - set(sfx "aarch64") - else () - set(sfx "x86") - endif () - if (NOT ANDROID) - # XXX i#1874: get working on Android - tobuild_api(api.ir api/ir_${sfx}.c "" "" OFF OFF) - # XXX i#1686: add ARM's headers too once they are all created - if (NOT ARM AND NOT AARCH64 AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") - # CMake's Unix Makefiles dependence analysis doesn't run the preprocessor - # and so doesn't find headers named via macros - # (http://www.cmake.org/Bug/view.php?id=13718) - set(api_ir_headers # must be full paths: - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_0args.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_1args.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args_mm.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_4args.h - # The following headers are x86 specific. - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args_avx512_evex.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_2args_avx512_vex.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx512_evex.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx512_evex_mask.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_3args_avx512_vex.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_4args_avx512_evex_mask_A.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_4args_avx512_evex_mask_B.h - ${CMAKE_CURRENT_SOURCE_DIR}/api/ir_${sfx}_5args_avx512_evex_mask.h) - append_property_string(SOURCE api/ir_${sfx}.c OBJECT_DEPENDS "${api_ir_headers}") - endif () - - if (AARCH64) - tobuild_api(api.ir_negative api/ir_aarch64_negative.c "" "" OFF OFF) - endif (AARCH64) - endif () - if (ARM) if (NOT ANDROID) # XXX i#1874: get working on Android # Helper exe, used offline to build smaller input binary to test itself: @@ -2556,18 +2584,6 @@ if (CLIENT_INTERFACE) link_with_pthread(${detach_spawn_quick_exit_name}) endif () endif () - # test static decoder library - tobuild_api(api.ir-static api/ir_${sfx}.c "" "" ON OFF) - - if (ARM) - if (NOT ANDROID) # XXX i#1874: get working on Android - tobuild_api(api.drdecode api/drdecode_arm.c "" "" ON OFF) - endif () - elseif (AARCH64) - tobuild_api(api.drdecode api/drdecode_aarch64.c "" "" ON OFF) - else () - tobuild_api(api.drdecode api/drdecode_x86.c "" "" ON OFF) - endif () if (X86) if (X64) tobuild_api(decenc.drdecode_decenc_x86_64 @@ -2606,7 +2622,7 @@ if (CLIENT_INTERFACE) get_filename_component(drname ${drpath} NAME_WE) append_link_flags(api.ibl-stress "${drdir}/${drname}.lib") endif () -endif () + endif () # XXX: we should expand this test of drsyms standalone to be cross-platform and # not just check libstdc++-6.dll. @@ -4146,6 +4162,8 @@ if (NOT ANDROID) mark_execstack("${TestMemProtChg}") endif () +endif (DR_HOST_NOT_TARGET) + if (vera++_FOUND) file(READ "${PROJECT_SOURCE_DIR}/make/style_checks/style_test.templatex" vera_regex) add_test(vera ${VERA++_EXECUTABLE} --root "${PROJECT_SOURCE_DIR}/make/style_checks" diff --git a/suite/tests/tools.h b/suite/tests/tools.h index b4a19dff9b1..b7468a80910 100644 --- a/suite/tests/tools.h +++ b/suite/tests/tools.h @@ -360,7 +360,14 @@ int code_dec(int foo); int dummy(void); -#ifdef AARCHXX +#ifdef DR_HOST_NOT_TARGET +static inline void +tools_clear_icache(void *start, void *end) +{ + assert(false); +} +#elif defined(AARCHXX) +/* In tools.c asm code. */ void tools_clear_icache(void *start, void *end); #endif