//===-- DWARFExpressionTest.cpp -------------------------------------------===//
//
// 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 "lldb/Expression/DWARFExpression.h"
#include "Plugins/Platform/Linux/PlatformLinux.h"
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/Symbol/YAMLModuleTester.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"

using namespace lldb_private;
using namespace lldb_private::dwarf;
using namespace lldb_private::plugin::dwarf;

static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
                                       lldb::ModuleSP module_sp = {},
                                       DWARFUnit *unit = nullptr,
                                       ExecutionContext *exe_ctx = nullptr) {
  DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
                          /*addr_size*/ 4);

  llvm::Expected<Value> result =
      DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp,
                                extractor, unit, lldb::eRegisterKindLLDB,
                                /*initial_value_ptr*/ nullptr,
                                /*object_address_ptr*/ nullptr);
  if (!result)
    return result.takeError();

  switch (result->GetValueType()) {
  case Value::ValueType::Scalar:
    return result->GetScalar();
  case Value::ValueType::LoadAddress:
    return LLDB_INVALID_ADDRESS;
  case Value::ValueType::HostAddress: {
    // Convert small buffers to scalars to simplify the tests.
    DataBufferHeap &buf = result->GetBuffer();
    if (buf.GetByteSize() <= 8) {
      uint64_t val = 0;
      memcpy(&val, buf.GetBytes(), buf.GetByteSize());
      return Scalar(llvm::APInt(buf.GetByteSize()*8, val, false));
    }
  }
    [[fallthrough]];
  default:
    break;
  }
  return llvm::createStringError("unsupported value type");
}

class DWARFExpressionTester : public YAMLModuleTester {
public:
  DWARFExpressionTester(llvm::StringRef yaml_data, size_t cu_index) :
      YAMLModuleTester(yaml_data, cu_index) {}

  using YAMLModuleTester::YAMLModuleTester;
  llvm::Expected<Scalar> Eval(llvm::ArrayRef<uint8_t> expr) {
    return ::Evaluate(expr, m_module_sp, m_dwarf_unit);
  }
};

/// Unfortunately Scalar's operator==() is really picky.
static Scalar GetScalar(unsigned bits, uint64_t value, bool sign) {
  Scalar scalar(value);
  scalar.TruncOrExtendTo(bits, sign);
  return scalar;
}

/// This is needed for the tests that use a mock process.
class DWARFExpressionMockProcessTest : public ::testing::Test {
public:
  void SetUp() override {
    FileSystem::Initialize();
    HostInfo::Initialize();
    platform_linux::PlatformLinux::Initialize();
  }
  void TearDown() override {
    platform_linux::PlatformLinux::Terminate();
    HostInfo::Terminate();
    FileSystem::Terminate();
  }
};

// NB: This class doesn't use the override keyword to avoid
// -Winconsistent-missing-override warnings from the compiler. The
// inconsistency comes from the overriding definitions in the MOCK_*** macros.
class MockTarget : public Target {
public:
  MockTarget(Debugger &debugger, const ArchSpec &target_arch,
             const lldb::PlatformSP &platform_sp)
      : Target(debugger, target_arch, platform_sp, true) {}

  MOCK_METHOD2(ReadMemory,
               llvm::Expected<std::vector<uint8_t>>(lldb::addr_t addr,
                                                    size_t size));

  size_t ReadMemory(const Address &addr, void *dst, size_t dst_len,
                    Status &error, bool force_live_memory = false,
                    lldb::addr_t *load_addr_ptr = nullptr) /*override*/ {
    auto expected_memory = this->ReadMemory(addr.GetOffset(), dst_len);
    if (!expected_memory) {
      llvm::consumeError(expected_memory.takeError());
      return 0;
    }
    const size_t bytes_read = expected_memory->size();
    assert(bytes_read <= dst_len);
    std::memcpy(dst, expected_memory->data(), bytes_read);
    return bytes_read;
  }
};

TEST(DWARFExpression, DW_OP_pick) {
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 0}),
                       llvm::HasValue(0));
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 1}),
                       llvm::HasValue(1));
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 2}),
                       llvm::Failed());
}

