DWARFExpression.cpp revision 8c12720c108cd5e7ed792596749218d8400f647e
1//===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/DWARFExpression.h"
11
12#include <vector>
13
14#include "lldb/Core/dwarf.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/StreamString.h"
17#include "lldb/Core/Scalar.h"
18#include "lldb/Core/Value.h"
19
20#include "lldb/Expression/ClangExpressionDeclMap.h"
21#include "lldb/Expression/ClangExpressionVariable.h"
22
23#include "lldb/Host/Host.h"
24
25#include "lldb/lldb-private-log.h"
26
27#include "lldb/Symbol/ClangASTType.h"
28#include "lldb/Symbol/ClangASTContext.h"
29#include "lldb/Symbol/Type.h"
30
31#include "lldb/Target/ExecutionContext.h"
32#include "lldb/Target/Process.h"
33#include "lldb/Target/RegisterContext.h"
34#include "lldb/Target/StackFrame.h"
35
36using namespace lldb;
37using namespace lldb_private;
38
39const char *
40DW_OP_value_to_name (uint32_t val)
41{
42  static char invalid[100];
43  switch (val) {
44    case 0x03: return "DW_OP_addr";
45    case 0x06: return "DW_OP_deref";
46    case 0x08: return "DW_OP_const1u";
47    case 0x09: return "DW_OP_const1s";
48    case 0x0a: return "DW_OP_const2u";
49    case 0x0b: return "DW_OP_const2s";
50    case 0x0c: return "DW_OP_const4u";
51    case 0x0d: return "DW_OP_const4s";
52    case 0x0e: return "DW_OP_const8u";
53    case 0x0f: return "DW_OP_const8s";
54    case 0x10: return "DW_OP_constu";
55    case 0x11: return "DW_OP_consts";
56    case 0x12: return "DW_OP_dup";
57    case 0x13: return "DW_OP_drop";
58    case 0x14: return "DW_OP_over";
59    case 0x15: return "DW_OP_pick";
60    case 0x16: return "DW_OP_swap";
61    case 0x17: return "DW_OP_rot";
62    case 0x18: return "DW_OP_xderef";
63    case 0x19: return "DW_OP_abs";
64    case 0x1a: return "DW_OP_and";
65    case 0x1b: return "DW_OP_div";
66    case 0x1c: return "DW_OP_minus";
67    case 0x1d: return "DW_OP_mod";
68    case 0x1e: return "DW_OP_mul";
69    case 0x1f: return "DW_OP_neg";
70    case 0x20: return "DW_OP_not";
71    case 0x21: return "DW_OP_or";
72    case 0x22: return "DW_OP_plus";
73    case 0x23: return "DW_OP_plus_uconst";
74    case 0x24: return "DW_OP_shl";
75    case 0x25: return "DW_OP_shr";
76    case 0x26: return "DW_OP_shra";
77    case 0x27: return "DW_OP_xor";
78    case 0x2f: return "DW_OP_skip";
79    case 0x28: return "DW_OP_bra";
80    case 0x29: return "DW_OP_eq";
81    case 0x2a: return "DW_OP_ge";
82    case 0x2b: return "DW_OP_gt";
83    case 0x2c: return "DW_OP_le";
84    case 0x2d: return "DW_OP_lt";
85    case 0x2e: return "DW_OP_ne";
86    case 0x30: return "DW_OP_lit0";
87    case 0x31: return "DW_OP_lit1";
88    case 0x32: return "DW_OP_lit2";
89    case 0x33: return "DW_OP_lit3";
90    case 0x34: return "DW_OP_lit4";
91    case 0x35: return "DW_OP_lit5";
92    case 0x36: return "DW_OP_lit6";
93    case 0x37: return "DW_OP_lit7";
94    case 0x38: return "DW_OP_lit8";
95    case 0x39: return "DW_OP_lit9";
96    case 0x3a: return "DW_OP_lit10";
97    case 0x3b: return "DW_OP_lit11";
98    case 0x3c: return "DW_OP_lit12";
99    case 0x3d: return "DW_OP_lit13";
100    case 0x3e: return "DW_OP_lit14";
101    case 0x3f: return "DW_OP_lit15";
102    case 0x40: return "DW_OP_lit16";
103    case 0x41: return "DW_OP_lit17";
104    case 0x42: return "DW_OP_lit18";
105    case 0x43: return "DW_OP_lit19";
106    case 0x44: return "DW_OP_lit20";
107    case 0x45: return "DW_OP_lit21";
108    case 0x46: return "DW_OP_lit22";
109    case 0x47: return "DW_OP_lit23";
110    case 0x48: return "DW_OP_lit24";
111    case 0x49: return "DW_OP_lit25";
112    case 0x4a: return "DW_OP_lit26";
113    case 0x4b: return "DW_OP_lit27";
114    case 0x4c: return "DW_OP_lit28";
115    case 0x4d: return "DW_OP_lit29";
116    case 0x4e: return "DW_OP_lit30";
117    case 0x4f: return "DW_OP_lit31";
118    case 0x50: return "DW_OP_reg0";
119    case 0x51: return "DW_OP_reg1";
120    case 0x52: return "DW_OP_reg2";
121    case 0x53: return "DW_OP_reg3";
122    case 0x54: return "DW_OP_reg4";
123    case 0x55: return "DW_OP_reg5";
124    case 0x56: return "DW_OP_reg6";
125    case 0x57: return "DW_OP_reg7";
126    case 0x58: return "DW_OP_reg8";
127    case 0x59: return "DW_OP_reg9";
128    case 0x5a: return "DW_OP_reg10";
129    case 0x5b: return "DW_OP_reg11";
130    case 0x5c: return "DW_OP_reg12";
131    case 0x5d: return "DW_OP_reg13";
132    case 0x5e: return "DW_OP_reg14";
133    case 0x5f: return "DW_OP_reg15";
134    case 0x60: return "DW_OP_reg16";
135    case 0x61: return "DW_OP_reg17";
136    case 0x62: return "DW_OP_reg18";
137    case 0x63: return "DW_OP_reg19";
138    case 0x64: return "DW_OP_reg20";
139    case 0x65: return "DW_OP_reg21";
140    case 0x66: return "DW_OP_reg22";
141    case 0x67: return "DW_OP_reg23";
142    case 0x68: return "DW_OP_reg24";
143    case 0x69: return "DW_OP_reg25";
144    case 0x6a: return "DW_OP_reg26";
145    case 0x6b: return "DW_OP_reg27";
146    case 0x6c: return "DW_OP_reg28";
147    case 0x6d: return "DW_OP_reg29";
148    case 0x6e: return "DW_OP_reg30";
149    case 0x6f: return "DW_OP_reg31";
150    case 0x70: return "DW_OP_breg0";
151    case 0x71: return "DW_OP_breg1";
152    case 0x72: return "DW_OP_breg2";
153    case 0x73: return "DW_OP_breg3";
154    case 0x74: return "DW_OP_breg4";
155    case 0x75: return "DW_OP_breg5";
156    case 0x76: return "DW_OP_breg6";
157    case 0x77: return "DW_OP_breg7";
158    case 0x78: return "DW_OP_breg8";
159    case 0x79: return "DW_OP_breg9";
160    case 0x7a: return "DW_OP_breg10";
161    case 0x7b: return "DW_OP_breg11";
162    case 0x7c: return "DW_OP_breg12";
163    case 0x7d: return "DW_OP_breg13";
164    case 0x7e: return "DW_OP_breg14";
165    case 0x7f: return "DW_OP_breg15";
166    case 0x80: return "DW_OP_breg16";
167    case 0x81: return "DW_OP_breg17";
168    case 0x82: return "DW_OP_breg18";
169    case 0x83: return "DW_OP_breg19";
170    case 0x84: return "DW_OP_breg20";
171    case 0x85: return "DW_OP_breg21";
172    case 0x86: return "DW_OP_breg22";
173    case 0x87: return "DW_OP_breg23";
174    case 0x88: return "DW_OP_breg24";
175    case 0x89: return "DW_OP_breg25";
176    case 0x8a: return "DW_OP_breg26";
177    case 0x8b: return "DW_OP_breg27";
178    case 0x8c: return "DW_OP_breg28";
179    case 0x8d: return "DW_OP_breg29";
180    case 0x8e: return "DW_OP_breg30";
181    case 0x8f: return "DW_OP_breg31";
182    case 0x90: return "DW_OP_regx";
183    case 0x91: return "DW_OP_fbreg";
184    case 0x92: return "DW_OP_bregx";
185    case 0x93: return "DW_OP_piece";
186    case 0x94: return "DW_OP_deref_size";
187    case 0x95: return "DW_OP_xderef_size";
188    case 0x96: return "DW_OP_nop";
189    case 0x97: return "DW_OP_push_object_address";
190    case 0x98: return "DW_OP_call2";
191    case 0x99: return "DW_OP_call4";
192    case 0x9a: return "DW_OP_call_ref";
193    case DW_OP_APPLE_array_ref: return "DW_OP_APPLE_array_ref";
194    case DW_OP_APPLE_extern: return "DW_OP_APPLE_extern";
195    case DW_OP_APPLE_uninit: return "DW_OP_APPLE_uninit";
196    case DW_OP_APPLE_assign: return "DW_OP_APPLE_assign";
197    case DW_OP_APPLE_address_of: return "DW_OP_APPLE_address_of";
198    case DW_OP_APPLE_value_of: return "DW_OP_APPLE_value_of";
199    case DW_OP_APPLE_deref_type: return "DW_OP_APPLE_deref_type";
200    case DW_OP_APPLE_expr_local: return "DW_OP_APPLE_expr_local";
201    case DW_OP_APPLE_constf: return "DW_OP_APPLE_constf";
202    case DW_OP_APPLE_scalar_cast: return "DW_OP_APPLE_scalar_cast";
203    case DW_OP_APPLE_clang_cast: return "DW_OP_APPLE_clang_cast";
204    case DW_OP_APPLE_clear: return "DW_OP_APPLE_clear";
205    case DW_OP_APPLE_error: return "DW_OP_APPLE_error";
206    default:
207       snprintf (invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
208       return invalid;
209  }
210}
211
212
213//----------------------------------------------------------------------
214// DWARFExpression constructor
215//----------------------------------------------------------------------
216DWARFExpression::DWARFExpression() :
217    m_data(),
218    m_reg_kind (eRegisterKindDWARF),
219    m_loclist_base_addr(),
220    m_expr_locals (NULL),
221    m_decl_map (NULL)
222{
223}
224
225DWARFExpression::DWARFExpression(const DWARFExpression& rhs) :
226    m_data(rhs.m_data),
227    m_reg_kind (rhs.m_reg_kind),
228    m_loclist_base_addr(rhs.m_loclist_base_addr),
229    m_expr_locals (rhs.m_expr_locals),
230    m_decl_map (rhs.m_decl_map)
231{
232}
233
234
235DWARFExpression::DWARFExpression(const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr) :
236    m_data(data, data_offset, data_length),
237    m_reg_kind (eRegisterKindDWARF),
238    m_loclist_base_addr(),
239    m_expr_locals (NULL),
240    m_decl_map (NULL)
241{
242    if (loclist_base_addr_ptr)
243        m_loclist_base_addr = *loclist_base_addr_ptr;
244}
245
246//----------------------------------------------------------------------
247// Destructor
248//----------------------------------------------------------------------
249DWARFExpression::~DWARFExpression()
250{
251}
252
253
254bool
255DWARFExpression::IsValid() const
256{
257    return m_data.GetByteSize() > 0;
258}
259
260
261void
262DWARFExpression::SetExpressionLocalVariableList (ClangExpressionVariableList *locals)
263{
264    m_expr_locals = locals;
265}
266
267void
268DWARFExpression::SetExpressionDeclMap (ClangExpressionDeclMap *decl_map)
269{
270    m_decl_map = decl_map;
271}
272
273void
274DWARFExpression::SetOpcodeData (const DataExtractor& data, const Address* loclist_base_addr_ptr)
275{
276    m_data = data;
277    if (loclist_base_addr_ptr != NULL)
278        m_loclist_base_addr = *loclist_base_addr_ptr;
279    else
280        m_loclist_base_addr.Clear();
281}
282
283void
284DWARFExpression::SetOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr)
285{
286    m_data.SetData(data, data_offset, data_length);
287    if (loclist_base_addr_ptr != NULL)
288        m_loclist_base_addr = *loclist_base_addr_ptr;
289    else
290        m_loclist_base_addr.Clear();
291}
292
293void
294DWARFExpression::DumpLocation (Stream *s, uint32_t offset, uint32_t length, lldb::DescriptionLevel level) const
295{
296    if (!m_data.ValidOffsetForDataOfSize(offset, length))
297        return;
298    const uint32_t start_offset = offset;
299    const uint32_t end_offset = offset + length;
300    while (m_data.ValidOffset(offset) && offset < end_offset)
301    {
302        const uint32_t op_offset = offset;
303        const uint8_t op = m_data.GetU8(&offset);
304
305        switch (level)
306        {
307        default:
308            break;
309
310        case lldb::eDescriptionLevelBrief:
311            if (offset > start_offset)
312                s->PutChar(' ');
313            break;
314
315        case lldb::eDescriptionLevelFull:
316        case lldb::eDescriptionLevelVerbose:
317            if (offset > start_offset)
318                s->EOL();
319            s->Indent();
320            if (level == lldb::eDescriptionLevelFull)
321                break;
322            // Fall through for verbose and print offset and DW_OP prefix..
323            s->Printf("0x%8.8x: %s", op_offset, op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
324            break;
325        }
326
327        switch (op)
328        {
329        case DW_OP_addr:    *s << "addr(" << m_data.GetAddress(&offset) << ") "; break;         // 0x03 1 address
330        case DW_OP_deref:   *s << "deref"; break;                                               // 0x06
331        case DW_OP_const1u: s->Printf("const1u(0x%2.2x) ", m_data.GetU8(&offset)); break;       // 0x08 1 1-byte constant
332        case DW_OP_const1s: s->Printf("const1s(0x%2.2x) ", m_data.GetU8(&offset)); break;       // 0x09 1 1-byte constant
333        case DW_OP_const2u: s->Printf("const2u(0x%4.4x) ", m_data.GetU16(&offset)); break;      // 0x0a 1 2-byte constant
334        case DW_OP_const2s: s->Printf("const2s(0x%4.4x) ", m_data.GetU16(&offset)); break;      // 0x0b 1 2-byte constant
335        case DW_OP_const4u: s->Printf("const4u(0x%8.8x) ", m_data.GetU32(&offset)); break;      // 0x0c 1 4-byte constant
336        case DW_OP_const4s: s->Printf("const4s(0x%8.8x) ", m_data.GetU32(&offset)); break;      // 0x0d 1 4-byte constant
337        case DW_OP_const8u: s->Printf("const8u(0x%16.16llx) ", m_data.GetU64(&offset)); break;  // 0x0e 1 8-byte constant
338        case DW_OP_const8s: s->Printf("const8s(0x%16.16llx) ", m_data.GetU64(&offset)); break;  // 0x0f 1 8-byte constant
339        case DW_OP_constu:  s->Printf("constu(0x%x) ", m_data.GetULEB128(&offset)); break;      // 0x10 1 ULEB128 constant
340        case DW_OP_consts:  s->Printf("consts(0x%x) ", m_data.GetSLEB128(&offset)); break;      // 0x11 1 SLEB128 constant
341        case DW_OP_dup:     s->PutCString("dup"); break;                                        // 0x12
342        case DW_OP_drop:    s->PutCString("drop"); break;                                       // 0x13
343        case DW_OP_over:    s->PutCString("over"); break;                                       // 0x14
344        case DW_OP_pick:    s->Printf("pick(0x%2.2x) ", m_data.GetU8(&offset)); break;          // 0x15 1 1-byte stack index
345        case DW_OP_swap:    s->PutCString("swap"); break;                                       // 0x16
346        case DW_OP_rot:     s->PutCString("rot"); break;                                        // 0x17
347        case DW_OP_xderef:  s->PutCString("xderef"); break;                                     // 0x18
348        case DW_OP_abs:     s->PutCString("abs"); break;                                        // 0x19
349        case DW_OP_and:     s->PutCString("and"); break;                                        // 0x1a
350        case DW_OP_div:     s->PutCString("div"); break;                                        // 0x1b
351        case DW_OP_minus:   s->PutCString("minus"); break;                                      // 0x1c
352        case DW_OP_mod:     s->PutCString("mod"); break;                                        // 0x1d
353        case DW_OP_mul:     s->PutCString("mul"); break;                                        // 0x1e
354        case DW_OP_neg:     s->PutCString("neg"); break;                                        // 0x1f
355        case DW_OP_not:     s->PutCString("not"); break;                                        // 0x20
356        case DW_OP_or:      s->PutCString("or"); break;                                         // 0x21
357        case DW_OP_plus:    s->PutCString("plus"); break;                                       // 0x22
358        case DW_OP_plus_uconst:                                                                 // 0x23 1 ULEB128 addend
359            s->Printf("plus_uconst(0x%x) ", m_data.GetULEB128(&offset));
360            break;
361
362        case DW_OP_shl:     s->PutCString("shl"); break;                                        // 0x24
363        case DW_OP_shr:     s->PutCString("shr"); break;                                        // 0x25
364        case DW_OP_shra:    s->PutCString("shra"); break;                                       // 0x26
365        case DW_OP_xor:     s->PutCString("xor"); break;                                        // 0x27
366        case DW_OP_skip:    s->Printf("skip(0x%4.4x)", m_data.GetU16(&offset)); break;          // 0x2f 1 signed 2-byte constant
367        case DW_OP_bra:     s->Printf("bra(0x%4.4x)", m_data.GetU16(&offset)); break;           // 0x28 1 signed 2-byte constant
368        case DW_OP_eq:      s->PutCString("eq"); break;                                         // 0x29
369        case DW_OP_ge:      s->PutCString("ge"); break;                                         // 0x2a
370        case DW_OP_gt:      s->PutCString("gt"); break;                                         // 0x2b
371        case DW_OP_le:      s->PutCString("le"); break;                                         // 0x2c
372        case DW_OP_lt:      s->PutCString("lt"); break;                                         // 0x2d
373        case DW_OP_ne:      s->PutCString("ne"); break;                                         // 0x2e
374
375        case DW_OP_lit0:    // 0x30
376        case DW_OP_lit1:    // 0x31
377        case DW_OP_lit2:    // 0x32
378        case DW_OP_lit3:    // 0x33
379        case DW_OP_lit4:    // 0x34
380        case DW_OP_lit5:    // 0x35
381        case DW_OP_lit6:    // 0x36
382        case DW_OP_lit7:    // 0x37
383        case DW_OP_lit8:    // 0x38
384        case DW_OP_lit9:    // 0x39
385        case DW_OP_lit10:   // 0x3A
386        case DW_OP_lit11:   // 0x3B
387        case DW_OP_lit12:   // 0x3C
388        case DW_OP_lit13:   // 0x3D
389        case DW_OP_lit14:   // 0x3E
390        case DW_OP_lit15:   // 0x3F
391        case DW_OP_lit16:   // 0x40
392        case DW_OP_lit17:   // 0x41
393        case DW_OP_lit18:   // 0x42
394        case DW_OP_lit19:   // 0x43
395        case DW_OP_lit20:   // 0x44
396        case DW_OP_lit21:   // 0x45
397        case DW_OP_lit22:   // 0x46
398        case DW_OP_lit23:   // 0x47
399        case DW_OP_lit24:   // 0x48
400        case DW_OP_lit25:   // 0x49
401        case DW_OP_lit26:   // 0x4A
402        case DW_OP_lit27:   // 0x4B
403        case DW_OP_lit28:   // 0x4C
404        case DW_OP_lit29:   // 0x4D
405        case DW_OP_lit30:   // 0x4E
406        case DW_OP_lit31:   s->Printf("lit%i", op - DW_OP_lit0); break; // 0x4f
407
408        case DW_OP_reg0:    // 0x50
409        case DW_OP_reg1:    // 0x51
410        case DW_OP_reg2:    // 0x52
411        case DW_OP_reg3:    // 0x53
412        case DW_OP_reg4:    // 0x54
413        case DW_OP_reg5:    // 0x55
414        case DW_OP_reg6:    // 0x56
415        case DW_OP_reg7:    // 0x57
416        case DW_OP_reg8:    // 0x58
417        case DW_OP_reg9:    // 0x59
418        case DW_OP_reg10:   // 0x5A
419        case DW_OP_reg11:   // 0x5B
420        case DW_OP_reg12:   // 0x5C
421        case DW_OP_reg13:   // 0x5D
422        case DW_OP_reg14:   // 0x5E
423        case DW_OP_reg15:   // 0x5F
424        case DW_OP_reg16:   // 0x60
425        case DW_OP_reg17:   // 0x61
426        case DW_OP_reg18:   // 0x62
427        case DW_OP_reg19:   // 0x63
428        case DW_OP_reg20:   // 0x64
429        case DW_OP_reg21:   // 0x65
430        case DW_OP_reg22:   // 0x66
431        case DW_OP_reg23:   // 0x67
432        case DW_OP_reg24:   // 0x68
433        case DW_OP_reg25:   // 0x69
434        case DW_OP_reg26:   // 0x6A
435        case DW_OP_reg27:   // 0x6B
436        case DW_OP_reg28:   // 0x6C
437        case DW_OP_reg29:   // 0x6D
438        case DW_OP_reg30:   // 0x6E
439        case DW_OP_reg31:   s->Printf("reg%i", op - DW_OP_reg0); break; // 0x6f
440
441        case DW_OP_breg0:
442        case DW_OP_breg1:
443        case DW_OP_breg2:
444        case DW_OP_breg3:
445        case DW_OP_breg4:
446        case DW_OP_breg5:
447        case DW_OP_breg6:
448        case DW_OP_breg7:
449        case DW_OP_breg8:
450        case DW_OP_breg9:
451        case DW_OP_breg10:
452        case DW_OP_breg11:
453        case DW_OP_breg12:
454        case DW_OP_breg13:
455        case DW_OP_breg14:
456        case DW_OP_breg15:
457        case DW_OP_breg16:
458        case DW_OP_breg17:
459        case DW_OP_breg18:
460        case DW_OP_breg19:
461        case DW_OP_breg20:
462        case DW_OP_breg21:
463        case DW_OP_breg22:
464        case DW_OP_breg23:
465        case DW_OP_breg24:
466        case DW_OP_breg25:
467        case DW_OP_breg26:
468        case DW_OP_breg27:
469        case DW_OP_breg28:
470        case DW_OP_breg29:
471        case DW_OP_breg30:
472        case DW_OP_breg31:  s->Printf("breg%i(0x%x)", op - DW_OP_breg0, m_data.GetULEB128(&offset)); break;
473
474        case DW_OP_regx:                                                    // 0x90 1 ULEB128 register
475            s->Printf("regx(0x%x)", m_data.GetULEB128(&offset));
476            break;
477        case DW_OP_fbreg:                                                   // 0x91 1 SLEB128 offset
478            s->Printf("fbreg(0x%x)",m_data.GetSLEB128(&offset));
479            break;
480        case DW_OP_bregx:                                                   // 0x92 2 ULEB128 register followed by SLEB128 offset
481            s->Printf("bregx(0x%x, 0x%x)", m_data.GetULEB128(&offset), m_data.GetSLEB128(&offset));
482            break;
483        case DW_OP_piece:                                                   // 0x93 1 ULEB128 size of piece addressed
484            s->Printf("piece(0x%x)", m_data.GetULEB128(&offset));
485            break;
486        case DW_OP_deref_size:                                              // 0x94 1 1-byte size of data retrieved
487            s->Printf("deref_size(0x%2.2x)", m_data.GetU8(&offset));
488            break;
489        case DW_OP_xderef_size:                                             // 0x95 1 1-byte size of data retrieved
490            s->Printf("xderef_size(0x%2.2x)", m_data.GetU8(&offset));
491            break;
492        case DW_OP_nop: s->PutCString("nop"); break;                                    // 0x96
493        case DW_OP_push_object_address: s->PutCString("push_object_address"); break;    // 0x97 DWARF3
494        case DW_OP_call2:                                                   // 0x98 DWARF3 1 2-byte offset of DIE
495            s->Printf("call2(0x%4.4x)", m_data.GetU16(&offset));
496            break;
497        case DW_OP_call4:                                                   // 0x99 DWARF3 1 4-byte offset of DIE
498            s->Printf("call4(0x%8.8x)", m_data.GetU32(&offset));
499            break;
500        case DW_OP_call_ref:                                                // 0x9a DWARF3 1 4- or 8-byte offset of DIE
501            s->Printf("call_ref(0x%8.8llx)", m_data.GetAddress(&offset));
502            break;
503//      case DW_OP_form_tls_address: s << "form_tls_address"; break;        // 0x9b DWARF3
504//      case DW_OP_call_frame_cfa: s << "call_frame_cfa"; break;            // 0x9c DWARF3
505//      case DW_OP_bit_piece:                                               // 0x9d DWARF3 2
506//          s->Printf("bit_piece(0x%x, 0x%x)", m_data.GetULEB128(&offset), m_data.GetULEB128(&offset));
507//          break;
508//      case DW_OP_lo_user:     s->PutCString("lo_user"); break;                        // 0xe0
509//      case DW_OP_hi_user:     s->PutCString("hi_user"); break;                        // 0xff
510        case DW_OP_APPLE_extern:
511            s->Printf("extern(%u)", m_data.GetULEB128(&offset));
512            break;
513        case DW_OP_APPLE_array_ref:
514            s->PutCString("array_ref");
515            break;
516        case DW_OP_APPLE_uninit:
517            s->PutCString("uninit");  // 0xF0
518            break;
519        case DW_OP_APPLE_assign:        // 0xF1 - pops value off and assigns it to second item on stack (2nd item must have assignable context)
520            s->PutCString("assign");
521            break;
522        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)
523            s->PutCString("address_of");
524            break;
525        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)
526            s->PutCString("value_of");
527            break;
528        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)
529            s->PutCString("deref_type");
530            break;
531        case DW_OP_APPLE_expr_local:    // 0xF5 - ULEB128 expression local index
532            s->Printf("expr_local(%u)", m_data.GetULEB128(&offset));
533            break;
534        case DW_OP_APPLE_constf:        // 0xF6 - 1 byte float size, followed by constant float data
535            {
536                uint8_t float_length = m_data.GetU8(&offset);
537                s->Printf("constf(<%u> ", float_length);
538                m_data.Dump(s, offset, eFormatHex, float_length, 1, UINT32_MAX, DW_INVALID_ADDRESS, 0, 0);
539                s->PutChar(')');
540                // Consume the float data
541                m_data.GetData(&offset, float_length);
542            }
543            break;
544        case DW_OP_APPLE_scalar_cast:
545            s->Printf("scalar_cast(%s)", Scalar::GetValueTypeAsCString ((Scalar::Type)m_data.GetU8(&offset)));
546            break;
547        case DW_OP_APPLE_clang_cast:
548            {
549                clang::Type *clang_type = (clang::Type *)m_data.GetMaxU64(&offset, sizeof(void*));
550                s->Printf("clang_cast(%p)", clang_type);
551            }
552            break;
553        case DW_OP_APPLE_clear:
554            s->PutCString("clear");
555            break;
556        case DW_OP_APPLE_error:         // 0xFF - Stops expression evaluation and returns an error (no args)
557            s->PutCString("error");
558            break;
559        }
560    }
561}
562
563void
564DWARFExpression::SetLocationListBaseAddress(Address& base_addr)
565{
566    m_loclist_base_addr = base_addr;
567}
568
569int
570DWARFExpression::GetRegisterKind ()
571{
572    return m_reg_kind;
573}
574
575void
576DWARFExpression::SetRegisterKind (int reg_kind)
577{
578    m_reg_kind = reg_kind;
579}
580
581bool
582DWARFExpression::IsLocationList() const
583{
584    return m_loclist_base_addr.IsSectionOffset();
585}
586
587void
588DWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level) const
589{
590    if (IsLocationList())
591    {
592        // We have a location list
593        uint32_t offset = 0;
594        uint32_t count = 0;
595        Address base_addr(m_loclist_base_addr);
596        while (m_data.ValidOffset(offset))
597        {
598            lldb::addr_t begin_addr_offset = m_data.GetAddress(&offset);
599            lldb::addr_t end_addr_offset = m_data.GetAddress(&offset);
600            if (begin_addr_offset < end_addr_offset)
601            {
602                if (count > 0)
603                    s->PutCString(", ");
604                AddressRange addr_range(base_addr, end_addr_offset - begin_addr_offset);
605                addr_range.GetBaseAddress().SetOffset(base_addr.GetOffset() + begin_addr_offset);
606                addr_range.Dump (s, NULL, Address::DumpStyleFileAddress);
607                s->PutChar('{');
608                uint32_t location_length = m_data.GetU16(&offset);
609                DumpLocation (s, offset, location_length, level);
610                s->PutChar('}');
611                offset += location_length;
612            }
613            else if (begin_addr_offset == 0 && end_addr_offset == 0)
614            {
615                // The end of the location list is marked by both the start and end offset being zero
616                break;
617            }
618            else
619            {
620                if (m_data.GetAddressByteSize() == 4 && begin_addr_offset == 0xFFFFFFFFull ||
621                    m_data.GetAddressByteSize() == 8 && begin_addr_offset == 0xFFFFFFFFFFFFFFFFull)
622                {
623                    // We have a new base address
624                    if (count > 0)
625                        s->PutCString(", ");
626                    *s << "base_addr = " << end_addr_offset;
627                }
628            }
629
630            count++;
631        }
632    }
633    else
634    {
635        // We have a normal location that contains DW_OP location opcodes
636        DumpLocation (s, 0, m_data.GetByteSize(), level);
637    }
638}
639
640static bool
641ReadRegisterValueAsScalar
642(
643    ExecutionContext *exe_ctx,
644    uint32_t reg_kind,
645    uint32_t reg_num,
646    Error *error_ptr,
647    Value &value
648)
649{
650    if (exe_ctx && exe_ctx->frame)
651    {
652        RegisterContext *reg_context = exe_ctx->frame->GetRegisterContext();
653
654        if (reg_context == NULL)
655        {
656            if (error_ptr)
657                error_ptr->SetErrorStringWithFormat("No register context in frame.\n");
658        }
659        else
660        {
661            uint32_t native_reg = reg_context->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
662            if (native_reg == LLDB_INVALID_REGNUM)
663            {
664                if (error_ptr)
665                    error_ptr->SetErrorStringWithFormat("Unable to convert register kind=%u reg_num=%u to a native register number.\n", reg_kind, reg_num);
666            }
667            else
668            {
669                value.SetValueType (Value::eValueTypeScalar);
670                value.SetContext (Value::eContextTypeDCRegisterInfo, const_cast<RegisterInfo *>(reg_context->GetRegisterInfoAtIndex(native_reg)));
671
672                if (reg_context->ReadRegisterValue (native_reg, value.GetScalar()))
673                    return true;
674
675                if (error_ptr)
676                    error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg);
677            }
678        }
679    }
680    else
681    {
682        if (error_ptr)
683            error_ptr->SetErrorStringWithFormat("Invalid frame in execution context.\n");
684    }
685    return false;
686}
687
688bool
689DWARFExpression::LocationListContainsLoadAddress (Process* process, const Address &addr) const
690{
691    if (IsLocationList())
692    {
693        uint32_t offset = 0;
694        const addr_t load_addr = addr.GetLoadAddress(process);
695
696        if (load_addr == LLDB_INVALID_ADDRESS)
697            return false;
698
699        addr_t loc_list_base_addr = m_loclist_base_addr.GetLoadAddress(process);
700
701        if (loc_list_base_addr == LLDB_INVALID_ADDRESS)
702            return false;
703
704        while (m_data.ValidOffset(offset))
705        {
706            // We need to figure out what the value is for the location.
707            addr_t lo_pc = m_data.GetAddress(&offset);
708            addr_t hi_pc = m_data.GetAddress(&offset);
709            if (lo_pc == 0 && hi_pc == 0)
710                break;
711            else
712            {
713                lo_pc += loc_list_base_addr;
714                hi_pc += loc_list_base_addr;
715
716                if (lo_pc <= load_addr && load_addr < hi_pc)
717                    return true;
718
719                offset += m_data.GetU16(&offset);
720            }
721        }
722    }
723    return false;
724}
725bool
726DWARFExpression::Evaluate
727(
728    ExecutionContextScope *exe_scope,
729    clang::ASTContext *ast_context,
730    const Value* initial_value_ptr,
731    Value& result,
732    Error *error_ptr
733) const
734{
735    ExecutionContext exe_ctx (exe_scope);
736    return Evaluate(&exe_ctx, ast_context, initial_value_ptr, result, error_ptr);
737}
738
739bool
740DWARFExpression::Evaluate
741(
742    ExecutionContext *exe_ctx,
743    clang::ASTContext *ast_context,
744    const Value* initial_value_ptr,
745    Value& result,
746    Error *error_ptr
747) const
748{
749    if (IsLocationList())
750    {
751        uint32_t offset = 0;
752        addr_t pc = exe_ctx->frame->GetPC().GetLoadAddress(exe_ctx->process);
753
754        if (pc == LLDB_INVALID_ADDRESS)
755        {
756            if (error_ptr)
757                error_ptr->SetErrorString("Invalid PC in frame.");
758            return false;
759        }
760
761        addr_t loc_list_base_addr = m_loclist_base_addr.GetLoadAddress(exe_ctx->process);
762
763        if (loc_list_base_addr == LLDB_INVALID_ADDRESS)
764        {
765            if (error_ptr)
766                error_ptr->SetErrorString("Out of scope.");
767            return false;
768        }
769
770        while (m_data.ValidOffset(offset))
771        {
772            // We need to figure out what the value is for the location.
773            addr_t lo_pc = m_data.GetAddress(&offset);
774            addr_t hi_pc = m_data.GetAddress(&offset);
775            if (lo_pc == 0 && hi_pc == 0)
776            {
777                break;
778            }
779            else
780            {
781                lo_pc += loc_list_base_addr;
782                hi_pc += loc_list_base_addr;
783
784                uint16_t length = m_data.GetU16(&offset);
785
786                if (length > 0 && lo_pc <= pc && pc < hi_pc)
787                {
788                    return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr);
789                }
790                offset += length;
791            }
792        }
793        if (error_ptr)
794            error_ptr->SetErrorStringWithFormat("Out of scope.\n", pc);
795        return false;
796    }
797
798    // Not a location list, just a single expression.
799    return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr);
800}
801
802
803
804bool
805DWARFExpression::Evaluate
806(
807    ExecutionContext *exe_ctx,
808    clang::ASTContext *ast_context,
809    const DataExtractor& opcodes,
810    ClangExpressionVariableList *expr_locals,
811    ClangExpressionDeclMap *decl_map,
812    const uint32_t opcodes_offset,
813    const uint32_t opcodes_length,
814    const uint32_t reg_kind,
815    const Value* initial_value_ptr,
816    Value& result,
817    Error *error_ptr
818)
819{
820    std::vector<Value> stack;
821
822    if (initial_value_ptr)
823        stack.push_back(*initial_value_ptr);
824
825    uint32_t offset = opcodes_offset;
826    const uint32_t end_offset = opcodes_offset + opcodes_length;
827    Value tmp;
828    uint32_t reg_num;
829
830    // Make sure all of the data is available in opcodes.
831    if (!opcodes.ValidOffsetForDataOfSize(opcodes_offset, opcodes_length))
832    {
833        if (error_ptr)
834            error_ptr->SetErrorString ("Invalid offset and/or length for opcodes buffer.");
835        return false;
836    }
837    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
838
839
840    while (opcodes.ValidOffset(offset) && offset < end_offset)
841    {
842        const uint32_t op_offset = offset;
843        const uint8_t op = opcodes.GetU8(&offset);
844
845        if (log)
846        {
847            size_t count = stack.size();
848            log->Printf("Stack before operation has %d values:", count);
849            for (size_t i=0; i<count; ++i)
850            {
851                StreamString new_value;
852                new_value.Printf("[%zu]", i);
853                stack[i].Dump(&new_value);
854                log->Printf("  %s", new_value.GetData());
855            }
856            log->Printf("0x%8.8x: %s", op_offset, DW_OP_value_to_name(op));
857        }
858        switch (op)
859        {
860        //----------------------------------------------------------------------
861        // The DW_OP_addr operation has a single operand that encodes a machine
862        // address and whose size is the size of an address on the target machine.
863        //----------------------------------------------------------------------
864        case DW_OP_addr:
865            stack.push_back(opcodes.GetAddress(&offset));
866            stack.back().SetValueType (Value::eValueTypeFileAddress);
867            break;
868
869        //----------------------------------------------------------------------
870        // The DW_OP_addr_sect_offset4 is used for any location expressions in
871        // shared libraries that have a location like:
872        //  DW_OP_addr(0x1000)
873        // If this address resides in a shared library, then this virtual
874        // address won't make sense when it is evaluated in the context of a
875        // running process where shared libraries have been slid. To account for
876        // this, this new address type where we can store the section pointer
877        // and a 4 byte offset.
878        //----------------------------------------------------------------------
879//      case DW_OP_addr_sect_offset4:
880//          {
881//              result_type = eResultTypeFileAddress;
882//              lldb::Section *sect = (lldb::Section *)opcodes.GetMaxU64(&offset, sizeof(void *));
883//              lldb::addr_t sect_offset = opcodes.GetU32(&offset);
884//
885//              Address so_addr (sect, sect_offset);
886//              lldb::addr_t load_addr = so_addr.GetLoadAddress();
887//              if (load_addr != LLDB_INVALID_ADDRESS)
888//              {
889//                  // We successfully resolve a file address to a load
890//                  // address.
891//                  stack.push_back(load_addr);
892//                  break;
893//              }
894//              else
895//              {
896//                  // We were able
897//                  if (error_ptr)
898//                      error_ptr->SetErrorStringWithFormat ("Section %s in %s is not currently loaded.\n", sect->GetName().AsCString(), sect->GetModule()->GetFileSpec().GetFilename().AsCString());
899//                  return false;
900//              }
901//          }
902//          break;
903
904        //----------------------------------------------------------------------
905        // OPCODE: DW_OP_deref
906        // OPERANDS: none
907        // DESCRIPTION: Pops the top stack entry and treats it as an address.
908        // The value retrieved from that address is pushed. The size of the
909        // data retrieved from the dereferenced address is the size of an
910        // address on the target machine.
911        //----------------------------------------------------------------------
912        case DW_OP_deref:
913            {
914                Value::ValueType value_type = stack.back().GetValueType();
915                switch (value_type)
916                {
917                case Value::eValueTypeHostAddress:
918                    {
919                        void *src = (void *)stack.back().GetScalar().ULongLong();
920                        intptr_t ptr;
921                        ::memcpy (&ptr, src, sizeof(void *));
922                        stack.back().GetScalar() = ptr;
923                        stack.back().ClearContext();
924                    }
925                    break;
926                case Value::eValueTypeLoadAddress:
927                    if (exe_ctx)
928                    {
929                        if (exe_ctx->process)
930                        {
931                            lldb::addr_t pointer_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
932                            uint8_t addr_bytes[sizeof(lldb::addr_t)];
933                            uint32_t addr_size = exe_ctx->process->GetAddressByteSize();
934                            Error error;
935                            if (exe_ctx->process->ReadMemory(pointer_addr, &addr_bytes, addr_size, error) == addr_size)
936                            {
937                                DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), exe_ctx->process->GetByteOrder(), addr_size);
938                                uint32_t addr_data_offset = 0;
939                                stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset);
940                                stack.back().ClearContext();
941                            }
942                            else
943                            {
944                                if (error_ptr)
945                                    error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%llx for DW_OP_deref: %s\n",
946                                                                         pointer_addr,
947                                                                         error.AsCString());
948                                return false;
949                            }
950                        }
951                        else
952                        {
953                            if (error_ptr)
954                                error_ptr->SetErrorStringWithFormat ("NULL process for DW_OP_deref.\n");
955                            return false;
956                        }
957                    }
958                    else
959                    {
960                        if (error_ptr)
961                            error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_deref.\n");
962                        return false;
963                    }
964                    break;
965
966                default:
967                    break;
968                }
969
970            }
971            break;
972
973        //----------------------------------------------------------------------
974        // OPCODE: DW_OP_deref_size
975        // OPERANDS: 1
976        //  1 - uint8_t that specifies the size of the data to dereference.
977        // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top
978        // stack entry and treats it as an address. The value retrieved from that
979        // address is pushed. In the DW_OP_deref_size operation, however, the
980        // size in bytes of the data retrieved from the dereferenced address is
981        // specified by the single operand. This operand is a 1-byte unsigned
982        // integral constant whose value may not be larger than the size of an
983        // address on the target machine. The data retrieved is zero extended
984        // to the size of an address on the target machine before being pushed
985        // on the expression stack.
986        //----------------------------------------------------------------------
987        case DW_OP_deref_size:
988            if (error_ptr)
989                error_ptr->SetErrorString("Unimplemented opcode: DW_OP_deref_size.");
990            return false;
991
992        //----------------------------------------------------------------------
993        // OPCODE: DW_OP_xderef_size
994        // OPERANDS: 1
995        //  1 - uint8_t that specifies the size of the data to dereference.
996        // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at
997        // the top of the stack is treated as an address. The second stack
998        // entry is treated as an “address space identifier” for those
999        // architectures that support multiple address spaces. The top two
1000        // stack elements are popped, a data item is retrieved through an
1001        // implementation-defined address calculation and pushed as the new
1002        // stack top. In the DW_OP_xderef_size operation, however, the size in
1003        // bytes of the data retrieved from the dereferenced address is
1004        // specified by the single operand. This operand is a 1-byte unsigned
1005        // integral constant whose value may not be larger than the size of an
1006        // address on the target machine. The data retrieved is zero extended
1007        // to the size of an address on the target machine before being pushed
1008        // on the expression stack.
1009        //----------------------------------------------------------------------
1010        case DW_OP_xderef_size:
1011            if (error_ptr)
1012                error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef_size.");
1013            return false;
1014        //----------------------------------------------------------------------
1015        // OPCODE: DW_OP_xderef
1016        // OPERANDS: none
1017        // DESCRIPTION: Provides an extended dereference mechanism. The entry at
1018        // the top of the stack is treated as an address. The second stack entry
1019        // is treated as an "address space identifier" for those architectures
1020        // that support multiple address spaces. The top two stack elements are
1021        // popped, a data item is retrieved through an implementation-defined
1022        // address calculation and pushed as the new stack top. The size of the
1023        // data retrieved from the dereferenced address is the size of an address
1024        // on the target machine.
1025        //----------------------------------------------------------------------
1026        case DW_OP_xderef:
1027            if (error_ptr)
1028                error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef.");
1029            return false;
1030
1031        //----------------------------------------------------------------------
1032        // All DW_OP_constXXX opcodes have a single operand as noted below:
1033        //
1034        // Opcode           Operand 1
1035        // ---------------  ----------------------------------------------------
1036        // DW_OP_const1u    1-byte unsigned integer constant
1037        // DW_OP_const1s    1-byte signed integer constant
1038        // DW_OP_const2u    2-byte unsigned integer constant
1039        // DW_OP_const2s    2-byte signed integer constant
1040        // DW_OP_const4u    4-byte unsigned integer constant
1041        // DW_OP_const4s    4-byte signed integer constant
1042        // DW_OP_const8u    8-byte unsigned integer constant
1043        // DW_OP_const8s    8-byte signed integer constant
1044        // DW_OP_constu     unsigned LEB128 integer constant
1045        // DW_OP_consts     signed LEB128 integer constant
1046        //----------------------------------------------------------------------
1047        case DW_OP_const1u             :    stack.push_back(( uint8_t)opcodes.GetU8(&offset)); break;
1048        case DW_OP_const1s             :    stack.push_back((  int8_t)opcodes.GetU8(&offset)); break;
1049        case DW_OP_const2u             :    stack.push_back((uint16_t)opcodes.GetU16(&offset)); break;
1050        case DW_OP_const2s             :    stack.push_back(( int16_t)opcodes.GetU16(&offset)); break;
1051        case DW_OP_const4u             :    stack.push_back((uint32_t)opcodes.GetU32(&offset)); break;
1052        case DW_OP_const4s             :    stack.push_back(( int32_t)opcodes.GetU32(&offset)); break;
1053        case DW_OP_const8u             :    stack.push_back((uint64_t)opcodes.GetU64(&offset)); break;
1054        case DW_OP_const8s             :    stack.push_back(( int64_t)opcodes.GetU64(&offset)); break;
1055        case DW_OP_constu              :    stack.push_back(opcodes.GetULEB128(&offset)); break;
1056        case DW_OP_consts              :    stack.push_back(opcodes.GetSLEB128(&offset)); break;
1057
1058        //----------------------------------------------------------------------
1059        // OPCODE: DW_OP_dup
1060        // OPERANDS: none
1061        // DESCRIPTION: duplicates the value at the top of the stack
1062        //----------------------------------------------------------------------
1063        case DW_OP_dup:
1064            if (stack.empty())
1065            {
1066                if (error_ptr)
1067                    error_ptr->SetErrorString("Expression stack empty for DW_OP_dup.");
1068                return false;
1069            }
1070            else
1071                stack.push_back(stack.back());
1072            break;
1073
1074        //----------------------------------------------------------------------
1075        // OPCODE: DW_OP_drop
1076        // OPERANDS: none
1077        // DESCRIPTION: pops the value at the top of the stack
1078        //----------------------------------------------------------------------
1079        case DW_OP_drop:
1080            if (stack.empty())
1081            {
1082                if (error_ptr)
1083                    error_ptr->SetErrorString("Expression stack empty for DW_OP_drop.");
1084                return false;
1085            }
1086            else
1087                stack.pop_back();
1088            break;
1089
1090        //----------------------------------------------------------------------
1091        // OPCODE: DW_OP_over
1092        // OPERANDS: none
1093        // DESCRIPTION: Duplicates the entry currently second in the stack at
1094        // the top of the stack.
1095        //----------------------------------------------------------------------
1096        case DW_OP_over:
1097            if (stack.size() < 2)
1098            {
1099                if (error_ptr)
1100                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_over.");
1101                return false;
1102            }
1103            else
1104                stack.push_back(stack[stack.size() - 2]);
1105            break;
1106
1107
1108        //----------------------------------------------------------------------
1109        // OPCODE: DW_OP_pick
1110        // OPERANDS: uint8_t index into the current stack
1111        // DESCRIPTION: The stack entry with the specified index (0 through 255,
1112        // inclusive) is pushed on the stack
1113        //----------------------------------------------------------------------
1114        case DW_OP_pick:
1115            {
1116                uint8_t pick_idx = opcodes.GetU8(&offset);
1117                if (pick_idx < stack.size())
1118                    stack.push_back(stack[pick_idx]);
1119                else
1120                {
1121                    if (error_ptr)
1122                        error_ptr->SetErrorStringWithFormat("Index %u out of range for DW_OP_pick.\n", pick_idx);
1123                    return false;
1124                }
1125            }
1126            break;
1127
1128        //----------------------------------------------------------------------
1129        // OPCODE: DW_OP_swap
1130        // OPERANDS: none
1131        // DESCRIPTION: swaps the top two stack entries. The entry at the top
1132        // of the stack becomes the second stack entry, and the second entry
1133        // becomes the top of the stack
1134        //----------------------------------------------------------------------
1135        case DW_OP_swap:
1136            if (stack.size() < 2)
1137            {
1138                if (error_ptr)
1139                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_swap.");
1140                return false;
1141            }
1142            else
1143            {
1144                tmp = stack.back();
1145                stack.back() = stack[stack.size() - 2];
1146                stack[stack.size() - 2] = tmp;
1147            }
1148            break;
1149
1150        //----------------------------------------------------------------------
1151        // OPCODE: DW_OP_rot
1152        // OPERANDS: none
1153        // DESCRIPTION: Rotates the first three stack entries. The entry at
1154        // the top of the stack becomes the third stack entry, the second
1155        // entry becomes the top of the stack, and the third entry becomes
1156        // the second entry.
1157        //----------------------------------------------------------------------
1158        case DW_OP_rot:
1159            if (stack.size() < 3)
1160            {
1161                if (error_ptr)
1162                    error_ptr->SetErrorString("Expression stack needs at least 3 items for DW_OP_rot.");
1163                return false;
1164            }
1165            else
1166            {
1167                size_t last_idx = stack.size() - 1;
1168                Value old_top = stack[last_idx];
1169                stack[last_idx] = stack[last_idx - 1];
1170                stack[last_idx - 1] = stack[last_idx - 2];
1171                stack[last_idx - 2] = old_top;
1172            }
1173            break;
1174
1175        //----------------------------------------------------------------------
1176        // OPCODE: DW_OP_abs
1177        // OPERANDS: none
1178        // DESCRIPTION: pops the top stack entry, interprets it as a signed
1179        // value and pushes its absolute value. If the absolute value can not be
1180        // represented, the result is undefined.
1181        //----------------------------------------------------------------------
1182        case DW_OP_abs:
1183            if (stack.empty())
1184            {
1185                if (error_ptr)
1186                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_abs.");
1187                return false;
1188            }
1189            else if (stack.back().ResolveValue(exe_ctx, ast_context).AbsoluteValue() == false)
1190            {
1191                if (error_ptr)
1192                    error_ptr->SetErrorString("Failed to take the absolute value of the first stack item.");
1193                return false;
1194            }
1195            break;
1196
1197        //----------------------------------------------------------------------
1198        // OPCODE: DW_OP_and
1199        // OPERANDS: none
1200        // DESCRIPTION: pops the top two stack values, performs a bitwise and
1201        // operation on the two, and pushes the result.
1202        //----------------------------------------------------------------------
1203        case DW_OP_and:
1204            if (stack.size() < 2)
1205            {
1206                if (error_ptr)
1207                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_and.");
1208                return false;
1209            }
1210            else
1211            {
1212                tmp = stack.back();
1213                stack.pop_back();
1214                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) & tmp.ResolveValue(exe_ctx, ast_context);
1215            }
1216            break;
1217
1218        //----------------------------------------------------------------------
1219        // OPCODE: DW_OP_div
1220        // OPERANDS: none
1221        // DESCRIPTION: pops the top two stack values, divides the former second
1222        // entry by the former top of the stack using signed division, and
1223        // pushes the result.
1224        //----------------------------------------------------------------------
1225        case DW_OP_div:
1226            if (stack.size() < 2)
1227            {
1228                if (error_ptr)
1229                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_div.");
1230                return false;
1231            }
1232            else
1233            {
1234                tmp = stack.back();
1235                if (tmp.ResolveValue(exe_ctx, ast_context).IsZero())
1236                {
1237                    if (error_ptr)
1238                        error_ptr->SetErrorString("Divide by zero.");
1239                    return false;
1240                }
1241                else
1242                {
1243                    stack.pop_back();
1244                    stack.back() = stack.back().ResolveValue(exe_ctx, ast_context) / tmp.ResolveValue(exe_ctx, ast_context);
1245                    if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid())
1246                    {
1247                        if (error_ptr)
1248                            error_ptr->SetErrorString("Divide failed.");
1249                        return false;
1250                    }
1251                }
1252            }
1253            break;
1254
1255        //----------------------------------------------------------------------
1256        // OPCODE: DW_OP_minus
1257        // OPERANDS: none
1258        // DESCRIPTION: pops the top two stack values, subtracts the former top
1259        // of the stack from the former second entry, and pushes the result.
1260        //----------------------------------------------------------------------
1261        case DW_OP_minus:
1262            if (stack.size() < 2)
1263            {
1264                if (error_ptr)
1265                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_minus.");
1266                return false;
1267            }
1268            else
1269            {
1270                tmp = stack.back();
1271                stack.pop_back();
1272                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) - tmp.ResolveValue(exe_ctx, ast_context);
1273            }
1274            break;
1275
1276        //----------------------------------------------------------------------
1277        // OPCODE: DW_OP_mod
1278        // OPERANDS: none
1279        // DESCRIPTION: pops the top two stack values and pushes the result of
1280        // the calculation: former second stack entry modulo the former top of
1281        // the stack.
1282        //----------------------------------------------------------------------
1283        case DW_OP_mod:
1284            if (stack.size() < 2)
1285            {
1286                if (error_ptr)
1287                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_mod.");
1288                return false;
1289            }
1290            else
1291            {
1292                tmp = stack.back();
1293                stack.pop_back();
1294                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) % tmp.ResolveValue(exe_ctx, ast_context);
1295            }
1296            break;
1297
1298
1299        //----------------------------------------------------------------------
1300        // OPCODE: DW_OP_mul
1301        // OPERANDS: none
1302        // DESCRIPTION: pops the top two stack entries, multiplies them
1303        // together, and pushes the result.
1304        //----------------------------------------------------------------------
1305        case DW_OP_mul:
1306            if (stack.size() < 2)
1307            {
1308                if (error_ptr)
1309                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_mul.");
1310                return false;
1311            }
1312            else
1313            {
1314                tmp = stack.back();
1315                stack.pop_back();
1316                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) * tmp.ResolveValue(exe_ctx, ast_context);
1317            }
1318            break;
1319
1320        //----------------------------------------------------------------------
1321        // OPCODE: DW_OP_neg
1322        // OPERANDS: none
1323        // DESCRIPTION: pops the top stack entry, and pushes its negation.
1324        //----------------------------------------------------------------------
1325        case DW_OP_neg:
1326            if (stack.empty())
1327            {
1328                if (error_ptr)
1329                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_neg.");
1330                return false;
1331            }
1332            else
1333            {
1334                if (stack.back().ResolveValue(exe_ctx, ast_context).UnaryNegate() == false)
1335                {
1336                    if (error_ptr)
1337                        error_ptr->SetErrorString("Unary negate failed.");
1338                    return false;
1339                }
1340            }
1341            break;
1342
1343        //----------------------------------------------------------------------
1344        // OPCODE: DW_OP_not
1345        // OPERANDS: none
1346        // DESCRIPTION: pops the top stack entry, and pushes its bitwise
1347        // complement
1348        //----------------------------------------------------------------------
1349        case DW_OP_not:
1350            if (stack.empty())
1351            {
1352                if (error_ptr)
1353                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_not.");
1354                return false;
1355            }
1356            else
1357            {
1358                if (stack.back().ResolveValue(exe_ctx, ast_context).OnesComplement() == false)
1359                {
1360                    if (error_ptr)
1361                        error_ptr->SetErrorString("Logical NOT failed.");
1362                    return false;
1363                }
1364            }
1365            break;
1366
1367        //----------------------------------------------------------------------
1368        // OPCODE: DW_OP_or
1369        // OPERANDS: none
1370        // DESCRIPTION: pops the top two stack entries, performs a bitwise or
1371        // operation on the two, and pushes the result.
1372        //----------------------------------------------------------------------
1373        case DW_OP_or:
1374            if (stack.size() < 2)
1375            {
1376                if (error_ptr)
1377                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_or.");
1378                return false;
1379            }
1380            else
1381            {
1382                tmp = stack.back();
1383                stack.pop_back();
1384                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) | tmp.ResolveValue(exe_ctx, ast_context);
1385            }
1386            break;
1387
1388        //----------------------------------------------------------------------
1389        // OPCODE: DW_OP_plus
1390        // OPERANDS: none
1391        // DESCRIPTION: pops the top two stack entries, adds them together, and
1392        // pushes the result.
1393        //----------------------------------------------------------------------
1394        case DW_OP_plus:
1395            if (stack.size() < 2)
1396            {
1397                if (error_ptr)
1398                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_plus.");
1399                return false;
1400            }
1401            else
1402            {
1403                tmp = stack.back();
1404                stack.pop_back();
1405                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) + tmp.ResolveValue(exe_ctx, ast_context);
1406            }
1407            break;
1408
1409        //----------------------------------------------------------------------
1410        // OPCODE: DW_OP_plus_uconst
1411        // OPERANDS: none
1412        // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
1413        // constant operand and pushes the result.
1414        //----------------------------------------------------------------------
1415        case DW_OP_plus_uconst:
1416            if (stack.empty())
1417            {
1418                if (error_ptr)
1419                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_plus_uconst.");
1420                return false;
1421            }
1422            else
1423            {
1424                uint32_t uconst_value = opcodes.GetULEB128(&offset);
1425                // Implicit conversion from a UINT to a Scalar...
1426                stack.back().ResolveValue(exe_ctx, ast_context) += uconst_value;
1427                if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid())
1428                {
1429                    if (error_ptr)
1430                        error_ptr->SetErrorString("DW_OP_plus_uconst failed.");
1431                    return false;
1432                }
1433            }
1434            break;
1435
1436        //----------------------------------------------------------------------
1437        // OPCODE: DW_OP_shl
1438        // OPERANDS: none
1439        // DESCRIPTION:  pops the top two stack entries, shifts the former
1440        // second entry left by the number of bits specified by the former top
1441        // of the stack, and pushes the result.
1442        //----------------------------------------------------------------------
1443        case DW_OP_shl:
1444            if (stack.size() < 2)
1445            {
1446                if (error_ptr)
1447                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shl.");
1448                return false;
1449            }
1450            else
1451            {
1452                tmp = stack.back();
1453                stack.pop_back();
1454                stack.back().ResolveValue(exe_ctx, ast_context) <<= tmp.ResolveValue(exe_ctx, ast_context);
1455            }
1456            break;
1457
1458        //----------------------------------------------------------------------
1459        // OPCODE: DW_OP_shr
1460        // OPERANDS: none
1461        // DESCRIPTION: pops the top two stack entries, shifts the former second
1462        // entry right logically (filling with zero bits) by the number of bits
1463        // specified by the former top of the stack, and pushes the result.
1464        //----------------------------------------------------------------------
1465        case DW_OP_shr:
1466            if (stack.size() < 2)
1467            {
1468                if (error_ptr)
1469                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shr.");
1470                return false;
1471            }
1472            else
1473            {
1474                tmp = stack.back();
1475                stack.pop_back();
1476                if (stack.back().ResolveValue(exe_ctx, ast_context).ShiftRightLogical(tmp.ResolveValue(exe_ctx, ast_context)) == false)
1477                {
1478                    if (error_ptr)
1479                        error_ptr->SetErrorString("DW_OP_shr failed.");
1480                    return false;
1481                }
1482            }
1483            break;
1484
1485        //----------------------------------------------------------------------
1486        // OPCODE: DW_OP_shra
1487        // OPERANDS: none
1488        // DESCRIPTION: pops the top two stack entries, shifts the former second
1489        // entry right arithmetically (divide the magnitude by 2, keep the same
1490        // sign for the result) by the number of bits specified by the former
1491        // top of the stack, and pushes the result.
1492        //----------------------------------------------------------------------
1493        case DW_OP_shra:
1494            if (stack.size() < 2)
1495            {
1496                if (error_ptr)
1497                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shra.");
1498                return false;
1499            }
1500            else
1501            {
1502                tmp = stack.back();
1503                stack.pop_back();
1504                stack.back().ResolveValue(exe_ctx, ast_context) >>= tmp.ResolveValue(exe_ctx, ast_context);
1505            }
1506            break;
1507
1508        //----------------------------------------------------------------------
1509        // OPCODE: DW_OP_xor
1510        // OPERANDS: none
1511        // DESCRIPTION: pops the top two stack entries, performs the bitwise
1512        // exclusive-or operation on the two, and pushes the result.
1513        //----------------------------------------------------------------------
1514        case DW_OP_xor:
1515            if (stack.size() < 2)
1516            {
1517                if (error_ptr)
1518                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_xor.");
1519                return false;
1520            }
1521            else
1522            {
1523                tmp = stack.back();
1524                stack.pop_back();
1525                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) ^ tmp.ResolveValue(exe_ctx, ast_context);
1526            }
1527            break;
1528
1529
1530        //----------------------------------------------------------------------
1531        // OPCODE: DW_OP_skip
1532        // OPERANDS: int16_t
1533        // DESCRIPTION:  An unconditional branch. Its single operand is a 2-byte
1534        // signed integer constant. The 2-byte constant is the number of bytes
1535        // of the DWARF expression to skip forward or backward from the current
1536        // operation, beginning after the 2-byte constant.
1537        //----------------------------------------------------------------------
1538        case DW_OP_skip:
1539            {
1540                int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
1541                uint32_t new_offset = offset + skip_offset;
1542                if (new_offset >= opcodes_offset && new_offset < end_offset)
1543                    offset = new_offset;
1544                else
1545                {
1546                    if (error_ptr)
1547                        error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip.");
1548                    return false;
1549                }
1550            }
1551            break;
1552
1553        //----------------------------------------------------------------------
1554        // OPCODE: DW_OP_bra
1555        // OPERANDS: int16_t
1556        // DESCRIPTION: A conditional branch. Its single operand is a 2-byte
1557        // signed integer constant. This operation pops the top of stack. If
1558        // the value popped is not the constant 0, the 2-byte constant operand
1559        // is the number of bytes of the DWARF expression to skip forward or
1560        // backward from the current operation, beginning after the 2-byte
1561        // constant.
1562        //----------------------------------------------------------------------
1563        case DW_OP_bra:
1564            {
1565                tmp = stack.back();
1566                stack.pop_back();
1567                int16_t bra_offset = (int16_t)opcodes.GetU16(&offset);
1568                Scalar zero(0);
1569                if (tmp.ResolveValue(exe_ctx, ast_context) != zero)
1570                {
1571                    uint32_t new_offset = offset + bra_offset;
1572                    if (new_offset >= opcodes_offset && new_offset < end_offset)
1573                        offset = new_offset;
1574                    else
1575                    {
1576                        if (error_ptr)
1577                            error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra.");
1578                        return false;
1579                    }
1580                }
1581            }
1582            break;
1583
1584        //----------------------------------------------------------------------
1585        // OPCODE: DW_OP_eq
1586        // OPERANDS: none
1587        // DESCRIPTION: pops the top two stack values, compares using the
1588        // equals (==) operator.
1589        // STACK RESULT: push the constant value 1 onto the stack if the result
1590        // of the operation is true or the constant value 0 if the result of the
1591        // operation is false.
1592        //----------------------------------------------------------------------
1593        case DW_OP_eq:
1594            if (stack.size() < 2)
1595            {
1596                if (error_ptr)
1597                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_eq.");
1598                return false;
1599            }
1600            else
1601            {
1602                tmp = stack.back();
1603                stack.pop_back();
1604                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) == tmp.ResolveValue(exe_ctx, ast_context);
1605            }
1606            break;
1607
1608        //----------------------------------------------------------------------
1609        // OPCODE: DW_OP_ge
1610        // OPERANDS: none
1611        // DESCRIPTION: pops the top two stack values, compares using the
1612        // greater than or equal to (>=) operator.
1613        // STACK RESULT: push the constant value 1 onto the stack if the result
1614        // of the operation is true or the constant value 0 if the result of the
1615        // operation is false.
1616        //----------------------------------------------------------------------
1617        case DW_OP_ge:
1618            if (stack.size() < 2)
1619            {
1620                if (error_ptr)
1621                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_ge.");
1622                return false;
1623            }
1624            else
1625            {
1626                tmp = stack.back();
1627                stack.pop_back();
1628                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) >= tmp.ResolveValue(exe_ctx, ast_context);
1629            }
1630            break;
1631
1632        //----------------------------------------------------------------------
1633        // OPCODE: DW_OP_gt
1634        // OPERANDS: none
1635        // DESCRIPTION: pops the top two stack values, compares using the
1636        // greater than (>) operator.
1637        // STACK RESULT: push the constant value 1 onto the stack if the result
1638        // of the operation is true or the constant value 0 if the result of the
1639        // operation is false.
1640        //----------------------------------------------------------------------
1641        case DW_OP_gt:
1642            if (stack.size() < 2)
1643            {
1644                if (error_ptr)
1645                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_gt.");
1646                return false;
1647            }
1648            else
1649            {
1650                tmp = stack.back();
1651                stack.pop_back();
1652                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) > tmp.ResolveValue(exe_ctx, ast_context);
1653            }
1654            break;
1655
1656        //----------------------------------------------------------------------
1657        // OPCODE: DW_OP_le
1658        // OPERANDS: none
1659        // DESCRIPTION: pops the top two stack values, compares using the
1660        // less than or equal to (<=) operator.
1661        // STACK RESULT: push the constant value 1 onto the stack if the result
1662        // of the operation is true or the constant value 0 if the result of the
1663        // operation is false.
1664        //----------------------------------------------------------------------
1665        case DW_OP_le:
1666            if (stack.size() < 2)
1667            {
1668                if (error_ptr)
1669                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_le.");
1670                return false;
1671            }
1672            else
1673            {
1674                tmp = stack.back();
1675                stack.pop_back();
1676                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) <= tmp.ResolveValue(exe_ctx, ast_context);
1677            }
1678            break;
1679
1680        //----------------------------------------------------------------------
1681        // OPCODE: DW_OP_lt
1682        // OPERANDS: none
1683        // DESCRIPTION: pops the top two stack values, compares using the
1684        // less than (<) operator.
1685        // STACK RESULT: push the constant value 1 onto the stack if the result
1686        // of the operation is true or the constant value 0 if the result of the
1687        // operation is false.
1688        //----------------------------------------------------------------------
1689        case DW_OP_lt:
1690            if (stack.size() < 2)
1691            {
1692                if (error_ptr)
1693                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_lt.");
1694                return false;
1695            }
1696            else
1697            {
1698                tmp = stack.back();
1699                stack.pop_back();
1700                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) < tmp.ResolveValue(exe_ctx, ast_context);
1701            }
1702            break;
1703
1704        //----------------------------------------------------------------------
1705        // OPCODE: DW_OP_ne
1706        // OPERANDS: none
1707        // DESCRIPTION: pops the top two stack values, compares using the
1708        // not equal (!=) operator.
1709        // STACK RESULT: push the constant value 1 onto the stack if the result
1710        // of the operation is true or the constant value 0 if the result of the
1711        // operation is false.
1712        //----------------------------------------------------------------------
1713        case DW_OP_ne:
1714            if (stack.size() < 2)
1715            {
1716                if (error_ptr)
1717                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_ne.");
1718                return false;
1719            }
1720            else
1721            {
1722                tmp = stack.back();
1723                stack.pop_back();
1724                stack.back().ResolveValue(exe_ctx, ast_context) = stack.back().ResolveValue(exe_ctx, ast_context) != tmp.ResolveValue(exe_ctx, ast_context);
1725            }
1726            break;
1727
1728        //----------------------------------------------------------------------
1729        // OPCODE: DW_OP_litn
1730        // OPERANDS: none
1731        // DESCRIPTION: encode the unsigned literal values from 0 through 31.
1732        // STACK RESULT: push the unsigned literal constant value onto the top
1733        // of the stack.
1734        //----------------------------------------------------------------------
1735        case DW_OP_lit0:
1736        case DW_OP_lit1:
1737        case DW_OP_lit2:
1738        case DW_OP_lit3:
1739        case DW_OP_lit4:
1740        case DW_OP_lit5:
1741        case DW_OP_lit6:
1742        case DW_OP_lit7:
1743        case DW_OP_lit8:
1744        case DW_OP_lit9:
1745        case DW_OP_lit10:
1746        case DW_OP_lit11:
1747        case DW_OP_lit12:
1748        case DW_OP_lit13:
1749        case DW_OP_lit14:
1750        case DW_OP_lit15:
1751        case DW_OP_lit16:
1752        case DW_OP_lit17:
1753        case DW_OP_lit18:
1754        case DW_OP_lit19:
1755        case DW_OP_lit20:
1756        case DW_OP_lit21:
1757        case DW_OP_lit22:
1758        case DW_OP_lit23:
1759        case DW_OP_lit24:
1760        case DW_OP_lit25:
1761        case DW_OP_lit26:
1762        case DW_OP_lit27:
1763        case DW_OP_lit28:
1764        case DW_OP_lit29:
1765        case DW_OP_lit30:
1766        case DW_OP_lit31:
1767            stack.push_back(op - DW_OP_lit0);
1768            break;
1769
1770        //----------------------------------------------------------------------
1771        // OPCODE: DW_OP_regN
1772        // OPERANDS: none
1773        // DESCRIPTION: Push the value in register n on the top of the stack.
1774        //----------------------------------------------------------------------
1775        case DW_OP_reg0:
1776        case DW_OP_reg1:
1777        case DW_OP_reg2:
1778        case DW_OP_reg3:
1779        case DW_OP_reg4:
1780        case DW_OP_reg5:
1781        case DW_OP_reg6:
1782        case DW_OP_reg7:
1783        case DW_OP_reg8:
1784        case DW_OP_reg9:
1785        case DW_OP_reg10:
1786        case DW_OP_reg11:
1787        case DW_OP_reg12:
1788        case DW_OP_reg13:
1789        case DW_OP_reg14:
1790        case DW_OP_reg15:
1791        case DW_OP_reg16:
1792        case DW_OP_reg17:
1793        case DW_OP_reg18:
1794        case DW_OP_reg19:
1795        case DW_OP_reg20:
1796        case DW_OP_reg21:
1797        case DW_OP_reg22:
1798        case DW_OP_reg23:
1799        case DW_OP_reg24:
1800        case DW_OP_reg25:
1801        case DW_OP_reg26:
1802        case DW_OP_reg27:
1803        case DW_OP_reg28:
1804        case DW_OP_reg29:
1805        case DW_OP_reg30:
1806        case DW_OP_reg31:
1807            {
1808                reg_num = op - DW_OP_reg0;
1809
1810                if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
1811                    stack.push_back(tmp);
1812                else
1813                    return false;
1814            }
1815            break;
1816        //----------------------------------------------------------------------
1817        // OPCODE: DW_OP_regx
1818        // OPERANDS:
1819        //      ULEB128 literal operand that encodes the register.
1820        // DESCRIPTION: Push the value in register on the top of the stack.
1821        //----------------------------------------------------------------------
1822        case DW_OP_regx:
1823            {
1824                reg_num = opcodes.GetULEB128(&offset);
1825                if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
1826                    stack.push_back(tmp);
1827                else
1828                    return false;
1829            }
1830            break;
1831
1832        //----------------------------------------------------------------------
1833        // OPCODE: DW_OP_bregN
1834        // OPERANDS:
1835        //      SLEB128 offset from register N
1836        // DESCRIPTION: Value is in memory at the address specified by register
1837        // N plus an offset.
1838        //----------------------------------------------------------------------
1839        case DW_OP_breg0:
1840        case DW_OP_breg1:
1841        case DW_OP_breg2:
1842        case DW_OP_breg3:
1843        case DW_OP_breg4:
1844        case DW_OP_breg5:
1845        case DW_OP_breg6:
1846        case DW_OP_breg7:
1847        case DW_OP_breg8:
1848        case DW_OP_breg9:
1849        case DW_OP_breg10:
1850        case DW_OP_breg11:
1851        case DW_OP_breg12:
1852        case DW_OP_breg13:
1853        case DW_OP_breg14:
1854        case DW_OP_breg15:
1855        case DW_OP_breg16:
1856        case DW_OP_breg17:
1857        case DW_OP_breg18:
1858        case DW_OP_breg19:
1859        case DW_OP_breg20:
1860        case DW_OP_breg21:
1861        case DW_OP_breg22:
1862        case DW_OP_breg23:
1863        case DW_OP_breg24:
1864        case DW_OP_breg25:
1865        case DW_OP_breg26:
1866        case DW_OP_breg27:
1867        case DW_OP_breg28:
1868        case DW_OP_breg29:
1869        case DW_OP_breg30:
1870        case DW_OP_breg31:
1871            {
1872                reg_num = op - DW_OP_breg0;
1873
1874                if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
1875                {
1876                    int64_t breg_offset = opcodes.GetSLEB128(&offset);
1877                    tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset;
1878                    stack.push_back(tmp);
1879                    stack.back().SetValueType (Value::eValueTypeLoadAddress);
1880                }
1881                else
1882                    return false;
1883            }
1884            break;
1885        //----------------------------------------------------------------------
1886        // OPCODE: DW_OP_bregx
1887        // OPERANDS: 2
1888        //      ULEB128 literal operand that encodes the register.
1889        //      SLEB128 offset from register N
1890        // DESCRIPTION: Value is in memory at the address specified by register
1891        // N plus an offset.
1892        //----------------------------------------------------------------------
1893        case DW_OP_bregx:
1894            {
1895                reg_num = opcodes.GetULEB128(&offset);
1896
1897                if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
1898                {
1899                    int64_t breg_offset = opcodes.GetSLEB128(&offset);
1900                    tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset;
1901                    stack.push_back(tmp);
1902                    stack.back().SetValueType (Value::eValueTypeLoadAddress);
1903                }
1904                else
1905                    return false;
1906            }
1907            break;
1908
1909        case DW_OP_fbreg:
1910            if (exe_ctx && exe_ctx->frame)
1911            {
1912                Scalar value;
1913                if (exe_ctx->frame->GetFrameBaseValue(value, error_ptr))
1914                {
1915                    int64_t fbreg_offset = opcodes.GetSLEB128(&offset);
1916                    value += fbreg_offset;
1917                    stack.push_back(value);
1918                    stack.back().SetValueType (Value::eValueTypeLoadAddress);
1919                }
1920                else
1921                    return false;
1922            }
1923            else
1924            {
1925                if (error_ptr)
1926                    error_ptr->SetErrorString ("Invalid stack frame in context for DW_OP_fbreg opcode.");
1927                return false;
1928            }
1929            break;
1930
1931        //----------------------------------------------------------------------
1932        // OPCODE: DW_OP_nop
1933        // OPERANDS: none
1934        // DESCRIPTION: A place holder. It has no effect on the location stack
1935        // or any of its values.
1936        //----------------------------------------------------------------------
1937        case DW_OP_nop:
1938            break;
1939
1940        //----------------------------------------------------------------------
1941        // OPCODE: DW_OP_piece
1942        // OPERANDS: 1
1943        //      ULEB128: byte size of the piece
1944        // DESCRIPTION: The operand describes the size in bytes of the piece of
1945        // the object referenced by the DWARF expression whose result is at the
1946        // top of the stack. If the piece is located in a register, but does not
1947        // occupy the entire register, the placement of the piece within that
1948        // register is defined by the ABI.
1949        //
1950        // Many compilers store a single variable in sets of registers, or store
1951        // a variable partially in memory and partially in registers.
1952        // DW_OP_piece provides a way of describing how large a part of a
1953        // variable a particular DWARF expression refers to.
1954        //----------------------------------------------------------------------
1955        case DW_OP_piece:
1956            if (error_ptr)
1957                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_piece.");
1958            return false;
1959
1960        //----------------------------------------------------------------------
1961        // OPCODE: DW_OP_push_object_address
1962        // OPERANDS: none
1963        // DESCRIPTION: Pushes the address of the object currently being
1964        // evaluated as part of evaluation of a user presented expression.
1965        // This object may correspond to an independent variable described by
1966        // its own DIE or it may be a component of an array, structure, or class
1967        // whose address has been dynamically determined by an earlier step
1968        // during user expression evaluation.
1969        //----------------------------------------------------------------------
1970        case DW_OP_push_object_address:
1971            if (error_ptr)
1972                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_push_object_address.");
1973            return false;
1974
1975        //----------------------------------------------------------------------
1976        // OPCODE: DW_OP_call2
1977        // OPERANDS:
1978        //      uint16_t compile unit relative offset of a DIE
1979        // DESCRIPTION: Performs subroutine calls during evaluation
1980        // of a DWARF expression. The operand is the 2-byte unsigned offset
1981        // of a debugging information entry in the current compilation unit.
1982        //
1983        // Operand interpretation is exactly like that for DW_FORM_ref2.
1984        //
1985        // This operation transfers control of DWARF expression evaluation
1986        // to the DW_AT_location attribute of the referenced DIE. If there is
1987        // no such attribute, then there is no effect. Execution of the DWARF
1988        // expression of a DW_AT_location attribute may add to and/or remove from
1989        // values on the stack. Execution returns to the point following the call
1990        // when the end of the attribute is reached. Values on the stack at the
1991        // time of the call may be used as parameters by the called expression
1992        // and values left on the stack by the called expression may be used as
1993        // return values by prior agreement between the calling and called
1994        // expressions.
1995        //----------------------------------------------------------------------
1996        case DW_OP_call2:
1997            if (error_ptr)
1998                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call2.");
1999            return false;
2000        //----------------------------------------------------------------------
2001        // OPCODE: DW_OP_call4
2002        // OPERANDS: 1
2003        //      uint32_t compile unit relative offset of a DIE
2004        // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
2005        // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset
2006        // of a debugging information entry in  the current compilation unit.
2007        //
2008        // Operand interpretation DW_OP_call4 is exactly like that for
2009        // DW_FORM_ref4.
2010        //
2011        // This operation transfers control of DWARF expression evaluation
2012        // to the DW_AT_location attribute of the referenced DIE. If there is
2013        // no such attribute, then there is no effect. Execution of the DWARF
2014        // expression of a DW_AT_location attribute may add to and/or remove from
2015        // values on the stack. Execution returns to the point following the call
2016        // when the end of the attribute is reached. Values on the stack at the
2017        // time of the call may be used as parameters by the called expression
2018        // and values left on the stack by the called expression may be used as
2019        // return values by prior agreement between the calling and called
2020        // expressions.
2021        //----------------------------------------------------------------------
2022        case DW_OP_call4:
2023            if (error_ptr)
2024                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call4.");
2025            return false;
2026
2027
2028        //----------------------------------------------------------------------
2029        // OPCODE: DW_OP_call_ref
2030        // OPERANDS:
2031        //      uint32_t absolute DIE offset for 32-bit DWARF or a uint64_t
2032        //               absolute DIE offset for 64 bit DWARF.
2033        // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF
2034        // expression. Takes a single operand. In the 32-bit DWARF format, the
2035        // operand is a 4-byte unsigned value; in the 64-bit DWARF format, it
2036        // is an 8-byte unsigned value. The operand is used as the offset of a
2037        // debugging information entry in a .debug_info section which may be
2038        // contained in a shared object for executable other than that
2039        // containing the operator. For references from one shared object or
2040        // executable to another, the relocation must be performed by the
2041        // consumer.
2042        //
2043        // Operand interpretation of DW_OP_call_ref is exactly like that for
2044        // DW_FORM_ref_addr.
2045        //
2046        // This operation transfers control of DWARF expression evaluation
2047        // to the DW_AT_location attribute of the referenced DIE. If there is
2048        // no such attribute, then there is no effect. Execution of the DWARF
2049        // expression of a DW_AT_location attribute may add to and/or remove from
2050        // values on the stack. Execution returns to the point following the call
2051        // when the end of the attribute is reached. Values on the stack at the
2052        // time of the call may be used as parameters by the called expression
2053        // and values left on the stack by the called expression may be used as
2054        // return values by prior agreement between the calling and called
2055        // expressions.
2056        //----------------------------------------------------------------------
2057        case DW_OP_call_ref:
2058            if (error_ptr)
2059                error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call_ref.");
2060            return false;
2061
2062        //----------------------------------------------------------------------
2063        // OPCODE: DW_OP_APPLE_array_ref
2064        // OPERANDS: none
2065        // DESCRIPTION: Pops a value off the stack and uses it as the array
2066        // index.  Pops a second value off the stack and uses it as the array
2067        // itself.  Pushes a value onto the stack representing the element of
2068        // the array specified by the index.
2069        //----------------------------------------------------------------------
2070        case DW_OP_APPLE_array_ref:
2071            {
2072                if (stack.size() < 2)
2073                {
2074                    if (error_ptr)
2075                        error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_APPLE_array_ref.");
2076                    return false;
2077                }
2078
2079                Value index_val = stack.back();
2080                stack.pop_back();
2081                Value array_val = stack.back();
2082                stack.pop_back();
2083
2084                Scalar &index_scalar = index_val.ResolveValue(exe_ctx, ast_context);
2085                int64_t index = index_scalar.SLongLong(LONG_LONG_MAX);
2086
2087                if (index == LONG_LONG_MAX)
2088                {
2089                    if (error_ptr)
2090                        error_ptr->SetErrorString("Invalid array index.");
2091                    return false;
2092                }
2093
2094                if (array_val.GetContextType() != Value::eContextTypeOpaqueClangQualType)
2095                {
2096                    if (error_ptr)
2097                        error_ptr->SetErrorString("Arrays without Clang types are unhandled at this time.");
2098                    return false;
2099                }
2100
2101                if (array_val.GetValueType() != Value::eValueTypeLoadAddress &&
2102                    array_val.GetValueType() != Value::eValueTypeHostAddress)
2103                {
2104                    if (error_ptr)
2105                        error_ptr->SetErrorString("Array must be stored in memory.");
2106                    return false;
2107                }
2108
2109                void *array_type = array_val.GetOpaqueClangQualType();
2110
2111                void *member_type;
2112                uint64_t size = 0;
2113
2114                if ((!ClangASTContext::IsPointerType(array_type, &member_type)) &&
2115                    (!ClangASTContext::IsArrayType(array_type, &member_type, &size)))
2116                {
2117                    if (error_ptr)
2118                        error_ptr->SetErrorString("Array reference from something that is neither a pointer nor an array.");
2119                    return false;
2120                }
2121
2122                if (size && (index >= size || index < 0))
2123                {
2124                    if (error_ptr)
2125                        error_ptr->SetErrorStringWithFormat("Out of bounds array access.  %lld is not in [0, %llu]", index, size);
2126                    return false;
2127                }
2128
2129                uint64_t member_bit_size = ClangASTType::GetClangTypeBitWidth(ast_context, member_type);
2130                uint64_t member_bit_align = ClangASTType::GetTypeBitAlign(ast_context, member_type);
2131                uint64_t member_bit_incr = ((member_bit_size + member_bit_align - 1) / member_bit_align) * member_bit_align;
2132                if (member_bit_incr % 8)
2133                {
2134                    if (error_ptr)
2135                        error_ptr->SetErrorStringWithFormat("Array increment is not byte aligned", index, size);
2136                    return false;
2137                }
2138                int64_t member_offset = (int64_t)(member_bit_incr / 8) * index;
2139
2140                Value member;
2141
2142                member.SetContext(Value::eContextTypeOpaqueClangQualType, member_type);
2143                member.SetValueType(array_val.GetValueType());
2144
2145                addr_t array_base = (addr_t)array_val.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
2146                addr_t member_loc = array_base + member_offset;
2147                member.GetScalar() = (uint64_t)member_loc;
2148
2149                stack.push_back(member);
2150            }
2151            break;
2152
2153        //----------------------------------------------------------------------
2154        // OPCODE: DW_OP_APPLE_uninit
2155        // OPERANDS: none
2156        // DESCRIPTION: Lets us know that the value is currently not initialized
2157        //----------------------------------------------------------------------
2158        case DW_OP_APPLE_uninit:
2159            //return eResultTypeErrorUninitialized;
2160            break;  // Ignore this as we have seen cases where this value is incorrectly added
2161
2162        //----------------------------------------------------------------------
2163        // OPCODE: DW_OP_APPLE_assign
2164        // OPERANDS: none
2165        // DESCRIPTION: Pops a value off of the stack and assigns it to the next
2166        // item on the stack which must be something assignable (inferior
2167        // Variable, inferior Type with address, inferior register, or
2168        // expression local variable.
2169        //----------------------------------------------------------------------
2170        case DW_OP_APPLE_assign:
2171            if (stack.size() < 2)
2172            {
2173                if (error_ptr)
2174                    error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_APPLE_assign.");
2175                return false;
2176            }
2177            else
2178            {
2179                tmp = stack.back();
2180                stack.pop_back();
2181                Value::ContextType context_type = stack.back().GetContextType();
2182                StreamString new_value(Stream::eBinary, 4, eByteOrderHost);
2183                switch (context_type)
2184                {
2185                case Value::eContextTypeOpaqueClangQualType:
2186                    {
2187                        void *clang_type = stack.back().GetOpaqueClangQualType();
2188
2189                        if (ClangASTContext::IsAggregateType (clang_type))
2190                        {
2191                            Value::ValueType source_value_type = tmp.GetValueType();
2192                            Value::ValueType target_value_type = stack.back().GetValueType();
2193
2194                            addr_t source_addr = (addr_t)tmp.GetScalar().ULongLong();
2195                            addr_t target_addr = (addr_t)stack.back().GetScalar().ULongLong();
2196
2197                            size_t byte_size = (ClangASTType::GetClangTypeBitWidth(ast_context, clang_type) + 7) / 8;
2198
2199                            switch (source_value_type)
2200                            {
2201                            case Value::eValueTypeLoadAddress:
2202                                switch (target_value_type)
2203                                {
2204                                case Value::eValueTypeLoadAddress:
2205                                    {
2206                                        DataBufferHeap data;
2207                                        data.SetByteSize(byte_size);
2208
2209                                        Error error;
2210                                        if (exe_ctx->process->ReadMemory (source_addr, data.GetBytes(), byte_size, error) != byte_size)
2211                                        {
2212                                            if (error_ptr)
2213                                                error_ptr->SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
2214                                            return false;
2215                                        }
2216
2217                                        if (exe_ctx->process->WriteMemory (target_addr, data.GetBytes(), byte_size, error) != byte_size)
2218                                        {
2219                                            if (error_ptr)
2220                                                error_ptr->SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
2221                                            return false;
2222                                        }
2223                                    }
2224                                    break;
2225                                case Value::eValueTypeHostAddress:
2226                                    if (exe_ctx->process->GetByteOrder() != Host::GetByteOrder())
2227                                    {
2228                                        if (error_ptr)
2229                                            error_ptr->SetErrorStringWithFormat ("Copy of composite types between incompatible byte orders is unimplemented");
2230                                        return false;
2231                                    }
2232                                    else
2233                                    {
2234                                        Error error;
2235                                        if (exe_ctx->process->ReadMemory (source_addr, (uint8_t*)target_addr, byte_size, error) != byte_size)
2236                                        {
2237                                            if (error_ptr)
2238                                                error_ptr->SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
2239                                            return false;
2240                                        }
2241                                    }
2242                                    break;
2243                                default:
2244                                    return false;
2245                                }
2246                                break;
2247                            case Value::eValueTypeHostAddress:
2248                                switch (target_value_type)
2249                                {
2250                                case Value::eValueTypeLoadAddress:
2251                                    if (exe_ctx->process->GetByteOrder() != Host::GetByteOrder())
2252                                    {
2253                                        if (error_ptr)
2254                                            error_ptr->SetErrorStringWithFormat ("Copy of composite types between incompatible byte orders is unimplemented");
2255                                        return false;
2256                                    }
2257                                    else
2258                                    {
2259                                        Error error;
2260                                        if (exe_ctx->process->WriteMemory (target_addr, (uint8_t*)source_addr, byte_size, error) != byte_size)
2261                                        {
2262                                            if (error_ptr)
2263                                                error_ptr->SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
2264                                            return false;
2265                                        }
2266                                    }
2267                                case Value::eValueTypeHostAddress:
2268                                    memcpy ((uint8_t*)target_addr, (uint8_t*)source_addr, byte_size);
2269                                    break;
2270                                default:
2271                                    return false;
2272                                }
2273                            }
2274                        }
2275                        else
2276                        {
2277                            if (!ClangASTType::SetValueFromScalar (ast_context,
2278                                                                  clang_type,
2279                                                                  tmp.ResolveValue(exe_ctx, ast_context),
2280                                                                  new_value))
2281                            {
2282                                if (error_ptr)
2283                                    error_ptr->SetErrorStringWithFormat ("Couldn't extract a value from an integral type.\n");
2284                                return false;
2285                            }
2286
2287                            Value::ValueType value_type = stack.back().GetValueType();
2288
2289                            switch (value_type)
2290                            {
2291                            case Value::eValueTypeLoadAddress:
2292                            case Value::eValueTypeHostAddress:
2293                                {
2294                                    lldb::AddressType address_type = (value_type == Value::eValueTypeLoadAddress ? eAddressTypeLoad : eAddressTypeHost);
2295                                    lldb::addr_t addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
2296                                    if (!ClangASTType::WriteToMemory (ast_context,
2297                                                                          clang_type,
2298                                                                          exe_ctx,
2299                                                                          addr,
2300                                                                          address_type,
2301                                                                          new_value))
2302                                    {
2303                                        if (error_ptr)
2304                                            error_ptr->SetErrorStringWithFormat ("Failed to write value to memory at 0x%llx.\n", addr);
2305                                        return false;
2306                                    }
2307                                }
2308                                break;
2309
2310                            default:
2311                                break;
2312                            }
2313                        }
2314                    }
2315                    break;
2316
2317                default:
2318                    if (error_ptr)
2319                        error_ptr->SetErrorString ("Assign failed.");
2320                    return false;
2321                }
2322            }
2323            break;
2324
2325        //----------------------------------------------------------------------
2326        // OPCODE: DW_OP_APPLE_address_of
2327        // OPERANDS: none
2328        // DESCRIPTION: Pops a value off of the stack and pushed its address.
2329        // The top item on the stack must be a variable, or already be a memory
2330        // location.
2331        //----------------------------------------------------------------------
2332        case DW_OP_APPLE_address_of:
2333            if (stack.empty())
2334            {
2335                if (error_ptr)
2336                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_address_of.");
2337                return false;
2338            }
2339            else
2340            {
2341                Value::ValueType value_type = stack.back().GetValueType();
2342                switch (value_type)
2343                {
2344                default:
2345                case Value::eValueTypeScalar:      // raw scalar value
2346                    if (error_ptr)
2347                        error_ptr->SetErrorString("Top stack item isn't a memory based object.");
2348                    return false;
2349
2350                case Value::eValueTypeLoadAddress: // load address value
2351                case Value::eValueTypeFileAddress: // file address value
2352                case Value::eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb)
2353                    // Taking the address of an object reduces it to the address
2354                    // of the value and removes any extra context it had.
2355                    //stack.back().SetValueType(Value::eValueTypeScalar);
2356                    stack.back().ClearContext();
2357                    break;
2358                }
2359            }
2360            break;
2361
2362        //----------------------------------------------------------------------
2363        // OPCODE: DW_OP_APPLE_value_of
2364        // OPERANDS: none
2365        // DESCRIPTION: Pops a value off of the stack and pushed its value.
2366        // The top item on the stack must be a variable, expression variable.
2367        //----------------------------------------------------------------------
2368        case DW_OP_APPLE_value_of:
2369            if (stack.empty())
2370            {
2371                if (error_ptr)
2372                    error_ptr->SetErrorString("Expression stack needs at least 1 items for DW_OP_APPLE_value_of.");
2373                return false;
2374            }
2375            else if (!stack.back().ValueOf(exe_ctx, ast_context))
2376            {
2377                if (error_ptr)
2378                    error_ptr->SetErrorString ("Top stack item isn't a valid candidate for DW_OP_APPLE_value_of.");
2379                return false;
2380            }
2381            break;
2382
2383        //----------------------------------------------------------------------
2384        // OPCODE: DW_OP_APPLE_deref_type
2385        // OPERANDS: none
2386        // DESCRIPTION: gets the value pointed to by the top stack item
2387        //----------------------------------------------------------------------
2388        case DW_OP_APPLE_deref_type:
2389            {
2390                if (stack.empty())
2391                {
2392                    if (error_ptr)
2393                        error_ptr->SetErrorString("Expression stack needs at least 1 items for DW_OP_APPLE_deref_type.");
2394                    return false;
2395                }
2396
2397                tmp = stack.back();
2398                stack.pop_back();
2399
2400                if (tmp.GetContextType() != Value::eContextTypeOpaqueClangQualType)
2401                {
2402                    if (error_ptr)
2403                        error_ptr->SetErrorString("Item at top of expression stack must have a Clang type");
2404                    return false;
2405                }
2406
2407                void *ptr_type = tmp.GetOpaqueClangQualType();
2408                void *target_type;
2409
2410                if (!ClangASTContext::IsPointerType(ptr_type, &target_type))
2411                {
2412                    if (error_ptr)
2413                        error_ptr->SetErrorString("Dereferencing a non-pointer type");
2414                    return false;
2415                }
2416
2417                // TODO do we want all pointers to be dereferenced as load addresses?
2418                Value::ValueType value_type = tmp.GetValueType();
2419
2420                tmp.ResolveValue(exe_ctx, ast_context);
2421
2422                tmp.SetValueType(value_type);
2423                tmp.SetContext(Value::eContextTypeOpaqueClangQualType, target_type);
2424
2425                stack.push_back(tmp);
2426            }
2427            break;
2428
2429        //----------------------------------------------------------------------
2430        // OPCODE: DW_OP_APPLE_expr_local
2431        // OPERANDS: ULEB128
2432        // DESCRIPTION: pushes the expression local variable index onto the
2433        // stack and set the appropriate context so we know the stack item is
2434        // an expression local variable index.
2435        //----------------------------------------------------------------------
2436        case DW_OP_APPLE_expr_local:
2437            {
2438                /*
2439                uint32_t idx = opcodes.GetULEB128(&offset);
2440                if (expr_locals == NULL)
2441                {
2442                    if (error_ptr)
2443                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) opcode encountered with no local variable list.\n", idx);
2444                    return false;
2445                }
2446                Value *expr_local_variable = expr_locals->GetVariableAtIndex(idx);
2447                if (expr_local_variable == NULL)
2448                {
2449                    if (error_ptr)
2450                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) with invalid index %u.\n", idx, idx);
2451                    return false;
2452                }
2453                Value *proxy = expr_local_variable->CreateProxy();
2454                stack.push_back(*proxy);
2455                delete proxy;
2456                //stack.back().SetContext (Value::eContextTypeOpaqueClangQualType, expr_local_variable->GetOpaqueClangQualType());
2457                */
2458            }
2459            break;
2460
2461        //----------------------------------------------------------------------
2462        // OPCODE: DW_OP_APPLE_extern
2463        // OPERANDS: ULEB128
2464        // DESCRIPTION: pushes a proxy for the extern object index onto the
2465        // stack.
2466        //----------------------------------------------------------------------
2467        case DW_OP_APPLE_extern:
2468            {
2469                /*
2470                uint32_t idx = opcodes.GetULEB128(&offset);
2471                if (!decl_map)
2472                {
2473                    if (error_ptr)
2474                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) opcode encountered with no decl map.\n", idx);
2475                    return false;
2476                }
2477                Value *extern_var = decl_map->GetValueForIndex(idx);
2478                if (!extern_var)
2479                {
2480                    if (error_ptr)
2481                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) with invalid index %u.\n", idx, idx);
2482                    return false;
2483                }
2484                Value *proxy = extern_var->CreateProxy();
2485                stack.push_back(*proxy);
2486                delete proxy;
2487                */
2488            }
2489            break;
2490
2491        case DW_OP_APPLE_scalar_cast:
2492            if (stack.empty())
2493            {
2494                if (error_ptr)
2495                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_scalar_cast.");
2496                return false;
2497            }
2498            else
2499            {
2500                // Simple scalar cast
2501                if (!stack.back().ResolveValue(exe_ctx, ast_context).Cast((Scalar::Type)opcodes.GetU8(&offset)))
2502                {
2503                    if (error_ptr)
2504                        error_ptr->SetErrorString("Cast failed.");
2505                    return false;
2506                }
2507            }
2508            break;
2509
2510
2511        case DW_OP_APPLE_clang_cast:
2512            if (stack.empty())
2513            {
2514                if (error_ptr)
2515                    error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_clang_cast.");
2516                return false;
2517            }
2518            else
2519            {
2520                void *clang_type = (void *)opcodes.GetMaxU64(&offset, sizeof(void*));
2521                stack.back().SetContext (Value::eContextTypeOpaqueClangQualType, clang_type);
2522            }
2523            break;
2524        //----------------------------------------------------------------------
2525        // OPCODE: DW_OP_APPLE_constf
2526        // OPERANDS: 1 byte float length, followed by that many bytes containing
2527        // the constant float data.
2528        // DESCRIPTION: Push a float value onto the expression stack.
2529        //----------------------------------------------------------------------
2530        case DW_OP_APPLE_constf:        // 0xF6 - 1 byte float size, followed by constant float data
2531            {
2532                uint8_t float_length = opcodes.GetU8(&offset);
2533                if (sizeof(float) == float_length)
2534                    tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetFloat (&offset);
2535                else if (sizeof(double) == float_length)
2536                    tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetDouble (&offset);
2537                else if (sizeof(long double) == float_length)
2538                    tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetLongDouble (&offset);
2539                else
2540                {
2541                    StreamString new_value;
2542                    opcodes.Dump(&new_value, offset, eFormatBytes, 1, float_length, UINT32_MAX, DW_INVALID_ADDRESS, 0, 0);
2543
2544                     if (error_ptr)
2545                        error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_constf(<%u> %s) unsupported float size.\n", float_length, new_value.GetData());
2546                    return false;
2547               }
2548               tmp.SetValueType(Value::eValueTypeScalar);
2549               tmp.ClearContext();
2550               stack.push_back(tmp);
2551            }
2552            break;
2553        //----------------------------------------------------------------------
2554        // OPCODE: DW_OP_APPLE_clear
2555        // OPERANDS: none
2556        // DESCRIPTION: Clears the expression stack.
2557        //----------------------------------------------------------------------
2558        case DW_OP_APPLE_clear:
2559            stack.clear();
2560            break;
2561
2562        //----------------------------------------------------------------------
2563        // OPCODE: DW_OP_APPLE_error
2564        // OPERANDS: none
2565        // DESCRIPTION: Pops a value off of the stack and pushed its value.
2566        // The top item on the stack must be a variable, expression variable.
2567        //----------------------------------------------------------------------
2568        case DW_OP_APPLE_error:         // 0xFF - Stops expression evaluation and returns an error (no args)
2569            if (error_ptr)
2570                error_ptr->SetErrorString ("Generic error.");
2571            return false;
2572        }
2573    }
2574
2575    if (stack.empty())
2576    {
2577        if (error_ptr)
2578            error_ptr->SetErrorString ("Stack empty after evaluation.");
2579        return false;
2580    }
2581    else if (log)
2582    {
2583        size_t count = stack.size();
2584        log->Printf("Stack after operation has %d values:", count);
2585        for (size_t i=0; i<count; ++i)
2586        {
2587            StreamString new_value;
2588            new_value.Printf("[%zu]", i);
2589            stack[i].Dump(&new_value);
2590            log->Printf("  %s", new_value.GetData());
2591        }
2592    }
2593
2594    result = stack.back();
2595    return true;    // Return true on success
2596}
2597
2598