summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2018-02-21 19:52:23 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2018-02-21 19:52:23 +0000
commit43271b18031b0812d5c46b681ec3199fcccb4044 (patch)
tree2ee5003821f87ac1d83cab0a6951bbd5799cc658 /llvm/lib/Transforms
parentb3568ec9287250e0fe7ded71138d35bda2c9482c (diff)
downloadbcm5719-llvm-43271b18031b0812d5c46b681ec3199fcccb4044.tar.gz
bcm5719-llvm-43271b18031b0812d5c46b681ec3199fcccb4044.zip
[hwasan] Fix inline instrumentation.
This patch changes hwasan inline instrumentation: Fixes address untagging for shadow address calculation (use 0xFF instead of 0x00 for the top byte). Emits brk instruction instead of hlt for the kernel and user space. Use 0x900 instead of 0x100 for brk immediate (0x100 - 0x800 are unavailable in the kernel). Fixes and adds appropriate tests. Patch by Andrey Konovalov. Differential Revision: https://reviews.llvm.org/D43135 llvm-svn: 325711
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index cc8abb8a60a..21541fc9029 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -134,6 +134,7 @@ public:
bool isInterestingAlloca(const AllocaInst &AI);
bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag);
Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag);
+ Value *untagPointer(IRBuilder<> &IRB, Value *PtrLong);
bool instrumentStack(SmallVectorImpl<AllocaInst *> &Allocas,
SmallVectorImpl<Instruction *> &RetVec);
Value *getNextTagWithCall(IRBuilder<> &IRB);
@@ -291,9 +292,7 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
Instruction *InsertBefore) {
IRBuilder<> IRB(InsertBefore);
Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, kPointerTagShift), IRB.getInt8Ty());
- Value *AddrLong =
- IRB.CreateAnd(PtrLong, ConstantInt::get(PtrLong->getType(),
- ~(0xFFULL << kPointerTagShift)));
+ Value *AddrLong = untagPointer(IRB, PtrLong);
Value *ShadowLong = IRB.CreateLShr(AddrLong, kShadowScale);
if (ClMappingOffset)
ShadowLong = IRB.CreateAdd(
@@ -311,8 +310,8 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
// The signal handler will find the data address in x0.
InlineAsm *Asm = InlineAsm::get(
FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
- "hlt #" +
- itostr(0x100 + Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex),
+ "brk #" +
+ itostr(0x900 + Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex),
"{x0}",
/*hasSideEffects=*/true);
IRB.CreateCall(Asm, PtrLong);
@@ -461,6 +460,21 @@ Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong
return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
}
+// Remove tag from an address.
+Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
+ Value *UntaggedPtrLong;
+ if (ClEnableKhwasan) {
+ // Kernel addresses have 0xFF in the most significant byte.
+ UntaggedPtrLong = IRB.CreateOr(PtrLong,
+ ConstantInt::get(PtrLong->getType(), 0xFFULL << kPointerTagShift));
+ } else {
+ // Userspace addresses have 0x00.
+ UntaggedPtrLong = IRB.CreateAnd(PtrLong,
+ ConstantInt::get(PtrLong->getType(), ~(0xFFULL << kPointerTagShift)));
+ }
+ return UntaggedPtrLong;
+}
+
bool HWAddressSanitizer::instrumentStack(
SmallVectorImpl<AllocaInst *> &Allocas,
SmallVectorImpl<Instruction *> &RetVec) {
OpenPOWER on IntegriCloud