TEST(DWARFExpression, DW_OP_const) {
  // Extend to address size.
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1u, 0x88}), llvm::HasValue(0x88));
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1s, 0x88}),
                       llvm::HasValue(0xffffff88));
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x47, 0x88}),
                       llvm::HasValue(0x8847));
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2s, 0x47, 0x88}),
                       llvm::HasValue(0xffff8847));
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const4u, 0x44, 0x42, 0x47, 0x88}),
                       llvm::HasValue(0x88474244));
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const4s, 0x44, 0x42, 0x47, 0x88}),
                       llvm::HasValue(0x88474244));

  // Truncate to address size.
  EXPECT_THAT_EXPECTED(
      Evaluate({DW_OP_const8u, 0x00, 0x11, 0x22, 0x33, 0x44, 0x42, 0x47, 0x88}),
      llvm::HasValue(0x33221100));
  EXPECT_THAT_EXPECTED(
      Evaluate({DW_OP_const8s, 0x00, 0x11, 0x22, 0x33, 0x44, 0x42, 0x47, 0x88}),
      llvm::HasValue(0x33221100));

  // Don't truncate to address size for compatibility with clang (pr48087).
  EXPECT_THAT_EXPECTED(
      Evaluate({DW_OP_constu, 0x81, 0x82, 0x84, 0x88, 0x90, 0xa0, 0x40}),
      llvm::HasValue(0x01010101010101));
  EXPECT_THAT_EXPECTED(
      Evaluate({DW_OP_consts, 0x81, 0x82, 0x84, 0x88, 0x90, 0xa0, 0x40}),
      llvm::HasValue(0xffff010101010101));
}

TEST(DWARFExpression, DW_OP_skip) {
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1u, 0x42, DW_OP_skip, 0x02, 0x00,
                                 DW_OP_const1u, 0xff}),
                       llvm::HasValue(0x42));
}

TEST(DWARFExpression, DW_OP_bra) {
  EXPECT_THAT_EXPECTED(
      // clang-format off
      Evaluate({
        DW_OP_const1u, 0x42,     // push 0x42
        DW_OP_const1u, 0x1,      // push 0x1
        DW_OP_bra, 0x02, 0x00,   // if 0x1 > 0, then skip 0x0002 opcodes
        DW_OP_const1u, 0xff,     // push 0xff
      }),
      // clang-format on
      llvm::HasValue(0x42));
}

