// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Test for the debug interfaces specific to processes.

#include <lib/zx/process.h>
#include <lib/zx/vmo.h>
#include <stdint.h>
#include <zircon/types.h>

#include <zxtest/zxtest.h>

constexpr size_t kVmoSize = 4096 * 3u;
constexpr size_t kVmarSize = kVmoSize * 2u;

namespace {
// xorshift PRNG, use as first value any number except 0. This simple looking function
// generates a random sequence with period 2^31 when fed its previous value.
uint32_t xorshift32(uint32_t prev) {
  prev ^= prev << 13;
  prev ^= prev >> 17;
  prev ^= prev << 5;
  return prev;
}

std::unique_ptr<uint32_t[]> MakeXorShiftBuf(size_t len) {
  const auto count = len / sizeof(uint32_t);
  auto buf = std::make_unique<uint32_t[]>(count);

  auto xorv = xorshift32(1u);
  for (size_t ix = 0; ix != count; ++ix) {
    buf[ix] = xorv;
    xorv = xorshift32(xorv);
  }
  return buf;
}

bool VerifyXorShiftBuf(const uint32_t* data, size_t len) {
  const auto count = len / sizeof(uint32_t);

  auto xorv = xorshift32(1u);
  for (size_t ix = 0; ix != count; ++ix) {
    if (data[ix] != xorv)
      return false;
    xorv = xorshift32(xorv);
  }
  return true;
}

bool VerifyXorShiftVmo(const zx::vmo& vmo, size_t len) {
  const auto count = len / sizeof(uint32_t);
  auto buf = std::make_unique<uint32_t[]>(count);

  if (vmo.read(buf.get(), 0, len) != ZX_OK) {
    return false;
  }
  return VerifyXorShiftBuf(buf.get(), len);
}

// This fixture creates a VMAR and a VMO mapped into it for the current process.
class ProcessDebugFixture : public zxtest::Test {
 public:
  const zx::vmo& vmo() { return vmo_; }
  const zx::vmar& vmar() { return vmar_; }
  zx_vaddr_t data_start() { return map_addr_; }
  zx_vaddr_t vmar_start() { return vmar_addr_; }

 private:
  static constexpr zx_vm_option_t kVmarOpts = ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE;
  static constexpr zx_vm_option_t kMapOpts = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;

  void SetUp() override {
    ASSERT_OK(zx::vmo::create(kVmoSize, 0u, &vmo_));
    ASSERT_OK(zx::vmar::root_self()->allocate(kVmarOpts, 0u, kVmarSize, &vmar_, &vmar_addr_));
    ASSERT_OK(vmar_.map(kMapOpts, 0u, vmo_, 0u, kVmoSize, &map_addr_));
  }

  zx::vmo vmo_;
  zx::vmar vmar_;
  zx_vaddr_t map_addr_ = 0u;
  zx_vaddr_t vmar_addr_ = 0u;
};

using ProcessDebugTest = ProcessDebugFixture;

TEST(ProcessDebugUtilsTest, XorShiftIsOk) {
  ASSERT_EQ(270369u, xorshift32(1u));
  ASSERT_EQ(67634689u, xorshift32(270369u));
}

TEST_F(ProcessDebugTest, ReadMemoryAtOffsetIsOk) {
  // Write pattern via VMO and read it via zx_process_read_memory().
  auto xr = MakeXorShiftBuf(kVmoSize);
  ASSERT_OK(vmo().write(xr.get(), 0u, kVmoSize));

  auto buf = std::make_unique<uint32_t[]>(kVmoSize);
  size_t actual = 0u;
  ASSERT_OK(zx::process::self()->read_memory(data_start(), buf.get(), kVmoSize, &actual));
  ASSERT_EQ(actual, kVmoSize);
  ASSERT_TRUE(VerifyXorShiftBuf(buf.get(), kVmoSize));
}

TEST_F(ProcessDebugTest, WriteMemoryAtOffsetIsOk) {
  // Write pattern via zx_process_write_memory() and read via vmo.
  auto xr = MakeXorShiftBuf(kVmoSize);
  size_t actual = 0u;
  ASSERT_OK(zx::process::self()->write_memory(data_start(), xr.get(), kVmoSize, &actual));
  ASSERT_TRUE(VerifyXorShiftVmo(vmo(), kVmoSize));
}

TEST_F(ProcessDebugTest, ReadMemoryAtInvalidOffsetReturnsErrorNoMemory) {
  char buf[64];
  size_t actual = 0u;
  ASSERT_EQ(zx::process::self()->read_memory(0u, buf, 64, &actual), ZX_ERR_NO_MEMORY);
  // Either the first page or the last page of the mapping is invalid, use that address.
  auto read_start = (data_start() > vmar_start())
                        ? vmar_start()
                        : vmar_start() + kVmarSize - zx_system_get_page_size();
  ASSERT_EQ(zx::process::self()->read_memory(read_start, buf, 64, &actual), ZX_ERR_NO_MEMORY);
}

TEST_F(ProcessDebugTest, WriteAtInvalidOffsetReturnsErrorNoMemory) {
  const char buf[64] = {0};
  size_t actual = 0u;
  ASSERT_EQ(zx::process::self()->write_memory(0u, buf, 64, &actual), ZX_ERR_NO_MEMORY);
  // Either the first page or the last page of the mapping is invalid, use that address.
  auto write_start = (data_start() > vmar_start())
                         ? vmar_start()
                         : vmar_start() + kVmarSize - zx_system_get_page_size();
  ASSERT_EQ(zx::process::self()->write_memory(write_start, buf, 64, &actual), ZX_ERR_NO_MEMORY);
}

TEST(ProcessDebugVDSO, WriteToVdsoAddressReturnsAccessDenied) {
  const uintptr_t code_addr[] = {reinterpret_cast<uintptr_t>(zx_channel_write),
                                 reinterpret_cast<uintptr_t>(zx_handle_close),
                                 reinterpret_cast<uintptr_t>(zx_ticks_per_second),
                                 reinterpret_cast<uintptr_t>(zx_deadline_after)};
  // If the kernel code gets this wrong, the expected result is a hard kernel panic.
  size_t actual = 0;
  const char buf[64] = {0x1c};
  for (auto addr : code_addr) {
    ASSERT_EQ(zx::process::self()->write_memory(addr, buf, 64, &actual), ZX_ERR_ACCESS_DENIED);
  }
}

}  // namespace
