blob: 20c97b28e0721a89ec2f3ef9d6843cc0c3794416 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
Greg Clayton1674b122010-07-21 22:12:05 +000027#include "lldb/Symbol/ClangASTType.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#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 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000307 default:
308 break;
309
Chris Lattner24943d22010-06-08 16:52:24 +0000310 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 {
Chris Lattner24943d22010-06-08 16:52:24 +0000847 size_t count = stack.size();
Sean Callanan6184dfe2010-06-23 00:47:48 +0000848 log->Printf("Stack before operation has %d values:", count);
Chris Lattner24943d22010-06-08 16:52:24 +0000849 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);
Sean Callanan6184dfe2010-06-23 00:47:48 +0000854 log->Printf(" %s", new_value.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000855 }
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 = ClangASTContext::GetTypeBitSize(ast_context, member_type);
2130 uint64_t member_bit_align = ClangASTContext::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 = (ClangASTContext::GetTypeBitSize(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 {
Greg Clayton1674b122010-07-21 22:12:05 +00002277 if (!ClangASTType::SetValueFromScalar (ast_context,
2278 clang_type,
2279 tmp.ResolveValue(exe_ctx, ast_context),
2280 new_value))
Chris Lattner24943d22010-06-08 16:52:24 +00002281 {
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);
Greg Clayton1674b122010-07-21 22:12:05 +00002296 if (!ClangASTType::WriteToMemory (ast_context,
2297 clang_type,
2298 exe_ctx,
2299 addr,
2300 address_type,
2301 new_value))
Chris Lattner24943d22010-06-08 16:52:24 +00002302 {
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 uint32_t idx = opcodes.GetULEB128(&offset);
2439 if (expr_locals == NULL)
2440 {
2441 if (error_ptr)
2442 error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) opcode encountered with no local variable list.\n", idx);
2443 return false;
2444 }
2445 Value *expr_local_variable = expr_locals->GetVariableAtIndex(idx);
2446 if (expr_local_variable == NULL)
2447 {
2448 if (error_ptr)
2449 error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) with invalid index %u.\n", idx, idx);
2450 return false;
2451 }
2452 Value *proxy = expr_local_variable->CreateProxy();
2453 stack.push_back(*proxy);
2454 delete proxy;
2455 //stack.back().SetContext (Value::eContextTypeOpaqueClangQualType, expr_local_variable->GetOpaqueClangQualType());
2456 }
2457 break;
2458
2459 //----------------------------------------------------------------------
2460 // OPCODE: DW_OP_APPLE_extern
2461 // OPERANDS: ULEB128
2462 // DESCRIPTION: pushes a proxy for the extern object index onto the
2463 // stack.
2464 //----------------------------------------------------------------------
2465 case DW_OP_APPLE_extern:
2466 {
2467 uint32_t idx = opcodes.GetULEB128(&offset);
2468 if (!decl_map)
2469 {
2470 if (error_ptr)
2471 error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) opcode encountered with no decl map.\n", idx);
2472 return false;
2473 }
2474 Value *extern_var = decl_map->GetValueForIndex(idx);
2475 if (!extern_var)
2476 {
2477 if (error_ptr)
2478 error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) with invalid index %u.\n", idx, idx);
2479 return false;
2480 }
2481 Value *proxy = extern_var->CreateProxy();
2482 stack.push_back(*proxy);
2483 delete proxy;
2484 }
2485 break;
2486
2487 case DW_OP_APPLE_scalar_cast:
2488 if (stack.empty())
2489 {
2490 if (error_ptr)
2491 error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_scalar_cast.");
2492 return false;
2493 }
2494 else
2495 {
2496 // Simple scalar cast
2497 if (!stack.back().ResolveValue(exe_ctx, ast_context).Cast((Scalar::Type)opcodes.GetU8(&offset)))
2498 {
2499 if (error_ptr)
2500 error_ptr->SetErrorString("Cast failed.");
2501 return false;
2502 }
2503 }
2504 break;
2505
2506
2507 case DW_OP_APPLE_clang_cast:
2508 if (stack.empty())
2509 {
2510 if (error_ptr)
2511 error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_APPLE_clang_cast.");
2512 return false;
2513 }
2514 else
2515 {
2516 void *clang_type = (void *)opcodes.GetMaxU64(&offset, sizeof(void*));
2517 stack.back().SetContext (Value::eContextTypeOpaqueClangQualType, clang_type);
2518 }
2519 break;
2520 //----------------------------------------------------------------------
2521 // OPCODE: DW_OP_APPLE_constf
2522 // OPERANDS: 1 byte float length, followed by that many bytes containing
2523 // the constant float data.
2524 // DESCRIPTION: Push a float value onto the expression stack.
2525 //----------------------------------------------------------------------
2526 case DW_OP_APPLE_constf: // 0xF6 - 1 byte float size, followed by constant float data
2527 {
2528 uint8_t float_length = opcodes.GetU8(&offset);
2529 if (sizeof(float) == float_length)
2530 tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetFloat (&offset);
2531 else if (sizeof(double) == float_length)
2532 tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetDouble (&offset);
2533 else if (sizeof(long double) == float_length)
2534 tmp.ResolveValue(exe_ctx, ast_context) = opcodes.GetLongDouble (&offset);
2535 else
2536 {
2537 StreamString new_value;
2538 opcodes.Dump(&new_value, offset, eFormatBytes, 1, float_length, UINT32_MAX, DW_INVALID_ADDRESS, 0, 0);
2539
2540 if (error_ptr)
2541 error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_constf(<%u> %s) unsupported float size.\n", float_length, new_value.GetData());
2542 return false;
2543 }
2544 tmp.SetValueType(Value::eValueTypeScalar);
2545 tmp.ClearContext();
2546 stack.push_back(tmp);
2547 }
2548 break;
2549 //----------------------------------------------------------------------
2550 // OPCODE: DW_OP_APPLE_clear
2551 // OPERANDS: none
2552 // DESCRIPTION: Clears the expression stack.
2553 //----------------------------------------------------------------------
2554 case DW_OP_APPLE_clear:
2555 stack.clear();
2556 break;
2557
2558 //----------------------------------------------------------------------
2559 // OPCODE: DW_OP_APPLE_error
2560 // OPERANDS: none
2561 // DESCRIPTION: Pops a value off of the stack and pushed its value.
2562 // The top item on the stack must be a variable, expression variable.
2563 //----------------------------------------------------------------------
2564 case DW_OP_APPLE_error: // 0xFF - Stops expression evaluation and returns an error (no args)
2565 if (error_ptr)
2566 error_ptr->SetErrorString ("Generic error.");
2567 return false;
2568 }
2569 }
2570
2571 if (stack.empty())
2572 {
2573 if (error_ptr)
2574 error_ptr->SetErrorString ("Stack empty after evaluation.");
2575 return false;
2576 }
2577 else if (log)
2578 {
Chris Lattner24943d22010-06-08 16:52:24 +00002579 size_t count = stack.size();
Sean Callanan6184dfe2010-06-23 00:47:48 +00002580 log->Printf("Stack after operation has %d values:", count);
Chris Lattner24943d22010-06-08 16:52:24 +00002581 for (size_t i=0; i<count; ++i)
2582 {
2583 StreamString new_value;
2584 new_value.Printf("[%zu]", i);
2585 stack[i].Dump(&new_value);
Sean Callanan6184dfe2010-06-23 00:47:48 +00002586 log->Printf(" %s", new_value.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +00002587 }
2588 }
2589
2590 result = stack.back();
2591 return true; // Return true on success
2592}
2593