//===-- asan_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 AddressSanitizer, an address sanity checker.
//
// Implementation of ASan's memory allocator, 2-nd version.
// This variant uses the allocator from sanitizer_common, i.e. the one shared
// with ThreadSanitizer and MemorySanitizer.
//
//===----------------------------------------------------------------------===//

#include "asan_allocator.h"

#include "asan_internal.h"
#include "asan_mapping.h"
#include "asan_poisoning.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_suppressions.h"
#include "asan_thread.h"
#include "lsan/lsan_common.h"
#include "sanitizer_common/sanitizer_allocator_checks.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_errno.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_list.h"
#include "sanitizer_common/sanitizer_quarantine.h"
#include "sanitizer_common/sanitizer_stackdepot.h"

namespace __asan {

// Valid redzone sizes are 16, 32, 64, ... 2048, so we encode them in 3 bits.
// We use adaptive redzones: for larger allocation larger redzones are used.
static u32 RZLog2Size(u32 rz_log) {
  CHECK_LT(rz_log, 8);
  return 16 << rz_log;
}

static u32 RZSize2Log(u32 rz_size) {
  CHECK_GE(rz_size, 16);
  CHECK_LE(rz_size, 2048);
  CHECK(IsPowerOfTwo(rz_size));
  u32 res = Log2(rz_size) - 4;
  CHECK_EQ(rz_size, RZLog2Size(res));
  return res;
}

static AsanAllocator& get_allocator();

static void AtomicContextStore(volatile atomic_uint64_t* atomic_context,
                               u32 tid, u32 stack) {
  u64 context = tid;
  context <<= 32;
  context += stack;
  atomic_store(atomic_context, context, memory_order_relaxed);
}

static void AtomicContextLoad(const volatile atomic_uint64_t* atomic_context,
                              u32& tid, u32& stack) {
  u64 context = atomic_load(atomic_context, memory_order_relaxed);
  stack = context;
  context >>= 32;
  tid = context;
}

// The memory chunk allocated from the underlying allocator looks like this:
// L L L L L L H H U U U U U U R R
//   L -- left redzone words (0 or more bytes)
//   H -- ChunkHeader (16 bytes), which is also a part of the left redzone.
//   U -- user memory.
//   R -- right redzone (0 or more bytes)
// ChunkBase consists of ChunkHeader and other bytes that overlap with user
// memory.

// If the left redzone is greater than the ChunkHeader size we store a magic
// value in the first uptr word of the memory block and store the address of
// ChunkBase in the next uptr.
// M B L L L L L L L L L  H H U U U U U U
//   |                    ^
//   ---------------------|
//   M -- magic value kAllocBegMagic
//   B -- address of ChunkHeader pointing to the first 'H'

class ChunkHeader {
 public:
  atomic_uint8_t chunk_state;
  u8 alloc_type : 2;
  u8 lsan_tag : 2;
#if SANITIZER_WINDOWS
  // True if this was a zero-size allocation upgraded to size 1.
  // Used to report the original size (0) to the user via HeapSize/RtlSizeHeap.
  u8 from_zero_alloc : 1;
#endif

  // align < 8 -> 0
  // else      -> log2(min(align, 512)) - 2
  u8 user_requested_alignment_log : 3;

 private:
  u16 user_requested_size_hi;
  u32 user_requested_size_lo;
  atomic_uint64_t alloc_context_id;

 public:
  uptr UsedSize() const {
    static_assert(sizeof(user_requested_size_lo) == 4,
                  "Expression below requires this");
    return FIRST_32_SECOND_64(0, ((uptr)user_requested_size_hi << 32)) +
           user_requested_size_lo;
  }

  void SetUsedSize(uptr size) {
    user_requested_size_lo = size;
    static_assert(sizeof(user_requested_size_lo) == 4,
                  "Expression below requires this");
    user_requested_size_hi = FIRST_32_SECOND_64(0, size >> 32);
    CHECK_EQ(UsedSize(), size);
  }

  void SetAllocContext(u32 tid, u32 stack) {
    AtomicContextStore(&alloc_context_id, tid, stack);
  }

  void GetAllocContext(u32& tid, u32& stack) const {
    AtomicContextLoad(&alloc_context_id, tid, stack);
  }
};

class ChunkBase : public ChunkHeader {
  atomic_uint64_t free_context_id;

 public:
  void SetFreeContext(u32 tid, u32 stack) {
    AtomicContextStore(&free_context_id, tid, stack);
  }

  void GetFreeContext(u32& tid, u32& stack) const {
    AtomicContextLoad(&free_context_id, tid, stack);
  }
};

static const uptr kChunkHeaderSize = sizeof(ChunkHeader);
static const uptr kChunkHeader2Size = sizeof(ChunkBase) - kChunkHeaderSize;
COMPILER_CHECK(kChunkHeaderSize == 16);
COMPILER_CHECK(kChunkHeader2Size <= 16);

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 = 2,
  // The chunk was freed and put into quarantine zone.
  CHUNK_QUARANTINE = 3,
};

class AsanChunk : public ChunkBase {
 public:
  uptr Beg() { return reinterpret_cast<uptr>(this) + kChunkHeaderSize; }
  bool AddrIsInside(uptr addr) {
    return (addr >= Beg()) && (addr < Beg() + UsedSize());
  }
};

class LargeChunkHeader {
  static constexpr uptr kAllocBegMagic =
      FIRST_32_SECOND_64(0xCC6E96B9, 0xCC6E96B9CC6E96B9ULL);
  atomic_uintptr_t magic;
  AsanChunk* chunk_header;

 public:
  AsanChunk* Get() const {
    return atomic_load(&magic, memory_order_acquire) == kAllocBegMagic
               ? chunk_header
               : nullptr;
  }

  void Set(AsanChunk* p) {
    if (p) {
      chunk_header = p;
      atomic_store(&magic, kAllocBegMagic, memory_order_release);
      return;
    }

    uptr old = kAllocBegMagic;
    if (!atomic_compare_exchange_strong(&magic, &old, 0,
                                        memory_order_release)) {
      CHECK_EQ(old, kAllocBegMagic);
    }
  }
};

static void FillChunk(AsanChunk* m) {
  // FIXME: Use ReleaseMemoryPagesToOS.
  Flags& fl = *flags();

  if (fl.max_free_fill_size > 0) {
    // We have to skip the chunk header, it contains free_context_id.
    uptr scribble_start = (uptr)m + kChunkHeaderSize + kChunkHeader2Size;
    if (m->UsedSize() >= kChunkHeader2Size) {  // Skip Header2 in user area.
      uptr size_to_fill = m->UsedSize() - kChunkHeader2Size;
      size_to_fill = Min(size_to_fill, (uptr)fl.max_free_fill_size);
      REAL(memset)((void*)scribble_start, fl.free_fill_byte, size_to_fill);
    }
  }
}

struct QuarantineCallback {
  QuarantineCallback(AllocatorCache* cache, BufferedStackTrace* stack)
      : cache_(cache), stack_(stack) {}

  void PreQuarantine(AsanChunk* m) const {
    FillChunk(m);
    // Poison the region.
    PoisonShadow(m->Beg(), RoundUpTo(m->UsedSize(), ASAN_SHADOW_GRANULARITY),
                 kAsanHeapFreeMagic);
  }

