//===-- 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/DataEncoder.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/VMRange.h"

#include "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"

#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.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,
    Error *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,
    Error *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,
    Error *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,
    Error *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);
                            Error 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)];
                            Error 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
                    {
                        Error 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_entry:
                    return false;
                case DW_LLE_start_end_entry:
                    {
                        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_start_length_entry:
                    {
                        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;
    }
}
