//===-- hwasan_allocator.cpp ------------------------ ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of HWAddressSanitizer.
//
// HWAddressSanitizer allocator.
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_errno.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "hwasan.h"
#include "hwasan_allocator.h"
#include "hwasan_checks.h"
#include "hwasan_mapping.h"
#include "hwasan_malloc_bisect.h"
#include "hwasan_thread.h"
#include "hwasan_report.h"
#include "lsan/lsan_common.h"

namespace __hwasan {

static Allocator allocator;
static AllocatorCache fallback_allocator_cache;
static SpinMutex fallback_mutex;
static atomic_uint8_t hwasan_allocator_tagging_enabled;

static constexpr tag_t kFallbackAllocTag = 0xBB & kTagMask;
static constexpr tag_t kFallbackFreeTag = 0xBC;

enum {
  // Either just allocated by underlying allocator, but AsanChunk is not yet
  // ready, or almost returned to undelying allocator and AsanChunk is already
  // meaningless.
  CHUNK_INVALID = 0,
  // The chunk is allocated and not yet freed.
  CHUNK_ALLOCATED = 1,
};


// Initialized in HwasanAllocatorInit, an never changed.
static ALIGNED(16) u8 tail_magic[kShadowAlignment - 1];
static uptr max_malloc_size;

bool HwasanChunkView::IsAllocated() const {
  return metadata_ && metadata_->IsAllocated();
}

uptr HwasanChunkView::Beg() const {
  return block_;
}
uptr HwasanChunkView::End() const {
  return Beg() + UsedSize();
}
uptr HwasanChunkView::UsedSize() const {
  return metadata_->GetRequestedSize();
}
u32 HwasanChunkView::GetAllocStackId() const {
  return metadata_->GetAllocStackId();
}

u32 HwasanChunkView::GetAllocThreadId() const {
  return metadata_->GetAllocThreadId();
}

uptr HwasanChunkView::ActualSize() const {
  return allocator.GetActuallyAllocatedSize(reinterpret_cast<void *>(block_));
}

bool HwasanChunkView::FromSmallHeap() const {
  return allocator.FromPrimary(reinterpret_cast<void *>(block_));
}

bool HwasanChunkView::AddrIsInside(uptr addr) const {
  return (addr >= Beg()) && (addr < Beg() + UsedSize());
}

inline void Metadata::SetAllocated(u32 stack, u64 size) {
  Thread *t = GetCurrentThread();
  u64 context = t ? t->unique_id() : kMainTid;
  context <<= 32;
  context += stack;
  requested_size_low = size & ((1ul << 32) - 1);
  requested_size_high = size >> 32;
  atomic_store(&alloc_context_id, context, memory_order_relaxed);
  atomic_store(&chunk_state, CHUNK_ALLOCATED, memory_order_release);
}

inline void Metadata::SetUnallocated() {
  atomic_store(&chunk_state, CHUNK_INVALID, memory_order_release);
  requested_size_low = 0;
  requested_size_high = 0;
  atomic_store(&alloc_context_id, 0, memory_order_relaxed);
}

inline bool Metadata::IsAllocated() const {
  return atomic_load(&chunk_state, memory_order_relaxed) == CHUNK_ALLOCATED;
}

inline u64 Metadata::GetRequestedSize() const {
  return (static_cast<u64>(requested_size_high) << 32) + requested_size_low;
}

inline u32 Metadata::GetAllocStackId() const {
  return atomic_load(&alloc_context_id, memory_order_relaxed);
}

inline u32 Metadata::GetAllocThreadId() const {
  u64 context = atomic_load(&alloc_context_id, memory_order_relaxed);
  u32 tid = context >> 32;
  return tid;
}

void GetAllocatorStats(AllocatorStatCounters s) {
  allocator.GetStats(s);
}

inline void Metadata::SetLsanTag(__lsan::ChunkTag tag) {
  lsan_tag = tag;
}

inline __lsan::ChunkTag Metadata::GetLsanTag() const {
  return static_cast<__lsan::ChunkTag>(lsan_tag);
}

uptr GetAliasRegionStart() {
#if defined(HWASAN_ALIASING_MODE)
  constexpr uptr kAliasRegionOffset = 1ULL << (kTaggableRegionCheckShift - 1);
  uptr AliasRegionStart =
      __hwasan_shadow_memory_dynamic_address + kAliasRegionOffset;

  CHECK_EQ(AliasRegionStart >> kTaggableRegionCheckShift,
           __hwasan_shadow_memory_dynamic_address >> kTaggableRegionCheckShift);
  CHECK_EQ(
      (AliasRegionStart + kAliasRegionOffset - 1) >> kTaggableRegionCheckShift,
      __hwasan_shadow_memory_dynamic_address >> kTaggableRegionCheckShift);
  return AliasRegionStart;
#else
  return 0;
#endif
}

void HwasanAllocatorInit() {
  atomic_store_relaxed(&hwasan_allocator_tagging_enabled,
                       !flags()->disable_allocator_tagging);
  SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null);
  allocator.InitLinkerInitialized(
      common_flags()->allocator_release_to_os_interval_ms,
      GetAliasRegionStart());
  for (uptr i = 0; i < sizeof(tail_magic); i++)
    tail_magic[i] = GetCurrentThread()->GenerateRandomTag();
  if (common_flags()->max_allocation_size_mb) {
    max_malloc_size = common_flags()->max_allocation_size_mb << 20;
    max_malloc_size = Min(max_malloc_size, kMaxAllowedMallocSize);
  } else {
    max_malloc_size = kMaxAllowedMallocSize;
  }
}

