//===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Expression/DWARFExpression.h"

// C Includes
#include <inttypes.h>

// C++ Includes
#include <vector>

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

#include "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.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/Thread.h"

#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h"

using namespace lldb;
using namespace lldb_private;

static lldb::addr_t
ReadAddressFromDebugAddrSection(const DWARFCompileUnit *dwarf_cu,
                                uint32_t index) {
  uint32_t index_size = dwarf_cu->GetAddressByteSize();
  dw_offset_t addr_base = dwarf_cu->GetAddrBase();
  lldb::offset_t offset = addr_base + index * index_size;
  return dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(
      &offset, index_size);
}

//----------------------------------------------------------------------
// DWARFExpression constructor
//----------------------------------------------------------------------
DWARFExpression::DWARFExpression(DWARFCompileUnit *dwarf_cu)
    : m_module_wp(), m_data(), m_dwarf_cu(dwarf_cu),
      m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) {}

DWARFExpression::DWARFExpression(const DWARFExpression &rhs)
    : m_module_wp(rhs.m_module_wp), m_data(rhs.m_data),
      m_dwarf_cu(rhs.m_dwarf_cu), m_reg_kind(rhs.m_reg_kind),
      m_loclist_slide(rhs.m_loclist_slide) {}

DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp,
                                 const DataExtractor &data,
                                 DWARFCompileUnit *dwarf_cu,
                                 lldb::offset_t data_offset,
                                 lldb::offset_t data_length)
    : m_module_wp(), m_data(data, data_offset, data_length),
      m_dwarf_cu(dwarf_cu), m_reg_kind(eRegisterKindDWARF),
      m_loclist_slide(LLDB_INVALID_ADDRESS) {
  if (module_sp)
    m_module_wp = module_sp;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
DWARFExpression::~DWARFExpression() {}

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

void DWARFExpression::SetOpcodeData(const DataExtractor &data) {
  m_data = data;
}

void DWARFExpression::CopyOpcodeData(lldb::ModuleSP module_sp,
                                     const DataExtractor &data,
                                     lldb::offset_t data_offset,
                                     lldb::offset_t data_length) {
  const uint8_t *bytes = data.PeekData(data_offset, data_length);
  if (bytes) {
    m_module_wp = module_sp;
    m_data.SetData(DataBufferSP(new DataBufferHeap(bytes, data_length)));
    m_data.SetByteOrder(data.GetByteOrder());
    m_data.SetAddressByteSize(data.GetAddressByteSize());
  }
}

void DWARFExpression::CopyOpcodeData(const void *data,
                                     lldb::offset_t data_length,
                                     ByteOrder byte_order,
                                     uint8_t addr_byte_size) {
  if (data && data_length) {
    m_data.SetData(DataBufferSP(new DataBufferHeap(data, data_length)));
    m_data.SetByteOrder(byte_order);
    m_data.SetAddressByteSize(addr_byte_size);
  }
}

void DWARFExpression::CopyOpcodeData(uint64_t const_value,
                                     lldb::offset_t const_value_byte_size,
                                     uint8_t addr_byte_size) {
  if (const_value_byte_size) {
    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::SetOpcodeData(lldb::ModuleSP module_sp,
                                    const DataExtractor &data,
                                    lldb::offset_t data_offset,
                                    lldb::offset_t data_length) {
  m_module_wp = module_sp;
  m_data.SetData(data, data_offset, data_length);
}

void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset,
                                   lldb::offset_t length,
                                   lldb::DescriptionLevel level,
                                   ABI *abi) const {
  if (!m_data.ValidOffsetForDataOfSize(offset, length))
    return;
  const lldb::offset_t start_offset = offset;
  const lldb::offset_t end_offset = offset + length;
  while (m_data.ValidOffset(offset) && offset < end_offset) {
    const lldb::offset_t op_offset = offset;
    const uint8_t op = m_data.GetU8(&offset);

    switch (level) {
    default:
      break;

    case lldb::eDescriptionLevelBrief:
      if (offset > start_offset)
        s->PutChar(' ');
      break;

    case lldb::eDescriptionLevelFull:
    case lldb::eDescriptionLevelVerbose:
      if (offset > start_offset)
        s->EOL();
      s->Indent();
      if (level == lldb::eDescriptionLevelFull)
        break;
      // Fall through for verbose and print offset and DW_OP prefix..
      s->Printf("0x%8.8" PRIx64 ": %s", op_offset,
                op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
      break;
    }

    switch (op) {
    case DW_OP_addr:
      *s << "DW_OP_addr(" << m_data.GetAddress(&offset) << ") ";
      break; // 0x03 1 address
    case DW_OP_deref:
      *s << "DW_OP_deref";
      break; // 0x06
    case DW_OP_const1u:
      s->Printf("DW_OP_const1u(0x%2.2x) ", m_data.GetU8(&offset));
      break; // 0x08 1 1-byte constant
    case DW_OP_const1s:
      s->Printf("DW_OP_const1s(0x%2.2x) ", m_data.GetU8(&offset));
      break; // 0x09 1 1-byte constant
    case DW_OP_const2u:
      s->Printf("DW_OP_const2u(0x%4.4x) ", m_data.GetU16(&offset));
      break; // 0x0a 1 2-byte constant
    case DW_OP_const2s:
      s->Printf("DW_OP_const2s(0x%4.4x) ", m_data.GetU16(&offset));
      break; // 0x0b 1 2-byte constant
    case DW_OP_const4u:
      s->Printf("DW_OP_const4u(0x%8.8x) ", m_data.GetU32(&offset));
      break; // 0x0c 1 4-byte constant
    case DW_OP_const4s:
      s->Printf("DW_OP_const4s(0x%8.8x) ", m_data.GetU32(&offset));
      break; // 0x0d 1 4-byte constant
    case DW_OP_const8u:
      s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset));
      break; // 0x0e 1 8-byte constant
    case DW_OP_const8s:
      s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset));
      break; // 0x0f 1 8-byte constant
    case DW_OP_constu:
      s->Printf("DW_OP_constu(0x%" PRIx64 ") ", m_data.GetULEB128(&offset));
      break; // 0x10 1 ULEB128 constant
    case DW_OP_consts:
      s->Printf("DW_OP_consts(0x%" PRId64 ") ", m_data.GetSLEB128(&offset));
      break; // 0x11 1 SLEB128 constant
    case DW_OP_dup:
      s->PutCString("DW_OP_dup");
      break; // 0x12
    case DW_OP_drop:
      s->PutCString("DW_OP_drop");
      break; // 0x13
    case DW_OP_over:
      s->PutCString("DW_OP_over");
      break; // 0x14
    case DW_OP_pick:
      s->Printf("DW_OP_pick(0x%2.2x) ", m_data.GetU8(&offset));
      break; // 0x15 1 1-byte stack index
    case DW_OP_swap:
      s->PutCString("DW_OP_swap");
      break; // 0x16
    case DW_OP_rot:
      s->PutCString("DW_OP_rot");
      break; // 0x17
    case DW_OP_xderef:
      s->PutCString("DW_OP_xderef");
      break; // 0x18
    case DW_OP_abs:
      s->PutCString("DW_OP_abs");
      break; // 0x19
    case DW_OP_and:
      s->PutCString("DW_OP_and");
      break; // 0x1a
    case DW_OP_div:
      s->PutCString("DW_OP_div");
      break; // 0x1b
    case DW_OP_minus:
      s->PutCString("DW_OP_minus");
      break; // 0x1c
    case DW_OP_mod:
      s->PutCString("DW_OP_mod");
      break; // 0x1d
    case DW_OP_mul:
      s->PutCString("DW_OP_mul");
      break; // 0x1e
    case DW_OP_neg:
      s->PutCString("DW_OP_neg");
      break; // 0x1f
    case DW_OP_not:
      s->PutCString("DW_OP_not");
      break; // 0x20
    case DW_OP_or:
      s->PutCString("DW_OP_or");
      break; // 0x21
    case DW_OP_plus:
      s->PutCString("DW_OP_plus");
      break;                // 0x22
    case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend
      s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ") ",
                m_data.GetULEB128(&offset));
      break;

    case DW_OP_shl:
      s->PutCString("DW_OP_shl");
      break; // 0x24
    case DW_OP_shr:
      s->PutCString("DW_OP_shr");
      break; // 0x25
    case DW_OP_shra:
      s->PutCString("DW_OP_shra");
      break; // 0x26
    case DW_OP_xor:
      s->PutCString("DW_OP_xor");
      break; // 0x27
    case DW_OP_skip:
      s->Printf("DW_OP_skip(0x%4.4x)", m_data.GetU16(&offset));
      break; // 0x2f 1 signed 2-byte constant
    case DW_OP_bra:
      s->Printf("DW_OP_bra(0x%4.4x)", m_data.GetU16(&offset));
      break; // 0x28 1 signed 2-byte constant
    case DW_OP_eq:
      s->PutCString("DW_OP_eq");
      break; // 0x29
    case DW_OP_ge:
      s->PutCString("DW_OP_ge");
      break; // 0x2a
    case DW_OP_gt:
      s->PutCString("DW_OP_gt");
      break; // 0x2b
    case DW_OP_le:
      s->PutCString("DW_OP_le");
      break; // 0x2c
    case DW_OP_lt:
      s->PutCString("DW_OP_lt");
      break; // 0x2d
    case DW_OP_ne:
      s->PutCString("DW_OP_ne");
      break; // 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:
      s->Printf("DW_OP_lit%i", op - DW_OP_lit0);
      break; // 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
    {
      uint32_t reg_num = op - DW_OP_reg0;
      if (abi) {
        RegisterInfo reg_info;
        if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
          if (reg_info.name) {
            s->PutCString(reg_info.name);
            break;
          } else if (reg_info.alt_name) {
            s->PutCString(reg_info.alt_name);
            break;
          }
        }
      }
      s->Printf("DW_OP_reg%u", reg_num);
      break;
    } 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: {
      uint32_t reg_num = op - DW_OP_breg0;
      int64_t reg_offset = m_data.GetSLEB128(&offset);
      if (abi) {
        RegisterInfo reg_info;
        if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
          if (reg_info.name) {
            s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
            break;
          } else if (reg_info.alt_name) {
            s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
            break;
          }
        }
      }
      s->Printf("DW_OP_breg%i(0x%" PRIx64 ")", reg_num, reg_offset);
    } break;

    case DW_OP_regx: // 0x90 1 ULEB128 register
    {
      uint32_t reg_num = m_data.GetULEB128(&offset);
      if (abi) {
        RegisterInfo reg_info;
        if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
          if (reg_info.name) {
            s->PutCString(reg_info.name);
            break;
          } else if (reg_info.alt_name) {
            s->PutCString(reg_info.alt_name);
            break;
          }
        }
      }
      s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num);
      break;
    } break;
    case DW_OP_fbreg: // 0x91 1 SLEB128 offset
      s->Printf("DW_OP_fbreg(%" PRIi64 ")", m_data.GetSLEB128(&offset));
      break;
    case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset
    {
      uint32_t reg_num = m_data.GetULEB128(&offset);
      int64_t reg_offset = m_data.GetSLEB128(&offset);
      if (abi) {
        RegisterInfo reg_info;
        if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
          if (reg_info.name) {
            s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
            break;
          } else if (reg_info.alt_name) {
            s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
            break;
          }
        }
      }
      s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num,
                reg_offset);
    } break;
    case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed
      s->Printf("DW_OP_piece(0x%" PRIx64 ")", m_data.GetULEB128(&offset));
      break;
    case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved
      s->Printf("DW_OP_deref_size(0x%2.2x)", m_data.GetU8(&offset));
      break;
    case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved
      s->Printf("DW_OP_xderef_size(0x%2.2x)", m_data.GetU8(&offset));
      break;
    case DW_OP_nop:
      s->PutCString("DW_OP_nop");
      break; // 0x96
    case DW_OP_push_object_address:
      s->PutCString("DW_OP_push_object_address");
      break;          // 0x97 DWARF3
    case DW_OP_call2: // 0x98 DWARF3 1 2-byte offset of DIE
      s->Printf("DW_OP_call2(0x%4.4x)", m_data.GetU16(&offset));
      break;
    case DW_OP_call4: // 0x99 DWARF3 1 4-byte offset of DIE
      s->Printf("DW_OP_call4(0x%8.8x)", m_data.GetU32(&offset));
      break;
    case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE
      s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset));
      break;
    //      case DW_OP_call_frame_cfa: s << "call_frame_cfa"; break;
    //      // 0x9c DWARF3
    //      case DW_OP_bit_piece: // 0x9d DWARF3 2
    //          s->Printf("DW_OP_bit_piece(0x%x, 0x%x)",
    //          m_data.GetULEB128(&offset), m_data.GetULEB128(&offset));
    //          break;
    //      case DW_OP_lo_user:     s->PutCString("DW_OP_lo_user"); break;
    //      // 0xe0
    //      case DW_OP_hi_user:     s->PutCString("DW_OP_hi_user"); break;
    //      // 0xff
    //        case DW_OP_APPLE_extern:
    //            s->Printf("DW_OP_APPLE_extern(%" PRIu64 ")",
    //            m_data.GetULEB128(&offset));
    //            break;
    //        case DW_OP_APPLE_array_ref:
    //            s->PutCString("DW_OP_APPLE_array_ref");
    //            break;
    case DW_OP_form_tls_address:
      s->PutCString("DW_OP_form_tls_address"); // 0x9b
      break;
    case DW_OP_GNU_addr_index: // 0xfb
      s->Printf("DW_OP_GNU_addr_index(0x%" PRIx64 ")",
                m_data.GetULEB128(&offset));
      break;
    case DW_OP_GNU_const_index: // 0xfc
      s->Printf("DW_OP_GNU_const_index(0x%" PRIx64 ")",
                m_data.GetULEB128(&offset));
      break;
    case DW_OP_GNU_push_tls_address:
      s->PutCString("DW_OP_GNU_push_tls_address"); // 0xe0
      break;
    case DW_OP_APPLE_uninit:
      s->PutCString("DW_OP_APPLE_uninit"); // 0xF0
      break;
      //        case DW_OP_APPLE_assign:        // 0xF1 - pops value off and
      //        assigns it to second item on stack (2nd item must have
      //        assignable context)
      //            s->PutCString("DW_OP_APPLE_assign");
      //            break;
      //        case DW_OP_APPLE_address_of:    // 0xF2 - gets the address of
      //        the top stack item (top item must be a variable, or have
      //        value_type that is an address already)
      //            s->PutCString("DW_OP_APPLE_address_of");
      //            break;
      //        case DW_OP_APPLE_value_of:      // 0xF3 - pops the value off the
      //        stack and pushes the value of that object (top item must be a
      //        variable, or expression local)
      //            s->PutCString("DW_OP_APPLE_value_of");
      //            break;
      //        case DW_OP_APPLE_deref_type:    // 0xF4 - gets the address of
      //        the top stack item (top item must be a variable, or a clang
      //        type)
      //            s->PutCString("DW_OP_APPLE_deref_type");
      //            break;
      //        case DW_OP_APPLE_expr_local:    // 0xF5 - ULEB128 expression
      //        local index
      //            s->Printf("DW_OP_APPLE_expr_local(%" PRIu64 ")",
      //            m_data.GetULEB128(&offset));
      //            break;
      //        case DW_OP_APPLE_constf:        // 0xF6 - 1 byte float size,
      //        followed by constant float data
      //            {
      //                uint8_t float_length = m_data.GetU8(&offset);
      //                s->Printf("DW_OP_APPLE_constf(<%u> ", float_length);
      //                m_data.Dump(s, offset, eFormatHex, float_length, 1,
      //                UINT32_MAX, DW_INVALID_ADDRESS, 0, 0);
      //                s->PutChar(')');
      //                // Consume the float data
      //                m_data.GetData(&offset, float_length);
      //            }
      //            break;
      //        case DW_OP_APPLE_scalar_cast:
      //            s->Printf("DW_OP_APPLE_scalar_cast(%s)",
      //            Scalar::GetValueTypeAsCString
      //            ((Scalar::Type)m_data.GetU8(&offset)));
      //            break;
      //        case DW_OP_APPLE_clang_cast:
      //            {
      //                clang::Type *clang_type = (clang::Type
      //                *)m_data.GetMaxU64(&offset, sizeof(void*));
      //                s->Printf("DW_OP_APPLE_clang_cast(%p)", clang_type);
      //            }
      //            break;
      //        case DW_OP_APPLE_clear:
      //            s->PutCString("DW_OP_APPLE_clear");
      //            break;
      //        case DW_OP_APPLE_error:         // 0xFF - Stops expression
      //        evaluation and returns an error (no args)
      //            s->PutCString("DW_OP_APPLE_error");
      //            break;
    }
  }
}