  void Recycle(AsanChunk* m) const {
    void* p = get_allocator().GetBlockBegin(m);

    // The secondary will immediately unpoison and unmap the memory, so this
    // branch is unnecessary.
    if (get_allocator().FromPrimary(p)) {
      if (p != m) {
        // Clear the magic value, as allocator internals may overwrite the
        // contents of deallocated chunk, confusing GetAsanChunk lookup.
        reinterpret_cast<LargeChunkHeader*>(p)->Set(nullptr);
      }

      u8 old_chunk_state = CHUNK_QUARANTINE;
      if (!atomic_compare_exchange_strong(&m->chunk_state, &old_chunk_state,
                                          CHUNK_INVALID,
                                          memory_order_acquire)) {
        CHECK_EQ(old_chunk_state, CHUNK_QUARANTINE);
      }

      PoisonShadow(m->Beg(), RoundUpTo(m->UsedSize(), ASAN_SHADOW_GRANULARITY),
                   kAsanHeapLeftRedzoneMagic);
    }

    // Statistics.
    AsanStats& thread_stats = GetCurrentThreadStats();
    thread_stats.real_frees++;
    thread_stats.really_freed += m->UsedSize();

    get_allocator().Deallocate(cache_, p);
  }

  void RecyclePassThrough(AsanChunk* m) const {
    // Recycle for the secondary will immediately unpoison and unmap the
    // memory, so quarantine preparation is unnecessary.
    if (get_allocator().FromPrimary(m)) {
      // The primary allocation may need pattern fill if enabled.
      FillChunk(m);
    }
    Recycle(m);
  }

  void* Allocate(uptr size) const {
    void* res = get_allocator().Allocate(cache_, size, 1);
    // TODO(alekseys): Consider making quarantine OOM-friendly.
    if (UNLIKELY(!res))
      ReportOutOfMemory(size, stack_);
    return res;
  }

  void Deallocate(void* p) const { get_allocator().Deallocate(cache_, p); }

 private:
  AllocatorCache* const cache_;
  BufferedStackTrace* const stack_;
};

typedef Quarantine<QuarantineCallback, AsanChunk> AsanQuarantine;
typedef AsanQuarantine::Cache QuarantineCache;

void AsanMapUnmapCallback::OnMap(uptr p, uptr size) const {
  PoisonShadow(p, size, kAsanHeapLeftRedzoneMagic);
  // Statistics.
  AsanStats& thread_stats = GetCurrentThreadStats();
  thread_stats.mmaps++;
  thread_stats.mmaped += size;
}

void AsanMapUnmapCallback::OnMapSecondary(uptr p, uptr size, uptr user_begin,
                                          uptr user_size) const {
  uptr user_end = RoundDownTo(user_begin + user_size, ASAN_SHADOW_GRANULARITY);
  user_begin = RoundUpTo(user_begin, ASAN_SHADOW_GRANULARITY);
  // The secondary mapping will be immediately returned to user, no value
  // poisoning that with non-zero just before unpoisoning by Allocate(). So just
  // poison head/tail invisible to Allocate().
  PoisonShadow(p, user_begin - p, kAsanHeapLeftRedzoneMagic);
  PoisonShadow(user_end, size - (user_end - p), kAsanHeapLeftRedzoneMagic);
  // Statistics.
  AsanStats& thread_stats = GetCurrentThreadStats();
  thread_stats.mmaps++;
  thread_stats.mmaped += size;
}

void AsanMapUnmapCallback::OnUnmap(uptr p, uptr size) const {
  PoisonShadow(p, size, 0);
  // We are about to unmap a chunk of user memory.
  // Mark the corresponding shadow memory as not needed.
  FlushUnneededASanShadowMemory(p, size);
  // Statistics.
  AsanStats& thread_stats = GetCurrentThreadStats();
  thread_stats.munmaps++;
  thread_stats.munmaped += size;
}

// We can not use THREADLOCAL because it is not supported on some of the
// platforms we care about (OSX 10.6, Android).
// static THREADLOCAL AllocatorCache cache;
AllocatorCache* GetAllocatorCache(AsanThreadLocalMallocStorage* ms) {
  CHECK(ms);
  return &ms->allocator_cache;
}

QuarantineCache* GetQuarantineCache(AsanThreadLocalMallocStorage* ms) {
  CHECK(ms);
  CHECK_LE(sizeof(QuarantineCache), sizeof(ms->quarantine_cache));
  return reinterpret_cast<QuarantineCache*>(ms->quarantine_cache);
}

void AllocatorOptions::SetFrom(const Flags* f, const CommonFlags* cf) {
  quarantine_size_mb = f->quarantine_size_mb;
  thread_local_quarantine_size_kb = f->thread_local_quarantine_size_kb;
  min_redzone = f->redzone;
  max_redzone = f->max_redzone;
  may_return_null = cf->allocator_may_return_null;
  alloc_dealloc_mismatch = f->alloc_dealloc_mismatch;
  release_to_os_interval_ms = cf->allocator_release_to_os_interval_ms;
}

void AllocatorOptions::CopyTo(Flags* f, CommonFlags* cf) {
  f->quarantine_size_mb = quarantine_size_mb;
  f->thread_local_quarantine_size_kb = thread_local_quarantine_size_kb;
  f->redzone = min_redzone;
  f->max_redzone = max_redzone;
  cf->allocator_may_return_null = may_return_null;
  f->alloc_dealloc_mismatch = alloc_dealloc_mismatch;
  cf->allocator_release_to_os_interval_ms = release_to_os_interval_ms;
}

struct Allocator {
  static const uptr kMaxAllowedMallocSize =
      FIRST_32_SECOND_64(3UL << 30, 1ULL << 40);

  AsanAllocator allocator;
  AsanQuarantine quarantine;
  StaticSpinMutex fallback_mutex;
  AllocatorCache fallback_allocator_cache;
  QuarantineCache fallback_quarantine_cache;

  uptr max_user_defined_malloc_size;

  // ------------------- Options --------------------------
  atomic_uint16_t min_redzone;
  atomic_uint16_t max_redzone;
  atomic_uint8_t alloc_dealloc_mismatch;

  // ------------------- Initialization ------------------------
  explicit Allocator(LinkerInitialized)
      : quarantine(LINKER_INITIALIZED),
        fallback_quarantine_cache(LINKER_INITIALIZED) {}

  void CheckOptions(const AllocatorOptions& options) const {
    CHECK_GE(options.min_redzone, 16);
    CHECK_GE(options.max_redzone, options.min_redzone);
    CHECK_LE(options.max_redzone, 2048);
    CHECK(IsPowerOfTwo(options.min_redzone));
    CHECK(IsPowerOfTwo(options.max_redzone));
  }

  void SharedInitCode(const AllocatorOptions& options) {
    CheckOptions(options);
    quarantine.Init((uptr)options.quarantine_size_mb << 20,
                    (uptr)options.thread_local_quarantine_size_kb << 10);
    atomic_store(&alloc_dealloc_mismatch, options.alloc_dealloc_mismatch,
                 memory_order_release);
    atomic_store(&min_redzone, options.min_redzone, memory_order_release);
    atomic_store(&max_redzone, options.max_redzone, memory_order_release);
  }