TEST(DWARFExpression, DW_OP_convert) {
  /// Auxiliary debug info.
  const char *yamldata = R"(
--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_EXEC
  Machine: EM_386
DWARF:
  debug_abbrev:
    - Table:
        - Code:            0x00000001
          Tag:             DW_TAG_compile_unit
          Children:        DW_CHILDREN_yes
          Attributes:
            - Attribute:       DW_AT_language
              Form:            DW_FORM_data2
        - Code:            0x00000002
          Tag:             DW_TAG_base_type
          Children:        DW_CHILDREN_no
          Attributes:
            - Attribute:       DW_AT_encoding
              Form:            DW_FORM_data1
            - Attribute:       DW_AT_byte_size
              Form:            DW_FORM_data1
  debug_info:
    - Version:         4
      AddrSize:        8
      AbbrevTableID:   0
      AbbrOffset:      0x0
      Entries:
        - AbbrCode:        0x00000001
          Values:
            - Value:           0x000000000000000C
        - AbbrCode:        0x00000000
    - Version:         4
      AddrSize:        8
      AbbrevTableID:   0
      AbbrOffset:      0x0
      Entries:
        - AbbrCode:        0x00000001
          Values:
            - Value:           0x000000000000000C
        # 0x0000000e:
        - AbbrCode:        0x00000002
          Values:
            - Value:           0x0000000000000007 # DW_ATE_unsigned
            - Value:           0x0000000000000004
        # 0x00000011:
        - AbbrCode:        0x00000002
          Values:
            - Value:           0x0000000000000007 # DW_ATE_unsigned
            - Value:           0x0000000000000008
        # 0x00000014:
        - AbbrCode:        0x00000002
          Values:
            - Value:           0x0000000000000005 # DW_ATE_signed
            - Value:           0x0000000000000008
        # 0x00000017:
        - AbbrCode:        0x00000002
          Values:
            - Value:           0x0000000000000008 # DW_ATE_unsigned_char
            - Value:           0x0000000000000001
        # 0x0000001a:
        - AbbrCode:        0x00000002
          Values:
            - Value:           0x0000000000000006 # DW_ATE_signed_char
            - Value:           0x0000000000000001
        # 0x0000001d:
        - AbbrCode:        0x00000002
          Values:
            - Value:           0x000000000000000b # DW_ATE_numeric_string
            - Value:           0x0000000000000001
        - AbbrCode:        0x00000000

)";
  // Compile unit relative offsets to each DW_TAG_base_type
  uint8_t offs_uint32_t = 0x0000000e;
  uint8_t offs_uint64_t = 0x00000011;
  uint8_t offs_sint64_t = 0x00000014;
  uint8_t offs_uchar = 0x00000017;
  uint8_t offs_schar = 0x0000001a;

  DWARFExpressionTester t(yamldata, /*cu_index=*/1);
  ASSERT_TRUE((bool)t.GetDwarfUnit());

  // Constant is given as little-endian.
  bool is_signed = true;
  bool not_signed = false;

  //
  // Positive tests.
  //

  // Leave as is.
  EXPECT_THAT_EXPECTED(
      t.Eval({DW_OP_const4u, 0x11, 0x22, 0x33, 0x44, //
              DW_OP_convert, offs_uint32_t, DW_OP_stack_value}),
      llvm::HasValue(GetScalar(64, 0x44332211, not_signed)));

  // Zero-extend to 64 bits.
  EXPECT_THAT_EXPECTED(
      t.Eval({DW_OP_const4u, 0x11, 0x22, 0x33, 0x44, //
              DW_OP_convert, offs_uint64_t, DW_OP_stack_value}),
      llvm::HasValue(GetScalar(64, 0x44332211, not_signed)));

  // Sign-extend to 64 bits.
  EXPECT_THAT_EXPECTED(
      t.Eval({DW_OP_const4s, 0xcc, 0xdd, 0xee, 0xff, //
              DW_OP_convert, offs_sint64_t, DW_OP_stack_value}),
      llvm::HasValue(GetScalar(64, 0xffffffffffeeddcc, is_signed)));

  // Sign-extend, then truncate.
  EXPECT_THAT_EXPECTED(
      t.Eval({DW_OP_const4s, 0xcc, 0xdd, 0xee, 0xff, //
              DW_OP_convert, offs_sint64_t,          //
              DW_OP_convert, offs_uint32_t, DW_OP_stack_value}),
      llvm::HasValue(GetScalar(32, 0xffeeddcc, not_signed)));

  // Truncate to default unspecified (pointer-sized) type.
  EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 0xcc, 0xdd, 0xee, 0xff, //
                               DW_OP_convert, offs_sint64_t,          //
                               DW_OP_convert, 0x00, DW_OP_stack_value}),
                       llvm::HasValue(GetScalar(32, 0xffeeddcc, not_signed)));

  // Truncate to 8 bits.
  EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', DW_OP_convert,
                               offs_uchar, DW_OP_stack_value}),
                       llvm::HasValue(GetScalar(8, 'A', not_signed)));

  // Also truncate to 8 bits.
  EXPECT_THAT_EXPECTED(t.Eval({DW_OP_const4s, 'A', 'B', 'C', 'D', DW_OP_convert,
                               offs_schar, DW_OP_stack_value}),
                       llvm::HasValue(GetScalar(8, 'A', is_signed)));

  //
  // Errors.
  //

  // No Module.
  EXPECT_THAT_ERROR(Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x00}, nullptr,
                             t.GetDwarfUnit())
                        .takeError(),
                    llvm::Failed());

  // No DIE.
  EXPECT_THAT_ERROR(
      t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x01}).takeError(),
      llvm::Failed());

  // Unsupported.
  EXPECT_THAT_ERROR(
      t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}).takeError(),
      llvm::Failed());
}

TEST(DWARFExpression, DW_OP_stack_value) {
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_stack_value}), llvm::Failed());
}

TEST(DWARFExpression, DW_OP_piece) {
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x11, 0x22, DW_OP_piece, 2,
                                 DW_OP_const2u, 0x33, 0x44, DW_OP_piece, 2}),
                       llvm::HasValue(GetScalar(32, 0x44332211, true)));
  EXPECT_THAT_EXPECTED(
      Evaluate({DW_OP_piece, 1, DW_OP_const1u, 0xff, DW_OP_piece, 1}),
      // Note that the "00" should really be "undef", but we can't
      // represent that yet.
      llvm::HasValue(GetScalar(16, 0xff00, true)));
}