void DWARFExpression::SetLocationListSlide(addr_t slide) {
  m_loclist_slide = slide;
}

int DWARFExpression::GetRegisterKind() { return m_reg_kind; }

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

bool DWARFExpression::IsLocationList() const {
  return m_loclist_slide != LLDB_INVALID_ADDRESS;
}

void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level,
                                     addr_t location_list_base_addr,
                                     ABI *abi) const {
  if (IsLocationList()) {
    // We have a location list
    lldb::offset_t offset = 0;
    uint32_t count = 0;
    addr_t curr_base_addr = location_list_base_addr;
    while (m_data.ValidOffset(offset)) {
      addr_t begin_addr_offset = LLDB_INVALID_ADDRESS;
      addr_t end_addr_offset = LLDB_INVALID_ADDRESS;
      if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset,
                                            begin_addr_offset, end_addr_offset))
        break;

      if (begin_addr_offset == 0 && end_addr_offset == 0)
        break;

      if (begin_addr_offset < end_addr_offset) {
        if (count > 0)
          s->PutCString(", ");
        VMRange addr_range(curr_base_addr + begin_addr_offset,
                           curr_base_addr + end_addr_offset);
        addr_range.Dump(s, 0, 8);
        s->PutChar('{');
        lldb::offset_t location_length = m_data.GetU16(&offset);
        DumpLocation(s, offset, location_length, level, abi);
        s->PutChar('}');
        offset += location_length;
      } else {
        if ((m_data.GetAddressByteSize() == 4 &&
             (begin_addr_offset == UINT32_MAX)) ||
            (m_data.GetAddressByteSize() == 8 &&
             (begin_addr_offset == UINT64_MAX))) {
          curr_base_addr = end_addr_offset + location_list_base_addr;
          // We have a new base address
          if (count > 0)
            s->PutCString(", ");
          *s << "base_addr = " << end_addr_offset;
        }
      }

      count++;
    }
  } else {
    // We have a normal location that contains DW_OP location opcodes
    DumpLocation(s, 0, m_data.GetByteSize(), level, abi);
  }
}

