From ef2c973556519bd985c25da79f080668b64efc1f Mon Sep 17 00:00:00 2001 From: Derek Bruening Date: Wed, 3 Jun 2020 16:26:15 -0400 Subject: [PATCH] i#3315,i#3348: Move mem{cpy,set,move} into memfuncs on AArchXX (#4309) Provides isolation of mem{cpy,set,move} in the DR static library on AArchXX. Moves the assembly mem{cpy,set} into a separate memfuncs.asm for arm and aarch64, and links in memmove.c. Marks the __mem{cpy,set}_chk aliases as weak. This brings AArchXX into parity with x86 on library symbol isolation. Removes the exceptions for AArchXX in the CMake_symbol_check test. Confirms the build-time test fails without the code changes here: CMake Error at xxx/core/CMake_symbol_check.cmake:98 (message): *** Error: xxx/build_a64_dbg_tests/lib64/debug/libdynamorio_static_nohide.a contains a likely-to-conflict symbol: 4279: 00000000002cea3c 0 FUNC GLOBAL HIDDEN 248 memcpy Issue: #3315, #3348 --- core/CMakeLists.txt | 15 +++--- core/CMake_symbol_check.cmake | 10 +--- core/arch/aarch64/aarch64.asm | 41 --------------- core/arch/aarch64/memfuncs.asm | 84 +++++++++++++++++++++++++++++++ core/arch/arm/arm.asm | 51 +------------------ core/arch/arm/memfuncs.asm | 91 ++++++++++++++++++++++++++++++++++ libutil/CMakeLists.txt | 6 +-- 7 files changed, 188 insertions(+), 110 deletions(-) create mode 100644 core/arch/aarch64/memfuncs.asm create mode 100644 core/arch/arm/memfuncs.asm diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 99ad6184b2c..1c5f5069d58 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,5 +1,5 @@ # ********************************************************** -# Copyright (c) 2010-2019 Google, Inc. All rights reserved. +# Copyright (c) 2010-2020 Google, Inc. All rights reserved. # Copyright (c) 2009-2010 VMware, Inc. All rights reserved. # ********************************************************** @@ -80,16 +80,17 @@ endif () add_asm_target(arch/pre_inject_asm.asm preinject_asm_src preinject_asm_tgt "" "-DNOT_DYNAMORIO_CORE_PROPER" "${asm_deps}") -if (UNIX AND X86) +if (UNIX) # i#3315: We want our own memcpy and memset for the shared-lib DR core and # for drinjectlib + drfrontendlib to avoid glibc-versioned symbols in # 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/x86/memfuncs.asm memfuncs_asm_src memfuncs_asm_tgt + add_asm_target(arch/${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) + add_dependencies(drmemfuncs api_headers) endif () # i#1409: to share core libc-ish code with non-core, we use the "drlibc" library. @@ -581,7 +582,7 @@ add_library(dynamorio SHARED ) configure_core_lib(dynamorio) -if (UNIX AND X86) +if (UNIX) # We need our own memcpy + memset for isolation. # They're separated out for sharing for i#1504. target_link_libraries(dynamorio drmemfuncs) @@ -901,7 +902,7 @@ if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") add_dependencies(${PRELOAD_NAME} ${preinject_asm_tgt}) endif () target_link_libraries(${PRELOAD_NAME} drlibc) -if (UNIX AND X86) +if (UNIX) # We need our own memcpy + memset for isolation. target_link_libraries(${PRELOAD_NAME} drmemfuncs) endif () @@ -995,7 +996,7 @@ endif () add_library(drinjectlib ${inject_lib_type} ${INJECTOR_SRCS}) add_gen_events_deps(drinjectlib) target_link_libraries(drinjectlib drdecode drlibc) -if (UNIX AND X86) +if (UNIX) # We need our own memcpy + memset to avoid glibc versioning (i#1504). target_link_libraries(drinjectlib drmemfuncs) endif () @@ -1168,7 +1169,7 @@ install_exported_target(drdecode ${INSTALL_LIB}) # We have to export drlibc as static libs we're exporting depend on it. DR_export_target(drlibc) install_exported_target(drlibc ${INSTALL_LIB_BASE}) -if (UNIX AND X86) +if (UNIX) DR_export_target(drmemfuncs) install_exported_target(drmemfuncs ${INSTALL_LIB_BASE}) endif () diff --git a/core/CMake_symbol_check.cmake b/core/CMake_symbol_check.cmake index a6149308a57..a30854a14e1 100644 --- a/core/CMake_symbol_check.cmake +++ b/core/CMake_symbol_check.cmake @@ -1,5 +1,5 @@ # ********************************************************** -# Copyright (c) 2019 Google, Inc. All rights reserved. +# Copyright (c) 2019-2020 Google, Inc. All rights reserved. # ********************************************************** # Redistribution and use in source and binary forms, with or without @@ -94,14 +94,6 @@ foreach(line ${lines}) # OK: an exception we allow for now. set(is_ok ON) endif () - if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR - CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") - if (line MATCHES "memcpy\n" OR - line MATCHES "memset\n") - # XXX i#3348: We need to remove these from the aarchxx builds too. - set(is_ok ON) - endif () - endif () if (NOT is_ok) message(FATAL_ERROR "*** Error: ${${lib_file}} contains a likely-to-conflict symbol: ${line}") diff --git a/core/arch/aarch64/aarch64.asm b/core/arch/aarch64/aarch64.asm index 90ad127ca70..290545e72ac 100644 --- a/core/arch/aarch64/aarch64.asm +++ b/core/arch/aarch64/aarch64.asm @@ -423,47 +423,6 @@ ADDRTAKEN_LABEL(safe_read_asm_recover:) ret END_FUNC(safe_read_asm) -#ifdef UNIX -/* i#46: Private memcpy and memset for libc isolation. Xref comment in x86.asm. - */ - -/* Private memcpy. - * FIXME i#1569: We should optimize this as it can be on the critical path. - */ - DECLARE_FUNC(memcpy) -GLOBAL_LABEL(memcpy:) - mov x3, ARG1 - cbz ARG3, 2f -1: ldrb w4, [ARG2], #1 - strb w4, [x3], #1 - sub ARG3, ARG3, #1 - cbnz ARG3, 1b -2: ret - END_FUNC(memcpy) - -/* Private memset. - * FIXME i#1569: we should optimize this as it can be on the critical path. - */ - DECLARE_FUNC(memset) -GLOBAL_LABEL(memset:) - mov x3, ARG1 - cbz ARG3, 2f -1: strb w1, [x3], #1 - sub ARG3, ARG3, #1 - cbnz ARG3, 1b -2: ret - END_FUNC(memset) - -/* See x86.asm notes about needing these to avoid gcc invoking *_chk */ -.global __memcpy_chk -.hidden __memcpy_chk -.set __memcpy_chk,memcpy - -.global __memset_chk -.hidden __memset_chk -.set __memset_chk,memset -#endif /* UNIX */ - #ifdef CLIENT_INTERFACE /* Xref x86.asm dr_try_start about calling dr_setjmp without a call frame. diff --git a/core/arch/aarch64/memfuncs.asm b/core/arch/aarch64/memfuncs.asm new file mode 100644 index 00000000000..28f0f737a9a --- /dev/null +++ b/core/arch/aarch64/memfuncs.asm @@ -0,0 +1,84 @@ +/* ********************************************************** + * Copyright (c) 2019-2020 Google, Inc. All rights reserved. + * 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. + */ + +/* + * memfuncs.asm: Contains our custom memcpy and memset routines. + * + * See the long comment at the top of x86/memfuncs.asm. + */ + +#include "../asm_defines.asm" +START_FILE +#ifdef UNIX + +/* Private memcpy. + * FIXME i#1569: We should optimize this as it can be on the critical path. + */ + DECLARE_FUNC(memcpy) +GLOBAL_LABEL(memcpy:) + mov x3, ARG1 + cbz ARG3, 2f +1: ldrb w4, [ARG2], #1 + strb w4, [x3], #1 + sub ARG3, ARG3, #1 + cbnz ARG3, 1b +2: ret + END_FUNC(memcpy) + +/* Private memset. + * FIXME i#1569: we should optimize this as it can be on the critical path. + */ + DECLARE_FUNC(memset) +GLOBAL_LABEL(memset:) + mov x3, ARG1 + cbz ARG3, 2f +1: strb w1, [x3], #1 + sub ARG3, ARG3, #1 + cbnz ARG3, 1b +2: ret + END_FUNC(memset) + +/* See x86.asm notes about needing these to avoid gcc invoking *_chk */ +.global __memcpy_chk +.hidden __memcpy_chk +WEAK(__memcpy_chk) +.set __memcpy_chk,memcpy + +.global __memset_chk +.hidden __memset_chk +WEAK(__memset_chk) +.set __memset_chk,memset + +#endif /* UNIX */ + +END_FILE diff --git a/core/arch/arm/arm.asm b/core/arch/arm/arm.asm index b44d8976026..09a72c1d4b6 100644 --- a/core/arch/arm/arm.asm +++ b/core/arch/arm/arm.asm @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2014-2019 Google, Inc. All rights reserved. + * Copyright (c) 2014-2020 Google, Inc. All rights reserved. * ********************************************************** */ /* @@ -412,55 +412,6 @@ ADDRTAKEN_LABEL(safe_read_asm_recover:) END_FUNC(safe_read_asm) -#ifdef UNIX -/* i#46: Private memcpy and memset for libc isolation. Xref comment in x86.asm. - */ - -/* Private memcpy. - * FIXME i#1551: we should optimize this as it can be on the critical path. - */ - DECLARE_FUNC(memcpy) -GLOBAL_LABEL(memcpy:) - cmp ARG3, #0 - mov REG_R12/*scratch reg*/, ARG1 -1: beq 2f - ldrb REG_R3, [ARG2] - strb REG_R3, [ARG1] - subs ARG3, ARG3, #1 - add ARG2, ARG2, #1 - add ARG1, ARG1, #1 - b 1b -2: mov REG_R0, REG_R12 - bx lr - END_FUNC(memcpy) - -/* Private memset. - * FIXME i#1551: we should optimize this as it can be on the critical path. - */ - DECLARE_FUNC(memset) -GLOBAL_LABEL(memset:) - cmp ARG3, #0 - mov REG_R12/*scratch reg*/, ARG1 -1: beq 2f - strb ARG2, [ARG1] - subs ARG3, ARG3, #1 - add ARG1, ARG1, #1 - b 1b -2: mov REG_R0, REG_R12 - bx lr - END_FUNC(memset) - -/* See x86.asm notes about needing these to avoid gcc invoking *_chk */ -.global __memcpy_chk -.hidden __memcpy_chk -.set __memcpy_chk,memcpy - -.global __memset_chk -.hidden __memset_chk -.set __memset_chk,memset -#endif /* UNIX */ - - #ifdef CLIENT_INTERFACE /* Xref x86.asm dr_try_start about calling dr_setjmp without a call frame. * diff --git a/core/arch/arm/memfuncs.asm b/core/arch/arm/memfuncs.asm new file mode 100644 index 00000000000..ce06cef0e88 --- /dev/null +++ b/core/arch/arm/memfuncs.asm @@ -0,0 +1,91 @@ +/* ********************************************************** + * Copyright (c) 2014-2020 Google, Inc. 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 Google, Inc. 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 + * 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. + */ + +/* + * memfuncs.asm: Contains our custom memcpy and memset routines. + * + * See the long comment at the top of x86/memfuncs.asm. + */ + +#include "../asm_defines.asm" +START_FILE + +#ifdef UNIX + +/* Private memcpy. + * FIXME i#1551: we should optimize this as it can be on the critical path. + */ + DECLARE_FUNC(memcpy) +GLOBAL_LABEL(memcpy:) + cmp ARG3, #0 + mov REG_R12/*scratch reg*/, ARG1 +1: beq 2f + ldrb REG_R3, [ARG2] + strb REG_R3, [ARG1] + subs ARG3, ARG3, #1 + add ARG2, ARG2, #1 + add ARG1, ARG1, #1 + b 1b +2: mov REG_R0, REG_R12 + bx lr + END_FUNC(memcpy) + +/* Private memset. + * FIXME i#1551: we should optimize this as it can be on the critical path. + */ + DECLARE_FUNC(memset) +GLOBAL_LABEL(memset:) + cmp ARG3, #0 + mov REG_R12/*scratch reg*/, ARG1 +1: beq 2f + strb ARG2, [ARG1] + subs ARG3, ARG3, #1 + add ARG1, ARG1, #1 + b 1b +2: mov REG_R0, REG_R12 + bx lr + END_FUNC(memset) + +/* See x86.asm notes about needing these to avoid gcc invoking *_chk */ +.global __memcpy_chk +.hidden __memcpy_chk +WEAK(__memcpy_chk) +.set __memcpy_chk,memcpy + +.global __memset_chk +.hidden __memset_chk +WEAK(__memset_chk) +.set __memset_chk,memset + +#endif /* UNIX */ + +END_FILE diff --git a/libutil/CMakeLists.txt b/libutil/CMakeLists.txt index 5e672ee9f18..40e7592f4af 100644 --- a/libutil/CMakeLists.txt +++ b/libutil/CMakeLists.txt @@ -1,5 +1,5 @@ # ********************************************************** -# Copyright (c) 2010-2019 Google, Inc. All rights reserved. +# Copyright (c) 2010-2020 Google, Inc. All rights reserved. # Copyright (c) 2009-2010 VMware, Inc. All rights reserved. # ********************************************************** @@ -186,7 +186,7 @@ DR_install(TARGETS drconfiglib DESTINATION ${INSTALL_BIN}) # drconfiglib now uses drfront_access() # drconfiglib needs drlibc for dr_fpu_exception_init() target_link_libraries(drconfiglib drfrontendlib drlibc) -if (UNIX AND X86) +if (UNIX) # We need our own memcpy + memset to avoid glibc versioning (i#1504). target_link_libraries(drconfiglib drmemfuncs) endif () @@ -202,7 +202,7 @@ if (UNIX) # We need drlibc for module-parsing routines. target_link_libraries(drfrontendlib drlibc) endif () -if (UNIX AND X86) +if (UNIX) # We need our own memcpy + memset to avoid glibc versioning (i#1504). target_link_libraries(drfrontendlib drmemfuncs) endif ()