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