TEST(DWARFExpression, DW_OP_implicit_value) {
  unsigned char bytes = 4;

  EXPECT_THAT_EXPECTED(
      Evaluate({DW_OP_implicit_value, bytes, 0x11, 0x22, 0x33, 0x44}),
      llvm::HasValue(GetScalar(8 * bytes, 0x44332211, true)));
}

TEST(DWARFExpression, DW_OP_unknown) {
  EXPECT_THAT_EXPECTED(
      Evaluate({0xff}),
      llvm::FailedWithMessage(
          "Unhandled opcode DW_OP_unknown_ff in DWARFExpression"));
}

TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_deref}), llvm::Failed());

  struct MockProcess : Process {
    MockProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
        : Process(target_sp, listener_sp) {}

    llvm::StringRef GetPluginName() override { return "mock process"; }
    bool CanDebug(lldb::TargetSP target,
                  bool plugin_specified_by_name) override {
      return false;
    };
    Status DoDestroy() override { return {}; }
    void RefreshStateAfterStop() override {}
    bool DoUpdateThreadList(ThreadList &old_thread_list,
                            ThreadList &new_thread_list) override {
      return false;
    };
    size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
                        Status &error) override {
      for (size_t i = 0; i < size; ++i)
        ((char *)buf)[i] = (vm_addr + i) & 0xff;
      error.Clear();
      return size;
    }
  };

  // Set up a mock process.
  ArchSpec arch("i386-pc-linux");
  Platform::SetHostPlatform(
      platform_linux::PlatformLinux::CreateInstance(true, &arch));
  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
  ASSERT_TRUE(debugger_sp);
  lldb::TargetSP target_sp;
  lldb::PlatformSP platform_sp;
  debugger_sp->GetTargetList().CreateTarget(
      *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp);
  ASSERT_TRUE(target_sp);
  ASSERT_TRUE(target_sp->GetArchitecture().IsValid());
  ASSERT_TRUE(platform_sp);
  lldb::ListenerSP listener_sp(Listener::MakeListener("dummy"));
  lldb::ProcessSP process_sp =
      std::make_shared<MockProcess>(target_sp, listener_sp);
  ASSERT_TRUE(process_sp);

  ExecutionContext exe_ctx(process_sp);
  // Implicit location: *0x4.
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value},
                                {}, {}, &exe_ctx),
                       llvm::HasValue(GetScalar(32, 0x07060504, false)));
  // Memory location: *(*0x4).
  // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses.
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4, DW_OP_deref}, {}, {}, &exe_ctx),
                       llvm::HasValue(Scalar(LLDB_INVALID_ADDRESS)));
  // Memory location: *0x4.
  // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses.
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4}, {}, {}, &exe_ctx),
                       llvm::HasValue(Scalar(4)));
  // Implicit location: *0x4.
  // Evaluate returns LLDB_INVALID_ADDRESS for all load addresses.
  EXPECT_THAT_EXPECTED(
      Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx),
      llvm::HasValue(GetScalar(32, 0x07060504, false)));
}

TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr) {
  // Set up a wasm target
  ArchSpec arch("wasm32-unknown-unknown-wasm");
  lldb::PlatformSP host_platform_sp =
      platform_linux::PlatformLinux::CreateInstance(true, &arch);
  ASSERT_TRUE(host_platform_sp);
  Platform::SetHostPlatform(host_platform_sp);
  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
  ASSERT_TRUE(debugger_sp);
  lldb::TargetSP target_sp;
  lldb::PlatformSP platform_sp;
  debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
                                            lldb_private::eLoadDependentsNo,
                                            platform_sp, target_sp);

  ExecutionContext exe_ctx(target_sp, false);
  // DW_OP_addr takes a single operand of address size width:
  uint8_t expr[] = {DW_OP_addr, 0x40, 0x0, 0x0, 0x0};
  DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
                          /*addr_size*/ 4);

  llvm::Expected<Value> result = DWARFExpression::Evaluate(
      &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
      /*unit*/ nullptr, lldb::eRegisterKindLLDB,
      /*initial_value_ptr*/ nullptr,
      /*object_address_ptr*/ nullptr);

  ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
  ASSERT_EQ(result->GetValueType(), Value::ValueType::LoadAddress);
}

TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
  const char *yamldata = R"(
--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_EXEC
  Machine: EM_386
