[llvm-branch-commits] [llvm] eea0313 - [AddressSanitizer] Split out memory intrinsic handling
Author: Jann Horn
Date: 2020-04-30T15:00:48+02:00
New Revision: eea0313cd52e43cc48665ba989b6d861c6e35232
URL:
https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232
DIFF:
https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232.diff
LOG: [AddressSanitizer] Split out memory intrinsic handling
Summary:
In both AddressSanitizer and HWAddressSanitizer, we first collect
instructions whose operands should be instrumented and memory intrinsics,
then instrument them. Both during collection and when inserting
instrumentation, they are handled separately.
Collect them separately and instrument them separately. This is a bit
more straightforward, and prepares for collecting operands instead of
instructions in a future patch.
This is patch 2/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77617
Added:
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Removed:
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index d6dedc6f76ab..fcb2b17a7cf5 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2652,6 +2652,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
// are calls between uses).
SmallPtrSet TempsToInstrument;
SmallVector ToInstrument;
+ SmallVector IntrinToInstrument;
SmallVector NoReturnCalls;
SmallVector AllBlocks;
SmallVector PointerComparisonsOrSubtracts;
@@ -2688,8 +2689,11 @@ bool AddressSanitizer::instrumentFunction(Function &F,
isInterestingPointerSubtraction(&Inst))) {
PointerComparisonsOrSubtracts.push_back(&Inst);
continue;
- } else if (isa(Inst)) {
+ } else if (MemIntrinsic *MI = dyn_cast(&Inst)) {
// ok, take it.
+IntrinToInstrument.push_back(MI);
+NumInsnsPerBB++;
+continue;
} else {
if (isa(Inst)) NumAllocas++;
if (auto *CB = dyn_cast(&Inst)) {
@@ -2708,9 +2712,9 @@ bool AddressSanitizer::instrumentFunction(Function &F,
}
}
- bool UseCalls =
- (ClInstrumentationWithCallsThreshold >= 0 &&
- ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold);
+ bool UseCalls = (ClInstrumentationWithCallsThreshold >= 0 &&
+ ToInstrument.size() + IntrinToInstrument.size() >
+ (unsigned)ClInstrumentationWithCallsThreshold);
const DataLayout &DL = F.getParent()->getDataLayout();
ObjectSizeOpts ObjSizeOpts;
ObjSizeOpts.RoundToAlign = true;
@@ -2723,9 +2727,11 @@ bool AddressSanitizer::instrumentFunction(Function &F,
if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment))
instrumentMop(ObjSizeVis, Inst, UseCalls,
F.getParent()->getDataLayout());
- else
-instrumentMemIntrinsic(cast(Inst));
}
+ }
+ for (auto Inst : IntrinToInstrument) {
+if (!suppressInstrumentationSiteForDebug(NumInstrumented))
+ instrumentMemIntrinsic(Inst);
FunctionModified = true;
}
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 9470cb2cfb28..8c9bc428e7f4 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -720,11 +720,6 @@ bool HWAddressSanitizer::instrumentMemAccess(Instruction
*I) {
uint64_t TypeSize = 0;
Value *MaybeMask = nullptr;
- if (ClInstrumentMemIntrinsics && isa(I)) {
-instrumentMemIntrinsic(cast(I));
-return true;
- }
-
Value *Addr =
isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment,
&MaybeMask);
@@ -1090,6 +1085,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
SmallVector ToInstrument;
+ SmallVector IntrinToInstrument;
SmallVector AllocasToInstrument;
SmallVector RetVec;
SmallVector LandingPadVec;
@@ -1121,8 +1117,11 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
uint64_t TypeSize;
Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
[llvm-branch-commits] [llvm] 84d341f - [AddressSanitizer] Instrument byval call arguments
Author: Jann Horn
Date: 2020-04-30T15:00:49+02:00
New Revision: 84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae
URL:
https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae
DIFF:
https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae.diff
LOG: [AddressSanitizer] Instrument byval call arguments
Summary:
In the LLVM IR, "call" instructions read memory for each byval operand.
For example:
```
$ cat blah.c
struct foo { void *a, *b, *c; };
struct bar { struct foo foo; };
void func1(const struct foo);
void func2(struct bar *bar) { func1(bar->foo); }
$ [...]/bin/clang -S -flto -c blah.c -O2 ; cat blah.s
[...]
define dso_local void @func2(%struct.bar* %bar) local_unnamed_addr #0 {
entry:
%foo = getelementptr inbounds %struct.bar, %struct.bar* %bar, i64 0, i32 0
tail call void @func1(%struct.foo* byval(%struct.foo) align 8 %foo) #2
ret void
}
[...]
$ [...]/bin/clang -S -c blah.c -O2 ; cat blah.s
[...]
func2: # @func2
[...]
subq$24, %rsp
[...]
movq16(%rdi), %rax
movq%rax, 16(%rsp)
movups (%rdi), %xmm0
movups %xmm0, (%rsp)
callq func1
addq$24, %rsp
[...]
retq
```
Let ASAN instrument these hidden memory accesses.
This is patch 4/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, dexonsmith, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77619
Added:
llvm/test/Instrumentation/AddressSanitizer/byval-args.ll
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Removed:
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 6226bcd35381..93326c8fd13a 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -213,6 +213,11 @@ static cl::opt ClInstrumentAtomics(
cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
cl::init(true));
+static cl::opt
+ClInstrumentByval("asan-instrument-byval",
+ cl::desc("instrument byval call arguments"), cl::Hidden,
+ cl::init(true));
+
static cl::opt ClAlwaysSlowPath(
"asan-always-slow-path",
cl::desc("use instrumentation with slow path for all accesses"),
cl::Hidden,
@@ -1414,6 +1419,14 @@ void AddressSanitizer::getInterestingMemoryOperands(
Alignment = (unsigned)AlignmentConstant->getZExtValue();
Value *Mask = CI->getOperand(2 + OpOffset);
Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, Mask);
+} else {
+ for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) {
+if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
+ignoreAccess(CI->getArgOperand(ArgNo)))
+ continue;
+Type *Ty = CI->getParamByValType(ArgNo);
+Interesting.emplace_back(I, ArgNo, false, Ty, 1);
+ }
}
}
}
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 982c1d3516cc..0b9856b5126a 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -97,6 +97,10 @@ static cl::opt ClInstrumentAtomics(
cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
cl::init(true));
+static cl::opt ClInstrumentByval("hwasan-instrument-byval",
+ cl::desc("instrument byval arguments"),
+ cl::Hidden, cl::init(true));
+
static cl::opt ClRecover(
"hwasan-recover",
cl::desc("Enable recovery mode (continue-after-error)."),
@@ -549,6 +553,14 @@ void HWAddressSanitizer::getInterestingMemoryOperands(
return;
Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true,
XCHG->getCompareOperand()->getType(), 0);
+ } else if (auto CI = dyn_cast(I)) {
+for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) {
+ if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
+ ignoreAccess(CI->getArgOperand(ArgNo)))
+continue;
+ Type *Ty = CI->getParamByValType(ArgNo);
+ Interesting.emplace_back(I, ArgNo
[llvm-branch-commits] [llvm] c9cba16 - [AddressSanitizer] Refactor ClDebug{Min, Max} handling
Author: Jann Horn
Date: 2020-04-30T15:00:48+02:00
New Revision: c9cba1600de842f803bb3d55cc4d97deba55f5c8
URL:
https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8
DIFF:
https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8.diff
LOG: [AddressSanitizer] Refactor ClDebug{Min,Max} handling
Summary:
A following commit will split the loop over ToInstrument into two.
To avoid having to duplicate the condition for suppressing instrumentation
sites based on ClDebug{Min,Max}, refactor it out into a new function.
While we're at it, we can also avoid the indirection through
NumInstrumented for setting FunctionModified.
This is patch 1/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77616
Added:
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Removed:
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 4556e3275a10..d6dedc6f76ab 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -638,6 +638,7 @@ struct AddressSanitizer {
Value *SizeArgument, uint32_t Exp);
void instrumentMemIntrinsic(MemIntrinsic *MI);
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
+ bool suppressInstrumentationSiteForDebug(int &Instrumented);
bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI);
bool maybeInsertAsanInitAtFunctionEntry(Function &F);
void maybeInsertDynamicShadowAtFunctionEntry(Function &F);
@@ -2610,6 +2611,14 @@ void AddressSanitizer::markEscapedLocalAllocas(Function
&F) {
}
}
+bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) {
+ bool ShouldInstrument =
+ ClDebugMin < 0 || ClDebugMax < 0 ||
+ (Instrumented >= ClDebugMin && Instrumented <= ClDebugMax);
+ Instrumented++;
+ return !ShouldInstrument;
+}
+
bool AddressSanitizer::instrumentFunction(Function &F,
const TargetLibraryInfo *TLI) {
if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
@@ -2710,15 +2719,14 @@ bool AddressSanitizer::instrumentFunction(Function &F,
// Instrument.
int NumInstrumented = 0;
for (auto Inst : ToInstrument) {
-if (ClDebugMin < 0 || ClDebugMax < 0 ||
-(NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
+if (!suppressInstrumentationSiteForDebug(NumInstrumented)) {
if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment))
instrumentMop(ObjSizeVis, Inst, UseCalls,
F.getParent()->getDataLayout());
else
instrumentMemIntrinsic(cast(Inst));
}
-NumInstrumented++;
+FunctionModified = true;
}
FunctionStackPoisoner FSP(F, *this);
@@ -2733,10 +2741,10 @@ bool AddressSanitizer::instrumentFunction(Function &F,
for (auto Inst : PointerComparisonsOrSubtracts) {
instrumentPointerComparisonOrSubtraction(Inst);
-NumInstrumented++;
+FunctionModified = true;
}
- if (NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty())
+ if (ChangedStack || !NoReturnCalls.empty())
FunctionModified = true;
LLVM_DEBUG(dbgs() << "ASAN done instrumenting: " << FunctionModified << " "
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 7df5537 - [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction
Author: Jann Horn
Date: 2020-04-30T15:00:48+02:00
New Revision: 7df5537f8d3c4f8033b7b32809684cb688fe5ebe
URL:
https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe
DIFF:
https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe.diff
LOG: [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction
Summary:
Refactor getInterestingMemoryOperands() so that information about the
pointer operand is returned through an array of structures instead of
passing each piece of information separately by-value.
This is in preparation for returning information about multiple pointer
operands from a single instruction.
A side effect is that, instead of repeatedly generating the same
information through isInterestingMemoryAccess(), it is now simply collected
once and then passed around; that's probably more efficient.
HWAddressSanitizer has a bunch of copypasted code from AddressSanitizer,
so these changes have to be duplicated.
This is patch 3/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
[glider: renamed llvm::InterestingMemoryOperand::Type to OpType to fix
GCC compilation]
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77618
Added:
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Removed:
diff --git
a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
new file mode 100644
index ..ef33fa2147d1
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
@@ -0,0 +1,49 @@
+//===- Definition of the AddressSanitizer class -*- C++
-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file declares common infrastructure for AddressSanitizer and
+// HWAddressSanitizer.
+//
+//===--===//
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H
+
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
+
+namespace llvm {
+
+class InterestingMemoryOperand {
+public:
+ Use *PtrUse;
+ bool IsWrite;
+ Type *OpType;
+ uint64_t TypeSize;
+ unsigned Alignment;
+ // The mask Value, if we're looking at a masked load/store.
+ Value *MaybeMask;
+
+ InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite,
+ class Type *OpType, unsigned Alignment,
+ Value *MaybeMask = nullptr)
+ : IsWrite(IsWrite), OpType(OpType), Alignment(Alignment),
+MaybeMask(MaybeMask) {
+const DataLayout &DL = I->getModule()->getDataLayout();
+TypeSize = DL.getTypeStoreSizeInBits(OpType);
+PtrUse = &I->getOperandUse(OperandNo);
+ }
+
+ Instruction *getInsn() { return cast(PtrUse->getUser()); }
+
+ Value *getPtr() { return PtrUse->get(); }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index fcb2b17a7cf5..6226bcd35381 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -69,6 +69,7 @@
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -612,16 +613,13 @@ struct AddressSanitizer {
/// Check if we want (and can) handle this alloca.
bool isInterestingAlloca(const AllocaInst &AI);
- /// If it is an interesting memory access, return the PointerOperand
- /// and set IsWrite/Alignment. Otherwise return nullptr.
- /// MaybeMask is an output parameter for the mask Value, if we're looking at
a
- /// masked load/store.
- Value *i
[llvm-branch-commits] [llvm] c9cba16 - [AddressSanitizer] Refactor ClDebug{Min, Max} handling
Author: Jann Horn
Date: 2020-04-30T15:00:48+02:00
New Revision: c9cba1600de842f803bb3d55cc4d97deba55f5c8
URL:
https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8
DIFF:
https://github.com/llvm/llvm-project/commit/c9cba1600de842f803bb3d55cc4d97deba55f5c8.diff
LOG: [AddressSanitizer] Refactor ClDebug{Min,Max} handling
Summary:
A following commit will split the loop over ToInstrument into two.
To avoid having to duplicate the condition for suppressing instrumentation
sites based on ClDebug{Min,Max}, refactor it out into a new function.
While we're at it, we can also avoid the indirection through
NumInstrumented for setting FunctionModified.
This is patch 1/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77616
Added:
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Removed:
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 4556e3275a10..d6dedc6f76ab 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -638,6 +638,7 @@ struct AddressSanitizer {
Value *SizeArgument, uint32_t Exp);
void instrumentMemIntrinsic(MemIntrinsic *MI);
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
+ bool suppressInstrumentationSiteForDebug(int &Instrumented);
bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI);
bool maybeInsertAsanInitAtFunctionEntry(Function &F);
void maybeInsertDynamicShadowAtFunctionEntry(Function &F);
@@ -2610,6 +2611,14 @@ void AddressSanitizer::markEscapedLocalAllocas(Function
&F) {
}
}
+bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) {
+ bool ShouldInstrument =
+ ClDebugMin < 0 || ClDebugMax < 0 ||
+ (Instrumented >= ClDebugMin && Instrumented <= ClDebugMax);
+ Instrumented++;
+ return !ShouldInstrument;
+}
+
bool AddressSanitizer::instrumentFunction(Function &F,
const TargetLibraryInfo *TLI) {
if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
@@ -2710,15 +2719,14 @@ bool AddressSanitizer::instrumentFunction(Function &F,
// Instrument.
int NumInstrumented = 0;
for (auto Inst : ToInstrument) {
-if (ClDebugMin < 0 || ClDebugMax < 0 ||
-(NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
+if (!suppressInstrumentationSiteForDebug(NumInstrumented)) {
if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment))
instrumentMop(ObjSizeVis, Inst, UseCalls,
F.getParent()->getDataLayout());
else
instrumentMemIntrinsic(cast(Inst));
}
-NumInstrumented++;
+FunctionModified = true;
}
FunctionStackPoisoner FSP(F, *this);
@@ -2733,10 +2741,10 @@ bool AddressSanitizer::instrumentFunction(Function &F,
for (auto Inst : PointerComparisonsOrSubtracts) {
instrumentPointerComparisonOrSubtraction(Inst);
-NumInstrumented++;
+FunctionModified = true;
}
- if (NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty())
+ if (ChangedStack || !NoReturnCalls.empty())
FunctionModified = true;
LLVM_DEBUG(dbgs() << "ASAN done instrumenting: " << FunctionModified << " "
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 84d341f - [AddressSanitizer] Instrument byval call arguments
Author: Jann Horn
Date: 2020-04-30T15:00:49+02:00
New Revision: 84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae
URL:
https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae
DIFF:
https://github.com/llvm/llvm-project/commit/84d341f53d050d2d1b6d657ebf8e23dc4aaab2ae.diff
LOG: [AddressSanitizer] Instrument byval call arguments
Summary:
In the LLVM IR, "call" instructions read memory for each byval operand.
For example:
```
$ cat blah.c
struct foo { void *a, *b, *c; };
struct bar { struct foo foo; };
void func1(const struct foo);
void func2(struct bar *bar) { func1(bar->foo); }
$ [...]/bin/clang -S -flto -c blah.c -O2 ; cat blah.s
[...]
define dso_local void @func2(%struct.bar* %bar) local_unnamed_addr #0 {
entry:
%foo = getelementptr inbounds %struct.bar, %struct.bar* %bar, i64 0, i32 0
tail call void @func1(%struct.foo* byval(%struct.foo) align 8 %foo) #2
ret void
}
[...]
$ [...]/bin/clang -S -c blah.c -O2 ; cat blah.s
[...]
func2: # @func2
[...]
subq$24, %rsp
[...]
movq16(%rdi), %rax
movq%rax, 16(%rsp)
movups (%rdi), %xmm0
movups %xmm0, (%rsp)
callq func1
addq$24, %rsp
[...]
retq
```
Let ASAN instrument these hidden memory accesses.
This is patch 4/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, dexonsmith, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77619
Added:
llvm/test/Instrumentation/AddressSanitizer/byval-args.ll
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Removed:
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 6226bcd35381..93326c8fd13a 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -213,6 +213,11 @@ static cl::opt ClInstrumentAtomics(
cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
cl::init(true));
+static cl::opt
+ClInstrumentByval("asan-instrument-byval",
+ cl::desc("instrument byval call arguments"), cl::Hidden,
+ cl::init(true));
+
static cl::opt ClAlwaysSlowPath(
"asan-always-slow-path",
cl::desc("use instrumentation with slow path for all accesses"),
cl::Hidden,
@@ -1414,6 +1419,14 @@ void AddressSanitizer::getInterestingMemoryOperands(
Alignment = (unsigned)AlignmentConstant->getZExtValue();
Value *Mask = CI->getOperand(2 + OpOffset);
Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, Mask);
+} else {
+ for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) {
+if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
+ignoreAccess(CI->getArgOperand(ArgNo)))
+ continue;
+Type *Ty = CI->getParamByValType(ArgNo);
+Interesting.emplace_back(I, ArgNo, false, Ty, 1);
+ }
}
}
}
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 982c1d3516cc..0b9856b5126a 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -97,6 +97,10 @@ static cl::opt ClInstrumentAtomics(
cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
cl::init(true));
+static cl::opt ClInstrumentByval("hwasan-instrument-byval",
+ cl::desc("instrument byval arguments"),
+ cl::Hidden, cl::init(true));
+
static cl::opt ClRecover(
"hwasan-recover",
cl::desc("Enable recovery mode (continue-after-error)."),
@@ -549,6 +553,14 @@ void HWAddressSanitizer::getInterestingMemoryOperands(
return;
Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true,
XCHG->getCompareOperand()->getType(), 0);
+ } else if (auto CI = dyn_cast(I)) {
+for (unsigned ArgNo = 0; ArgNo < CI->getNumArgOperands(); ArgNo++) {
+ if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
+ ignoreAccess(CI->getArgOperand(ArgNo)))
+continue;
+ Type *Ty = CI->getParamByValType(ArgNo);
+ Interesting.emplace_back(I, ArgNo
[llvm-branch-commits] [llvm] eea0313 - [AddressSanitizer] Split out memory intrinsic handling
Author: Jann Horn
Date: 2020-04-30T15:00:48+02:00
New Revision: eea0313cd52e43cc48665ba989b6d861c6e35232
URL:
https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232
DIFF:
https://github.com/llvm/llvm-project/commit/eea0313cd52e43cc48665ba989b6d861c6e35232.diff
LOG: [AddressSanitizer] Split out memory intrinsic handling
Summary:
In both AddressSanitizer and HWAddressSanitizer, we first collect
instructions whose operands should be instrumented and memory intrinsics,
then instrument them. Both during collection and when inserting
instrumentation, they are handled separately.
Collect them separately and instrument them separately. This is a bit
more straightforward, and prepares for collecting operands instead of
instructions in a future patch.
This is patch 2/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77617
Added:
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Removed:
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index d6dedc6f76ab..fcb2b17a7cf5 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2652,6 +2652,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
// are calls between uses).
SmallPtrSet TempsToInstrument;
SmallVector ToInstrument;
+ SmallVector IntrinToInstrument;
SmallVector NoReturnCalls;
SmallVector AllBlocks;
SmallVector PointerComparisonsOrSubtracts;
@@ -2688,8 +2689,11 @@ bool AddressSanitizer::instrumentFunction(Function &F,
isInterestingPointerSubtraction(&Inst))) {
PointerComparisonsOrSubtracts.push_back(&Inst);
continue;
- } else if (isa(Inst)) {
+ } else if (MemIntrinsic *MI = dyn_cast(&Inst)) {
// ok, take it.
+IntrinToInstrument.push_back(MI);
+NumInsnsPerBB++;
+continue;
} else {
if (isa(Inst)) NumAllocas++;
if (auto *CB = dyn_cast(&Inst)) {
@@ -2708,9 +2712,9 @@ bool AddressSanitizer::instrumentFunction(Function &F,
}
}
- bool UseCalls =
- (ClInstrumentationWithCallsThreshold >= 0 &&
- ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold);
+ bool UseCalls = (ClInstrumentationWithCallsThreshold >= 0 &&
+ ToInstrument.size() + IntrinToInstrument.size() >
+ (unsigned)ClInstrumentationWithCallsThreshold);
const DataLayout &DL = F.getParent()->getDataLayout();
ObjectSizeOpts ObjSizeOpts;
ObjSizeOpts.RoundToAlign = true;
@@ -2723,9 +2727,11 @@ bool AddressSanitizer::instrumentFunction(Function &F,
if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment))
instrumentMop(ObjSizeVis, Inst, UseCalls,
F.getParent()->getDataLayout());
- else
-instrumentMemIntrinsic(cast(Inst));
}
+ }
+ for (auto Inst : IntrinToInstrument) {
+if (!suppressInstrumentationSiteForDebug(NumInstrumented))
+ instrumentMemIntrinsic(Inst);
FunctionModified = true;
}
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 9470cb2cfb28..8c9bc428e7f4 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -720,11 +720,6 @@ bool HWAddressSanitizer::instrumentMemAccess(Instruction
*I) {
uint64_t TypeSize = 0;
Value *MaybeMask = nullptr;
- if (ClInstrumentMemIntrinsics && isa(I)) {
-instrumentMemIntrinsic(cast(I));
-return true;
- }
-
Value *Addr =
isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment,
&MaybeMask);
@@ -1090,6 +1085,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
SmallVector ToInstrument;
+ SmallVector IntrinToInstrument;
SmallVector AllocasToInstrument;
SmallVector RetVec;
SmallVector LandingPadVec;
@@ -1121,8 +1117,11 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
uint64_t TypeSize;
Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
[llvm-branch-commits] [llvm] 7df5537 - [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction
Author: Jann Horn
Date: 2020-04-30T15:00:48+02:00
New Revision: 7df5537f8d3c4f8033b7b32809684cb688fe5ebe
URL:
https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe
DIFF:
https://github.com/llvm/llvm-project/commit/7df5537f8d3c4f8033b7b32809684cb688fe5ebe.diff
LOG: [AddressSanitizer] Refactor: Permit >1 interesting operands per instruction
Summary:
Refactor getInterestingMemoryOperands() so that information about the
pointer operand is returned through an array of structures instead of
passing each piece of information separately by-value.
This is in preparation for returning information about multiple pointer
operands from a single instruction.
A side effect is that, instead of repeatedly generating the same
information through isInterestingMemoryAccess(), it is now simply collected
once and then passed around; that's probably more efficient.
HWAddressSanitizer has a bunch of copypasted code from AddressSanitizer,
so these changes have to be duplicated.
This is patch 3/4 of a patch series:
https://reviews.llvm.org/D77616 [PATCH 1/4] [AddressSanitizer] Refactor
ClDebug{Min,Max} handling
https://reviews.llvm.org/D77617 [PATCH 2/4] [AddressSanitizer] Split out memory
intrinsic handling
https://reviews.llvm.org/D77618 [PATCH 3/4] [AddressSanitizer] Refactor: Permit
>1 interesting operands per instruction
https://reviews.llvm.org/D77619 [PATCH 4/4] [AddressSanitizer] Instrument byval
call arguments
[glider: renamed llvm::InterestingMemoryOperand::Type to OpType to fix
GCC compilation]
Reviewers: kcc, glider
Reviewed By: glider
Subscribers: hiraditya, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77618
Added:
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
Modified:
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Removed:
diff --git
a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
new file mode 100644
index ..ef33fa2147d1
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
@@ -0,0 +1,49 @@
+//===- Definition of the AddressSanitizer class -*- C++
-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file declares common infrastructure for AddressSanitizer and
+// HWAddressSanitizer.
+//
+//===--===//
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H
+
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
+
+namespace llvm {
+
+class InterestingMemoryOperand {
+public:
+ Use *PtrUse;
+ bool IsWrite;
+ Type *OpType;
+ uint64_t TypeSize;
+ unsigned Alignment;
+ // The mask Value, if we're looking at a masked load/store.
+ Value *MaybeMask;
+
+ InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite,
+ class Type *OpType, unsigned Alignment,
+ Value *MaybeMask = nullptr)
+ : IsWrite(IsWrite), OpType(OpType), Alignment(Alignment),
+MaybeMask(MaybeMask) {
+const DataLayout &DL = I->getModule()->getDataLayout();
+TypeSize = DL.getTypeStoreSizeInBits(OpType);
+PtrUse = &I->getOperandUse(OperandNo);
+ }
+
+ Instruction *getInsn() { return cast(PtrUse->getUser()); }
+
+ Value *getPtr() { return PtrUse->get(); }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index fcb2b17a7cf5..6226bcd35381 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -69,6 +69,7 @@
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -612,16 +613,13 @@ struct AddressSanitizer {
/// Check if we want (and can) handle this alloca.
bool isInterestingAlloca(const AllocaInst &AI);
- /// If it is an interesting memory access, return the PointerOperand
- /// and set IsWrite/Alignment. Otherwise return nullptr.
- /// MaybeMask is an output parameter for the mask Value, if we're looking at
a
- /// masked load/store.
- Value *i
[llvm-branch-commits] [clang] [Clang] Add __builtin_allow_sanitize_check() (PR #172030)
@@ -3549,6 +3549,38 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl
GD, unsigned BuiltinID,
llvm::MetadataAsValue::get(Ctx, llvm::MDString::get(Ctx, Kind)));
return RValue::get(Allow);
}
+ case Builtin::BI__builtin_allow_sanitize_check: {
+Intrinsic::ID IntrID = Intrinsic::not_intrinsic;
+StringRef SanitizerName =
+cast(E->getArg(0)->IgnoreParenCasts())->getString();
+
+if (SanitizerName == "address" || SanitizerName == "kernel-address") {
ramosian-glider wrote:
Won't this provoke the users to use "address" and "kernel-address"
interchangeably?
If we want this, maybe it should be reflected in the documentation?
https://github.com/llvm/llvm-project/pull/172030
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Clang] Add __builtin_allow_sanitize_check() (PR #172030)
https://github.com/ramosian-glider approved this pull request. Two nits. https://github.com/llvm/llvm-project/pull/172030 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Clang] Add __builtin_allow_sanitize_check() (PR #172030)
https://github.com/ramosian-glider edited https://github.com/llvm/llvm-project/pull/172030 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Clang] Add __builtin_allow_sanitize_check() (PR #172030)
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void test_builtin_allow_sanitize_check() {
+ // Test with non-string literal argument
ramosian-glider wrote:
Shouldn't comments in this file end with a period?
https://github.com/llvm/llvm-project/pull/172030
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