static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
                                      lldb::RegisterKind reg_kind,
                                      uint32_t reg_num, Status *error_ptr,
                                      Value &value) {
  if (reg_ctx == NULL) {
    if (error_ptr)
      error_ptr->SetErrorStringWithFormat("No register context in frame.\n");
  } else {
    uint32_t native_reg =
        reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
    if (native_reg == LLDB_INVALID_REGNUM) {
      if (error_ptr)
        error_ptr->SetErrorStringWithFormat("Unable to convert register "
                                            "kind=%u reg_num=%u to a native "
                                            "register number.\n",
                                            reg_kind, reg_num);
    } else {
      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::eValueTypeScalar);
          value.SetContext(Value::eContextTypeRegisterInfo,
                           const_cast<RegisterInfo *>(reg_info));
          if (error_ptr)
            error_ptr->Clear();
          return true;
        } else {
          // If we get this error, then we need to implement a value
          // buffer in the dwarf expression evaluation function...
          if (error_ptr)
            error_ptr->SetErrorStringWithFormat(
                "register %s can't be converted to a scalar value",
                reg_info->name);
        }
      } else {
        if (error_ptr)
          error_ptr->SetErrorStringWithFormat("register %s is not available",
                                              reg_info->name);
      }
    }
  }
  return false;
}

// bool
// DWARFExpression::LocationListContainsLoadAddress (Process* process, const
// Address &addr) const
//{
//    return LocationListContainsLoadAddress(process,
//    addr.GetLoadAddress(process));
//}
//
// bool
// DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t
// load_addr) const
//{
//    if (load_addr == LLDB_INVALID_ADDRESS)
//        return false;
//
//    if (IsLocationList())
//    {
//        lldb::offset_t offset = 0;
//
//        addr_t loc_list_base_addr = m_loclist_slide.GetLoadAddress(process);
//
//        if (loc_list_base_addr == LLDB_INVALID_ADDRESS)
//            return false;
//
//        while (m_data.ValidOffset(offset))
//        {
//            // We need to figure out what the value is for the location.
//            addr_t lo_pc = m_data.GetAddress(&offset);
//            addr_t hi_pc = m_data.GetAddress(&offset);
//            if (lo_pc == 0 && hi_pc == 0)
//                break;
//            else
//            {
//                lo_pc += loc_list_base_addr;
//                hi_pc += loc_list_base_addr;
//
//                if (lo_pc <= load_addr && load_addr < hi_pc)
//                    return true;
//
//                offset += m_data.GetU16(&offset);
//            }
//        }
//    }
//    return false;
//}

static offset_t GetOpcodeDataSize(const DataExtractor &data,
                                  const lldb::offset_t data_offset,
                                  const uint8_t op) {
  lldb::offset_t offset = data_offset;
  switch (op) {
  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
    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_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);
    data.Skip_LEB128(&offset);
    data.Skip_LEB128(&offset);
    return offset - data_offset;

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

  default:
    break;
  }
  return LLDB_INVALID_OFFSET;
}

lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx,
                                                     bool &error) const {
  error = false;
  if (IsLocationList())
    return LLDB_INVALID_ADDRESS;
  lldb::offset_t offset = 0;
  uint32_t curr_op_addr_idx = 0;
  while (m_data.ValidOffset(offset)) {
    const uint8_t op = m_data.GetU8(&offset);

    if (op == DW_OP_addr) {
      const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
      if (curr_op_addr_idx == op_addr_idx)
        return op_file_addr;
      else
        ++curr_op_addr_idx;
    } else if (op == DW_OP_GNU_addr_index) {
      uint64_t index = m_data.GetULEB128(&offset);
      if (curr_op_addr_idx == op_addr_idx) {
        if (!m_dwarf_cu) {
          error = true;
          break;
        }

        return ReadAddressFromDebugAddrSection(m_dwarf_cu, index);
      } else
        ++curr_op_addr_idx;
    } else {
      const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
      if (op_arg_size == LLDB_INVALID_OFFSET) {
        error = true;
        break;
      }
      offset += op_arg_size;
    }
  }
  return LLDB_INVALID_ADDRESS;
}

bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
  if (IsLocationList())
    return false;
  lldb::offset_t offset = 0;
  while (m_data.ValidOffset(offset)) {
    const uint8_t op = 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

      // So first we copy the data into a heap buffer
      std::unique_ptr<DataBufferHeap> head_data_ap(
          new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize()));

      // Make en encoder so we can write the address into the buffer using
      // the correct byte order (endianness)
      DataEncoder encoder(head_data_ap->GetBytes(), head_data_ap->GetByteSize(),
                          m_data.GetByteOrder(), addr_byte_size);

      // Replace the address in the new buffer
      if (encoder.PutMaxU64(offset, addr_byte_size, 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(DataBufferSP(head_data_ap.release()));
      return true;
    } else {
      const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
      if (op_arg_size == LLDB_INVALID_OFFSET)
        break;
      offset += op_arg_size;
    }
  }
  return false;
}

bool DWARFExpression::ContainsThreadLocalStorage() const {
  // We are assuming for now that any thread local variable will not
  // have a location list. This has been true for all thread local
  // variables we have seen so far produced by any compiler.
  if (IsLocationList())
    return false;
  lldb::offset_t offset = 0;
  while (m_data.ValidOffset(offset)) {
    const uint8_t op = m_data.GetU8(&offset);

    if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address)
      return true;
    const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
    if (op_arg_size == LLDB_INVALID_OFFSET)
      return false;
    else
      offset += op_arg_size;
  }
  return false;
}
bool DWARFExpression::LinkThreadLocalStorage(
    lldb::ModuleSP new_module_sp,
    std::function<lldb::addr_t(lldb::addr_t file_addr)> const
        &link_address_callback) {
  // We are assuming for now that any thread local variable will not
  // have a location list. This has been true for all thread local
  // variables we have seen so far produced by any compiler.
  if (IsLocationList())
    return false;

  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

  // So first we copy the data into a heap buffer
  std::shared_ptr<DataBufferHeap> heap_data_sp(
      new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize()));

  // Make en encoder so we can write the address into the buffer using
  // the correct byte order (endianness)
  DataEncoder encoder(heap_data_sp->GetBytes(), heap_data_sp->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 uint8_t op = 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 accodingly. 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.PutMaxU64(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 offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
      if (op_arg_size == LLDB_INVALID_OFFSET)
        return false;
      else
        offset += op_arg_size;
    }
  }

  // If we linked the TLS address correctly, update the module so that when the
  // expression
  // is evaluated it can resolve the file address to a load address and read the
  // TLS data
  m_module_wp = new_module_sp;
  m_data.SetData(heap_data_sp);
  return true;
}