DWARF:
  debug_abbrev:
    - Table:
        - Code:            0x00000001
          Tag:             DW_TAG_compile_unit
          Children:        DW_CHILDREN_no
          Attributes:
            - Attribute:       DW_AT_addr_base
              Form:            DW_FORM_sec_offset

  debug_info:
    - Version:         5
      AddrSize:        4
      UnitType:        DW_UT_compile
      Entries:
        - AbbrCode:        0x00000001
          Values:
            - Value:           0x8 # Offset of the first Address past the header
        - AbbrCode:        0x0

  debug_addr:
    - Version: 5
      AddressSize: 4
      Entries:
        - Address: 0x1234
        - Address: 0x5678
)";

  // Can't use DWARFExpressionTester from above because subsystems overlap with
  // the fixture.
  SubsystemRAII<ObjectFileELF, SymbolFileDWARF> subsystems;
  llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
  EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
  auto module_sp = std::make_shared<Module>(file->moduleSpec());
  auto *dwarf_cu = llvm::cast<SymbolFileDWARF>(module_sp->GetSymbolFile())
                       ->DebugInfo()
                       .GetUnitAtIndex(0);
  ASSERT_TRUE(dwarf_cu);
  dwarf_cu->ExtractDIEsIfNeeded();

  // Set up a wasm target
  ArchSpec arch("wasm32-unknown-unknown-wasm");
  lldb::PlatformSP host_platform_sp =
      platform_linux::PlatformLinux::CreateInstance(true, &arch);
  ASSERT_TRUE(host_platform_sp);
  Platform::SetHostPlatform(host_platform_sp);
  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
  ASSERT_TRUE(debugger_sp);
  lldb::TargetSP target_sp;
  lldb::PlatformSP platform_sp;
  debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
                                            lldb_private::eLoadDependentsNo,
                                            platform_sp, target_sp);

  ExecutionContext exe_ctx(target_sp, false);

  auto evaluate = [&](DWARFExpression &expr) -> llvm::Expected<Value> {
    DataExtractor extractor;
    expr.GetExpressionData(extractor);
    return DWARFExpression::Evaluate(&exe_ctx, /*reg_ctx*/ nullptr,
                                     /*module_sp*/ {}, extractor, dwarf_cu,
                                     lldb::eRegisterKindLLDB,
                                     /*initial_value_ptr*/ nullptr,
                                     /*object_address_ptr*/ nullptr);
  };

  // DW_OP_addrx takes a single leb128 operand, the index in the addr table:
  uint8_t expr_data[] = {DW_OP_addrx, 0x01};
  DataExtractor extractor(expr_data, sizeof(expr_data), lldb::eByteOrderLittle,
                          /*addr_size*/ 4);
  DWARFExpression expr(extractor);

  llvm::Expected<Value> result = evaluate(expr);
  ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
  ASSERT_EQ(result->GetValueType(), Value::ValueType::LoadAddress);
  ASSERT_EQ(result->GetScalar().UInt(), 0x5678u);

  ASSERT_TRUE(expr.Update_DW_OP_addr(dwarf_cu, 0xdeadbeef));
  result = evaluate(expr);
  ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
  ASSERT_EQ(result->GetValueType(), Value::ValueType::LoadAddress);
  ASSERT_EQ(result->GetScalar().UInt(), 0xdeadbeefu);
}

class CustomSymbolFileDWARF : public SymbolFileDWARF {
  static char ID;

public:
  using SymbolFileDWARF::SymbolFileDWARF;

