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