1 //===-- Address.cpp ---------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Core/Address.h" 11 12 // C Includes 13 // C++ Includes 14 #include "llvm/ADT/Triple.h" 15 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Core/DumpDataExtractor.h" 19 #include "lldb/Core/Module.h" 20 #include "lldb/Core/Section.h" 21 #include "lldb/Symbol/Block.h" 22 #include "lldb/Symbol/ObjectFile.h" 23 #include "lldb/Symbol/SymbolVendor.h" 24 #include "lldb/Symbol/Variable.h" 25 #include "lldb/Symbol/VariableList.h" 26 #include "lldb/Target/ExecutionContext.h" 27 #include "lldb/Target/Process.h" 28 #include "lldb/Target/SectionLoadList.h" 29 #include "lldb/Target/Target.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 static size_t ReadBytes(ExecutionContextScope *exe_scope, 35 const Address &address, void *dst, size_t dst_len) { 36 if (exe_scope == nullptr) 37 return 0; 38 39 TargetSP target_sp(exe_scope->CalculateTarget()); 40 if (target_sp) { 41 Error error; 42 bool prefer_file_cache = false; 43 return target_sp->ReadMemory(address, prefer_file_cache, dst, dst_len, 44 error); 45 } 46 return 0; 47 } 48 49 static bool GetByteOrderAndAddressSize(ExecutionContextScope *exe_scope, 50 const Address &address, 51 ByteOrder &byte_order, 52 uint32_t &addr_size) { 53 byte_order = eByteOrderInvalid; 54 addr_size = 0; 55 if (exe_scope == nullptr) 56 return false; 57 58 TargetSP target_sp(exe_scope->CalculateTarget()); 59 if (target_sp) { 60 byte_order = target_sp->GetArchitecture().GetByteOrder(); 61 addr_size = target_sp->GetArchitecture().GetAddressByteSize(); 62 } 63 64 if (byte_order == eByteOrderInvalid || addr_size == 0) { 65 ModuleSP module_sp(address.GetModule()); 66 if (module_sp) { 67 byte_order = module_sp->GetArchitecture().GetByteOrder(); 68 addr_size = module_sp->GetArchitecture().GetAddressByteSize(); 69 } 70 } 71 return byte_order != eByteOrderInvalid && addr_size != 0; 72 } 73 74 static uint64_t ReadUIntMax64(ExecutionContextScope *exe_scope, 75 const Address &address, uint32_t byte_size, 76 bool &success) { 77 uint64_t uval64 = 0; 78 if (exe_scope == nullptr || byte_size > sizeof(uint64_t)) { 79 success = false; 80 return 0; 81 } 82 uint64_t buf = 0; 83 84 success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size; 85 if (success) { 86 ByteOrder byte_order = eByteOrderInvalid; 87 uint32_t addr_size = 0; 88 if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) { 89 DataExtractor data(&buf, sizeof(buf), byte_order, addr_size); 90 lldb::offset_t offset = 0; 91 uval64 = data.GetU64(&offset); 92 } else 93 success = false; 94 } 95 return uval64; 96 } 97 98 static bool ReadAddress(ExecutionContextScope *exe_scope, 99 const Address &address, uint32_t pointer_size, 100 Address &deref_so_addr) { 101 if (exe_scope == nullptr) 102 return false; 103 104 bool success = false; 105 addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success); 106 if (success) { 107 ExecutionContext exe_ctx; 108 exe_scope->CalculateExecutionContext(exe_ctx); 109 // If we have any sections that are loaded, try and resolve using the 110 // section load list 111 Target *target = exe_ctx.GetTargetPtr(); 112 if (target && !target->GetSectionLoadList().IsEmpty()) { 113 if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr, 114 deref_so_addr)) 115 return true; 116 } else { 117 // If we were not running, yet able to read an integer, we must 118 // have a module 119 ModuleSP module_sp(address.GetModule()); 120 121 assert(module_sp); 122 if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr)) 123 return true; 124 } 125 126 // We couldn't make "deref_addr" into a section offset value, but we were 127 // able to read the address, so we return a section offset address with 128 // no section and "deref_addr" as the offset (address). 129 deref_so_addr.SetRawAddress(deref_addr); 130 return true; 131 } 132 return false; 133 } 134 135 static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address, 136 uint32_t byte_size, Stream *strm) { 137 if (exe_scope == nullptr || byte_size == 0) 138 return 0; 139 std::vector<uint8_t> buf(byte_size, 0); 140 141 if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) { 142 ByteOrder byte_order = eByteOrderInvalid; 143 uint32_t addr_size = 0; 144 if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) { 145 DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size); 146 147 DumpDataExtractor(data, strm, 148 0, // Start offset in "data" 149 eFormatHex, // Print as characters 150 buf.size(), // Size of item 151 1, // Items count 152 UINT32_MAX, // num per line 153 LLDB_INVALID_ADDRESS, // base address 154 0, // bitfield bit size 155 0); // bitfield bit offset 156 157 return true; 158 } 159 } 160 return false; 161 } 162 163 static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope, 164 const Address &address, Stream *strm) { 165 if (exe_scope == nullptr) 166 return 0; 167 const size_t k_buf_len = 256; 168 char buf[k_buf_len + 1]; 169 buf[k_buf_len] = '\0'; // NULL terminate 170 171 // Byte order and address size don't matter for C string dumping.. 172 DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4); 173 size_t total_len = 0; 174 size_t bytes_read; 175 Address curr_address(address); 176 strm->PutChar('"'); 177 while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) > 178 0) { 179 size_t len = strlen(buf); 180 if (len == 0) 181 break; 182 if (len > bytes_read) 183 len = bytes_read; 184 185 DumpDataExtractor(data, strm, 186 0, // Start offset in "data" 187 eFormatChar, // Print as characters 188 1, // Size of item (1 byte for a char!) 189 len, // How many bytes to print? 190 UINT32_MAX, // num per line 191 LLDB_INVALID_ADDRESS, // base address 192 0, // bitfield bit size 193 194 0); // bitfield bit offset 195 196 total_len += bytes_read; 197 198 if (len < k_buf_len) 199 break; 200 curr_address.SetOffset(curr_address.GetOffset() + bytes_read); 201 } 202 strm->PutChar('"'); 203 return total_len; 204 } 205 206 Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {} 207 208 Address::Address(addr_t address, const SectionList *section_list) 209 : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) { 210 ResolveAddressUsingFileSections(address, section_list); 211 } 212 213 const Address &Address::operator=(const Address &rhs) { 214 if (this != &rhs) { 215 m_section_wp = rhs.m_section_wp; 216 m_offset = rhs.m_offset; 217 } 218 return *this; 219 } 220 221 bool Address::ResolveAddressUsingFileSections(addr_t file_addr, 222 const SectionList *section_list) { 223 if (section_list) { 224 SectionSP section_sp( 225 section_list->FindSectionContainingFileAddress(file_addr)); 226 m_section_wp = section_sp; 227 if (section_sp) { 228 assert(section_sp->ContainsFileAddress(file_addr)); 229 m_offset = file_addr - section_sp->GetFileAddress(); 230 return true; // Successfully transformed addr into a section offset 231 // address 232 } 233 } 234 m_offset = file_addr; 235 return false; // Failed to resolve this address to a section offset value 236 } 237 238 ModuleSP Address::GetModule() const { 239 lldb::ModuleSP module_sp; 240 SectionSP section_sp(GetSection()); 241 if (section_sp) 242 module_sp = section_sp->GetModule(); 243 return module_sp; 244 } 245 246 addr_t Address::GetFileAddress() const { 247 SectionSP section_sp(GetSection()); 248 if (section_sp) { 249 addr_t sect_file_addr = section_sp->GetFileAddress(); 250 if (sect_file_addr == LLDB_INVALID_ADDRESS) { 251 // Section isn't resolved, we can't return a valid file address 252 return LLDB_INVALID_ADDRESS; 253 } 254 // We have a valid file range, so we can return the file based 255 // address by adding the file base address to our offset 256 return sect_file_addr + m_offset; 257 } else if (SectionWasDeletedPrivate()) { 258 // Used to have a valid section but it got deleted so the 259 // offset doesn't mean anything without the section 260 return LLDB_INVALID_ADDRESS; 261 } 262 // No section, we just return the offset since it is the value in this case 263 return m_offset; 264 } 265 266 addr_t Address::GetLoadAddress(Target *target) const { 267 SectionSP section_sp(GetSection()); 268 if (section_sp) { 269 if (target) { 270 addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target); 271 272 if (sect_load_addr != LLDB_INVALID_ADDRESS) { 273 // We have a valid file range, so we can return the file based 274 // address by adding the file base address to our offset 275 return sect_load_addr + m_offset; 276 } 277 } 278 } else if (SectionWasDeletedPrivate()) { 279 // Used to have a valid section but it got deleted so the 280 // offset doesn't mean anything without the section 281 return LLDB_INVALID_ADDRESS; 282 } else { 283 // We don't have a section so the offset is the load address 284 return m_offset; 285 } 286 // The section isn't resolved or an invalid target was passed in 287 // so we can't return a valid load address. 288 return LLDB_INVALID_ADDRESS; 289 } 290 291 addr_t Address::GetCallableLoadAddress(Target *target, bool is_indirect) const { 292 addr_t code_addr = LLDB_INVALID_ADDRESS; 293 294 if (is_indirect && target) { 295 ProcessSP processSP = target->GetProcessSP(); 296 Error error; 297 if (processSP) { 298 code_addr = processSP->ResolveIndirectFunction(this, error); 299 if (!error.Success()) 300 code_addr = LLDB_INVALID_ADDRESS; 301 } 302 } else { 303 code_addr = GetLoadAddress(target); 304 } 305 306 if (code_addr == LLDB_INVALID_ADDRESS) 307 return code_addr; 308 309 if (target) 310 return target->GetCallableLoadAddress(code_addr, GetAddressClass()); 311 return code_addr; 312 } 313 314 bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) { 315 if (SetLoadAddress(load_addr, target)) { 316 if (target) 317 m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass()); 318 return true; 319 } 320 return false; 321 } 322 323 addr_t Address::GetOpcodeLoadAddress(Target *target, 324 AddressClass addr_class) const { 325 addr_t code_addr = GetLoadAddress(target); 326 if (code_addr != LLDB_INVALID_ADDRESS) { 327 if (addr_class == eAddressClassInvalid) 328 addr_class = GetAddressClass(); 329 code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class); 330 } 331 return code_addr; 332 } 333 334 bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, 335 AddressClass addr_class) { 336 if (SetLoadAddress(load_addr, target)) { 337 if (target) { 338 if (addr_class == eAddressClassInvalid) 339 addr_class = GetAddressClass(); 340 m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class); 341 } 342 return true; 343 } 344 return false; 345 } 346 347 bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, 348 DumpStyle fallback_style, uint32_t addr_size) const { 349 // If the section was nullptr, only load address is going to work unless we 350 // are 351 // trying to deref a pointer 352 SectionSP section_sp(GetSection()); 353 if (!section_sp && style != DumpStyleResolvedPointerDescription) 354 style = DumpStyleLoadAddress; 355 356 ExecutionContext exe_ctx(exe_scope); 357 Target *target = exe_ctx.GetTargetPtr(); 358 // If addr_byte_size is UINT32_MAX, then determine the correct address 359 // byte size for the process or default to the size of addr_t 360 if (addr_size == UINT32_MAX) { 361 if (target) 362 addr_size = target->GetArchitecture().GetAddressByteSize(); 363 else 364 addr_size = sizeof(addr_t); 365 } 366 367 Address so_addr; 368 switch (style) { 369 case DumpStyleInvalid: 370 return false; 371 372 case DumpStyleSectionNameOffset: 373 if (section_sp) { 374 section_sp->DumpName(s); 375 s->Printf(" + %" PRIu64, m_offset); 376 } else { 377 s->Address(m_offset, addr_size); 378 } 379 break; 380 381 case DumpStyleSectionPointerOffset: 382 s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get())); 383 s->Address(m_offset, addr_size); 384 break; 385 386 case DumpStyleModuleWithFileAddress: 387 if (section_sp) { 388 ModuleSP module_sp = section_sp->GetModule(); 389 if (module_sp) 390 s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString( 391 "<Unknown>")); 392 else 393 s->Printf("%s[", "<Unknown>"); 394 } 395 LLVM_FALLTHROUGH; 396 case DumpStyleFileAddress: { 397 addr_t file_addr = GetFileAddress(); 398 if (file_addr == LLDB_INVALID_ADDRESS) { 399 if (fallback_style != DumpStyleInvalid) 400 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 401 return false; 402 } 403 s->Address(file_addr, addr_size); 404 if (style == DumpStyleModuleWithFileAddress && section_sp) 405 s->PutChar(']'); 406 } break; 407 408 case DumpStyleLoadAddress: { 409 addr_t load_addr = GetLoadAddress(target); 410 411 /* 412 * MIPS: 413 * Display address in compressed form for MIPS16 or microMIPS 414 * if the address belongs to eAddressClassCodeAlternateISA. 415 */ 416 if (target) { 417 const llvm::Triple::ArchType llvm_arch = 418 target->GetArchitecture().GetMachine(); 419 if (llvm_arch == llvm::Triple::mips || 420 llvm_arch == llvm::Triple::mipsel || 421 llvm_arch == llvm::Triple::mips64 || 422 llvm_arch == llvm::Triple::mips64el) 423 load_addr = GetCallableLoadAddress(target); 424 } 425 426 if (load_addr == LLDB_INVALID_ADDRESS) { 427 if (fallback_style != DumpStyleInvalid) 428 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 429 return false; 430 } 431 s->Address(load_addr, addr_size); 432 } break; 433 434 case DumpStyleResolvedDescription: 435 case DumpStyleResolvedDescriptionNoModule: 436 case DumpStyleResolvedDescriptionNoFunctionArguments: 437 case DumpStyleNoFunctionName: 438 if (IsSectionOffset()) { 439 uint32_t pointer_size = 4; 440 ModuleSP module_sp(GetModule()); 441 if (target) 442 pointer_size = target->GetArchitecture().GetAddressByteSize(); 443 else if (module_sp) 444 pointer_size = module_sp->GetArchitecture().GetAddressByteSize(); 445 446 bool showed_info = false; 447 if (section_sp) { 448 SectionType sect_type = section_sp->GetType(); 449 switch (sect_type) { 450 case eSectionTypeData: 451 if (module_sp) { 452 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); 453 if (sym_vendor) { 454 Symtab *symtab = sym_vendor->GetSymtab(); 455 if (symtab) { 456 const addr_t file_Addr = GetFileAddress(); 457 Symbol *symbol = 458 symtab->FindSymbolContainingFileAddress(file_Addr); 459 if (symbol) { 460 const char *symbol_name = symbol->GetName().AsCString(); 461 if (symbol_name) { 462 s->PutCString(symbol_name); 463 addr_t delta = 464 file_Addr - symbol->GetAddressRef().GetFileAddress(); 465 if (delta) 466 s->Printf(" + %" PRIu64, delta); 467 showed_info = true; 468 } 469 } 470 } 471 } 472 } 473 break; 474 475 case eSectionTypeDataCString: 476 // Read the C string from memory and display it 477 showed_info = true; 478 ReadCStringFromMemory(exe_scope, *this, s); 479 break; 480 481 case eSectionTypeDataCStringPointers: 482 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) { 483 #if VERBOSE_OUTPUT 484 s->PutCString("(char *)"); 485 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, 486 DumpStyleFileAddress); 487 s->PutCString(": "); 488 #endif 489 showed_info = true; 490 ReadCStringFromMemory(exe_scope, so_addr, s); 491 } 492 break; 493 494 case eSectionTypeDataObjCMessageRefs: 495 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) { 496 if (target && so_addr.IsSectionOffset()) { 497 SymbolContext func_sc; 498 target->GetImages().ResolveSymbolContextForAddress( 499 so_addr, eSymbolContextEverything, func_sc); 500 if (func_sc.function != nullptr || func_sc.symbol != nullptr) { 501 showed_info = true; 502 #if VERBOSE_OUTPUT 503 s->PutCString("(objc_msgref *) -> { (func*)"); 504 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, 505 DumpStyleFileAddress); 506 #else 507 s->PutCString("{ "); 508 #endif 509 Address cstr_addr(*this); 510 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size); 511 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, 512 false, true, true); 513 if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) { 514 #if VERBOSE_OUTPUT 515 s->PutCString("), (char *)"); 516 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, 517 DumpStyleFileAddress); 518 s->PutCString(" ("); 519 #else 520 s->PutCString(", "); 521 #endif 522 ReadCStringFromMemory(exe_scope, so_addr, s); 523 } 524 #if VERBOSE_OUTPUT 525 s->PutCString(") }"); 526 #else 527 s->PutCString(" }"); 528 #endif 529 } 530 } 531 } 532 break; 533 534 case eSectionTypeDataObjCCFStrings: { 535 Address cfstring_data_addr(*this); 536 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + 537 (2 * pointer_size)); 538 if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size, 539 so_addr)) { 540 #if VERBOSE_OUTPUT 541 s->PutCString("(CFString *) "); 542 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, 543 DumpStyleFileAddress); 544 s->PutCString(" -> @"); 545 #else 546 s->PutChar('@'); 547 #endif 548 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription)) 549 showed_info = true; 550 } 551 } break; 552 553 case eSectionTypeData4: 554 // Read the 4 byte data and display it 555 showed_info = true; 556 s->PutCString("(uint32_t) "); 557 DumpUInt(exe_scope, *this, 4, s); 558 break; 559 560 case eSectionTypeData8: 561 // Read the 8 byte data and display it 562 showed_info = true; 563 s->PutCString("(uint64_t) "); 564 DumpUInt(exe_scope, *this, 8, s); 565 break; 566 567 case eSectionTypeData16: 568 // Read the 16 byte data and display it 569 showed_info = true; 570 s->PutCString("(uint128_t) "); 571 DumpUInt(exe_scope, *this, 16, s); 572 break; 573 574 case eSectionTypeDataPointers: 575 // Read the pointer data and display it 576 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) { 577 s->PutCString("(void *)"); 578 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, 579 DumpStyleFileAddress); 580 581 showed_info = true; 582 if (so_addr.IsSectionOffset()) { 583 SymbolContext pointer_sc; 584 if (target) { 585 target->GetImages().ResolveSymbolContextForAddress( 586 so_addr, eSymbolContextEverything, pointer_sc); 587 if (pointer_sc.function != nullptr || 588 pointer_sc.symbol != nullptr) { 589 s->PutCString(": "); 590 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, 591 false, true, true); 592 } 593 } 594 } 595 } 596 break; 597 598 default: 599 break; 600 } 601 } 602 603 if (!showed_info) { 604 if (module_sp) { 605 SymbolContext sc; 606 module_sp->ResolveSymbolContextForAddress( 607 *this, eSymbolContextEverything, sc); 608 if (sc.function || sc.symbol) { 609 bool show_stop_context = true; 610 const bool show_module = (style == DumpStyleResolvedDescription); 611 const bool show_fullpaths = false; 612 const bool show_inlined_frames = true; 613 const bool show_function_arguments = 614 (style != DumpStyleResolvedDescriptionNoFunctionArguments); 615 const bool show_function_name = (style != DumpStyleNoFunctionName); 616 if (sc.function == nullptr && sc.symbol != nullptr) { 617 // If we have just a symbol make sure it is in the right section 618 if (sc.symbol->ValueIsAddress()) { 619 if (sc.symbol->GetAddressRef().GetSection() != GetSection()) { 620 // don't show the module if the symbol is a trampoline symbol 621 show_stop_context = false; 622 } 623 } 624 } 625 if (show_stop_context) { 626 // We have a function or a symbol from the same 627 // sections as this address. 628 sc.DumpStopContext(s, exe_scope, *this, show_fullpaths, 629 show_module, show_inlined_frames, 630 show_function_arguments, show_function_name); 631 } else { 632 // We found a symbol but it was in a different 633 // section so it isn't the symbol we should be 634 // showing, just show the section name + offset 635 Dump(s, exe_scope, DumpStyleSectionNameOffset); 636 } 637 } 638 } 639 } 640 } else { 641 if (fallback_style != DumpStyleInvalid) 642 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 643 return false; 644 } 645 break; 646 647 case DumpStyleDetailedSymbolContext: 648 if (IsSectionOffset()) { 649 ModuleSP module_sp(GetModule()); 650 if (module_sp) { 651 SymbolContext sc; 652 module_sp->ResolveSymbolContextForAddress( 653 *this, eSymbolContextEverything | eSymbolContextVariable, sc); 654 if (sc.symbol) { 655 // If we have just a symbol make sure it is in the same section 656 // as our address. If it isn't, then we might have just found 657 // the last symbol that came before the address that we are 658 // looking up that has nothing to do with our address lookup. 659 if (sc.symbol->ValueIsAddress() && 660 sc.symbol->GetAddressRef().GetSection() != GetSection()) 661 sc.symbol = nullptr; 662 } 663 sc.GetDescription(s, eDescriptionLevelBrief, target); 664 665 if (sc.block) { 666 bool can_create = true; 667 bool get_parent_variables = true; 668 bool stop_if_block_is_inlined_function = false; 669 VariableList variable_list; 670 sc.block->AppendVariables(can_create, get_parent_variables, 671 stop_if_block_is_inlined_function, 672 [](Variable *) { return true; }, 673 &variable_list); 674 675 const size_t num_variables = variable_list.GetSize(); 676 for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) { 677 Variable *var = variable_list.GetVariableAtIndex(var_idx).get(); 678 if (var && var->LocationIsValidForAddress(*this)) { 679 s->Indent(); 680 s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"", 681 var->GetID(), var->GetName().GetCString()); 682 Type *type = var->GetType(); 683 if (type) 684 s->Printf(", type = \"%s\"", type->GetName().GetCString()); 685 else 686 s->PutCString(", type = <unknown>"); 687 s->PutCString(", location = "); 688 var->DumpLocationForAddress(s, *this); 689 s->PutCString(", decl = "); 690 var->GetDeclaration().DumpStopContext(s, false); 691 s->EOL(); 692 } 693 } 694 } 695 } 696 } else { 697 if (fallback_style != DumpStyleInvalid) 698 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 699 return false; 700 } 701 break; 702 703 case DumpStyleResolvedPointerDescription: { 704 Process *process = exe_ctx.GetProcessPtr(); 705 if (process) { 706 addr_t load_addr = GetLoadAddress(target); 707 if (load_addr != LLDB_INVALID_ADDRESS) { 708 Error memory_error; 709 addr_t dereferenced_load_addr = 710 process->ReadPointerFromMemory(load_addr, memory_error); 711 if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) { 712 Address dereferenced_addr; 713 if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, 714 target)) { 715 StreamString strm; 716 if (dereferenced_addr.Dump(&strm, exe_scope, 717 DumpStyleResolvedDescription, 718 DumpStyleInvalid, addr_size)) { 719 s->Address(dereferenced_load_addr, addr_size, " -> ", " "); 720 s->Write(strm.GetString().data(), strm.GetSize()); 721 return true; 722 } 723 } 724 } 725 } 726 } 727 if (fallback_style != DumpStyleInvalid) 728 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 729 return false; 730 } break; 731 } 732 733 return true; 734 } 735 736 bool Address::SectionWasDeleted() const { 737 if (GetSection()) 738 return false; 739 return SectionWasDeletedPrivate(); 740 } 741 742 bool Address::SectionWasDeletedPrivate() const { 743 lldb::SectionWP empty_section_wp; 744 745 // If either call to "std::weak_ptr::owner_before(...) value returns true, 746 // this 747 // indicates that m_section_wp once contained (possibly still does) a 748 // reference 749 // to a valid shared pointer. This helps us know if we had a valid reference 750 // to 751 // a section which is now invalid because the module it was in was 752 // unloaded/deleted, 753 // or if the address doesn't have a valid reference to a section. 754 return empty_section_wp.owner_before(m_section_wp) || 755 m_section_wp.owner_before(empty_section_wp); 756 } 757 758 uint32_t Address::CalculateSymbolContext(SymbolContext *sc, 759 uint32_t resolve_scope) const { 760 sc->Clear(false); 761 // Absolute addresses don't have enough information to reconstruct even their 762 // target. 763 764 SectionSP section_sp(GetSection()); 765 if (section_sp) { 766 ModuleSP module_sp(section_sp->GetModule()); 767 if (module_sp) { 768 sc->module_sp = module_sp; 769 if (sc->module_sp) 770 return sc->module_sp->ResolveSymbolContextForAddress( 771 *this, resolve_scope, *sc); 772 } 773 } 774 return 0; 775 } 776 777 ModuleSP Address::CalculateSymbolContextModule() const { 778 SectionSP section_sp(GetSection()); 779 if (section_sp) 780 return section_sp->GetModule(); 781 return ModuleSP(); 782 } 783 784 CompileUnit *Address::CalculateSymbolContextCompileUnit() const { 785 SectionSP section_sp(GetSection()); 786 if (section_sp) { 787 SymbolContext sc; 788 sc.module_sp = section_sp->GetModule(); 789 if (sc.module_sp) { 790 sc.module_sp->ResolveSymbolContextForAddress(*this, 791 eSymbolContextCompUnit, sc); 792 return sc.comp_unit; 793 } 794 } 795 return nullptr; 796 } 797 798 Function *Address::CalculateSymbolContextFunction() const { 799 SectionSP section_sp(GetSection()); 800 if (section_sp) { 801 SymbolContext sc; 802 sc.module_sp = section_sp->GetModule(); 803 if (sc.module_sp) { 804 sc.module_sp->ResolveSymbolContextForAddress(*this, 805 eSymbolContextFunction, sc); 806 return sc.function; 807 } 808 } 809 return nullptr; 810 } 811 812 Block *Address::CalculateSymbolContextBlock() const { 813 SectionSP section_sp(GetSection()); 814 if (section_sp) { 815 SymbolContext sc; 816 sc.module_sp = section_sp->GetModule(); 817 if (sc.module_sp) { 818 sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock, 819 sc); 820 return sc.block; 821 } 822 } 823 return nullptr; 824 } 825 826 Symbol *Address::CalculateSymbolContextSymbol() const { 827 SectionSP section_sp(GetSection()); 828 if (section_sp) { 829 SymbolContext sc; 830 sc.module_sp = section_sp->GetModule(); 831 if (sc.module_sp) { 832 sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol, 833 sc); 834 return sc.symbol; 835 } 836 } 837 return nullptr; 838 } 839 840 bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const { 841 SectionSP section_sp(GetSection()); 842 if (section_sp) { 843 SymbolContext sc; 844 sc.module_sp = section_sp->GetModule(); 845 if (sc.module_sp) { 846 sc.module_sp->ResolveSymbolContextForAddress(*this, 847 eSymbolContextLineEntry, sc); 848 if (sc.line_entry.IsValid()) { 849 line_entry = sc.line_entry; 850 return true; 851 } 852 } 853 } 854 line_entry.Clear(); 855 return false; 856 } 857 858 int Address::CompareFileAddress(const Address &a, const Address &b) { 859 addr_t a_file_addr = a.GetFileAddress(); 860 addr_t b_file_addr = b.GetFileAddress(); 861 if (a_file_addr < b_file_addr) 862 return -1; 863 if (a_file_addr > b_file_addr) 864 return +1; 865 return 0; 866 } 867 868 int Address::CompareLoadAddress(const Address &a, const Address &b, 869 Target *target) { 870 assert(target != nullptr); 871 addr_t a_load_addr = a.GetLoadAddress(target); 872 addr_t b_load_addr = b.GetLoadAddress(target); 873 if (a_load_addr < b_load_addr) 874 return -1; 875 if (a_load_addr > b_load_addr) 876 return +1; 877 return 0; 878 } 879 880 int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) { 881 ModuleSP a_module_sp(a.GetModule()); 882 ModuleSP b_module_sp(b.GetModule()); 883 Module *a_module = a_module_sp.get(); 884 Module *b_module = b_module_sp.get(); 885 if (a_module < b_module) 886 return -1; 887 if (a_module > b_module) 888 return +1; 889 // Modules are the same, just compare the file address since they should 890 // be unique 891 addr_t a_file_addr = a.GetFileAddress(); 892 addr_t b_file_addr = b.GetFileAddress(); 893 if (a_file_addr < b_file_addr) 894 return -1; 895 if (a_file_addr > b_file_addr) 896 return +1; 897 return 0; 898 } 899 900 size_t Address::MemorySize() const { 901 // Noting special for the memory size of a single Address object, 902 // it is just the size of itself. 903 return sizeof(Address); 904 } 905 906 //---------------------------------------------------------------------- 907 // NOTE: Be careful using this operator. It can correctly compare two 908 // addresses from the same Module correctly. It can't compare two 909 // addresses from different modules in any meaningful way, but it will 910 // compare the module pointers. 911 // 912 // To sum things up: 913 // - works great for addresses within the same module 914 // - it works for addresses across multiple modules, but don't expect the 915 // address results to make much sense 916 // 917 // This basically lets Address objects be used in ordered collection 918 // classes. 919 //---------------------------------------------------------------------- 920 921 bool lldb_private::operator<(const Address &lhs, const Address &rhs) { 922 ModuleSP lhs_module_sp(lhs.GetModule()); 923 ModuleSP rhs_module_sp(rhs.GetModule()); 924 Module *lhs_module = lhs_module_sp.get(); 925 Module *rhs_module = rhs_module_sp.get(); 926 if (lhs_module == rhs_module) { 927 // Addresses are in the same module, just compare the file addresses 928 return lhs.GetFileAddress() < rhs.GetFileAddress(); 929 } else { 930 // The addresses are from different modules, just use the module 931 // pointer value to get consistent ordering 932 return lhs_module < rhs_module; 933 } 934 } 935 936 bool lldb_private::operator>(const Address &lhs, const Address &rhs) { 937 ModuleSP lhs_module_sp(lhs.GetModule()); 938 ModuleSP rhs_module_sp(rhs.GetModule()); 939 Module *lhs_module = lhs_module_sp.get(); 940 Module *rhs_module = rhs_module_sp.get(); 941 if (lhs_module == rhs_module) { 942 // Addresses are in the same module, just compare the file addresses 943 return lhs.GetFileAddress() > rhs.GetFileAddress(); 944 } else { 945 // The addresses are from different modules, just use the module 946 // pointer value to get consistent ordering 947 return lhs_module > rhs_module; 948 } 949 } 950 951 // The operator == checks for exact equality only (same section, same offset) 952 bool lldb_private::operator==(const Address &a, const Address &rhs) { 953 return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection(); 954 } 955 956 // The operator != checks for exact inequality only (differing section, or 957 // different offset) 958 bool lldb_private::operator!=(const Address &a, const Address &rhs) { 959 return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection(); 960 } 961 962 AddressClass Address::GetAddressClass() const { 963 ModuleSP module_sp(GetModule()); 964 if (module_sp) { 965 ObjectFile *obj_file = module_sp->GetObjectFile(); 966 if (obj_file) { 967 // Give the symbol vendor a chance to add to the unified section list. 968 module_sp->GetSymbolVendor(); 969 return obj_file->GetAddressClass(GetFileAddress()); 970 } 971 } 972 return eAddressClassUnknown; 973 } 974 975 bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target) { 976 if (target && 977 target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this)) 978 return true; 979 m_section_wp.reset(); 980 m_offset = load_addr; 981 return false; 982 } 983