// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include "test.h"

#include <lib/arch/cache.h>
#include <lib/code-patching/code-patching.h>
#include <lib/zbitl/error_stdio.h>
#include <lib/zbitl/view.h>
#include <stdio.h>

#include <ktl/byte.h>
#include <ktl/span.h>
#include <ktl/string_view.h>

#include "../test-main.h"

const char Symbolize::kProgramName_[] = "code-patching-test";

// Defined in add-one.S.
extern "C" uint64_t AddOne(uint64_t x);

// Defined by //zircon/kernel/phys/test/code-patching:multiply_by_factor.
extern "C" uint64_t multiply_by_factor(uint64_t x);

namespace {

constexpr size_t kExpectedNumPatches = 2;

// Returns the address range within this executable associated with a given
// link-time, virtual range.
ktl::span<ktl::byte> GetInstructionRange(uint64_t range_start, size_t range_size) {
// If we are not static PIE, then we expect link-time addresses to already
// be offset from PHYS_LOAD_ADDRESS; in that case, adjust.
#ifndef ZX_STATIC_PIE
  range_start -= reinterpret_cast<uint64_t>(PHYS_LOAD_ADDRESS);
#endif

  auto* loaded_start = reinterpret_cast<ktl::byte*>(const_cast<char*>(PHYS_LOAD_ADDRESS));
  const size_t loaded_size = static_cast<size_t>(_end - PHYS_LOAD_ADDRESS);
  ktl::span<ktl::byte> loaded_range{loaded_start, loaded_size};
  ZX_ASSERT(range_size <= loaded_range.size());
  ZX_ASSERT(range_start <= loaded_range.size() - range_size);
  return loaded_range.subspan(range_start, range_size);
}

int TestAddOnePatching(const code_patching::Directive& patch) {
  ZX_ASSERT_MSG(patch.range_size == kAddOnePatchSize,
                "Expected patch case #%u to cover %zu bytes; got %u", kAddOneCaseId,
                kAddOnePatchSize, patch.range_size);

  {
    uint64_t result = AddOne(583);
    ZX_ASSERT_MSG(result == 584, "AddOne(583) returned %lu; expected 584.\n", result);
  }

  // After patching (and synchronizing the instruction and data caches), we
  // expect AddOne() to be the identity function.
  auto insns = GetInstructionRange(patch.range_start, patch.range_size);
  code_patching::NopFill(insns);
  arch::CacheConsistencyContext().SyncRange(patch.range_start, patch.range_size);
  {
    uint64_t result = AddOne(583);
    ZX_ASSERT_MSG(result == 583, "Patched AddOne(583) returned %lu; expected 583.\n", result);
  }
  return 0;
}

int TestMultiplyByFactorPatching(const code_patching::Directive& patch) {
  ZX_ASSERT_MSG(patch.range_size == kMultiplyByFactorPatchSize,
                "Expected patch case #%u to cover %zu bytes; got %u", kMultiplyByFactorCaseId,
                kMultiplyByFactorPatchSize, patch.range_size);

  auto insns = GetInstructionRange(patch.range_start, patch.range_size);

  // After patching and synchronizing, we expect multiply_by_factor() to
  // multiply by 2.
  ktl::span<const ktl::byte> multiply_by_two = GetPatchAlternative("multiply_by_two");
  code_patching::Patch(insns, multiply_by_two);
  arch::CacheConsistencyContext().SyncRange(patch.range_start, patch.range_size);

  {
    uint64_t result = multiply_by_factor(583);
    ZX_ASSERT_MSG(result == 2 * 583, "multiply_by_factor(583) returned %lu; expected %d.\n", result,
                  2 * 583);
  }

  // After patching and synchronizing, we expect multiply_by_factor() to
  // multiply by ten.
  ktl::span<const ktl::byte> multiply_by_ten = GetPatchAlternative("multiply_by_ten");
  code_patching::Patch(insns, multiply_by_ten);
  arch::CacheConsistencyContext().SyncRange(patch.range_start, patch.range_size);
  {
    uint64_t result = multiply_by_factor(583);
    ZX_ASSERT_MSG(result == 10 * 583, "multiply_by_factor(583) returned %lu; expected %d.\n",
                  result, 10 * 583);
  }

  return 0;
}

}  // namespace

int TestMain(void* zbi_ptr, arch::EarlyTicks) {
  zbitl::View<ktl::span<ktl::byte>> zbi({static_cast<ktl::byte*>(zbi_ptr), SIZE_MAX});

  ktl::span<ktl::byte> raw_patches;
  for (auto [header, payload] : zbi) {
    // The patch metadata is expected to be stored in an uncompressed ramdisk
    // item.
    if (header->type == ZBI_TYPE_STORAGE_RAMDISK &&
        (header->flags & ZBI_FLAG_STORAGE_COMPRESSED) == 0) {
      raw_patches = payload;
      break;
    }
  }
  if (auto result = zbi.take_error(); result.is_error()) {
    zbitl::PrintViewError(result.error_value());
    return 1;
  }

  if (raw_patches.size() % sizeof(code_patching::Directive)) {
    printf("Expected total size of code patch directives to be a multiple of %lu: got %zu\n",
           sizeof(code_patching::Directive), raw_patches.size());
    return 1;
  }

  ktl::span<code_patching::Directive> patches{
      reinterpret_cast<code_patching::Directive*>(raw_patches.data()),
      raw_patches.size() / sizeof(code_patching::Directive),
  };

  printf("Patches found:\n");
  printf("| %-4s | %-8s | %-8s | %-4s |\n", "ID", "Start", "End", "Size");
  for (const auto& patch : patches) {
    printf("| %-4u | %#-8lx | %#-8lx | %-4u |\n", patch.id, patch.range_start,
           patch.range_start + patch.range_size, patch.range_size);
  }

  if (patches.size() != kExpectedNumPatches) {
    printf("Expected %zu code patch directive: got %zu", kExpectedNumPatches, patches.size());
    return 1;
  }

  for (size_t i = 0; i < patches.size(); ++i) {
    const auto& patch = patches[i];
    switch (patch.id) {
      case kAddOneCaseId:
        if (int result = TestAddOnePatching(patch); result != 0) {
          return result;
        }
        break;
      case kMultiplyByFactorCaseId:
        if (int result = TestMultiplyByFactorPatching(patch); result != 0) {
          return result;
        }
        break;
      default:
        printf("Unexpected patch case ID: %u\n", patch.id);
        return 1;
    }
  }

  return 0;
}