bool DWARFExpression::LocationListContainsAddress(
    lldb::addr_t loclist_base_addr, lldb::addr_t addr) const {
  if (addr == LLDB_INVALID_ADDRESS)
    return false;

  if (IsLocationList()) {
    lldb::offset_t offset = 0;

    if (loclist_base_addr == LLDB_INVALID_ADDRESS)
      return false;

    while (m_data.ValidOffset(offset)) {
      // We need to figure out what the value is for the location.
      addr_t lo_pc = LLDB_INVALID_ADDRESS;
      addr_t hi_pc = LLDB_INVALID_ADDRESS;
      if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, lo_pc,
                                            hi_pc))
        break;

      if (lo_pc == 0 && hi_pc == 0)
        break;

      lo_pc += loclist_base_addr - m_loclist_slide;
      hi_pc += loclist_base_addr - m_loclist_slide;

      if (lo_pc <= addr && addr < hi_pc)
        return true;

      offset += m_data.GetU16(&offset);
    }
  }
  return false;
}

bool DWARFExpression::GetLocation(addr_t base_addr, addr_t pc,
                                  lldb::offset_t &offset,
                                  lldb::offset_t &length) {
  offset = 0;
  if (!IsLocationList()) {
    length = m_data.GetByteSize();
    return true;
  }

  if (base_addr != LLDB_INVALID_ADDRESS && pc != LLDB_INVALID_ADDRESS) {
    addr_t curr_base_addr = base_addr;

    while (m_data.ValidOffset(offset)) {
      // We need to figure out what the value is for the location.
      addr_t lo_pc = LLDB_INVALID_ADDRESS;
      addr_t hi_pc = LLDB_INVALID_ADDRESS;
      if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, lo_pc,
                                            hi_pc))
        break;

      if (lo_pc == 0 && hi_pc == 0)
        break;

      lo_pc += curr_base_addr - m_loclist_slide;
      hi_pc += curr_base_addr - m_loclist_slide;

      length = m_data.GetU16(&offset);

      if (length > 0 && lo_pc <= pc && pc < hi_pc)
        return true;

      offset += length;
    }
  }
  offset = LLDB_INVALID_OFFSET;
  length = 0;
  return false;
}

bool DWARFExpression::DumpLocationForAddress(Stream *s,
                                             lldb::DescriptionLevel level,
                                             addr_t base_addr, addr_t address,
                                             ABI *abi) {
  lldb::offset_t offset = 0;
  lldb::offset_t length = 0;

  if (GetLocation(base_addr, address, offset, length)) {
    if (length > 0) {
      DumpLocation(s, offset, length, level, abi);
      return true;
    }
  }
  return false;
}

bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope,
                               ClangExpressionVariableList *expr_locals,
                               ClangExpressionDeclMap *decl_map,
                               lldb::addr_t loclist_base_load_addr,
                               const Value *initial_value_ptr,
                               const Value *object_address_ptr, Value &result,
                               Status *error_ptr) const {
  ExecutionContext exe_ctx(exe_scope);
  return Evaluate(&exe_ctx, expr_locals, decl_map, nullptr,
                  loclist_base_load_addr, initial_value_ptr, object_address_ptr,
                  result, error_ptr);
}

bool DWARFExpression::Evaluate(
    ExecutionContext *exe_ctx, ClangExpressionVariableList *expr_locals,
    ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx,
    lldb::addr_t loclist_base_load_addr, const Value *initial_value_ptr,
    const Value *object_address_ptr, Value &result, Status *error_ptr) const {
  ModuleSP module_sp = m_module_wp.lock();

  if (IsLocationList()) {
    lldb::offset_t offset = 0;
    addr_t pc;
    StackFrame *frame = NULL;
    if (reg_ctx)
      pc = reg_ctx->GetPC();
    else {
      frame = exe_ctx->GetFramePtr();
      if (!frame)
        return false;
      RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
      if (!reg_ctx_sp)
        return false;
      pc = reg_ctx_sp->GetPC();
    }

    if (loclist_base_load_addr != LLDB_INVALID_ADDRESS) {
      if (pc == LLDB_INVALID_ADDRESS) {
        if (error_ptr)
          error_ptr->SetErrorString("Invalid PC in frame.");
        return false;
      }

      addr_t curr_loclist_base_load_addr = loclist_base_load_addr;

      while (m_data.ValidOffset(offset)) {
        // We need to figure out what the value is for the location.
        addr_t lo_pc = LLDB_INVALID_ADDRESS;
        addr_t hi_pc = LLDB_INVALID_ADDRESS;
        if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset,
                                              lo_pc, hi_pc))
          break;

        if (lo_pc == 0 && hi_pc == 0)
          break;

        lo_pc += curr_loclist_base_load_addr - m_loclist_slide;
        hi_pc += curr_loclist_base_load_addr - m_loclist_slide;

        uint16_t length = m_data.GetU16(&offset);

        if (length > 0 && lo_pc <= pc && pc < hi_pc) {
          return DWARFExpression::Evaluate(
              exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data,
              m_dwarf_cu, offset, length, m_reg_kind, initial_value_ptr,
              object_address_ptr, result, error_ptr);
        }
        offset += length;
      }
    }
    if (error_ptr)
      error_ptr->SetErrorString("variable not available");
    return false;
  }

  // Not a location list, just a single expression.
  return DWARFExpression::Evaluate(
      exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data, m_dwarf_cu, 0,
      m_data.GetByteSize(), m_reg_kind, initial_value_ptr, object_address_ptr,
      result, error_ptr);
}

bool DWARFExpression::Evaluate(
    ExecutionContext *exe_ctx, ClangExpressionVariableList *expr_locals,
    ClangExpressionDeclMap *decl_map, RegisterContext *reg_ctx,
    lldb::ModuleSP module_sp, const DataExtractor &opcodes,
    DWARFCompileUnit *dwarf_cu, const lldb::offset_t opcodes_offset,
    const lldb::offset_t opcodes_length, const lldb::RegisterKind reg_kind,
    const Value *initial_value_ptr, const Value *object_address_ptr,
    Value &result, Status *error_ptr) {

  if (opcodes_length == 0) {
    if (error_ptr)
      error_ptr->SetErrorString(
          "no location, value may have been optimized out");
    return false;
  }
  std::vector<Value> stack;

  Process *process = NULL;
  StackFrame *frame = NULL;

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

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

  lldb::offset_t offset = opcodes_offset;
  const lldb::offset_t end_offset = opcodes_offset + opcodes_length;
  Value tmp;
  uint32_t reg_num;

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

  // Make sure all of the data is available in opcodes.
  if (!opcodes.ValidOffsetForDataOfSize(opcodes_offset, opcodes_length)) {
    if (error_ptr)
      error_ptr->SetErrorString(
          "invalid offset and/or length for opcodes buffer.");
    return false;
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

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

    if (log && log->GetVerbose()) {
      size_t count = stack.size();
      log->Printf("Stack before operation has %" PRIu64 " values:",
                  (uint64_t)count);
      for (size_t i = 0; i < count; ++i) {
        StreamString new_value;
        new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
        stack[i].Dump(&new_value);
        log->Printf("  %s", new_value.GetData());
      }
      log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op));
    }
    switch (op) {
    //----------------------------------------------------------------------
    // The DW_OP_addr operation has a single operand that encodes a machine
    // address and whose size is the size of an address on the target machine.
    //----------------------------------------------------------------------
    case DW_OP_addr:
      stack.push_back(Scalar(opcodes.GetAddress(&offset)));
      stack.back().SetValueType(Value::eValueTypeFileAddress);
      break;

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

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_deref
    // OPERANDS: none
    // DESCRIPTION: Pops the top stack entry and treats it as an address.
    // The value retrieved from that address is pushed. The size of the
    // data retrieved from the dereferenced address is the size of an
    // address on the target machine.
    //----------------------------------------------------------------------
    case DW_OP_deref: {
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString("Expression stack empty for DW_OP_deref.");
        return false;
      }
      Value::ValueType value_type = stack.back().GetValueType();
      switch (value_type) {
      case Value::eValueTypeHostAddress: {
        void *src = (void *)stack.back().GetScalar().ULongLong();
        intptr_t ptr;
        ::memcpy(&ptr, src, sizeof(void *));
        stack.back().GetScalar() = ptr;
        stack.back().ClearContext();
      } break;
      case Value::eValueTypeLoadAddress:
        if (exe_ctx) {
          if (process) {
            lldb::addr_t pointer_addr =
                stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
            Status error;
            lldb::addr_t pointer_value =
                process->ReadPointerFromMemory(pointer_addr, error);
            if (pointer_value != LLDB_INVALID_ADDRESS) {
              stack.back().GetScalar() = pointer_value;
              stack.back().ClearContext();
            } else {
              if (error_ptr)
                error_ptr->SetErrorStringWithFormat(
                    "Failed to dereference pointer from 0x%" PRIx64
                    " for DW_OP_deref: %s\n",
                    pointer_addr, error.AsCString());
              return false;
            }
          } else {
            if (error_ptr)
              error_ptr->SetErrorStringWithFormat(
                  "NULL process for DW_OP_deref.\n");
            return false;
          }
        } else {
          if (error_ptr)
            error_ptr->SetErrorStringWithFormat(
                "NULL execution context for DW_OP_deref.\n");
          return false;
        }
        break;

      default:
        break;
      }

    } break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_deref_size
    // OPERANDS: 1
    //  1 - uint8_t that specifies the size of the data to dereference.
    // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
    // stack entry and treats it as an address. The value retrieved from that
    // address is pushed. In the DW_OP_deref_size operation, however, the
    // size in bytes of the data retrieved from the dereferenced address is
    // specified by the single operand. This operand is a 1-byte unsigned
    // integral constant whose value may not be larger than the size of an
    // address on the target machine. The data retrieved is zero extended
    // to the size of an address on the target machine before being pushed
    // on the expression stack.
    //----------------------------------------------------------------------
    case DW_OP_deref_size: {
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack empty for DW_OP_deref_size.");
        return false;
      }
      uint8_t size = opcodes.GetU8(&offset);
      Value::ValueType value_type = stack.back().GetValueType();
      switch (value_type) {
      case Value::eValueTypeHostAddress: {
        void *src = (void *)stack.back().GetScalar().ULongLong();
        intptr_t ptr;
        ::memcpy(&ptr, src, sizeof(void *));
        // I can't decide whether the size operand should apply to the bytes in
        // their
        // lldb-host endianness or the target endianness.. I doubt this'll ever
        // come up
        // but I'll opt for assuming big endian regardless.
        switch (size) {
        case 1:
          ptr = ptr & 0xff;
          break;
        case 2:
          ptr = ptr & 0xffff;
          break;
        case 3:
          ptr = ptr & 0xffffff;
          break;
        case 4:
          ptr = ptr & 0xffffffff;
          break;
        // the casts are added to work around the case where intptr_t is a 32
        // bit quantity;
        // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
        // program.
        case 5:
          ptr = (intptr_t)ptr & 0xffffffffffULL;
          break;
        case 6:
          ptr = (intptr_t)ptr & 0xffffffffffffULL;
          break;
        case 7:
          ptr = (intptr_t)ptr & 0xffffffffffffffULL;
          break;
        default:
          break;
        }
        stack.back().GetScalar() = ptr;
        stack.back().ClearContext();
      } break;
      case Value::eValueTypeLoadAddress:
        if (exe_ctx) {
          if (process) {
            lldb::addr_t pointer_addr =
                stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
            uint8_t addr_bytes[sizeof(lldb::addr_t)];
            Status error;
            if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) ==
                size) {
              DataExtractor addr_data(addr_bytes, sizeof(addr_bytes),
                                      process->GetByteOrder(), size);
              lldb::offset_t addr_data_offset = 0;
              switch (size) {
              case 1:
                stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset);
                break;
              case 2:
                stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset);
                break;
              case 4:
                stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset);
                break;
              case 8:
                stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset);
                break;
              default:
                stack.back().GetScalar() =
                    addr_data.GetPointer(&addr_data_offset);
              }
              stack.back().ClearContext();
            } else {
              if (error_ptr)
                error_ptr->SetErrorStringWithFormat(
                    "Failed to dereference pointer from 0x%" PRIx64
                    " for DW_OP_deref: %s\n",
                    pointer_addr, error.AsCString());
              return false;
            }
          } else {
            if (error_ptr)
              error_ptr->SetErrorStringWithFormat(
                  "NULL process for DW_OP_deref.\n");
            return false;
          }
        } else {
          if (error_ptr)
            error_ptr->SetErrorStringWithFormat(
                "NULL execution context for DW_OP_deref.\n");
          return false;
        }
        break;

      default:
        break;
      }

    } break;

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

    //----------------------------------------------------------------------
    // All DW_OP_constXXX opcodes have a single operand as noted below:
    //
    // Opcode           Operand 1
    // ---------------  ----------------------------------------------------
    // DW_OP_const1u    1-byte unsigned integer constant
    // DW_OP_const1s    1-byte signed integer constant
    // DW_OP_const2u    2-byte unsigned integer constant
    // DW_OP_const2s    2-byte signed integer constant
    // DW_OP_const4u    4-byte unsigned integer constant
    // DW_OP_const4s    4-byte signed integer constant
    // DW_OP_const8u    8-byte unsigned integer constant
    // DW_OP_const8s    8-byte signed integer constant
    // DW_OP_constu     unsigned LEB128 integer constant
    // DW_OP_consts     signed LEB128 integer constant
    //----------------------------------------------------------------------
    case DW_OP_const1u:
      stack.push_back(Scalar((uint8_t)opcodes.GetU8(&offset)));
      break;
    case DW_OP_const1s:
      stack.push_back(Scalar((int8_t)opcodes.GetU8(&offset)));
      break;
    case DW_OP_const2u:
      stack.push_back(Scalar((uint16_t)opcodes.GetU16(&offset)));
      break;
    case DW_OP_const2s:
      stack.push_back(Scalar((int16_t)opcodes.GetU16(&offset)));
      break;
    case DW_OP_const4u:
      stack.push_back(Scalar((uint32_t)opcodes.GetU32(&offset)));
      break;
    case DW_OP_const4s:
      stack.push_back(Scalar((int32_t)opcodes.GetU32(&offset)));
      break;
    case DW_OP_const8u:
      stack.push_back(Scalar((uint64_t)opcodes.GetU64(&offset)));
      break;
    case DW_OP_const8s:
      stack.push_back(Scalar((int64_t)opcodes.GetU64(&offset)));
      break;
    case DW_OP_constu:
      stack.push_back(Scalar(opcodes.GetULEB128(&offset)));
      break;
    case DW_OP_consts:
      stack.push_back(Scalar(opcodes.GetSLEB128(&offset)));
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_dup
    // OPERANDS: none
    // DESCRIPTION: duplicates the value at the top of the stack
    //----------------------------------------------------------------------
    case DW_OP_dup:
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString("Expression stack empty for DW_OP_dup.");
        return false;
      } else
        stack.push_back(stack.back());
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_drop
    // OPERANDS: none
    // DESCRIPTION: pops the value at the top of the stack
    //----------------------------------------------------------------------
    case DW_OP_drop:
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString("Expression stack empty for DW_OP_drop.");
        return false;
      } else
        stack.pop_back();
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_over
    // OPERANDS: none
    // DESCRIPTION: Duplicates the entry currently second in the stack at
    // the top of the stack.
    //----------------------------------------------------------------------
    case DW_OP_over:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_over.");
        return false;
      } else
        stack.push_back(stack[stack.size() - 2]);
      break;

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

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_swap
    // OPERANDS: none
    // DESCRIPTION: swaps the top two stack entries. The entry at the top
    // of the stack becomes the second stack entry, and the second entry
    // becomes the top of the stack
    //----------------------------------------------------------------------
    case DW_OP_swap:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_swap.");
        return false;
      } else {
        tmp = stack.back();
        stack.back() = stack[stack.size() - 2];
        stack[stack.size() - 2] = tmp;
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_rot
    // OPERANDS: none
    // DESCRIPTION: Rotates the first three stack entries. The entry at
    // the top of the stack becomes the third stack entry, the second
    // entry becomes the top of the stack, and the third entry becomes
    // the second entry.
    //----------------------------------------------------------------------
    case DW_OP_rot:
      if (stack.size() < 3) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 3 items for DW_OP_rot.");
        return false;
      } else {
        size_t last_idx = stack.size() - 1;
        Value old_top = stack[last_idx];
        stack[last_idx] = stack[last_idx - 1];
        stack[last_idx - 1] = stack[last_idx - 2];
        stack[last_idx - 2] = old_top;
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_abs
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, interprets it as a signed
    // value and pushes its absolute value. If the absolute value can not be
    // represented, the result is undefined.
    //----------------------------------------------------------------------
    case DW_OP_abs:
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 1 item for DW_OP_abs.");
        return false;
      } else if (stack.back().ResolveValue(exe_ctx).AbsoluteValue() == false) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Failed to take the absolute value of the first stack item.");
        return false;
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_and
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, performs a bitwise and
    // operation on the two, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_and:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_and.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_div
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, divides the former second
    // entry by the former top of the stack using signed division, and
    // pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_div:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_div.");
        return false;
      } else {
        tmp = stack.back();
        if (tmp.ResolveValue(exe_ctx).IsZero()) {
          if (error_ptr)
            error_ptr->SetErrorString("Divide by zero.");
          return false;
        } else {
          stack.pop_back();
          stack.back() =
              stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx);
          if (!stack.back().ResolveValue(exe_ctx).IsValid()) {
            if (error_ptr)
              error_ptr->SetErrorString("Divide failed.");
            return false;
          }
        }
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_minus
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, subtracts the former top
    // of the stack from the former second entry, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_minus:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_minus.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_mod
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values and pushes the result of
    // the calculation: former second stack entry modulo the former top of
    // the stack.
    //----------------------------------------------------------------------
    case DW_OP_mod:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_mod.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_mul
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, multiplies them
    // together, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_mul:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_mul.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_neg
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, and pushes its negation.
    //----------------------------------------------------------------------
    case DW_OP_neg:
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 1 item for DW_OP_neg.");
        return false;
      } else {
        if (stack.back().ResolveValue(exe_ctx).UnaryNegate() == false) {
          if (error_ptr)
            error_ptr->SetErrorString("Unary negate failed.");
          return false;
        }
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_not
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, and pushes its bitwise
    // complement
    //----------------------------------------------------------------------
    case DW_OP_not:
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 1 item for DW_OP_not.");
        return false;
      } else {
        if (stack.back().ResolveValue(exe_ctx).OnesComplement() == false) {
          if (error_ptr)
            error_ptr->SetErrorString("Logical NOT failed.");
          return false;
        }
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_or
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, performs a bitwise or
    // operation on the two, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_or:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_or.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_plus
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, adds them together, and
    // pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_plus:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_plus.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().GetScalar() += tmp.GetScalar();
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_plus_uconst
    // OPERANDS: none
    // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
    // constant operand and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_plus_uconst:
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 1 item for DW_OP_plus_uconst.");
        return false;
      } else {
        const uint64_t uconst_value = opcodes.GetULEB128(&offset);
        // Implicit conversion from a UINT to a Scalar...
        stack.back().GetScalar() += uconst_value;
        if (!stack.back().GetScalar().IsValid()) {
          if (error_ptr)
            error_ptr->SetErrorString("DW_OP_plus_uconst failed.");
          return false;
        }
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_shl
    // OPERANDS: none
    // DESCRIPTION:  pops the top two stack entries, shifts the former
    // second entry left by the number of bits specified by the former top
    // of the stack, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_shl:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_shl.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_shr
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, shifts the former second
    // entry right logically (filling with zero bits) by the number of bits
    // specified by the former top of the stack, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_shr:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_shr.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        if (stack.back().ResolveValue(exe_ctx).ShiftRightLogical(
                tmp.ResolveValue(exe_ctx)) == false) {
          if (error_ptr)
            error_ptr->SetErrorString("DW_OP_shr failed.");
          return false;
        }
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_shra
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, shifts the former second
    // entry right arithmetically (divide the magnitude by 2, keep the same
    // sign for the result) by the number of bits specified by the former
    // top of the stack, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_shra:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_shra.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_xor
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack entries, performs the bitwise
    // exclusive-or operation on the two, and pushes the result.
    //----------------------------------------------------------------------
    case DW_OP_xor:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_xor.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_skip
    // OPERANDS: int16_t
    // DESCRIPTION:  An unconditional branch. Its single operand is a 2-byte
    // signed integer constant. The 2-byte constant is the number of bytes
    // of the DWARF expression to skip forward or backward from the current
    // operation, beginning after the 2-byte constant.
    //----------------------------------------------------------------------
    case DW_OP_skip: {
      int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
      lldb::offset_t new_offset = offset + skip_offset;
      if (new_offset >= opcodes_offset && new_offset < end_offset)
        offset = new_offset;
      else {
        if (error_ptr)
          error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip.");
        return false;
      }
    } break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_bra
    // OPERANDS: int16_t
    // DESCRIPTION: A conditional branch. Its single operand is a 2-byte
    // signed integer constant. This operation pops the top of stack. If
    // the value popped is not the constant 0, the 2-byte constant operand
    // is the number of bytes of the DWARF expression to skip forward or
    // backward from the current operation, beginning after the 2-byte
    // constant.
    //----------------------------------------------------------------------
    case DW_OP_bra:
      if (stack.empty()) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 1 item for DW_OP_bra.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
        Scalar zero(0);
        if (tmp.ResolveValue(exe_ctx) != zero) {
          lldb::offset_t new_offset = offset + bra_offset;
          if (new_offset >= opcodes_offset && new_offset < end_offset)
            offset = new_offset;
          else {
            if (error_ptr)
              error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra.");
            return false;
          }
        }
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_eq
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // equals (==) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    //----------------------------------------------------------------------
    case DW_OP_eq:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_eq.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_ge
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // greater than or equal to (>=) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    //----------------------------------------------------------------------
    case DW_OP_ge:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_ge.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_gt
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // greater than (>) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    //----------------------------------------------------------------------
    case DW_OP_gt:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_gt.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_le
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // less than or equal to (<=) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    //----------------------------------------------------------------------
    case DW_OP_le:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_le.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_lt
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // less than (<) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    //----------------------------------------------------------------------
    case DW_OP_lt:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_lt.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx);
      }
      break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_ne
    // OPERANDS: none
    // DESCRIPTION: pops the top two stack values, compares using the
    // not equal (!=) operator.
    // STACK RESULT: push the constant value 1 onto the stack if the result
    // of the operation is true or the constant value 0 if the result of the
    // operation is false.
    //----------------------------------------------------------------------
    case DW_OP_ne:
      if (stack.size() < 2) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 2 items for DW_OP_ne.");
        return false;
      } else {
        tmp = stack.back();
        stack.pop_back();
        stack.back().ResolveValue(exe_ctx) =
            stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx);
      }
      break;

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

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

      if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp))
        stack.push_back(tmp);
      else
        return false;
    } break;
    //----------------------------------------------------------------------
    // OPCODE: DW_OP_regx
    // OPERANDS:
    //      ULEB128 literal operand that encodes the register.
    // DESCRIPTION: Push the value in register on the top of the stack.
    //----------------------------------------------------------------------
    case DW_OP_regx: {
      reg_num = opcodes.GetULEB128(&offset);
      if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp))
        stack.push_back(tmp);
      else
        return false;
    } break;

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

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

      if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr,
                                    tmp)) {
        int64_t breg_offset = opcodes.GetSLEB128(&offset);
        tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
        tmp.ClearContext();
        stack.push_back(tmp);
        stack.back().SetValueType(Value::eValueTypeLoadAddress);
      } else
        return false;
    } break;

    case DW_OP_fbreg:
      if (exe_ctx) {
        if (frame) {
          Scalar value;
          if (frame->GetFrameBaseValue(value, error_ptr)) {
            int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
            value += fbreg_offset;
            stack.push_back(value);
            stack.back().SetValueType(Value::eValueTypeLoadAddress);
          } else
            return false;
        } else {
          if (error_ptr)
            error_ptr->SetErrorString(
                "Invalid stack frame in context for DW_OP_fbreg opcode.");
          return false;
        }
      } else {
        if (error_ptr)
          error_ptr->SetErrorStringWithFormat(
              "NULL execution context for DW_OP_fbreg.\n");
        return false;
      }

      break;

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

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

      if (piece_byte_size > 0) {
        Value curr_piece;

        if (stack.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);
          ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
          pieces.AppendDataToHostBuffer(curr_piece);
        } else {
          Status error;
          // Extract the current piece into "curr_piece"
          Value curr_piece_source_value(stack.back());
          stack.pop_back();

          const Value::ValueType curr_piece_source_value_type =
              curr_piece_source_value.GetValueType();
          switch (curr_piece_source_value_type) {
          case Value::eValueTypeLoadAddress:
            if (process) {
              if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) {
                lldb::addr_t load_addr =
                    curr_piece_source_value.GetScalar().ULongLong(
                        LLDB_INVALID_ADDRESS);
                if (process->ReadMemory(
                        load_addr, curr_piece.GetBuffer().GetBytes(),
                        piece_byte_size, error) != piece_byte_size) {
                  if (error_ptr)
                    error_ptr->SetErrorStringWithFormat(
                        "failed to read memory DW_OP_piece(%" PRIu64
                        ") from 0x%" PRIx64,
                        piece_byte_size, load_addr);
                  return false;
                }
              } else {
                if (error_ptr)
                  error_ptr->SetErrorStringWithFormat(
                      "failed to resize the piece memory buffer for "
                      "DW_OP_piece(%" PRIu64 ")",
                      piece_byte_size);
                return false;
              }
            }
            break;

          case Value::eValueTypeFileAddress:
          case Value::eValueTypeHostAddress:
            if (error_ptr) {
              lldb::addr_t addr = curr_piece_source_value.GetScalar().ULongLong(
                  LLDB_INVALID_ADDRESS);
              error_ptr->SetErrorStringWithFormat(
                  "failed to read memory DW_OP_piece(%" PRIu64
                  ") from %s address 0x%" PRIx64,
                  piece_byte_size, curr_piece_source_value.GetValueType() ==
                                           Value::eValueTypeFileAddress
                                       ? "file"
                                       : "host",
                  addr);
            }
            return false;

          case Value::eValueTypeScalar: {
            uint32_t bit_size = piece_byte_size * 8;
            uint32_t bit_offset = 0;
            if (!curr_piece_source_value.GetScalar().ExtractBitfield(
                    bit_size, bit_offset)) {
              if (error_ptr)
                error_ptr->SetErrorStringWithFormat(
                    "unable to extract %" PRIu64 " bytes from a %" PRIu64
                    " byte scalar value.",
                    piece_byte_size,
                    (uint64_t)curr_piece_source_value.GetScalar()
                        .GetByteSize());
              return false;
            }
            curr_piece = curr_piece_source_value;
          } break;

          case Value::eValueTypeVector: {
            if (curr_piece_source_value.GetVector().length >= piece_byte_size)
              curr_piece_source_value.GetVector().length = piece_byte_size;
            else {
              if (error_ptr)
                error_ptr->SetErrorStringWithFormat(
                    "unable to extract %" PRIu64 " bytes from a %" PRIu64
                    " byte vector value.",
                    piece_byte_size,
                    (uint64_t)curr_piece_source_value.GetVector().length);
              return false;
            }
          } break;
          }

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

            if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
              if (error_ptr)
                error_ptr->SetErrorString("failed to append piece data");
              return false;
            }
          }
          op_piece_offset += piece_byte_size;
        }
      }
    } break;

    case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
      if (stack.size() < 1) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "Expression stack needs at least 1 item for DW_OP_bit_piece.");
        return false;
      } else {
        const uint64_t piece_bit_size = opcodes.GetULEB128(&offset);
        const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset);
        switch (stack.back().GetValueType()) {
        case Value::eValueTypeScalar: {
          if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size,
                                                        piece_bit_offset)) {
            if (error_ptr)
              error_ptr->SetErrorStringWithFormat(
                  "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));
            return false;
          }
        } break;

        case Value::eValueTypeFileAddress:
        case Value::eValueTypeLoadAddress:
        case Value::eValueTypeHostAddress:
          if (error_ptr) {
            error_ptr->SetErrorStringWithFormat(
                "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
                ", bit_offset = %" PRIu64 ") from an addresss value.",
                piece_bit_size, piece_bit_offset);
          }
          return false;

        case Value::eValueTypeVector:
          if (error_ptr) {
            error_ptr->SetErrorStringWithFormat(
                "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
                ", bit_offset = %" PRIu64 ") from a vector value.",
                piece_bit_size, piece_bit_offset);
          }
          return false;
        }
      }
      break;

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

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

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

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

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

      if (!exe_ctx || !module_sp) {
        if (error_ptr)
          error_ptr->SetErrorString("No context to evaluate TLS within.");
        return false;
      }

      Thread *thread = exe_ctx->GetThreadPtr();
      if (!thread) {
        if (error_ptr)
          error_ptr->SetErrorString("No thread to evaluate TLS within.");
        return false;
      }

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

      if (tls_load_addr == LLDB_INVALID_ADDRESS) {
        if (error_ptr)
          error_ptr->SetErrorString(
              "No TLS data currently exists for this thread.");
        return false;
      }

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

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_GNU_addr_index
    // OPERANDS: 1
    //      ULEB128: index to the .debug_addr section
    // DESCRIPTION: Pushes an address to the stack from the .debug_addr
    // section with the base address specified by the DW_AT_addr_base
    // attribute and the 0 based index is the ULEB128 encoded index.
    //----------------------------------------------------------------------
    case DW_OP_GNU_addr_index: {
      if (!dwarf_cu) {
        if (error_ptr)
          error_ptr->SetErrorString("DW_OP_GNU_addr_index found without a "
                                    "compile unit being specified");
        return false;
      }
      uint64_t index = opcodes.GetULEB128(&offset);
      uint32_t index_size = dwarf_cu->GetAddressByteSize();
      dw_offset_t addr_base = dwarf_cu->GetAddrBase();
      lldb::offset_t offset = addr_base + index * index_size;
      uint64_t value =
          dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(
              &offset, index_size);
      stack.push_back(Scalar(value));
      stack.back().SetValueType(Value::eValueTypeFileAddress);
    } break;

    //----------------------------------------------------------------------
    // OPCODE: DW_OP_GNU_const_index
    // OPERANDS: 1
    //      ULEB128: index to the .debug_addr section
    // DESCRIPTION: Pushes an constant with the size of a machine address to
    // the stack from the .debug_addr section with the base address specified
    // by the DW_AT_addr_base attribute and the 0 based index is the ULEB128
    // encoded index.
    //----------------------------------------------------------------------
    case DW_OP_GNU_const_index: {
      if (!dwarf_cu) {
        if (error_ptr)
          error_ptr->SetErrorString("DW_OP_GNU_const_index found without a "
                                    "compile unit being specified");
        return false;
      }
      uint64_t index = opcodes.GetULEB128(&offset);
      uint32_t index_size = dwarf_cu->GetAddressByteSize();
      dw_offset_t addr_base = dwarf_cu->GetAddrBase();
      lldb::offset_t offset = addr_base + index * index_size;
      const DWARFDataExtractor &debug_addr =
          dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data();
      switch (index_size) {
      case 4:
        stack.push_back(Scalar(debug_addr.GetU32(&offset)));
        break;
      case 8:
        stack.push_back(Scalar(debug_addr.GetU64(&offset)));
        break;
      default:
        assert(false && "Unhandled index size");
        return false;
      }
    } break;

    default:
      if (log)
        log->Printf("Unhandled opcode %s in DWARFExpression.",
                    DW_OP_value_to_name(op));
      break;
    }
  }

  if (stack.empty()) {
    // Nothing on the stack, check if we created a piece value from DW_OP_piece
    // or DW_OP_bit_piece opcodes
    if (pieces.GetBuffer().GetByteSize()) {
      result = pieces;
    } else {
      if (error_ptr)
        error_ptr->SetErrorString("Stack empty after evaluation.");
      return false;
    }
  } else {
    if (log && log->GetVerbose()) {
      size_t count = stack.size();
      log->Printf("Stack after operation has %" PRIu64 " values:",
                  (uint64_t)count);
      for (size_t i = 0; i < count; ++i) {
        StreamString new_value;
        new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
        stack[i].Dump(&new_value);
        log->Printf("  %s", new_value.GetData());
      }
    }
    result = stack.back();
  }
  return true; // Return true on success
}

