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