  void InitLinkerInitialized(const AllocatorOptions& options) {
    SetAllocatorMayReturnNull(options.may_return_null);
    allocator.InitLinkerInitialized(options.release_to_os_interval_ms);
    SharedInitCode(options);
    max_user_defined_malloc_size = common_flags()->max_allocation_size_mb
                                       ? common_flags()->max_allocation_size_mb
                                             << 20
                                       : kMaxAllowedMallocSize;
  }

  void RePoisonChunk(uptr chunk) {
    // This could be a user-facing chunk (with redzones), or some internal
    // housekeeping chunk, like TransferBatch. Start by assuming the former.
    AsanChunk* ac = GetAsanChunk((void*)chunk);
    uptr allocated_size = allocator.GetActuallyAllocatedSize((void*)chunk);
    if (ac && atomic_load(&ac->chunk_state, memory_order_acquire) ==
                  CHUNK_ALLOCATED) {
      uptr beg = ac->Beg();
      uptr end = ac->Beg() + ac->UsedSize();
      uptr chunk_end = chunk + allocated_size;
      if (chunk < beg && beg < end && end <= chunk_end) {
        // Looks like a valid AsanChunk in use, poison redzones only.
        PoisonShadow(chunk, beg - chunk, kAsanHeapLeftRedzoneMagic);
        uptr end_aligned_down = RoundDownTo(end, ASAN_SHADOW_GRANULARITY);
        FastPoisonShadowPartialRightRedzone(
            end_aligned_down, end - end_aligned_down,
            chunk_end - end_aligned_down, kAsanHeapLeftRedzoneMagic);
        return;
      }
    }

    // This is either not an AsanChunk or freed or quarantined AsanChunk.
    // In either case, poison everything.
    PoisonShadow(chunk, allocated_size, kAsanHeapLeftRedzoneMagic);
  }

  // Apply provided AllocatorOptions to an Allocator
  void ApplyOptions(const AllocatorOptions& options) {
    SetAllocatorMayReturnNull(options.may_return_null);
    allocator.SetReleaseToOSIntervalMs(options.release_to_os_interval_ms);
    SharedInitCode(options);
  }

  void ReInitialize(const AllocatorOptions& options) {
    ApplyOptions(options);

    // Poison all existing allocation's redzones.
    if (CanPoisonMemory()) {
      allocator.ForceLock();
      allocator.ForEachChunk(
          [](uptr chunk, void* alloc) {
            ((Allocator*)alloc)->RePoisonChunk(chunk);
          },
          this);
      allocator.ForceUnlock();
    }
  }

  void GetOptions(AllocatorOptions* options) const {
    options->quarantine_size_mb = quarantine.GetMaxSize() >> 20;
    options->thread_local_quarantine_size_kb =
        quarantine.GetMaxCacheSize() >> 10;
    options->min_redzone = atomic_load(&min_redzone, memory_order_acquire);
    options->max_redzone = atomic_load(&max_redzone, memory_order_acquire);
    options->may_return_null = AllocatorMayReturnNull();
    options->alloc_dealloc_mismatch =
        atomic_load(&alloc_dealloc_mismatch, memory_order_acquire);
    options->release_to_os_interval_ms = allocator.ReleaseToOSIntervalMs();
  }

  // -------------------- Helper methods. -------------------------
  uptr ComputeRZLog(uptr user_requested_size) {
    u32 rz_log = user_requested_size <= 64 - 16            ? 0
                 : user_requested_size <= 128 - 32         ? 1
                 : user_requested_size <= 512 - 64         ? 2
                 : user_requested_size <= 4096 - 128       ? 3
                 : user_requested_size <= (1 << 14) - 256  ? 4
                 : user_requested_size <= (1 << 15) - 512  ? 5
                 : user_requested_size <= (1 << 16) - 1024 ? 6
                                                           : 7;
    u32 hdr_log = RZSize2Log(RoundUpToPowerOfTwo(sizeof(ChunkHeader)));
    u32 min_log = RZSize2Log(atomic_load(&min_redzone, memory_order_acquire));
    u32 max_log = RZSize2Log(atomic_load(&max_redzone, memory_order_acquire));
    return Min(Max(rz_log, Max(min_log, hdr_log)), Max(max_log, hdr_log));
  }

  static uptr ComputeUserRequestedAlignmentLog(uptr user_requested_alignment) {
    if (user_requested_alignment < 8)
      return 0;
    if (user_requested_alignment > 512)
      user_requested_alignment = 512;
    return Log2(user_requested_alignment) - 2;
  }

  static uptr ComputeUserAlignment(uptr user_requested_alignment_log) {
    if (user_requested_alignment_log == 0)
      return 0;
    return 1LL << (user_requested_alignment_log + 2);
  }

  // We have an address between two chunks, and we want to report just one.
  AsanChunk* ChooseChunk(uptr addr, AsanChunk* left_chunk,
                         AsanChunk* right_chunk) {
    if (!left_chunk)
      return right_chunk;
    if (!right_chunk)
      return left_chunk;
    // Prefer an allocated chunk over freed chunk and freed chunk
    // over available chunk.
    u8 left_state = atomic_load(&left_chunk->chunk_state, memory_order_relaxed);
    u8 right_state =
        atomic_load(&right_chunk->chunk_state, memory_order_relaxed);
    if (left_state != right_state) {
      if (left_state == CHUNK_ALLOCATED)
        return left_chunk;
      if (right_state == CHUNK_ALLOCATED)
        return right_chunk;
      if (left_state == CHUNK_QUARANTINE)
        return left_chunk;
      if (right_state == CHUNK_QUARANTINE)
        return right_chunk;
    }
    // Same chunk_state: choose based on offset.
    sptr l_offset = 0, r_offset = 0;
    CHECK(AsanChunkView(left_chunk).AddrIsAtRight(addr, 1, &l_offset));
    CHECK(AsanChunkView(right_chunk).AddrIsAtLeft(addr, 1, &r_offset));
    if (l_offset < r_offset)
      return left_chunk;
    return right_chunk;
  }

  bool UpdateAllocationStack(uptr addr, BufferedStackTrace* stack) {
    AsanChunk* m = GetAsanChunkByAddr(addr);
    if (!m)
      return false;
    if (atomic_load(&m->chunk_state, memory_order_acquire) != CHUNK_ALLOCATED)
      return false;
    if (m->Beg() != addr)
      return false;
    AsanThread* t = GetCurrentThread();
    m->SetAllocContext(t ? t->tid() : kMainTid, StackDepotPut(*stack));
    return true;
  }

