1254721Semaste//===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Expression/DWARFExpression.h"
11254721Semaste
12254721Semaste#include <vector>
13254721Semaste
14254721Semaste#include "lldb/Core/DataEncoder.h"
15254721Semaste#include "lldb/Core/dwarf.h"
16254721Semaste#include "lldb/Core/Log.h"
17254721Semaste#include "lldb/Core/RegisterValue.h"
18254721Semaste#include "lldb/Core/StreamString.h"
19254721Semaste#include "lldb/Core/Scalar.h"
20254721Semaste#include "lldb/Core/Value.h"
21254721Semaste#include "lldb/Core/VMRange.h"
22254721Semaste
23254721Semaste#include "lldb/Expression/ClangExpressionDeclMap.h"
24254721Semaste#include "lldb/Expression/ClangExpressionVariable.h"
25254721Semaste
26254721Semaste#include "lldb/Host/Endian.h"
27254721Semaste#include "lldb/Host/Host.h"
28254721Semaste
29254721Semaste#include "lldb/lldb-private-log.h"
30254721Semaste
31254721Semaste#include "lldb/Symbol/ClangASTType.h"
32254721Semaste#include "lldb/Symbol/ClangASTContext.h"
33254721Semaste#include "lldb/Symbol/Type.h"
34254721Semaste
35254721Semaste#include "lldb/Target/ABI.h"
36254721Semaste#include "lldb/Target/ExecutionContext.h"
37254721Semaste#include "lldb/Target/Process.h"
38254721Semaste#include "lldb/Target/RegisterContext.h"
39254721Semaste#include "lldb/Target/StackFrame.h"
40254721Semaste#include "lldb/Target/StackID.h"
41254721Semaste
42254721Semasteusing namespace lldb;
43254721Semasteusing namespace lldb_private;
44254721Semaste
45254721Semasteconst char *
46254721SemasteDW_OP_value_to_name (uint32_t val)
47254721Semaste{
48254721Semaste  static char invalid[100];
49254721Semaste  switch (val) {
50254721Semaste    case 0x03: return "DW_OP_addr";
51254721Semaste    case 0x06: return "DW_OP_deref";
52254721Semaste    case 0x08: return "DW_OP_const1u";
53254721Semaste    case 0x09: return "DW_OP_const1s";
54254721Semaste    case 0x0a: return "DW_OP_const2u";
55254721Semaste    case 0x0b: return "DW_OP_const2s";
56254721Semaste    case 0x0c: return "DW_OP_const4u";
57254721Semaste    case 0x0d: return "DW_OP_const4s";
58254721Semaste    case 0x0e: return "DW_OP_const8u";
59254721Semaste    case 0x0f: return "DW_OP_const8s";
60254721Semaste    case 0x10: return "DW_OP_constu";
61254721Semaste    case 0x11: return "DW_OP_consts";
62254721Semaste    case 0x12: return "DW_OP_dup";
63254721Semaste    case 0x13: return "DW_OP_drop";
64254721Semaste    case 0x14: return "DW_OP_over";
65254721Semaste    case 0x15: return "DW_OP_pick";
66254721Semaste    case 0x16: return "DW_OP_swap";
67254721Semaste    case 0x17: return "DW_OP_rot";
68254721Semaste    case 0x18: return "DW_OP_xderef";
69254721Semaste    case 0x19: return "DW_OP_abs";
70254721Semaste    case 0x1a: return "DW_OP_and";
71254721Semaste    case 0x1b: return "DW_OP_div";
72254721Semaste    case 0x1c: return "DW_OP_minus";
73254721Semaste    case 0x1d: return "DW_OP_mod";
74254721Semaste    case 0x1e: return "DW_OP_mul";
75254721Semaste    case 0x1f: return "DW_OP_neg";
76254721Semaste    case 0x20: return "DW_OP_not";
77254721Semaste    case 0x21: return "DW_OP_or";
78254721Semaste    case 0x22: return "DW_OP_plus";
79254721Semaste    case 0x23: return "DW_OP_plus_uconst";
80254721Semaste    case 0x24: return "DW_OP_shl";
81254721Semaste    case 0x25: return "DW_OP_shr";
82254721Semaste    case 0x26: return "DW_OP_shra";
83254721Semaste    case 0x27: return "DW_OP_xor";
84254721Semaste    case 0x2f: return "DW_OP_skip";
85254721Semaste    case 0x28: return "DW_OP_bra";
86254721Semaste    case 0x29: return "DW_OP_eq";
87254721Semaste    case 0x2a: return "DW_OP_ge";
88254721Semaste    case 0x2b: return "DW_OP_gt";
89254721Semaste    case 0x2c: return "DW_OP_le";
90254721Semaste    case 0x2d: return "DW_OP_lt";
91254721Semaste    case 0x2e: return "DW_OP_ne";
92254721Semaste    case 0x30: return "DW_OP_lit0";
93254721Semaste    case 0x31: return "DW_OP_lit1";
94254721Semaste    case 0x32: return "DW_OP_lit2";
95254721Semaste    case 0x33: return "DW_OP_lit3";
96254721Semaste    case 0x34: return "DW_OP_lit4";
97254721Semaste    case 0x35: return "DW_OP_lit5";
98254721Semaste    case 0x36: return "DW_OP_lit6";
99254721Semaste    case 0x37: return "DW_OP_lit7";
100254721Semaste    case 0x38: return "DW_OP_lit8";
101254721Semaste    case 0x39: return "DW_OP_lit9";
102254721Semaste    case 0x3a: return "DW_OP_lit10";
103254721Semaste    case 0x3b: return "DW_OP_lit11";
104254721Semaste    case 0x3c: return "DW_OP_lit12";
105254721Semaste    case 0x3d: return "DW_OP_lit13";
106254721Semaste    case 0x3e: return "DW_OP_lit14";
107254721Semaste    case 0x3f: return "DW_OP_lit15";
108254721Semaste    case 0x40: return "DW_OP_lit16";
109254721Semaste    case 0x41: return "DW_OP_lit17";
110254721Semaste    case 0x42: return "DW_OP_lit18";
111254721Semaste    case 0x43: return "DW_OP_lit19";
112254721Semaste    case 0x44: return "DW_OP_lit20";
113254721Semaste    case 0x45: return "DW_OP_lit21";
114254721Semaste    case 0x46: return "DW_OP_lit22";
115254721Semaste    case 0x47: return "DW_OP_lit23";
116254721Semaste    case 0x48: return "DW_OP_lit24";
117254721Semaste    case 0x49: return "DW_OP_lit25";
118254721Semaste    case 0x4a: return "DW_OP_lit26";
119254721Semaste    case 0x4b: return "DW_OP_lit27";
120254721Semaste    case 0x4c: return "DW_OP_lit28";
121254721Semaste    case 0x4d: return "DW_OP_lit29";
122254721Semaste    case 0x4e: return "DW_OP_lit30";
123254721Semaste    case 0x4f: return "DW_OP_lit31";
124254721Semaste    case 0x50: return "DW_OP_reg0";
125254721Semaste    case 0x51: return "DW_OP_reg1";
126254721Semaste    case 0x52: return "DW_OP_reg2";
127254721Semaste    case 0x53: return "DW_OP_reg3";
128254721Semaste    case 0x54: return "DW_OP_reg4";
129254721Semaste    case 0x55: return "DW_OP_reg5";
130254721Semaste    case 0x56: return "DW_OP_reg6";
131254721Semaste    case 0x57: return "DW_OP_reg7";
132254721Semaste    case 0x58: return "DW_OP_reg8";
133254721Semaste    case 0x59: return "DW_OP_reg9";
134254721Semaste    case 0x5a: return "DW_OP_reg10";
135254721Semaste    case 0x5b: return "DW_OP_reg11";
136254721Semaste    case 0x5c: return "DW_OP_reg12";
137254721Semaste    case 0x5d: return "DW_OP_reg13";
138254721Semaste    case 0x5e: return "DW_OP_reg14";
139254721Semaste    case 0x5f: return "DW_OP_reg15";
140254721Semaste    case 0x60: return "DW_OP_reg16";
141254721Semaste    case 0x61: return "DW_OP_reg17";
142254721Semaste    case 0x62: return "DW_OP_reg18";
143254721Semaste    case 0x63: return "DW_OP_reg19";
144254721Semaste    case 0x64: return "DW_OP_reg20";
145254721Semaste    case 0x65: return "DW_OP_reg21";
146254721Semaste    case 0x66: return "DW_OP_reg22";
147254721Semaste    case 0x67: return "DW_OP_reg23";
148254721Semaste    case 0x68: return "DW_OP_reg24";
149254721Semaste    case 0x69: return "DW_OP_reg25";
150254721Semaste    case 0x6a: return "DW_OP_reg26";
151254721Semaste    case 0x6b: return "DW_OP_reg27";
152254721Semaste    case 0x6c: return "DW_OP_reg28";
153254721Semaste    case 0x6d: return "DW_OP_reg29";
154254721Semaste    case 0x6e: return "DW_OP_reg30";
155254721Semaste    case 0x6f: return "DW_OP_reg31";
156254721Semaste    case 0x70: return "DW_OP_breg0";
157254721Semaste    case 0x71: return "DW_OP_breg1";
158254721Semaste    case 0x72: return "DW_OP_breg2";
159254721Semaste    case 0x73: return "DW_OP_breg3";
160254721Semaste    case 0x74: return "DW_OP_breg4";
161254721Semaste    case 0x75: return "DW_OP_breg5";
162254721Semaste    case 0x76: return "DW_OP_breg6";
163254721Semaste    case 0x77: return "DW_OP_breg7";
164254721Semaste    case 0x78: return "DW_OP_breg8";
165254721Semaste    case 0x79: return "DW_OP_breg9";
166254721Semaste    case 0x7a: return "DW_OP_breg10";
167254721Semaste    case 0x7b: return "DW_OP_breg11";
168254721Semaste    case 0x7c: return "DW_OP_breg12";
169254721Semaste    case 0x7d: return "DW_OP_breg13";
170254721Semaste    case 0x7e: return "DW_OP_breg14";
171254721Semaste    case 0x7f: return "DW_OP_breg15";
172254721Semaste    case 0x80: return "DW_OP_breg16";
173254721Semaste    case 0x81: return "DW_OP_breg17";
174254721Semaste    case 0x82: return "DW_OP_breg18";
175254721Semaste    case 0x83: return "DW_OP_breg19";
176254721Semaste    case 0x84: return "DW_OP_breg20";
177254721Semaste    case 0x85: return "DW_OP_breg21";
178254721Semaste    case 0x86: return "DW_OP_breg22";
179254721Semaste    case 0x87: return "DW_OP_breg23";
180254721Semaste    case 0x88: return "DW_OP_breg24";
181254721Semaste    case 0x89: return "DW_OP_breg25";
182254721Semaste    case 0x8a: return "DW_OP_breg26";
183254721Semaste    case 0x8b: return "DW_OP_breg27";
184254721Semaste    case 0x8c: return "DW_OP_breg28";
185254721Semaste    case 0x8d: return "DW_OP_breg29";
186254721Semaste    case 0x8e: return "DW_OP_breg30";
187254721Semaste    case 0x8f: return "DW_OP_breg31";
188254721Semaste    case 0x90: return "DW_OP_regx";
189254721Semaste    case 0x91: return "DW_OP_fbreg";
190254721Semaste    case 0x92: return "DW_OP_bregx";
191254721Semaste    case 0x93: return "DW_OP_piece";
192254721Semaste    case 0x94: return "DW_OP_deref_size";
193254721Semaste    case 0x95: return "DW_OP_xderef_size";
194254721Semaste    case 0x96: return "DW_OP_nop";
195254721Semaste    case 0x97: return "DW_OP_push_object_address";
196254721Semaste    case 0x98: return "DW_OP_call2";
197254721Semaste    case 0x99: return "DW_OP_call4";
198254721Semaste    case 0x9a: return "DW_OP_call_ref";
199254721Semaste//    case DW_OP_APPLE_array_ref: return "DW_OP_APPLE_array_ref";
200254721Semaste//    case DW_OP_APPLE_extern: return "DW_OP_APPLE_extern";
201254721Semaste    case DW_OP_APPLE_uninit: return "DW_OP_APPLE_uninit";
202254721Semaste//    case DW_OP_APPLE_assign: return "DW_OP_APPLE_assign";
203254721Semaste//    case DW_OP_APPLE_address_of: return "DW_OP_APPLE_address_of";
204254721Semaste//    case DW_OP_APPLE_value_of: return "DW_OP_APPLE_value_of";
205254721Semaste//    case DW_OP_APPLE_deref_type: return "DW_OP_APPLE_deref_type";
206254721Semaste//    case DW_OP_APPLE_expr_local: return "DW_OP_APPLE_expr_local";
207254721Semaste//    case DW_OP_APPLE_constf: return "DW_OP_APPLE_constf";
208254721Semaste//    case DW_OP_APPLE_scalar_cast: return "DW_OP_APPLE_scalar_cast";
209254721Semaste//    case DW_OP_APPLE_clang_cast: return "DW_OP_APPLE_clang_cast";
210254721Semaste//    case DW_OP_APPLE_clear: return "DW_OP_APPLE_clear";
211254721Semaste//    case DW_OP_APPLE_error: return "DW_OP_APPLE_error";
212254721Semaste    default:
213254721Semaste       snprintf (invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
214254721Semaste       return invalid;
215254721Semaste  }
216254721Semaste}
217254721Semaste
218254721Semaste
219254721Semaste//----------------------------------------------------------------------
220254721Semaste// DWARFExpression constructor
221254721Semaste//----------------------------------------------------------------------
222254721SemasteDWARFExpression::DWARFExpression() :
223254721Semaste    m_data(),
224254721Semaste    m_reg_kind (eRegisterKindDWARF),
225254721Semaste    m_loclist_slide (LLDB_INVALID_ADDRESS)
226254721Semaste{
227254721Semaste}
228254721Semaste
229254721SemasteDWARFExpression::DWARFExpression(const DWARFExpression& rhs) :
230254721Semaste    m_data(rhs.m_data),
231254721Semaste    m_reg_kind (rhs.m_reg_kind),
232254721Semaste    m_loclist_slide(rhs.m_loclist_slide)
233254721Semaste{
234254721Semaste}
235254721Semaste
236254721Semaste
237254721SemasteDWARFExpression::DWARFExpression(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) :
238254721Semaste    m_data(data, data_offset, data_length),
239254721Semaste    m_reg_kind (eRegisterKindDWARF),
240254721Semaste    m_loclist_slide(LLDB_INVALID_ADDRESS)
241254721Semaste{
242254721Semaste}
243254721Semaste
244254721Semaste//----------------------------------------------------------------------
245254721Semaste// Destructor
246254721Semaste//----------------------------------------------------------------------
247254721SemasteDWARFExpression::~DWARFExpression()
248254721Semaste{
249254721Semaste}
250254721Semaste
251254721Semaste
252254721Semastebool
253254721SemasteDWARFExpression::IsValid() const
254254721Semaste{
255254721Semaste    return m_data.GetByteSize() > 0;
256254721Semaste}
257254721Semaste
258254721Semastevoid
259254721SemasteDWARFExpression::SetOpcodeData (const DataExtractor& data)
260254721Semaste{
261254721Semaste    m_data = data;
262254721Semaste}
263254721Semaste
264254721Semastevoid
265254721SemasteDWARFExpression::CopyOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length)
266254721Semaste{
267254721Semaste    const uint8_t *bytes = data.PeekData(data_offset, data_length);
268254721Semaste    if (bytes)
269254721Semaste    {
270254721Semaste        m_data.SetData(DataBufferSP(new DataBufferHeap(bytes, data_length)));
271254721Semaste        m_data.SetByteOrder(data.GetByteOrder());
272254721Semaste        m_data.SetAddressByteSize(data.GetAddressByteSize());
273254721Semaste    }
274254721Semaste}
275254721Semaste
276254721Semastevoid
277254721SemasteDWARFExpression::SetOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length)
278254721Semaste{
279254721Semaste    m_data.SetData(data, data_offset, data_length);
280254721Semaste}
281254721Semaste
282254721Semastevoid
283254721SemasteDWARFExpression::DumpLocation (Stream *s, lldb::offset_t offset, lldb::offset_t length, lldb::DescriptionLevel level, ABI *abi) const
284254721Semaste{
285254721Semaste    if (!m_data.ValidOffsetForDataOfSize(offset, length))
286254721Semaste        return;
287254721Semaste    const lldb::offset_t start_offset = offset;
288254721Semaste    const lldb::offset_t end_offset = offset + length;
289254721Semaste    while (m_data.ValidOffset(offset) && offset < end_offset)
290254721Semaste    {
291254721Semaste        const lldb::offset_t op_offset = offset;
292254721Semaste        const uint8_t op = m_data.GetU8(&offset);
293254721Semaste
294254721Semaste        switch (level)
295254721Semaste        {
296254721Semaste        default:
297254721Semaste            break;
298254721Semaste
299254721Semaste        case lldb::eDescriptionLevelBrief:
300254721Semaste            if (offset > start_offset)
301254721Semaste                s->PutChar(' ');
302254721Semaste            break;
303254721Semaste
304254721Semaste        case lldb::eDescriptionLevelFull:
305254721Semaste        case lldb::eDescriptionLevelVerbose:
306254721Semaste            if (offset > start_offset)
307254721Semaste                s->EOL();
308254721Semaste            s->Indent();
309254721Semaste            if (level == lldb::eDescriptionLevelFull)
310254721Semaste                break;
311254721Semaste            // Fall through for verbose and print offset and DW_OP prefix..
312254721Semaste            s->Printf("0x%8.8" PRIx64 ": %s", op_offset, op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
313254721Semaste            break;
314254721Semaste        }
315254721Semaste
316254721Semaste        switch (op)
317254721Semaste        {
318254721Semaste        case DW_OP_addr:    *s << "DW_OP_addr(" << m_data.GetAddress(&offset) << ") "; break;         // 0x03 1 address
319254721Semaste        case DW_OP_deref:   *s << "DW_OP_deref"; break;                                               // 0x06
320254721Semaste        case DW_OP_const1u: s->Printf("DW_OP_const1u(0x%2.2x) ", m_data.GetU8(&offset)); break;       // 0x08 1 1-byte constant
321254721Semaste        case DW_OP_const1s: s->Printf("DW_OP_const1s(0x%2.2x) ", m_data.GetU8(&offset)); break;       // 0x09 1 1-byte constant
322254721Semaste        case DW_OP_const2u: s->Printf("DW_OP_const2u(0x%4.4x) ", m_data.GetU16(&offset)); break;      // 0x0a 1 2-byte constant
323254721Semaste        case DW_OP_const2s: s->Printf("DW_OP_const2s(0x%4.4x) ", m_data.GetU16(&offset)); break;      // 0x0b 1 2-byte constant
324254721Semaste        case DW_OP_const4u: s->Printf("DW_OP_const4u(0x%8.8x) ", m_data.GetU32(&offset)); break;      // 0x0c 1 4-byte constant
325254721Semaste        case DW_OP_const4s: s->Printf("DW_OP_const4s(0x%8.8x) ", m_data.GetU32(&offset)); break;      // 0x0d 1 4-byte constant
326254721Semaste        case DW_OP_const8u: s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset)); break;  // 0x0e 1 8-byte constant
327254721Semaste        case DW_OP_const8s: s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset)); break;  // 0x0f 1 8-byte constant
328254721Semaste        case DW_OP_constu:  s->Printf("DW_OP_constu(0x%" PRIx64 ") ", m_data.GetULEB128(&offset)); break;    // 0x10 1 ULEB128 constant
329254721Semaste        case DW_OP_consts:  s->Printf("DW_OP_consts(0x%" PRId64 ") ", m_data.GetSLEB128(&offset)); break;    // 0x11 1 SLEB128 constant
330254721Semaste        case DW_OP_dup:     s->PutCString("DW_OP_dup"); break;                                        // 0x12
331254721Semaste        case DW_OP_drop:    s->PutCString("DW_OP_drop"); break;                                       // 0x13
332254721Semaste        case DW_OP_over:    s->PutCString("DW_OP_over"); break;                                       // 0x14
333254721Semaste        case DW_OP_pick:    s->Printf("DW_OP_pick(0x%2.2x) ", m_data.GetU8(&offset)); break;          // 0x15 1 1-byte stack index
334254721Semaste        case DW_OP_swap:    s->PutCString("DW_OP_swap"); break;                                       // 0x16
335254721Semaste        case DW_OP_rot:     s->PutCString("DW_OP_rot"); break;                                        // 0x17
336254721Semaste        case DW_OP_xderef:  s->PutCString("DW_OP_xderef"); break;                                     // 0x18
337254721Semaste        case DW_OP_abs:     s->PutCString("DW_OP_abs"); break;                                        // 0x19
338254721Semaste        case DW_OP_and:     s->PutCString("DW_OP_and"); break;                                        // 0x1a
339254721Semaste        case DW_OP_div:     s->PutCString("DW_OP_div"); break;                                        // 0x1b
340254721Semaste        case DW_OP_minus:   s->PutCString("DW_OP_minus"); break;                                      // 0x1c
341254721Semaste        case DW_OP_mod:     s->PutCString("DW_OP_mod"); break;                                        // 0x1d
342254721Semaste        case DW_OP_mul:     s->PutCString("DW_OP_mul"); break;                                        // 0x1e
343254721Semaste        case DW_OP_neg:     s->PutCString("DW_OP_neg"); break;                                        // 0x1f
344254721Semaste        case DW_OP_not:     s->PutCString("DW_OP_not"); break;                                        // 0x20
345254721Semaste        case DW_OP_or:      s->PutCString("DW_OP_or"); break;                                         // 0x21
346254721Semaste        case DW_OP_plus:    s->PutCString("DW_OP_plus"); break;                                       // 0x22
347254721Semaste        case DW_OP_plus_uconst:                                                                 // 0x23 1 ULEB128 addend
348254721Semaste            s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ") ", m_data.GetULEB128(&offset));
349254721Semaste            break;
350254721Semaste
351254721Semaste        case DW_OP_shl:     s->PutCString("DW_OP_shl"); break;                                        // 0x24
352254721Semaste        case DW_OP_shr:     s->PutCString("DW_OP_shr"); break;                                        // 0x25
353254721Semaste        case DW_OP_shra:    s->PutCString("DW_OP_shra"); break;                                       // 0x26
354254721Semaste        case DW_OP_xor:     s->PutCString("DW_OP_xor"); break;                                        // 0x27
355254721Semaste        case DW_OP_skip:    s->Printf("DW_OP_skip(0x%4.4x)", m_data.GetU16(&offset)); break;          // 0x2f 1 signed 2-byte constant
356254721Semaste        case DW_OP_bra:     s->Printf("DW_OP_bra(0x%4.4x)", m_data.GetU16(&offset)); break;           // 0x28 1 signed 2-byte constant
357254721Semaste        case DW_OP_eq:      s->PutCString("DW_OP_eq"); break;                                         // 0x29
358254721Semaste        case DW_OP_ge:      s->PutCString("DW_OP_ge"); break;                                         // 0x2a
359254721Semaste        case DW_OP_gt:      s->PutCString("DW_OP_gt"); break;                                         // 0x2b
360254721Semaste        case DW_OP_le:      s->PutCString("DW_OP_le"); break;                                         // 0x2c
361254721Semaste        case DW_OP_lt:      s->PutCString("DW_OP_lt"); break;                                         // 0x2d
362254721Semaste        case DW_OP_ne:      s->PutCString("DW_OP_ne"); break;                                         // 0x2e
363254721Semaste
364254721Semaste        case DW_OP_lit0:    // 0x30
365254721Semaste        case DW_OP_lit1:    // 0x31
366254721Semaste        case DW_OP_lit2:    // 0x32
367254721Semaste        case DW_OP_lit3:    // 0x33
368254721Semaste        case DW_OP_lit4:    // 0x34
369254721Semaste        case DW_OP_lit5:    // 0x35
370254721Semaste        case DW_OP_lit6:    // 0x36
371254721Semaste        case DW_OP_lit7:    // 0x37
372254721Semaste        case DW_OP_lit8:    // 0x38
373254721Semaste        case DW_OP_lit9:    // 0x39
374254721Semaste        case DW_OP_lit10:   // 0x3A
375254721Semaste        case DW_OP_lit11:   // 0x3B
376254721Semaste        case DW_OP_lit12:   // 0x3C
377254721Semaste        case DW_OP_lit13:   // 0x3D
378254721Semaste        case DW_OP_lit14:   // 0x3E
379254721Semaste        case DW_OP_lit15:   // 0x3F
380254721Semaste        case DW_OP_lit16:   // 0x40
381254721Semaste        case DW_OP_lit17:   // 0x41
382254721Semaste        case DW_OP_lit18:   // 0x42
383254721Semaste        case DW_OP_lit19:   // 0x43
384254721Semaste        case DW_OP_lit20:   // 0x44
385254721Semaste        case DW_OP_lit21:   // 0x45
386254721Semaste        case DW_OP_lit22:   // 0x46
387254721Semaste        case DW_OP_lit23:   // 0x47
388254721Semaste        case DW_OP_lit24:   // 0x48
389254721Semaste        case DW_OP_lit25:   // 0x49
390254721Semaste        case DW_OP_lit26:   // 0x4A
391254721Semaste        case DW_OP_lit27:   // 0x4B
392254721Semaste        case DW_OP_lit28:   // 0x4C
393254721Semaste        case DW_OP_lit29:   // 0x4D
394254721Semaste        case DW_OP_lit30:   // 0x4E
395254721Semaste        case DW_OP_lit31:   s->Printf("DW_OP_lit%i", op - DW_OP_lit0); break; // 0x4f
396254721Semaste
397254721Semaste        case DW_OP_reg0:    // 0x50
398254721Semaste        case DW_OP_reg1:    // 0x51
399254721Semaste        case DW_OP_reg2:    // 0x52
400254721Semaste        case DW_OP_reg3:    // 0x53
401254721Semaste        case DW_OP_reg4:    // 0x54
402254721Semaste        case DW_OP_reg5:    // 0x55
403254721Semaste        case DW_OP_reg6:    // 0x56
404254721Semaste        case DW_OP_reg7:    // 0x57
405254721Semaste        case DW_OP_reg8:    // 0x58
406254721Semaste        case DW_OP_reg9:    // 0x59
407254721Semaste        case DW_OP_reg10:   // 0x5A
408254721Semaste        case DW_OP_reg11:   // 0x5B
409254721Semaste        case DW_OP_reg12:   // 0x5C
410254721Semaste        case DW_OP_reg13:   // 0x5D
411254721Semaste        case DW_OP_reg14:   // 0x5E
412254721Semaste        case DW_OP_reg15:   // 0x5F
413254721Semaste        case DW_OP_reg16:   // 0x60
414254721Semaste        case DW_OP_reg17:   // 0x61
415254721Semaste        case DW_OP_reg18:   // 0x62
416254721Semaste        case DW_OP_reg19:   // 0x63
417254721Semaste        case DW_OP_reg20:   // 0x64
418254721Semaste        case DW_OP_reg21:   // 0x65
419254721Semaste        case DW_OP_reg22:   // 0x66
420254721Semaste        case DW_OP_reg23:   // 0x67
421254721Semaste        case DW_OP_reg24:   // 0x68
422254721Semaste        case DW_OP_reg25:   // 0x69
423254721Semaste        case DW_OP_reg26:   // 0x6A
424254721Semaste        case DW_OP_reg27:   // 0x6B
425254721Semaste        case DW_OP_reg28:   // 0x6C
426254721Semaste        case DW_OP_reg29:   // 0x6D
427254721Semaste        case DW_OP_reg30:   // 0x6E
428254721Semaste        case DW_OP_reg31:   // 0x6F
429254721Semaste            {
430254721Semaste                uint32_t reg_num = op - DW_OP_reg0;
431254721Semaste                if (abi)
432254721Semaste                {
433254721Semaste                    RegisterInfo reg_info;
434254721Semaste                    if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info))
435254721Semaste                    {
436254721Semaste                        if (reg_info.name)
437254721Semaste                        {
438254721Semaste                            s->PutCString (reg_info.name);
439254721Semaste                            break;
440254721Semaste                        }
441254721Semaste                        else if (reg_info.alt_name)
442254721Semaste                        {
443254721Semaste                            s->PutCString (reg_info.alt_name);
444254721Semaste                            break;
445254721Semaste                        }
446254721Semaste                    }
447254721Semaste                }
448254721Semaste                s->Printf("DW_OP_reg%u", reg_num); break;
449254721Semaste            }
450254721Semaste            break;
451254721Semaste
452254721Semaste        case DW_OP_breg0:
453254721Semaste        case DW_OP_breg1:
454254721Semaste        case DW_OP_breg2:
455254721Semaste        case DW_OP_breg3:
456254721Semaste        case DW_OP_breg4:
457254721Semaste        case DW_OP_breg5:
458254721Semaste        case DW_OP_breg6:
459254721Semaste        case DW_OP_breg7:
460254721Semaste        case DW_OP_breg8:
461254721Semaste        case DW_OP_breg9:
462254721Semaste        case DW_OP_breg10:
463254721Semaste        case DW_OP_breg11:
464254721Semaste        case DW_OP_breg12:
465254721Semaste        case DW_OP_breg13:
466254721Semaste        case DW_OP_breg14:
467254721Semaste        case DW_OP_breg15:
468254721Semaste        case DW_OP_breg16:
469254721Semaste        case DW_OP_breg17:
470254721Semaste        case DW_OP_breg18:
471254721Semaste        case DW_OP_breg19:
472254721Semaste        case DW_OP_breg20:
473254721Semaste        case DW_OP_breg21:
474254721Semaste        case DW_OP_breg22:
475254721Semaste        case DW_OP_breg23:
476254721Semaste        case DW_OP_breg24:
477254721Semaste        case DW_OP_breg25:
478254721Semaste        case DW_OP_breg26:
479254721Semaste        case DW_OP_breg27:
480254721Semaste        case DW_OP_breg28:
481254721Semaste        case DW_OP_breg29:
482254721Semaste        case DW_OP_breg30:
483254721Semaste        case DW_OP_breg31:
484254721Semaste            {
485254721Semaste                uint32_t reg_num = op - DW_OP_breg0;
486254721Semaste                int64_t reg_offset = m_data.GetSLEB128(&offset);
487254721Semaste                if (abi)
488254721Semaste                {
489254721Semaste                    RegisterInfo reg_info;
490254721Semaste                    if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info))
491254721Semaste                    {
492254721Semaste                        if (reg_info.name)
493254721Semaste                        {
494254721Semaste                            s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
495254721Semaste                            break;
496254721Semaste                        }
497254721Semaste                        else if (reg_info.alt_name)
498254721Semaste                        {
499254721Semaste                            s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
500254721Semaste                            break;
501254721Semaste                        }
502254721Semaste                    }
503254721Semaste                }
504254721Semaste                s->Printf("DW_OP_breg%i(0x%" PRIx64 ")", reg_num, reg_offset);
505254721Semaste            }
506254721Semaste            break;
507254721Semaste
508254721Semaste        case DW_OP_regx:                                                    // 0x90 1 ULEB128 register
509254721Semaste            {
510254721Semaste                uint32_t reg_num = m_data.GetULEB128(&offset);
511254721Semaste                if (abi)
512254721Semaste                {
513254721Semaste                    RegisterInfo reg_info;
514254721Semaste                    if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info))
515254721Semaste                    {
516254721Semaste                        if (reg_info.name)
517254721Semaste                        {
518254721Semaste                            s->PutCString (reg_info.name);
519254721Semaste                            break;
520254721Semaste                        }
521254721Semaste                        else if (reg_info.alt_name)
522254721Semaste                        {
523254721Semaste                            s->PutCString (reg_info.alt_name);
524254721Semaste                            break;
525254721Semaste                        }
526254721Semaste                    }
527254721Semaste                }
528254721Semaste                s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num); break;
529254721Semaste            }
530254721Semaste            break;
531254721Semaste        case DW_OP_fbreg:                                                   // 0x91 1 SLEB128 offset
532254721Semaste            s->Printf("DW_OP_fbreg(%" PRIi64 ")",m_data.GetSLEB128(&offset));
533254721Semaste            break;
534254721Semaste        case DW_OP_bregx:                                                   // 0x92 2 ULEB128 register followed by SLEB128 offset
535254721Semaste            {
536254721Semaste                uint32_t reg_num = m_data.GetULEB128(&offset);
537254721Semaste                int64_t reg_offset = m_data.GetSLEB128(&offset);
538254721Semaste                if (abi)
539254721Semaste                {
540254721Semaste                    RegisterInfo reg_info;
541254721Semaste                    if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info))
542254721Semaste                    {
543254721Semaste                        if (reg_info.name)
544254721Semaste                        {
545254721Semaste                            s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
546254721Semaste                            break;
547254721Semaste                        }
548254721Semaste                        else if (reg_info.alt_name)
549254721Semaste                        {
550254721Semaste                            s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
551254721Semaste                            break;
552254721Semaste                        }
553254721Semaste                    }
554254721Semaste                }
555254721Semaste                s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num, reg_offset);
556254721Semaste            }
557254721Semaste            break;
558254721Semaste        case DW_OP_piece:                                                   // 0x93 1 ULEB128 size of piece addressed
559254721Semaste            s->Printf("DW_OP_piece(0x%" PRIx64 ")", m_data.GetULEB128(&offset));
560254721Semaste            break;
561254721Semaste        case DW_OP_deref_size:                                              // 0x94 1 1-byte size of data retrieved
562254721Semaste            s->Printf("DW_OP_deref_size(0x%2.2x)", m_data.GetU8(&offset));
563254721Semaste            break;
564254721Semaste        case DW_OP_xderef_size:                                             // 0x95 1 1-byte size of data retrieved
565254721Semaste            s->Printf("DW_OP_xderef_size(0x%2.2x)", m_data.GetU8(&offset));
566254721Semaste            break;
567254721Semaste        case DW_OP_nop: s->PutCString("DW_OP_nop"); break;                                    // 0x96
568254721Semaste        case DW_OP_push_object_address: s->PutCString("DW_OP_push_object_address"); break;    // 0x97 DWARF3
569254721Semaste        case DW_OP_call2:                                                   // 0x98 DWARF3 1 2-byte offset of DIE
570254721Semaste            s->Printf("DW_OP_call2(0x%4.4x)", m_data.GetU16(&offset));
571254721Semaste            break;
572254721Semaste        case DW_OP_call4:                                                   // 0x99 DWARF3 1 4-byte offset of DIE
573254721Semaste            s->Printf("DW_OP_call4(0x%8.8x)", m_data.GetU32(&offset));
574254721Semaste            break;
575254721Semaste        case DW_OP_call_ref:                                                // 0x9a DWARF3 1 4- or 8-byte offset of DIE
576254721Semaste            s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset));
577254721Semaste            break;
578254721Semaste//      case DW_OP_form_tls_address: s << "form_tls_address"; break;        // 0x9b DWARF3
579254721Semaste//      case DW_OP_call_frame_cfa: s << "call_frame_cfa"; break;            // 0x9c DWARF3
580254721Semaste//      case DW_OP_bit_piece:                                               // 0x9d DWARF3 2
581254721Semaste//          s->Printf("DW_OP_bit_piece(0x%x, 0x%x)", m_data.GetULEB128(&offset), m_data.GetULEB128(&offset));
582254721Semaste//          break;
583254721Semaste//      case DW_OP_lo_user:     s->PutCString("DW_OP_lo_user"); break;                        // 0xe0
584254721Semaste//      case DW_OP_hi_user:     s->PutCString("DW_OP_hi_user"); break;                        // 0xff
585254721Semaste//        case DW_OP_APPLE_extern:
586254721Semaste//            s->Printf("DW_OP_APPLE_extern(%" PRIu64 ")", m_data.GetULEB128(&offset));
587254721Semaste//            break;
588254721Semaste//        case DW_OP_APPLE_array_ref:
589254721Semaste//            s->PutCString("DW_OP_APPLE_array_ref");
590254721Semaste//            break;
591254721Semaste        case DW_OP_APPLE_uninit:
592254721Semaste            s->PutCString("DW_OP_APPLE_uninit");  // 0xF0
593254721Semaste            break;
594254721Semaste//        case DW_OP_APPLE_assign:        // 0xF1 - pops value off and assigns it to second item on stack (2nd item must have assignable context)
595254721Semaste//            s->PutCString("DW_OP_APPLE_assign");
596254721Semaste//            break;
597254721Semaste//        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)
598254721Semaste//            s->PutCString("DW_OP_APPLE_address_of");
599254721Semaste//            break;
600254721Semaste//        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)
601254721Semaste//            s->PutCString("DW_OP_APPLE_value_of");
602254721Semaste//            break;
603254721Semaste//        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)
604254721Semaste//            s->PutCString("DW_OP_APPLE_deref_type");
605254721Semaste//            break;
606254721Semaste//        case DW_OP_APPLE_expr_local:    // 0xF5 - ULEB128 expression local index
607254721Semaste//            s->Printf("DW_OP_APPLE_expr_local(%" PRIu64 ")", m_data.GetULEB128(&offset));
608254721Semaste//            break;
609254721Semaste//        case DW_OP_APPLE_constf:        // 0xF6 - 1 byte float size, followed by constant float data
610254721Semaste//            {
611254721Semaste//                uint8_t float_length = m_data.GetU8(&offset);
612254721Semaste//                s->Printf("DW_OP_APPLE_constf(<%u> ", float_length);
613254721Semaste//                m_data.Dump(s, offset, eFormatHex, float_length, 1, UINT32_MAX, DW_INVALID_ADDRESS, 0, 0);
614254721Semaste//                s->PutChar(')');
615254721Semaste//                // Consume the float data
616254721Semaste//                m_data.GetData(&offset, float_length);
617254721Semaste//            }
618254721Semaste//            break;
619254721Semaste//        case DW_OP_APPLE_scalar_cast:
620254721Semaste//            s->Printf("DW_OP_APPLE_scalar_cast(%s)", Scalar::GetValueTypeAsCString ((Scalar::Type)m_data.GetU8(&offset)));
621254721Semaste//            break;
622254721Semaste//        case DW_OP_APPLE_clang_cast:
623254721Semaste//            {
624254721Semaste//                clang::Type *clang_type = (clang::Type *)m_data.GetMaxU64(&offset, sizeof(void*));
625254721Semaste//                s->Printf("DW_OP_APPLE_clang_cast(%p)", clang_type);
626254721Semaste//            }
627254721Semaste//            break;
628254721Semaste//        case DW_OP_APPLE_clear:
629254721Semaste//            s->PutCString("DW_OP_APPLE_clear");
630254721Semaste//            break;
631254721Semaste//        case DW_OP_APPLE_error:         // 0xFF - Stops expression evaluation and returns an error (no args)
632254721Semaste//            s->PutCString("DW_OP_APPLE_error");
633254721Semaste//            break;
634254721Semaste        }
635254721Semaste    }
636254721Semaste}
637254721Semaste
638254721Semastevoid
639254721SemasteDWARFExpression::SetLocationListSlide (addr_t slide)
640254721Semaste{
641254721Semaste    m_loclist_slide = slide;
642254721Semaste}
643254721Semaste
644254721Semasteint
645254721SemasteDWARFExpression::GetRegisterKind ()
646254721Semaste{
647254721Semaste    return m_reg_kind;
648254721Semaste}
649254721Semaste
650254721Semastevoid
651254721SemasteDWARFExpression::SetRegisterKind (RegisterKind reg_kind)
652254721Semaste{
653254721Semaste    m_reg_kind = reg_kind;
654254721Semaste}
655254721Semaste
656254721Semastebool
657254721SemasteDWARFExpression::IsLocationList() const
658254721Semaste{
659254721Semaste    return m_loclist_slide != LLDB_INVALID_ADDRESS;
660254721Semaste}
661254721Semaste
662254721Semastevoid
663254721SemasteDWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level, addr_t location_list_base_addr, ABI *abi) const
664254721Semaste{
665254721Semaste    if (IsLocationList())
666254721Semaste    {
667254721Semaste        // We have a location list
668254721Semaste        lldb::offset_t offset = 0;
669254721Semaste        uint32_t count = 0;
670254721Semaste        addr_t curr_base_addr = location_list_base_addr;
671254721Semaste        while (m_data.ValidOffset(offset))
672254721Semaste        {
673254721Semaste            lldb::addr_t begin_addr_offset = m_data.GetAddress(&offset);
674254721Semaste            lldb::addr_t end_addr_offset = m_data.GetAddress(&offset);
675254721Semaste            if (begin_addr_offset < end_addr_offset)
676254721Semaste            {
677254721Semaste                if (count > 0)
678254721Semaste                    s->PutCString(", ");
679254721Semaste                VMRange addr_range(curr_base_addr + begin_addr_offset, curr_base_addr + end_addr_offset);
680254721Semaste                addr_range.Dump(s, 0, 8);
681254721Semaste                s->PutChar('{');
682254721Semaste                lldb::offset_t location_length = m_data.GetU16(&offset);
683254721Semaste                DumpLocation (s, offset, location_length, level, abi);
684254721Semaste                s->PutChar('}');
685254721Semaste                offset += location_length;
686254721Semaste            }
687254721Semaste            else if (begin_addr_offset == 0 && end_addr_offset == 0)
688254721Semaste            {
689254721Semaste                // The end of the location list is marked by both the start and end offset being zero
690254721Semaste                break;
691254721Semaste            }
692254721Semaste            else
693254721Semaste            {
694254721Semaste                if ((m_data.GetAddressByteSize() == 4 && (begin_addr_offset == UINT32_MAX)) ||
695254721Semaste                    (m_data.GetAddressByteSize() == 8 && (begin_addr_offset == UINT64_MAX)))
696254721Semaste                {
697254721Semaste                    curr_base_addr = end_addr_offset + location_list_base_addr;
698254721Semaste                    // We have a new base address
699254721Semaste                    if (count > 0)
700254721Semaste                        s->PutCString(", ");
701254721Semaste                    *s << "base_addr = " << end_addr_offset;
702254721Semaste                }
703254721Semaste            }
704254721Semaste
705254721Semaste            count++;
706254721Semaste        }
707254721Semaste    }
708254721Semaste    else
709254721Semaste    {
710254721Semaste        // We have a normal location that contains DW_OP location opcodes
711254721Semaste        DumpLocation (s, 0, m_data.GetByteSize(), level, abi);
712254721Semaste    }
713254721Semaste}
714254721Semaste
715254721Semastestatic bool
716254721SemasteReadRegisterValueAsScalar
717254721Semaste(
718254721Semaste    RegisterContext *reg_ctx,
719254721Semaste    uint32_t reg_kind,
720254721Semaste    uint32_t reg_num,
721254721Semaste    Error *error_ptr,
722254721Semaste    Value &value
723254721Semaste)
724254721Semaste{
725254721Semaste    if (reg_ctx == NULL)
726254721Semaste    {
727254721Semaste        if (error_ptr)
728254721Semaste            error_ptr->SetErrorStringWithFormat("No register context in frame.\n");
729254721Semaste    }
730254721Semaste    else
731254721Semaste    {
732254721Semaste        uint32_t native_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
733254721Semaste        if (native_reg == LLDB_INVALID_REGNUM)
734254721Semaste        {
735254721Semaste            if (error_ptr)
736254721Semaste                error_ptr->SetErrorStringWithFormat("Unable to convert register kind=%u reg_num=%u to a native register number.\n", reg_kind, reg_num);
737254721Semaste        }
738254721Semaste        else
739254721Semaste        {
740254721Semaste            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(native_reg);
741254721Semaste            RegisterValue reg_value;
742254721Semaste            if (reg_ctx->ReadRegister (reg_info, reg_value))
743254721Semaste            {
744254721Semaste                if (reg_value.GetScalarValue(value.GetScalar()))
745254721Semaste                {
746254721Semaste                    value.SetValueType (Value::eValueTypeScalar);
747254721Semaste                    value.SetContext (Value::eContextTypeRegisterInfo,
748254721Semaste                                      const_cast<RegisterInfo *>(reg_info));
749254721Semaste                    if (error_ptr)
750254721Semaste                        error_ptr->Clear();
751254721Semaste                    return true;
752254721Semaste                }
753254721Semaste                else
754254721Semaste                {
755254721Semaste                    // If we get this error, then we need to implement a value
756254721Semaste                    // buffer in the dwarf expression evaluation function...
757254721Semaste                    if (error_ptr)
758254721Semaste                        error_ptr->SetErrorStringWithFormat ("register %s can't be converted to a scalar value",
759254721Semaste                                                             reg_info->name);
760254721Semaste                }
761254721Semaste            }
762254721Semaste            else
763254721Semaste            {
764254721Semaste                if (error_ptr)
765254721Semaste                    error_ptr->SetErrorStringWithFormat("register %s is not available", reg_info->name);
766254721Semaste            }
767254721Semaste        }
768254721Semaste    }
769254721Semaste    return false;
770254721Semaste}
771254721Semaste
772254721Semaste//bool
773254721Semaste//DWARFExpression::LocationListContainsLoadAddress (Process* process, const Address &addr) const
774254721Semaste//{
775254721Semaste//    return LocationListContainsLoadAddress(process, addr.GetLoadAddress(process));
776254721Semaste//}
777254721Semaste//
778254721Semaste//bool
779254721Semaste//DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t load_addr) const
780254721Semaste//{
781254721Semaste//    if (load_addr == LLDB_INVALID_ADDRESS)
782254721Semaste//        return false;
783254721Semaste//
784254721Semaste//    if (IsLocationList())
785254721Semaste//    {
786254721Semaste//        lldb::offset_t offset = 0;
787254721Semaste//
788254721Semaste//        addr_t loc_list_base_addr = m_loclist_slide.GetLoadAddress(process);
789254721Semaste//
790254721Semaste//        if (loc_list_base_addr == LLDB_INVALID_ADDRESS)
791254721Semaste//            return false;
792254721Semaste//
793254721Semaste//        while (m_data.ValidOffset(offset))
794254721Semaste//        {
795254721Semaste//            // We need to figure out what the value is for the location.
796254721Semaste//            addr_t lo_pc = m_data.GetAddress(&offset);
797254721Semaste//            addr_t hi_pc = m_data.GetAddress(&offset);
798254721Semaste//            if (lo_pc == 0 && hi_pc == 0)
799254721Semaste//                break;
800254721Semaste//            else
801254721Semaste//            {
802254721Semaste//                lo_pc += loc_list_base_addr;
803254721Semaste//                hi_pc += loc_list_base_addr;
804254721Semaste//
805254721Semaste//                if (lo_pc <= load_addr && load_addr < hi_pc)
806254721Semaste//                    return true;
807254721Semaste//
808254721Semaste//                offset += m_data.GetU16(&offset);
809254721Semaste//            }
810254721Semaste//        }
811254721Semaste//    }
812254721Semaste//    return false;
813254721Semaste//}
814254721Semaste
815254721Semastestatic offset_t
816254721SemasteGetOpcodeDataSize (const DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op)
817254721Semaste{
818254721Semaste    lldb::offset_t offset = data_offset;
819254721Semaste    switch (op)
820254721Semaste    {
821254721Semaste        case DW_OP_addr:
822254721Semaste        case DW_OP_call_ref:    // 0x9a 1 address sized offset of DIE (DWARF3)
823254721Semaste            return data.GetAddressByteSize();
824254721Semaste
825254721Semaste        // Opcodes with no arguments
826254721Semaste        case DW_OP_deref:   // 0x06
827254721Semaste        case DW_OP_dup:     // 0x12
828254721Semaste        case DW_OP_drop:    // 0x13
829254721Semaste        case DW_OP_over:    // 0x14
830254721Semaste        case DW_OP_swap:    // 0x16
831254721Semaste        case DW_OP_rot:     // 0x17
832254721Semaste        case DW_OP_xderef:  // 0x18
833254721Semaste        case DW_OP_abs:     // 0x19
834254721Semaste        case DW_OP_and:     // 0x1a
835254721Semaste        case DW_OP_div:     // 0x1b
836254721Semaste        case DW_OP_minus:   // 0x1c
837254721Semaste        case DW_OP_mod:     // 0x1d
838254721Semaste        case DW_OP_mul:     // 0x1e
839254721Semaste        case DW_OP_neg:     // 0x1f
840254721Semaste        case DW_OP_not:     // 0x20
841254721Semaste        case DW_OP_or:      // 0x21
842254721Semaste        case DW_OP_plus:    // 0x22
843254721Semaste        case DW_OP_shl:     // 0x24
844254721Semaste        case DW_OP_shr:     // 0x25
845254721Semaste        case DW_OP_shra:    // 0x26
846254721Semaste        case DW_OP_xor:     // 0x27
847254721Semaste        case DW_OP_eq:      // 0x29
848254721Semaste        case DW_OP_ge:      // 0x2a
849254721Semaste        case DW_OP_gt:      // 0x2b
850254721Semaste        case DW_OP_le:      // 0x2c
851254721Semaste        case DW_OP_lt:      // 0x2d
852254721Semaste        case DW_OP_ne:      // 0x2e
853254721Semaste        case DW_OP_lit0:    // 0x30
854254721Semaste        case DW_OP_lit1:    // 0x31
855254721Semaste        case DW_OP_lit2:    // 0x32
856254721Semaste        case DW_OP_lit3:    // 0x33
857254721Semaste        case DW_OP_lit4:    // 0x34
858254721Semaste        case DW_OP_lit5:    // 0x35
859254721Semaste        case DW_OP_lit6:    // 0x36
860254721Semaste        case DW_OP_lit7:    // 0x37
861254721Semaste        case DW_OP_lit8:    // 0x38
862254721Semaste        case DW_OP_lit9:    // 0x39
863254721Semaste        case DW_OP_lit10:   // 0x3A
864254721Semaste        case DW_OP_lit11:   // 0x3B
865254721Semaste        case DW_OP_lit12:   // 0x3C
866254721Semaste        case DW_OP_lit13:   // 0x3D
867254721Semaste        case DW_OP_lit14:   // 0x3E
868254721Semaste        case DW_OP_lit15:   // 0x3F
869254721Semaste        case DW_OP_lit16:   // 0x40
870254721Semaste        case DW_OP_lit17:   // 0x41
871254721Semaste        case DW_OP_lit18:   // 0x42
872254721Semaste        case DW_OP_lit19:   // 0x43
873254721Semaste        case DW_OP_lit20:   // 0x44
874254721Semaste        case DW_OP_lit21:   // 0x45
875254721Semaste        case DW_OP_lit22:   // 0x46
876254721Semaste        case DW_OP_lit23:   // 0x47
877254721Semaste        case DW_OP_lit24:   // 0x48
878254721Semaste        case DW_OP_lit25:   // 0x49
879254721Semaste        case DW_OP_lit26:   // 0x4A
880254721Semaste        case DW_OP_lit27:   // 0x4B
881254721Semaste        case DW_OP_lit28:   // 0x4C
882254721Semaste        case DW_OP_lit29:   // 0x4D
883254721Semaste        case DW_OP_lit30:   // 0x4E
884254721Semaste        case DW_OP_lit31:   // 0x4f
885254721Semaste        case DW_OP_reg0:    // 0x50
886254721Semaste        case DW_OP_reg1:    // 0x51
887254721Semaste        case DW_OP_reg2:    // 0x52
888254721Semaste        case DW_OP_reg3:    // 0x53
889254721Semaste        case DW_OP_reg4:    // 0x54
890254721Semaste        case DW_OP_reg5:    // 0x55
891254721Semaste        case DW_OP_reg6:    // 0x56
892254721Semaste        case DW_OP_reg7:    // 0x57
893254721Semaste        case DW_OP_reg8:    // 0x58
894254721Semaste        case DW_OP_reg9:    // 0x59
895254721Semaste        case DW_OP_reg10:   // 0x5A
896254721Semaste        case DW_OP_reg11:   // 0x5B
897254721Semaste        case DW_OP_reg12:   // 0x5C
898254721Semaste        case DW_OP_reg13:   // 0x5D
899254721Semaste        case DW_OP_reg14:   // 0x5E
900254721Semaste        case DW_OP_reg15:   // 0x5F
901254721Semaste        case DW_OP_reg16:   // 0x60
902254721Semaste        case DW_OP_reg17:   // 0x61
903254721Semaste        case DW_OP_reg18:   // 0x62
904254721Semaste        case DW_OP_reg19:   // 0x63
905254721Semaste        case DW_OP_reg20:   // 0x64
906254721Semaste        case DW_OP_reg21:   // 0x65
907254721Semaste        case DW_OP_reg22:   // 0x66
908254721Semaste        case DW_OP_reg23:   // 0x67
909254721Semaste        case DW_OP_reg24:   // 0x68
910254721Semaste        case DW_OP_reg25:   // 0x69
911254721Semaste        case DW_OP_reg26:   // 0x6A
912254721Semaste        case DW_OP_reg27:   // 0x6B
913254721Semaste        case DW_OP_reg28:   // 0x6C
914254721Semaste        case DW_OP_reg29:   // 0x6D
915254721Semaste        case DW_OP_reg30:   // 0x6E
916254721Semaste        case DW_OP_reg31:   // 0x6F
917254721Semaste        case DW_OP_nop:     // 0x96
918254721Semaste        case DW_OP_push_object_address: // 0x97 DWARF3
919254721Semaste        case DW_OP_form_tls_address:    // 0x9b DWARF3
920254721Semaste        case DW_OP_call_frame_cfa:      // 0x9c DWARF3
921254721Semaste        case DW_OP_stack_value: // 0x9f DWARF4
922254721Semaste            return 0;
923254721Semaste
924254721Semaste        // Opcodes with a single 1 byte arguments
925254721Semaste        case DW_OP_const1u:     // 0x08 1 1-byte constant
926254721Semaste        case DW_OP_const1s:     // 0x09 1 1-byte constant
927254721Semaste        case DW_OP_pick:        // 0x15 1 1-byte stack index
928254721Semaste        case DW_OP_deref_size:  // 0x94 1 1-byte size of data retrieved
929254721Semaste        case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved
930254721Semaste            return 1;
931254721Semaste
932254721Semaste        // Opcodes with a single 2 byte arguments
933254721Semaste        case DW_OP_const2u:     // 0x0a 1 2-byte constant
934254721Semaste        case DW_OP_const2s:     // 0x0b 1 2-byte constant
935254721Semaste        case DW_OP_skip:        // 0x2f 1 signed 2-byte constant
936254721Semaste        case DW_OP_bra:         // 0x28 1 signed 2-byte constant
937254721Semaste        case DW_OP_call2:       // 0x98 1 2-byte offset of DIE (DWARF3)
938254721Semaste            return 2;
939254721Semaste
940254721Semaste        // Opcodes with a single 4 byte arguments
941254721Semaste        case DW_OP_const4u:     // 0x0c 1 4-byte constant
942254721Semaste        case DW_OP_const4s:     // 0x0d 1 4-byte constant
943254721Semaste        case DW_OP_call4:       // 0x99 1 4-byte offset of DIE (DWARF3)
944254721Semaste            return 4;
945254721Semaste
946254721Semaste        // Opcodes with a single 8 byte arguments
947254721Semaste        case DW_OP_const8u:     // 0x0e 1 8-byte constant
948254721Semaste        case DW_OP_const8s:     // 0x0f 1 8-byte constant
949254721Semaste             return 8;
950254721Semaste
951254721Semaste        // All opcodes that have a single ULEB (signed or unsigned) argument
952254721Semaste        case DW_OP_constu:      // 0x10 1 ULEB128 constant
953254721Semaste        case DW_OP_consts:      // 0x11 1 SLEB128 constant
954254721Semaste        case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend
955254721Semaste        case DW_OP_breg0:       // 0x70 1 ULEB128 register
956254721Semaste        case DW_OP_breg1:       // 0x71 1 ULEB128 register
957254721Semaste        case DW_OP_breg2:       // 0x72 1 ULEB128 register
958254721Semaste        case DW_OP_breg3:       // 0x73 1 ULEB128 register
959254721Semaste        case DW_OP_breg4:       // 0x74 1 ULEB128 register
960254721Semaste        case DW_OP_breg5:       // 0x75 1 ULEB128 register
961254721Semaste        case DW_OP_breg6:       // 0x76 1 ULEB128 register
962254721Semaste        case DW_OP_breg7:       // 0x77 1 ULEB128 register
963254721Semaste        case DW_OP_breg8:       // 0x78 1 ULEB128 register
964254721Semaste        case DW_OP_breg9:       // 0x79 1 ULEB128 register
965254721Semaste        case DW_OP_breg10:      // 0x7a 1 ULEB128 register
966254721Semaste        case DW_OP_breg11:      // 0x7b 1 ULEB128 register
967254721Semaste        case DW_OP_breg12:      // 0x7c 1 ULEB128 register
968254721Semaste        case DW_OP_breg13:      // 0x7d 1 ULEB128 register
969254721Semaste        case DW_OP_breg14:      // 0x7e 1 ULEB128 register
970254721Semaste        case DW_OP_breg15:      // 0x7f 1 ULEB128 register
971254721Semaste        case DW_OP_breg16:      // 0x80 1 ULEB128 register
972254721Semaste        case DW_OP_breg17:      // 0x81 1 ULEB128 register
973254721Semaste        case DW_OP_breg18:      // 0x82 1 ULEB128 register
974254721Semaste        case DW_OP_breg19:      // 0x83 1 ULEB128 register
975254721Semaste        case DW_OP_breg20:      // 0x84 1 ULEB128 register
976254721Semaste        case DW_OP_breg21:      // 0x85 1 ULEB128 register
977254721Semaste        case DW_OP_breg22:      // 0x86 1 ULEB128 register
978254721Semaste        case DW_OP_breg23:      // 0x87 1 ULEB128 register
979254721Semaste        case DW_OP_breg24:      // 0x88 1 ULEB128 register
980254721Semaste        case DW_OP_breg25:      // 0x89 1 ULEB128 register
981254721Semaste        case DW_OP_breg26:      // 0x8a 1 ULEB128 register
982254721Semaste        case DW_OP_breg27:      // 0x8b 1 ULEB128 register
983254721Semaste        case DW_OP_breg28:      // 0x8c 1 ULEB128 register
984254721Semaste        case DW_OP_breg29:      // 0x8d 1 ULEB128 register
985254721Semaste        case DW_OP_breg30:      // 0x8e 1 ULEB128 register
986254721Semaste        case DW_OP_breg31:      // 0x8f 1 ULEB128 register
987254721Semaste        case DW_OP_regx:        // 0x90 1 ULEB128 register
988254721Semaste        case DW_OP_fbreg:       // 0x91 1 SLEB128 offset
989254721Semaste        case DW_OP_piece:       // 0x93 1 ULEB128 size of piece addressed
990254721Semaste            data.Skip_LEB128(&offset);
991254721Semaste            return offset - data_offset;
992254721Semaste
993254721Semaste            // All opcodes that have a 2 ULEB (signed or unsigned) arguments
994254721Semaste        case DW_OP_bregx:       // 0x92 2 ULEB128 register followed by SLEB128 offset
995254721Semaste        case DW_OP_bit_piece:   // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
996254721Semaste            data.Skip_LEB128(&offset);
997254721Semaste            data.Skip_LEB128(&offset);
998254721Semaste            return offset - data_offset;
999254721Semaste
1000254721Semaste        case DW_OP_implicit_value: // 0x9e ULEB128 size followed by block of that size (DWARF4)
1001254721Semaste            {
1002254721Semaste                uint64_t block_len = data.Skip_LEB128(&offset);
1003254721Semaste                offset += block_len;
1004254721Semaste                return offset - data_offset;
1005254721Semaste            }
1006254721Semaste
1007254721Semaste        default:
1008254721Semaste            break;
1009254721Semaste    }
1010254721Semaste    return LLDB_INVALID_OFFSET;
1011254721Semaste}
1012254721Semaste
1013254721Semastelldb::addr_t
1014254721SemasteDWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const
1015254721Semaste{
1016254721Semaste    error = false;
1017254721Semaste    if (IsLocationList())
1018254721Semaste        return LLDB_INVALID_ADDRESS;
1019254721Semaste    lldb::offset_t offset = 0;
1020254721Semaste    uint32_t curr_op_addr_idx = 0;
1021254721Semaste    while (m_data.ValidOffset(offset))
1022254721Semaste    {
1023254721Semaste        const uint8_t op = m_data.GetU8(&offset);
1024254721Semaste
1025254721Semaste        if (op == DW_OP_addr)
1026254721Semaste        {
1027254721Semaste            const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
1028254721Semaste            if (curr_op_addr_idx == op_addr_idx)
1029254721Semaste                return op_file_addr;
1030254721Semaste            else
1031254721Semaste                ++curr_op_addr_idx;
1032254721Semaste        }
1033254721Semaste        else
1034254721Semaste        {
1035254721Semaste            const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
1036254721Semaste            if (op_arg_size == LLDB_INVALID_OFFSET)
1037254721Semaste            {
1038254721Semaste                error = true;
1039254721Semaste                break;
1040254721Semaste            }
1041254721Semaste            offset += op_arg_size;
1042254721Semaste        }
1043254721Semaste    }
1044254721Semaste    return LLDB_INVALID_ADDRESS;
1045254721Semaste}
1046254721Semaste
1047254721Semastebool
1048254721SemasteDWARFExpression::Update_DW_OP_addr (lldb::addr_t file_addr)
1049254721Semaste{
1050254721Semaste    if (IsLocationList())
1051254721Semaste        return false;
1052254721Semaste    lldb::offset_t offset = 0;
1053254721Semaste    while (m_data.ValidOffset(offset))
1054254721Semaste    {
1055254721Semaste        const uint8_t op = m_data.GetU8(&offset);
1056254721Semaste
1057254721Semaste        if (op == DW_OP_addr)
1058254721Semaste        {
1059254721Semaste            const uint32_t addr_byte_size = m_data.GetAddressByteSize();
1060254721Semaste            // We have to make a copy of the data as we don't know if this
1061254721Semaste            // data is from a read only memory mapped buffer, so we duplicate
1062254721Semaste            // all of the data first, then modify it, and if all goes well,
1063254721Semaste            // we then replace the data for this expression
1064254721Semaste
1065254721Semaste            // So first we copy the data into a heap buffer
1066254721Semaste            std::unique_ptr<DataBufferHeap> head_data_ap (new DataBufferHeap (m_data.GetDataStart(),
1067254721Semaste                                                                             m_data.GetByteSize()));
1068254721Semaste
1069254721Semaste            // Make en encoder so we can write the address into the buffer using
1070254721Semaste            // the correct byte order (endianness)
1071254721Semaste            DataEncoder encoder (head_data_ap->GetBytes(),
1072254721Semaste                                 head_data_ap->GetByteSize(),
1073254721Semaste                                 m_data.GetByteOrder(),
1074254721Semaste                                 addr_byte_size);
1075254721Semaste
1076254721Semaste            // Replace the address in the new buffer
1077254721Semaste            if (encoder.PutMaxU64 (offset, addr_byte_size, file_addr) == UINT32_MAX)
1078254721Semaste                return false;
1079254721Semaste
1080254721Semaste            // All went well, so now we can reset the data using a shared
1081254721Semaste            // pointer to the heap data so "m_data" will now correctly
1082254721Semaste            // manage the heap data.
1083254721Semaste            m_data.SetData (DataBufferSP (head_data_ap.release()));
1084254721Semaste            return true;
1085254721Semaste        }
1086254721Semaste        else
1087254721Semaste        {
1088254721Semaste            const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
1089254721Semaste            if (op_arg_size == LLDB_INVALID_OFFSET)
1090254721Semaste                break;
1091254721Semaste            offset += op_arg_size;
1092254721Semaste        }
1093254721Semaste    }
1094254721Semaste    return false;
1095254721Semaste}
1096254721Semaste
1097254721Semastebool
1098254721SemasteDWARFExpression::LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const
1099254721Semaste{
1100254721Semaste    if (addr == LLDB_INVALID_ADDRESS)
1101254721Semaste        return false;
1102254721Semaste
1103254721Semaste    if (IsLocationList())
1104254721Semaste    {
1105254721Semaste        lldb::offset_t offset = 0;
1106254721Semaste
1107254721Semaste        if (loclist_base_addr == LLDB_INVALID_ADDRESS)
1108254721Semaste            return false;
1109254721Semaste
1110254721Semaste        while (m_data.ValidOffset(offset))
1111254721Semaste        {
1112254721Semaste            // We need to figure out what the value is for the location.
1113254721Semaste            addr_t lo_pc = m_data.GetAddress(&offset);
1114254721Semaste            addr_t hi_pc = m_data.GetAddress(&offset);
1115254721Semaste            if (lo_pc == 0 && hi_pc == 0)
1116254721Semaste                break;
1117254721Semaste            else
1118254721Semaste            {
1119254721Semaste                lo_pc += loclist_base_addr - m_loclist_slide;
1120254721Semaste                hi_pc += loclist_base_addr - m_loclist_slide;
1121254721Semaste
1122254721Semaste                if (lo_pc <= addr && addr < hi_pc)
1123254721Semaste                    return true;
1124254721Semaste
1125254721Semaste                offset += m_data.GetU16(&offset);
1126254721Semaste            }
1127254721Semaste        }
1128254721Semaste    }
1129254721Semaste    return false;
1130254721Semaste}
1131254721Semaste
1132254721Semastebool
1133254721SemasteDWARFExpression::GetLocation (addr_t base_addr, addr_t pc, lldb::offset_t &offset, lldb::offset_t &length)
1134254721Semaste{
1135254721Semaste    offset = 0;
1136254721Semaste    if (!IsLocationList())
1137254721Semaste    {
1138254721Semaste        length = m_data.GetByteSize();
1139254721Semaste        return true;
1140254721Semaste    }
1141254721Semaste
1142254721Semaste    if (base_addr != LLDB_INVALID_ADDRESS && pc != LLDB_INVALID_ADDRESS)
1143254721Semaste    {
1144254721Semaste        addr_t curr_base_addr = base_addr;
1145254721Semaste
1146254721Semaste        while (m_data.ValidOffset(offset))
1147254721Semaste        {
1148254721Semaste            // We need to figure out what the value is for the location.
1149254721Semaste            addr_t lo_pc = m_data.GetAddress(&offset);
1150254721Semaste            addr_t hi_pc = m_data.GetAddress(&offset);
1151254721Semaste            if (lo_pc == 0 && hi_pc == 0)
1152254721Semaste            {
1153254721Semaste                break;
1154254721Semaste            }
1155254721Semaste            else
1156254721Semaste            {
1157254721Semaste                lo_pc += curr_base_addr - m_loclist_slide;
1158254721Semaste                hi_pc += curr_base_addr - m_loclist_slide;
1159254721Semaste
1160254721Semaste                length = m_data.GetU16(&offset);
1161254721Semaste
1162254721Semaste                if (length > 0 && lo_pc <= pc && pc < hi_pc)
1163254721Semaste                    return true;
1164254721Semaste
1165254721Semaste                offset += length;
1166254721Semaste            }
1167254721Semaste        }
1168254721Semaste    }
1169254721Semaste    offset = LLDB_INVALID_OFFSET;
1170254721Semaste    length = 0;
1171254721Semaste    return false;
1172254721Semaste}
1173254721Semaste
1174254721Semastebool
1175254721SemasteDWARFExpression::DumpLocationForAddress (Stream *s,
1176254721Semaste                                         lldb::DescriptionLevel level,
1177254721Semaste                                         addr_t base_addr,
1178254721Semaste                                         addr_t address,
1179254721Semaste                                         ABI *abi)
1180254721Semaste{
1181254721Semaste    lldb::offset_t offset = 0;
1182254721Semaste    lldb::offset_t length = 0;
1183254721Semaste
1184254721Semaste    if (GetLocation (base_addr, address, offset, length))
1185254721Semaste    {
1186254721Semaste        if (length > 0)
1187254721Semaste        {
1188254721Semaste            DumpLocation(s, offset, length, level, abi);
1189254721Semaste            return true;
1190254721Semaste        }
1191254721Semaste    }
1192254721Semaste    return false;
1193254721Semaste}
1194254721Semaste
1195254721Semastebool
1196254721SemasteDWARFExpression::Evaluate
1197254721Semaste(
1198254721Semaste    ExecutionContextScope *exe_scope,
1199254721Semaste    ClangExpressionVariableList *expr_locals,
1200254721Semaste    ClangExpressionDeclMap *decl_map,
1201254721Semaste    lldb::addr_t loclist_base_load_addr,
1202254721Semaste    const Value* initial_value_ptr,
1203254721Semaste    Value& result,
1204254721Semaste    Error *error_ptr
1205254721Semaste) const
1206254721Semaste{
1207254721Semaste    ExecutionContext exe_ctx (exe_scope);
1208254721Semaste    return Evaluate(&exe_ctx, expr_locals, decl_map, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr);
1209254721Semaste}
1210254721Semaste
1211254721Semastebool
1212254721SemasteDWARFExpression::Evaluate
1213254721Semaste(
1214254721Semaste    ExecutionContext *exe_ctx,
1215254721Semaste    ClangExpressionVariableList *expr_locals,
1216254721Semaste    ClangExpressionDeclMap *decl_map,
1217254721Semaste    RegisterContext *reg_ctx,
1218254721Semaste    lldb::addr_t loclist_base_load_addr,
1219254721Semaste    const Value* initial_value_ptr,
1220254721Semaste    Value& result,
1221254721Semaste    Error *error_ptr
1222254721Semaste) const
1223254721Semaste{
1224254721Semaste    if (IsLocationList())
1225254721Semaste    {
1226254721Semaste        lldb::offset_t offset = 0;
1227254721Semaste        addr_t pc;
1228254721Semaste        StackFrame *frame = NULL;
1229254721Semaste        if (reg_ctx)
1230254721Semaste            pc = reg_ctx->GetPC();
1231254721Semaste        else
1232254721Semaste        {
1233254721Semaste            frame = exe_ctx->GetFramePtr();
1234254721Semaste            if (!frame)
1235254721Semaste                return false;
1236254721Semaste            RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
1237254721Semaste            if (!reg_ctx_sp)
1238254721Semaste                return false;
1239254721Semaste            pc = reg_ctx_sp->GetPC();
1240254721Semaste        }
1241254721Semaste
1242254721Semaste        if (loclist_base_load_addr != LLDB_INVALID_ADDRESS)
1243254721Semaste        {
1244254721Semaste            if (pc == LLDB_INVALID_ADDRESS)
1245254721Semaste            {
1246254721Semaste                if (error_ptr)
1247254721Semaste                    error_ptr->SetErrorString("Invalid PC in frame.");
1248254721Semaste                return false;
1249254721Semaste            }
1250254721Semaste
1251254721Semaste            addr_t curr_loclist_base_load_addr = loclist_base_load_addr;
1252254721Semaste
1253254721Semaste            while (m_data.ValidOffset(offset))
1254254721Semaste            {
1255254721Semaste                // We need to figure out what the value is for the location.
1256254721Semaste                addr_t lo_pc = m_data.GetAddress(&offset);
1257254721Semaste                addr_t hi_pc = m_data.GetAddress(&offset);
1258254721Semaste                if (lo_pc == 0 && hi_pc == 0)
1259254721Semaste                {
1260254721Semaste                    break;
1261254721Semaste                }
1262254721Semaste                else
1263254721Semaste                {
1264254721Semaste                    lo_pc += curr_loclist_base_load_addr - m_loclist_slide;
1265254721Semaste                    hi_pc += curr_loclist_base_load_addr - m_loclist_slide;
1266254721Semaste
1267254721Semaste                    uint16_t length = m_data.GetU16(&offset);
1268254721Semaste
1269254721Semaste                    if (length > 0 && lo_pc <= pc && pc < hi_pc)
1270254721Semaste                    {
1271254721Semaste                        return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr);
1272254721Semaste                    }
1273254721Semaste                    offset += length;
1274254721Semaste                }
1275254721Semaste            }
1276254721Semaste        }
1277254721Semaste        if (error_ptr)
1278254721Semaste            error_ptr->SetErrorString ("variable not available");
1279254721Semaste        return false;
1280254721Semaste    }
1281254721Semaste
1282254721Semaste    // Not a location list, just a single expression.
1283254721Semaste    return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr);
1284254721Semaste}
1285254721Semaste
1286254721Semaste
1287254721Semaste
1288254721Semastebool
1289254721SemasteDWARFExpression::Evaluate
1290254721Semaste(
1291254721Semaste    ExecutionContext *exe_ctx,
1292254721Semaste    ClangExpressionVariableList *expr_locals,
1293254721Semaste    ClangExpressionDeclMap *decl_map,
1294254721Semaste    RegisterContext *reg_ctx,
1295254721Semaste    const DataExtractor& opcodes,
1296254721Semaste    const lldb::offset_t opcodes_offset,
1297254721Semaste    const lldb::offset_t opcodes_length,
1298254721Semaste    const uint32_t reg_kind,
1299254721Semaste    const Value* initial_value_ptr,
1300254721Semaste    Value& result,
1301254721Semaste    Error *error_ptr
1302254721Semaste)
1303254721Semaste{
1304254721Semaste
1305254721Semaste    if (opcodes_length == 0)
1306254721Semaste    {
1307254721Semaste        if (error_ptr)
1308254721Semaste            error_ptr->SetErrorString ("no location, value may have been optimized out");
1309254721Semaste        return false;
1310254721Semaste    }
1311254721Semaste    std::vector<Value> stack;
1312254721Semaste
1313254721Semaste    Process *process = NULL;
1314254721Semaste    StackFrame *frame = NULL;
1315254721Semaste
1316254721Semaste    if (exe_ctx)
1317254721Semaste    {
1318254721Semaste        process = exe_ctx->GetProcessPtr();
1319254721Semaste        frame = exe_ctx->GetFramePtr();
1320254721Semaste    }
1321254721Semaste    if (reg_ctx == NULL && frame)
1322254721Semaste        reg_ctx = frame->GetRegisterContext().get();
1323254721Semaste
1324254721Semaste    if (initial_value_ptr)
1325254721Semaste        stack.push_back(*initial_value_ptr);
1326254721Semaste
1327254721Semaste    lldb::offset_t offset = opcodes_offset;
1328254721Semaste    const lldb::offset_t end_offset = opcodes_offset + opcodes_length;
1329254721Semaste    Value tmp;
1330254721Semaste    uint32_t reg_num;
1331254721Semaste
1332254721Semaste    // Make sure all of the data is available in opcodes.
1333254721Semaste    if (!opcodes.ValidOffsetForDataOfSize(opcodes_offset, opcodes_length))
1334254721Semaste    {
1335254721Semaste        if (error_ptr)
1336254721Semaste            error_ptr->SetErrorString ("invalid offset and/or length for opcodes buffer.");
1337254721Semaste        return false;
1338254721Semaste    }
1339254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1340254721Semaste
1341254721Semaste
1342254721Semaste    while (opcodes.ValidOffset(offset) && offset < end_offset)
1343254721Semaste    {
1344254721Semaste        const lldb::offset_t op_offset = offset;
1345254721Semaste        const uint8_t op = opcodes.GetU8(&offset);
1346254721Semaste
1347254721Semaste        if (log && log->GetVerbose())
1348254721Semaste        {
1349254721Semaste            size_t count = stack.size();
1350254721Semaste            log->Printf("Stack before operation has %lu values:", count);
1351254721Semaste            for (size_t i=0; i<count; ++i)
1352254721Semaste            {
1353254721Semaste                StreamString new_value;
1354254721Semaste                new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
1355254721Semaste                stack[i].Dump(&new_value);
1356254721Semaste                log->Printf("  %s", new_value.GetData());
1357254721Semaste            }
1358254721Semaste            log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op));
1359254721Semaste        }
1360254721Semaste        switch (op)
1361254721Semaste        {
1362254721Semaste        //----------------------------------------------------------------------
1363254721Semaste        // The DW_OP_addr operation has a single operand that encodes a machine
1364254721Semaste        // address and whose size is the size of an address on the target machine.
1365254721Semaste        //----------------------------------------------------------------------
1366254721Semaste        case DW_OP_addr:
1367254721Semaste            stack.push_back(Scalar(opcodes.GetAddress(&offset)));
1368254721Semaste            stack.back().SetValueType (Value::eValueTypeFileAddress);
1369254721Semaste            break;
1370254721Semaste
1371254721Semaste        //----------------------------------------------------------------------
1372254721Semaste        // The DW_OP_addr_sect_offset4 is used for any location expressions in
1373254721Semaste        // shared libraries that have a location like:
1374254721Semaste        //  DW_OP_addr(0x1000)
1375254721Semaste        // If this address resides in a shared library, then this virtual
1376254721Semaste        // address won't make sense when it is evaluated in the context of a
1377254721Semaste        // running process where shared libraries have been slid. To account for
1378254721Semaste        // this, this new address type where we can store the section pointer
1379254721Semaste        // and a 4 byte offset.
1380254721Semaste        //----------------------------------------------------------------------
1381254721Semaste//      case DW_OP_addr_sect_offset4:
1382254721Semaste//          {
1383254721Semaste//              result_type = eResultTypeFileAddress;
1384254721Semaste//              lldb::Section *sect = (lldb::Section *)opcodes.GetMaxU64(&offset, sizeof(void *));
1385254721Semaste//              lldb::addr_t sect_offset = opcodes.GetU32(&offset);
1386254721Semaste//
1387254721Semaste//              Address so_addr (sect, sect_offset);
1388254721Semaste//              lldb::addr_t load_addr = so_addr.GetLoadAddress();
1389254721Semaste//              if (load_addr != LLDB_INVALID_ADDRESS)
1390254721Semaste//              {
1391254721Semaste//                  // We successfully resolve a file address to a load
1392254721Semaste//                  // address.
1393254721Semaste//                  stack.push_back(load_addr);
1394254721Semaste//                  break;
1395254721Semaste//              }
1396254721Semaste//              else
1397254721Semaste//              {
1398254721Semaste//                  // We were able
1399254721Semaste//                  if (error_ptr)
1400254721Semaste//                      error_ptr->SetErrorStringWithFormat ("Section %s in %s is not currently loaded.\n", sect->GetName().AsCString(), sect->GetModule()->GetFileSpec().GetFilename().AsCString());
1401254721Semaste//                  return false;
1402254721Semaste//              }
1403254721Semaste//          }
1404254721Semaste//          break;
1405254721Semaste
1406254721Semaste        //----------------------------------------------------------------------
1407254721Semaste        // OPCODE: DW_OP_deref
1408254721Semaste        // OPERANDS: none
1409254721Semaste        // DESCRIPTION: Pops the top stack entry and treats it as an address.
1410254721Semaste        // The value retrieved from that address is pushed. The size of the
1411254721Semaste        // data retrieved from the dereferenced address is the size of an
1412254721Semaste        // address on the target machine.
1413254721Semaste        //----------------------------------------------------------------------
1414254721Semaste        case DW_OP_deref:
1415254721Semaste            {
1416254721Semaste                Value::ValueType value_type = stack.back().GetValueType();
1417254721Semaste                switch (value_type)
1418254721Semaste                {
1419254721Semaste                case Value::eValueTypeHostAddress:
1420254721Semaste                    {
1421254721Semaste                        void *src = (void *)stack.back().GetScalar().ULongLong();
1422254721Semaste                        intptr_t ptr;
1423254721Semaste                        ::memcpy (&ptr, src, sizeof(void *));
1424254721Semaste                        stack.back().GetScalar() = ptr;
1425254721Semaste                        stack.back().ClearContext();
1426254721Semaste                    }
1427254721Semaste                    break;
1428254721Semaste                case Value::eValueTypeLoadAddress:
1429254721Semaste                    if (exe_ctx)
1430254721Semaste                    {
1431254721Semaste                        if (process)
1432254721Semaste                        {
1433254721Semaste                            lldb::addr_t pointer_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1434254721Semaste                            uint8_t addr_bytes[sizeof(lldb::addr_t)];
1435254721Semaste                            uint32_t addr_size = process->GetAddressByteSize();
1436254721Semaste                            Error error;
1437254721Semaste                            if (process->ReadMemory(pointer_addr, &addr_bytes, addr_size, error) == addr_size)
1438254721Semaste                            {
1439254721Semaste                                DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), addr_size);
1440254721Semaste                                lldb::offset_t addr_data_offset = 0;
1441254721Semaste                                stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset);
1442254721Semaste                                stack.back().ClearContext();
1443254721Semaste                            }
1444254721Semaste                            else
1445254721Semaste                            {
1446254721Semaste                                if (error_ptr)
1447254721Semaste                                    error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%" PRIx64 " for DW_OP_deref: %s\n",
1448254721Semaste                                                                         pointer_addr,
1449254721Semaste                                                                         error.AsCString());
1450254721Semaste                                return false;
1451254721Semaste                            }
1452254721Semaste                        }
1453254721Semaste                        else
1454254721Semaste                        {
1455254721Semaste                            if (error_ptr)
1456254721Semaste                                error_ptr->SetErrorStringWithFormat ("NULL process for DW_OP_deref.\n");
1457254721Semaste                            return false;
1458254721Semaste                        }
1459254721Semaste                    }
1460254721Semaste                    else
1461254721Semaste                    {
1462254721Semaste                        if (error_ptr)
1463254721Semaste                            error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_deref.\n");
1464254721Semaste                        return false;
1465254721Semaste                    }
1466254721Semaste                    break;
1467254721Semaste
1468254721Semaste                default:
1469254721Semaste                    break;
1470254721Semaste                }
1471254721Semaste
1472254721Semaste            }
1473254721Semaste            break;
1474254721Semaste
1475254721Semaste        //----------------------------------------------------------------------
1476254721Semaste        // OPCODE: DW_OP_deref_size
1477254721Semaste        // OPERANDS: 1
1478254721Semaste        //  1 - uint8_t that specifies the size of the data to dereference.
1479254721Semaste        // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
1480254721Semaste        // stack entry and treats it as an address. The value retrieved from that
1481254721Semaste        // address is pushed. In the DW_OP_deref_size operation, however, the
1482254721Semaste        // size in bytes of the data retrieved from the dereferenced address is
1483254721Semaste        // specified by the single operand. This operand is a 1-byte unsigned
1484254721Semaste        // integral constant whose value may not be larger than the size of an
1485254721Semaste        // address on the target machine. The data retrieved is zero extended
1486254721Semaste        // to the size of an address on the target machine before being pushed
1487254721Semaste        // on the expression stack.
1488254721Semaste        //----------------------------------------------------------------------
1489254721Semaste        case DW_OP_deref_size:
1490254721Semaste            {
1491254721Semaste                uint8_t size = opcodes.GetU8(&offset);
1492254721Semaste                Value::ValueType value_type = stack.back().GetValueType();
1493254721Semaste                switch (value_type)
1494254721Semaste                {
1495254721Semaste                case Value::eValueTypeHostAddress:
1496254721Semaste                    {
1497254721Semaste                        void *src = (void *)stack.back().GetScalar().ULongLong();
1498254721Semaste                        intptr_t ptr;
1499254721Semaste                        ::memcpy (&ptr, src, sizeof(void *));
1500254721Semaste                        // I can't decide whether the size operand should apply to the bytes in their
1501254721Semaste                        // lldb-host endianness or the target endianness.. I doubt this'll ever come up
1502254721Semaste                        // but I'll opt for assuming big endian regardless.
1503254721Semaste                        switch (size)
1504254721Semaste                        {
1505254721Semaste                            case 1: ptr = ptr & 0xff; break;
1506254721Semaste                            case 2: ptr = ptr & 0xffff; break;
1507254721Semaste                            case 3: ptr = ptr & 0xffffff; break;
1508254721Semaste                            case 4: ptr = ptr & 0xffffffff; break;
1509254721Semaste                            // the casts are added to work around the case where intptr_t is a 32 bit quantity;
1510254721Semaste                            // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this program.
1511254721Semaste                            case 5: ptr = (intptr_t) ptr & 0xffffffffffULL; break;
1512254721Semaste                            case 6: ptr = (intptr_t) ptr & 0xffffffffffffULL; break;
1513254721Semaste                            case 7: ptr = (intptr_t) ptr & 0xffffffffffffffULL; break;
1514254721Semaste                            default: break;
1515254721Semaste                        }
1516254721Semaste                        stack.back().GetScalar() = ptr;
1517254721Semaste                        stack.back().ClearContext();
1518254721Semaste                    }
1519254721Semaste                    break;
1520254721Semaste                case Value::eValueTypeLoadAddress:
1521254721Semaste                    if (exe_ctx)
1522254721Semaste                    {
1523254721Semaste                        if (process)
1524254721Semaste                        {
1525254721Semaste                            lldb::addr_t pointer_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1526254721Semaste                            uint8_t addr_bytes[sizeof(lldb::addr_t)];
1527254721Semaste                            Error error;
1528254721Semaste                            if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) == size)
1529254721Semaste                            {
1530254721Semaste                                DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), size);
1531254721Semaste                                lldb::offset_t addr_data_offset = 0;
1532254721Semaste                                switch (size)
1533254721Semaste                                {
1534254721Semaste                                    case 1: stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset); break;
1535254721Semaste                                    case 2: stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset); break;
1536254721Semaste                                    case 4: stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset); break;
1537254721Semaste                                    case 8: stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset); break;
1538254721Semaste                                    default: stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset);
1539254721Semaste                                }
1540254721Semaste                                stack.back().ClearContext();
1541254721Semaste                            }
1542254721Semaste                            else
1543254721Semaste                            {
1544254721Semaste                                if (error_ptr)
1545254721Semaste                                    error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%" PRIx64 " for DW_OP_deref: %s\n",
1546254721Semaste                                                                         pointer_addr,
1547254721Semaste                                                                         error.AsCString());
1548254721Semaste                                return false;
1549254721Semaste                            }
1550254721Semaste                        }
1551254721Semaste                        else
1552254721Semaste                        {
1553254721Semaste                            if (error_ptr)
1554254721Semaste                                error_ptr->SetErrorStringWithFormat ("NULL process for DW_OP_deref.\n");
1555254721Semaste                            return false;
1556254721Semaste                        }
1557254721Semaste                    }
1558254721Semaste                    else
1559254721Semaste                    {
1560254721Semaste                        if (error_ptr)
1561254721Semaste                            error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_deref.\n");
1562254721Semaste                        return false;
1563254721Semaste                    }
1564254721Semaste                    break;
1565254721Semaste
1566254721Semaste                default:
1567254721Semaste                    break;
1568254721Semaste                }
1569254721Semaste
1570254721Semaste            }
1571254721Semaste            break;
1572254721Semaste
1573254721Semaste        //----------------------------------------------------------------------
1574254721Semaste        // OPCODE: DW_OP_xderef_size
1575254721Semaste        // OPERANDS: 1
1576254721Semaste        //  1 - uint8_t that specifies the size of the data to dereference.
1577254721Semaste        // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at
1578254721Semaste        // the top of the stack is treated as an address. The second stack
1579254721Semaste        // entry is treated as an "address space identifier" for those
1580254721Semaste        // architectures that support multiple address spaces. The top two
1581254721Semaste        // stack elements are popped, a data item is retrieved through an
1582254721Semaste        // implementation-defined address calculation and pushed as the new
1583254721Semaste        // stack top. In the DW_OP_xderef_size operation, however, the size in
1584254721Semaste        // bytes of the data retrieved from the dereferenced address is
1585254721Semaste        // specified by the single operand. This operand is a 1-byte unsigned
1586254721Semaste        // integral constant whose value may not be larger than the size of an
1587254721Semaste        // address on the target machine. The data retrieved is zero extended
1588254721Semaste        // to the size of an address on the target machine before being pushed
1589254721Semaste        // on the expression stack.
1590254721Semaste        //----------------------------------------------------------------------
1591254721Semaste        case DW_OP_xderef_size:
1592254721Semaste            if (error_ptr)
1593254721Semaste                error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef_size.");
1594254721Semaste            return false;
1595254721Semaste        //----------------------------------------------------------------------
1596254721Semaste        // OPCODE: DW_OP_xderef
1597254721Semaste        // OPERANDS: none
1598254721Semaste        // DESCRIPTION: Provides an extended dereference mechanism. The entry at
1599254721Semaste        // the top of the stack is treated as an address. The second stack entry
1600254721Semaste        // is treated as an "address space identifier" for those architectures
1601254721Semaste        // that support multiple address spaces. The top two stack elements are
1602254721Semaste        // popped, a data item is retrieved through an implementation-defined
1603254721Semaste        // address calculation and pushed as the new stack top. The size of the
1604254721Semaste        // data retrieved from the dereferenced address is the size of an address
1605254721Semaste        // on the target machine.
1606254721Semaste        //----------------------------------------------------------------------
1607254721Semaste        case DW_OP_xderef:
1608254721Semaste            if (error_ptr)
1609254721Semaste                error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef.");
1610254721Semaste            return false;
1611254721Semaste
1612254721Semaste        //----------------------------------------------------------------------
1613254721Semaste        // All DW_OP_constXXX opcodes have a single operand as noted below:
1614254721Semaste        //
1615254721Semaste        // Opcode           Operand 1
1616254721Semaste        // ---------------  ----------------------------------------------------
1617254721Semaste        // DW_OP_const1u    1-byte unsigned integer constant
1618254721Semaste        // DW_OP_const1s    1-byte signed integer constant
1619254721Semaste        // DW_OP_const2u    2-byte unsigned integer constant
1620254721Semaste        // DW_OP_const2s    2-byte signed integer constant
1621254721Semaste        // DW_OP_const4u    4-byte unsigned integer constant
1622254721Semaste        // DW_OP_const4s    4-byte signed integer constant
1623254721Semaste        // DW_OP_const8u    8-byte unsigned integer constant
1624254721Semaste        // DW_OP_const8s    8-byte signed integer constant
1625254721Semaste        // DW_OP_constu     unsigned LEB128 integer constant
1626254721Semaste        // DW_OP_consts     signed LEB128 integer constant
1627254721Semaste        //----------------------------------------------------------------------
1628254721Semaste        case DW_OP_const1u             :    stack.push_back(Scalar(( uint8_t)opcodes.GetU8 (&offset))); break;
1629254721Semaste        case DW_OP_const1s             :    stack.push_back(Scalar((  int8_t)opcodes.GetU8 (&offset))); break;
1630254721Semaste        case DW_OP_const2u             :    stack.push_back(Scalar((uint16_t)opcodes.GetU16 (&offset))); break;
1631254721Semaste        case DW_OP_const2s             :    stack.push_back(Scalar(( int16_t)opcodes.GetU16 (&offset))); break;
1632254721Semaste        case DW_OP_const4u             :    stack.push_back(Scalar((uint32_t)opcodes.GetU32 (&offset))); break;
1633254721Semaste        case DW_OP_const4s             :    stack.push_back(Scalar(( int32_t)opcodes.GetU32 (&offset))); break;
1634254721Semaste        case DW_OP_const8u             :    stack.push_back(Scalar((uint64_t)opcodes.GetU64 (&offset))); break;
1635254721Semaste        case DW_OP_const8s             :    stack.push_back(Scalar(( int64_t)opcodes.GetU64 (&offset))); break;
1636254721Semaste        case DW_OP_constu              :    stack.push_back(Scalar(opcodes.GetULEB128 (&offset))); break;
1637254721Semaste        case DW_OP_consts              :    stack.push_back(Scalar(opcodes.GetSLEB128 (&offset))); break;
1638254721Semaste
1639254721Semaste        //----------------------------------------------------------------------
1640254721Semaste        // OPCODE: DW_OP_dup
1641254721Semaste        // OPERANDS: none
1642254721Semaste        // DESCRIPTION: duplicates the value at the top of the stack
1643254721Semaste        //----------------------------------------------------------------------
1644254721Semaste        case DW_OP_dup:
1645254721Semaste            if (stack.empty())
1646254721Semaste            {
1647254721Semaste                if (error_ptr)
1648254721Semaste                    error_ptr->SetErrorString("Expression stack empty for DW_OP_dup.");
1649254721Semaste                return false;
1650254721Semaste            }
1651254721Semaste            else
1652254721Semaste                stack.push_back(stack.back());
1653254721Semaste            break;
1654254721Semaste
1655254721Semaste        //----------------------------------------------------------------------
1656254721Semaste        // OPCODE: DW_OP_drop
1657254721Semaste        // OPERANDS: none
1658254721Semaste        // DESCRIPTION: pops the value at the top of the stack
1659254721Semaste        //----------------------------------------------------------------------
1660254721Semaste        case DW_OP_drop:
1661254721Semaste            if (stack.empty())
1662254721Semaste            {
1663254721Semaste                if (error_ptr)
1664254721Semaste                    error_ptr->SetErrorString("Expression stack empty for DW_OP_drop.");
1665254721Semaste                return false;
1666254721Semaste            }
1667254721Semaste            else
1668254721Semaste                stack.pop_back();
1669254721Semaste            break;
1670254721Semaste
1671254721Semaste        //----------------------------------------------------------------------
1672254721Semaste        // OPCODE: DW_OP_over
1673254721Semaste        // OPERANDS: none
1674254721Semaste        // DESCRIPTION: Duplicates the entry currently second in the stack at
1675254721Semaste        // the top of the stack.
1676254721Semaste        //----------------------------------------------------------------------
1677254721Semaste        case DW_OP_over:
1678254721Semaste            if (stack.size() < 2)
1679254721Semaste            {
1680254721Semaste                if (error_ptr)
1681254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_over.");
1682254721Semaste                return false;
1683254721Semaste            }
1684254721Semaste            else
1685254721Semaste                stack.push_back(stack[stack.size() - 2]);
1686254721Semaste            break;
1687254721Semaste
1688254721Semaste
1689254721Semaste        //----------------------------------------------------------------------
1690254721Semaste        // OPCODE: DW_OP_pick
1691254721Semaste        // OPERANDS: uint8_t index into the current stack
1692254721Semaste        // DESCRIPTION: The stack entry with the specified index (0 through 255,
1693254721Semaste        // inclusive) is pushed on the stack
1694254721Semaste        //----------------------------------------------------------------------
1695254721Semaste        case DW_OP_pick:
1696254721Semaste            {
1697254721Semaste                uint8_t pick_idx = opcodes.GetU8(&offset);
1698254721Semaste                if (pick_idx < stack.size())
1699254721Semaste                    stack.push_back(stack[pick_idx]);
1700254721Semaste                else
1701254721Semaste                {
1702254721Semaste                    if (error_ptr)
1703254721Semaste                        error_ptr->SetErrorStringWithFormat("Index %u out of range for DW_OP_pick.\n", pick_idx);
1704254721Semaste                    return false;
1705254721Semaste                }
1706254721Semaste            }
1707254721Semaste            break;
1708254721Semaste
1709254721Semaste        //----------------------------------------------------------------------
1710254721Semaste        // OPCODE: DW_OP_swap
1711254721Semaste        // OPERANDS: none
1712254721Semaste        // DESCRIPTION: swaps the top two stack entries. The entry at the top
1713254721Semaste        // of the stack becomes the second stack entry, and the second entry
1714254721Semaste        // becomes the top of the stack
1715254721Semaste        //----------------------------------------------------------------------
1716254721Semaste        case DW_OP_swap:
1717254721Semaste            if (stack.size() < 2)
1718254721Semaste            {
1719254721Semaste                if (error_ptr)
1720254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_swap.");
1721254721Semaste                return false;
1722254721Semaste            }
1723254721Semaste            else
1724254721Semaste            {
1725254721Semaste                tmp = stack.back();
1726254721Semaste                stack.back() = stack[stack.size() - 2];
1727254721Semaste                stack[stack.size() - 2] = tmp;
1728254721Semaste            }
1729254721Semaste            break;
1730254721Semaste
1731254721Semaste        //----------------------------------------------------------------------
1732254721Semaste        // OPCODE: DW_OP_rot
1733254721Semaste        // OPERANDS: none
1734254721Semaste        // DESCRIPTION: Rotates the first three stack entries. The entry at
1735254721Semaste        // the top of the stack becomes the third stack entry, the second
1736254721Semaste        // entry becomes the top of the stack, and the third entry becomes
1737254721Semaste        // the second entry.
1738254721Semaste        //----------------------------------------------------------------------
1739254721Semaste        case DW_OP_rot:
1740254721Semaste            if (stack.size() < 3)
1741254721Semaste            {
1742254721Semaste                if (error_ptr)
1743254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 3 items for DW_OP_rot.");
1744254721Semaste                return false;
1745254721Semaste            }
1746254721Semaste            else
1747254721Semaste            {
1748254721Semaste                size_t last_idx = stack.size() - 1;
1749254721Semaste                Value old_top = stack[last_idx];
1750254721Semaste                stack[last_idx] = stack[last_idx - 1];
1751254721Semaste                stack[last_idx - 1] = stack[last_idx - 2];
1752254721Semaste                stack[last_idx - 2] = old_top;
1753254721Semaste            }
1754254721Semaste            break;
1755254721Semaste
1756254721Semaste        //----------------------------------------------------------------------
1757254721Semaste        // OPCODE: DW_OP_abs
1758254721Semaste        // OPERANDS: none
1759254721Semaste        // DESCRIPTION: pops the top stack entry, interprets it as a signed
1760254721Semaste        // value and pushes its absolute value. If the absolute value can not be
1761254721Semaste        // represented, the result is undefined.
1762254721Semaste        //----------------------------------------------------------------------
1763254721Semaste        case DW_OP_abs:
1764254721Semaste            if (stack.empty())
1765254721Semaste            {
1766254721Semaste                if (error_ptr)
1767254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_abs.");
1768254721Semaste                return false;
1769254721Semaste            }
1770254721Semaste            else if (stack.back().ResolveValue(exe_ctx).AbsoluteValue() == false)
1771254721Semaste            {
1772254721Semaste                if (error_ptr)
1773254721Semaste                    error_ptr->SetErrorString("Failed to take the absolute value of the first stack item.");
1774254721Semaste                return false;
1775254721Semaste            }
1776254721Semaste            break;
1777254721Semaste
1778254721Semaste        //----------------------------------------------------------------------
1779254721Semaste        // OPCODE: DW_OP_and
1780254721Semaste        // OPERANDS: none
1781254721Semaste        // DESCRIPTION: pops the top two stack values, performs a bitwise and
1782254721Semaste        // operation on the two, and pushes the result.
1783254721Semaste        //----------------------------------------------------------------------
1784254721Semaste        case DW_OP_and:
1785254721Semaste            if (stack.size() < 2)
1786254721Semaste            {
1787254721Semaste                if (error_ptr)
1788254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_and.");
1789254721Semaste                return false;
1790254721Semaste            }
1791254721Semaste            else
1792254721Semaste            {
1793254721Semaste                tmp = stack.back();
1794254721Semaste                stack.pop_back();
1795254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx);
1796254721Semaste            }
1797254721Semaste            break;
1798254721Semaste
1799254721Semaste        //----------------------------------------------------------------------
1800254721Semaste        // OPCODE: DW_OP_div
1801254721Semaste        // OPERANDS: none
1802254721Semaste        // DESCRIPTION: pops the top two stack values, divides the former second
1803254721Semaste        // entry by the former top of the stack using signed division, and
1804254721Semaste        // pushes the result.
1805254721Semaste        //----------------------------------------------------------------------
1806254721Semaste        case DW_OP_div:
1807254721Semaste            if (stack.size() < 2)
1808254721Semaste            {
1809254721Semaste                if (error_ptr)
1810254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_div.");
1811254721Semaste                return false;
1812254721Semaste            }
1813254721Semaste            else
1814254721Semaste            {
1815254721Semaste                tmp = stack.back();
1816254721Semaste                if (tmp.ResolveValue(exe_ctx).IsZero())
1817254721Semaste                {
1818254721Semaste                    if (error_ptr)
1819254721Semaste                        error_ptr->SetErrorString("Divide by zero.");
1820254721Semaste                    return false;
1821254721Semaste                }
1822254721Semaste                else
1823254721Semaste                {
1824254721Semaste                    stack.pop_back();
1825254721Semaste                    stack.back() = stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx);
1826254721Semaste                    if (!stack.back().ResolveValue(exe_ctx).IsValid())
1827254721Semaste                    {
1828254721Semaste                        if (error_ptr)
1829254721Semaste                            error_ptr->SetErrorString("Divide failed.");
1830254721Semaste                        return false;
1831254721Semaste                    }
1832254721Semaste                }
1833254721Semaste            }
1834254721Semaste            break;
1835254721Semaste
1836254721Semaste        //----------------------------------------------------------------------
1837254721Semaste        // OPCODE: DW_OP_minus
1838254721Semaste        // OPERANDS: none
1839254721Semaste        // DESCRIPTION: pops the top two stack values, subtracts the former top
1840254721Semaste        // of the stack from the former second entry, and pushes the result.
1841254721Semaste        //----------------------------------------------------------------------
1842254721Semaste        case DW_OP_minus:
1843254721Semaste            if (stack.size() < 2)
1844254721Semaste            {
1845254721Semaste                if (error_ptr)
1846254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_minus.");
1847254721Semaste                return false;
1848254721Semaste            }
1849254721Semaste            else
1850254721Semaste            {
1851254721Semaste                tmp = stack.back();
1852254721Semaste                stack.pop_back();
1853254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx);
1854254721Semaste            }
1855254721Semaste            break;
1856254721Semaste
1857254721Semaste        //----------------------------------------------------------------------
1858254721Semaste        // OPCODE: DW_OP_mod
1859254721Semaste        // OPERANDS: none
1860254721Semaste        // DESCRIPTION: pops the top two stack values and pushes the result of
1861254721Semaste        // the calculation: former second stack entry modulo the former top of
1862254721Semaste        // the stack.
1863254721Semaste        //----------------------------------------------------------------------
1864254721Semaste        case DW_OP_mod:
1865254721Semaste            if (stack.size() < 2)
1866254721Semaste            {
1867254721Semaste                if (error_ptr)
1868254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_mod.");
1869254721Semaste                return false;
1870254721Semaste            }
1871254721Semaste            else
1872254721Semaste            {
1873254721Semaste                tmp = stack.back();
1874254721Semaste                stack.pop_back();
1875254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx);
1876254721Semaste            }
1877254721Semaste            break;
1878254721Semaste
1879254721Semaste
1880254721Semaste        //----------------------------------------------------------------------
1881254721Semaste        // OPCODE: DW_OP_mul
1882254721Semaste        // OPERANDS: none
1883254721Semaste        // DESCRIPTION: pops the top two stack entries, multiplies them
1884254721Semaste        // together, and pushes the result.
1885254721Semaste        //----------------------------------------------------------------------
1886254721Semaste        case DW_OP_mul:
1887254721Semaste            if (stack.size() < 2)
1888254721Semaste            {
1889254721Semaste                if (error_ptr)
1890254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_mul.");
1891254721Semaste                return false;
1892254721Semaste            }
1893254721Semaste            else
1894254721Semaste            {
1895254721Semaste                tmp = stack.back();
1896254721Semaste                stack.pop_back();
1897254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx);
1898254721Semaste            }
1899254721Semaste            break;
1900254721Semaste
1901254721Semaste        //----------------------------------------------------------------------
1902254721Semaste        // OPCODE: DW_OP_neg
1903254721Semaste        // OPERANDS: none
1904254721Semaste        // DESCRIPTION: pops the top stack entry, and pushes its negation.
1905254721Semaste        //----------------------------------------------------------------------
1906254721Semaste        case DW_OP_neg:
1907254721Semaste            if (stack.empty())
1908254721Semaste            {
1909254721Semaste                if (error_ptr)
1910254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_neg.");
1911254721Semaste                return false;
1912254721Semaste            }
1913254721Semaste            else
1914254721Semaste            {
1915254721Semaste                if (stack.back().ResolveValue(exe_ctx).UnaryNegate() == false)
1916254721Semaste                {
1917254721Semaste                    if (error_ptr)
1918254721Semaste                        error_ptr->SetErrorString("Unary negate failed.");
1919254721Semaste                    return false;
1920254721Semaste                }
1921254721Semaste            }
1922254721Semaste            break;
1923254721Semaste
1924254721Semaste        //----------------------------------------------------------------------
1925254721Semaste        // OPCODE: DW_OP_not
1926254721Semaste        // OPERANDS: none
1927254721Semaste        // DESCRIPTION: pops the top stack entry, and pushes its bitwise
1928254721Semaste        // complement
1929254721Semaste        //----------------------------------------------------------------------
1930254721Semaste        case DW_OP_not:
1931254721Semaste            if (stack.empty())
1932254721Semaste            {
1933254721Semaste                if (error_ptr)
1934254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_not.");
1935254721Semaste                return false;
1936254721Semaste            }
1937254721Semaste            else
1938254721Semaste            {
1939254721Semaste                if (stack.back().ResolveValue(exe_ctx).OnesComplement() == false)
1940254721Semaste                {
1941254721Semaste                    if (error_ptr)
1942254721Semaste                        error_ptr->SetErrorString("Logical NOT failed.");
1943254721Semaste                    return false;
1944254721Semaste                }
1945254721Semaste            }
1946254721Semaste            break;
1947254721Semaste
1948254721Semaste        //----------------------------------------------------------------------
1949254721Semaste        // OPCODE: DW_OP_or
1950254721Semaste        // OPERANDS: none
1951254721Semaste        // DESCRIPTION: pops the top two stack entries, performs a bitwise or
1952254721Semaste        // operation on the two, and pushes the result.
1953254721Semaste        //----------------------------------------------------------------------
1954254721Semaste        case DW_OP_or:
1955254721Semaste            if (stack.size() < 2)
1956254721Semaste            {
1957254721Semaste                if (error_ptr)
1958254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_or.");
1959254721Semaste                return false;
1960254721Semaste            }
1961254721Semaste            else
1962254721Semaste            {
1963254721Semaste                tmp = stack.back();
1964254721Semaste                stack.pop_back();
1965254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx);
1966254721Semaste            }
1967254721Semaste            break;
1968254721Semaste
1969254721Semaste        //----------------------------------------------------------------------
1970254721Semaste        // OPCODE: DW_OP_plus
1971254721Semaste        // OPERANDS: none
1972254721Semaste        // DESCRIPTION: pops the top two stack entries, adds them together, and
1973254721Semaste        // pushes the result.
1974254721Semaste        //----------------------------------------------------------------------
1975254721Semaste        case DW_OP_plus:
1976254721Semaste            if (stack.size() < 2)
1977254721Semaste            {
1978254721Semaste                if (error_ptr)
1979254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_plus.");
1980254721Semaste                return false;
1981254721Semaste            }
1982254721Semaste            else
1983254721Semaste            {
1984254721Semaste                tmp = stack.back();
1985254721Semaste                stack.pop_back();
1986254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) + tmp.ResolveValue(exe_ctx);
1987254721Semaste            }
1988254721Semaste            break;
1989254721Semaste
1990254721Semaste        //----------------------------------------------------------------------
1991254721Semaste        // OPCODE: DW_OP_plus_uconst
1992254721Semaste        // OPERANDS: none
1993254721Semaste        // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
1994254721Semaste        // constant operand and pushes the result.
1995254721Semaste        //----------------------------------------------------------------------
1996254721Semaste        case DW_OP_plus_uconst:
1997254721Semaste            if (stack.empty())
1998254721Semaste            {
1999254721Semaste                if (error_ptr)
2000254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_plus_uconst.");
2001254721Semaste                return false;
2002254721Semaste            }
2003254721Semaste            else
2004254721Semaste            {
2005254721Semaste                const uint64_t uconst_value = opcodes.GetULEB128(&offset);
2006254721Semaste                // Implicit conversion from a UINT to a Scalar...
2007254721Semaste                stack.back().ResolveValue(exe_ctx) += uconst_value;
2008254721Semaste                if (!stack.back().ResolveValue(exe_ctx).IsValid())
2009254721Semaste                {
2010254721Semaste                    if (error_ptr)
2011254721Semaste                        error_ptr->SetErrorString("DW_OP_plus_uconst failed.");
2012254721Semaste                    return false;
2013254721Semaste                }
2014254721Semaste            }
2015254721Semaste            break;
2016254721Semaste
2017254721Semaste        //----------------------------------------------------------------------
2018254721Semaste        // OPCODE: DW_OP_shl
2019254721Semaste        // OPERANDS: none
2020254721Semaste        // DESCRIPTION:  pops the top two stack entries, shifts the former
2021254721Semaste        // second entry left by the number of bits specified by the former top
2022254721Semaste        // of the stack, and pushes the result.
2023254721Semaste        //----------------------------------------------------------------------
2024254721Semaste        case DW_OP_shl:
2025254721Semaste            if (stack.size() < 2)
2026254721Semaste            {
2027254721Semaste                if (error_ptr)
2028254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shl.");
2029254721Semaste                return false;
2030254721Semaste            }
2031254721Semaste            else
2032254721Semaste            {
2033254721Semaste                tmp = stack.back();
2034254721Semaste                stack.pop_back();
2035254721Semaste                stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx);
2036254721Semaste            }
2037254721Semaste            break;
2038254721Semaste
2039254721Semaste        //----------------------------------------------------------------------
2040254721Semaste        // OPCODE: DW_OP_shr
2041254721Semaste        // OPERANDS: none
2042254721Semaste        // DESCRIPTION: pops the top two stack entries, shifts the former second
2043254721Semaste        // entry right logically (filling with zero bits) by the number of bits
2044254721Semaste        // specified by the former top of the stack, and pushes the result.
2045254721Semaste        //----------------------------------------------------------------------
2046254721Semaste        case DW_OP_shr:
2047254721Semaste            if (stack.size() < 2)
2048254721Semaste            {
2049254721Semaste                if (error_ptr)
2050254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shr.");
2051254721Semaste                return false;
2052254721Semaste            }
2053254721Semaste            else
2054254721Semaste            {
2055254721Semaste                tmp = stack.back();
2056254721Semaste                stack.pop_back();
2057254721Semaste                if (stack.back().ResolveValue(exe_ctx).ShiftRightLogical(tmp.ResolveValue(exe_ctx)) == false)
2058254721Semaste                {
2059254721Semaste                    if (error_ptr)
2060254721Semaste                        error_ptr->SetErrorString("DW_OP_shr failed.");
2061254721Semaste                    return false;
2062254721Semaste                }
2063254721Semaste            }
2064254721Semaste            break;
2065254721Semaste
2066254721Semaste        //----------------------------------------------------------------------
2067254721Semaste        // OPCODE: DW_OP_shra
2068254721Semaste        // OPERANDS: none
2069254721Semaste        // DESCRIPTION: pops the top two stack entries, shifts the former second
2070254721Semaste        // entry right arithmetically (divide the magnitude by 2, keep the same
2071254721Semaste        // sign for the result) by the number of bits specified by the former
2072254721Semaste        // top of the stack, and pushes the result.
2073254721Semaste        //----------------------------------------------------------------------
2074254721Semaste        case DW_OP_shra:
2075254721Semaste            if (stack.size() < 2)
2076254721Semaste            {
2077254721Semaste                if (error_ptr)
2078254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shra.");
2079254721Semaste                return false;
2080254721Semaste            }
2081254721Semaste            else
2082254721Semaste            {
2083254721Semaste                tmp = stack.back();
2084254721Semaste                stack.pop_back();
2085254721Semaste                stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx);
2086254721Semaste            }
2087254721Semaste            break;
2088254721Semaste
2089254721Semaste        //----------------------------------------------------------------------
2090254721Semaste        // OPCODE: DW_OP_xor
2091254721Semaste        // OPERANDS: none
2092254721Semaste        // DESCRIPTION: pops the top two stack entries, performs the bitwise
2093254721Semaste        // exclusive-or operation on the two, and pushes the result.
2094254721Semaste        //----------------------------------------------------------------------
2095254721Semaste        case DW_OP_xor:
2096254721Semaste            if (stack.size() < 2)
2097254721Semaste            {
2098254721Semaste                if (error_ptr)
2099254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_xor.");
2100254721Semaste                return false;
2101254721Semaste            }
2102254721Semaste            else
2103254721Semaste            {
2104254721Semaste                tmp = stack.back();
2105254721Semaste                stack.pop_back();
2106254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx);
2107254721Semaste            }
2108254721Semaste            break;
2109254721Semaste
2110254721Semaste
2111254721Semaste        //----------------------------------------------------------------------
2112254721Semaste        // OPCODE: DW_OP_skip
2113254721Semaste        // OPERANDS: int16_t
2114254721Semaste        // DESCRIPTION:  An unconditional branch. Its single operand is a 2-byte
2115254721Semaste        // signed integer constant. The 2-byte constant is the number of bytes
2116254721Semaste        // of the DWARF expression to skip forward or backward from the current
2117254721Semaste        // operation, beginning after the 2-byte constant.
2118254721Semaste        //----------------------------------------------------------------------
2119254721Semaste        case DW_OP_skip:
2120254721Semaste            {
2121254721Semaste                int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
2122254721Semaste                lldb::offset_t new_offset = offset + skip_offset;
2123254721Semaste                if (new_offset >= opcodes_offset && new_offset < end_offset)
2124254721Semaste                    offset = new_offset;
2125254721Semaste                else
2126254721Semaste                {
2127254721Semaste                    if (error_ptr)
2128254721Semaste                        error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip.");
2129254721Semaste                    return false;
2130254721Semaste                }
2131254721Semaste            }
2132254721Semaste            break;
2133254721Semaste
2134254721Semaste        //----------------------------------------------------------------------
2135254721Semaste        // OPCODE: DW_OP_bra
2136254721Semaste        // OPERANDS: int16_t
2137254721Semaste        // DESCRIPTION: A conditional branch. Its single operand is a 2-byte
2138254721Semaste        // signed integer constant. This operation pops the top of stack. If
2139254721Semaste        // the value popped is not the constant 0, the 2-byte constant operand
2140254721Semaste        // is the number of bytes of the DWARF expression to skip forward or
2141254721Semaste        // backward from the current operation, beginning after the 2-byte
2142254721Semaste        // constant.
2143254721Semaste        //----------------------------------------------------------------------
2144254721Semaste        case DW_OP_bra:
2145254721Semaste            {
2146254721Semaste                tmp = stack.back();
2147254721Semaste                stack.pop_back();
2148254721Semaste                int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
2149254721Semaste                Scalar zero(0);
2150254721Semaste                if (tmp.ResolveValue(exe_ctx) != zero)
2151254721Semaste                {
2152254721Semaste                    lldb::offset_t new_offset = offset + bra_offset;
2153254721Semaste                    if (new_offset >= opcodes_offset && new_offset < end_offset)
2154254721Semaste                        offset = new_offset;
2155254721Semaste                    else
2156254721Semaste                    {
2157254721Semaste                        if (error_ptr)
2158254721Semaste                            error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra.");
2159254721Semaste                        return false;
2160254721Semaste                    }
2161254721Semaste                }
2162254721Semaste            }
2163254721Semaste            break;
2164254721Semaste
2165254721Semaste        //----------------------------------------------------------------------
2166254721Semaste        // OPCODE: DW_OP_eq
2167254721Semaste        // OPERANDS: none
2168254721Semaste        // DESCRIPTION: pops the top two stack values, compares using the
2169254721Semaste        // equals (==) operator.
2170254721Semaste        // STACK RESULT: push the constant value 1 onto the stack if the result
2171254721Semaste        // of the operation is true or the constant value 0 if the result of the
2172254721Semaste        // operation is false.
2173254721Semaste        //----------------------------------------------------------------------
2174254721Semaste        case DW_OP_eq:
2175254721Semaste            if (stack.size() < 2)
2176254721Semaste            {
2177254721Semaste                if (error_ptr)
2178254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_eq.");
2179254721Semaste                return false;
2180254721Semaste            }
2181254721Semaste            else
2182254721Semaste            {
2183254721Semaste                tmp = stack.back();
2184254721Semaste                stack.pop_back();
2185254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx);
2186254721Semaste            }
2187254721Semaste            break;
2188254721Semaste
2189254721Semaste        //----------------------------------------------------------------------
2190254721Semaste        // OPCODE: DW_OP_ge
2191254721Semaste        // OPERANDS: none
2192254721Semaste        // DESCRIPTION: pops the top two stack values, compares using the
2193254721Semaste        // greater than or equal to (>=) operator.
2194254721Semaste        // STACK RESULT: push the constant value 1 onto the stack if the result
2195254721Semaste        // of the operation is true or the constant value 0 if the result of the
2196254721Semaste        // operation is false.
2197254721Semaste        //----------------------------------------------------------------------
2198254721Semaste        case DW_OP_ge:
2199254721Semaste            if (stack.size() < 2)
2200254721Semaste            {
2201254721Semaste                if (error_ptr)
2202254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_ge.");
2203254721Semaste                return false;
2204254721Semaste            }
2205254721Semaste            else
2206254721Semaste            {
2207254721Semaste                tmp = stack.back();
2208254721Semaste                stack.pop_back();
2209254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx);
2210254721Semaste            }
2211254721Semaste            break;
2212254721Semaste
2213254721Semaste        //----------------------------------------------------------------------
2214254721Semaste        // OPCODE: DW_OP_gt
2215254721Semaste        // OPERANDS: none
2216254721Semaste        // DESCRIPTION: pops the top two stack values, compares using the
2217254721Semaste        // greater than (>) operator.
2218254721Semaste        // STACK RESULT: push the constant value 1 onto the stack if the result
2219254721Semaste        // of the operation is true or the constant value 0 if the result of the
2220254721Semaste        // operation is false.
2221254721Semaste        //----------------------------------------------------------------------
2222254721Semaste        case DW_OP_gt:
2223254721Semaste            if (stack.size() < 2)
2224254721Semaste            {
2225254721Semaste                if (error_ptr)
2226254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_gt.");
2227254721Semaste                return false;
2228254721Semaste            }
2229254721Semaste            else
2230254721Semaste            {
2231254721Semaste                tmp = stack.back();
2232254721Semaste                stack.pop_back();
2233254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx);
2234254721Semaste            }
2235254721Semaste            break;
2236254721Semaste
2237254721Semaste        //----------------------------------------------------------------------
2238254721Semaste        // OPCODE: DW_OP_le
2239254721Semaste        // OPERANDS: none
2240254721Semaste        // DESCRIPTION: pops the top two stack values, compares using the
2241254721Semaste        // less than or equal to (<=) operator.
2242254721Semaste        // STACK RESULT: push the constant value 1 onto the stack if the result
2243254721Semaste        // of the operation is true or the constant value 0 if the result of the
2244254721Semaste        // operation is false.
2245254721Semaste        //----------------------------------------------------------------------
2246254721Semaste        case DW_OP_le:
2247254721Semaste            if (stack.size() < 2)
2248254721Semaste            {
2249254721Semaste                if (error_ptr)
2250254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_le.");
2251254721Semaste                return false;
2252254721Semaste            }
2253254721Semaste            else
2254254721Semaste            {
2255254721Semaste                tmp = stack.back();
2256254721Semaste                stack.pop_back();
2257254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx);
2258254721Semaste            }
2259254721Semaste            break;
2260254721Semaste
2261254721Semaste        //----------------------------------------------------------------------
2262254721Semaste        // OPCODE: DW_OP_lt
2263254721Semaste        // OPERANDS: none
2264254721Semaste        // DESCRIPTION: pops the top two stack values, compares using the
2265254721Semaste        // less than (<) operator.
2266254721Semaste        // STACK RESULT: push the constant value 1 onto the stack if the result
2267254721Semaste        // of the operation is true or the constant value 0 if the result of the
2268254721Semaste        // operation is false.
2269254721Semaste        //----------------------------------------------------------------------
2270254721Semaste        case DW_OP_lt:
2271254721Semaste            if (stack.size() < 2)
2272254721Semaste            {
2273254721Semaste                if (error_ptr)
2274254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_lt.");
2275254721Semaste                return false;
2276254721Semaste            }
2277254721Semaste            else
2278254721Semaste            {
2279254721Semaste                tmp = stack.back();
2280254721Semaste                stack.pop_back();
2281254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx);
2282254721Semaste            }
2283254721Semaste            break;
2284254721Semaste
2285254721Semaste        //----------------------------------------------------------------------
2286254721Semaste        // OPCODE: DW_OP_ne
2287254721Semaste        // OPERANDS: none
2288254721Semaste        // DESCRIPTION: pops the top two stack values, compares using the
2289254721Semaste        // not equal (!=) operator.
2290254721Semaste        // STACK RESULT: push the constant value 1 onto the stack if the result
2291254721Semaste        // of the operation is true or the constant value 0 if the result of the
2292254721Semaste        // operation is false.
2293254721Semaste        //----------------------------------------------------------------------
2294254721Semaste        case DW_OP_ne:
2295254721Semaste            if (stack.size() < 2)
2296254721Semaste            {
2297254721Semaste                if (error_ptr)
2298254721Semaste                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_ne.");
2299254721Semaste                return false;
2300254721Semaste            }
2301254721Semaste            else
2302254721Semaste            {
2303254721Semaste                tmp = stack.back();
2304254721Semaste                stack.pop_back();
2305254721Semaste                stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx);
2306254721Semaste            }
2307254721Semaste            break;
2308254721Semaste
2309254721Semaste        //----------------------------------------------------------------------
2310254721Semaste        // OPCODE: DW_OP_litn
2311254721Semaste        // OPERANDS: none
2312254721Semaste        // DESCRIPTION: encode the unsigned literal values from 0 through 31.
2313254721Semaste        // STACK RESULT: push the unsigned literal constant value onto the top
2314254721Semaste        // of the stack.
2315254721Semaste        //----------------------------------------------------------------------
2316254721Semaste        case DW_OP_lit0:
2317254721Semaste        case DW_OP_lit1:
2318254721Semaste        case DW_OP_lit2:
2319254721Semaste        case DW_OP_lit3:
2320254721Semaste        case DW_OP_lit4:
2321254721Semaste        case DW_OP_lit5:
2322254721Semaste        case DW_OP_lit6:
2323254721Semaste        case DW_OP_lit7:
2324254721Semaste        case DW_OP_lit8:
2325254721Semaste        case DW_OP_lit9:
2326254721Semaste        case DW_OP_lit10:
2327254721Semaste        case DW_OP_lit11:
2328254721Semaste        case DW_OP_lit12:
2329254721Semaste        case DW_OP_lit13:
2330254721Semaste        case DW_OP_lit14:
2331254721Semaste        case DW_OP_lit15:
2332254721Semaste        case DW_OP_lit16:
2333254721Semaste        case DW_OP_lit17:
2334254721Semaste        case DW_OP_lit18:
2335254721Semaste        case DW_OP_lit19:
2336254721Semaste        case DW_OP_lit20:
2337254721Semaste        case DW_OP_lit21:
2338254721Semaste        case DW_OP_lit22:
2339254721Semaste        case DW_OP_lit23:
2340254721Semaste        case DW_OP_lit24:
2341254721Semaste        case DW_OP_lit25:
2342254721Semaste        case DW_OP_lit26:
2343254721Semaste        case DW_OP_lit27:
2344254721Semaste        case DW_OP_lit28:
2345254721Semaste        case DW_OP_lit29:
2346254721Semaste        case DW_OP_lit30:
2347254721Semaste        case DW_OP_lit31:
2348254721Semaste            stack.push_back(Scalar(op - DW_OP_lit0));
2349254721Semaste            break;
2350254721Semaste
2351254721Semaste        //----------------------------------------------------------------------
2352254721Semaste        // OPCODE: DW_OP_regN
2353254721Semaste        // OPERANDS: none
2354254721Semaste        // DESCRIPTION: Push the value in register n on the top of the stack.
2355254721Semaste        //----------------------------------------------------------------------
2356254721Semaste        case DW_OP_reg0:
2357254721Semaste        case DW_OP_reg1:
2358254721Semaste        case DW_OP_reg2:
2359254721Semaste        case DW_OP_reg3:
2360254721Semaste        case DW_OP_reg4:
2361254721Semaste        case DW_OP_reg5:
2362254721Semaste        case DW_OP_reg6:
2363254721Semaste        case DW_OP_reg7:
2364254721Semaste        case DW_OP_reg8:
2365254721Semaste        case DW_OP_reg9:
2366254721Semaste        case DW_OP_reg10:
2367254721Semaste        case DW_OP_reg11:
2368254721Semaste        case DW_OP_reg12:
2369254721Semaste        case DW_OP_reg13:
2370254721Semaste        case DW_OP_reg14:
2371254721Semaste        case DW_OP_reg15:
2372254721Semaste        case DW_OP_reg16:
2373254721Semaste        case DW_OP_reg17:
2374254721Semaste        case DW_OP_reg18:
2375254721Semaste        case DW_OP_reg19:
2376254721Semaste        case DW_OP_reg20:
2377254721Semaste        case DW_OP_reg21:
2378254721Semaste        case DW_OP_reg22:
2379254721Semaste        case DW_OP_reg23:
2380254721Semaste        case DW_OP_reg24:
2381254721Semaste        case DW_OP_reg25:
2382254721Semaste        case DW_OP_reg26:
2383254721Semaste        case DW_OP_reg27:
2384254721Semaste        case DW_OP_reg28:
2385254721Semaste        case DW_OP_reg29:
2386254721Semaste        case DW_OP_reg30:
2387254721Semaste        case DW_OP_reg31:
2388254721Semaste            {
2389254721Semaste                reg_num = op - DW_OP_reg0;
2390254721Semaste
2391254721Semaste                if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
2392254721Semaste                    stack.push_back(tmp);
2393254721Semaste                else
2394254721Semaste                    return false;
2395254721Semaste            }
2396254721Semaste            break;
2397254721Semaste        //----------------------------------------------------------------------
2398254721Semaste        // OPCODE: DW_OP_regx
2399254721Semaste        // OPERANDS:
2400254721Semaste        //      ULEB128 literal operand that encodes the register.
2401254721Semaste        // DESCRIPTION: Push the value in register on the top of the stack.
2402254721Semaste        //----------------------------------------------------------------------
2403254721Semaste        case DW_OP_regx:
2404254721Semaste            {
2405254721Semaste                reg_num = opcodes.GetULEB128(&offset);
2406254721Semaste                if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
2407254721Semaste                    stack.push_back(tmp);
2408254721Semaste                else
2409254721Semaste                    return false;
2410254721Semaste            }
2411254721Semaste            break;
2412254721Semaste
2413254721Semaste        //----------------------------------------------------------------------
2414254721Semaste        // OPCODE: DW_OP_bregN
2415254721Semaste        // OPERANDS:
2416254721Semaste        //      SLEB128 offset from register N
2417254721Semaste        // DESCRIPTION: Value is in memory at the address specified by register
2418254721Semaste        // N plus an offset.
2419254721Semaste        //----------------------------------------------------------------------
2420254721Semaste        case DW_OP_breg0:
2421254721Semaste        case DW_OP_breg1:
2422254721Semaste        case DW_OP_breg2:
2423254721Semaste        case DW_OP_breg3:
2424254721Semaste        case DW_OP_breg4:
2425254721Semaste        case DW_OP_breg5:
2426254721Semaste        case DW_OP_breg6:
2427254721Semaste        case DW_OP_breg7:
2428254721Semaste        case DW_OP_breg8:
2429254721Semaste        case DW_OP_breg9:
2430254721Semaste        case DW_OP_breg10:
2431254721Semaste        case DW_OP_breg11:
2432254721Semaste        case DW_OP_breg12:
2433254721Semaste        case DW_OP_breg13:
2434254721Semaste        case DW_OP_breg14:
2435254721Semaste        case DW_OP_breg15:
2436254721Semaste        case DW_OP_breg16:
2437254721Semaste        case DW_OP_breg17:
2438254721Semaste        case DW_OP_breg18:
2439254721Semaste        case DW_OP_breg19:
2440254721Semaste        case DW_OP_breg20:
2441254721Semaste        case DW_OP_breg21:
2442254721Semaste        case DW_OP_breg22:
2443254721Semaste        case DW_OP_breg23:
2444254721Semaste        case DW_OP_breg24:
2445254721Semaste        case DW_OP_breg25:
2446254721Semaste        case DW_OP_breg26:
2447254721Semaste        case DW_OP_breg27:
2448254721Semaste        case DW_OP_breg28:
2449254721Semaste        case DW_OP_breg29:
2450254721Semaste        case DW_OP_breg30:
2451254721Semaste        case DW_OP_breg31:
2452254721Semaste            {
2453254721Semaste                reg_num = op - DW_OP_breg0;
2454254721Semaste
2455254721Semaste                if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
2456254721Semaste                {
2457254721Semaste                    int64_t breg_offset = opcodes.GetSLEB128(&offset);
2458254721Semaste                    tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
2459254721Semaste                    tmp.ClearContext();
2460254721Semaste                    stack.push_back(tmp);
2461254721Semaste                    stack.back().SetValueType (Value::eValueTypeLoadAddress);
2462254721Semaste                }
2463254721Semaste                else
2464254721Semaste                    return false;
2465254721Semaste            }
2466254721Semaste            break;
2467254721Semaste        //----------------------------------------------------------------------
2468254721Semaste        // OPCODE: DW_OP_bregx
2469254721Semaste        // OPERANDS: 2
2470254721Semaste        //      ULEB128 literal operand that encodes the register.
2471254721Semaste        //      SLEB128 offset from register N
2472254721Semaste        // DESCRIPTION: Value is in memory at the address specified by register
2473254721Semaste        // N plus an offset.
2474254721Semaste        //----------------------------------------------------------------------
2475254721Semaste        case DW_OP_bregx:
2476254721Semaste            {
2477254721Semaste                reg_num = opcodes.GetULEB128(&offset);
2478254721Semaste
2479254721Semaste                if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
2480254721Semaste                {
2481254721Semaste                    int64_t breg_offset = opcodes.GetSLEB128(&offset);
2482254721Semaste                    tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset;
2483254721Semaste                    tmp.ClearContext();
2484254721Semaste                    stack.push_back(tmp);
2485254721Semaste                    stack.back().SetValueType (Value::eValueTypeLoadAddress);
2486254721Semaste                }
2487254721Semaste                else
2488254721Semaste                    return false;
2489254721Semaste            }
2490254721Semaste            break;
2491254721Semaste
2492254721Semaste        case DW_OP_fbreg:
2493254721Semaste            if (exe_ctx)
2494254721Semaste            {
2495254721Semaste                if (frame)
2496254721Semaste                {
2497254721Semaste                    Scalar value;
2498254721Semaste                    if (frame->GetFrameBaseValue(value, error_ptr))
2499254721Semaste                    {
2500254721Semaste                        int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
2501254721Semaste                        value += fbreg_offset;
2502254721Semaste                        stack.push_back(value);
2503254721Semaste                        stack.back().SetValueType (Value::eValueTypeLoadAddress);
2504254721Semaste                    }
2505254721Semaste                    else
2506254721Semaste                        return false;
2507254721Semaste                }
2508254721Semaste                else
2509254721Semaste                {
2510254721Semaste                    if (error_ptr)
2511254721Semaste                        error_ptr->SetErrorString ("Invalid stack frame in context for DW_OP_fbreg opcode.");
2512254721Semaste                    return false;
2513254721Semaste                }
2514254721Semaste            }
2515254721Semaste            else
2516254721Semaste            {
2517254721Semaste                if (error_ptr)
2518254721Semaste                    error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_fbreg.\n");
2519254721Semaste                return false;
2520254721Semaste            }
2521254721Semaste
2522254721Semaste            break;
2523254721Semaste
2524254721Semaste        //----------------------------------------------------------------------
2525254721Semaste        // OPCODE: DW_OP_nop
2526254721Semaste        // OPERANDS: none
2527254721Semaste        // DESCRIPTION: A place holder. It has no effect on the location stack
2528254721Semaste        // or any of its values.
2529254721Semaste        //----------------------------------------------------------------------
2530254721Semaste        case DW_OP_nop:
2531254721Semaste            break;
2532254721Semaste
2533254721Semaste        //----------------------------------------------------------------------
2534254721Semaste        // OPCODE: DW_OP_piece
2535254721Semaste        // OPERANDS: 1
2536254721Semaste        //      ULEB128: byte size of the piece
2537254721Semaste        // DESCRIPTION: The operand describes the size in bytes of the piece of
2538254721Semaste        // the object referenced by the DWARF expression whose result is at the
2539254721Semaste        // top of the stack. If the piece is located in a register, but does not
2540254721Semaste        // occupy the entire register, the placement of the piece within that
2541254721Semaste        // register is defined by the ABI.
2542254721Semaste        //
2543254721Semaste        // Many compilers store a single variable in sets of registers, or store
2544254721Semaste        // a variable partially in memory and partially in registers.
2545254721Semaste        // DW_OP_piece provides a way of describing how large a part of a
2546254721Semaste        // variable a particular DWARF expression refers to.
2547254721Semaste        //----------------------------------------------------------------------
2548254721Semaste        case DW_OP_piece:
2549254721Semaste            if (error_ptr)
2550254721Semaste                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_piece.");
2551254721Semaste            return false;
2552254721Semaste
2553254721Semaste        //----------------------------------------------------------------------
2554254721Semaste        // OPCODE: DW_OP_push_object_address
2555254721Semaste        // OPERANDS: none
2556254721Semaste        // DESCRIPTION: Pushes the address of the object currently being
2557254721Semaste        // evaluated as part of evaluation of a user presented expression.
2558254721Semaste        // This object may correspond to an independent variable described by
2559254721Semaste        // its own DIE or it may be a component of an array, structure, or class
2560254721Semaste        // whose address has been dynamically determined by an earlier step
2561254721Semaste        // during user expression evaluation.
2562254721Semaste        //----------------------------------------------------------------------
2563254721Semaste        case DW_OP_push_object_address:
2564254721Semaste            if (error_ptr)
2565254721Semaste                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_push_object_address.");
2566254721Semaste            return false;
2567254721Semaste
2568254721Semaste        //----------------------------------------------------------------------
2569254721Semaste        // OPCODE: DW_OP_call2
2570254721Semaste        // OPERANDS:
2571254721Semaste        //      uint16_t compile unit relative offset of a DIE
2572254721Semaste        // DESCRIPTION: Performs subroutine calls during evaluation
2573254721Semaste        // of a DWARF expression. The operand is the 2-byte unsigned offset
2574254721Semaste        // of a debugging information entry in the current compilation unit.
2575254721Semaste        //
2576254721Semaste        // Operand interpretation is exactly like that for DW_FORM_ref2.
2577254721Semaste        //
2578254721Semaste        // This operation transfers control of DWARF expression evaluation
2579254721Semaste        // to the DW_AT_location attribute of the referenced DIE. If there is
2580254721Semaste        // no such attribute, then there is no effect. Execution of the DWARF
2581254721Semaste        // expression of a DW_AT_location attribute may add to and/or remove from
2582254721Semaste        // values on the stack. Execution returns to the point following the call
2583254721Semaste        // when the end of the attribute is reached. Values on the stack at the
2584254721Semaste        // time of the call may be used as parameters by the called expression
2585254721Semaste        // and values left on the stack by the called expression may be used as
2586254721Semaste        // return values by prior agreement between the calling and called
2587254721Semaste        // expressions.
2588254721Semaste        //----------------------------------------------------------------------
2589254721Semaste        case DW_OP_call2:
2590254721Semaste            if (error_ptr)
2591254721Semaste                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call2.");
2592254721Semaste            return false;
2593254721Semaste        //----------------------------------------------------------------------
2594254721Semaste        // OPCODE: DW_OP_call4
2595254721Semaste        // OPERANDS: 1
2596254721Semaste        //      uint32_t compile unit relative offset of a DIE
2597254721Semaste        // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
2598254721Semaste        // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset
2599254721Semaste        // of a debugging information entry in  the current compilation unit.
2600254721Semaste        //
2601254721Semaste        // Operand interpretation DW_OP_call4 is exactly like that for
2602254721Semaste        // DW_FORM_ref4.
2603254721Semaste        //
2604254721Semaste        // This operation transfers control of DWARF expression evaluation
2605254721Semaste        // to the DW_AT_location attribute of the referenced DIE. If there is
2606254721Semaste        // no such attribute, then there is no effect. Execution of the DWARF
2607254721Semaste        // expression of a DW_AT_location attribute may add to and/or remove from
2608254721Semaste        // values on the stack. Execution returns to the point following the call
2609254721Semaste        // when the end of the attribute is reached. Values on the stack at the
2610254721Semaste        // time of the call may be used as parameters by the called expression
2611254721Semaste        // and values left on the stack by the called expression may be used as
2612254721Semaste        // return values by prior agreement between the calling and called
2613254721Semaste        // expressions.
2614254721Semaste        //----------------------------------------------------------------------
2615254721Semaste        case DW_OP_call4:
2616254721Semaste            if (error_ptr)
2617254721Semaste                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call4.");
2618254721Semaste            return false;
2619254721Semaste
2620254721Semaste        //----------------------------------------------------------------------
2621254721Semaste        // OPCODE: DW_OP_stack_value
2622254721Semaste        // OPERANDS: None
2623254721Semaste        // DESCRIPTION: Specifies that the object does not exist in memory but
2624254721Semaste        // rather is a constant value.  The value from the top of the stack is
2625254721Semaste        // the value to be used.  This is the actual object value and not the
2626254721Semaste        // location.
2627254721Semaste        //----------------------------------------------------------------------
2628254721Semaste        case DW_OP_stack_value:
2629254721Semaste            stack.back().SetValueType(Value::eValueTypeScalar);
2630254721Semaste            break;
2631254721Semaste
2632254721Semaste        //----------------------------------------------------------------------
2633254721Semaste        // OPCODE: DW_OP_call_frame_cfa
2634254721Semaste        // OPERANDS: None
2635254721Semaste        // DESCRIPTION: Specifies a DWARF expression that pushes the value of
2636254721Semaste        // the canonical frame address consistent with the call frame information
2637254721Semaste        // located in .debug_frame (or in the FDEs of the eh_frame section).
2638254721Semaste        //----------------------------------------------------------------------
2639254721Semaste        case DW_OP_call_frame_cfa:
2640254721Semaste            if (frame)
2641254721Semaste            {
2642254721Semaste                // Note that we don't have to parse FDEs because this DWARF expression
2643254721Semaste                // is commonly evaluated with a valid stack frame.
2644254721Semaste                StackID id = frame->GetStackID();
2645254721Semaste                addr_t cfa = id.GetCallFrameAddress();
2646254721Semaste                if (cfa != LLDB_INVALID_ADDRESS)
2647254721Semaste                {
2648254721Semaste                    stack.push_back(Scalar(cfa));
2649254721Semaste                    stack.back().SetValueType (Value::eValueTypeHostAddress);
2650254721Semaste                }
2651254721Semaste                else
2652254721Semaste                    if (error_ptr)
2653254721Semaste                        error_ptr->SetErrorString ("Stack frame does not include a canonical frame address for DW_OP_call_frame_cfa opcode.");
2654254721Semaste            }
2655254721Semaste            else
2656254721Semaste            {
2657254721Semaste                if (error_ptr)
2658254721Semaste                    error_ptr->SetErrorString ("Invalid stack frame in context for DW_OP_call_frame_cfa opcode.");
2659254721Semaste                return false;
2660254721Semaste            }
2661254721Semaste            break;
2662254721Semaste        default:
2663254721Semaste            if (log)
2664254721Semaste                log->Printf("Unhandled opcode %s in DWARFExpression.", DW_OP_value_to_name(op));
2665254721Semaste            break;
2666254721Semaste        }
2667254721Semaste    }
2668254721Semaste
2669254721Semaste    if (stack.empty())
2670254721Semaste    {
2671254721Semaste        if (error_ptr)
2672254721Semaste            error_ptr->SetErrorString ("Stack empty after evaluation.");
2673254721Semaste        return false;
2674254721Semaste    }
2675254721Semaste    else if (log && log->GetVerbose())
2676254721Semaste    {
2677254721Semaste        size_t count = stack.size();
2678254721Semaste        log->Printf("Stack after operation has %lu values:", count);
2679254721Semaste        for (size_t i=0; i<count; ++i)
2680254721Semaste        {
2681254721Semaste            StreamString new_value;
2682254721Semaste            new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
2683254721Semaste            stack[i].Dump(&new_value);
2684254721Semaste            log->Printf("  %s", new_value.GetData());
2685254721Semaste        }
2686254721Semaste    }
2687254721Semaste
2688254721Semaste    result = stack.back();
2689254721Semaste    return true;    // Return true on success
2690254721Semaste}
2691254721Semaste
2692