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