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