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