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