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