//===-- 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
//
//===----------------------------------------------------------------------===//
//
// The DWARF expression opcodes evaluated in this file are defined by the DWARF
// Debugging Information Format specification, available at:
//
//   https://dwarfstd.org/
//
//===----------------------------------------------------------------------===//

#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/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"
#include "llvm/Support/ErrorExtras.h"

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

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*/
};

/// Aggregates the inputs, derived pointers, and mutable evaluation state for
/// a single DWARF expression evaluation. Passed by reference to every helper
/// so they don't need to re-thread these individually.
struct EvalContext {
  ExecutionContext *exe_ctx;
  RegisterContext *reg_ctx;
  lldb::ModuleSP module_sp;
  const DWARFExpression::Delegate *dwarf_cu;
  lldb::RegisterKind reg_kind;
  const Value *initial_value_ptr;
  const Value *object_address_ptr;
  Process *process = nullptr;
  Target *target = nullptr;
  StackFrame *frame = nullptr;

  /// Mutable evaluation state.
  /// @{
  std::vector<Value> stack;
  Value pieces;
  uint64_t op_piece_offset = 0;
  LocationDescriptionKind loc_desc_kind = Memory;
  /// @}

  EvalContext(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
              lldb::ModuleSP module_sp,
              const DWARFExpression::Delegate *dwarf_cu,
              lldb::RegisterKind reg_kind, const Value *initial_value_ptr,
              const Value *object_address_ptr)
      : exe_ctx(exe_ctx), reg_ctx(reg_ctx), module_sp(std::move(module_sp)),
        dwarf_cu(dwarf_cu), reg_kind(reg_kind),
        initial_value_ptr(initial_value_ptr),
        object_address_ptr(object_address_ptr) {
    if (exe_ctx) {
      process = exe_ctx->GetProcessPtr();
      frame = exe_ctx->GetFramePtr();
      target = exe_ctx->GetTargetPtr();
    }
    if (this->reg_ctx == nullptr && frame)
      this->reg_ctx = frame->GetRegisterContext().get();
  }
};
} // namespace

// 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,
                                   llvm::DIDumpOptions options) 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 {};
  };
  options.GetNameForDWARFReg = GetRegName;
  llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
  llvm::printDwarfExpression(&E, s->AsRawOstream(), options, nullptr);
}

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

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

llvm::Error
DWARFExpression::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.GetULEB128(&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(EvalContext &eval_ctx,
                                              llvm::ArrayRef<uint8_t> subexpr) {
  Log *log = GetLog(LLDBLog::Expressions);
  // 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 ((!eval_ctx.exe_ctx || !eval_ctx.exe_ctx->HasTargetScope()) ||
      !eval_ctx.reg_ctx) {
    return llvm::createStringError("no exe/reg context");
  }

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

  Target &target = eval_ctx.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 = *eval_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::createStringErrorV(
          "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 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.size());
    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.size()) == 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;

  // Recurse through the public entry point so the call-site parameter is
  // evaluated with a fresh EvalContext (separate stack and piece state).
  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();
  }

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

/// Adjust value's ValueType according to the kind of location description.
static void UpdateValueTypeFromLocationDescription(EvalContext &eval_ctx,
                                                   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 (eval_ctx.dwarf_cu && eval_ctx.dwarf_cu->GetVersion() >= 4) {
    Log *log = GetLog(LLDBLog::Expressions);
    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;
    }
  }
}

/// Helper function to move common code used to resolve a file address and turn
/// into a load address.
///
/// \param eval_ctx Evaluation context (provides exe_ctx and module_sp).
/// \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(EvalContext &eval_ctx, const char *dw_op_type,
                   lldb::addr_t file_addr, Address &so_addr,
                   bool check_sectionoffset = false) {
  if (!eval_ctx.module_sp)
    return llvm::createStringError("need module to resolve file address for %s",
                                   dw_op_type);

  if (!eval_ctx.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(eval_ctx.target);

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

  return load_addr;
}

/// @brief Helper function to load sized data from a uint8_t buffer.
///
/// @param addr_bytes The buffer containing raw data.
/// @param size_addr_bytes How large is the underlying raw data.
/// @param byte_order What is the byte order of the underlying 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);
  return addr_data.GetAddress(&addr_data_offset);
}