  // -------------------- Allocation/Deallocation routines ---------------
  // may_return_null tells AllocateImpl() whether OOM should produce a nullptr
  // (true) or a fatal Report*+Die() (false).
  void* AllocateImpl(uptr size, uptr alignment, BufferedStackTrace* stack,
                     AllocType alloc_type, bool can_fill,
                     bool may_return_null) {
    if (UNLIKELY(!AsanInited()))
      AsanInitFromRtl();
    if (UNLIKELY(IsRssLimitExceeded())) {
      if (may_return_null)
        return nullptr;
      ReportRssLimitExceeded(stack);
    }
    Flags& fl = *flags();
    CHECK(stack);
    const uptr min_alignment = ASAN_SHADOW_GRANULARITY;
    const uptr user_requested_alignment_log =
        ComputeUserRequestedAlignmentLog(alignment);
    if (alignment < min_alignment)
      alignment = min_alignment;
    bool upgraded_from_zero = false;
    if (size == 0) {
      // We'd be happy to avoid allocating memory for zero-size requests, but
      // some programs/tests depend on this behavior and assume that malloc
      // would not return NULL even for zero-size allocations. Moreover, it
      // looks like operator new should never return NULL, and results of
      // consecutive "new" calls must be different even if the allocated size
      // is zero.
      size = 1;
      upgraded_from_zero = true;
    }
    CHECK(IsPowerOfTwo(alignment));
    uptr rz_log = ComputeRZLog(size);
    uptr rz_size = RZLog2Size(rz_log);
    uptr rounded_size = RoundUpTo(Max(size, kChunkHeader2Size), alignment);
    uptr needed_size = rounded_size + rz_size;
    if (alignment > min_alignment)
      needed_size += alignment;
    bool from_primary = PrimaryAllocator::CanAllocate(needed_size, alignment);
    // If we are allocating from the secondary allocator, there will be no
    // automatic right redzone, so add the right redzone manually.
    if (!from_primary)
      needed_size += rz_size;
    CHECK(IsAligned(needed_size, min_alignment));
    if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize ||
        size > max_user_defined_malloc_size) {
      if (may_return_null) {
        Report("WARNING: AddressSanitizer failed to allocate 0x%zx bytes\n",
               size);
        return nullptr;
      }
      uptr malloc_limit =
          Min(kMaxAllowedMallocSize, max_user_defined_malloc_size);
      ReportAllocationSizeTooBig(size, needed_size, malloc_limit, stack);
    }

    AsanThread* t = GetCurrentThread();
    void* allocated;
    if (t) {
      AllocatorCache* cache = GetAllocatorCache(&t->malloc_storage());
      allocated = allocator.Allocate(cache, needed_size, 8);
    } else {
      SpinMutexLock l(&fallback_mutex);
      AllocatorCache* cache = &fallback_allocator_cache;
      allocated = allocator.Allocate(cache, needed_size, 8);
    }
    if (UNLIKELY(!allocated)) {
      SetAllocatorOutOfMemory();
      if (may_return_null)
        return nullptr;
      ReportOutOfMemory(size, stack);
    }

    uptr alloc_beg = reinterpret_cast<uptr>(allocated);
    uptr alloc_end = alloc_beg + needed_size;
    uptr user_beg = alloc_beg + rz_size;
    if (!IsAligned(user_beg, alignment))
      user_beg = RoundUpTo(user_beg, alignment);
    uptr user_end = user_beg + size;
    CHECK_LE(user_end, alloc_end);
    uptr chunk_beg = user_beg - kChunkHeaderSize;
    AsanChunk* m = reinterpret_cast<AsanChunk*>(chunk_beg);
    m->alloc_type = alloc_type;
#if SANITIZER_WINDOWS
    m->from_zero_alloc = upgraded_from_zero;
#endif
    CHECK(size);
    m->SetUsedSize(size);
    m->user_requested_alignment_log = user_requested_alignment_log;

    m->SetAllocContext(t ? t->tid() : kMainTid, StackDepotPut(*stack));

    if (!from_primary || *(u8*)MEM_TO_SHADOW((uptr)allocated) == 0) {
      // The allocator provides an unpoisoned chunk. This is possible for the
      // secondary allocator, or if CanPoisonMemory() was false for some time,
      // for example, due to flags()->start_disabled. Anyway, poison left and
      // right of the block before using it for anything else.
      uptr tail_beg = RoundUpTo(user_end, ASAN_SHADOW_GRANULARITY);
      uptr tail_end = alloc_beg + allocator.GetActuallyAllocatedSize(allocated);
      PoisonShadow(alloc_beg, user_beg - alloc_beg, kAsanHeapLeftRedzoneMagic);
      PoisonShadow(tail_beg, tail_end - tail_beg, kAsanHeapLeftRedzoneMagic);
    }

    uptr size_rounded_down_to_granularity =
        RoundDownTo(size, ASAN_SHADOW_GRANULARITY);
    // Unpoison the bulk of the memory region.
    if (size_rounded_down_to_granularity)
      PoisonShadow(user_beg, size_rounded_down_to_granularity, 0);
    // Deal with the end of the region if size is not aligned to granularity.
    if (size != size_rounded_down_to_granularity && CanPoisonMemory()) {
      u8* shadow =
          (u8*)MemToShadow(user_beg + size_rounded_down_to_granularity);
      *shadow = fl.poison_partial ? (size & (ASAN_SHADOW_GRANULARITY - 1)) : 0;
    }

    if (upgraded_from_zero)
      PoisonShadow(user_beg, ASAN_SHADOW_GRANULARITY,
                   kAsanHeapLeftRedzoneMagic);

    AsanStats& thread_stats = GetCurrentThreadStats();
    thread_stats.mallocs++;
    thread_stats.malloced += size;
    thread_stats.malloced_redzones += needed_size - size;
    if (needed_size > SizeClassMap::kMaxSize)
      thread_stats.malloc_large++;
    else
      thread_stats.malloced_by_size[SizeClassMap::ClassID(needed_size)]++;