  bool isA(const void *ClassID) const override {
    return ClassID == &ID || SymbolFile::isA(ClassID);
  }
  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }

  static llvm::StringRef GetPluginNameStatic() { return "custom_dwarf"; }

  static llvm::StringRef GetPluginDescriptionStatic() {
    return "Symbol file reader with expression extensions.";
  }

  static void Initialize() {
    PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                  GetPluginDescriptionStatic(), CreateInstance,
                                  SymbolFileDWARF::DebuggerInitialize);
  }

  static void Terminate() { PluginManager::UnregisterPlugin(CreateInstance); }

  static lldb_private::SymbolFile *
  CreateInstance(lldb::ObjectFileSP objfile_sp) {
    return new CustomSymbolFileDWARF(std::move(objfile_sp),
                                     /*dwo_section_list*/ nullptr);
  }

  lldb::offset_t
  GetVendorDWARFOpcodeSize(const lldb_private::DataExtractor &data,
                           const lldb::offset_t data_offset,
                           const uint8_t op) const final {
    auto offset = data_offset;
    if (op != DW_OP_WASM_location) {
      return LLDB_INVALID_OFFSET;
    }

    // DW_OP_WASM_location WASM_GLOBAL:0x03 index:u32
    // Called with "arguments" 0x03 and 0x04
    // Location type:
    if (data.GetU8(&offset) != /* global */ 0x03) {
      return LLDB_INVALID_OFFSET;
    }

    // Index
    if (data.GetU32(&offset) != 0x04) {
      return LLDB_INVALID_OFFSET;
    }

    // Report the skipped distance:
    return offset - data_offset;
  }

  bool
  ParseVendorDWARFOpcode(uint8_t op, const lldb_private::DataExtractor &opcodes,
                         lldb::offset_t &offset,
                         std::vector<lldb_private::Value> &stack) const final {
    if (op != DW_OP_WASM_location) {
      return false;
    }

    // DW_OP_WASM_location WASM_GLOBAL:0x03 index:u32
    // Called with "arguments" 0x03 and  0x04
    // Location type:
    if (opcodes.GetU8(&offset) != /* global */ 0x03) {
      return false;
    }

    // Index:
    if (opcodes.GetU32(&offset) != 0x04) {
      return false;
    }

    // Return some value:
    stack.push_back({GetScalar(32, 42, false)});
    return true;
  }
};

char CustomSymbolFileDWARF::ID;

static auto testExpressionVendorExtensions(lldb::ModuleSP module_sp,
                                           DWARFUnit &dwarf_unit) {
  // Test that expression extensions can be evaluated, for example
  // DW_OP_WASM_location which is not currently handled by DWARFExpression:
  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_WASM_location, 0x03, // WASM_GLOBAL:0x03
                                 0x04, 0x00, 0x00,          // index:u32
                                 0x00, DW_OP_stack_value},
                                module_sp, &dwarf_unit),
                       llvm::HasValue(GetScalar(32, 42, false)));

  // Test that searches for opcodes work in the presence of extensions:
  uint8_t expr[] = {DW_OP_WASM_location,   0x03, 0x04, 0x00, 0x00, 0x00,
                    DW_OP_form_tls_address};
  DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
                          /*addr_size*/ 4);
  DWARFExpression dwarf_expr(extractor);
  ASSERT_TRUE(dwarf_expr.ContainsThreadLocalStorage(&dwarf_unit));
}

TEST(DWARFExpression, Extensions) {
  const char *yamldata = R"(
--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_EXEC
  Machine: EM_386
DWARF:
  debug_abbrev:
    - Table:
        - Code:            0x00000001
          Tag:             DW_TAG_compile_unit
          Children:        DW_CHILDREN_no
  debug_info:
    - Version:         4
      AddrSize:        4
      Entries:
        - AbbrCode:        0x1
        - AbbrCode:        0x0
)";

  SubsystemRAII<FileSystem, HostInfo, TypeSystemClang, ObjectFileELF,
                CustomSymbolFileDWARF>
      subsystems;

  llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
  EXPECT_THAT_EXPECTED(file, llvm::Succeeded());

  auto module_sp = std::make_shared<Module>(file->moduleSpec());
  auto &symfile =
      *llvm::cast<CustomSymbolFileDWARF>(module_sp->GetSymbolFile());
  auto *dwarf_unit = symfile.DebugInfo().GetUnitAtIndex(0);

  testExpressionVendorExtensions(module_sp, *dwarf_unit);
}

TEST(DWARFExpression, ExtensionsDWO) {
  const char *skeleton_yamldata = R"(
--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_EXEC
  Machine: EM_386
DWARF:
  debug_abbrev:
    - Table:
        - Code:            0x00000001
          Tag:             DW_TAG_skeleton_unit
          Children:        DW_CHILDREN_no
          Attributes:
            - Attribute:       DW_AT_dwo_name
              Form:            DW_FORM_string
            - Attribute:       DW_AT_dwo_id
              Form:            DW_FORM_data4
  debug_info:
    - Version:         4
      AddrSize:        4
      Entries:
        - AbbrCode:        0x1
          Values:
            - CStr:           "dwo_unit"
            - Value:           0x01020304
        - AbbrCode:        0x0
)";

  // .dwo sections aren't currently supported by dwarfyaml. The dwo_yamldata
  // contents where generated by roundtripping the following yaml through
  // yaml2obj | obj2yaml and renaming the sections. This works because the
  // structure of the .dwo and non-.dwo sections is identical.
  //
  // --- !ELF
  // FileHeader:
  //   Class:   ELFCLASS64
  //   Data:    ELFDATA2LSB
  //   Type:    ET_EXEC
  //   Machine: EM_386
  // DWARF:
  //   debug_abbrev: #.dwo
  //     - Table:
  //         - Code:            0x00000001
  //           Tag:             DW_TAG_compile_unit
  //           Children:        DW_CHILDREN_no
  //           Attributes:
  //             - Attribute:       DW_AT_dwo_id
  //               Form:            DW_FORM_data4
  //   debug_info: #.dwo
  //     - Version:         4
  //       AddrSize:        4
  //       Entries:
  //         - AbbrCode:        0x1
  //           Values:
  //             - Value:           0x0120304
  //         - AbbrCode:        0x0
  const char *dwo_yamldata = R"(
