Index: lib/Transforms/Instrumentation/HWAddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -134,6 +134,7 @@ 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 &Allocas, SmallVectorImpl &RetVec); Value *getNextTagWithCall(IRBuilder<> &IRB); @@ -291,9 +292,7 @@ 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,9 @@ // 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((ClEnableKhwasan ? 0x900 : 0x100) + Recover * 0x20 + + IsWrite * 0x10 + AccessSizeIndex), "{x0}", /*hasSideEffects=*/true); IRB.CreateCall(Asm, PtrLong); @@ -461,6 +461,21 @@ 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 &Allocas, SmallVectorImpl &RetVec) { Index: test/Instrumentation/HWAddressSanitizer/atomic.ll =================================================================== --- test/Instrumentation/HWAddressSanitizer/atomic.ll +++ test/Instrumentation/HWAddressSanitizer/atomic.ll @@ -8,7 +8,7 @@ define void @atomicrmw(i64* %ptr) sanitize_hwaddress { ; CHECK-LABEL: @atomicrmw( ; CHECK: lshr i64 %[[A:[^ ]*]], 56 -; CHECK: call void asm sideeffect "hlt #275", "{x0}"(i64 %[[A]]) +; CHECK: call void asm sideeffect "brk #275", "{x0}"(i64 %[[A]]) ; CHECK: atomicrmw add i64* %ptr, i64 1 seq_cst ; CHECK: ret void @@ -20,7 +20,7 @@ define void @cmpxchg(i64* %ptr, i64 %compare_to, i64 %new_value) sanitize_hwaddress { ; CHECK-LABEL: @cmpxchg( ; CHECK: lshr i64 %[[A:[^ ]*]], 56 -; CHECK: call void asm sideeffect "hlt #275", "{x0}"(i64 %[[A]]) +; CHECK: call void asm sideeffect "brk #275", "{x0}"(i64 %[[A]]) ; CHECK: cmpxchg i64* %ptr, i64 %compare_to, i64 %new_value seq_cst seq_cst ; CHECK: ret void Index: test/Instrumentation/HWAddressSanitizer/basic.ll =================================================================== --- test/Instrumentation/HWAddressSanitizer/basic.ll +++ test/Instrumentation/HWAddressSanitizer/basic.ll @@ -18,9 +18,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #256", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #256", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #288", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #288", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4 @@ -43,9 +43,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #257", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #257", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #289", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #289", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: %[[G:[^ ]*]] = load i16, i16* %a, align 4 @@ -68,9 +68,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #258", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #258", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #290", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #290", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: %[[G:[^ ]*]] = load i32, i32* %a, align 4 @@ -93,9 +93,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #259", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #259", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #291", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #291", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: %[[G:[^ ]*]] = load i64, i64* %a, align 8 @@ -118,9 +118,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #260", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #260", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #292", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #292", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: %[[G:[^ ]*]] = load i128, i128* %a, align 16 @@ -156,9 +156,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #272", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #272", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #304", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #304", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: store i8 %b, i8* %a, align 4 @@ -181,9 +181,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #273", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #273", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #305", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #305", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: store i16 %b, i16* %a, align 4 @@ -206,9 +206,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #274", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #274", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #306", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #306", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: store i32 %b, i32* %a, align 4 @@ -231,9 +231,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #275", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #275", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #307", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #307", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: store i64 %b, i64* %a, align 8 @@ -256,9 +256,9 @@ ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} -; ABORT: call void asm sideeffect "hlt #276", "{x0}"(i64 %[[A]]) +; ABORT: call void asm sideeffect "brk #276", "{x0}"(i64 %[[A]]) ; ABORT: unreachable -; RECOVER: call void asm sideeffect "hlt #308", "{x0}"(i64 %[[A]]) +; RECOVER: call void asm sideeffect "brk #308", "{x0}"(i64 %[[A]]) ; RECOVER: br label ; CHECK: store i128 %b, i128* %a, align 16 Index: test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll =================================================================== --- test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll +++ test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll @@ -1,4 +1,4 @@ -; Test basic address sanitizer instrumentation. +; Test kernel hwasan instrumentation for alloca. ; ; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s Index: test/Instrumentation/HWAddressSanitizer/kernel.ll =================================================================== --- test/Instrumentation/HWAddressSanitizer/kernel.ll +++ test/Instrumentation/HWAddressSanitizer/kernel.ll @@ -1,27 +1,42 @@ ; Test kernel hwasan instrumentation. ; -; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s --allow-empty --check-prefixes=KERNEL -; RUN: opt < %s -hwasan -hwasan-mapping-offset=12345678 -S | FileCheck %s --check-prefixes=OFFSET +; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s --allow-empty --check-prefixes=INIT +; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s --check-prefixes=CHECK,NOOFFSET +; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-mapping-offset=12345678 -S | FileCheck %s --check-prefixes=CHECK,OFFSET +; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=0 -S | FileCheck %s --check-prefixes=CHECK,NOOFFSET,ABORT +; RUN: opt < %s -hwasan -hwasan-kernel=1 -hwasan-recover=1 -S | FileCheck %s --check-prefixes=CHECK,NOOFFSET,RECOVER target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64--linux-android" define i8 @test_load(i8* %a) sanitize_hwaddress { -; OFFSET-LABEL: @test_load( -; OFFSET: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 -; OFFSET: %[[B:[^ ]*]] = lshr i64 %[[A]], 56 -; OFFSET: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8 -; OFFSET: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935 -; OFFSET: %[[D:[^ ]*]] = lshr i64 %[[C]], 4 +; CHECK-LABEL: @test_load( +; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 +; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56 +; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8 +; CHECK: %[[C:[^ ]*]] = or i64 %[[A]], -72057594037927936 +; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4 + +; NOOFFSET: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8* + ; OFFSET: %[[D1:[^ ]*]] = add i64 %[[D]], 12345678 ; OFFSET: %[[E:[^ ]*]] = inttoptr i64 %[[D1]] to i8* -; OFFSET: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]] -; OFFSET: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] -; OFFSET: br i1 %[[F]], + +; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]] +; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]] +; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}} + +; ABORT: call void asm sideeffect "brk #2304", "{x0}"(i64 %[[A]]) +; ABORT: unreachable +; RECOVER: call void asm sideeffect "brk #2336", "{x0}"(i64 %[[A]]) +; RECOVER: br label + +; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4 +; CHECK: ret i8 %[[G]] entry: %b = load i8, i8* %a, align 4 ret i8 %b } -; KERNEL-NOT: call void @__hwasan_init +; INIT-NOT: call void @__hwasan_init