static llvm::Error Evaluate_DW_OP_deref(EvalContext &eval_ctx,
                                        LocationAtom opcode, unsigned size,
                                        size_t size_addr_bytes) {
  const char *op_name = DW_OP_value_to_name(opcode);
  if (eval_ctx.stack.empty())
    return llvm::createStringError("expression stack empty for %s", op_name);

  if (size > 8)
    return llvm::createStringError("Invalid address size for %s: %u", op_name,
                                   size);

  if (opcode == DW_OP_deref_size && size > size_addr_bytes)
    return llvm::createStringError(
        "DW_OP_deref_size size (%u) exceeds address size (%zu)", size,
        size_addr_bytes);

  // Deref a register or implicit location and truncate the value to `size`
  // bytes. See the corresponding comment in DW_OP_deref for more details on
  // why we deref these locations this way.
  if (eval_ctx.loc_desc_kind == Register ||
      eval_ctx.loc_desc_kind == Implicit) {
    // Reset context to default values.
    eval_ctx.loc_desc_kind = Memory;
    eval_ctx.stack.back().ClearContext();

    // Truncate the value on top of the stack to *size* bytes then
    // extend to the size of an address (e.g. generic type).
    Scalar scalar = eval_ctx.stack.back().GetScalar();
    scalar.TruncOrExtendTo(size * 8, /*sign=*/false);
    scalar.TruncOrExtendTo(size_addr_bytes * 8,
                           /*sign=*/false);
    eval_ctx.stack.back().GetScalar() = scalar;
    return llvm::Error::success();
  }

  Value::ValueType value_type = eval_ctx.stack.back().GetValueType();
  switch (value_type) {
  case Value::ValueType::HostAddress: {
    void *src = (void *)eval_ctx.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;
    }
    eval_ctx.stack.back().GetScalar() = ptr;
    eval_ctx.stack.back().ClearContext();
  } break;
  case Value::ValueType::FileAddress: {
    auto file_addr =
        eval_ctx.stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
    Address so_addr;
    auto maybe_load_addr =
        ResolveLoadAddress(eval_ctx, op_name, 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 (!eval_ctx.target ||
          eval_ctx.target->ReadMemory(so_addr, &addr_bytes, size, error,
                                      /*force_live_memory=*/false) != size)
        return llvm::createStringError("failed to dereference pointer for %s: "
                                       "%s\n",
                                       op_name, error.AsCString());

      ObjectFile *objfile = eval_ctx.module_sp->GetObjectFile();

      eval_ctx.stack.back().GetScalar() = DerefSizeExtractDataHelper(
          addr_bytes, size, objfile->GetByteOrder(), size);
      eval_ctx.stack.back().ClearContext();
      break;
    }
    eval_ctx.stack.back().GetScalar() = load_addr;
    // Fall through to load address promotion code below.
  }

    [[fallthrough]];
  case Value::ValueType::Scalar:
    // Promote Scalar to LoadAddress and fall through.
    eval_ctx.stack.back().SetValueType(Value::ValueType::LoadAddress);
    [[fallthrough]];
  case Value::ValueType::LoadAddress: {
    if (!eval_ctx.exe_ctx)
      return llvm::createStringError("no execution context for %s", op_name);
    if (!eval_ctx.process)
      return llvm::createStringError("no process for %s", op_name);

    lldb::addr_t pointer_addr =
        eval_ctx.stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
    uint8_t addr_bytes[sizeof(lldb::addr_t)];
    Status error;

    if (eval_ctx.process->ReadMemory(pointer_addr, &addr_bytes, size, error) !=
        size)
      return llvm::createStringError(
          "failed to dereference pointer from 0x%" PRIx64 " for %s: %s\n",
          pointer_addr, op_name, error.AsCString());

    eval_ctx.stack.back().GetScalar() = DerefSizeExtractDataHelper(
        addr_bytes, sizeof(addr_bytes), eval_ctx.process->GetByteOrder(), size);
    eval_ctx.stack.back().ClearContext();
  } break;

  case Value::ValueType::Invalid:
    return llvm::createStringError("invalid value for %s", op_name);
  }

  return llvm::Error::success();
}

