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