void HwasanAllocatorLock() { allocator.ForceLock(); }

void HwasanAllocatorUnlock() { allocator.ForceUnlock(); }

void AllocatorThreadStart(AllocatorCache *cache) { allocator.InitCache(cache); }

void AllocatorThreadFinish(AllocatorCache *cache) {
  allocator.SwallowCache(cache);
  allocator.DestroyCache(cache);
}

static uptr TaggedSize(uptr size) {
  if (!size) size = 1;
  uptr new_size = RoundUpTo(size, kShadowAlignment);
  CHECK_GE(new_size, size);
  return new_size;
}

static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
                            bool zeroise) {
  // Keep this consistent with LSAN and ASAN behavior.
  if (UNLIKELY(orig_size == 0))
    orig_size = 1;
  if (UNLIKELY(orig_size > max_malloc_size)) {
    if (AllocatorMayReturnNull()) {
      Report("WARNING: HWAddressSanitizer failed to allocate 0x%zx bytes\n",
             orig_size);
      return nullptr;
    }
    ReportAllocationSizeTooBig(orig_size, max_malloc_size, stack);
  }
  if (UNLIKELY(IsRssLimitExceeded())) {
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportRssLimitExceeded(stack);
  }

  alignment = Max(alignment, kShadowAlignment);
  uptr size = TaggedSize(orig_size);
  Thread *t = GetCurrentThread();
  void *allocated;
  if (t) {
    allocated = allocator.Allocate(t->allocator_cache(), size, alignment);
  } else {
    SpinMutexLock l(&fallback_mutex);
    AllocatorCache *cache = &fallback_allocator_cache;
    allocated = allocator.Allocate(cache, size, alignment);
  }
  if (UNLIKELY(!allocated)) {
    SetAllocatorOutOfMemory();
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportOutOfMemory(size, stack);
  }
  if (zeroise) {
    // The secondary allocator mmaps memory, which should be zero-inited so we
    // don't need to explicitly clear it.
    if (allocator.FromPrimary(allocated))
      internal_memset(allocated, 0, size);
  } else if (flags()->max_malloc_fill_size > 0) {
    uptr fill_size = Min(size, (uptr)flags()->max_malloc_fill_size);
    internal_memset(allocated, flags()->malloc_fill_byte, fill_size);
  }
  if (size != orig_size) {
    u8 *tail = reinterpret_cast<u8 *>(allocated) + orig_size;
    uptr tail_length = size - orig_size;
    internal_memcpy(tail, tail_magic, tail_length - 1);
    // Short granule is excluded from magic tail, so we explicitly untag.
    tail[tail_length - 1] = 0;
  }

  void *user_ptr = allocated;
  if (InTaggableRegion(reinterpret_cast<uptr>(user_ptr)) &&
      atomic_load_relaxed(&hwasan_allocator_tagging_enabled) &&
      flags()->tag_in_malloc && malloc_bisect(stack, orig_size)) {
    tag_t tag = t ? t->GenerateRandomTag() : kFallbackAllocTag;
    uptr tag_size = orig_size ? orig_size : 1;
    uptr full_granule_size = RoundDownTo(tag_size, kShadowAlignment);
    user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, full_granule_size, tag);
    if (full_granule_size != tag_size) {
      u8 *short_granule = reinterpret_cast<u8 *>(allocated) + full_granule_size;
      TagMemoryAligned((uptr)short_granule, kShadowAlignment,
                       tag_size % kShadowAlignment);
      short_granule[kShadowAlignment - 1] = tag;
    }
  } else {
    // Tagging can not be completely skipped. If it's disabled, we need to tag
    // with zeros.
    user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, size, 0);
  }

  Metadata *meta =
      reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
