//===-- 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::IsImplicit(
    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));

    switch (op) {
    // Implicit locations have no storage in the inferior. Composite locations
    // might, but we conservatively treat them as non-writable because LLDB
    // does not write their pieces back.
    case DW_OP_stack_value:
    case DW_OP_implicit_value:
    case DW_OP_implicit_pointer:
    case DW_OP_piece:
    case DW_OP_bit_piece:
      return true;
    default:
      break;
    }

    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 == 0 || 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 {
    if (!eval_ctx.dwarf_cu)
      return llvm::createStringError(
          "DW_OP_convert with a DIE offset requires a DWARF unit");
    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();
}

static llvm::Error CheckScalarOperandsHaveSameType(const Scalar &lhs,
                                                   const Scalar &rhs,
                                                   LocationAtom opcode,
                                                   size_t address_size) {
  auto mismatch = [&](const char *what) {
    return llvm::createStringError("%s requires operands to have the same %s",
                                   DW_OP_value_to_name(opcode), what);
  };

  // Scalar does not preserve the original DWARF DIE, but it does carry the
  // pieces of base-type information used by the evaluator: kind, size, and
  // integer signedness.
  if (lhs.GetType() != rhs.GetType())
    return mismatch("type");

  // Only integer scalars have signedness. Non-integer operands (e.g. floats)
  // have no further scalar type information to compare once kind and size
  // match.
  if (lhs.GetType() != Scalar::e_int) {
    if (lhs.GetByteSize() != rhs.GetByteSize())
      return mismatch("size");
    return llvm::Error::success();
  }

  // DWARF generic values are address-sized integers with unspecified
  // signedness. LLDB does not explicitly preserve genericness on the
  // expression stack, so treat integers at least as wide as the generic type
  // as potentially generic and compatible with one another, regardless of
  // exact width or signedness. This keeps common expressions working: e.g.
  // DW_OP_breg produces a register-sized value while DW_OP_const* produces an
  // address-sized one, yet both are meant to be generic. DW_OP_constu and
  // DW_OP_consts also do not always use to_generic due to
  // https://github.com/llvm/llvm-project/issues/47431. A precise fix would
  // require tracking genericness directly, which is a larger type-system
  // change.
  if (address_size != 0 && lhs.GetByteSize() >= address_size &&
      rhs.GetByteSize() >= address_size)
    return llvm::Error::success();

  // For non-generic integer operands, size and signedness are part of the
  // base-type information preserved by Scalar, so require them to match.
  if (lhs.GetByteSize() != rhs.GetByteSize())
    return mismatch("size");
  if (lhs.IsSigned() != rhs.IsSigned())
    return mismatch("signedness");

  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)));
      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;
    case DW_OP_constu:
      stack.push_back(to_generic(op->getRawOperand(0)));
      break;
    case DW_OP_consts:
      stack.push_back(to_generic(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:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() & tmp.GetScalar();
      break;

    case DW_OP_div: {
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      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:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() - tmp.GetScalar();
      break;

    case DW_OP_mod:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() % tmp.GetScalar();
      break;

    case DW_OP_mul:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      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:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() = stack.back().GetScalar() | tmp.GetScalar();
      break;

    case DW_OP_plus:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      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:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() <<= tmp.GetScalar();
      break;

    case DW_OP_shr:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      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:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() >>= tmp.GetScalar();
      break;

    case DW_OP_xor:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      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:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() =
          to_generic(stack.back().GetScalar() == tmp.GetScalar());
      break;

    case DW_OP_ge:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() =
          to_generic(stack.back().GetScalar() >= tmp.GetScalar());
      break;

    case DW_OP_gt:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() =
          to_generic(stack.back().GetScalar() > tmp.GetScalar());
      break;

    case DW_OP_le:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() =
          to_generic(stack.back().GetScalar() <= tmp.GetScalar());
      break;

    case DW_OP_lt:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() =
          to_generic(stack.back().GetScalar() < tmp.GetScalar());
      break;

    case DW_OP_ne:
      if (llvm::Error err = CheckScalarOperandsHaveSameType(
              stack[stack.size() - 2].GetScalar(), stack.back().GetScalar(),
              opcode, address_size))
        return err;
      tmp = stack.back();
      stack.pop_back();
      stack.back().GetScalar() =
          to_generic(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));
      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);
  }
}
