Index: llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -183,6 +183,7 @@ void initializeCallbacks(Module &M); + Value *getDynamicShadowIfunc(IRBuilder<> &IRB); Value *getDynamicShadowNonTls(IRBuilder<> &IRB); void untagPointerOperand(Instruction *I, Value *Addr); @@ -384,9 +385,8 @@ HwasanGenerateTagFunc = checkSanitizerInterfaceFunction( M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty)); - if (Mapping.InGlobal) - ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow", - ArrayType::get(IRB.getInt8Ty(), 0)); + ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow", + ArrayType::get(IRB.getInt8Ty(), 0)); const std::string MemIntrinCallbackPrefix = CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix; @@ -404,19 +404,23 @@ M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy())); } +Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) { + // An empty inline asm with input reg == output reg. + // An opaque no-op cast, basically. + InlineAsm *Asm = InlineAsm::get( + FunctionType::get(Int8PtrTy, {ShadowGlobal->getType()}, false), + StringRef(""), StringRef("=r,0"), + /*hasSideEffects=*/false); + return IRB.CreateCall(Asm, {ShadowGlobal}, ".hwasan.shadow"); +} + Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) { // Generate code only when dynamic addressing is needed. if (Mapping.Offset != kDynamicShadowSentinel) return nullptr; if (Mapping.InGlobal) { - // An empty inline asm with input reg == output reg. - // An opaque no-op cast, basically. - InlineAsm *Asm = InlineAsm::get( - FunctionType::get(Int8PtrTy, {ShadowGlobal->getType()}, false), - StringRef(""), StringRef("=r,0"), - /*hasSideEffects=*/false); - return IRB.CreateCall(Asm, {ShadowGlobal}, ".hwasan.shadow"); + return getDynamicShadowIfunc(IRB); } else { Value *GlobalDynamicAddress = IRB.GetInsertBlock()->getParent()->getParent()->getOrInsertGlobal( @@ -828,13 +832,19 @@ if (!Mapping.InTls) return getDynamicShadowNonTls(IRB); + Function *F = IRB.GetInsertBlock()->getParent(); + bool UseInterceptorABI = + F->getFnAttribute("hwasan-abi").getValueAsString() == "interceptor"; + + if (UseInterceptorABI && !WithFrameRecord && TargetTriple.isAndroid()) + return getDynamicShadowIfunc(IRB); + Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy); assert(SlotPtr); Instruction *ThreadLong = IRB.CreateLoad(SlotPtr); - Function *F = IRB.GetInsertBlock()->getParent(); - if (F->getFnAttribute("hwasan-abi").getValueAsString() == "interceptor") { + if (UseInterceptorABI) { Value *ThreadLongEqZero = IRB.CreateICmpEQ(ThreadLong, ConstantInt::get(IntptrTy, 0)); auto *Br = cast(SplitBlockAndInsertIfThen( Index: llvm/test/Instrumentation/HWAddressSanitizer/lazy-thread-init.ll =================================================================== --- llvm/test/Instrumentation/HWAddressSanitizer/lazy-thread-init.ll +++ llvm/test/Instrumentation/HWAddressSanitizer/lazy-thread-init.ll @@ -1,17 +1,20 @@ ; RUN: opt -S -hwasan < %s | FileCheck %s -target triple = "x86_64-unknown-linux-gnu" +target triple = "aarch64--linux-android" declare void @bar([16 x i32]* %p) -define void @foo() sanitize_hwaddress "hwasan-abi"="interceptor" { - ; CHECK: [[LOAD:%[^ ]*]] = load i64, i64* @__hwasan_tls +define void @alloca() sanitize_hwaddress "hwasan-abi"="interceptor" { + ; CHECK: [[A:%[^ ]*]] = call i8* @llvm.thread.pointer() + ; CHECK: [[B:%[^ ]*]] = getelementptr i8, i8* [[A]], i32 48 + ; CHECK: [[C:%[^ ]*]] = bitcast i8* [[B]] to i64* + ; CHECK: [[LOAD:%[^ ]*]] = load i64, i64* [[C]] ; CHECK: [[ICMP:%[^ ]*]] = icmp eq i64 [[LOAD]], 0 ; CHECK: br i1 [[ICMP]], label %[[INIT:[^,]*]], label %[[CONT:[^,]*]], !prof [[PROF:![0-9]+]] ; CHECK: [[INIT]]: ; CHECK: call void @__hwasan_thread_enter() - ; CHECK: [[RELOAD:%[^ ]*]] = load i64, i64* @__hwasan_tls + ; CHECK: [[RELOAD:%[^ ]*]] = load i64, i64* [[C]] ; CHECK: br label %[[CONT]] ; CHECK: [[CONT]]: @@ -22,4 +25,11 @@ ret void } +define i32 @load(i32* %p) sanitize_hwaddress "hwasan-abi"="interceptor" { + ; CHECK: [[SHADOW:%[^ ]*]] = call i8* asm "", "=r,0"([0 x i8]* @__hwasan_shadow) + ; CHECK: call void @llvm.hwasan.check.memaccess(i8* [[SHADOW]], + %v = load i32, i32* %p + ret i32 %v +} + ; CHECK: [[PROF]] = !{!"branch_weights", i32 1, i32 100000}