diff --git a/compiler-rt/test/hwasan/TestCases/deep-recursion.c b/compiler-rt/test/hwasan/TestCases/deep-recursion.c --- a/compiler-rt/test/hwasan/TestCases/deep-recursion.c +++ b/compiler-rt/test/hwasan/TestCases/deep-recursion.c @@ -7,6 +7,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include // At least -O1 is needed for this function to not have a stack frame on // AArch64. diff --git a/compiler-rt/test/hwasan/TestCases/global.c b/compiler-rt/test/hwasan/TestCases/global.c --- a/compiler-rt/test/hwasan/TestCases/global.c +++ b/compiler-rt/test/hwasan/TestCases/global.c @@ -5,6 +5,9 @@ // RUN: not %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LSYM %s // RUN: not %env_hwasan_opts=symbolize=0 %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LNOSYM %s +// Global aliasing is not implemented on x86. +// XFAIL: x86_64 + int x = 1; int main(int argc, char **argv) { diff --git a/compiler-rt/test/hwasan/TestCases/longjmp.c b/compiler-rt/test/hwasan/TestCases/longjmp.c --- a/compiler-rt/test/hwasan/TestCases/longjmp.c +++ b/compiler-rt/test/hwasan/TestCases/longjmp.c @@ -3,6 +3,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include #include diff --git a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c --- a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c +++ b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c @@ -5,6 +5,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include #include diff --git a/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp b/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp --- a/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp +++ b/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp @@ -16,7 +16,7 @@ __attribute__((noinline)) void f(int *p) { *p = 3; } // CHECK: ERROR: HWAddressSanitizer: -// CHECK: #0 {{.*}} in f(int*) {{.*}}register-dump-no-fp.cpp:[[@LINE-3]] +// CHECK: #{{[0-9]}} {{.*}} in f(int*) {{.*}}register-dump-no-fp.cpp:[[@LINE-3]] int main() { __hwasan_enable_allocator_tagging(); @@ -24,5 +24,5 @@ int *volatile a = new int; a = (int *)__hwasan_tag_pointer(a, 0); f(a); - // CHECK: #1 {{.*}} in main {{.*}}register-dump-no-fp.cpp:[[@LINE-1]] + // CHECK: #{{[0-9]}} {{.*}} in main {{.*}}register-dump-no-fp.cpp:[[@LINE-1]] } diff --git a/compiler-rt/test/hwasan/TestCases/rich-stack.c b/compiler-rt/test/hwasan/TestCases/rich-stack.c --- a/compiler-rt/test/hwasan/TestCases/rich-stack.c +++ b/compiler-rt/test/hwasan/TestCases/rich-stack.c @@ -2,6 +2,10 @@ // RUN: %clang_hwasan %s -o %t // RUN: not %run %t 3 2 -1 2>&1 | FileCheck %s --check-prefix=R321 // REQUIRES: stable-runtime + +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include void USE(void *x) { // pretend_to_do_something(void *x) diff --git a/compiler-rt/test/hwasan/TestCases/stack-history-length.c b/compiler-rt/test/hwasan/TestCases/stack-history-length.c --- a/compiler-rt/test/hwasan/TestCases/stack-history-length.c +++ b/compiler-rt/test/hwasan/TestCases/stack-history-length.c @@ -4,6 +4,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include void USE(void *x) { // pretend_to_do_something(void *x) diff --git a/compiler-rt/test/hwasan/TestCases/stack-oob.c b/compiler-rt/test/hwasan/TestCases/stack-oob.c --- a/compiler-rt/test/hwasan/TestCases/stack-oob.c +++ b/compiler-rt/test/hwasan/TestCases/stack-oob.c @@ -9,6 +9,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + #include #include diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c --- a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c @@ -4,6 +4,9 @@ // still be using FP-relative debug info locations that we can use to find stack // objects. +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + __attribute((noinline)) char *buggy(int b) { char c[64]; diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c b/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c --- a/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c @@ -6,6 +6,9 @@ // be able to handle this case somehow (e.g. by using a different register for // DW_AT_frame_base) but at least we shouldn't get confused by it. +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + __attribute((noinline)) char *buggy() { _Alignas(64) char c[64]; diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar.c b/compiler-rt/test/hwasan/TestCases/stack-uar.c --- a/compiler-rt/test/hwasan/TestCases/stack-uar.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar.c @@ -4,6 +4,9 @@ // REQUIRES: stable-runtime +// Stack aliasing is not implemented on x86. +// XFAIL: x86_64 + void USE(void *x) { // pretend_to_do_something(void *x) __asm__ __volatile__("" : : "r" (x) : "memory"); } diff --git a/compiler-rt/test/hwasan/TestCases/use-after-free.c b/compiler-rt/test/hwasan/TestCases/use-after-free.c --- a/compiler-rt/test/hwasan/TestCases/use-after-free.c +++ b/compiler-rt/test/hwasan/TestCases/use-after-free.c @@ -23,7 +23,7 @@ int r = 0; if (ISREAD) r = x[5]; else x[5] = 42; // should be on the same line. // CHECK: [[TYPE]] of size 1 at {{.*}} tags: [[PTR_TAG:[0-9a-f][0-9a-f]]]/[[MEM_TAG:[0-9a-f][0-9a-f]]] (ptr/mem) - // CHECK: #0 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]] + // CHECK: #{{[0-9]}} {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]] // Offset is 5 or 11 depending on left/right alignment. // CHECK: is a small unallocated heap chunk; size: 32 offset: {{5|11}} // CHECK: is located 5 bytes inside of 10-byte region @@ -37,6 +37,6 @@ // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-19]] // CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes): // CHECK: =>{{.*}}[[MEM_TAG]] - // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main + // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch return r; } diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -267,7 +267,7 @@ bool InGlobal; bool InTls; - void init(Triple &TargetTriple); + void init(Triple &TargetTriple, bool InstrumentWithCalls); unsigned getObjectAlignment() const { return 1U << Scale; } }; ShadowMapping Mapping; @@ -284,6 +284,9 @@ bool OutlinedChecks; bool UseShortGranules; bool InstrumentLandingPads; + bool InstrumentWithCalls; + bool InstrumentStack; + bool UsePageAliases; bool HasMatchAllTag = false; uint8_t MatchAllTag = 0; @@ -479,7 +482,13 @@ TargetTriple = Triple(M.getTargetTriple()); - Mapping.init(TargetTriple); + // x86_64 uses userspace pointer aliases, currently heap-only with callback + // instrumentation only. + UsePageAliases = TargetTriple.getArch() == Triple::x86_64; + InstrumentWithCalls = UsePageAliases ? true : ClInstrumentWithCalls; + InstrumentStack = UsePageAliases ? false : ClInstrumentStack; + + Mapping.init(TargetTriple, InstrumentWithCalls); C = &(M.getContext()); IRBuilder<> IRB(*C); @@ -521,7 +530,7 @@ createHwasanCtorComdat(); bool InstrumentGlobals = ClGlobals.getNumOccurrences() ? ClGlobals : NewRuntime; - if (InstrumentGlobals) + if (InstrumentGlobals && !UsePageAliases) instrumentGlobals(); bool InstrumentPersonalityFunctions = @@ -721,6 +730,7 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite, unsigned AccessSizeIndex, Instruction *InsertBefore) { + assert(!UsePageAliases); const int64_t AccessInfo = (CompileKernel << HWASanAccessInfo::CompileKernelShift) + (HasMatchAllTag << HWASanAccessInfo::HasMatchAllShift) + @@ -849,7 +859,7 @@ (!O.Alignment || *O.Alignment >= (1ULL << Mapping.Scale) || *O.Alignment >= O.TypeSize / 8)) { size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeSize); - if (ClInstrumentWithCalls) { + if (InstrumentWithCalls) { IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex], IRB.CreatePointerCast(Addr, IntptrTy)); } else { @@ -884,7 +894,7 @@ Size = AlignedSize; Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty()); - if (ClInstrumentWithCalls) { + if (InstrumentWithCalls) { IRB.CreateCall(HwasanTagMemoryFunc, {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag, ConstantInt::get(IntptrTy, AlignedSize)}); @@ -976,6 +986,7 @@ // Add a tag to an address. Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag) { + assert(!UsePageAliases); Value *TaggedPtrLong; if (CompileKernel) { // Kernel addresses have 0xFF in the most significant byte. @@ -1207,7 +1218,7 @@ DenseMap> AllocaDbgMap; for (auto &BB : F) { for (auto &Inst : BB) { - if (ClInstrumentStack) + if (InstrumentStack) if (AllocaInst *AI = dyn_cast(&Inst)) { if (isInterestingAlloca(*AI)) AllocasToInstrument.push_back(AI); @@ -1343,6 +1354,7 @@ } void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) { + assert(!UsePageAliases); Constant *Initializer = GV->getInitializer(); uint64_t SizeInBytes = M.getDataLayout().getTypeAllocSize(Initializer->getType()); @@ -1515,13 +1527,14 @@ } } -void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple) { +void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple, + bool InstrumentWithCalls) { Scale = kDefaultShadowScale; if (ClMappingOffset.getNumOccurrences() > 0) { InGlobal = false; InTls = false; Offset = ClMappingOffset; - } else if (ClEnableKhwasan || ClInstrumentWithCalls) { + } else if (ClEnableKhwasan || InstrumentWithCalls) { InGlobal = false; InTls = false; Offset = 0; diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll b/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll --- a/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll +++ b/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll @@ -9,7 +9,7 @@ ; CHECK-LABEL: @atomicrmw( ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64 -; CHECK: call void asm sideeffect "int3\0Anopl 83(%rax)", "{rdi}"(i64 %[[A]]) +; CHECK: call void @__hwasan_store8(i64 %[[A]]) ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935 @@ -26,7 +26,7 @@ ; CHECK-LABEL: @cmpxchg( ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64 -; CHECK: call void asm sideeffect "int3\0Anopl 83(%rax)", "{rdi}"(i64 %[[A]]) +; CHECK: call void @__hwasan_store8(i64 %[[A]]) ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935 diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll b/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll --- a/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll +++ b/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll @@ -12,10 +12,8 @@ ; CHECK-LABEL: @test_load8( ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 -; ABORT: call void asm sideeffect "int3\0Anopl 64(%rax)", "{rdi}"(i64 %[[A]]) -; ABORT: unreachable -; RECOVER: call void asm sideeffect "int3\0Anopl 96(%rax)", "{rdi}"(i64 %[[A]]) -; RECOVER: br label +; ABORT: call void @__hwasan_load1(i64 %[[A]]) +; RECOVER: call void @__hwasan_load1_noabort(i64 %[[A]]) ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935 @@ -50,10 +48,8 @@ ; CHECK-LABEL: @test_store8( ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 -; ABORT: call void asm sideeffect "int3\0Anopl 80(%rax)", "{rdi}"(i64 %[[A]]) -; ABORT: unreachable -; RECOVER: call void asm sideeffect "int3\0Anopl 112(%rax)", "{rdi}"(i64 %[[A]]) -; RECOVER: br label +; ABORT: call void @__hwasan_store1(i64 %[[A]]) +; RECOVER: call void @__hwasan_store1_noabort(i64 %[[A]]) ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935 diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll b/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll --- a/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll +++ b/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll @@ -15,10 +15,8 @@ ; CHECK-LABEL: @test_load( ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 -; ABORT: call void asm sideeffect "int3\0Anopl 64(%rax)", "{rdi}"(i64 %[[A]]) -; ABORT: unreachable -; RECOVER: call void asm sideeffect "int3\0Anopl 96(%rax)", "{rdi}"(i64 %[[A]]) -; RECOVER: br label +; ABORT: call void @__hwasan_load1(i64 %[[A]]) +; RECOVER: call void @__hwasan_load1_noabort(i64 %[[A]]) ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64 ; CHECK: %[[UNTAGGED:[^ ]*]] = or i64 %[[A]], -72057594037927936