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