Created
June 1, 2022 03:58
-
-
Save Enna1/f8696072bd9dc36ac236ba63839b7c16 to your computer and use it in GitHub Desktop.
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
commit 3a87bff1977a02feb072a14930add69ff47cf08d | |
Author: Enna1 <xumingjie.enna1@bytedance.com> | |
Date: Tue May 31 12:06:41 2022 +0800 | |
DumbSanitizer | |
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def | |
index 9b8936cc520c..6aa6e24d4ec4 100644 | |
--- a/clang/include/clang/Basic/Sanitizers.def | |
+++ b/clang/include/clang/Basic/Sanitizers.def | |
@@ -73,6 +73,9 @@ SANITIZER("fuzzer-no-link", FuzzerNoLink) | |
// ThreadSanitizer | |
SANITIZER("thread", Thread) | |
+// DumbSanitizer | |
+SANITIZER("dumb", Dumb) | |
+ | |
// LeakSanitizer | |
SANITIZER("leak", Leak) | |
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h | |
index d288b0151c9f..a885d68f81dd 100644 | |
--- a/clang/include/clang/Driver/SanitizerArgs.h | |
+++ b/clang/include/clang/Driver/SanitizerArgs.h | |
@@ -80,6 +80,7 @@ public: | |
return needsHwasanRt() && HwasanUseAliases; | |
} | |
bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } | |
+ bool needsDbsanRt() const { return Sanitizers.has(SanitizerKind::Dumb); } | |
bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } | |
bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); } | |
bool needsLsanRt() const { | |
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp | |
index a4d330c0ba93..fd4bff63a3d7 100644 | |
--- a/clang/lib/CodeGen/BackendUtil.cpp | |
+++ b/clang/lib/CodeGen/BackendUtil.cpp | |
@@ -68,6 +68,7 @@ | |
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" | |
#include "llvm/Transforms/Instrumentation/BoundsChecking.h" | |
#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h" | |
+#include "llvm/Transforms/Instrumentation/DumbSanitizer.h" | |
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h" | |
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" | |
#include "llvm/Transforms/Instrumentation/InstrProfiling.h" | |
@@ -390,6 +391,11 @@ static void addThreadSanitizerPass(const PassManagerBuilder &Builder, | |
PM.add(createThreadSanitizerLegacyPassPass()); | |
} | |
+static void addDumbSanitizerPass(const PassManagerBuilder &Builder, | |
+ legacy::PassManagerBase &PM) { | |
+ PM.add(createDumbSanitizerLegacyPassPass()); | |
+} | |
+ | |
static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder, | |
legacy::PassManagerBase &PM) { | |
const PassManagerBuilderWrapper &BuilderWrapper = | |
@@ -834,6 +840,13 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, | |
addThreadSanitizerPass); | |
} | |
+ if (LangOpts.Sanitize.has(SanitizerKind::Dumb)) { | |
+ PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, | |
+ addDumbSanitizerPass); | |
+ PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, | |
+ addDumbSanitizerPass); | |
+ } | |
+ | |
if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { | |
PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, | |
addDataFlowSanitizerPass); | |
@@ -1194,6 +1207,11 @@ static void addSanitizers(const Triple &TargetTriple, | |
MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); | |
} | |
+ if (LangOpts.Sanitize.has(SanitizerKind::Dumb)) { | |
+ MPM.addPass(ModuleDumbSanitizerPass()); | |
+ MPM.addPass(createModuleToFunctionPassAdaptor(DumbSanitizerPass())); | |
+ } | |
+ | |
auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) { | |
if (LangOpts.Sanitize.has(Mask)) { | |
bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts); | |
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp | |
index 8f9244cae8db..37c2cf724fc3 100644 | |
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp | |
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp | |
@@ -845,6 +845,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, | |
} | |
if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes()) | |
SharedRuntimes.push_back("tsan"); | |
+ if (SanArgs.needsDbsanRt() && SanArgs.linkRuntimes()) | |
+ SharedRuntimes.push_back("dbsan"); | |
if (SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { | |
if (SanArgs.needsHwasanAliasesRt()) | |
SharedRuntimes.push_back("hwasan_aliases"); | |
@@ -896,6 +898,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, | |
} | |
if (SanArgs.needsDfsanRt() && SanArgs.linkRuntimes()) | |
StaticRuntimes.push_back("dfsan"); | |
+ if (SanArgs.needsDbsanRt() && SanArgs.linkRuntimes()) | |
+ StaticRuntimes.push_back("dbsan"); | |
if (SanArgs.needsLsanRt() && SanArgs.linkRuntimes()) | |
StaticRuntimes.push_back("lsan"); | |
if (SanArgs.needsMsanRt() && SanArgs.linkRuntimes()) { | |
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp | |
index 83cb41159de7..82936d06cdb1 100644 | |
--- a/clang/lib/Driver/ToolChains/Linux.cpp | |
+++ b/clang/lib/Driver/ToolChains/Linux.cpp | |
@@ -719,6 +719,8 @@ SanitizerMask Linux::getSupportedSanitizers() const { | |
Res |= SanitizerKind::Leak; | |
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ) | |
Res |= SanitizerKind::Thread; | |
+ if (IsX86_64) | |
+ Res |= SanitizerKind::Dumb; | |
if (IsX86_64) | |
Res |= SanitizerKind::KernelMemory; | |
if (IsX86 || IsX86_64) | |
diff --git a/clang/runtime/CMakeLists.txt b/clang/runtime/CMakeLists.txt | |
index ca7e17927ee1..afd58a1412a1 100644 | |
--- a/clang/runtime/CMakeLists.txt | |
+++ b/clang/runtime/CMakeLists.txt | |
@@ -119,7 +119,7 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/) | |
COMPONENT compiler-rt) | |
# Add top-level targets that build specific compiler-rt runtimes. | |
- set(COMPILER_RT_RUNTIMES fuzzer asan builtins dfsan lsan msan profile tsan ubsan ubsan-minimal) | |
+ set(COMPILER_RT_RUNTIMES fuzzer asan builtins dfsan lsan msan profile tsan dbsan ubsan ubsan-minimal) | |
foreach(runtime ${COMPILER_RT_RUNTIMES}) | |
get_ext_project_build_command(build_runtime_cmd ${runtime}) | |
add_custom_target(${runtime} | |
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake | |
index 3e86cf63c789..e67342c7c5c1 100644 | |
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake | |
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake | |
@@ -60,6 +60,7 @@ set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64}) | |
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64} | |
${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}) | |
set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) | |
+set(ALL_DBSAN_SUPPORTED_ARCH ${X86} ${X86_64}) | |
set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} | |
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}) | |
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64} | |
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake | |
index fc62d5ecc0a9..3e8563e8c2d4 100644 | |
--- a/compiler-rt/cmake/config-ix.cmake | |
+++ b/compiler-rt/cmake/config-ix.cmake | |
@@ -570,6 +570,9 @@ if(APPLE) | |
list_intersect(TSAN_SUPPORTED_ARCH | |
ALL_TSAN_SUPPORTED_ARCH | |
SANITIZER_COMMON_SUPPORTED_ARCH) | |
+ list_intersect(DBSAN_SUPPORTED_ARCH | |
+ ALL_DBSAN_SUPPORTED_ARCH | |
+ SANITIZER_COMMON_SUPPORTED_ARCH) | |
list_intersect(UBSAN_SUPPORTED_ARCH | |
ALL_UBSAN_SUPPORTED_ARCH | |
SANITIZER_COMMON_SUPPORTED_ARCH) | |
@@ -618,6 +621,7 @@ else() | |
filter_available_targets(MEMPROF_SUPPORTED_ARCH ${ALL_MEMPROF_SUPPORTED_ARCH}) | |
filter_available_targets(PROFILE_SUPPORTED_ARCH ${ALL_PROFILE_SUPPORTED_ARCH}) | |
filter_available_targets(TSAN_SUPPORTED_ARCH ${ALL_TSAN_SUPPORTED_ARCH}) | |
+ filter_available_targets(DBSAN_SUPPORTED_ARCH ${ALL_DBSAN_SUPPORTED_ARCH}) | |
filter_available_targets(UBSAN_SUPPORTED_ARCH ${ALL_UBSAN_SUPPORTED_ARCH}) | |
filter_available_targets(SAFESTACK_SUPPORTED_ARCH | |
${ALL_SAFESTACK_SUPPORTED_ARCH}) | |
@@ -662,7 +666,7 @@ if(COMPILER_RT_SUPPORTED_ARCH) | |
endif() | |
message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}") | |
-set(ALL_SANITIZERS asan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo;ubsan_minimal;gwp_asan) | |
+set(ALL_SANITIZERS asan;dfsan;msan;hwasan;tsan;dbsan;safestack;cfi;scudo;ubsan_minimal;gwp_asan) | |
set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING | |
"sanitizers to build if supported on the target (all;${ALL_SANITIZERS})") | |
list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}") | |
@@ -762,6 +766,19 @@ else() | |
set(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME FALSE) | |
endif() | |
+if (COMPILER_RT_HAS_SANITIZER_COMMON AND DBSAN_SUPPORTED_ARCH AND | |
+ OS_NAME MATCHES "Linux") | |
+ set(COMPILER_RT_HAS_DBSAN TRUE) | |
+else() | |
+ set(COMPILER_RT_HAS_DBSAN FALSE) | |
+endif() | |
+ | |
+if (OS_NAME MATCHES "Linux") | |
+ set(COMPILER_RT_DBSAN_HAS_STATIC_RUNTIME TRUE) | |
+else() | |
+ set(COMPILER_RT_DBSAN_HAS_STATIC_RUNTIME FALSE) | |
+endif() | |
+ | |
if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND | |
OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS") | |
set(COMPILER_RT_HAS_UBSAN TRUE) | |
diff --git a/compiler-rt/lib/dbsan/CMakeLists.txt b/compiler-rt/lib/dbsan/CMakeLists.txt | |
new file mode 100644 | |
index 000000000000..b6c9ed649968 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/CMakeLists.txt | |
@@ -0,0 +1,47 @@ | |
+include_directories(..) | |
+ | |
+# Runtime library sources and build flags. | |
+set(DBSAN_RTL_SOURCES | |
+ dbsan_flags.cpp | |
+ dbsan_interface.cpp | |
+ dbsan_rtl.cpp | |
+ ) | |
+ | |
+set(DBSAN_RTL_HEADERS | |
+ dbsan_flags.h | |
+ dbsan_interface.h | |
+ dbsan_rtl.h | |
+ ) | |
+ | |
+set(DBSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS}) | |
+append_rtti_flag(OFF DBSAN_COMMON_CFLAGS) | |
+# Prevent clang from generating libc calls. | |
+append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding DBSAN_COMMON_CFLAGS) | |
+ | |
+# Too many existing bugs, needs cleanup. | |
+append_list_if(COMPILER_RT_HAS_WNO_FORMAT -Wno-format DBSAN_COMMON_CFLAGS) | |
+ | |
+# Static runtime library. | |
+add_compiler_rt_component(dbsan) | |
+ | |
+foreach(arch ${DBSAN_SUPPORTED_ARCH}) | |
+ set(DBSAN_CFLAGS ${DBSAN_COMMON_CFLAGS}) | |
+ append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE DBSAN_CFLAGS) | |
+ add_compiler_rt_runtime(clang_rt.dbsan | |
+ STATIC | |
+ ARCHS ${arch} | |
+ SOURCES ${DBSAN_RTL_SOURCES} | |
+ $<TARGET_OBJECTS:RTInterception.${arch}> | |
+ $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> | |
+ $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> | |
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}> | |
+ ADDITIONAL_HEADERS ${DBSAN_RTL_HEADERS} | |
+ CFLAGS ${DBSAN_CFLAGS} | |
+ PARENT_TARGET dbsan) | |
+ add_sanitizer_rt_symbols(clang_rt.dbsan | |
+ ARCHS ${arch} | |
+ EXTRA dbsan.syms.extra) | |
+ add_dependencies(dbsan | |
+ clang_rt.dbsan-${arch}-symbols) | |
+endforeach() | |
+ | |
diff --git a/compiler-rt/lib/dbsan/dbsan.syms.extra b/compiler-rt/lib/dbsan/dbsan.syms.extra | |
new file mode 100644 | |
index 000000000000..561a73aa1369 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan.syms.extra | |
@@ -0,0 +1,3 @@ | |
+__dbsan_init | |
+__dbsan_read* | |
+__dbsan_write* | |
diff --git a/compiler-rt/lib/dbsan/dbsan_flags.cpp b/compiler-rt/lib/dbsan/dbsan_flags.cpp | |
new file mode 100644 | |
index 000000000000..cacc4f07bf9c | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan_flags.cpp | |
@@ -0,0 +1,47 @@ | |
+//===-- dbsan_flags.cpp --------------------------------------*- 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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file is a part of DumbSanitizer. | |
+// | |
+// DbSan flag parsing logic. | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#include "dbsan_flags.h" | |
+#include "sanitizer_common/sanitizer_common.h" | |
+#include "sanitizer_common/sanitizer_flag_parser.h" | |
+#include "sanitizer_common/sanitizer_flags.h" | |
+ | |
+namespace __dbsan { | |
+ | |
+Flags dbsan_flags_dont_use_directly; // use via flags(). | |
+ | |
+void Flags::SetDefaults() { | |
+#define DBSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; | |
+#include "dbsan_flags.inc" | |
+#undef DBSAN_FLAG | |
+} | |
+ | |
+static void RegisterDbSanFlags(__sanitizer::FlagParser *parser, Flags *f) { | |
+#define DBSAN_FLAG(Type, Name, DefaultValue, Description) \ | |
+ RegisterFlag(parser, #Name, Description, &f->Name); | |
+#include "dbsan_flags.inc" | |
+#undef DBSAN_FLAG | |
+} | |
+ | |
+void InitializeFlags() { | |
+ Flags *f = flags(); | |
+ f->SetDefaults(); | |
+ | |
+ __sanitizer::FlagParser dbsan_parser; | |
+ RegisterDbSanFlags(&dbsan_parser, f); | |
+ | |
+ // Override from command line. | |
+ dbsan_parser.ParseStringFromEnv("DBSAN_OPTIONS"); | |
+} | |
+ | |
+} // namespace __dbsan | |
diff --git a/compiler-rt/lib/dbsan/dbsan_flags.h b/compiler-rt/lib/dbsan/dbsan_flags.h | |
new file mode 100644 | |
index 000000000000..4803ec8fc830 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan_flags.h | |
@@ -0,0 +1,37 @@ | |
+//===-- dbsan_flags.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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file is a part of DumbSanitizer. | |
+// | |
+// DumbSanitizer runtime flags. | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef DBSAN_FLAGS_H | |
+#define DBSAN_FLAGS_H | |
+ | |
+#include "sanitizer_common/sanitizer_flag_parser.h" | |
+#include "sanitizer_common/sanitizer_internal_defs.h" | |
+ | |
+namespace __dbsan { | |
+ | |
+struct Flags { | |
+#define DBSAN_FLAG(Type, Name, DefaultValue, Description) Type Name; | |
+#include "dbsan_flags.inc" | |
+#undef DBSAN_FLAG | |
+ | |
+ void SetDefaults(); | |
+}; | |
+ | |
+extern Flags dbsan_flags_dont_use_directly; | |
+inline Flags *flags() { return &dbsan_flags_dont_use_directly; } | |
+ | |
+void InitializeFlags(); | |
+ | |
+} // namespace __dbsan | |
+ | |
+#endif // DBSAN_FLAGS_H | |
diff --git a/compiler-rt/lib/dbsan/dbsan_flags.inc b/compiler-rt/lib/dbsan/dbsan_flags.inc | |
new file mode 100644 | |
index 000000000000..b4fc06cfa0a0 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan_flags.inc | |
@@ -0,0 +1,19 @@ | |
+//===-- dbsan_flags.inc ------------------------------------------*- 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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// DbSan runtime flags. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+#ifndef DBSAN_FLAG | |
+# error "Define DBSAN_FLAG prior to including this file!" | |
+#endif | |
+ | |
+// DBSAN_FLAG(Type, Name, DefaultValue, Description) | |
+ | |
+DBSAN_FLAG(bool, verbose, false, "Print runtime loginfo.") | |
+DBSAN_FLAG(bool, print_frequent_access, false, "Print most frequently access info at exit.") | |
diff --git a/compiler-rt/lib/dbsan/dbsan_interface.cpp b/compiler-rt/lib/dbsan/dbsan_interface.cpp | |
new file mode 100644 | |
index 000000000000..c977d812d5e6 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan_interface.cpp | |
@@ -0,0 +1,39 @@ | |
+//===-- dbsan_interface.cpp | |
+//------------------------------------------------===// | |
+// | |
+// 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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file is a part of DumbSanitizer (DbSan). | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#include "dbsan_interface.h" | |
+#include "dbsan_rtl.h" | |
+ | |
+using namespace __dbsan; | |
+ | |
+void __dbsan_init() { Initialize(); } | |
+ | |
+void __dbsan_read1(void *addr) { MemoryAccess((uptr)addr, 1, kAccessRead); } | |
+ | |
+void __dbsan_read2(void *addr) { MemoryAccess((uptr)addr, 2, kAccessRead); } | |
+ | |
+void __dbsan_read4(void *addr) { MemoryAccess((uptr)addr, 4, kAccessRead); } | |
+ | |
+void __dbsan_read8(void *addr) { MemoryAccess((uptr)addr, 8, kAccessRead); } | |
+ | |
+void __dbsan_read16(void *addr) { MemoryAccess((uptr)addr, 16, kAccessRead); } | |
+ | |
+void __dbsan_write1(void *addr) { MemoryAccess((uptr)addr, 1, kAccessWrite); } | |
+ | |
+void __dbsan_write2(void *addr) { MemoryAccess((uptr)addr, 2, kAccessWrite); } | |
+ | |
+void __dbsan_write4(void *addr) { MemoryAccess((uptr)addr, 4, kAccessWrite); } | |
+ | |
+void __dbsan_write8(void *addr) { MemoryAccess((uptr)addr, 8, kAccessWrite); } | |
+ | |
+void __dbsan_write16(void *addr) { MemoryAccess((uptr)addr, 16, kAccessWrite); } | |
\ No newline at end of file | |
diff --git a/compiler-rt/lib/dbsan/dbsan_interface.h b/compiler-rt/lib/dbsan/dbsan_interface.h | |
new file mode 100644 | |
index 000000000000..2157cc3bfb54 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan_interface.h | |
@@ -0,0 +1,45 @@ | |
+//===-- dbsan_interface.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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file is a part of DumbSanitizer (DbSan). | |
+// | |
+// The functions declared in this header will be inserted by the instrumentation | |
+// module. | |
+//===----------------------------------------------------------------------===// | |
+#ifndef DBSAN_INTERFACE_H | |
+#define DBSAN_INTERFACE_H | |
+ | |
+#include <sanitizer_common/sanitizer_internal_defs.h> | |
+ | |
+// This header should NOT include any other headers. | |
+// All functions in this header are extern "C" and start with __dbsan_. | |
+ | |
+#ifdef __cplusplus | |
+extern "C" { | |
+#endif | |
+ | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_init(); | |
+ | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_read1(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_read2(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_read4(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_read8(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_read16(void *addr); | |
+ | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_write1(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_write2(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_write4(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_write8(void *addr); | |
+SANITIZER_INTERFACE_ATTRIBUTE void __dbsan_write16(void *addr); | |
+ | |
+#ifdef __cplusplus | |
+} // extern "C" | |
+#endif | |
+ | |
+#endif // DBSAN_INTERFACE_H | |
\ No newline at end of file | |
diff --git a/compiler-rt/lib/dbsan/dbsan_rtl.cpp b/compiler-rt/lib/dbsan/dbsan_rtl.cpp | |
new file mode 100644 | |
index 000000000000..65efc1c3a6e4 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan_rtl.cpp | |
@@ -0,0 +1,77 @@ | |
+//===-- dbsan_rtl.cpp | |
+//------------------------------------------------------===// | |
+// | |
+// 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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file is a part of DumbSanitizer (DbSan). | |
+// | |
+// Main file (entry points) for the DbSan run-time. | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#include "dbsan_rtl.h" | |
+#include "dbsan_flags.h" | |
+#include "sanitizer_common/sanitizer_common.h" | |
+#include "sanitizer_common/sanitizer_placement_new.h" | |
+ | |
+namespace __dbsan { | |
+ | |
+static void dbsan_atexit() { | |
+ __sanitizer::Printf( | |
+ "#Most frequently accessed address: %p, access count: %zd\n", | |
+ (void *)ctx->most_frequently_accessed_addr, | |
+ ctx->most_frequently_accessed_count); | |
+} | |
+ | |
+static char ctx_placeholder[sizeof(Context)] ALIGNED(SANITIZER_CACHE_LINE_SIZE); | |
+Context *ctx; | |
+ | |
+void Initialize() { | |
+ InitializeFlags(); | |
+ if (flags()->print_frequent_access) | |
+ __sanitizer::Atexit(dbsan_atexit); | |
+ ctx = new (ctx_placeholder) Context; | |
+} | |
+ | |
+ALWAYS_INLINE USED void MemoryAccess(uptr addr, uptr size, AccessType typ) { | |
+ if (flags()->verbose) { | |
+ __sanitizer::Printf("#Memory Access: %p/%zd typ=0x%x\n", (void *)addr, size, | |
+ static_cast<int>(typ)); | |
+ } | |
+ | |
+ uptr access_count = 0; | |
+ switch (size) { | |
+ case 1: | |
+ ctx->rw1_count[addr]++; | |
+ access_count = ctx->rw1_count[addr]; | |
+ break; | |
+ case 2: | |
+ ctx->rw2_count[addr]++; | |
+ access_count = ctx->rw2_count[addr]; | |
+ break; | |
+ case 4: | |
+ ctx->rw4_count[addr]++; | |
+ access_count = ctx->rw4_count[addr]; | |
+ break; | |
+ case 8: | |
+ ctx->rw8_count[addr]++; | |
+ access_count = ctx->rw8_count[addr]; | |
+ break; | |
+ case 16: | |
+ ctx->rw16_count[addr]++; | |
+ access_count = ctx->rw16_count[addr]; | |
+ break; | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ if (access_count > ctx->most_frequently_accessed_count) { | |
+ ctx->most_frequently_accessed_count = access_count; | |
+ ctx->most_frequently_accessed_addr = addr; | |
+ } | |
+} | |
+ | |
+} // namespace __dbsan | |
\ No newline at end of file | |
diff --git a/compiler-rt/lib/dbsan/dbsan_rtl.h b/compiler-rt/lib/dbsan/dbsan_rtl.h | |
new file mode 100644 | |
index 000000000000..61ae15e84713 | |
--- /dev/null | |
+++ b/compiler-rt/lib/dbsan/dbsan_rtl.h | |
@@ -0,0 +1,52 @@ | |
+//===-- dbsan_rtl.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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file is a part of DumbSanitizer (DbSan). | |
+// | |
+// Main internal DbSan header file. | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef DBSAN_RTL_H | |
+#define DBSAN_RTL_H | |
+ | |
+#include "sanitizer_common/sanitizer_dense_map.h" | |
+#include "sanitizer_common/sanitizer_internal_defs.h" | |
+ | |
+namespace __dbsan { | |
+ | |
+using __sanitizer::uptr; | |
+typedef uptr AccessType; | |
+enum : AccessType { | |
+ kAccessWrite = 0, | |
+ kAccessRead = 1 << 0, | |
+}; | |
+ | |
+struct Context { | |
+ Context() | |
+ : initialized(), most_frequently_accessed_addr(), | |
+ most_frequently_accessed_count(), rw1_count(), rw2_count(), rw4_count(), | |
+ rw8_count(), rw16_count(){}; | |
+ bool initialized; | |
+ uptr most_frequently_accessed_addr; | |
+ uptr most_frequently_accessed_count; | |
+ __sanitizer::DenseMap<uptr, uptr> rw1_count; | |
+ __sanitizer::DenseMap<uptr, uptr> rw2_count; | |
+ __sanitizer::DenseMap<uptr, uptr> rw4_count; | |
+ __sanitizer::DenseMap<uptr, uptr> rw8_count; | |
+ __sanitizer::DenseMap<uptr, uptr> rw16_count; | |
+}; | |
+ | |
+extern Context *ctx; // The one and the only global runtime context. | |
+ | |
+void Initialize(); | |
+void MemoryAccess(uptr addr, uptr size, AccessType typ); | |
+ | |
+} // namespace __dbsan | |
+ | |
+#endif | |
\ No newline at end of file | |
diff --git a/compiler-rt/test/dbsan/CMakeLists.txt b/compiler-rt/test/dbsan/CMakeLists.txt | |
new file mode 100644 | |
index 000000000000..e69de29bb2d1 | |
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h | |
index 489ef045796f..a101b96167b6 100644 | |
--- a/llvm/include/llvm/InitializePasses.h | |
+++ b/llvm/include/llvm/InitializePasses.h | |
@@ -143,6 +143,7 @@ void initializeDomPrinterPass(PassRegistry&); | |
void initializeDomViewerPass(PassRegistry&); | |
void initializeDominanceFrontierWrapperPassPass(PassRegistry&); | |
void initializeDominatorTreeWrapperPassPass(PassRegistry&); | |
+void initializeDumbSanitizerLegacyPassPass(PassRegistry &); | |
void initializeDwarfEHPrepareLegacyPassPass(PassRegistry &); | |
void initializeEarlyCSELegacyPassPass(PassRegistry&); | |
void initializeEarlyCSEMemSSALegacyPassPass(PassRegistry&); | |
diff --git a/llvm/include/llvm/Transforms/Instrumentation/DumbSanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/DumbSanitizer.h | |
new file mode 100644 | |
index 000000000000..024a89d7c2b6 | |
--- /dev/null | |
+++ b/llvm/include/llvm/Transforms/Instrumentation/DumbSanitizer.h | |
@@ -0,0 +1,41 @@ | |
+//===--------- Definition of the DumbSanitizer class --------------*- 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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file defines the dumb sanitizer pass. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DUMBSANITIZER_H | |
+#define LLVM_TRANSFORMS_INSTRUMENTATION_DUMBSANITIZER_H | |
+ | |
+#include "llvm/IR/Function.h" | |
+#include "llvm/IR/Module.h" | |
+#include "llvm/IR/PassManager.h" | |
+#include "llvm/Pass.h" | |
+ | |
+namespace llvm { | |
+// Insert DumbSanitizer instrumentation | |
+FunctionPass *createDumbSanitizerLegacyPassPass(); | |
+ | |
+// A function pass for dbsan instrumentation. | |
+/// Inserts calls to runtime library functions. | |
+struct DumbSanitizerPass : public PassInfoMixin<DumbSanitizerPass> { | |
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); | |
+ static bool isRequired() { return true; } | |
+}; | |
+ | |
+/// A module pass for dbsan instrumentation. | |
+/// Create ctor and init functions. | |
+struct ModuleDumbSanitizerPass : public PassInfoMixin<ModuleDumbSanitizerPass> { | |
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); | |
+ static bool isRequired() { return true; } | |
+}; | |
+ | |
+} // namespace llvm | |
+ | |
+#endif | |
diff --git a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt | |
index 3b29c3df6429..8830152f2988 100644 | |
--- a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt | |
+++ b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt | |
@@ -4,6 +4,7 @@ add_llvm_component_library(LLVMInstrumentation | |
CGProfile.cpp | |
ControlHeightReduction.cpp | |
DataFlowSanitizer.cpp | |
+ DumbSanitizer.cpp | |
GCOVProfiling.cpp | |
MemProfiler.cpp | |
MemorySanitizer.cpp | |
diff --git a/llvm/lib/Transforms/Instrumentation/DumbSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DumbSanitizer.cpp | |
new file mode 100644 | |
index 000000000000..ea6331948c4d | |
--- /dev/null | |
+++ b/llvm/lib/Transforms/Instrumentation/DumbSanitizer.cpp | |
@@ -0,0 +1,271 @@ | |
+//===- DumbSanitizer.cpp - dumb memory access profiler ------------===// | |
+// | |
+// 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 | |
+// | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// This file is a part of DumbSanitizer. Memory accesses are instrumented | |
+// to calls to run-time library which increment the access count held in a map. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#include "llvm/Transforms/Instrumentation/DumbSanitizer.h" | |
+#include "llvm/ADT/SmallVector.h" | |
+#include "llvm/ADT/Statistic.h" | |
+#include "llvm/ADT/StringRef.h" | |
+#include "llvm/IR/Constant.h" | |
+#include "llvm/IR/DataLayout.h" | |
+#include "llvm/IR/Function.h" | |
+#include "llvm/IR/GlobalValue.h" | |
+#include "llvm/IR/IRBuilder.h" | |
+#include "llvm/IR/Instruction.h" | |
+#include "llvm/IR/LLVMContext.h" | |
+#include "llvm/IR/Module.h" | |
+#include "llvm/IR/Type.h" | |
+#include "llvm/IR/Value.h" | |
+#include "llvm/InitializePasses.h" | |
+#include "llvm/Pass.h" | |
+#include "llvm/Support/CommandLine.h" | |
+#include "llvm/Support/Debug.h" | |
+#include "llvm/Transforms/Instrumentation.h" | |
+#include "llvm/Transforms/Utils/ModuleUtils.h" | |
+ | |
+using namespace llvm; | |
+ | |
+#define DEBUG_TYPE "dbsan" | |
+ | |
+const char kDbsanModuleCtorName[] = "dbsan.module_ctor"; | |
+const char kDbsanInitName[] = "__dbsan_init"; | |
+ | |
+// Command-line flags. | |
+ | |
+static cl::opt<bool> ClInstrumentReads("dbsan-instrument-reads", | |
+ cl::desc("instrument read instructions"), | |
+ cl::Hidden, cl::init(true)); | |
+ | |
+static cl::opt<bool> | |
+ ClInstrumentWrites("dbsan-instrument-writes", | |
+ cl::desc("instrument write instructions"), cl::Hidden, | |
+ cl::init(true)); | |
+ | |
+STATISTIC(NumInstrumentedReads, "Number of instrumented reads"); | |
+STATISTIC(NumInstrumentedWrites, "Number of instrumented writes"); | |
+ | |
+namespace { | |
+ | |
+struct InterestingMemoryAccess { | |
+ Value *Addr = nullptr; | |
+ bool IsWrite; | |
+ unsigned Alignment; | |
+ Type *AccessTy; | |
+ uint64_t TypeSize; | |
+}; | |
+ | |
+/// Instrument the code in module to profile memory accesses. | |
+class DumbSanitizer { | |
+public: | |
+ DumbSanitizer(Module &M) { C = &(M.getContext()); } | |
+ | |
+ bool sanitizeFunction(Function &F); | |
+ | |
+private: | |
+ void initializeCallbacks(Module &M); | |
+ int getMemoryAccessFuncIndex(uint32_t TypeSize); | |
+ /// If it is an interesting memory access, populate information | |
+ /// about the access and return a InterestingMemoryAccess struct. | |
+ /// Otherwise return None. | |
+ Optional<InterestingMemoryAccess> | |
+ isInterestingMemoryAccess(Instruction *I) const; | |
+ void instrumentMemoryAccess(Instruction *I, const DataLayout &DL, | |
+ InterestingMemoryAccess &Access); | |
+ | |
+ LLVMContext *C; | |
+ int LongSize; | |
+ Type *IntptrTy; | |
+ // Accesses sizes are powers of two: 1, 2, 4, 8, 16. | |
+ static const size_t kNumberOfAccessSizes = 5; | |
+ FunctionCallee DbsanRead[kNumberOfAccessSizes]; | |
+ FunctionCallee DbsanWrite[kNumberOfAccessSizes]; | |
+ Value *DynamicShadowOffset = nullptr; | |
+}; | |
+ | |
+struct DumbSanitizerLegacyPass : public FunctionPass { | |
+ DumbSanitizerLegacyPass() : FunctionPass(ID) { | |
+ initializeDumbSanitizerLegacyPassPass(*PassRegistry::getPassRegistry()); | |
+ } | |
+ StringRef getPassName() const override; | |
+ bool doInitialization(Module &M) override; | |
+ bool runOnFunction(Function &F) override; | |
+ static char ID; | |
+ | |
+private: | |
+ Optional<DumbSanitizer> DbSan; | |
+}; | |
+ | |
+void insertModuleCtor(Module &M) { | |
+ getOrCreateSanitizerCtorAndInitFunctions( | |
+ M, kDbsanModuleCtorName, kDbsanInitName, /*InitArgTypes=*/{}, | |
+ /*InitArgs=*/{}, | |
+ // This callback is invoked when the functions are created the first | |
+ // time. Hook them into the global ctors list in that case: | |
+ [&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); }); | |
+} | |
+ | |
+} // end anonymous namespace | |
+ | |
+PreservedAnalyses DumbSanitizerPass::run(Function &F, | |
+ FunctionAnalysisManager &FAM) { | |
+ DumbSanitizer DbSan(*F.getParent()); | |
+ if (DbSan.sanitizeFunction(F)) | |
+ return PreservedAnalyses::none(); | |
+ return PreservedAnalyses::all(); | |
+} | |
+ | |
+PreservedAnalyses ModuleDumbSanitizerPass::run(Module &M, | |
+ ModuleAnalysisManager &MAM) { | |
+ insertModuleCtor(M); | |
+ return PreservedAnalyses::none(); | |
+} | |
+ | |
+char DumbSanitizerLegacyPass::ID = 0; | |
+INITIALIZE_PASS_BEGIN(DumbSanitizerLegacyPass, "dbsan", | |
+ "DumbSanitizer: profile memory accesses.", false, false) | |
+INITIALIZE_PASS_END(DumbSanitizerLegacyPass, "dbsan", | |
+ "DumbSanitizer: profile memory accesses.", false, false) | |
+ | |
+StringRef DumbSanitizerLegacyPass::getPassName() const { | |
+ return "DumbSanitizerLegacyPass"; | |
+} | |
+ | |
+bool DumbSanitizerLegacyPass::doInitialization(Module &M) { | |
+ insertModuleCtor(M); | |
+ DbSan.emplace(M); | |
+ return true; | |
+} | |
+ | |
+bool DumbSanitizerLegacyPass::runOnFunction(Function &F) { | |
+ return DbSan->sanitizeFunction(F); | |
+} | |
+ | |
+FunctionPass *llvm::createDumbSanitizerLegacyPassPass() { | |
+ return new DumbSanitizerLegacyPass(); | |
+} | |
+ | |
+Optional<InterestingMemoryAccess> | |
+DumbSanitizer::isInterestingMemoryAccess(Instruction *I) const { | |
+ InterestingMemoryAccess Access; | |
+ | |
+ if (LoadInst *LI = dyn_cast<LoadInst>(I)) { | |
+ if (!ClInstrumentReads) | |
+ return None; | |
+ Access.IsWrite = false; | |
+ Access.AccessTy = LI->getType(); | |
+ Access.Alignment = LI->getAlignment(); | |
+ Access.Addr = LI->getPointerOperand(); | |
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) { | |
+ if (!ClInstrumentWrites) | |
+ return None; | |
+ Access.IsWrite = true; | |
+ Access.AccessTy = SI->getValueOperand()->getType(); | |
+ Access.Alignment = SI->getAlignment(); | |
+ Access.Addr = SI->getPointerOperand(); | |
+ } | |
+ | |
+ if (!Access.Addr) | |
+ return None; | |
+ | |
+ // Do not instrument acesses from different address spaces; we cannot deal | |
+ // with them. | |
+ Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType()); | |
+ if (PtrTy->getPointerAddressSpace() != 0) | |
+ return None; | |
+ | |
+ const DataLayout &DL = I->getModule()->getDataLayout(); | |
+ Access.TypeSize = DL.getTypeStoreSizeInBits(Access.AccessTy); | |
+ return Access; | |
+} | |
+ | |
+void DumbSanitizer::instrumentMemoryAccess(Instruction *I, const DataLayout &DL, | |
+ InterestingMemoryAccess &Access) { | |
+ if (Access.IsWrite) | |
+ NumInstrumentedWrites++; | |
+ else | |
+ NumInstrumentedReads++; | |
+ | |
+ IRBuilder<> IRB(I); | |
+ int Idx = getMemoryAccessFuncIndex(Access.TypeSize); | |
+ if (Idx < 0) | |
+ return; | |
+ FunctionCallee OnAccessFunc = | |
+ Access.IsWrite ? DbsanWrite[Idx] : DbsanRead[Idx]; | |
+ IRB.CreateCall(OnAccessFunc, | |
+ IRB.CreatePointerCast(Access.Addr, IRB.getInt8PtrTy())); | |
+} | |
+ | |
+int DumbSanitizer::getMemoryAccessFuncIndex(uint32_t TypeSize) { | |
+ if (TypeSize != 8 && TypeSize != 16 && TypeSize != 32 && TypeSize != 64 && | |
+ TypeSize != 128) { | |
+ // Ignore all unusual sizes. | |
+ return -1; | |
+ } | |
+ size_t Idx = countTrailingZeros(TypeSize / 8); | |
+ assert(Idx < kNumberOfAccessSizes); | |
+ return Idx; | |
+} | |
+ | |
+void DumbSanitizer::initializeCallbacks(Module &M) { | |
+ IRBuilder<> IRB(*C); | |
+ AttributeList Attr; | |
+ Attr = Attr.addFnAttribute(M.getContext(), Attribute::NoUnwind); | |
+ | |
+ for (size_t i = 0; i < kNumberOfAccessSizes; ++i) { | |
+ const unsigned ByteSize = 1U << i; | |
+ std::string ByteSizeStr = utostr(ByteSize); | |
+ SmallString<32> ReadName("__dbsan_read" + ByteSizeStr); | |
+ DbsanRead[i] = M.getOrInsertFunction(ReadName, Attr, IRB.getVoidTy(), | |
+ IRB.getInt8PtrTy()); | |
+ | |
+ SmallString<32> WriteName("__dbsan_write" + ByteSizeStr); | |
+ DbsanWrite[i] = M.getOrInsertFunction(WriteName, Attr, IRB.getVoidTy(), | |
+ IRB.getInt8PtrTy()); | |
+ } | |
+} | |
+ | |
+bool DumbSanitizer::sanitizeFunction(Function &F) { | |
+ if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) | |
+ return false; | |
+ if (F.getName().startswith("__dbsan_")) | |
+ return false; | |
+ if (F.getName() == kDbsanModuleCtorName) | |
+ return false; | |
+ | |
+ bool FunctionModified = false; | |
+ LLVM_DEBUG(dbgs() << "dbsan instrumenting:\n" << F << "\n"); | |
+ | |
+ initializeCallbacks(*F.getParent()); | |
+ | |
+ SmallVector<Instruction *, 16> LoadsAndStores; | |
+ for (auto &BB : F) { | |
+ for (auto &Inst : BB) { | |
+ if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) | |
+ LoadsAndStores.push_back(&Inst); | |
+ } | |
+ } | |
+ | |
+ int NumInstrumented = 0; | |
+ for (auto *Inst : LoadsAndStores) { | |
+ Optional<InterestingMemoryAccess> Access = isInterestingMemoryAccess(Inst); | |
+ if (Access) { | |
+ instrumentMemoryAccess(Inst, F.getParent()->getDataLayout(), *Access); | |
+ NumInstrumented++; | |
+ } | |
+ } | |
+ | |
+ if (NumInstrumented > 0) | |
+ FunctionModified = true; | |
+ LLVM_DEBUG(dbgs() << "dbsan done instrumenting: " << FunctionModified << " " | |
+ << F << "\n"); | |
+ return FunctionModified; | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment