//===-- DWARFExpression.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 <cinttypes>

#include <optional>
#include <vector>

#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Utility/DataEncoder.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/VMRange.h"

#include "lldb/Host/Host.h"
#include "lldb/Utility/Endian.h"

#include "lldb/Symbol/Function.h"

#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StackID.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"

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

// DWARFExpression constructor
DWARFExpression::DWARFExpression() : m_data() {}

DWARFExpression::DWARFExpression(const DataExtractor &data) : m_data(data) {}

// Destructor
DWARFExpression::~DWARFExpression() = default;

bool DWARFExpression::IsValid() const { return m_data.GetByteSize() > 0; }

void DWARFExpression::UpdateValue(uint64_t const_value,
                                  lldb::offset_t const_value_byte_size,
                                  uint8_t addr_byte_size) {
  if (!const_value_byte_size)
    return;

  m_data.SetData(
      DataBufferSP(new DataBufferHeap(&const_value, const_value_byte_size)));
  m_data.SetByteOrder(endian::InlHostByteOrder());
  m_data.SetAddressByteSize(addr_byte_size);
}

void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
                                   ABI *abi) const {
  auto *MCRegInfo = abi ? &abi->GetMCRegisterInfo() : nullptr;
  auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum,
                                 bool IsEH) -> llvm::StringRef {
    if (!MCRegInfo)
      return {};
    if (std::optional<unsigned> LLVMRegNum =
            MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))
      if (const char *RegName = MCRegInfo->getName(*LLVMRegNum))
        return llvm::StringRef(RegName);
    return {};
  };
  llvm::DIDumpOptions DumpOpts;
  DumpOpts.GetNameForDWARFReg = GetRegName;
  llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
  llvm::printDwarfExpression(&E, s->AsRawOstream(), DumpOpts, nullptr);
}

RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }

void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {
  m_reg_kind = reg_kind;
}

static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
                                             lldb::RegisterKind reg_kind,
                                             uint32_t reg_num, Value &value) {
  if (reg_ctx == nullptr)
    return llvm::createStringError("no register context in frame");

  const uint32_t native_reg =
      reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
  if (native_reg == LLDB_INVALID_REGNUM)
    return llvm::createStringError(
        "unable to convert register kind=%u reg_num=%u to a native "
        "register number",
        reg_kind, reg_num);

  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(native_reg);
  RegisterValue reg_value;
  if (reg_ctx->ReadRegister(reg_info, reg_value)) {
    if (reg_value.GetScalarValue(value.GetScalar())) {
      value.SetValueType(Value::ValueType::Scalar);
      value.SetContext(Value::ContextType::RegisterInfo,
                       const_cast<RegisterInfo *>(reg_info));
      return llvm::Error::success();
    }

    // If we get this error, then we need to implement a value buffer in
    // the dwarf expression evaluation function...
    return llvm::createStringError(
        "register %s can't be converted to a scalar value", reg_info->name);
  }

  return llvm::createStringError("register %s is not available",
                                 reg_info->name);
}

/// Return the length in bytes of the set of operands for \p op. No guarantees
/// are made on the state of \p data after this call.
static lldb::offset_t
GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset,
                  const LocationAtom op,
                  const DWARFExpression::Delegate *dwarf_cu) {
  lldb::offset_t offset = data_offset;
  switch (op) {
  // Only used in LLVM metadata.
  case DW_OP_LLVM_fragment:
  case DW_OP_LLVM_convert:
  case DW_OP_LLVM_tag_offset:
  case DW_OP_LLVM_entry_value:
  case DW_OP_LLVM_implicit_pointer:
  case DW_OP_LLVM_arg:
  case DW_OP_LLVM_extract_bits_sext:
  case DW_OP_LLVM_extract_bits_zext:
    break;
  // Vendor extensions:
  case DW_OP_HP_is_value:
  case DW_OP_HP_fltconst4:
  case DW_OP_HP_fltconst8:
  case DW_OP_HP_mod_range:
  case DW_OP_HP_unmod_range:
  case DW_OP_HP_tls:
  case DW_OP_INTEL_bit_piece:
  case DW_OP_WASM_location:
  case DW_OP_WASM_location_int:
  case DW_OP_APPLE_uninit:
  case DW_OP_PGI_omp_thread_num:
  case DW_OP_hi_user:
  case DW_OP_GNU_implicit_pointer:
    break;

  case DW_OP_addr:
  case DW_OP_call_ref: // 0x9a 1 address sized offset of DIE (DWARF3)
    return data.GetAddressByteSize();

  // Opcodes with no arguments
  case DW_OP_deref:                // 0x06
  case DW_OP_dup:                  // 0x12
  case DW_OP_drop:                 // 0x13
  case DW_OP_over:                 // 0x14
  case DW_OP_swap:                 // 0x16
  case DW_OP_rot:                  // 0x17
  case DW_OP_xderef:               // 0x18
  case DW_OP_abs:                  // 0x19
  case DW_OP_and:                  // 0x1a
  case DW_OP_div:                  // 0x1b
  case DW_OP_minus:                // 0x1c
  case DW_OP_mod:                  // 0x1d
  case DW_OP_mul:                  // 0x1e
  case DW_OP_neg:                  // 0x1f
  case DW_OP_not:                  // 0x20
  case DW_OP_or:                   // 0x21
  case DW_OP_plus:                 // 0x22
  case DW_OP_shl:                  // 0x24
  case DW_OP_shr:                  // 0x25
  case DW_OP_shra:                 // 0x26
  case DW_OP_xor:                  // 0x27
  case DW_OP_eq:                   // 0x29
  case DW_OP_ge:                   // 0x2a
  case DW_OP_gt:                   // 0x2b
  case DW_OP_le:                   // 0x2c
  case DW_OP_lt:                   // 0x2d
  case DW_OP_ne:                   // 0x2e
  case DW_OP_lit0:                 // 0x30
  case DW_OP_lit1:                 // 0x31
  case DW_OP_lit2:                 // 0x32
  case DW_OP_lit3:                 // 0x33
  case DW_OP_lit4:                 // 0x34
  case DW_OP_lit5:                 // 0x35
  case DW_OP_lit6:                 // 0x36
  case DW_OP_lit7:                 // 0x37
  case DW_OP_lit8:                 // 0x38
  case DW_OP_lit9:                 // 0x39
  case DW_OP_lit10:                // 0x3A
  case DW_OP_lit11:                // 0x3B
  case DW_OP_lit12:                // 0x3C
  case DW_OP_lit13:                // 0x3D
  case DW_OP_lit14:                // 0x3E
  case DW_OP_lit15:                // 0x3F
  case DW_OP_lit16:                // 0x40
  case DW_OP_lit17:                // 0x41
  case DW_OP_lit18:                // 0x42
  case DW_OP_lit19:                // 0x43
  case DW_OP_lit20:                // 0x44
  case DW_OP_lit21:                // 0x45
  case DW_OP_lit22:                // 0x46
  case DW_OP_lit23:                // 0x47
  case DW_OP_lit24:                // 0x48
  case DW_OP_lit25:                // 0x49
  case DW_OP_lit26:                // 0x4A
  case DW_OP_lit27:                // 0x4B
  case DW_OP_lit28:                // 0x4C
  case DW_OP_lit29:                // 0x4D
  case DW_OP_lit30:                // 0x4E
  case DW_OP_lit31:                // 0x4f
  case DW_OP_reg0:                 // 0x50
  case DW_OP_reg1:                 // 0x51
  case DW_OP_reg2:                 // 0x52
  case DW_OP_reg3:                 // 0x53
  case DW_OP_reg4:                 // 0x54
  case DW_OP_reg5:                 // 0x55
  case DW_OP_reg6:                 // 0x56
  case DW_OP_reg7:                 // 0x57
  case DW_OP_reg8:                 // 0x58
  case DW_OP_reg9:                 // 0x59
  case DW_OP_reg10:                // 0x5A
  case DW_OP_reg11:                // 0x5B
  case DW_OP_reg12:                // 0x5C
  case DW_OP_reg13:                // 0x5D
  case DW_OP_reg14:                // 0x5E
  case DW_OP_reg15:                // 0x5F
  case DW_OP_reg16:                // 0x60
  case DW_OP_reg17:                // 0x61
  case DW_OP_reg18:                // 0x62
  case DW_OP_reg19:                // 0x63
  case DW_OP_reg20:                // 0x64
  case DW_OP_reg21:                // 0x65
  case DW_OP_reg22:                // 0x66
  case DW_OP_reg23:                // 0x67
  case DW_OP_reg24:                // 0x68
  case DW_OP_reg25:                // 0x69
  case DW_OP_reg26:                // 0x6A
  case DW_OP_reg27:                // 0x6B
  case DW_OP_reg28:                // 0x6C
  case DW_OP_reg29:                // 0x6D
  case DW_OP_reg30:                // 0x6E
  case DW_OP_reg31:                // 0x6F
  case DW_OP_nop:                  // 0x96
  case DW_OP_push_object_address:  // 0x97 DWARF3
  case DW_OP_form_tls_address:     // 0x9b DWARF3
  case DW_OP_call_frame_cfa:       // 0x9c DWARF3
  case DW_OP_stack_value:          // 0x9f DWARF4
  case DW_OP_GNU_push_tls_address: // 0xe0 GNU extension
    return 0;

  // Opcodes with a single 1 byte arguments
  case DW_OP_const1u:     // 0x08 1 1-byte constant
  case DW_OP_const1s:     // 0x09 1 1-byte constant
  case DW_OP_pick:        // 0x15 1 1-byte stack index
  case DW_OP_deref_size:  // 0x94 1 1-byte size of data retrieved
  case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved
  case DW_OP_deref_type:  // 0xa6 1 1-byte constant
    return 1;

  // Opcodes with a single 2 byte arguments
  case DW_OP_const2u: // 0x0a 1 2-byte constant
  case DW_OP_const2s: // 0x0b 1 2-byte constant
  case DW_OP_skip:    // 0x2f 1 signed 2-byte constant
  case DW_OP_bra:     // 0x28 1 signed 2-byte constant
  case DW_OP_call2:   // 0x98 1 2-byte offset of DIE (DWARF3)
    return 2;

  // Opcodes with a single 4 byte arguments
  case DW_OP_const4u: // 0x0c 1 4-byte constant
  case DW_OP_const4s: // 0x0d 1 4-byte constant
  case DW_OP_call4:   // 0x99 1 4-byte offset of DIE (DWARF3)
    return 4;

  // Opcodes with a single 8 byte arguments
  case DW_OP_const8u: // 0x0e 1 8-byte constant
  case DW_OP_const8s: // 0x0f 1 8-byte constant
    return 8;

  // All opcodes that have a single ULEB (signed or unsigned) argument
  case DW_OP_constu:          // 0x10 1 ULEB128 constant
  case DW_OP_consts:          // 0x11 1 SLEB128 constant
  case DW_OP_plus_uconst:     // 0x23 1 ULEB128 addend
  case DW_OP_breg0:           // 0x70 1 ULEB128 register
  case DW_OP_breg1:           // 0x71 1 ULEB128 register
  case DW_OP_breg2:           // 0x72 1 ULEB128 register
  case DW_OP_breg3:           // 0x73 1 ULEB128 register
  case DW_OP_breg4:           // 0x74 1 ULEB128 register
  case DW_OP_breg5:           // 0x75 1 ULEB128 register
  case DW_OP_breg6:           // 0x76 1 ULEB128 register
  case DW_OP_breg7:           // 0x77 1 ULEB128 register
  case DW_OP_breg8:           // 0x78 1 ULEB128 register
  case DW_OP_breg9:           // 0x79 1 ULEB128 register
  case DW_OP_breg10:          // 0x7a 1 ULEB128 register
  case DW_OP_breg11:          // 0x7b 1 ULEB128 register
  case DW_OP_breg12:          // 0x7c 1 ULEB128 register
  case DW_OP_breg13:          // 0x7d 1 ULEB128 register
  case DW_OP_breg14:          // 0x7e 1 ULEB128 register
  case DW_OP_breg15:          // 0x7f 1 ULEB128 register
  case DW_OP_breg16:          // 0x80 1 ULEB128 register
  case DW_OP_breg17:          // 0x81 1 ULEB128 register
  case DW_OP_breg18:          // 0x82 1 ULEB128 register
  case DW_OP_breg19:          // 0x83 1 ULEB128 register
  case DW_OP_breg20:          // 0x84 1 ULEB128 register
  case DW_OP_breg21:          // 0x85 1 ULEB128 register
  case DW_OP_breg22:          // 0x86 1 ULEB128 register
  case DW_OP_breg23:          // 0x87 1 ULEB128 register
  case DW_OP_breg24:          // 0x88 1 ULEB128 register
  case DW_OP_breg25:          // 0x89 1 ULEB128 register
  case DW_OP_breg26:          // 0x8a 1 ULEB128 register
  case DW_OP_breg27:          // 0x8b 1 ULEB128 register
  case DW_OP_breg28:          // 0x8c 1 ULEB128 register
  case DW_OP_breg29:          // 0x8d 1 ULEB128 register
  case DW_OP_breg30:          // 0x8e 1 ULEB128 register
  case DW_OP_breg31:          // 0x8f 1 ULEB128 register
  case DW_OP_regx:            // 0x90 1 ULEB128 register
  case DW_OP_fbreg:           // 0x91 1 SLEB128 offset
  case DW_OP_piece:           // 0x93 1 ULEB128 size of piece addressed
  case DW_OP_convert:         // 0xa8 1 ULEB128 offset
  case DW_OP_reinterpret:     // 0xa9 1 ULEB128 offset
  case DW_OP_addrx:           // 0xa1 1 ULEB128 index
  case DW_OP_constx:          // 0xa2 1 ULEB128 index
  case DW_OP_xderef_type:     // 0xa7 1 ULEB128 index
  case DW_OP_GNU_addr_index:  // 0xfb 1 ULEB128 index
  case DW_OP_GNU_const_index: // 0xfc 1 ULEB128 index
    data.Skip_LEB128(&offset);
    return offset - data_offset;

  // All opcodes that have a 2 ULEB (signed or unsigned) arguments
  case DW_OP_bregx:       // 0x92 2 ULEB128 register followed by SLEB128 offset
  case DW_OP_bit_piece:   // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
  case DW_OP_regval_type: // 0xa5 ULEB128 + ULEB128
    data.Skip_LEB128(&offset);
    data.Skip_LEB128(&offset);
    return offset - data_offset;

  case DW_OP_implicit_value: // 0x9e ULEB128 size followed by block of that size
                             // (DWARF4)
  {
    uint64_t block_len = data.Skip_LEB128(&offset);
    offset += block_len;
    return offset - data_offset;
  }

  case DW_OP_implicit_pointer: // 0xa0 4-byte (or 8-byte for DWARF 64) constant
                               // + LEB128
  {
    data.Skip_LEB128(&offset);
    return (dwarf_cu ? dwarf_cu->GetAddressByteSize() : 4) + offset -
           data_offset;
  }

  case DW_OP_GNU_entry_value:
  case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block
  {
    uint64_t subexpr_len = data.GetULEB128(&offset);
    return (offset - data_offset) + subexpr_len;
  }

  case DW_OP_const_type: // 0xa4 ULEB128 + size + variable-length block
  {
    data.Skip_LEB128(&offset);
    uint8_t length = data.GetU8(&offset);
    return (offset - data_offset) + length;
  }

  case DW_OP_LLVM_user: // 0xe9: ULEB128 + variable length constant
  {
    uint64_t constants = data.GetULEB128(&offset);
    return (offset - data_offset) + constants;
  }
  }

  if (dwarf_cu)
    return dwarf_cu->GetVendorDWARFOpcodeSize(data, data_offset, op);

  return LLDB_INVALID_OFFSET;
}

