diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index e1245391ba2..1bcc4681498 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -168,7 +168,7 @@ endif (WIN32 AND NOT X64) set(DECODER_SRCS arch/opnd_shared.c - arch/${ARCH_NAME}/opnd.c + arch/${ARCH_NAME_SHARED}/opnd.c arch/instr_shared.c arch/${ARCH_NAME}/instr.c arch/instrlist.c diff --git a/core/arch/aarch64/clean_call_opt.c b/core/arch/aarch64/clean_call_opt.c index 590481f14f1..cf659cf1106 100644 --- a/core/arch/aarch64/clean_call_opt.c +++ b/core/arch/aarch64/clean_call_opt.c @@ -35,10 +35,24 @@ #ifdef CLIENT_INTERFACE +static void +callee_info_init(callee_info_t *ci) +{ + memset(ci, 0, sizeof(*ci)); + ci->bailout = true; + /* to be conservative */ + ci->has_locals = true; + ci->write_aflags = true; + ci->read_aflags = true; + ci->tls_used = true; +} + void clean_call_opt_init(void) { - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + /* FIXME i#1569: NYI on AArch64 */ + ASSERT_NOT_IMPLEMENTED(INTERNAL_OPTION(opt_cleancall) == 0); + callee_info_init(&default_callee_info); } void diff --git a/core/arch/aarch64/opnd.c b/core/arch/aarch64/opnd.c deleted file mode 100644 index c3fee894c91..00000000000 --- a/core/arch/aarch64/opnd.c +++ /dev/null @@ -1,71 +0,0 @@ -/* ********************************************************** - * Copyright (c) 2016 ARM Limited. All rights reserved. - * **********************************************************/ - -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of ARM Limited nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL ARM LIMITED OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - */ - -#include "../globals.h" -#include "instr.h" -#include "arch.h" - -reg_id_t dr_reg_stolen = DR_REG_NULL; - -uint -opnd_immed_float_arch(uint opcode) -{ - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ - return 0; -} - -DR_API -bool -reg_is_stolen(reg_id_t reg) -{ - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ - return false; -} - -int -opnd_get_reg_dcontext_offs(reg_id_t reg) -{ - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ - return 0; -} - -#ifndef STANDALONE_DECODER - -opnd_t -opnd_create_sized_tls_slot(int offs, opnd_size_t size) -{ - opnd_t x = {0}; - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ - return x; -} - -#endif /* !STANDALONE_DECODER */ diff --git a/core/arch/aarch64/proc.c b/core/arch/aarch64/proc.c index 48c30d5b883..56a1db742ce 100644 --- a/core/arch/aarch64/proc.c +++ b/core/arch/aarch64/proc.c @@ -37,7 +37,7 @@ void proc_init_arch(void) { - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + /* FIXME i#1569: NYI */ } bool @@ -50,7 +50,7 @@ proc_has_feature(feature_bit_t f) void machine_cache_sync(void *pc_start, void *pc_end, bool flush_icache) { - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + cache_sync_asm(pc_start, pc_end); } DR_API diff --git a/core/arch/arm/opnd.c b/core/arch/aarchxx/opnd.c similarity index 85% rename from core/arch/arm/opnd.c rename to core/arch/aarchxx/opnd.c index 08a4d694085..40f99b0b4f0 100644 --- a/core/arch/arm/opnd.c +++ b/core/arch/aarchxx/opnd.c @@ -1,5 +1,6 @@ /* ********************************************************** * Copyright (c) 2014-2015 Google, Inc. All rights reserved. + * Copyright (c) 2016 ARM Limited. All rights reserved. * **********************************************************/ /* @@ -13,14 +14,14 @@ * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * * Neither the name of Google, Inc. nor the names of its contributors may be + * * Neither the name of ARM Limited nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL ARM LIMITED OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER @@ -39,8 +40,7 @@ reg_id_t dr_reg_stolen = DR_REG_NULL; uint opnd_immed_float_arch(uint opcode) { - /* FIXME i#1551: NYI */ - CLIENT_ASSERT(false, "NYI"); + ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1551, i#1569 */ return 0; } @@ -48,14 +48,23 @@ DR_API bool reg_is_stolen(reg_id_t reg) { +#ifdef AARCH64 + ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + return false; +#else if (dr_reg_fixer[reg] == dr_reg_stolen && dr_reg_fixer[reg] != DR_REG_NULL) return true; return false; +#endif } int opnd_get_reg_dcontext_offs(reg_id_t reg) { +#ifdef AARCH64 + ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + return 0; +#else switch (reg) { case DR_REG_R0: return R0_OFFSET; case DR_REG_R1: return R1_OFFSET; @@ -76,9 +85,9 @@ opnd_get_reg_dcontext_offs(reg_id_t reg) default: CLIENT_ASSERT(false, "opnd_get_reg_dcontext_offs: invalid reg"); return -1; } +#endif } -/****************************************************************************/ #ifndef STANDALONE_DECODER opnd_t @@ -88,4 +97,3 @@ opnd_create_sized_tls_slot(int offs, opnd_size_t size) } #endif /* !STANDALONE_DECODER */ -/****************************************************************************/ diff --git a/core/arch/arch_exports.h b/core/arch/arch_exports.h index 4ce23fe1a20..fd80d1290ed 100644 --- a/core/arch/arch_exports.h +++ b/core/arch/arch_exports.h @@ -1188,6 +1188,10 @@ void dr_fxsave32(byte *buf_aligned); void dr_fxrstor32(byte *buf_aligned); #endif +#ifdef AARCH64 +void cache_sync_asm(void *beg, void *end); +#endif + /* Keep in synch with x86.asm. This is the difference between the SP saved in * the mcontext and the SP of the caller of dr_app_start() and * dynamorio_app_take_over(). diff --git a/core/arch/emit_utils_shared.c b/core/arch/emit_utils_shared.c index 46f661604e6..dd92144a4f2 100644 --- a/core/arch/emit_utils_shared.c +++ b/core/arch/emit_utils_shared.c @@ -1872,7 +1872,17 @@ append_jmp_to_fcache_target(dcontext_t *dcontext, instrlist_t *ilist, if (shared) { /* next_tag placed into tls slot earlier in this routine */ #ifdef AARCH64 - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + /* Load next_tag from FCACHE_ENTER_TARGET_SLOT (TLS_REG0_SLOT): + * ldr x0, [x28] + */ + APP(ilist, INSTR_CREATE_xx(dcontext, 0xf9400380)); + /* Subtract 4 to include the fragment prefix, + * which restores X0 from TLS_REG1_SLOT: + * sub x0, x0, #4 + */ + APP(ilist, INSTR_CREATE_xx(dcontext, 0xd1000000 | 4 << 10)); + /* br x0 */ + APP(ilist, INSTR_CREATE_xx(dcontext, 0xd61f0000)); #else APP(ilist, XINST_CREATE_jump_mem(dcontext, @@ -2054,6 +2064,12 @@ emit_fcache_enter_common(dcontext_t *dcontext, generated_code_t *code, SCRATCH_REG0/*scratch*/, false/*to app*/); #endif +#ifdef AARCH64 + /* Put app's X0 in TLS_REG1_SLOT: */ + APP(&ilist, INSTR_CREATE_xx(dcontext, 0xf94000a0)); /* ldr x0, [x5] */ + APP(&ilist, INSTR_CREATE_xx(dcontext, 0xf9000780)); /* str x0, [x28, #8] */ +#endif + /* restore the original register state */ append_restore_xflags(dcontext, &ilist, absolute); append_restore_simd_reg(dcontext, &ilist, absolute); @@ -2426,7 +2442,8 @@ append_fcache_return_common(dcontext_t *dcontext, generated_code_t *code, * attacks, the dstack is not perfectly protected. */ #ifdef AARCH64 - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + APP(ilist, RESTORE_FROM_DC(dcontext, DR_REG_X1, DSTACK_OFFSET)); + APP(ilist, INSTR_CREATE_xx(dcontext, 0x9100001f | 1 << 5)); /* mov sp, x1 */ #else APP(ilist, RESTORE_FROM_DC(dcontext, REG_XSP, DSTACK_OFFSET)); #endif @@ -5209,7 +5226,8 @@ emit_special_ibl_xfer(dcontext_t *dcontext, byte *pc, generated_code_t *code, APP(&ilist, XINST_CREATE_jump(dcontext, opnd_create_pc(ibl_tgt))); #elif defined(AARCH64) (void)ibl_tgt; - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ + /* Random unallocated encoding to detect if code is excecuted: */ + APP(&ilist, INSTR_CREATE_xx(dcontext, 0x801e04)); #elif defined(ARM) /* i#1906: loads to PC must use word-aligned addresses */ ASSERT(ALIGNED(get_ibl_entry_tls_offs(dcontext, ibl_tgt), PC_LOAD_ADDR_ALIGN)); diff --git a/core/arch/mangle_shared.c b/core/arch/mangle_shared.c index 5da4caa3976..e0334c25cf4 100644 --- a/core/arch/mangle_shared.c +++ b/core/arch/mangle_shared.c @@ -822,15 +822,23 @@ mangle(dcontext_t *dcontext, instrlist_t *ilist, uint *flags INOUT, } #endif /* X64 || ARM */ -#ifdef ARM -# ifdef X64 -# error NYI on AArch64 for writing thread register -# endif +#if defined(ARM) || defined(AARCH64) if (!instr_is_meta(instr) && instr_reads_thread_register(instr)) { next_instr = mangle_reads_thread_register(dcontext, ilist, instr, next_instr); continue; } +#endif /* ARM || AARCH64 */ + +#ifdef AARCH64 + if (!instr_is_meta(instr) && instr_writes_thread_register(instr)) { + next_instr = mangle_writes_thread_register(dcontext, ilist, + instr, next_instr); + continue; + } +#endif /* AARCH64 */ + +#ifdef ARM /* Our stolen reg model is to expose to the client. We assume that any * meta instrs using it are using it as TLS. Ditto w/ use of PC. */