//===-- crash_handler_api.cpp -----------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "gwp_asan/crash_handler.h"
#include "gwp_asan/guarded_pool_allocator.h"
#include "gwp_asan/stack_trace_compressor.h"
#include "gwp_asan/tests/harness.h"

using Error = gwp_asan::Error;
using GuardedPoolAllocator = gwp_asan::GuardedPoolAllocator;
using AllocationMetadata = gwp_asan::AllocationMetadata;
using AllocatorState = gwp_asan::AllocatorState;

class CrashHandlerAPITest : public Test {
public:
  void SetUp() override { setupState(); }

protected:
  size_t metadata(uintptr_t Addr, uintptr_t Size, bool IsDeallocated) {
    // Should only be allocating the 0x3000, 0x5000, 0x7000, 0x9000 pages.
    EXPECT_GE(Addr, 0x3000u);
    EXPECT_LT(Addr, 0xa000u);

    size_t Slot = State.getNearestSlot(Addr);

    Metadata[Slot].Addr = Addr;
    Metadata[Slot].RequestedSize = Size;
    Metadata[Slot].IsDeallocated = IsDeallocated;
    Metadata[Slot].AllocationTrace.ThreadID = 123;
    Metadata[Slot].DeallocationTrace.ThreadID = 321;
    setupBacktraces(&Metadata[Slot]);

    return Slot;
  }

  void setupState() {
    State.GuardedPagePool = 0x2000;
    State.GuardedPagePoolEnd = 0xb000;
    State.MaxSimultaneousAllocations = 4; // 0x3000, 0x5000, 0x7000, 0x9000.
    State.PageSize = 0x1000;
  }

  void setupBacktraces(AllocationMetadata *Meta) {
    Meta->AllocationTrace.TraceSize = gwp_asan::compression::pack(
        BacktraceConstants, kNumBacktraceConstants,
        Meta->AllocationTrace.CompressedTrace,
        AllocationMetadata::kStackFrameStorageBytes);

    if (Meta->IsDeallocated)
      Meta->DeallocationTrace.TraceSize = gwp_asan::compression::pack(
          BacktraceConstants, kNumBacktraceConstants,
          Meta->DeallocationTrace.CompressedTrace,
          AllocationMetadata::kStackFrameStorageBytes);
  }

  void checkBacktrace(const AllocationMetadata *Meta, bool IsDeallocated) {
    uintptr_t Buffer[kNumBacktraceConstants];
    size_t NumBacktraceConstants = kNumBacktraceConstants;
    EXPECT_EQ(NumBacktraceConstants, __gwp_asan_get_allocation_trace(
                                         Meta, Buffer, kNumBacktraceConstants));
    for (size_t i = 0; i < kNumBacktraceConstants; ++i)
      EXPECT_EQ(Buffer[i], BacktraceConstants[i]);

    if (IsDeallocated) {
      EXPECT_EQ(NumBacktraceConstants,
                __gwp_asan_get_deallocation_trace(Meta, Buffer,
                                                  kNumBacktraceConstants));
      for (size_t i = 0; i < kNumBacktraceConstants; ++i)
        EXPECT_EQ(Buffer[i], BacktraceConstants[i]);
    }
  }

  void checkMetadata(size_t Index, uintptr_t ErrorPtr) {
    const AllocationMetadata *Meta =
        __gwp_asan_get_metadata(&State, Metadata, ErrorPtr);
    EXPECT_NE(nullptr, Meta);
    EXPECT_EQ(Metadata[Index].Addr, __gwp_asan_get_allocation_address(Meta));
    EXPECT_EQ(Metadata[Index].RequestedSize,
              __gwp_asan_get_allocation_size(Meta));
    EXPECT_EQ(Metadata[Index].AllocationTrace.ThreadID,
              __gwp_asan_get_allocation_thread_id(Meta));

    bool IsDeallocated = __gwp_asan_is_deallocated(Meta);
    EXPECT_EQ(Metadata[Index].IsDeallocated, IsDeallocated);
    checkBacktrace(Meta, IsDeallocated);

    if (!IsDeallocated)
      return;

    EXPECT_EQ(Metadata[Index].DeallocationTrace.ThreadID,
              __gwp_asan_get_deallocation_thread_id(Meta));
  }

  static constexpr size_t kNumBacktraceConstants = 4;
  static uintptr_t BacktraceConstants[kNumBacktraceConstants];
  AllocatorState State = {};
  AllocationMetadata Metadata[4] = {};
};

uintptr_t CrashHandlerAPITest::BacktraceConstants[kNumBacktraceConstants] = {
    0xdeadbeef, 0xdeadc0de, 0xbadc0ffe, 0xcafef00d};

