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 53namespace lldb_private { 54class CompileUnit; 55} 56namespace lldb_private { 57class Function; 58} 59 60using namespace lldb; 61using namespace lldb_private; 62 63static 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 78static 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 103static 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 127static 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 164static 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 192static 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 235Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {} 236 237Address::Address(addr_t address, const SectionList *section_list) 238 : m_section_wp() { 239 ResolveAddressUsingFileSections(address, section_list); 240} 241 242const 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 250bool 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. 268bool 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 285ModuleSP 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 293addr_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 313addr_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 338addr_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 361bool 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 370addr_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 381bool 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 395bool 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.file.GetFilename().GetCString(), 402 line_entry.line, line_entry.column); 403 return true; 404 } 405 return false; 406} 407 408bool 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, 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 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 811bool Address::SectionWasDeleted() const { 812 if (GetSection()) 813 return false; 814 return SectionWasDeletedPrivate(); 815} 816 817bool 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 830uint32_t 831Address::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 850ModuleSP Address::CalculateSymbolContextModule() const { 851 SectionSP section_sp(GetSection()); 852 if (section_sp) 853 return section_sp->GetModule(); 854 return ModuleSP(); 855} 856 857CompileUnit *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 871Function *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 885Block *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 899Symbol *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 913bool 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 931int 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 941int 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 953int 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 973size_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 991bool 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 1006bool 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) 1022bool 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) 1028bool lldb_private::operator!=(const Address &a, const Address &rhs) { 1029 return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection(); 1030} 1031 1032AddressClass 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 1046bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target, 1047 bool allow_section_end) { 1048 if (target && target->GetSectionLoadList().ResolveLoadAddress( 1049 load_addr, *this, allow_section_end)) 1050 return true; 1051 m_section_wp.reset(); 1052 m_offset = load_addr; 1053 return false; 1054} 1055