#if CAN_SANITIZE_LEAKS
  meta->SetLsanTag(__lsan::DisabledInThisThread() ? __lsan::kIgnored
                                                  : __lsan::kDirectlyLeaked);
#endif
  meta->SetAllocated(StackDepotPut(*stack), orig_size);
  RunMallocHooks(user_ptr, orig_size);
  return user_ptr;
}

static bool PointerAndMemoryTagsMatch(void *tagged_ptr) {
  CHECK(tagged_ptr);
  uptr tagged_uptr = reinterpret_cast<uptr>(tagged_ptr);
  if (!InTaggableRegion(tagged_uptr))
    return true;
  tag_t mem_tag = *reinterpret_cast<tag_t *>(
      MemToShadow(reinterpret_cast<uptr>(UntagPtr(tagged_ptr))));
  return PossiblyShortTagMatches(mem_tag, tagged_uptr, 1);
}

static bool CheckInvalidFree(StackTrace *stack, void *untagged_ptr,
                             void *tagged_ptr) {
  // This function can return true if halt_on_error is false.
  if (!MemIsApp(reinterpret_cast<uptr>(untagged_ptr)) ||
      !PointerAndMemoryTagsMatch(tagged_ptr)) {
    ReportInvalidFree(stack, reinterpret_cast<uptr>(tagged_ptr));
    return true;
  }
  return false;
}

