xref: /llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (revision 51dc1882166894ce3dadb587488f8101c4fb9dca)
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 &sect_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