//===-- 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].Size = 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].Size, __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);
}