static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
  CHECK(tagged_ptr);
  void *untagged_ptr = UntagPtr(tagged_ptr);

  if (CheckInvalidFree(stack, untagged_ptr, tagged_ptr))
    return;

  void *aligned_ptr = reinterpret_cast<void *>(
      RoundDownTo(reinterpret_cast<uptr>(untagged_ptr), kShadowAlignment));
  tag_t pointer_tag = GetTagFromPointer(reinterpret_cast<uptr>(tagged_ptr));
  Metadata *meta =
      reinterpret_cast<Metadata *>(allocator.GetMetaData(aligned_ptr));
  if (!meta) {
    ReportInvalidFree(stack, reinterpret_cast<uptr>(tagged_ptr));
    return;
  }

  RunFreeHooks(tagged_ptr);

  uptr orig_size = meta->GetRequestedSize();
  u32 free_context_id = StackDepotPut(*stack);
  u32 alloc_context_id = meta->GetAllocStackId();
  u32 alloc_thread_id = meta->GetAllocThreadId();

  bool in_taggable_region =
      InTaggableRegion(reinterpret_cast<uptr>(tagged_ptr));

  // Check tail magic.
  uptr tagged_size = TaggedSize(orig_size);
  if (flags()->free_checks_tail_magic && orig_size &&
      tagged_size != orig_size) {
    uptr tail_size = tagged_size - orig_size - 1;
    CHECK_LT(tail_size, kShadowAlignment);
    void *tail_beg = reinterpret_cast<void *>(
        reinterpret_cast<uptr>(aligned_ptr) + orig_size);
    tag_t short_granule_memtag = *(reinterpret_cast<tag_t *>(
        reinterpret_cast<uptr>(tail_beg) + tail_size));
    if (tail_size &&
        (internal_memcmp(tail_beg, tail_magic, tail_size) ||
         (in_taggable_region && pointer_tag != short_granule_memtag)))
      ReportTailOverwritten(stack, reinterpret_cast<uptr>(tagged_ptr),
                            orig_size, tail_magic);
  }

  // TODO(kstoimenov): consider meta->SetUnallocated(free_context_id).
  meta->SetUnallocated();
  // This memory will not be reused by anyone else, so we are free to keep it
  // poisoned.
  Thread *t = GetCurrentThread();
  if (flags()->max_free_fill_size > 0) {
    uptr fill_size =
        Min(TaggedSize(orig_size), (uptr)flags()->max_free_fill_size);
    internal_memset(aligned_ptr, flags()->free_fill_byte, fill_size);
  }
  if (in_taggable_region && flags()->tag_in_free && malloc_bisect(stack, 0) &&
      atomic_load_relaxed(&hwasan_allocator_tagging_enabled) &&
      allocator.FromPrimary(untagged_ptr) /* Secondary 0-tag and unmap.*/) {
    // Always store full 8-bit tags on free to maximize UAF detection.
    tag_t tag;
    if (t) {
      // Make sure we are not using a short granule tag as a poison tag. This
      // would make us attempt to read the memory on a UaF.
      // The tag can be zero if tagging is disabled on this thread.
      do {
        tag = t->GenerateRandomTag(/*num_bits=*/8);
      } while (
          UNLIKELY((tag < kShadowAlignment || tag == pointer_tag) && tag != 0));
    } else {
      static_assert(kFallbackFreeTag >= kShadowAlignment,
                    "fallback tag must not be a short granule tag.");
      tag = kFallbackFreeTag;
    }
    TagMemoryAligned(reinterpret_cast<uptr>(aligned_ptr), TaggedSize(orig_size),
                     tag);
  }
  if (t) {
    allocator.Deallocate(t->allocator_cache(), aligned_ptr);
    if (auto *ha = t->heap_allocations())
      ha->push({reinterpret_cast<uptr>(tagged_ptr), alloc_thread_id,
                alloc_context_id, free_context_id,
                static_cast<u32>(orig_size)});
  } else {
    SpinMutexLock l(&fallback_mutex);
    AllocatorCache *cache = &fallback_allocator_cache;
    allocator.Deallocate(cache, aligned_ptr);
  }
}

static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old,
                              uptr new_size, uptr alignment) {
  void *untagged_ptr_old = UntagPtr(tagged_ptr_old);
  if (CheckInvalidFree(stack, untagged_ptr_old, tagged_ptr_old))
    return nullptr;
  void *tagged_ptr_new =
      HwasanAllocate(stack, new_size, alignment, false /*zeroise*/);
  if (tagged_ptr_old && tagged_ptr_new) {
    Metadata *meta =
        reinterpret_cast<Metadata *>(allocator.GetMetaData(untagged_ptr_old));
    void *untagged_ptr_new = UntagPtr(tagged_ptr_new);
    internal_memcpy(untagged_ptr_new, untagged_ptr_old,
                    Min(new_size, static_cast<uptr>(meta->GetRequestedSize())));
    HwasanDeallocate(stack, tagged_ptr_old);
  }
  return tagged_ptr_new;
}

static void *HwasanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
  if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportCallocOverflow(nmemb, size, stack);
  }
  return HwasanAllocate(stack, nmemb * size, sizeof(u64), true);
}

HwasanChunkView FindHeapChunkByAddress(uptr address) {
  if (!allocator.PointerIsMine(reinterpret_cast<void *>(address)))
    return HwasanChunkView();
  void *block = allocator.GetBlockBegin(reinterpret_cast<void*>(address));
  if (!block)
    return HwasanChunkView();
  Metadata *metadata =
      reinterpret_cast<Metadata*>(allocator.GetMetaData(block));
  return HwasanChunkView(reinterpret_cast<uptr>(block), metadata);
}

static const void *AllocationBegin(const void *p) {
  const void *untagged_ptr = UntagPtr(p);
  if (!untagged_ptr)
    return nullptr;

  const void *beg = allocator.GetBlockBegin(untagged_ptr);
  if (!beg)
    return nullptr;

  Metadata *b = (Metadata *)allocator.GetMetaData(beg);
  if (b->GetRequestedSize() == 0)
    return nullptr;

  tag_t tag = GetTagFromPointer((uptr)p);
  return (const void *)AddTagToPointer((uptr)beg, tag);
}

