@@ -441,27 +441,35 @@ static cl::opt<AsanDtorKind> ClOverrideDestructorKind(
441441 cl::init(AsanDtorKind::Invalid), cl::Hidden);
442442
443443// SYCL flags
444+ static cl::opt<bool > ClSpirOffloadPrivates (
445+ " asan-spir-privates" ,
446+ cl::desc (" Instrument private pointer on SPIR-V target" ), cl::Hidden,
447+ cl::init(true ));
448+
444449static cl::opt<bool >
445- ClSpirOffloadPrivates (" asan-spir-privates " ,
446- cl::desc (" instrument private pointer" ), cl::Hidden ,
447- cl::init(true ));
450+ ClSpirOffloadGlobals (" asan-spir-globals " ,
451+ cl::desc (" Instrument global pointer on SPIR-V target " ) ,
452+ cl::Hidden, cl::init(true ));
448453
449- static cl::opt<bool > ClSpirOffloadGlobals (" asan-spir-globals" ,
450- cl::desc (" instrument global pointer" ),
451- cl::Hidden, cl::init(true ));
454+ static cl::opt<bool >
455+ ClSpirOffloadLocals (" asan-spir-locals" ,
456+ cl::desc (" Instrument local pointer on SPIR-V target" ),
457+ cl::Hidden, cl::init(true ));
452458
453- static cl::opt<bool > ClSpirOffloadLocals (" asan-spir-locals" ,
454- cl::desc (" instrument local pointer" ),
455- cl::Hidden, cl::init(true ));
459+ static cl::opt<bool > ClSpirOffloadGenerics (
460+ " asan-spir-generics" ,
461+ cl::desc (" Instrument generic pointer on SPIR-V target" ), cl::Hidden,
462+ cl::init(true ));
456463
457464static cl::opt<bool >
458- ClSpirOffloadGenerics (" asan-spir-generics " ,
459- cl::desc (" instrument generic pointer " ), cl::Hidden ,
460- cl::init(true ));
465+ ClDeviceGlobals (" asan-device-globals " ,
466+ cl::desc (" Instrument device globals on SPIR-V target " ) ,
467+ cl::Hidden, cl::init(true ));
461468
462- static cl::opt<bool > ClDeviceGlobals (" asan-device-globals" ,
463- cl::desc (" instrument device globals" ),
464- cl::Hidden, cl::init(true ));
469+ static cl::opt<bool > ClSpirCheckShadowBounds (
470+ " asan-spir-shadow-bounds" ,
471+ cl::desc (" Enable checking shadow bounds on SPIR-V target" ), cl::Hidden,
472+ cl::init(false ));
465473
466474// Debug flags.
467475
@@ -1394,7 +1402,8 @@ static void ExtendSpirKernelArgs(Module &M, FunctionAnalysisManager &FAM,
13941402 // following structure:
13951403 // uptr unmangled_kernel_name
13961404 // uptr unmangled_kernel_name_size
1397- StructType *StructTy = StructType::get (IntptrTy, IntptrTy);
1405+ // uptr sanitized_flags
1406+ StructType *StructTy = StructType::get (IntptrTy, IntptrTy, IntptrTy);
13981407
13991408 if (!HasESIMD)
14001409 for (Function &F : M) {
@@ -1425,9 +1434,21 @@ static void ExtendSpirKernelArgs(Module &M, FunctionAnalysisManager &FAM,
14251434 KernelNamesBytes.append (KernelName.begin (), KernelName.end ());
14261435 auto *KernelNameGV = GetOrCreateGlobalString (
14271436 M, " __asan_kernel" , KernelName, kSpirOffloadConstantAS );
1437+
1438+ uintptr_t SanitizerFlags = 0 ;
1439+ SanitizerFlags |= ClSpirOffloadLocals ? SanitizedKernelFlags::CHECK_LOCALS
1440+ : SanitizedKernelFlags::NO_CHECK;
1441+ SanitizerFlags |= ClSpirOffloadPrivates
1442+ ? SanitizedKernelFlags::CHECK_PRIVATES
1443+ : SanitizedKernelFlags::NO_CHECK;
1444+ SanitizerFlags |= ClSpirCheckShadowBounds != 0
1445+ ? SanitizedKernelFlags::ASAN_CHECK_SHADOW_BOUNDS
1446+ : SanitizedKernelFlags::NO_CHECK;
1447+
14281448 SpirKernelsMetadata.emplace_back (ConstantStruct::get (
14291449 StructTy, ConstantExpr::getPointerCast (KernelNameGV, IntptrTy),
1430- ConstantInt::get (IntptrTy, KernelName.size ())));
1450+ ConstantInt::get (IntptrTy, KernelName.size ()),
1451+ ConstantInt::get (IntptrTy, SanitizerFlags)));
14311452 }
14321453
14331454 // Create global variable to record spirv kernels' information
@@ -1615,6 +1636,17 @@ PreservedAnalyses AddressSanitizerPass::run(Module &M,
16151636 ExtendSpirKernelArgs (M, FAM, HasESIMD);
16161637 Modified = true ;
16171638
1639+ {
1640+ IRBuilder<> IRB (M.getContext ());
1641+ M.getOrInsertGlobal (" __asan_check_shadow_bounds" , IRB.getInt32Ty (), [&] {
1642+ return new GlobalVariable (
1643+ M, IRB.getInt32Ty (), true , GlobalValue::WeakODRLinkage,
1644+ ConstantInt::get (IRB.getInt32Ty (), ClSpirCheckShadowBounds),
1645+ " __asan_check_shadow_bounds" , nullptr ,
1646+ llvm::GlobalValue::NotThreadLocal, kSpirOffloadGlobalAS );
1647+ });
1648+ }
1649+
16181650 if (HasESIMD) {
16191651 GlobalStringMap.clear ();
16201652 return PreservedAnalyses::none ();
@@ -1693,19 +1725,21 @@ static bool isUnsupportedAMDGPUAddrspace(Value *Addr) {
16931725}
16941726
16951727static bool isUnsupportedDeviceGlobal (GlobalVariable *G) {
1696- // Non image scope device globals are implemented by device USM, and the
1697- // out-of-bounds check for them will be done by sanitizer USM part. So we
1698- // exclude them here.
1699- if (!G->hasAttribute (" sycl-device-image-scope" ))
1700- return true ;
1701-
17021728 // Skip instrumenting on "__AsanKernelMetadata" etc.
1703- if (G->getName ().starts_with (" __Asan" ))
1729+ if (G->getName ().starts_with (" __Asan" ) || G-> getName (). starts_with ( " __asan " ) )
17041730 return true ;
17051731
17061732 if (G->getAddressSpace () == kSpirOffloadLocalAS )
17071733 return !ClSpirOffloadLocals;
17081734
1735+ // When shadow bounds check is enabled, we need to instrument all global
1736+ // variables that user code can access
1737+ if (ClSpirCheckShadowBounds)
1738+ return false ;
1739+
1740+ // Non image scope device globals are implemented by device USM, and the
1741+ // out-of-bounds check for them will be done by sanitizer USM part. So we
1742+ // exclude them here.
17091743 Attribute Attr = G->getAttribute (" sycl-device-image-scope" );
17101744 return (!Attr.isStringAttribute () || Attr.getValueAsString () == " false" );
17111745}
0 commit comments