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