@@ -55,8 +55,18 @@ static __SYCL_CONSTANT__ const char __generic_to[] =
5555
5656namespace {
5757
58- void __asan_report_unknown_device ();
59- void __asan_print_shadow_memory (uptr addr, uptr shadow_address, uint32_t as);
58+ struct DebugInfo {
59+ uptr addr;
60+ uint32_t as;
61+ size_t access_size;
62+ bool is_write;
63+ const char __SYCL_CONSTANT__ *file;
64+ const char __SYCL_CONSTANT__ *func;
65+ uint32_t line;
66+ };
67+
68+ void ReportUnknownDevice (const DebugInfo *debug);
69+ void PrintShadowMemory (uptr addr, uptr shadow_address, uint32_t as);
6070
6171__SYCL_GLOBAL__ void *ToGlobal (void *ptr) {
6272 return __spirv_GenericCastToPtrExplicit_ToGlobal (ptr, 5 );
@@ -88,7 +98,8 @@ inline uptr MemToShadow_CPU(uptr addr) {
8898 return launch_info->GlobalShadowOffset + (addr >> ASAN_SHADOW_SCALE);
8999}
90100
91- inline uptr MemToShadow_DG2 (uptr addr, uint32_t as) {
101+ inline uptr MemToShadow_DG2 (uptr addr, uint32_t as,
102+ [[maybe_unused]] const DebugInfo *debug) {
92103 if (as == ADDRESS_SPACE_GENERIC) {
93104 ConvertGenericPointer (addr, as);
94105 }
@@ -166,7 +177,8 @@ inline uptr MemToShadow_DG2(uptr addr, uint32_t as) {
166177 return 0 ;
167178}
168179
169- inline uptr MemToShadow_PVC (uptr addr, uint32_t as) {
180+ inline uptr MemToShadow_PVC (uptr addr, uint32_t as,
181+ [[maybe_unused]] const DebugInfo *debug) {
170182 if (as == ADDRESS_SPACE_GENERIC) {
171183 ConvertGenericPointer (addr, as);
172184 }
@@ -243,35 +255,36 @@ inline uptr MemToShadow_PVC(uptr addr, uint32_t as) {
243255 return 0 ;
244256}
245257
246- inline uptr MemToShadow (uptr addr, uint32_t as) {
258+ inline uptr MemToShadow (uptr addr, uint32_t as,
259+ const DebugInfo *debug = nullptr ) {
247260 uptr shadow_ptr = 0 ;
248261
249262#if defined(__LIBDEVICE_PVC__)
250- shadow_ptr = MemToShadow_PVC (addr, as);
263+ shadow_ptr = MemToShadow_PVC (addr, as, debug );
251264#elif defined(__LIBDEVICE_CPU__)
252265 shadow_ptr = MemToShadow_CPU (addr);
253266#elif defined(__LIBDEVICE_DG2__)
254- shadow_ptr = MemToShadow_DG2 (addr, as);
267+ shadow_ptr = MemToShadow_DG2 (addr, as, debug );
255268#else
256269 auto launch_info = (__SYCL_GLOBAL__ const AsanRuntimeData *)__AsanLaunchInfo;
257270 if (launch_info->DeviceTy == DeviceType::CPU) {
258271 shadow_ptr = MemToShadow_CPU (addr);
259272 } else if (launch_info->DeviceTy == DeviceType::GPU_PVC) {
260- shadow_ptr = MemToShadow_PVC (addr, as);
273+ shadow_ptr = MemToShadow_PVC (addr, as, debug );
261274 } else if (launch_info->DeviceTy == DeviceType::GPU_DG2) {
262- shadow_ptr = MemToShadow_DG2 (addr, as);
275+ shadow_ptr = MemToShadow_DG2 (addr, as, debug );
263276 } else {
264277 ASAN_DEBUG (__spirv_ocl_printf (__asan_print_unsupport_device_type,
265278 (int )launch_info->DeviceTy ));
266- __asan_report_unknown_device ( );
279+ ReportUnknownDevice (debug );
267280 return 0 ;
268281 }
269282#endif
270283
271284 ASAN_DEBUG (
272285 if (shadow_ptr) {
273286 if (as == ADDRESS_SPACE_PRIVATE)
274- __asan_print_shadow_memory (addr, shadow_ptr, as);
287+ PrintShadowMemory (addr, shadow_ptr, as);
275288 else
276289 __spirv_ocl_printf (__asan_print_shadow_value1, addr, as, shadow_ptr,
277290 *(u8 *)shadow_ptr);
@@ -320,7 +333,7 @@ bool MemIsZero(__SYCL_GLOBAL__ const char *beg, uptr size) {
320333static __SYCL_CONSTANT__ const char __mem_sanitizer_report[] =
321334 " [kernel] SanitizerReport (ErrorType=%d, IsRecover=%d)\n " ;
322335
323- void __asan_exit (ErrorType error_type) {
336+ void Exit (ErrorType error_type) {
324337 // Exit the kernel when we really need it
325338 switch (error_type) {
326339 case ErrorType::UNKNOWN:
@@ -333,37 +346,8 @@ void __asan_exit(ErrorType error_type) {
333346 }
334347}
335348
336- void __asan_internal_report_save (ErrorType error_type) {
337- const int Expected = ASAN_REPORT_NONE;
338- int Desired = ASAN_REPORT_START;
339-
340- const size_t wid = WorkGroupLinearId ();
341- auto &SanitizerReport = ((__SYCL_GLOBAL__ AsanRuntimeData *)__AsanLaunchInfo)
342- ->Report [wid % ASAN_MAX_NUM_REPORTS];
343-
344- if (atomicCompareAndSet (
345- &(((__SYCL_GLOBAL__ AsanRuntimeData *)__AsanLaunchInfo)->ReportFlag ),
346- 1 , 0 ) == 0 &&
347- atomicCompareAndSet (&SanitizerReport.Flag , Desired, Expected) ==
348- Expected) {
349- SanitizerReport.ErrorTy = error_type;
350- SanitizerReport.IsRecover = false ;
351-
352- // Show we've done copying
353- atomicStore (&SanitizerReport.Flag , ASAN_REPORT_FINISH);
354-
355- ASAN_DEBUG (__spirv_ocl_printf (__mem_sanitizer_report,
356- SanitizerReport.ErrorTy ,
357- SanitizerReport.IsRecover ));
358- }
359- __asan_exit (error_type);
360- }
361-
362- void __asan_internal_report_save (
363- uptr ptr, uint32_t as, const char __SYCL_CONSTANT__ *file, uint32_t line,
364- const char __SYCL_CONSTANT__ *func, bool is_write, uint32_t access_size,
365- MemoryType memory_type, ErrorType error_type, bool is_recover = false ) {
366-
349+ void SaveReport (ErrorType error_type, MemoryType memory_type, bool is_recover,
350+ const DebugInfo *debug) {
367351 const int Expected = ASAN_REPORT_NONE;
368352 int Desired = ASAN_REPORT_START;
369353
@@ -378,6 +362,14 @@ void __asan_internal_report_save(
378362 atomicCompareAndSet (&SanitizerReport.Flag , Desired, Expected) ==
379363 Expected) {
380364
365+ const uptr ptr = debug ? debug->addr : 0 ;
366+ const uint32_t as = debug ? debug->as : 5 ;
367+ const char __SYCL_CONSTANT__ *file = debug ? debug->file : nullptr ;
368+ const uint32_t line = debug ? debug->line : 0 ;
369+ const char __SYCL_CONSTANT__ *func = debug ? debug->func : nullptr ;
370+ const bool is_write = debug ? debug->is_write : false ;
371+ const uint32_t access_size = debug ? debug->access_size : 0 ;
372+
381373 int FileLength = 0 ;
382374 int FuncLength = 0 ;
383375
@@ -426,7 +418,7 @@ void __asan_internal_report_save(
426418 SanitizerReport.ErrorTy ,
427419 SanitizerReport.IsRecover ));
428420 }
429- __asan_exit (error_type);
421+ Exit (error_type);
430422}
431423
432424// /
@@ -459,14 +451,11 @@ MemoryType GetMemoryTypeByShadowValue(int shadow_value) {
459451 }
460452}
461453
462- void __asan_report_access_error (uptr addr, uint32_t as, size_t size,
463- bool is_write, uptr poisoned_addr,
464- const char __SYCL_CONSTANT__ *file,
465- uint32_t line,
466- const char __SYCL_CONSTANT__ *func,
467- bool is_recover = false ) {
454+ void ReportAccessError (uptr poisoned_addr, uint32_t as, bool is_recover,
455+ const DebugInfo *debug) {
468456 // Check Error Type
469- auto *shadow_address = (__SYCL_GLOBAL__ s8 *)MemToShadow (poisoned_addr, as);
457+ auto *shadow_address =
458+ (__SYCL_GLOBAL__ s8 *)MemToShadow (poisoned_addr, as, debug);
470459 int shadow_value = *shadow_address;
471460 if (shadow_value > 0 ) {
472461 shadow_value = *(shadow_address + 1 );
@@ -500,39 +489,31 @@ void __asan_report_access_error(uptr addr, uint32_t as, size_t size,
500489 error_type = ErrorType::UNKNOWN;
501490 }
502491
503- __asan_internal_report_save (addr, as, file, line, func, is_write, size,
504- memory_type, error_type, is_recover);
492+ SaveReport (error_type, memory_type, is_recover, debug);
505493}
506494
507- void __asan_report_misalign_error (uptr addr, uint32_t as, size_t size,
508- bool is_write, uptr poisoned_addr,
509- const char __SYCL_CONSTANT__ *file,
510- uint32_t line,
511- const char __SYCL_CONSTANT__ *func,
512- bool is_recover = false ) {
495+ void ReportMisalignError (uptr addr, uint32_t as, bool is_recover,
496+ const DebugInfo *debug) {
513497
514- auto *shadow = (__SYCL_GLOBAL__ s8 *)MemToShadow (addr, as);
498+ auto *shadow = (__SYCL_GLOBAL__ s8 *)MemToShadow (addr, as, debug );
515499 while (*shadow >= 0 ) {
516500 ++shadow;
517501 }
518502 int shadow_value = *shadow;
519503
520- ErrorType error_type = ErrorType::MISALIGNED;
521- MemoryType memory_type = GetMemoryTypeByShadowValue (shadow_value);
522-
523- __asan_internal_report_save (addr, as, file, line, func, is_write, size,
524- memory_type, error_type, is_recover);
504+ SaveReport (ErrorType::MISALIGNED, GetMemoryTypeByShadowValue (shadow_value),
505+ is_recover, debug);
525506}
526507
527- void __asan_report_unknown_device ( ) {
528- __asan_internal_report_save (ErrorType::UNKNOWN_DEVICE);
508+ void ReportUnknownDevice ( const DebugInfo *debug ) {
509+ SaveReport (ErrorType::UNKNOWN_DEVICE, MemoryType::UNKNOWN, false , debug );
529510}
530511
531512// /
532513// / ASan utils
533514// /
534515
535- void __asan_print_shadow_memory (uptr addr, uptr shadow_address, uint32_t as) {
516+ void PrintShadowMemory (uptr addr, uptr shadow_address, uint32_t as) {
536517 uptr p = shadow_address & (~0xf );
537518 __spirv_ocl_printf (__asan_shadow_value_start, addr, as, p);
538519 for (int i = 0 ; i < 0xf ; ++i) {
@@ -546,23 +527,10 @@ void __asan_print_shadow_memory(uptr addr, uptr shadow_address, uint32_t as) {
546527 __spirv_ocl_printf (__newline);
547528}
548529
549- bool __asan_region_is_value (uptr addr, uint32_t as, std::size_t size,
550- char value) {
551- if (size == 0 )
552- return true ;
553- while (size--) {
554- auto *shadow = (__SYCL_GLOBAL__ char *)MemToShadow (addr, as);
555- if (*shadow != value) {
556- return false ;
557- }
558- ++addr;
559- }
560- return true ;
561- }
562-
563530// NOTE: size <= 16
564- inline int __asan_address_is_poisoned (uptr a, uint32_t as, size_t size = 1 ) {
565- auto *shadow_address = (__SYCL_GLOBAL__ s8 *)MemToShadow (a, as);
531+ inline int IsAddressPoisoned (uptr a, uint32_t as, size_t size,
532+ const DebugInfo *debug) {
533+ auto *shadow_address = (__SYCL_GLOBAL__ s8 *)MemToShadow (a, as, debug);
566534 if (shadow_address) {
567535 auto shadow_value = *shadow_address;
568536 if (shadow_value) {
@@ -575,28 +543,29 @@ inline int __asan_address_is_poisoned(uptr a, uint32_t as, size_t size = 1) {
575543 return false ;
576544}
577545
578- inline uptr __asan_region_is_poisoned (uptr beg, uint32_t as, size_t size) {
546+ inline uptr IsRegionPoisoned (uptr beg, uint32_t as, size_t size,
547+ const DebugInfo *debug) {
579548 if (!size)
580549 return 0 ;
581550
582551 uptr end = beg + size;
583552 uptr aligned_b = RoundUpTo (beg, ASAN_SHADOW_GRANULARITY);
584553 uptr aligned_e = RoundDownTo (end, ASAN_SHADOW_GRANULARITY);
585554
586- uptr shadow_beg = MemToShadow (aligned_b, as);
555+ uptr shadow_beg = MemToShadow (aligned_b, as, debug );
587556 if (!shadow_beg) {
588557 return 0 ;
589558 }
590- uptr shadow_end = MemToShadow (aligned_e, as);
559+ uptr shadow_end = MemToShadow (aligned_e, as, debug );
591560 if (!shadow_end) {
592561 return 0 ;
593562 }
594563
595564 // First check the first and the last application bytes,
596565 // then check the ASAN_SHADOW_GRANULARITY-aligned region by calling
597566 // MemIsZero on the corresponding shadow.
598- if (!__asan_address_is_poisoned (beg, as) &&
599- !__asan_address_is_poisoned (end - 1 , as) &&
567+ if (!IsAddressPoisoned (beg, as, 1 , debug ) &&
568+ !IsAddressPoisoned (end - 1 , as, 1 , debug ) &&
600569 (shadow_end <= shadow_beg ||
601570 MemIsZero ((__SYCL_GLOBAL__ const char *)shadow_beg,
602571 shadow_end - shadow_beg)))
@@ -605,7 +574,7 @@ inline uptr __asan_region_is_poisoned(uptr beg, uint32_t as, size_t size) {
605574 // The fast check failed, so we have a poisoned byte somewhere.
606575 // Find it slowly.
607576 for (; beg < end; beg++)
608- if (__asan_address_is_poisoned (beg, as))
577+ if (IsAddressPoisoned (beg, as, 1 , debug ))
609578 return beg;
610579
611580 return 0 ;
@@ -628,27 +597,25 @@ constexpr size_t AlignMask(size_t n) { return n - 1; }
628597 const char __SYCL_CONSTANT__ *func) { \
629598 if (!__AsanLaunchInfo) \
630599 return ; \
600+ DebugInfo debug{addr, as, size, is_write, file, func, line}; \
631601 if (addr & AlignMask (size)) { \
632- __asan_report_misalign_error (addr, as, size, is_write, addr, file, line, \
633- func); \
602+ ReportMisalignError (addr, as, false , &debug); \
634603 } \
635- if (__asan_address_is_poisoned (addr, as, size)) { \
636- __asan_report_access_error (addr, as, size, is_write, addr, file, line, \
637- func); \
604+ if (IsAddressPoisoned (addr, as, size, &debug)) { \
605+ ReportAccessError (addr, as, false , &debug); \
638606 } \
639607 } \
640608 DEVICE_EXTERN_C_NOINLINE void __asan_##type##size##_as##as##_noabort( \
641609 uptr addr, const char __SYCL_CONSTANT__ *file, uint32_t line, \
642610 const char __SYCL_CONSTANT__ *func) { \
643611 if (!__AsanLaunchInfo) \
644612 return ; \
613+ DebugInfo debug{addr, as, size, is_write, file, func, line}; \
645614 if (addr & AlignMask (size)) { \
646- __asan_report_misalign_error (addr, as, size, is_write, addr, file, line, \
647- func, true ); \
615+ ReportMisalignError (addr, as, true , &debug); \
648616 } \
649- if (__asan_address_is_poisoned (addr, as, size)) { \
650- __asan_report_access_error (addr, as, size, is_write, addr, file, line, \
651- func, true ); \
617+ if (IsAddressPoisoned (addr, as, size, &debug)) { \
618+ ReportAccessError (addr, as, true , &debug); \
652619 } \
653620 }
654621
@@ -676,19 +643,19 @@ ASAN_REPORT_ERROR(store, true, 16)
676643 uint32_t line, const char __SYCL_CONSTANT__ *func) { \
677644 if (!__AsanLaunchInfo) \
678645 return ; \
679- if ( auto poisoned_addr = __asan_region_is_poisoned ( addr, as, size)) { \
680- __asan_report_access_error (addr, as, size, is_write, poisoned_addr, \
681- file, line, func); \
646+ DebugInfo debug{ addr, as, size, is_write, file, func, line}; \
647+ if ( auto poisoned_addr = IsRegionPoisoned (addr, as, size, &debug)) { \
648+ ReportAccessError (poisoned_addr, as, false , &debug); \
682649 } \
683650 } \
684651 DEVICE_EXTERN_C_NOINLINE void __asan_##type##N_as##as##_noabort( \
685652 uptr addr, size_t size, const char __SYCL_CONSTANT__ *file, \
686653 uint32_t line, const char __SYCL_CONSTANT__ *func) { \
687654 if (!__AsanLaunchInfo) \
688655 return ; \
689- if ( auto poisoned_addr = __asan_region_is_poisoned ( addr, as, size)) { \
690- __asan_report_access_error (addr, as, size, is_write, poisoned_addr, \
691- file, line, func, true ); \
656+ DebugInfo debug{ addr, as, size, is_write, file, func, line}; \
657+ if ( auto poisoned_addr = IsRegionPoisoned (addr, as, size, &debug)) { \
658+ ReportAccessError (poisoned_addr, as, true , &debug ); \
692659 } \
693660 }
694661
0 commit comments