size_t DWARFExpression::LocationListSize(const DWARFCompileUnit *dwarf_cu,
                                         const DataExtractor &debug_loc_data,
                                         lldb::offset_t offset) {
  const lldb::offset_t debug_loc_offset = offset;
  while (debug_loc_data.ValidOffset(offset)) {
    lldb::addr_t start_addr = LLDB_INVALID_ADDRESS;
    lldb::addr_t end_addr = LLDB_INVALID_ADDRESS;
    if (!AddressRangeForLocationListEntry(dwarf_cu, debug_loc_data, &offset,
                                          start_addr, end_addr))
      break;

    if (start_addr == 0 && end_addr == 0)
      break;

    uint16_t loc_length = debug_loc_data.GetU16(&offset);
    offset += loc_length;
  }

  if (offset > debug_loc_offset)
    return offset - debug_loc_offset;
  return 0;
}

bool DWARFExpression::AddressRangeForLocationListEntry(
    const DWARFCompileUnit *dwarf_cu, const DataExtractor &debug_loc_data,
    lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc) {
  if (!debug_loc_data.ValidOffset(*offset_ptr))
    return false;

  switch (dwarf_cu->GetSymbolFileDWARF()->GetLocationListFormat()) {
  case NonLocationList:
    return false;
  case RegularLocationList:
    low_pc = debug_loc_data.GetAddress(offset_ptr);
    high_pc = debug_loc_data.GetAddress(offset_ptr);
    return true;
  case SplitDwarfLocationList:
    switch (debug_loc_data.GetU8(offset_ptr)) {
    case DW_LLE_end_of_list:
      return false;
    case DW_LLE_startx_endx: {
      uint64_t index = debug_loc_data.GetULEB128(offset_ptr);
      low_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index);
      index = debug_loc_data.GetULEB128(offset_ptr);
      high_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index);
      return true;
    }
    case DW_LLE_startx_length: {
      uint64_t index = debug_loc_data.GetULEB128(offset_ptr);
      low_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index);
      uint32_t length = debug_loc_data.GetU32(offset_ptr);
      high_pc = low_pc + length;
      return true;
    }
    default:
      // Not supported entry type
      return false;
    }
  }
  assert(false && "Not supported location list type");
  return false;
}