    void* res = reinterpret_cast<void*>(user_beg);
    if (can_fill && fl.max_malloc_fill_size) {
      uptr fill_size = Min(size, (uptr)fl.max_malloc_fill_size);
      REAL(memset)(res, fl.malloc_fill_byte, fill_size);
    }
#if CAN_SANITIZE_LEAKS
    m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored
                                                 : __lsan::kDirectlyLeaked;
#endif
    // Must be the last mutation of metadata in this function.
    atomic_store(&m->chunk_state, CHUNK_ALLOCATED, memory_order_release);
    if (alloc_beg != chunk_beg) {
      CHECK_LE(alloc_beg + sizeof(LargeChunkHeader), chunk_beg);
      reinterpret_cast<LargeChunkHeader*>(alloc_beg)->Set(m);
    }
    RunMallocHooks(res, size);
    return res;
  }

  // Defer to the global, flag controlled, OOM policy.
  void* Allocate(uptr size, uptr alignment, BufferedStackTrace* stack,
                 AllocType alloc_type, bool can_fill) {
    return AllocateImpl(size, alignment, stack, alloc_type, can_fill,
                        AllocatorMayReturnNull());
  }

  // Set quarantine flag if chunk is allocated, issue ASan error report on
  // available and quarantined chunks. Return true on success, false otherwise.
  bool AtomicallySetQuarantineFlagIfAllocated(AsanChunk* m, void* ptr,
                                              BufferedStackTrace* stack) {
    u8 old_chunk_state = CHUNK_ALLOCATED;
    // Flip the chunk_state atomically to avoid race on double-free.
    if (!atomic_compare_exchange_strong(&m->chunk_state, &old_chunk_state,
                                        CHUNK_QUARANTINE,
                                        memory_order_acquire)) {
      ReportInvalidFree(ptr, old_chunk_state, stack);
      // It's not safe to push a chunk in quarantine on invalid free.
      return false;
    }
    CHECK_EQ(CHUNK_ALLOCATED, old_chunk_state);
    // It was a user data.
    m->SetFreeContext(kInvalidTid, 0);
    return true;
  }

  // Expects the chunk to already be marked as quarantined by using
  // AtomicallySetQuarantineFlagIfAllocated.
  void QuarantineChunk(AsanChunk* m, void* ptr, BufferedStackTrace* stack) {
    CHECK_EQ(atomic_load(&m->chunk_state, memory_order_relaxed),
             CHUNK_QUARANTINE);
    AsanThread* t = GetCurrentThread();
    m->SetFreeContext(t ? t->tid() : 0, StackDepotPut(*stack));

    // Push into quarantine.
    if (t) {
      AsanThreadLocalMallocStorage* ms = &t->malloc_storage();
      AllocatorCache* ac = GetAllocatorCache(ms);
      quarantine.Put(GetQuarantineCache(ms), QuarantineCallback(ac, stack), m,
                     m->UsedSize());
    } else {
      SpinMutexLock l(&fallback_mutex);
      AllocatorCache* ac = &fallback_allocator_cache;
      quarantine.Put(&fallback_quarantine_cache, QuarantineCallback(ac, stack),
                     m, m->UsedSize());
    }
  }

  void Deallocate(void* ptr, uptr delete_size, uptr delete_alignment,
                  BufferedStackTrace* stack, AllocType alloc_type) {
    uptr p = reinterpret_cast<uptr>(ptr);
    if (p == 0)
      return;

    uptr chunk_beg = p - kChunkHeaderSize;
    AsanChunk* m = reinterpret_cast<AsanChunk*>(chunk_beg);

    // On Windows, uninstrumented DLLs may allocate memory before ASan hooks
    // malloc. Don't report an invalid free in this case.
    if (SANITIZER_WINDOWS && !get_allocator().PointerIsMine(ptr)) {
      if (!IsSystemHeapAddress(p))
        ReportFreeNotMalloced(p, stack);
      return;
    }

    if (RunFreeHooks(ptr)) {
      // Someone used __sanitizer_ignore_free_hook() and decided that they
      // didn't want the memory to __sanitizer_ignore_free_hook freed right now.
      // When they call free() on this pointer again at a later time, we should
      // ignore the alloc-type mismatch and allow them to deallocate the pointer
      // through free(), rather than the initial alloc type.
      m->alloc_type = FROM_MALLOC;
      return;
    }

    // Must mark the chunk as quarantined before any changes to its metadata.
    // Do not quarantine given chunk if we failed to set CHUNK_QUARANTINE flag.
    if (!AtomicallySetQuarantineFlagIfAllocated(m, ptr, stack))
      return;

    if (m->alloc_type != alloc_type) {
      if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire) &&
          !IsAllocDeallocMismatchSuppressed(stack)) {
        ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type,
                                (AllocType)alloc_type);
      }
    } else {
      switch (alloc_type) {
        case FROM_NEW:
        case FROM_NEW_BR:
          if (flags()->new_delete_type_mismatch &&
              ((delete_size && delete_size != m->UsedSize()) ||
               ComputeUserRequestedAlignmentLog(delete_alignment) !=
                   m->user_requested_alignment_log)) {
            ReportNewDeleteTypeMismatch(p, delete_size, delete_alignment,
                                        stack);
          }
          break;
        case FROM_MALLOC:
          if (flags()->free_size_mismatch &&
              ((delete_size && delete_size != m->UsedSize()) ||
               (delete_alignment &&
                ComputeUserRequestedAlignmentLog(delete_alignment) !=
                    m->user_requested_alignment_log))) {
            ReportFreeSizeMismatch(p, delete_size, delete_alignment, stack);
          }
          break;
      }
    }

    AsanStats& thread_stats = GetCurrentThreadStats();
    thread_stats.frees++;
    thread_stats.freed += m->UsedSize();

    QuarantineChunk(m, ptr, stack);
  }

  void* Reallocate(void* old_ptr, uptr new_size, BufferedStackTrace* stack) {
    CHECK(old_ptr && new_size);
    uptr p = reinterpret_cast<uptr>(old_ptr);
    uptr chunk_beg = p - kChunkHeaderSize;
    AsanChunk* m = reinterpret_cast<AsanChunk*>(chunk_beg);

    AsanStats& thread_stats = GetCurrentThreadStats();
    thread_stats.reallocs++;
    thread_stats.realloced += new_size;

    void* new_ptr = Allocate(new_size, /*alignment=*/8, stack, FROM_MALLOC,
                             /*can_fill=*/true);
    if (new_ptr) {
      u8 chunk_state = atomic_load(&m->chunk_state, memory_order_acquire);
      if (chunk_state != CHUNK_ALLOCATED)
        ReportInvalidFree(old_ptr, chunk_state, stack);
      CHECK_NE(REAL(memcpy), nullptr);
      uptr memcpy_size = Min(new_size, m->UsedSize());
      // If realloc() races with free(), we may start copying freed memory.
      // However, we will report racy double-free later anyway.
      REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
      Deallocate(old_ptr, 0, 0, stack, FROM_MALLOC);
    }
    return new_ptr;
  }

  void* Calloc(uptr nmemb, uptr size, BufferedStackTrace* stack,
               uptr align = 8) {
    if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
      if (AllocatorMayReturnNull())
        return nullptr;
      ReportCallocOverflow(nmemb, size, stack);
    }
    void* ptr = Allocate(nmemb * size, align, stack, FROM_MALLOC,
                         /*can_fill=*/false);
    // If the memory comes from the secondary allocator no need to clear it
    // as it comes directly from mmap.
    if (ptr && allocator.FromPrimary(ptr))
      REAL(memset)(ptr, 0, nmemb * size);
    return ptr;
  }

  void ReportInvalidFree(void* ptr, u8 chunk_state, BufferedStackTrace* stack) {
    if (chunk_state == CHUNK_QUARANTINE)
      ReportDoubleFree((uptr)ptr, stack);
    else
      ReportFreeNotMalloced((uptr)ptr, stack);
  }

  void CommitBack(AsanThreadLocalMallocStorage* ms, BufferedStackTrace* stack) {
    AllocatorCache* ac = GetAllocatorCache(ms);
    quarantine.Drain(GetQuarantineCache(ms), QuarantineCallback(ac, stack));
    allocator.SwallowCache(ac);
  }

  // -------------------------- Chunk lookup ----------------------

  // Assumes alloc_beg == allocator.GetBlockBegin(alloc_beg).
  // Returns nullptr if AsanChunk is not yet initialized just after
  // get_allocator().Allocate(), or is being destroyed just before
  // get_allocator().Deallocate().
  AsanChunk* GetAsanChunk(void* alloc_beg) {
    if (!alloc_beg)
      return nullptr;
    AsanChunk* p = reinterpret_cast<LargeChunkHeader*>(alloc_beg)->Get();
    if (!p) {
      if (!allocator.FromPrimary(alloc_beg))
        return nullptr;
      p = reinterpret_cast<AsanChunk*>(alloc_beg);
    }
    u8 state = atomic_load(&p->chunk_state, memory_order_relaxed);
    // It does not guaranty that Chunk is initialized, but it's
    // definitely not for any other value.
    if (state == CHUNK_ALLOCATED || state == CHUNK_QUARANTINE)
      return p;
    return nullptr;
  }

  AsanChunk* GetAsanChunkByAddr(uptr p) {
    void* alloc_beg = allocator.GetBlockBegin(reinterpret_cast<void*>(p));
    return GetAsanChunk(alloc_beg);
  }

  // Allocator must be locked when this function is called.
  AsanChunk* GetAsanChunkByAddrFastLocked(uptr p) {
    void* alloc_beg =
        allocator.GetBlockBeginFastLocked(reinterpret_cast<void*>(p));
    return GetAsanChunk(alloc_beg);
  }

  uptr AllocationSize(uptr p) {
    AsanChunk* m = GetAsanChunkByAddr(p);
    if (!m)
      return 0;
    if (atomic_load(&m->chunk_state, memory_order_acquire) != CHUNK_ALLOCATED)
      return 0;
    if (m->Beg() != p)
      return 0;
    return m->UsedSize();
  }

