1 //===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Expression/DWARFExpression.h" 10 11 #include <inttypes.h> 12 13 #include <vector> 14 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/Value.h" 17 #include "lldb/Core/dwarf.h" 18 #include "lldb/Utility/DataEncoder.h" 19 #include "lldb/Utility/Log.h" 20 #include "lldb/Utility/RegisterValue.h" 21 #include "lldb/Utility/Scalar.h" 22 #include "lldb/Utility/StreamString.h" 23 #include "lldb/Utility/VMRange.h" 24 25 #include "lldb/Host/Host.h" 26 #include "lldb/Utility/Endian.h" 27 28 #include "lldb/Symbol/Function.h" 29 30 #include "lldb/Target/ABI.h" 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 #include "lldb/Target/StackID.h" 36 #include "lldb/Target/Thread.h" 37 38 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h" 39 40 using namespace lldb; 41 using namespace lldb_private; 42 43 static lldb::addr_t 44 ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu, 45 uint32_t index) { 46 uint32_t index_size = dwarf_cu->GetAddressByteSize(); 47 dw_offset_t addr_base = dwarf_cu->GetAddrBase(); 48 lldb::offset_t offset = addr_base + index * index_size; 49 return dwarf_cu->GetSymbolFileDWARF() 50 .GetDWARFContext() 51 .getOrLoadAddrData() 52 .GetMaxU64(&offset, index_size); 53 } 54 55 // DWARFExpression constructor 56 DWARFExpression::DWARFExpression() 57 : m_module_wp(), m_data(), m_dwarf_cu(nullptr), 58 m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) {} 59 60 DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, 61 const DataExtractor &data, 62 const DWARFUnit *dwarf_cu) 63 : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu), 64 m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) { 65 if (module_sp) 66 m_module_wp = module_sp; 67 } 68 69 // Destructor 70 DWARFExpression::~DWARFExpression() {} 71 72 bool DWARFExpression::IsValid() const { return m_data.GetByteSize() > 0; } 73 74 void DWARFExpression::UpdateValue(uint64_t const_value, 75 lldb::offset_t const_value_byte_size, 76 uint8_t addr_byte_size) { 77 if (!const_value_byte_size) 78 return; 79 80 m_data.SetData( 81 DataBufferSP(new DataBufferHeap(&const_value, const_value_byte_size))); 82 m_data.SetByteOrder(endian::InlHostByteOrder()); 83 m_data.SetAddressByteSize(addr_byte_size); 84 } 85 86 void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, 87 lldb::offset_t length, 88 lldb::DescriptionLevel level, 89 ABI *abi) const { 90 if (!m_data.ValidOffsetForDataOfSize(offset, length)) 91 return; 92 const lldb::offset_t start_offset = offset; 93 const lldb::offset_t end_offset = offset + length; 94 while (m_data.ValidOffset(offset) && offset < end_offset) { 95 const lldb::offset_t op_offset = offset; 96 const uint8_t op = m_data.GetU8(&offset); 97 98 switch (level) { 99 default: 100 break; 101 102 case lldb::eDescriptionLevelBrief: 103 if (op_offset > start_offset) 104 s->PutChar(' '); 105 break; 106 107 case lldb::eDescriptionLevelFull: 108 case lldb::eDescriptionLevelVerbose: 109 if (op_offset > start_offset) 110 s->EOL(); 111 s->Indent(); 112 if (level == lldb::eDescriptionLevelFull) 113 break; 114 // Fall through for verbose and print offset and DW_OP prefix.. 115 s->Printf("0x%8.8" PRIx64 ": %s", op_offset, 116 op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_"); 117 break; 118 } 119 120 switch (op) { 121 case DW_OP_addr: 122 *s << "DW_OP_addr(" << m_data.GetAddress(&offset) << ") "; 123 break; // 0x03 1 address 124 case DW_OP_deref: 125 *s << "DW_OP_deref"; 126 break; // 0x06 127 case DW_OP_const1u: 128 s->Printf("DW_OP_const1u(0x%2.2x)", m_data.GetU8(&offset)); 129 break; // 0x08 1 1-byte constant 130 case DW_OP_const1s: 131 s->Printf("DW_OP_const1s(0x%2.2x)", m_data.GetU8(&offset)); 132 break; // 0x09 1 1-byte constant 133 case DW_OP_const2u: 134 s->Printf("DW_OP_const2u(0x%4.4x)", m_data.GetU16(&offset)); 135 break; // 0x0a 1 2-byte constant 136 case DW_OP_const2s: 137 s->Printf("DW_OP_const2s(0x%4.4x)", m_data.GetU16(&offset)); 138 break; // 0x0b 1 2-byte constant 139 case DW_OP_const4u: 140 s->Printf("DW_OP_const4u(0x%8.8x)", m_data.GetU32(&offset)); 141 break; // 0x0c 1 4-byte constant 142 case DW_OP_const4s: 143 s->Printf("DW_OP_const4s(0x%8.8x)", m_data.GetU32(&offset)); 144 break; // 0x0d 1 4-byte constant 145 case DW_OP_const8u: 146 s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ")", m_data.GetU64(&offset)); 147 break; // 0x0e 1 8-byte constant 148 case DW_OP_const8s: 149 s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ")", m_data.GetU64(&offset)); 150 break; // 0x0f 1 8-byte constant 151 case DW_OP_constu: 152 s->Printf("DW_OP_constu(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); 153 break; // 0x10 1 ULEB128 constant 154 case DW_OP_consts: 155 s->Printf("DW_OP_consts(0x%" PRId64 ")", m_data.GetSLEB128(&offset)); 156 break; // 0x11 1 SLEB128 constant 157 case DW_OP_dup: 158 s->PutCString("DW_OP_dup"); 159 break; // 0x12 160 case DW_OP_drop: 161 s->PutCString("DW_OP_drop"); 162 break; // 0x13 163 case DW_OP_over: 164 s->PutCString("DW_OP_over"); 165 break; // 0x14 166 case DW_OP_pick: 167 s->Printf("DW_OP_pick(0x%2.2x)", m_data.GetU8(&offset)); 168 break; // 0x15 1 1-byte stack index 169 case DW_OP_swap: 170 s->PutCString("DW_OP_swap"); 171 break; // 0x16 172 case DW_OP_rot: 173 s->PutCString("DW_OP_rot"); 174 break; // 0x17 175 case DW_OP_xderef: 176 s->PutCString("DW_OP_xderef"); 177 break; // 0x18 178 case DW_OP_abs: 179 s->PutCString("DW_OP_abs"); 180 break; // 0x19 181 case DW_OP_and: 182 s->PutCString("DW_OP_and"); 183 break; // 0x1a 184 case DW_OP_div: 185 s->PutCString("DW_OP_div"); 186 break; // 0x1b 187 case DW_OP_minus: 188 s->PutCString("DW_OP_minus"); 189 break; // 0x1c 190 case DW_OP_mod: 191 s->PutCString("DW_OP_mod"); 192 break; // 0x1d 193 case DW_OP_mul: 194 s->PutCString("DW_OP_mul"); 195 break; // 0x1e 196 case DW_OP_neg: 197 s->PutCString("DW_OP_neg"); 198 break; // 0x1f 199 case DW_OP_not: 200 s->PutCString("DW_OP_not"); 201 break; // 0x20 202 case DW_OP_or: 203 s->PutCString("DW_OP_or"); 204 break; // 0x21 205 case DW_OP_plus: 206 s->PutCString("DW_OP_plus"); 207 break; // 0x22 208 case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend 209 s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ")", 210 m_data.GetULEB128(&offset)); 211 break; 212 213 case DW_OP_shl: 214 s->PutCString("DW_OP_shl"); 215 break; // 0x24 216 case DW_OP_shr: 217 s->PutCString("DW_OP_shr"); 218 break; // 0x25 219 case DW_OP_shra: 220 s->PutCString("DW_OP_shra"); 221 break; // 0x26 222 case DW_OP_xor: 223 s->PutCString("DW_OP_xor"); 224 break; // 0x27 225 case DW_OP_skip: 226 s->Printf("DW_OP_skip(0x%4.4x)", m_data.GetU16(&offset)); 227 break; // 0x2f 1 signed 2-byte constant 228 case DW_OP_bra: 229 s->Printf("DW_OP_bra(0x%4.4x)", m_data.GetU16(&offset)); 230 break; // 0x28 1 signed 2-byte constant 231 case DW_OP_eq: 232 s->PutCString("DW_OP_eq"); 233 break; // 0x29 234 case DW_OP_ge: 235 s->PutCString("DW_OP_ge"); 236 break; // 0x2a 237 case DW_OP_gt: 238 s->PutCString("DW_OP_gt"); 239 break; // 0x2b 240 case DW_OP_le: 241 s->PutCString("DW_OP_le"); 242 break; // 0x2c 243 case DW_OP_lt: 244 s->PutCString("DW_OP_lt"); 245 break; // 0x2d 246 case DW_OP_ne: 247 s->PutCString("DW_OP_ne"); 248 break; // 0x2e 249 250 case DW_OP_lit0: // 0x30 251 case DW_OP_lit1: // 0x31 252 case DW_OP_lit2: // 0x32 253 case DW_OP_lit3: // 0x33 254 case DW_OP_lit4: // 0x34 255 case DW_OP_lit5: // 0x35 256 case DW_OP_lit6: // 0x36 257 case DW_OP_lit7: // 0x37 258 case DW_OP_lit8: // 0x38 259 case DW_OP_lit9: // 0x39 260 case DW_OP_lit10: // 0x3A 261 case DW_OP_lit11: // 0x3B 262 case DW_OP_lit12: // 0x3C 263 case DW_OP_lit13: // 0x3D 264 case DW_OP_lit14: // 0x3E 265 case DW_OP_lit15: // 0x3F 266 case DW_OP_lit16: // 0x40 267 case DW_OP_lit17: // 0x41 268 case DW_OP_lit18: // 0x42 269 case DW_OP_lit19: // 0x43 270 case DW_OP_lit20: // 0x44 271 case DW_OP_lit21: // 0x45 272 case DW_OP_lit22: // 0x46 273 case DW_OP_lit23: // 0x47 274 case DW_OP_lit24: // 0x48 275 case DW_OP_lit25: // 0x49 276 case DW_OP_lit26: // 0x4A 277 case DW_OP_lit27: // 0x4B 278 case DW_OP_lit28: // 0x4C 279 case DW_OP_lit29: // 0x4D 280 case DW_OP_lit30: // 0x4E 281 case DW_OP_lit31: 282 s->Printf("DW_OP_lit%i", op - DW_OP_lit0); 283 break; // 0x4f 284 285 case DW_OP_reg0: // 0x50 286 case DW_OP_reg1: // 0x51 287 case DW_OP_reg2: // 0x52 288 case DW_OP_reg3: // 0x53 289 case DW_OP_reg4: // 0x54 290 case DW_OP_reg5: // 0x55 291 case DW_OP_reg6: // 0x56 292 case DW_OP_reg7: // 0x57 293 case DW_OP_reg8: // 0x58 294 case DW_OP_reg9: // 0x59 295 case DW_OP_reg10: // 0x5A 296 case DW_OP_reg11: // 0x5B 297 case DW_OP_reg12: // 0x5C 298 case DW_OP_reg13: // 0x5D 299 case DW_OP_reg14: // 0x5E 300 case DW_OP_reg15: // 0x5F 301 case DW_OP_reg16: // 0x60 302 case DW_OP_reg17: // 0x61 303 case DW_OP_reg18: // 0x62 304 case DW_OP_reg19: // 0x63 305 case DW_OP_reg20: // 0x64 306 case DW_OP_reg21: // 0x65 307 case DW_OP_reg22: // 0x66 308 case DW_OP_reg23: // 0x67 309 case DW_OP_reg24: // 0x68 310 case DW_OP_reg25: // 0x69 311 case DW_OP_reg26: // 0x6A 312 case DW_OP_reg27: // 0x6B 313 case DW_OP_reg28: // 0x6C 314 case DW_OP_reg29: // 0x6D 315 case DW_OP_reg30: // 0x6E 316 case DW_OP_reg31: // 0x6F 317 { 318 uint32_t reg_num = op - DW_OP_reg0; 319 if (abi) { 320 RegisterInfo reg_info; 321 if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { 322 if (reg_info.name) { 323 s->PutCString(reg_info.name); 324 break; 325 } else if (reg_info.alt_name) { 326 s->PutCString(reg_info.alt_name); 327 break; 328 } 329 } 330 } 331 s->Printf("DW_OP_reg%u", reg_num); 332 break; 333 } break; 334 335 case DW_OP_breg0: 336 case DW_OP_breg1: 337 case DW_OP_breg2: 338 case DW_OP_breg3: 339 case DW_OP_breg4: 340 case DW_OP_breg5: 341 case DW_OP_breg6: 342 case DW_OP_breg7: 343 case DW_OP_breg8: 344 case DW_OP_breg9: 345 case DW_OP_breg10: 346 case DW_OP_breg11: 347 case DW_OP_breg12: 348 case DW_OP_breg13: 349 case DW_OP_breg14: 350 case DW_OP_breg15: 351 case DW_OP_breg16: 352 case DW_OP_breg17: 353 case DW_OP_breg18: 354 case DW_OP_breg19: 355 case DW_OP_breg20: 356 case DW_OP_breg21: 357 case DW_OP_breg22: 358 case DW_OP_breg23: 359 case DW_OP_breg24: 360 case DW_OP_breg25: 361 case DW_OP_breg26: 362 case DW_OP_breg27: 363 case DW_OP_breg28: 364 case DW_OP_breg29: 365 case DW_OP_breg30: 366 case DW_OP_breg31: { 367 uint32_t reg_num = op - DW_OP_breg0; 368 int64_t reg_offset = m_data.GetSLEB128(&offset); 369 if (abi) { 370 RegisterInfo reg_info; 371 if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { 372 if (reg_info.name) { 373 s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset); 374 break; 375 } else if (reg_info.alt_name) { 376 s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset); 377 break; 378 } 379 } 380 } 381 s->Printf("DW_OP_breg%i(0x%" PRIx64 ")", reg_num, reg_offset); 382 } break; 383 384 case DW_OP_regx: // 0x90 1 ULEB128 register 385 { 386 uint32_t reg_num = m_data.GetULEB128(&offset); 387 if (abi) { 388 RegisterInfo reg_info; 389 if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { 390 if (reg_info.name) { 391 s->PutCString(reg_info.name); 392 break; 393 } else if (reg_info.alt_name) { 394 s->PutCString(reg_info.alt_name); 395 break; 396 } 397 } 398 } 399 s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num); 400 break; 401 } break; 402 case DW_OP_fbreg: // 0x91 1 SLEB128 offset 403 s->Printf("DW_OP_fbreg(%" PRIi64 ")", m_data.GetSLEB128(&offset)); 404 break; 405 case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset 406 { 407 uint32_t reg_num = m_data.GetULEB128(&offset); 408 int64_t reg_offset = m_data.GetSLEB128(&offset); 409 if (abi) { 410 RegisterInfo reg_info; 411 if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) { 412 if (reg_info.name) { 413 s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset); 414 break; 415 } else if (reg_info.alt_name) { 416 s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset); 417 break; 418 } 419 } 420 } 421 s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num, 422 reg_offset); 423 } break; 424 case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed 425 s->Printf("DW_OP_piece(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); 426 break; 427 case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved 428 s->Printf("DW_OP_deref_size(0x%2.2x)", m_data.GetU8(&offset)); 429 break; 430 case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved 431 s->Printf("DW_OP_xderef_size(0x%2.2x)", m_data.GetU8(&offset)); 432 break; 433 case DW_OP_nop: 434 s->PutCString("DW_OP_nop"); 435 break; // 0x96 436 case DW_OP_push_object_address: 437 s->PutCString("DW_OP_push_object_address"); 438 break; // 0x97 DWARF3 439 case DW_OP_call2: // 0x98 DWARF3 1 2-byte offset of DIE 440 s->Printf("DW_OP_call2(0x%4.4x)", m_data.GetU16(&offset)); 441 break; 442 case DW_OP_call4: // 0x99 DWARF3 1 4-byte offset of DIE 443 s->Printf("DW_OP_call4(0x%8.8x)", m_data.GetU32(&offset)); 444 break; 445 case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE 446 s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset)); 447 break; 448 case DW_OP_form_tls_address: 449 s->PutCString("DW_OP_form_tls_address"); // 0x9b 450 break; 451 case DW_OP_GNU_addr_index: // 0xfb 452 s->Printf("DW_OP_GNU_addr_index(0x%" PRIx64 ")", 453 m_data.GetULEB128(&offset)); 454 break; 455 case DW_OP_addrx: 456 s->Printf("DW_OP_addrx(0x%" PRIx64 ")", 457 m_data.GetULEB128(&offset)); 458 break; 459 case DW_OP_GNU_const_index: // 0xfc 460 s->Printf("DW_OP_GNU_const_index(0x%" PRIx64 ")", 461 m_data.GetULEB128(&offset)); 462 break; 463 case DW_OP_GNU_push_tls_address: 464 s->PutCString("DW_OP_GNU_push_tls_address"); // 0xe0 465 break; 466 case DW_OP_APPLE_uninit: 467 s->PutCString("DW_OP_APPLE_uninit"); // 0xF0 468 break; 469 } 470 } 471 } 472 473 void DWARFExpression::SetLocationListSlide(addr_t slide) { 474 m_loclist_slide = slide; 475 } 476 477 int DWARFExpression::GetRegisterKind() { return m_reg_kind; } 478 479 void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) { 480 m_reg_kind = reg_kind; 481 } 482 483 bool DWARFExpression::IsLocationList() const { 484 return m_loclist_slide != LLDB_INVALID_ADDRESS; 485 } 486 487 void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level, 488 addr_t location_list_base_addr, 489 ABI *abi) const { 490 if (IsLocationList()) { 491 // We have a location list 492 lldb::offset_t offset = 0; 493 uint32_t count = 0; 494 addr_t curr_base_addr = location_list_base_addr; 495 while (m_data.ValidOffset(offset)) { 496 addr_t begin_addr_offset = LLDB_INVALID_ADDRESS; 497 addr_t end_addr_offset = LLDB_INVALID_ADDRESS; 498 if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, 499 begin_addr_offset, end_addr_offset)) 500 break; 501 502 if (begin_addr_offset == 0 && end_addr_offset == 0) 503 break; 504 505 if (begin_addr_offset < end_addr_offset) { 506 if (count > 0) 507 s->PutCString(", "); 508 VMRange addr_range(curr_base_addr + begin_addr_offset, 509 curr_base_addr + end_addr_offset); 510 addr_range.Dump(s, 0, 8); 511 s->PutChar('{'); 512 lldb::offset_t location_length = m_data.GetU16(&offset); 513 DumpLocation(s, offset, location_length, level, abi); 514 s->PutChar('}'); 515 offset += location_length; 516 } else { 517 if ((m_data.GetAddressByteSize() == 4 && 518 (begin_addr_offset == UINT32_MAX)) || 519 (m_data.GetAddressByteSize() == 8 && 520 (begin_addr_offset == UINT64_MAX))) { 521 curr_base_addr = end_addr_offset + location_list_base_addr; 522 // We have a new base address 523 if (count > 0) 524 s->PutCString(", "); 525 *s << "base_addr = " << end_addr_offset; 526 } 527 } 528 529 count++; 530 } 531 } else { 532 // We have a normal location that contains DW_OP location opcodes 533 DumpLocation(s, 0, m_data.GetByteSize(), level, abi); 534 } 535 } 536 537 static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx, 538 lldb::RegisterKind reg_kind, 539 uint32_t reg_num, Status *error_ptr, 540 Value &value) { 541 if (reg_ctx == nullptr) { 542 if (error_ptr) 543 error_ptr->SetErrorStringWithFormat("No register context in frame.\n"); 544 } else { 545 uint32_t native_reg = 546 reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 547 if (native_reg == LLDB_INVALID_REGNUM) { 548 if (error_ptr) 549 error_ptr->SetErrorStringWithFormat("Unable to convert register " 550 "kind=%u reg_num=%u to a native " 551 "register number.\n", 552 reg_kind, reg_num); 553 } else { 554 const RegisterInfo *reg_info = 555 reg_ctx->GetRegisterInfoAtIndex(native_reg); 556 RegisterValue reg_value; 557 if (reg_ctx->ReadRegister(reg_info, reg_value)) { 558 if (reg_value.GetScalarValue(value.GetScalar())) { 559 value.SetValueType(Value::eValueTypeScalar); 560 value.SetContext(Value::eContextTypeRegisterInfo, 561 const_cast<RegisterInfo *>(reg_info)); 562 if (error_ptr) 563 error_ptr->Clear(); 564 return true; 565 } else { 566 // If we get this error, then we need to implement a value buffer in 567 // the dwarf expression evaluation function... 568 if (error_ptr) 569 error_ptr->SetErrorStringWithFormat( 570 "register %s can't be converted to a scalar value", 571 reg_info->name); 572 } 573 } else { 574 if (error_ptr) 575 error_ptr->SetErrorStringWithFormat("register %s is not available", 576 reg_info->name); 577 } 578 } 579 } 580 return false; 581 } 582 583 static offset_t GetOpcodeDataSize(const DataExtractor &data, 584 const lldb::offset_t data_offset, 585 const uint8_t op) { 586 lldb::offset_t offset = data_offset; 587 switch (op) { 588 case DW_OP_addr: 589 case DW_OP_call_ref: // 0x9a 1 address sized offset of DIE (DWARF3) 590 return data.GetAddressByteSize(); 591 592 // Opcodes with no arguments 593 case DW_OP_deref: // 0x06 594 case DW_OP_dup: // 0x12 595 case DW_OP_drop: // 0x13 596 case DW_OP_over: // 0x14 597 case DW_OP_swap: // 0x16 598 case DW_OP_rot: // 0x17 599 case DW_OP_xderef: // 0x18 600 case DW_OP_abs: // 0x19 601 case DW_OP_and: // 0x1a 602 case DW_OP_div: // 0x1b 603 case DW_OP_minus: // 0x1c 604 case DW_OP_mod: // 0x1d 605 case DW_OP_mul: // 0x1e 606 case DW_OP_neg: // 0x1f 607 case DW_OP_not: // 0x20 608 case DW_OP_or: // 0x21 609 case DW_OP_plus: // 0x22 610 case DW_OP_shl: // 0x24 611 case DW_OP_shr: // 0x25 612 case DW_OP_shra: // 0x26 613 case DW_OP_xor: // 0x27 614 case DW_OP_eq: // 0x29 615 case DW_OP_ge: // 0x2a 616 case DW_OP_gt: // 0x2b 617 case DW_OP_le: // 0x2c 618 case DW_OP_lt: // 0x2d 619 case DW_OP_ne: // 0x2e 620 case DW_OP_lit0: // 0x30 621 case DW_OP_lit1: // 0x31 622 case DW_OP_lit2: // 0x32 623 case DW_OP_lit3: // 0x33 624 case DW_OP_lit4: // 0x34 625 case DW_OP_lit5: // 0x35 626 case DW_OP_lit6: // 0x36 627 case DW_OP_lit7: // 0x37 628 case DW_OP_lit8: // 0x38 629 case DW_OP_lit9: // 0x39 630 case DW_OP_lit10: // 0x3A 631 case DW_OP_lit11: // 0x3B 632 case DW_OP_lit12: // 0x3C 633 case DW_OP_lit13: // 0x3D 634 case DW_OP_lit14: // 0x3E 635 case DW_OP_lit15: // 0x3F 636 case DW_OP_lit16: // 0x40 637 case DW_OP_lit17: // 0x41 638 case DW_OP_lit18: // 0x42 639 case DW_OP_lit19: // 0x43 640 case DW_OP_lit20: // 0x44 641 case DW_OP_lit21: // 0x45 642 case DW_OP_lit22: // 0x46 643 case DW_OP_lit23: // 0x47 644 case DW_OP_lit24: // 0x48 645 case DW_OP_lit25: // 0x49 646 case DW_OP_lit26: // 0x4A 647 case DW_OP_lit27: // 0x4B 648 case DW_OP_lit28: // 0x4C 649 case DW_OP_lit29: // 0x4D 650 case DW_OP_lit30: // 0x4E 651 case DW_OP_lit31: // 0x4f 652 case DW_OP_reg0: // 0x50 653 case DW_OP_reg1: // 0x51 654 case DW_OP_reg2: // 0x52 655 case DW_OP_reg3: // 0x53 656 case DW_OP_reg4: // 0x54 657 case DW_OP_reg5: // 0x55 658 case DW_OP_reg6: // 0x56 659 case DW_OP_reg7: // 0x57 660 case DW_OP_reg8: // 0x58 661 case DW_OP_reg9: // 0x59 662 case DW_OP_reg10: // 0x5A 663 case DW_OP_reg11: // 0x5B 664 case DW_OP_reg12: // 0x5C 665 case DW_OP_reg13: // 0x5D 666 case DW_OP_reg14: // 0x5E 667 case DW_OP_reg15: // 0x5F 668 case DW_OP_reg16: // 0x60 669 case DW_OP_reg17: // 0x61 670 case DW_OP_reg18: // 0x62 671 case DW_OP_reg19: // 0x63 672 case DW_OP_reg20: // 0x64 673 case DW_OP_reg21: // 0x65 674 case DW_OP_reg22: // 0x66 675 case DW_OP_reg23: // 0x67 676 case DW_OP_reg24: // 0x68 677 case DW_OP_reg25: // 0x69 678 case DW_OP_reg26: // 0x6A 679 case DW_OP_reg27: // 0x6B 680 case DW_OP_reg28: // 0x6C 681 case DW_OP_reg29: // 0x6D 682 case DW_OP_reg30: // 0x6E 683 case DW_OP_reg31: // 0x6F 684 case DW_OP_nop: // 0x96 685 case DW_OP_push_object_address: // 0x97 DWARF3 686 case DW_OP_form_tls_address: // 0x9b DWARF3 687 case DW_OP_call_frame_cfa: // 0x9c DWARF3 688 case DW_OP_stack_value: // 0x9f DWARF4 689 case DW_OP_GNU_push_tls_address: // 0xe0 GNU extension 690 return 0; 691 692 // Opcodes with a single 1 byte arguments 693 case DW_OP_const1u: // 0x08 1 1-byte constant 694 case DW_OP_const1s: // 0x09 1 1-byte constant 695 case DW_OP_pick: // 0x15 1 1-byte stack index 696 case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved 697 case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved 698 return 1; 699 700 // Opcodes with a single 2 byte arguments 701 case DW_OP_const2u: // 0x0a 1 2-byte constant 702 case DW_OP_const2s: // 0x0b 1 2-byte constant 703 case DW_OP_skip: // 0x2f 1 signed 2-byte constant 704 case DW_OP_bra: // 0x28 1 signed 2-byte constant 705 case DW_OP_call2: // 0x98 1 2-byte offset of DIE (DWARF3) 706 return 2; 707 708 // Opcodes with a single 4 byte arguments 709 case DW_OP_const4u: // 0x0c 1 4-byte constant 710 case DW_OP_const4s: // 0x0d 1 4-byte constant 711 case DW_OP_call4: // 0x99 1 4-byte offset of DIE (DWARF3) 712 return 4; 713 714 // Opcodes with a single 8 byte arguments 715 case DW_OP_const8u: // 0x0e 1 8-byte constant 716 case DW_OP_const8s: // 0x0f 1 8-byte constant 717 return 8; 718 719 // All opcodes that have a single ULEB (signed or unsigned) argument 720 case DW_OP_addrx: // 0xa1 1 ULEB128 index 721 case DW_OP_constu: // 0x10 1 ULEB128 constant 722 case DW_OP_consts: // 0x11 1 SLEB128 constant 723 case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend 724 case DW_OP_breg0: // 0x70 1 ULEB128 register 725 case DW_OP_breg1: // 0x71 1 ULEB128 register 726 case DW_OP_breg2: // 0x72 1 ULEB128 register 727 case DW_OP_breg3: // 0x73 1 ULEB128 register 728 case DW_OP_breg4: // 0x74 1 ULEB128 register 729 case DW_OP_breg5: // 0x75 1 ULEB128 register 730 case DW_OP_breg6: // 0x76 1 ULEB128 register 731 case DW_OP_breg7: // 0x77 1 ULEB128 register 732 case DW_OP_breg8: // 0x78 1 ULEB128 register 733 case DW_OP_breg9: // 0x79 1 ULEB128 register 734 case DW_OP_breg10: // 0x7a 1 ULEB128 register 735 case DW_OP_breg11: // 0x7b 1 ULEB128 register 736 case DW_OP_breg12: // 0x7c 1 ULEB128 register 737 case DW_OP_breg13: // 0x7d 1 ULEB128 register 738 case DW_OP_breg14: // 0x7e 1 ULEB128 register 739 case DW_OP_breg15: // 0x7f 1 ULEB128 register 740 case DW_OP_breg16: // 0x80 1 ULEB128 register 741 case DW_OP_breg17: // 0x81 1 ULEB128 register 742 case DW_OP_breg18: // 0x82 1 ULEB128 register 743 case DW_OP_breg19: // 0x83 1 ULEB128 register 744 case DW_OP_breg20: // 0x84 1 ULEB128 register 745 case DW_OP_breg21: // 0x85 1 ULEB128 register 746 case DW_OP_breg22: // 0x86 1 ULEB128 register 747 case DW_OP_breg23: // 0x87 1 ULEB128 register 748 case DW_OP_breg24: // 0x88 1 ULEB128 register 749 case DW_OP_breg25: // 0x89 1 ULEB128 register 750 case DW_OP_breg26: // 0x8a 1 ULEB128 register 751 case DW_OP_breg27: // 0x8b 1 ULEB128 register 752 case DW_OP_breg28: // 0x8c 1 ULEB128 register 753 case DW_OP_breg29: // 0x8d 1 ULEB128 register 754 case DW_OP_breg30: // 0x8e 1 ULEB128 register 755 case DW_OP_breg31: // 0x8f 1 ULEB128 register 756 case DW_OP_regx: // 0x90 1 ULEB128 register 757 case DW_OP_fbreg: // 0x91 1 SLEB128 offset 758 case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed 759 case DW_OP_GNU_addr_index: // 0xfb 1 ULEB128 index 760 case DW_OP_GNU_const_index: // 0xfc 1 ULEB128 index 761 data.Skip_LEB128(&offset); 762 return offset - data_offset; 763 764 // All opcodes that have a 2 ULEB (signed or unsigned) arguments 765 case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset 766 case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3); 767 data.Skip_LEB128(&offset); 768 data.Skip_LEB128(&offset); 769 return offset - data_offset; 770 771 case DW_OP_implicit_value: // 0x9e ULEB128 size followed by block of that size 772 // (DWARF4) 773 { 774 uint64_t block_len = data.Skip_LEB128(&offset); 775 offset += block_len; 776 return offset - data_offset; 777 } 778 779 default: 780 break; 781 } 782 return LLDB_INVALID_OFFSET; 783 } 784 785 lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx, 786 bool &error) const { 787 error = false; 788 if (IsLocationList()) 789 return LLDB_INVALID_ADDRESS; 790 lldb::offset_t offset = 0; 791 uint32_t curr_op_addr_idx = 0; 792 while (m_data.ValidOffset(offset)) { 793 const uint8_t op = m_data.GetU8(&offset); 794 795 if (op == DW_OP_addr) { 796 const lldb::addr_t op_file_addr = m_data.GetAddress(&offset); 797 if (curr_op_addr_idx == op_addr_idx) 798 return op_file_addr; 799 else 800 ++curr_op_addr_idx; 801 } else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) { 802 uint64_t index = m_data.GetULEB128(&offset); 803 if (curr_op_addr_idx == op_addr_idx) { 804 if (!m_dwarf_cu) { 805 error = true; 806 break; 807 } 808 809 return ReadAddressFromDebugAddrSection(m_dwarf_cu, index); 810 } else 811 ++curr_op_addr_idx; 812 } else { 813 const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op); 814 if (op_arg_size == LLDB_INVALID_OFFSET) { 815 error = true; 816 break; 817 } 818 offset += op_arg_size; 819 } 820 } 821 return LLDB_INVALID_ADDRESS; 822 } 823 824 bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) { 825 if (IsLocationList()) 826 return false; 827 lldb::offset_t offset = 0; 828 while (m_data.ValidOffset(offset)) { 829 const uint8_t op = m_data.GetU8(&offset); 830 831 if (op == DW_OP_addr) { 832 const uint32_t addr_byte_size = m_data.GetAddressByteSize(); 833 // We have to make a copy of the data as we don't know if this data is 834 // from a read only memory mapped buffer, so we duplicate all of the data 835 // first, then modify it, and if all goes well, we then replace the data 836 // for this expression 837 838 // So first we copy the data into a heap buffer 839 std::unique_ptr<DataBufferHeap> head_data_up( 840 new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize())); 841 842 // Make en encoder so we can write the address into the buffer using the 843 // correct byte order (endianness) 844 DataEncoder encoder(head_data_up->GetBytes(), head_data_up->GetByteSize(), 845 m_data.GetByteOrder(), addr_byte_size); 846 847 // Replace the address in the new buffer 848 if (encoder.PutMaxU64(offset, addr_byte_size, file_addr) == UINT32_MAX) 849 return false; 850 851 // All went well, so now we can reset the data using a shared pointer to 852 // the heap data so "m_data" will now correctly manage the heap data. 853 m_data.SetData(DataBufferSP(head_data_up.release())); 854 return true; 855 } else { 856 const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op); 857 if (op_arg_size == LLDB_INVALID_OFFSET) 858 break; 859 offset += op_arg_size; 860 } 861 } 862 return false; 863 } 864 865 bool DWARFExpression::ContainsThreadLocalStorage() const { 866 // We are assuming for now that any thread local variable will not have a 867 // location list. This has been true for all thread local variables we have 868 // seen so far produced by any compiler. 869 if (IsLocationList()) 870 return false; 871 lldb::offset_t offset = 0; 872 while (m_data.ValidOffset(offset)) { 873 const uint8_t op = m_data.GetU8(&offset); 874 875 if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address) 876 return true; 877 const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op); 878 if (op_arg_size == LLDB_INVALID_OFFSET) 879 return false; 880 else 881 offset += op_arg_size; 882 } 883 return false; 884 } 885 bool DWARFExpression::LinkThreadLocalStorage( 886 lldb::ModuleSP new_module_sp, 887 std::function<lldb::addr_t(lldb::addr_t file_addr)> const 888 &link_address_callback) { 889 // We are assuming for now that any thread local variable will not have a 890 // location list. This has been true for all thread local variables we have 891 // seen so far produced by any compiler. 892 if (IsLocationList()) 893 return false; 894 895 const uint32_t addr_byte_size = m_data.GetAddressByteSize(); 896 // We have to make a copy of the data as we don't know if this data is from a 897 // read only memory mapped buffer, so we duplicate all of the data first, 898 // then modify it, and if all goes well, we then replace the data for this 899 // expression 900 901 // So first we copy the data into a heap buffer 902 std::shared_ptr<DataBufferHeap> heap_data_sp( 903 new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize())); 904 905 // Make en encoder so we can write the address into the buffer using the 906 // correct byte order (endianness) 907 DataEncoder encoder(heap_data_sp->GetBytes(), heap_data_sp->GetByteSize(), 908 m_data.GetByteOrder(), addr_byte_size); 909 910 lldb::offset_t offset = 0; 911 lldb::offset_t const_offset = 0; 912 lldb::addr_t const_value = 0; 913 size_t const_byte_size = 0; 914 while (m_data.ValidOffset(offset)) { 915 const uint8_t op = m_data.GetU8(&offset); 916 917 bool decoded_data = false; 918 switch (op) { 919 case DW_OP_const4u: 920 // Remember the const offset in case we later have a 921 // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address 922 const_offset = offset; 923 const_value = m_data.GetU32(&offset); 924 decoded_data = true; 925 const_byte_size = 4; 926 break; 927 928 case DW_OP_const8u: 929 // Remember the const offset in case we later have a 930 // DW_OP_form_tls_address or DW_OP_GNU_push_tls_address 931 const_offset = offset; 932 const_value = m_data.GetU64(&offset); 933 decoded_data = true; 934 const_byte_size = 8; 935 break; 936 937 case DW_OP_form_tls_address: 938 case DW_OP_GNU_push_tls_address: 939 // DW_OP_form_tls_address and DW_OP_GNU_push_tls_address must be preceded 940 // by a file address on the stack. We assume that DW_OP_const4u or 941 // DW_OP_const8u is used for these values, and we check that the last 942 // opcode we got before either of these was DW_OP_const4u or 943 // DW_OP_const8u. If so, then we can link the value accodingly. For 944 // Darwin, the value in the DW_OP_const4u or DW_OP_const8u is the file 945 // address of a structure that contains a function pointer, the pthread 946 // key and the offset into the data pointed to by the pthread key. So we 947 // must link this address and also set the module of this expression to 948 // the new_module_sp so we can resolve the file address correctly 949 if (const_byte_size > 0) { 950 lldb::addr_t linked_file_addr = link_address_callback(const_value); 951 if (linked_file_addr == LLDB_INVALID_ADDRESS) 952 return false; 953 // Replace the address in the new buffer 954 if (encoder.PutMaxU64(const_offset, const_byte_size, 955 linked_file_addr) == UINT32_MAX) 956 return false; 957 } 958 break; 959 960 default: 961 const_offset = 0; 962 const_value = 0; 963 const_byte_size = 0; 964 break; 965 } 966 967 if (!decoded_data) { 968 const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op); 969 if (op_arg_size == LLDB_INVALID_OFFSET) 970 return false; 971 else 972 offset += op_arg_size; 973 } 974 } 975 976 // If we linked the TLS address correctly, update the module so that when the 977 // expression is evaluated it can resolve the file address to a load address 978 // and read the 979 // TLS data 980 m_module_wp = new_module_sp; 981 m_data.SetData(heap_data_sp); 982 return true; 983 } 984 985 bool DWARFExpression::LocationListContainsAddress( 986 lldb::addr_t loclist_base_addr, lldb::addr_t addr) const { 987 if (addr == LLDB_INVALID_ADDRESS) 988 return false; 989 990 if (IsLocationList()) { 991 lldb::offset_t offset = 0; 992 993 if (loclist_base_addr == LLDB_INVALID_ADDRESS) 994 return false; 995 996 while (m_data.ValidOffset(offset)) { 997 // We need to figure out what the value is for the location. 998 addr_t lo_pc = LLDB_INVALID_ADDRESS; 999 addr_t hi_pc = LLDB_INVALID_ADDRESS; 1000 if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, lo_pc, 1001 hi_pc)) 1002 break; 1003 1004 if (lo_pc == 0 && hi_pc == 0) 1005 break; 1006 1007 lo_pc += loclist_base_addr - m_loclist_slide; 1008 hi_pc += loclist_base_addr - m_loclist_slide; 1009 1010 if (lo_pc <= addr && addr < hi_pc) 1011 return true; 1012 1013 offset += m_data.GetU16(&offset); 1014 } 1015 } 1016 return false; 1017 } 1018 1019 bool DWARFExpression::GetLocation(addr_t base_addr, addr_t pc, 1020 lldb::offset_t &offset, 1021 lldb::offset_t &length) { 1022 offset = 0; 1023 if (!IsLocationList()) { 1024 length = m_data.GetByteSize(); 1025 return true; 1026 } 1027 1028 if (base_addr != LLDB_INVALID_ADDRESS && pc != LLDB_INVALID_ADDRESS) { 1029 addr_t curr_base_addr = base_addr; 1030 1031 while (m_data.ValidOffset(offset)) { 1032 // We need to figure out what the value is for the location. 1033 addr_t lo_pc = LLDB_INVALID_ADDRESS; 1034 addr_t hi_pc = LLDB_INVALID_ADDRESS; 1035 if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, lo_pc, 1036 hi_pc)) 1037 break; 1038 1039 if (lo_pc == 0 && hi_pc == 0) 1040 break; 1041 1042 lo_pc += curr_base_addr - m_loclist_slide; 1043 hi_pc += curr_base_addr - m_loclist_slide; 1044 1045 length = m_data.GetU16(&offset); 1046 1047 if (length > 0 && lo_pc <= pc && pc < hi_pc) 1048 return true; 1049 1050 offset += length; 1051 } 1052 } 1053 offset = LLDB_INVALID_OFFSET; 1054 length = 0; 1055 return false; 1056 } 1057 1058 bool DWARFExpression::DumpLocationForAddress(Stream *s, 1059 lldb::DescriptionLevel level, 1060 addr_t base_addr, addr_t address, 1061 ABI *abi) { 1062 lldb::offset_t offset = 0; 1063 lldb::offset_t length = 0; 1064 1065 if (GetLocation(base_addr, address, offset, length)) { 1066 if (length > 0) { 1067 DumpLocation(s, offset, length, level, abi); 1068 return true; 1069 } 1070 } 1071 return false; 1072 } 1073 1074 bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope, 1075 lldb::addr_t loclist_base_load_addr, 1076 const Value *initial_value_ptr, 1077 const Value *object_address_ptr, Value &result, 1078 Status *error_ptr) const { 1079 ExecutionContext exe_ctx(exe_scope); 1080 return Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, initial_value_ptr, 1081 object_address_ptr, result, error_ptr); 1082 } 1083 1084 bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx, 1085 RegisterContext *reg_ctx, 1086 lldb::addr_t loclist_base_load_addr, 1087 const Value *initial_value_ptr, 1088 const Value *object_address_ptr, Value &result, 1089 Status *error_ptr) const { 1090 ModuleSP module_sp = m_module_wp.lock(); 1091 1092 if (IsLocationList()) { 1093 lldb::offset_t offset = 0; 1094 addr_t pc; 1095 StackFrame *frame = nullptr; 1096 if (reg_ctx) 1097 pc = reg_ctx->GetPC(); 1098 else { 1099 frame = exe_ctx->GetFramePtr(); 1100 if (!frame) 1101 return false; 1102 RegisterContextSP reg_ctx_sp = frame->GetRegisterContext(); 1103 if (!reg_ctx_sp) 1104 return false; 1105 pc = reg_ctx_sp->GetPC(); 1106 } 1107 1108 if (loclist_base_load_addr != LLDB_INVALID_ADDRESS) { 1109 if (pc == LLDB_INVALID_ADDRESS) { 1110 if (error_ptr) 1111 error_ptr->SetErrorString("Invalid PC in frame."); 1112 return false; 1113 } 1114 1115 addr_t curr_loclist_base_load_addr = loclist_base_load_addr; 1116 1117 while (m_data.ValidOffset(offset)) { 1118 // We need to figure out what the value is for the location. 1119 addr_t lo_pc = LLDB_INVALID_ADDRESS; 1120 addr_t hi_pc = LLDB_INVALID_ADDRESS; 1121 if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, 1122 lo_pc, hi_pc)) 1123 break; 1124 1125 if (lo_pc == 0 && hi_pc == 0) 1126 break; 1127 1128 lo_pc += curr_loclist_base_load_addr - m_loclist_slide; 1129 hi_pc += curr_loclist_base_load_addr - m_loclist_slide; 1130 1131 uint16_t length = m_data.GetU16(&offset); 1132 1133 if (length > 0 && lo_pc <= pc && pc < hi_pc) { 1134 return DWARFExpression::Evaluate( 1135 exe_ctx, reg_ctx, module_sp, 1136 DataExtractor(m_data, offset, length), m_dwarf_cu, m_reg_kind, 1137 initial_value_ptr, object_address_ptr, result, error_ptr); 1138 } 1139 offset += length; 1140 } 1141 } 1142 if (error_ptr) 1143 error_ptr->SetErrorString("variable not available"); 1144 return false; 1145 } 1146 1147 // Not a location list, just a single expression. 1148 return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, m_data, 1149 m_dwarf_cu, m_reg_kind, initial_value_ptr, 1150 object_address_ptr, result, error_ptr); 1151 } 1152 1153 bool DWARFExpression::Evaluate( 1154 ExecutionContext *exe_ctx, RegisterContext *reg_ctx, 1155 lldb::ModuleSP module_sp, const DataExtractor &opcodes, 1156 const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind, 1157 const Value *initial_value_ptr, const Value *object_address_ptr, 1158 Value &result, Status *error_ptr) { 1159 1160 if (opcodes.GetByteSize() == 0) { 1161 if (error_ptr) 1162 error_ptr->SetErrorString( 1163 "no location, value may have been optimized out"); 1164 return false; 1165 } 1166 std::vector<Value> stack; 1167 1168 Process *process = nullptr; 1169 StackFrame *frame = nullptr; 1170 1171 if (exe_ctx) { 1172 process = exe_ctx->GetProcessPtr(); 1173 frame = exe_ctx->GetFramePtr(); 1174 } 1175 if (reg_ctx == nullptr && frame) 1176 reg_ctx = frame->GetRegisterContext().get(); 1177 1178 if (initial_value_ptr) 1179 stack.push_back(*initial_value_ptr); 1180 1181 lldb::offset_t offset = 0; 1182 Value tmp; 1183 uint32_t reg_num; 1184 1185 /// Insertion point for evaluating multi-piece expression. 1186 uint64_t op_piece_offset = 0; 1187 Value pieces; // Used for DW_OP_piece 1188 1189 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1190 1191 while (opcodes.ValidOffset(offset)) { 1192 const lldb::offset_t op_offset = offset; 1193 const uint8_t op = opcodes.GetU8(&offset); 1194 1195 if (log && log->GetVerbose()) { 1196 size_t count = stack.size(); 1197 LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:", 1198 (uint64_t)count); 1199 for (size_t i = 0; i < count; ++i) { 1200 StreamString new_value; 1201 new_value.Printf("[%" PRIu64 "]", (uint64_t)i); 1202 stack[i].Dump(&new_value); 1203 LLDB_LOGF(log, " %s", new_value.GetData()); 1204 } 1205 LLDB_LOGF(log, "0x%8.8" PRIx64 ": %s", op_offset, 1206 DW_OP_value_to_name(op)); 1207 } 1208 1209 switch (op) { 1210 // The DW_OP_addr operation has a single operand that encodes a machine 1211 // address and whose size is the size of an address on the target machine. 1212 case DW_OP_addr: 1213 stack.push_back(Scalar(opcodes.GetAddress(&offset))); 1214 stack.back().SetValueType(Value::eValueTypeFileAddress); 1215 // Convert the file address to a load address, so subsequent 1216 // DWARF operators can operate on it. 1217 if (frame) 1218 stack.back().ConvertToLoadAddress(module_sp.get(), 1219 frame->CalculateTarget().get()); 1220 break; 1221 1222 // The DW_OP_addr_sect_offset4 is used for any location expressions in 1223 // shared libraries that have a location like: 1224 // DW_OP_addr(0x1000) 1225 // If this address resides in a shared library, then this virtual address 1226 // won't make sense when it is evaluated in the context of a running 1227 // process where shared libraries have been slid. To account for this, this 1228 // new address type where we can store the section pointer and a 4 byte 1229 // offset. 1230 // case DW_OP_addr_sect_offset4: 1231 // { 1232 // result_type = eResultTypeFileAddress; 1233 // lldb::Section *sect = (lldb::Section 1234 // *)opcodes.GetMaxU64(&offset, sizeof(void *)); 1235 // lldb::addr_t sect_offset = opcodes.GetU32(&offset); 1236 // 1237 // Address so_addr (sect, sect_offset); 1238 // lldb::addr_t load_addr = so_addr.GetLoadAddress(); 1239 // if (load_addr != LLDB_INVALID_ADDRESS) 1240 // { 1241 // // We successfully resolve a file address to a load 1242 // // address. 1243 // stack.push_back(load_addr); 1244 // break; 1245 // } 1246 // else 1247 // { 1248 // // We were able 1249 // if (error_ptr) 1250 // error_ptr->SetErrorStringWithFormat ("Section %s in 1251 // %s is not currently loaded.\n", 1252 // sect->GetName().AsCString(), 1253 // sect->GetModule()->GetFileSpec().GetFilename().AsCString()); 1254 // return false; 1255 // } 1256 // } 1257 // break; 1258 1259 // OPCODE: DW_OP_deref 1260 // OPERANDS: none 1261 // DESCRIPTION: Pops the top stack entry and treats it as an address. 1262 // The value retrieved from that address is pushed. The size of the data 1263 // retrieved from the dereferenced address is the size of an address on the 1264 // target machine. 1265 case DW_OP_deref: { 1266 if (stack.empty()) { 1267 if (error_ptr) 1268 error_ptr->SetErrorString("Expression stack empty for DW_OP_deref."); 1269 return false; 1270 } 1271 Value::ValueType value_type = stack.back().GetValueType(); 1272 switch (value_type) { 1273 case Value::eValueTypeHostAddress: { 1274 void *src = (void *)stack.back().GetScalar().ULongLong(); 1275 intptr_t ptr; 1276 ::memcpy(&ptr, src, sizeof(void *)); 1277 stack.back().GetScalar() = ptr; 1278 stack.back().ClearContext(); 1279 } break; 1280 case Value::eValueTypeFileAddress: { 1281 auto file_addr = stack.back().GetScalar().ULongLong( 1282 LLDB_INVALID_ADDRESS); 1283 if (!module_sp) { 1284 if (error_ptr) 1285 error_ptr->SetErrorStringWithFormat( 1286 "need module to resolve file address for DW_OP_deref"); 1287 return false; 1288 } 1289 Address so_addr; 1290 if (!module_sp->ResolveFileAddress(file_addr, so_addr)) { 1291 if (error_ptr) 1292 error_ptr->SetErrorStringWithFormat( 1293 "failed to resolve file address in module"); 1294 return false; 1295 } 1296 addr_t load_Addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr()); 1297 if (load_Addr == LLDB_INVALID_ADDRESS) { 1298 if (error_ptr) 1299 error_ptr->SetErrorStringWithFormat( 1300 "failed to resolve load address"); 1301 return false; 1302 } 1303 stack.back().GetScalar() = load_Addr; 1304 stack.back().SetValueType(Value::eValueTypeLoadAddress); 1305 // Fall through to load address code below... 1306 } LLVM_FALLTHROUGH; 1307 case Value::eValueTypeLoadAddress: 1308 if (exe_ctx) { 1309 if (process) { 1310 lldb::addr_t pointer_addr = 1311 stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1312 Status error; 1313 lldb::addr_t pointer_value = 1314 process->ReadPointerFromMemory(pointer_addr, error); 1315 if (pointer_value != LLDB_INVALID_ADDRESS) { 1316 stack.back().GetScalar() = pointer_value; 1317 stack.back().ClearContext(); 1318 } else { 1319 if (error_ptr) 1320 error_ptr->SetErrorStringWithFormat( 1321 "Failed to dereference pointer from 0x%" PRIx64 1322 " for DW_OP_deref: %s\n", 1323 pointer_addr, error.AsCString()); 1324 return false; 1325 } 1326 } else { 1327 if (error_ptr) 1328 error_ptr->SetErrorStringWithFormat( 1329 "NULL process for DW_OP_deref.\n"); 1330 return false; 1331 } 1332 } else { 1333 if (error_ptr) 1334 error_ptr->SetErrorStringWithFormat( 1335 "NULL execution context for DW_OP_deref.\n"); 1336 return false; 1337 } 1338 break; 1339 1340 default: 1341 break; 1342 } 1343 1344 } break; 1345 1346 // OPCODE: DW_OP_deref_size 1347 // OPERANDS: 1 1348 // 1 - uint8_t that specifies the size of the data to dereference. 1349 // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top 1350 // stack entry and treats it as an address. The value retrieved from that 1351 // address is pushed. In the DW_OP_deref_size operation, however, the size 1352 // in bytes of the data retrieved from the dereferenced address is 1353 // specified by the single operand. This operand is a 1-byte unsigned 1354 // integral constant whose value may not be larger than the size of an 1355 // address on the target machine. The data retrieved is zero extended to 1356 // the size of an address on the target machine before being pushed on the 1357 // expression stack. 1358 case DW_OP_deref_size: { 1359 if (stack.empty()) { 1360 if (error_ptr) 1361 error_ptr->SetErrorString( 1362 "Expression stack empty for DW_OP_deref_size."); 1363 return false; 1364 } 1365 uint8_t size = opcodes.GetU8(&offset); 1366 Value::ValueType value_type = stack.back().GetValueType(); 1367 switch (value_type) { 1368 case Value::eValueTypeHostAddress: { 1369 void *src = (void *)stack.back().GetScalar().ULongLong(); 1370 intptr_t ptr; 1371 ::memcpy(&ptr, src, sizeof(void *)); 1372 // I can't decide whether the size operand should apply to the bytes in 1373 // their 1374 // lldb-host endianness or the target endianness.. I doubt this'll ever 1375 // come up but I'll opt for assuming big endian regardless. 1376 switch (size) { 1377 case 1: 1378 ptr = ptr & 0xff; 1379 break; 1380 case 2: 1381 ptr = ptr & 0xffff; 1382 break; 1383 case 3: 1384 ptr = ptr & 0xffffff; 1385 break; 1386 case 4: 1387 ptr = ptr & 0xffffffff; 1388 break; 1389 // the casts are added to work around the case where intptr_t is a 32 1390 // bit quantity; 1391 // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this 1392 // program. 1393 case 5: 1394 ptr = (intptr_t)ptr & 0xffffffffffULL; 1395 break; 1396 case 6: 1397 ptr = (intptr_t)ptr & 0xffffffffffffULL; 1398 break; 1399 case 7: 1400 ptr = (intptr_t)ptr & 0xffffffffffffffULL; 1401 break; 1402 default: 1403 break; 1404 } 1405 stack.back().GetScalar() = ptr; 1406 stack.back().ClearContext(); 1407 } break; 1408 case Value::eValueTypeLoadAddress: 1409 if (exe_ctx) { 1410 if (process) { 1411 lldb::addr_t pointer_addr = 1412 stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1413 uint8_t addr_bytes[sizeof(lldb::addr_t)]; 1414 Status error; 1415 if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) == 1416 size) { 1417 DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), 1418 process->GetByteOrder(), size); 1419 lldb::offset_t addr_data_offset = 0; 1420 switch (size) { 1421 case 1: 1422 stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset); 1423 break; 1424 case 2: 1425 stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset); 1426 break; 1427 case 4: 1428 stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset); 1429 break; 1430 case 8: 1431 stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset); 1432 break; 1433 default: 1434 stack.back().GetScalar() = 1435 addr_data.GetPointer(&addr_data_offset); 1436 } 1437 stack.back().ClearContext(); 1438 } else { 1439 if (error_ptr) 1440 error_ptr->SetErrorStringWithFormat( 1441 "Failed to dereference pointer from 0x%" PRIx64 1442 " for DW_OP_deref: %s\n", 1443 pointer_addr, error.AsCString()); 1444 return false; 1445 } 1446 } else { 1447 if (error_ptr) 1448 error_ptr->SetErrorStringWithFormat( 1449 "NULL process for DW_OP_deref.\n"); 1450 return false; 1451 } 1452 } else { 1453 if (error_ptr) 1454 error_ptr->SetErrorStringWithFormat( 1455 "NULL execution context for DW_OP_deref.\n"); 1456 return false; 1457 } 1458 break; 1459 1460 default: 1461 break; 1462 } 1463 1464 } break; 1465 1466 // OPCODE: DW_OP_xderef_size 1467 // OPERANDS: 1 1468 // 1 - uint8_t that specifies the size of the data to dereference. 1469 // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at 1470 // the top of the stack is treated as an address. The second stack entry is 1471 // treated as an "address space identifier" for those architectures that 1472 // support multiple address spaces. The top two stack elements are popped, 1473 // a data item is retrieved through an implementation-defined address 1474 // calculation and pushed as the new stack top. In the DW_OP_xderef_size 1475 // operation, however, the size in bytes of the data retrieved from the 1476 // dereferenced address is specified by the single operand. This operand is 1477 // a 1-byte unsigned integral constant whose value may not be larger than 1478 // the size of an address on the target machine. The data retrieved is zero 1479 // extended to the size of an address on the target machine before being 1480 // pushed on the expression stack. 1481 case DW_OP_xderef_size: 1482 if (error_ptr) 1483 error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef_size."); 1484 return false; 1485 // OPCODE: DW_OP_xderef 1486 // OPERANDS: none 1487 // DESCRIPTION: Provides an extended dereference mechanism. The entry at 1488 // the top of the stack is treated as an address. The second stack entry is 1489 // treated as an "address space identifier" for those architectures that 1490 // support multiple address spaces. The top two stack elements are popped, 1491 // a data item is retrieved through an implementation-defined address 1492 // calculation and pushed as the new stack top. The size of the data 1493 // retrieved from the dereferenced address is the size of an address on the 1494 // target machine. 1495 case DW_OP_xderef: 1496 if (error_ptr) 1497 error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef."); 1498 return false; 1499 1500 // All DW_OP_constXXX opcodes have a single operand as noted below: 1501 // 1502 // Opcode Operand 1 1503 // DW_OP_const1u 1-byte unsigned integer constant DW_OP_const1s 1504 // 1-byte signed integer constant DW_OP_const2u 2-byte unsigned integer 1505 // constant DW_OP_const2s 2-byte signed integer constant DW_OP_const4u 1506 // 4-byte unsigned integer constant DW_OP_const4s 4-byte signed integer 1507 // constant DW_OP_const8u 8-byte unsigned integer constant DW_OP_const8s 1508 // 8-byte signed integer constant DW_OP_constu unsigned LEB128 integer 1509 // constant DW_OP_consts signed LEB128 integer constant 1510 case DW_OP_const1u: 1511 stack.push_back(Scalar((uint8_t)opcodes.GetU8(&offset))); 1512 break; 1513 case DW_OP_const1s: 1514 stack.push_back(Scalar((int8_t)opcodes.GetU8(&offset))); 1515 break; 1516 case DW_OP_const2u: 1517 stack.push_back(Scalar((uint16_t)opcodes.GetU16(&offset))); 1518 break; 1519 case DW_OP_const2s: 1520 stack.push_back(Scalar((int16_t)opcodes.GetU16(&offset))); 1521 break; 1522 case DW_OP_const4u: 1523 stack.push_back(Scalar((uint32_t)opcodes.GetU32(&offset))); 1524 break; 1525 case DW_OP_const4s: 1526 stack.push_back(Scalar((int32_t)opcodes.GetU32(&offset))); 1527 break; 1528 case DW_OP_const8u: 1529 stack.push_back(Scalar((uint64_t)opcodes.GetU64(&offset))); 1530 break; 1531 case DW_OP_const8s: 1532 stack.push_back(Scalar((int64_t)opcodes.GetU64(&offset))); 1533 break; 1534 case DW_OP_constu: 1535 stack.push_back(Scalar(opcodes.GetULEB128(&offset))); 1536 break; 1537 case DW_OP_consts: 1538 stack.push_back(Scalar(opcodes.GetSLEB128(&offset))); 1539 break; 1540 1541 // OPCODE: DW_OP_dup 1542 // OPERANDS: none 1543 // DESCRIPTION: duplicates the value at the top of the stack 1544 case DW_OP_dup: 1545 if (stack.empty()) { 1546 if (error_ptr) 1547 error_ptr->SetErrorString("Expression stack empty for DW_OP_dup."); 1548 return false; 1549 } else 1550 stack.push_back(stack.back()); 1551 break; 1552 1553 // OPCODE: DW_OP_drop 1554 // OPERANDS: none 1555 // DESCRIPTION: pops the value at the top of the stack 1556 case DW_OP_drop: 1557 if (stack.empty()) { 1558 if (error_ptr) 1559 error_ptr->SetErrorString("Expression stack empty for DW_OP_drop."); 1560 return false; 1561 } else 1562 stack.pop_back(); 1563 break; 1564 1565 // OPCODE: DW_OP_over 1566 // OPERANDS: none 1567 // DESCRIPTION: Duplicates the entry currently second in the stack at 1568 // the top of the stack. 1569 case DW_OP_over: 1570 if (stack.size() < 2) { 1571 if (error_ptr) 1572 error_ptr->SetErrorString( 1573 "Expression stack needs at least 2 items for DW_OP_over."); 1574 return false; 1575 } else 1576 stack.push_back(stack[stack.size() - 2]); 1577 break; 1578 1579 // OPCODE: DW_OP_pick 1580 // OPERANDS: uint8_t index into the current stack 1581 // DESCRIPTION: The stack entry with the specified index (0 through 255, 1582 // inclusive) is pushed on the stack 1583 case DW_OP_pick: { 1584 uint8_t pick_idx = opcodes.GetU8(&offset); 1585 if (pick_idx < stack.size()) 1586 stack.push_back(stack[stack.size() - 1 - pick_idx]); 1587 else { 1588 if (error_ptr) 1589 error_ptr->SetErrorStringWithFormat( 1590 "Index %u out of range for DW_OP_pick.\n", pick_idx); 1591 return false; 1592 } 1593 } break; 1594 1595 // OPCODE: DW_OP_swap 1596 // OPERANDS: none 1597 // DESCRIPTION: swaps the top two stack entries. The entry at the top 1598 // of the stack becomes the second stack entry, and the second entry 1599 // becomes the top of the stack 1600 case DW_OP_swap: 1601 if (stack.size() < 2) { 1602 if (error_ptr) 1603 error_ptr->SetErrorString( 1604 "Expression stack needs at least 2 items for DW_OP_swap."); 1605 return false; 1606 } else { 1607 tmp = stack.back(); 1608 stack.back() = stack[stack.size() - 2]; 1609 stack[stack.size() - 2] = tmp; 1610 } 1611 break; 1612 1613 // OPCODE: DW_OP_rot 1614 // OPERANDS: none 1615 // DESCRIPTION: Rotates the first three stack entries. The entry at 1616 // the top of the stack becomes the third stack entry, the second entry 1617 // becomes the top of the stack, and the third entry becomes the second 1618 // entry. 1619 case DW_OP_rot: 1620 if (stack.size() < 3) { 1621 if (error_ptr) 1622 error_ptr->SetErrorString( 1623 "Expression stack needs at least 3 items for DW_OP_rot."); 1624 return false; 1625 } else { 1626 size_t last_idx = stack.size() - 1; 1627 Value old_top = stack[last_idx]; 1628 stack[last_idx] = stack[last_idx - 1]; 1629 stack[last_idx - 1] = stack[last_idx - 2]; 1630 stack[last_idx - 2] = old_top; 1631 } 1632 break; 1633 1634 // OPCODE: DW_OP_abs 1635 // OPERANDS: none 1636 // DESCRIPTION: pops the top stack entry, interprets it as a signed 1637 // value and pushes its absolute value. If the absolute value can not be 1638 // represented, the result is undefined. 1639 case DW_OP_abs: 1640 if (stack.empty()) { 1641 if (error_ptr) 1642 error_ptr->SetErrorString( 1643 "Expression stack needs at least 1 item for DW_OP_abs."); 1644 return false; 1645 } else if (!stack.back().ResolveValue(exe_ctx).AbsoluteValue()) { 1646 if (error_ptr) 1647 error_ptr->SetErrorString( 1648 "Failed to take the absolute value of the first stack item."); 1649 return false; 1650 } 1651 break; 1652 1653 // OPCODE: DW_OP_and 1654 // OPERANDS: none 1655 // DESCRIPTION: pops the top two stack values, performs a bitwise and 1656 // operation on the two, and pushes the result. 1657 case DW_OP_and: 1658 if (stack.size() < 2) { 1659 if (error_ptr) 1660 error_ptr->SetErrorString( 1661 "Expression stack needs at least 2 items for DW_OP_and."); 1662 return false; 1663 } else { 1664 tmp = stack.back(); 1665 stack.pop_back(); 1666 stack.back().ResolveValue(exe_ctx) = 1667 stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx); 1668 } 1669 break; 1670 1671 // OPCODE: DW_OP_div 1672 // OPERANDS: none 1673 // DESCRIPTION: pops the top two stack values, divides the former second 1674 // entry by the former top of the stack using signed division, and pushes 1675 // the result. 1676 case DW_OP_div: 1677 if (stack.size() < 2) { 1678 if (error_ptr) 1679 error_ptr->SetErrorString( 1680 "Expression stack needs at least 2 items for DW_OP_div."); 1681 return false; 1682 } else { 1683 tmp = stack.back(); 1684 if (tmp.ResolveValue(exe_ctx).IsZero()) { 1685 if (error_ptr) 1686 error_ptr->SetErrorString("Divide by zero."); 1687 return false; 1688 } else { 1689 stack.pop_back(); 1690 stack.back() = 1691 stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx); 1692 if (!stack.back().ResolveValue(exe_ctx).IsValid()) { 1693 if (error_ptr) 1694 error_ptr->SetErrorString("Divide failed."); 1695 return false; 1696 } 1697 } 1698 } 1699 break; 1700 1701 // OPCODE: DW_OP_minus 1702 // OPERANDS: none 1703 // DESCRIPTION: pops the top two stack values, subtracts the former top 1704 // of the stack from the former second entry, and pushes the result. 1705 case DW_OP_minus: 1706 if (stack.size() < 2) { 1707 if (error_ptr) 1708 error_ptr->SetErrorString( 1709 "Expression stack needs at least 2 items for DW_OP_minus."); 1710 return false; 1711 } else { 1712 tmp = stack.back(); 1713 stack.pop_back(); 1714 stack.back().ResolveValue(exe_ctx) = 1715 stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx); 1716 } 1717 break; 1718 1719 // OPCODE: DW_OP_mod 1720 // OPERANDS: none 1721 // DESCRIPTION: pops the top two stack values and pushes the result of 1722 // the calculation: former second stack entry modulo the former top of the 1723 // stack. 1724 case DW_OP_mod: 1725 if (stack.size() < 2) { 1726 if (error_ptr) 1727 error_ptr->SetErrorString( 1728 "Expression stack needs at least 2 items for DW_OP_mod."); 1729 return false; 1730 } else { 1731 tmp = stack.back(); 1732 stack.pop_back(); 1733 stack.back().ResolveValue(exe_ctx) = 1734 stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx); 1735 } 1736 break; 1737 1738 // OPCODE: DW_OP_mul 1739 // OPERANDS: none 1740 // DESCRIPTION: pops the top two stack entries, multiplies them 1741 // together, and pushes the result. 1742 case DW_OP_mul: 1743 if (stack.size() < 2) { 1744 if (error_ptr) 1745 error_ptr->SetErrorString( 1746 "Expression stack needs at least 2 items for DW_OP_mul."); 1747 return false; 1748 } else { 1749 tmp = stack.back(); 1750 stack.pop_back(); 1751 stack.back().ResolveValue(exe_ctx) = 1752 stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx); 1753 } 1754 break; 1755 1756 // OPCODE: DW_OP_neg 1757 // OPERANDS: none 1758 // DESCRIPTION: pops the top stack entry, and pushes its negation. 1759 case DW_OP_neg: 1760 if (stack.empty()) { 1761 if (error_ptr) 1762 error_ptr->SetErrorString( 1763 "Expression stack needs at least 1 item for DW_OP_neg."); 1764 return false; 1765 } else { 1766 if (!stack.back().ResolveValue(exe_ctx).UnaryNegate()) { 1767 if (error_ptr) 1768 error_ptr->SetErrorString("Unary negate failed."); 1769 return false; 1770 } 1771 } 1772 break; 1773 1774 // OPCODE: DW_OP_not 1775 // OPERANDS: none 1776 // DESCRIPTION: pops the top stack entry, and pushes its bitwise 1777 // complement 1778 case DW_OP_not: 1779 if (stack.empty()) { 1780 if (error_ptr) 1781 error_ptr->SetErrorString( 1782 "Expression stack needs at least 1 item for DW_OP_not."); 1783 return false; 1784 } else { 1785 if (!stack.back().ResolveValue(exe_ctx).OnesComplement()) { 1786 if (error_ptr) 1787 error_ptr->SetErrorString("Logical NOT failed."); 1788 return false; 1789 } 1790 } 1791 break; 1792 1793 // OPCODE: DW_OP_or 1794 // OPERANDS: none 1795 // DESCRIPTION: pops the top two stack entries, performs a bitwise or 1796 // operation on the two, and pushes the result. 1797 case DW_OP_or: 1798 if (stack.size() < 2) { 1799 if (error_ptr) 1800 error_ptr->SetErrorString( 1801 "Expression stack needs at least 2 items for DW_OP_or."); 1802 return false; 1803 } else { 1804 tmp = stack.back(); 1805 stack.pop_back(); 1806 stack.back().ResolveValue(exe_ctx) = 1807 stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx); 1808 } 1809 break; 1810 1811 // OPCODE: DW_OP_plus 1812 // OPERANDS: none 1813 // DESCRIPTION: pops the top two stack entries, adds them together, and 1814 // pushes the result. 1815 case DW_OP_plus: 1816 if (stack.size() < 2) { 1817 if (error_ptr) 1818 error_ptr->SetErrorString( 1819 "Expression stack needs at least 2 items for DW_OP_plus."); 1820 return false; 1821 } else { 1822 tmp = stack.back(); 1823 stack.pop_back(); 1824 stack.back().GetScalar() += tmp.GetScalar(); 1825 } 1826 break; 1827 1828 // OPCODE: DW_OP_plus_uconst 1829 // OPERANDS: none 1830 // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128 1831 // constant operand and pushes the result. 1832 case DW_OP_plus_uconst: 1833 if (stack.empty()) { 1834 if (error_ptr) 1835 error_ptr->SetErrorString( 1836 "Expression stack needs at least 1 item for DW_OP_plus_uconst."); 1837 return false; 1838 } else { 1839 const uint64_t uconst_value = opcodes.GetULEB128(&offset); 1840 // Implicit conversion from a UINT to a Scalar... 1841 stack.back().GetScalar() += uconst_value; 1842 if (!stack.back().GetScalar().IsValid()) { 1843 if (error_ptr) 1844 error_ptr->SetErrorString("DW_OP_plus_uconst failed."); 1845 return false; 1846 } 1847 } 1848 break; 1849 1850 // OPCODE: DW_OP_shl 1851 // OPERANDS: none 1852 // DESCRIPTION: pops the top two stack entries, shifts the former 1853 // second entry left by the number of bits specified by the former top of 1854 // the stack, and pushes the result. 1855 case DW_OP_shl: 1856 if (stack.size() < 2) { 1857 if (error_ptr) 1858 error_ptr->SetErrorString( 1859 "Expression stack needs at least 2 items for DW_OP_shl."); 1860 return false; 1861 } else { 1862 tmp = stack.back(); 1863 stack.pop_back(); 1864 stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx); 1865 } 1866 break; 1867 1868 // OPCODE: DW_OP_shr 1869 // OPERANDS: none 1870 // DESCRIPTION: pops the top two stack entries, shifts the former second 1871 // entry right logically (filling with zero bits) by the number of bits 1872 // specified by the former top of the stack, and pushes the result. 1873 case DW_OP_shr: 1874 if (stack.size() < 2) { 1875 if (error_ptr) 1876 error_ptr->SetErrorString( 1877 "Expression stack needs at least 2 items for DW_OP_shr."); 1878 return false; 1879 } else { 1880 tmp = stack.back(); 1881 stack.pop_back(); 1882 if (!stack.back().ResolveValue(exe_ctx).ShiftRightLogical( 1883 tmp.ResolveValue(exe_ctx))) { 1884 if (error_ptr) 1885 error_ptr->SetErrorString("DW_OP_shr failed."); 1886 return false; 1887 } 1888 } 1889 break; 1890 1891 // OPCODE: DW_OP_shra 1892 // OPERANDS: none 1893 // DESCRIPTION: pops the top two stack entries, shifts the former second 1894 // entry right arithmetically (divide the magnitude by 2, keep the same 1895 // sign for the result) by the number of bits specified by the former top 1896 // of the stack, and pushes the result. 1897 case DW_OP_shra: 1898 if (stack.size() < 2) { 1899 if (error_ptr) 1900 error_ptr->SetErrorString( 1901 "Expression stack needs at least 2 items for DW_OP_shra."); 1902 return false; 1903 } else { 1904 tmp = stack.back(); 1905 stack.pop_back(); 1906 stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx); 1907 } 1908 break; 1909 1910 // OPCODE: DW_OP_xor 1911 // OPERANDS: none 1912 // DESCRIPTION: pops the top two stack entries, performs the bitwise 1913 // exclusive-or operation on the two, and pushes the result. 1914 case DW_OP_xor: 1915 if (stack.size() < 2) { 1916 if (error_ptr) 1917 error_ptr->SetErrorString( 1918 "Expression stack needs at least 2 items for DW_OP_xor."); 1919 return false; 1920 } else { 1921 tmp = stack.back(); 1922 stack.pop_back(); 1923 stack.back().ResolveValue(exe_ctx) = 1924 stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx); 1925 } 1926 break; 1927 1928 // OPCODE: DW_OP_skip 1929 // OPERANDS: int16_t 1930 // DESCRIPTION: An unconditional branch. Its single operand is a 2-byte 1931 // signed integer constant. The 2-byte constant is the number of bytes of 1932 // the DWARF expression to skip forward or backward from the current 1933 // operation, beginning after the 2-byte constant. 1934 case DW_OP_skip: { 1935 int16_t skip_offset = (int16_t)opcodes.GetU16(&offset); 1936 lldb::offset_t new_offset = offset + skip_offset; 1937 if (opcodes.ValidOffset(new_offset)) 1938 offset = new_offset; 1939 else { 1940 if (error_ptr) 1941 error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip."); 1942 return false; 1943 } 1944 } break; 1945 1946 // OPCODE: DW_OP_bra 1947 // OPERANDS: int16_t 1948 // DESCRIPTION: A conditional branch. Its single operand is a 2-byte 1949 // signed integer constant. This operation pops the top of stack. If the 1950 // value popped is not the constant 0, the 2-byte constant operand is the 1951 // number of bytes of the DWARF expression to skip forward or backward from 1952 // the current operation, beginning after the 2-byte constant. 1953 case DW_OP_bra: 1954 if (stack.empty()) { 1955 if (error_ptr) 1956 error_ptr->SetErrorString( 1957 "Expression stack needs at least 1 item for DW_OP_bra."); 1958 return false; 1959 } else { 1960 tmp = stack.back(); 1961 stack.pop_back(); 1962 int16_t bra_offset = (int16_t)opcodes.GetU16(&offset); 1963 Scalar zero(0); 1964 if (tmp.ResolveValue(exe_ctx) != zero) { 1965 lldb::offset_t new_offset = offset + bra_offset; 1966 if (opcodes.ValidOffset(new_offset)) 1967 offset = new_offset; 1968 else { 1969 if (error_ptr) 1970 error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra."); 1971 return false; 1972 } 1973 } 1974 } 1975 break; 1976 1977 // OPCODE: DW_OP_eq 1978 // OPERANDS: none 1979 // DESCRIPTION: pops the top two stack values, compares using the 1980 // equals (==) operator. 1981 // STACK RESULT: push the constant value 1 onto the stack if the result 1982 // of the operation is true or the constant value 0 if the result of the 1983 // operation is false. 1984 case DW_OP_eq: 1985 if (stack.size() < 2) { 1986 if (error_ptr) 1987 error_ptr->SetErrorString( 1988 "Expression stack needs at least 2 items for DW_OP_eq."); 1989 return false; 1990 } else { 1991 tmp = stack.back(); 1992 stack.pop_back(); 1993 stack.back().ResolveValue(exe_ctx) = 1994 stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx); 1995 } 1996 break; 1997 1998 // OPCODE: DW_OP_ge 1999 // OPERANDS: none 2000 // DESCRIPTION: pops the top two stack values, compares using the 2001 // greater than or equal to (>=) operator. 2002 // STACK RESULT: push the constant value 1 onto the stack if the result 2003 // of the operation is true or the constant value 0 if the result of the 2004 // operation is false. 2005 case DW_OP_ge: 2006 if (stack.size() < 2) { 2007 if (error_ptr) 2008 error_ptr->SetErrorString( 2009 "Expression stack needs at least 2 items for DW_OP_ge."); 2010 return false; 2011 } else { 2012 tmp = stack.back(); 2013 stack.pop_back(); 2014 stack.back().ResolveValue(exe_ctx) = 2015 stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx); 2016 } 2017 break; 2018 2019 // OPCODE: DW_OP_gt 2020 // OPERANDS: none 2021 // DESCRIPTION: pops the top two stack values, compares using the 2022 // greater than (>) operator. 2023 // STACK RESULT: push the constant value 1 onto the stack if the result 2024 // of the operation is true or the constant value 0 if the result of the 2025 // operation is false. 2026 case DW_OP_gt: 2027 if (stack.size() < 2) { 2028 if (error_ptr) 2029 error_ptr->SetErrorString( 2030 "Expression stack needs at least 2 items for DW_OP_gt."); 2031 return false; 2032 } else { 2033 tmp = stack.back(); 2034 stack.pop_back(); 2035 stack.back().ResolveValue(exe_ctx) = 2036 stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx); 2037 } 2038 break; 2039 2040 // OPCODE: DW_OP_le 2041 // OPERANDS: none 2042 // DESCRIPTION: pops the top two stack values, compares using the 2043 // less than or equal to (<=) operator. 2044 // STACK RESULT: push the constant value 1 onto the stack if the result 2045 // of the operation is true or the constant value 0 if the result of the 2046 // operation is false. 2047 case DW_OP_le: 2048 if (stack.size() < 2) { 2049 if (error_ptr) 2050 error_ptr->SetErrorString( 2051 "Expression stack needs at least 2 items for DW_OP_le."); 2052 return false; 2053 } else { 2054 tmp = stack.back(); 2055 stack.pop_back(); 2056 stack.back().ResolveValue(exe_ctx) = 2057 stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx); 2058 } 2059 break; 2060 2061 // OPCODE: DW_OP_lt 2062 // OPERANDS: none 2063 // DESCRIPTION: pops the top two stack values, compares using the 2064 // less than (<) operator. 2065 // STACK RESULT: push the constant value 1 onto the stack if the result 2066 // of the operation is true or the constant value 0 if the result of the 2067 // operation is false. 2068 case DW_OP_lt: 2069 if (stack.size() < 2) { 2070 if (error_ptr) 2071 error_ptr->SetErrorString( 2072 "Expression stack needs at least 2 items for DW_OP_lt."); 2073 return false; 2074 } else { 2075 tmp = stack.back(); 2076 stack.pop_back(); 2077 stack.back().ResolveValue(exe_ctx) = 2078 stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx); 2079 } 2080 break; 2081 2082 // OPCODE: DW_OP_ne 2083 // OPERANDS: none 2084 // DESCRIPTION: pops the top two stack values, compares using the 2085 // not equal (!=) operator. 2086 // STACK RESULT: push the constant value 1 onto the stack if the result 2087 // of the operation is true or the constant value 0 if the result of the 2088 // operation is false. 2089 case DW_OP_ne: 2090 if (stack.size() < 2) { 2091 if (error_ptr) 2092 error_ptr->SetErrorString( 2093 "Expression stack needs at least 2 items for DW_OP_ne."); 2094 return false; 2095 } else { 2096 tmp = stack.back(); 2097 stack.pop_back(); 2098 stack.back().ResolveValue(exe_ctx) = 2099 stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx); 2100 } 2101 break; 2102 2103 // OPCODE: DW_OP_litn 2104 // OPERANDS: none 2105 // DESCRIPTION: encode the unsigned literal values from 0 through 31. 2106 // STACK RESULT: push the unsigned literal constant value onto the top 2107 // of the stack. 2108 case DW_OP_lit0: 2109 case DW_OP_lit1: 2110 case DW_OP_lit2: 2111 case DW_OP_lit3: 2112 case DW_OP_lit4: 2113 case DW_OP_lit5: 2114 case DW_OP_lit6: 2115 case DW_OP_lit7: 2116 case DW_OP_lit8: 2117 case DW_OP_lit9: 2118 case DW_OP_lit10: 2119 case DW_OP_lit11: 2120 case DW_OP_lit12: 2121 case DW_OP_lit13: 2122 case DW_OP_lit14: 2123 case DW_OP_lit15: 2124 case DW_OP_lit16: 2125 case DW_OP_lit17: 2126 case DW_OP_lit18: 2127 case DW_OP_lit19: 2128 case DW_OP_lit20: 2129 case DW_OP_lit21: 2130 case DW_OP_lit22: 2131 case DW_OP_lit23: 2132 case DW_OP_lit24: 2133 case DW_OP_lit25: 2134 case DW_OP_lit26: 2135 case DW_OP_lit27: 2136 case DW_OP_lit28: 2137 case DW_OP_lit29: 2138 case DW_OP_lit30: 2139 case DW_OP_lit31: 2140 stack.push_back(Scalar((uint64_t)(op - DW_OP_lit0))); 2141 break; 2142 2143 // OPCODE: DW_OP_regN 2144 // OPERANDS: none 2145 // DESCRIPTION: Push the value in register n on the top of the stack. 2146 case DW_OP_reg0: 2147 case DW_OP_reg1: 2148 case DW_OP_reg2: 2149 case DW_OP_reg3: 2150 case DW_OP_reg4: 2151 case DW_OP_reg5: 2152 case DW_OP_reg6: 2153 case DW_OP_reg7: 2154 case DW_OP_reg8: 2155 case DW_OP_reg9: 2156 case DW_OP_reg10: 2157 case DW_OP_reg11: 2158 case DW_OP_reg12: 2159 case DW_OP_reg13: 2160 case DW_OP_reg14: 2161 case DW_OP_reg15: 2162 case DW_OP_reg16: 2163 case DW_OP_reg17: 2164 case DW_OP_reg18: 2165 case DW_OP_reg19: 2166 case DW_OP_reg20: 2167 case DW_OP_reg21: 2168 case DW_OP_reg22: 2169 case DW_OP_reg23: 2170 case DW_OP_reg24: 2171 case DW_OP_reg25: 2172 case DW_OP_reg26: 2173 case DW_OP_reg27: 2174 case DW_OP_reg28: 2175 case DW_OP_reg29: 2176 case DW_OP_reg30: 2177 case DW_OP_reg31: { 2178 reg_num = op - DW_OP_reg0; 2179 2180 if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp)) 2181 stack.push_back(tmp); 2182 else 2183 return false; 2184 } break; 2185 // OPCODE: DW_OP_regx 2186 // OPERANDS: 2187 // ULEB128 literal operand that encodes the register. 2188 // DESCRIPTION: Push the value in register on the top of the stack. 2189 case DW_OP_regx: { 2190 reg_num = opcodes.GetULEB128(&offset); 2191 if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, tmp)) 2192 stack.push_back(tmp); 2193 else 2194 return false; 2195 } break; 2196 2197 // OPCODE: DW_OP_bregN 2198 // OPERANDS: 2199 // SLEB128 offset from register N 2200 // DESCRIPTION: Value is in memory at the address specified by register 2201 // N plus an offset. 2202 case DW_OP_breg0: 2203 case DW_OP_breg1: 2204 case DW_OP_breg2: 2205 case DW_OP_breg3: 2206 case DW_OP_breg4: 2207 case DW_OP_breg5: 2208 case DW_OP_breg6: 2209 case DW_OP_breg7: 2210 case DW_OP_breg8: 2211 case DW_OP_breg9: 2212 case DW_OP_breg10: 2213 case DW_OP_breg11: 2214 case DW_OP_breg12: 2215 case DW_OP_breg13: 2216 case DW_OP_breg14: 2217 case DW_OP_breg15: 2218 case DW_OP_breg16: 2219 case DW_OP_breg17: 2220 case DW_OP_breg18: 2221 case DW_OP_breg19: 2222 case DW_OP_breg20: 2223 case DW_OP_breg21: 2224 case DW_OP_breg22: 2225 case DW_OP_breg23: 2226 case DW_OP_breg24: 2227 case DW_OP_breg25: 2228 case DW_OP_breg26: 2229 case DW_OP_breg27: 2230 case DW_OP_breg28: 2231 case DW_OP_breg29: 2232 case DW_OP_breg30: 2233 case DW_OP_breg31: { 2234 reg_num = op - DW_OP_breg0; 2235 2236 if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, 2237 tmp)) { 2238 int64_t breg_offset = opcodes.GetSLEB128(&offset); 2239 tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; 2240 tmp.ClearContext(); 2241 stack.push_back(tmp); 2242 stack.back().SetValueType(Value::eValueTypeLoadAddress); 2243 } else 2244 return false; 2245 } break; 2246 // OPCODE: DW_OP_bregx 2247 // OPERANDS: 2 2248 // ULEB128 literal operand that encodes the register. 2249 // SLEB128 offset from register N 2250 // DESCRIPTION: Value is in memory at the address specified by register 2251 // N plus an offset. 2252 case DW_OP_bregx: { 2253 reg_num = opcodes.GetULEB128(&offset); 2254 2255 if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, 2256 tmp)) { 2257 int64_t breg_offset = opcodes.GetSLEB128(&offset); 2258 tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; 2259 tmp.ClearContext(); 2260 stack.push_back(tmp); 2261 stack.back().SetValueType(Value::eValueTypeLoadAddress); 2262 } else 2263 return false; 2264 } break; 2265 2266 case DW_OP_fbreg: 2267 if (exe_ctx) { 2268 if (frame) { 2269 Scalar value; 2270 if (frame->GetFrameBaseValue(value, error_ptr)) { 2271 int64_t fbreg_offset = opcodes.GetSLEB128(&offset); 2272 value += fbreg_offset; 2273 stack.push_back(value); 2274 stack.back().SetValueType(Value::eValueTypeLoadAddress); 2275 } else 2276 return false; 2277 } else { 2278 if (error_ptr) 2279 error_ptr->SetErrorString( 2280 "Invalid stack frame in context for DW_OP_fbreg opcode."); 2281 return false; 2282 } 2283 } else { 2284 if (error_ptr) 2285 error_ptr->SetErrorStringWithFormat( 2286 "NULL execution context for DW_OP_fbreg.\n"); 2287 return false; 2288 } 2289 2290 break; 2291 2292 // OPCODE: DW_OP_nop 2293 // OPERANDS: none 2294 // DESCRIPTION: A place holder. It has no effect on the location stack 2295 // or any of its values. 2296 case DW_OP_nop: 2297 break; 2298 2299 // OPCODE: DW_OP_piece 2300 // OPERANDS: 1 2301 // ULEB128: byte size of the piece 2302 // DESCRIPTION: The operand describes the size in bytes of the piece of 2303 // the object referenced by the DWARF expression whose result is at the top 2304 // of the stack. If the piece is located in a register, but does not occupy 2305 // the entire register, the placement of the piece within that register is 2306 // defined by the ABI. 2307 // 2308 // Many compilers store a single variable in sets of registers, or store a 2309 // variable partially in memory and partially in registers. DW_OP_piece 2310 // provides a way of describing how large a part of a variable a particular 2311 // DWARF expression refers to. 2312 case DW_OP_piece: { 2313 const uint64_t piece_byte_size = opcodes.GetULEB128(&offset); 2314 2315 if (piece_byte_size > 0) { 2316 Value curr_piece; 2317 2318 if (stack.empty()) { 2319 // In a multi-piece expression, this means that the current piece is 2320 // not available. Fill with zeros for now by resizing the data and 2321 // appending it 2322 curr_piece.ResizeData(piece_byte_size); 2323 ::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size); 2324 pieces.AppendDataToHostBuffer(curr_piece); 2325 } else { 2326 Status error; 2327 // Extract the current piece into "curr_piece" 2328 Value curr_piece_source_value(stack.back()); 2329 stack.pop_back(); 2330 2331 const Value::ValueType curr_piece_source_value_type = 2332 curr_piece_source_value.GetValueType(); 2333 switch (curr_piece_source_value_type) { 2334 case Value::eValueTypeLoadAddress: 2335 if (process) { 2336 if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size) { 2337 lldb::addr_t load_addr = 2338 curr_piece_source_value.GetScalar().ULongLong( 2339 LLDB_INVALID_ADDRESS); 2340 if (process->ReadMemory( 2341 load_addr, curr_piece.GetBuffer().GetBytes(), 2342 piece_byte_size, error) != piece_byte_size) { 2343 if (error_ptr) 2344 error_ptr->SetErrorStringWithFormat( 2345 "failed to read memory DW_OP_piece(%" PRIu64 2346 ") from 0x%" PRIx64, 2347 piece_byte_size, load_addr); 2348 return false; 2349 } 2350 } else { 2351 if (error_ptr) 2352 error_ptr->SetErrorStringWithFormat( 2353 "failed to resize the piece memory buffer for " 2354 "DW_OP_piece(%" PRIu64 ")", 2355 piece_byte_size); 2356 return false; 2357 } 2358 } 2359 break; 2360 2361 case Value::eValueTypeFileAddress: 2362 case Value::eValueTypeHostAddress: 2363 if (error_ptr) { 2364 lldb::addr_t addr = curr_piece_source_value.GetScalar().ULongLong( 2365 LLDB_INVALID_ADDRESS); 2366 error_ptr->SetErrorStringWithFormat( 2367 "failed to read memory DW_OP_piece(%" PRIu64 2368 ") from %s address 0x%" PRIx64, 2369 piece_byte_size, curr_piece_source_value.GetValueType() == 2370 Value::eValueTypeFileAddress 2371 ? "file" 2372 : "host", 2373 addr); 2374 } 2375 return false; 2376 2377 case Value::eValueTypeScalar: { 2378 uint32_t bit_size = piece_byte_size * 8; 2379 uint32_t bit_offset = 0; 2380 if (!curr_piece_source_value.GetScalar().ExtractBitfield( 2381 bit_size, bit_offset)) { 2382 if (error_ptr) 2383 error_ptr->SetErrorStringWithFormat( 2384 "unable to extract %" PRIu64 " bytes from a %" PRIu64 2385 " byte scalar value.", 2386 piece_byte_size, 2387 (uint64_t)curr_piece_source_value.GetScalar() 2388 .GetByteSize()); 2389 return false; 2390 } 2391 curr_piece = curr_piece_source_value; 2392 } break; 2393 2394 case Value::eValueTypeVector: { 2395 if (curr_piece_source_value.GetVector().length >= piece_byte_size) 2396 curr_piece_source_value.GetVector().length = piece_byte_size; 2397 else { 2398 if (error_ptr) 2399 error_ptr->SetErrorStringWithFormat( 2400 "unable to extract %" PRIu64 " bytes from a %" PRIu64 2401 " byte vector value.", 2402 piece_byte_size, 2403 (uint64_t)curr_piece_source_value.GetVector().length); 2404 return false; 2405 } 2406 } break; 2407 } 2408 2409 // Check if this is the first piece? 2410 if (op_piece_offset == 0) { 2411 // This is the first piece, we should push it back onto the stack 2412 // so subsequent pieces will be able to access this piece and add 2413 // to it 2414 if (pieces.AppendDataToHostBuffer(curr_piece) == 0) { 2415 if (error_ptr) 2416 error_ptr->SetErrorString("failed to append piece data"); 2417 return false; 2418 } 2419 } else { 2420 // If this is the second or later piece there should be a value on 2421 // the stack 2422 if (pieces.GetBuffer().GetByteSize() != op_piece_offset) { 2423 if (error_ptr) 2424 error_ptr->SetErrorStringWithFormat( 2425 "DW_OP_piece for offset %" PRIu64 2426 " but top of stack is of size %" PRIu64, 2427 op_piece_offset, pieces.GetBuffer().GetByteSize()); 2428 return false; 2429 } 2430 2431 if (pieces.AppendDataToHostBuffer(curr_piece) == 0) { 2432 if (error_ptr) 2433 error_ptr->SetErrorString("failed to append piece data"); 2434 return false; 2435 } 2436 } 2437 op_piece_offset += piece_byte_size; 2438 } 2439 } 2440 } break; 2441 2442 case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3); 2443 if (stack.size() < 1) { 2444 if (error_ptr) 2445 error_ptr->SetErrorString( 2446 "Expression stack needs at least 1 item for DW_OP_bit_piece."); 2447 return false; 2448 } else { 2449 const uint64_t piece_bit_size = opcodes.GetULEB128(&offset); 2450 const uint64_t piece_bit_offset = opcodes.GetULEB128(&offset); 2451 switch (stack.back().GetValueType()) { 2452 case Value::eValueTypeScalar: { 2453 if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size, 2454 piece_bit_offset)) { 2455 if (error_ptr) 2456 error_ptr->SetErrorStringWithFormat( 2457 "unable to extract %" PRIu64 " bit value with %" PRIu64 2458 " bit offset from a %" PRIu64 " bit scalar value.", 2459 piece_bit_size, piece_bit_offset, 2460 (uint64_t)(stack.back().GetScalar().GetByteSize() * 8)); 2461 return false; 2462 } 2463 } break; 2464 2465 case Value::eValueTypeFileAddress: 2466 case Value::eValueTypeLoadAddress: 2467 case Value::eValueTypeHostAddress: 2468 if (error_ptr) { 2469 error_ptr->SetErrorStringWithFormat( 2470 "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64 2471 ", bit_offset = %" PRIu64 ") from an address value.", 2472 piece_bit_size, piece_bit_offset); 2473 } 2474 return false; 2475 2476 case Value::eValueTypeVector: 2477 if (error_ptr) { 2478 error_ptr->SetErrorStringWithFormat( 2479 "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64 2480 ", bit_offset = %" PRIu64 ") from a vector value.", 2481 piece_bit_size, piece_bit_offset); 2482 } 2483 return false; 2484 } 2485 } 2486 break; 2487 2488 // OPCODE: DW_OP_push_object_address 2489 // OPERANDS: none 2490 // DESCRIPTION: Pushes the address of the object currently being 2491 // evaluated as part of evaluation of a user presented expression. This 2492 // object may correspond to an independent variable described by its own 2493 // DIE or it may be a component of an array, structure, or class whose 2494 // address has been dynamically determined by an earlier step during user 2495 // expression evaluation. 2496 case DW_OP_push_object_address: 2497 if (object_address_ptr) 2498 stack.push_back(*object_address_ptr); 2499 else { 2500 if (error_ptr) 2501 error_ptr->SetErrorString("DW_OP_push_object_address used without " 2502 "specifying an object address"); 2503 return false; 2504 } 2505 break; 2506 2507 // OPCODE: DW_OP_call2 2508 // OPERANDS: 2509 // uint16_t compile unit relative offset of a DIE 2510 // DESCRIPTION: Performs subroutine calls during evaluation 2511 // of a DWARF expression. The operand is the 2-byte unsigned offset of a 2512 // debugging information entry in the current compilation unit. 2513 // 2514 // Operand interpretation is exactly like that for DW_FORM_ref2. 2515 // 2516 // This operation transfers control of DWARF expression evaluation to the 2517 // DW_AT_location attribute of the referenced DIE. If there is no such 2518 // attribute, then there is no effect. Execution of the DWARF expression of 2519 // a DW_AT_location attribute may add to and/or remove from values on the 2520 // stack. Execution returns to the point following the call when the end of 2521 // the attribute is reached. Values on the stack at the time of the call 2522 // may be used as parameters by the called expression and values left on 2523 // the stack by the called expression may be used as return values by prior 2524 // agreement between the calling and called expressions. 2525 case DW_OP_call2: 2526 if (error_ptr) 2527 error_ptr->SetErrorString("Unimplemented opcode DW_OP_call2."); 2528 return false; 2529 // OPCODE: DW_OP_call4 2530 // OPERANDS: 1 2531 // uint32_t compile unit relative offset of a DIE 2532 // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF 2533 // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset of 2534 // a debugging information entry in the current compilation unit. 2535 // 2536 // Operand interpretation DW_OP_call4 is exactly like that for 2537 // DW_FORM_ref4. 2538 // 2539 // This operation transfers control of DWARF expression evaluation to the 2540 // DW_AT_location attribute of the referenced DIE. If there is no such 2541 // attribute, then there is no effect. Execution of the DWARF expression of 2542 // a DW_AT_location attribute may add to and/or remove from values on the 2543 // stack. Execution returns to the point following the call when the end of 2544 // the attribute is reached. Values on the stack at the time of the call 2545 // may be used as parameters by the called expression and values left on 2546 // the stack by the called expression may be used as return values by prior 2547 // agreement between the calling and called expressions. 2548 case DW_OP_call4: 2549 if (error_ptr) 2550 error_ptr->SetErrorString("Unimplemented opcode DW_OP_call4."); 2551 return false; 2552 2553 // OPCODE: DW_OP_stack_value 2554 // OPERANDS: None 2555 // DESCRIPTION: Specifies that the object does not exist in memory but 2556 // rather is a constant value. The value from the top of the stack is the 2557 // value to be used. This is the actual object value and not the location. 2558 case DW_OP_stack_value: 2559 stack.back().SetValueType(Value::eValueTypeScalar); 2560 break; 2561 2562 // OPCODE: DW_OP_call_frame_cfa 2563 // OPERANDS: None 2564 // DESCRIPTION: Specifies a DWARF expression that pushes the value of 2565 // the canonical frame address consistent with the call frame information 2566 // located in .debug_frame (or in the FDEs of the eh_frame section). 2567 case DW_OP_call_frame_cfa: 2568 if (frame) { 2569 // Note that we don't have to parse FDEs because this DWARF expression 2570 // is commonly evaluated with a valid stack frame. 2571 StackID id = frame->GetStackID(); 2572 addr_t cfa = id.GetCallFrameAddress(); 2573 if (cfa != LLDB_INVALID_ADDRESS) { 2574 stack.push_back(Scalar(cfa)); 2575 stack.back().SetValueType(Value::eValueTypeLoadAddress); 2576 } else if (error_ptr) 2577 error_ptr->SetErrorString("Stack frame does not include a canonical " 2578 "frame address for DW_OP_call_frame_cfa " 2579 "opcode."); 2580 } else { 2581 if (error_ptr) 2582 error_ptr->SetErrorString("Invalid stack frame in context for " 2583 "DW_OP_call_frame_cfa opcode."); 2584 return false; 2585 } 2586 break; 2587 2588 // OPCODE: DW_OP_form_tls_address (or the old pre-DWARFv3 vendor extension 2589 // opcode, DW_OP_GNU_push_tls_address) 2590 // OPERANDS: none 2591 // DESCRIPTION: Pops a TLS offset from the stack, converts it to 2592 // an address in the current thread's thread-local storage block, and 2593 // pushes it on the stack. 2594 case DW_OP_form_tls_address: 2595 case DW_OP_GNU_push_tls_address: { 2596 if (stack.size() < 1) { 2597 if (error_ptr) { 2598 if (op == DW_OP_form_tls_address) 2599 error_ptr->SetErrorString( 2600 "DW_OP_form_tls_address needs an argument."); 2601 else 2602 error_ptr->SetErrorString( 2603 "DW_OP_GNU_push_tls_address needs an argument."); 2604 } 2605 return false; 2606 } 2607 2608 if (!exe_ctx || !module_sp) { 2609 if (error_ptr) 2610 error_ptr->SetErrorString("No context to evaluate TLS within."); 2611 return false; 2612 } 2613 2614 Thread *thread = exe_ctx->GetThreadPtr(); 2615 if (!thread) { 2616 if (error_ptr) 2617 error_ptr->SetErrorString("No thread to evaluate TLS within."); 2618 return false; 2619 } 2620 2621 // Lookup the TLS block address for this thread and module. 2622 const addr_t tls_file_addr = 2623 stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 2624 const addr_t tls_load_addr = 2625 thread->GetThreadLocalData(module_sp, tls_file_addr); 2626 2627 if (tls_load_addr == LLDB_INVALID_ADDRESS) { 2628 if (error_ptr) 2629 error_ptr->SetErrorString( 2630 "No TLS data currently exists for this thread."); 2631 return false; 2632 } 2633 2634 stack.back().GetScalar() = tls_load_addr; 2635 stack.back().SetValueType(Value::eValueTypeLoadAddress); 2636 } break; 2637 2638 // OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.) 2639 // OPERANDS: 1 2640 // ULEB128: index to the .debug_addr section 2641 // DESCRIPTION: Pushes an address to the stack from the .debug_addr 2642 // section with the base address specified by the DW_AT_addr_base attribute 2643 // and the 0 based index is the ULEB128 encoded index. 2644 case DW_OP_addrx: 2645 case DW_OP_GNU_addr_index: { 2646 if (!dwarf_cu) { 2647 if (error_ptr) 2648 error_ptr->SetErrorString("DW_OP_GNU_addr_index found without a " 2649 "compile unit being specified"); 2650 return false; 2651 } 2652 uint64_t index = opcodes.GetULEB128(&offset); 2653 lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index); 2654 stack.push_back(Scalar(value)); 2655 stack.back().SetValueType(Value::eValueTypeFileAddress); 2656 } break; 2657 2658 // OPCODE: DW_OP_GNU_const_index 2659 // OPERANDS: 1 2660 // ULEB128: index to the .debug_addr section 2661 // DESCRIPTION: Pushes an constant with the size of a machine address to 2662 // the stack from the .debug_addr section with the base address specified 2663 // by the DW_AT_addr_base attribute and the 0 based index is the ULEB128 2664 // encoded index. 2665 case DW_OP_GNU_const_index: { 2666 if (!dwarf_cu) { 2667 if (error_ptr) 2668 error_ptr->SetErrorString("DW_OP_GNU_const_index found without a " 2669 "compile unit being specified"); 2670 return false; 2671 } 2672 uint64_t index = opcodes.GetULEB128(&offset); 2673 lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index); 2674 stack.push_back(Scalar(value)); 2675 } break; 2676 2677 default: 2678 LLDB_LOGF(log, "Unhandled opcode %s in DWARFExpression.", 2679 DW_OP_value_to_name(op)); 2680 break; 2681 } 2682 } 2683 2684 if (stack.empty()) { 2685 // Nothing on the stack, check if we created a piece value from DW_OP_piece 2686 // or DW_OP_bit_piece opcodes 2687 if (pieces.GetBuffer().GetByteSize()) { 2688 result = pieces; 2689 } else { 2690 if (error_ptr) 2691 error_ptr->SetErrorString("Stack empty after evaluation."); 2692 return false; 2693 } 2694 } else { 2695 if (log && log->GetVerbose()) { 2696 size_t count = stack.size(); 2697 LLDB_LOGF(log, "Stack after operation has %" PRIu64 " values:", 2698 (uint64_t)count); 2699 for (size_t i = 0; i < count; ++i) { 2700 StreamString new_value; 2701 new_value.Printf("[%" PRIu64 "]", (uint64_t)i); 2702 stack[i].Dump(&new_value); 2703 LLDB_LOGF(log, " %s", new_value.GetData()); 2704 } 2705 } 2706 result = stack.back(); 2707 } 2708 return true; // Return true on success 2709 } 2710 2711 bool DWARFExpression::AddressRangeForLocationListEntry( 2712 const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data, 2713 lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc) { 2714 if (!debug_loc_data.ValidOffset(*offset_ptr)) 2715 return false; 2716 2717 DWARFExpression::LocationListFormat format = 2718 dwarf_cu->GetSymbolFileDWARF().GetLocationListFormat(); 2719 switch (format) { 2720 case NonLocationList: 2721 return false; 2722 case RegularLocationList: 2723 low_pc = debug_loc_data.GetAddress(offset_ptr); 2724 high_pc = debug_loc_data.GetAddress(offset_ptr); 2725 return true; 2726 case SplitDwarfLocationList: 2727 case LocLists: 2728 switch (debug_loc_data.GetU8(offset_ptr)) { 2729 case DW_LLE_end_of_list: 2730 return false; 2731 case DW_LLE_startx_endx: { 2732 uint64_t index = debug_loc_data.GetULEB128(offset_ptr); 2733 low_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index); 2734 index = debug_loc_data.GetULEB128(offset_ptr); 2735 high_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index); 2736 return true; 2737 } 2738 case DW_LLE_startx_length: { 2739 uint64_t index = debug_loc_data.GetULEB128(offset_ptr); 2740 low_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index); 2741 uint64_t length = (format == LocLists) 2742 ? debug_loc_data.GetULEB128(offset_ptr) 2743 : debug_loc_data.GetU32(offset_ptr); 2744 high_pc = low_pc + length; 2745 return true; 2746 } 2747 case DW_LLE_start_length: { 2748 low_pc = debug_loc_data.GetAddress(offset_ptr); 2749 high_pc = low_pc + debug_loc_data.GetULEB128(offset_ptr); 2750 return true; 2751 } 2752 case DW_LLE_start_end: { 2753 low_pc = debug_loc_data.GetAddress(offset_ptr); 2754 high_pc = debug_loc_data.GetAddress(offset_ptr); 2755 return true; 2756 } 2757 default: 2758 // Not supported entry type 2759 lldbassert(false && "Not supported location list type"); 2760 return false; 2761 } 2762 } 2763 assert(false && "Not supported location list type"); 2764 return false; 2765 } 2766 2767 static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data, 2768 lldb::offset_t *offset_ptr, int address_size, 2769 int dwarf_ref_size) { 2770 uint8_t opcode = data.GetU8(offset_ptr); 2771 DRC_class opcode_class; 2772 uint64_t uint; 2773 int64_t sint; 2774 2775 int size; 2776 2777 opcode_class = DW_OP_value_to_class(opcode) & (~DRC_DWARFv3); 2778 2779 s.Printf("%s ", DW_OP_value_to_name(opcode)); 2780 2781 /* Does this take zero parameters? If so we can shortcut this function. */ 2782 if (opcode_class == DRC_ZEROOPERANDS) 2783 return true; 2784 2785 if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx) { 2786 uint = data.GetULEB128(offset_ptr); 2787 sint = data.GetSLEB128(offset_ptr); 2788 s.Printf("%" PRIu64 " %" PRIi64, uint, sint); 2789 return true; 2790 } 2791 if (opcode_class != DRC_ONEOPERAND) { 2792 s.Printf("UNKNOWN OP %u", opcode); 2793 return false; 2794 } 2795 2796 switch (opcode) { 2797 case DW_OP_addr: 2798 size = address_size; 2799 break; 2800 case DW_OP_const1u: 2801 size = 1; 2802 break; 2803 case DW_OP_const1s: 2804 size = -1; 2805 break; 2806 case DW_OP_const2u: 2807 size = 2; 2808 break; 2809 case DW_OP_const2s: 2810 size = -2; 2811 break; 2812 case DW_OP_const4u: 2813 size = 4; 2814 break; 2815 case DW_OP_const4s: 2816 size = -4; 2817 break; 2818 case DW_OP_const8u: 2819 size = 8; 2820 break; 2821 case DW_OP_const8s: 2822 size = -8; 2823 break; 2824 case DW_OP_constu: 2825 size = 128; 2826 break; 2827 case DW_OP_consts: 2828 size = -128; 2829 break; 2830 case DW_OP_fbreg: 2831 size = -128; 2832 break; 2833 case DW_OP_breg0: 2834 case DW_OP_breg1: 2835 case DW_OP_breg2: 2836 case DW_OP_breg3: 2837 case DW_OP_breg4: 2838 case DW_OP_breg5: 2839 case DW_OP_breg6: 2840 case DW_OP_breg7: 2841 case DW_OP_breg8: 2842 case DW_OP_breg9: 2843 case DW_OP_breg10: 2844 case DW_OP_breg11: 2845 case DW_OP_breg12: 2846 case DW_OP_breg13: 2847 case DW_OP_breg14: 2848 case DW_OP_breg15: 2849 case DW_OP_breg16: 2850 case DW_OP_breg17: 2851 case DW_OP_breg18: 2852 case DW_OP_breg19: 2853 case DW_OP_breg20: 2854 case DW_OP_breg21: 2855 case DW_OP_breg22: 2856 case DW_OP_breg23: 2857 case DW_OP_breg24: 2858 case DW_OP_breg25: 2859 case DW_OP_breg26: 2860 case DW_OP_breg27: 2861 case DW_OP_breg28: 2862 case DW_OP_breg29: 2863 case DW_OP_breg30: 2864 case DW_OP_breg31: 2865 size = -128; 2866 break; 2867 case DW_OP_pick: 2868 case DW_OP_deref_size: 2869 case DW_OP_xderef_size: 2870 size = 1; 2871 break; 2872 case DW_OP_skip: 2873 case DW_OP_bra: 2874 size = -2; 2875 break; 2876 case DW_OP_call2: 2877 size = 2; 2878 break; 2879 case DW_OP_call4: 2880 size = 4; 2881 break; 2882 case DW_OP_call_ref: 2883 size = dwarf_ref_size; 2884 break; 2885 case DW_OP_addrx: 2886 case DW_OP_piece: 2887 case DW_OP_plus_uconst: 2888 case DW_OP_regx: 2889 case DW_OP_GNU_addr_index: 2890 case DW_OP_GNU_const_index: 2891 size = 128; 2892 break; 2893 default: 2894 s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode); 2895 return false; 2896 } 2897 2898 switch (size) { 2899 case -1: 2900 sint = (int8_t)data.GetU8(offset_ptr); 2901 s.Printf("%+" PRIi64, sint); 2902 break; 2903 case -2: 2904 sint = (int16_t)data.GetU16(offset_ptr); 2905 s.Printf("%+" PRIi64, sint); 2906 break; 2907 case -4: 2908 sint = (int32_t)data.GetU32(offset_ptr); 2909 s.Printf("%+" PRIi64, sint); 2910 break; 2911 case -8: 2912 sint = (int64_t)data.GetU64(offset_ptr); 2913 s.Printf("%+" PRIi64, sint); 2914 break; 2915 case -128: 2916 sint = data.GetSLEB128(offset_ptr); 2917 s.Printf("%+" PRIi64, sint); 2918 break; 2919 case 1: 2920 uint = data.GetU8(offset_ptr); 2921 s.Printf("0x%2.2" PRIx64, uint); 2922 break; 2923 case 2: 2924 uint = data.GetU16(offset_ptr); 2925 s.Printf("0x%4.4" PRIx64, uint); 2926 break; 2927 case 4: 2928 uint = data.GetU32(offset_ptr); 2929 s.Printf("0x%8.8" PRIx64, uint); 2930 break; 2931 case 8: 2932 uint = data.GetU64(offset_ptr); 2933 s.Printf("0x%16.16" PRIx64, uint); 2934 break; 2935 case 128: 2936 uint = data.GetULEB128(offset_ptr); 2937 s.Printf("0x%" PRIx64, uint); 2938 break; 2939 } 2940 2941 return true; 2942 } 2943 2944 bool DWARFExpression::PrintDWARFExpression(Stream &s, const DataExtractor &data, 2945 int address_size, int dwarf_ref_size, 2946 bool location_expression) { 2947 int op_count = 0; 2948 lldb::offset_t offset = 0; 2949 while (data.ValidOffset(offset)) { 2950 if (location_expression && op_count > 0) 2951 return false; 2952 if (op_count > 0) 2953 s.PutCString(", "); 2954 if (!print_dwarf_exp_op(s, data, &offset, address_size, dwarf_ref_size)) 2955 return false; 2956 op_count++; 2957 } 2958 2959 return true; 2960 } 2961 2962 void DWARFExpression::PrintDWARFLocationList( 2963 Stream &s, const DWARFUnit *cu, const DataExtractor &debug_loc_data, 2964 lldb::offset_t offset) { 2965 uint64_t start_addr, end_addr; 2966 uint32_t addr_size = DWARFUnit::GetAddressByteSize(cu); 2967 s.SetAddressByteSize(DWARFUnit::GetAddressByteSize(cu)); 2968 dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; 2969 while (debug_loc_data.ValidOffset(offset)) { 2970 start_addr = debug_loc_data.GetMaxU64(&offset, addr_size); 2971 end_addr = debug_loc_data.GetMaxU64(&offset, addr_size); 2972 2973 if (start_addr == 0 && end_addr == 0) 2974 break; 2975 2976 s.PutCString("\n "); 2977 s.Indent(); 2978 if (cu) 2979 s.AddressRange(start_addr + base_addr, end_addr + base_addr, 2980 cu->GetAddressByteSize(), nullptr, ": "); 2981 uint32_t loc_length = debug_loc_data.GetU16(&offset); 2982 2983 DataExtractor locationData(debug_loc_data, offset, loc_length); 2984 PrintDWARFExpression(s, locationData, addr_size, 4, false); 2985 offset += loc_length; 2986 } 2987 } 2988 2989 bool DWARFExpression::GetOpAndEndOffsets(StackFrame &frame, 2990 lldb::offset_t &op_offset, 2991 lldb::offset_t &end_offset) { 2992 SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction); 2993 if (!sc.function) { 2994 return false; 2995 } 2996 2997 addr_t loclist_base_file_addr = 2998 sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); 2999 if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) { 3000 return false; 3001 } 3002 3003 addr_t pc_file_addr = frame.GetFrameCodeAddress().GetFileAddress(); 3004 lldb::offset_t opcodes_offset, opcodes_length; 3005 if (!GetLocation(loclist_base_file_addr, pc_file_addr, opcodes_offset, 3006 opcodes_length)) { 3007 return false; 3008 } 3009 3010 if (opcodes_length == 0) { 3011 return false; 3012 } 3013 3014 op_offset = opcodes_offset; 3015 end_offset = opcodes_offset + opcodes_length; 3016 return true; 3017 } 3018 3019 bool DWARFExpression::MatchesOperand(StackFrame &frame, 3020 const Instruction::Operand &operand) { 3021 using namespace OperandMatchers; 3022 3023 lldb::offset_t op_offset; 3024 lldb::offset_t end_offset; 3025 if (!GetOpAndEndOffsets(frame, op_offset, end_offset)) { 3026 return false; 3027 } 3028 3029 if (!m_data.ValidOffset(op_offset) || op_offset >= end_offset) { 3030 return false; 3031 } 3032 3033 RegisterContextSP reg_ctx_sp = frame.GetRegisterContext(); 3034 if (!reg_ctx_sp) { 3035 return false; 3036 } 3037 3038 DataExtractor opcodes = m_data; 3039 uint8_t opcode = opcodes.GetU8(&op_offset); 3040 3041 if (opcode == DW_OP_fbreg) { 3042 int64_t offset = opcodes.GetSLEB128(&op_offset); 3043 3044 DWARFExpression *fb_expr = frame.GetFrameBaseExpression(nullptr); 3045 if (!fb_expr) { 3046 return false; 3047 } 3048 3049 auto recurse = [&frame, fb_expr](const Instruction::Operand &child) { 3050 return fb_expr->MatchesOperand(frame, child); 3051 }; 3052 3053 if (!offset && 3054 MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference), 3055 recurse)(operand)) { 3056 return true; 3057 } 3058 3059 return MatchUnaryOp( 3060 MatchOpType(Instruction::Operand::Type::Dereference), 3061 MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum), 3062 MatchImmOp(offset), recurse))(operand); 3063 } 3064 3065 bool dereference = false; 3066 const RegisterInfo *reg = nullptr; 3067 int64_t offset = 0; 3068 3069 if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31) { 3070 reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_reg0); 3071 } else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31) { 3072 offset = opcodes.GetSLEB128(&op_offset); 3073 reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_breg0); 3074 } else if (opcode == DW_OP_regx) { 3075 uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset)); 3076 reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num); 3077 } else if (opcode == DW_OP_bregx) { 3078 uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset)); 3079 offset = opcodes.GetSLEB128(&op_offset); 3080 reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num); 3081 } else { 3082 return false; 3083 } 3084 3085 if (!reg) { 3086 return false; 3087 } 3088 3089 if (dereference) { 3090 if (!offset && 3091 MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference), 3092 MatchRegOp(*reg))(operand)) { 3093 return true; 3094 } 3095 3096 return MatchUnaryOp( 3097 MatchOpType(Instruction::Operand::Type::Dereference), 3098 MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum), 3099 MatchRegOp(*reg), 3100 MatchImmOp(offset)))(operand); 3101 } else { 3102 return MatchRegOp(*reg)(operand); 3103 } 3104 } 3105 3106