// Copyright 2022 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.

#include "src/lib/unwinder/dwarf_expr.h"

#include <cstdint>

#include <gtest/gtest.h>

#include "src/lib/unwinder/memory.h"
#include "src/lib/unwinder/registers.h"

namespace unwinder {

namespace {

Error EvaluateWithError(const std::vector<uint8_t>& expr,
                        const std::map<RegisterID, uint64_t>& register_values,
                        std::vector<uint64_t> stack, uint64_t& result) {
  LocalMemory mem;
  Registers regs(Registers::Arch::kArm64);
  for (auto [reg, val] : register_values) {
    Error err = regs.Set(reg, val);
    EXPECT_TRUE(err.ok()) << err.msg();
  }
  DwarfExpr dwarf_expr(&mem, reinterpret_cast<uint64_t>(expr.data()), expr.size());
  return dwarf_expr.Eval(&mem, regs, std::move(stack), result);
}

uint64_t Evaluate(const std::vector<uint8_t>& expr,
                  const std::map<RegisterID, uint64_t>& register_values = {},
                  std::vector<uint64_t> stack = {}) {
  uint64_t res;
  Error err = EvaluateWithError(expr, register_values, std::move(stack), res);
  EXPECT_TRUE(err.ok()) << err.msg();
  return res;
}

TEST(DwarfExpr, Const) {
  EXPECT_EQ(10u, Evaluate({}, {}, {10}));
  EXPECT_EQ(20u, Evaluate({DW_OP_lit20}));
  EXPECT_EQ(30u, Evaluate({DW_OP_const2s, 30, 0}));
  EXPECT_EQ(40u, Evaluate({DW_OP_constu, 40}));
}

TEST(DwarfExpr, Comparison) {
  EXPECT_EQ(0u, Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_eq}));
  EXPECT_EQ(1u, Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_le}));
  EXPECT_EQ(0u, Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_gt}));
}

TEST(DwarfExpr, Arithmetic) {
  // 1 + 1
  EXPECT_EQ(2u, Evaluate({DW_OP_lit1, DW_OP_plus}, {}, {1}));

  // 10 - (3 * 3) / 4
  EXPECT_EQ(8u, Evaluate({DW_OP_lit10, DW_OP_lit3, DW_OP_lit3, DW_OP_mul, DW_OP_lit4, DW_OP_div,
                          DW_OP_minus}));

  // 0 + 30 + 70
  EXPECT_EQ(100u, Evaluate({DW_OP_lit30, DW_OP_plus_uconst, 70, DW_OP_plus}, {}, {0}));

  // Invalid
  uint64_t res;
  EXPECT_TRUE(EvaluateWithError({DW_OP_eq}, {}, {0}, res).has_err());
}

TEST(DwarfExpr, StackOperations) {
  // Dup.
  EXPECT_EQ(3u, Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_dup}));

  // Swap and minus.
  EXPECT_EQ(1u, Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_swap, DW_OP_minus}));

  // Pick.
  EXPECT_EQ(1u, Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_pick, 2}));

  // Over.
  EXPECT_EQ(2u, Evaluate({DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_over}));

  // Stack too shallow.
  uint64_t res;
  EXPECT_TRUE(EvaluateWithError({DW_OP_drop}, {}, {0}, res).has_err());
}

TEST(DwarfExpr, Breg) {
  // breg18 - 8
  EXPECT_EQ(0x1000u, Evaluate({DW_OP_breg18, (-8) & 0x7f}, {{RegisterID::kArm64_x18, 0x1008}}));

  // *(breg0 + 0) & *(breg16 + 8)
  uint64_t data[] = {0xBEEF0812, 0xBEEF0724};
  EXPECT_EQ(0xBEEF0000u,
            Evaluate({DW_OP_breg0, 0, DW_OP_deref, DW_OP_breg16, 8, DW_OP_deref, DW_OP_and},
                     {
                         {RegisterID::kArm64_x0, reinterpret_cast<uint64_t>(data)},
                         {RegisterID::kArm64_x16, reinterpret_cast<uint64_t>(data)},
                     }));

  // breg3 not present.
  uint64_t res;
  EXPECT_TRUE(EvaluateWithError({DW_OP_breg3, 0}, {}, {0}, res).has_err());
}

TEST(DwarfExpr, ControlFlow) {
  // breg0 + 1 <= 1 ? breg1 + 0 : breg2 + 0
  std::vector<uint8_t> expr = {DW_OP_breg0, 1, DW_OP_lit1, DW_OP_le, DW_OP_bra, 5,           0,
                               DW_OP_breg2, 0, DW_OP_skip, 2,        0,         DW_OP_breg1, 0};
  EXPECT_EQ(10u, Evaluate(expr, {
                                    {RegisterID::kArm64_x0, 0},
                                    {RegisterID::kArm64_x1, 10},
                                    {RegisterID::kArm64_x2, 20},
                                }));
  EXPECT_EQ(20u, Evaluate(expr, {
                                    {RegisterID::kArm64_x0, 1},
                                    {RegisterID::kArm64_x1, 10},
                                    {RegisterID::kArm64_x2, 20},
                                }));

  // Condition with wrong offset.
  uint64_t res;
  EXPECT_TRUE(
      EvaluateWithError({DW_OP_bra, 3, 0, DW_OP_lit10, DW_OP_lit20}, {}, {1}, res).has_err());
}

}  // namespace

}  // namespace unwinder
