summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.h2
-rw-r--r--clang/include/clang/Driver/CC1Options.td2
-rw-r--r--clang/include/clang/Driver/Options.td4
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h1
-rw-r--r--clang/lib/CodeGen/CGCall.cpp6
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp17
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/test/CodeGen/default-function-attr.c6
-rw-r--r--clang/test/Driver/fsanitize.c8
-rw-r--r--compiler-rt/lib/hwasan/hwasan_interceptors.cc30
-rw-r--r--compiler-rt/lib/hwasan/hwasan_linux.cc7
-rw-r--r--llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp29
-rw-r--r--llvm/test/Instrumentation/HWAddressSanitizer/lazy-thread-init.ll25
13 files changed, 106 insertions, 33 deletions
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index a12744ee3d2..ec6eda7fb78 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -286,6 +286,8 @@ public:
/// Set of XRay instrumentation kinds to emit.
XRayInstrSet XRayInstrumentationBundle;
+ std::vector<std::string> DefaultFunctionAttrs;
+
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
index c0e73e56d7a..07c76884063 100644
--- a/clang/include/clang/Driver/CC1Options.td
+++ b/clang/include/clang/Driver/CC1Options.td
@@ -163,6 +163,8 @@ let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
def debug_info_macro : Flag<["-"], "debug-info-macro">,
HelpText<"Emit macro debug information">;
+def default_function_attr : Separate<["-"], "default-function-attr">,
+ HelpText<"Apply given attribute to all functions">;
def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 809b28b9ddb..1c5cae683a1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -998,6 +998,10 @@ def fno_sanitize_address_use_odr_indicator
: Flag<["-"], "fno-sanitize-address-use-odr-indicator">,
Group<f_clang_Group>,
HelpText<"Disable ODR indicator globals">;
+def fsanitize_hwaddress_abi_EQ
+ : Joined<["-"], "fsanitize-hwaddress-abi=">,
+ Group<f_clang_Group>,
+ HelpText<"Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor)">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
Flags<[CoreOption, DriverOption]>,
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 55c5826bfb0..02338c22165 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -39,6 +39,7 @@ class SanitizerArgs {
bool AsanPoisonCustomArrayCookie = false;
bool AsanGlobalsDeadStripping = false;
bool AsanUseOdrIndicator = false;
+ std::string HwasanAbi;
bool LinkCXXRuntimes = false;
bool NeedPIE = false;
bool SafeStackRuntime = false;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 64e18e171e0..09116d465e3 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1816,6 +1816,12 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
if (CodeGenOpts.FlushDenorm)
FuncAttrs.addAttribute("nvptx-f32ftz", "true");
}
+
+ for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) {
+ StringRef Var, Value;
+ std::tie(Var, Value) = Attr.split('=');
+ FuncAttrs.addAttribute(Var, Value);
+ }
}
void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 4e0d7491bbe..6667cbb347c 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -741,6 +741,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
AsanUseAfterScope = false;
}
+ if (AllAddedKinds & HWAddress) {
+ if (Arg *HwasanAbiArg =
+ Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
+ HwasanAbi = HwasanAbiArg->getValue();
+ if (HwasanAbi != "platform" && HwasanAbi != "interceptor")
+ D.Diag(clang::diag::err_drv_invalid_value)
+ << HwasanAbiArg->getAsString(Args) << HwasanAbi;
+ } else {
+ HwasanAbi = "interceptor";
+ }
+ }
+
if (AllAddedKinds & SafeStack) {
// SafeStack runtime is built into the system on Fuchsia.
SafeStackRuntime = !TC.getTriple().isOSFuchsia();
@@ -913,6 +925,11 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
if (AsanUseOdrIndicator)
CmdArgs.push_back("-fsanitize-address-use-odr-indicator");
+ if (!HwasanAbi.empty()) {
+ CmdArgs.push_back("-default-function-attr");
+ CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
+ }
+
// MSan: Workaround for PR16386.
// ASan: This is mainly to help LSan with cases such as
// https://github.com/google/sanitizers/issues/373
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 39152fda998..00083bd6225 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1319,6 +1319,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening);
+ Opts.DefaultFunctionAttrs = Args.getAllArgValues(OPT_default_function_attr);
+
return Success;
}
diff --git a/clang/test/CodeGen/default-function-attr.c b/clang/test/CodeGen/default-function-attr.c
new file mode 100644
index 00000000000..b0d1398a157
--- /dev/null
+++ b/clang/test/CodeGen/default-function-attr.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -default-function-attr foo=bar -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: define void @foo() #[[X:[0-9]+]]
+void foo() {}
+
+// CHECK: attributes #[[X]] = {{.*}} "foo"="bar"
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index 0a82174aaa4..de455617141 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -837,3 +837,11 @@
//
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,kernel-memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-KMSAN
// CHECK-SCUDO-KMSAN: error: invalid argument '-fsanitize=kernel-memory' not allowed with '-fsanitize=scudo'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-INTERCEPTOR-ABI
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=interceptor %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-INTERCEPTOR-ABI
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=platform %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-PLATFORM-ABI
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=foo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-FOO-ABI
+// CHECK-HWASAN-INTERCEPTOR-ABI: "-default-function-attr" "hwasan-abi=interceptor"
+// CHECK-HWASAN-PLATFORM-ABI: "-default-function-attr" "hwasan-abi=platform"
+// CHECK-HWASAN-FOO-ABI: error: invalid value 'foo' in '-fsanitize-hwaddress-abi=foo'
diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cc b/compiler-rt/lib/hwasan/hwasan_interceptors.cc
index 533426c2e38..edb19a56113 100644
--- a/compiler-rt/lib/hwasan/hwasan_interceptors.cc
+++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cc
@@ -217,35 +217,6 @@ INTERCEPTOR_ALIAS(void, malloc_stats, void);
#endif
#endif // HWASAN_WITH_INTERCEPTORS
-
-#if HWASAN_WITH_INTERCEPTORS
-extern "C" int pthread_attr_init(void *attr);
-extern "C" int pthread_attr_destroy(void *attr);
-
-struct ThreadStartArg {
- thread_callback_t callback;
- void *param;
-};
-
-static void *HwasanThreadStartFunc(void *arg) {
- __hwasan_thread_enter();
- ThreadStartArg A = *reinterpret_cast<ThreadStartArg*>(arg);
- UnmapOrDie(arg, GetPageSizeCached());
- return A.callback(A.param);
-}
-
-INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
- void * param) {
- ScopedTaggingDisabler disabler;
- ThreadStartArg *A = reinterpret_cast<ThreadStartArg *> (MmapOrDie(
- GetPageSizeCached(), "pthread_create"));
- *A = {callback, param};
- int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr),
- &HwasanThreadStartFunc, A);
- return res;
-}
-#endif // HWASAN_WITH_INTERCEPTORS
-
static void BeforeFork() {
StackDepotLockAll();
}
@@ -285,7 +256,6 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(fork);
#if HWASAN_WITH_INTERCEPTORS
- INTERCEPT_FUNCTION(pthread_create);
INTERCEPT_FUNCTION(realloc);
INTERCEPT_FUNCTION(free);
#endif
diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cc b/compiler-rt/lib/hwasan/hwasan_linux.cc
index 2238d3848d8..5b0a8b4ac98 100644
--- a/compiler-rt/lib/hwasan/hwasan_linux.cc
+++ b/compiler-rt/lib/hwasan/hwasan_linux.cc
@@ -302,7 +302,12 @@ void AndroidTestTlsSlot() {}
#endif
Thread *GetCurrentThread() {
- auto *R = (StackAllocationsRingBuffer*)GetCurrentThreadLongPtr();
+ uptr *ThreadLong = GetCurrentThreadLongPtr();
+#if HWASAN_WITH_INTERCEPTORS
+ if (!*ThreadLong)
+ __hwasan_thread_enter();
+#endif
+ auto *R = (StackAllocationsRingBuffer *)ThreadLong;
return hwasanThreadList().GetThreadByBufferAddress((uptr)(R->Next()));
}
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 67a0e98cbd5..caa383b57f9 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -264,6 +264,7 @@ private:
Function *HwasanTagMemoryFunc;
Function *HwasanGenerateTagFunc;
+ Function *HwasanThreadEnterFunc;
Constant *ShadowGlobal;
@@ -391,6 +392,9 @@ void HWAddressSanitizer::initializeCallbacks(Module &M) {
HWAsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy));
+
+ HwasanThreadEnterFunc = checkSanitizerInterfaceFunction(
+ M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy()));
}
Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) {
@@ -806,14 +810,35 @@ Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB,
Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
assert(SlotPtr);
- Value *ThreadLong = IRB.CreateLoad(SlotPtr);
+ Instruction *ThreadLong = IRB.CreateLoad(SlotPtr);
+
+ Function *F = IRB.GetInsertBlock()->getParent();
+ if (F->getFnAttribute("hwasan-abi").getValueAsString() == "interceptor") {
+ Value *ThreadLongEqZero =
+ IRB.CreateICmpEQ(ThreadLong, ConstantInt::get(IntptrTy, 0));
+ auto *Br = cast<BranchInst>(SplitBlockAndInsertIfThen(
+ ThreadLongEqZero, cast<Instruction>(ThreadLongEqZero)->getNextNode(),
+ false, MDBuilder(*C).createBranchWeights(1, 100000)));
+
+ IRB.SetInsertPoint(Br);
+ // FIXME: This should call a new runtime function with a custom calling
+ // convention to avoid needing to spill all arguments here.
+ IRB.CreateCall(HwasanThreadEnterFunc);
+ LoadInst *ReloadThreadLong = IRB.CreateLoad(SlotPtr);
+
+ IRB.SetInsertPoint(&*Br->getSuccessor(0)->begin());
+ PHINode *ThreadLongPhi = IRB.CreatePHI(IntptrTy, 2);
+ ThreadLongPhi->addIncoming(ThreadLong, ThreadLong->getParent());
+ ThreadLongPhi->addIncoming(ReloadThreadLong, ReloadThreadLong->getParent());
+ ThreadLong = ThreadLongPhi;
+ }
+
// Extract the address field from ThreadLong. Unnecessary on AArch64 with TBI.
Value *ThreadLongMaybeUntagged =
TargetTriple.isAArch64() ? ThreadLong : untagPointer(IRB, ThreadLong);
if (WithFrameRecord) {
// Prepare ring buffer data.
- Function *F = IRB.GetInsertBlock()->getParent();
auto PC = IRB.CreatePtrToInt(F, IntptrTy);
auto GetStackPointerFn =
Intrinsic::getDeclaration(F->getParent(), Intrinsic::frameaddress);
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/lazy-thread-init.ll b/llvm/test/Instrumentation/HWAddressSanitizer/lazy-thread-init.ll
new file mode 100644
index 00000000000..dab62d6f6b2
--- /dev/null
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/lazy-thread-init.ll
@@ -0,0 +1,25 @@
+; RUN: opt -S -hwasan < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @bar([16 x i32]* %p)
+
+define void @foo() sanitize_hwaddress "hwasan-abi"="interceptor" {
+ ; CHECK: [[LOAD:%[^ ]*]] = load i64, i64* @__hwasan_tls
+ ; CHECK: [[ICMP:%[^ ]*]] = icmp eq i64 [[LOAD]], 0
+ ; CHECK: br i1 [[ICMP]], label %[[INIT:[^,]*]], label %[[CONT:[^,]*]], !prof [[PROF:![0-9]+]]
+
+ ; CHECK: [[INIT]]:
+ ; CHECK: call void @__hwasan_thread_enter()
+ ; CHECK: [[RELOAD:%[^ ]*]] = load i64, i64* @__hwasan_tls
+ ; CHECK: br label %[[CONT]]
+
+ ; CHECK: [[CONT]]:
+ ; CHECK: phi i64 [ [[LOAD]], %0 ], [ [[RELOAD]], %[[INIT]] ]
+
+ %p = alloca [16 x i32]
+ call void @bar([16 x i32]* %p)
+ ret void
+}
+
+; CHECK: [[PROF]] = !{!"branch_weights", i32 1, i32 100000}
OpenPOWER on IntegriCloud