ObjectFileELF.cpp revision cd298d8af1dce57282b6d7635896ea297255f776
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/PluginManager.h" 20#include "lldb/Core/Section.h" 21#include "lldb/Core/Stream.h" 22 23#define CASE_AND_STREAM(s, def, width) \ 24 case def: s->Printf("%-*s", width, #def); break; 25 26using namespace lldb; 27using namespace lldb_private; 28using namespace elf; 29using namespace llvm::ELF; 30 31//------------------------------------------------------------------ 32// Static methods. 33//------------------------------------------------------------------ 34void 35ObjectFileELF::Initialize() 36{ 37 PluginManager::RegisterPlugin(GetPluginNameStatic(), 38 GetPluginDescriptionStatic(), 39 CreateInstance); 40} 41 42void 43ObjectFileELF::Terminate() 44{ 45 PluginManager::UnregisterPlugin(CreateInstance); 46} 47 48const char * 49ObjectFileELF::GetPluginNameStatic() 50{ 51 return "object-file.elf"; 52} 53 54const char * 55ObjectFileELF::GetPluginDescriptionStatic() 56{ 57 return "ELF object file reader."; 58} 59 60ObjectFile * 61ObjectFileELF::CreateInstance(Module *module, 62 DataBufferSP &data_sp, 63 const FileSpec *file, addr_t offset, 64 addr_t length) 65{ 66 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + offset)) 67 { 68 const uint8_t *magic = data_sp->GetBytes() + offset; 69 if (ELFHeader::MagicBytesMatch(magic)) 70 { 71 unsigned address_size = ELFHeader::AddressSizeInBytes(magic); 72 if (address_size == 4 || address_size == 8) 73 { 74 std::auto_ptr<ObjectFileELF> objfile_ap( 75 new ObjectFileELF(module, data_sp, file, offset, length)); 76 ArchSpec spec = objfile_ap->GetArchitecture(); 77 if (spec.IsValid() && objfile_ap->SetModulesArchitecture(spec)) 78 return objfile_ap.release(); 79 } 80 } 81 } 82 return NULL; 83} 84 85ArchSpec 86ObjectFileELF::GetArchitecture() 87{ 88 if (!ParseHeader()) 89 return ArchSpec(); 90 91 return ArchSpec(eArchTypeELF, m_header.e_machine, m_header.e_flags); 92} 93 94//------------------------------------------------------------------ 95// PluginInterface protocol 96//------------------------------------------------------------------ 97const char * 98ObjectFileELF::GetPluginName() 99{ 100 return "ObjectFileELF"; 101} 102 103const char * 104ObjectFileELF::GetShortPluginName() 105{ 106 return GetPluginNameStatic(); 107} 108 109uint32_t 110ObjectFileELF::GetPluginVersion() 111{ 112 return m_plugin_version; 113} 114 115void 116ObjectFileELF::GetPluginCommandHelp(const char *command, Stream *strm) 117{ 118} 119 120Error 121ObjectFileELF::ExecutePluginCommand(Args &command, Stream *strm) 122{ 123 Error error; 124 error.SetErrorString("No plug-in commands are currently supported."); 125 return error; 126} 127 128Log * 129ObjectFileELF::EnablePluginLogging(Stream *strm, Args &command) 130{ 131 return NULL; 132} 133 134//------------------------------------------------------------------ 135// ObjectFile protocol 136//------------------------------------------------------------------ 137 138ObjectFileELF::ObjectFileELF(Module* module, DataBufferSP& dataSP, 139 const FileSpec* file, addr_t offset, 140 addr_t length) 141 : ObjectFile(module, file, offset, length, dataSP), 142 m_header(), 143 m_program_headers(), 144 m_section_headers(), 145 m_sections_ap(), 146 m_symtab_ap(), 147 m_filespec_ap(), 148 m_shstr_data() 149{ 150 if (file) 151 m_file = *file; 152 ::memset(&m_header, 0, sizeof(m_header)); 153} 154 155ObjectFileELF::~ObjectFileELF() 156{ 157} 158 159bool 160ObjectFileELF::IsExecutable() const 161{ 162 return m_header.e_entry != 0; 163} 164 165Address 166ObjectFileELF::GetEntryPoint() const 167{ 168 if (m_header.e_entry) 169 return Address(NULL, m_header.e_entry); 170 else 171 return Address(); 172} 173 174ByteOrder 175ObjectFileELF::GetByteOrder() const 176{ 177 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB) 178 return eByteOrderBig; 179 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB) 180 return eByteOrderLittle; 181 return eByteOrderInvalid; 182} 183 184size_t 185ObjectFileELF::GetAddressByteSize() const 186{ 187 return m_data.GetAddressByteSize(); 188} 189 190unsigned 191ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) 192{ 193 return std::distance(m_section_headers.begin(), I) + 1; 194} 195 196unsigned 197ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const 198{ 199 return std::distance(m_section_headers.begin(), I) + 1; 200} 201 202bool 203ObjectFileELF::ParseHeader() 204{ 205 uint32_t offset = GetOffset(); 206 return m_header.Parse(m_data, &offset); 207} 208 209bool 210ObjectFileELF::GetUUID(lldb_private::UUID* uuid) 211{ 212 // FIXME: Return MD5 sum here. See comment in ObjectFile.h. 213 return false; 214} 215 216uint32_t 217ObjectFileELF::GetDependentModules(FileSpecList &files) 218{ 219 size_t num_modules = ParseDependentModules(); 220 uint32_t num_specs = 0; 221 222 for (unsigned i = 0; i < num_modules; ++i) 223 { 224 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i))) 225 num_specs++; 226 } 227 228 return num_specs; 229} 230 231Address 232ObjectFileELF::GetImageInfoAddress() 233{ 234 if (!ParseSectionHeaders()) 235 return Address(); 236 237 user_id_t dynsym_id = 0; 238 for (SectionHeaderCollIter sh_pos = m_section_headers.begin(); 239 sh_pos != m_section_headers.end(); ++sh_pos) 240 { 241 if (sh_pos->sh_type == SHT_DYNAMIC) 242 { 243 dynsym_id = SectionIndex(sh_pos); 244 break; 245 } 246 } 247 248 if (!dynsym_id) 249 return Address(); 250 251 SectionList *section_list = GetSectionList(); 252 if (!section_list) 253 return Address(); 254 255 // Resolve the dynamic table entries. 256 Section *dynsym = section_list->FindSectionByID(dynsym_id).get(); 257 if (!dynsym) 258 return Address(); 259 260 DataExtractor dynsym_data; 261 if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data)) 262 { 263 ELFDynamic symbol; 264 const unsigned section_size = dynsym_data.GetByteSize(); 265 unsigned offset = 0; 266 unsigned cursor = 0; 267 268 // Look for a DT_DEBUG entry. 269 while (cursor < section_size) 270 { 271 offset = cursor; 272 if (!symbol.Parse(dynsym_data, &cursor)) 273 break; 274 275 if (symbol.d_tag != DT_DEBUG) 276 continue; 277 278 return Address(dynsym, offset + sizeof(symbol.d_tag)); 279 } 280 } 281 282 return Address(); 283} 284 285//---------------------------------------------------------------------- 286// ParseDependentModules 287//---------------------------------------------------------------------- 288size_t 289ObjectFileELF::ParseDependentModules() 290{ 291 if (m_filespec_ap.get()) 292 return m_filespec_ap->GetSize(); 293 294 m_filespec_ap.reset(new FileSpecList()); 295 296 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 297 return 0; 298 299 // Locate the dynamic table. 300 user_id_t dynsym_id = 0; 301 user_id_t dynstr_id = 0; 302 for (SectionHeaderCollIter sh_pos = m_section_headers.begin(); 303 sh_pos != m_section_headers.end(); ++sh_pos) 304 { 305 if (sh_pos->sh_type == SHT_DYNAMIC) 306 { 307 dynsym_id = SectionIndex(sh_pos); 308 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based. 309 break; 310 } 311 } 312 313 if (!(dynsym_id && dynstr_id)) 314 return 0; 315 316 SectionList *section_list = GetSectionList(); 317 if (!section_list) 318 return 0; 319 320 // Resolve and load the dynamic table entries and corresponding string 321 // table. 322 Section *dynsym = section_list->FindSectionByID(dynsym_id).get(); 323 Section *dynstr = section_list->FindSectionByID(dynstr_id).get(); 324 if (!(dynsym && dynstr)) 325 return 0; 326 327 DataExtractor dynsym_data; 328 DataExtractor dynstr_data; 329 if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data) && 330 dynstr->ReadSectionDataFromObjectFile(this, dynstr_data)) 331 { 332 ELFDynamic symbol; 333 const unsigned section_size = dynsym_data.GetByteSize(); 334 unsigned offset = 0; 335 336 // The only type of entries we are concerned with are tagged DT_NEEDED, 337 // yielding the name of a required library. 338 while (offset < section_size) 339 { 340 if (!symbol.Parse(dynsym_data, &offset)) 341 break; 342 343 if (symbol.d_tag != DT_NEEDED) 344 continue; 345 346 uint32_t str_index = static_cast<uint32_t>(symbol.d_val); 347 const char *lib_name = dynstr_data.PeekCStr(str_index); 348 m_filespec_ap->Append(FileSpec(lib_name, true)); 349 } 350 } 351 352 return m_filespec_ap->GetSize(); 353} 354 355//---------------------------------------------------------------------- 356// ParseProgramHeaders 357//---------------------------------------------------------------------- 358size_t 359ObjectFileELF::ParseProgramHeaders() 360{ 361 // We have already parsed the program headers 362 if (!m_program_headers.empty()) 363 return m_program_headers.size(); 364 365 // If there are no program headers to read we are done. 366 if (m_header.e_phnum == 0) 367 return 0; 368 369 m_program_headers.resize(m_header.e_phnum); 370 if (m_program_headers.size() != m_header.e_phnum) 371 return 0; 372 373 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize; 374 const elf_off ph_offset = m_offset + m_header.e_phoff; 375 DataBufferSP buffer_sp(m_file.ReadFileContents(ph_offset, ph_size)); 376 377 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != ph_size) 378 return 0; 379 380 DataExtractor data(buffer_sp, m_data.GetByteOrder(), 381 m_data.GetAddressByteSize()); 382 383 uint32_t idx; 384 uint32_t offset; 385 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx) 386 { 387 if (m_program_headers[idx].Parse(data, &offset) == false) 388 break; 389 } 390 391 if (idx < m_program_headers.size()) 392 m_program_headers.resize(idx); 393 394 return m_program_headers.size(); 395} 396 397//---------------------------------------------------------------------- 398// ParseSectionHeaders 399//---------------------------------------------------------------------- 400size_t 401ObjectFileELF::ParseSectionHeaders() 402{ 403 // We have already parsed the section headers 404 if (!m_section_headers.empty()) 405 return m_section_headers.size(); 406 407 // If there are no section headers we are done. 408 if (m_header.e_shnum == 0) 409 return 0; 410 411 m_section_headers.resize(m_header.e_shnum); 412 if (m_section_headers.size() != m_header.e_shnum) 413 return 0; 414 415 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize; 416 const elf_off sh_offset = m_offset + m_header.e_shoff; 417 DataBufferSP buffer_sp(m_file.ReadFileContents(sh_offset, sh_size)); 418 419 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != sh_size) 420 return 0; 421 422 DataExtractor data(buffer_sp, 423 m_data.GetByteOrder(), 424 m_data.GetAddressByteSize()); 425 426 uint32_t idx; 427 uint32_t offset; 428 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx) 429 { 430 if (m_section_headers[idx].Parse(data, &offset) == false) 431 break; 432 } 433 if (idx < m_section_headers.size()) 434 m_section_headers.resize(idx); 435 436 return m_section_headers.size(); 437} 438 439size_t 440ObjectFileELF::GetSectionHeaderStringTable() 441{ 442 if (m_shstr_data.GetByteSize() == 0) 443 { 444 const unsigned strtab_idx = m_header.e_shstrndx; 445 446 if (strtab_idx && strtab_idx < m_section_headers.size()) 447 { 448 const ELFSectionHeader &sheader = m_section_headers[strtab_idx]; 449 const size_t byte_size = sheader.sh_size; 450 const Elf64_Off offset = m_offset + sheader.sh_offset; 451 DataBufferSP buffer_sp(m_file.ReadFileContents(offset, byte_size)); 452 453 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size) 454 return 0; 455 456 m_shstr_data.SetData(buffer_sp); 457 } 458 } 459 return m_shstr_data.GetByteSize(); 460} 461 462lldb::user_id_t 463ObjectFileELF::GetSectionIndexByName(const char *name) 464{ 465 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 466 return 0; 467 468 // Search the collection of section headers for one with a matching name. 469 for (SectionHeaderCollIter I = m_section_headers.begin(); 470 I != m_section_headers.end(); ++I) 471 { 472 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name); 473 474 if (!sectionName) 475 return 0; 476 477 if (strcmp(name, sectionName) != 0) 478 continue; 479 480 return SectionIndex(I); 481 } 482 483 return 0; 484} 485 486SectionList * 487ObjectFileELF::GetSectionList() 488{ 489 if (m_sections_ap.get()) 490 return m_sections_ap.get(); 491 492 if (ParseSectionHeaders() && GetSectionHeaderStringTable()) 493 { 494 m_sections_ap.reset(new SectionList()); 495 496 for (SectionHeaderCollIter I = m_section_headers.begin(); 497 I != m_section_headers.end(); ++I) 498 { 499 const ELFSectionHeader &header = *I; 500 501 ConstString name(m_shstr_data.PeekCStr(header.sh_name)); 502 uint64_t size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size; 503 504 static ConstString g_sect_name_text (".text"); 505 static ConstString g_sect_name_data (".data"); 506 static ConstString g_sect_name_bss (".bss"); 507 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev"); 508 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges"); 509 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame"); 510 static ConstString g_sect_name_dwarf_debug_info (".debug_info"); 511 static ConstString g_sect_name_dwarf_debug_line (".debug_line"); 512 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc"); 513 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo"); 514 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames"); 515 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes"); 516 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges"); 517 static ConstString g_sect_name_dwarf_debug_str (".debug_str"); 518 static ConstString g_sect_name_eh_frame (".eh_frame"); 519 520 SectionType sect_type = eSectionTypeOther; 521 522 if (name == g_sect_name_text) sect_type = eSectionTypeCode; 523 else if (name == g_sect_name_data) sect_type = eSectionTypeData; 524 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill; 525 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev; 526 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges; 527 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame; 528 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo; 529 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine; 530 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc; 531 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo; 532 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames; 533 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes; 534 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges; 535 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr; 536 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame; 537 538 539 SectionSP section(new Section( 540 0, // Parent section. 541 GetModule(), // Module to which this section belongs. 542 SectionIndex(I), // Section ID. 543 name, // Section name. 544 sect_type, // Section type. 545 header.sh_addr, // VM address. 546 header.sh_size, // VM size in bytes of this section. 547 header.sh_offset, // Offset of this section in the file. 548 size, // Size of the section as found in the file. 549 header.sh_flags)); // Flags for this section. 550 551 m_sections_ap->AddSection(section); 552 } 553 } 554 555 return m_sections_ap.get(); 556} 557 558static void 559ParseSymbols(Symtab *symtab, SectionList *section_list, 560 const ELFSectionHeader &symtab_shdr, 561 const DataExtractor &symtab_data, 562 const DataExtractor &strtab_data) 563{ 564 ELFSymbol symbol; 565 uint32_t offset = 0; 566 const unsigned numSymbols = 567 symtab_data.GetByteSize() / symtab_shdr.sh_entsize; 568 569 static ConstString text_section_name(".text"); 570 static ConstString init_section_name(".init"); 571 static ConstString fini_section_name(".fini"); 572 static ConstString ctors_section_name(".ctors"); 573 static ConstString dtors_section_name(".dtors"); 574 575 static ConstString data_section_name(".data"); 576 static ConstString rodata_section_name(".rodata"); 577 static ConstString rodata1_section_name(".rodata1"); 578 static ConstString data2_section_name(".data1"); 579 static ConstString bss_section_name(".bss"); 580 581 for (unsigned i = 0; i < numSymbols; ++i) 582 { 583 if (symbol.Parse(symtab_data, &offset) == false) 584 break; 585 586 Section *symbol_section = NULL; 587 SymbolType symbol_type = eSymbolTypeInvalid; 588 Elf64_Half symbol_idx = symbol.st_shndx; 589 590 switch (symbol_idx) 591 { 592 case SHN_ABS: 593 symbol_type = eSymbolTypeAbsolute; 594 break; 595 case SHN_UNDEF: 596 symbol_type = eSymbolTypeUndefined; 597 break; 598 default: 599 symbol_section = section_list->GetSectionAtIndex(symbol_idx).get(); 600 break; 601 } 602 603 switch (symbol.getType()) 604 { 605 default: 606 case STT_NOTYPE: 607 // The symbol's type is not specified. 608 break; 609 610 case STT_OBJECT: 611 // The symbol is associated with a data object, such as a variable, 612 // an array, etc. 613 symbol_type = eSymbolTypeData; 614 break; 615 616 case STT_FUNC: 617 // The symbol is associated with a function or other executable code. 618 symbol_type = eSymbolTypeCode; 619 break; 620 621 case STT_SECTION: 622 // The symbol is associated with a section. Symbol table entries of 623 // this type exist primarily for relocation and normally have 624 // STB_LOCAL binding. 625 break; 626 627 case STT_FILE: 628 // Conventionally, the symbol's name gives the name of the source 629 // file associated with the object file. A file symbol has STB_LOCAL 630 // binding, its section index is SHN_ABS, and it precedes the other 631 // STB_LOCAL symbols for the file, if it is present. 632 symbol_type = eSymbolTypeObjectFile; 633 break; 634 } 635 636 if (symbol_type == eSymbolTypeInvalid) 637 { 638 if (symbol_section) 639 { 640 const ConstString §_name = symbol_section->GetName(); 641 if (sect_name == text_section_name || 642 sect_name == init_section_name || 643 sect_name == fini_section_name || 644 sect_name == ctors_section_name || 645 sect_name == dtors_section_name) 646 { 647 symbol_type = eSymbolTypeCode; 648 } 649 else if (sect_name == data_section_name || 650 sect_name == data2_section_name || 651 sect_name == rodata_section_name || 652 sect_name == rodata1_section_name || 653 sect_name == bss_section_name) 654 { 655 symbol_type = eSymbolTypeData; 656 } 657 } 658 } 659 660 uint64_t symbol_value = symbol.st_value; 661 if (symbol_section != NULL) 662 symbol_value -= symbol_section->GetFileAddress(); 663 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 664 bool is_global = symbol.getBinding() == STB_GLOBAL; 665 uint32_t flags = symbol.st_other << 8 | symbol.st_info; 666 667 Symbol dc_symbol( 668 i, // ID is the original symbol table index. 669 symbol_name, // Symbol name. 670 false, // Is the symbol name mangled? 671 symbol_type, // Type of this symbol 672 is_global, // Is this globally visible? 673 false, // Is this symbol debug info? 674 false, // Is this symbol a trampoline? 675 false, // Is this symbol artificial? 676 symbol_section, // Section in which this symbol is defined or null. 677 symbol_value, // Offset in section or symbol value. 678 symbol.st_size, // Size in bytes of this symbol. 679 flags); // Symbol flags. 680 symtab->AddSymbol(dc_symbol); 681 } 682} 683 684void 685ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, 686 const ELFSectionHeader &symtab_hdr, 687 user_id_t symtab_id) 688{ 689 assert(symtab_hdr.sh_type == SHT_SYMTAB || 690 symtab_hdr.sh_type == SHT_DYNSYM); 691 692 // Parse in the section list if needed. 693 SectionList *section_list = GetSectionList(); 694 if (!section_list) 695 return; 696 697 // Section ID's are ones based. 698 user_id_t strtab_id = symtab_hdr.sh_link + 1; 699 700 Section *symtab = section_list->FindSectionByID(symtab_id).get(); 701 Section *strtab = section_list->FindSectionByID(strtab_id).get(); 702 if (symtab && strtab) 703 { 704 DataExtractor symtab_data; 705 DataExtractor strtab_data; 706 if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) && 707 strtab->ReadSectionDataFromObjectFile(this, strtab_data)) 708 { 709 ParseSymbols(symbol_table, section_list, symtab_hdr, 710 symtab_data, strtab_data); 711 } 712 } 713} 714 715Symtab * 716ObjectFileELF::GetSymtab() 717{ 718 if (m_symtab_ap.get()) 719 return m_symtab_ap.get(); 720 721 Symtab *symbol_table = new Symtab(this); 722 m_symtab_ap.reset(symbol_table); 723 724 Mutex::Locker locker (symbol_table->GetMutex ()); 725 726 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 727 return symbol_table; 728 729 // Locate and parse all linker symbol tables. 730 for (SectionHeaderCollIter I = m_section_headers.begin(); 731 I != m_section_headers.end(); ++I) 732 { 733 if (I->sh_type == SHT_SYMTAB) 734 { 735 const ELFSectionHeader &symtab_section = *I; 736 user_id_t section_id = SectionIndex(I); 737 ParseSymbolTable (symbol_table, symtab_section, section_id); 738 } 739 } 740 741 return symbol_table; 742} 743 744//===----------------------------------------------------------------------===// 745// Dump 746// 747// Dump the specifics of the runtime file container (such as any headers 748// segments, sections, etc). 749//---------------------------------------------------------------------- 750void 751ObjectFileELF::Dump(Stream *s) 752{ 753 DumpELFHeader(s, m_header); 754 s->EOL(); 755 DumpELFProgramHeaders(s); 756 s->EOL(); 757 DumpELFSectionHeaders(s); 758 s->EOL(); 759 SectionList *section_list = GetSectionList(); 760 if (section_list) 761 section_list->Dump(s, NULL, true, UINT32_MAX); 762 Symtab *symtab = GetSymtab(); 763 if (symtab) 764 symtab->Dump(s, NULL, lldb::eSortOrderNone); 765 s->EOL(); 766 DumpDependentModules(s); 767 s->EOL(); 768} 769 770//---------------------------------------------------------------------- 771// DumpELFHeader 772// 773// Dump the ELF header to the specified output stream 774//---------------------------------------------------------------------- 775void 776ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) 777{ 778 s->PutCString("ELF Header\n"); 779 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); 780 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", 781 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]); 782 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", 783 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]); 784 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", 785 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]); 786 787 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]); 788 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]); 789 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]); 790 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]); 791 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]); 792 793 s->Printf("e_type = 0x%4.4x ", header.e_type); 794 DumpELFHeader_e_type(s, header.e_type); 795 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine); 796 s->Printf("e_version = 0x%8.8x\n", header.e_version); 797 s->Printf("e_entry = 0x%8.8lx\n", header.e_entry); 798 s->Printf("e_phoff = 0x%8.8lx\n", header.e_phoff); 799 s->Printf("e_shoff = 0x%8.8lx\n", header.e_shoff); 800 s->Printf("e_flags = 0x%8.8x\n", header.e_flags); 801 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize); 802 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize); 803 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum); 804 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); 805 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum); 806 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx); 807} 808 809//---------------------------------------------------------------------- 810// DumpELFHeader_e_type 811// 812// Dump an token value for the ELF header member e_type 813//---------------------------------------------------------------------- 814void 815ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) 816{ 817 switch (e_type) 818 { 819 case ET_NONE: *s << "ET_NONE"; break; 820 case ET_REL: *s << "ET_REL"; break; 821 case ET_EXEC: *s << "ET_EXEC"; break; 822 case ET_DYN: *s << "ET_DYN"; break; 823 case ET_CORE: *s << "ET_CORE"; break; 824 default: 825 break; 826 } 827} 828 829//---------------------------------------------------------------------- 830// DumpELFHeader_e_ident_EI_DATA 831// 832// Dump an token value for the ELF header member e_ident[EI_DATA] 833//---------------------------------------------------------------------- 834void 835ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data) 836{ 837 switch (ei_data) 838 { 839 case ELFDATANONE: *s << "ELFDATANONE"; break; 840 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break; 841 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break; 842 default: 843 break; 844 } 845} 846 847 848//---------------------------------------------------------------------- 849// DumpELFProgramHeader 850// 851// Dump a single ELF program header to the specified output stream 852//---------------------------------------------------------------------- 853void 854ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph) 855{ 856 DumpELFProgramHeader_p_type(s, ph.p_type); 857 s->Printf(" %8.8lx %8.8lx %8.8lx", ph.p_offset, ph.p_vaddr, ph.p_paddr); 858 s->Printf(" %8.8lx %8.8lx %8.8lx (", ph.p_filesz, ph.p_memsz, ph.p_flags); 859 860 DumpELFProgramHeader_p_flags(s, ph.p_flags); 861 s->Printf(") %8.8x", ph.p_align); 862} 863 864//---------------------------------------------------------------------- 865// DumpELFProgramHeader_p_type 866// 867// Dump an token value for the ELF program header member p_type which 868// describes the type of the program header 869// ---------------------------------------------------------------------- 870void 871ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) 872{ 873 const int kStrWidth = 10; 874 switch (p_type) 875 { 876 CASE_AND_STREAM(s, PT_NULL , kStrWidth); 877 CASE_AND_STREAM(s, PT_LOAD , kStrWidth); 878 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth); 879 CASE_AND_STREAM(s, PT_INTERP , kStrWidth); 880 CASE_AND_STREAM(s, PT_NOTE , kStrWidth); 881 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth); 882 CASE_AND_STREAM(s, PT_PHDR , kStrWidth); 883 default: 884 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, ""); 885 break; 886 } 887} 888 889 890//---------------------------------------------------------------------- 891// DumpELFProgramHeader_p_flags 892// 893// Dump an token value for the ELF program header member p_flags 894//---------------------------------------------------------------------- 895void 896ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) 897{ 898 *s << ((p_flags & PF_X) ? "PF_X" : " ") 899 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') 900 << ((p_flags & PF_W) ? "PF_W" : " ") 901 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ') 902 << ((p_flags & PF_R) ? "PF_R" : " "); 903} 904 905//---------------------------------------------------------------------- 906// DumpELFProgramHeaders 907// 908// Dump all of the ELF program header to the specified output stream 909//---------------------------------------------------------------------- 910void 911ObjectFileELF::DumpELFProgramHeaders(Stream *s) 912{ 913 if (ParseProgramHeaders()) 914 { 915 s->PutCString("Program Headers\n"); 916 s->PutCString("IDX p_type p_offset p_vaddr p_paddr " 917 "p_filesz p_memsz p_flags p_align\n"); 918 s->PutCString("==== ---------- -------- -------- -------- " 919 "-------- -------- ------------------------- --------\n"); 920 921 uint32_t idx = 0; 922 for (ProgramHeaderCollConstIter I = m_program_headers.begin(); 923 I != m_program_headers.end(); ++I, ++idx) 924 { 925 s->Printf("[%2u] ", idx); 926 ObjectFileELF::DumpELFProgramHeader(s, *I); 927 s->EOL(); 928 } 929 } 930} 931 932//---------------------------------------------------------------------- 933// DumpELFSectionHeader 934// 935// Dump a single ELF section header to the specified output stream 936//---------------------------------------------------------------------- 937void 938ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh) 939{ 940 s->Printf("%8.8x ", sh.sh_name); 941 DumpELFSectionHeader_sh_type(s, sh.sh_type); 942 s->Printf(" %8.8lx (", sh.sh_flags); 943 DumpELFSectionHeader_sh_flags(s, sh.sh_flags); 944 s->Printf(") %8.8lx %8.8lx %8.8lx", sh.sh_addr, sh.sh_offset, sh.sh_size); 945 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info); 946 s->Printf(" %8.8lx %8.8lx", sh.sh_addralign, sh.sh_entsize); 947} 948 949//---------------------------------------------------------------------- 950// DumpELFSectionHeader_sh_type 951// 952// Dump an token value for the ELF section header member sh_type which 953// describes the type of the section 954//---------------------------------------------------------------------- 955void 956ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) 957{ 958 const int kStrWidth = 12; 959 switch (sh_type) 960 { 961 CASE_AND_STREAM(s, SHT_NULL , kStrWidth); 962 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth); 963 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth); 964 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth); 965 CASE_AND_STREAM(s, SHT_RELA , kStrWidth); 966 CASE_AND_STREAM(s, SHT_HASH , kStrWidth); 967 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth); 968 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth); 969 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth); 970 CASE_AND_STREAM(s, SHT_REL , kStrWidth); 971 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth); 972 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth); 973 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth); 974 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth); 975 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth); 976 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth); 977 default: 978 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, ""); 979 break; 980 } 981} 982 983//---------------------------------------------------------------------- 984// DumpELFSectionHeader_sh_flags 985// 986// Dump an token value for the ELF section header member sh_flags 987//---------------------------------------------------------------------- 988void 989ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags) 990{ 991 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") 992 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ') 993 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ") 994 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ') 995 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); 996} 997 998//---------------------------------------------------------------------- 999// DumpELFSectionHeaders 1000// 1001// Dump all of the ELF section header to the specified output stream 1002//---------------------------------------------------------------------- 1003void 1004ObjectFileELF::DumpELFSectionHeaders(Stream *s) 1005{ 1006 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 1007 return; 1008 1009 s->PutCString("Section Headers\n"); 1010 s->PutCString("IDX name type flags " 1011 "addr offset size link info addralgn " 1012 "entsize Name\n"); 1013 s->PutCString("==== -------- ------------ -------------------------------- " 1014 "-------- -------- -------- -------- -------- -------- " 1015 "-------- ====================\n"); 1016 1017 uint32_t idx = 0; 1018 for (SectionHeaderCollConstIter I = m_section_headers.begin(); 1019 I != m_section_headers.end(); ++I, ++idx) 1020 { 1021 s->Printf("[%2u] ", idx); 1022 ObjectFileELF::DumpELFSectionHeader(s, *I); 1023 const char* section_name = m_shstr_data.PeekCStr(I->sh_name); 1024 if (section_name) 1025 *s << ' ' << section_name << "\n"; 1026 } 1027} 1028 1029void 1030ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) 1031{ 1032 size_t num_modules = ParseDependentModules(); 1033 1034 if (num_modules > 0) 1035 { 1036 s->PutCString("Dependent Modules:\n"); 1037 for (unsigned i = 0; i < num_modules; ++i) 1038 { 1039 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i); 1040 s->Printf(" %s\n", spec.GetFilename().GetCString()); 1041 } 1042 } 1043} 1044 1045bool 1046ObjectFileELF::GetArchitecture (ArchSpec &arch) 1047{ 1048 switch (m_header.e_machine) 1049 { 1050 default: 1051 assert(false && "Unexpected machine type."); 1052 break; 1053 case EM_SPARC: arch.GetTriple().setArchName("sparc"); break; 1054 case EM_386: arch.GetTriple().setArchName("i386"); break; 1055 case EM_68K: arch.GetTriple().setArchName("68k"); break; 1056 case EM_88K: arch.GetTriple().setArchName("88k"); break; 1057 case EM_860: arch.GetTriple().setArchName("i860"); break; 1058 case EM_MIPS: arch.GetTriple().setArchName("mips"); break; 1059 case EM_PPC: arch.GetTriple().setArchName("powerpc"); break; 1060 case EM_PPC64: arch.GetTriple().setArchName("powerpc64"); break; 1061 case EM_ARM: arch.GetTriple().setArchName("arm"); break; 1062 case EM_X86_64: arch.GetTriple().setArchName("x86_64"); break; 1063 } 1064 // TODO: determine if there is a vendor in the ELF? Default to "linux" for now 1065 arch.GetTriple().setOSName ("linux"); 1066 // TODO: determine if there is an OS in the ELF? Default to "gnu" for now 1067 arch.GetTriple().setVendorName("gnu"); 1068 1069 arch.SetElfArch(m_header.e_machine, m_header.e_flags); 1070 return true; 1071} 1072 1073