static llvm::Error Evaluate_DW_OP_piece(EvalContext &eval_ctx,
                                        uint64_t piece_byte_size) {
  LocationDescriptionKind piece_locdesc = eval_ctx.loc_desc_kind;
  // Reset for the next piece.
  eval_ctx.loc_desc_kind = Memory;

  if (piece_byte_size == 0)
    return llvm::Error::success();

  Value curr_piece;

  if (eval_ctx.stack.empty()) {
    UpdateValueTypeFromLocationDescription(eval_ctx,
                                           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);
    eval_ctx.pieces.AppendDataToHostBuffer(curr_piece);
  } else {
    Status error;
    // Extract the current piece into "curr_piece"
    Value curr_piece_source_value(eval_ctx.stack.back());
    eval_ctx.stack.pop_back();
    UpdateValueTypeFromLocationDescription(eval_ctx, 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 (eval_ctx.target) {
        curr_piece_source_value.ConvertToLoadAddress(eval_ctx.module_sp.get(),
                                                     eval_ctx.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 (eval_ctx.target) {
        if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {
          if (eval_ctx.target->ReadMemory(
                  Address(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());
      }

      // We have seen a case where we have expression like:
      //      DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x28
      // here we are assuming the compiler was trying to zero
      // extend the value that we should append to the buffer.
      scalar.TruncOrExtendTo(bit_size, /*sign=*/false);
      curr_piece.GetScalar() = scalar;
    } break;
    }

    // Check if this is the first piece?
    if (eval_ctx.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 (eval_ctx.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 (eval_ctx.pieces.GetBuffer().GetByteSize() !=
          eval_ctx.op_piece_offset) {
        return llvm::createStringError(
            "DW_OP_piece for offset %" PRIu64
            " but top of stack is of size %" PRIu64,
            eval_ctx.op_piece_offset,
            eval_ctx.pieces.GetBuffer().GetByteSize());
      }

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

static llvm::Error Evaluate_DW_OP_convert(EvalContext &eval_ctx,
                                          uint64_t relative_die_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 (!eval_ctx.module_sp)
      return llvm::createStringError("no module");
    sign = false;
    bit_size = eval_ctx.module_sp->GetArchitecture().GetAddressByteSize() * 8;
    if (!bit_size)
      return llvm::createStringError("unspecified architecture");
  } else {
    auto bit_size_sign_or_err =
        eval_ctx.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;
  }
  eval_ctx.stack.back().GetScalar().TruncOrExtendTo(bit_size, sign);
  return llvm::Error::success();
}

static llvm::Error Evaluate_DW_OP_form_tls_address(EvalContext &eval_ctx,
                                                   LocationAtom opcode) {
  if (eval_ctx.stack.empty())
    return llvm::createStringError("%s needs an argument",
                                   opcode == DW_OP_form_tls_address
                                       ? "DW_OP_form_tls_address"
                                       : "DW_OP_GNU_push_tls_address");

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

  Thread *thread = eval_ctx.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 =
      eval_ctx.stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
  const addr_t tls_load_addr =
      thread->GetThreadLocalData(eval_ctx.module_sp, tls_file_addr);

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

  eval_ctx.stack.back().GetScalar() = tls_load_addr;
  eval_ctx.stack.back().SetValueType(Value::ValueType::LoadAddress);
  return llvm::Error::success();
}

static llvm::Error Evaluate_DW_OP_fbreg(EvalContext &eval_ctx,
                                        int64_t fbreg_offset) {
  if (!eval_ctx.exe_ctx)
    return llvm::createStringError("NULL execution context for DW_OP_fbreg");
  if (!eval_ctx.frame)
    return llvm::createStringError(
        "invalid stack frame in context for DW_OP_fbreg opcode");

  Scalar value;
  if (llvm::Error err = eval_ctx.frame->GetFrameBaseValue(value))
    return err;
  value += fbreg_offset;
  eval_ctx.stack.push_back(value);
  eval_ctx.stack.back().SetValueType(Value::ValueType::LoadAddress);
  return llvm::Error::success();
}

static llvm::Error Evaluate_DW_OP_call_frame_cfa(EvalContext &eval_ctx) {
  if (!eval_ctx.frame)
    return llvm::createStringError(
        "invalid stack frame in context for DW_OP_call_frame_cfa opcode");

  // Note that we don't have to parse FDEs because this DWARF expression
  // is commonly evaluated with a valid stack frame.
  StackID id = eval_ctx.frame->GetStackID();
  addr_t cfa = id.GetCallFrameAddressWithMetadata();
  if (cfa == LLDB_INVALID_ADDRESS)
    return llvm::createStringError("stack frame does not include a canonical "
                                   "frame address for DW_OP_call_frame_cfa "
                                   "opcode");

  eval_ctx.stack.push_back(Scalar(cfa));
  eval_ctx.stack.back().SetValueType(Value::ValueType::LoadAddress);
  return llvm::Error::success();
}

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) {
  uint32_t address_size = opcodes.GetAddressByteSize();
  llvm::DataExtractor expr_data = opcodes.GetAsLLVM();
  llvm::DWARFExpression expr(expr_data, address_size);

  if (expr_data.size() == 0)
    return llvm::createStringError(
        "no location, value may have been optimized out");

  EvalContext eval_ctx(exe_ctx, reg_ctx, std::move(module_sp), dwarf_cu,
                       reg_kind, initial_value_ptr, object_address_ptr);

  Stack &stack = eval_ctx.stack;

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

  Value tmp;
  uint32_t reg_num;

  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 * address_size, v, is_signed, /*implicitTrunc=*/true),
        !is_signed));
  };

  llvm::DWARFExpression::iterator op = expr.begin(), op_end = expr.end();
  while (op != op_end) {
    const uint64_t op_offset = op.getOffset();
    const LocationAtom opcode = static_cast<LocationAtom>(op->getCode());

    if (log && log->GetVerbose()) {
      size_t count = stack.size();
      LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:",
                static_cast<uint64_t>(count));
      for (size_t i = 0; i < count; ++i) {
        StreamString new_value;
        new_value.Printf("[%" PRIu64 "]", static_cast<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(opcode));
    }

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

    switch (opcode) {
    case DW_OP_addr:
      stack.push_back(Scalar(op->getRawOperand(0)));
      if (eval_ctx.target && eval_ctx.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;

    case DW_OP_deref: {
      size_t size = address_size;
      if (llvm::Error err = Evaluate_DW_OP_deref(eval_ctx, opcode, size, size))
        return err;
    } break;

    case DW_OP_deref_size: {
      size_t size = op->getRawOperand(0);
      if (llvm::Error err =
              Evaluate_DW_OP_deref(eval_ctx, opcode, size, address_size))
        return err;
    } break;

    case DW_OP_xderef_size:
      return llvm::createStringError("unimplemented opcode: DW_OP_xderef_size");
    case DW_OP_xderef:
      return llvm::createStringError("unimplemented opcode: DW_OP_xderef");

    case DW_OP_const1u:
      stack.push_back(to_generic(op->getRawOperand(0)));
      break;
    case DW_OP_const1s:
      stack.push_back(to_generic(static_cast<int8_t>(op->getRawOperand(0))));
      break;
    case DW_OP_const2u:
      stack.push_back(to_generic(op->getRawOperand(0)));
      break;
    case DW_OP_const2s:
      stack.push_back(to_generic(static_cast<int16_t>(op->getRawOperand(0))));
      break;
    case DW_OP_const4u:
      stack.push_back(to_generic(op->getRawOperand(0)));
      break;
    case DW_OP_const4s:
      stack.push_back(to_generic(static_cast<int32_t>(op->getRawOperand(0))));
      break;
    case DW_OP_const8u:
      stack.push_back(to_generic(op->getRawOperand(0)));
      break;
    case DW_OP_const8s:
      stack.push_back(to_generic(static_cast<int64_t>(op->getRawOperand(0))));
      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(op->getRawOperand(0)));
      break;
    case DW_OP_consts:
      stack.push_back(Scalar(static_cast<int64_t>(op->getRawOperand(0))));
      break;

    case DW_OP_dup:
      if (stack.empty()) {
        return llvm::createStringError("expression stack empty for DW_OP_dup");
      } else
        stack.push_back(stack.back());
      break;

    case DW_OP_drop:
      if (stack.empty()) {
        return llvm::createStringError("expression stack empty for DW_OP_drop");
      } else
        stack.pop_back();
      break;

    case DW_OP_over:
      stack.push_back(stack[stack.size() - 2]);
      break;

    case DW_OP_pick: {
      uint8_t pick_idx = op->getRawOperand(0);
      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;

    case DW_OP_swap:
      tmp = stack.back();
      stack.back() = stack[stack.size() - 2];
      stack[stack.size() - 2] = tmp;
      break;

    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;

    case DW_OP_abs:
      if (!stack.back().GetScalar().AbsoluteValue()) {
        return llvm::createStringError(
            "failed to take the absolute value of the first stack item");
      }
      break;

    case DW_OP_and:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() & tmp.GetScalar();
      break;

    case DW_OP_div: {
      tmp = stack.back();
      if (tmp.GetScalar().IsZero())
        return llvm::createStringError("divide by zero");

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

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

    case DW_OP_minus:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() - tmp.GetScalar();
      break;

    case DW_OP_mod:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() % tmp.GetScalar();
      break;

    case DW_OP_mul:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() * tmp.GetScalar();
      break;

    case DW_OP_neg:
      if (!stack.back().GetScalar().UnaryNegate())
        return llvm::createStringError("unary negate failed");
      break;

    case DW_OP_not:
      if (!stack.back().GetScalar().OnesComplement())
        return llvm::createStringError("logical NOT failed");
      break;

    case DW_OP_or:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() | tmp.GetScalar();
      break;

    case DW_OP_plus:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() += tmp.GetScalar();
      break;

    case DW_OP_plus_uconst: {
      const uint64_t uconst_value = op->getRawOperand(0);
      // 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;

    case DW_OP_shl:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() <<= tmp.GetScalar();
      break;

    case DW_OP_shr:
      tmp = stack.back();
      stack.pop_back();
      if (!stack.back().GetScalar().ShiftRightLogical(tmp.GetScalar()))
        return llvm::createStringError("DW_OP_shr failed");
      break;

    case DW_OP_shra:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() >>= tmp.GetScalar();
      break;

    case DW_OP_xor:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() ^ tmp.GetScalar();
      break;

    case DW_OP_skip: {
      int16_t skip_offset = static_cast<int16_t>(op->getRawOperand(0));
      lldb::offset_t new_offset = op->getEndOffset() + 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 <= expr_data.size()) {
        op = op.skipBytes(skip_offset);
        continue;
      }
      return llvm::createStringErrorV(
          "Invalid opcode offset in DW_OP_skip: {0}+({1}) > {2}",
          op->getEndOffset(), skip_offset, expr_data.size());
    }

    case DW_OP_bra: {
      tmp = stack.back();
      stack.pop_back();
      int16_t bra_offset = static_cast<int16_t>(op->getRawOperand(0));
      Scalar zero(0);
      if (tmp.GetScalar() != zero) {
        lldb::offset_t new_offset = op->getEndOffset() + 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 <= expr_data.size()) {
          op = op.skipBytes(bra_offset);
          continue;
        }
        return llvm::createStringErrorV(
            "Invalid opcode offset in DW_OP_bra: {0}+({1}) > {2}",
            op->getEndOffset(), bra_offset, expr_data.size());
      }
    } break;

    case DW_OP_eq:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() == tmp.GetScalar();
      break;

    case DW_OP_ge:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() >= tmp.GetScalar();
      break;

    case DW_OP_gt:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() > tmp.GetScalar();
      break;

    case DW_OP_le:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() <= tmp.GetScalar();
      break;

    case DW_OP_lt:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() < tmp.GetScalar();
      break;

    case DW_OP_ne:
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() != tmp.GetScalar();
      break;

    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(opcode - DW_OP_lit0));
      break;

    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: {
      eval_ctx.loc_desc_kind = Register;
      reg_num = opcode - DW_OP_reg0;

      if (llvm::Error err = ReadRegisterValueAsScalar(
              eval_ctx.reg_ctx, eval_ctx.reg_kind, reg_num, tmp))
        return err;
      stack.push_back(tmp);
    } break;
    case DW_OP_regx: {
      eval_ctx.loc_desc_kind = Register;
      reg_num = op->getRawOperand(0);
      Status read_err;
      if (llvm::Error err = ReadRegisterValueAsScalar(
              eval_ctx.reg_ctx, eval_ctx.reg_kind, reg_num, tmp))
        return err;
      stack.push_back(tmp);
    } break;

    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 = opcode - DW_OP_breg0;
      if (llvm::Error err = ReadRegisterValueAsScalar(
              eval_ctx.reg_ctx, eval_ctx.reg_kind, reg_num, tmp))
        return err;

      int64_t breg_offset = op->getRawOperand(0);
      tmp.GetScalar() += static_cast<uint64_t>(breg_offset);
      tmp.ClearContext();
      stack.push_back(tmp);
      stack.back().SetValueType(Value::ValueType::LoadAddress);
    } break;
    case DW_OP_bregx: {
      reg_num = op->getRawOperand(0);
      if (llvm::Error err = ReadRegisterValueAsScalar(
              eval_ctx.reg_ctx, eval_ctx.reg_kind, reg_num, tmp))
        return err;

      int64_t breg_offset = op->getRawOperand(1);
      tmp.GetScalar() += static_cast<uint64_t>(breg_offset);
      tmp.ClearContext();
      stack.push_back(tmp);
      stack.back().SetValueType(Value::ValueType::LoadAddress);
    } break;

    case DW_OP_fbreg:
      if (llvm::Error err =
              Evaluate_DW_OP_fbreg(eval_ctx, op->getRawOperand(0)))
        return err;
      break;

    case DW_OP_nop:
      break;

    case DW_OP_piece: {
      if (llvm::Error err =
              Evaluate_DW_OP_piece(eval_ctx, op->getRawOperand(0)))
        return err;
    } break;

    case DW_OP_bit_piece:
      if (stack.size() < 1) {
        UpdateValueTypeFromLocationDescription(eval_ctx,
                                               LocationDescriptionKind::Empty);
        // Reset for the next piece.
        eval_ctx.loc_desc_kind = Memory;
        return llvm::createStringError(
            "expression stack needs at least 1 item for DW_OP_bit_piece");
      } else {
        UpdateValueTypeFromLocationDescription(eval_ctx, eval_ctx.loc_desc_kind,
                                               &stack.back());
        // Reset for the next piece.
        eval_ctx.loc_desc_kind = Memory;
        const uint64_t piece_bit_size = op->getRawOperand(0);
        const uint64_t piece_bit_offset = op->getRawOperand(1);
        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;

    case DW_OP_implicit_value: {
      eval_ctx.loc_desc_kind = Implicit;

      // The second operand is a sequence of bytes of the length specified by
      // the first operand. LLVM represents it as an offset to that sequence.
      const uint64_t block_size = op->getRawOperand(0);
      uint64_t block_offset = op->getRawOperand(1);

      llvm::Error error = llvm::Error::success();
      llvm::StringRef block_data =
          expr_data.getBytes(&block_offset, block_size, &error);

      if (error)
        return error;

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

    case DW_OP_implicit_pointer: {
      eval_ctx.loc_desc_kind = Implicit;
      return llvm::createStringError("could not evaluate %s",
                                     DW_OP_value_to_name(opcode));
    }

    case DW_OP_push_object_address:
      if (eval_ctx.object_address_ptr)
        stack.push_back(*eval_ctx.object_address_ptr);
      else {
        return llvm::createStringError("DW_OP_push_object_address used without "
                                       "specifying an object address");
      }
      break;

    case DW_OP_call2:
      return llvm::createStringError("unimplemented opcode DW_OP_call2");
    case DW_OP_call4:
      return llvm::createStringError("unimplemented opcode DW_OP_call4");

    case DW_OP_stack_value:
      eval_ctx.loc_desc_kind = Implicit;
      stack.back().SetValueType(Value::ValueType::Scalar);
      break;

    case DW_OP_convert:
      if (llvm::Error err =
              Evaluate_DW_OP_convert(eval_ctx, op->getRawOperand(0)))
        return err;
      break;

    case DW_OP_call_frame_cfa:
      if (llvm::Error err = Evaluate_DW_OP_call_frame_cfa(eval_ctx))
        return err;
      break;

    case DW_OP_form_tls_address:
    case DW_OP_GNU_push_tls_address:
      if (llvm::Error err = Evaluate_DW_OP_form_tls_address(eval_ctx, opcode))
        return err;
      break;

    case DW_OP_addrx:
    case DW_OP_GNU_addr_index: {
      if (!eval_ctx.dwarf_cu)
        return llvm::createStringError("DW_OP_GNU_addr_index found without a "
                                       "compile unit being specified");
      uint64_t index = op->getRawOperand(0);
      lldb::addr_t value =
          eval_ctx.dwarf_cu->ReadAddressFromDebugAddrSection(index);
      stack.push_back(Scalar(value));
      if (eval_ctx.target && eval_ctx.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;

    case DW_OP_GNU_const_index: {
      if (!eval_ctx.dwarf_cu) {
        return llvm::createStringError("DW_OP_GNU_const_index found without a "
                                       "compile unit being specified");
      }
      uint64_t index = op->getRawOperand(0);
      lldb::addr_t value =
          eval_ctx.dwarf_cu->ReadAddressFromDebugAddrSection(index);
      stack.push_back(Scalar(value));
    } break;

    case DW_OP_GNU_entry_value:
    case DW_OP_entry_value: {
      // Technically, DW_OP_entry_value has two operands, but LLVM represents
      // it as a single-operand operation (bug?). We can deal with this: the
      // second operand immediately follows the first, but have to be careful
      // when advancing the iterator, see the comment below.
      const uint64_t block_size = op->getRawOperand(0);
      uint64_t block_offset = op->getEndOffset();

      llvm::Error error = llvm::Error::success();
      llvm::ArrayRef<uint8_t> block_data = llvm::arrayRefFromStringRef(
          expr_data.getBytes(&block_offset, block_size, &error));

      if (error)
        return error;

      if (llvm::Error err = Evaluate_DW_OP_entry_value(eval_ctx, block_data))
        return llvm::createStringError(
            "could not evaluate DW_OP_entry_value: %s",
            llvm::toString(std::move(err)).c_str());

      // We can't use `operator++` here because the iterator currently points
      // to the second operand. See the comment above.
      op = op.skipBytes(block_size);
      continue;
    }

    default:
      if (eval_ctx.dwarf_cu) {
        const uint64_t operands_offset = op_offset + 1;
        uint64_t offset = operands_offset; // Updated by the callee.
        if (eval_ctx.dwarf_cu->ParseVendorDWARFOpcode(
                opcode, expr_data, offset, eval_ctx.reg_ctx, eval_ctx.reg_kind,
                stack)) {
          // This is a little tricky. If LLVM knows about this vendor-specific
          // operation, `getEndOffset()` points past its last operand. If LLVM
          // knows nothing about this operation, `getEndOffset()` points to its
          // opcode. In both cases `offset` will point to the next operation,
          // but we can't use it directly because the only available mutating
          // method of `iterator` (not counting `operator++`) is `skipBytes()`.
          // So we calculate the offset and pass it to `skipBytes()`.
          assert(offset >= op->getEndOffset());
          uint64_t offset_to_next_op = offset - op->getEndOffset();
          op = op.skipBytes(offset_to_next_op);
          continue;
        }
      }
      return llvm::createStringErrorV("unhandled opcode {0} in DWARFExpression",
                                      opcode);
    }
    ++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 (eval_ctx.pieces.GetBuffer().GetByteSize())
      return eval_ctx.pieces;

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

  UpdateValueTypeFromLocationDescription(eval_ctx, eval_ctx.loc_desc_kind,
                                         &stack.back());

  if (log && log->GetVerbose()) {
    size_t count = stack.size();
    LLDB_LOGF(log, "Stack after operation has %" PRIu64 " values:",
              static_cast<uint64_t>(count));
    for (size_t i = 0; i < count; ++i) {
      StreamString new_value;
      new_value.Printf("[%" PRIu64 "]", static_cast<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);
  }
}
