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