--- !ELF
FileHeader:
  Class:           ELFCLASS64
  Data:            ELFDATA2LSB
  Type:            ET_EXEC
  Machine:         EM_386
Sections:
  - Name:            .debug_abbrev.dwo
    Type:            SHT_PROGBITS
    AddressAlign:    0x1
    Content:         '0111007506000000'
  - Name:            .debug_info.dwo
    Type:            SHT_PROGBITS
    AddressAlign:    0x1
    Content:         0D00000004000000000004010403020100
)";

  SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, CustomSymbolFileDWARF>
      subsystems;

  llvm::Expected<TestFile> skeleton_file =
      TestFile::fromYaml(skeleton_yamldata);
  EXPECT_THAT_EXPECTED(skeleton_file, llvm::Succeeded());
  llvm::Expected<TestFile> dwo_file = TestFile::fromYaml(dwo_yamldata);
  EXPECT_THAT_EXPECTED(dwo_file, llvm::Succeeded());

  auto skeleton_module_sp =
      std::make_shared<Module>(skeleton_file->moduleSpec());
  auto &skeleton_symfile =
      *llvm::cast<CustomSymbolFileDWARF>(skeleton_module_sp->GetSymbolFile());

  auto dwo_module_sp = std::make_shared<Module>(dwo_file->moduleSpec());
  SymbolFileDWARFDwo dwo_symfile(
      skeleton_symfile, dwo_module_sp->GetObjectFile()->shared_from_this(),
      0x0120304);
  auto *dwo_dwarf_unit = dwo_symfile.DebugInfo().GetUnitAtIndex(0);

  testExpressionVendorExtensions(dwo_module_sp, *dwo_dwarf_unit);
}

TEST_F(DWARFExpressionMockProcessTest, DW_OP_piece_file_addr) {
  using ::testing::ByMove;
  using ::testing::ElementsAre;
  using ::testing::Return;

  // Set up a mock process.
  ArchSpec arch("i386-pc-linux");
  Platform::SetHostPlatform(
      platform_linux::PlatformLinux::CreateInstance(true, &arch));
  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
  ASSERT_TRUE(debugger_sp);
  lldb::PlatformSP platform_sp;
  auto target_sp =
      std::make_shared<MockTarget>(*debugger_sp, arch, platform_sp);
  ASSERT_TRUE(target_sp);
  ASSERT_TRUE(target_sp->GetArchitecture().IsValid());

  EXPECT_CALL(*target_sp, ReadMemory(0x40, 1))
      .WillOnce(Return(ByMove(std::vector<uint8_t>{0x11})));
  EXPECT_CALL(*target_sp, ReadMemory(0x50, 1))
      .WillOnce(Return(ByMove(std::vector<uint8_t>{0x22})));

  ExecutionContext exe_ctx(static_cast<lldb::TargetSP>(target_sp), false);

  uint8_t expr[] = {DW_OP_addr, 0x40, 0x0, 0x0, 0x0, DW_OP_piece, 1,
                    DW_OP_addr, 0x50, 0x0, 0x0, 0x0, DW_OP_piece, 1};
  DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
                          /*addr_size*/ 4);
  llvm::Expected<Value> result = DWARFExpression::Evaluate(
      &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
      /*unit*/ nullptr, lldb::eRegisterKindLLDB,
      /*initial_value_ptr*/ nullptr,
      /*object_address_ptr*/ nullptr);

  ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
  ASSERT_EQ(result->GetValueType(), Value::ValueType::HostAddress);
  ASSERT_THAT(result->GetBuffer().GetData(), ElementsAre(0x11, 0x22));
}