static uptr AllocationSize(const void *p) {
  const void *untagged_ptr = UntagPtr(p);
  if (!untagged_ptr) return 0;
  const void *beg = allocator.GetBlockBegin(untagged_ptr);
  if (!beg)
    return 0;
  Metadata *b = (Metadata *)allocator.GetMetaData(beg);
  return b->GetRequestedSize();
}

static uptr AllocationSizeFast(const void *p) {
  const void *untagged_ptr = UntagPtr(p);
  void *aligned_ptr = reinterpret_cast<void *>(
      RoundDownTo(reinterpret_cast<uptr>(untagged_ptr), kShadowAlignment));
  Metadata *meta =
      reinterpret_cast<Metadata *>(allocator.GetMetaData(aligned_ptr));
  return meta->GetRequestedSize();
}

void *hwasan_malloc(uptr size, StackTrace *stack) {
  return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64), false));
}

void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
  return SetErrnoOnNull(HwasanCalloc(stack, nmemb, size));
}

void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack) {
  if (!ptr)
    return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64), false));
  if (size == 0) {
    HwasanDeallocate(stack, ptr);
    return nullptr;
  }
  return SetErrnoOnNull(HwasanReallocate(stack, ptr, size, sizeof(u64)));
}

void *hwasan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) {
  if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
    errno = errno_ENOMEM;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportReallocArrayOverflow(nmemb, size, stack);
  }
  return hwasan_realloc(ptr, nmemb * size, stack);
}

void *hwasan_valloc(uptr size, StackTrace *stack) {
  return SetErrnoOnNull(
      HwasanAllocate(stack, size, GetPageSizeCached(), false));
}

void *hwasan_pvalloc(uptr size, StackTrace *stack) {
  uptr PageSize = GetPageSizeCached();
  if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) {
    errno = errno_ENOMEM;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportPvallocOverflow(size, stack);
  }
  // pvalloc(0) should allocate one page.
  size = size ? RoundUpTo(size, PageSize) : PageSize;
  return SetErrnoOnNull(HwasanAllocate(stack, size, PageSize, false));
}

void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
  if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) {
    errno = errno_EINVAL;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportInvalidAlignedAllocAlignment(size, alignment, stack);
  }
  return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false));
}

void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack) {
  if (UNLIKELY(!IsPowerOfTwo(alignment))) {
    errno = errno_EINVAL;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportInvalidAllocationAlignment(alignment, stack);
  }
  return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false));
}

int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
                        StackTrace *stack) {
  if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
    if (AllocatorMayReturnNull())
      return errno_EINVAL;
    ReportInvalidPosixMemalignAlignment(alignment, stack);
  }
  void *ptr = HwasanAllocate(stack, size, alignment, false);
  if (UNLIKELY(!ptr))
    // OOM error is already taken care of by HwasanAllocate.
    return errno_ENOMEM;
  CHECK(IsAligned((uptr)ptr, alignment));
  *memptr = ptr;
  return 0;
}

void hwasan_free(void *ptr, StackTrace *stack) {
  return HwasanDeallocate(stack, ptr);
}

}  // namespace __hwasan