static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data,
                               lldb::offset_t *offset_ptr, int address_size,
                               int dwarf_ref_size) {
  uint8_t opcode = data.GetU8(offset_ptr);
  DRC_class opcode_class;
  uint64_t uint;
  int64_t sint;

  int size;

  opcode_class = DW_OP_value_to_class(opcode) & (~DRC_DWARFv3);

  s.Printf("%s ", DW_OP_value_to_name(opcode));

  /* Does this take zero parameters?  If so we can shortcut this function.  */
  if (opcode_class == DRC_ZEROOPERANDS)
    return true;

  if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx) {
    uint = data.GetULEB128(offset_ptr);
    sint = data.GetSLEB128(offset_ptr);
    s.Printf("%" PRIu64 " %" PRIi64, uint, sint);
    return true;
  }
  if (opcode_class != DRC_ONEOPERAND) {
    s.Printf("UNKNOWN OP %u", opcode);
    return false;
  }

  switch (opcode) {
  case DW_OP_addr:
    size = address_size;
    break;
  case DW_OP_const1u:
    size = 1;
    break;
  case DW_OP_const1s:
    size = -1;
    break;
  case DW_OP_const2u:
    size = 2;
    break;
  case DW_OP_const2s:
    size = -2;
    break;
  case DW_OP_const4u:
    size = 4;
    break;
  case DW_OP_const4s:
    size = -4;
    break;
  case DW_OP_const8u:
    size = 8;
    break;
  case DW_OP_const8s:
    size = -8;
    break;
  case DW_OP_constu:
    size = 128;
    break;
  case DW_OP_consts:
    size = -128;
    break;
  case DW_OP_fbreg:
    size = -128;
    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:
    size = -128;
    break;
  case DW_OP_pick:
  case DW_OP_deref_size:
  case DW_OP_xderef_size:
    size = 1;
    break;
  case DW_OP_skip:
  case DW_OP_bra:
    size = -2;
    break;
  case DW_OP_call2:
    size = 2;
    break;
  case DW_OP_call4:
    size = 4;
    break;
  case DW_OP_call_ref:
    size = dwarf_ref_size;
    break;
  case DW_OP_piece:
  case DW_OP_plus_uconst:
  case DW_OP_regx:
  case DW_OP_GNU_addr_index:
  case DW_OP_GNU_const_index:
    size = 128;
    break;
  default:
    s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode);
    return true;
  }

  switch (size) {
  case -1:
    sint = (int8_t)data.GetU8(offset_ptr);
    s.Printf("%+" PRIi64, sint);
    break;
  case -2:
    sint = (int16_t)data.GetU16(offset_ptr);
    s.Printf("%+" PRIi64, sint);
    break;
  case -4:
    sint = (int32_t)data.GetU32(offset_ptr);
    s.Printf("%+" PRIi64, sint);
    break;
  case -8:
    sint = (int64_t)data.GetU64(offset_ptr);
    s.Printf("%+" PRIi64, sint);
    break;
  case -128:
    sint = data.GetSLEB128(offset_ptr);
    s.Printf("%+" PRIi64, sint);
    break;
  case 1:
    uint = data.GetU8(offset_ptr);
    s.Printf("0x%2.2" PRIx64, uint);
    break;
  case 2:
    uint = data.GetU16(offset_ptr);
    s.Printf("0x%4.4" PRIx64, uint);
    break;
  case 4:
    uint = data.GetU32(offset_ptr);
    s.Printf("0x%8.8" PRIx64, uint);
    break;
  case 8:
    uint = data.GetU64(offset_ptr);
    s.Printf("0x%16.16" PRIx64, uint);
    break;
  case 128:
    uint = data.GetULEB128(offset_ptr);
    s.Printf("0x%" PRIx64, uint);
    break;
  }

  return false;
}