static const char *DW_OP_value_to_name(uint32_t val) {
  static char invalid[100];
  llvm::StringRef llvmstr = llvm::dwarf::OperationEncodingString(val);
  if (llvmstr.empty()) {
    snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
    return invalid;
  }
  return llvmstr.data();
}

llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
    const DWARFExpression::Delegate *dwarf_cu) const {
  lldb::offset_t offset = 0;
  while (m_data.ValidOffset(offset)) {
    const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));

    if (op == DW_OP_addr)
      return m_data.GetAddress(&offset);

    if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {
      const uint64_t index = m_data.GetULEB128(&offset);
      if (dwarf_cu)
        return dwarf_cu->ReadAddressFromDebugAddrSection(index);
      return llvm::createStringError("cannot evaluate %s without a DWARF unit",
                                     DW_OP_value_to_name(op));
    }

    const lldb::offset_t op_arg_size =
        GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
    if (op_arg_size == LLDB_INVALID_OFFSET)
      return llvm::createStringError("cannot get opcode data size for %s",
                                     DW_OP_value_to_name(op));

    offset += op_arg_size;
  }

  return LLDB_INVALID_ADDRESS;
}

bool DWARFExpression::Update_DW_OP_addr(
    const DWARFExpression::Delegate *dwarf_cu, lldb::addr_t file_addr) {
  lldb::offset_t offset = 0;
  while (m_data.ValidOffset(offset)) {
    const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));

    if (op == DW_OP_addr) {
      const uint32_t addr_byte_size = m_data.GetAddressByteSize();
      // We have to make a copy of the data as we don't know if this data is
      // from a read only memory mapped buffer, so we duplicate all of the data
      // first, then modify it, and if all goes well, we then replace the data
      // for this expression

      // Make en encoder that contains a copy of the location expression data
      // so we can write the address into the buffer using the correct byte
      // order.
      DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
                          m_data.GetByteOrder(), addr_byte_size);

      // Replace the address in the new buffer
      if (encoder.PutAddress(offset, file_addr) == UINT32_MAX)
        return false;

      // All went well, so now we can reset the data using a shared pointer to
      // the heap data so "m_data" will now correctly manage the heap data.
      m_data.SetData(encoder.GetDataBuffer());
      return true;
    }
    if (op == DW_OP_addrx) {
      // Replace DW_OP_addrx with DW_OP_addr, since we can't modify the
      // read-only debug_addr table.
      // Subtract one to account for the opcode.
      llvm::ArrayRef data_before_op = m_data.GetData().take_front(offset - 1);

      // Read the addrx index to determine how many bytes it needs.
      const lldb::offset_t old_offset = offset;
      m_data.GetULEB128(&offset);
      if (old_offset == offset)
        return false;
      llvm::ArrayRef data_after_op = m_data.GetData().drop_front(offset);

      DataEncoder encoder(m_data.GetByteOrder(), m_data.GetAddressByteSize());
      encoder.AppendData(data_before_op);
      encoder.AppendU8(DW_OP_addr);
      encoder.AppendAddress(file_addr);
      encoder.AppendData(data_after_op);
      m_data.SetData(encoder.GetDataBuffer());
      return true;
    }
    const lldb::offset_t op_arg_size =
        GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
    if (op_arg_size == LLDB_INVALID_OFFSET)
      break;
    offset += op_arg_size;
  }
  return false;
}

