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