[PATCH] D108377: [asan] Implemented custom calling convention similar used by HWASan for X86.
kstoimenov updated this revision to Diff 367577. kstoimenov added a comment. Update before expanding intrinsics. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D108377/new/ https://reviews.llvm.org/D108377 Files: clang/test/CodeGen/asan-use-callbacks.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp === --- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -348,6 +348,10 @@ static cl::opt ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); +static cl::opt ClOptimizeCallbacks("asan-optimize-callbacks", + cl::desc("Optimize callbacks"), + cl::Hidden, cl::init(false)); + static cl::opt ClOptSameTemp( "asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true)); @@ -634,6 +638,7 @@ C = &(M.getContext()); LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); +Int8PtrTy = Type::getInt8PtrTy(*C); TargetTriple = Triple(M.getTargetTriple()); Mapping = getShadowMapping(TargetTriple, LongSize, this->CompileKernel); @@ -684,6 +689,7 @@ Value *SizeArgument, uint32_t Exp); void instrumentMemIntrinsic(MemIntrinsic *MI); Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); + void encodeMemToShadowInfo(int64_t *AccessInfo); bool suppressInstrumentationSiteForDebug(int &Instrumented); bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI); bool maybeInsertAsanInitAtFunctionEntry(Function &F); @@ -724,6 +730,7 @@ bool UseAfterScope; AsanDetectStackUseAfterReturnMode UseAfterReturn; Type *IntptrTy; + Type *Int8PtrTy; ShadowMapping Mapping; FunctionCallee AsanHandleNoReturnFunc; FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction; @@ -1753,12 +1760,21 @@ size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); if (UseCalls) { -if (Exp == 0) - IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], - AddrLong); -else - IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], - {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); +if (ClOptimizeCallbacks) { + Value *Ptr8 = IRB.CreatePointerCast(Addr, Int8PtrTy); + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + IRB.CreateCall( + Intrinsic::getDeclaration(M, Intrinsic::asan_check_memaccess), + {Ptr8, ConstantInt::get(IRB.getInt8Ty(), IsWrite), + ConstantInt::get(IRB.getInt8Ty(), AccessSizeIndex)}); +} else { + if (Exp == 0) +IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], + AddrLong); + else +IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], + {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); +} return; } Index: clang/test/CodeGen/asan-use-callbacks.cpp === --- clang/test/CodeGen/asan-use-callbacks.cpp +++ clang/test/CodeGen/asan-use-callbacks.cpp @@ -1,12 +1,18 @@ -// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -fsanitize=address \ -// RUN: -o - %s \ +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - \ +// RUN: -fsanitize=address %s \ // RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE // RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - \ // RUN: -fsanitize=address %s -fsanitize-address-outline-instrumentation \ // RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - \ +// RUN: -fsanitize=address %s -fsanitize-address-outline-instrumentation \ +// RUN: -mllvm -asan-optimize-callbacks \ +// RUN: | FileCheck %s --check-prefixes=CHECK-OPTIMIZED + // CHECK-NO-OUTLINE-NOT: call{{.*}}@__asan_load4 // CHECK-OUTLINE: call{{.*}}@__asan_load4 +// CHECK-OPTIMIZED: call{{.*}}@llvm.asan.check.memaccess(i8*{{.*}}, i64{{.*}}, i32{{.*}}) int deref(int *p) { return *p; Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp === --- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -348,6 +348,10 @@ static cl::opt ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); +static cl::opt ClOptimizeCallbacks("asan-optimize-callbacks", + cl::desc("Optimize callbacks"), +
[PATCH] D108377: [asan] Implemented custom calling convention similar used by HWASan for X86.
vitalybuka added inline comments. Comment at: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp:571 + getShadowMapping(TargetTriple, M.getDataLayout().getPointerSizeInBits(), + ClEnableKasan.getNumOccurrences() > 0); + *ShadowBase = Mapping.Offset; Unfortunately we need Kernel as argument, similar to RecoverShift in HWAsan. Look at CL flags as internal per process constants. So if value is controlled by them then it's OK to assume the same value. Kernel value however can be set by fronted e.g. from clang and does not match ClEnableKasan. I propose to have own set of intrinsics for kernel/non-kernel to avoid fancy bit packing or unreadable 1/0 arguments. Later we can cleunup hwasan as well. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D108377/new/ https://reviews.llvm.org/D108377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D108377: [asan] Implemented custom calling convention similar used by HWASan for X86.
vitalybuka added inline comments. Comment at: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h:151 +// Get AddressSanitizer parameters. +void getAddressSanitizerParams(Module &M, uint64_t *ShadowBase, + int *MappingScale, bool *OrShadowOffset); Could please please replace Module with targetTriple and pointerSizeInBits. We don't need entire module for that even if current callers have it. Comment at: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h:90 +void getASanShadowMapping(int *Scale, uint64_t *Offset, bool *OrShadowOffset); + I don't see implementation of this one. And I expected getAddressSanitizerParams here, not in AddressSanitizer.h. Is there a reson to declare it there? Comment at: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp:566 +void getAddressSanitizerParams(Module &M, uint64_t *ShadowBase, + int *MappingScale, bool *OrShadowOffset) { It would be nice to introduce this function as a separate NFC patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D108377/new/ https://reviews.llvm.org/D108377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D108377: [asan] Implemented custom calling convention similar used by HWASan for X86.
kstoimenov updated this revision to Diff 367500. kstoimenov added a comment. Pulled constants like shadow base, etc out of the intrinsic. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D108377/new/ https://reviews.llvm.org/D108377 Files: clang/test/CodeGen/asan-use-callbacks.cpp llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp === --- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -348,6 +348,10 @@ static cl::opt ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); +static cl::opt ClOptimizeCallbacks("asan-optimize-callbacks", + cl::desc("Optimize callbacks"), + cl::Hidden, cl::init(false)); + static cl::opt ClOptSameTemp( "asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true)); @@ -559,6 +563,17 @@ return Mapping; } +void getAddressSanitizerParams(Module &M, uint64_t *ShadowBase, + int *MappingScale, bool *OrShadowOffset) { + Triple TargetTriple = Triple(M.getTargetTriple()); + auto Mapping = + getShadowMapping(TargetTriple, M.getDataLayout().getPointerSizeInBits(), + ClEnableKasan.getNumOccurrences() > 0); + *ShadowBase = Mapping.Offset; + *MappingScale = Mapping.Scale; + *OrShadowOffset = Mapping.OrShadowOffset; +} + static uint64_t getRedzoneSizeForScale(int MappingScale) { // Redzone used for stack and globals is at least 32 bytes. // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. @@ -623,6 +638,7 @@ C = &(M.getContext()); LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); +Int8PtrTy = Type::getInt8PtrTy(*C); TargetTriple = Triple(M.getTargetTriple()); Mapping = getShadowMapping(TargetTriple, LongSize, this->CompileKernel); @@ -673,6 +689,7 @@ Value *SizeArgument, uint32_t Exp); void instrumentMemIntrinsic(MemIntrinsic *MI); Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); + void encodeMemToShadowInfo(int64_t *AccessInfo); bool suppressInstrumentationSiteForDebug(int &Instrumented); bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI); bool maybeInsertAsanInitAtFunctionEntry(Function &F); @@ -713,6 +730,7 @@ bool UseAfterScope; AsanDetectStackUseAfterReturnMode UseAfterReturn; Type *IntptrTy; + Type *Int8PtrTy; ShadowMapping Mapping; FunctionCallee AsanHandleNoReturnFunc; FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction; @@ -1742,12 +1760,21 @@ size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); if (UseCalls) { -if (Exp == 0) - IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], - AddrLong); -else - IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], - {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); +if (ClOptimizeCallbacks) { + Value *Ptr8 = IRB.CreatePointerCast(Addr, Int8PtrTy); + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + IRB.CreateCall( + Intrinsic::getDeclaration(M, Intrinsic::asan_check_memaccess), + {Ptr8, ConstantInt::get(IRB.getInt8Ty(), IsWrite), + ConstantInt::get(IRB.getInt8Ty(), AccessSizeIndex)}); +} else { + if (Exp == 0) +IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], + AddrLong); + else +IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], + {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); +} return; } Index: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h === --- llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h +++ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h @@ -87,6 +87,8 @@ return true; } +void getASanShadowMapping(int *Scale, uint64_t *Offset, bool *OrShadowOffset); + } // namespace llvm #endif Index: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h === --- llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h +++ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h @@ -147,6 +147,10 @@ bool UseOdrIndicator = true, AsanDtorKind DestructorKind = AsanDtorKind::Global); +// Get
[PATCH] D108377: [asan] Implemented custom calling convention similar used by HWASan for X86.
kstoimenov created this revision. kstoimenov added a reviewer: vitalybuka. Herald added a subscriber: hiraditya. kstoimenov requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits. The address sanitizer part of the code. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D108377 Files: clang/test/CodeGen/asan-use-callbacks.cpp llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp === --- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -348,6 +348,10 @@ static cl::opt ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); +static cl::opt ClOptimizeCallbacks("asan-optimize-callbacks", + cl::desc("Optimize callbacks"), + cl::Hidden, cl::init(false)); + static cl::opt ClOptSameTemp( "asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true)); @@ -559,6 +563,17 @@ return Mapping; } +void getAddressSanitizerParams(Module &M, uint64_t *ShadowBase, + int *MappingScale, bool *OrShadowOffset) { + Triple TargetTriple = Triple(M.getTargetTriple()); + auto Mapping = + getShadowMapping(TargetTriple, M.getDataLayout().getPointerSizeInBits(), + ClEnableKasan.getNumOccurrences() > 0); + *ShadowBase = Mapping.Offset; + *MappingScale = Mapping.Scale; + *OrShadowOffset = Mapping.OrShadowOffset; +} + static uint64_t getRedzoneSizeForScale(int MappingScale) { // Redzone used for stack and globals is at least 32 bytes. // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. @@ -623,6 +638,7 @@ C = &(M.getContext()); LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); +Int8PtrTy = Type::getInt8PtrTy(*C); TargetTriple = Triple(M.getTargetTriple()); Mapping = getShadowMapping(TargetTriple, LongSize, this->CompileKernel); @@ -673,6 +689,7 @@ Value *SizeArgument, uint32_t Exp); void instrumentMemIntrinsic(MemIntrinsic *MI); Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); + void encodeMemToShadowInfo(int64_t *AccessInfo); bool suppressInstrumentationSiteForDebug(int &Instrumented); bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI); bool maybeInsertAsanInitAtFunctionEntry(Function &F); @@ -713,6 +730,7 @@ bool UseAfterScope; AsanDetectStackUseAfterReturnMode UseAfterReturn; Type *IntptrTy; + Type *Int8PtrTy; ShadowMapping Mapping; FunctionCallee AsanHandleNoReturnFunc; FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction; @@ -1742,12 +1760,21 @@ size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); if (UseCalls) { -if (Exp == 0) - IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], - AddrLong); -else - IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], - {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); +if (ClOptimizeCallbacks) { + Value *Ptr8 = IRB.CreatePointerCast(Addr, Int8PtrTy); + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + IRB.CreateCall( + Intrinsic::getDeclaration(M, Intrinsic::asan_check_memaccess), + {Ptr8, ConstantInt::get(IRB.getInt8Ty(), IsWrite), + ConstantInt::get(IRB.getInt8Ty(), AccessSizeIndex)}); +} else { + if (Exp == 0) +IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], + AddrLong); + else +IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], + {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); +} return; } Index: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h === --- llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h +++ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h @@ -87,6 +87,8 @@ return true; } +void getASanShadowMapping(int *Scale, uint64_t *Offset, bool *OrShadowOffset); + } // namespace llvm #endif Index: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h === --- llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h +++ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h @@ -147,6 +147,10 @@ bool UseOdrIn