bool DWARFExpression::ContainsThreadLocalStorage(
    const DWARFExpression::Delegate *dwarf_cu) const {
  lldb::offset_t offset = 0;
  while (m_data.ValidOffset(offset)) {
    const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));

    if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address)
      return true;
    const lldb::offset_t op_arg_size =
        GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
    if (op_arg_size == LLDB_INVALID_OFFSET)
      return false;
    offset += op_arg_size;
  }
  return false;
}
bool DWARFExpression::LinkThreadLocalStorage(
    const DWARFExpression::Delegate *dwarf_cu,
    std::function<lldb::addr_t(lldb::addr_t file_addr)> const
        &link_address_callback) {
  const uint32_t addr_byte_size = m_data.GetAddressByteSize();
  // We have to make a copy of the data as we don't know if this data is from a
  // read only memory mapped buffer, so we duplicate all of the data first,
  // then modify it, and if all goes well, we then replace the data for this
  // expression.
  // Make en encoder that contains a copy of the location expression data so we
  // can write the address into the buffer using the correct byte order.
  DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
                      m_data.GetByteOrder(), addr_byte_size);

  lldb::offset_t offset = 0;
  lldb::offset_t const_offset = 0;
  lldb::addr_t const_value = 0;
  size_t const_byte_size = 0;
  while (m_data.ValidOffset(offset)) {
    const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));

    bool decoded_data = false;
    switch (op) {
    case DW_OP_const4u:
      // Remember the const offset in case we later have a
      // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address
      const_offset = offset;
      const_value = m_data.GetU32(&offset);
      decoded_data = true;
      const_byte_size = 4;
      break;

    case DW_OP_const8u:
      // Remember the const offset in case we later have a
      // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address
      const_offset = offset;
      const_value = m_data.GetU64(&offset);
      decoded_data = true;
      const_byte_size = 8;
      break;

    case DW_OP_form_tls_address:
    case DW_OP_GNU_push_tls_address:
      // DW_OP_form_tls_address and DW_OP_GNU_push_tls_address must be preceded
      // by a file address on the stack. We assume that DW_OP_const4u or
      // DW_OP_const8u is used for these values, and we check that the last
      // opcode we got before either of these was DW_OP_const4u or
      // DW_OP_const8u. If so, then we can link the value accordingly. For
      // Darwin, the value in the DW_OP_const4u or DW_OP_const8u is the file
      // address of a structure that contains a function pointer, the pthread
      // key and the offset into the data pointed to by the pthread key. So we
      // must link this address and also set the module of this expression to
      // the new_module_sp so we can resolve the file address correctly
      if (const_byte_size > 0) {
        lldb::addr_t linked_file_addr = link_address_callback(const_value);
        if (linked_file_addr == LLDB_INVALID_ADDRESS)
          return false;
        // Replace the address in the new buffer
        if (encoder.PutUnsigned(const_offset, const_byte_size,
                                linked_file_addr) == UINT32_MAX)
          return false;
      }
      break;

    default:
      const_offset = 0;
      const_value = 0;
      const_byte_size = 0;
      break;
    }

    if (!decoded_data) {
      const lldb::offset_t op_arg_size =
          GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
      if (op_arg_size == LLDB_INVALID_OFFSET)
        return false;
      else
        offset += op_arg_size;
    }
  }

  m_data.SetData(encoder.GetDataBuffer());
  return true;
}

static llvm::Error Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
                                              ExecutionContext *exe_ctx,
                                              RegisterContext *reg_ctx,
                                              const DataExtractor &opcodes,
                                              lldb::offset_t &opcode_offset,
                                              Log *log) {
  // DW_OP_entry_value(sub-expr) describes the location a variable had upon
  // function entry: this variable location is presumed to be optimized out at
  // the current PC value.  The caller of the function may have call site
  // information that describes an alternate location for the variable (e.g. a
  // constant literal, or a spilled stack value) in the parent frame.
  //
  // Example (this is pseudo-code & pseudo-DWARF, but hopefully illustrative):
  //
  //     void child(int &sink, int x) {
  //       ...
  //       /* "x" gets optimized out. */
  //
  //       /* The location of "x" here is: DW_OP_entry_value($reg2). */
  //       ++sink;
  //     }
  //
  //     void parent() {
  //       int sink;
  //
  //       /*
  //        * The callsite information emitted here is:
  //        *
  //        * DW_TAG_call_site
  //        *   DW_AT_return_pc ... (for "child(sink, 123);")
  //        *   DW_TAG_call_site_parameter (for "sink")
  //        *     DW_AT_location   ($reg1)
  //        *     DW_AT_call_value ($SP - 8)
  //        *   DW_TAG_call_site_parameter (for "x")
  //        *     DW_AT_location   ($reg2)
  //        *     DW_AT_call_value ($literal 123)
  //        *
  //        * DW_TAG_call_site
  //        *   DW_AT_return_pc ... (for "child(sink, 456);")
  //        *   ...
  //        */
  //       child(sink, 123);
  //       child(sink, 456);
  //     }
  //
  // When the program stops at "++sink" within `child`, the debugger determines
  // the call site by analyzing the return address. Once the call site is found,
  // the debugger determines which parameter is referenced by DW_OP_entry_value
  // and evaluates the corresponding location for that parameter in `parent`.

  // 1. Find the function which pushed the current frame onto the stack.
  if ((!exe_ctx || !exe_ctx->HasTargetScope()) || !reg_ctx) {
    return llvm::createStringError("no exe/reg context");
  }

  StackFrame *current_frame = exe_ctx->GetFramePtr();
  Thread *thread = exe_ctx->GetThreadPtr();
  if (!current_frame || !thread)
    return llvm::createStringError("no current frame/thread");

  Target &target = exe_ctx->GetTargetRef();
  StackFrameSP parent_frame = nullptr;
  addr_t return_pc = LLDB_INVALID_ADDRESS;
  uint32_t current_frame_idx = current_frame->GetFrameIndex();

  for (uint32_t parent_frame_idx = current_frame_idx + 1;;parent_frame_idx++) {
    parent_frame = thread->GetStackFrameAtIndex(parent_frame_idx);
    // If this is null, we're at the end of the stack.
    if (!parent_frame)
      break;

    // Record the first valid return address, even if this is an inlined frame,
    // in order to look up the associated call edge in the first non-inlined
    // parent frame.
    if (return_pc == LLDB_INVALID_ADDRESS) {
      return_pc = parent_frame->GetFrameCodeAddress().GetLoadAddress(&target);
      LLDB_LOG(log, "immediate ancestor with pc = {0:x}", return_pc);
    }

    // If we've found an inlined frame, skip it (these have no call site
    // parameters).
    if (parent_frame->IsInlined())
      continue;

    // We've found the first non-inlined parent frame.
    break;
  }
  if (!parent_frame || !parent_frame->GetRegisterContext()) {
    return llvm::createStringError("no parent frame with reg ctx");
  }

  Function *parent_func =
      parent_frame->GetSymbolContext(eSymbolContextFunction).function;
  if (!parent_func)
    return llvm::createStringError("no parent function");

  // 2. Find the call edge in the parent function responsible for creating the
  //    current activation.
  Function *current_func =
      current_frame->GetSymbolContext(eSymbolContextFunction).function;
  if (!current_func)
    return llvm::createStringError("no current function");

  CallEdge *call_edge = nullptr;
  ModuleList &modlist = target.GetImages();
  ExecutionContext parent_exe_ctx = *exe_ctx;
  parent_exe_ctx.SetFrameSP(parent_frame);
  if (!parent_frame->IsArtificial()) {
    // If the parent frame is not artificial, the current activation may be
    // produced by an ambiguous tail call. In this case, refuse to proceed.
    call_edge = parent_func->GetCallEdgeForReturnAddress(return_pc, target);
    if (!call_edge) {
      return llvm::createStringError(
          llvm::formatv("no call edge for retn-pc = {0:x} in parent frame {1}",
                        return_pc, parent_func->GetName()));
    }
    Function *callee_func = call_edge->GetCallee(modlist, parent_exe_ctx);
    if (callee_func != current_func) {
      return llvm::createStringError(
          "ambiguous call sequence, can't find real parent frame");
    }
  } else {
    // The StackFrameList solver machinery has deduced that an unambiguous tail
    // call sequence that produced the current activation.  The first edge in
    // the parent that points to the current function must be valid.
    for (auto &edge : parent_func->GetTailCallingEdges()) {
      if (edge->GetCallee(modlist, parent_exe_ctx) == current_func) {
        call_edge = edge.get();
        break;
      }
    }
  }
  if (!call_edge)
    return llvm::createStringError("no unambiguous edge from parent "
                                   "to current function");

  // 3. Attempt to locate the DW_OP_entry_value expression in the set of
  //    available call site parameters. If found, evaluate the corresponding
  //    parameter in the context of the parent frame.
  const uint32_t subexpr_len = opcodes.GetULEB128(&opcode_offset);
  const void *subexpr_data = opcodes.GetData(&opcode_offset, subexpr_len);
  if (!subexpr_data)
    return llvm::createStringError("subexpr could not be read");

  const CallSiteParameter *matched_param = nullptr;
  for (const CallSiteParameter &param : call_edge->GetCallSiteParameters()) {
    DataExtractor param_subexpr_extractor;
    if (!param.LocationInCallee.GetExpressionData(param_subexpr_extractor))
      continue;
    lldb::offset_t param_subexpr_offset = 0;
    const void *param_subexpr_data =
        param_subexpr_extractor.GetData(&param_subexpr_offset, subexpr_len);
    if (!param_subexpr_data ||
        param_subexpr_extractor.BytesLeft(param_subexpr_offset) != 0)
      continue;

    // At this point, the DW_OP_entry_value sub-expression and the callee-side
    // expression in the call site parameter are known to have the same length.
    // Check whether they are equal.
    //
    // Note that an equality check is sufficient: the contents of the
    // DW_OP_entry_value subexpression are only used to identify the right call
    // site parameter in the parent, and do not require any special handling.
    if (memcmp(subexpr_data, param_subexpr_data, subexpr_len) == 0) {
      matched_param = &param;
      break;
    }
  }
  if (!matched_param)
    return llvm::createStringError("no matching call site param found");

  // TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value
  // subexpresion whenever llvm does.
  const DWARFExpressionList &param_expr = matched_param->LocationInCaller;

  llvm::Expected<Value> maybe_result = param_expr.Evaluate(
      &parent_exe_ctx, parent_frame->GetRegisterContext().get(),
      LLDB_INVALID_ADDRESS,
      /*initial_value_ptr=*/nullptr,
      /*object_address_ptr=*/nullptr);
  if (!maybe_result) {
    LLDB_LOG(log,
             "Evaluate_DW_OP_entry_value: call site param evaluation failed");
    return maybe_result.takeError();
  }

  stack.push_back(*maybe_result);
  return llvm::Error::success();
}

namespace {
/// The location description kinds described by the DWARF v5
/// specification.  Composite locations are handled out-of-band and
/// thus aren't part of the enum.
enum LocationDescriptionKind {
  Empty,
  Memory,
  Register,
  Implicit
  /* Composite*/
};
/// Adjust value's ValueType according to the kind of location description.
void UpdateValueTypeFromLocationDescription(
    Log *log, const DWARFExpression::Delegate *dwarf_cu,
    LocationDescriptionKind kind, Value *value = nullptr) {
  // Note that this function is conflating DWARF expressions with
  // DWARF location descriptions. Perhaps it would be better to define
  // a wrapper for DWARFExpression::Eval() that deals with DWARF
  // location descriptions (which consist of one or more DWARF
  // expressions). But doing this would mean we'd also need factor the
  // handling of DW_OP_(bit_)piece out of this function.
  if (dwarf_cu && dwarf_cu->GetVersion() >= 4) {
    const char *log_msg = "DWARF location description kind: %s";
    switch (kind) {
    case Empty:
      LLDB_LOGF(log, log_msg, "Empty");
      break;
    case Memory:
      LLDB_LOGF(log, log_msg, "Memory");
      if (value->GetValueType() == Value::ValueType::Scalar)
        value->SetValueType(Value::ValueType::LoadAddress);
      break;
    case Register:
      LLDB_LOGF(log, log_msg, "Register");
      value->SetValueType(Value::ValueType::Scalar);
      break;
    case Implicit:
      LLDB_LOGF(log, log_msg, "Implicit");
      if (value->GetValueType() == Value::ValueType::LoadAddress)
        value->SetValueType(Value::ValueType::Scalar);
      break;
    }
  }
}
} // namespace

