fmayer updated this revision to Diff 358043.
fmayer added a comment.
update
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D105703/new/
https://reviews.llvm.org/D105703
Files:
clang/lib/CodeGen/BackendUtil.cpp
clang/test/CodeGen/hwasan-stack-safety-analysis-asm.c
clang/test/CodeGen/hwasan-stack-safety-analysis.c
llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Index: llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -109,6 +110,10 @@
cl::desc("instrument stack (allocas)"),
cl::Hidden, cl::init(true));
+static cl::opt<bool>
+ ClUseStackSafety("hwasan-use-stack-safety", cl::Hidden, cl::init(true),
+ cl::Hidden, cl::desc("Use Stack Safety analysis results"));
+
static cl::opt<bool> ClUARRetagToZero(
"hwasan-uar-retag-to-zero",
cl::desc("Clear alloca tags before returning from the function to allow "
@@ -192,13 +197,31 @@
namespace {
+bool shouldUsePageAliases(const Triple &TargetTriple) {
+ return ClUsePageAliases && TargetTriple.getArch() == Triple::x86_64;
+// No one should use the option directly.
+#pragma GCC poison ClUsePageAliases
+}
+
+bool shouldInstrumentStack(const Triple &TargetTriple) {
+ return shouldUsePageAliases(TargetTriple) ? false : ClInstrumentStack;
+// No one should use the option directly.
+#pragma GCC poison ClInstrumentStack
+}
+
+bool shouldUseStackSafetyAnalysis(const Triple &TargetTriple) {
+ return shouldInstrumentStack(TargetTriple) && ClUseStackSafety;
+// No one should use the option directly.
+#pragma GCC poison ClUseStackSafety
+}
/// An instrumentation pass implementing detection of addressability bugs
/// using tagged pointers.
class HWAddressSanitizer {
public:
explicit HWAddressSanitizer(Module &M, bool CompileKernel = false,
- bool Recover = false)
- : M(M) {
+ bool Recover = false,
+ const StackSafetyGlobalInfo *SSI = nullptr)
+ : M(M), SSI(SSI) {
this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0
? ClEnableKhwasan
@@ -207,6 +230,8 @@
initializeModule();
}
+ void setSSI(const StackSafetyGlobalInfo *S) { SSI = S; }
+
bool sanitizeFunction(Function &F);
void initializeModule();
void createHwasanCtorComdat();
@@ -259,6 +284,7 @@
private:
LLVMContext *C;
Module &M;
+ const StackSafetyGlobalInfo *SSI;
Triple TargetTriple;
FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset;
FunctionCallee HWAsanHandleVfork;
@@ -329,8 +355,10 @@
static char ID;
explicit HWAddressSanitizerLegacyPass(bool CompileKernel = false,
- bool Recover = false)
- : FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover) {
+ bool Recover = false,
+ Triple TargetTriple = {})
+ : FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover),
+ TargetTriple(TargetTriple) {
initializeHWAddressSanitizerLegacyPassPass(
*PassRegistry::getPassRegistry());
}
@@ -338,11 +366,18 @@
StringRef getPassName() const override { return "HWAddressSanitizer"; }
bool doInitialization(Module &M) override {
- HWASan = std::make_unique<HWAddressSanitizer>(M, CompileKernel, Recover);
+ HWASan = std::make_unique<HWAddressSanitizer>(M, CompileKernel, Recover,
+ /*SSI=*/nullptr);
return true;
}
bool runOnFunction(Function &F) override {
+ if (shouldUseStackSafetyAnalysis(TargetTriple)) {
+ // We cannot call getAnalysis in doInitialization, that would cause a
+ // crash as the required analyses are not initialized yet.
+ HWASan->setSSI(
+ &getAnalysis<StackSafetyGlobalInfoWrapperPass>().getResult());
+ }
return HWASan->sanitizeFunction(F);
}
@@ -351,10 +386,17 @@
return false;
}
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ if (shouldUseStackSafetyAnalysis(TargetTriple)) {
+ AU.addRequired<StackSafetyGlobalInfoWrapperPass>();
+ }
+ }
+
private:
std::unique_ptr<HWAddressSanitizer> HWASan;
bool CompileKernel;
bool Recover;
+ Triple TargetTriple;
};
} // end anonymous namespace
@@ -370,18 +412,25 @@
"HWAddressSanitizer: detect memory bugs using tagged addressing.", false,
false)
-FunctionPass *llvm::createHWAddressSanitizerLegacyPassPass(bool CompileKernel,
- bool Recover) {
+FunctionPass *
+llvm::createHWAddressSanitizerLegacyPassPass(bool CompileKernel, bool Recover,
+ Triple TargetTriple) {
assert(!CompileKernel || Recover);
- return new HWAddressSanitizerLegacyPass(CompileKernel, Recover);
+ return new HWAddressSanitizerLegacyPass(CompileKernel, Recover, TargetTriple);
}
-HWAddressSanitizerPass::HWAddressSanitizerPass(bool CompileKernel, bool Recover)
- : CompileKernel(CompileKernel), Recover(Recover) {}
+HWAddressSanitizerPass::HWAddressSanitizerPass(bool CompileKernel, bool Recover,
+ Triple TargetTriple)
+ : CompileKernel(CompileKernel), Recover(Recover),
+ TargetTriple(TargetTriple) {}
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
ModuleAnalysisManager &MAM) {
- HWAddressSanitizer HWASan(M, CompileKernel, Recover);
+ const StackSafetyGlobalInfo *SSI = nullptr;
+ if (shouldUseStackSafetyAnalysis(TargetTriple)) {
+ SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
+ }
+ HWAddressSanitizer HWASan(M, CompileKernel, Recover, SSI);
bool Modified = false;
for (Function &F : M)
Modified |= HWASan.sanitizeFunction(F);
@@ -503,9 +552,9 @@
// - Intel LAM (default)
// - pointer aliasing (heap only)
bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
- UsePageAliases = ClUsePageAliases && IsX86_64;
+ UsePageAliases = shouldUsePageAliases(TargetTriple);
InstrumentWithCalls = IsX86_64 ? true : ClInstrumentWithCalls;
- InstrumentStack = UsePageAliases ? false : ClInstrumentStack;
+ InstrumentStack = shouldInstrumentStack(TargetTriple);
PointerTagShift = IsX86_64 ? 57 : 56;
TagMaskByte = IsX86_64 ? 0x3F : 0xFF;
@@ -1223,6 +1272,7 @@
}
bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
+ // clang-format off
return (AI.getAllocatedType()->isSized() &&
// FIXME: instrument dynamic allocas, too
AI.isStaticAlloca() &&
@@ -1235,7 +1285,10 @@
// dynamic alloca instrumentation for them as well.
!AI.isUsedWithInAlloca() &&
// swifterror allocas are register promoted by ISel
- !AI.isSwiftError());
+ !AI.isSwiftError()) &&
+ // safe allocas are not interesting
+ !(SSI && SSI->isSafe(AI));
+ // clang-format on
}
bool HWAddressSanitizer::sanitizeFunction(Function &F) {
Index: llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
===================================================================
--- llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
+++ llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
@@ -14,6 +14,8 @@
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_HWADDRESSSANITIZER_H
#define LLVM_TRANSFORMS_INSTRUMENTATION_HWADDRESSSANITIZER_H
+#include "llvm/ADT/Triple.h"
+
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
@@ -25,17 +27,20 @@
class HWAddressSanitizerPass : public PassInfoMixin<HWAddressSanitizerPass> {
public:
explicit HWAddressSanitizerPass(bool CompileKernel = false,
- bool Recover = false);
+ bool Recover = false,
+ Triple TargetTriple = {});
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
static bool isRequired() { return true; }
private:
bool CompileKernel;
bool Recover;
+ Triple TargetTriple;
};
FunctionPass *createHWAddressSanitizerLegacyPassPass(bool CompileKernel = false,
- bool Recover = false);
+ bool Recover = false,
+ Triple TargetTriple = {});
namespace HWASanAccessInfo {
Index: clang/test/CodeGen/hwasan-stack-safety-analysis.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/hwasan-stack-safety-analysis.c
@@ -0,0 +1,11 @@
+// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -emit-llvm -mllvm -hwasan-use-stack-safety=true -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=SAFETY
+// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -emit-llvm -mllvm -hwasan-use-stack-safety=false -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=NOSAFETY
+
+int main(int argc, char **argv) {
+ char buf[10];
+ volatile char *x = buf;
+ *x = 0;
+ return buf[0];
+ // NOSAFETY: __hwasan_generate_tag
+ // SAFETY-NOT: __hwasan_generate_tag
+}
Index: clang/test/CodeGen/hwasan-stack-safety-analysis-asm.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/hwasan-stack-safety-analysis-asm.c
@@ -0,0 +1,11 @@
+// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -mllvm -hwasan-use-stack-safety=true -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=SAFETY
+// RUN: %clang -fsanitize=hwaddress -target aarch64-linux-gnu -S -mllvm -hwasan-use-stack-safety=false -mllvm -hwasan-generate-tags-with-calls -O2 %s -o - | FileCheck %s --check-prefix=NOSAFETY
+
+int main(int argc, char **argv) {
+ char buf[10];
+ volatile char *x = buf;
+ *x = 0;
+ return buf[0];
+ // NOSAFETY: __hwasan_generate_tag
+ // SAFETY-NOT: __hwasan_generate_tag
+}
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -314,14 +314,17 @@
static_cast<const PassManagerBuilderWrapper &>(Builder);
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
- PM.add(
- createHWAddressSanitizerLegacyPassPass(/*CompileKernel*/ false, Recover));
+ PM.add(createHWAddressSanitizerLegacyPassPass(
+ /*CompileKernel*/ false, Recover, BuilderWrapper.getTargetTriple()));
}
static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
legacy::PassManagerBase &PM) {
+ const PassManagerBuilderWrapper &BuilderWrapper =
+ static_cast<const PassManagerBuilderWrapper &>(Builder);
PM.add(createHWAddressSanitizerLegacyPassPass(
- /*CompileKernel*/ true, /*Recover*/ true));
+ /*CompileKernel*/ true, /*Recover*/ true,
+ BuilderWrapper.getTargetTriple()));
}
static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder,
@@ -1164,7 +1167,8 @@
auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
if (LangOpts.Sanitize.has(Mask)) {
bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
- MPM.addPass(HWAddressSanitizerPass(CompileKernel, Recover));
+ MPM.addPass(
+ HWAddressSanitizerPass(CompileKernel, Recover, TargetTriple));
}
};
HWASanPass(SanitizerKind::HWAddress, false);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits