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/Target/ExecutionContext.h" 15 #include "lldb/Target/Process.h" 16 #include "lldb/Target/Target.h" 17 18 #include "llvm/ADT/Triple.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 23 static size_t 24 ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len) 25 { 26 if (exe_scope == NULL) 27 return 0; 28 29 Target *target = exe_scope->CalculateTarget(); 30 if (target) 31 { 32 Error error; 33 bool prefer_file_cache = false; 34 return target->ReadMemory (address, prefer_file_cache, dst, dst_len, error); 35 } 36 return 0; 37 } 38 39 static bool 40 GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size) 41 { 42 byte_order = eByteOrderInvalid; 43 addr_size = 0; 44 if (exe_scope == NULL) 45 return false; 46 47 Target *target = exe_scope->CalculateTarget(); 48 if (target) 49 { 50 byte_order = target->GetArchitecture().GetByteOrder(); 51 addr_size = target->GetArchitecture().GetAddressByteSize(); 52 } 53 54 if (byte_order == eByteOrderInvalid || addr_size == 0) 55 { 56 Module *module = address.GetModule(); 57 if (module) 58 { 59 byte_order = module->GetArchitecture().GetByteOrder(); 60 addr_size = module->GetArchitecture().GetAddressByteSize(); 61 } 62 } 63 return byte_order != eByteOrderInvalid && addr_size != 0; 64 } 65 66 static uint64_t 67 ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success) 68 { 69 uint64_t uval64 = 0; 70 if (exe_scope == NULL || byte_size > sizeof(uint64_t)) 71 { 72 success = false; 73 return 0; 74 } 75 uint64_t buf; 76 77 success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size; 78 if (success) 79 { 80 ByteOrder byte_order = eByteOrderInvalid; 81 uint32_t addr_size = 0; 82 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size)) 83 { 84 DataExtractor data (&buf, sizeof(buf), byte_order, addr_size); 85 uint32_t offset = 0; 86 uval64 = data.GetU64(&offset); 87 } 88 else 89 success = false; 90 } 91 return uval64; 92 } 93 94 static bool 95 ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr) 96 { 97 if (exe_scope == NULL) 98 return false; 99 100 101 bool success = false; 102 addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success); 103 if (success) 104 { 105 ExecutionContext exe_ctx; 106 exe_scope->CalculateExecutionContext(exe_ctx); 107 // If we have any sections that are loaded, try and resolve using the 108 // section load list 109 if (exe_ctx.target && !exe_ctx.target->GetSectionLoadList().IsEmpty()) 110 { 111 if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (deref_addr, deref_so_addr)) 112 return true; 113 } 114 else 115 { 116 // If we were not running, yet able to read an integer, we must 117 // have a module 118 Module *module = address.GetModule(); 119 assert (module); 120 if (module->ResolveFileAddress(deref_addr, deref_so_addr)) 121 return true; 122 } 123 124 // We couldn't make "deref_addr" into a section offset value, but we were 125 // able to read the address, so we return a section offset address with 126 // no section and "deref_addr" as the offset (address). 127 deref_so_addr.SetSection(NULL); 128 deref_so_addr.SetOffset(deref_addr); 129 return true; 130 } 131 return false; 132 } 133 134 static bool 135 DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm) 136 { 137 if (exe_scope == NULL || byte_size == 0) 138 return 0; 139 std::vector<uint8_t> buf(byte_size, 0); 140 141 if (ReadBytes (exe_scope, address, &buf[0], buf.size()) == buf.size()) 142 { 143 ByteOrder byte_order = eByteOrderInvalid; 144 uint32_t addr_size = 0; 145 if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size)) 146 { 147 DataExtractor data (&buf.front(), buf.size(), byte_order, addr_size); 148 149 data.Dump (strm, 150 0, // Start offset in "data" 151 eFormatHex, // Print as characters 152 buf.size(), // Size of item 153 1, // Items count 154 UINT32_MAX, // num per line 155 LLDB_INVALID_ADDRESS,// base address 156 0, // bitfield bit size 157 0); // bitfield bit offset 158 159 return true; 160 } 161 } 162 return false; 163 } 164 165 166 static size_t 167 ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm) 168 { 169 if (exe_scope == NULL) 170 return 0; 171 const size_t k_buf_len = 256; 172 char buf[k_buf_len+1]; 173 buf[k_buf_len] = '\0'; // NULL terminate 174 175 // Byte order and address size don't matter for C string dumping.. 176 DataExtractor data (buf, sizeof(buf), lldb::endian::InlHostByteOrder(), 4); 177 size_t total_len = 0; 178 size_t bytes_read; 179 Address curr_address(address); 180 strm->PutChar ('"'); 181 while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0) 182 { 183 size_t len = strlen(buf); 184 if (len == 0) 185 break; 186 if (len > bytes_read) 187 len = bytes_read; 188 189 data.Dump (strm, 190 0, // Start offset in "data" 191 eFormatChar, // Print as characters 192 1, // Size of item (1 byte for a char!) 193 len, // How many bytes to print? 194 UINT32_MAX, // num per line 195 LLDB_INVALID_ADDRESS,// base address 196 0, // bitfield bit size 197 198 0); // bitfield bit offset 199 200 total_len += bytes_read; 201 202 if (len < k_buf_len) 203 break; 204 curr_address.SetOffset (curr_address.GetOffset() + bytes_read); 205 } 206 strm->PutChar ('"'); 207 return total_len; 208 } 209 210 Address::Address (addr_t address, const SectionList * sections) : 211 m_section (NULL), 212 m_offset (LLDB_INVALID_ADDRESS) 213 { 214 ResolveAddressUsingFileSections(address, sections); 215 } 216 217 const Address& 218 Address::operator= (const Address& rhs) 219 { 220 if (this != &rhs) 221 { 222 m_section = rhs.m_section; 223 m_offset = rhs.m_offset; 224 } 225 return *this; 226 } 227 228 bool 229 Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections) 230 { 231 if (sections) 232 m_section = sections->FindSectionContainingFileAddress(addr).get(); 233 else 234 m_section = NULL; 235 236 if (m_section != NULL) 237 { 238 assert( m_section->ContainsFileAddress(addr) ); 239 m_offset = addr - m_section->GetFileAddress(); 240 return true; // Successfully transformed addr into a section offset address 241 } 242 243 m_offset = addr; 244 return false; // Failed to resolve this address to a section offset value 245 } 246 247 Module * 248 Address::GetModule () const 249 { 250 if (m_section) 251 return m_section->GetModule(); 252 return NULL; 253 } 254 255 addr_t 256 Address::GetFileAddress () const 257 { 258 if (m_section != NULL) 259 { 260 addr_t sect_file_addr = m_section->GetFileAddress(); 261 if (sect_file_addr == LLDB_INVALID_ADDRESS) 262 { 263 // Section isn't resolved, we can't return a valid file address 264 return LLDB_INVALID_ADDRESS; 265 } 266 // We have a valid file range, so we can return the file based 267 // address by adding the file base address to our offset 268 return sect_file_addr + m_offset; 269 } 270 // No section, we just return the offset since it is the value in this case 271 return m_offset; 272 } 273 274 addr_t 275 Address::GetLoadAddress (Target *target) const 276 { 277 if (m_section == NULL) 278 { 279 // No section, we just return the offset since it is the value in this case 280 return m_offset; 281 } 282 283 if (target) 284 { 285 addr_t sect_load_addr = m_section->GetLoadBaseAddress (target); 286 287 if (sect_load_addr != LLDB_INVALID_ADDRESS) 288 { 289 // We have a valid file range, so we can return the file based 290 // address by adding the file base address to our offset 291 return sect_load_addr + m_offset; 292 } 293 } 294 // The section isn't resolved or no process was supplied so we can't 295 // return a valid file address. 296 return LLDB_INVALID_ADDRESS; 297 } 298 299 addr_t 300 Address::GetCallableLoadAddress (Target *target) const 301 { 302 addr_t code_addr = GetLoadAddress (target); 303 304 if (target) 305 return target->GetCallableLoadAddress (code_addr, GetAddressClass()); 306 return code_addr; 307 } 308 309 bool 310 Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target) 311 { 312 if (SetLoadAddress (load_addr, target)) 313 { 314 if (target) 315 m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass()); 316 return true; 317 } 318 return false; 319 } 320 321 addr_t 322 Address::GetOpcodeLoadAddress (Target *target) const 323 { 324 addr_t code_addr = GetLoadAddress (target); 325 if (code_addr != LLDB_INVALID_ADDRESS) 326 code_addr = target->GetOpcodeLoadAddress (code_addr, GetAddressClass()); 327 return code_addr; 328 } 329 330 bool 331 Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target) 332 { 333 if (SetLoadAddress (load_addr, target)) 334 { 335 if (target) 336 m_offset = target->GetOpcodeLoadAddress (m_offset, GetAddressClass()); 337 return true; 338 } 339 return false; 340 } 341 342 bool 343 Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const 344 { 345 // If the section was NULL, only load address is going to work. 346 if (m_section == NULL) 347 style = DumpStyleLoadAddress; 348 349 Target *target = NULL; 350 Process *process = NULL; 351 if (exe_scope) 352 { 353 target = exe_scope->CalculateTarget(); 354 process = exe_scope->CalculateProcess(); 355 } 356 // If addr_byte_size is UINT32_MAX, then determine the correct address 357 // byte size for the process or default to the size of addr_t 358 if (addr_size == UINT32_MAX) 359 { 360 if (process) 361 addr_size = target->GetArchitecture().GetAddressByteSize (); 362 else 363 addr_size = sizeof(addr_t); 364 } 365 366 Address so_addr; 367 switch (style) 368 { 369 case DumpStyleInvalid: 370 return false; 371 372 case DumpStyleSectionNameOffset: 373 if (m_section != NULL) 374 { 375 m_section->DumpName(s); 376 s->Printf (" + %llu", m_offset); 377 } 378 else 379 { 380 s->Address(m_offset, addr_size); 381 } 382 break; 383 384 case DumpStyleSectionPointerOffset: 385 s->Printf("(Section *)%.*p + ", (int)sizeof(void*) * 2, m_section); 386 s->Address(m_offset, addr_size); 387 break; 388 389 case DumpStyleModuleWithFileAddress: 390 if (m_section) 391 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString()); 392 // Fall through 393 case DumpStyleFileAddress: 394 { 395 addr_t file_addr = GetFileAddress(); 396 if (file_addr == LLDB_INVALID_ADDRESS) 397 { 398 if (fallback_style != DumpStyleInvalid) 399 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 400 return false; 401 } 402 s->Address (file_addr, addr_size); 403 if (style == DumpStyleModuleWithFileAddress && m_section) 404 s->PutChar(']'); 405 } 406 break; 407 408 case DumpStyleLoadAddress: 409 { 410 addr_t load_addr = GetLoadAddress (target); 411 if (load_addr == LLDB_INVALID_ADDRESS) 412 { 413 if (fallback_style != DumpStyleInvalid) 414 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 415 return false; 416 } 417 s->Address (load_addr, addr_size); 418 } 419 break; 420 421 case DumpStyleResolvedDescription: 422 case DumpStyleResolvedDescriptionNoModule: 423 if (IsSectionOffset()) 424 { 425 AddressType addr_type = eAddressTypeLoad; 426 addr_t addr = GetLoadAddress (target); 427 if (addr == LLDB_INVALID_ADDRESS) 428 { 429 addr = GetFileAddress(); 430 addr_type = eAddressTypeFile; 431 } 432 433 uint32_t pointer_size = 4; 434 Module *module = GetModule(); 435 if (target) 436 pointer_size = target->GetArchitecture().GetAddressByteSize(); 437 else if (module) 438 pointer_size = module->GetArchitecture().GetAddressByteSize(); 439 440 bool showed_info = false; 441 const Section *section = GetSection(); 442 if (section) 443 { 444 SectionType sect_type = section->GetType(); 445 switch (sect_type) 446 { 447 case eSectionTypeData: 448 if (module) 449 { 450 ObjectFile *objfile = module->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->GetAddressRangePtr()->GetBaseAddress().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) 616 { 617 SymbolContext sc; 618 module->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->GetAddressRangePtr()) 629 { 630 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().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 Module *module = GetModule(); 671 if (module) 672 { 673 SymbolContext sc; 674 module->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->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection()) 682 sc.symbol = NULL; 683 } 684 sc.GetDescription(s, eDescriptionLevelBrief, target); 685 } 686 } 687 if (fallback_style != DumpStyleInvalid) 688 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 689 return false; 690 break; 691 } 692 693 return true; 694 } 695 696 void 697 Address::CalculateSymbolContext (SymbolContext *sc) 698 { 699 sc->Clear(); 700 // Absolute addresses don't have enough information to reconstruct even their target. 701 if (m_section == NULL) 702 return; 703 704 if (m_section->GetModule()) 705 { 706 sc->module_sp = m_section->GetModule()->GetSP(); 707 if (sc->module_sp) 708 sc->module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextEverything, *sc); 709 } 710 } 711 712 int 713 Address::CompareFileAddress (const Address& a, const Address& b) 714 { 715 addr_t a_file_addr = a.GetFileAddress(); 716 addr_t b_file_addr = b.GetFileAddress(); 717 if (a_file_addr < b_file_addr) 718 return -1; 719 if (a_file_addr > b_file_addr) 720 return +1; 721 return 0; 722 } 723 724 725 int 726 Address::CompareLoadAddress (const Address& a, const Address& b, Target *target) 727 { 728 assert (target != NULL); 729 addr_t a_load_addr = a.GetLoadAddress (target); 730 addr_t b_load_addr = b.GetLoadAddress (target); 731 if (a_load_addr < b_load_addr) 732 return -1; 733 if (a_load_addr > b_load_addr) 734 return +1; 735 return 0; 736 } 737 738 int 739 Address::CompareModulePointerAndOffset (const Address& a, const Address& b) 740 { 741 Module *a_module = a.GetModule (); 742 Module *b_module = b.GetModule (); 743 if (a_module < b_module) 744 return -1; 745 if (a_module > b_module) 746 return +1; 747 // Modules are the same, just compare the file address since they should 748 // be unique 749 addr_t a_file_addr = a.GetFileAddress(); 750 addr_t b_file_addr = b.GetFileAddress(); 751 if (a_file_addr < b_file_addr) 752 return -1; 753 if (a_file_addr > b_file_addr) 754 return +1; 755 return 0; 756 } 757 758 759 size_t 760 Address::MemorySize () const 761 { 762 // Noting special for the memory size of a single Address object, 763 // it is just the size of itself. 764 return sizeof(Address); 765 } 766 767 768 //---------------------------------------------------------------------- 769 // NOTE: Be careful using this operator. It can correctly compare two 770 // addresses from the same Module correctly. It can't compare two 771 // addresses from different modules in any meaningful way, but it will 772 // compare the module pointers. 773 // 774 // To sum things up: 775 // - works great for addresses within the same module 776 // - it works for addresses across multiple modules, but don't expect the 777 // address results to make much sense 778 // 779 // This basically lets Address objects be used in ordered collection 780 // classes. 781 //---------------------------------------------------------------------- 782 783 bool 784 lldb_private::operator< (const Address& lhs, const Address& rhs) 785 { 786 Module *lhs_module = lhs.GetModule(); 787 Module *rhs_module = rhs.GetModule(); 788 if (lhs_module == rhs_module) 789 { 790 // Addresses are in the same module, just compare the file addresses 791 return lhs.GetFileAddress() < rhs.GetFileAddress(); 792 } 793 else 794 { 795 // The addresses are from different modules, just use the module 796 // pointer value to get consistent ordering 797 return lhs_module < rhs_module; 798 } 799 } 800 801 bool 802 lldb_private::operator> (const Address& lhs, const Address& rhs) 803 { 804 Module *lhs_module = lhs.GetModule(); 805 Module *rhs_module = rhs.GetModule(); 806 if (lhs_module == rhs_module) 807 { 808 // Addresses are in the same module, just compare the file addresses 809 return lhs.GetFileAddress() > rhs.GetFileAddress(); 810 } 811 else 812 { 813 // The addresses are from different modules, just use the module 814 // pointer value to get consistent ordering 815 return lhs_module > rhs_module; 816 } 817 } 818 819 820 // The operator == checks for exact equality only (same section, same offset) 821 bool 822 lldb_private::operator== (const Address& a, const Address& rhs) 823 { 824 return a.GetSection() == rhs.GetSection() && 825 a.GetOffset() == rhs.GetOffset(); 826 } 827 // The operator != checks for exact inequality only (differing section, or 828 // different offset) 829 bool 830 lldb_private::operator!= (const Address& a, const Address& rhs) 831 { 832 return a.GetSection() != rhs.GetSection() || 833 a.GetOffset() != rhs.GetOffset(); 834 } 835 836 bool 837 Address::IsLinkedAddress () const 838 { 839 return m_section && m_section->GetLinkedSection(); 840 } 841 842 843 void 844 Address::ResolveLinkedAddress () 845 { 846 if (m_section) 847 { 848 const Section *linked_section = m_section->GetLinkedSection(); 849 if (linked_section) 850 { 851 m_offset += m_section->GetLinkedOffset(); 852 m_section = linked_section; 853 } 854 } 855 } 856 857 AddressClass 858 Address::GetAddressClass () const 859 { 860 Module *module = GetModule(); 861 if (module) 862 { 863 ObjectFile *obj_file = module->GetObjectFile(); 864 if (obj_file) 865 return obj_file->GetAddressClass (GetFileAddress()); 866 } 867 return eAddressClassUnknown; 868 } 869 870 bool 871 Address::SetLoadAddress (lldb::addr_t load_addr, Target *target) 872 { 873 if (target && target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this)) 874 return true; 875 m_section = NULL; 876 m_offset = load_addr; 877 return false; 878 } 879 880