#if SANITIZER_WINDOWS
  // Returns true if the allocation at p was a zero-size request that was
  // internally upgraded to size 1.
  bool FromZeroAllocation(uptr p) {
    return reinterpret_cast<AsanChunk*>(p - kChunkHeaderSize)->from_zero_alloc;
  }

  // Marks an existing size 1 allocation as having originally been zero-size.
  // Used by SharedReAlloc which augments size 0 to 1 before calling
  // asan_realloc, bypassing Allocate's own zero-size tracking.
  void MarkAsZeroAllocation(uptr p) {
    AsanChunk* m = reinterpret_cast<AsanChunk*>(p - kChunkHeaderSize);
    m->from_zero_alloc = 1;
    PoisonShadow(p, ASAN_SHADOW_GRANULARITY, kAsanHeapLeftRedzoneMagic);
  }
#endif

  uptr AllocationSizeFast(uptr p) {
    return reinterpret_cast<AsanChunk*>(p - kChunkHeaderSize)->UsedSize();
  }

  AsanChunkView FindHeapChunkByAddress(uptr addr) {
    AsanChunk* m1 = GetAsanChunkByAddr(addr);
    sptr offset = 0;
    if (!m1 || AsanChunkView(m1).AddrIsAtLeft(addr, 1, &offset)) {
      // The address is in the chunk's left redzone, so maybe it is actually
      // a right buffer overflow from the other chunk before.
      // Search a bit before to see if there is another chunk.
      AsanChunk* m2 = nullptr;
      for (uptr l = 1; l < GetPageSizeCached(); l++) {
        m2 = GetAsanChunkByAddr(addr - l);
        if (m2 == m1)
          continue;  // Still the same chunk.
        break;
      }
      if (m2 && AsanChunkView(m2).AddrIsAtRight(addr, 1, &offset))
        m1 = ChooseChunk(addr, m2, m1);
    }
    return AsanChunkView(m1);
  }

  void Purge(BufferedStackTrace* stack) {
    AsanThread* t = GetCurrentThread();
    if (t) {
      AsanThreadLocalMallocStorage* ms = &t->malloc_storage();
      quarantine.DrainAndRecycle(
          GetQuarantineCache(ms),
          QuarantineCallback(GetAllocatorCache(ms), stack));
    }
    {
      SpinMutexLock l(&fallback_mutex);
      quarantine.DrainAndRecycle(
          &fallback_quarantine_cache,
          QuarantineCallback(&fallback_allocator_cache, stack));
    }

    allocator.ForceReleaseToOS();
  }

  void PrintStats() {
    allocator.PrintStats();
    quarantine.PrintStats();
  }

  void ForceLock() SANITIZER_ACQUIRE(fallback_mutex) {
    allocator.ForceLock();
    fallback_mutex.Lock();
  }

  void ForceUnlock() SANITIZER_RELEASE(fallback_mutex) {
    fallback_mutex.Unlock();
    allocator.ForceUnlock();
  }
};

static Allocator instance(LINKER_INITIALIZED);

static AsanAllocator& get_allocator() { return instance.allocator; }

bool AsanChunkView::IsValid() const {
  return chunk_ && atomic_load(&chunk_->chunk_state, memory_order_relaxed) !=
                       CHUNK_INVALID;
}
bool AsanChunkView::IsAllocated() const {
  return chunk_ && atomic_load(&chunk_->chunk_state, memory_order_relaxed) ==
                       CHUNK_ALLOCATED;
}
bool AsanChunkView::IsQuarantined() const {
  return chunk_ && atomic_load(&chunk_->chunk_state, memory_order_relaxed) ==
                       CHUNK_QUARANTINE;
}
uptr AsanChunkView::Beg() const { return chunk_->Beg(); }
uptr AsanChunkView::End() const { return Beg() + UsedSize(); }
uptr AsanChunkView::UsedSize() const { return chunk_->UsedSize(); }
u32 AsanChunkView::UserRequestedAlignment() const {
  return Allocator::ComputeUserAlignment(chunk_->user_requested_alignment_log);
}

uptr AsanChunkView::AllocTid() const {
  u32 tid = 0;
  u32 stack = 0;
  chunk_->GetAllocContext(tid, stack);
  return tid;
}

uptr AsanChunkView::FreeTid() const {
  if (!IsQuarantined())
    return kInvalidTid;
  u32 tid = 0;
  u32 stack = 0;
  chunk_->GetFreeContext(tid, stack);
  return tid;
}

AllocType AsanChunkView::GetAllocType() const {
  return (AllocType)chunk_->alloc_type;
}

u32 AsanChunkView::GetAllocStackId() const {
  u32 tid = 0;
  u32 stack = 0;
  chunk_->GetAllocContext(tid, stack);
  return stack;
}

u32 AsanChunkView::GetFreeStackId() const {
  if (!IsQuarantined())
    return 0;
  u32 tid = 0;
  u32 stack = 0;
  chunk_->GetFreeContext(tid, stack);
  return stack;
}

void InitializeAllocator(const AllocatorOptions& options) {
  instance.InitLinkerInitialized(options);
}

void ReInitializeAllocator(const AllocatorOptions& options) {
  instance.ReInitialize(options);
}

// Apply provided AllocatorOptions to an Allocator
void ApplyAllocatorOptions(const AllocatorOptions& options) {
  instance.ApplyOptions(options);
}

void GetAllocatorOptions(AllocatorOptions* options) {
  instance.GetOptions(options);
}

AsanChunkView FindHeapChunkByAddress(uptr addr) {
  return instance.FindHeapChunkByAddress(addr);
}
AsanChunkView FindHeapChunkByAllocBeg(uptr addr) {
  return AsanChunkView(instance.GetAsanChunk(reinterpret_cast<void*>(addr)));
}

void AsanThreadLocalMallocStorage::CommitBack() {
  GET_STACK_TRACE_MALLOC;
  instance.CommitBack(this, &stack);
}

void PrintInternalAllocatorStats() { instance.PrintStats(); }

void asan_free(void* ptr, BufferedStackTrace* stack) {
  instance.Deallocate(ptr, 0, 0, stack, FROM_MALLOC);
}

void asan_free_sized(void* ptr, uptr size, BufferedStackTrace* stack) {
  instance.Deallocate(ptr, size, /*delete_alignment=*/0, stack, FROM_MALLOC);
}

