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