ObjectFileELF.cpp revision 4a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7
1//===-- ObjectFileELF.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 "ObjectFileELF.h" 11 12#include <cassert> 13#include <algorithm> 14 15#include "lldb/Core/ArchSpec.h" 16#include "lldb/Core/DataBuffer.h" 17#include "lldb/Core/Error.h" 18#include "lldb/Core/FileSpecList.h" 19#include "lldb/Core/Module.h" 20#include "lldb/Core/PluginManager.h" 21#include "lldb/Core/Section.h" 22#include "lldb/Core/Stream.h" 23#include "lldb/Symbol/SymbolContext.h" 24#include "lldb/Host/Host.h" 25 26#include "llvm/ADT/PointerUnion.h" 27 28#define CASE_AND_STREAM(s, def, width) \ 29 case def: s->Printf("%-*s", width, #def); break; 30 31using namespace lldb; 32using namespace lldb_private; 33using namespace elf; 34using namespace llvm::ELF; 35 36namespace { 37//===----------------------------------------------------------------------===// 38/// @class ELFRelocation 39/// @brief Generic wrapper for ELFRel and ELFRela. 40/// 41/// This helper class allows us to parse both ELFRel and ELFRela relocation 42/// entries in a generic manner. 43class ELFRelocation 44{ 45public: 46 47 /// Constructs an ELFRelocation entry with a personality as given by @p 48 /// type. 49 /// 50 /// @param type Either DT_REL or DT_RELA. Any other value is invalid. 51 ELFRelocation(unsigned type); 52 53 ~ELFRelocation(); 54 55 bool 56 Parse(const lldb_private::DataExtractor &data, uint32_t *offset); 57 58 static unsigned 59 RelocType32(const ELFRelocation &rel); 60 61 static unsigned 62 RelocType64(const ELFRelocation &rel); 63 64 static unsigned 65 RelocSymbol32(const ELFRelocation &rel); 66 67 static unsigned 68 RelocSymbol64(const ELFRelocation &rel); 69 70private: 71 typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion; 72 73 RelocUnion reloc; 74}; 75 76ELFRelocation::ELFRelocation(unsigned type) 77{ 78 if (type == DT_REL) 79 reloc = new ELFRel(); 80 else if (type == DT_RELA) 81 reloc = new ELFRela(); 82 else { 83 assert(false && "unexpected relocation type"); 84 reloc = static_cast<ELFRel*>(NULL); 85 } 86} 87 88ELFRelocation::~ELFRelocation() 89{ 90 if (reloc.is<ELFRel*>()) 91 delete reloc.get<ELFRel*>(); 92 else 93 delete reloc.get<ELFRela*>(); 94} 95 96bool 97ELFRelocation::Parse(const lldb_private::DataExtractor &data, uint32_t *offset) 98{ 99 if (reloc.is<ELFRel*>()) 100 return reloc.get<ELFRel*>()->Parse(data, offset); 101 else 102 return reloc.get<ELFRela*>()->Parse(data, offset); 103} 104 105unsigned 106ELFRelocation::RelocType32(const ELFRelocation &rel) 107{ 108 if (rel.reloc.is<ELFRel*>()) 109 return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>()); 110 else 111 return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>()); 112} 113 114unsigned 115ELFRelocation::RelocType64(const ELFRelocation &rel) 116{ 117 if (rel.reloc.is<ELFRel*>()) 118 return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>()); 119 else 120 return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>()); 121} 122 123unsigned 124ELFRelocation::RelocSymbol32(const ELFRelocation &rel) 125{ 126 if (rel.reloc.is<ELFRel*>()) 127 return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>()); 128 else 129 return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>()); 130} 131 132unsigned 133ELFRelocation::RelocSymbol64(const ELFRelocation &rel) 134{ 135 if (rel.reloc.is<ELFRel*>()) 136 return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>()); 137 else 138 return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>()); 139} 140 141} // end anonymous namespace 142 143//------------------------------------------------------------------ 144// Static methods. 145//------------------------------------------------------------------ 146void 147ObjectFileELF::Initialize() 148{ 149 PluginManager::RegisterPlugin(GetPluginNameStatic(), 150 GetPluginDescriptionStatic(), 151 CreateInstance, 152 CreateMemoryInstance); 153} 154 155void 156ObjectFileELF::Terminate() 157{ 158 PluginManager::UnregisterPlugin(CreateInstance); 159} 160 161const char * 162ObjectFileELF::GetPluginNameStatic() 163{ 164 return "object-file.elf"; 165} 166 167const char * 168ObjectFileELF::GetPluginDescriptionStatic() 169{ 170 return "ELF object file reader."; 171} 172 173ObjectFile * 174ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp, 175 DataBufferSP &data_sp, 176 const FileSpec *file, 177 addr_t offset, 178 addr_t length) 179{ 180 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + offset)) 181 { 182 const uint8_t *magic = data_sp->GetBytes() + offset; 183 if (ELFHeader::MagicBytesMatch(magic)) 184 { 185 unsigned address_size = ELFHeader::AddressSizeInBytes(magic); 186 if (address_size == 4 || address_size == 8) 187 { 188 std::auto_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, file, offset, length)); 189 ArchSpec spec; 190 if (objfile_ap->GetArchitecture(spec) && 191 objfile_ap->SetModulesArchitecture(spec)) 192 return objfile_ap.release(); 193 } 194 } 195 } 196 return NULL; 197} 198 199 200ObjectFile* 201ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp, 202 DataBufferSP& data_sp, 203 const lldb::ProcessSP &process_sp, 204 lldb::addr_t header_addr) 205{ 206 return NULL; 207} 208 209 210//------------------------------------------------------------------ 211// PluginInterface protocol 212//------------------------------------------------------------------ 213const char * 214ObjectFileELF::GetPluginName() 215{ 216 return "ObjectFileELF"; 217} 218 219const char * 220ObjectFileELF::GetShortPluginName() 221{ 222 return GetPluginNameStatic(); 223} 224 225uint32_t 226ObjectFileELF::GetPluginVersion() 227{ 228 return m_plugin_version; 229} 230//------------------------------------------------------------------ 231// ObjectFile protocol 232//------------------------------------------------------------------ 233 234ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp, 235 DataBufferSP& dataSP, 236 const FileSpec* file, 237 addr_t offset, 238 addr_t length) : 239 ObjectFile(module_sp, file, offset, length, dataSP), 240 m_header(), 241 m_program_headers(), 242 m_section_headers(), 243 m_sections_ap(), 244 m_symtab_ap(), 245 m_filespec_ap(), 246 m_shstr_data() 247{ 248 if (file) 249 m_file = *file; 250 ::memset(&m_header, 0, sizeof(m_header)); 251} 252 253ObjectFileELF::~ObjectFileELF() 254{ 255} 256 257bool 258ObjectFileELF::IsExecutable() const 259{ 260 return m_header.e_entry != 0; 261} 262 263ByteOrder 264ObjectFileELF::GetByteOrder() const 265{ 266 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB) 267 return eByteOrderBig; 268 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB) 269 return eByteOrderLittle; 270 return eByteOrderInvalid; 271} 272 273size_t 274ObjectFileELF::GetAddressByteSize() const 275{ 276 return m_data.GetAddressByteSize(); 277} 278 279unsigned 280ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) 281{ 282 return std::distance(m_section_headers.begin(), I) + 1; 283} 284 285unsigned 286ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const 287{ 288 return std::distance(m_section_headers.begin(), I) + 1; 289} 290 291bool 292ObjectFileELF::ParseHeader() 293{ 294 uint32_t offset = GetOffset(); 295 return m_header.Parse(m_data, &offset); 296} 297 298bool 299ObjectFileELF::GetUUID(lldb_private::UUID* uuid) 300{ 301 // FIXME: Return MD5 sum here. See comment in ObjectFile.h. 302 return false; 303} 304 305uint32_t 306ObjectFileELF::GetDependentModules(FileSpecList &files) 307{ 308 size_t num_modules = ParseDependentModules(); 309 uint32_t num_specs = 0; 310 311 for (unsigned i = 0; i < num_modules; ++i) 312 { 313 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i))) 314 num_specs++; 315 } 316 317 return num_specs; 318} 319 320user_id_t 321ObjectFileELF::GetSectionIndexByType(unsigned type) 322{ 323 if (!ParseSectionHeaders()) 324 return 0; 325 326 for (SectionHeaderCollIter sh_pos = m_section_headers.begin(); 327 sh_pos != m_section_headers.end(); ++sh_pos) 328 { 329 if (sh_pos->sh_type == type) 330 return SectionIndex(sh_pos); 331 } 332 333 return 0; 334} 335 336Address 337ObjectFileELF::GetImageInfoAddress() 338{ 339 if (!ParseDynamicSymbols()) 340 return Address(); 341 342 SectionList *section_list = GetSectionList(); 343 if (!section_list) 344 return Address(); 345 346 user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC); 347 if (!dynsym_id) 348 return Address(); 349 350 const ELFSectionHeader *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id); 351 if (!dynsym_hdr) 352 return Address(); 353 354 SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id)); 355 if (dynsym_section_sp) 356 { 357 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) 358 { 359 ELFDynamic &symbol = m_dynamic_symbols[i]; 360 361 if (symbol.d_tag == DT_DEBUG) 362 { 363 // Compute the offset as the number of previous entries plus the 364 // size of d_tag. 365 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); 366 return Address(dynsym_section_sp, offset); 367 } 368 } 369 } 370 371 return Address(); 372} 373 374lldb_private::Address 375ObjectFileELF::GetEntryPointAddress () 376{ 377 SectionList *sections; 378 addr_t offset; 379 380 if (m_entry_point_address.IsValid()) 381 return m_entry_point_address; 382 383 if (!ParseHeader() || !IsExecutable()) 384 return m_entry_point_address; 385 386 sections = GetSectionList(); 387 offset = m_header.e_entry; 388 389 if (!sections) 390 { 391 m_entry_point_address.SetOffset(offset); 392 return m_entry_point_address; 393 } 394 395 m_entry_point_address.ResolveAddressUsingFileSections(offset, sections); 396 397 return m_entry_point_address; 398} 399 400//---------------------------------------------------------------------- 401// ParseDependentModules 402//---------------------------------------------------------------------- 403size_t 404ObjectFileELF::ParseDependentModules() 405{ 406 if (m_filespec_ap.get()) 407 return m_filespec_ap->GetSize(); 408 409 m_filespec_ap.reset(new FileSpecList()); 410 411 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 412 return 0; 413 414 // Locate the dynamic table. 415 user_id_t dynsym_id = 0; 416 user_id_t dynstr_id = 0; 417 for (SectionHeaderCollIter sh_pos = m_section_headers.begin(); 418 sh_pos != m_section_headers.end(); ++sh_pos) 419 { 420 if (sh_pos->sh_type == SHT_DYNAMIC) 421 { 422 dynsym_id = SectionIndex(sh_pos); 423 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based. 424 break; 425 } 426 } 427 428 if (!(dynsym_id && dynstr_id)) 429 return 0; 430 431 SectionList *section_list = GetSectionList(); 432 if (!section_list) 433 return 0; 434 435 // Resolve and load the dynamic table entries and corresponding string 436 // table. 437 Section *dynsym = section_list->FindSectionByID(dynsym_id).get(); 438 Section *dynstr = section_list->FindSectionByID(dynstr_id).get(); 439 if (!(dynsym && dynstr)) 440 return 0; 441 442 DataExtractor dynsym_data; 443 DataExtractor dynstr_data; 444 if (ReadSectionData(dynsym, dynsym_data) && 445 ReadSectionData(dynstr, dynstr_data)) 446 { 447 ELFDynamic symbol; 448 const unsigned section_size = dynsym_data.GetByteSize(); 449 unsigned offset = 0; 450 451 // The only type of entries we are concerned with are tagged DT_NEEDED, 452 // yielding the name of a required library. 453 while (offset < section_size) 454 { 455 if (!symbol.Parse(dynsym_data, &offset)) 456 break; 457 458 if (symbol.d_tag != DT_NEEDED) 459 continue; 460 461 uint32_t str_index = static_cast<uint32_t>(symbol.d_val); 462 const char *lib_name = dynstr_data.PeekCStr(str_index); 463 m_filespec_ap->Append(FileSpec(lib_name, true)); 464 } 465 } 466 467 return m_filespec_ap->GetSize(); 468} 469 470//---------------------------------------------------------------------- 471// ParseProgramHeaders 472//---------------------------------------------------------------------- 473size_t 474ObjectFileELF::ParseProgramHeaders() 475{ 476 // We have already parsed the program headers 477 if (!m_program_headers.empty()) 478 return m_program_headers.size(); 479 480 // If there are no program headers to read we are done. 481 if (m_header.e_phnum == 0) 482 return 0; 483 484 m_program_headers.resize(m_header.e_phnum); 485 if (m_program_headers.size() != m_header.e_phnum) 486 return 0; 487 488 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize; 489 const elf_off ph_offset = m_header.e_phoff; 490 DataExtractor data; 491 if (GetData (ph_offset, ph_size, data) != ph_size) 492 return 0; 493 494 uint32_t idx; 495 uint32_t offset; 496 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx) 497 { 498 if (m_program_headers[idx].Parse(data, &offset) == false) 499 break; 500 } 501 502 if (idx < m_program_headers.size()) 503 m_program_headers.resize(idx); 504 505 return m_program_headers.size(); 506} 507 508//---------------------------------------------------------------------- 509// ParseSectionHeaders 510//---------------------------------------------------------------------- 511size_t 512ObjectFileELF::ParseSectionHeaders() 513{ 514 // We have already parsed the section headers 515 if (!m_section_headers.empty()) 516 return m_section_headers.size(); 517 518 // If there are no section headers we are done. 519 if (m_header.e_shnum == 0) 520 return 0; 521 522 m_section_headers.resize(m_header.e_shnum); 523 if (m_section_headers.size() != m_header.e_shnum) 524 return 0; 525 526 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize; 527 const elf_off sh_offset = m_header.e_shoff; 528 DataExtractor data; 529 if (GetData (sh_offset, sh_size, data) != sh_size) 530 return 0; 531 532 uint32_t idx; 533 uint32_t offset; 534 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx) 535 { 536 if (m_section_headers[idx].Parse(data, &offset) == false) 537 break; 538 } 539 if (idx < m_section_headers.size()) 540 m_section_headers.resize(idx); 541 542 return m_section_headers.size(); 543} 544 545size_t 546ObjectFileELF::GetSectionHeaderStringTable() 547{ 548 if (m_shstr_data.GetByteSize() == 0) 549 { 550 const unsigned strtab_idx = m_header.e_shstrndx; 551 552 if (strtab_idx && strtab_idx < m_section_headers.size()) 553 { 554 const ELFSectionHeader &sheader = m_section_headers[strtab_idx]; 555 const size_t byte_size = sheader.sh_size; 556 const Elf64_Off offset = sheader.sh_offset; 557 m_shstr_data.SetData (m_data, offset, byte_size); 558 559 if (m_shstr_data.GetByteSize() != byte_size) 560 return 0; 561 } 562 } 563 return m_shstr_data.GetByteSize(); 564} 565 566lldb::user_id_t 567ObjectFileELF::GetSectionIndexByName(const char *name) 568{ 569 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 570 return 0; 571 572 // Search the collection of section headers for one with a matching name. 573 for (SectionHeaderCollIter I = m_section_headers.begin(); 574 I != m_section_headers.end(); ++I) 575 { 576 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name); 577 578 if (!sectionName) 579 return 0; 580 581 if (strcmp(name, sectionName) != 0) 582 continue; 583 584 return SectionIndex(I); 585 } 586 587 return 0; 588} 589 590const elf::ELFSectionHeader * 591ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) 592{ 593 if (!ParseSectionHeaders() || !id) 594 return NULL; 595 596 if (--id < m_section_headers.size()) 597 return &m_section_headers[id]; 598 599 return NULL; 600} 601 602SectionList * 603ObjectFileELF::GetSectionList() 604{ 605 if (m_sections_ap.get()) 606 return m_sections_ap.get(); 607 608 if (ParseSectionHeaders() && GetSectionHeaderStringTable()) 609 { 610 m_sections_ap.reset(new SectionList()); 611 612 for (SectionHeaderCollIter I = m_section_headers.begin(); 613 I != m_section_headers.end(); ++I) 614 { 615 const ELFSectionHeader &header = *I; 616 617 ConstString name(m_shstr_data.PeekCStr(header.sh_name)); 618 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size; 619 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0; 620 621 static ConstString g_sect_name_text (".text"); 622 static ConstString g_sect_name_data (".data"); 623 static ConstString g_sect_name_bss (".bss"); 624 static ConstString g_sect_name_tdata (".tdata"); 625 static ConstString g_sect_name_tbss (".tbss"); 626 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev"); 627 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges"); 628 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame"); 629 static ConstString g_sect_name_dwarf_debug_info (".debug_info"); 630 static ConstString g_sect_name_dwarf_debug_line (".debug_line"); 631 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc"); 632 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo"); 633 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames"); 634 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes"); 635 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges"); 636 static ConstString g_sect_name_dwarf_debug_str (".debug_str"); 637 static ConstString g_sect_name_eh_frame (".eh_frame"); 638 639 SectionType sect_type = eSectionTypeOther; 640 641 bool is_thread_specific = false; 642 643 if (name == g_sect_name_text) sect_type = eSectionTypeCode; 644 else if (name == g_sect_name_data) sect_type = eSectionTypeData; 645 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill; 646 else if (name == g_sect_name_tdata) 647 { 648 sect_type = eSectionTypeData; 649 is_thread_specific = true; 650 } 651 else if (name == g_sect_name_tbss) 652 { 653 sect_type = eSectionTypeZeroFill; 654 is_thread_specific = true; 655 } 656 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev; 657 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges; 658 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame; 659 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo; 660 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine; 661 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc; 662 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo; 663 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames; 664 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes; 665 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges; 666 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr; 667 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame; 668 669 670 SectionSP section_sp(new Section( 671 GetModule(), // Module to which this section belongs. 672 SectionIndex(I), // Section ID. 673 name, // Section name. 674 sect_type, // Section type. 675 header.sh_addr, // VM address. 676 vm_size, // VM size in bytes of this section. 677 header.sh_offset, // Offset of this section in the file. 678 file_size, // Size of the section as found in the file. 679 header.sh_flags)); // Flags for this section. 680 681 if (is_thread_specific) 682 section_sp->SetIsThreadSpecific (is_thread_specific); 683 m_sections_ap->AddSection(section_sp); 684 } 685 686 m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches 687 } 688 689 return m_sections_ap.get(); 690} 691 692static unsigned 693ParseSymbols(Symtab *symtab, 694 user_id_t start_id, 695 SectionList *section_list, 696 const ELFSectionHeader *symtab_shdr, 697 const DataExtractor &symtab_data, 698 const DataExtractor &strtab_data) 699{ 700 ELFSymbol symbol; 701 uint32_t offset = 0; 702 const unsigned num_symbols = 703 symtab_data.GetByteSize() / symtab_shdr->sh_entsize; 704 705 static ConstString text_section_name(".text"); 706 static ConstString init_section_name(".init"); 707 static ConstString fini_section_name(".fini"); 708 static ConstString ctors_section_name(".ctors"); 709 static ConstString dtors_section_name(".dtors"); 710 711 static ConstString data_section_name(".data"); 712 static ConstString rodata_section_name(".rodata"); 713 static ConstString rodata1_section_name(".rodata1"); 714 static ConstString data2_section_name(".data1"); 715 static ConstString bss_section_name(".bss"); 716 717 unsigned i; 718 for (i = 0; i < num_symbols; ++i) 719 { 720 if (symbol.Parse(symtab_data, &offset) == false) 721 break; 722 723 SectionSP symbol_section_sp; 724 SymbolType symbol_type = eSymbolTypeInvalid; 725 Elf64_Half symbol_idx = symbol.st_shndx; 726 727 switch (symbol_idx) 728 { 729 case SHN_ABS: 730 symbol_type = eSymbolTypeAbsolute; 731 break; 732 case SHN_UNDEF: 733 symbol_type = eSymbolTypeUndefined; 734 break; 735 default: 736 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx); 737 break; 738 } 739 740 switch (symbol.getType()) 741 { 742 default: 743 case STT_NOTYPE: 744 // The symbol's type is not specified. 745 break; 746 747 case STT_OBJECT: 748 // The symbol is associated with a data object, such as a variable, 749 // an array, etc. 750 symbol_type = eSymbolTypeData; 751 break; 752 753 case STT_FUNC: 754 // The symbol is associated with a function or other executable code. 755 symbol_type = eSymbolTypeCode; 756 break; 757 758 case STT_SECTION: 759 // The symbol is associated with a section. Symbol table entries of 760 // this type exist primarily for relocation and normally have 761 // STB_LOCAL binding. 762 break; 763 764 case STT_FILE: 765 // Conventionally, the symbol's name gives the name of the source 766 // file associated with the object file. A file symbol has STB_LOCAL 767 // binding, its section index is SHN_ABS, and it precedes the other 768 // STB_LOCAL symbols for the file, if it is present. 769 symbol_type = eSymbolTypeObjectFile; 770 break; 771 } 772 773 if (symbol_type == eSymbolTypeInvalid) 774 { 775 if (symbol_section_sp) 776 { 777 const ConstString §_name = symbol_section_sp->GetName(); 778 if (sect_name == text_section_name || 779 sect_name == init_section_name || 780 sect_name == fini_section_name || 781 sect_name == ctors_section_name || 782 sect_name == dtors_section_name) 783 { 784 symbol_type = eSymbolTypeCode; 785 } 786 else if (sect_name == data_section_name || 787 sect_name == data2_section_name || 788 sect_name == rodata_section_name || 789 sect_name == rodata1_section_name || 790 sect_name == bss_section_name) 791 { 792 symbol_type = eSymbolTypeData; 793 } 794 } 795 } 796 797 uint64_t symbol_value = symbol.st_value; 798 if (symbol_section_sp) 799 symbol_value -= symbol_section_sp->GetFileAddress(); 800 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 801 bool is_global = symbol.getBinding() == STB_GLOBAL; 802 uint32_t flags = symbol.st_other << 8 | symbol.st_info; 803 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false; 804 Symbol dc_symbol( 805 i + start_id, // ID is the original symbol table index. 806 symbol_name, // Symbol name. 807 is_mangled, // Is the symbol name mangled? 808 symbol_type, // Type of this symbol 809 is_global, // Is this globally visible? 810 false, // Is this symbol debug info? 811 false, // Is this symbol a trampoline? 812 false, // Is this symbol artificial? 813 symbol_section_sp, // Section in which this symbol is defined or null. 814 symbol_value, // Offset in section or symbol value. 815 symbol.st_size, // Size in bytes of this symbol. 816 flags); // Symbol flags. 817 symtab->AddSymbol(dc_symbol); 818 } 819 820 return i; 821} 822 823unsigned 824ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, 825 const ELFSectionHeader *symtab_hdr, 826 user_id_t symtab_id) 827{ 828 assert(symtab_hdr->sh_type == SHT_SYMTAB || 829 symtab_hdr->sh_type == SHT_DYNSYM); 830 831 // Parse in the section list if needed. 832 SectionList *section_list = GetSectionList(); 833 if (!section_list) 834 return 0; 835 836 // Section ID's are ones based. 837 user_id_t strtab_id = symtab_hdr->sh_link + 1; 838 839 Section *symtab = section_list->FindSectionByID(symtab_id).get(); 840 Section *strtab = section_list->FindSectionByID(strtab_id).get(); 841 unsigned num_symbols = 0; 842 if (symtab && strtab) 843 { 844 DataExtractor symtab_data; 845 DataExtractor strtab_data; 846 if (ReadSectionData(symtab, symtab_data) && 847 ReadSectionData(strtab, strtab_data)) 848 { 849 num_symbols = ParseSymbols(symbol_table, start_id, 850 section_list, symtab_hdr, 851 symtab_data, strtab_data); 852 } 853 } 854 855 return num_symbols; 856} 857 858size_t 859ObjectFileELF::ParseDynamicSymbols() 860{ 861 if (m_dynamic_symbols.size()) 862 return m_dynamic_symbols.size(); 863 864 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC); 865 if (!dyn_id) 866 return 0; 867 868 SectionList *section_list = GetSectionList(); 869 if (!section_list) 870 return 0; 871 872 Section *dynsym = section_list->FindSectionByID(dyn_id).get(); 873 if (!dynsym) 874 return 0; 875 876 ELFDynamic symbol; 877 DataExtractor dynsym_data; 878 if (ReadSectionData(dynsym, dynsym_data)) 879 { 880 const unsigned section_size = dynsym_data.GetByteSize(); 881 unsigned cursor = 0; 882 883 while (cursor < section_size) 884 { 885 if (!symbol.Parse(dynsym_data, &cursor)) 886 break; 887 888 m_dynamic_symbols.push_back(symbol); 889 } 890 } 891 892 return m_dynamic_symbols.size(); 893} 894 895const ELFDynamic * 896ObjectFileELF::FindDynamicSymbol(unsigned tag) 897{ 898 if (!ParseDynamicSymbols()) 899 return NULL; 900 901 SectionList *section_list = GetSectionList(); 902 if (!section_list) 903 return 0; 904 905 DynamicSymbolCollIter I = m_dynamic_symbols.begin(); 906 DynamicSymbolCollIter E = m_dynamic_symbols.end(); 907 for ( ; I != E; ++I) 908 { 909 ELFDynamic *symbol = &*I; 910 911 if (symbol->d_tag == tag) 912 return symbol; 913 } 914 915 return NULL; 916} 917 918Section * 919ObjectFileELF::PLTSection() 920{ 921 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); 922 SectionList *section_list = GetSectionList(); 923 924 if (symbol && section_list) 925 { 926 addr_t addr = symbol->d_ptr; 927 return section_list->FindSectionContainingFileAddress(addr).get(); 928 } 929 930 return NULL; 931} 932 933unsigned 934ObjectFileELF::PLTRelocationType() 935{ 936 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL); 937 938 if (symbol) 939 return symbol->d_val; 940 941 return 0; 942} 943 944static unsigned 945ParsePLTRelocations(Symtab *symbol_table, 946 user_id_t start_id, 947 unsigned rel_type, 948 const ELFHeader *hdr, 949 const ELFSectionHeader *rel_hdr, 950 const ELFSectionHeader *plt_hdr, 951 const ELFSectionHeader *sym_hdr, 952 const lldb::SectionSP &plt_section_sp, 953 DataExtractor &rel_data, 954 DataExtractor &symtab_data, 955 DataExtractor &strtab_data) 956{ 957 ELFRelocation rel(rel_type); 958 ELFSymbol symbol; 959 uint32_t offset = 0; 960 const unsigned plt_entsize = plt_hdr->sh_entsize; 961 const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; 962 963 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel); 964 reloc_info_fn reloc_type; 965 reloc_info_fn reloc_symbol; 966 967 if (hdr->Is32Bit() == 4) 968 { 969 reloc_type = ELFRelocation::RelocType32; 970 reloc_symbol = ELFRelocation::RelocSymbol32; 971 } 972 else 973 { 974 reloc_type = ELFRelocation::RelocType64; 975 reloc_symbol = ELFRelocation::RelocSymbol64; 976 } 977 978 unsigned slot_type = hdr->GetRelocationJumpSlotType(); 979 unsigned i; 980 for (i = 0; i < num_relocations; ++i) 981 { 982 if (rel.Parse(rel_data, &offset) == false) 983 break; 984 985 if (reloc_type(rel) != slot_type) 986 continue; 987 988 unsigned symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize; 989 uint64_t plt_index = (i + 1) * plt_entsize; 990 991 if (!symbol.Parse(symtab_data, &symbol_offset)) 992 break; 993 994 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 995 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false; 996 997 Symbol jump_symbol( 998 i + start_id, // Symbol table index 999 symbol_name, // symbol name. 1000 is_mangled, // is the symbol name mangled? 1001 eSymbolTypeTrampoline, // Type of this symbol 1002 false, // Is this globally visible? 1003 false, // Is this symbol debug info? 1004 true, // Is this symbol a trampoline? 1005 true, // Is this symbol artificial? 1006 plt_section_sp, // Section in which this symbol is defined or null. 1007 plt_index, // Offset in section or symbol value. 1008 plt_entsize, // Size in bytes of this symbol. 1009 0); // Symbol flags. 1010 1011 symbol_table->AddSymbol(jump_symbol); 1012 } 1013 1014 return i; 1015} 1016 1017unsigned 1018ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, 1019 user_id_t start_id, 1020 const ELFSectionHeader *rel_hdr, 1021 user_id_t rel_id) 1022{ 1023 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); 1024 1025 // The link field points to the asscoiated symbol table. The info field 1026 // points to the section holding the plt. 1027 user_id_t symtab_id = rel_hdr->sh_link; 1028 user_id_t plt_id = rel_hdr->sh_info; 1029 1030 if (!symtab_id || !plt_id) 1031 return 0; 1032 1033 // Section ID's are ones based; 1034 symtab_id++; 1035 plt_id++; 1036 1037 const ELFSectionHeader *plt_hdr = GetSectionHeaderByIndex(plt_id); 1038 if (!plt_hdr) 1039 return 0; 1040 1041 const ELFSectionHeader *sym_hdr = GetSectionHeaderByIndex(symtab_id); 1042 if (!sym_hdr) 1043 return 0; 1044 1045 SectionList *section_list = GetSectionList(); 1046 if (!section_list) 1047 return 0; 1048 1049 Section *rel_section = section_list->FindSectionByID(rel_id).get(); 1050 if (!rel_section) 1051 return 0; 1052 1053 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id)); 1054 if (!plt_section_sp) 1055 return 0; 1056 1057 Section *symtab = section_list->FindSectionByID(symtab_id).get(); 1058 if (!symtab) 1059 return 0; 1060 1061 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get(); 1062 if (!strtab) 1063 return 0; 1064 1065 DataExtractor rel_data; 1066 if (!ReadSectionData(rel_section, rel_data)) 1067 return 0; 1068 1069 DataExtractor symtab_data; 1070 if (!ReadSectionData(symtab, symtab_data)) 1071 return 0; 1072 1073 DataExtractor strtab_data; 1074 if (!ReadSectionData(strtab, strtab_data)) 1075 return 0; 1076 1077 unsigned rel_type = PLTRelocationType(); 1078 if (!rel_type) 1079 return 0; 1080 1081 return ParsePLTRelocations (symbol_table, 1082 start_id, 1083 rel_type, 1084 &m_header, 1085 rel_hdr, 1086 plt_hdr, 1087 sym_hdr, 1088 plt_section_sp, 1089 rel_data, 1090 symtab_data, 1091 strtab_data); 1092} 1093 1094Symtab * 1095ObjectFileELF::GetSymtab() 1096{ 1097 if (m_symtab_ap.get()) 1098 return m_symtab_ap.get(); 1099 1100 Symtab *symbol_table = new Symtab(this); 1101 m_symtab_ap.reset(symbol_table); 1102 1103 Mutex::Locker locker(symbol_table->GetMutex()); 1104 1105 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 1106 return symbol_table; 1107 1108 // Locate and parse all linker symbol tables. 1109 uint64_t symbol_id = 0; 1110 for (SectionHeaderCollIter I = m_section_headers.begin(); 1111 I != m_section_headers.end(); ++I) 1112 { 1113 if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM) 1114 { 1115 const ELFSectionHeader &symtab_header = *I; 1116 user_id_t section_id = SectionIndex(I); 1117 symbol_id += ParseSymbolTable(symbol_table, symbol_id, 1118 &symtab_header, section_id); 1119 } 1120 } 1121 1122 // Synthesize trampoline symbols to help navigate the PLT. 1123 Section *reloc_section = PLTSection(); 1124 if (reloc_section) 1125 { 1126 user_id_t reloc_id = reloc_section->GetID(); 1127 const ELFSectionHeader *reloc_header = GetSectionHeaderByIndex(reloc_id); 1128 assert(reloc_header); 1129 1130 ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id); 1131 } 1132 1133 return symbol_table; 1134} 1135 1136//===----------------------------------------------------------------------===// 1137// Dump 1138// 1139// Dump the specifics of the runtime file container (such as any headers 1140// segments, sections, etc). 1141//---------------------------------------------------------------------- 1142void 1143ObjectFileELF::Dump(Stream *s) 1144{ 1145 DumpELFHeader(s, m_header); 1146 s->EOL(); 1147 DumpELFProgramHeaders(s); 1148 s->EOL(); 1149 DumpELFSectionHeaders(s); 1150 s->EOL(); 1151 SectionList *section_list = GetSectionList(); 1152 if (section_list) 1153 section_list->Dump(s, NULL, true, UINT32_MAX); 1154 Symtab *symtab = GetSymtab(); 1155 if (symtab) 1156 symtab->Dump(s, NULL, eSortOrderNone); 1157 s->EOL(); 1158 DumpDependentModules(s); 1159 s->EOL(); 1160} 1161 1162//---------------------------------------------------------------------- 1163// DumpELFHeader 1164// 1165// Dump the ELF header to the specified output stream 1166//---------------------------------------------------------------------- 1167void 1168ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) 1169{ 1170 s->PutCString("ELF Header\n"); 1171 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); 1172 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", 1173 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]); 1174 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", 1175 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]); 1176 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", 1177 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]); 1178 1179 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]); 1180 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]); 1181 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]); 1182 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]); 1183 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]); 1184 1185 s->Printf("e_type = 0x%4.4x ", header.e_type); 1186 DumpELFHeader_e_type(s, header.e_type); 1187 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine); 1188 s->Printf("e_version = 0x%8.8x\n", header.e_version); 1189 s->Printf("e_entry = 0x%8.8llx\n", header.e_entry); 1190 s->Printf("e_phoff = 0x%8.8llx\n", header.e_phoff); 1191 s->Printf("e_shoff = 0x%8.8llx\n", header.e_shoff); 1192 s->Printf("e_flags = 0x%8.8x\n", header.e_flags); 1193 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize); 1194 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize); 1195 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum); 1196 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); 1197 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum); 1198 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx); 1199} 1200 1201//---------------------------------------------------------------------- 1202// DumpELFHeader_e_type 1203// 1204// Dump an token value for the ELF header member e_type 1205//---------------------------------------------------------------------- 1206void 1207ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) 1208{ 1209 switch (e_type) 1210 { 1211 case ET_NONE: *s << "ET_NONE"; break; 1212 case ET_REL: *s << "ET_REL"; break; 1213 case ET_EXEC: *s << "ET_EXEC"; break; 1214 case ET_DYN: *s << "ET_DYN"; break; 1215 case ET_CORE: *s << "ET_CORE"; break; 1216 default: 1217 break; 1218 } 1219} 1220 1221//---------------------------------------------------------------------- 1222// DumpELFHeader_e_ident_EI_DATA 1223// 1224// Dump an token value for the ELF header member e_ident[EI_DATA] 1225//---------------------------------------------------------------------- 1226void 1227ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data) 1228{ 1229 switch (ei_data) 1230 { 1231 case ELFDATANONE: *s << "ELFDATANONE"; break; 1232 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break; 1233 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break; 1234 default: 1235 break; 1236 } 1237} 1238 1239 1240//---------------------------------------------------------------------- 1241// DumpELFProgramHeader 1242// 1243// Dump a single ELF program header to the specified output stream 1244//---------------------------------------------------------------------- 1245void 1246ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph) 1247{ 1248 DumpELFProgramHeader_p_type(s, ph.p_type); 1249 s->Printf(" %8.8llx %8.8llx %8.8llx", ph.p_offset, ph.p_vaddr, ph.p_paddr); 1250 s->Printf(" %8.8llx %8.8llx %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags); 1251 1252 DumpELFProgramHeader_p_flags(s, ph.p_flags); 1253 s->Printf(") %8.8llx", ph.p_align); 1254} 1255 1256//---------------------------------------------------------------------- 1257// DumpELFProgramHeader_p_type 1258// 1259// Dump an token value for the ELF program header member p_type which 1260// describes the type of the program header 1261// ---------------------------------------------------------------------- 1262void 1263ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) 1264{ 1265 const int kStrWidth = 10; 1266 switch (p_type) 1267 { 1268 CASE_AND_STREAM(s, PT_NULL , kStrWidth); 1269 CASE_AND_STREAM(s, PT_LOAD , kStrWidth); 1270 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth); 1271 CASE_AND_STREAM(s, PT_INTERP , kStrWidth); 1272 CASE_AND_STREAM(s, PT_NOTE , kStrWidth); 1273 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth); 1274 CASE_AND_STREAM(s, PT_PHDR , kStrWidth); 1275 default: 1276 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, ""); 1277 break; 1278 } 1279} 1280 1281 1282//---------------------------------------------------------------------- 1283// DumpELFProgramHeader_p_flags 1284// 1285// Dump an token value for the ELF program header member p_flags 1286//---------------------------------------------------------------------- 1287void 1288ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) 1289{ 1290 *s << ((p_flags & PF_X) ? "PF_X" : " ") 1291 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') 1292 << ((p_flags & PF_W) ? "PF_W" : " ") 1293 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ') 1294 << ((p_flags & PF_R) ? "PF_R" : " "); 1295} 1296 1297//---------------------------------------------------------------------- 1298// DumpELFProgramHeaders 1299// 1300// Dump all of the ELF program header to the specified output stream 1301//---------------------------------------------------------------------- 1302void 1303ObjectFileELF::DumpELFProgramHeaders(Stream *s) 1304{ 1305 if (ParseProgramHeaders()) 1306 { 1307 s->PutCString("Program Headers\n"); 1308 s->PutCString("IDX p_type p_offset p_vaddr p_paddr " 1309 "p_filesz p_memsz p_flags p_align\n"); 1310 s->PutCString("==== ---------- -------- -------- -------- " 1311 "-------- -------- ------------------------- --------\n"); 1312 1313 uint32_t idx = 0; 1314 for (ProgramHeaderCollConstIter I = m_program_headers.begin(); 1315 I != m_program_headers.end(); ++I, ++idx) 1316 { 1317 s->Printf("[%2u] ", idx); 1318 ObjectFileELF::DumpELFProgramHeader(s, *I); 1319 s->EOL(); 1320 } 1321 } 1322} 1323 1324//---------------------------------------------------------------------- 1325// DumpELFSectionHeader 1326// 1327// Dump a single ELF section header to the specified output stream 1328//---------------------------------------------------------------------- 1329void 1330ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh) 1331{ 1332 s->Printf("%8.8x ", sh.sh_name); 1333 DumpELFSectionHeader_sh_type(s, sh.sh_type); 1334 s->Printf(" %8.8llx (", sh.sh_flags); 1335 DumpELFSectionHeader_sh_flags(s, sh.sh_flags); 1336 s->Printf(") %8.8llx %8.8llx %8.8llx", sh.sh_addr, sh.sh_offset, sh.sh_size); 1337 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info); 1338 s->Printf(" %8.8llx %8.8llx", sh.sh_addralign, sh.sh_entsize); 1339} 1340 1341//---------------------------------------------------------------------- 1342// DumpELFSectionHeader_sh_type 1343// 1344// Dump an token value for the ELF section header member sh_type which 1345// describes the type of the section 1346//---------------------------------------------------------------------- 1347void 1348ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) 1349{ 1350 const int kStrWidth = 12; 1351 switch (sh_type) 1352 { 1353 CASE_AND_STREAM(s, SHT_NULL , kStrWidth); 1354 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth); 1355 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth); 1356 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth); 1357 CASE_AND_STREAM(s, SHT_RELA , kStrWidth); 1358 CASE_AND_STREAM(s, SHT_HASH , kStrWidth); 1359 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth); 1360 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth); 1361 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth); 1362 CASE_AND_STREAM(s, SHT_REL , kStrWidth); 1363 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth); 1364 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth); 1365 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth); 1366 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth); 1367 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth); 1368 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth); 1369 default: 1370 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, ""); 1371 break; 1372 } 1373} 1374 1375//---------------------------------------------------------------------- 1376// DumpELFSectionHeader_sh_flags 1377// 1378// Dump an token value for the ELF section header member sh_flags 1379//---------------------------------------------------------------------- 1380void 1381ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags) 1382{ 1383 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") 1384 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ') 1385 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ") 1386 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ') 1387 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); 1388} 1389 1390//---------------------------------------------------------------------- 1391// DumpELFSectionHeaders 1392// 1393// Dump all of the ELF section header to the specified output stream 1394//---------------------------------------------------------------------- 1395void 1396ObjectFileELF::DumpELFSectionHeaders(Stream *s) 1397{ 1398 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 1399 return; 1400 1401 s->PutCString("Section Headers\n"); 1402 s->PutCString("IDX name type flags " 1403 "addr offset size link info addralgn " 1404 "entsize Name\n"); 1405 s->PutCString("==== -------- ------------ -------------------------------- " 1406 "-------- -------- -------- -------- -------- -------- " 1407 "-------- ====================\n"); 1408 1409 uint32_t idx = 0; 1410 for (SectionHeaderCollConstIter I = m_section_headers.begin(); 1411 I != m_section_headers.end(); ++I, ++idx) 1412 { 1413 s->Printf("[%2u] ", idx); 1414 ObjectFileELF::DumpELFSectionHeader(s, *I); 1415 const char* section_name = m_shstr_data.PeekCStr(I->sh_name); 1416 if (section_name) 1417 *s << ' ' << section_name << "\n"; 1418 } 1419} 1420 1421void 1422ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) 1423{ 1424 size_t num_modules = ParseDependentModules(); 1425 1426 if (num_modules > 0) 1427 { 1428 s->PutCString("Dependent Modules:\n"); 1429 for (unsigned i = 0; i < num_modules; ++i) 1430 { 1431 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i); 1432 s->Printf(" %s\n", spec.GetFilename().GetCString()); 1433 } 1434 } 1435} 1436 1437bool 1438ObjectFileELF::GetArchitecture (ArchSpec &arch) 1439{ 1440 if (!ParseHeader()) 1441 return false; 1442 1443 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE); 1444 arch.GetTriple().setOSName (Host::GetOSString().GetCString()); 1445 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString()); 1446 return true; 1447} 1448 1449ObjectFile::Type 1450ObjectFileELF::CalculateType() 1451{ 1452 switch (m_header.e_type) 1453 { 1454 case llvm::ELF::ET_NONE: 1455 // 0 - No file type 1456 return eTypeUnknown; 1457 1458 case llvm::ELF::ET_REL: 1459 // 1 - Relocatable file 1460 return eTypeObjectFile; 1461 1462 case llvm::ELF::ET_EXEC: 1463 // 2 - Executable file 1464 return eTypeExecutable; 1465 1466 case llvm::ELF::ET_DYN: 1467 // 3 - Shared object file 1468 return eTypeSharedLibrary; 1469 1470 case ET_CORE: 1471 // 4 - Core file 1472 return eTypeCoreFile; 1473 1474 default: 1475 break; 1476 } 1477 return eTypeUnknown; 1478} 1479 1480ObjectFile::Strata 1481ObjectFileELF::CalculateStrata() 1482{ 1483 switch (m_header.e_type) 1484 { 1485 case llvm::ELF::ET_NONE: 1486 // 0 - No file type 1487 return eStrataUnknown; 1488 1489 case llvm::ELF::ET_REL: 1490 // 1 - Relocatable file 1491 return eStrataUnknown; 1492 1493 case llvm::ELF::ET_EXEC: 1494 // 2 - Executable file 1495 // TODO: is there any way to detect that an executable is a kernel 1496 // related executable by inspecting the program headers, section 1497 // headers, symbols, or any other flag bits??? 1498 return eStrataUser; 1499 1500 case llvm::ELF::ET_DYN: 1501 // 3 - Shared object file 1502 // TODO: is there any way to detect that an shared library is a kernel 1503 // related executable by inspecting the program headers, section 1504 // headers, symbols, or any other flag bits??? 1505 return eStrataUnknown; 1506 1507 case ET_CORE: 1508 // 4 - Core file 1509 // TODO: is there any way to detect that an core file is a kernel 1510 // related executable by inspecting the program headers, section 1511 // headers, symbols, or any other flag bits??? 1512 return eStrataUnknown; 1513 1514 default: 1515 break; 1516 } 1517 return eStrataUnknown; 1518} 1519 1520