void asan_free_aligned_sized(void* ptr, uptr alignment, uptr size,
                             BufferedStackTrace* stack) {
  instance.Deallocate(ptr, size, alignment, stack, FROM_MALLOC);
}

void* asan_malloc(uptr size, BufferedStackTrace* stack) {
  return SetErrnoOnNull(instance.Allocate(size, /*alignment=*/8, stack,
                                          FROM_MALLOC, /*can_fill=*/true));
}

void* asan_calloc(uptr nmemb, uptr size, BufferedStackTrace* stack) {
  return SetErrnoOnNull(instance.Calloc(nmemb, size, stack));
}

#if SANITIZER_AIX
void* asan_vec_malloc(uptr size, BufferedStackTrace* stack) {
  return SetErrnoOnNull(instance.Allocate(size, /*alignment=*/16, stack,
                                          FROM_MALLOC, /*can_fill=*/true));
}

void* asan_vec_calloc(uptr nmemb, uptr size, BufferedStackTrace* stack) {
  return SetErrnoOnNull(instance.Calloc(nmemb, size, stack, 16));
}
#endif

void* asan_reallocarray(void* p, uptr nmemb, uptr size,
                        BufferedStackTrace* stack) {
  if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
    errno = errno_ENOMEM;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportReallocArrayOverflow(nmemb, size, stack);
  }
  return asan_realloc(p, nmemb * size, stack);
}

void* asan_realloc(void* p, uptr size, BufferedStackTrace* stack) {
  if (!p)
    return SetErrnoOnNull(instance.Allocate(size, /*alignment=*/8, stack,
                                            FROM_MALLOC, /*can_fill=*/true));
  if (size == 0) {
    if (flags()->allocator_frees_and_returns_null_on_realloc_zero) {
      instance.Deallocate(p, 0, 0, stack, FROM_MALLOC);
      return nullptr;
    }
    // Allocate a size of 1 if we shouldn't free() on Realloc to 0
    size = 1;
  }
  return SetErrnoOnNull(instance.Reallocate(p, size, stack));
}

void* asan_valloc(uptr size, BufferedStackTrace* stack) {
  return SetErrnoOnNull(instance.Allocate(size, GetPageSizeCached(), stack,
                                          FROM_MALLOC, /*can_fill=*/true));
}

void* asan_pvalloc(uptr size, BufferedStackTrace* 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(
      instance.Allocate(size, PageSize, stack, FROM_MALLOC, /*can_fill=*/true));
}

void* asan_memalign(uptr alignment, uptr size, BufferedStackTrace* stack) {
  if (UNLIKELY(!IsPowerOfTwo(alignment))) {
    errno = errno_EINVAL;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportInvalidAllocationAlignment(alignment, stack);
  }
  return SetErrnoOnNull(instance.Allocate(size, alignment, stack, FROM_MALLOC,
                                          /*can_fill=*/true));
}

void* asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace* stack) {
  if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) {
    errno = errno_EINVAL;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportInvalidAlignedAllocAlignment(size, alignment, stack);
  }
  return SetErrnoOnNull(instance.Allocate(size, alignment, stack, FROM_MALLOC,
                                          /*can_fill=*/true));
}

int asan_posix_memalign(void** memptr, uptr alignment, uptr size,
                        BufferedStackTrace* stack) {
  if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
    if (AllocatorMayReturnNull())
      return errno_EINVAL;
    ReportInvalidPosixMemalignAlignment(alignment, stack);
  }
  void* ptr = instance.Allocate(size, alignment, stack, FROM_MALLOC,
                                /*can_fill=*/true);
  if (UNLIKELY(!ptr))
    // OOM error is already taken care of by Allocate.
    return errno_ENOMEM;
  CHECK(IsAligned((uptr)ptr, alignment));
  *memptr = ptr;
  return 0;
}

uptr asan_malloc_usable_size(const void* ptr, uptr pc, uptr bp) {
  if (!ptr)
    return 0;
  uptr usable_size = instance.AllocationSize(reinterpret_cast<uptr>(ptr));
  if (flags()->check_malloc_usable_size && (usable_size == 0)) {
    GET_STACK_TRACE_FATAL(pc, bp);
    ReportMallocUsableSizeNotOwned((uptr)ptr, &stack);
  }
#if SANITIZER_WINDOWS
  // Zero-size allocations are internally upgraded to size 1 so that
  // malloc(0)/new(0) return unique non-NULL pointers as required by the
  // standard. Windows heap APIs (HeapSize, RtlSizeHeap, _msize) should still
  // report the originally requested size (0).
  if (usable_size > 0 &&
      instance.FromZeroAllocation(reinterpret_cast<uptr>(ptr))) {
    DCHECK(usable_size == 1);
    return 0;
  }
#endif
  return usable_size;
}

namespace {

void* asan_new(uptr size, BufferedStackTrace* stack, bool array) {
  return SetErrnoOnNull(instance.Allocate(size, /*alignment=*/0, stack,
                                          array ? FROM_NEW_BR : FROM_NEW,
                                          /*can_fill=*/true));
}

void* asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace* stack,
                       bool array) {
  if (UNLIKELY(alignment == 0 || !IsPowerOfTwo(alignment))) {
    errno = errno_EINVAL;
    if (AllocatorMayReturnNull())
      return nullptr;
    ReportInvalidAllocationAlignment(alignment, stack);
  }
  return SetErrnoOnNull(instance.Allocate(size, alignment, stack,
                                          array ? FROM_NEW_BR : FROM_NEW,
                                          /*can_fill=*/true));
}

void asan_delete(void* ptr, BufferedStackTrace* stack, bool array) {
  instance.Deallocate(ptr, 0, 0, stack, array ? FROM_NEW_BR : FROM_NEW);
}

void asan_delete_aligned(void* ptr, uptr alignment, BufferedStackTrace* stack,
                         bool array) {
  instance.Deallocate(ptr, 0, alignment, stack, array ? FROM_NEW_BR : FROM_NEW);
}

void asan_delete_sized(void* ptr, uptr size, BufferedStackTrace* stack,
                       bool array) {
  instance.Deallocate(ptr, size, 0, stack, array ? FROM_NEW_BR : FROM_NEW);
}

void asan_delete_sized_aligned(void* ptr, uptr size, uptr alignment,
                               BufferedStackTrace* stack, bool array) {
  instance.Deallocate(ptr, size, alignment, stack,
                      array ? FROM_NEW_BR : FROM_NEW);
}

}  // namespace

void* asan_new(uptr size, BufferedStackTrace* stack) {
  return asan_new(size, stack, /*array=*/false);
}

void* asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace* stack) {
  return asan_new_aligned(size, alignment, stack, /*array=*/false);
}

void* asan_new_array(uptr size, BufferedStackTrace* stack) {
  return asan_new(size, stack, /*array=*/true);
}

void* asan_new_array_aligned(uptr size, uptr alignment,
                             BufferedStackTrace* stack) {
  return asan_new_aligned(size, alignment, stack, /*array=*/true);
}

void asan_delete(void* ptr, BufferedStackTrace* stack) {
  asan_delete(ptr, stack, /*array=*/false);
}