TEST_F(CrashHandlerAPITest, PointerNotMine) {
  uintptr_t UnknownPtr = reinterpret_cast<uintptr_t>(&State);

  EXPECT_FALSE(__gwp_asan_error_is_mine(&State, 0));
  EXPECT_FALSE(__gwp_asan_error_is_mine(&State, UnknownPtr));

  EXPECT_EQ(Error::UNKNOWN, __gwp_asan_diagnose_error(&State, Metadata, 0));
  EXPECT_EQ(Error::UNKNOWN,
            __gwp_asan_diagnose_error(&State, Metadata, UnknownPtr));

  EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, 0));
  EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, UnknownPtr));
}

TEST_F(CrashHandlerAPITest, PointerNotAllocated) {
  uintptr_t FailureAddress = 0x9000;

  EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
  EXPECT_EQ(Error::UNKNOWN,
            __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
  EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State));
  EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, FailureAddress));
}

TEST_F(CrashHandlerAPITest, DoubleFree) {
  size_t Index =
      metadata(/* Addr */ 0x7000, /* Size */ 0x20, /* IsDeallocated */ true);
  uintptr_t FailureAddress = 0x7000;

  State.FailureType = Error::DOUBLE_FREE;
  State.FailureAddress = FailureAddress;

  EXPECT_TRUE(__gwp_asan_error_is_mine(&State));
  EXPECT_EQ(Error::DOUBLE_FREE,
            __gwp_asan_diagnose_error(&State, Metadata, 0x0));
  EXPECT_EQ(FailureAddress, __gwp_asan_get_internal_crash_address(&State));
  checkMetadata(Index, FailureAddress);
}

TEST_F(CrashHandlerAPITest, InvalidFree) {
  size_t Index =
      metadata(/* Addr */ 0x7000, /* Size */ 0x20, /* IsDeallocated */ false);
  uintptr_t FailureAddress = 0x7001;

  State.FailureType = Error::INVALID_FREE;
  State.FailureAddress = FailureAddress;

  EXPECT_TRUE(__gwp_asan_error_is_mine(&State));
  EXPECT_EQ(Error::INVALID_FREE,
            __gwp_asan_diagnose_error(&State, Metadata, 0x0));
  EXPECT_EQ(FailureAddress, __gwp_asan_get_internal_crash_address(&State));
  checkMetadata(Index, FailureAddress);
}

TEST_F(CrashHandlerAPITest, InvalidFreeNoMetadata) {
  uintptr_t FailureAddress = 0x7001;

  State.FailureType = Error::INVALID_FREE;
  State.FailureAddress = FailureAddress;

  EXPECT_TRUE(__gwp_asan_error_is_mine(&State));
  EXPECT_EQ(Error::INVALID_FREE,
            __gwp_asan_diagnose_error(&State, Metadata, 0x0));
  EXPECT_EQ(FailureAddress, __gwp_asan_get_internal_crash_address(&State));
  EXPECT_EQ(nullptr, __gwp_asan_get_metadata(&State, Metadata, FailureAddress));
}

TEST_F(CrashHandlerAPITest, UseAfterFree) {
  size_t Index =
      metadata(/* Addr */ 0x7000, /* Size */ 0x20, /* IsDeallocated */ true);
  uintptr_t FailureAddress = 0x7001;

  EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
  EXPECT_EQ(Error::USE_AFTER_FREE,
            __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
  EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State));
  checkMetadata(Index, FailureAddress);
}

TEST_F(CrashHandlerAPITest, BufferOverflow) {
  size_t Index =
      metadata(/* Addr */ 0x5f00, /* Size */ 0x100, /* IsDeallocated */ false);
  uintptr_t FailureAddress = 0x6000;

  EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
  EXPECT_EQ(Error::BUFFER_OVERFLOW,
            __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
  EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State));
  checkMetadata(Index, FailureAddress);
}

TEST_F(CrashHandlerAPITest, BufferUnderflow) {
  size_t Index =
      metadata(/* Addr */ 0x3000, /* Size */ 0x10, /* IsDeallocated*/ false);
  uintptr_t FailureAddress = 0x2fff;

  EXPECT_TRUE(__gwp_asan_error_is_mine(&State, FailureAddress));
  EXPECT_EQ(Error::BUFFER_UNDERFLOW,
            __gwp_asan_diagnose_error(&State, Metadata, FailureAddress));
  EXPECT_EQ(0u, __gwp_asan_get_internal_crash_address(&State));
  checkMetadata(Index, FailureAddress);
}
