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 25 using namespace lldb; 26 using namespace lldb_private; 27 using namespace elf; 28 using namespace llvm::ELF; 29 30 //------------------------------------------------------------------ 31 // Static methods. 32 //------------------------------------------------------------------ 33 void 34 ObjectFileELF::Initialize() 35 { 36 PluginManager::RegisterPlugin(GetPluginNameStatic(), 37 GetPluginDescriptionStatic(), 38 CreateInstance); 39 } 40 41 void 42 ObjectFileELF::Terminate() 43 { 44 PluginManager::UnregisterPlugin(CreateInstance); 45 } 46 47 const char * 48 ObjectFileELF::GetPluginNameStatic() 49 { 50 return "object-file.elf"; 51 } 52 53 const char * 54 ObjectFileELF::GetPluginDescriptionStatic() 55 { 56 return "ELF object file reader."; 57 } 58 59 ObjectFile * 60 ObjectFileELF::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 //------------------------------------------------------------------ 86 const char * 87 ObjectFileELF::GetPluginName() 88 { 89 return "ObjectFileELF"; 90 } 91 92 const char * 93 ObjectFileELF::GetShortPluginName() 94 { 95 return GetPluginNameStatic(); 96 } 97 98 uint32_t 99 ObjectFileELF::GetPluginVersion() 100 { 101 return m_plugin_version; 102 } 103 104 void 105 ObjectFileELF::GetPluginCommandHelp(const char *command, Stream *strm) 106 { 107 } 108 109 Error 110 ObjectFileELF::ExecutePluginCommand(Args &command, Stream *strm) 111 { 112 Error error; 113 error.SetErrorString("No plug-in commands are currently supported."); 114 return error; 115 } 116 117 Log * 118 ObjectFileELF::EnablePluginLogging(Stream *strm, Args &command) 119 { 120 return NULL; 121 } 122 123 //------------------------------------------------------------------ 124 // ObjectFile protocol 125 //------------------------------------------------------------------ 126 127 ObjectFileELF::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 144 ObjectFileELF::~ObjectFileELF() 145 { 146 } 147 148 ByteOrder 149 ObjectFileELF::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 158 size_t 159 ObjectFileELF::GetAddressByteSize() const 160 { 161 return m_data.GetAddressByteSize(); 162 } 163 164 unsigned 165 ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) 166 { 167 return std::distance(m_section_headers.begin(), I) + 1; 168 } 169 170 unsigned 171 ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const 172 { 173 return std::distance(m_section_headers.begin(), I) + 1; 174 } 175 176 bool 177 ObjectFileELF::ParseHeader() 178 { 179 uint32_t offset = GetOffset(); 180 return m_header.Parse(m_data, &offset); 181 } 182 183 bool 184 ObjectFileELF::GetUUID(UUID* uuid) 185 { 186 // FIXME: Return MD5 sum here. See comment in ObjectFile.h. 187 return false; 188 } 189 190 uint32_t 191 ObjectFileELF::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 //---------------------------------------------------------------------- 208 size_t 209 ObjectFileELF::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 //---------------------------------------------------------------------- 278 size_t 279 ObjectFileELF::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 //---------------------------------------------------------------------- 320 size_t 321 ObjectFileELF::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 359 size_t 360 ObjectFileELF::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 382 lldb::user_id_t 383 ObjectFileELF::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 406 SectionList * 407 ObjectFileELF::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 SectionSP section(new Section( 425 0, // Parent section. 426 GetModule(), // Module to which this section belongs. 427 SectionIndex(I), // Section ID. 428 name, // Section name. 429 eSectionTypeOther, // FIXME: Fill in as appropriate. 430 header.sh_addr, // VM address. 431 header.sh_size, // VM size in bytes of this section. 432 header.sh_offset, // Offset of this section in the file. 433 size, // Size of the section as found in the file. 434 header.sh_flags)); // Flags for this section. 435 436 m_sections_ap->AddSection(section); 437 } 438 } 439 440 return m_sections_ap.get(); 441 } 442 443 static void 444 ParseSymbols(Symtab *symtab, SectionList *section_list, 445 const ELFSectionHeader &symtab_shdr, 446 const DataExtractor &symtab_data, 447 const DataExtractor &strtab_data) 448 { 449 ELFSymbol symbol; 450 uint32_t offset = 0; 451 const unsigned numSymbols = 452 symtab_data.GetByteSize() / symtab_shdr.sh_entsize; 453 454 static ConstString text_section_name(".text"); 455 static ConstString init_section_name(".init"); 456 static ConstString fini_section_name(".fini"); 457 static ConstString ctors_section_name(".ctors"); 458 static ConstString dtors_section_name(".dtors"); 459 460 static ConstString data_section_name(".data"); 461 static ConstString rodata_section_name(".rodata"); 462 static ConstString rodata1_section_name(".rodata1"); 463 static ConstString data2_section_name(".data1"); 464 static ConstString bss_section_name(".bss"); 465 466 for (unsigned i = 0; i < numSymbols; ++i) 467 { 468 if (symbol.Parse(symtab_data, &offset) == false) 469 break; 470 471 Section *symbol_section = NULL; 472 SymbolType symbol_type = eSymbolTypeInvalid; 473 Elf64_Half symbol_idx = symbol.st_shndx; 474 475 switch (symbol_idx) 476 { 477 case SHN_ABS: 478 symbol_type = eSymbolTypeAbsolute; 479 break; 480 case SHN_UNDEF: 481 symbol_type = eSymbolTypeUndefined; 482 break; 483 default: 484 symbol_section = section_list->GetSectionAtIndex(symbol_idx).get(); 485 break; 486 } 487 488 switch (symbol.getType()) 489 { 490 default: 491 case STT_NOTYPE: 492 // The symbol's type is not specified. 493 break; 494 495 case STT_OBJECT: 496 // The symbol is associated with a data object, such as a variable, 497 // an array, etc. 498 symbol_type = eSymbolTypeData; 499 break; 500 501 case STT_FUNC: 502 // The symbol is associated with a function or other executable code. 503 symbol_type = eSymbolTypeCode; 504 break; 505 506 case STT_SECTION: 507 // The symbol is associated with a section. Symbol table entries of 508 // this type exist primarily for relocation and normally have 509 // STB_LOCAL binding. 510 break; 511 512 case STT_FILE: 513 // Conventionally, the symbol's name gives the name of the source 514 // file associated with the object file. A file symbol has STB_LOCAL 515 // binding, its section index is SHN_ABS, and it precedes the other 516 // STB_LOCAL symbols for the file, if it is present. 517 symbol_type = eSymbolTypeObjectFile; 518 break; 519 } 520 521 if (symbol_type == eSymbolTypeInvalid) 522 { 523 if (symbol_section) 524 { 525 const ConstString §_name = symbol_section->GetName(); 526 if (sect_name == text_section_name || 527 sect_name == init_section_name || 528 sect_name == fini_section_name || 529 sect_name == ctors_section_name || 530 sect_name == dtors_section_name) 531 { 532 symbol_type = eSymbolTypeCode; 533 } 534 else if (sect_name == data_section_name || 535 sect_name == data2_section_name || 536 sect_name == rodata_section_name || 537 sect_name == rodata1_section_name || 538 sect_name == bss_section_name) 539 { 540 symbol_type = eSymbolTypeData; 541 } 542 } 543 } 544 545 uint64_t symbol_value = symbol.st_value; 546 if (symbol_section != NULL) 547 symbol_value -= symbol_section->GetFileAddress(); 548 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 549 bool is_global = symbol.getBinding() == STB_GLOBAL; 550 uint32_t flags = symbol.st_other << 8 | symbol.st_info; 551 552 Symbol dc_symbol( 553 i, // ID is the original symbol table index. 554 symbol_name, // Symbol name. 555 false, // Is the symbol name mangled? 556 symbol_type, // Type of this symbol 557 is_global, // Is this globally visible? 558 false, // Is this symbol debug info? 559 false, // Is this symbol a trampoline? 560 false, // Is this symbol artificial? 561 symbol_section, // Section in which this symbol is defined or null. 562 symbol_value, // Offset in section or symbol value. 563 symbol.st_size, // Size in bytes of this symbol. 564 flags); // Symbol flags. 565 symtab->AddSymbol(dc_symbol); 566 } 567 } 568 569 void 570 ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, 571 const ELFSectionHeader &symtab_hdr, 572 user_id_t symtab_id) 573 { 574 assert(symtab_hdr.sh_type == SHT_SYMTAB || 575 symtab_hdr.sh_type == SHT_DYNSYM); 576 577 // Parse in the section list if needed. 578 SectionList *section_list = GetSectionList(); 579 if (!section_list) 580 return; 581 582 // Section ID's are ones based. 583 user_id_t strtab_id = symtab_hdr.sh_link + 1; 584 585 Section *symtab = section_list->FindSectionByID(symtab_id).get(); 586 Section *strtab = section_list->FindSectionByID(strtab_id).get(); 587 if (symtab && strtab) 588 { 589 DataExtractor symtab_data; 590 DataExtractor strtab_data; 591 if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) && 592 strtab->ReadSectionDataFromObjectFile(this, strtab_data)) 593 { 594 ParseSymbols(symbol_table, section_list, symtab_hdr, 595 symtab_data, strtab_data); 596 } 597 } 598 } 599 600 Symtab * 601 ObjectFileELF::GetSymtab() 602 { 603 if (m_symtab_ap.get()) 604 return m_symtab_ap.get(); 605 606 Symtab *symbol_table = new Symtab(this); 607 m_symtab_ap.reset(symbol_table); 608 609 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 610 return symbol_table; 611 612 // Locate and parse all linker symbol tables. 613 for (SectionHeaderCollIter I = m_section_headers.begin(); 614 I != m_section_headers.end(); ++I) 615 { 616 if (I->sh_type == SHT_SYMTAB) 617 { 618 const ELFSectionHeader &symtab_section = *I; 619 user_id_t section_id = SectionIndex(I); 620 ParseSymbolTable(symbol_table, symtab_section, section_id); 621 } 622 } 623 624 return symbol_table; 625 } 626 627 //===----------------------------------------------------------------------===// 628 // Dump 629 // 630 // Dump the specifics of the runtime file container (such as any headers 631 // segments, sections, etc). 632 //---------------------------------------------------------------------- 633 void 634 ObjectFileELF::Dump(Stream *s) 635 { 636 DumpELFHeader(s, m_header); 637 s->EOL(); 638 DumpELFProgramHeaders(s); 639 s->EOL(); 640 DumpELFSectionHeaders(s); 641 s->EOL(); 642 SectionList *section_list = GetSectionList(); 643 if (section_list) 644 section_list->Dump(s, NULL, true); 645 Symtab *symtab = GetSymtab(); 646 if (symtab) 647 symtab->Dump(s, NULL); 648 s->EOL(); 649 DumpDependentModules(s); 650 s->EOL(); 651 } 652 653 //---------------------------------------------------------------------- 654 // DumpELFHeader 655 // 656 // Dump the ELF header to the specified output stream 657 //---------------------------------------------------------------------- 658 void 659 ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) 660 { 661 s->PutCString("ELF Header\n"); 662 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); 663 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", 664 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]); 665 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", 666 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]); 667 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", 668 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]); 669 670 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]); 671 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]); 672 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]); 673 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]); 674 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]); 675 676 s->Printf("e_type = 0x%4.4x ", header.e_type); 677 DumpELFHeader_e_type(s, header.e_type); 678 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine); 679 s->Printf("e_version = 0x%8.8x\n", header.e_version); 680 s->Printf("e_entry = 0x%8.8lx\n", header.e_entry); 681 s->Printf("e_phoff = 0x%8.8lx\n", header.e_phoff); 682 s->Printf("e_shoff = 0x%8.8lx\n", header.e_shoff); 683 s->Printf("e_flags = 0x%8.8x\n", header.e_flags); 684 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize); 685 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize); 686 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum); 687 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); 688 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum); 689 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx); 690 } 691 692 //---------------------------------------------------------------------- 693 // DumpELFHeader_e_type 694 // 695 // Dump an token value for the ELF header member e_type 696 //---------------------------------------------------------------------- 697 void 698 ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) 699 { 700 switch (e_type) 701 { 702 case ET_NONE: *s << "ET_NONE"; break; 703 case ET_REL: *s << "ET_REL"; break; 704 case ET_EXEC: *s << "ET_EXEC"; break; 705 case ET_DYN: *s << "ET_DYN"; break; 706 case ET_CORE: *s << "ET_CORE"; break; 707 default: 708 break; 709 } 710 } 711 712 //---------------------------------------------------------------------- 713 // DumpELFHeader_e_ident_EI_DATA 714 // 715 // Dump an token value for the ELF header member e_ident[EI_DATA] 716 //---------------------------------------------------------------------- 717 void 718 ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data) 719 { 720 switch (ei_data) 721 { 722 case ELFDATANONE: *s << "ELFDATANONE"; break; 723 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break; 724 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break; 725 default: 726 break; 727 } 728 } 729 730 731 //---------------------------------------------------------------------- 732 // DumpELFProgramHeader 733 // 734 // Dump a single ELF program header to the specified output stream 735 //---------------------------------------------------------------------- 736 void 737 ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph) 738 { 739 DumpELFProgramHeader_p_type(s, ph.p_type); 740 s->Printf(" %8.8lx %8.8lx %8.8lx", ph.p_offset, ph.p_vaddr, ph.p_paddr); 741 s->Printf(" %8.8lx %8.8lx %8.8lx (", ph.p_filesz, ph.p_memsz, ph.p_flags); 742 743 DumpELFProgramHeader_p_flags(s, ph.p_flags); 744 s->Printf(") %8.8x", ph.p_align); 745 } 746 747 //---------------------------------------------------------------------- 748 // DumpELFProgramHeader_p_type 749 // 750 // Dump an token value for the ELF program header member p_type which 751 // describes the type of the program header 752 // ---------------------------------------------------------------------- 753 void 754 ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) 755 { 756 const int kStrWidth = 10; 757 switch (p_type) 758 { 759 CASE_AND_STREAM(s, PT_NULL , kStrWidth); 760 CASE_AND_STREAM(s, PT_LOAD , kStrWidth); 761 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth); 762 CASE_AND_STREAM(s, PT_INTERP , kStrWidth); 763 CASE_AND_STREAM(s, PT_NOTE , kStrWidth); 764 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth); 765 CASE_AND_STREAM(s, PT_PHDR , kStrWidth); 766 default: 767 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, ""); 768 break; 769 } 770 } 771 772 773 //---------------------------------------------------------------------- 774 // DumpELFProgramHeader_p_flags 775 // 776 // Dump an token value for the ELF program header member p_flags 777 //---------------------------------------------------------------------- 778 void 779 ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) 780 { 781 *s << ((p_flags & PF_X) ? "PF_X" : " ") 782 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') 783 << ((p_flags & PF_W) ? "PF_W" : " ") 784 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ') 785 << ((p_flags & PF_R) ? "PF_R" : " "); 786 } 787 788 //---------------------------------------------------------------------- 789 // DumpELFProgramHeaders 790 // 791 // Dump all of the ELF program header to the specified output stream 792 //---------------------------------------------------------------------- 793 void 794 ObjectFileELF::DumpELFProgramHeaders(Stream *s) 795 { 796 if (ParseProgramHeaders()) 797 { 798 s->PutCString("Program Headers\n"); 799 s->PutCString("IDX p_type p_offset p_vaddr p_paddr " 800 "p_filesz p_memsz p_flags p_align\n"); 801 s->PutCString("==== ---------- -------- -------- -------- " 802 "-------- -------- ------------------------- --------\n"); 803 804 uint32_t idx = 0; 805 for (ProgramHeaderCollConstIter I = m_program_headers.begin(); 806 I != m_program_headers.end(); ++I, ++idx) 807 { 808 s->Printf("[%2u] ", idx); 809 ObjectFileELF::DumpELFProgramHeader(s, *I); 810 s->EOL(); 811 } 812 } 813 } 814 815 //---------------------------------------------------------------------- 816 // DumpELFSectionHeader 817 // 818 // Dump a single ELF section header to the specified output stream 819 //---------------------------------------------------------------------- 820 void 821 ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh) 822 { 823 s->Printf("%8.8x ", sh.sh_name); 824 DumpELFSectionHeader_sh_type(s, sh.sh_type); 825 s->Printf(" %8.8lx (", sh.sh_flags); 826 DumpELFSectionHeader_sh_flags(s, sh.sh_flags); 827 s->Printf(") %8.8lx %8.8lx %8.8lx", sh.sh_addr, sh.sh_offset, sh.sh_size); 828 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info); 829 s->Printf(" %8.8lx %8.8lx", sh.sh_addralign, sh.sh_entsize); 830 } 831 832 //---------------------------------------------------------------------- 833 // DumpELFSectionHeader_sh_type 834 // 835 // Dump an token value for the ELF section header member sh_type which 836 // describes the type of the section 837 //---------------------------------------------------------------------- 838 void 839 ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) 840 { 841 const int kStrWidth = 12; 842 switch (sh_type) 843 { 844 CASE_AND_STREAM(s, SHT_NULL , kStrWidth); 845 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth); 846 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth); 847 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth); 848 CASE_AND_STREAM(s, SHT_RELA , kStrWidth); 849 CASE_AND_STREAM(s, SHT_HASH , kStrWidth); 850 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth); 851 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth); 852 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth); 853 CASE_AND_STREAM(s, SHT_REL , kStrWidth); 854 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth); 855 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth); 856 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth); 857 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth); 858 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth); 859 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth); 860 default: 861 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, ""); 862 break; 863 } 864 } 865 866 //---------------------------------------------------------------------- 867 // DumpELFSectionHeader_sh_flags 868 // 869 // Dump an token value for the ELF section header member sh_flags 870 //---------------------------------------------------------------------- 871 void 872 ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags) 873 { 874 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") 875 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ') 876 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ") 877 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ') 878 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); 879 } 880 881 //---------------------------------------------------------------------- 882 // DumpELFSectionHeaders 883 // 884 // Dump all of the ELF section header to the specified output stream 885 //---------------------------------------------------------------------- 886 void 887 ObjectFileELF::DumpELFSectionHeaders(Stream *s) 888 { 889 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable())) 890 return; 891 892 s->PutCString("Section Headers\n"); 893 s->PutCString("IDX name type flags " 894 "addr offset size link info addralgn " 895 "entsize Name\n"); 896 s->PutCString("==== -------- ------------ -------------------------------- " 897 "-------- -------- -------- -------- -------- -------- " 898 "-------- ====================\n"); 899 900 uint32_t idx = 0; 901 for (SectionHeaderCollConstIter I = m_section_headers.begin(); 902 I != m_section_headers.end(); ++I, ++idx) 903 { 904 s->Printf("[%2u] ", idx); 905 ObjectFileELF::DumpELFSectionHeader(s, *I); 906 const char* section_name = m_shstr_data.PeekCStr(I->sh_name); 907 if (section_name) 908 *s << ' ' << section_name << "\n"; 909 } 910 } 911 912 void 913 ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) 914 { 915 size_t num_modules = ParseDependentModules(); 916 917 if (num_modules > 0) 918 { 919 s->PutCString("Dependent Modules:\n"); 920 for (unsigned i = 0; i < num_modules; ++i) 921 { 922 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i); 923 s->Printf(" %s\n", spec.GetFilename().GetCString()); 924 } 925 } 926 } 927 928 bool 929 ObjectFileELF::GetTargetTriple(ConstString &target_triple) 930 { 931 static ConstString g_target_triple; 932 933 if (g_target_triple) 934 { 935 target_triple = g_target_triple; 936 return true; 937 } 938 939 std::string triple; 940 switch (m_header.e_machine) 941 { 942 default: 943 assert(false && "Unexpected machine type."); 944 break; 945 case EM_SPARC: triple.assign("sparc-"); break; 946 case EM_386: triple.assign("i386-"); break; 947 case EM_68K: triple.assign("68k-"); break; 948 case EM_88K: triple.assign("88k-"); break; 949 case EM_860: triple.assign("i860-"); break; 950 case EM_MIPS: triple.assign("mips-"); break; 951 case EM_PPC: triple.assign("powerpc-"); break; 952 case EM_PPC64: triple.assign("powerpc64-"); break; 953 case EM_ARM: triple.assign("arm-"); break; 954 case EM_X86_64: triple.assign("x86_64-"); break; 955 } 956 // TODO: determine if there is a vendor in the ELF? Default to "linux" for now 957 triple += "linux-"; 958 // TODO: determine if there is an OS in the ELF? Default to "gnu" for now 959 triple += "gnu"; 960 g_target_triple.SetCString(triple.c_str()); 961 target_triple = g_target_triple; 962 963 return true; 964 } 965 966