summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Features.def2
-rw-r--r--clang/include/clang/Basic/Sanitizers.def7
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h3
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp20
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp19
-rw-r--r--clang/lib/Driver/ToolChains/CommonArgs.cpp2
-rw-r--r--clang/lib/Driver/ToolChains/Darwin.cpp2
-rw-r--r--clang/lib/Driver/ToolChains/Linux.cpp2
-rw-r--r--clang/lib/Driver/ToolChains/NetBSD.cpp1
-rw-r--r--clang/test/Driver/esan.c16
-rw-r--r--clang/test/Driver/fsanitize.c56
-rw-r--r--clang/test/Driver/sanitize_unwind_tables.c2
-rw-r--r--clang/test/Driver/sanitizer-ld.c10
-rw-r--r--clang/test/Lexer/has_feature_efficiency_sanitizer.cpp12
-rw-r--r--compiler-rt/cmake/config-ix.cmake14
-rw-r--r--compiler-rt/include/CMakeLists.txt1
-rw-r--r--compiler-rt/include/sanitizer/esan_interface.h49
-rw-r--r--compiler-rt/lib/esan/CMakeLists.txt55
-rw-r--r--compiler-rt/lib/esan/cache_frag.cpp207
-rw-r--r--compiler-rt/lib/esan/cache_frag.h28
-rw-r--r--compiler-rt/lib/esan/esan.cpp277
-rw-r--r--compiler-rt/lib/esan/esan.h60
-rw-r--r--compiler-rt/lib/esan/esan.syms.extra4
-rw-r--r--compiler-rt/lib/esan/esan_circular_buffer.h95
-rw-r--r--compiler-rt/lib/esan/esan_flags.cpp59
-rw-r--r--compiler-rt/lib/esan/esan_flags.h40
-rw-r--r--compiler-rt/lib/esan/esan_flags.inc55
-rw-r--r--compiler-rt/lib/esan/esan_hashtable.h380
-rw-r--r--compiler-rt/lib/esan/esan_interceptors.cpp512
-rw-r--r--compiler-rt/lib/esan/esan_interface.cpp121
-rw-r--r--compiler-rt/lib/esan/esan_interface_internal.h82
-rw-r--r--compiler-rt/lib/esan/esan_linux.cpp82
-rw-r--r--compiler-rt/lib/esan/esan_shadow.h291
-rw-r--r--compiler-rt/lib/esan/esan_sideline.h63
-rw-r--r--compiler-rt/lib/esan/esan_sideline_bsd.cpp34
-rw-r--r--compiler-rt/lib/esan/esan_sideline_linux.cpp177
-rw-r--r--compiler-rt/lib/esan/working_set.cpp279
-rw-r--r--compiler-rt/lib/esan/working_set.h39
-rw-r--r--compiler-rt/lib/esan/working_set_posix.cpp133
-rw-r--r--compiler-rt/lib/sanitizer_common/CMakeLists.txt20
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.h1
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h1
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux.cc24
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux.h4
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux_mips64.S24
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux_x86_64.S26
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc4
-rw-r--r--compiler-rt/test/esan/CMakeLists.txt32
-rw-r--r--compiler-rt/test/esan/TestCases/large-stack-linux.c76
-rw-r--r--compiler-rt/test/esan/TestCases/libc-intercept.c20
-rw-r--r--compiler-rt/test/esan/TestCases/mmap-shadow-conflict.c44
-rw-r--r--compiler-rt/test/esan/TestCases/struct-simple.cpp204
-rw-r--r--compiler-rt/test/esan/TestCases/verbose-simple.c18
-rw-r--r--compiler-rt/test/esan/TestCases/workingset-early-fault.c35
-rw-r--r--compiler-rt/test/esan/TestCases/workingset-memset.cpp22
-rw-r--r--compiler-rt/test/esan/TestCases/workingset-midreport.cpp76
-rw-r--r--compiler-rt/test/esan/TestCases/workingset-samples.cpp48
-rw-r--r--compiler-rt/test/esan/TestCases/workingset-signal-posix.cpp77
-rw-r--r--compiler-rt/test/esan/TestCases/workingset-simple.cpp35
-rw-r--r--compiler-rt/test/esan/Unit/circular_buffer.cpp61
-rw-r--r--compiler-rt/test/esan/Unit/hashtable.cpp179
-rw-r--r--compiler-rt/test/esan/lit.cfg43
-rw-r--r--compiler-rt/test/esan/lit.site.cfg.in14
-rw-r--r--llvm/include/llvm/InitializePasses.h1
-rw-r--r--llvm/include/llvm/Transforms/Instrumentation.h15
-rw-r--r--llvm/lib/Transforms/Instrumentation/CMakeLists.txt1
-rw-r--r--llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp892
-rw-r--r--llvm/lib/Transforms/Instrumentation/Instrumentation.cpp1
-rw-r--r--llvm/test/Instrumentation/EfficiencySanitizer/str-nobuiltin.ll33
-rw-r--r--llvm/test/Instrumentation/EfficiencySanitizer/struct_field_count_basic.ll157
-rw-r--r--llvm/test/Instrumentation/EfficiencySanitizer/struct_field_gep.ll41
-rw-r--r--llvm/test/Instrumentation/EfficiencySanitizer/struct_field_small.ll133
-rw-r--r--llvm/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll275
-rw-r--r--llvm/test/Instrumentation/EfficiencySanitizer/working_set_slow.ll291
-rw-r--r--llvm/test/Instrumentation/EfficiencySanitizer/working_set_strict.ll156
-rw-r--r--llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn1
-rw-r--r--llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn3
-rw-r--r--llvm/utils/gn/secondary/llvm/lib/Transforms/Instrumentation/BUILD.gn1
78 files changed, 5 insertions, 6375 deletions
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 8fc4e5a6b9a..44ef9e7d94d 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -86,8 +86,6 @@ FEATURE(memory_sanitizer,
SanitizerKind::KernelMemory))
FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
-FEATURE(efficiency_sanitizer,
- LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency))
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
// Objective-C features
FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index 98e9aaa5b8b..3e153488b46 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -165,13 +165,6 @@ SANITIZER_GROUP("integer", Integer,
SANITIZER("local-bounds", LocalBounds)
SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
-// EfficiencySanitizer
-SANITIZER("efficiency-cache-frag", EfficiencyCacheFrag)
-SANITIZER("efficiency-working-set", EfficiencyWorkingSet)
-// Meta-group only used internally.
-SANITIZER_GROUP("efficiency-all", Efficiency,
- EfficiencyCacheFrag | EfficiencyWorkingSet)
-
// Scudo hardened allocator
SANITIZER("scudo", Scudo)
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 18e8e4fedca..b12e7ab9bf2 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -73,9 +73,6 @@ class SanitizerArgs {
bool needsCfiRt() const;
bool needsCfiDiagRt() const;
bool needsStatsRt() const { return Stats; }
- bool needsEsanRt() const {
- return Sanitizers.hasOneOf(SanitizerKind::Efficiency);
- }
bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
bool requiresPIE() const;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 9b0432d44ac..30a3dc830f6 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -319,19 +319,6 @@ static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles));
}
-static void addEfficiencySanitizerPass(const PassManagerBuilder &Builder,
- legacy::PassManagerBase &PM) {
- const PassManagerBuilderWrapper &BuilderWrapper =
- static_cast<const PassManagerBuilderWrapper&>(Builder);
- const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
- EfficiencySanitizerOptions Opts;
- if (LangOpts.Sanitize.has(SanitizerKind::EfficiencyCacheFrag))
- Opts.ToolType = EfficiencySanitizerOptions::ESAN_CacheFrag;
- else if (LangOpts.Sanitize.has(SanitizerKind::EfficiencyWorkingSet))
- Opts.ToolType = EfficiencySanitizerOptions::ESAN_WorkingSet;
- PM.add(createEfficiencySanitizerPass(Opts));
-}
-
static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
const CodeGenOptions &CodeGenOpts) {
TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple);
@@ -656,13 +643,6 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
addDataFlowSanitizerPass);
}
- if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency)) {
- PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
- addEfficiencySanitizerPass);
- PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
- addEfficiencySanitizerPass);
- }
-
// Set up the per-function pass manager.
FPM.add(new TargetLibraryInfoWrapperPass(*TLII));
if (CodeGenOpts.VerifyModule)
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index e84933bea02..6e2528a6a0b 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -401,31 +401,24 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
std::make_pair(SanitizerKind::HWAddress,
SanitizerKind::Address | SanitizerKind::Thread |
SanitizerKind::Memory | SanitizerKind::KernelAddress),
- std::make_pair(SanitizerKind::Efficiency,
- SanitizerKind::Address | SanitizerKind::HWAddress |
- SanitizerKind::Leak | SanitizerKind::Thread |
- SanitizerKind::Memory | SanitizerKind::KernelAddress),
std::make_pair(SanitizerKind::Scudo,
SanitizerKind::Address | SanitizerKind::HWAddress |
SanitizerKind::Leak | SanitizerKind::Thread |
- SanitizerKind::Memory | SanitizerKind::KernelAddress |
- SanitizerKind::Efficiency),
+ SanitizerKind::Memory | SanitizerKind::KernelAddress),
std::make_pair(SanitizerKind::SafeStack,
SanitizerKind::Address | SanitizerKind::HWAddress |
SanitizerKind::Leak | SanitizerKind::Thread |
- SanitizerKind::Memory | SanitizerKind::KernelAddress |
- SanitizerKind::Efficiency),
+ SanitizerKind::Memory | SanitizerKind::KernelAddress),
std::make_pair(SanitizerKind::KernelHWAddress,
SanitizerKind::Address | SanitizerKind::HWAddress |
SanitizerKind::Leak | SanitizerKind::Thread |
SanitizerKind::Memory | SanitizerKind::KernelAddress |
- SanitizerKind::Efficiency | SanitizerKind::SafeStack),
+ SanitizerKind::SafeStack),
std::make_pair(SanitizerKind::KernelMemory,
SanitizerKind::Address | SanitizerKind::HWAddress |
SanitizerKind::Leak | SanitizerKind::Thread |
SanitizerKind::Memory | SanitizerKind::KernelAddress |
- SanitizerKind::Efficiency | SanitizerKind::Scudo |
- SanitizerKind::SafeStack)};
+ SanitizerKind::Scudo | SanitizerKind::SafeStack)};
// Enable toolchain specific default sanitizers if not explicitly disabled.
SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
@@ -1011,10 +1004,6 @@ SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
0 == strcmp("all", Value))
Kind = SanitizerMask();
- // Similarly, don't accept -fsanitize=efficiency-all.
- else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
- 0 == strcmp("efficiency-all", Value))
- Kind = SanitizerMask();
else
Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index a3d7a603c9f..a90ac9fcc83 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -713,8 +713,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
NonWholeStaticRuntimes.push_back("stats");
RequiredSymbols.push_back("__sanitizer_stats_register");
}
- if (SanArgs.needsEsanRt())
- StaticRuntimes.push_back("esan");
if (SanArgs.needsScudoRt()) {
if (SanArgs.requiresMinimalRuntime()) {
StaticRuntimes.push_back("scudo_minimal");
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 8cd9263f651..ea93fadcdc2 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1115,8 +1115,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);
AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
}
- if (Sanitize.needsEsanRt())
- AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
const XRayArgs &XRay = getXRayArgs();
if (XRay.needsXRayRt()) {
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 64631781117..3c6096468d8 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -1006,8 +1006,6 @@ SanitizerMask Linux::getSupportedSanitizers() const {
Res |= SanitizerKind::Thread;
if (IsX86_64)
Res |= SanitizerKind::KernelMemory;
- if (IsX86_64 || IsMIPS64)
- Res |= SanitizerKind::Efficiency;
if (IsX86 || IsX86_64)
Res |= SanitizerKind::Function;
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch ||
diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp
index 53587e27853..287596071ea 100644
--- a/clang/lib/Driver/ToolChains/NetBSD.cpp
+++ b/clang/lib/Driver/ToolChains/NetBSD.cpp
@@ -471,7 +471,6 @@ SanitizerMask NetBSD::getSupportedSanitizers() const {
}
if (IsX86_64) {
Res |= SanitizerKind::DataFlow;
- Res |= SanitizerKind::Efficiency;
Res |= SanitizerKind::Fuzzer;
Res |= SanitizerKind::FuzzerNoLink;
Res |= SanitizerKind::HWAddress;
diff --git a/clang/test/Driver/esan.c b/clang/test/Driver/esan.c
deleted file mode 100644
index f734bef1245..00000000000
--- a/clang/test/Driver/esan.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %clang -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O3 -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O3 -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64el-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64el-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// Verify that -fsanitize=efficiency-* invokes esan instrumentation.
-
-int foo(int *a) { return *a; }
-// CHECK: __esan_init
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index db888723992..ebfd76281c9 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -181,30 +181,6 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANA
// CHECK-SANHA-SANA: '-fsanitize=hwaddress' not allowed with '-fsanitize=address'
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANA
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANA
-// CHECK-SANE-SANA: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=address'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,leak -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANL
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,leak -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANL
-// CHECK-SANE-SANL: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=leak'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,thread -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANT
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,thread -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANT
-// CHECK-SANE-SANT: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=thread'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANM
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANM
-// CHECK-SANE-SANM: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=memory'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,kernel-memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKM
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,kernel-memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKM
-// CHECK-SANE-SANKM: '-fsanitize=kernel-memory' not allowed with '-fsanitize=efficiency-{{.*}}'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,kernel-address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKA
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,kernel-address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKA
-// CHECK-SANE-SANKA: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=kernel-address'
-
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-use-after-scope %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE
// RUN: %clang_cl --target=x86_64-windows -fsanitize=address -fsanitize-address-use-after-scope -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE
// CHECK-USE-AFTER-SCOPE: -cc1{{.*}}-fsanitize-address-use-after-scope
@@ -546,10 +522,6 @@
// RUN: %clang -target i386-pc-openbsd -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-OPENBSD
// CHECK-MSAN-OPENBSD: unsupported option '-fsanitize=memory' for target 'i386-pc-openbsd'
-// RUN: %clang -target i386-pc-openbsd -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-OPENBSD
-// RUN: %clang -target i386-pc-openbsd -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-OPENBSD
-// CHECK-ESAN-OPENBSD: error: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-pc-openbsd'
-
// RUN: %clang -target x86_64-apple-darwin -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-DARWIN
// CHECK-LSAN-X86-64-DARWIN-NOT: unsupported option
@@ -571,31 +543,6 @@
// RUN: %clang -target i386-apple-tvossimulator -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-TVOSSIMULATOR
// CHECK-LSAN-I386-TVOSSIMULATOR-NOT: unsupported option
-// RUN: %clang -target i686-linux-gnu -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-X86
-// RUN: %clang -target i686-linux-gnu -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-X86
-// CHECK-ESAN-X86: error: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i686-unknown-linux-gnu'
-
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-DARWIN
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-DARWIN
-// CHECK-ESAN-DARWIN: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'x86_64-apple-darwin10'
-
-// RUN: %clang -target i386-apple-darwin -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-DARWIN
-// RUN: %clang -target i386-apple-darwin -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-DARWIN
-// CHECK-ESAN-I386-DARWIN: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-darwin'
-
-// RUN: %clang -target arm-apple-ios -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-ARM-IOS
-// RUN: %clang -target arm-apple-ios -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-ARM-IOS
-// CHECK-ESAN-ARM-IOS: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'arm-apple-ios'
-
-// RUN: %clang -target i386-apple-iossimulator -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-IOSSIMULATOR
-// RUN: %clang -target i386-apple-iossimulator -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-IOSSIMULATOR
-// CHECK-ESAN-I386-IOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-iossimulator-simulator'
-
-// RUN: %clang -target i386-apple-tvossimulator -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-TVOSSIMULATOR
-// RUN: %clang -target i386-apple-tvossimulator -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-TVOSSIMULATOR
-// CHECK-ESAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-tvossimulator-simulator'
-
-
// RUN: %clang -target x86_64-linux-gnu -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
// RUN: %clang -target x86_64-apple-darwin10 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
@@ -783,9 +730,6 @@
// CHECK-MSAN-PS4: unsupported option '-fsanitize=memory' for target 'x86_64-scei-ps4'
// RUN: %clang -target x86_64-scei-ps4 -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-PS4
// CHECK-TSAN-PS4: unsupported option '-fsanitize=thread' for target 'x86_64-scei-ps4'
-// RUN: %clang -target x86_64-scei-ps4 -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-PS4
-// RUN: %clang -target x86_64-scei-ps4 -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-PS4
-// CHECK-ESAN-PS4: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'x86_64-scei-ps4'
// RUN: %clang -target x86_64-scei-ps4 -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-PS4
// Make sure there are no *.{o,bc} or -l passed before the ASan library.
// CHECK-ASAN-PS4-NOT: {{(\.(o|bc)"? |-l).*-lSceDbgAddressSanitizer_stub_weak}}
diff --git a/clang/test/Driver/sanitize_unwind_tables.c b/clang/test/Driver/sanitize_unwind_tables.c
index e74c15833f9..d361fbd8b41 100644
--- a/clang/test/Driver/sanitize_unwind_tables.c
+++ b/clang/test/Driver/sanitize_unwind_tables.c
@@ -7,8 +7,6 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-linux-gnu -fsanitize=dataflow %s -### 2>&1 | FileCheck %s
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s
// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s
// RUN: %clang -target aarch64-linux-android -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index db699410f7e..c2783b4dad2 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -680,16 +680,6 @@
// RUN: | FileCheck --check-prefix=CHECK-NOLIB-PS4 %s
// CHECK-NOLIB-PS4-NOT: SceDbgAddressSanitizer_stub_weak
-// RUN: %clang -fsanitize=efficiency-cache-frag %s -### -o %t.o 2>&1 \
-// RUN: -target x86_64-unknown-linux -fuse-ld=ld \
-// RUN: | FileCheck --check-prefix=CHECK-ESAN-LINUX %s
-// RUN: %clang -fsanitize=efficiency-working-set %s -### -o %t.o 2>&1 \
-// RUN: -target x86_64-unknown-linux -fuse-ld=ld \
-// RUN: | FileCheck --check-prefix=CHECK-ESAN-LINUX %s
-//
-// CHECK-ESAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-ESAN-LINUX: libclang_rt.esan-x86_64.a
-
// RUN: %clang -fsanitize=scudo %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
diff --git a/clang/test/Lexer/has_feature_efficiency_sanitizer.cpp b/clang/test/Lexer/has_feature_efficiency_sanitizer.cpp
deleted file mode 100644
index ef9e2736025..00000000000
--- a/clang/test/Lexer/has_feature_efficiency_sanitizer.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_cc1 -E -fsanitize=efficiency-cache-frag %s -o - | FileCheck --check-prefix=CHECK-ESAN %s
-// RUN: %clang_cc1 -E -fsanitize=efficiency-working-set %s -o - | FileCheck --check-prefix=CHECK-ESAN %s
-// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-ESAN %s
-
-#if __has_feature(efficiency_sanitizer)
-int EfficiencySanitizerEnabled();
-#else
-int EfficiencySanitizerDisabled();
-#endif
-
-// CHECK-ESAN: EfficiencySanitizerEnabled
-// CHECK-NO-ESAN: EfficiencySanitizerDisabled
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index a667dce690b..b072c1180e3 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -246,7 +246,6 @@ set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
${MIPS32} ${MIPS64} ${PPC64} ${S390X})
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64})
set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64})
-set(ALL_ESAN_SUPPORTED_ARCH ${X86_64} ${MIPS64})
set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64})
set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64})
if(APPLE)
@@ -456,9 +455,6 @@ if(APPLE)
list_intersect(CFI_SUPPORTED_ARCH
ALL_CFI_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH)
- list_intersect(ESAN_SUPPORTED_ARCH
- ALL_ESAN_SUPPORTED_ARCH
- SANITIZER_COMMON_SUPPORTED_ARCH)
list_intersect(SCUDO_SUPPORTED_ARCH
ALL_SCUDO_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH)
@@ -497,7 +493,6 @@ else()
filter_available_targets(SAFESTACK_SUPPORTED_ARCH
${ALL_SAFESTACK_SUPPORTED_ARCH})
filter_available_targets(CFI_SUPPORTED_ARCH ${ALL_CFI_SUPPORTED_ARCH})
- filter_available_targets(ESAN_SUPPORTED_ARCH ${ALL_ESAN_SUPPORTED_ARCH})
filter_available_targets(SCUDO_SUPPORTED_ARCH ${ALL_SCUDO_SUPPORTED_ARCH})
filter_available_targets(SCUDO_STANDALONE_SUPPORTED_ARCH ${ALL_SCUDO_STANDALONE_SUPPORTED_ARCH})
filter_available_targets(XRAY_SUPPORTED_ARCH ${ALL_XRAY_SUPPORTED_ARCH})
@@ -530,7 +525,7 @@ else()
set(OS_NAME "${CMAKE_SYSTEM_NAME}")
endif()
-set(ALL_SANITIZERS asan;dfsan;msan;hwasan;tsan;safestack;cfi;esan;scudo;ubsan_minimal)
+set(ALL_SANITIZERS asan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo;ubsan_minimal)
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}")
@@ -634,13 +629,6 @@ else()
set(COMPILER_RT_HAS_CFI FALSE)
endif()
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND ESAN_SUPPORTED_ARCH AND
- OS_NAME MATCHES "Linux|FreeBSD")
- set(COMPILER_RT_HAS_ESAN TRUE)
-else()
- set(COMPILER_RT_HAS_ESAN FALSE)
-endif()
-
#TODO(kostyak): add back Android & Fuchsia when the code settles a bit.
if (SCUDO_STANDALONE_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux")
set(COMPILER_RT_HAS_SCUDO_STANDALONE TRUE)
diff --git a/compiler-rt/include/CMakeLists.txt b/compiler-rt/include/CMakeLists.txt
index 3212ea8bcd9..38bd6e41a91 100644
--- a/compiler-rt/include/CMakeLists.txt
+++ b/compiler-rt/include/CMakeLists.txt
@@ -5,7 +5,6 @@ if (COMPILER_RT_BUILD_SANITIZERS)
sanitizer/common_interface_defs.h
sanitizer/coverage_interface.h
sanitizer/dfsan_interface.h
- sanitizer/esan_interface.h
sanitizer/hwasan_interface.h
sanitizer/linux_syscall_hooks.h
sanitizer/lsan_interface.h
diff --git a/compiler-rt/include/sanitizer/esan_interface.h b/compiler-rt/include/sanitizer/esan_interface.h
deleted file mode 100644
index 80cdecbcc2b..00000000000
--- a/compiler-rt/include/sanitizer/esan_interface.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- sanitizer/esan_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 EfficiencySanitizer, a family of performance tuners.
-//
-// Public interface header.
-//===----------------------------------------------------------------------===//
-#ifndef SANITIZER_ESAN_INTERFACE_H
-#define SANITIZER_ESAN_INTERFACE_H
-
-#include <sanitizer/common_interface_defs.h>
-
-// We declare our interface routines as weak to allow the user to avoid
-// ifdefs and instead use this pattern to allow building the same sources
-// with and without our runtime library:
-// if (__esan_report)
-// __esan_report();
-#ifdef _MSC_VER
-/* selectany is as close to weak as we'll get. */
-#define COMPILER_RT_WEAK __declspec(selectany)
-#elif __GNUC__
-#define COMPILER_RT_WEAK __attribute__((weak))
-#else
-#define COMPILER_RT_WEAK
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// This function can be called mid-run (or at the end of a run for
-// a server process that doesn't shut down normally) to request that
-// data for that point in the run be reported from the tool.
-void COMPILER_RT_WEAK __esan_report(void);
-
-// This function returns the number of samples that the esan tool has collected
-// to this point. This is useful for testing.
-unsigned int COMPILER_RT_WEAK __esan_get_sample_count(void);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // SANITIZER_ESAN_INTERFACE_H
diff --git a/compiler-rt/lib/esan/CMakeLists.txt b/compiler-rt/lib/esan/CMakeLists.txt
deleted file mode 100644
index c880971e3dd..00000000000
--- a/compiler-rt/lib/esan/CMakeLists.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-# Build for the EfficiencySanitizer runtime support library.
-
-add_compiler_rt_component(esan)
-
-set(ESAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF ESAN_RTL_CFLAGS)
-
-include_directories(..)
-
-set(ESAN_SOURCES
- esan.cpp
- esan_flags.cpp
- esan_interface.cpp
- esan_interceptors.cpp
- esan_linux.cpp
- esan_sideline_linux.cpp
- esan_sideline_bsd.cpp
- cache_frag.cpp
- working_set.cpp
- working_set_posix.cpp)
-
-set(ESAN_HEADERS
- cache_frag.h
- esan.h
- esan_circular_buffer.h
- esan_flags.h
- esan_flags.inc
- esan_hashtable.h
- esan_interface_internal.h
- esan_shadow.h
- esan_sideline.h
- working_set.h)
-
-foreach (arch ${ESAN_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.esan
- STATIC
- ARCHS ${arch}
- SOURCES ${ESAN_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- ADDITIONAL_HEADERS ${ESAN_HEADERS}
- CFLAGS ${ESAN_RTL_CFLAGS})
- add_sanitizer_rt_symbols(clang_rt.esan
- ARCHS ${arch}
- EXTRA esan.syms.extra)
- add_dependencies(esan
- clang_rt.esan-${arch}
- clang_rt.esan-${arch}-symbols)
-endforeach()
-
-if (COMPILER_RT_INCLUDE_TESTS)
- # TODO(bruening): add tests via add_subdirectory(tests)
-endif()
diff --git a/compiler-rt/lib/esan/cache_frag.cpp b/compiler-rt/lib/esan/cache_frag.cpp
deleted file mode 100644
index 60e1c3b4c24..00000000000
--- a/compiler-rt/lib/esan/cache_frag.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-//===-- cache_frag.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 EfficiencySanitizer, a family of performance tuners.
-//
-// This file contains cache fragmentation-specific code.
-//===----------------------------------------------------------------------===//
-
-#include "esan.h"
-#include "esan_flags.h"
-#include "sanitizer_common/sanitizer_addrhashmap.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_placement_new.h"
-#include <string.h>
-
-namespace __esan {
-
-//===-- Struct field access counter runtime -------------------------------===//
-
-// This should be kept consistent with LLVM's EfficiencySanitizer StructInfo.
-struct StructInfo {
- const char *StructName;
- u32 Size;
- u32 NumFields;
- u32 *FieldOffset; // auxiliary struct field info.
- u32 *FieldSize; // auxiliary struct field info.
- const char **FieldTypeName; // auxiliary struct field info.
- u64 *FieldCounters;
- u64 *ArrayCounter;
- bool hasAuxFieldInfo() { return FieldOffset != nullptr; }
-};
-
-// This should be kept consistent with LLVM's EfficiencySanitizer CacheFragInfo.
-// The tool-specific information per compilation unit (module).
-struct CacheFragInfo {
- const char *UnitName;
- u32 NumStructs;
- StructInfo *Structs;
-};
-
-struct StructCounter {
- StructInfo *Struct;
- u64 Count; // The total access count of the struct.
- u64 Ratio; // Difference ratio for the struct layout access.
-};
-
-// We use StructHashMap to keep track of an unique copy of StructCounter.
-typedef AddrHashMap<StructCounter, 31051> StructHashMap;
-struct Context {
- StructHashMap StructMap;
- u32 NumStructs;
- u64 TotalCount; // The total access count of all structs.
-};
-static Context *Ctx;
-
-static void reportStructSummary() {
- // FIXME: provide a better struct field access summary report.
- Report("%s: total struct field access count = %llu\n", SanitizerToolName,
- Ctx->TotalCount);
-}
-
-// FIXME: we are still exploring proper ways to evaluate the difference between
-// struct field counts. Currently, we use a simple formula to calculate the
-// difference ratio: V1/V2.
-static inline u64 computeDifferenceRatio(u64 Val1, u64 Val2) {
- if (Val2 > Val1) {
- Swap(Val1, Val2);
- }
- if (Val2 == 0)
- Val2 = 1;
- return (Val1 / Val2);
-}
-
-static void reportStructCounter(StructHashMap::Handle &Handle) {
- const u32 TypePrintLimit = 512;
- const char *type, *start, *end;
- StructInfo *Struct = Handle->Struct;
- // Union field address calculation is done via bitcast instead of GEP,
- // so the count for union is always 0.
- // We skip the union report to avoid confusion.
- if (strncmp(Struct->StructName, "union.", 6) == 0)
- return;
- // Remove the '.' after class/struct during print.
- if (strncmp(Struct->StructName, "class.", 6) == 0) {
- type = "class";
- start = &Struct->StructName[6];
- } else {
- type = "struct";
- start = &Struct->StructName[7];
- }
- // Remove the suffixes with '$' during print.
- end = strchr(start, '$');
- CHECK(end != nullptr);
- Report(" %s %.*s\n", type, end - start, start);
- Report(" size = %u, count = %llu, ratio = %llu, array access = %llu\n",
- Struct->Size, Handle->Count, Handle->Ratio, *Struct->ArrayCounter);
- if (Struct->hasAuxFieldInfo()) {
- for (u32 i = 0; i < Struct->NumFields; ++i) {
- Report(" #%2u: offset = %u,\t size = %u,"
- "\t count = %llu,\t type = %.*s\n",
- i, Struct->FieldOffset[i], Struct->FieldSize[i],
- Struct->FieldCounters[i], TypePrintLimit, Struct->FieldTypeName[i]);
- }
- } else {
- for (u32 i = 0; i < Struct->NumFields; ++i) {
- Report(" #%2u: count = %llu\n", i, Struct->FieldCounters[i]);
- }
- }
-}
-
-static void computeStructRatio(StructHashMap::Handle &Handle) {
- Handle->Ratio = 0;
- Handle->Count = Handle->Struct->FieldCounters[0];
- for (u32 i = 1; i < Handle->Struct->NumFields; ++i) {
- Handle->Count += Handle->Struct->FieldCounters[i];
- Handle->Ratio += computeDifferenceRatio(
- Handle->Struct->FieldCounters[i - 1], Handle->Struct->FieldCounters[i]);
- }
- Ctx->TotalCount += Handle->Count;
- if (Handle->Ratio >= (u64)getFlags()->report_threshold ||
- (Verbosity() >= 1 && Handle->Count > 0))
- reportStructCounter(Handle);
-}
-
-static void registerStructInfo(CacheFragInfo *CacheFrag) {
- for (u32 i = 0; i < CacheFrag->NumStructs; ++i) {
- StructInfo *Struct = &CacheFrag->Structs[i];
- StructHashMap::Handle H(&Ctx->StructMap, (uptr)Struct->FieldCounters);
- if (H.created()) {
- VPrintf(2, " Register %s: %u fields\n", Struct->StructName,
- Struct->NumFields);
- H->Struct = Struct;
- ++Ctx->NumStructs;
- } else {
- VPrintf(2, " Duplicated %s: %u fields\n", Struct->StructName,
- Struct->NumFields);
- }
- }
-}
-
-static void unregisterStructInfo(CacheFragInfo *CacheFrag) {
- // FIXME: if the library is unloaded before finalizeCacheFrag, we should
- // collect the result for later report.
- for (u32 i = 0; i < CacheFrag->NumStructs; ++i) {
- StructInfo *Struct = &CacheFrag->Structs[i];
- StructHashMap::Handle H(&Ctx->StructMap, (uptr)Struct->FieldCounters, true);
- if (H.exists()) {
- VPrintf(2, " Unregister %s: %u fields\n", Struct->StructName,
- Struct->NumFields);
- // FIXME: we should move this call to finalizeCacheFrag once we can
- // iterate over the hash map there.
- computeStructRatio(H);
- --Ctx->NumStructs;
- } else {
- VPrintf(2, " Duplicated %s: %u fields\n", Struct->StructName,
- Struct->NumFields);
- }
- }
- static bool Reported = false;
- if (Ctx->NumStructs == 0 && !Reported) {
- Reported = true;
- reportStructSummary();
- }
-}
-
-//===-- Init/exit functions -----------------------------------------------===//
-
-void processCacheFragCompilationUnitInit(void *Ptr) {
- CacheFragInfo *CacheFrag = (CacheFragInfo *)Ptr;
- VPrintf(2, "in esan::%s: %s with %u class(es)/struct(s)\n", __FUNCTION__,
- CacheFrag->UnitName, CacheFrag->NumStructs);
- registerStructInfo(CacheFrag);
-}
-
-void processCacheFragCompilationUnitExit(void *Ptr) {
- CacheFragInfo *CacheFrag = (CacheFragInfo *)Ptr;
- VPrintf(2, "in esan::%s: %s with %u class(es)/struct(s)\n", __FUNCTION__,
- CacheFrag->UnitName, CacheFrag->NumStructs);
- unregisterStructInfo(CacheFrag);
-}
-
-void initializeCacheFrag() {
- VPrintf(2, "in esan::%s\n", __FUNCTION__);
- // We use placement new to initialize Ctx before C++ static initializaion.
- // We make CtxMem 8-byte aligned for atomic operations in AddrHashMap.
- static u64 CtxMem[sizeof(Context) / sizeof(u64) + 1];
- Ctx = new (CtxMem) Context();
- Ctx->NumStructs = 0;
-}
-
-int finalizeCacheFrag() {
- VPrintf(2, "in esan::%s\n", __FUNCTION__);
- return 0;
-}
-
-void reportCacheFrag() {
- VPrintf(2, "in esan::%s\n", __FUNCTION__);
- // FIXME: Not yet implemented. We need to iterate over all of the
- // compilation unit data.
-}
-
-} // namespace __esan
diff --git a/compiler-rt/lib/esan/cache_frag.h b/compiler-rt/lib/esan/cache_frag.h
deleted file mode 100644
index bd96d2983c7..00000000000
--- a/compiler-rt/lib/esan/cache_frag.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===-- cache_frag.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Header for cache-fragmentation-specific code.
-//===----------------------------------------------------------------------===//
-
-#ifndef CACHE_FRAG_H
-#define CACHE_FRAG_H
-
-namespace __esan {
-
-void processCacheFragCompilationUnitInit(void *Ptr);
-void processCacheFragCompilationUnitExit(void *Ptr);
-
-void initializeCacheFrag();
-int finalizeCacheFrag();
-void reportCacheFrag();
-
-} // namespace __esan
-
-#endif // CACHE_FRAG_H
diff --git a/compiler-rt/lib/esan/esan.cpp b/compiler-rt/lib/esan/esan.cpp
deleted file mode 100644
index 2fbe72ac277..00000000000
--- a/compiler-rt/lib/esan/esan.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-//===-- esan.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Main file (entry points) for the Esan run-time.
-//===----------------------------------------------------------------------===//
-
-#include "esan.h"
-#include "esan_flags.h"
-#include "esan_interface_internal.h"
-#include "esan_shadow.h"
-#include "cache_frag.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "working_set.h"
-
-// See comment below.
-extern "C" {
-extern void __cxa_atexit(void (*function)(void));
-}
-
-namespace __esan {
-
-bool EsanIsInitialized;
-bool EsanDuringInit;
-ShadowMapping Mapping;
-
-// Different tools use different scales within the same shadow mapping scheme.
-// The scale used here must match that used by the compiler instrumentation.
-// This array is indexed by the ToolType enum.
-static const uptr ShadowScale[] = {
- 0, // ESAN_None.
- 2, // ESAN_CacheFrag: 4B:1B, so 4 to 1 == >>2.
- 6, // ESAN_WorkingSet: 64B:1B, so 64 to 1 == >>6.
-};
-
-// We are combining multiple performance tuning tools under the umbrella of
-// one EfficiencySanitizer super-tool. Most of our tools have very similar
-// memory access instrumentation, shadow memory mapping, libc interception,
-// etc., and there is typically more shared code than distinct code.
-//
-// We are not willing to dispatch on tool dynamically in our fastpath
-// instrumentation: thus, which tool to use is a static option selected
-// at compile time and passed to __esan_init().
-//
-// We are willing to pay the overhead of tool dispatch in the slowpath to more
-// easily share code. We expect to only come here rarely.
-// If this becomes a performance hit, we can add separate interface
-// routines for each subtool (e.g., __esan_cache_frag_aligned_load_4).
-// But for libc interceptors, we'll have to do one of the following:
-// A) Add multiple-include support to sanitizer_common_interceptors.inc,
-// instantiate it separately for each tool, and call the selected
-// tool's intercept setup code.
-// B) Build separate static runtime libraries, one for each tool.
-// C) Completely split the tools into separate sanitizers.
-
-void processRangeAccess(uptr PC, uptr Addr, int Size, bool IsWrite) {
- VPrintf(3, "in esan::%s %p: %c %p %d\n", __FUNCTION__, PC,
- IsWrite ? 'w' : 'r', Addr, Size);
- if (__esan_which_tool == ESAN_CacheFrag) {
- // TODO(bruening): add shadow mapping and update shadow bits here.
- // We'll move this to cache_frag.cpp once we have something.
- } else if (__esan_which_tool == ESAN_WorkingSet) {
- processRangeAccessWorkingSet(PC, Addr, Size, IsWrite);
- }
-}
-
-bool processSignal(int SigNum, void (*Handler)(int), void (**Result)(int)) {
- if (__esan_which_tool == ESAN_WorkingSet)
- return processWorkingSetSignal(SigNum, Handler, Result);
- return true;
-}
-
-bool processSigaction(int SigNum, const void *Act, void *OldAct) {
- if (__esan_which_tool == ESAN_WorkingSet)
- return processWorkingSetSigaction(SigNum, Act, OldAct);
- return true;
-}
-
-bool processSigprocmask(int How, void *Set, void *OldSet) {
- if (__esan_which_tool == ESAN_WorkingSet)
- return processWorkingSetSigprocmask(How, Set, OldSet);
- return true;
-}
-
-#if SANITIZER_DEBUG
-static bool verifyShadowScheme() {
- // Sanity checks for our shadow mapping scheme.
- uptr AppStart, AppEnd;
- if (Verbosity() >= 3) {
- for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) {
- VPrintf(3, "App #%d: [%zx-%zx) (%zuGB)\n", i, AppStart, AppEnd,
- (AppEnd - AppStart) >> 30);
- }
- }
- for (int Scale = 0; Scale < 8; ++Scale) {
- Mapping.initialize(Scale);
- if (Verbosity() >= 3) {
- VPrintf(3, "\nChecking scale %d\n", Scale);
- uptr ShadowStart, ShadowEnd;
- for (int i = 0; getShadowRegion(i, &ShadowStart, &ShadowEnd); ++i) {
- VPrintf(3, "Shadow #%d: [%zx-%zx) (%zuGB)\n", i, ShadowStart,
- ShadowEnd, (ShadowEnd - ShadowStart) >> 30);
- }
- for (int i = 0; getShadowRegion(i, &ShadowStart, &ShadowEnd); ++i) {
- VPrintf(3, "Shadow(Shadow) #%d: [%zx-%zx)\n", i,
- appToShadow(ShadowStart), appToShadow(ShadowEnd - 1)+1);
- }
- }
- for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) {
- DCHECK(isAppMem(AppStart));
- DCHECK(!isAppMem(AppStart - 1));
- DCHECK(isAppMem(AppEnd - 1));
- DCHECK(!isAppMem(AppEnd));
- DCHECK(!isShadowMem(AppStart));
- DCHECK(!isShadowMem(AppEnd - 1));
- DCHECK(isShadowMem(appToShadow(AppStart)));
- DCHECK(isShadowMem(appToShadow(AppEnd - 1)));
- // Double-shadow checks.
- DCHECK(!isShadowMem(appToShadow(appToShadow(AppStart))));
- DCHECK(!isShadowMem(appToShadow(appToShadow(AppEnd - 1))));
- }
- // Ensure no shadow regions overlap each other.
- uptr ShadowAStart, ShadowBStart, ShadowAEnd, ShadowBEnd;
- for (int i = 0; getShadowRegion(i, &ShadowAStart, &ShadowAEnd); ++i) {
- for (int j = 0; getShadowRegion(j, &ShadowBStart, &ShadowBEnd); ++j) {
- DCHECK(i == j || ShadowAStart >= ShadowBEnd ||
- ShadowAEnd <= ShadowBStart);
- }
- }
- }
- return true;
-}
-#endif
-
-uptr VmaSize;
-
-static void initializeShadow() {
- verifyAddressSpace();
-
- // This is based on the assumption that the intial stack is always allocated
- // in the topmost segment of the user address space and the assumption
- // holds true on all the platforms currently supported.
- VmaSize =
- (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
-
- DCHECK(verifyShadowScheme());
-
- Mapping.initialize(ShadowScale[__esan_which_tool]);
-
- VPrintf(1, "Shadow scale=%d offset=%p\n", Mapping.Scale, Mapping.Offset);
-
- uptr ShadowStart, ShadowEnd;
- for (int i = 0; getShadowRegion(i, &ShadowStart, &ShadowEnd); ++i) {
- VPrintf(1, "Shadow #%d: [%zx-%zx) (%zuGB)\n", i, ShadowStart, ShadowEnd,
- (ShadowEnd - ShadowStart) >> 30);
-
- uptr Map = 0;
- if (__esan_which_tool == ESAN_WorkingSet) {
- // We want to identify all shadow pages that are touched so we start
- // out inaccessible.
- Map = (uptr)MmapFixedNoAccess(ShadowStart, ShadowEnd- ShadowStart,
- "shadow");
- } else {
- if (MmapFixedNoReserve(ShadowStart, ShadowEnd - ShadowStart, "shadow"))
- Map = ShadowStart;
- }
- if (Map != ShadowStart) {
- Printf("FATAL: EfficiencySanitizer failed to map its shadow memory.\n");
- Die();
- }
-
- if (common_flags()->no_huge_pages_for_shadow)
- NoHugePagesInRegion(ShadowStart, ShadowEnd - ShadowStart);
- if (common_flags()->use_madv_dontdump)
- DontDumpShadowMemory(ShadowStart, ShadowEnd - ShadowStart);
-
- // TODO: Call MmapNoAccess() on in-between regions.
- }
-}
-
-void initializeLibrary(ToolType Tool) {
- // We assume there is only one thread during init, but we need to
- // guard against double-init when we're (re-)called from an
- // early interceptor.
- if (EsanIsInitialized || EsanDuringInit)
- return;
- EsanDuringInit = true;
- CHECK(Tool == __esan_which_tool);
- SanitizerToolName = "EfficiencySanitizer";
- CacheBinaryName();
- initializeFlags();
-
- // Intercepting libc _exit or exit via COMMON_INTERCEPTOR_ON_EXIT only
- // finalizes on an explicit exit call by the app. To handle a normal
- // exit we register an atexit handler.
- ::__cxa_atexit((void (*)())finalizeLibrary);
-
- VPrintf(1, "in esan::%s\n", __FUNCTION__);
- if (__esan_which_tool <= ESAN_None || __esan_which_tool >= ESAN_Max) {
- Printf("ERROR: unknown tool %d requested\n", __esan_which_tool);
- Die();
- }
-
- initializeShadow();
- if (__esan_which_tool == ESAN_WorkingSet)
- initializeShadowWorkingSet();
-
- initializeInterceptors();
-
- if (__esan_which_tool == ESAN_CacheFrag) {
- initializeCacheFrag();
- } else if (__esan_which_tool == ESAN_WorkingSet) {
- initializeWorkingSet();
- }
-
- EsanIsInitialized = true;
- EsanDuringInit = false;
-}
-
-int finalizeLibrary() {
- VPrintf(1, "in esan::%s\n", __FUNCTION__);
- if (__esan_which_tool == ESAN_CacheFrag) {
- return finalizeCacheFrag();
- } else if (__esan_which_tool == ESAN_WorkingSet) {
- return finalizeWorkingSet();
- }
- return 0;
-}
-
-void reportResults() {
- VPrintf(1, "in esan::%s\n", __FUNCTION__);
- if (__esan_which_tool == ESAN_CacheFrag) {
- return reportCacheFrag();
- } else if (__esan_which_tool == ESAN_WorkingSet) {
- return reportWorkingSet();
- }
-}
-
-void processCompilationUnitInit(void *Ptr) {
- VPrintf(2, "in esan::%s\n", __FUNCTION__);
- if (__esan_which_tool == ESAN_CacheFrag) {
- DCHECK(Ptr != nullptr);
- processCacheFragCompilationUnitInit(Ptr);
- } else {
- DCHECK(Ptr == nullptr);
- }
-}
-
-// This is called when the containing module is unloaded.
-// For the main executable module, this is called after finalizeLibrary.
-void processCompilationUnitExit(void *Ptr) {
- VPrintf(2, "in esan::%s\n", __FUNCTION__);
- if (__esan_which_tool == ESAN_CacheFrag) {
- DCHECK(Ptr != nullptr);
- processCacheFragCompilationUnitExit(Ptr);
- } else {
- DCHECK(Ptr == nullptr);
- }
-}
-
-unsigned int getSampleCount() {
- VPrintf(1, "in esan::%s\n", __FUNCTION__);
- if (__esan_which_tool == ESAN_WorkingSet) {
- return getSampleCountWorkingSet();
- }
- return 0;
-}
-
-} // namespace __esan
diff --git a/compiler-rt/lib/esan/esan.h b/compiler-rt/lib/esan/esan.h
deleted file mode 100644
index b9bdff3ab5e..00000000000
--- a/compiler-rt/lib/esan/esan.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===-- esan.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Main internal esan header file.
-//
-// Ground rules:
-// - C++ run-time should not be used (static CTORs, RTTI, exceptions, static
-// function-scope locals)
-// - All functions/classes/etc reside in namespace __esan, except for those
-// declared in esan_interface_internal.h.
-// - Platform-specific files should be used instead of ifdefs (*).
-// - No system headers included in header files (*).
-// - Platform specific headers included only into platform-specific files (*).
-//
-// (*) Except when inlining is critical for performance.
-//===----------------------------------------------------------------------===//
-
-#ifndef ESAN_H
-#define ESAN_H
-
-#include "interception/interception.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "esan_interface_internal.h"
-
-namespace __esan {
-
-extern bool EsanIsInitialized;
-extern bool EsanDuringInit;
-extern uptr VmaSize;
-
-void initializeLibrary(ToolType Tool);
-int finalizeLibrary();
-void reportResults();
-unsigned int getSampleCount();
-// Esan creates the variable per tool per compilation unit at compile time
-// and passes its pointer Ptr to the runtime library.
-void processCompilationUnitInit(void *Ptr);
-void processCompilationUnitExit(void *Ptr);
-void processRangeAccess(uptr PC, uptr Addr, int Size, bool IsWrite);
-void initializeInterceptors();
-
-// Platform-dependent routines.
-void verifyAddressSpace();
-bool fixMmapAddr(void **Addr, SIZE_T Size, int Flags);
-uptr checkMmapResult(uptr Addr, SIZE_T Size);
-// The return value indicates whether to call the real version or not.
-bool processSignal(int SigNum, void (*Handler)(int), void (**Result)(int));
-bool processSigaction(int SigNum, const void *Act, void *OldAct);
-bool processSigprocmask(int How, void *Set, void *OldSet);
-
-} // namespace __esan
-
-#endif // ESAN_H
diff --git a/compiler-rt/lib/esan/esan.syms.extra b/compiler-rt/lib/esan/esan.syms.extra
deleted file mode 100644
index d6397d4c350..00000000000
--- a/compiler-rt/lib/esan/esan.syms.extra
+++ /dev/null
@@ -1,4 +0,0 @@
-__esan_init
-__esan_exit
-__esan_aligned*
-__esan_unaligned*
diff --git a/compiler-rt/lib/esan/esan_circular_buffer.h b/compiler-rt/lib/esan/esan_circular_buffer.h
deleted file mode 100644
index 3dcae69ac7a..00000000000
--- a/compiler-rt/lib/esan/esan_circular_buffer.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- esan_circular_buffer.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Circular buffer data structure.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_common.h"
-
-namespace __esan {
-
-// A circular buffer for POD data whose memory is allocated using mmap.
-// There are two usage models: one is to use initialize/free (for global
-// instances) and the other is to use placement new with the
-// constructor and to call the destructor or free (they are equivalent).
-template<typename T>
-class CircularBuffer {
- public:
- // To support global instances we cannot initialize any field in the
- // default constructor.
- explicit CircularBuffer() {}
- CircularBuffer(uptr BufferCapacity) {
- initialize(BufferCapacity);
- WasConstructed = true;
- }
- ~CircularBuffer() {
- if (WasConstructed) // Else caller will call free() explicitly.
- free();
- }
- void initialize(uptr BufferCapacity) {
- Capacity = BufferCapacity;
- // MmapOrDie rounds up to the page size for us.
- Data = (T *)MmapOrDie(Capacity * sizeof(T), "CircularBuffer");
- StartIdx = 0;
- Count = 0;
- WasConstructed = false;
- }
- void free() {
- UnmapOrDie(Data, Capacity * sizeof(T));
- }
- T &operator[](uptr Idx) {
- CHECK_LT(Idx, Count);
- uptr ArrayIdx = (StartIdx + Idx) % Capacity;
- return Data[ArrayIdx];
- }
- const T &operator[](uptr Idx) const {
- CHECK_LT(Idx, Count);
- uptr ArrayIdx = (StartIdx + Idx) % Capacity;
- return Data[ArrayIdx];
- }
- void push_back(const T &Item) {
- CHECK_GT(Capacity, 0);
- uptr ArrayIdx = (StartIdx + Count) % Capacity;
- Data[ArrayIdx] = Item;
- if (Count < Capacity)
- ++Count;
- else
- StartIdx = (StartIdx + 1) % Capacity;
- }
- T &back() {
- CHECK_GT(Count, 0);
- uptr ArrayIdx = (StartIdx + Count - 1) % Capacity;
- return Data[ArrayIdx];
- }
- void pop_back() {
- CHECK_GT(Count, 0);
- --Count;
- }
- uptr size() const {
- return Count;
- }
- void clear() {
- StartIdx = 0;
- Count = 0;
- }
- bool empty() const { return size() == 0; }
-
- private:
- CircularBuffer(const CircularBuffer&);
- void operator=(const CircularBuffer&);
-
- bool WasConstructed;
- T *Data;
- uptr Capacity;
- uptr StartIdx;
- uptr Count;
-};
-
-} // namespace __esan
diff --git a/compiler-rt/lib/esan/esan_flags.cpp b/compiler-rt/lib/esan/esan_flags.cpp
deleted file mode 100644
index 2559e41bc64..00000000000
--- a/compiler-rt/lib/esan/esan_flags.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- esan_flags.cc -------------------------------------------*- 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 EfficiencySanitizer, a family of performance tuners.
-//
-// Esan flag parsing logic.
-//===----------------------------------------------------------------------===//
-
-#include "esan_flags.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
-#include "sanitizer_common/sanitizer_flags.h"
-
-using namespace __sanitizer;
-
-namespace __esan {
-
-static const char EsanOptsEnv[] = "ESAN_OPTIONS";
-
-Flags EsanFlagsDontUseDirectly;
-
-void Flags::setDefaults() {
-#define ESAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
-#include "esan_flags.inc"
-#undef ESAN_FLAG
-}
-
-static void registerEsanFlags(FlagParser *Parser, Flags *F) {
-#define ESAN_FLAG(Type, Name, DefaultValue, Description) \
- RegisterFlag(Parser, #Name, Description, &F->Name);
-#include "esan_flags.inc"
-#undef ESAN_FLAG
-}
-
-void initializeFlags() {
- SetCommonFlagsDefaults();
- Flags *F = getFlags();
- F->setDefaults();
-
- FlagParser Parser;
- registerEsanFlags(&Parser, F);
- RegisterCommonFlags(&Parser);
- Parser.ParseString(GetEnv(EsanOptsEnv));
-
- InitializeCommonFlags();
- if (Verbosity())
- ReportUnrecognizedFlags();
- if (common_flags()->help)
- Parser.PrintFlagDescriptions();
-
- __sanitizer_set_report_path(common_flags()->log_path);
-}
-
-} // namespace __esan
diff --git a/compiler-rt/lib/esan/esan_flags.h b/compiler-rt/lib/esan/esan_flags.h
deleted file mode 100644
index a5bdeb0bc3e..00000000000
--- a/compiler-rt/lib/esan/esan_flags.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- esan_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 EfficiencySanitizer, a family of performance tuners.
-//
-// Esan runtime flags.
-//===----------------------------------------------------------------------===//
-
-#ifndef ESAN_FLAGS_H
-#define ESAN_FLAGS_H
-
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
-
-namespace __esan {
-
-class Flags {
-public:
-#define ESAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
-#include "esan_flags.inc"
-#undef ESAN_FLAG
-
- void setDefaults();
-};
-
-extern Flags EsanFlagsDontUseDirectly;
-inline Flags *getFlags() {
- return &EsanFlagsDontUseDirectly;
-}
-
-void initializeFlags();
-
-} // namespace __esan
-
-#endif // ESAN_FLAGS_H
diff --git a/compiler-rt/lib/esan/esan_flags.inc b/compiler-rt/lib/esan/esan_flags.inc
deleted file mode 100644
index 43e47d951fc..00000000000
--- a/compiler-rt/lib/esan/esan_flags.inc
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- esan_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
-//
-//===----------------------------------------------------------------------===//
-//
-// Esan runtime flags.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ESAN_FLAG
-# error "Define ESAN_FLAG prior to including this file!"
-#endif
-
-// ESAN_FLAG(Type, Name, DefaultValue, Description)
-// See COMMON_FLAG in sanitizer_flags.inc for more details.
-
-//===----------------------------------------------------------------------===//
-// Cross-tool options
-//===----------------------------------------------------------------------===//
-
-ESAN_FLAG(int, cache_line_size, 64,
- "The number of bytes in a cache line. For the working-set tool, this "
- "cannot be changed without also changing the compiler "
- "instrumentation.")
-
-//===----------------------------------------------------------------------===//
-// Working set tool options
-//===----------------------------------------------------------------------===//
-
-ESAN_FLAG(bool, record_snapshots, true,
- "Working set tool: whether to sample snapshots during a run.")
-
-// Typical profiling uses a 10ms timer. Our snapshots take some work
-// to scan memory so we reduce to 20ms.
-// To disable samples, turn off record_snapshots.
-ESAN_FLAG(int, sample_freq, 20,
- "Working set tool: sampling frequency in milliseconds.")
-
-// This controls the difference in frequency between each successive series
-// of snapshots. There are 8 in total, with number 0 using sample_freq.
-// Number N samples number N-1 every (1 << snapshot_step) instance of N-1.
-ESAN_FLAG(int, snapshot_step, 2, "Working set tool: the log of the sampling "
- "performed for the next-higher-frequency snapshot series.")
-
-//===----------------------------------------------------------------------===//
-// Cache Fragmentation tool options
-//===----------------------------------------------------------------------===//
-
-// The difference information of a struct is reported if the struct's difference
-// score is greater than the report_threshold.
-ESAN_FLAG(int, report_threshold, 1<<10, "Cache-frag tool: the struct difference"
- " score threshold for reporting.")
diff --git a/compiler-rt/lib/esan/esan_hashtable.h b/compiler-rt/lib/esan/esan_hashtable.h
deleted file mode 100644
index 579faa312c2..00000000000
--- a/compiler-rt/lib/esan/esan_hashtable.h
+++ /dev/null
@@ -1,380 +0,0 @@
-//===-- esan_hashtable.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Generic resizing hashtable.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_allocator_internal.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_mutex.h"
-#include <stddef.h>
-
-namespace __esan {
-
-//===----------------------------------------------------------------------===//
-// Default hash and comparison functions
-//===----------------------------------------------------------------------===//
-
-template <typename T> struct DefaultHash {
- size_t operator()(const T &Key) const {
- return (size_t)Key;
- }
-};
-
-template <typename T> struct DefaultEqual {
- bool operator()(const T &Key1, const T &Key2) const {
- return Key1 == Key2;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// HashTable declaration
-//===----------------------------------------------------------------------===//
-
-// A simple resizing and mutex-locked hashtable.
-//
-// If the default hash functor is used, KeyTy must have an operator size_t().
-// If the default comparison functor is used, KeyTy must have an operator ==.
-//
-// By default all operations are internally-synchronized with a mutex, with no
-// synchronization for payloads once hashtable functions return. If
-// ExternalLock is set to true, the caller should call the lock() and unlock()
-// routines around all hashtable operations and subsequent manipulation of
-// payloads.
-template <typename KeyTy, typename DataTy, bool ExternalLock = false,
- typename HashFuncTy = DefaultHash<KeyTy>,
- typename EqualFuncTy = DefaultEqual<KeyTy> >
-class HashTable {
-public:
- // InitialCapacity must be a power of 2.
- // ResizeFactor must be between 1 and 99 and indicates the
- // maximum percentage full that the table should ever be.
- HashTable(u32 InitialCapacity = 2048, u32 ResizeFactor = 70);
- ~HashTable();
- bool lookup(const KeyTy &Key, DataTy &Payload); // Const except for Mutex.
- bool add(const KeyTy &Key, const DataTy &Payload);
- bool remove(const KeyTy &Key);
- u32 size(); // Const except for Mutex.
- // If the table is internally-synchronized, this lock must not be held
- // while a hashtable function is called as it will deadlock: the lock
- // is not recursive. This is meant for use with externally-synchronized
- // tables or with an iterator.
- void lock();
- void unlock();
-
-private:
- struct HashEntry {
- KeyTy Key;
- DataTy Payload;
- HashEntry *Next;
- };
-
-public:
- struct HashPair {
- HashPair(KeyTy Key, DataTy Data) : Key(Key), Data(Data) {}
- KeyTy Key;
- DataTy Data;
- };
-
- // This iterator does not perform any synchronization.
- // It expects the caller to lock the table across the whole iteration.
- // Calling HashTable functions while using the iterator is not supported.
- // The iterator returns copies of the keys and data.
- class iterator {
- public:
- iterator(
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy> *Table);
- iterator(const iterator &Src) = default;
- iterator &operator=(const iterator &Src) = default;
- HashPair operator*();
- iterator &operator++();
- iterator &operator++(int);
- bool operator==(const iterator &Cmp) const;
- bool operator!=(const iterator &Cmp) const;
-
- private:
- iterator(
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy> *Table,
- int Idx);
- friend HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>;
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy> *Table;
- int Idx;
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::HashEntry
- *Entry;
- };
-
- // No erase or insert iterator supported
- iterator begin();
- iterator end();
-
-private:
- void resize();
-
- HashEntry **Table;
- u32 Capacity;
- u32 Entries;
- const u32 ResizeFactor;
- BlockingMutex Mutex;
- const HashFuncTy HashFunc;
- const EqualFuncTy EqualFunc;
-};
-
-//===----------------------------------------------------------------------===//
-// Hashtable implementation
-//===----------------------------------------------------------------------===//
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::HashTable(
- u32 InitialCapacity, u32 ResizeFactor)
- : Capacity(InitialCapacity), Entries(0), ResizeFactor(ResizeFactor),
- HashFunc(HashFuncTy()), EqualFunc(EqualFuncTy()) {
- CHECK(IsPowerOfTwo(Capacity));
- CHECK(ResizeFactor >= 1 && ResizeFactor <= 99);
- Table = (HashEntry **)InternalAlloc(Capacity * sizeof(HashEntry *));
- internal_memset(Table, 0, Capacity * sizeof(HashEntry *));
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::~HashTable() {
- for (u32 i = 0; i < Capacity; ++i) {
- HashEntry *Entry = Table[i];
- while (Entry != nullptr) {
- HashEntry *Next = Entry->Next;
- Entry->Payload.~DataTy();
- InternalFree(Entry);
- Entry = Next;
- }
- }
- InternalFree(Table);
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-u32 HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::size() {
- u32 Res;
- if (!ExternalLock)
- Mutex.Lock();
- Res = Entries;
- if (!ExternalLock)
- Mutex.Unlock();
- return Res;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-bool HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::lookup(
- const KeyTy &Key, DataTy &Payload) {
- if (!ExternalLock)
- Mutex.Lock();
- bool Found = false;
- size_t Hash = HashFunc(Key) % Capacity;
- HashEntry *Entry = Table[Hash];
- for (; Entry != nullptr; Entry = Entry->Next) {
- if (EqualFunc(Entry->Key, Key)) {
- Payload = Entry->Payload;
- Found = true;
- break;
- }
- }
- if (!ExternalLock)
- Mutex.Unlock();
- return Found;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-void HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::resize() {
- if (!ExternalLock)
- Mutex.CheckLocked();
- size_t OldCapacity = Capacity;
- HashEntry **OldTable = Table;
- Capacity *= 2;
- Table = (HashEntry **)InternalAlloc(Capacity * sizeof(HashEntry *));
- internal_memset(Table, 0, Capacity * sizeof(HashEntry *));
- // Re-hash
- for (u32 i = 0; i < OldCapacity; ++i) {
- HashEntry *OldEntry = OldTable[i];
- while (OldEntry != nullptr) {
- HashEntry *Next = OldEntry->Next;
- size_t Hash = HashFunc(OldEntry->Key) % Capacity;
- OldEntry->Next = Table[Hash];
- Table[Hash] = OldEntry;
- OldEntry = Next;
- }
- }
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-bool HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::add(
- const KeyTy &Key, const DataTy &Payload) {
- if (!ExternalLock)
- Mutex.Lock();
- bool Exists = false;
- size_t Hash = HashFunc(Key) % Capacity;
- HashEntry *Entry = Table[Hash];
- for (; Entry != nullptr; Entry = Entry->Next) {
- if (EqualFunc(Entry->Key, Key)) {
- Exists = true;
- break;
- }
- }
- if (!Exists) {
- Entries++;
- if (Entries * 100 >= Capacity * ResizeFactor) {
- resize();
- Hash = HashFunc(Key) % Capacity;
- }
- HashEntry *Add = (HashEntry *)InternalAlloc(sizeof(*Add));
- Add->Key = Key;
- Add->Payload = Payload;
- Add->Next = Table[Hash];
- Table[Hash] = Add;
- }
- if (!ExternalLock)
- Mutex.Unlock();
- return !Exists;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-bool HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::remove(
- const KeyTy &Key) {
- if (!ExternalLock)
- Mutex.Lock();
- bool Found = false;
- size_t Hash = HashFunc(Key) % Capacity;
- HashEntry *Entry = Table[Hash];
- HashEntry *Prev = nullptr;
- for (; Entry != nullptr; Prev = Entry, Entry = Entry->Next) {
- if (EqualFunc(Entry->Key, Key)) {
- Found = true;
- Entries--;
- if (Prev == nullptr)
- Table[Hash] = Entry->Next;
- else
- Prev->Next = Entry->Next;
- Entry->Payload.~DataTy();
- InternalFree(Entry);
- break;
- }
- }
- if (!ExternalLock)
- Mutex.Unlock();
- return Found;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-void HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::lock() {
- Mutex.Lock();
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-void HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::unlock() {
- Mutex.Unlock();
-}
-
-//===----------------------------------------------------------------------===//
-// Iterator implementation
-//===----------------------------------------------------------------------===//
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::iterator::
- iterator(
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy> *Table)
- : Table(Table), Idx(-1), Entry(nullptr) {
- operator++();
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::iterator::
- iterator(
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy> *Table,
- int Idx)
- : Table(Table), Idx(Idx), Entry(nullptr) {
- CHECK(Idx >= (int)Table->Capacity); // Only used to create end().
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-typename HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy,
- EqualFuncTy>::HashPair
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::iterator::
- operator*() {
- CHECK(Idx >= 0 && Idx < (int)Table->Capacity);
- CHECK(Entry != nullptr);
- return HashPair(Entry->Key, Entry->Payload);
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-typename HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy,
- EqualFuncTy>::iterator &
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::iterator::
- operator++() {
- if (Entry != nullptr)
- Entry = Entry->Next;
- while (Entry == nullptr) {
- ++Idx;
- if (Idx >= (int)Table->Capacity)
- break; // At end().
- Entry = Table->Table[Idx];
- }
- return *this;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-typename HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy,
- EqualFuncTy>::iterator &
- HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::iterator::
- operator++(int) {
- iterator Temp(*this);
- operator++();
- return Temp;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-bool HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::iterator::
-operator==(const iterator &Cmp) const {
- return Cmp.Table == Table && Cmp.Idx == Idx && Cmp.Entry == Entry;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-bool HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::iterator::
-operator!=(const iterator &Cmp) const {
- return Cmp.Table != Table || Cmp.Idx != Idx || Cmp.Entry != Entry;
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-typename HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy,
- EqualFuncTy>::iterator
-HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::begin() {
- return iterator(this);
-}
-
-template <typename KeyTy, typename DataTy, bool ExternalLock,
- typename HashFuncTy, typename EqualFuncTy>
-typename HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy,
- EqualFuncTy>::iterator
-HashTable<KeyTy, DataTy, ExternalLock, HashFuncTy, EqualFuncTy>::end() {
- return iterator(this, Capacity);
-}
-
-} // namespace __esan
diff --git a/compiler-rt/lib/esan/esan_interceptors.cpp b/compiler-rt/lib/esan/esan_interceptors.cpp
deleted file mode 100644
index 1e8e67c4bb3..00000000000
--- a/compiler-rt/lib/esan/esan_interceptors.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-//===-- esan_interceptors.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Interception routines for the esan run-time.
-//===----------------------------------------------------------------------===//
-
-#include "esan.h"
-#include "esan_shadow.h"
-#include "interception/interception.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_linux.h"
-#include "sanitizer_common/sanitizer_stacktrace.h"
-
-using namespace __esan; // NOLINT
-
-#define CUR_PC() (StackTrace::GetCurrentPc())
-
-//===----------------------------------------------------------------------===//
-// Interception via sanitizer common interceptors
-//===----------------------------------------------------------------------===//
-
-// Get the per-platform defines for what is possible to intercept
-#include "sanitizer_common/sanitizer_platform_interceptors.h"
-
-DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
-
-// TODO(bruening): tsan disables several interceptors (getpwent, etc.) claiming
-// that interception is a perf hit: should we do the same?
-
-// We have no need to intercept:
-#undef SANITIZER_INTERCEPT_TLS_GET_ADDR
-
-// TODO(bruening): the common realpath interceptor assumes malloc is
-// intercepted! We should try to parametrize that, though we'll
-// intercept malloc soon ourselves and can then remove this undef.
-#undef SANITIZER_INTERCEPT_REALPATH
-
-// We provide our own version:
-#undef SANITIZER_INTERCEPT_SIGPROCMASK
-#undef SANITIZER_INTERCEPT_PTHREAD_SIGMASK
-
-#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!EsanIsInitialized)
-
-#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
-#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
- INTERCEPT_FUNCTION_VER(name, ver)
-
-// We must initialize during early interceptors, to support tcmalloc.
-// This means that for some apps we fully initialize prior to
-// __esan_init() being called.
-// We currently do not use ctx.
-#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
- do { \
- if (UNLIKELY(COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)) { \
- if (!UNLIKELY(EsanDuringInit)) \
- initializeLibrary(__esan_which_tool); \
- return REAL(func)(__VA_ARGS__); \
- } \
- ctx = nullptr; \
- (void)ctx; \
- } while (false)
-
-#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, func, ...) \
- COMMON_INTERCEPTOR_ENTER(ctx, func, __VA_ARGS__)
-
-#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
- processRangeAccess(CUR_PC(), (uptr)ptr, size, true)
-
-#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
- processRangeAccess(CUR_PC(), (uptr)ptr, size, false)
-
-// This is only called if the app explicitly calls exit(), not on
-// a normal exit.
-#define COMMON_INTERCEPTOR_ON_EXIT(ctx) finalizeLibrary()
-
-#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \
- do { \
- (void)(ctx); \
- (void)(file); \
- (void)(path); \
- } while (false)
-#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) \
- do { \
- (void)(ctx); \
- (void)(file); \
- } while (false)
-#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
- do { \
- (void)(filename); \
- (void)(handle); \
- } while (false)
-#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() \
- do { \
- } while (false)
-#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) \
- do { \
- (void)(ctx); \
- (void)(u); \
- } while (false)
-#define COMMON_INTERCEPTOR_RELEASE(ctx, u) \
- do { \
- (void)(ctx); \
- (void)(u); \
- } while (false)
-#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
- do { \
- (void)(ctx); \
- (void)(path); \
- } while (false)
-#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
- do { \
- (void)(ctx); \
- (void)(fd); \
- } while (false)
-#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
- do { \
- (void)(ctx); \
- (void)(fd); \
- } while (false)
-#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \
- do { \
- (void)(ctx); \
- (void)(fd); \
- } while (false)
-#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
- do { \
- (void)(ctx); \
- (void)(fd); \
- (void)(newfd); \
- } while (false)
-#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
- do { \
- (void)(ctx); \
- (void)(name); \
- } while (false)
-#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
- do { \
- (void)(ctx); \
- (void)(thread); \
- (void)(name); \
- } while (false)
-#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
-#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \
- do { \
- (void)(ctx); \
- (void)(m); \
- } while (false)
-#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \
- do { \
- (void)(ctx); \
- (void)(m); \
- } while (false)
-#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) \
- do { \
- (void)(ctx); \
- (void)(m); \
- } while (false)
-#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) \
- do { \
- (void)(ctx); \
- (void)(msg); \
- } while (false)
-#define COMMON_INTERCEPTOR_USER_CALLBACK_START() \
- do { \
- } while (false)
-#define COMMON_INTERCEPTOR_USER_CALLBACK_END() \
- do { \
- } while (false)
-
-#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
- off) \
- do { \
- if (!fixMmapAddr(&addr, sz, flags)) \
- return (void *)-1; \
- void *result = REAL(mmap)(addr, sz, prot, flags, fd, off); \
- return (void *)checkMmapResult((uptr)result, sz); \
- } while (false)
-
-#include "sanitizer_common/sanitizer_common_interceptors.inc"
-
-//===----------------------------------------------------------------------===//
-// Syscall interception
-//===----------------------------------------------------------------------===//
-
-// We want the caller's PC b/c unlike the other function interceptors these
-// are separate pre and post functions called around the app's syscall().
-
-#define COMMON_SYSCALL_PRE_READ_RANGE(ptr, size) \
- processRangeAccess(GET_CALLER_PC(), (uptr)ptr, size, false)
-
-#define COMMON_SYSCALL_PRE_WRITE_RANGE(ptr, size) \
- do { \
- (void)(ptr); \
- (void)(size); \
- } while (false)
-
-#define COMMON_SYSCALL_POST_READ_RANGE(ptr, size) \
- do { \
- (void)(ptr); \
- (void)(size); \
- } while (false)
-
-// The actual amount written is in post, not pre.
-#define COMMON_SYSCALL_POST_WRITE_RANGE(ptr, size) \
- processRangeAccess(GET_CALLER_PC(), (uptr)ptr, size, true)
-
-#define COMMON_SYSCALL_ACQUIRE(addr) \
- do { \
- (void)(addr); \
- } while (false)
-#define COMMON_SYSCALL_RELEASE(addr) \
- do { \
- (void)(addr); \
- } while (false)
-#define COMMON_SYSCALL_FD_CLOSE(fd) \
- do { \
- (void)(fd); \
- } while (false)
-#define COMMON_SYSCALL_FD_ACQUIRE(fd) \
- do { \
- (void)(fd); \
- } while (false)
-#define COMMON_SYSCALL_FD_RELEASE(fd) \
- do { \
- (void)(fd); \
- } while (false)
-#define COMMON_SYSCALL_PRE_FORK() \
- do { \
- } while (false)
-#define COMMON_SYSCALL_POST_FORK(res) \
- do { \
- (void)(res); \
- } while (false)
-
-#include "sanitizer_common/sanitizer_common_syscalls.inc"
-#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
-
-//===----------------------------------------------------------------------===//
-// Custom interceptors
-//===----------------------------------------------------------------------===//
-
-// TODO(bruening): move more of these to the common interception pool as they
-// are shared with tsan and asan.
-// While our other files match LLVM style, here we match sanitizer style as we
-// expect to move these to the common pool.
-
-INTERCEPTOR(char *, strcpy, char *dst, const char *src) { // NOLINT
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, strcpy, dst, src);
- uptr srclen = internal_strlen(src);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, srclen + 1);
- COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclen + 1);
- return REAL(strcpy)(dst, src); // NOLINT
-}
-
-INTERCEPTOR(char *, strncpy, char *dst, char *src, uptr n) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, strncpy, dst, src, n);
- uptr srclen = internal_strnlen(src, n);
- uptr copied_size = srclen + 1 > n ? n : srclen + 1;
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, copied_size);
- COMMON_INTERCEPTOR_READ_RANGE(ctx, src, copied_size);
- return REAL(strncpy)(dst, src, n);
-}
-
-INTERCEPTOR(int, open, const char *name, int flags, int mode) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, open, name, flags, mode);
- COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
- return REAL(open)(name, flags, mode);
-}
-
-#if SANITIZER_LINUX
-INTERCEPTOR(int, open64, const char *name, int flags, int mode) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, open64, name, flags, mode);
- COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
- return REAL(open64)(name, flags, mode);
-}
-#define ESAN_MAYBE_INTERCEPT_OPEN64 INTERCEPT_FUNCTION(open64)
-#else
-#define ESAN_MAYBE_INTERCEPT_OPEN64
-#endif
-
-INTERCEPTOR(int, creat, const char *name, int mode) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, creat, name, mode);
- COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
- return REAL(creat)(name, mode);
-}
-
-#if SANITIZER_LINUX
-INTERCEPTOR(int, creat64, const char *name, int mode) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, creat64, name, mode);
- COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
- return REAL(creat64)(name, mode);
-}
-#define ESAN_MAYBE_INTERCEPT_CREAT64 INTERCEPT_FUNCTION(creat64)
-#else
-#define ESAN_MAYBE_INTERCEPT_CREAT64
-#endif
-
-INTERCEPTOR(int, unlink, char *path) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, unlink, path);
- COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
- return REAL(unlink)(path);
-}
-
-INTERCEPTOR(int, rmdir, char *path) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, rmdir, path);
- COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
- return REAL(rmdir)(path);
-}
-
-//===----------------------------------------------------------------------===//
-// Signal-related interceptors
-//===----------------------------------------------------------------------===//
-
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
-typedef void (*signal_handler_t)(int);
-INTERCEPTOR(signal_handler_t, signal, int signum, signal_handler_t handler) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, signal, signum, handler);
- signal_handler_t result;
- if (!processSignal(signum, handler, &result))
- return result;
- else
- return REAL(signal)(signum, handler);
-}
-#define ESAN_MAYBE_INTERCEPT_SIGNAL INTERCEPT_FUNCTION(signal)
-#else
-#error Platform not supported
-#define ESAN_MAYBE_INTERCEPT_SIGNAL
-#endif
-
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
-DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act,
- struct sigaction *oldact)
-INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
- struct sigaction *oldact) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, sigaction, signum, act, oldact);
- if (!processSigaction(signum, act, oldact))
- return 0;
- else
- return REAL(sigaction)(signum, act, oldact);
-}
-
-// This is required to properly use internal_sigaction.
-namespace __sanitizer {
-int real_sigaction(int signum, const void *act, void *oldact) {
- if (REAL(sigaction) == nullptr) {
- // With an instrumented allocator, this is called during interceptor init
- // and we need a raw syscall solution.
-#if SANITIZER_LINUX
- return internal_sigaction_syscall(signum, act, oldact);
-#else
- return internal_sigaction(signum, act, oldact);
-#endif
- }
- return REAL(sigaction)(signum, (const struct sigaction *)act,
- (struct sigaction *)oldact);
-}
-} // namespace __sanitizer
-
-#define ESAN_MAYBE_INTERCEPT_SIGACTION INTERCEPT_FUNCTION(sigaction)
-#else
-#error Platform not supported
-#define ESAN_MAYBE_INTERCEPT_SIGACTION
-#endif
-
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
-INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
- __sanitizer_sigset_t *oldset) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
- int res = 0;
- if (processSigprocmask(how, set, oldset))
- res = REAL(sigprocmask)(how, set, oldset);
- if (!res && oldset)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
- return res;
-}
-#define ESAN_MAYBE_INTERCEPT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask)
-#else
-#define ESAN_MAYBE_INTERCEPT_SIGPROCMASK
-#endif
-
-#if !SANITIZER_WINDOWS
-INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
- __sanitizer_sigset_t *oldset) {
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
- int res = 0;
- if (processSigprocmask(how, set, oldset))
- res = REAL(sigprocmask)(how, set, oldset);
- if (!res && oldset)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
- return res;
-}
-#define ESAN_MAYBE_INTERCEPT_PTHREAD_SIGMASK INTERCEPT_FUNCTION(pthread_sigmask)
-#else
-#define ESAN_MAYBE_INTERCEPT_PTHREAD_SIGMASK
-#endif
-
-//===----------------------------------------------------------------------===//
-// Malloc interceptors
-//===----------------------------------------------------------------------===//
-
-static const uptr early_alloc_buf_size = 4096;
-static uptr allocated_bytes;
-static char early_alloc_buf[early_alloc_buf_size];
-
-static bool isInEarlyAllocBuf(const void *ptr) {
- return ((uptr)ptr >= (uptr)early_alloc_buf &&
- ((uptr)ptr - (uptr)early_alloc_buf) < sizeof(early_alloc_buf));
-}
-
-static void *handleEarlyAlloc(uptr size) {
- // If esan is initialized during an interceptor (which happens with some
- // tcmalloc implementations that call pthread_mutex_lock), the call from
- // dlsym to calloc will deadlock.
- // dlsym may also call malloc before REAL(malloc) is retrieved from dlsym.
- // We work around it by using a static buffer for the early malloc/calloc
- // requests.
- // This solution will also allow us to deliberately intercept malloc & family
- // in the future (to perform tool actions on each allocation, without
- // replacing the allocator), as it also solves the problem of intercepting
- // calloc when it will itself be called before its REAL pointer is
- // initialized.
- // We do not handle multiple threads here. This only happens at process init
- // time, and while it's possible for a shared library to create early threads
- // that race here, we consider that to be a corner case extreme enough that
- // it's not worth the effort to handle.
- void *mem = (void *)&early_alloc_buf[allocated_bytes];
- allocated_bytes += size;
- CHECK_LT(allocated_bytes, early_alloc_buf_size);
- return mem;
-}
-
-INTERCEPTOR(void*, calloc, uptr size, uptr n) {
- if (EsanDuringInit && REAL(calloc) == nullptr)
- return handleEarlyAlloc(size * n);
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, calloc, size, n);
- void *res = REAL(calloc)(size, n);
- // The memory is zeroed and thus is all written.
- COMMON_INTERCEPTOR_WRITE_RANGE(nullptr, (uptr)res, size * n);
- return res;
-}
-
-INTERCEPTOR(void*, malloc, uptr size) {
- if (EsanDuringInit && REAL(malloc) == nullptr)
- return handleEarlyAlloc(size);
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, malloc, size);
- return REAL(malloc)(size);
-}
-
-INTERCEPTOR(void, free, void *p) {
- void *ctx;
- // There are only a few early allocation requests, so we simply skip the free.
- if (isInEarlyAllocBuf(p))
- return;
- COMMON_INTERCEPTOR_ENTER(ctx, free, p);
- REAL(free)(p);
-}
-
-namespace __esan {
-
-void initializeInterceptors() {
- InitializeCommonInterceptors();
-
- INTERCEPT_FUNCTION(strcpy); // NOLINT
- INTERCEPT_FUNCTION(strncpy);
-
- INTERCEPT_FUNCTION(open);
- ESAN_MAYBE_INTERCEPT_OPEN64;
- INTERCEPT_FUNCTION(creat);
- ESAN_MAYBE_INTERCEPT_CREAT64;
- INTERCEPT_FUNCTION(unlink);
- INTERCEPT_FUNCTION(rmdir);
-
- ESAN_MAYBE_INTERCEPT_SIGNAL;
- ESAN_MAYBE_INTERCEPT_SIGACTION;
- ESAN_MAYBE_INTERCEPT_SIGPROCMASK;
- ESAN_MAYBE_INTERCEPT_PTHREAD_SIGMASK;
-
- INTERCEPT_FUNCTION(calloc);
- INTERCEPT_FUNCTION(malloc);
- INTERCEPT_FUNCTION(free);
-
- // TODO(bruening): intercept routines that other sanitizers intercept that
- // are not in the common pool or here yet, ideally by adding to the common
- // pool. Examples include wcslen and bcopy.
-
- // TODO(bruening): there are many more libc routines that read or write data
- // structures that no sanitizer is intercepting: sigaction, strtol, etc.
-}
-
-} // namespace __esan
diff --git a/compiler-rt/lib/esan/esan_interface.cpp b/compiler-rt/lib/esan/esan_interface.cpp
deleted file mode 100644
index 5035e73b03d..00000000000
--- a/compiler-rt/lib/esan/esan_interface.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-//===-- esan_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 EfficiencySanitizer, a family of performance tuners.
-//
-//===----------------------------------------------------------------------===//
-
-#include "esan_interface_internal.h"
-#include "esan.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-
-using namespace __esan; // NOLINT
-
-void __esan_init(ToolType Tool, void *Ptr) {
- if (Tool != __esan_which_tool) {
- Printf("ERROR: tool mismatch: %d vs %d\n", Tool, __esan_which_tool);
- Die();
- }
- initializeLibrary(Tool);
- processCompilationUnitInit(Ptr);
-}
-
-void __esan_exit(void *Ptr) {
- processCompilationUnitExit(Ptr);
-}
-
-void __esan_aligned_load1(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 1, false);
-}
-
-void __esan_aligned_load2(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 2, false);
-}
-
-void __esan_aligned_load4(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 4, false);
-}
-
-void __esan_aligned_load8(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 8, false);
-}
-
-void __esan_aligned_load16(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 16, false);
-}
-
-void __esan_aligned_store1(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 1, true);
-}
-
-void __esan_aligned_store2(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 2, true);
-}
-
-void __esan_aligned_store4(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 4, true);
-}
-
-void __esan_aligned_store8(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 8, true);
-}
-
-void __esan_aligned_store16(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 16, true);
-}
-
-void __esan_unaligned_load2(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 2, false);
-}
-
-void __esan_unaligned_load4(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 4, false);
-}
-
-void __esan_unaligned_load8(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 8, false);
-}
-
-void __esan_unaligned_load16(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 16, false);
-}
-
-void __esan_unaligned_store2(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 2, true);
-}
-
-void __esan_unaligned_store4(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 4, true);
-}
-
-void __esan_unaligned_store8(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 8, true);
-}
-
-void __esan_unaligned_store16(void *Addr) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, 16, true);
-}
-
-void __esan_unaligned_loadN(void *Addr, uptr Size) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, Size, false);
-}
-
-void __esan_unaligned_storeN(void *Addr, uptr Size) {
- processRangeAccess(GET_CALLER_PC(), (uptr)Addr, Size, true);
-}
-
-// Public interface:
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_report() {
- reportResults();
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE unsigned int __esan_get_sample_count() {
- return getSampleCount();
-}
-} // extern "C"
diff --git a/compiler-rt/lib/esan/esan_interface_internal.h b/compiler-rt/lib/esan/esan_interface_internal.h
deleted file mode 100644
index 5ea12b6ff46..00000000000
--- a/compiler-rt/lib/esan/esan_interface_internal.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- esan_interface_internal.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Calls to the functions declared in this header will be inserted by
-// the instrumentation module.
-//===----------------------------------------------------------------------===//
-
-#ifndef ESAN_INTERFACE_INTERNAL_H
-#define ESAN_INTERFACE_INTERNAL_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 __esan_.
-
-using __sanitizer::uptr;
-using __sanitizer::u32;
-
-extern "C" {
-
-// This should be kept consistent with LLVM's EfficiencySanitizerOptions.
-// The value is passed as a 32-bit integer by the compiler.
-typedef enum Type : u32 {
- ESAN_None = 0,
- ESAN_CacheFrag,
- ESAN_WorkingSet,
- ESAN_Max,
-} ToolType;
-
-// To handle interceptors that invoke instrumented code prior to
-// __esan_init() being called, the instrumentation module creates this
-// global variable specifying the tool.
-extern ToolType __esan_which_tool;
-
-// This function should be called at the very beginning of the process,
-// before any instrumented code is executed and before any call to malloc.
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_init(ToolType Tool, void *Ptr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_exit(void *Ptr);
-
-// The instrumentation module will insert a call to one of these routines prior
-// to each load and store instruction for which we do not have "fastpath"
-// inlined instrumentation. These calls constitute the "slowpath" for our
-// tools. We have separate routines for each type of memory access to enable
-// targeted optimization.
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_load1(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_load2(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_load4(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_load8(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_load16(void *Addr);
-
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_store1(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_store2(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_store4(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_store8(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_aligned_store16(void *Addr);
-
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_load2(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_load4(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_load8(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_load16(void *Addr);
-
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_store2(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_store4(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_store8(void *Addr);
-SANITIZER_INTERFACE_ATTRIBUTE void __esan_unaligned_store16(void *Addr);
-
-// These cover unusually-sized accesses.
-SANITIZER_INTERFACE_ATTRIBUTE
-void __esan_unaligned_loadN(void *Addr, uptr Size);
-SANITIZER_INTERFACE_ATTRIBUTE
-void __esan_unaligned_storeN(void *Addr, uptr Size);
-
-} // extern "C"
-
-#endif // ESAN_INTERFACE_INTERNAL_H
diff --git a/compiler-rt/lib/esan/esan_linux.cpp b/compiler-rt/lib/esan/esan_linux.cpp
deleted file mode 100644
index 0fe0fb1deed..00000000000
--- a/compiler-rt/lib/esan/esan_linux.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- esan.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Linux-specific code for the Esan run-time.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX
-
-#include "esan.h"
-#include "esan_shadow.h"
-#include "interception/interception.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include <sys/mman.h>
-#include <errno.h>
-
-namespace __esan {
-
-void verifyAddressSpace() {
-#if SANITIZER_LINUX && (defined(__x86_64__) || SANITIZER_MIPS64)
- // The kernel determines its mmap base from the stack size limit.
- // Our Linux 64-bit shadow mapping assumes the stack limit is less than a
- // terabyte, which keeps the mmap region above 0x7e00'.
- uptr StackLimit = GetStackSizeLimitInBytes();
- if (StackSizeIsUnlimited() || StackLimit > MaxStackSize) {
- VReport(1, "The stack size limit is beyond the maximum supported.\n"
- "Re-execing with a stack size below 1TB.\n");
- SetStackSizeLimitInBytes(MaxStackSize);
- ReExec();
- }
-#endif
-}
-
-static bool liesWithinSingleAppRegion(uptr Start, SIZE_T Size) {
- uptr AppStart, AppEnd;
- for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) {
- if (Start >= AppStart && Start + Size - 1 <= AppEnd) {
- return true;
- }
- }
- return false;
-}
-
-bool fixMmapAddr(void **Addr, SIZE_T Size, int Flags) {
- if (*Addr) {
- if (!liesWithinSingleAppRegion((uptr)*Addr, Size)) {
- VPrintf(1, "mmap conflict: [%p-%p) is not in an app region\n",
- *Addr, (uptr)*Addr + Size);
- if (Flags & MAP_FIXED) {
- errno = EINVAL;
- return false;
- } else {
- *Addr = 0;
- }
- }
- }
- return true;
-}
-
-uptr checkMmapResult(uptr Addr, SIZE_T Size) {
- if ((void *)Addr == MAP_FAILED)
- return Addr;
- if (!liesWithinSingleAppRegion(Addr, Size)) {
- // FIXME: attempt to dynamically add this as an app region if it
- // fits our shadow criteria.
- // We could also try to remap somewhere else.
- Printf("ERROR: unsupported mapping at [%p-%p)\n", Addr, Addr+Size);
- Die();
- }
- return Addr;
-}
-
-} // namespace __esan
-
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
diff --git a/compiler-rt/lib/esan/esan_shadow.h b/compiler-rt/lib/esan/esan_shadow.h
deleted file mode 100644
index e79e9f88c1a..00000000000
--- a/compiler-rt/lib/esan/esan_shadow.h
+++ /dev/null
@@ -1,291 +0,0 @@
-//===-- esan_shadow.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Shadow memory mappings for the esan run-time.
-//===----------------------------------------------------------------------===//
-
-#ifndef ESAN_SHADOW_H
-#define ESAN_SHADOW_H
-
-#include "esan.h"
-#include <sanitizer_common/sanitizer_platform.h>
-
-#if SANITIZER_WORDSIZE != 64
-#error Only 64-bit is supported
-#endif
-
-namespace __esan {
-
-struct ApplicationRegion {
- uptr Start;
- uptr End;
- bool ShadowMergedWithPrev;
-};
-
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && defined(__x86_64__)
-// Linux x86_64
-//
-// Application memory falls into these 5 regions (ignoring the corner case
-// of PIE with a non-zero PT_LOAD base):
-//
-// [0x00000000'00000000, 0x00000100'00000000) non-PIE + heap
-// [0x00005500'00000000, 0x00005700'00000000) PIE
-// [0x00007e00'00000000, 0x00007fff'ff600000) libraries + stack, part 1
-// [0x00007fff'ff601000, 0x00008000'00000000) libraries + stack, part 2
-// [0xffffffff'ff600000, 0xffffffff'ff601000) vsyscall
-//
-// Although we can ignore the vsyscall for the most part as there are few data
-// references there (other sanitizers ignore it), we enforce a gap inside the
-// library region to distinguish the vsyscall's shadow, considering this gap to
-// be an invalid app region.
-// We disallow application memory outside of those 5 regions.
-// Our regions assume that the stack rlimit is less than a terabyte (otherwise
-// the Linux kernel's default mmap region drops below 0x7e00'), which we enforce
-// at init time (we can support larger and unlimited sizes for shadow
-// scaledowns, but it is difficult for 1:1 mappings).
-//
-// Our shadow memory is scaled from a 1:1 mapping and supports a scale
-// specified at library initialization time that can be any power-of-2
-// scaledown (1x, 2x, 4x, 8x, 16x, etc.).
-//
-// We model our shadow memory after Umbra, a library used by the Dr. Memory
-// tool: https://github.com/DynamoRIO/drmemory/blob/master/umbra/umbra_x64.c.
-// We use Umbra's scheme as it was designed to support different
-// offsets, it supports two different shadow mappings (which we may want to
-// use for future tools), and it ensures that the shadow of a shadow will
-// not overlap either shadow memory or application memory.
-//
-// This formula translates from application memory to shadow memory:
-//
-// shadow(app) = ((app & 0x00000fff'ffffffff) + offset) >> scale
-//
-// Where the offset for 1:1 is 0x00001300'00000000. For other scales, the
-// offset is shifted left by the scale, except for scales of 1 and 2 where
-// it must be tweaked in order to pass the double-shadow test
-// (see the "shadow(shadow)" comments below):
-// scale == 0: 0x00001300'000000000
-// scale == 1: 0x00002200'000000000
-// scale == 2: 0x00004400'000000000
-// scale >= 3: (0x00001300'000000000 << scale)
-//
-// Do not pass in the open-ended end value to the formula as it will fail.
-//
-// The resulting shadow memory regions for a 0 scaling are:
-//
-// [0x00001300'00000000, 0x00001400'00000000)
-// [0x00001800'00000000, 0x00001a00'00000000)
-// [0x00002100'00000000, 0x000022ff'ff600000)
-// [0x000022ff'ff601000, 0x00002300'00000000)
-// [0x000022ff'ff600000, 0x000022ff'ff601000]
-//
-// We also want to ensure that a wild access by the application into the shadow
-// regions will not corrupt our own shadow memory. shadow(shadow) ends up
-// disjoint from shadow(app):
-//
-// [0x00001600'00000000, 0x00001700'00000000)
-// [0x00001b00'00000000, 0x00001d00'00000000)
-// [0x00001400'00000000, 0x000015ff'ff600000]
-// [0x000015ff'ff601000, 0x00001600'00000000]
-// [0x000015ff'ff600000, 0x000015ff'ff601000]
-
-static const struct ApplicationRegion AppRegions[] = {
- {0x0000000000000000ull, 0x0000010000000000u, false},
- {0x0000550000000000u, 0x0000570000000000u, false},
- // We make one shadow mapping to hold the shadow regions for all 3 of these
- // app regions, as the mappings interleave, and the gap between the 3rd and
- // 4th scales down below a page.
- {0x00007e0000000000u, 0x00007fffff600000u, false},
- {0x00007fffff601000u, 0x0000800000000000u, true},
- {0xffffffffff600000u, 0xffffffffff601000u, true},
-};
-
-#elif SANITIZER_LINUX && SANITIZER_MIPS64
-
-// Application memory falls into these 3 regions
-//
-// [0x00000001'00000000, 0x00000002'00000000) non-PIE + heap
-// [0x000000aa'00000000, 0x000000ab'00000000) PIE
-// [0x000000ff'00000000, 0x000000ff'ffffffff) libraries + stack
-//
-// This formula translates from application memory to shadow memory:
-//
-// shadow(app) = ((app & 0x00000f'ffffffff) + offset) >> scale
-//
-// Where the offset for 1:1 is 0x000013'00000000. For other scales, the
-// offset is shifted left by the scale, except for scales of 1 and 2 where
-// it must be tweaked in order to pass the double-shadow test
-// (see the "shadow(shadow)" comments below):
-// scale == 0: 0x000013'00000000
-// scale == 1: 0x000022'00000000
-// scale == 2: 0x000044'00000000
-// scale >= 3: (0x000013'00000000 << scale)
-//
-// The resulting shadow memory regions for a 0 scaling are:
-//
-// [0x00000014'00000000, 0x00000015'00000000)
-// [0x0000001d'00000000, 0x0000001e'00000000)
-// [0x00000022'00000000, 0x00000022'ffffffff)
-//
-// We also want to ensure that a wild access by the application into the shadow
-// regions will not corrupt our own shadow memory. shadow(shadow) ends up
-// disjoint from shadow(app):
-//
-// [0x00000017'00000000, 0x00000018'00000000)
-// [0x00000020'00000000, 0x00000021'00000000)
-// [0x00000015'00000000, 0x00000015'ffffffff]
-
-static const struct ApplicationRegion AppRegions[] = {
- {0x0100000000u, 0x0200000000u, false},
- {0xaa00000000u, 0xab00000000u, false},
- {0xff00000000u, 0xffffffffffu, false},
-};
-
-#else
-#error Platform not supported
-#endif
-
-static const u32 NumAppRegions = sizeof(AppRegions)/sizeof(AppRegions[0]);
-
-// See the comment above: we do not currently support a stack size rlimit
-// equal to or larger than 1TB.
-static const uptr MaxStackSize = (1ULL << 40) - 4096;
-
-class ShadowMapping {
-public:
-
- // The scale and offset vary by tool.
- uptr Scale;
- uptr Offset;
-
- // TODO(sagar.thakur): Try to hardcode the mask as done in the compiler
- // instrumentation to reduce the runtime cost of appToShadow.
- struct ShadowMemoryMask40 {
- static const uptr Mask = 0x0000000fffffffffu;
- };
-
- struct ShadowMemoryMask47 {
- static const uptr Mask = 0x00000fffffffffffu;
- };
-
- void initialize(uptr ShadowScale) {
-
- const uptr OffsetArray40[3] = {
- 0x0000001300000000u,
- 0x0000002200000000u,
- 0x0000004400000000u,
- };
-
- const uptr OffsetArray47[3] = {
- 0x0000130000000000u,
- 0x0000220000000000u,
- 0x0000440000000000u,
- };
-
- Scale = ShadowScale;
- switch (VmaSize) {
- case 40: {
- if (Scale <= 2)
- Offset = OffsetArray40[Scale];
- else
- Offset = OffsetArray40[0] << Scale;
- }
- break;
- case 47: {
- if (Scale <= 2)
- Offset = OffsetArray47[Scale];
- else
- Offset = OffsetArray47[0] << Scale;
- }
- break;
- default: {
- Printf("ERROR: %d-bit virtual memory address size not supported\n", VmaSize);
- Die();
- }
- }
- }
-};
-extern ShadowMapping Mapping;
-
-static inline bool getAppRegion(u32 i, uptr *Start, uptr *End) {
- if (i >= NumAppRegions)
- return false;
- *Start = AppRegions[i].Start;
- *End = AppRegions[i].End;
- return true;
-}
-
-ALWAYS_INLINE
-bool isAppMem(uptr Mem) {
- for (u32 i = 0; i < NumAppRegions; ++i) {
- if (Mem >= AppRegions[i].Start && Mem < AppRegions[i].End)
- return true;
- }
- return false;
-}
-
-template<typename Params>
-uptr appToShadowImpl(uptr App) {
- return (((App & Params::Mask) + Mapping.Offset) >> Mapping.Scale);
-}
-
-ALWAYS_INLINE
-uptr appToShadow(uptr App) {
- switch (VmaSize) {
- case 40: return appToShadowImpl<ShadowMapping::ShadowMemoryMask40>(App);
- case 47: return appToShadowImpl<ShadowMapping::ShadowMemoryMask47>(App);
- default: {
- Printf("ERROR: %d-bit virtual memory address size not supported\n", VmaSize);
- Die();
- }
- }
-}
-
-static inline bool getShadowRegion(u32 i, uptr *Start, uptr *End) {
- if (i >= NumAppRegions)
- return false;
- u32 UnmergedShadowCount = 0;
- u32 AppIdx;
- for (AppIdx = 0; AppIdx < NumAppRegions; ++AppIdx) {
- if (!AppRegions[AppIdx].ShadowMergedWithPrev) {
- if (UnmergedShadowCount == i)
- break;
- UnmergedShadowCount++;
- }
- }
- if (AppIdx >= NumAppRegions || UnmergedShadowCount != i)
- return false;
- *Start = appToShadow(AppRegions[AppIdx].Start);
- // The formula fails for the end itself.
- *End = appToShadow(AppRegions[AppIdx].End - 1) + 1;
- // Merge with adjacent shadow regions:
- for (++AppIdx; AppIdx < NumAppRegions; ++AppIdx) {
- if (!AppRegions[AppIdx].ShadowMergedWithPrev)
- break;
- *Start = Min(*Start, appToShadow(AppRegions[AppIdx].Start));
- *End = Max(*End, appToShadow(AppRegions[AppIdx].End - 1) + 1);
- }
- return true;
-}
-
-ALWAYS_INLINE
-bool isShadowMem(uptr Mem) {
- // We assume this is not used on any critical performance path and so there's
- // no need to hardcode the mapping results.
- for (uptr i = 0; i < NumAppRegions; ++i) {
- if (Mem >= appToShadow(AppRegions[i].Start) &&
- Mem < appToShadow(AppRegions[i].End - 1) + 1)
- return true;
- }
- return false;
-}
-
-} // namespace __esan
-
-#endif /* ESAN_SHADOW_H */
diff --git a/compiler-rt/lib/esan/esan_sideline.h b/compiler-rt/lib/esan/esan_sideline.h
deleted file mode 100644
index 2dde57bda6c..00000000000
--- a/compiler-rt/lib/esan/esan_sideline.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- esan_sideline.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Esan sideline thread support.
-//===----------------------------------------------------------------------===//
-
-#ifndef ESAN_SIDELINE_H
-#define ESAN_SIDELINE_H
-
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_platform_limits_freebsd.h"
-#include "sanitizer_common/sanitizer_platform_limits_posix.h"
-
-namespace __esan {
-
-typedef void (*SidelineFunc)(void *Arg);
-
-// Currently only one sideline thread is supported.
-// It calls the SidelineFunc passed to launchThread once on each sample at the
-// given frequency in real time (i.e., wall clock time).
-class SidelineThread {
-public:
- // We cannot initialize any fields in the constructor as it will be called
- // *after* launchThread for a static instance, as esan.module_ctor is called
- // before static initializers.
- SidelineThread() {}
- ~SidelineThread() {}
-
- // To simplify declaration in sanitizer code where we want to avoid
- // heap allocations, the constructor and destructor do nothing and
- // launchThread and joinThread do the real work.
- // They should each be called just once.
- bool launchThread(SidelineFunc takeSample, void *Arg, u32 FreqMilliSec);
- bool joinThread();
-
- // Must be called from the sideline thread itself.
- bool adjustTimer(u32 FreqMilliSec);
-
-private:
- static int runSideline(void *Arg);
- static void registerSignal(int SigNum);
- static void handleSidelineSignal(int SigNum, __sanitizer_siginfo *SigInfo,
- void *Ctx);
-
- char *Stack;
- SidelineFunc sampleFunc;
- void *FuncArg;
- u32 Freq;
- uptr SidelineId;
- atomic_uintptr_t SidelineExit;
-};
-
-} // namespace __esan
-
-#endif // ESAN_SIDELINE_H
diff --git a/compiler-rt/lib/esan/esan_sideline_bsd.cpp b/compiler-rt/lib/esan/esan_sideline_bsd.cpp
deleted file mode 100644
index 7c20ae31db2..00000000000
--- a/compiler-rt/lib/esan/esan_sideline_bsd.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- esan_sideline_bsd.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Support for a separate or "sideline" tool thread on FreeBSD.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_FREEBSD
-
-#include "esan_sideline.h"
-
-namespace __esan {
-
-static SidelineThread *TheThread;
-
-bool SidelineThread::launchThread(SidelineFunc takeSample, void *Arg,
- u32 FreqMilliSec) {
- return true;
-}
-
-bool SidelineThread::joinThread() {
- return true;
-}
-
-} // namespace __esan
-
-#endif // SANITIZER_FREEBSD
diff --git a/compiler-rt/lib/esan/esan_sideline_linux.cpp b/compiler-rt/lib/esan/esan_sideline_linux.cpp
deleted file mode 100644
index a9845436687..00000000000
--- a/compiler-rt/lib/esan/esan_sideline_linux.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-//===-- esan_sideline_linux.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Support for a separate or "sideline" tool thread on Linux.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_LINUX
-
-#include "esan_sideline.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_linux.h"
-#include <errno.h>
-#include <sched.h>
-#include <sys/prctl.h>
-#include <sys/signal.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-namespace __esan {
-
-static const int SigAltStackSize = 4*1024;
-static const int SidelineStackSize = 4*1024;
-static const uptr SidelineIdUninitialized = 1;
-
-// FIXME: we'll need some kind of TLS (can we trust that a pthread key will
-// work in our non-POSIX thread?) to access our data in our signal handler
-// with multiple sideline threads. For now we assume there is only one
-// sideline thread and we use a dirty solution of a global var.
-static SidelineThread *TheThread;
-
-// We aren't passing SA_NODEFER so the same signal is blocked while here.
-void SidelineThread::handleSidelineSignal(int SigNum,
- __sanitizer_siginfo *SigInfo,
- void *Ctx) {
- VPrintf(3, "Sideline signal %d\n", SigNum);
- CHECK_EQ(SigNum, SIGALRM);
- // See above about needing TLS to avoid this global var.
- SidelineThread *Thread = TheThread;
- if (atomic_load(&Thread->SidelineExit, memory_order_relaxed) != 0)
- return;
- Thread->sampleFunc(Thread->FuncArg);
-}
-
-void SidelineThread::registerSignal(int SigNum) {
- __sanitizer_sigaction SigAct;
- internal_memset(&SigAct, 0, sizeof(SigAct));
- SigAct.sigaction = handleSidelineSignal;
- // We do not pass SA_NODEFER as we want to block the same signal.
- SigAct.sa_flags = SA_ONSTACK | SA_SIGINFO;
- int Res = internal_sigaction(SigNum, &SigAct, nullptr);
- CHECK_EQ(Res, 0);
-}
-
-int SidelineThread::runSideline(void *Arg) {
- VPrintf(1, "Sideline thread starting\n");
- SidelineThread *Thread = static_cast<SidelineThread*>(Arg);
-
- // If the parent dies, we want to exit also.
- internal_prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
-
- // Set up a signal handler on an alternate stack for safety.
- InternalMmapVector<char> StackMap(SigAltStackSize);
- stack_t SigAltStack;
- SigAltStack.ss_sp = StackMap.data();
- SigAltStack.ss_size = SigAltStackSize;
- SigAltStack.ss_flags = 0;
- internal_sigaltstack(&SigAltStack, nullptr);
-
- // We inherit the signal mask from the app thread. In case
- // we weren't created at init time, we ensure the mask is empty.
- __sanitizer_sigset_t SigSet;
- internal_sigfillset(&SigSet);
- int Res = internal_sigprocmask(SIG_UNBLOCK, &SigSet, nullptr);
- CHECK_EQ(Res, 0);
-
- registerSignal(SIGALRM);
-
- bool TimerSuccess = Thread->adjustTimer(Thread->Freq);
- CHECK(TimerSuccess);
-
- // We loop, doing nothing but handling itimer signals.
- while (atomic_load(&TheThread->SidelineExit, memory_order_relaxed) == 0)
- sched_yield();
-
- if (!Thread->adjustTimer(0))
- VPrintf(1, "Failed to disable timer\n");
-
- VPrintf(1, "Sideline thread exiting\n");
- return 0;
-}
-
-bool SidelineThread::launchThread(SidelineFunc takeSample, void *Arg,
- u32 FreqMilliSec) {
- // This can only be called once. However, we can't clear a field in
- // the constructor and check for that here as the constructor for
- // a static instance is called *after* our module_ctor and thus after
- // this routine! Thus we rely on the TheThread check below.
- CHECK(TheThread == nullptr); // Only one sideline thread is supported.
- TheThread = this;
- sampleFunc = takeSample;
- FuncArg = Arg;
- Freq = FreqMilliSec;
- atomic_store(&SidelineExit, 0, memory_order_relaxed);
-
- // We do without a guard page.
- Stack = static_cast<char*>(MmapOrDie(SidelineStackSize, "SidelineStack"));
- // We need to handle the return value from internal_clone() not having been
- // assigned yet (for our CHECK in adjustTimer()) so we ensure this has a
- // sentinel value.
- SidelineId = SidelineIdUninitialized;
- // By omitting CLONE_THREAD, the child is in its own thread group and will not
- // receive any of the application's signals.
- SidelineId = internal_clone(
- runSideline, Stack + SidelineStackSize,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_UNTRACED,
- this, nullptr /* parent_tidptr */,
- nullptr /* newtls */, nullptr /* child_tidptr */);
- int ErrCode;
- if (internal_iserror(SidelineId, &ErrCode)) {
- Printf("FATAL: EfficiencySanitizer failed to spawn a thread (code %d).\n",
- ErrCode);
- Die();
- return false; // Not reached.
- }
- return true;
-}
-
-bool SidelineThread::joinThread() {
- VPrintf(1, "Joining sideline thread\n");
- bool Res = true;
- atomic_store(&SidelineExit, 1, memory_order_relaxed);
- while (true) {
- uptr Status = internal_waitpid(SidelineId, nullptr, __WALL);
- int ErrCode;
- if (!internal_iserror(Status, &ErrCode))
- break;
- if (ErrCode == EINTR)
- continue;
- VPrintf(1, "Failed to join sideline thread (errno %d)\n", ErrCode);
- Res = false;
- break;
- }
- UnmapOrDie(Stack, SidelineStackSize);
- return Res;
-}
-
-// Must be called from the sideline thread itself.
-bool SidelineThread::adjustTimer(u32 FreqMilliSec) {
- // The return value of internal_clone() may not have been assigned yet:
- CHECK(internal_getpid() == SidelineId ||
- SidelineId == SidelineIdUninitialized);
- Freq = FreqMilliSec;
- struct itimerval TimerVal;
- TimerVal.it_interval.tv_sec = (time_t) Freq / 1000;
- TimerVal.it_interval.tv_usec = (time_t) (Freq % 1000) * 1000;
- TimerVal.it_value.tv_sec = (time_t) Freq / 1000;
- TimerVal.it_value.tv_usec = (time_t) (Freq % 1000) * 1000;
- // As we're in a different thread group, we cannot use either
- // ITIMER_PROF or ITIMER_VIRTUAL without taking up scheduled
- // time ourselves: thus we must use real time.
- int Res = setitimer(ITIMER_REAL, &TimerVal, nullptr);
- return (Res == 0);
-}
-
-} // namespace __esan
-
-#endif // SANITIZER_LINUX
diff --git a/compiler-rt/lib/esan/working_set.cpp b/compiler-rt/lib/esan/working_set.cpp
deleted file mode 100644
index 8361a081502..00000000000
--- a/compiler-rt/lib/esan/working_set.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-//===-- working_set.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 EfficiencySanitizer, a family of performance tuners.
-//
-// This file contains working-set-specific code.
-//===----------------------------------------------------------------------===//
-
-#include "working_set.h"
-#include "esan.h"
-#include "esan_circular_buffer.h"
-#include "esan_flags.h"
-#include "esan_shadow.h"
-#include "esan_sideline.h"
-#include "sanitizer_common/sanitizer_procmaps.h"
-
-// We shadow every cache line of app memory with one shadow byte.
-// - The highest bit of each shadow byte indicates whether the corresponding
-// cache line has ever been accessed.
-// - The lowest bit of each shadow byte indicates whether the corresponding
-// cache line was accessed since the last sample.
-// - The other bits are used for working set snapshots at successively
-// lower frequencies, each bit to the left from the lowest bit stepping
-// down the frequency by 2 to the power of getFlags()->snapshot_step.
-// Thus we have something like this:
-// Bit 0: Since last sample
-// Bit 1: Since last 2^2 samples
-// Bit 2: Since last 2^4 samples
-// Bit 3: ...
-// Bit 7: Ever accessed.
-// We live with races in accessing each shadow byte.
-typedef unsigned char byte;
-
-namespace __esan {
-
-// Our shadow memory assumes that the line size is 64.
-static const u32 CacheLineSize = 64;
-
-// See the shadow byte layout description above.
-static const u32 TotalWorkingSetBitIdx = 7;
-// We accumulate to the left until we hit this bit.
-// We don't need to accumulate to the final bit as it's set on each ref
-// by the compiler instrumentation.
-static const u32 MaxAccumBitIdx = 6;
-static const u32 CurWorkingSetBitIdx = 0;
-static const byte ShadowAccessedVal =
- (1 << TotalWorkingSetBitIdx) | (1 << CurWorkingSetBitIdx);
-
-static SidelineThread Thread;
-// If we use real-time-based timer samples this won't overflow in any realistic
-// scenario, but if we switch to some other unit (such as memory accesses) we
-// may want to consider a 64-bit int.
-static u32 SnapshotNum;
-
-// We store the wset size for each of 8 different sampling frequencies.
-static const u32 NumFreq = 8; // One for each bit of our shadow bytes.
-// We cannot use static objects as the global destructor is called
-// prior to our finalize routine.
-// These are each circular buffers, sized up front.
-CircularBuffer<u32> SizePerFreq[NumFreq];
-// We cannot rely on static initializers (they may run too late) but
-// we record the size here for clarity:
-u32 CircularBufferSizes[NumFreq] = {
- // These are each mmap-ed so our minimum is one page.
- 32*1024,
- 16*1024,
- 8*1024,
- 4*1024,
- 4*1024,
- 4*1024,
- 4*1024,
- 4*1024,
-};
-
-void processRangeAccessWorkingSet(uptr PC, uptr Addr, SIZE_T Size,
- bool IsWrite) {
- if (Size == 0)
- return;
- SIZE_T I = 0;
- uptr LineSize = getFlags()->cache_line_size;
- // As Addr+Size could overflow at the top of a 32-bit address space,
- // we avoid the simpler formula that rounds the start and end.
- SIZE_T NumLines = Size / LineSize +
- // Add any extra at the start or end adding on an extra line:
- (LineSize - 1 + Addr % LineSize + Size % LineSize) / LineSize;
- byte *Shadow = (byte *)appToShadow(Addr);
- // Write shadow bytes until we're word-aligned.
- while (I < NumLines && (uptr)Shadow % 4 != 0) {
- if ((*Shadow & ShadowAccessedVal) != ShadowAccessedVal)
- *Shadow |= ShadowAccessedVal;
- ++Shadow;
- ++I;
- }
- // Write whole shadow words at a time.
- // Using a word-stride loop improves the runtime of a microbenchmark of
- // memset calls by 10%.
- u32 WordValue = ShadowAccessedVal | ShadowAccessedVal << 8 |
- ShadowAccessedVal << 16 | ShadowAccessedVal << 24;
- while (I + 4 <= NumLines) {
- if ((*(u32*)Shadow & WordValue) != WordValue)
- *(u32*)Shadow |= WordValue;
- Shadow += 4;
- I += 4;
- }
- // Write any trailing shadow bytes.
- while (I < NumLines) {
- if ((*Shadow & ShadowAccessedVal) != ShadowAccessedVal)
- *Shadow |= ShadowAccessedVal;
- ++Shadow;
- ++I;
- }
-}
-
-// This routine will word-align ShadowStart and ShadowEnd prior to scanning.
-// It does *not* clear for BitIdx==TotalWorkingSetBitIdx, as that top bit
-// measures the access during the entire execution and should never be cleared.
-static u32 countAndClearShadowValues(u32 BitIdx, uptr ShadowStart,
- uptr ShadowEnd) {
- u32 WorkingSetSize = 0;
- u32 ByteValue = 0x1 << BitIdx;
- u32 WordValue = ByteValue | ByteValue << 8 | ByteValue << 16 |
- ByteValue << 24;
- // Get word aligned start.
- ShadowStart = RoundDownTo(ShadowStart, sizeof(u32));
- bool Accum = getFlags()->record_snapshots && BitIdx < MaxAccumBitIdx;
- // Do not clear the bit that measures access during the entire execution.
- bool Clear = BitIdx < TotalWorkingSetBitIdx;
- for (u32 *Ptr = (u32 *)ShadowStart; Ptr < (u32 *)ShadowEnd; ++Ptr) {
- if ((*Ptr & WordValue) != 0) {
- byte *BytePtr = (byte *)Ptr;
- for (u32 j = 0; j < sizeof(u32); ++j) {
- if (BytePtr[j] & ByteValue) {
- ++WorkingSetSize;
- if (Accum) {
- // Accumulate to the lower-frequency bit to the left.
- BytePtr[j] |= (ByteValue << 1);
- }
- }
- }
- if (Clear) {
- // Clear this bit from every shadow byte.
- *Ptr &= ~WordValue;
- }
- }
- }
- return WorkingSetSize;
-}
-
-// Scan shadow memory to calculate the number of cache lines being accessed,
-// i.e., the number of non-zero bits indexed by BitIdx in each shadow byte.
-// We also clear the lowest bits (most recent working set snapshot).
-// We do *not* clear for BitIdx==TotalWorkingSetBitIdx, as that top bit
-// measures the access during the entire execution and should never be cleared.
-static u32 computeWorkingSizeAndReset(u32 BitIdx) {
- u32 WorkingSetSize = 0;
- MemoryMappingLayout MemIter(true/*cache*/);
- MemoryMappedSegment Segment;
- while (MemIter.Next(&Segment)) {
- VPrintf(4, "%s: considering %p-%p app=%d shadow=%d prot=%u\n", __FUNCTION__,
- Segment.start, Segment.end, Segment.protection,
- isAppMem(Segment.start), isShadowMem(Segment.start));
- if (isShadowMem(Segment.start) && Segment.IsWritable()) {
- VPrintf(3, "%s: walking %p-%p\n", __FUNCTION__, Segment.start,
- Segment.end);
- WorkingSetSize +=
- countAndClearShadowValues(BitIdx, Segment.start, Segment.end);
- }
- }
- return WorkingSetSize;
-}
-
-// This is invoked from a signal handler but in a sideline thread doing nothing
-// else so it is a little less fragile than a typical signal handler.
-static void takeSample(void *Arg) {
- u32 BitIdx = CurWorkingSetBitIdx;
- u32 Freq = 1;
- ++SnapshotNum; // Simpler to skip 0 whose mod matches everything.
- while (BitIdx <= MaxAccumBitIdx && (SnapshotNum % Freq) == 0) {
- u32 NumLines = computeWorkingSizeAndReset(BitIdx);
- VReport(1, "%s: snapshot #%5d bit %d freq %4d: %8u\n", SanitizerToolName,
- SnapshotNum, BitIdx, Freq, NumLines);
- SizePerFreq[BitIdx].push_back(NumLines);
- Freq = Freq << getFlags()->snapshot_step;
- BitIdx++;
- }
-}
-
-unsigned int getSampleCountWorkingSet()
-{
- return SnapshotNum;
-}
-
-// Initialization that must be done before any instrumented code is executed.
-void initializeShadowWorkingSet() {
- CHECK(getFlags()->cache_line_size == CacheLineSize);
- registerMemoryFaultHandler();
-}
-
-void initializeWorkingSet() {
- if (getFlags()->record_snapshots) {
- for (u32 i = 0; i < NumFreq; ++i)
- SizePerFreq[i].initialize(CircularBufferSizes[i]);
- Thread.launchThread(takeSample, nullptr, getFlags()->sample_freq);
- }
-}
-
-static u32 getPeriodForPrinting(u32 MilliSec, const char *&Unit) {
- if (MilliSec > 600000) {
- Unit = "min";
- return MilliSec / 60000;
- } else if (MilliSec > 10000) {
- Unit = "sec";
- return MilliSec / 1000;
- } else {
- Unit = "ms";
- return MilliSec;
- }
-}
-
-static u32 getSizeForPrinting(u32 NumOfCachelines, const char *&Unit) {
- // We need a constant to avoid software divide support:
- static const u32 KilobyteCachelines = (0x1 << 10) / CacheLineSize;
- static const u32 MegabyteCachelines = KilobyteCachelines << 10;
-
- if (NumOfCachelines > 10 * MegabyteCachelines) {
- Unit = "MB";
- return NumOfCachelines / MegabyteCachelines;
- } else if (NumOfCachelines > 10 * KilobyteCachelines) {
- Unit = "KB";
- return NumOfCachelines / KilobyteCachelines;
- } else {
- Unit = "Bytes";
- return NumOfCachelines * CacheLineSize;
- }
-}
-
-void reportWorkingSet() {
- const char *Unit;
- if (getFlags()->record_snapshots) {
- u32 Freq = 1;
- Report(" Total number of samples: %u\n", SnapshotNum);
- for (u32 i = 0; i < NumFreq; ++i) {
- u32 Time = getPeriodForPrinting(getFlags()->sample_freq*Freq, Unit);
- Report(" Samples array #%d at period %u %s\n", i, Time, Unit);
- // FIXME: report whether we wrapped around and thus whether we
- // have data on the whole run or just the last N samples.
- for (u32 j = 0; j < SizePerFreq[i].size(); ++j) {
- u32 Size = getSizeForPrinting(SizePerFreq[i][j], Unit);
- Report("#%4d: %8u %s (%9u cache lines)\n", j, Size, Unit,
- SizePerFreq[i][j]);
- }
- Freq = Freq << getFlags()->snapshot_step;
- }
- }
-
- // Get the working set size for the entire execution.
- u32 NumOfCachelines = computeWorkingSizeAndReset(TotalWorkingSetBitIdx);
- u32 Size = getSizeForPrinting(NumOfCachelines, Unit);
- Report(" %s: the total working set size: %u %s (%u cache lines)\n",
- SanitizerToolName, Size, Unit, NumOfCachelines);
-}
-
-int finalizeWorkingSet() {
- if (getFlags()->record_snapshots)
- Thread.joinThread();
- reportWorkingSet();
- if (getFlags()->record_snapshots) {
- for (u32 i = 0; i < NumFreq; ++i)
- SizePerFreq[i].free();
- }
- return 0;
-}
-
-} // namespace __esan
diff --git a/compiler-rt/lib/esan/working_set.h b/compiler-rt/lib/esan/working_set.h
deleted file mode 100644
index 83b360e07e6..00000000000
--- a/compiler-rt/lib/esan/working_set.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- working_set.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 EfficiencySanitizer, a family of performance tuners.
-//
-// Header for working-set-specific code.
-//===----------------------------------------------------------------------===//
-
-#ifndef WORKING_SET_H
-#define WORKING_SET_H
-
-#include "interception/interception.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-
-namespace __esan {
-
-void initializeWorkingSet();
-void initializeShadowWorkingSet();
-int finalizeWorkingSet();
-void reportWorkingSet();
-unsigned int getSampleCountWorkingSet();
-void processRangeAccessWorkingSet(uptr PC, uptr Addr, SIZE_T Size,
- bool IsWrite);
-
-// Platform-dependent.
-void registerMemoryFaultHandler();
-bool processWorkingSetSignal(int SigNum, void (*Handler)(int),
- void (**Result)(int));
-bool processWorkingSetSigaction(int SigNum, const void *Act, void *OldAct);
-bool processWorkingSetSigprocmask(int How, void *Set, void *OldSet);
-
-} // namespace __esan
-
-#endif // WORKING_SET_H
diff --git a/compiler-rt/lib/esan/working_set_posix.cpp b/compiler-rt/lib/esan/working_set_posix.cpp
deleted file mode 100644
index b3f42d31d87..00000000000
--- a/compiler-rt/lib/esan/working_set_posix.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-//===-- working_set_posix.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 EfficiencySanitizer, a family of performance tuners.
-//
-// POSIX-specific working set tool code.
-//===----------------------------------------------------------------------===//
-
-#include "working_set.h"
-#include "esan_flags.h"
-#include "esan_shadow.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_linux.h"
-#include <signal.h>
-#include <sys/mman.h>
-
-namespace __esan {
-
-// We only support regular POSIX threads with a single signal handler
-// for the whole process == thread group.
-// Thus we only need to store one app signal handler.
-// FIXME: Store and use any alternate stack and signal flags set by
-// the app. For now we just call the app handler from our handler.
-static __sanitizer_sigaction AppSigAct;
-
-bool processWorkingSetSignal(int SigNum, void (*Handler)(int),
- void (**Result)(int)) {
- VPrintf(2, "%s: %d\n", __FUNCTION__, SigNum);
- if (SigNum == SIGSEGV) {
- *Result = AppSigAct.handler;
- AppSigAct.sigaction = (decltype(AppSigAct.sigaction))Handler;
- return false; // Skip real call.
- }
- return true;
-}
-
-bool processWorkingSetSigaction(int SigNum, const void *ActVoid,
- void *OldActVoid) {
- VPrintf(2, "%s: %d\n", __FUNCTION__, SigNum);
- if (SigNum == SIGSEGV) {
- const struct sigaction *Act = (const struct sigaction *) ActVoid;
- struct sigaction *OldAct = (struct sigaction *) OldActVoid;
- if (OldAct)
- internal_memcpy(OldAct, &AppSigAct, sizeof(OldAct));
- if (Act)
- internal_memcpy(&AppSigAct, Act, sizeof(AppSigAct));
- return false; // Skip real call.
- }
- return true;
-}
-
-bool processWorkingSetSigprocmask(int How, void *Set, void *OldSet) {
- VPrintf(2, "%s\n", __FUNCTION__);
- // All we need to do is ensure that SIGSEGV is not blocked.
- // FIXME: we are not fully transparent as we do not pretend that
- // SIGSEGV is still blocked on app queries: that would require
- // per-thread mask tracking.
- if (Set && (How == SIG_BLOCK || How == SIG_SETMASK)) {
- if (internal_sigismember((__sanitizer_sigset_t *)Set, SIGSEGV)) {
- VPrintf(1, "%s: removing SIGSEGV from the blocked set\n", __FUNCTION__);
- internal_sigdelset((__sanitizer_sigset_t *)Set, SIGSEGV);
- }
- }
- return true;
-}
-
-static void reinstateDefaultHandler(int SigNum) {
- __sanitizer_sigaction SigAct;
- internal_memset(&SigAct, 0, sizeof(SigAct));
- SigAct.sigaction = (decltype(SigAct.sigaction))SIG_DFL;
- int Res = internal_sigaction(SigNum, &SigAct, nullptr);
- CHECK(Res == 0);
- VPrintf(1, "Unregistered for %d handler\n", SigNum);
-}
-
-// If this is a shadow fault, we handle it here; otherwise, we pass it to the
-// app to handle it just as the app would do without our tool in place.
-static void handleMemoryFault(int SigNum, __sanitizer_siginfo *Info,
- void *Ctx) {
- if (SigNum == SIGSEGV) {
- // We rely on si_addr being filled in (thus we do not support old kernels).
- siginfo_t *SigInfo = (siginfo_t *)Info;
- uptr Addr = (uptr)SigInfo->si_addr;
- if (isShadowMem(Addr)) {
- VPrintf(3, "Shadow fault @%p\n", Addr);
- uptr PageSize = GetPageSizeCached();
- int Res = internal_mprotect((void *)RoundDownTo(Addr, PageSize),
- PageSize, PROT_READ|PROT_WRITE);
- CHECK(Res == 0);
- } else if (AppSigAct.sigaction) {
- // FIXME: For simplicity we ignore app options including its signal stack
- // (we just use ours) and all the delivery flags.
- AppSigAct.sigaction(SigNum, Info, Ctx);
- } else {
- // Crash instead of spinning with infinite faults.
- reinstateDefaultHandler(SigNum);
- }
- } else
- UNREACHABLE("signal not registered");
-}
-
-void registerMemoryFaultHandler() {
- // We do not use an alternate signal stack, as doing so would require
- // setting it up for each app thread.
- // FIXME: This could result in problems with emulating the app's signal
- // handling if the app relies on an alternate stack for SIGSEGV.
-
- // We require that SIGSEGV is not blocked. We use a sigprocmask
- // interceptor to ensure that in the future. Here we ensure it for
- // the current thread. We assume there are no other threads at this
- // point during initialization, or that at least they do not block
- // SIGSEGV.
- __sanitizer_sigset_t SigSet;
- internal_sigemptyset(&SigSet);
- internal_sigprocmask(SIG_BLOCK, &SigSet, nullptr);
-
- __sanitizer_sigaction SigAct;
- internal_memset(&SigAct, 0, sizeof(SigAct));
- SigAct.sigaction = handleMemoryFault;
- // We want to handle nested signals b/c we need to handle a
- // shadow fault in an app signal handler.
- SigAct.sa_flags = SA_SIGINFO | SA_NODEFER;
- int Res = internal_sigaction(SIGSEGV, &SigAct, &AppSigAct);
- CHECK(Res == 0);
- VPrintf(1, "Registered for SIGSEGV handler\n");
-}
-
-} // namespace __esan
diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
index d3780457206..094d8293c25 100644
--- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
@@ -42,13 +42,6 @@ set(SANITIZER_SOURCES_NOTERMINATION
sanitizer_win.cc
)
-if(UNIX AND NOT APPLE AND NOT OS_NAME MATCHES "SunOS")
- list(APPEND SANITIZER_SOURCES_NOTERMINATION
- sanitizer_linux_x86_64.S)
- list(APPEND SANITIZER_SOURCES_NOTERMINATION
- sanitizer_linux_mips64.S)
-endif()
-
set(SANITIZER_SOURCES
${SANITIZER_SOURCES_NOTERMINATION} sanitizer_termination.cc)
@@ -210,19 +203,6 @@ append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=570
append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors
SANITIZER_CFLAGS)
-if (LLVM_ENABLE_PEDANTIC AND UNIX AND NOT APPLE)
- # With -pedantic, our .S files raise warnings about empty macro arguments
- # from __USER_LABEL_PREFIX__ being an empty arg to GLUE(). Unfortunately,
- # there is no simple way to test for an empty define, nor to disable just
- # that warning or to disable -pedantic. There is also no simple way to
- # remove -pedantic from just this file (we'd have to remove from
- # CMAKE_C*_FLAGS and re-add as a source property to all the non-.S files).
- set_source_files_properties(sanitizer_linux_x86_64.S
- PROPERTIES COMPILE_FLAGS "-w")
- set_source_files_properties(sanitizer_linux_mips64.S
- PROPERTIES COMPILE_FLAGS "-w")
-endif ()
-
if(APPLE)
set(OS_OPTION OS ${SANITIZER_COMMON_SUPPORTED_OS})
endif()
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 19c968e2fde..1703899e32b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -238,7 +238,6 @@ char **GetArgv();
char **GetEnviron();
void PrintCmdline();
bool StackSizeIsUnlimited();
-uptr GetStackSizeLimitInBytes();
void SetStackSizeLimitInBytes(uptr limit);
bool AddressSpaceIsUnlimited();
void SetAddressSpaceUnlimited();
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
index a4540240738..e0c6506bed5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
@@ -422,7 +422,6 @@ inline void Trap() {
namespace __asan { using namespace __sanitizer; } // NOLINT
namespace __dsan { using namespace __sanitizer; } // NOLINT
namespace __dfsan { using namespace __sanitizer; } // NOLINT
-namespace __esan { using namespace __sanitizer; } // NOLINT
namespace __lsan { using namespace __sanitizer; } // NOLINT
namespace __msan { using namespace __sanitizer; } // NOLINT
namespace __hwasan { using namespace __sanitizer; } // NOLINT
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
index 8b981fb025f..75437fd89c9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
@@ -128,12 +128,6 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
#endif
-#if defined(__x86_64__) || SANITIZER_MIPS64
-extern "C" {
-extern void internal_sigreturn();
-}
-#endif
-
// Note : FreeBSD had implemented both
// Linux and OpenBSD apis, available from
// future 12.x version most likely
@@ -837,24 +831,6 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
}
return result;
}
-
-// Invokes sigaction via a raw syscall with a restorer, but does not support
-// all platforms yet.
-// We disable for Go simply because we have not yet added to buildgo.sh.
-#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO
-int internal_sigaction_syscall(int signum, const void *act, void *oldact) {
- if (act == nullptr)
- return internal_sigaction_norestorer(signum, act, oldact);
- __sanitizer_sigaction u_adjust;
- internal_memcpy(&u_adjust, act, sizeof(u_adjust));
-#if !SANITIZER_ANDROID || !SANITIZER_MIPS32
- if (u_adjust.sa_restorer == nullptr) {
- u_adjust.sa_restorer = internal_sigreturn;
- }
-#endif
- return internal_sigaction_norestorer(signum, (const void *)&u_adjust, oldact);
-}
-#endif // defined(__x86_64__) && !SANITIZER_GO
#endif // SANITIZER_LINUX
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index 1047ee6e712..d2186ef5a53 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -58,10 +58,6 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
// (like the process-wide error reporting SEGV handler) must use
// internal_sigaction instead.
int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
-#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO
-// Uses a raw system call to avoid interceptors.
-int internal_sigaction_syscall(int signum, const void *act, void *oldact);
-#endif
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \
|| defined(__powerpc64__) || defined(__s390__) || defined(__i386__) \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_mips64.S b/compiler-rt/lib/sanitizer_common/sanitizer_linux_mips64.S
deleted file mode 100644
index ac6ff22e71c..00000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_mips64.S
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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
-
-#include "sanitizer_common/sanitizer_asm.h"
-
-// Avoid being marked as needing an executable stack:
-NO_EXEC_STACK_DIRECTIVE
-
-// Further contents are mips64 only:
-#if defined(__linux__) && defined(__mips64)
-
-.section .text
-.set noreorder
-.globl internal_sigreturn
-.type internal_sigreturn, @function
-internal_sigreturn:
-
- li $v0,5211 // #5211 is for SYS_rt_sigreturn
- syscall
-
-.size internal_sigreturn, .-internal_sigreturn
-
-#endif // defined(__linux__) && defined(__mips64)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_x86_64.S b/compiler-rt/lib/sanitizer_common/sanitizer_linux_x86_64.S
deleted file mode 100644
index d22d6d1c24f..00000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_x86_64.S
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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
-
-#include "sanitizer_common/sanitizer_asm.h"
-
-// Avoid being marked as needing an executable stack:
-NO_EXEC_STACK_DIRECTIVE
-
-// Further contents are x86_64-only:
-#if defined(__linux__) && defined(__x86_64__)
-
-#include "../builtins/assembly.h"
-
-// If the "naked" function attribute were supported for x86 we could
-// do this via inline asm.
-.text
-.balign 4
-DEFINE_COMPILERRT_FUNCTION(internal_sigreturn)
- mov $0xf, %eax // 0xf == SYS_rt_sigreturn
- mov %rcx, %r10
- syscall
- ret // Won't normally reach here.
-END_COMPILERRT_FUNCTION(internal_sigreturn)
-
-#endif // defined(__linux__) && defined(__x86_64__)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index e67343709ad..efe51ec2014 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -116,10 +116,6 @@ bool StackSizeIsUnlimited() {
return (stack_size == RLIM_INFINITY);
}
-uptr GetStackSizeLimitInBytes() {
- return (uptr)getlim(RLIMIT_STACK);
-}
-
void SetStackSizeLimitInBytes(uptr limit) {
setlim(RLIMIT_STACK, (rlim_t)limit);
CHECK(!StackSizeIsUnlimited());
diff --git a/compiler-rt/test/esan/CMakeLists.txt b/compiler-rt/test/esan/CMakeLists.txt
deleted file mode 100644
index bbdcd51af78..00000000000
--- a/compiler-rt/test/esan/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-set(ESAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
-if(NOT COMPILER_RT_STANDALONE_BUILD)
- list(APPEND ESAN_TEST_DEPS esan)
-endif()
-
-set(ESAN_TESTSUITES)
-
-set(ESAN_TEST_ARCH ${ESAN_SUPPORTED_ARCH})
-
-set(ESAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-
-foreach(arch ${ESAN_TEST_ARCH})
- set(ESAN_TEST_TARGET_ARCH ${arch})
- string(TOLOWER "-${arch}" ESAN_TEST_CONFIG_SUFFIX)
- get_target_flags_for_arch(${arch} ESAN_TEST_TARGET_CFLAGS)
- string(REPLACE ";" " " ESAN_TEST_TARGET_CFLAGS "${ESAN_TEST_TARGET_CFLAGS}")
-
- string(TOUPPER ${arch} ARCH_UPPER_CASE)
- set(CONFIG_NAME ${ARCH_UPPER_CASE}Config)
-
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
- list(APPEND ESAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
-endforeach()
-
-# TODO(bruening): add Unit/ tests as well
-
-add_lit_testsuite(check-esan "Running EfficiencySanitizer tests"
- ${ESAN_TESTSUITES}
- DEPENDS ${ESAN_TEST_DEPS})
-set_target_properties(check-esan PROPERTIES FOLDER "Compiler-RT Misc")
diff --git a/compiler-rt/test/esan/TestCases/large-stack-linux.c b/compiler-rt/test/esan/TestCases/large-stack-linux.c
deleted file mode 100644
index 17d88674ba1..00000000000
--- a/compiler-rt/test/esan/TestCases/large-stack-linux.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
-// RUN: %env_esan_opts="verbosity=1 record_snapshots=0" %run %t %t 2>&1 | FileCheck %s
-// Stucks at init and no clone feature equivalent.
-// UNSUPPORTED: freebsd
-
-#include <assert.h>
-#include <stdio.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-static void testChildStackLimit(rlim_t StackLimit, char *ToRun) {
- int Res;
- struct rlimit Limit;
- Limit.rlim_cur = RLIM_INFINITY;
- Limit.rlim_max = RLIM_INFINITY;
- Res = setrlimit(RLIMIT_STACK, &Limit);
- if (Res != 0) {
- // Probably our environment had a large limit and we ourselves got
- // re-execed and can no longer raise our limit.
- // We have to bail and emulate the regular test.
- // We'd prefer to have branches in our FileCheck output to ensure the
- // initial program was re-execed but this is the best we can do for now.
- fprintf(stderr, "in esan::initializeLibrary\n");
- fprintf(stderr, "==1234==The stack size limit is beyond the maximum supported.\n");
- fprintf(stderr, "Re-execing with a stack size below 1TB.\n");
- fprintf(stderr, "in esan::initializeLibrary\n");
- fprintf(stderr, "done\n");
- fprintf(stderr, "in esan::finalizeLibrary\n");
- return;
- }
-
- pid_t Child = fork();
- assert(Child >= 0);
- if (Child > 0) {
- pid_t WaitRes = waitpid(Child, NULL, 0);
- assert(WaitRes == Child);
- } else {
- char *Args[2];
- Args[0] = ToRun;
- Args[1] = NULL;
- Res = execv(ToRun, Args);
- assert(0); // Should not be reached.
- }
-}
-
-int main(int argc, char *argv[]) {
- // The path to the program to exec must be passed in the first time.
- if (argc == 2) {
- fprintf(stderr, "Testing child with infinite stack\n");
- testChildStackLimit(RLIM_INFINITY, argv[1]);
- fprintf(stderr, "Testing child with 1TB stack\n");
- testChildStackLimit(1ULL << 40, argv[1]);
- }
- fprintf(stderr, "done\n");
- // CHECK: in esan::initializeLibrary
- // CHECK: Testing child with infinite stack
- // CHECK-NEXT: in esan::initializeLibrary
- // CHECK-NEXT: =={{[0-9:]+}}==The stack size limit is beyond the maximum supported.
- // CHECK-NEXT: Re-execing with a stack size below 1TB.
- // CHECK-NEXT: in esan::initializeLibrary
- // CHECK: done
- // CHECK: in esan::finalizeLibrary
- // CHECK: Testing child with 1TB stack
- // CHECK-NEXT: in esan::initializeLibrary
- // CHECK-NEXT: =={{[0-9:]+}}==The stack size limit is beyond the maximum supported.
- // CHECK-NEXT: Re-execing with a stack size below 1TB.
- // CHECK-NEXT: in esan::initializeLibrary
- // CHECK: done
- // CHECK-NEXT: in esan::finalizeLibrary
- // CHECK: done
- // CHECK-NEXT: in esan::finalizeLibrary
- return 0;
-}
diff --git a/compiler-rt/test/esan/TestCases/libc-intercept.c b/compiler-rt/test/esan/TestCases/libc-intercept.c
deleted file mode 100644
index 8d8d81f0bd0..00000000000
--- a/compiler-rt/test/esan/TestCases/libc-intercept.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_esan_frag -O0 %s -o %t 2>&1
-// RUN: %env_esan_opts=verbosity=3 %run %t 2>&1 | FileCheck %s
-
-#include <string.h>
-
-int main(int argc, char **argv) {
- char Buf[2048];
- const char Str[] = "TestStringOfParticularLength"; // 29 chars.
- strcpy(Buf, Str);
- strncpy(Buf, Str, 17);
- return strncmp(Buf, Str, 17);
- // CHECK: in esan::initializeLibrary
- // CHECK: in esan::processRangeAccess {{.*}} 29
- // CHECK: in esan::processRangeAccess {{.*}} 29
- // CHECK: in esan::processRangeAccess {{.*}} 17
- // CHECK: in esan::processRangeAccess {{.*}} 17
- // CHECK: in esan::processRangeAccess {{.*}} 17
- // CHECK: in esan::processRangeAccess {{.*}} 17
- // CHECK: in esan::finalizeLibrary
-}
diff --git a/compiler-rt/test/esan/TestCases/mmap-shadow-conflict.c b/compiler-rt/test/esan/TestCases/mmap-shadow-conflict.c
deleted file mode 100644
index 8e86bba4adb..00000000000
--- a/compiler-rt/test/esan/TestCases/mmap-shadow-conflict.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: %clang_esan_frag -O0 %s -o %t 2>&1
-// RUN: %env_esan_opts=verbosity=1 %run %t 2>&1 | FileCheck --check-prefix=%arch --check-prefix=CHECK %s
-
-#include <unistd.h>
-#include <sys/mman.h>
-#include <stdio.h>
-
-int main(int argc, char **argv) {
-#if defined(__mips64)
- void *Map = mmap((void *)0x0000001600000000ULL, 0x1000, PROT_READ,
- MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-#else
- void *Map = mmap((void *)0x0000016000000000ULL, 0x1000, PROT_READ,
- MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-#endif
- if (Map == (void *)-1)
- fprintf(stderr, "map failed\n");
- else
- fprintf(stderr, "mapped %p\n", Map);
-#if defined(__mips64)
- Map = mmap((void *)0x0000001600000000ULL, 0x1000, PROT_READ,
- MAP_ANON|MAP_PRIVATE, -1, 0);
-#else
- Map = mmap((void *)0x0000016000000000ULL, 0x1000, PROT_READ,
- MAP_ANON|MAP_PRIVATE, -1, 0);
-#endif
- fprintf(stderr, "mapped %p\n", Map);
- // CHECK: in esan::initializeLibrary
- // (There can be a re-exec for stack limit here.)
- // x86_64: Shadow scale=2 offset=0x440000000000
- // x86_64-NEXT: Shadow #0: [110000000000-114000000000) (256GB)
- // x86_64-NEXT: Shadow #1: [124000000000-12c000000000) (512GB)
- // x86_64-NEXT: Shadow #2: [148000000000-150000000000) (512GB)
- // mips64: Shadow scale=2 offset=0x4400000000
- // mips64-NEXT: Shadow #0: [1140000000-1180000000) (1GB)
- // mips64-NEXT: Shadow #1: [1380000000-13c0000000) (1GB)
- // mips64-NEXT: Shadow #2: [14c0000000-1500000000) (1GB)
- // CHECK-NEXT: mmap conflict: {{.*}}
- // CHECK-NEXT: map failed
- // CHECK-NEXT: mmap conflict: {{.*}}
- // CHECK-NEXT: mapped {{.*}}
- // CHECK-NEXT: in esan::finalizeLibrary
- return 0;
-}
diff --git a/compiler-rt/test/esan/TestCases/struct-simple.cpp b/compiler-rt/test/esan/TestCases/struct-simple.cpp
deleted file mode 100644
index 7ec9761fffa..00000000000
--- a/compiler-rt/test/esan/TestCases/struct-simple.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-// RUN: %clang_esan_frag -O0 %s -DPART1 -mllvm -esan-aux-field-info=0 -c -o %t-part1.o 2>&1
-// RUN: %clang_esan_frag -O0 %s -DPART2 -c -o %t-part2.o 2>&1
-// RUN: %clang_esan_frag -O0 %s -DMAIN -c -o %t-main.o 2>&1
-// RUN: %clang_esan_frag -O0 %t-part1.o %t-part2.o %t-main.o -o %t 2>&1
-// RUN: %env_esan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s
-
-// We generate two different object files from this file with different
-// macros, and then link them together. We do this to test how we handle
-// separate compilation with multiple compilation units.
-
-#include <stdio.h>
-
-extern "C" {
- void part1();
- void part2();
-}
-
-//===-- compilation unit part1 without main function ----------------------===//
-
-#ifdef PART1
-struct A {
- int x;
- int y;
-};
-
-struct B {
- float m;
- double n;
-};
-
-union U {
- float f;
- double d;
-};
-
-// Same struct in both main and part1.
-struct S {
- int s1;
- int s2;
-};
-
-// Different structs with the same name in main and part1.
-struct D {
- int d1;
- int d2;
- struct {
- int x;
- int y;
- int z;
- } ds[10];
-};
-
-void part1()
-{
- struct A a;
- struct B b;
- union U u;
- struct S s;
- struct D d;
- for (int i = 0; i < (1 << 11); i++)
- a.x = 0;
- a.y = 1;
- b.m = 2.0;
- for (int i = 0; i < (1 << 21); i++) {
- b.n = 3.0;
- d.ds[3].y = 0;
- }
- u.f = 0.0;
- u.d = 1.0;
- s.s1 = 0;
- d.d1 = 0;
-}
-#endif // PART1
-
-//===-- compilation unit part2 without main function ----------------------===//
-#ifdef PART2
-// No struct in this part.
-void part2()
-{
- // do nothing
-}
-#endif // PART2
-
-//===-- compilation unit with main function -------------------------------===//
-
-#ifdef MAIN
-class C {
-public:
- struct {
- int x;
- int y;
- } cs;
- union {
- float f;
- double d;
- } cu;
- char c[10];
-};
-
-// Same struct in both main and part1.
-struct S {
- int s1;
- int s2;
-};
-
-// Different structs with the same name in main and part1.
-struct D {
- int d1;
- int d2;
- int d3;
-};
-
-int main(int argc, char **argv) {
- // CHECK: in esan::initializeLibrary
- // CHECK: in esan::initializeCacheFrag
- // CHECK-NEXT: in esan::processCompilationUnitInit
- // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 6 class(es)/struct(s)
- // CHECK-NEXT: Register struct.A$2$11$11: 2 fields
- // CHECK-NEXT: Register struct.B$2$3$2: 2 fields
- // CHECK-NEXT: Register union.U$1$3: 1 fields
- // CHECK-NEXT: Register struct.S$2$11$11: 2 fields
- // CHECK-NEXT: Register struct.D$3$14$11$11: 3 fields
- // CHECK-NEXT: Register struct.anon$3$11$11$11: 3 fields
- // CHECK-NEXT: in esan::processCompilationUnitInit
- // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s)
- // CHECK-NEXT: in esan::processCompilationUnitInit
- // CHECK-NEXT: in esan::processCacheFragCompilationUnitInit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s)
- // CHECK-NEXT: Register class.C$3$14$13$13: 3 fields
- // CHECK-NEXT: Register struct.anon$2$11$11: 2 fields
- // CHECK-NEXT: Register union.anon$1$3: 1 fields
- // CHECK-NEXT: Duplicated struct.S$2$11$11: 2 fields
- // CHECK-NEXT: Register struct.D$3$11$11$11: 3 fields
- struct C c[2];
- struct S s;
- struct D d;
- c[0].cs.x = 0;
- c[1].cs.y = 1;
- c[0].cu.f = 0.0;
- c[1].cu.d = 1.0;
- c[0].c[2] = 0;
- s.s1 = 0;
- d.d1 = 0;
- d.d2 = 0;
- part1();
- part2();
- return 0;
- // CHECK: in esan::finalizeLibrary
- // CHECK-NEXT: in esan::finalizeCacheFrag
- // CHECK-NEXT: in esan::processCompilationUnitExit
- // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 5 class(es)/struct(s)
- // CHECK-NEXT: Unregister class.C$3$14$13$13: 3 fields
- // CHECK-NEXT: {{.*}} class C
- // CHECK-NEXT: {{.*}} size = 32, count = 5, ratio = 3, array access = 5
- // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 8, count = 2, type = %struct.anon = type { i32, i32 }
- // CHECK-NEXT: {{.*}} # 1: offset = 8, size = 8, count = 2, type = %union.anon = type { double }
- // CHECK-NEXT: {{.*}} # 2: offset = 16, size = 10, count = 1, type = [10 x i8]
- // CHECK-NEXT: Unregister struct.anon$2$11$11: 2 fields
- // CHECK-NEXT: {{.*}} struct anon
- // CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 1, array access = 0
- // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32
- // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32
- // CHECK-NEXT: Unregister union.anon$1$3: 1 fields
- // CHECK-NEXT: Unregister struct.S$2$11$11: 2 fields
- // CHECK-NEXT: {{.*}} struct S
- // CHECK-NEXT: {{.*}} size = 8, count = 2, ratio = 2, array access = 0
- // CHECK-NEXT: {{.*}} # 0: count = 2
- // CHECK-NEXT: {{.*}} # 1: count = 0
- // CHECK-NEXT: Unregister struct.D$3$11$11$11: 3 fields
- // CHECK-NEXT: {{.*}} struct D
- // CHECK-NEXT: {{.*}} size = 12, count = 2, ratio = 2, array access = 0
- // CHECK-NEXT: {{.*}} # 0: offset = 0, size = 4, count = 1, type = i32
- // CHECK-NEXT: {{.*}} # 1: offset = 4, size = 4, count = 1, type = i32
- // CHECK-NEXT: {{.*}} # 2: offset = 8, size = 4, count = 0, type = i32
- // CHECK-NEXT: in esan::processCompilationUnitExit
- // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 0 class(es)/struct(s)
- // CHECK-NEXT: in esan::processCompilationUnitExit
- // CHECK-NEXT: in esan::processCacheFragCompilationUnitExit: {{.*}}struct-simple.cpp with 6 class(es)/struct(s)
- // CHECK-NEXT: Unregister struct.A$2$11$11: 2 fields
- // CHECK-NEXT: {{.*}} struct A
- // CHECK-NEXT: {{.*}} size = 8, count = 2049, ratio = 2048, array access = 0
- // CHECK-NEXT: {{.*}} # 0: count = 2048
- // CHECK-NEXT: {{.*}} # 1: count = 1
- // CHECK-NEXT: Unregister struct.B$2$3$2: 2 fields
- // CHECK-NEXT: {{.*}} struct B
- // CHECK-NEXT: {{.*}} size = 16, count = 2097153, ratio = 2097152, array access = 0
- // CHECK-NEXT: {{.*}} # 0: count = 1
- // CHECK-NEXT: {{.*}} # 1: count = 2097152
- // CHECK-NEXT: Unregister union.U$1$3: 1 fields
- // CHECK-NEXT: Duplicated struct.S$2$11$11: 2 fields
- // CHECK-NEXT: Unregister struct.D$3$14$11$11: 3 fields
- // CHECK-NEXT: {{.*}} struct D
- // CHECK-NEXT: {{.*}} size = 128, count = 2097153, ratio = 2097153, array access = 0
- // CHECK-NEXT: {{.*}} # 0: count = 1
- // CHECK-NEXT: {{.*}} # 1: count = 0
- // CHECK-NEXT: {{.*}} # 2: count = 2097152
- // CHECK-NEXT: Unregister struct.anon$3$11$11$11: 3 fields
- // CHECK-NEXT: {{.*}} struct anon
- // CHECK-NEXT: {{.*}} size = 12, count = 2097152, ratio = 4194304, array access = 2097152
- // CHECK-NEXT: {{.*}} # 0: count = 0
- // CHECK-NEXT: {{.*}} # 1: count = 2097152
- // CHECK-NEXT: {{.*}} # 2: count = 0
- // CHECK-NEXT: {{.*}}EfficiencySanitizer: total struct field access count = 6293518
-}
-#endif // MAIN
diff --git a/compiler-rt/test/esan/TestCases/verbose-simple.c b/compiler-rt/test/esan/TestCases/verbose-simple.c
deleted file mode 100644
index 5ac37e15929..00000000000
--- a/compiler-rt/test/esan/TestCases/verbose-simple.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_esan_frag -O0 %s -o %t 2>&1
-// RUN: %env_esan_opts="verbosity=1 log_exe_name=1" %run %t 2>&1 | FileCheck --check-prefix=%arch --check-prefix=CHECK %s
-
-int main(int argc, char **argv) {
- // CHECK: in esan::initializeLibrary
- // (There can be a re-exec for stack limit here.)
- // x86_64: Shadow scale=2 offset=0x440000000000
- // x86_64-NEXT: Shadow #0: [110000000000-114000000000) (256GB)
- // x86_64-NEXT: Shadow #1: [124000000000-12c000000000) (512GB)
- // x86_64-NEXT: Shadow #2: [148000000000-150000000000) (512GB)
- // mips64: Shadow scale=2 offset=0x4400000000
- // mips64-NEXT: Shadow #0: [1140000000-1180000000) (1GB)
- // mips64-NEXT: Shadow #1: [1380000000-13c0000000) (1GB)
- // mips64-NEXT: Shadow #2: [14c0000000-1500000000) (1GB)
- // CHECK: in esan::finalizeLibrary
- // CHECK: ==verbose-simple{{.*}}EfficiencySanitizer: total struct field access count = 0
- return 0;
-}
diff --git a/compiler-rt/test/esan/TestCases/workingset-early-fault.c b/compiler-rt/test/esan/TestCases/workingset-early-fault.c
deleted file mode 100644
index 971285b3f81..00000000000
--- a/compiler-rt/test/esan/TestCases/workingset-early-fault.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// Test shadow faults during esan initialization as well as
-// faults during dlsym's calloc during interceptor init.
-//
-// RUN: %clang_esan_wset %s -o %t
-// RUN: %run %t 2>&1 | FileCheck %s
-// Stucks at init and no clone feature equivalent.
-// UNSUPPORTED: freebsd
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// Our goal is to emulate an instrumented allocator, whose calloc
-// invoked from dlsym will trigger shadow faults, to test an
-// early shadow fault during esan interceptor init.
-// We do this by replacing calloc:
-void *calloc(size_t size, size_t n) {
- // Unfortunately we can't print anything to make the test
- // ensure we got here b/c the sanitizer interceptors can't
- // handle that during interceptor init.
-
- // Ensure we trigger a shadow write fault:
- int x[16];
- x[0] = size;
- // Now just emulate calloc.
- void *res = malloc(size*n);
- memset(res, 0, size*n);
- return res;
-}
-
-int main(int argc, char **argv) {
- printf("all done\n");
- return 0;
-}
-// CHECK: all done
diff --git a/compiler-rt/test/esan/TestCases/workingset-memset.cpp b/compiler-rt/test/esan/TestCases/workingset-memset.cpp
deleted file mode 100644
index 56ed2f5b7c4..00000000000
--- a/compiler-rt/test/esan/TestCases/workingset-memset.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
-// RUN: %run %t 2>&1 | FileCheck %s
-// Stucks at init and no clone feature equivalent.
-// UNSUPPORTED: freebsd
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <assert.h>
-#include <string.h>
-
-int main(int argc, char **argv) {
- const int size = 128*1024*1024;
- char *p = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_ANON | MAP_PRIVATE, -1, 0);
- // Test the slowpath at different cache line boundaries.
- for (int i = 0; i < 630; i++)
- memset((char *)p + 63*i, i, 63*i);
- munmap(p, size);
- return 0;
- // CHECK: {{.*}} EfficiencySanitizer: the total working set size: 77 KB (12{{[0-9]+}} cache lines)
-}
diff --git a/compiler-rt/test/esan/TestCases/workingset-midreport.cpp b/compiler-rt/test/esan/TestCases/workingset-midreport.cpp
deleted file mode 100644
index acd1eed1761..00000000000
--- a/compiler-rt/test/esan/TestCases/workingset-midreport.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
-// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN
-
-// RUN: %clang -O0 %s -o %t 2>&1
-// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ESAN
-
-// FIXME: Re-enable once PR33590 is fixed.
-// UNSUPPORTED: x86_64
-// Stucks at init and no clone feature equivalent.
-// UNSUPPORTED: freebsd
-
-#include <sanitizer/esan_interface.h>
-#include <sched.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-
-const int size = 0x1 << 25; // 523288 cache lines
-const int iters = 6;
-
-int main(int argc, char **argv) {
- char *buf = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- // To avoid flakiness stemming from whether the sideline thread
- // is scheduled enough on a loaded test machine, we coordinate
- // with esan itself:
- if (__esan_get_sample_count) {
- while (__esan_get_sample_count() < 4) {
- for (int i = 0; i < size; ++i)
- buf[i] = i;
- sched_yield();
- }
- }
- // Ensure a non-esan build works without ifdefs:
- if (__esan_report) {
- // We should get 2 roughly identical reports:
- __esan_report();
- }
- munmap(buf, size);
- fprintf(stderr, "all done\n");
- // CHECK-NO-ESAN: all done
- // We only check for a few samples here to reduce the chance of flakiness:
- // CHECK-ESAN: =={{[0-9]+}}== Total number of samples: {{[0-9]+}}
- // CHECK-ESAN-NEXT: =={{[0-9]+}}== Samples array #0 at period 20 ms
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 1: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 2: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 3: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #1 at period 80 ms
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #2 at period 320 ms
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #3 at period 1280 ms
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #4 at period 5120 ms
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #5 at period 20 sec
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #6 at period 81 sec
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #7 at period 327 sec
- // CHECK-ESAN: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (5242{{[0-9][0-9]}} cache lines)
- // CHECK-ESAN-NEXT: all done
- // CHECK-ESAN-NEXT: =={{[0-9]+}}== Total number of samples: {{[0-9]+}}
- // CHECK-ESAN-NEXT: =={{[0-9]+}}== Samples array #0 at period 20 ms
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 1: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 2: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 3: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #1 at period 80 ms
- // CHECK-ESAN-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #2 at period 320 ms
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #3 at period 1280 ms
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #4 at period 5120 ms
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #5 at period 20 sec
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #6 at period 81 sec
- // CHECK-ESAN: =={{[0-9]+}}== Samples array #7 at period 327 sec
- // CHECK-ESAN: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (5242{{[0-9][0-9]}} cache lines)
- return 0;
-}
diff --git a/compiler-rt/test/esan/TestCases/workingset-samples.cpp b/compiler-rt/test/esan/TestCases/workingset-samples.cpp
deleted file mode 100644
index 1f8e97dadcc..00000000000
--- a/compiler-rt/test/esan/TestCases/workingset-samples.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
-// RUN: %run %t 2>&1 | FileCheck %s
-
-// FIXME: Re-enable once PR33590 is fixed.
-// UNSUPPORTED: x86_64
-// Stucks at init and no clone feature equivalent.
-// UNSUPPORTED: freebsd
-
-#include <sanitizer/esan_interface.h>
-#include <sched.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-
-const int size = 0x1 << 25; // 523288 cache lines
-
-int main(int argc, char **argv) {
- char *buf = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- // To avoid flakiness stemming from whether the sideline thread
- // is scheduled enough on a loaded test machine, we coordinate
- // with esan itself:
- if (__esan_get_sample_count) {
- while (__esan_get_sample_count() < 4) {
- for (int i = 0; i < size; ++i)
- buf[i] = i;
- sched_yield();
- }
- }
- munmap(buf, size);
- // We only check for a few samples here to reduce the chance of flakiness.
- // CHECK: =={{[0-9]+}}== Total number of samples: {{[0-9]+}}
- // CHECK-NEXT: =={{[0-9]+}}== Samples array #0 at period 20 ms
- // CHECK-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-NEXT: =={{[0-9]+}}==# 1: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-NEXT: =={{[0-9]+}}==# 2: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK-NEXT: =={{[0-9]+}}==# 3: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK: =={{[0-9]+}}== Samples array #1 at period 80 ms
- // CHECK-NEXT: =={{[0-9]+}}==# 0: {{[ 0-9]+}} {{KB|MB|Bytes}} ({{[ 0-9]+}} cache lines)
- // CHECK: =={{[0-9]+}}== Samples array #2 at period 320 ms
- // CHECK: =={{[0-9]+}}== Samples array #3 at period 1280 ms
- // CHECK: =={{[0-9]+}}== Samples array #4 at period 5120 ms
- // CHECK: =={{[0-9]+}}== Samples array #5 at period 20 sec
- // CHECK: =={{[0-9]+}}== Samples array #6 at period 81 sec
- // CHECK: =={{[0-9]+}}== Samples array #7 at period 327 sec
- // CHECK: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (5242{{[0-9][0-9]}} cache lines)
- return 0;
-}
diff --git a/compiler-rt/test/esan/TestCases/workingset-signal-posix.cpp b/compiler-rt/test/esan/TestCases/workingset-signal-posix.cpp
deleted file mode 100644
index 6f9787bd73e..00000000000
--- a/compiler-rt/test/esan/TestCases/workingset-signal-posix.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
-// RUN: %run %t 2>&1 | FileCheck %s
-// Stucks at init and no clone feature equivalent.
-// UNSUPPORTED: freebsd
-
-#include <assert.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-sigjmp_buf mark;
-
-static void SignalHandler(int Sig) {
- if (Sig == SIGSEGV) {
- fprintf(stderr, "Handling SIGSEGV for signal\n");
- siglongjmp(mark, 1);
- }
- exit(1);
-}
-
-static void SigactionHandler(int Sig, siginfo_t *Info, void *Ctx) {
- if (Sig == SIGSEGV) {
- fprintf(stderr, "Handling SIGSEGV for sigaction\n");
- siglongjmp(mark, 1);
- }
- exit(1);
-}
-
-int main(int argc, char **argv) {
- __sighandler_t Prior = signal(SIGSEGV, SignalHandler);
- assert(Prior == SIG_DFL);
- if (sigsetjmp(mark, 1) == 0)
- *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV
- fprintf(stderr, "Past longjmp for signal\n");
-
- Prior = signal(SIGSEGV, SIG_DFL);
- assert(Prior == SignalHandler);
-
- struct sigaction SigAct;
- SigAct.sa_sigaction = SigactionHandler;
- int Res = sigfillset(&SigAct.sa_mask);
- assert(Res == 0);
- SigAct.sa_flags = SA_SIGINFO;
- Res = sigaction(SIGSEGV, &SigAct, NULL);
- assert(Res == 0);
-
- if (sigsetjmp(mark, 1) == 0)
- *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV
- fprintf(stderr, "Past longjmp for sigaction\n");
-
- Res = sigaction(SIGSEGV, NULL, &SigAct);
- assert(Res == 0);
- assert(SigAct.sa_sigaction == SigactionHandler);
-
- // Test blocking SIGSEGV and raising a shadow fault.
- sigset_t Set;
- sigemptyset(&Set);
- sigaddset(&Set, SIGSEGV);
- Res = sigprocmask(SIG_BLOCK, &Set, NULL);
- // Make a large enough mapping that its start point will be before any
- // prior library-region shadow access.
- char *buf = (char *)mmap(0, 640*1024, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- buf[0] = 4;
- munmap(buf, 640*1024);
- fprintf(stderr, "Past blocked-SIGSEGV shadow fault\n");
-
- return 0;
-}
-// CHECK: Handling SIGSEGV for signal
-// CHECK-NEXT: Past longjmp for signal
-// CHECK-NEXT: Handling SIGSEGV for sigaction
-// CHECK-NEXT: Past longjmp for sigaction
-// CHECK-NEXT: Past blocked-SIGSEGV shadow fault
-// CHECK: {{.*}} EfficiencySanitizer: the total working set size: {{[0-9]+}} Bytes ({{[0-9][0-9]}} cache lines)
diff --git a/compiler-rt/test/esan/TestCases/workingset-simple.cpp b/compiler-rt/test/esan/TestCases/workingset-simple.cpp
deleted file mode 100644
index dc17bcfd540..00000000000
--- a/compiler-rt/test/esan/TestCases/workingset-simple.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
-// RUN: %run %t 2>&1 | FileCheck %s
-
-// FIXME: Re-enable once PR33590 is fixed.
-// UNSUPPORTED: x86_64
-// Stucks at init and no clone feature equivalent.
-// UNSUPPORTED: freebsd
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <assert.h>
-
-const int size = 0x1 << 25; // 523288 cache lines
-const int line_size = 64;
-
-int main(int argc, char **argv) {
- char *bufA = (char *)malloc(sizeof(char) * line_size);
- char bufB[64];
- char *bufC = (char *)mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- bufA[0] = 0;
- // This additional access to the same line should not increase the line
- // count: but it's difficult to make a non-flaky test that measures the
- // lines down to the ones digit so right now we're not really testing that.
- // If we add a heap-only mode we may be able to be more precise.
- bufA[1] = 0;
- bufB[33] = 1;
- for (int i = 0; i < size; i += line_size)
- bufC[i] = 0;
- free(bufA);
- munmap(bufC, 0x4000);
- // CHECK: {{.*}} EfficiencySanitizer: the total working set size: 32 MB (524{{[0-9][0-9][0-9]}} cache lines)
- return 0;
-}
diff --git a/compiler-rt/test/esan/Unit/circular_buffer.cpp b/compiler-rt/test/esan/Unit/circular_buffer.cpp
deleted file mode 100644
index 00999a2724c..00000000000
--- a/compiler-rt/test/esan/Unit/circular_buffer.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-// RUN: %clangxx_unit -O0 %s -o %t 2>&1
-// RUN: %env_esan_opts="record_snapshots=0" %run %t 2>&1 | FileCheck %s
-
-#include "esan/esan_circular_buffer.h"
-#include "sanitizer_common/sanitizer_placement_new.h"
-#include <assert.h>
-#include <stdio.h>
-
-static const int TestBufCapacity = 4;
-
-// The buffer should have a capacity of TestBufCapacity.
-void testBuffer(__esan::CircularBuffer<int> *Buf) {
- assert(Buf->size() == 0);
- assert(Buf->empty());
-
- Buf->push_back(1);
- assert(Buf->back() == 1);
- assert((*Buf)[0] == 1);
- assert(Buf->size() == 1);
- assert(!Buf->empty());
-
- Buf->push_back(2);
- Buf->push_back(3);
- Buf->push_back(4);
- Buf->push_back(5);
- assert((*Buf)[0] == 2);
- assert(Buf->size() == 4);
-
- Buf->pop_back();
- assert((*Buf)[0] == 2);
- assert(Buf->size() == 3);
-
- Buf->pop_back();
- Buf->pop_back();
- assert((*Buf)[0] == 2);
- assert(Buf->size() == 1);
- assert(!Buf->empty());
-
- Buf->pop_back();
- assert(Buf->empty());
-}
-
-int main()
-{
- // Test initialize/free.
- __esan::CircularBuffer<int> GlobalBuf;
- GlobalBuf.initialize(TestBufCapacity);
- testBuffer(&GlobalBuf);
- GlobalBuf.free();
-
- // Test constructor/free.
- __esan::CircularBuffer<int> *LocalBuf;
- static char placeholder[sizeof(*LocalBuf)];
- LocalBuf = new(placeholder) __esan::CircularBuffer<int>(TestBufCapacity);
- testBuffer(LocalBuf);
- LocalBuf->free();
-
- fprintf(stderr, "All checks passed.\n");
- // CHECK: All checks passed.
- return 0;
-}
diff --git a/compiler-rt/test/esan/Unit/hashtable.cpp b/compiler-rt/test/esan/Unit/hashtable.cpp
deleted file mode 100644
index 390a427da25..00000000000
--- a/compiler-rt/test/esan/Unit/hashtable.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-// RUN: %clangxx_unit -esan-instrument-loads-and-stores=0 -O0 %s -o %t 2>&1
-// RUN: %env_esan_opts="record_snapshots=0" %run %t 2>&1 | FileCheck %s
-
-#include "esan/esan_hashtable.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-class MyData {
- public:
- MyData(const char *Str) : RefCount(0) { Buf = strdup(Str); }
- ~MyData() {
- fprintf(stderr, " Destructor: %s.\n", Buf);
- free(Buf);
- }
- bool operator==(MyData &Cmp) { return strcmp(Buf, Cmp.Buf) == 0; }
- operator size_t() const {
- size_t Res = 0;
- for (int i = 0; i < strlen(Buf); ++i)
- Res ^= Buf[i];
- return Res;
- }
- char *Buf;
- int RefCount;
-};
-
-// We use a smart pointer wrapper to free the payload on hashtable removal.
-struct MyDataPayload {
- MyDataPayload() : Data(nullptr) {}
- explicit MyDataPayload(MyData *Data) : Data(Data) { ++Data->RefCount; }
- ~MyDataPayload() {
- if (Data && --Data->RefCount == 0) {
- fprintf(stderr, "Deleting %s.\n", Data->Buf);
- delete Data;
- }
- }
- MyDataPayload(const MyDataPayload &Copy) {
- Data = Copy.Data;
- ++Data->RefCount;
- }
- MyDataPayload & operator=(const MyDataPayload &Copy) {
- if (this != &Copy) {
- this->~MyDataPayload();
- Data = Copy.Data;
- ++Data->RefCount;
- }
- return *this;
- }
- bool operator==(MyDataPayload &Cmp) { return *Data == *Cmp.Data; }
- operator size_t() const { return (size_t)*Data; }
- MyData *Data;
-};
-
-int main()
-{
- __esan::HashTable<int, int> IntTable;
- assert(IntTable.size() == 0);
-
- // Test iteration on an empty table.
- int Count = 0;
- for (auto Iter = IntTable.begin(); Iter != IntTable.end();
- ++Iter, ++Count) {
- // Empty.
- }
- assert(Count == 0);
-
- bool Added = IntTable.add(4, 42);
- assert(Added);
- assert(!IntTable.add(4, 42));
- assert(IntTable.size() == 1);
- int Value;
- bool Found = IntTable.lookup(4, Value);
- assert(Found && Value == 42);
-
- // Test iterator.
- IntTable.lock();
- for (auto Iter = IntTable.begin(); Iter != IntTable.end();
- ++Iter, ++Count) {
- assert((*Iter).Key == 4);
- assert((*Iter).Data == 42);
- }
- IntTable.unlock();
- assert(Count == 1);
- assert(Count == IntTable.size());
- assert(!IntTable.remove(5));
- assert(IntTable.remove(4));
-
- // Test a more complex payload.
- __esan::HashTable<int, MyDataPayload> DataTable(4);
- MyDataPayload NewData(new MyData("mystring"));
- Added = DataTable.add(4, NewData);
- assert(Added);
- MyDataPayload FoundData;
- Found = DataTable.lookup(4, FoundData);
- assert(Found && strcmp(FoundData.Data->Buf, "mystring") == 0);
- assert(!DataTable.remove(5));
- assert(DataTable.remove(4));
- // Test resize.
- for (int i = 0; i < 4; ++i) {
- MyDataPayload MoreData(new MyData("delete-at-end"));
- Added = DataTable.add(i+1, MoreData);
- assert(Added);
- assert(!DataTable.add(i+1, MoreData));
- }
- for (int i = 0; i < 4; ++i) {
- Found = DataTable.lookup(i+1, FoundData);
- assert(Found && strcmp(FoundData.Data->Buf, "delete-at-end") == 0);
- }
- DataTable.lock();
- Count = 0;
- for (auto Iter = DataTable.begin(); Iter != DataTable.end();
- ++Iter, ++Count) {
- int Key = (*Iter).Key;
- FoundData = (*Iter).Data;
- assert(Key >= 1 && Key <= 4);
- assert(strcmp(FoundData.Data->Buf, "delete-at-end") == 0);
- }
- DataTable.unlock();
- assert(Count == 4);
- assert(Count == DataTable.size());
-
- // Ensure the iterator supports a range-based for loop.
- DataTable.lock();
- Count = 0;
- for (auto Pair : DataTable) {
- assert(Pair.Key >= 1 && Pair.Key <= 4);
- assert(strcmp(Pair.Data.Data->Buf, "delete-at-end") == 0);
- ++Count;
- }
- DataTable.unlock();
- assert(Count == 4);
- assert(Count == DataTable.size());
-
- // Test payload freeing via smart pointer wrapper.
- __esan::HashTable<MyDataPayload, MyDataPayload, true> DataKeyTable;
- MyDataPayload DataA(new MyData("string AB"));
- DataKeyTable.lock();
- Added = DataKeyTable.add(DataA, DataA);
- assert(Added);
- Found = DataKeyTable.lookup(DataA, FoundData);
- assert(Found && strcmp(FoundData.Data->Buf, "string AB") == 0);
- MyDataPayload DataB(new MyData("string AB"));
- Added = DataKeyTable.add(DataB, DataB);
- assert(!Added);
- DataKeyTable.remove(DataB); // Should free the DataA payload.
- DataKeyTable.unlock();
-
- // Test custom functors.
- struct CustomHash {
- size_t operator()(int Key) const { return Key % 4; }
- };
- struct CustomEqual {
- bool operator()(int Key1, int Key2) const { return Key1 %4 == Key2 % 4; }
- };
- __esan::HashTable<int, int, false, CustomHash, CustomEqual> ModTable;
- Added = ModTable.add(2, 42);
- assert(Added);
- Added = ModTable.add(6, 42);
- assert(!Added);
-
- fprintf(stderr, "All checks passed.\n");
- return 0;
-}
-// CHECK: Deleting mystring.
-// CHECK-NEXT: Destructor: mystring.
-// CHECK-NEXT: All checks passed.
-// CHECK-NEXT: Deleting string AB.
-// CHECK-NEXT: Destructor: string AB.
-// CHECK-NEXT: Deleting string AB.
-// CHECK-NEXT: Destructor: string AB.
-// CHECK-NEXT: Deleting delete-at-end.
-// CHECK-NEXT: Destructor: delete-at-end.
-// CHECK-NEXT: Deleting delete-at-end.
-// CHECK-NEXT: Destructor: delete-at-end.
-// CHECK-NEXT: Deleting delete-at-end.
-// CHECK-NEXT: Destructor: delete-at-end.
-// CHECK-NEXT: Deleting delete-at-end.
-// CHECK-NEXT: Destructor: delete-at-end.
diff --git a/compiler-rt/test/esan/lit.cfg b/compiler-rt/test/esan/lit.cfg
deleted file mode 100644
index 1bb34ee0865..00000000000
--- a/compiler-rt/test/esan/lit.cfg
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- Python -*-
-
-import os
-
-# Setup config name.
-config.name = 'EfficiencySanitizer' + config.name_suffix
-
-# Setup source root.
-config.test_source_root = os.path.dirname(__file__)
-
-# Setup default compiler flags used with -fsanitize=efficiency option.
-base_cflags = ([config.target_cflags] + config.debug_info_flags)
-base_cxxflags = config.cxx_mode_flags + base_cflags
-
-frag_cflags = (["-fsanitize=efficiency-cache-frag"] + base_cflags)
-wset_cflags = (["-fsanitize=efficiency-working-set"] + base_cflags)
-esan_incdir = config.test_source_root + "/../../lib"
-unit_cxxflags = (["-I%s" % esan_incdir, "-std=c++11",
- # We need to link with the esan runtime.
- # Tests should pass %env_esan_opts="record_snapshots=0".
- "-fsanitize=efficiency-working-set"] + base_cxxflags)
-
-def build_invocation(compile_flags):
- return " " + " ".join([config.clang] + compile_flags) + " "
-
-config.substitutions.append( ("%clang ",
- build_invocation(base_cflags)) )
-config.substitutions.append( ("%clang_esan_frag ",
- build_invocation(frag_cflags)) )
-config.substitutions.append( ("%clang_esan_wset ",
- build_invocation(wset_cflags)) )
-config.substitutions.append( ("%clangxx_unit",
- build_invocation(unit_cxxflags)) )
-
-default_esan_opts = ''
-config.substitutions.append(('%env_esan_opts=',
- 'env ESAN_OPTIONS=' + default_esan_opts))
-
-# Default test suffixes.
-config.suffixes = ['.c', '.cpp']
-
-if config.host_os not in ['Linux', 'FreeBSD'] or config.target_arch not in ['x86_64', 'mips64'] :
- config.unsupported = True
diff --git a/compiler-rt/test/esan/lit.site.cfg.in b/compiler-rt/test/esan/lit.site.cfg.in
deleted file mode 100644
index b631ce42d4d..00000000000
--- a/compiler-rt/test/esan/lit.site.cfg.in
+++ /dev/null
@@ -1,14 +0,0 @@
-## Autogenerated by LLVM/Clang configuration.
-# Do not edit!
-
-# Tool-specific config options.
-config.name_suffix = "@ESAN_TEST_CONFIG_SUFFIX@"
-config.esan_lit_source_dir = "@ESAN_LIT_SOURCE_DIR@"
-config.target_cflags = "@ESAN_TEST_TARGET_CFLAGS@"
-config.target_arch = "@ESAN_TEST_TARGET_ARCH@"
-
-# Load common config for all compiler-rt lit tests.
-lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
-
-# Load tool-specific config that would do the real work.
-lit_config.load_config(config, "@ESAN_LIT_SOURCE_DIR@/lit.cfg")
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 057a4298ad5..c1ed43562ba 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -134,7 +134,6 @@ void initializeEarlyIfConverterPass(PassRegistry&);
void initializeEarlyMachineLICMPass(PassRegistry&);
void initializeEarlyTailDuplicatePass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&);
-void initializeEfficiencySanitizerPass(PassRegistry&);
void initializeEliminateAvailableExternallyLegacyPassPass(PassRegistry&);
void initializeEntryExitInstrumenterPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&);
diff --git a/llvm/include/llvm/Transforms/Instrumentation.h b/llvm/include/llvm/Transforms/Instrumentation.h
index 27ac7423e2c..e747a744b74 100644
--- a/llvm/include/llvm/Transforms/Instrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation.h
@@ -160,21 +160,6 @@ ModulePass *createDataFlowSanitizerPass(
const std::vector<std::string> &ABIListFiles = std::vector<std::string>(),
void *(*getArgTLS)() = nullptr, void *(*getRetValTLS)() = nullptr);
-// Options for EfficiencySanitizer sub-tools.
-struct EfficiencySanitizerOptions {
- enum Type {
- ESAN_None = 0,
- ESAN_CacheFrag,
- ESAN_WorkingSet,
- } ToolType = ESAN_None;
-
- EfficiencySanitizerOptions() = default;
-};
-
-// Insert EfficiencySanitizer instrumentation.
-ModulePass *createEfficiencySanitizerPass(
- const EfficiencySanitizerOptions &Options = EfficiencySanitizerOptions());
-
// Options for sanitizer coverage instrumentation.
struct SanitizerCoverageOptions {
enum Type {
diff --git a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt
index 7db989d4608..969529c21c5 100644
--- a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt
+++ b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt
@@ -14,7 +14,6 @@ add_llvm_library(LLVMInstrumentation
PGOMemOPSizeOpt.cpp
SanitizerCoverage.cpp
ThreadSanitizer.cpp
- EfficiencySanitizer.cpp
HWAddressSanitizer.cpp
ADDITIONAL_HEADER_DIRS
diff --git a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
deleted file mode 100644
index 26c4cbcb63f..00000000000
--- a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
+++ /dev/null
@@ -1,892 +0,0 @@
-//===-- EfficiencySanitizer.cpp - performance tuner -----------------------===//
-//
-// 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 EfficiencySanitizer, a family of performance tuners
-// that detects multiple performance issues via separate sub-tools.
-//
-// The instrumentation phase is straightforward:
-// - Take action on every memory access: either inlined instrumentation,
-// or Inserted calls to our run-time library.
-// - Optimizations may apply to avoid instrumenting some of the accesses.
-// - Turn mem{set,cpy,move} instrinsics into library calls.
-// The rest is handled by the run-time library.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Type.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/ModuleUtils.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "esan"
-
-// The tool type must be just one of these ClTool* options, as the tools
-// cannot be combined due to shadow memory constraints.
-static cl::opt<bool>
- ClToolCacheFrag("esan-cache-frag", cl::init(false),
- cl::desc("Detect data cache fragmentation"), cl::Hidden);
-static cl::opt<bool>
- ClToolWorkingSet("esan-working-set", cl::init(false),
- cl::desc("Measure the working set size"), cl::Hidden);
-// Each new tool will get its own opt flag here.
-// These are converted to EfficiencySanitizerOptions for use
-// in the code.
-
-static cl::opt<bool> ClInstrumentLoadsAndStores(
- "esan-instrument-loads-and-stores", cl::init(true),
- cl::desc("Instrument loads and stores"), cl::Hidden);
-static cl::opt<bool> ClInstrumentMemIntrinsics(
- "esan-instrument-memintrinsics", cl::init(true),
- cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden);
-static cl::opt<bool> ClInstrumentFastpath(
- "esan-instrument-fastpath", cl::init(true),
- cl::desc("Instrument fastpath"), cl::Hidden);
-static cl::opt<bool> ClAuxFieldInfo(
- "esan-aux-field-info", cl::init(true),
- cl::desc("Generate binary with auxiliary struct field information"),
- cl::Hidden);
-
-// Experiments show that the performance difference can be 2x or more,
-// and accuracy loss is typically negligible, so we turn this on by default.
-static cl::opt<bool> ClAssumeIntraCacheLine(
- "esan-assume-intra-cache-line", cl::init(true),
- cl::desc("Assume each memory access touches just one cache line, for "
- "better performance but with a potential loss of accuracy."),
- cl::Hidden);
-
-STATISTIC(NumInstrumentedLoads, "Number of instrumented loads");
-STATISTIC(NumInstrumentedStores, "Number of instrumented stores");
-STATISTIC(NumFastpaths, "Number of instrumented fastpaths");
-STATISTIC(NumAccessesWithIrregularSize,
- "Number of accesses with a size outside our targeted callout sizes");
-STATISTIC(NumIgnoredStructs, "Number of ignored structs");
-STATISTIC(NumIgnoredGEPs, "Number of ignored GEP instructions");
-STATISTIC(NumInstrumentedGEPs, "Number of instrumented GEP instructions");
-STATISTIC(NumAssumedIntraCacheLine,
- "Number of accesses assumed to be intra-cache-line");
-
-static const uint64_t EsanCtorAndDtorPriority = 0;
-static const char *const EsanModuleCtorName = "esan.module_ctor";
-static const char *const EsanModuleDtorName = "esan.module_dtor";
-static const char *const EsanInitName = "__esan_init";
-static const char *const EsanExitName = "__esan_exit";
-
-// We need to specify the tool to the runtime earlier than
-// the ctor is called in some cases, so we set a global variable.
-static const char *const EsanWhichToolName = "__esan_which_tool";
-
-// We must keep these Shadow* constants consistent with the esan runtime.
-// FIXME: Try to place these shadow constants, the names of the __esan_*
-// interface functions, and the ToolType enum into a header shared between
-// llvm and compiler-rt.
-struct ShadowMemoryParams {
- uint64_t ShadowMask;
- uint64_t ShadowOffs[3];
-};
-
-static const ShadowMemoryParams ShadowParams47 = {
- 0x00000fffffffffffull,
- {
- 0x0000130000000000ull, 0x0000220000000000ull, 0x0000440000000000ull,
- }};
-
-static const ShadowMemoryParams ShadowParams40 = {
- 0x0fffffffffull,
- {
- 0x1300000000ull, 0x2200000000ull, 0x4400000000ull,
- }};
-
-// This array is indexed by the ToolType enum.
-static const int ShadowScale[] = {
- 0, // ESAN_None.
- 2, // ESAN_CacheFrag: 4B:1B, so 4 to 1 == >>2.
- 6, // ESAN_WorkingSet: 64B:1B, so 64 to 1 == >>6.
-};
-
-// MaxStructCounterNameSize is a soft size limit to avoid insanely long
-// names for those extremely large structs.
-static const unsigned MaxStructCounterNameSize = 512;
-
-namespace {
-
-static EfficiencySanitizerOptions
-OverrideOptionsFromCL(EfficiencySanitizerOptions Options) {
- if (ClToolCacheFrag)
- Options.ToolType = EfficiencySanitizerOptions::ESAN_CacheFrag;
- else if (ClToolWorkingSet)
- Options.ToolType = EfficiencySanitizerOptions::ESAN_WorkingSet;
-
- // Direct opt invocation with no params will have the default ESAN_None.
- // We run the default tool in that case.
- if (Options.ToolType == EfficiencySanitizerOptions::ESAN_None)
- Options.ToolType = EfficiencySanitizerOptions::ESAN_CacheFrag;
-
- return Options;
-}
-
-/// EfficiencySanitizer: instrument each module to find performance issues.
-class EfficiencySanitizer : public ModulePass {
-public:
- EfficiencySanitizer(
- const EfficiencySanitizerOptions &Opts = EfficiencySanitizerOptions())
- : ModulePass(ID), Options(OverrideOptionsFromCL(Opts)) {}
- StringRef getPassName() const override;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnModule(Module &M) override;
- static char ID;
-
-private:
- bool initOnModule(Module &M);
- void initializeCallbacks(Module &M);
- bool shouldIgnoreStructType(StructType *StructTy);
- void createStructCounterName(
- StructType *StructTy, SmallString<MaxStructCounterNameSize> &NameStr);
- void createCacheFragAuxGV(
- Module &M, const DataLayout &DL, StructType *StructTy,
- GlobalVariable *&TypeNames, GlobalVariable *&Offsets, GlobalVariable *&Size);
- GlobalVariable *createCacheFragInfoGV(Module &M, const DataLayout &DL,
- Constant *UnitName);
- Constant *createEsanInitToolInfoArg(Module &M, const DataLayout &DL);
- void createDestructor(Module &M, Constant *ToolInfoArg);
- bool runOnFunction(Function &F, Module &M);
- bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
- bool instrumentMemIntrinsic(MemIntrinsic *MI);
- bool instrumentGetElementPtr(Instruction *I, Module &M);
- bool insertCounterUpdate(Instruction *I, StructType *StructTy,
- unsigned CounterIdx);
- unsigned getFieldCounterIdx(StructType *StructTy) {
- return 0;
- }
- unsigned getArrayCounterIdx(StructType *StructTy) {
- return StructTy->getNumElements();
- }
- unsigned getStructCounterSize(StructType *StructTy) {
- // The struct counter array includes:
- // - one counter for each struct field,
- // - one counter for the struct access within an array.
- return (StructTy->getNumElements()/*field*/ + 1/*array*/);
- }
- bool shouldIgnoreMemoryAccess(Instruction *I);
- int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL);
- Value *appToShadow(Value *Shadow, IRBuilder<> &IRB);
- bool instrumentFastpath(Instruction *I, const DataLayout &DL, bool IsStore,
- Value *Addr, unsigned Alignment);
- // Each tool has its own fastpath routine:
- bool instrumentFastpathCacheFrag(Instruction *I, const DataLayout &DL,
- Value *Addr, unsigned Alignment);
- bool instrumentFastpathWorkingSet(Instruction *I, const DataLayout &DL,
- Value *Addr, unsigned Alignment);
-
- EfficiencySanitizerOptions Options;
- LLVMContext *Ctx;
- Type *IntptrTy;
- // Our slowpath involves callouts to the runtime library.
- // Access sizes are powers of two: 1, 2, 4, 8, 16.
- static const size_t NumberOfAccessSizes = 5;
- FunctionCallee EsanAlignedLoad[NumberOfAccessSizes];
- FunctionCallee EsanAlignedStore[NumberOfAccessSizes];
- FunctionCallee EsanUnalignedLoad[NumberOfAccessSizes];
- FunctionCallee EsanUnalignedStore[NumberOfAccessSizes];
- // For irregular sizes of any alignment:
- FunctionCallee EsanUnalignedLoadN, EsanUnalignedStoreN;
- FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
- Function *EsanCtorFunction;
- Function *EsanDtorFunction;
- // Remember the counter variable for each struct type to avoid
- // recomputing the variable name later during instrumentation.
- std::map<Type *, GlobalVariable *> StructTyMap;
- ShadowMemoryParams ShadowParams;
-};
-} // namespace
-
-char EfficiencySanitizer::ID = 0;
-INITIALIZE_PASS_BEGIN(
- EfficiencySanitizer, "esan",
- "EfficiencySanitizer: finds performance issues.", false, false)
-INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_END(
- EfficiencySanitizer, "esan",
- "EfficiencySanitizer: finds performance issues.", false, false)
-
-StringRef EfficiencySanitizer::getPassName() const {
- return "EfficiencySanitizer";
-}
-
-void EfficiencySanitizer::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetLibraryInfoWrapperPass>();
-}
-
-ModulePass *
-llvm::createEfficiencySanitizerPass(const EfficiencySanitizerOptions &Options) {
- return new EfficiencySanitizer(Options);
-}
-
-void EfficiencySanitizer::initializeCallbacks(Module &M) {
- IRBuilder<> IRB(M.getContext());
- // Initialize the callbacks.
- for (size_t Idx = 0; Idx < NumberOfAccessSizes; ++Idx) {
- const unsigned ByteSize = 1U << Idx;
- std::string ByteSizeStr = utostr(ByteSize);
- // We'll inline the most common (i.e., aligned and frequent sizes)
- // load + store instrumentation: these callouts are for the slowpath.
- SmallString<32> AlignedLoadName("__esan_aligned_load" + ByteSizeStr);
- EsanAlignedLoad[Idx] = M.getOrInsertFunction(
- AlignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy());
- SmallString<32> AlignedStoreName("__esan_aligned_store" + ByteSizeStr);
- EsanAlignedStore[Idx] = M.getOrInsertFunction(
- AlignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy());
- SmallString<32> UnalignedLoadName("__esan_unaligned_load" + ByteSizeStr);
- EsanUnalignedLoad[Idx] = M.getOrInsertFunction(
- UnalignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy());
- SmallString<32> UnalignedStoreName("__esan_unaligned_store" + ByteSizeStr);
- EsanUnalignedStore[Idx] = M.getOrInsertFunction(
- UnalignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy());
- }
- EsanUnalignedLoadN = M.getOrInsertFunction(
- "__esan_unaligned_loadN", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy);
- EsanUnalignedStoreN = M.getOrInsertFunction(
- "__esan_unaligned_storeN", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy);
- MemmoveFn =
- M.getOrInsertFunction("memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
- IRB.getInt8PtrTy(), IntptrTy);
- MemcpyFn =
- M.getOrInsertFunction("memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
- IRB.getInt8PtrTy(), IntptrTy);
- MemsetFn =
- M.getOrInsertFunction("memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
- IRB.getInt32Ty(), IntptrTy);
-}
-
-bool EfficiencySanitizer::shouldIgnoreStructType(StructType *StructTy) {
- if (StructTy == nullptr || StructTy->isOpaque() /* no struct body */)
- return true;
- return false;
-}
-
-void EfficiencySanitizer::createStructCounterName(
- StructType *StructTy, SmallString<MaxStructCounterNameSize> &NameStr) {
- // Append NumFields and field type ids to avoid struct conflicts
- // with the same name but different fields.
- if (StructTy->hasName())
- NameStr += StructTy->getName();
- else
- NameStr += "struct.anon";
- // We allow the actual size of the StructCounterName to be larger than
- // MaxStructCounterNameSize and append $NumFields and at least one
- // field type id.
- // Append $NumFields.
- NameStr += "$";
- Twine(StructTy->getNumElements()).toVector(NameStr);
- // Append struct field type ids in the reverse order.
- for (int i = StructTy->getNumElements() - 1; i >= 0; --i) {
- NameStr += "$";
- Twine(StructTy->getElementType(i)->getTypeID()).toVector(NameStr);
- if (NameStr.size() >= MaxStructCounterNameSize)
- break;
- }
- if (StructTy->isLiteral()) {
- // End with $ for literal struct.
- NameStr += "$";
- }
-}
-
-// Create global variables with auxiliary information (e.g., struct field size,
-// offset, and type name) for better user report.
-void EfficiencySanitizer::createCacheFragAuxGV(
- Module &M, const DataLayout &DL, StructType *StructTy,
- GlobalVariable *&TypeName, GlobalVariable *&Offset,
- GlobalVariable *&Size) {
- auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
- auto *Int32Ty = Type::getInt32Ty(*Ctx);
- // FieldTypeName.
- auto *TypeNameArrayTy = ArrayType::get(Int8PtrTy, StructTy->getNumElements());
- TypeName = new GlobalVariable(M, TypeNameArrayTy, true,
- GlobalVariable::InternalLinkage, nullptr);
- SmallVector<Constant *, 16> TypeNameVec;
- // FieldOffset.
- auto *OffsetArrayTy = ArrayType::get(Int32Ty, StructTy->getNumElements());
- Offset = new GlobalVariable(M, OffsetArrayTy, true,
- GlobalVariable::InternalLinkage, nullptr);
- SmallVector<Constant *, 16> OffsetVec;
- // FieldSize
- auto *SizeArrayTy = ArrayType::get(Int32Ty, StructTy->getNumElements());
- Size = new GlobalVariable(M, SizeArrayTy, true,
- GlobalVariable::InternalLinkage, nullptr);
- SmallVector<Constant *, 16> SizeVec;
- for (unsigned i = 0; i < StructTy->getNumElements(); ++i) {
- Type *Ty = StructTy->getElementType(i);
- std::string Str;
- raw_string_ostream StrOS(Str);
- Ty->print(StrOS);
- TypeNameVec.push_back(
- ConstantExpr::getPointerCast(
- createPrivateGlobalForString(M, StrOS.str(), true),
- Int8PtrTy));
- OffsetVec.push_back(
- ConstantInt::get(Int32Ty,
- DL.getStructLayout(StructTy)->getElementOffset(i)));
- SizeVec.push_back(ConstantInt::get(Int32Ty,
- DL.getTypeAllocSize(Ty)));
- }
- TypeName->setInitializer(ConstantArray::get(TypeNameArrayTy, TypeNameVec));
- Offset->setInitializer(ConstantArray::get(OffsetArrayTy, OffsetVec));
- Size->setInitializer(ConstantArray::get(SizeArrayTy, SizeVec));
-}
-
-// Create the global variable for the cache-fragmentation tool.
-GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
- Module &M, const DataLayout &DL, Constant *UnitName) {
- assert(Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag);
-
- auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
- auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo();
- auto *Int32Ty = Type::getInt32Ty(*Ctx);
- auto *Int32PtrTy = Type::getInt32PtrTy(*Ctx);
- auto *Int64Ty = Type::getInt64Ty(*Ctx);
- auto *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
- // This structure should be kept consistent with the StructInfo struct
- // in the runtime library.
- // struct StructInfo {
- // const char *StructName;
- // u32 Size;
- // u32 NumFields;
- // u32 *FieldOffset; // auxiliary struct field info.
- // u32 *FieldSize; // auxiliary struct field info.
- // const char **FieldTypeName; // auxiliary struct field info.
- // u64 *FieldCounters;
- // u64 *ArrayCounter;
- // };
- auto *StructInfoTy =
- StructType::get(Int8PtrTy, Int32Ty, Int32Ty, Int32PtrTy, Int32PtrTy,
- Int8PtrPtrTy, Int64PtrTy, Int64PtrTy);
- auto *StructInfoPtrTy = StructInfoTy->getPointerTo();
- // This structure should be kept consistent with the CacheFragInfo struct
- // in the runtime library.
- // struct CacheFragInfo {
- // const char *UnitName;
- // u32 NumStructs;
- // StructInfo *Structs;
- // };
- auto *CacheFragInfoTy = StructType::get(Int8PtrTy, Int32Ty, StructInfoPtrTy);
-
- std::vector<StructType *> Vec = M.getIdentifiedStructTypes();
- unsigned NumStructs = 0;
- SmallVector<Constant *, 16> Initializers;
-
- for (auto &StructTy : Vec) {
- if (shouldIgnoreStructType(StructTy)) {
- ++NumIgnoredStructs;
- continue;
- }
- ++NumStructs;
-
- // StructName.
- SmallString<MaxStructCounterNameSize> CounterNameStr;
- createStructCounterName(StructTy, CounterNameStr);
- GlobalVariable *StructCounterName = createPrivateGlobalForString(
- M, CounterNameStr, /*AllowMerging*/true);
-
- // Counters.
- // We create the counter array with StructCounterName and weak linkage
- // so that the structs with the same name and layout from different
- // compilation units will be merged into one.
- auto *CounterArrayTy = ArrayType::get(Int64Ty,
- getStructCounterSize(StructTy));
- GlobalVariable *Counters =
- new GlobalVariable(M, CounterArrayTy, false,
- GlobalVariable::WeakAnyLinkage,
- ConstantAggregateZero::get(CounterArrayTy),
- CounterNameStr);
-
- // Remember the counter variable for each struct type.
- StructTyMap.insert(std::pair<Type *, GlobalVariable *>(StructTy, Counters));
-
- // We pass the field type name array, offset array, and size array to
- // the runtime for better reporting.
- GlobalVariable *TypeName = nullptr, *Offset = nullptr, *Size = nullptr;
- if (ClAuxFieldInfo)
- createCacheFragAuxGV(M, DL, StructTy, TypeName, Offset, Size);
-
- Constant *FieldCounterIdx[2];
- FieldCounterIdx[0] = ConstantInt::get(Int32Ty, 0);
- FieldCounterIdx[1] = ConstantInt::get(Int32Ty,
- getFieldCounterIdx(StructTy));
- Constant *ArrayCounterIdx[2];
- ArrayCounterIdx[0] = ConstantInt::get(Int32Ty, 0);
- ArrayCounterIdx[1] = ConstantInt::get(Int32Ty,
- getArrayCounterIdx(StructTy));
- Initializers.push_back(ConstantStruct::get(
- StructInfoTy,
- ConstantExpr::getPointerCast(StructCounterName, Int8PtrTy),
- ConstantInt::get(Int32Ty,
- DL.getStructLayout(StructTy)->getSizeInBytes()),
- ConstantInt::get(Int32Ty, StructTy->getNumElements()),
- Offset == nullptr ? ConstantPointerNull::get(Int32PtrTy)
- : ConstantExpr::getPointerCast(Offset, Int32PtrTy),
- Size == nullptr ? ConstantPointerNull::get(Int32PtrTy)
- : ConstantExpr::getPointerCast(Size, Int32PtrTy),
- TypeName == nullptr
- ? ConstantPointerNull::get(Int8PtrPtrTy)
- : ConstantExpr::getPointerCast(TypeName, Int8PtrPtrTy),
- ConstantExpr::getGetElementPtr(CounterArrayTy, Counters,
- FieldCounterIdx),
- ConstantExpr::getGetElementPtr(CounterArrayTy, Counters,
- ArrayCounterIdx)));
- }
- // Structs.
- Constant *StructInfo;
- if (NumStructs == 0) {
- StructInfo = ConstantPointerNull::get(StructInfoPtrTy);
- } else {
- auto *StructInfoArrayTy = ArrayType::get(StructInfoTy, NumStructs);
- StructInfo = ConstantExpr::getPointerCast(
- new GlobalVariable(M, StructInfoArrayTy, false,
- GlobalVariable::InternalLinkage,
- ConstantArray::get(StructInfoArrayTy, Initializers)),
- StructInfoPtrTy);
- }
-
- auto *CacheFragInfoGV = new GlobalVariable(
- M, CacheFragInfoTy, true, GlobalVariable::InternalLinkage,
- ConstantStruct::get(CacheFragInfoTy, UnitName,
- ConstantInt::get(Int32Ty, NumStructs), StructInfo));
- return CacheFragInfoGV;
-}
-
-// Create the tool-specific argument passed to EsanInit and EsanExit.
-Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M,
- const DataLayout &DL) {
- // This structure contains tool-specific information about each compilation
- // unit (module) and is passed to the runtime library.
- GlobalVariable *ToolInfoGV = nullptr;
-
- auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
- // Compilation unit name.
- auto *UnitName = ConstantExpr::getPointerCast(
- createPrivateGlobalForString(M, M.getModuleIdentifier(), true),
- Int8PtrTy);
-
- // Create the tool-specific variable.
- if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag)
- ToolInfoGV = createCacheFragInfoGV(M, DL, UnitName);
-
- if (ToolInfoGV != nullptr)
- return ConstantExpr::getPointerCast(ToolInfoGV, Int8PtrTy);
-
- // Create the null pointer if no tool-specific variable created.
- return ConstantPointerNull::get(Int8PtrTy);
-}
-
-void EfficiencySanitizer::createDestructor(Module &M, Constant *ToolInfoArg) {
- PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
- EsanDtorFunction = Function::Create(FunctionType::get(Type::getVoidTy(*Ctx),
- false),
- GlobalValue::InternalLinkage,
- EsanModuleDtorName, &M);
- ReturnInst::Create(*Ctx, BasicBlock::Create(*Ctx, "", EsanDtorFunction));
- IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator());
- FunctionCallee EsanExit =
- M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(), Int8PtrTy);
- IRB_Dtor.CreateCall(EsanExit, {ToolInfoArg});
- appendToGlobalDtors(M, EsanDtorFunction, EsanCtorAndDtorPriority);
-}
-
-bool EfficiencySanitizer::initOnModule(Module &M) {
-
- Triple TargetTriple(M.getTargetTriple());
- if (TargetTriple.isMIPS64())
- ShadowParams = ShadowParams40;
- else
- ShadowParams = ShadowParams47;
-
- Ctx = &M.getContext();
- const DataLayout &DL = M.getDataLayout();
- IRBuilder<> IRB(M.getContext());
- IntegerType *OrdTy = IRB.getInt32Ty();
- PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
- IntptrTy = DL.getIntPtrType(M.getContext());
- // Create the variable passed to EsanInit and EsanExit.
- Constant *ToolInfoArg = createEsanInitToolInfoArg(M, DL);
- // Constructor
- // We specify the tool type both in the EsanWhichToolName global
- // and as an arg to the init routine as a sanity check.
- std::tie(EsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
- M, EsanModuleCtorName, EsanInitName, /*InitArgTypes=*/{OrdTy, Int8PtrTy},
- /*InitArgs=*/{
- ConstantInt::get(OrdTy, static_cast<int>(Options.ToolType)),
- ToolInfoArg});
- appendToGlobalCtors(M, EsanCtorFunction, EsanCtorAndDtorPriority);
-
- createDestructor(M, ToolInfoArg);
-
- new GlobalVariable(M, OrdTy, true,
- GlobalValue::WeakAnyLinkage,
- ConstantInt::get(OrdTy,
- static_cast<int>(Options.ToolType)),
- EsanWhichToolName);
-
- return true;
-}
-
-Value *EfficiencySanitizer::appToShadow(Value *Shadow, IRBuilder<> &IRB) {
- // Shadow = ((App & Mask) + Offs) >> Scale
- Shadow = IRB.CreateAnd(Shadow, ConstantInt::get(IntptrTy, ShadowParams.ShadowMask));
- uint64_t Offs;
- int Scale = ShadowScale[Options.ToolType];
- if (Scale <= 2)
- Offs = ShadowParams.ShadowOffs[Scale];
- else
- Offs = ShadowParams.ShadowOffs[0] << Scale;
- Shadow = IRB.CreateAdd(Shadow, ConstantInt::get(IntptrTy, Offs));
- if (Scale > 0)
- Shadow = IRB.CreateLShr(Shadow, Scale);
- return Shadow;
-}
-
-bool EfficiencySanitizer::shouldIgnoreMemoryAccess(Instruction *I) {
- if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag) {
- // We'd like to know about cache fragmentation in vtable accesses and
- // constant data references, so we do not currently ignore anything.
- return false;
- } else if (Options.ToolType == EfficiencySanitizerOptions::ESAN_WorkingSet) {
- // TODO: the instrumentation disturbs the data layout on the stack, so we
- // may want to add an option to ignore stack references (if we can
- // distinguish them) to reduce overhead.
- }
- // TODO(bruening): future tools will be returning true for some cases.
- return false;
-}
-
-bool EfficiencySanitizer::runOnModule(Module &M) {
- bool Res = initOnModule(M);
- initializeCallbacks(M);
- for (auto &F : M) {
- Res |= runOnFunction(F, M);
- }
- return Res;
-}
-
-bool EfficiencySanitizer::runOnFunction(Function &F, Module &M) {
- // This is required to prevent instrumenting the call to __esan_init from
- // within the module constructor.
- if (&F == EsanCtorFunction)
- return false;
- SmallVector<Instruction *, 8> LoadsAndStores;
- SmallVector<Instruction *, 8> MemIntrinCalls;
- SmallVector<Instruction *, 8> GetElementPtrs;
- bool Res = false;
- const DataLayout &DL = M.getDataLayout();
- const TargetLibraryInfo *TLI =
- &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
-
- for (auto &BB : F) {
- for (auto &Inst : BB) {
- if ((isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
- isa<AtomicRMWInst>(Inst) || isa<AtomicCmpXchgInst>(Inst)) &&
- !shouldIgnoreMemoryAccess(&Inst))
- LoadsAndStores.push_back(&Inst);
- else if (isa<MemIntrinsic>(Inst))
- MemIntrinCalls.push_back(&Inst);
- else if (isa<GetElementPtrInst>(Inst))
- GetElementPtrs.push_back(&Inst);
- else if (CallInst *CI = dyn_cast<CallInst>(&Inst))
- maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);
- }
- }
-
- if (ClInstrumentLoadsAndStores) {
- for (auto Inst : LoadsAndStores) {
- Res |= instrumentLoadOrStore(Inst, DL);
- }
- }
-
- if (ClInstrumentMemIntrinsics) {
- for (auto Inst : MemIntrinCalls) {
- Res |= instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
- }
- }
-
- if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag) {
- for (auto Inst : GetElementPtrs) {
- Res |= instrumentGetElementPtr(Inst, M);
- }
- }
-
- return Res;
-}
-
-bool EfficiencySanitizer::instrumentLoadOrStore(Instruction *I,
- const DataLayout &DL) {
- IRBuilder<> IRB(I);
- bool IsStore;
- Value *Addr;
- unsigned Alignment;
- if (LoadInst *Load = dyn_cast<LoadInst>(I)) {
- IsStore = false;
- Alignment = Load->getAlignment();
- Addr = Load->getPointerOperand();
- } else if (StoreInst *Store = dyn_cast<StoreInst>(I)) {
- IsStore = true;
- Alignment = Store->getAlignment();
- Addr = Store->getPointerOperand();
- } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
- IsStore = true;
- Alignment = 0;
- Addr = RMW->getPointerOperand();
- } else if (AtomicCmpXchgInst *Xchg = dyn_cast<AtomicCmpXchgInst>(I)) {
- IsStore = true;
- Alignment = 0;
- Addr = Xchg->getPointerOperand();
- } else
- llvm_unreachable("Unsupported mem access type");
-
- Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType();
- const uint32_t TypeSizeBytes = DL.getTypeStoreSizeInBits(OrigTy) / 8;
- FunctionCallee OnAccessFunc = nullptr;
-
- // Convert 0 to the default alignment.
- if (Alignment == 0)
- Alignment = DL.getPrefTypeAlignment(OrigTy);
-
- if (IsStore)
- NumInstrumentedStores++;
- else
- NumInstrumentedLoads++;
- int Idx = getMemoryAccessFuncIndex(Addr, DL);
- if (Idx < 0) {
- OnAccessFunc = IsStore ? EsanUnalignedStoreN : EsanUnalignedLoadN;
- IRB.CreateCall(OnAccessFunc,
- {IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
- ConstantInt::get(IntptrTy, TypeSizeBytes)});
- } else {
- if (ClInstrumentFastpath &&
- instrumentFastpath(I, DL, IsStore, Addr, Alignment)) {
- NumFastpaths++;
- return true;
- }
- if (Alignment == 0 || (Alignment % TypeSizeBytes) == 0)
- OnAccessFunc = IsStore ? EsanAlignedStore[Idx] : EsanAlignedLoad[Idx];
- else
- OnAccessFunc = IsStore ? EsanUnalignedStore[Idx] : EsanUnalignedLoad[Idx];
- IRB.CreateCall(OnAccessFunc,
- IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
- }
- return true;
-}
-
-// It's simplest to replace the memset/memmove/memcpy intrinsics with
-// calls that the runtime library intercepts.
-// Our pass is late enough that calls should not turn back into intrinsics.
-bool EfficiencySanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
- IRBuilder<> IRB(MI);
- bool Res = false;
- if (isa<MemSetInst>(MI)) {
- IRB.CreateCall(
- MemsetFn,
- {IRB.CreatePointerCast(MI->getArgOperand(0), IRB.getInt8PtrTy()),
- IRB.CreateIntCast(MI->getArgOperand(1), IRB.getInt32Ty(), false),
- IRB.CreateIntCast(MI->getArgOperand(2), IntptrTy, false)});
- MI->eraseFromParent();
- Res = true;
- } else if (isa<MemTransferInst>(MI)) {
- IRB.CreateCall(
- isa<MemCpyInst>(MI) ? MemcpyFn : MemmoveFn,
- {IRB.CreatePointerCast(MI->getArgOperand(0), IRB.getInt8PtrTy()),
- IRB.CreatePointerCast(MI->getArgOperand(1), IRB.getInt8PtrTy()),
- IRB.CreateIntCast(MI->getArgOperand(2), IntptrTy, false)});
- MI->eraseFromParent();
- Res = true;
- } else
- llvm_unreachable("Unsupported mem intrinsic type");
- return Res;
-}
-
-bool EfficiencySanitizer::instrumentGetElementPtr(Instruction *I, Module &M) {
- GetElementPtrInst *GepInst = dyn_cast<GetElementPtrInst>(I);
- bool Res = false;
- if (GepInst == nullptr || GepInst->getNumIndices() == 1) {
- ++NumIgnoredGEPs;
- return false;
- }
- Type *SourceTy = GepInst->getSourceElementType();
- StructType *StructTy = nullptr;
- ConstantInt *Idx;
- // Check if GEP calculates address from a struct array.
- if (isa<StructType>(SourceTy)) {
- StructTy = cast<StructType>(SourceTy);
- Idx = dyn_cast<ConstantInt>(GepInst->getOperand(1));
- if ((Idx == nullptr || Idx->getSExtValue() != 0) &&
- !shouldIgnoreStructType(StructTy) && StructTyMap.count(StructTy) != 0)
- Res |= insertCounterUpdate(I, StructTy, getArrayCounterIdx(StructTy));
- }
- // Iterate all (except the first and the last) idx within each GEP instruction
- // for possible nested struct field address calculation.
- for (unsigned i = 1; i < GepInst->getNumIndices(); ++i) {
- SmallVector<Value *, 8> IdxVec(GepInst->idx_begin(),
- GepInst->idx_begin() + i);
- Type *Ty = GetElementPtrInst::getIndexedType(SourceTy, IdxVec);
- unsigned CounterIdx = 0;
- if (isa<ArrayType>(Ty)) {
- ArrayType *ArrayTy = cast<ArrayType>(Ty);
- StructTy = dyn_cast<StructType>(ArrayTy->getElementType());
- if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
- continue;
- // The last counter for struct array access.
- CounterIdx = getArrayCounterIdx(StructTy);
- } else if (isa<StructType>(Ty)) {
- StructTy = cast<StructType>(Ty);
- if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
- continue;
- // Get the StructTy's subfield index.
- Idx = cast<ConstantInt>(GepInst->getOperand(i+1));
- assert(Idx->getSExtValue() >= 0 &&
- Idx->getSExtValue() < StructTy->getNumElements());
- CounterIdx = getFieldCounterIdx(StructTy) + Idx->getSExtValue();
- }
- Res |= insertCounterUpdate(I, StructTy, CounterIdx);
- }
- if (Res)
- ++NumInstrumentedGEPs;
- else
- ++NumIgnoredGEPs;
- return Res;
-}
-
-bool EfficiencySanitizer::insertCounterUpdate(Instruction *I,
- StructType *StructTy,
- unsigned CounterIdx) {
- GlobalVariable *CounterArray = StructTyMap[StructTy];
- if (CounterArray == nullptr)
- return false;
- IRBuilder<> IRB(I);
- Constant *Indices[2];
- // Xref http://llvm.org/docs/LangRef.html#i-getelementptr and
- // http://llvm.org/docs/GetElementPtr.html.
- // The first index of the GEP instruction steps through the first operand,
- // i.e., the array itself.
- Indices[0] = ConstantInt::get(IRB.getInt32Ty(), 0);
- // The second index is the index within the array.
- Indices[1] = ConstantInt::get(IRB.getInt32Ty(), CounterIdx);
- Constant *Counter =
- ConstantExpr::getGetElementPtr(
- ArrayType::get(IRB.getInt64Ty(), getStructCounterSize(StructTy)),
- CounterArray, Indices);
- Value *Load = IRB.CreateLoad(IRB.getInt64Ty(), Counter);
- IRB.CreateStore(IRB.CreateAdd(Load, ConstantInt::get(IRB.getInt64Ty(), 1)),
- Counter);
- return true;
-}
-
-int EfficiencySanitizer::getMemoryAccessFuncIndex(Value *Addr,
- const DataLayout &DL) {
- Type *OrigPtrTy = Addr->getType();
- Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType();
- assert(OrigTy->isSized());
- // The size is always a multiple of 8.
- uint32_t TypeSizeBytes = DL.getTypeStoreSizeInBits(OrigTy) / 8;
- if (TypeSizeBytes != 1 && TypeSizeBytes != 2 && TypeSizeBytes != 4 &&
- TypeSizeBytes != 8 && TypeSizeBytes != 16) {
- // Irregular sizes do not have per-size call targets.
- NumAccessesWithIrregularSize++;
- return -1;
- }
- size_t Idx = countTrailingZeros(TypeSizeBytes);
- assert(Idx < NumberOfAccessSizes);
- return Idx;
-}
-
-bool EfficiencySanitizer::instrumentFastpath(Instruction *I,
- const DataLayout &DL, bool IsStore,
- Value *Addr, unsigned Alignment) {
- if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag) {
- return instrumentFastpathCacheFrag(I, DL, Addr, Alignment);
- } else if (Options.ToolType == EfficiencySanitizerOptions::ESAN_WorkingSet) {
- return instrumentFastpathWorkingSet(I, DL, Addr, Alignment);
- }
- return false;
-}
-
-bool EfficiencySanitizer::instrumentFastpathCacheFrag(Instruction *I,
- const DataLayout &DL,
- Value *Addr,
- unsigned Alignment) {
- // Do nothing.
- return true; // Return true to avoid slowpath instrumentation.
-}
-
-bool EfficiencySanitizer::instrumentFastpathWorkingSet(
- Instruction *I, const DataLayout &DL, Value *Addr, unsigned Alignment) {
- assert(ShadowScale[Options.ToolType] == 6); // The code below assumes this
- IRBuilder<> IRB(I);
- Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType();
- const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
- // Bail to the slowpath if the access might touch multiple cache lines.
- // An access aligned to its size is guaranteed to be intra-cache-line.
- // getMemoryAccessFuncIndex has already ruled out a size larger than 16
- // and thus larger than a cache line for platforms this tool targets
- // (and our shadow memory setup assumes 64-byte cache lines).
- assert(TypeSize <= 128);
- if (!(TypeSize == 8 ||
- (Alignment % (TypeSize / 8)) == 0)) {
- if (ClAssumeIntraCacheLine)
- ++NumAssumedIntraCacheLine;
- else
- return false;
- }
-
- // We inline instrumentation to set the corresponding shadow bits for
- // each cache line touched by the application. Here we handle a single
- // load or store where we've already ruled out the possibility that it
- // might touch more than one cache line and thus we simply update the
- // shadow memory for a single cache line.
- // Our shadow memory model is fine with races when manipulating shadow values.
- // We generate the following code:
- //
- // const char BitMask = 0x81;
- // char *ShadowAddr = appToShadow(AppAddr);
- // if ((*ShadowAddr & BitMask) != BitMask)
- // *ShadowAddr |= Bitmask;
- //
- Value *AddrPtr = IRB.CreatePointerCast(Addr, IntptrTy);
- Value *ShadowPtr = appToShadow(AddrPtr, IRB);
- Type *ShadowTy = IntegerType::get(*Ctx, 8U);
- Type *ShadowPtrTy = PointerType::get(ShadowTy, 0);
- // The bottom bit is used for the current sampling period's working set.
- // The top bit is used for the total working set. We set both on each
- // memory access, if they are not already set.
- Value *ValueMask = ConstantInt::get(ShadowTy, 0x81); // 10000001B
-
- Value *OldValue =
- IRB.CreateLoad(ShadowTy, IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy));
- // The AND and CMP will be turned into a TEST instruction by the compiler.
- Value *Cmp = IRB.CreateICmpNE(IRB.CreateAnd(OldValue, ValueMask), ValueMask);
- Instruction *CmpTerm = SplitBlockAndInsertIfThen(Cmp, I, false);
- // FIXME: do I need to call SetCurrentDebugLocation?
- IRB.SetInsertPoint(CmpTerm);
- // We use OR to set the shadow bits to avoid corrupting the middle 6 bits,
- // which are used by the runtime library.
- Value *NewVal = IRB.CreateOr(OldValue, ValueMask);
- IRB.CreateStore(NewVal, IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy));
- IRB.SetInsertPoint(I);
-
- return true;
-}
diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
index 9ba4b7902e4..1ed0927cd73 100644
--- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
@@ -116,7 +116,6 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) {
initializeThreadSanitizerLegacyPassPass(Registry);
initializeSanitizerCoverageModulePass(Registry);
initializeDataFlowSanitizerPass(Registry);
- initializeEfficiencySanitizerPass(Registry);
}
/// LLVMInitializeInstrumentation - C binding for
diff --git a/llvm/test/Instrumentation/EfficiencySanitizer/str-nobuiltin.ll b/llvm/test/Instrumentation/EfficiencySanitizer/str-nobuiltin.ll
deleted file mode 100644
index 978d3b372bc..00000000000
--- a/llvm/test/Instrumentation/EfficiencySanitizer/str-nobuiltin.ll
+++ /dev/null
@@ -1,33 +0,0 @@
-; Test marking string functions as nobuiltin in efficiency sanitizer.
-;
-; RUN: opt < %s -esan -S | FileCheck %s
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
-target triple = "x86_64-unknown-linux-gnu"
-
-declare i8* @memchr(i8* %a, i32 %b, i64 %c)
-declare i32 @memcmp(i8* %a, i8* %b, i64 %c)
-declare i32 @strcmp(i8* %a, i8* %b)
-declare i8* @strcpy(i8* %a, i8* %b)
-declare i8* @stpcpy(i8* %a, i8* %b)
-declare i64 @strlen(i8* %a)
-declare i64 @strnlen(i8* %a, i64 %b)
-
-; CHECK: call{{.*}}@memchr{{.*}} #[[ATTR:[0-9]+]]
-; CHECK: call{{.*}}@memcmp{{.*}} #[[ATTR]]
-; CHECK: call{{.*}}@strcmp{{.*}} #[[ATTR]]
-; CHECK: call{{.*}}@strcpy{{.*}} #[[ATTR]]
-; CHECK: call{{.*}}@stpcpy{{.*}} #[[ATTR]]
-; CHECK: call{{.*}}@strlen{{.*}} #[[ATTR]]
-; CHECK: call{{.*}}@strnlen{{.*}} #[[ATTR]]
-; attributes #[[ATTR]] = { nobuiltin }
-
-define void @f1(i8* %a, i8* %b) nounwind uwtable {
- tail call i8* @memchr(i8* %a, i32 1, i64 12)
- tail call i32 @memcmp(i8* %a, i8* %b, i64 12)
- tail call i32 @strcmp(i8* %a, i8* %b)
- tail call i8* @strcpy(i8* %a, i8* %b)
- tail call i8* @stpcpy(i8* %a, i8* %b)
- tail call i64 @strlen(i8* %a)
- tail call i64 @strnlen(i8* %a, i64 12)
- ret void
-}
diff --git a/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_count_basic.ll b/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_count_basic.ll
deleted file mode 100644
index 93e0b426333..00000000000
--- a/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_count_basic.ll
+++ /dev/null
@@ -1,157 +0,0 @@
-; Test basic EfficiencySanitizer struct field count instrumentation.
-;
-; RUN: opt < %s -esan -esan-cache-frag -S | FileCheck %s
-
-%struct.A = type { i32, i32 }
-%union.U = type { double }
-%struct.C = type { %struct.anon, %union.anon, [10 x i8] }
-%struct.anon = type { i32, i32 }
-%union.anon = type { double }
-
-; CHECK: @0 = private unnamed_addr constant [8 x i8] c"<stdin>\00", align 1
-; CHECK-NEXT: @1 = private unnamed_addr constant [17 x i8] c"struct.A$2$11$11\00", align 1
-; CHECK-NEXT: @"struct.A$2$11$11" = weak global [3 x i64] zeroinitializer
-; CHECK-NEXT: @2 = internal constant [2 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @5, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @6, i32 0, i32 0)]
-; CHECK-NEXT: @3 = internal constant [2 x i32] [i32 0, i32 4]
-; CHECK-NEXT: @4 = internal constant [2 x i32] [i32 4, i32 4]
-; CHECK-NEXT: @5 = private unnamed_addr constant [4 x i8] c"i32\00", align 1
-; CHECK-NEXT: @6 = private unnamed_addr constant [4 x i8] c"i32\00", align 1
-; CHECK-NEXT: @7 = private unnamed_addr constant [12 x i8] c"union.U$1$3\00", align 1
-; CHECK-NEXT: @"union.U$1$3" = weak global [2 x i64] zeroinitializer
-; CHECK-NEXT: @8 = internal constant [1 x i8*] [i8* getelementptr inbounds ([7 x i8], [7 x i8]* @11, i32 0, i32 0)]
-; CHECK-NEXT: @9 = internal constant [1 x i32] zeroinitializer
-; CHECK-NEXT: @10 = internal constant [1 x i32] [i32 8]
-; CHECK-NEXT: @11 = private unnamed_addr constant [7 x i8] c"double\00", align 1
-; CHECK-NEXT: @12 = private unnamed_addr constant [20 x i8] c"struct.C$3$14$13$13\00", align 1
-; CHECK-NEXT: @"struct.C$3$14$13$13" = weak global [4 x i64] zeroinitializer
-; CHECK-NEXT: @13 = internal constant [3 x i8*] [i8* getelementptr inbounds ([33 x i8], [33 x i8]* @16, i32 0, i32 0), i8* getelementptr inbounds ([30 x i8], [30 x i8]* @17, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @18, i32 0, i32 0)]
-; CHECK-NEXT: @14 = internal constant [3 x i32] [i32 0, i32 8, i32 16]
-; CHECK-NEXT: @15 = internal constant [3 x i32] [i32 8, i32 8, i32 10]
-; CHECK-NEXT: @16 = private unnamed_addr constant [33 x i8] c"%struct.anon = type { i32, i32 }\00", align 1
-; CHECK-NEXT: @17 = private unnamed_addr constant [30 x i8] c"%union.anon = type { double }\00", align 1
-; CHECK-NEXT: @18 = private unnamed_addr constant [10 x i8] c"[10 x i8]\00", align 1
-; CHECK-NEXT: @19 = private unnamed_addr constant [20 x i8] c"struct.anon$2$11$11\00", align 1
-; CHECK-NEXT: @"struct.anon$2$11$11" = weak global [3 x i64] zeroinitializer
-; CHECK-NEXT: @20 = internal constant [2 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @23, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @24, i32 0, i32 0)]
-; CHECK-NEXT: @21 = internal constant [2 x i32] [i32 0, i32 4]
-; CHECK-NEXT: @22 = internal constant [2 x i32] [i32 4, i32 4]
-; CHECK-NEXT: @23 = private unnamed_addr constant [4 x i8] c"i32\00", align 1
-; CHECK-NEXT: @24 = private unnamed_addr constant [4 x i8] c"i32\00", align 1
-; CHECK-NEXT: @25 = private unnamed_addr constant [15 x i8] c"union.anon$1$3\00", align 1
-; CHECK-NEXT: @"union.anon$1$3" = weak global [2 x i64] zeroinitializer
-; CHECK-NEXT: @26 = internal constant [1 x i8*] [i8* getelementptr inbounds ([7 x i8], [7 x i8]* @29, i32 0, i32 0)]
-; CHECK-NEXT: @27 = internal constant [1 x i32] zeroinitializer
-; CHECK-NEXT: @28 = internal constant [1 x i32] [i32 8]
-; CHECK-NEXT: @29 = private unnamed_addr constant [7 x i8] c"double\00", align 1
-; CHECK-NEXT: @30 = internal global [5 x { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }] [{ i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([17 x i8], [17 x i8]* @1, i32 0, i32 0), i32 8, i32 2, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @3, i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* @4, i32 0, i32 0), i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @2, i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 2) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([12 x i8], [12 x i8]* @7, i32 0, i32 0), i32 8, i32 1, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @9, i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* @10, i32 0, i32 0), i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @8, i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.U$1$3", i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.U$1$3", i32 0, i32 1) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @12, i32 0, i32 0), i32 32, i32 3, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @14, i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* @15, i32 0, i32 0), i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @13, i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @19, i32 0, i32 0), i32 8, i32 2, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @21, i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* @22, i32 0, i32 0), i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @20, i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 2) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([15 x i8], [15 x i8]* @25, i32 0, i32 0), i32 8, i32 1, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @27, i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* @28, i32 0, i32 0), i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @26, i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.anon$1$3", i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.anon$1$3", i32 0, i32 1) }]
-; CHECK-NEXT: @31 = internal constant { i8*, i32, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* } { i8* getelementptr inbounds ([8 x i8], [8 x i8]* @0, i32 0, i32 0), i32 5, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* getelementptr inbounds ([5 x { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }], [5 x { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }]* @30, i32 0, i32 0) }
-
-define i32 @main() {
-entry:
- %a = alloca %struct.A, align 4
- %u = alloca %union.U, align 8
- %c = alloca [2 x %struct.C], align 16
- %k = alloca %struct.A*, align 8
- %x = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
- %y = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 1
- %f = bitcast %union.U* %u to float*
- %d = bitcast %union.U* %u to double*
- %arrayidx = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
- %cs = getelementptr inbounds %struct.C, %struct.C* %arrayidx, i32 0, i32 0
- %x1 = getelementptr inbounds %struct.anon, %struct.anon* %cs, i32 0, i32 0
- %arrayidx2 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
- %cs3 = getelementptr inbounds %struct.C, %struct.C* %arrayidx2, i32 0, i32 0
- %y4 = getelementptr inbounds %struct.anon, %struct.anon* %cs3, i32 0, i32 1
- %arrayidx5 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
- %cu = getelementptr inbounds %struct.C, %struct.C* %arrayidx5, i32 0, i32 1
- %f6 = bitcast %union.anon* %cu to float*
- %arrayidx7 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
- %cu8 = getelementptr inbounds %struct.C, %struct.C* %arrayidx7, i32 0, i32 1
- %d9 = bitcast %union.anon* %cu8 to double*
- %arrayidx10 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
- %c11 = getelementptr inbounds %struct.C, %struct.C* %arrayidx10, i32 0, i32 2
- %arrayidx12 = getelementptr inbounds [10 x i8], [10 x i8]* %c11, i64 0, i64 2
- %k1 = load %struct.A*, %struct.A** %k, align 8
- %arrayidx13 = getelementptr inbounds %struct.A, %struct.A* %k1, i64 0
- ret i32 0
-}
-
-; CHECK: @llvm.global_ctors = {{.*}}@esan.module_ctor
-; CHECK: @llvm.global_dtors = {{.*}}@esan.module_dtor
-
-; CHECK: %a = alloca %struct.A, align 4
-; CHECK-NEXT: %u = alloca %union.U, align 8
-; CHECK-NEXT: %c = alloca [2 x %struct.C], align 16
-; CHECK-NEXT: %k = alloca %struct.A*, align 8
-; CHECK-NEXT: %0 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %1 = add i64 %0, 1
-; CHECK-NEXT: store i64 %1, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %x = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
-; CHECK-NEXT: %2 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %3 = add i64 %2, 1
-; CHECK-NEXT: store i64 %3, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %y = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 1
-; CHECK-NEXT: %f = bitcast %union.U* %u to float*
-; CHECK-NEXT: %d = bitcast %union.U* %u to double*
-; CHECK-NEXT: %4 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %5 = add i64 %4, 1
-; CHECK-NEXT: store i64 %5, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
-; CHECK-NEXT: %6 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %7 = add i64 %6, 1
-; CHECK-NEXT: store i64 %7, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %cs = getelementptr inbounds %struct.C, %struct.C* %arrayidx, i32 0, i32 0
-; CHECK-NEXT: %8 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %9 = add i64 %8, 1
-; CHECK-NEXT: store i64 %9, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %x1 = getelementptr inbounds %struct.anon, %struct.anon* %cs, i32 0, i32 0
-; CHECK-NEXT: %10 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %11 = add i64 %10, 1
-; CHECK-NEXT: store i64 %11, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx2 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
-; CHECK-NEXT: %12 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %13 = add i64 %12, 1
-; CHECK-NEXT: store i64 %13, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %cs3 = getelementptr inbounds %struct.C, %struct.C* %arrayidx2, i32 0, i32 0
-; CHECK-NEXT: %14 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %15 = add i64 %14, 1
-; CHECK-NEXT: store i64 %15, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %y4 = getelementptr inbounds %struct.anon, %struct.anon* %cs3, i32 0, i32 1
-; CHECK-NEXT: %16 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %17 = add i64 %16, 1
-; CHECK-NEXT: store i64 %17, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx5 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
-; CHECK-NEXT: %18 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %19 = add i64 %18, 1
-; CHECK-NEXT: store i64 %19, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %cu = getelementptr inbounds %struct.C, %struct.C* %arrayidx5, i32 0, i32 1
-; CHECK-NEXT: %f6 = bitcast %union.anon* %cu to float*
-; CHECK-NEXT: %20 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %21 = add i64 %20, 1
-; CHECK-NEXT: store i64 %21, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx7 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
-; CHECK-NEXT: %22 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %23 = add i64 %22, 1
-; CHECK-NEXT: store i64 %23, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %cu8 = getelementptr inbounds %struct.C, %struct.C* %arrayidx7, i32 0, i32 1
-; CHECK-NEXT: %d9 = bitcast %union.anon* %cu8 to double*
-; CHECK-NEXT: %24 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %25 = add i64 %24, 1
-; CHECK-NEXT: store i64 %25, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx10 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
-; CHECK-NEXT: %26 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 2)
-; CHECK-NEXT: %27 = add i64 %26, 1
-; CHECK-NEXT: store i64 %27, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 2)
-; CHECK-NEXT: %c11 = getelementptr inbounds %struct.C, %struct.C* %arrayidx10, i32 0, i32 2
-; CHECK-NEXT: %arrayidx12 = getelementptr inbounds [10 x i8], [10 x i8]* %c11, i64 0, i64 2
-; CHECK-NEXT: %k1 = load %struct.A*, %struct.A** %k, align 8
-; CHECK-NEXT: %arrayidx13 = getelementptr inbounds %struct.A, %struct.A* %k1, i64 0
-; CHECK-NEXT: ret i32 0
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Top-level:
-
-; CHECK: define internal void @esan.module_ctor()
-; CHECK: call void @__esan_init(i32 1, i8* bitcast ({ i8*, i32, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* }* @31 to i8*))
-; CHECK: define internal void @esan.module_dtor()
-; CHECK: call void @__esan_exit(i8* bitcast ({ i8*, i32, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* }* @31 to i8*))
diff --git a/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_gep.ll b/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_gep.ll
deleted file mode 100644
index a6b08396abb..00000000000
--- a/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_gep.ll
+++ /dev/null
@@ -1,41 +0,0 @@
-; Test the complex GetElementPtr instruction handling in the EfficiencySanitizer
-; cache fragmentation tool.
-;
-; RUN: opt < %s -esan -esan-cache-frag -S | FileCheck %s
-
-; Code from http://llvm.org/docs/LangRef.html#getelementptr-instruction
-; struct RT {
-; char A;
-; int B[10][20];
-; char C;
-; };
-; struct ST {
-; int X;
-; double Y;
-; struct RT Z;
-; };
-;
-; int *foo(struct ST *s) {
-; return &s[1].Z.B[5][13];
-; }
-
-%struct.RT = type { i8, [10 x [20 x i32]], i8 }
-%struct.ST = type { i32, double, %struct.RT }
-
-define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
-entry:
- %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13
- ret i32* %arrayidx
-}
-
-; CHECK: %0 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.ST$3$13$3$11", i32 0, i32 3)
-; CHECK-NEXT: %1 = add i64 %0, 1
-; CHECK-NEXT: store i64 %1, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.ST$3$13$3$11", i32 0, i32 3)
-; CHECK-NEXT: %2 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.ST$3$13$3$11", i32 0, i32 2)
-; CHECK-NEXT: %3 = add i64 %2, 1
-; CHECK-NEXT: store i64 %3, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.ST$3$13$3$11", i32 0, i32 2)
-; CHECK-NEXT: %4 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.RT$3$11$14$11", i32 0, i32 1)
-; CHECK-NEXT: %5 = add i64 %4, 1
-; CHECK-NEXT: store i64 %5, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.RT$3$11$14$11", i32 0, i32 1)
-; CHECK-NEXT: %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13
-; CHECK-NEXT: ret i32* %arrayidx
diff --git a/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_small.ll b/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_small.ll
deleted file mode 100644
index 1c7a46ded59..00000000000
--- a/llvm/test/Instrumentation/EfficiencySanitizer/struct_field_small.ll
+++ /dev/null
@@ -1,133 +0,0 @@
-; Test basic EfficiencySanitizer struct field count instrumentation with -esan-small-binary
-;
-; RUN: opt < %s -esan -esan-cache-frag -esan-aux-field-info=false -S | FileCheck %s
-
-%struct.A = type { i32, i32 }
-%union.U = type { double }
-%struct.C = type { %struct.anon, %union.anon, [10 x i8] }
-%struct.anon = type { i32, i32 }
-%union.anon = type { double }
-
-; CHECK: @0 = private unnamed_addr constant [8 x i8] c"<stdin>\00", align 1
-; CHECK-NEXT: @1 = private unnamed_addr constant [17 x i8] c"struct.A$2$11$11\00", align 1
-; CHECK-NEXT: @"struct.A$2$11$11" = weak global [3 x i64] zeroinitializer
-; CHECK-NEXT: @2 = private unnamed_addr constant [12 x i8] c"union.U$1$3\00", align 1
-; CHECK-NEXT: @"union.U$1$3" = weak global [2 x i64] zeroinitializer
-; CHECK-NEXT: @3 = private unnamed_addr constant [20 x i8] c"struct.C$3$14$13$13\00", align 1
-; CHECK-NEXT: @"struct.C$3$14$13$13" = weak global [4 x i64] zeroinitializer
-; CHECK-NEXT: @4 = private unnamed_addr constant [20 x i8] c"struct.anon$2$11$11\00", align 1
-; CHECK-NEXT: @"struct.anon$2$11$11" = weak global [3 x i64] zeroinitializer
-; CHECK-NEXT: @5 = private unnamed_addr constant [15 x i8] c"union.anon$1$3\00", align 1
-; CHECK-NEXT: @"union.anon$1$3" = weak global [2 x i64] zeroinitializer
-; CHECK-NEXT: @6 = internal global [5 x { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }] [{ i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([17 x i8], [17 x i8]* @1, i32 0, i32 0), i32 8, i32 2, i32* null, i32* null, i8** null, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 2) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([12 x i8], [12 x i8]* @2, i32 0, i32 0), i32 8, i32 1, i32* null, i32* null, i8** null, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.U$1$3", i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.U$1$3", i32 0, i32 1) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @3, i32 0, i32 0), i32 32, i32 3, i32* null, i32* null, i8** null, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @4, i32 0, i32 0), i32 8, i32 2, i32* null, i32* null, i8** null, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 2) }, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* } { i8* getelementptr inbounds ([15 x i8], [15 x i8]* @5, i32 0, i32 0), i32 8, i32 1, i32* null, i32* null, i8** null, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.anon$1$3", i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* @"union.anon$1$3", i32 0, i32 1) }]
-; CHECK-NEXT: @7 = internal constant { i8*, i32, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* } { i8* getelementptr inbounds ([8 x i8], [8 x i8]* @0, i32 0, i32 0), i32 5, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* getelementptr inbounds ([5 x { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }], [5 x { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }]* @6, i32 0, i32 0) }
-
-define i32 @main() {
-entry:
- %a = alloca %struct.A, align 4
- %u = alloca %union.U, align 8
- %c = alloca [2 x %struct.C], align 16
- %k = alloca %struct.A*, align 8
- %x = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
- %y = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 1
- %f = bitcast %union.U* %u to float*
- %d = bitcast %union.U* %u to double*
- %arrayidx = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
- %cs = getelementptr inbounds %struct.C, %struct.C* %arrayidx, i32 0, i32 0
- %x1 = getelementptr inbounds %struct.anon, %struct.anon* %cs, i32 0, i32 0
- %arrayidx2 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
- %cs3 = getelementptr inbounds %struct.C, %struct.C* %arrayidx2, i32 0, i32 0
- %y4 = getelementptr inbounds %struct.anon, %struct.anon* %cs3, i32 0, i32 1
- %arrayidx5 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
- %cu = getelementptr inbounds %struct.C, %struct.C* %arrayidx5, i32 0, i32 1
- %f6 = bitcast %union.anon* %cu to float*
- %arrayidx7 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
- %cu8 = getelementptr inbounds %struct.C, %struct.C* %arrayidx7, i32 0, i32 1
- %d9 = bitcast %union.anon* %cu8 to double*
- %arrayidx10 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
- %c11 = getelementptr inbounds %struct.C, %struct.C* %arrayidx10, i32 0, i32 2
- %arrayidx12 = getelementptr inbounds [10 x i8], [10 x i8]* %c11, i64 0, i64 2
- %k1 = load %struct.A*, %struct.A** %k, align 8
- %arrayidx13 = getelementptr inbounds %struct.A, %struct.A* %k1, i64 0
- ret i32 0
-}
-
-; CHECK: @llvm.global_ctors = {{.*}}@esan.module_ctor
-; CHECK: @llvm.global_dtors = {{.*}}@esan.module_dtor
-
-; CHECK: %a = alloca %struct.A, align 4
-; CHECK-NEXT: %u = alloca %union.U, align 8
-; CHECK-NEXT: %c = alloca [2 x %struct.C], align 16
-; CHECK-NEXT: %k = alloca %struct.A*, align 8
-; CHECK-NEXT: %0 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %1 = add i64 %0, 1
-; CHECK-NEXT: store i64 %1, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %x = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
-; CHECK-NEXT: %2 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %3 = add i64 %2, 1
-; CHECK-NEXT: store i64 %3, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.A$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %y = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 1
-; CHECK-NEXT: %f = bitcast %union.U* %u to float*
-; CHECK-NEXT: %d = bitcast %union.U* %u to double*
-; CHECK-NEXT: %4 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %5 = add i64 %4, 1
-; CHECK-NEXT: store i64 %5, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
-; CHECK-NEXT: %6 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %7 = add i64 %6, 1
-; CHECK-NEXT: store i64 %7, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %cs = getelementptr inbounds %struct.C, %struct.C* %arrayidx, i32 0, i32 0
-; CHECK-NEXT: %8 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %9 = add i64 %8, 1
-; CHECK-NEXT: store i64 %9, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 0)
-; CHECK-NEXT: %x1 = getelementptr inbounds %struct.anon, %struct.anon* %cs, i32 0, i32 0
-; CHECK-NEXT: %10 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %11 = add i64 %10, 1
-; CHECK-NEXT: store i64 %11, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx2 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
-; CHECK-NEXT: %12 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %13 = add i64 %12, 1
-; CHECK-NEXT: store i64 %13, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 0)
-; CHECK-NEXT: %cs3 = getelementptr inbounds %struct.C, %struct.C* %arrayidx2, i32 0, i32 0
-; CHECK-NEXT: %14 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %15 = add i64 %14, 1
-; CHECK-NEXT: store i64 %15, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @"struct.anon$2$11$11", i32 0, i32 1)
-; CHECK-NEXT: %y4 = getelementptr inbounds %struct.anon, %struct.anon* %cs3, i32 0, i32 1
-; CHECK-NEXT: %16 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %17 = add i64 %16, 1
-; CHECK-NEXT: store i64 %17, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx5 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
-; CHECK-NEXT: %18 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %19 = add i64 %18, 1
-; CHECK-NEXT: store i64 %19, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %cu = getelementptr inbounds %struct.C, %struct.C* %arrayidx5, i32 0, i32 1
-; CHECK-NEXT: %f6 = bitcast %union.anon* %cu to float*
-; CHECK-NEXT: %20 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %21 = add i64 %20, 1
-; CHECK-NEXT: store i64 %21, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx7 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 1
-; CHECK-NEXT: %22 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %23 = add i64 %22, 1
-; CHECK-NEXT: store i64 %23, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 1)
-; CHECK-NEXT: %cu8 = getelementptr inbounds %struct.C, %struct.C* %arrayidx7, i32 0, i32 1
-; CHECK-NEXT: %d9 = bitcast %union.anon* %cu8 to double*
-; CHECK-NEXT: %24 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %25 = add i64 %24, 1
-; CHECK-NEXT: store i64 %25, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 3)
-; CHECK-NEXT: %arrayidx10 = getelementptr inbounds [2 x %struct.C], [2 x %struct.C]* %c, i64 0, i64 0
-; CHECK-NEXT: %26 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 2)
-; CHECK-NEXT: %27 = add i64 %26, 1
-; CHECK-NEXT: store i64 %27, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @"struct.C$3$14$13$13", i32 0, i32 2)
-; CHECK-NEXT: %c11 = getelementptr inbounds %struct.C, %struct.C* %arrayidx10, i32 0, i32 2
-; CHECK-NEXT: %arrayidx12 = getelementptr inbounds [10 x i8], [10 x i8]* %c11, i64 0, i64 2
-; CHECK-NEXT: %k1 = load %struct.A*, %struct.A** %k, align 8
-; CHECK-NEXT: %arrayidx13 = getelementptr inbounds %struct.A, %struct.A* %k1, i64 0
-; CHECK-NEXT: ret i32 0
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Top-level:
-
-; CHECK: define internal void @esan.module_ctor()
-; CHECK: call void @__esan_init(i32 1, i8* bitcast ({ i8*, i32, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* }* @7 to i8*))
-; CHECK: define internal void @esan.module_dtor()
-; CHECK: call void @__esan_exit(i8* bitcast ({ i8*, i32, { i8*, i32, i32, i32*, i32*, i8**, i64*, i64* }* }* @7 to i8*))
diff --git a/llvm/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll b/llvm/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll
deleted file mode 100644
index 75d1aa0697b..00000000000
--- a/llvm/test/Instrumentation/EfficiencySanitizer/working_set_basic.ll
+++ /dev/null
@@ -1,275 +0,0 @@
-; Test basic EfficiencySanitizer working set instrumentation.
-;
-; RUN: opt < %s -esan -esan-working-set -S | FileCheck %s
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Intra-cache-line
-
-define i8 @aligned1(i8* %a) {
-entry:
- %tmp1 = load i8, i8* %a, align 1
- ret i8 %tmp1
-; CHECK: @llvm.global_ctors = {{.*}}@esan.module_ctor
-; CHECK: %0 = ptrtoint i8* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i8, i8* %a, align 1
-; CHECK-NEXT: ret i8 %tmp1
-}
-
-define i16 @aligned2(i16* %a) {
-entry:
- %tmp1 = load i16, i16* %a, align 2
- ret i16 %tmp1
-; CHECK: %0 = ptrtoint i16* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i16, i16* %a, align 2
-; CHECK-NEXT: ret i16 %tmp1
-}
-
-define i32 @aligned4(i32* %a) {
-entry:
- %tmp1 = load i32, i32* %a, align 4
- ret i32 %tmp1
-; CHECK: %0 = ptrtoint i32* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i32, i32* %a, align 4
-; CHECK-NEXT: ret i32 %tmp1
-}
-
-define i64 @aligned8(i64* %a) {
-entry:
- %tmp1 = load i64, i64* %a, align 8
- ret i64 %tmp1
-; CHECK: %0 = ptrtoint i64* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i64, i64* %a, align 8
-; CHECK-NEXT: ret i64 %tmp1
-}
-
-define i128 @aligned16(i128* %a) {
-entry:
- %tmp1 = load i128, i128* %a, align 16
- ret i128 %tmp1
-; CHECK: %0 = ptrtoint i128* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i128, i128* %a, align 16
-; CHECK-NEXT: ret i128 %tmp1
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Not guaranteed to be intra-cache-line, but our defaults are to
-; assume they are:
-
-define i16 @unaligned2(i16* %a) {
-entry:
- %tmp1 = load i16, i16* %a, align 1
- ret i16 %tmp1
-; CHECK: %0 = ptrtoint i16* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i16, i16* %a, align 1
-; CHECK-NEXT: ret i16 %tmp1
-}
-
-define i32 @unaligned4(i32* %a) {
-entry:
- %tmp1 = load i32, i32* %a, align 2
- ret i32 %tmp1
-; CHECK: %0 = ptrtoint i32* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i32, i32* %a, align 2
-; CHECK-NEXT: ret i32 %tmp1
-}
-
-define i64 @unaligned8(i64* %a) {
-entry:
- %tmp1 = load i64, i64* %a, align 4
- ret i64 %tmp1
-; CHECK: %0 = ptrtoint i64* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i64, i64* %a, align 4
-; CHECK-NEXT: ret i64 %tmp1
-}
-
-define i128 @unaligned16(i128* %a) {
-entry:
- %tmp1 = load i128, i128* %a, align 8
- ret i128 %tmp1
-; CHECK: %0 = ptrtoint i128* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i128, i128* %a, align 8
-; CHECK-NEXT: ret i128 %tmp1
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Ensure that esan converts intrinsics to calls:
-
-declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
-declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
-declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
-
-define void @memCpyTest(i8* nocapture %x, i8* nocapture %y) {
-entry:
- tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false)
- ret void
-; CHECK: define void @memCpyTest
-; CHECK: call i8* @memcpy
-; CHECK: ret void
-}
-
-define void @memMoveTest(i8* nocapture %x, i8* nocapture %y) {
-entry:
- tail call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false)
- ret void
-; CHECK: define void @memMoveTest
-; CHECK: call i8* @memmove
-; CHECK: ret void
-}
-
-define void @memSetTest(i8* nocapture %x) {
-entry:
- tail call void @llvm.memset.p0i8.i64(i8* align 4 %x, i8 77, i64 16, i1 false)
- ret void
-; CHECK: define void @memSetTest
-; CHECK: call i8* @memset
-; CHECK: ret void
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Ensure that esan doesn't convert element atomic memory intrinsics to
-; calls.
-
-declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture writeonly, i8, i64, i32) nounwind
-declare void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32) nounwind
-declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32) nounwind
-
-define void @elementAtomic_memCpyTest(i8* nocapture %x, i8* nocapture %y) {
- ; CHECK-LABEL: elementAtomic_memCpyTest
- ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ; CHECK-NEXT: ret void
- tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ret void
-}
-
-define void @elementAtomic_memMoveTest(i8* nocapture %x, i8* nocapture %y) {
- ; CHECK-LABEL: elementAtomic_memMoveTest
- ; CHECK-NEXT: tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ; CHECK-NEXT: ret void
- tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ret void
-}
-
-define void @elementAtomic_memSetTest(i8* nocapture %x) {
- ; CHECK-LABEL: elementAtomic_memSetTest
- ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %x, i8 77, i64 16, i32 1)
- ; CHECK-NEXT: ret void
- tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %x, i8 77, i64 16, i32 1)
- ret void
-}
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Top-level:
-
-; CHECK: define internal void @esan.module_ctor()
-; CHECK: call void @__esan_init(i32 2, i8* null)
-; CHECK: define internal void @esan.module_dtor()
-; CHECK: call void @__esan_exit(i8* null)
diff --git a/llvm/test/Instrumentation/EfficiencySanitizer/working_set_slow.ll b/llvm/test/Instrumentation/EfficiencySanitizer/working_set_slow.ll
deleted file mode 100644
index 3937d0ce2c7..00000000000
--- a/llvm/test/Instrumentation/EfficiencySanitizer/working_set_slow.ll
+++ /dev/null
@@ -1,291 +0,0 @@
-; Test basic EfficiencySanitizer slowpath instrumentation.
-;
-; RUN: opt < %s -esan -esan-working-set -esan-instrument-fastpath=false -S | FileCheck %s
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Aligned loads:
-
-define i8 @loadAligned1(i8* %a) {
-entry:
- %tmp1 = load i8, i8* %a, align 1
- ret i8 %tmp1
-; CHECK: @llvm.global_ctors = {{.*}}@esan.module_ctor
-; CHECK: call void @__esan_aligned_load1(i8* %a)
-; CHECK-NEXT: %tmp1 = load i8, i8* %a, align 1
-; CHECK-NEXT: ret i8 %tmp1
-}
-
-define i16 @loadAligned2(i16* %a) {
-entry:
- %tmp1 = load i16, i16* %a, align 2
- ret i16 %tmp1
-; CHECK: %0 = bitcast i16* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_load2(i8* %0)
-; CHECK-NEXT: %tmp1 = load i16, i16* %a, align 2
-; CHECK-NEXT: ret i16 %tmp1
-}
-
-define i32 @loadAligned4(i32* %a) {
-entry:
- %tmp1 = load i32, i32* %a, align 4
- ret i32 %tmp1
-; CHECK: %0 = bitcast i32* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_load4(i8* %0)
-; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 4
-; CHECK-NEXT: ret i32 %tmp1
-}
-
-define i64 @loadAligned8(i64* %a) {
-entry:
- %tmp1 = load i64, i64* %a, align 8
- ret i64 %tmp1
-; CHECK: %0 = bitcast i64* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_load8(i8* %0)
-; CHECK-NEXT: %tmp1 = load i64, i64* %a, align 8
-; CHECK-NEXT: ret i64 %tmp1
-}
-
-define i128 @loadAligned16(i128* %a) {
-entry:
- %tmp1 = load i128, i128* %a, align 16
- ret i128 %tmp1
-; CHECK: %0 = bitcast i128* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_load16(i8* %0)
-; CHECK-NEXT: %tmp1 = load i128, i128* %a, align 16
-; CHECK-NEXT: ret i128 %tmp1
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Aligned stores:
-
-define void @storeAligned1(i8* %a) {
-entry:
- store i8 1, i8* %a, align 1
- ret void
-; CHECK: call void @__esan_aligned_store1(i8* %a)
-; CHECK-NEXT: store i8 1, i8* %a, align 1
-; CHECK-NEXT: ret void
-}
-
-define void @storeAligned2(i16* %a) {
-entry:
- store i16 1, i16* %a, align 2
- ret void
-; CHECK: %0 = bitcast i16* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_store2(i8* %0)
-; CHECK-NEXT: store i16 1, i16* %a, align 2
-; CHECK-NEXT: ret void
-}
-
-define void @storeAligned4(i32* %a) {
-entry:
- store i32 1, i32* %a, align 4
- ret void
-; CHECK: %0 = bitcast i32* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_store4(i8* %0)
-; CHECK-NEXT: store i32 1, i32* %a, align 4
-; CHECK-NEXT: ret void
-}
-
-define void @storeAligned8(i64* %a) {
-entry:
- store i64 1, i64* %a, align 8
- ret void
-; CHECK: %0 = bitcast i64* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_store8(i8* %0)
-; CHECK-NEXT: store i64 1, i64* %a, align 8
-; CHECK-NEXT: ret void
-}
-
-define void @storeAligned16(i128* %a) {
-entry:
- store i128 1, i128* %a, align 16
- ret void
-; CHECK: %0 = bitcast i128* %a to i8*
-; CHECK-NEXT: call void @__esan_aligned_store16(i8* %0)
-; CHECK-NEXT: store i128 1, i128* %a, align 16
-; CHECK-NEXT: ret void
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Unaligned loads:
-
-define i16 @loadUnaligned2(i16* %a) {
-entry:
- %tmp1 = load i16, i16* %a, align 1
- ret i16 %tmp1
-; CHECK: %0 = bitcast i16* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load2(i8* %0)
-; CHECK-NEXT: %tmp1 = load i16, i16* %a, align 1
-; CHECK-NEXT: ret i16 %tmp1
-}
-
-define i32 @loadUnaligned4(i32* %a) {
-entry:
- %tmp1 = load i32, i32* %a, align 1
- ret i32 %tmp1
-; CHECK: %0 = bitcast i32* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load4(i8* %0)
-; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 1
-; CHECK-NEXT: ret i32 %tmp1
-}
-
-define i64 @loadUnaligned8(i64* %a) {
-entry:
- %tmp1 = load i64, i64* %a, align 1
- ret i64 %tmp1
-; CHECK: %0 = bitcast i64* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load8(i8* %0)
-; CHECK-NEXT: %tmp1 = load i64, i64* %a, align 1
-; CHECK-NEXT: ret i64 %tmp1
-}
-
-define i128 @loadUnaligned16(i128* %a) {
-entry:
- %tmp1 = load i128, i128* %a, align 1
- ret i128 %tmp1
-; CHECK: %0 = bitcast i128* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load16(i8* %0)
-; CHECK-NEXT: %tmp1 = load i128, i128* %a, align 1
-; CHECK-NEXT: ret i128 %tmp1
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Unaligned stores:
-
-define void @storeUnaligned2(i16* %a) {
-entry:
- store i16 1, i16* %a, align 1
- ret void
-; CHECK: %0 = bitcast i16* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_store2(i8* %0)
-; CHECK-NEXT: store i16 1, i16* %a, align 1
-; CHECK-NEXT: ret void
-}
-
-define void @storeUnaligned4(i32* %a) {
-entry:
- store i32 1, i32* %a, align 1
- ret void
-; CHECK: %0 = bitcast i32* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_store4(i8* %0)
-; CHECK-NEXT: store i32 1, i32* %a, align 1
-; CHECK-NEXT: ret void
-}
-
-define void @storeUnaligned8(i64* %a) {
-entry:
- store i64 1, i64* %a, align 1
- ret void
-; CHECK: %0 = bitcast i64* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_store8(i8* %0)
-; CHECK-NEXT: store i64 1, i64* %a, align 1
-; CHECK-NEXT: ret void
-}
-
-define void @storeUnaligned16(i128* %a) {
-entry:
- store i128 1, i128* %a, align 1
- ret void
-; CHECK: %0 = bitcast i128* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_store16(i8* %0)
-; CHECK-NEXT: store i128 1, i128* %a, align 1
-; CHECK-NEXT: ret void
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Unusual loads and stores:
-
-define x86_fp80 @loadUnalignedFP(x86_fp80* %a) {
-entry:
- %tmp1 = load x86_fp80, x86_fp80* %a, align 1
- ret x86_fp80 %tmp1
-; CHECK: %0 = bitcast x86_fp80* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_loadN(i8* %0, i64 10)
-; CHECK-NEXT: %tmp1 = load x86_fp80, x86_fp80* %a, align 1
-; CHECK-NEXT: ret x86_fp80 %tmp1
-}
-
-define void @storeUnalignedFP(x86_fp80* %a) {
-entry:
- store x86_fp80 0xK00000000000000000000, x86_fp80* %a, align 1
- ret void
-; CHECK: %0 = bitcast x86_fp80* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_storeN(i8* %0, i64 10)
-; CHECK-NEXT: store x86_fp80 0xK00000000000000000000, x86_fp80* %a, align 1
-; CHECK-NEXT: ret void
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Ensure that esan converts memcpy intrinsics to calls:
-
-declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
-declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
-declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
-
-define void @memCpyTest(i8* nocapture %x, i8* nocapture %y) {
-entry:
- tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false)
- ret void
-; CHECK: define void @memCpyTest
-; CHECK: call i8* @memcpy
-; CHECK: ret void
-}
-
-define void @memMoveTest(i8* nocapture %x, i8* nocapture %y) {
-entry:
- tail call void @llvm.memmove.p0i8.p0i8.i64(i8* align 4 %x, i8* align 4 %y, i64 16, i1 false)
- ret void
-; CHECK: define void @memMoveTest
-; CHECK: call i8* @memmove
-; CHECK: ret void
-}
-
-define void @memSetTest(i8* nocapture %x) {
-entry:
- tail call void @llvm.memset.p0i8.i64(i8* align 4 %x, i8 77, i64 16, i1 false)
- ret void
-; CHECK: define void @memSetTest
-; CHECK: call i8* @memset
-; CHECK: ret void
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Ensure that esan doesn't convert element atomic memory intrinsics to
-; calls.
-
-declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture writeonly, i8, i64, i32) nounwind
-declare void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32) nounwind
-declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32) nounwind
-
-define void @elementAtomic_memCpyTest(i8* nocapture %x, i8* nocapture %y) {
- ; CHECK-LABEL: elementAtomic_memCpyTest
- ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ; CHECK-NEXT: ret void
- tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ret void
-}
-
-define void @elementAtomic_memMoveTest(i8* nocapture %x, i8* nocapture %y) {
- ; CHECK-LABEL: elementAtomic_memMoveTest
- ; CHECK-NEXT: tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ; CHECK-NEXT: ret void
- tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %x, i8* align 1 %y, i64 16, i32 1)
- ret void
-}
-
-define void @elementAtomic_memSetTest(i8* nocapture %x) {
- ; CHECK-LABEL: elementAtomic_memSetTest
- ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %x, i8 77, i64 16, i32 1)
- ; CHECK-NEXT: ret void
- tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %x, i8 77, i64 16, i32 1)
- ret void
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Top-level:
-
-; CHECK: define internal void @esan.module_ctor()
-; CHECK: call void @__esan_init(i32 2, i8* null)
-; CHECK: define internal void @esan.module_dtor()
-; CHECK: call void @__esan_exit(i8* null)
diff --git a/llvm/test/Instrumentation/EfficiencySanitizer/working_set_strict.ll b/llvm/test/Instrumentation/EfficiencySanitizer/working_set_strict.ll
deleted file mode 100644
index 6eaa5e36a2a..00000000000
--- a/llvm/test/Instrumentation/EfficiencySanitizer/working_set_strict.ll
+++ /dev/null
@@ -1,156 +0,0 @@
-; Test EfficiencySanitizer working set instrumentation without aggressive
-; optimization flags.
-;
-; RUN: opt < %s -esan -esan-working-set -esan-assume-intra-cache-line=0 -S | FileCheck %s
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Intra-cache-line
-
-define i8 @aligned1(i8* %a) {
-entry:
- %tmp1 = load i8, i8* %a, align 1
- ret i8 %tmp1
-; CHECK: @llvm.global_ctors = {{.*}}@esan.module_ctor
-; CHECK: %0 = ptrtoint i8* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i8, i8* %a, align 1
-; CHECK-NEXT: ret i8 %tmp1
-}
-
-define i16 @aligned2(i16* %a) {
-entry:
- %tmp1 = load i16, i16* %a, align 2
- ret i16 %tmp1
-; CHECK: %0 = ptrtoint i16* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i16, i16* %a, align 2
-; CHECK-NEXT: ret i16 %tmp1
-}
-
-define i32 @aligned4(i32* %a) {
-entry:
- %tmp1 = load i32, i32* %a, align 4
- ret i32 %tmp1
-; CHECK: %0 = ptrtoint i32* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i32, i32* %a, align 4
-; CHECK-NEXT: ret i32 %tmp1
-}
-
-define i64 @aligned8(i64* %a) {
-entry:
- %tmp1 = load i64, i64* %a, align 8
- ret i64 %tmp1
-; CHECK: %0 = ptrtoint i64* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i64, i64* %a, align 8
-; CHECK-NEXT: ret i64 %tmp1
-}
-
-define i128 @aligned16(i128* %a) {
-entry:
- %tmp1 = load i128, i128* %a, align 16
- ret i128 %tmp1
-; CHECK: %0 = ptrtoint i128* %a to i64
-; CHECK-NEXT: %1 = and i64 %0, 17592186044415
-; CHECK-NEXT: %2 = add i64 %1, 1337006139375616
-; CHECK-NEXT: %3 = lshr i64 %2, 6
-; CHECK-NEXT: %4 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: %5 = load i8, i8* %4
-; CHECK-NEXT: %6 = and i8 %5, -127
-; CHECK-NEXT: %7 = icmp ne i8 %6, -127
-; CHECK-NEXT: br i1 %7, label %8, label %11
-; CHECK: %9 = or i8 %5, -127
-; CHECK-NEXT: %10 = inttoptr i64 %3 to i8*
-; CHECK-NEXT: store i8 %9, i8* %10
-; CHECK-NEXT: br label %11
-; CHECK: %tmp1 = load i128, i128* %a, align 16
-; CHECK-NEXT: ret i128 %tmp1
-}
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Not guaranteed to be intra-cache-line
-
-define i16 @unaligned2(i16* %a) {
-entry:
- %tmp1 = load i16, i16* %a, align 1
- ret i16 %tmp1
-; CHECK: %0 = bitcast i16* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load2(i8* %0)
-; CHECK-NEXT: %tmp1 = load i16, i16* %a, align 1
-; CHECK-NEXT: ret i16 %tmp1
-}
-
-define i32 @unaligned4(i32* %a) {
-entry:
- %tmp1 = load i32, i32* %a, align 2
- ret i32 %tmp1
-; CHECK: %0 = bitcast i32* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load4(i8* %0)
-; CHECK-NEXT: %tmp1 = load i32, i32* %a, align 2
-; CHECK-NEXT: ret i32 %tmp1
-}
-
-define i64 @unaligned8(i64* %a) {
-entry:
- %tmp1 = load i64, i64* %a, align 4
- ret i64 %tmp1
-; CHECK: %0 = bitcast i64* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load8(i8* %0)
-; CHECK-NEXT: %tmp1 = load i64, i64* %a, align 4
-; CHECK-NEXT: ret i64 %tmp1
-}
-
-define i128 @unaligned16(i128* %a) {
-entry:
- %tmp1 = load i128, i128* %a, align 8
- ret i128 %tmp1
-; CHECK: %0 = bitcast i128* %a to i8*
-; CHECK-NEXT: call void @__esan_unaligned_load16(i8* %0)
-; CHECK-NEXT: %tmp1 = load i128, i128* %a, align 8
-; CHECK-NEXT: ret i128 %tmp1
-}
diff --git a/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn
index 39aac9fd933..446df713820 100644
--- a/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/include/BUILD.gn
@@ -7,7 +7,6 @@ copy("include") {
"sanitizer/common_interface_defs.h",
"sanitizer/coverage_interface.h",
"sanitizer/dfsan_interface.h",
- "sanitizer/esan_interface.h",
"sanitizer/hwasan_interface.h",
"sanitizer/linux_syscall_hooks.h",
"sanitizer/lsan_interface.h",
diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn
index 474c3b62598..0c4c2e27785 100644
--- a/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn
@@ -157,7 +157,4 @@ source_set("sources") {
"sanitizer_win_dll_thunk.h",
"sanitizer_win_weak_interception.h",
]
- if (current_cpu == "x64") {
- sources += [ "sanitizer_linux_x86_64.S" ]
- }
}
diff --git a/llvm/utils/gn/secondary/llvm/lib/Transforms/Instrumentation/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Transforms/Instrumentation/BUILD.gn
index c381dfd76e0..14dd7097c87 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Transforms/Instrumentation/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Transforms/Instrumentation/BUILD.gn
@@ -14,7 +14,6 @@ static_library("Instrumentation") {
"CGProfile.cpp",
"ControlHeightReduction.cpp",
"DataFlowSanitizer.cpp",
- "EfficiencySanitizer.cpp",
"GCOVProfiling.cpp",
"HWAddressSanitizer.cpp",
"IndirectCallPromotion.cpp",
OpenPOWER on IntegriCloud