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