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