//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
// 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 "llvm/Support/Memory.h"
#include "llvm/Support/Process.h"
#include "gtest/gtest.h"
#include <cstdlib>

#if defined(__NetBSD__)
// clang-format off
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <err.h>
#include <unistd.h>
// clang-format on
#endif

using namespace llvm;
using namespace sys;

namespace {

bool IsMPROTECT() {
#if defined(__NetBSD__)
  int mib[3];
  int paxflags;
  size_t len = sizeof(paxflags);

  mib[0] = CTL_PROC;
  mib[1] = getpid();
  mib[2] = PROC_PID_PAXFLAGS;

  if (sysctl(mib, 3, &paxflags, &len, NULL, 0) != 0)
    err(EXIT_FAILURE, "sysctl");

  return !!(paxflags & CTL_PROC_PAXFLAGS_MPROTECT);
#elif (defined(__APPLE__) && defined(__aarch64__)) || defined(__OpenBSD__)
  return true;
#else
  return false;
#endif
}

class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
public:
  MappedMemoryTest() {
    Flags = GetParam();
    PageSize = sys::Process::getPageSizeEstimate();
  }

protected:
  // Adds RW flags to permit testing of the resulting memory
  unsigned getTestableEquivalent(unsigned RequestedFlags) {
    switch (RequestedFlags) {
    case Memory::MF_READ:
    case Memory::MF_WRITE:
    case Memory::MF_READ|Memory::MF_WRITE:
      return Memory::MF_READ|Memory::MF_WRITE;
    case Memory::MF_READ|Memory::MF_EXEC:
    case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
    case Memory::MF_EXEC:
      return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
    }
    // Default in case values are added to the enum, as required by some compilers
    return Memory::MF_READ|Memory::MF_WRITE;
  }

  // Returns true if the memory blocks overlap
  bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
    if (M1.base() == M2.base())
      return true;

    if (M1.base() > M2.base())
      return (unsigned char *)M2.base() + M2.allocatedSize() > M1.base();

    return (unsigned char *)M1.base() + M1.allocatedSize() > M2.base();
  }

  unsigned Flags;
  size_t   PageSize;
};

// MPROTECT prevents W+X mmaps
#define CHECK_UNSUPPORTED() \
  do { \
    if ((Flags & Memory::MF_WRITE) && (Flags & Memory::MF_EXEC) && \
        IsMPROTECT()) \
      GTEST_SKIP();   \
  } while (0)

TEST_P(MappedMemoryTest, AllocAndRelease) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(sizeof(int), M1.allocatedSize());

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
}

TEST_P(MappedMemoryTest, AllocAndReleaseHuge) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock M1 = Memory::allocateMappedMemory(
      sizeof(int), nullptr, Flags | Memory::MF_HUGE_HINT, EC);
  EXPECT_EQ(std::error_code(), EC);

  // Test large/huge memory pages. In the worst case, 4kb pages should be
  // returned, if large pages aren't available.

  EXPECT_NE((void *)nullptr, M1.base());
  EXPECT_LE(sizeof(int), M1.allocatedSize());

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
}

TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M2 = Memory::allocateMappedMemory(64, nullptr, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M3 = Memory::allocateMappedMemory(32, nullptr, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(16U, M1.allocatedSize());
  EXPECT_NE((void*)nullptr, M2.base());
  EXPECT_LE(64U, M2.allocatedSize());
  EXPECT_NE((void*)nullptr, M3.base());
  EXPECT_LE(32U, M3.allocatedSize());

  EXPECT_FALSE(doesOverlap(M1, M2));
  EXPECT_FALSE(doesOverlap(M2, M3));
  EXPECT_FALSE(doesOverlap(M1, M3));

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  EXPECT_NE((void*)nullptr, M4.base());
  EXPECT_LE(16U, M4.allocatedSize());
  EXPECT_FALSE(Memory::releaseMappedMemory(M4));
  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}

TEST_P(MappedMemoryTest, BasicWrite) {
  // This test applies only to readable and writeable combinations
  if (Flags &&
      !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
    GTEST_SKIP();
  CHECK_UNSUPPORTED();

  std::error_code EC;
  MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(sizeof(int), M1.allocatedSize());

  int *a = (int*)M1.base();
  *a = 1;
  EXPECT_EQ(1, *a);

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
}

TEST_P(MappedMemoryTest, MultipleWrite) {
  // This test applies only to readable and writeable combinations
  if (Flags &&
      !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
    GTEST_SKIP();
  CHECK_UNSUPPORTED();

  std::error_code EC;
  MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
                                                EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
                                                EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
                                                EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_FALSE(doesOverlap(M1, M2));
  EXPECT_FALSE(doesOverlap(M2, M3));
  EXPECT_FALSE(doesOverlap(M1, M3));

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(1U * sizeof(int), M1.allocatedSize());
  EXPECT_NE((void*)nullptr, M2.base());
  EXPECT_LE(8U * sizeof(int), M2.allocatedSize());
  EXPECT_NE((void*)nullptr, M3.base());
  EXPECT_LE(4U * sizeof(int), M3.allocatedSize());

  int *x = (int*)M1.base();
  *x = 1;

  int *y = (int*)M2.base();
  for (int i = 0; i < 8; i++) {
    y[i] = i;
  }

  int *z = (int*)M3.base();
  *z = 42;

  EXPECT_EQ(1, *x);
  EXPECT_EQ(7, y[7]);
  EXPECT_EQ(42, *z);

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  EXPECT_FALSE(Memory::releaseMappedMemory(M3));

  MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
                                                Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  EXPECT_NE((void*)nullptr, M4.base());
  EXPECT_LE(64U * sizeof(int), M4.allocatedSize());
  x = (int*)M4.base();
  *x = 4;
  EXPECT_EQ(4, *x);
  EXPECT_FALSE(Memory::releaseMappedMemory(M4));

  // Verify that M2 remains unaffected by other activity
  for (int i = 0; i < 8; i++) {
    EXPECT_EQ(i, y[i]);
  }
  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}

TEST_P(MappedMemoryTest, EnabledWrite) {
  // MPROTECT prevents W+X, and since this test always adds W we need
  // to block any variant with X.
  if ((Flags & Memory::MF_EXEC) && IsMPROTECT())
    GTEST_SKIP();

  std::error_code EC;
  MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
                                                EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
                                                EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
                                                EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(2U * sizeof(int), M1.allocatedSize());
  EXPECT_NE((void*)nullptr, M2.base());
  EXPECT_LE(8U * sizeof(int), M2.allocatedSize());
  EXPECT_NE((void*)nullptr, M3.base());
  EXPECT_LE(4U * sizeof(int), M3.allocatedSize());

  EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
  EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
  EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));

  EXPECT_FALSE(doesOverlap(M1, M2));
  EXPECT_FALSE(doesOverlap(M2, M3));
  EXPECT_FALSE(doesOverlap(M1, M3));

  int *x = (int*)M1.base();
  *x = 1;
  int *y = (int*)M2.base();
  for (unsigned int i = 0; i < 8; i++) {
    y[i] = i;
  }
  int *z = (int*)M3.base();
  *z = 42;

  EXPECT_EQ(1, *x);
  EXPECT_EQ(7, y[7]);
  EXPECT_EQ(42, *z);

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  EXPECT_EQ(6, y[6]);

  MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  EXPECT_NE((void*)nullptr, M4.base());
  EXPECT_LE(16U, M4.allocatedSize());
  EXPECT_EQ(std::error_code(),
            Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
  x = (int*)M4.base();
  *x = 4;
  EXPECT_EQ(4, *x);
  EXPECT_FALSE(Memory::releaseMappedMemory(M4));
  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}

TEST_P(MappedMemoryTest, SuccessiveNear) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(16U, M1.allocatedSize());
  EXPECT_NE((void*)nullptr, M2.base());
  EXPECT_LE(64U, M2.allocatedSize());
  EXPECT_NE((void*)nullptr, M3.base());
  EXPECT_LE(32U, M3.allocatedSize());

  EXPECT_FALSE(doesOverlap(M1, M2));
  EXPECT_FALSE(doesOverlap(M2, M3));
  EXPECT_FALSE(doesOverlap(M1, M3));

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}

TEST_P(MappedMemoryTest, DuplicateNear) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock Near((void*)(3*PageSize), 16);
  MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(16U, M1.allocatedSize());
  EXPECT_NE((void*)nullptr, M2.base());
  EXPECT_LE(64U, M2.allocatedSize());
  EXPECT_NE((void*)nullptr, M3.base());
  EXPECT_LE(32U, M3.allocatedSize());

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}

TEST_P(MappedMemoryTest, ZeroNear) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock Near(nullptr, 0);
  MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(16U, M1.allocatedSize());
  EXPECT_NE((void*)nullptr, M2.base());
  EXPECT_LE(64U, M2.allocatedSize());
  EXPECT_NE((void*)nullptr, M3.base());
  EXPECT_LE(32U, M3.allocatedSize());

  EXPECT_FALSE(doesOverlap(M1, M2));
  EXPECT_FALSE(doesOverlap(M2, M3));
  EXPECT_FALSE(doesOverlap(M1, M3));

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}

TEST_P(MappedMemoryTest, ZeroSizeNear) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock Near((void*)(4*PageSize), 0);
  MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);
  MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(16U, M1.allocatedSize());
  EXPECT_NE((void*)nullptr, M2.base());
  EXPECT_LE(64U, M2.allocatedSize());
  EXPECT_NE((void*)nullptr, M3.base());
  EXPECT_LE(32U, M3.allocatedSize());

  EXPECT_FALSE(doesOverlap(M1, M2));
  EXPECT_FALSE(doesOverlap(M2, M3));
  EXPECT_FALSE(doesOverlap(M1, M3));

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}

TEST_P(MappedMemoryTest, UnalignedNear) {
  CHECK_UNSUPPORTED();
  std::error_code EC;
  MemoryBlock Near((void*)(2*PageSize+5), 0);
  MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
  EXPECT_EQ(std::error_code(), EC);

  EXPECT_NE((void*)nullptr, M1.base());
  EXPECT_LE(sizeof(int), M1.allocatedSize());

  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
}

// Note that Memory::MF_WRITE is not supported exclusively across
// operating systems and architectures and can imply MF_READ|MF_WRITE
unsigned MemoryFlags[] = {
                           Memory::MF_READ,
                           Memory::MF_WRITE,
                           Memory::MF_READ|Memory::MF_WRITE,
                           Memory::MF_EXEC,
                           Memory::MF_READ|Memory::MF_EXEC,
                           Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
                         };

INSTANTIATE_TEST_SUITE_P(AllocationTests, MappedMemoryTest,
                         ::testing::ValuesIn(MemoryFlags));

}  // anonymous namespace