/// Helper function to move common code used to resolve a file address and turn
/// into a load address.
///
/// \param exe_ctx Pointer to the execution context
/// \param module_sp shared_ptr contains the module if we have one
/// \param dw_op_type C-style string used to vary the error output
/// \param file_addr the file address we are trying to resolve and turn into a
///                  load address
/// \param so_addr out parameter, will be set to load address or section offset
/// \param check_sectionoffset bool which determines if having a section offset
///                            but not a load address is considerd a success
/// \returns std::optional containing the load address if resolving and getting
///          the load address succeed or an empty Optinal otherwise. If
///          check_sectionoffset is true we consider LLDB_INVALID_ADDRESS a
///          success if so_addr.IsSectionOffset() is true.
static llvm::Expected<lldb::addr_t>
ResolveLoadAddress(ExecutionContext *exe_ctx, lldb::ModuleSP &module_sp,
                   const char *dw_op_type, lldb::addr_t file_addr,
                   Address &so_addr, bool check_sectionoffset = false) {
  if (!module_sp)
    return llvm::createStringError("need module to resolve file address for %s",
                                   dw_op_type);

  if (!module_sp->ResolveFileAddress(file_addr, so_addr))
    return llvm::createStringError("failed to resolve file address in module");

  const addr_t load_addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());

  if (load_addr == LLDB_INVALID_ADDRESS &&
      (check_sectionoffset && !so_addr.IsSectionOffset()))
    return llvm::createStringError("failed to resolve load address");

  return load_addr;
}

/// Helper function to move common code used to load sized data from a uint8_t
/// buffer.
///
/// \param addr_bytes uint8_t buffer containg raw data
/// \param size_addr_bytes how large is the underlying raw data
/// \param byte_order what is the byter order of the underlyig data
/// \param size How much of the underlying data we want to use
/// \return The underlying data converted into a Scalar
static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
                                         size_t size_addr_bytes,
                                         ByteOrder byte_order, size_t size) {
  DataExtractor addr_data(addr_bytes, size_addr_bytes, byte_order, size);

  lldb::offset_t addr_data_offset = 0;
  if (size <= 8)
    return addr_data.GetMaxU64(&addr_data_offset, size);
  else
    return addr_data.GetAddress(&addr_data_offset);
}

