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 31 using namespace lldb; 32 using namespace lldb_private; 33 using namespace elf; 34 using namespace llvm::ELF; 35 36 namespace { 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. 43 class ELFRelocation 44 { 45 public: 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 70 private: 71 typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion; 72 73 RelocUnion reloc; 74 }; 75 76 ELFRelocation::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 88 ELFRelocation::~ELFRelocation() 89 { 90 if (reloc.is<ELFRel*>()) 91 delete reloc.get<ELFRel*>(); 92 else 93 delete reloc.get<ELFRela*>(); 94 } 95 96 bool 97 ELFRelocation::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 105 unsigned 106 ELFRelocation::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 114 unsigned 115 ELFRelocation::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 123 unsigned 124 ELFRelocation::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 132 unsigned 133 ELFRelocation::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 //------------------------------------------------------------------ 146 void 147 ObjectFileELF::Initialize() 148 { 149 PluginManager::RegisterPlugin(GetPluginNameStatic(), 150 GetPluginDescriptionStatic(), 151 CreateInstance, 152 CreateMemoryInstance); 153 } 154 155 void 156 ObjectFileELF::Terminate() 157 { 158 PluginManager::UnregisterPlugin(CreateInstance); 159 } 160 161 const char * 162 ObjectFileELF::GetPluginNameStatic() 163 { 164 return "object-file.elf"; 165 } 166 167 const char * 168 ObjectFileELF::GetPluginDescriptionStatic() 169 { 170 return "ELF object file reader."; 171 } 172 173 ObjectFile * 174 ObjectFileELF::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 200 ObjectFile* 201 ObjectFileELF::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 //------------------------------------------------------------------ 213 const char * 214 ObjectFileELF::GetPluginName() 215 { 216 return "ObjectFileELF"; 217 } 218 219 const char * 220 ObjectFileELF::GetShortPluginName() 221 { 222 return GetPluginNameStatic(); 223 } 224 225 uint32_t 226 ObjectFileELF::GetPluginVersion() 227 { 228 return m_plugin_version; 229 } 230 //------------------------------------------------------------------ 231 // ObjectFile protocol 232 //------------------------------------------------------------------ 233 234 ObjectFileELF::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 253 ObjectFileELF::~ObjectFileELF() 254 { 255 } 256 257 bool 258 ObjectFileELF::IsExecutable() const 259 { 260 return m_header.e_entry != 0; 261 } 262 263 ByteOrder 264 ObjectFileELF::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 273 size_t 274 ObjectFileELF::GetAddressByteSize() const 275 { 276 return m_data.GetAddressByteSize(); 277 } 278 279 unsigned 280 ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) 281 { 282 return std::distance(m_section_headers.begin(), I) + 1; 283 } 284 285 unsigned 286 ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const 287 { 288 return std::distance(m_section_headers.begin(), I) + 1; 289 } 290 291 bool 292 ObjectFileELF::ParseHeader() 293 { 294 uint32_t offset = GetOffset(); 295 return m_header.Parse(m_data, &offset); 296 } 297 298 bool 299 ObjectFileELF::GetUUID(lldb_private::UUID* uuid) 300 { 301 // FIXME: Return MD5 sum here. See comment in ObjectFile.h. 302 return false; 303 } 304 305 uint32_t 306 ObjectFileELF::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 320 user_id_t 321 ObjectFileELF::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 336 Address 337 ObjectFileELF::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 374 lldb_private::Address 375 ObjectFileELF::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 //---------------------------------------------------------------------- 403 size_t 404 ObjectFileELF::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 //---------------------------------------------------------------------- 473 size_t 474 ObjectFileELF::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 //---------------------------------------------------------------------- 511 size_t 512 ObjectFileELF::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 545 size_t 546 ObjectFileELF::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 566 lldb::user_id_t 567 ObjectFileELF::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 590 const elf::ELFSectionHeader * 591 ObjectFileELF::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 602 SectionList * 603 ObjectFileELF::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 uint64_t size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size; 619 620 static ConstString g_sect_name_text (".text"); 621 static ConstString g_sect_name_data (".data"); 622 static ConstString g_sect_name_bss (".bss"); 623 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev"); 624 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges"); 625 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame"); 626 static ConstString g_sect_name_dwarf_debug_info (".debug_info"); 627 static ConstString g_sect_name_dwarf_debug_line (".debug_line"); 628 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc"); 629 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo"); 630 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames"); 631 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes"); 632 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges"); 633 static ConstString g_sect_name_dwarf_debug_str (".debug_str"); 634 static ConstString g_sect_name_eh_frame (".eh_frame"); 635 636 SectionType sect_type = eSectionTypeOther; 637 638 if (name == g_sect_name_text) sect_type = eSectionTypeCode; 639 else if (name == g_sect_name_data) sect_type = eSectionTypeData; 640 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill; 641 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev; 642 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges; 643 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame; 644 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo; 645 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine; 646 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc; 647 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo; 648 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames; 649 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes; 650 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges; 651 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr; 652 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame; 653 654 655 SectionSP section(new Section( 656 GetModule(), // Module to which this section belongs. 657 SectionIndex(I), // Section ID. 658 name, // Section name. 659 sect_type, // Section type. 660 header.sh_addr, // VM address. 661 header.sh_size, // VM size in bytes of this section. 662 header.sh_offset, // Offset of this section in the file. 663 size, // Size of the section as found in the file. 664 header.sh_flags)); // Flags for this section. 665 666 m_sections_ap->AddSection(section); 667 } 668 } 669 670 return m_sections_ap.get(); 671 } 672 673 static unsigned 674 ParseSymbols(Symtab *symtab, 675 user_id_t start_id, 676 SectionList *section_list, 677 const ELFSectionHeader *symtab_shdr, 678 const DataExtractor &symtab_data, 679 const DataExtractor &strtab_data) 680 { 681 ELFSymbol symbol; 682 uint32_t offset = 0; 683 const unsigned num_symbols = 684 symtab_data.GetByteSize() / symtab_shdr->sh_entsize; 685 686 static ConstString text_section_name(".text"); 687 static ConstString init_section_name(".init"); 688 static ConstString fini_section_name(".fini"); 689 static ConstString ctors_section_name(".ctors"); 690 static ConstString dtors_section_name(".dtors"); 691 692 static ConstString data_section_name(".data"); 693 static ConstString rodata_section_name(".rodata"); 694 static ConstString rodata1_section_name(".rodata1"); 695 static ConstString data2_section_name(".data1"); 696 static ConstString bss_section_name(".bss"); 697 698 unsigned i; 699 for (i = 0; i < num_symbols; ++i) 700 { 701 if (symbol.Parse(symtab_data, &offset) == false) 702 break; 703 704 SectionSP symbol_section_sp; 705 SymbolType symbol_type = eSymbolTypeInvalid; 706 Elf64_Half symbol_idx = symbol.st_shndx; 707 708 switch (symbol_idx) 709 { 710 case SHN_ABS: 711 symbol_type = eSymbolTypeAbsolute; 712 break; 713 case SHN_UNDEF: 714 symbol_type = eSymbolTypeUndefined; 715 break; 716 default: 717 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx); 718 break; 719 } 720 721 switch (symbol.getType()) 722 { 723 default: 724 case STT_NOTYPE: 725 // The symbol's type is not specified. 726 break; 727 728 case STT_OBJECT: 729 // The symbol is associated with a data object, such as a variable, 730 // an array, etc. 731 symbol_type = eSymbolTypeData; 732 break; 733 734 case STT_FUNC: 735 // The symbol is associated with a function or other executable code. 736 symbol_type = eSymbolTypeCode; 737 break; 738 739 case STT_SECTION: 740 // The symbol is associated with a section. Symbol table entries of 741 // this type exist primarily for relocation and normally have 742 // STB_LOCAL binding. 743 break; 744 745 case STT_FILE: 746 // Conventionally, the symbol's name gives the name of the source 747 // file associated with the object file. A file symbol has STB_LOCAL 748 // binding, its section index is SHN_ABS, and it precedes the other 749 // STB_LOCAL symbols for the file, if it is present. 750 symbol_type = eSymbolTypeObjectFile; 751 break; 752 } 753 754 if (symbol_type == eSymbolTypeInvalid) 755 { 756 if (symbol_section_sp) 757 { 758 const ConstString §_name = symbol_section_sp->GetName(); 759 if (sect_name == text_section_name || 760 sect_name == init_section_name || 761 sect_name == fini_section_name || 762 sect_name == ctors_section_name || 763 sect_name == dtors_section_name) 764 { 765 symbol_type = eSymbolTypeCode; 766 } 767 else if (sect_name == data_section_name || 768 sect_name == data2_section_name || 769 sect_name == rodata_section_name || 770 sect_name == rodata1_section_name || 771 sect_name == bss_section_name) 772 { 773 symbol_type = eSymbolTypeData; 774 } 775 } 776 } 777 778 uint64_t symbol_value = symbol.st_value; 779 if (symbol_section_sp) 780 symbol_value -= symbol_section_sp->GetFileAddress(); 781 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 782 bool is_global = symbol.getBinding() == STB_GLOBAL; 783 uint32_t flags = symbol.st_other << 8 | symbol.st_info; 784 785 Symbol dc_symbol( 786 i + start_id, // ID is the original symbol table index. 787 symbol_name, // Symbol name. 788 false, // Is the symbol name mangled? 789 symbol_type, // Type of this symbol 790 is_global, // Is this globally visible? 791 false, // Is this symbol debug info? 792 false, // Is this symbol a trampoline? 793 false, // Is this symbol artificial? 794 symbol_section_sp, // Section in which this symbol is defined or null. 795 symbol_value, // Offset in section or symbol value. 796 symbol.st_size, // Size in bytes of this symbol. 797 flags); // Symbol flags. 798 symtab->AddSymbol(dc_symbol); 799 } 800 801 return i; 802 } 803 804 unsigned 805 ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, 806 const ELFSectionHeader *symtab_hdr, 807 user_id_t symtab_id) 808 { 809 assert(symtab_hdr->sh_type == SHT_SYMTAB || 810 symtab_hdr->sh_type == SHT_DYNSYM); 811 812 // Parse in the section list if needed. 813 SectionList *section_list = GetSectionList(); 814 if (!section_list) 815 return 0; 816 817 // Section ID's are ones based. 818 user_id_t strtab_id = symtab_hdr->sh_link + 1; 819 820 Section *symtab = section_list->FindSectionByID(symtab_id).get(); 821 Section *strtab = section_list->FindSectionByID(strtab_id).get(); 822 unsigned num_symbols = 0; 823 if (symtab && strtab) 824 { 825 DataExtractor symtab_data; 826 DataExtractor strtab_data; 827 if (ReadSectionData(symtab, symtab_data) && 828 ReadSectionData(strtab, strtab_data)) 829 { 830 num_symbols = ParseSymbols(symbol_table, start_id, 831 section_list, symtab_hdr, 832 symtab_data, strtab_data); 833 } 834 } 835 836 return num_symbols; 837 } 838 839 size_t 840 ObjectFileELF::ParseDynamicSymbols() 841 { 842 if (m_dynamic_symbols.size()) 843 return m_dynamic_symbols.size(); 844 845 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC); 846 if (!dyn_id) 847 return NULL; 848 849 SectionList *section_list = GetSectionList(); 850 if (!section_list) 851 return NULL; 852 853 Section *dynsym = section_list->FindSectionByID(dyn_id).get(); 854 if (!dynsym) 855 return NULL; 856 857 ELFDynamic symbol; 858 DataExtractor dynsym_data; 859 if (ReadSectionData(dynsym, dynsym_data)) 860 { 861 862 const unsigned section_size = dynsym_data.GetByteSize(); 863 unsigned offset = 0; 864 unsigned cursor = 0; 865 866 while (cursor < section_size) 867 { 868 offset = cursor; 869 if (!symbol.Parse(dynsym_data, &cursor)) 870 break; 871 872 m_dynamic_symbols.push_back(symbol); 873 } 874 } 875 876 return m_dynamic_symbols.size(); 877 } 878 879 const ELFDynamic * 880 ObjectFileELF::FindDynamicSymbol(unsigned tag) 881 { 882 if (!ParseDynamicSymbols()) 883 return NULL; 884 885 SectionList *section_list = GetSectionList(); 886 if (!section_list) 887 return 0; 888 889 DynamicSymbolCollIter I = m_dynamic_symbols.begin(); 890 DynamicSymbolCollIter E = m_dynamic_symbols.end(); 891 for ( ; I != E; ++I) 892 { 893 ELFDynamic *symbol = &*I; 894 895 if (symbol->d_tag == tag) 896 return symbol; 897 } 898 899 return NULL; 900 } 901 902 Section * 903 ObjectFileELF::PLTSection() 904 { 905 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); 906 SectionList *section_list = GetSectionList(); 907 908 if (symbol && section_list) 909 { 910 addr_t addr = symbol->d_ptr; 911 return section_list->FindSectionContainingFileAddress(addr).get(); 912 } 913 914 return NULL; 915 } 916 917 unsigned 918 ObjectFileELF::PLTRelocationType() 919 { 920 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL); 921 922 if (symbol) 923 return symbol->d_val; 924 925 return 0; 926 } 927 928 static unsigned 929 ParsePLTRelocations(Symtab *symbol_table, 930 user_id_t start_id, 931 unsigned rel_type, 932 const ELFHeader *hdr, 933 const ELFSectionHeader *rel_hdr, 934 const ELFSectionHeader *plt_hdr, 935 const ELFSectionHeader *sym_hdr, 936 const lldb::SectionSP &plt_section_sp, 937 DataExtractor &rel_data, 938 DataExtractor &symtab_data, 939 DataExtractor &strtab_data) 940 { 941 ELFRelocation rel(rel_type); 942 ELFSymbol symbol; 943 uint32_t offset = 0; 944 const unsigned plt_entsize = plt_hdr->sh_entsize; 945 const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; 946 947 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel); 948 reloc_info_fn reloc_type; 949 reloc_info_fn reloc_symbol; 950 951 if (hdr->Is32Bit() == 4) 952 { 953 reloc_type = ELFRelocation::RelocType32; 954 reloc_symbol = ELFRelocation::RelocSymbol32; 955 } 956 else 957 { 958 reloc_type = ELFRelocation::RelocType64; 959 reloc_symbol = ELFRelocation::RelocSymbol64; 960 } 961 962 unsigned slot_type = hdr->GetRelocationJumpSlotType(); 963 unsigned i; 964 for (i = 0; i < num_relocations; ++i) 965 { 966 if (rel.Parse(rel_data, &offset) == false) 967 break; 968 969 if (reloc_type(rel) != slot_type) 970 continue; 971 972 unsigned symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize; 973 uint64_t plt_index = (i + 1) * plt_entsize; 974 975 if (!symbol.Parse(symtab_data, &symbol_offset)) 976 break; 977 978 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 979 980 Symbol jump_symbol( 981 i + start_id, // Symbol table index 982 symbol_name, // symbol name. 983 false, // is the symbol name mangled? 984 eSymbolTypeTrampoline, // Type of this symbol 985 false, // Is this globally visible? 986 false, // Is this symbol debug info? 987 true, // Is this symbol a trampoline? 988 true, // Is this symbol artificial? 989 plt_section_sp, // Section in which this symbol is defined or null. 990 plt_index, // Offset in section or symbol value. 991 plt_entsize, // Size in bytes of this symbol. 992 0); // Symbol flags. 993 994 symbol_table->AddSymbol(jump_symbol); 995 } 996 997 return i; 998 } 999 1000 unsigned 1001 ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, 1002 user_id_t start_id, 1003 const ELFSectionHeader *rel_hdr, 1004 user_id_t rel_id) 1005 { 1006 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); 1007 1008 // The link field points to the asscoiated symbol table. The info field 1009 // points to the section holding the plt. 1010 user_id_t symtab_id = rel_hdr->sh_link; 1011 user_id_t plt_id = rel_hdr->sh_info; 1012 1013 if (!symtab_id || !plt_id) 1014 return 0; 1015 1016 // Section ID's are ones based; 1017 symtab_id++; 1018 plt_id++; 1019 1020 const ELFSectionHeader *plt_hdr = GetSectionHeaderByIndex(plt_id); 1021 if (!plt_hdr) 1022 return 0; 1023 1024 const ELFSectionHeader *sym_hdr = GetSectionHeaderByIndex(symtab_id); 1025 if (!sym_hdr) 1026 return 0; 1027 1028 SectionList *section_list = GetSectionList(); 1029 if (!section_list) 1030 return 0; 1031 1032 Section *rel_section = section_list->FindSectionByID(rel_id).get(); 1033 if (!rel_section) 1034 return 0; 1035 1036 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id)); 1037 if (!plt_section_sp) 1038 return 0; 1039 1040 Section *symtab = section_list->FindSectionByID(symtab_id).get(); 1041 if (!symtab) 1042 return 0; 1043 1044 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get(); 1045 if (!strtab) 1046 return 0; 1047 1048 DataExtractor rel_data; 1049 if (!ReadSectionData(rel_section, rel_data)) 1050 return 0; 1051 1052 DataExtractor symtab_data; 1053 if (!ReadSectionData(symtab, symtab_data)) 1054 return 0; 1055 1056 DataExtractor strtab_data; 1057 if (!ReadSectionData(strtab, strtab_data)) 1058 return 0; 1059 1060 unsigned rel_type = PLTRelocationType(); 1061 if (!rel_type) 1062 return 0; 1063 1064 return ParsePLTRelocations (symbol_table, 1065 start_id, 1066 rel_type, 1067 &m_header, 1068 rel_hdr, 1069 plt_hdr, 1070 sym_hdr, 1071 plt_section_sp, 1072 rel_data, 1073 symtab_data, 1074 strtab_data); 1075 } 1076 1077 Symtab * 1078 ObjectFileELF::GetSymtab() 1079 { 1080 if (m_symtab_ap.get()) 1081 return m_symtab_ap.get(); 1082 1083 Symtab *symbol_table = new Symtab(this); 1084 m_symtab_ap.reset(symbol_table); 1085 1086 Mutex::Locker locker(symbol_table->GetMutex()); 1087 1088 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 1089 return symbol_table; 1090 1091 // Locate and parse all linker symbol tables. 1092 uint64_t symbol_id = 0; 1093 for (SectionHeaderCollIter I = m_section_headers.begin(); 1094 I != m_section_headers.end(); ++I) 1095 { 1096 if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM) 1097 { 1098 const ELFSectionHeader &symtab_header = *I; 1099 user_id_t section_id = SectionIndex(I); 1100 symbol_id += ParseSymbolTable(symbol_table, symbol_id, 1101 &symtab_header, section_id); 1102 } 1103 } 1104 1105 // Synthesize trampoline symbols to help navigate the PLT. 1106 Section *reloc_section = PLTSection(); 1107 if (reloc_section) 1108 { 1109 user_id_t reloc_id = reloc_section->GetID(); 1110 const ELFSectionHeader *reloc_header = GetSectionHeaderByIndex(reloc_id); 1111 assert(reloc_header); 1112 1113 ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id); 1114 } 1115 1116 return symbol_table; 1117 } 1118 1119 //===----------------------------------------------------------------------===// 1120 // Dump 1121 // 1122 // Dump the specifics of the runtime file container (such as any headers 1123 // segments, sections, etc). 1124 //---------------------------------------------------------------------- 1125 void 1126 ObjectFileELF::Dump(Stream *s) 1127 { 1128 DumpELFHeader(s, m_header); 1129 s->EOL(); 1130 DumpELFProgramHeaders(s); 1131 s->EOL(); 1132 DumpELFSectionHeaders(s); 1133 s->EOL(); 1134 SectionList *section_list = GetSectionList(); 1135 if (section_list) 1136 section_list->Dump(s, NULL, true, UINT32_MAX); 1137 Symtab *symtab = GetSymtab(); 1138 if (symtab) 1139 symtab->Dump(s, NULL, eSortOrderNone); 1140 s->EOL(); 1141 DumpDependentModules(s); 1142 s->EOL(); 1143 } 1144 1145 //---------------------------------------------------------------------- 1146 // DumpELFHeader 1147 // 1148 // Dump the ELF header to the specified output stream 1149 //---------------------------------------------------------------------- 1150 void 1151 ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) 1152 { 1153 s->PutCString("ELF Header\n"); 1154 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); 1155 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", 1156 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]); 1157 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", 1158 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]); 1159 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", 1160 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]); 1161 1162 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]); 1163 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]); 1164 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]); 1165 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]); 1166 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]); 1167 1168 s->Printf("e_type = 0x%4.4x ", header.e_type); 1169 DumpELFHeader_e_type(s, header.e_type); 1170 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine); 1171 s->Printf("e_version = 0x%8.8x\n", header.e_version); 1172 s->Printf("e_entry = 0x%8.8llx\n", header.e_entry); 1173 s->Printf("e_phoff = 0x%8.8llx\n", header.e_phoff); 1174 s->Printf("e_shoff = 0x%8.8llx\n", header.e_shoff); 1175 s->Printf("e_flags = 0x%8.8x\n", header.e_flags); 1176 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize); 1177 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize); 1178 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum); 1179 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); 1180 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum); 1181 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx); 1182 } 1183 1184 //---------------------------------------------------------------------- 1185 // DumpELFHeader_e_type 1186 // 1187 // Dump an token value for the ELF header member e_type 1188 //---------------------------------------------------------------------- 1189 void 1190 ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) 1191 { 1192 switch (e_type) 1193 { 1194 case ET_NONE: *s << "ET_NONE"; break; 1195 case ET_REL: *s << "ET_REL"; break; 1196 case ET_EXEC: *s << "ET_EXEC"; break; 1197 case ET_DYN: *s << "ET_DYN"; break; 1198 case ET_CORE: *s << "ET_CORE"; break; 1199 default: 1200 break; 1201 } 1202 } 1203 1204 //---------------------------------------------------------------------- 1205 // DumpELFHeader_e_ident_EI_DATA 1206 // 1207 // Dump an token value for the ELF header member e_ident[EI_DATA] 1208 //---------------------------------------------------------------------- 1209 void 1210 ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data) 1211 { 1212 switch (ei_data) 1213 { 1214 case ELFDATANONE: *s << "ELFDATANONE"; break; 1215 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break; 1216 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break; 1217 default: 1218 break; 1219 } 1220 } 1221 1222 1223 //---------------------------------------------------------------------- 1224 // DumpELFProgramHeader 1225 // 1226 // Dump a single ELF program header to the specified output stream 1227 //---------------------------------------------------------------------- 1228 void 1229 ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph) 1230 { 1231 DumpELFProgramHeader_p_type(s, ph.p_type); 1232 s->Printf(" %8.8llx %8.8llx %8.8llx", ph.p_offset, ph.p_vaddr, ph.p_paddr); 1233 s->Printf(" %8.8llx %8.8llx %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags); 1234 1235 DumpELFProgramHeader_p_flags(s, ph.p_flags); 1236 s->Printf(") %8.8llx", ph.p_align); 1237 } 1238 1239 //---------------------------------------------------------------------- 1240 // DumpELFProgramHeader_p_type 1241 // 1242 // Dump an token value for the ELF program header member p_type which 1243 // describes the type of the program header 1244 // ---------------------------------------------------------------------- 1245 void 1246 ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) 1247 { 1248 const int kStrWidth = 10; 1249 switch (p_type) 1250 { 1251 CASE_AND_STREAM(s, PT_NULL , kStrWidth); 1252 CASE_AND_STREAM(s, PT_LOAD , kStrWidth); 1253 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth); 1254 CASE_AND_STREAM(s, PT_INTERP , kStrWidth); 1255 CASE_AND_STREAM(s, PT_NOTE , kStrWidth); 1256 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth); 1257 CASE_AND_STREAM(s, PT_PHDR , kStrWidth); 1258 default: 1259 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, ""); 1260 break; 1261 } 1262 } 1263 1264 1265 //---------------------------------------------------------------------- 1266 // DumpELFProgramHeader_p_flags 1267 // 1268 // Dump an token value for the ELF program header member p_flags 1269 //---------------------------------------------------------------------- 1270 void 1271 ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) 1272 { 1273 *s << ((p_flags & PF_X) ? "PF_X" : " ") 1274 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') 1275 << ((p_flags & PF_W) ? "PF_W" : " ") 1276 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ') 1277 << ((p_flags & PF_R) ? "PF_R" : " "); 1278 } 1279 1280 //---------------------------------------------------------------------- 1281 // DumpELFProgramHeaders 1282 // 1283 // Dump all of the ELF program header to the specified output stream 1284 //---------------------------------------------------------------------- 1285 void 1286 ObjectFileELF::DumpELFProgramHeaders(Stream *s) 1287 { 1288 if (ParseProgramHeaders()) 1289 { 1290 s->PutCString("Program Headers\n"); 1291 s->PutCString("IDX p_type p_offset p_vaddr p_paddr " 1292 "p_filesz p_memsz p_flags p_align\n"); 1293 s->PutCString("==== ---------- -------- -------- -------- " 1294 "-------- -------- ------------------------- --------\n"); 1295 1296 uint32_t idx = 0; 1297 for (ProgramHeaderCollConstIter I = m_program_headers.begin(); 1298 I != m_program_headers.end(); ++I, ++idx) 1299 { 1300 s->Printf("[%2u] ", idx); 1301 ObjectFileELF::DumpELFProgramHeader(s, *I); 1302 s->EOL(); 1303 } 1304 } 1305 } 1306 1307 //---------------------------------------------------------------------- 1308 // DumpELFSectionHeader 1309 // 1310 // Dump a single ELF section header to the specified output stream 1311 //---------------------------------------------------------------------- 1312 void 1313 ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh) 1314 { 1315 s->Printf("%8.8x ", sh.sh_name); 1316 DumpELFSectionHeader_sh_type(s, sh.sh_type); 1317 s->Printf(" %8.8llx (", sh.sh_flags); 1318 DumpELFSectionHeader_sh_flags(s, sh.sh_flags); 1319 s->Printf(") %8.8llx %8.8llx %8.8llx", sh.sh_addr, sh.sh_offset, sh.sh_size); 1320 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info); 1321 s->Printf(" %8.8llx %8.8llx", sh.sh_addralign, sh.sh_entsize); 1322 } 1323 1324 //---------------------------------------------------------------------- 1325 // DumpELFSectionHeader_sh_type 1326 // 1327 // Dump an token value for the ELF section header member sh_type which 1328 // describes the type of the section 1329 //---------------------------------------------------------------------- 1330 void 1331 ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) 1332 { 1333 const int kStrWidth = 12; 1334 switch (sh_type) 1335 { 1336 CASE_AND_STREAM(s, SHT_NULL , kStrWidth); 1337 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth); 1338 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth); 1339 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth); 1340 CASE_AND_STREAM(s, SHT_RELA , kStrWidth); 1341 CASE_AND_STREAM(s, SHT_HASH , kStrWidth); 1342 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth); 1343 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth); 1344 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth); 1345 CASE_AND_STREAM(s, SHT_REL , kStrWidth); 1346 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth); 1347 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth); 1348 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth); 1349 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth); 1350 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth); 1351 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth); 1352 default: 1353 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, ""); 1354 break; 1355 } 1356 } 1357 1358 //---------------------------------------------------------------------- 1359 // DumpELFSectionHeader_sh_flags 1360 // 1361 // Dump an token value for the ELF section header member sh_flags 1362 //---------------------------------------------------------------------- 1363 void 1364 ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags) 1365 { 1366 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") 1367 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ') 1368 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ") 1369 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ') 1370 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); 1371 } 1372 1373 //---------------------------------------------------------------------- 1374 // DumpELFSectionHeaders 1375 // 1376 // Dump all of the ELF section header to the specified output stream 1377 //---------------------------------------------------------------------- 1378 void 1379 ObjectFileELF::DumpELFSectionHeaders(Stream *s) 1380 { 1381 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 1382 return; 1383 1384 s->PutCString("Section Headers\n"); 1385 s->PutCString("IDX name type flags " 1386 "addr offset size link info addralgn " 1387 "entsize Name\n"); 1388 s->PutCString("==== -------- ------------ -------------------------------- " 1389 "-------- -------- -------- -------- -------- -------- " 1390 "-------- ====================\n"); 1391 1392 uint32_t idx = 0; 1393 for (SectionHeaderCollConstIter I = m_section_headers.begin(); 1394 I != m_section_headers.end(); ++I, ++idx) 1395 { 1396 s->Printf("[%2u] ", idx); 1397 ObjectFileELF::DumpELFSectionHeader(s, *I); 1398 const char* section_name = m_shstr_data.PeekCStr(I->sh_name); 1399 if (section_name) 1400 *s << ' ' << section_name << "\n"; 1401 } 1402 } 1403 1404 void 1405 ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) 1406 { 1407 size_t num_modules = ParseDependentModules(); 1408 1409 if (num_modules > 0) 1410 { 1411 s->PutCString("Dependent Modules:\n"); 1412 for (unsigned i = 0; i < num_modules; ++i) 1413 { 1414 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i); 1415 s->Printf(" %s\n", spec.GetFilename().GetCString()); 1416 } 1417 } 1418 } 1419 1420 bool 1421 ObjectFileELF::GetArchitecture (ArchSpec &arch) 1422 { 1423 if (!ParseHeader()) 1424 return false; 1425 1426 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE); 1427 arch.GetTriple().setOSName (Host::GetOSString().GetCString()); 1428 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString()); 1429 return true; 1430 } 1431 1432 ObjectFile::Type 1433 ObjectFileELF::CalculateType() 1434 { 1435 switch (m_header.e_type) 1436 { 1437 case llvm::ELF::ET_NONE: 1438 // 0 - No file type 1439 return eTypeUnknown; 1440 1441 case llvm::ELF::ET_REL: 1442 // 1 - Relocatable file 1443 return eTypeObjectFile; 1444 1445 case llvm::ELF::ET_EXEC: 1446 // 2 - Executable file 1447 return eTypeExecutable; 1448 1449 case llvm::ELF::ET_DYN: 1450 // 3 - Shared object file 1451 return eTypeSharedLibrary; 1452 1453 case ET_CORE: 1454 // 4 - Core file 1455 return eTypeCoreFile; 1456 1457 default: 1458 break; 1459 } 1460 return eTypeUnknown; 1461 } 1462 1463 ObjectFile::Strata 1464 ObjectFileELF::CalculateStrata() 1465 { 1466 switch (m_header.e_type) 1467 { 1468 case llvm::ELF::ET_NONE: 1469 // 0 - No file type 1470 return eStrataUnknown; 1471 1472 case llvm::ELF::ET_REL: 1473 // 1 - Relocatable file 1474 return eStrataUnknown; 1475 1476 case llvm::ELF::ET_EXEC: 1477 // 2 - Executable file 1478 // TODO: is there any way to detect that an executable is a kernel 1479 // related executable by inspecting the program headers, section 1480 // headers, symbols, or any other flag bits??? 1481 return eStrataUser; 1482 1483 case llvm::ELF::ET_DYN: 1484 // 3 - Shared object file 1485 // TODO: is there any way to detect that an shared library is a kernel 1486 // related executable by inspecting the program headers, section 1487 // headers, symbols, or any other flag bits??? 1488 return eStrataUnknown; 1489 1490 case ET_CORE: 1491 // 4 - Core file 1492 // TODO: is there any way to detect that an core file is a kernel 1493 // related executable by inspecting the program headers, section 1494 // headers, symbols, or any other flag bits??? 1495 return eStrataUnknown; 1496 1497 default: 1498 break; 1499 } 1500 return eStrataUnknown; 1501 } 1502 1503