bool DWARFExpression::PrintDWARFExpression(Stream &s, const DataExtractor &data,
                                           int address_size, int dwarf_ref_size,
                                           bool location_expression) {
  int op_count = 0;
  lldb::offset_t offset = 0;
  while (data.ValidOffset(offset)) {
    if (location_expression && op_count > 0)
      return false;
    if (op_count > 0)
      s.PutCString(", ");
    if (!print_dwarf_exp_op(s, data, &offset, address_size, dwarf_ref_size))
      return false;
    op_count++;
  }

  return true;
}

void DWARFExpression::PrintDWARFLocationList(
    Stream &s, const DWARFCompileUnit *cu, const DataExtractor &debug_loc_data,
    lldb::offset_t offset) {
  uint64_t start_addr, end_addr;
  uint32_t addr_size = DWARFCompileUnit::GetAddressByteSize(cu);
  s.SetAddressByteSize(DWARFCompileUnit::GetAddressByteSize(cu));
  dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
  while (debug_loc_data.ValidOffset(offset)) {
    start_addr = debug_loc_data.GetMaxU64(&offset, addr_size);
    end_addr = debug_loc_data.GetMaxU64(&offset, addr_size);

    if (start_addr == 0 && end_addr == 0)
      break;

    s.PutCString("\n            ");
    s.Indent();
    if (cu)
      s.AddressRange(start_addr + base_addr, end_addr + base_addr,
                     cu->GetAddressByteSize(), NULL, ": ");
    uint32_t loc_length = debug_loc_data.GetU16(&offset);

    DataExtractor locationData(debug_loc_data, offset, loc_length);
    PrintDWARFExpression(s, locationData, addr_size, 4, false);
    offset += loc_length;
  }
}

bool DWARFExpression::GetOpAndEndOffsets(StackFrame &frame,
                                         lldb::offset_t &op_offset,
                                         lldb::offset_t &end_offset) {
  SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction);
  if (!sc.function) {
    return false;
  }

  addr_t loclist_base_file_addr =
      sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
  if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) {
    return false;
  }

  addr_t pc_file_addr = frame.GetFrameCodeAddress().GetFileAddress();
  lldb::offset_t opcodes_offset, opcodes_length;
  if (!GetLocation(loclist_base_file_addr, pc_file_addr, opcodes_offset,
                   opcodes_length)) {
    return false;
  }

  if (opcodes_length == 0) {
    return false;
  }

  op_offset = opcodes_offset;
  end_offset = opcodes_offset + opcodes_length;
  return true;
}

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

  lldb::offset_t op_offset;
  lldb::offset_t end_offset;
  if (!GetOpAndEndOffsets(frame, op_offset, end_offset)) {
    return false;
  }

  if (!m_data.ValidOffset(op_offset) || op_offset >= end_offset) {
    return false;
  }

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

  DataExtractor opcodes = m_data;
  uint8_t opcode = opcodes.GetU8(&op_offset);

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

    DWARFExpression *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);
  }
}