llvm::Expected<Value> DWARFExpression::Evaluate(
    ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
    lldb::ModuleSP module_sp, const DataExtractor &opcodes,
    const DWARFExpression::Delegate *dwarf_cu,
    const lldb::RegisterKind reg_kind, const Value *initial_value_ptr,
    const Value *object_address_ptr) {

  if (opcodes.GetByteSize() == 0)
    return llvm::createStringError(
        "no location, value may have been optimized out");
  std::vector<Value> stack;

  Process *process = nullptr;
  StackFrame *frame = nullptr;
  Target *target = nullptr;

  if (exe_ctx) {
    process = exe_ctx->GetProcessPtr();
    frame = exe_ctx->GetFramePtr();
    target = exe_ctx->GetTargetPtr();
  }
  if (reg_ctx == nullptr && frame)
    reg_ctx = frame->GetRegisterContext().get();

  if (initial_value_ptr)
    stack.push_back(*initial_value_ptr);

  lldb::offset_t offset = 0;
  Value tmp;
  uint32_t reg_num;

  /// Insertion point for evaluating multi-piece expression.
  uint64_t op_piece_offset = 0;
  Value pieces; // Used for DW_OP_piece

  Log *log = GetLog(LLDBLog::Expressions);
  // A generic type is "an integral type that has the size of an address and an
  // unspecified signedness". For now, just use the signedness of the operand.
  // TODO: Implement a real typed stack, and store the genericness of the value
  // there.
  auto to_generic = [&](auto v) {
    // TODO: Avoid implicit trunc?
    // See https://github.com/llvm/llvm-project/issues/112510.
    bool is_signed = std::is_signed<decltype(v)>::value;
    return Scalar(llvm::APSInt(llvm::APInt(8 * opcodes.GetAddressByteSize(), v,
                                           is_signed, /*implicitTrunc=*/true),
                               !is_signed));
  };

  // The default kind is a memory location. This is updated by any
  // operation that changes this, such as DW_OP_stack_value, and reset
  // by composition operations like DW_OP_piece.
  LocationDescriptionKind dwarf4_location_description_kind = Memory;

  while (opcodes.ValidOffset(offset)) {
    const lldb::offset_t op_offset = offset;
    const uint8_t op = opcodes.GetU8(&offset);

    if (log && log->GetVerbose()) {
      size_t count = stack.size();
      LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:",
                (uint64_t)count);
      for (size_t i = 0; i < count; ++i) {
        StreamString new_value;
        new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
        stack[i].Dump(&new_value);
        LLDB_LOGF(log, "  %s", new_value.GetData());
      }
      LLDB_LOGF(log, "0x%8.8" PRIx64 ": %s", op_offset,
                DW_OP_value_to_name(op));
    }

    if (std::optional<unsigned> arity =
            llvm::dwarf::OperationArity(static_cast<LocationAtom>(op))) {
      if (stack.size() < *arity)
        return llvm::createStringError(
            "%s needs at least %d stack entries (stack has %d entries)",
            DW_OP_value_to_name(op), *arity, stack.size());
    }

    switch (op) {
    // The DW_OP_addr operation has a single operand that encodes a machine
    // address and whose size is the size of an address on the target machine.
    case DW_OP_addr:
      stack.push_back(Scalar(opcodes.GetAddress(&offset)));
      if (target &&
          target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
        // wasm file sections aren't mapped into memory, therefore addresses can
        // never point into a file section and are always LoadAddresses.
        stack.back().SetValueType(Value::ValueType::LoadAddress);
      } else {
        stack.back().SetValueType(Value::ValueType::FileAddress);
      }
      break;

    // The DW_OP_addr_sect_offset4 is used for any location expressions in
    // shared libraries that have a location like:
    //  DW_OP_addr(0x1000)
    // If this address resides in a shared library, then this virtual address
    // won't make sense when it is evaluated in the context of a running
    // process where shared libraries have been slid. To account for this, this
    // new address type where we can store the section pointer and a 4 byte
    // offset.
    //      case DW_OP_addr_sect_offset4:
    //          {
    //              result_type = eResultTypeFileAddress;
    //              lldb::Section *sect = (lldb::Section
    //              *)opcodes.GetMaxU64(&offset, sizeof(void *));
    //              lldb::addr_t sect_offset = opcodes.GetU32(&offset);
    //
    //              Address so_addr (sect, sect_offset);
    //              lldb::addr_t load_addr = so_addr.GetLoadAddress();
    //              if (load_addr != LLDB_INVALID_ADDRESS)
    //              {
    //                  // We successfully resolve a file address to a load
    //                  // address.
    //                  stack.push_back(load_addr);
    //                  break;
    //              }
    //              else
    //              {
    //                  // We were able
    //                  if (error_ptr)
    //                      error_ptr->SetErrorStringWithFormat ("Section %s in
    //                      %s is not currently loaded.\n",
    //                      sect->GetName().AsCString(),
    //                      sect->GetModule()->GetFileSpec().GetFilename().AsCString());
    //                  return false;
    //              }
    //          }
    //          break;

    // OPCODE: DW_OP_deref
    // OPERANDS: none
    // DESCRIPTION: Pops the top stack entry and treats it as an address.
    // The value retrieved from that address is pushed. The size of the data
    // retrieved from the dereferenced address is the size of an address on the
    // target machine.
    case DW_OP_deref: {
      if (stack.empty())
        return llvm::createStringError(
            "expression stack empty for DW_OP_deref");
      Value::ValueType value_type = stack.back().GetValueType();
      switch (value_type) {
      case Value::ValueType::HostAddress: {
        void *src = (void *)stack.back().GetScalar().ULongLong();
        intptr_t ptr;
        ::memcpy(&ptr, src, sizeof(void *));
        stack.back().GetScalar() = ptr;
        stack.back().ClearContext();
      } break;
      case Value::ValueType::FileAddress: {
        auto file_addr = stack.back().GetScalar().ULongLong(
            LLDB_INVALID_ADDRESS);

        Address so_addr;
        auto maybe_load_addr = ResolveLoadAddress(
            exe_ctx, module_sp, "DW_OP_deref", file_addr, so_addr);

        if (!maybe_load_addr)
          return maybe_load_addr.takeError();

        stack.back().GetScalar() = *maybe_load_addr;
        // Fall through to load address promotion code below.
      }
        [[fallthrough]];
      case Value::ValueType::Scalar:
        // Promote Scalar to LoadAddress and fall through.
        stack.back().SetValueType(Value::ValueType::LoadAddress);
        [[fallthrough]];
      case Value::ValueType::LoadAddress:
        if (exe_ctx) {
          if (process) {
            lldb::addr_t pointer_addr =
                stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
            Status error;
            lldb::addr_t pointer_value =
                process->ReadPointerFromMemory(pointer_addr, error);
            if (pointer_value != LLDB_INVALID_ADDRESS) {
              if (ABISP abi_sp = process->GetABI())
                pointer_value = abi_sp->FixCodeAddress(pointer_value);
              stack.back().GetScalar() = pointer_value;
              stack.back().ClearContext();
            } else {
              return llvm::createStringError(
                  "Failed to dereference pointer from 0x%" PRIx64
                  " for DW_OP_deref: %s\n",
                  pointer_addr, error.AsCString());
            }
          } else {
            return llvm::createStringError("NULL process for DW_OP_deref");
          }
        } else {
          return llvm::createStringError(
              "NULL execution context for DW_OP_deref");
        }
        break;

      case Value::ValueType::Invalid:
        return llvm::createStringError("invalid value type for DW_OP_deref");
      }

    } break;

    // OPCODE: DW_OP_deref_size
    // OPERANDS: 1
    //  1 - uint8_t that specifies the size of the data to dereference.
    // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
    // stack entry and treats it as an address. The value retrieved from that
    // address is pushed. In the DW_OP_deref_size operation, however, the size
    // in bytes of the data retrieved from the dereferenced address is
    // specified by the single operand. This operand is a 1-byte unsigned
    // integral constant whose value may not be larger than the size of an
    // address on the target machine. The data retrieved is zero extended to
    // the size of an address on the target machine before being pushed on the
    // expression stack.
    case DW_OP_deref_size: {
      if (stack.empty()) {
        return llvm::createStringError(
            "expression stack empty for DW_OP_deref_size");
      }
      uint8_t size = opcodes.GetU8(&offset);
      if (size > 8) {
        return llvm::createStringError(
            "Invalid address size for DW_OP_deref_size: %d\n", size);
      }
      Value::ValueType value_type = stack.back().GetValueType();
      switch (value_type) {
      case Value::ValueType::HostAddress: {
        void *src = (void *)stack.back().GetScalar().ULongLong();
        intptr_t ptr;
        ::memcpy(&ptr, src, sizeof(void *));
        // I can't decide whether the size operand should apply to the bytes in
        // their
        // lldb-host endianness or the target endianness.. I doubt this'll ever
        // come up but I'll opt for assuming big endian regardless.
        switch (size) {
        case 1:
          ptr = ptr & 0xff;
          break;
        case 2:
          ptr = ptr & 0xffff;
          break;
        case 3:
          ptr = ptr & 0xffffff;
          break;
        case 4:
          ptr = ptr & 0xffffffff;
          break;
        // the casts are added to work around the case where intptr_t is a 32
        // bit quantity;
        // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
        // program.
        case 5:
          ptr = (intptr_t)ptr & 0xffffffffffULL;
          break;
        case 6:
          ptr = (intptr_t)ptr & 0xffffffffffffULL;
          break;
        case 7:
          ptr = (intptr_t)ptr & 0xffffffffffffffULL;
          break;
        default:
          break;
        }
        stack.back().GetScalar() = ptr;
        stack.back().ClearContext();
      } break;
      case Value::ValueType::FileAddress: {
        auto file_addr =
            stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
        Address so_addr;
        auto maybe_load_addr = ResolveLoadAddress(
            exe_ctx, module_sp, "DW_OP_deref_size", file_addr, so_addr,
            /*check_sectionoffset=*/true);

        if (!maybe_load_addr)
          return maybe_load_addr.takeError();

        addr_t load_addr = *maybe_load_addr;

        if (load_addr == LLDB_INVALID_ADDRESS && so_addr.IsSectionOffset()) {
          uint8_t addr_bytes[8];
          Status error;

          if (target &&
              target->ReadMemory(so_addr, &addr_bytes, size, error,
                                 /*force_live_memory=*/false) == size) {
            ObjectFile *objfile = module_sp->GetObjectFile();

            stack.back().GetScalar() = DerefSizeExtractDataHelper(
                addr_bytes, size, objfile->GetByteOrder(), size);
            stack.back().ClearContext();
            break;
          } else {
            return llvm::createStringError(
                "Failed to dereference pointer for DW_OP_deref_size: "
                "%s\n",
                error.AsCString());
          }
        }
        stack.back().GetScalar() = load_addr;
        // Fall through to load address promotion code below.
      }

        [[fallthrough]];
      case Value::ValueType::Scalar:
      case Value::ValueType::LoadAddress:
        if (exe_ctx) {
          if (process) {
            lldb::addr_t pointer_addr =
                stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
            uint8_t addr_bytes[sizeof(lldb::addr_t)];
            Status error;
            if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) ==
                size) {

              stack.back().GetScalar() =
                  DerefSizeExtractDataHelper(addr_bytes, sizeof(addr_bytes),
                                             process->GetByteOrder(), size);
              stack.back().ClearContext();
            } else {
              return llvm::createStringError(
                  "Failed to dereference pointer from 0x%" PRIx64
                  " for DW_OP_deref: %s\n",
                  pointer_addr, error.AsCString());
            }
          } else {

            return llvm::createStringError("NULL process for DW_OP_deref_size");
          }
        } else {
          return llvm::createStringError(
              "NULL execution context for DW_OP_deref_size");
        }
        break;

      case Value::ValueType::Invalid:

        return llvm::createStringError("invalid value for DW_OP_deref_size");
      }

    } break;

    // OPCODE: DW_OP_xderef_size
    // OPERANDS: 1
    //  1 - uint8_t that specifies the size of the data to dereference.
    // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at
    // the top of the stack is treated as an address. The second stack entry is
    // treated as an "address space identifier" for those architectures that
    // support multiple address spaces. The top two stack elements are popped,
    // a data item is retrieved through an implementation-defined address
    // calculation and pushed as the new stack top. In the DW_OP_xderef_size
    // operation, however, the size in bytes of the data retrieved from the
    // dereferenced address is specified by the single operand. This operand is
    // a 1-byte unsigned integral constant whose value may not be larger than
    // the size of an address on the target machine. The data retrieved is zero
    // extended to the size of an address on the target machine before being
    // pushed on the expression stack.
    case DW_OP_xderef_size:
      return llvm::createStringError("unimplemented opcode: DW_OP_xderef_size");
    // OPCODE: DW_OP_xderef
    // OPERANDS: none
    // DESCRIPTION: Provides an extended dereference mechanism. The entry at
    // the top of the stack is treated as an address. The second stack entry is
    // treated as an "address space identifier" for those architectures that
    // support multiple address spaces. The top two stack elements are popped,
    // a data item is retrieved through an implementation-defined address
    // calculation and pushed as the new stack top. The size of the data
    // retrieved from the dereferenced address is the size of an address on the
    // target machine.
    case DW_OP_xderef:
      return llvm::createStringError("unimplemented opcode: DW_OP_xderef");

    // All DW_OP_constXXX opcodes have a single operand as noted below:
    //
    // Opcode           Operand 1
    // DW_OP_const1u    1-byte unsigned integer constant
    // DW_OP_const1s    1-byte signed integer constant
    // DW_OP_const2u    2-byte unsigned integer constant
    // DW_OP_const2s    2-byte signed integer constant
    // DW_OP_const4u    4-byte unsigned integer constant
    // DW_OP_const4s    4-byte signed integer constant
    // DW_OP_const8u    8-byte unsigned integer constant
    // DW_OP_const8s    8-byte signed integer constant
    // DW_OP_constu     unsigned LEB128 integer constant
    // DW_OP_consts     signed LEB128 integer constant
    case DW_OP_const1u:
      stack.push_back(to_generic(opcodes.GetU8(&offset)));
      break;
    case DW_OP_const1s:
      stack.push_back(to_generic((int8_t)opcodes.GetU8(&offset)));
      break;
    case DW_OP_const2u:
      stack.push_back(to_generic(opcodes.GetU16(&offset)));
      break;
    case DW_OP_const2s:
      stack.push_back(to_generic((int16_t)opcodes.GetU16(&offset)));
      break;
    case DW_OP_const4u:
      stack.push_back(to_generic(opcodes.GetU32(&offset)));
      break;
    case DW_OP_const4s:
      stack.push_back(to_generic((int32_t)opcodes.GetU32(&offset)));
      break;
    case DW_OP_const8u:
      stack.push_back(to_generic(opcodes.GetU64(&offset)));
      break;
    case DW_OP_const8s:
      stack.push_back(to_generic((int64_t)opcodes.GetU64(&offset)));
      break;
    // These should also use to_generic, but we can't do that due to a
    // producer-side bug in llvm. See llvm.org/pr48087.
    case DW_OP_constu:
      stack.push_back(Scalar(opcodes.GetULEB128(&offset)));
      break;
    case DW_OP_consts:
      stack.push_back(Scalar(opcodes.GetSLEB128(&offset)));
      break;

    // OPCODE: DW_OP_dup
    // OPERANDS: none
    // DESCRIPTION: duplicates the value at the top of the stack
    case DW_OP_dup:
      if (stack.empty()) {
        return llvm::createStringError("expression stack empty for DW_OP_dup");
      } else
        stack.push_back(stack.back());
      break;

    // OPCODE: DW_OP_drop
    // OPERANDS: none
    // DESCRIPTION: pops the value at the top of the stack
    case DW_OP_drop:
      if (stack.empty()) {
        return llvm::createStringError("expression stack empty for DW_OP_drop");
      } else
        stack.pop_back();
      break;

    // OPCODE: DW_OP_over
    // OPERANDS: none
    // DESCRIPTION: Duplicates the entry currently second in the stack at
    // the top of the stack.
    case DW_OP_over:
      stack.push_back(stack[stack.size() - 2]);
      break;

    // OPCODE: DW_OP_pick
    // OPERANDS: uint8_t index into the current stack
    // DESCRIPTION: The stack entry with the specified index (0 through 255,
    // inclusive) is pushed on the stack
    case DW_OP_pick: {
      uint8_t pick_idx = opcodes.GetU8(&offset);
      if (pick_idx < stack.size())
        stack.push_back(stack[stack.size() - 1 - pick_idx]);
      else {
        return llvm::createStringError(
            "Index %u out of range for DW_OP_pick.\n", pick_idx);
      }
    } break;

    // OPCODE: DW_OP_swap
    // OPERANDS: none
    // DESCRIPTION: swaps the top two stack entries. The entry at the top
    // of the stack becomes the second stack entry, and the second entry
    // becomes the top of the stack
    case DW_OP_swap:
      tmp = stack.back();
      stack.back() = stack[stack.size() - 2];
      stack[stack.size() - 2] = tmp;
      break;

    // OPCODE: DW_OP_rot
    // OPERANDS: none
    // DESCRIPTION: Rotates the first three stack entries. The entry at
    // the top of the stack becomes the third stack entry, the second entry
    // becomes the top of the stack, and the third entry becomes the second
    // entry.
    case DW_OP_rot: {
      size_t last_idx = stack.size() - 1;
      Value old_top = stack[last_idx];
      stack[last_idx] = stack[last_idx - 1];
      stack[last_idx - 1] = stack[last_idx - 2];
      stack[last_idx - 2] = old_top;
    } break;

    // OPCODE: DW_OP_abs
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, interprets it as a signed
    // value and pushes its absolute value. If the absolute value can not be
    // represented, the result is undefined.
    case DW_OP_abs:
      if (!stack.back().ResolveValue(exe_ctx).AbsoluteValue()) {
        return llvm::createStringError(
            "failed to take the absolute value of the first stack item");
      }
      break;

    // OPCODE: DW_OP_and
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, performs a bitwise and
    // operation on the two, and pushes the result.
    case DW_OP_and:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_div
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, divides the former second
    // entry by the former top of the stack using signed division, and pushes
    // the result.
    case DW_OP_div: {
      tmp = stack.back();
      if (tmp.ResolveValue(exe_ctx).IsZero())
        return llvm::createStringError("divide by zero");

      stack.pop_back();
      Scalar divisor, dividend;
      divisor = tmp.ResolveValue(exe_ctx);
      dividend = stack.back().ResolveValue(exe_ctx);
      divisor.MakeSigned();
      dividend.MakeSigned();
      stack.back() = dividend / divisor;

      if (!stack.back().ResolveValue(exe_ctx).IsValid())
        return llvm::createStringError("divide failed");
    } break;

    // OPCODE: DW_OP_minus
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, subtracts the former top
    // of the stack from the former second entry, and pushes the result.
    case DW_OP_minus:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_mod
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values and pushes the result of
    // the calculation: former second stack entry modulo the former top of the
    // stack.
    case DW_OP_mod:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_mul
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, multiplies them
    // together, and pushes the result.
    case DW_OP_mul:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_neg
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, and pushes its negation.
    case DW_OP_neg:
      if (!stack.back().ResolveValue(exe_ctx).UnaryNegate())
        return llvm::createStringError("unary negate failed");
      break;

    // OPCODE: DW_OP_not
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, and pushes its bitwise
    // complement
    case DW_OP_not:
      if (!stack.back().ResolveValue(exe_ctx).OnesComplement())
        return llvm::createStringError("logical NOT failed");
      break;

    // OPCODE: DW_OP_or
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, performs a bitwise or
    // operation on the two, and pushes the result.
    case DW_OP_or:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_plus
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, adds them together, and
    // pushes the result.
    case DW_OP_plus:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() += tmp.GetScalar();
      break;

    // OPCODE: DW_OP_plus_uconst
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
    // constant operand and pushes the result.
    case DW_OP_plus_uconst: {
      const uint64_t uconst_value = opcodes.GetULEB128(&offset);
      // Implicit conversion from a UINT to a Scalar...
      stack.back().GetScalar() += uconst_value;
      if (!stack.back().GetScalar().IsValid())
        return llvm::createStringError("DW_OP_plus_uconst failed");
    } break;

    // OPCODE: DW_OP_shl
    // OPERANDS: none
    // DESCRIPTION:  pops the top two stack entries, shifts the former
    // second entry left by the number of bits specified by the former top of
    // the stack, and pushes the result.
    case DW_OP_shl:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_shr
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, shifts the former second
    // entry right logically (filling with zero bits) by the number of bits
    // specified by the former top of the stack, and pushes the result.
    case DW_OP_shr:
      tmp = stack.back();
      stack.pop_back();
      if (!stack.back().ResolveValue(exe_ctx).ShiftRightLogical(
              tmp.ResolveValue(exe_ctx)))
        return llvm::createStringError("DW_OP_shr failed");
      break;

    // OPCODE: DW_OP_shra
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, shifts the former second
    // entry right arithmetically (divide the magnitude by 2, keep the same
    // sign for the result) by the number of bits specified by the former top
    // of the stack, and pushes the result.
    case DW_OP_shra:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_xor
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, performs the bitwise
    // exclusive-or operation on the two, and pushes the result.
    case DW_OP_xor:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_skip
    // OPERANDS: int16_t
    // DESCRIPTION:  An unconditional branch. Its single operand is a 2-byte
    // signed integer constant. The 2-byte constant is the number of bytes of
    // the DWARF expression to skip forward or backward from the current
    // operation, beginning after the 2-byte constant.
    case DW_OP_skip: {
      int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
      lldb::offset_t new_offset = offset + skip_offset;
      // New offset can point at the end of the data, in this case we should
      // terminate the DWARF expression evaluation (will happen in the loop
      // condition).
      if (new_offset <= opcodes.GetByteSize())
        offset = new_offset;
      else {
        return llvm::createStringError(llvm::formatv(
            "Invalid opcode offset in DW_OP_skip: {0}+({1}) > {2}", offset,
            skip_offset, opcodes.GetByteSize()));
      }
    } break;

    // OPCODE: DW_OP_bra
    // OPERANDS: int16_t
    // DESCRIPTION: A conditional branch. Its single operand is a 2-byte
    // signed integer constant. This operation pops the top of stack. If the
    // value popped is not the constant 0, the 2-byte constant operand is the
    // number of bytes of the DWARF expression to skip forward or backward from
    // the current operation, beginning after the 2-byte constant.
    case DW_OP_bra: {
      tmp = stack.back();
      stack.pop_back();
      int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
      Scalar zero(0);
      if (tmp.ResolveValue(exe_ctx) != zero) {
        lldb::offset_t new_offset = offset + bra_offset;
        // New offset can point at the end of the data, in this case we should
        // terminate the DWARF expression evaluation (will happen in the loop
        // condition).
        if (new_offset <= opcodes.GetByteSize())
          offset = new_offset;
        else {
          return llvm::createStringError(llvm::formatv(
              "Invalid opcode offset in DW_OP_bra: {0}+({1}) > {2}", offset,
              bra_offset, opcodes.GetByteSize()));
        }
      }
    } break;

    // OPCODE: DW_OP_eq
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // equals (==) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    case DW_OP_eq:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_ge
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // greater than or equal to (>=) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    case DW_OP_ge:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_gt
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // greater than (>) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    case DW_OP_gt:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_le
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // less than or equal to (<=) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    case DW_OP_le:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_lt
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // less than (<) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    case DW_OP_lt:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_ne
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // not equal (!=) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    case DW_OP_ne:
      tmp = stack.back();
      stack.pop_back();
      stack.back().ResolveValue(exe_ctx) =
          stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx);
      break;

    // OPCODE: DW_OP_litn
    // OPERANDS: none
    // DESCRIPTION: encode the unsigned literal values from 0 through 31.
    // STACK RESULT: push the unsigned literal constant value onto the top
    // of the stack.
    case DW_OP_lit0:
    case DW_OP_lit1:
    case DW_OP_lit2:
    case DW_OP_lit3:
    case DW_OP_lit4:
    case DW_OP_lit5:
    case DW_OP_lit6:
    case DW_OP_lit7:
    case DW_OP_lit8:
    case DW_OP_lit9:
    case DW_OP_lit10:
    case DW_OP_lit11:
    case DW_OP_lit12:
    case DW_OP_lit13:
    case DW_OP_lit14:
    case DW_OP_lit15:
    case DW_OP_lit16:
    case DW_OP_lit17:
    case DW_OP_lit18:
    case DW_OP_lit19:
    case DW_OP_lit20:
    case DW_OP_lit21:
    case DW_OP_lit22:
    case DW_OP_lit23:
    case DW_OP_lit24:
    case DW_OP_lit25:
    case DW_OP_lit26:
    case DW_OP_lit27:
    case DW_OP_lit28:
    case DW_OP_lit29:
    case DW_OP_lit30:
    case DW_OP_lit31:
      stack.push_back(to_generic(op - DW_OP_lit0));
      break;

    // OPCODE: DW_OP_regN
    // OPERANDS: none
    // DESCRIPTION: Push the value in register n on the top of the stack.
    case DW_OP_reg0:
    case DW_OP_reg1:
    case DW_OP_reg2:
    case DW_OP_reg3:
    case DW_OP_reg4:
    case DW_OP_reg5:
    case DW_OP_reg6:
    case DW_OP_reg7:
    case DW_OP_reg8:
    case DW_OP_reg9:
    case DW_OP_reg10:
    case DW_OP_reg11:
    case DW_OP_reg12:
    case DW_OP_reg13:
    case DW_OP_reg14:
    case DW_OP_reg15:
    case DW_OP_reg16:
    case DW_OP_reg17:
    case DW_OP_reg18:
    case DW_OP_reg19:
    case DW_OP_reg20:
    case DW_OP_reg21:
    case DW_OP_reg22:
    case DW_OP_reg23:
    case DW_OP_reg24:
    case DW_OP_reg25:
    case DW_OP_reg26:
    case DW_OP_reg27:
    case DW_OP_reg28:
    case DW_OP_reg29:
    case DW_OP_reg30:
    case DW_OP_reg31: {
      dwarf4_location_description_kind = Register;
      reg_num = op - DW_OP_reg0;

      if (llvm::Error err =
              ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
        return err;
      stack.push_back(tmp);
    } break;
    // OPCODE: DW_OP_regx
    // OPERANDS:
    //      ULEB128 literal operand that encodes the register.
    // DESCRIPTION: Push the value in register on the top of the stack.
    case DW_OP_regx: {
      dwarf4_location_description_kind = Register;
      reg_num = opcodes.GetULEB128(&offset);
      Status read_err;
      if (llvm::Error err =
              ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
        return err;
      stack.push_back(tmp);
    } break;

    // OPCODE: DW_OP_bregN
    // OPERANDS:
    //      SLEB128 offset from register N
    // DESCRIPTION: Value is in memory at the address specified by register
    // N plus an offset.
    case DW_OP_breg0:
    case DW_OP_breg1:
    case DW_OP_breg2:
    case DW_OP_breg3:
    case DW_OP_breg4:
    case DW_OP_breg5:
    case DW_OP_breg6:
    case DW_OP_breg7:
    case DW_OP_breg8:
    case DW_OP_breg9:
    case DW_OP_breg10:
    case DW_OP_breg11:
    case DW_OP_breg12:
    case DW_OP_breg13:
    case DW_OP_breg14:
    case DW_OP_breg15:
    case DW_OP_breg16:
    case DW_OP_breg17:
    case DW_OP_breg18:
    case DW_OP_breg19:
    case DW_OP_breg20:
    case DW_OP_breg21:
    case DW_OP_breg22:
    case DW_OP_breg23:
    case DW_OP_breg24:
    case DW_OP_breg25:
    case DW_OP_breg26:
    case DW_OP_breg27:
    case DW_OP_breg28:
    case DW_OP_breg29:
    case DW_OP_breg30:
    case DW_OP_breg31: {
      reg_num = op - DW_OP_breg0;
      if (llvm::Error err =
              ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
        return err;

      int64_t breg_offset = opcodes.GetSLEB128(&offset);
      tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
      tmp.ClearContext();
      stack.push_back(tmp);
      stack.back().SetValueType(Value::ValueType::LoadAddress);
    } break;
    // OPCODE: DW_OP_bregx
    // OPERANDS: 2
    //      ULEB128 literal operand that encodes the register.
    //      SLEB128 offset from register N
    // DESCRIPTION: Value is in memory at the address specified by register
    // N plus an offset.
    case DW_OP_bregx: {
      reg_num = opcodes.GetULEB128(&offset);
      if (llvm::Error err =
              ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
        return err;

      int64_t breg_offset = opcodes.GetSLEB128(&offset);
      tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
      tmp.ClearContext();
      stack.push_back(tmp);
      stack.back().SetValueType(Value::ValueType::LoadAddress);
    } break;

    case DW_OP_fbreg:
      if (exe_ctx) {
        if (frame) {
          Scalar value;
          if (llvm::Error err = frame->GetFrameBaseValue(value))
            return err;
          int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
          value += fbreg_offset;
          stack.push_back(value);
          stack.back().SetValueType(Value::ValueType::LoadAddress);
        } else {
          return llvm::createStringError(
              "invalid stack frame in context for DW_OP_fbreg opcode");
        }
      } else {
        return llvm::createStringError(
            "NULL execution context for DW_OP_fbreg");
      }

      break;

    // OPCODE: DW_OP_nop
    // OPERANDS: none
    // DESCRIPTION: A place holder. It has no effect on the location stack
    // or any of its values.
    case DW_OP_nop:
      break;

    // OPCODE: DW_OP_piece
    // OPERANDS: 1
    //      ULEB128: byte size of the piece
    // DESCRIPTION: The operand describes the size in bytes of the piece of
    // the object referenced by the DWARF expression whose result is at the top
    // of the stack. If the piece is located in a register, but does not occupy
    // the entire register, the placement of the piece within that register is
    // defined by the ABI.
    //
    // Many compilers store a single variable in sets of registers, or store a
    // variable partially in memory and partially in registers. DW_OP_piece
    // provides a way of describing how large a part of a variable a particular
    // DWARF expression refers to.
    case DW_OP_piece: {
      LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind;
      // Reset for the next piece.
      dwarf4_location_description_kind = Memory;

      const uint64_t piece_byte_size = opcodes.GetULEB128(&offset);

      if (piece_byte_size > 0) {
        Value curr_piece;

        if (stack.empty()) {
          UpdateValueTypeFromLocationDescription(
              log, dwarf_cu, LocationDescriptionKind::Empty);
          // In a multi-piece expression, this means that the current piece is
          // not available. Fill with zeros for now by resizing the data and
          // appending it
          curr_piece.ResizeData(piece_byte_size);
          // Note that "0" is not a correct value for the unknown bits.
          // It would be better to also return a mask of valid bits together
          // with the expression result, so the debugger can print missing
          // members as "<optimized out>" or something.
          ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
          pieces.AppendDataToHostBuffer(curr_piece);
        } else {
          Status error;
          // Extract the current piece into "curr_piece"
          Value curr_piece_source_value(stack.back());
          stack.pop_back();
          UpdateValueTypeFromLocationDescription(log, dwarf_cu, piece_locdesc,
                                                 &curr_piece_source_value);

          const Value::ValueType curr_piece_source_value_type =
              curr_piece_source_value.GetValueType();
          Scalar &scalar = curr_piece_source_value.GetScalar();
          lldb::addr_t addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
          switch (curr_piece_source_value_type) {
          case Value::ValueType::Invalid:
            return llvm::createStringError("invalid value type");
          case Value::ValueType::FileAddress:
            if (target) {
              curr_piece_source_value.ConvertToLoadAddress(module_sp.get(),
                                                           target);
              addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
            } else {
              return llvm::createStringError(
                  "unable to convert file address 0x%" PRIx64
                  " to load address "
                  "for DW_OP_piece(%" PRIu64 "): "
                  "no target available",
                  addr, piece_byte_size);
            }
            [[fallthrough]];
          case Value::ValueType::LoadAddress: {
            if (target) {
              if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {
                if (target->ReadMemory(addr, curr_piece.GetBuffer().GetBytes(),
                                       piece_byte_size, error,
                                       /*force_live_memory=*/false) !=
                    piece_byte_size) {
                  const char *addr_type = (curr_piece_source_value_type ==
                                           Value::ValueType::LoadAddress)
                                              ? "load"
                                              : "file";
                  return llvm::createStringError(
                      "failed to read memory DW_OP_piece(%" PRIu64
                      ") from %s address 0x%" PRIx64,
                      piece_byte_size, addr_type, addr);
                }
              } else {
                return llvm::createStringError(
                    "failed to resize the piece memory buffer for "
                    "DW_OP_piece(%" PRIu64 ")",
                    piece_byte_size);
              }
            }
          } break;
          case Value::ValueType::HostAddress: {
            return llvm::createStringError(
                "failed to read memory DW_OP_piece(%" PRIu64
                ") from host address 0x%" PRIx64,
                piece_byte_size, addr);
          } break;

          case Value::ValueType::Scalar: {
            uint32_t bit_size = piece_byte_size * 8;
            uint32_t bit_offset = 0;
            if (!scalar.ExtractBitfield(
                    bit_size, bit_offset)) {
              return llvm::createStringError(
                  "unable to extract %" PRIu64 " bytes from a %" PRIu64
                  " byte scalar value.",
                  piece_byte_size,
                  (uint64_t)curr_piece_source_value.GetScalar().GetByteSize());
            }
            // Create curr_piece with bit_size. By default Scalar
            // grows to the nearest host integer type.
            llvm::APInt fail_value(1, 0, false);
            llvm::APInt ap_int = scalar.UInt128(fail_value);
            assert(ap_int.getBitWidth() >= bit_size);
            llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
                                         ap_int.getNumWords()};
            curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
          } break;
          }

          // Check if this is the first piece?
          if (op_piece_offset == 0) {
            // This is the first piece, we should push it back onto the stack
            // so subsequent pieces will be able to access this piece and add
            // to it.
            if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
              return llvm::createStringError("failed to append piece data");
            }
          } else {
            // If this is the second or later piece there should be a value on
            // the stack.
            if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {
              return llvm::createStringError(
                  "DW_OP_piece for offset %" PRIu64
                  " but top of stack is of size %" PRIu64,
                  op_piece_offset, pieces.GetBuffer().GetByteSize());
            }

            if (pieces.AppendDataToHostBuffer(curr_piece) == 0)
              return llvm::createStringError("failed to append piece data");
          }
        }
        op_piece_offset += piece_byte_size;
      }
    } break;

    case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
      if (stack.size() < 1) {
        UpdateValueTypeFromLocationDescription(log, dwarf_cu,
                                               LocationDescriptionKind::Empty);
        // Reset for the next piece.
        dwarf4_location_description_kind = Memory;
        return llvm::createStringError(
            "expression stack needs at least 1 item for DW_OP_bit_piece");
      } else {
        UpdateValueTypeFromLocationDescription(
            log, dwarf_cu, dwarf4_location_description_kind, &stack.back());
        // Reset for the next piece.
        dwarf4_location_description_kind = Memory;
        const uint64_t piece_bit_size = opcodes.GetULEB128(&offset);
        const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset);
        switch (stack.back().GetValueType()) {
        case Value::ValueType::Invalid:
          return llvm::createStringError(
              "unable to extract bit value from invalid value");
        case Value::ValueType::Scalar: {
          if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size,
                                                        piece_bit_offset)) {
            return llvm::createStringError(
                "unable to extract %" PRIu64 " bit value with %" PRIu64
                " bit offset from a %" PRIu64 " bit scalar value.",
                piece_bit_size, piece_bit_offset,
                (uint64_t)(stack.back().GetScalar().GetByteSize() * 8));
          }
        } break;

        case Value::ValueType::FileAddress:
        case Value::ValueType::LoadAddress:
        case Value::ValueType::HostAddress:
          return llvm::createStringError(
              "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
              ", bit_offset = %" PRIu64 ") from an address value.",
              piece_bit_size, piece_bit_offset);
        }
      }
      break;

    // OPCODE: DW_OP_implicit_value
    // OPERANDS: 2
    //      ULEB128  size of the value block in bytes
    //      uint8_t* block bytes encoding value in target's memory
    //      representation
    // DESCRIPTION: Value is immediately stored in block in the debug info with
    // the memory representation of the target.
    case DW_OP_implicit_value: {
      dwarf4_location_description_kind = Implicit;

      const uint32_t len = opcodes.GetULEB128(&offset);
      const void *data = opcodes.GetData(&offset, len);

      if (!data) {
        LLDB_LOG(log, "Evaluate_DW_OP_implicit_value: could not be read data");
        return llvm::createStringError("could not evaluate %s",
                                       DW_OP_value_to_name(op));
      }

      Value result(data, len);
      stack.push_back(result);
      break;
    }

    case DW_OP_implicit_pointer: {
      dwarf4_location_description_kind = Implicit;
      return llvm::createStringError("Could not evaluate %s.",
                                     DW_OP_value_to_name(op));
    }

    // OPCODE: DW_OP_push_object_address
    // OPERANDS: none
    // DESCRIPTION: Pushes the address of the object currently being
    // evaluated as part of evaluation of a user presented expression. This
    // object may correspond to an independent variable described by its own
    // DIE or it may be a component of an array, structure, or class whose
    // address has been dynamically determined by an earlier step during user
    // expression evaluation.
    case DW_OP_push_object_address:
      if (object_address_ptr)
        stack.push_back(*object_address_ptr);
      else {
        return llvm::createStringError("DW_OP_push_object_address used without "
                                       "specifying an object address");
      }
      break;

    // OPCODE: DW_OP_call2
    // OPERANDS:
    //      uint16_t compile unit relative offset of a DIE
    // DESCRIPTION: Performs subroutine calls during evaluation
    // of a DWARF expression. The operand is the 2-byte unsigned offset of a
    // debugging information entry in the current compilation unit.
    //
    // Operand interpretation is exactly like that for DW_FORM_ref2.
    //
    // This operation transfers control of DWARF expression evaluation to the
    // DW_AT_location attribute of the referenced DIE. If there is no such
    // attribute, then there is no effect. Execution of the DWARF expression of
    // a DW_AT_location attribute may add to and/or remove from values on the
    // stack. Execution returns to the point following the call when the end of
    // the attribute is reached. Values on the stack at the time of the call
    // may be used as parameters by the called expression and values left on
    // the stack by the called expression may be used as return values by prior
    // agreement between the calling and called expressions.
    case DW_OP_call2:
      return llvm::createStringError("unimplemented opcode DW_OP_call2");
    // OPCODE: DW_OP_call4
    // OPERANDS: 1
    //      uint32_t compile unit relative offset of a DIE
    // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
    // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset of
    // a debugging information entry in  the current compilation unit.
    //
    // Operand interpretation DW_OP_call4 is exactly like that for
    // DW_FORM_ref4.
    //
    // This operation transfers control of DWARF expression evaluation to the
    // DW_AT_location attribute of the referenced DIE. If there is no such
    // attribute, then there is no effect. Execution of the DWARF expression of
    // a DW_AT_location attribute may add to and/or remove from values on the
    // stack. Execution returns to the point following the call when the end of
    // the attribute is reached. Values on the stack at the time of the call
    // may be used as parameters by the called expression and values left on
    // the stack by the called expression may be used as return values by prior
    // agreement between the calling and called expressions.
    case DW_OP_call4:
      return llvm::createStringError("unimplemented opcode DW_OP_call4");

    // OPCODE: DW_OP_stack_value
    // OPERANDS: None
    // DESCRIPTION: Specifies that the object does not exist in memory but
    // rather is a constant value.  The value from the top of the stack is the
    // value to be used.  This is the actual object value and not the location.
    case DW_OP_stack_value:
      dwarf4_location_description_kind = Implicit;
      stack.back().SetValueType(Value::ValueType::Scalar);
      break;

    // OPCODE: DW_OP_convert
    // OPERANDS: 1
    //      A ULEB128 that is either a DIE offset of a
    //      DW_TAG_base_type or 0 for the generic (pointer-sized) type.
    //
    // DESCRIPTION: Pop the top stack element, convert it to a
    // different type, and push the result.
    case DW_OP_convert: {
      const uint64_t relative_die_offset = opcodes.GetULEB128(&offset);
      uint64_t bit_size;
      bool sign;
      if (relative_die_offset == 0) {
        // The generic type has the size of an address on the target
        // machine and an unspecified signedness. Scalar has no
        // "unspecified signedness", so we use unsigned types.
        if (!module_sp)
          return llvm::createStringError("no module");
        sign = false;
        bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
        if (!bit_size)
          return llvm::createStringError("unspecified architecture");
      } else {
        auto bit_size_sign_or_err =
            dwarf_cu->GetDIEBitSizeAndSign(relative_die_offset);
        if (!bit_size_sign_or_err)
          return bit_size_sign_or_err.takeError();
        bit_size = bit_size_sign_or_err->first;
        sign = bit_size_sign_or_err->second;
      }
      Scalar &top = stack.back().ResolveValue(exe_ctx);
      top.TruncOrExtendTo(bit_size, sign);
      break;
    }

    // OPCODE: DW_OP_call_frame_cfa
    // OPERANDS: None
    // DESCRIPTION: Specifies a DWARF expression that pushes the value of
    // the canonical frame address consistent with the call frame information
    // located in .debug_frame (or in the FDEs of the eh_frame section).
    case DW_OP_call_frame_cfa:
      if (frame) {
        // Note that we don't have to parse FDEs because this DWARF expression
        // is commonly evaluated with a valid stack frame.
        StackID id = frame->GetStackID();
        addr_t cfa = id.GetCallFrameAddress();
        if (cfa != LLDB_INVALID_ADDRESS) {
          stack.push_back(Scalar(cfa));
          stack.back().SetValueType(Value::ValueType::LoadAddress);
        } else {
          return llvm::createStringError(
              "stack frame does not include a canonical "
              "frame address for DW_OP_call_frame_cfa "
              "opcode");
        }
      } else {
        return llvm::createStringError("unvalid stack frame in context for "
                                       "DW_OP_call_frame_cfa opcode");
      }
      break;

    // OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension
    // opcode, DW_OP_GNU_push_tls_address)
    // OPERANDS: none
    // DESCRIPTION: Pops a TLS offset from the stack, converts it to
    // an address in the current thread's thread-local storage block, and
    // pushes it on the stack.
    case DW_OP_form_tls_address:
    case DW_OP_GNU_push_tls_address: {
      if (stack.size() < 1) {
        if (op == DW_OP_form_tls_address)
          return llvm::createStringError(
              "DW_OP_form_tls_address needs an argument");
        else
          return llvm::createStringError(
              "DW_OP_GNU_push_tls_address needs an argument");
      }

      if (!exe_ctx || !module_sp)
        return llvm::createStringError("no context to evaluate TLS within");

      Thread *thread = exe_ctx->GetThreadPtr();
      if (!thread)
        return llvm::createStringError("no thread to evaluate TLS within");

      // Lookup the TLS block address for this thread and module.
      const addr_t tls_file_addr =
          stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
      const addr_t tls_load_addr =
          thread->GetThreadLocalData(module_sp, tls_file_addr);

      if (tls_load_addr == LLDB_INVALID_ADDRESS)
        return llvm::createStringError(
            "no TLS data currently exists for this thread");

      stack.back().GetScalar() = tls_load_addr;
      stack.back().SetValueType(Value::ValueType::LoadAddress);
    } break;

    // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.)
    // OPERANDS: 1
    //      ULEB128: index to the .debug_addr section
    // DESCRIPTION: Pushes an address to the stack from the .debug_addr
    // section with the base address specified by the DW_AT_addr_base attribute
    // and the 0 based index is the ULEB128 encoded index.
    case DW_OP_addrx:
    case DW_OP_GNU_addr_index: {
      if (!dwarf_cu)
        return llvm::createStringError("DW_OP_GNU_addr_index found without a "
                                       "compile unit being specified");
      uint64_t index = opcodes.GetULEB128(&offset);
      lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
      stack.push_back(Scalar(value));
      if (target &&
          target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
        // wasm file sections aren't mapped into memory, therefore addresses can
        // never point into a file section and are always LoadAddresses.
        stack.back().SetValueType(Value::ValueType::LoadAddress);
      } else {
        stack.back().SetValueType(Value::ValueType::FileAddress);
      }
    } break;

    // OPCODE: DW_OP_GNU_const_index
    // OPERANDS: 1
    //      ULEB128: index to the .debug_addr section
    // DESCRIPTION: Pushes an constant with the size of a machine address to
    // the stack from the .debug_addr section with the base address specified
    // by the DW_AT_addr_base attribute and the 0 based index is the ULEB128
    // encoded index.
    case DW_OP_GNU_const_index: {
      if (!dwarf_cu) {
        return llvm::createStringError("DW_OP_GNU_const_index found without a "
                                       "compile unit being specified");
      }
      uint64_t index = opcodes.GetULEB128(&offset);
      lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
      stack.push_back(Scalar(value));
    } break;

    case DW_OP_GNU_entry_value:
    case DW_OP_entry_value: {
      if (llvm::Error err = Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx,
                                                       opcodes, offset, log))
        return llvm::createStringError(
            "could not evaluate DW_OP_entry_value: %s",
            llvm::toString(std::move(err)).c_str());
      break;
    }

    default:
      if (dwarf_cu) {
        if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, stack)) {
          break;
        }
      }
      return llvm::createStringError(llvm::formatv(
          "Unhandled opcode {0} in DWARFExpression", LocationAtom(op)));
    }
  }

  if (stack.empty()) {
    // Nothing on the stack, check if we created a piece value from DW_OP_piece
    // or DW_OP_bit_piece opcodes
    if (pieces.GetBuffer().GetByteSize())
      return pieces;

    return llvm::createStringError("stack empty after evaluation");
  }

  UpdateValueTypeFromLocationDescription(
      log, dwarf_cu, dwarf4_location_description_kind, &stack.back());

  if (log && log->GetVerbose()) {
    size_t count = stack.size();
    LLDB_LOGF(log,
              "Stack after operation has %" PRIu64 " values:", (uint64_t)count);
    for (size_t i = 0; i < count; ++i) {
      StreamString new_value;
      new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
      stack[i].Dump(&new_value);
      LLDB_LOGF(log, "  %s", new_value.GetData());
    }
  }
  return stack.back();
}