// --- Implementation of LSan-specific functions --- {{{1
namespace __lsan {

void LockAllocator() {
  __hwasan::HwasanAllocatorLock();
}

void UnlockAllocator() {
  __hwasan::HwasanAllocatorUnlock();
}

void GetAllocatorGlobalRange(uptr *begin, uptr *end) {
  *begin = (uptr)&__hwasan::allocator;
  *end = *begin + sizeof(__hwasan::allocator);
}

uptr PointsIntoChunk(void *p) {
  p = UntagPtr(p);
  uptr addr = reinterpret_cast<uptr>(p);
  uptr chunk =
      reinterpret_cast<uptr>(__hwasan::allocator.GetBlockBeginFastLocked(p));
  if (!chunk)
    return 0;
  __hwasan::Metadata *metadata = reinterpret_cast<__hwasan::Metadata *>(
      __hwasan::allocator.GetMetaData(reinterpret_cast<void *>(chunk)));
  if (!metadata || !metadata->IsAllocated())
    return 0;
  if (addr < chunk + metadata->GetRequestedSize())
    return chunk;
  if (IsSpecialCaseOfOperatorNew0(chunk, metadata->GetRequestedSize(), addr))
    return chunk;
  return 0;
}

uptr GetUserBegin(uptr chunk) {
  CHECK_EQ(UntagAddr(chunk), chunk);
  void *block = __hwasan::allocator.GetBlockBeginFastLocked(
      reinterpret_cast<void *>(chunk));
  if (!block)
    return 0;
  __hwasan::Metadata *metadata = reinterpret_cast<__hwasan::Metadata *>(
      __hwasan::allocator.GetMetaData(block));
  if (!metadata || !metadata->IsAllocated())
    return 0;

  return reinterpret_cast<uptr>(block);
}

uptr GetUserAddr(uptr chunk) {
  if (!InTaggableRegion(chunk))
    return chunk;
  tag_t mem_tag = *(tag_t *)__hwasan::MemToShadow(chunk);
  return AddTagToPointer(chunk, mem_tag);
}

LsanMetadata::LsanMetadata(uptr chunk) {
  CHECK_EQ(UntagAddr(chunk), chunk);
  metadata_ =
      chunk ? __hwasan::allocator.GetMetaData(reinterpret_cast<void *>(chunk))
            : nullptr;
}

bool LsanMetadata::allocated() const {
  if (!metadata_)
    return false;
  __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
  return m->IsAllocated();
}

ChunkTag LsanMetadata::tag() const {
  __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
  return m->GetLsanTag();
}

void LsanMetadata::set_tag(ChunkTag value) {
  __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
  m->SetLsanTag(value);
}

uptr LsanMetadata::requested_size() const {
  __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
  return m->GetRequestedSize();
}

u32 LsanMetadata::stack_trace_id() const {
  __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
  return m->GetAllocStackId();
}

void ForEachChunk(ForEachChunkCallback callback, void *arg) {
  __hwasan::allocator.ForEachChunk(callback, arg);
}

IgnoreObjectResult IgnoreObject(const void *p) {
  p = UntagPtr(p);
  uptr addr = reinterpret_cast<uptr>(p);
  uptr chunk = reinterpret_cast<uptr>(__hwasan::allocator.GetBlockBegin(p));
  if (!chunk)
    return kIgnoreObjectInvalid;
  __hwasan::Metadata *metadata = reinterpret_cast<__hwasan::Metadata *>(
      __hwasan::allocator.GetMetaData(reinterpret_cast<void *>(chunk)));
  if (!metadata || !metadata->IsAllocated())
    return kIgnoreObjectInvalid;
  if (addr >= chunk + metadata->GetRequestedSize())
    return kIgnoreObjectInvalid;
  if (metadata->GetLsanTag() == kIgnored)
    return kIgnoreObjectAlreadyIgnored;

  metadata->SetLsanTag(kIgnored);
  return kIgnoreObjectSuccess;
}

}  // namespace __lsan

using namespace __hwasan;

void __hwasan_enable_allocator_tagging() {
  atomic_store_relaxed(&hwasan_allocator_tagging_enabled, 1);
}

void __hwasan_disable_allocator_tagging() {
  atomic_store_relaxed(&hwasan_allocator_tagging_enabled, 0);
}

uptr __sanitizer_get_current_allocated_bytes() {
  uptr stats[AllocatorStatCount];
  allocator.GetStats(stats);
  return stats[AllocatorStatAllocated];
}

uptr __sanitizer_get_heap_size() {
  uptr stats[AllocatorStatCount];
  allocator.GetStats(stats);
  return stats[AllocatorStatMapped];
}

uptr __sanitizer_get_free_bytes() { return 1; }

uptr __sanitizer_get_unmapped_bytes() { return 1; }

uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }

int __sanitizer_get_ownership(const void *p) { return AllocationSize(p) != 0; }

const void *__sanitizer_get_allocated_begin(const void *p) {
  return AllocationBegin(p);
}

uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); }

uptr __sanitizer_get_allocated_size_fast(const void *p) {
  DCHECK_EQ(p, __sanitizer_get_allocated_begin(p));
  uptr ret = AllocationSizeFast(p);
  DCHECK_EQ(ret, __sanitizer_get_allocated_size(p));
  return ret;
}

void __sanitizer_purge_allocator() { allocator.ForceReleaseToOS(); }
