@@ -128,6 +128,12 @@ inline __lsan::ChunkTag Metadata::GetLsanTag() const {
128128 return static_cast <__lsan::ChunkTag>(lsan_tag);
129129}
130130
131+ inline void Metadata::SetAllocType (AllocType type) { alloc_type = type; }
132+
133+ inline AllocType Metadata::GetAllocType () const {
134+ return static_cast <AllocType>(alloc_type);
135+ }
136+
131137uptr GetAliasRegionStart () {
132138#if defined(HWASAN_ALIASING_MODE)
133139 constexpr uptr kAliasRegionOffset = 1ULL << (kTaggableRegionCheckShift - 1 );
@@ -181,7 +187,7 @@ static uptr TaggedSize(uptr size) {
181187}
182188
183189static void *HwasanAllocate (StackTrace *stack, uptr orig_size, uptr alignment,
184- bool zeroise) {
190+ AllocType alloc_type, bool zeroise) {
185191 // Keep this consistent with LSAN and ASAN behavior.
186192 if (UNLIKELY (orig_size == 0 ))
187193 orig_size = 1 ;
@@ -259,6 +265,7 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
259265 meta->SetLsanTag (__lsan::DisabledInThisThread () ? __lsan::kIgnored
260266 : __lsan::kDirectlyLeaked );
261267#endif
268+ meta->SetAllocType (alloc_type);
262269 meta->SetAllocated (StackDepotPut (*stack), orig_size);
263270 RunMallocHooks (user_ptr, orig_size);
264271 return user_ptr;
@@ -285,7 +292,7 @@ static bool CheckInvalidFree(StackTrace *stack, void *untagged_ptr,
285292 return false ;
286293}
287294
288- static void HwasanDeallocate (StackTrace *stack, void *tagged_ptr) {
295+ static void HwasanDeallocate (StackTrace *stack, void *tagged_ptr, AllocType ) {
289296 CHECK (tagged_ptr);
290297 void *untagged_ptr = UntagPtr (tagged_ptr);
291298
@@ -379,15 +386,15 @@ static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old,
379386 void *untagged_ptr_old = UntagPtr (tagged_ptr_old);
380387 if (CheckInvalidFree (stack, untagged_ptr_old, tagged_ptr_old))
381388 return nullptr ;
382- void *tagged_ptr_new =
383- HwasanAllocate (stack, new_size, alignment, false /* zeroise*/ );
389+ void *tagged_ptr_new = HwasanAllocate (stack, new_size, alignment, FROM_MALLOC,
390+ false /* zeroise*/ );
384391 if (tagged_ptr_old && tagged_ptr_new) {
385392 Metadata *meta =
386393 reinterpret_cast <Metadata *>(allocator.GetMetaData (untagged_ptr_old));
387394 void *untagged_ptr_new = UntagPtr (tagged_ptr_new);
388395 internal_memcpy (untagged_ptr_new, untagged_ptr_old,
389396 Min (new_size, static_cast <uptr>(meta->GetRequestedSize ())));
390- HwasanDeallocate (stack, tagged_ptr_old);
397+ HwasanDeallocate (stack, tagged_ptr_old, FROM_MALLOC );
391398 }
392399 return tagged_ptr_new;
393400}
@@ -398,7 +405,7 @@ static void *HwasanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
398405 return nullptr ;
399406 ReportCallocOverflow (nmemb, size, stack);
400407 }
401- return HwasanAllocate (stack, nmemb * size, sizeof (u64 ), true );
408+ return HwasanAllocate (stack, nmemb * size, sizeof (u64 ), FROM_MALLOC, true );
402409}
403410
404411HwasanChunkView FindHeapChunkByAddress (uptr address) {
@@ -449,7 +456,8 @@ static uptr AllocationSizeFast(const void *p) {
449456}
450457
451458void *hwasan_malloc (uptr size, StackTrace *stack) {
452- return SetErrnoOnNull (HwasanAllocate (stack, size, sizeof (u64 ), false ));
459+ return SetErrnoOnNull (
460+ HwasanAllocate (stack, size, sizeof (u64 ), FROM_MALLOC, false ));
453461}
454462
455463void *hwasan_calloc (uptr nmemb, uptr size, StackTrace *stack) {
@@ -458,9 +466,10 @@ void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
458466
459467void *hwasan_realloc (void *ptr, uptr size, StackTrace *stack) {
460468 if (!ptr)
461- return SetErrnoOnNull (HwasanAllocate (stack, size, sizeof (u64 ), false ));
469+ return SetErrnoOnNull (
470+ HwasanAllocate (stack, size, sizeof (u64 ), FROM_MALLOC, false ));
462471 if (size == 0 ) {
463- HwasanDeallocate (stack, ptr);
472+ HwasanDeallocate (stack, ptr, FROM_MALLOC );
464473 return nullptr ;
465474 }
466475 return SetErrnoOnNull (HwasanReallocate (stack, ptr, size, sizeof (u64 )));
@@ -478,7 +487,7 @@ void *hwasan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) {
478487
479488void *hwasan_valloc (uptr size, StackTrace *stack) {
480489 return SetErrnoOnNull (
481- HwasanAllocate (stack, size, GetPageSizeCached (), false ));
490+ HwasanAllocate (stack, size, GetPageSizeCached (), FROM_MALLOC, false ));
482491}
483492
484493void *hwasan_pvalloc (uptr size, StackTrace *stack) {
@@ -491,7 +500,8 @@ void *hwasan_pvalloc(uptr size, StackTrace *stack) {
491500 }
492501 // pvalloc(0) should allocate one page.
493502 size = size ? RoundUpTo (size, PageSize) : PageSize;
494- return SetErrnoOnNull (HwasanAllocate (stack, size, PageSize, false ));
503+ return SetErrnoOnNull (
504+ HwasanAllocate (stack, size, PageSize, FROM_MALLOC, false ));
495505}
496506
497507void *hwasan_aligned_alloc (uptr alignment, uptr size, StackTrace *stack) {
@@ -501,7 +511,8 @@ void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
501511 return nullptr ;
502512 ReportInvalidAlignedAllocAlignment (size, alignment, stack);
503513 }
504- return SetErrnoOnNull (HwasanAllocate (stack, size, alignment, false ));
514+ return SetErrnoOnNull (
515+ HwasanAllocate (stack, size, alignment, FROM_MALLOC, false ));
505516}
506517
507518void *hwasan_memalign (uptr alignment, uptr size, StackTrace *stack) {
@@ -511,7 +522,8 @@ void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack) {
511522 return nullptr ;
512523 ReportInvalidAllocationAlignment (alignment, stack);
513524 }
514- return SetErrnoOnNull (HwasanAllocate (stack, size, alignment, false ));
525+ return SetErrnoOnNull (
526+ HwasanAllocate (stack, size, alignment, FROM_MALLOC, false ));
515527}
516528
517529int hwasan_posix_memalign (void **memptr, uptr alignment, uptr size,
@@ -521,7 +533,7 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
521533 return errno_EINVAL;
522534 ReportInvalidPosixMemalignAlignment (alignment, stack);
523535 }
524- void *ptr = HwasanAllocate (stack, size, alignment, false );
536+ void *ptr = HwasanAllocate (stack, size, alignment, FROM_MALLOC, false );
525537 if (UNLIKELY (!ptr))
526538 // OOM error is already taken care of by HwasanAllocate.
527539 return errno_ENOMEM;
@@ -531,7 +543,95 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
531543}
532544
533545void hwasan_free (void *ptr, StackTrace *stack) {
534- return HwasanDeallocate (stack, ptr);
546+ HwasanDeallocate (stack, ptr, FROM_MALLOC);
547+ }
548+
549+ namespace {
550+
551+ void *hwasan_new (uptr size, StackTrace *stack, bool array) {
552+ return SetErrnoOnNull (HwasanAllocate (stack, size, sizeof (u64 ),
553+ array ? FROM_NEW_BR : FROM_NEW, true ));
554+ }
555+
556+ void *hwasan_new_aligned (uptr size, uptr alignment, StackTrace *stack,
557+ bool array) {
558+ if (UNLIKELY (alignment == 0 || !IsPowerOfTwo (alignment))) {
559+ errno = errno_EINVAL;
560+ if (AllocatorMayReturnNull ())
561+ return nullptr ;
562+ ReportInvalidAllocationAlignment (alignment, stack);
563+ }
564+ return SetErrnoOnNull (HwasanAllocate (stack, size, alignment,
565+ array ? FROM_NEW_BR : FROM_NEW, false ));
566+ }
567+
568+ void hwasan_delete (void *ptr, StackTrace *stack, bool array) {
569+ HwasanDeallocate (stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
570+ }
571+
572+ void hwasan_delete_aligned (void *ptr, uptr, StackTrace *stack, bool array) {
573+ HwasanDeallocate (stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
574+ }
575+
576+ void hwasan_delete_sized (void *ptr, uptr, StackTrace *stack, bool array) {
577+ HwasanDeallocate (stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
578+ }
579+
580+ void hwasan_delete_sized_aligned (void *ptr, uptr, uptr, StackTrace *stack,
581+ bool array) {
582+ HwasanDeallocate (stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
583+ }
584+
585+ } // namespace
586+
587+ void *hwasan_new (uptr size, StackTrace *stack) {
588+ return hwasan_new (size, stack, /* array=*/ false );
589+ }
590+
591+ void *hwasan_new_aligned (uptr size, uptr alignment, StackTrace *stack) {
592+ return hwasan_new_aligned (size, alignment, stack, /* array=*/ false );
593+ }
594+
595+ void *hwasan_new_array (uptr size, StackTrace *stack) {
596+ return hwasan_new (size, stack, /* array=*/ true );
597+ }
598+
599+ void *hwasan_new_array_aligned (uptr size, uptr alignment, StackTrace *stack) {
600+ return hwasan_new_aligned (size, alignment, stack, /* array=*/ true );
601+ }
602+
603+ void hwasan_delete (void *ptr, StackTrace *stack) {
604+ hwasan_delete (ptr, stack, /* array=*/ false );
605+ }
606+
607+ void hwasan_delete_aligned (void *ptr, uptr alignment, StackTrace *stack) {
608+ hwasan_delete_aligned (ptr, alignment, stack, /* array=*/ false );
609+ }
610+
611+ void hwasan_delete_sized (void *ptr, uptr size, StackTrace *stack) {
612+ hwasan_delete_sized (ptr, size, stack, /* array=*/ false );
613+ }
614+
615+ void hwasan_delete_sized_aligned (void *ptr, uptr size, uptr alignment,
616+ StackTrace *stack) {
617+ hwasan_delete_sized_aligned (ptr, size, alignment, stack, /* array=*/ false );
618+ }
619+
620+ void hwasan_delete_array (void *ptr, StackTrace *stack) {
621+ hwasan_delete (ptr, stack, /* array=*/ true );
622+ }
623+
624+ void hwasan_delete_array_aligned (void *ptr, uptr alignment, StackTrace *stack) {
625+ hwasan_delete_aligned (ptr, alignment, stack, /* array=*/ true );
626+ }
627+
628+ void hwasan_delete_array_sized (void *ptr, uptr size, StackTrace *stack) {
629+ hwasan_delete_sized (ptr, size, stack, /* array=*/ true );
630+ }
631+
632+ void hwasan_delete_array_sized_aligned (void *ptr, uptr size, uptr alignment,
633+ StackTrace *stack) {
634+ hwasan_delete_sized_aligned (ptr, size, alignment, stack, /* array=*/ true );
535635}
536636
537637} // namespace __hwasan
0 commit comments