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