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 Target *target = exe_scope->CalculateTarget(); 32 if (target) 33 { 34 Error error; 35 bool prefer_file_cache = false; 36 return target->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 Target *target = exe_scope->CalculateTarget(); 50 if (target) 51 { 52 byte_order = target->GetArchitecture().GetByteOrder(); 53 addr_size = target->GetArchitecture().GetAddressByteSize(); 54 } 55 56 if (byte_order == eByteOrderInvalid || addr_size == 0) 57 { 58 Module *module = address.GetModulePtr(); 59 if (module) 60 { 61 byte_order = module->GetArchitecture().GetByteOrder(); 62 addr_size = module->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 Module *module = address.GetModulePtr(); 122 assert (module); 123 if (module->ResolveFileAddress(deref_addr, deref_so_addr)) 124 return true; 125 } 126 127 // We couldn't make "deref_addr" into a section offset value, but we were 128 // able to read the address, so we return a section offset address with 129 // no section and "deref_addr" as the offset (address). 130 deref_so_addr.SetSection(NULL); 131 deref_so_addr.SetOffset(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 (addr_t address, const SectionList * sections) : 214 m_section (NULL), 215 m_offset (LLDB_INVALID_ADDRESS) 216 { 217 ResolveAddressUsingFileSections(address, sections); 218 } 219 220 const Address& 221 Address::operator= (const Address& rhs) 222 { 223 if (this != &rhs) 224 { 225 m_section = rhs.m_section; 226 m_offset = rhs.m_offset; 227 } 228 return *this; 229 } 230 231 bool 232 Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections) 233 { 234 if (sections) 235 m_section = sections->FindSectionContainingFileAddress(addr).get(); 236 else 237 m_section = NULL; 238 239 if (m_section != NULL) 240 { 241 assert( m_section->ContainsFileAddress(addr) ); 242 m_offset = addr - m_section->GetFileAddress(); 243 return true; // Successfully transformed addr into a section offset address 244 } 245 246 m_offset = addr; 247 return false; // Failed to resolve this address to a section offset value 248 } 249 250 Module * 251 Address::GetModulePtr () const 252 { 253 if (m_section) 254 return m_section->GetModule(); 255 return NULL; 256 } 257 258 ModuleSP 259 Address::GetModuleSP () const 260 { 261 lldb::ModuleSP module_sp; 262 if (m_section) 263 { 264 Module *module = m_section->GetModule(); 265 if (module) 266 module_sp = module->shared_from_this(); 267 } 268 return module_sp; 269 } 270 271 addr_t 272 Address::GetFileAddress () const 273 { 274 if (m_section != NULL) 275 { 276 addr_t sect_file_addr = m_section->GetFileAddress(); 277 if (sect_file_addr == LLDB_INVALID_ADDRESS) 278 { 279 // Section isn't resolved, we can't return a valid file address 280 return LLDB_INVALID_ADDRESS; 281 } 282 // We have a valid file range, so we can return the file based 283 // address by adding the file base address to our offset 284 return sect_file_addr + m_offset; 285 } 286 // No section, we just return the offset since it is the value in this case 287 return m_offset; 288 } 289 290 addr_t 291 Address::GetLoadAddress (Target *target) const 292 { 293 if (m_section == NULL) 294 { 295 // No section, we just return the offset since it is the value in this case 296 return m_offset; 297 } 298 299 if (target) 300 { 301 addr_t sect_load_addr = m_section->GetLoadBaseAddress (target); 302 303 if (sect_load_addr != LLDB_INVALID_ADDRESS) 304 { 305 // We have a valid file range, so we can return the file based 306 // address by adding the file base address to our offset 307 return sect_load_addr + m_offset; 308 } 309 } 310 // The section isn't resolved or no process was supplied so we can't 311 // return a valid file address. 312 return LLDB_INVALID_ADDRESS; 313 } 314 315 addr_t 316 Address::GetCallableLoadAddress (Target *target) const 317 { 318 addr_t code_addr = GetLoadAddress (target); 319 320 if (target) 321 return target->GetCallableLoadAddress (code_addr, GetAddressClass()); 322 return code_addr; 323 } 324 325 bool 326 Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target) 327 { 328 if (SetLoadAddress (load_addr, target)) 329 { 330 if (target) 331 m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass()); 332 return true; 333 } 334 return false; 335 } 336 337 addr_t 338 Address::GetOpcodeLoadAddress (Target *target) const 339 { 340 addr_t code_addr = GetLoadAddress (target); 341 if (code_addr != LLDB_INVALID_ADDRESS) 342 code_addr = target->GetOpcodeLoadAddress (code_addr, GetAddressClass()); 343 return code_addr; 344 } 345 346 bool 347 Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target) 348 { 349 if (SetLoadAddress (load_addr, target)) 350 { 351 if (target) 352 m_offset = target->GetOpcodeLoadAddress (m_offset, GetAddressClass()); 353 return true; 354 } 355 return false; 356 } 357 358 bool 359 Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const 360 { 361 // If the section was NULL, only load address is going to work. 362 if (m_section == NULL) 363 style = DumpStyleLoadAddress; 364 365 Target *target = NULL; 366 Process *process = NULL; 367 if (exe_scope) 368 { 369 target = exe_scope->CalculateTarget(); 370 process = exe_scope->CalculateProcess(); 371 } 372 // If addr_byte_size is UINT32_MAX, then determine the correct address 373 // byte size for the process or default to the size of addr_t 374 if (addr_size == UINT32_MAX) 375 { 376 if (process) 377 addr_size = target->GetArchitecture().GetAddressByteSize (); 378 else 379 addr_size = sizeof(addr_t); 380 } 381 382 Address so_addr; 383 switch (style) 384 { 385 case DumpStyleInvalid: 386 return false; 387 388 case DumpStyleSectionNameOffset: 389 if (m_section != NULL) 390 { 391 m_section->DumpName(s); 392 s->Printf (" + %llu", m_offset); 393 } 394 else 395 { 396 s->Address(m_offset, addr_size); 397 } 398 break; 399 400 case DumpStyleSectionPointerOffset: 401 s->Printf("(Section *)%p + ", m_section); 402 s->Address(m_offset, addr_size); 403 break; 404 405 case DumpStyleModuleWithFileAddress: 406 if (m_section) 407 s->Printf("%s[", m_section->GetModule()->GetFileSpec().GetFilename().AsCString()); 408 // Fall through 409 case DumpStyleFileAddress: 410 { 411 addr_t file_addr = GetFileAddress(); 412 if (file_addr == LLDB_INVALID_ADDRESS) 413 { 414 if (fallback_style != DumpStyleInvalid) 415 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 416 return false; 417 } 418 s->Address (file_addr, addr_size); 419 if (style == DumpStyleModuleWithFileAddress && m_section) 420 s->PutChar(']'); 421 } 422 break; 423 424 case DumpStyleLoadAddress: 425 { 426 addr_t load_addr = GetLoadAddress (target); 427 if (load_addr == LLDB_INVALID_ADDRESS) 428 { 429 if (fallback_style != DumpStyleInvalid) 430 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 431 return false; 432 } 433 s->Address (load_addr, addr_size); 434 } 435 break; 436 437 case DumpStyleResolvedDescription: 438 case DumpStyleResolvedDescriptionNoModule: 439 if (IsSectionOffset()) 440 { 441 AddressType addr_type = eAddressTypeLoad; 442 addr_t addr = GetLoadAddress (target); 443 if (addr == LLDB_INVALID_ADDRESS) 444 { 445 addr = GetFileAddress(); 446 addr_type = eAddressTypeFile; 447 } 448 449 uint32_t pointer_size = 4; 450 Module *module = GetModulePtr(); 451 if (target) 452 pointer_size = target->GetArchitecture().GetAddressByteSize(); 453 else if (module) 454 pointer_size = module->GetArchitecture().GetAddressByteSize(); 455 456 bool showed_info = false; 457 const Section *section = GetSection(); 458 if (section) 459 { 460 SectionType sect_type = section->GetType(); 461 switch (sect_type) 462 { 463 case eSectionTypeData: 464 if (module) 465 { 466 ObjectFile *objfile = module->GetObjectFile(); 467 if (objfile) 468 { 469 Symtab *symtab = objfile->GetSymtab(); 470 if (symtab) 471 { 472 const addr_t file_Addr = GetFileAddress(); 473 Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr); 474 if (symbol) 475 { 476 const char *symbol_name = symbol->GetName().AsCString(); 477 if (symbol_name) 478 { 479 s->PutCString(symbol_name); 480 addr_t delta = file_Addr - symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(); 481 if (delta) 482 s->Printf(" + %llu", delta); 483 showed_info = true; 484 } 485 } 486 } 487 } 488 } 489 break; 490 491 case eSectionTypeDataCString: 492 // Read the C string from memory and display it 493 showed_info = true; 494 ReadCStringFromMemory (exe_scope, *this, s); 495 break; 496 497 case eSectionTypeDataCStringPointers: 498 { 499 if (ReadAddress (exe_scope, *this, pointer_size, so_addr)) 500 { 501 #if VERBOSE_OUTPUT 502 s->PutCString("(char *)"); 503 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress); 504 s->PutCString(": "); 505 #endif 506 showed_info = true; 507 ReadCStringFromMemory (exe_scope, so_addr, s); 508 } 509 } 510 break; 511 512 case eSectionTypeDataObjCMessageRefs: 513 { 514 if (ReadAddress (exe_scope, *this, pointer_size, so_addr)) 515 { 516 if (target && so_addr.IsSectionOffset()) 517 { 518 SymbolContext func_sc; 519 target->GetImages().ResolveSymbolContextForAddress (so_addr, 520 eSymbolContextEverything, 521 func_sc); 522 if (func_sc.function || func_sc.symbol) 523 { 524 showed_info = true; 525 #if VERBOSE_OUTPUT 526 s->PutCString ("(objc_msgref *) -> { (func*)"); 527 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress); 528 #else 529 s->PutCString ("{ "); 530 #endif 531 Address cstr_addr(*this); 532 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size); 533 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false); 534 if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr)) 535 { 536 #if VERBOSE_OUTPUT 537 s->PutCString("), (char *)"); 538 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress); 539 s->PutCString(" ("); 540 #else 541 s->PutCString(", "); 542 #endif 543 ReadCStringFromMemory (exe_scope, so_addr, s); 544 } 545 #if VERBOSE_OUTPUT 546 s->PutCString(") }"); 547 #else 548 s->PutCString(" }"); 549 #endif 550 } 551 } 552 } 553 } 554 break; 555 556 case eSectionTypeDataObjCCFStrings: 557 { 558 Address cfstring_data_addr(*this); 559 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size)); 560 if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr)) 561 { 562 #if VERBOSE_OUTPUT 563 s->PutCString("(CFString *) "); 564 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress); 565 s->PutCString(" -> @"); 566 #else 567 s->PutChar('@'); 568 #endif 569 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription)) 570 showed_info = true; 571 } 572 } 573 break; 574 575 case eSectionTypeData4: 576 // Read the 4 byte data and display it 577 showed_info = true; 578 s->PutCString("(uint32_t) "); 579 DumpUInt (exe_scope, *this, 4, s); 580 break; 581 582 case eSectionTypeData8: 583 // Read the 8 byte data and display it 584 showed_info = true; 585 s->PutCString("(uint64_t) "); 586 DumpUInt (exe_scope, *this, 8, s); 587 break; 588 589 case eSectionTypeData16: 590 // Read the 16 byte data and display it 591 showed_info = true; 592 s->PutCString("(uint128_t) "); 593 DumpUInt (exe_scope, *this, 16, s); 594 break; 595 596 case eSectionTypeDataPointers: 597 // Read the pointer data and display it 598 { 599 if (ReadAddress (exe_scope, *this, pointer_size, so_addr)) 600 { 601 s->PutCString ("(void *)"); 602 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress); 603 604 showed_info = true; 605 if (so_addr.IsSectionOffset()) 606 { 607 SymbolContext pointer_sc; 608 if (target) 609 { 610 target->GetImages().ResolveSymbolContextForAddress (so_addr, 611 eSymbolContextEverything, 612 pointer_sc); 613 if (pointer_sc.function || pointer_sc.symbol) 614 { 615 s->PutCString(": "); 616 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false); 617 } 618 } 619 } 620 } 621 } 622 break; 623 624 default: 625 break; 626 } 627 } 628 629 if (!showed_info) 630 { 631 if (module) 632 { 633 SymbolContext sc; 634 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc); 635 if (sc.function || sc.symbol) 636 { 637 bool show_stop_context = true; 638 const bool show_module = (style == DumpStyleResolvedDescription); 639 const bool show_fullpaths = false; 640 const bool show_inlined_frames = true; 641 if (sc.function == NULL && sc.symbol != NULL) 642 { 643 // If we have just a symbol make sure it is in the right section 644 if (sc.symbol->GetAddressRangePtr()) 645 { 646 if (sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection()) 647 { 648 // don't show the module if the symbol is a trampoline symbol 649 show_stop_context = false; 650 } 651 } 652 } 653 if (show_stop_context) 654 { 655 // We have a function or a symbol from the same 656 // sections as this address. 657 sc.DumpStopContext (s, 658 exe_scope, 659 *this, 660 show_fullpaths, 661 show_module, 662 show_inlined_frames); 663 } 664 else 665 { 666 // We found a symbol but it was in a different 667 // section so it isn't the symbol we should be 668 // showing, just show the section name + offset 669 Dump (s, exe_scope, DumpStyleSectionNameOffset); 670 } 671 } 672 } 673 } 674 } 675 else 676 { 677 if (fallback_style != DumpStyleInvalid) 678 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 679 return false; 680 } 681 break; 682 683 case DumpStyleDetailedSymbolContext: 684 if (IsSectionOffset()) 685 { 686 Module *module = GetModulePtr(); 687 if (module) 688 { 689 SymbolContext sc; 690 module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc); 691 if (sc.symbol) 692 { 693 // If we have just a symbol make sure it is in the same section 694 // as our address. If it isn't, then we might have just found 695 // the last symbol that came before the address that we are 696 // looking up that has nothing to do with our address lookup. 697 if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection()) 698 sc.symbol = NULL; 699 } 700 sc.GetDescription(s, eDescriptionLevelBrief, target); 701 702 if (sc.block) 703 { 704 bool can_create = true; 705 bool get_parent_variables = true; 706 bool stop_if_block_is_inlined_function = false; 707 VariableList variable_list; 708 sc.block->AppendVariables (can_create, 709 get_parent_variables, 710 stop_if_block_is_inlined_function, 711 &variable_list); 712 713 uint32_t num_variables = variable_list.GetSize(); 714 for (uint32_t var_idx = 0; var_idx < num_variables; ++var_idx) 715 { 716 Variable *var = variable_list.GetVariableAtIndex (var_idx).get(); 717 if (var && var->LocationIsValidForAddress (*this)) 718 { 719 s->Printf (" Variable: id = {0x%8.8llx}, name = \"%s\", type= \"%s\", location =", 720 var->GetID(), 721 var->GetName().GetCString(), 722 var->GetType()->GetName().GetCString()); 723 var->DumpLocationForAddress(s, *this); 724 s->PutCString(", decl = "); 725 var->GetDeclaration().DumpStopContext(s, false); 726 s->EOL(); 727 } 728 } 729 } 730 } 731 } 732 else 733 { 734 if (fallback_style != DumpStyleInvalid) 735 return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); 736 return false; 737 } 738 break; 739 } 740 741 return true; 742 } 743 744 uint32_t 745 Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const 746 { 747 sc->Clear(); 748 // Absolute addresses don't have enough information to reconstruct even their target. 749 if (m_section) 750 { 751 Module *address_module = m_section->GetModule(); 752 if (address_module) 753 { 754 sc->module_sp = address_module->shared_from_this(); 755 if (sc->module_sp) 756 return sc->module_sp->ResolveSymbolContextForAddress (*this, resolve_scope, *sc); 757 } 758 } 759 return 0; 760 } 761 762 Module * 763 Address::CalculateSymbolContextModule () const 764 { 765 if (m_section) 766 return m_section->GetModule(); 767 return NULL; 768 } 769 770 CompileUnit * 771 Address::CalculateSymbolContextCompileUnit () const 772 { 773 if (m_section) 774 { 775 SymbolContext sc; 776 sc.module_sp = m_section->GetModule()->shared_from_this(); 777 if (sc.module_sp) 778 { 779 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextCompUnit, sc); 780 return sc.comp_unit; 781 } 782 } 783 return NULL; 784 } 785 786 Function * 787 Address::CalculateSymbolContextFunction () const 788 { 789 if (m_section) 790 { 791 SymbolContext sc; 792 sc.module_sp = m_section->GetModule()->shared_from_this(); 793 if (sc.module_sp) 794 { 795 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextFunction, sc); 796 return sc.function; 797 } 798 } 799 return NULL; 800 } 801 802 Block * 803 Address::CalculateSymbolContextBlock () const 804 { 805 if (m_section) 806 { 807 SymbolContext sc; 808 sc.module_sp = m_section->GetModule()->shared_from_this(); 809 if (sc.module_sp) 810 { 811 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextBlock, sc); 812 return sc.block; 813 } 814 } 815 return NULL; 816 } 817 818 Symbol * 819 Address::CalculateSymbolContextSymbol () const 820 { 821 if (m_section) 822 { 823 SymbolContext sc; 824 sc.module_sp = m_section->GetModule()->shared_from_this(); 825 if (sc.module_sp) 826 { 827 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextSymbol, sc); 828 return sc.symbol; 829 } 830 } 831 return NULL; 832 } 833 834 bool 835 Address::CalculateSymbolContextLineEntry (LineEntry &line_entry) const 836 { 837 if (m_section) 838 { 839 SymbolContext sc; 840 sc.module_sp = m_section->GetModule()->shared_from_this(); 841 if (sc.module_sp) 842 { 843 sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextLineEntry, sc); 844 if (sc.line_entry.IsValid()) 845 { 846 line_entry = sc.line_entry; 847 return true; 848 } 849 } 850 } 851 line_entry.Clear(); 852 return false; 853 } 854 855 int 856 Address::CompareFileAddress (const Address& a, const Address& b) 857 { 858 addr_t a_file_addr = a.GetFileAddress(); 859 addr_t b_file_addr = b.GetFileAddress(); 860 if (a_file_addr < b_file_addr) 861 return -1; 862 if (a_file_addr > b_file_addr) 863 return +1; 864 return 0; 865 } 866 867 868 int 869 Address::CompareLoadAddress (const Address& a, const Address& b, Target *target) 870 { 871 assert (target != NULL); 872 addr_t a_load_addr = a.GetLoadAddress (target); 873 addr_t b_load_addr = b.GetLoadAddress (target); 874 if (a_load_addr < b_load_addr) 875 return -1; 876 if (a_load_addr > b_load_addr) 877 return +1; 878 return 0; 879 } 880 881 int 882 Address::CompareModulePointerAndOffset (const Address& a, const Address& b) 883 { 884 Module *a_module = a.GetModulePtr (); 885 Module *b_module = b.GetModulePtr (); 886 if (a_module < b_module) 887 return -1; 888 if (a_module > b_module) 889 return +1; 890 // Modules are the same, just compare the file address since they should 891 // be unique 892 addr_t a_file_addr = a.GetFileAddress(); 893 addr_t b_file_addr = b.GetFileAddress(); 894 if (a_file_addr < b_file_addr) 895 return -1; 896 if (a_file_addr > b_file_addr) 897 return +1; 898 return 0; 899 } 900 901 902 size_t 903 Address::MemorySize () const 904 { 905 // Noting special for the memory size of a single Address object, 906 // it is just the size of itself. 907 return sizeof(Address); 908 } 909 910 911 //---------------------------------------------------------------------- 912 // NOTE: Be careful using this operator. It can correctly compare two 913 // addresses from the same Module correctly. It can't compare two 914 // addresses from different modules in any meaningful way, but it will 915 // compare the module pointers. 916 // 917 // To sum things up: 918 // - works great for addresses within the same module 919 // - it works for addresses across multiple modules, but don't expect the 920 // address results to make much sense 921 // 922 // This basically lets Address objects be used in ordered collection 923 // classes. 924 //---------------------------------------------------------------------- 925 926 bool 927 lldb_private::operator< (const Address& lhs, const Address& rhs) 928 { 929 Module *lhs_module = lhs.GetModulePtr(); 930 Module *rhs_module = rhs.GetModulePtr(); 931 if (lhs_module == rhs_module) 932 { 933 // Addresses are in the same module, just compare the file addresses 934 return lhs.GetFileAddress() < rhs.GetFileAddress(); 935 } 936 else 937 { 938 // The addresses are from different modules, just use the module 939 // pointer value to get consistent ordering 940 return lhs_module < rhs_module; 941 } 942 } 943 944 bool 945 lldb_private::operator> (const Address& lhs, const Address& rhs) 946 { 947 Module *lhs_module = lhs.GetModulePtr(); 948 Module *rhs_module = rhs.GetModulePtr(); 949 if (lhs_module == rhs_module) 950 { 951 // Addresses are in the same module, just compare the file addresses 952 return lhs.GetFileAddress() > rhs.GetFileAddress(); 953 } 954 else 955 { 956 // The addresses are from different modules, just use the module 957 // pointer value to get consistent ordering 958 return lhs_module > rhs_module; 959 } 960 } 961 962 963 // The operator == checks for exact equality only (same section, same offset) 964 bool 965 lldb_private::operator== (const Address& a, const Address& rhs) 966 { 967 return a.GetSection() == rhs.GetSection() && 968 a.GetOffset() == rhs.GetOffset(); 969 } 970 // The operator != checks for exact inequality only (differing section, or 971 // different offset) 972 bool 973 lldb_private::operator!= (const Address& a, const Address& rhs) 974 { 975 return a.GetSection() != rhs.GetSection() || 976 a.GetOffset() != rhs.GetOffset(); 977 } 978 979 bool 980 Address::IsLinkedAddress () const 981 { 982 return m_section && m_section->GetLinkedSection(); 983 } 984 985 986 void 987 Address::ResolveLinkedAddress () 988 { 989 if (m_section) 990 { 991 const Section *linked_section = m_section->GetLinkedSection(); 992 if (linked_section) 993 { 994 m_offset += m_section->GetLinkedOffset(); 995 m_section = linked_section; 996 } 997 } 998 } 999 1000 AddressClass 1001 Address::GetAddressClass () const 1002 { 1003 Module *module = GetModulePtr(); 1004 if (module) 1005 { 1006 ObjectFile *obj_file = module->GetObjectFile(); 1007 if (obj_file) 1008 return obj_file->GetAddressClass (GetFileAddress()); 1009 } 1010 return eAddressClassUnknown; 1011 } 1012 1013 bool 1014 Address::SetLoadAddress (lldb::addr_t load_addr, Target *target) 1015 { 1016 if (target && target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this)) 1017 return true; 1018 m_section = NULL; 1019 m_offset = load_addr; 1020 return false; 1021 } 1022 1023