void asan_delete_aligned(void* ptr, uptr alignment, BufferedStackTrace* stack) {
  asan_delete_aligned(ptr, alignment, stack, /*array=*/false);
}

void asan_delete_sized(void* ptr, uptr size, BufferedStackTrace* stack) {
  asan_delete_sized(ptr, size, stack, /*array=*/false);
}

void asan_delete_sized_aligned(void* ptr, uptr size, uptr alignment,
                               BufferedStackTrace* stack) {
  asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/false);
}

void asan_delete_array(void* ptr, BufferedStackTrace* stack) {
  asan_delete(ptr, stack, /*array=*/true);
}

void asan_delete_array_aligned(void* ptr, uptr alignment,
                               BufferedStackTrace* stack) {
  asan_delete_aligned(ptr, alignment, stack, /*array=*/true);
}

void asan_delete_array_sized(void* ptr, uptr size, BufferedStackTrace* stack) {
  asan_delete_sized(ptr, size, stack, /*array=*/true);
}

void asan_delete_array_sized_aligned(void* ptr, uptr size, uptr alignment,
                                     BufferedStackTrace* stack) {
  asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/true);
}

uptr asan_mz_size(const void* ptr) {
  uptr size = instance.AllocationSize(reinterpret_cast<uptr>(ptr));

#if SANITIZER_WINDOWS
  if (size > 0 && instance.FromZeroAllocation(reinterpret_cast<uptr>(ptr))) {
    DCHECK(size == 1);
    return 0;
  }
#endif

  return size;
}

#if SANITIZER_WINDOWS
void asan_mark_zero_allocation(void* ptr) {
  instance.MarkAsZeroAllocation(reinterpret_cast<uptr>(ptr));
}
#endif

void asan_mz_force_lock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
  instance.ForceLock();
}

void asan_mz_force_unlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
  instance.ForceUnlock();
}

}  // namespace __asan

// --- Implementation of LSan-specific functions --- {{{1
namespace __lsan {
void LockAllocator() { __asan::get_allocator().ForceLock(); }

void UnlockAllocator() { __asan::get_allocator().ForceUnlock(); }

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

uptr PointsIntoChunk(void* p) {
  uptr addr = reinterpret_cast<uptr>(p);
  __asan::AsanChunk* m = __asan::instance.GetAsanChunkByAddrFastLocked(addr);
  if (!m || atomic_load(&m->chunk_state, memory_order_acquire) !=
                __asan::CHUNK_ALLOCATED)
    return 0;
  uptr chunk = m->Beg();
  if (m->AddrIsInside(addr))
    return chunk;
  if (IsSpecialCaseOfOperatorNew0(chunk, m->UsedSize(), addr))
    return chunk;
  return 0;
}

uptr GetUserBegin(uptr chunk) {
  // FIXME: All usecases provide chunk address, GetAsanChunkByAddrFastLocked is
  // not needed.
  __asan::AsanChunk* m = __asan::instance.GetAsanChunkByAddrFastLocked(chunk);
  return m ? m->Beg() : 0;
}

uptr GetUserAddr(uptr chunk) { return chunk; }

LsanMetadata::LsanMetadata(uptr chunk) {
  metadata_ = chunk ? reinterpret_cast<void*>(chunk - __asan::kChunkHeaderSize)
                    : nullptr;
}

bool LsanMetadata::allocated() const {
  if (!metadata_)
    return false;
  __asan::AsanChunk* m = reinterpret_cast<__asan::AsanChunk*>(metadata_);
  return atomic_load(&m->chunk_state, memory_order_relaxed) ==
         __asan::CHUNK_ALLOCATED;
}

ChunkTag LsanMetadata::tag() const {
  __asan::AsanChunk* m = reinterpret_cast<__asan::AsanChunk*>(metadata_);
  return static_cast<ChunkTag>(m->lsan_tag);
}

void LsanMetadata::set_tag(ChunkTag value) {
  __asan::AsanChunk* m = reinterpret_cast<__asan::AsanChunk*>(metadata_);
  m->lsan_tag = value;
}

uptr LsanMetadata::requested_size() const {
  __asan::AsanChunk* m = reinterpret_cast<__asan::AsanChunk*>(metadata_);
  return m->UsedSize();
}

u32 LsanMetadata::stack_trace_id() const {
  __asan::AsanChunk* m = reinterpret_cast<__asan::AsanChunk*>(metadata_);
  u32 tid = 0;
  u32 stack = 0;
  m->GetAllocContext(tid, stack);
  return stack;
}

void ForEachChunk(ForEachChunkCallback callback, void* arg) {
  __asan::get_allocator().ForEachChunk(callback, arg);
}

IgnoreObjectResult IgnoreObject(const void* p) {
  uptr addr = reinterpret_cast<uptr>(p);
  __asan::AsanChunk* m = __asan::instance.GetAsanChunkByAddr(addr);
  if (!m ||
      (atomic_load(&m->chunk_state, memory_order_acquire) !=
       __asan::CHUNK_ALLOCATED) ||
      !m->AddrIsInside(addr)) {
    return kIgnoreObjectInvalid;
  }
  if (m->lsan_tag == kIgnored)
    return kIgnoreObjectAlreadyIgnored;
  m->lsan_tag = __lsan::kIgnored;
  return kIgnoreObjectSuccess;
}

}  // namespace __lsan

// ---------------------- Interface ---------------- {{{1
using namespace __asan;

static const void* AllocationBegin(const void* p) {
  AsanChunk* m = __asan::instance.GetAsanChunkByAddr((uptr)p);
  if (!m)
    return nullptr;
  if (atomic_load(&m->chunk_state, memory_order_acquire) != CHUNK_ALLOCATED)
    return nullptr;
  if (m->UsedSize() == 0)
    return nullptr;
  return (const void*)(m->Beg());
}

// ASan allocator doesn't reserve extra bytes, so normally we would
// just return "size". We don't want to expose our redzone sizes, etc here.
uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }

int __sanitizer_get_ownership(const void* p) {
  uptr ptr = reinterpret_cast<uptr>(p);
  return instance.AllocationSize(ptr) > 0;
}

uptr __sanitizer_get_allocated_size(const void* p) {
  if (!p)
    return 0;
  uptr ptr = reinterpret_cast<uptr>(p);
  uptr allocated_size = instance.AllocationSize(ptr);
  // Die if p is not malloced or if it is already freed.
  if (allocated_size == 0) {
    GET_STACK_TRACE_FATAL_HERE;
    ReportSanitizerGetAllocatedSizeNotOwned(ptr, &stack);
  }
  return allocated_size;
}

uptr __sanitizer_get_allocated_size_fast(const void* p) {
  DCHECK_EQ(p, __sanitizer_get_allocated_begin(p));
  uptr ret = instance.AllocationSizeFast(reinterpret_cast<uptr>(p));
  DCHECK_EQ(ret, __sanitizer_get_allocated_size(p));
  return ret;
}

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

void __sanitizer_purge_allocator() {
  GET_STACK_TRACE_MALLOC;
  instance.Purge(&stack);
}

int __asan_update_allocation_context(void* addr) {
  GET_STACK_TRACE_MALLOC;
  return instance.UpdateAllocationStack((uptr)addr, &stack);
}