bool DWARFExpression::MatchesOperand(
    StackFrame &frame, const Instruction::Operand &operand) const {
  using namespace OperandMatchers;

  RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
  if (!reg_ctx_sp) {
    return false;
  }

  DataExtractor opcodes(m_data);

  lldb::offset_t op_offset = 0;
  uint8_t opcode = opcodes.GetU8(&op_offset);

  if (opcode == DW_OP_fbreg) {
    int64_t offset = opcodes.GetSLEB128(&op_offset);

    DWARFExpressionList *fb_expr = frame.GetFrameBaseExpression(nullptr);
    if (!fb_expr) {
      return false;
    }

    auto recurse = [&frame, fb_expr](const Instruction::Operand &child) {
      return fb_expr->MatchesOperand(frame, child);
    };

    if (!offset &&
        MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),
                     recurse)(operand)) {
      return true;
    }

    return MatchUnaryOp(
        MatchOpType(Instruction::Operand::Type::Dereference),
        MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
                      MatchImmOp(offset), recurse))(operand);
  }

  bool dereference = false;
  const RegisterInfo *reg = nullptr;
  int64_t offset = 0;

  if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31) {
    reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_reg0);
  } else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31) {
    offset = opcodes.GetSLEB128(&op_offset);
    reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_breg0);
  } else if (opcode == DW_OP_regx) {
    uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset));
    reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num);
  } else if (opcode == DW_OP_bregx) {
    uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset));
    offset = opcodes.GetSLEB128(&op_offset);
    reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num);
  } else {
    return false;
  }

  if (!reg) {
    return false;
  }

  if (dereference) {
    if (!offset &&
        MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),
                     MatchRegOp(*reg))(operand)) {
      return true;
    }

    return MatchUnaryOp(
        MatchOpType(Instruction::Operand::Type::Dereference),
        MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
                      MatchRegOp(*reg),
                      MatchImmOp(offset)))(operand);
  } else {
    return MatchRegOp(*reg)(operand);
  }
}
