-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[compiler-rt] Avoid memintrinsic calls inserted by the compiler
D135716 introduced -ftrivial-auto-var-init=pattern where supported. Unfortunately this introduces unwanted memset() for large stack arrays, as shown by the new tests added for asan and msan (tsan already had this test). In general, the problem of compiler-inserted memintrinsic calls (memset/memcpy/memmove) is not new to compiler-rt, and has been a problem before. To avoid introducing unwanted memintrinsic calls, we redefine memintrinsics as __sanitizer_internal_mem* at the assembly level for most source files automatically (where sanitizer_common_internal_defs.h is included). In few cases, redefining a symbol in this way causes issues for interceptors, namely the memintrinsic interceptor themselves. For such source files we have to selectively disable the redefinition. Other alternatives have been considered, but simply do not work well in the context of compiler-rt: 1. Linker --wrap: this does not work because --wrap only applies to the final link, and would not apply when building sanitizer static libraries. 2. Changing references to memset() via objcopy: this may work, but due to the complexities of the build system, introducing such a post-processing step for the right object files (in particular object files defining memset cannot be touched) seems infeasible. The chosen solution works well (as shown by the tests). Other libraries have chosen the same solution where nothing else works (see e.g. glibc's "symbol-hacks.h"). v4: - Add interface attribute to __sanitizer_internal_mem* declarations as well, as otherwise some compilers (MSVC) will complain. - Add SANITIZER_COMMON_NO_REDEFINE_BUILTINS to source files using C++STL, since this could lead to ODR violations (see added comment). v3: - Don't use ALIAS() to alias internal_mem*() functions to __sanitizer_internal_mem*() functions, but just define them as ALWAYS_INLINE functions instead. This will work on darwin and windows. v2: - Fix ubsan_minimal build where compiler decides to insert memset/memcpy: ubsan_minimal has work without RTSanitizerCommonLibc, therefore do not redefine the builtins. - Fix definition of internal_mem* functions with compilers that want the aliased function to already be defined before. - Fix definition of __sanitizer_internal_mem* functions with compilers more pedantic about attribute placement around extern "C". Reviewed By: vitalybuka, dvyukov Differential Revision: https://reviews.llvm.org/D151152
- Loading branch information
Showing
23 changed files
with
138 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//===-- sanitizer_redefine_builtins.h ---------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Redefine builtin functions to use internal versions. This is needed where | ||
// compiler optimizations end up producing unwanted libcalls! | ||
// | ||
//===----------------------------------------------------------------------===// | ||
#ifndef SANITIZER_COMMON_NO_REDEFINE_BUILTINS | ||
#ifndef SANITIZER_REDEFINE_BUILTINS_H | ||
#define SANITIZER_REDEFINE_BUILTINS_H | ||
|
||
// The asm hack only works with GCC and Clang. | ||
#if !defined(_MSC_VER) || defined(__clang__) | ||
|
||
asm("memcpy = __sanitizer_internal_memcpy"); | ||
asm("memmove = __sanitizer_internal_memmove"); | ||
asm("memset = __sanitizer_internal_memset"); | ||
|
||
// The builtins should not be redefined in source files that make use of C++ | ||
// standard libraries, in particular where C++STL headers with inline functions | ||
// are used. The redefinition in such cases would lead to ODR violations. | ||
// | ||
// Try to break the build in common cases where builtins shouldn't be redefined. | ||
namespace std { | ||
class Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file { | ||
Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file( | ||
const Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file&) = delete; | ||
Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file& operator=( | ||
const Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file&) = delete; | ||
}; | ||
using array = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using atomic = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using function = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using map = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using set = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using shared_ptr = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using string = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using unique_ptr = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using unordered_map = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using unordered_set = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
using vector = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; | ||
} // namespace std | ||
|
||
#endif // !_MSC_VER || __clang__ | ||
|
||
#endif // SANITIZER_REDEFINE_BUILTINS_H | ||
#endif // SANITIZER_COMMON_NO_REDEFINE_BUILTINS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Verify runtime doesn't contain compiler-emitted memcpy/memmove calls. | ||
// | ||
// REQUIRES: shared_unwind, x86_64-target-arch | ||
|
||
// RUN: %clang_asan -O1 %s -o %t | ||
// RUN: llvm-objdump -d -l %t | FileCheck --implicit-check-not="{{(callq|jmpq) .*<(__interceptor_.*)?mem(cpy|set|move)>}}" %s | ||
|
||
int main() { return 0; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Verify runtime doesn't contain compiler-emitted memcpy/memmove calls. | ||
// | ||
// REQUIRES: shared_unwind, x86_64-target-arch | ||
|
||
// RUN: %clang_msan -O1 %s -o %t | ||
// RUN: llvm-objdump -d -l %t | FileCheck --implicit-check-not="{{(callq|jmpq) .*<(__interceptor_.*)?mem(cpy|set|move)>}}" %s | ||
|
||
int main() { return 0; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters