ObjectFileELF.cpp revision 36b877d2d27f7d1890f2d13807a3addb216648e2
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/Module.h"
20#include "lldb/Core/ModuleSpec.h"
21#include "lldb/Core/PluginManager.h"
22#include "lldb/Core/Section.h"
23#include "lldb/Core/Stream.h"
24#include "lldb/Symbol/SymbolContext.h"
25#include "lldb/Host/Host.h"
26
27#include "llvm/ADT/PointerUnion.h"
28
29#define CASE_AND_STREAM(s, def, width)                  \
30    case def: s->Printf("%-*s", width, #def); break;
31
32using namespace lldb;
33using namespace lldb_private;
34using namespace elf;
35using namespace llvm::ELF;
36
37namespace {
38//===----------------------------------------------------------------------===//
39/// @class ELFRelocation
40/// @brief Generic wrapper for ELFRel and ELFRela.
41///
42/// This helper class allows us to parse both ELFRel and ELFRela relocation
43/// entries in a generic manner.
44class ELFRelocation
45{
46public:
47
48    /// Constructs an ELFRelocation entry with a personality as given by @p
49    /// type.
50    ///
51    /// @param type Either DT_REL or DT_RELA.  Any other value is invalid.
52    ELFRelocation(unsigned type);
53
54    ~ELFRelocation();
55
56    bool
57    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
58
59    static unsigned
60    RelocType32(const ELFRelocation &rel);
61
62    static unsigned
63    RelocType64(const ELFRelocation &rel);
64
65    static unsigned
66    RelocSymbol32(const ELFRelocation &rel);
67
68    static unsigned
69    RelocSymbol64(const ELFRelocation &rel);
70
71private:
72    typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion;
73
74    RelocUnion reloc;
75};
76
77ELFRelocation::ELFRelocation(unsigned type)
78{
79    if (type == DT_REL)
80        reloc = new ELFRel();
81    else if (type == DT_RELA)
82        reloc = new ELFRela();
83    else {
84        assert(false && "unexpected relocation type");
85        reloc = static_cast<ELFRel*>(NULL);
86    }
87}
88
89ELFRelocation::~ELFRelocation()
90{
91    if (reloc.is<ELFRel*>())
92        delete reloc.get<ELFRel*>();
93    else
94        delete reloc.get<ELFRela*>();
95}
96
97bool
98ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
99{
100    if (reloc.is<ELFRel*>())
101        return reloc.get<ELFRel*>()->Parse(data, offset);
102    else
103        return reloc.get<ELFRela*>()->Parse(data, offset);
104}
105
106unsigned
107ELFRelocation::RelocType32(const ELFRelocation &rel)
108{
109    if (rel.reloc.is<ELFRel*>())
110        return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>());
111    else
112        return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>());
113}
114
115unsigned
116ELFRelocation::RelocType64(const ELFRelocation &rel)
117{
118    if (rel.reloc.is<ELFRel*>())
119        return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>());
120    else
121        return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>());
122}
123
124unsigned
125ELFRelocation::RelocSymbol32(const ELFRelocation &rel)
126{
127    if (rel.reloc.is<ELFRel*>())
128        return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>());
129    else
130        return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>());
131}
132
133unsigned
134ELFRelocation::RelocSymbol64(const ELFRelocation &rel)
135{
136    if (rel.reloc.is<ELFRel*>())
137        return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>());
138    else
139        return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>());
140}
141
142} // end anonymous namespace
143
144//------------------------------------------------------------------
145// Static methods.
146//------------------------------------------------------------------
147void
148ObjectFileELF::Initialize()
149{
150    PluginManager::RegisterPlugin(GetPluginNameStatic(),
151                                  GetPluginDescriptionStatic(),
152                                  CreateInstance,
153                                  CreateMemoryInstance,
154                                  GetModuleSpecifications);
155}
156
157void
158ObjectFileELF::Terminate()
159{
160    PluginManager::UnregisterPlugin(CreateInstance);
161}
162
163const char *
164ObjectFileELF::GetPluginNameStatic()
165{
166    return "object-file.elf";
167}
168
169const char *
170ObjectFileELF::GetPluginDescriptionStatic()
171{
172    return "ELF object file reader.";
173}
174
175ObjectFile *
176ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
177                               DataBufferSP &data_sp,
178                               lldb::offset_t data_offset,
179                               const lldb_private::FileSpec* file,
180                               lldb::offset_t file_offset,
181                               lldb::offset_t length)
182{
183    if (!data_sp)
184    {
185        data_sp = file->MemoryMapFileContents(file_offset, length);
186        data_offset = 0;
187    }
188
189    if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
190    {
191        const uint8_t *magic = data_sp->GetBytes() + data_offset;
192        if (ELFHeader::MagicBytesMatch(magic))
193        {
194            // Update the data to contain the entire file if it doesn't already
195            if (data_sp->GetByteSize() < length) {
196                data_sp = file->MemoryMapFileContents(file_offset, length);
197                data_offset = 0;
198                magic = data_sp->GetBytes();
199            }
200            unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
201            if (address_size == 4 || address_size == 8)
202            {
203                std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, data_offset, file, file_offset, length));
204                ArchSpec spec;
205                if (objfile_ap->GetArchitecture(spec) &&
206                    objfile_ap->SetModulesArchitecture(spec))
207                    return objfile_ap.release();
208            }
209        }
210    }
211    return NULL;
212}
213
214
215ObjectFile*
216ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
217                                     DataBufferSP& data_sp,
218                                     const lldb::ProcessSP &process_sp,
219                                     lldb::addr_t header_addr)
220{
221    return NULL;
222}
223
224
225size_t
226ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
227                                        lldb::DataBufferSP& data_sp,
228                                        lldb::offset_t data_offset,
229                                        lldb::offset_t file_offset,
230                                        lldb::offset_t length,
231                                        lldb_private::ModuleSpecList &specs)
232{
233    return 0;
234}
235
236//------------------------------------------------------------------
237// PluginInterface protocol
238//------------------------------------------------------------------
239const char *
240ObjectFileELF::GetPluginName()
241{
242    return "ObjectFileELF";
243}
244
245const char *
246ObjectFileELF::GetShortPluginName()
247{
248    return GetPluginNameStatic();
249}
250
251uint32_t
252ObjectFileELF::GetPluginVersion()
253{
254    return m_plugin_version;
255}
256//------------------------------------------------------------------
257// ObjectFile protocol
258//------------------------------------------------------------------
259
260ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
261                              DataBufferSP& data_sp,
262                              lldb::offset_t data_offset,
263                              const FileSpec* file,
264                              lldb::offset_t file_offset,
265                              lldb::offset_t length) :
266    ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
267    m_header(),
268    m_program_headers(),
269    m_section_headers(),
270    m_filespec_ap(),
271    m_shstr_data()
272{
273    if (file)
274        m_file = *file;
275    ::memset(&m_header, 0, sizeof(m_header));
276}
277
278ObjectFileELF::~ObjectFileELF()
279{
280}
281
282bool
283ObjectFileELF::IsExecutable() const
284{
285    return m_header.e_entry != 0;
286}
287
288ByteOrder
289ObjectFileELF::GetByteOrder() const
290{
291    if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
292        return eByteOrderBig;
293    if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
294        return eByteOrderLittle;
295    return eByteOrderInvalid;
296}
297
298uint32_t
299ObjectFileELF::GetAddressByteSize() const
300{
301    return m_data.GetAddressByteSize();
302}
303
304size_t
305ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
306{
307    return std::distance(m_section_headers.begin(), I) + 1u;
308}
309
310size_t
311ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
312{
313    return std::distance(m_section_headers.begin(), I) + 1u;
314}
315
316bool
317ObjectFileELF::ParseHeader()
318{
319    lldb::offset_t offset = GetFileOffset();
320    return m_header.Parse(m_data, &offset);
321}
322
323bool
324ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
325{
326    // FIXME: Return MD5 sum here.  See comment in ObjectFile.h.
327    return false;
328}
329
330uint32_t
331ObjectFileELF::GetDependentModules(FileSpecList &files)
332{
333    size_t num_modules = ParseDependentModules();
334    uint32_t num_specs = 0;
335
336    for (unsigned i = 0; i < num_modules; ++i)
337    {
338        if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
339            num_specs++;
340    }
341
342    return num_specs;
343}
344
345user_id_t
346ObjectFileELF::GetSectionIndexByType(unsigned type)
347{
348    if (!ParseSectionHeaders())
349        return 0;
350
351    for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
352         sh_pos != m_section_headers.end(); ++sh_pos)
353    {
354        if (sh_pos->sh_type == type)
355            return SectionIndex(sh_pos);
356    }
357
358    return 0;
359}
360
361Address
362ObjectFileELF::GetImageInfoAddress()
363{
364    if (!ParseDynamicSymbols())
365        return Address();
366
367    SectionList *section_list = GetSectionList();
368    if (!section_list)
369        return Address();
370
371    user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
372    if (!dynsym_id)
373        return Address();
374
375    const ELFSectionHeader *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
376    if (!dynsym_hdr)
377        return Address();
378
379    SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
380    if (dynsym_section_sp)
381    {
382        for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
383        {
384            ELFDynamic &symbol = m_dynamic_symbols[i];
385
386            if (symbol.d_tag == DT_DEBUG)
387            {
388                // Compute the offset as the number of previous entries plus the
389                // size of d_tag.
390                addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
391                return Address(dynsym_section_sp, offset);
392            }
393        }
394    }
395
396    return Address();
397}
398
399lldb_private::Address
400ObjectFileELF::GetEntryPointAddress ()
401{
402    SectionList *sections;
403    addr_t offset;
404
405    if (m_entry_point_address.IsValid())
406        return m_entry_point_address;
407
408    if (!ParseHeader() || !IsExecutable())
409        return m_entry_point_address;
410
411    sections = GetSectionList();
412    offset = m_header.e_entry;
413
414    if (!sections)
415    {
416        m_entry_point_address.SetOffset(offset);
417        return m_entry_point_address;
418    }
419
420    m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
421
422    return m_entry_point_address;
423}
424
425//----------------------------------------------------------------------
426// ParseDependentModules
427//----------------------------------------------------------------------
428size_t
429ObjectFileELF::ParseDependentModules()
430{
431    if (m_filespec_ap.get())
432        return m_filespec_ap->GetSize();
433
434    m_filespec_ap.reset(new FileSpecList());
435
436    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
437        return 0;
438
439    // Locate the dynamic table.
440    user_id_t dynsym_id = 0;
441    user_id_t dynstr_id = 0;
442    for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
443         sh_pos != m_section_headers.end(); ++sh_pos)
444    {
445        if (sh_pos->sh_type == SHT_DYNAMIC)
446        {
447            dynsym_id = SectionIndex(sh_pos);
448            dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
449            break;
450        }
451    }
452
453    if (!(dynsym_id && dynstr_id))
454        return 0;
455
456    SectionList *section_list = GetSectionList();
457    if (!section_list)
458        return 0;
459
460    // Resolve and load the dynamic table entries and corresponding string
461    // table.
462    Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
463    Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
464    if (!(dynsym && dynstr))
465        return 0;
466
467    DataExtractor dynsym_data;
468    DataExtractor dynstr_data;
469    if (ReadSectionData(dynsym, dynsym_data) &&
470        ReadSectionData(dynstr, dynstr_data))
471    {
472        ELFDynamic symbol;
473        const lldb::offset_t section_size = dynsym_data.GetByteSize();
474        lldb::offset_t offset = 0;
475
476        // The only type of entries we are concerned with are tagged DT_NEEDED,
477        // yielding the name of a required library.
478        while (offset < section_size)
479        {
480            if (!symbol.Parse(dynsym_data, &offset))
481                break;
482
483            if (symbol.d_tag != DT_NEEDED)
484                continue;
485
486            uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
487            const char *lib_name = dynstr_data.PeekCStr(str_index);
488            m_filespec_ap->Append(FileSpec(lib_name, true));
489        }
490    }
491
492    return m_filespec_ap->GetSize();
493}
494
495//----------------------------------------------------------------------
496// ParseProgramHeaders
497//----------------------------------------------------------------------
498size_t
499ObjectFileELF::ParseProgramHeaders()
500{
501    // We have already parsed the program headers
502    if (!m_program_headers.empty())
503        return m_program_headers.size();
504
505    // If there are no program headers to read we are done.
506    if (m_header.e_phnum == 0)
507        return 0;
508
509    m_program_headers.resize(m_header.e_phnum);
510    if (m_program_headers.size() != m_header.e_phnum)
511        return 0;
512
513    const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
514    const elf_off ph_offset = m_header.e_phoff;
515    DataExtractor data;
516    if (GetData (ph_offset, ph_size, data) != ph_size)
517        return 0;
518
519    uint32_t idx;
520    lldb::offset_t offset;
521    for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
522    {
523        if (m_program_headers[idx].Parse(data, &offset) == false)
524            break;
525    }
526
527    if (idx < m_program_headers.size())
528        m_program_headers.resize(idx);
529
530    return m_program_headers.size();
531}
532
533//----------------------------------------------------------------------
534// ParseSectionHeaders
535//----------------------------------------------------------------------
536size_t
537ObjectFileELF::ParseSectionHeaders()
538{
539    // We have already parsed the section headers
540    if (!m_section_headers.empty())
541        return m_section_headers.size();
542
543    // If there are no section headers we are done.
544    if (m_header.e_shnum == 0)
545        return 0;
546
547    m_section_headers.resize(m_header.e_shnum);
548    if (m_section_headers.size() != m_header.e_shnum)
549        return 0;
550
551    const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
552    const elf_off sh_offset = m_header.e_shoff;
553    DataExtractor data;
554    if (GetData (sh_offset, sh_size, data) != sh_size)
555        return 0;
556
557    uint32_t idx;
558    lldb::offset_t offset;
559    for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
560    {
561        if (m_section_headers[idx].Parse(data, &offset) == false)
562            break;
563    }
564    if (idx < m_section_headers.size())
565        m_section_headers.resize(idx);
566
567    return m_section_headers.size();
568}
569
570size_t
571ObjectFileELF::GetSectionHeaderStringTable()
572{
573    if (m_shstr_data.GetByteSize() == 0)
574    {
575        const unsigned strtab_idx = m_header.e_shstrndx;
576
577        if (strtab_idx && strtab_idx < m_section_headers.size())
578        {
579            const ELFSectionHeader &sheader = m_section_headers[strtab_idx];
580            const size_t byte_size = sheader.sh_size;
581            const Elf64_Off offset = sheader.sh_offset;
582            m_shstr_data.SetData (m_data, offset, byte_size);
583
584            if (m_shstr_data.GetByteSize() != byte_size)
585                return 0;
586        }
587    }
588    return m_shstr_data.GetByteSize();
589}
590
591lldb::user_id_t
592ObjectFileELF::GetSectionIndexByName(const char *name)
593{
594    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
595        return 0;
596
597    // Search the collection of section headers for one with a matching name.
598    for (SectionHeaderCollIter I = m_section_headers.begin();
599         I != m_section_headers.end(); ++I)
600    {
601        const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
602
603        if (!sectionName)
604            return 0;
605
606        if (strcmp(name, sectionName) != 0)
607            continue;
608
609        return SectionIndex(I);
610    }
611
612    return 0;
613}
614
615const elf::ELFSectionHeader *
616ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
617{
618    if (!ParseSectionHeaders() || !id)
619        return NULL;
620
621    if (--id < m_section_headers.size())
622        return &m_section_headers[id];
623
624    return NULL;
625}
626
627SectionList *
628ObjectFileELF::GetSectionList()
629{
630    if (m_sections_ap.get())
631        return m_sections_ap.get();
632
633    if (ParseSectionHeaders() && GetSectionHeaderStringTable())
634    {
635        m_sections_ap.reset(new SectionList());
636
637        for (SectionHeaderCollIter I = m_section_headers.begin();
638             I != m_section_headers.end(); ++I)
639        {
640            const ELFSectionHeader &header = *I;
641
642            ConstString name(m_shstr_data.PeekCStr(header.sh_name));
643            const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
644            const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
645
646            static ConstString g_sect_name_text (".text");
647            static ConstString g_sect_name_data (".data");
648            static ConstString g_sect_name_bss (".bss");
649            static ConstString g_sect_name_tdata (".tdata");
650            static ConstString g_sect_name_tbss (".tbss");
651            static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
652            static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
653            static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
654            static ConstString g_sect_name_dwarf_debug_info (".debug_info");
655            static ConstString g_sect_name_dwarf_debug_line (".debug_line");
656            static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
657            static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
658            static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
659            static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
660            static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
661            static ConstString g_sect_name_dwarf_debug_str (".debug_str");
662            static ConstString g_sect_name_eh_frame (".eh_frame");
663
664            SectionType sect_type = eSectionTypeOther;
665
666            bool is_thread_specific = false;
667
668            if      (name == g_sect_name_text)                  sect_type = eSectionTypeCode;
669            else if (name == g_sect_name_data)                  sect_type = eSectionTypeData;
670            else if (name == g_sect_name_bss)                   sect_type = eSectionTypeZeroFill;
671            else if (name == g_sect_name_tdata)
672            {
673                sect_type = eSectionTypeData;
674                is_thread_specific = true;
675            }
676            else if (name == g_sect_name_tbss)
677            {
678                sect_type = eSectionTypeZeroFill;
679                is_thread_specific = true;
680            }
681            else if (name == g_sect_name_dwarf_debug_abbrev)    sect_type = eSectionTypeDWARFDebugAbbrev;
682            else if (name == g_sect_name_dwarf_debug_aranges)   sect_type = eSectionTypeDWARFDebugAranges;
683            else if (name == g_sect_name_dwarf_debug_frame)     sect_type = eSectionTypeDWARFDebugFrame;
684            else if (name == g_sect_name_dwarf_debug_info)      sect_type = eSectionTypeDWARFDebugInfo;
685            else if (name == g_sect_name_dwarf_debug_line)      sect_type = eSectionTypeDWARFDebugLine;
686            else if (name == g_sect_name_dwarf_debug_loc)       sect_type = eSectionTypeDWARFDebugLoc;
687            else if (name == g_sect_name_dwarf_debug_macinfo)   sect_type = eSectionTypeDWARFDebugMacInfo;
688            else if (name == g_sect_name_dwarf_debug_pubnames)  sect_type = eSectionTypeDWARFDebugPubNames;
689            else if (name == g_sect_name_dwarf_debug_pubtypes)  sect_type = eSectionTypeDWARFDebugPubTypes;
690            else if (name == g_sect_name_dwarf_debug_ranges)    sect_type = eSectionTypeDWARFDebugRanges;
691            else if (name == g_sect_name_dwarf_debug_str)       sect_type = eSectionTypeDWARFDebugStr;
692            else if (name == g_sect_name_eh_frame)              sect_type = eSectionTypeEHFrame;
693
694
695            SectionSP section_sp(new Section(
696                GetModule(),        // Module to which this section belongs.
697                SectionIndex(I),    // Section ID.
698                name,               // Section name.
699                sect_type,          // Section type.
700                header.sh_addr,     // VM address.
701                vm_size,            // VM size in bytes of this section.
702                header.sh_offset,   // Offset of this section in the file.
703                file_size,          // Size of the section as found in the file.
704                header.sh_flags));  // Flags for this section.
705
706            if (is_thread_specific)
707                section_sp->SetIsThreadSpecific (is_thread_specific);
708            m_sections_ap->AddSection(section_sp);
709        }
710
711        m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
712    }
713
714    return m_sections_ap.get();
715}
716
717static unsigned
718ParseSymbols(Symtab *symtab,
719             user_id_t start_id,
720             SectionList *section_list,
721             const ELFSectionHeader *symtab_shdr,
722             const DataExtractor &symtab_data,
723             const DataExtractor &strtab_data)
724{
725    ELFSymbol symbol;
726    lldb::offset_t offset = 0;
727    const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
728
729    static ConstString text_section_name(".text");
730    static ConstString init_section_name(".init");
731    static ConstString fini_section_name(".fini");
732    static ConstString ctors_section_name(".ctors");
733    static ConstString dtors_section_name(".dtors");
734
735    static ConstString data_section_name(".data");
736    static ConstString rodata_section_name(".rodata");
737    static ConstString rodata1_section_name(".rodata1");
738    static ConstString data2_section_name(".data1");
739    static ConstString bss_section_name(".bss");
740
741    //StreamFile strm(stdout, false);
742    unsigned i;
743    for (i = 0; i < num_symbols; ++i)
744    {
745        if (symbol.Parse(symtab_data, &offset) == false)
746            break;
747
748        const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
749
750        // No need to add symbols that have no names
751        if (symbol_name == NULL || symbol_name[0] == '\0')
752            continue;
753
754        //symbol.Dump (&strm, i, &strtab_data, section_list);
755
756        SectionSP symbol_section_sp;
757        SymbolType symbol_type = eSymbolTypeInvalid;
758        Elf64_Half symbol_idx = symbol.st_shndx;
759
760        switch (symbol_idx)
761        {
762        case SHN_ABS:
763            symbol_type = eSymbolTypeAbsolute;
764            break;
765        case SHN_UNDEF:
766            symbol_type = eSymbolTypeUndefined;
767            break;
768        default:
769            symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
770            break;
771        }
772
773        // If a symbol is undefined do not process it further even if it has a STT type
774        if (symbol_type != eSymbolTypeUndefined)
775        {
776            switch (symbol.getType())
777            {
778            default:
779            case STT_NOTYPE:
780                // The symbol's type is not specified.
781                break;
782
783            case STT_OBJECT:
784                // The symbol is associated with a data object, such as a variable,
785                // an array, etc.
786                symbol_type = eSymbolTypeData;
787                break;
788
789            case STT_FUNC:
790                // The symbol is associated with a function or other executable code.
791                symbol_type = eSymbolTypeCode;
792                break;
793
794            case STT_SECTION:
795                // The symbol is associated with a section. Symbol table entries of
796                // this type exist primarily for relocation and normally have
797                // STB_LOCAL binding.
798                break;
799
800            case STT_FILE:
801                // Conventionally, the symbol's name gives the name of the source
802                // file associated with the object file. A file symbol has STB_LOCAL
803                // binding, its section index is SHN_ABS, and it precedes the other
804                // STB_LOCAL symbols for the file, if it is present.
805                symbol_type = eSymbolTypeSourceFile;
806                break;
807
808            case STT_GNU_IFUNC:
809                // The symbol is associated with an indirect function. The actual
810                // function will be resolved if it is referenced.
811                symbol_type = eSymbolTypeResolver;
812                break;
813            }
814        }
815
816        if (symbol_type == eSymbolTypeInvalid)
817        {
818            if (symbol_section_sp)
819            {
820                const ConstString &sect_name = symbol_section_sp->GetName();
821                if (sect_name == text_section_name ||
822                    sect_name == init_section_name ||
823                    sect_name == fini_section_name ||
824                    sect_name == ctors_section_name ||
825                    sect_name == dtors_section_name)
826                {
827                    symbol_type = eSymbolTypeCode;
828                }
829                else if (sect_name == data_section_name ||
830                         sect_name == data2_section_name ||
831                         sect_name == rodata_section_name ||
832                         sect_name == rodata1_section_name ||
833                         sect_name == bss_section_name)
834                {
835                    symbol_type = eSymbolTypeData;
836                }
837            }
838        }
839
840        uint64_t symbol_value = symbol.st_value;
841        if (symbol_section_sp)
842            symbol_value -= symbol_section_sp->GetFileAddress();
843        bool is_global = symbol.getBinding() == STB_GLOBAL;
844        uint32_t flags = symbol.st_other << 8 | symbol.st_info;
845        bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
846        Symbol dc_symbol(
847            i + start_id,       // ID is the original symbol table index.
848            symbol_name,        // Symbol name.
849            is_mangled,         // Is the symbol name mangled?
850            symbol_type,        // Type of this symbol
851            is_global,          // Is this globally visible?
852            false,              // Is this symbol debug info?
853            false,              // Is this symbol a trampoline?
854            false,              // Is this symbol artificial?
855            symbol_section_sp,  // Section in which this symbol is defined or null.
856            symbol_value,       // Offset in section or symbol value.
857            symbol.st_size,     // Size in bytes of this symbol.
858            true,               // Size is valid
859            flags);             // Symbol flags.
860        symtab->AddSymbol(dc_symbol);
861    }
862
863    return i;
864}
865
866unsigned
867ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
868                                const ELFSectionHeader *symtab_hdr,
869                                user_id_t symtab_id)
870{
871    assert(symtab_hdr->sh_type == SHT_SYMTAB ||
872           symtab_hdr->sh_type == SHT_DYNSYM);
873
874    // Parse in the section list if needed.
875    SectionList *section_list = GetSectionList();
876    if (!section_list)
877        return 0;
878
879    // Section ID's are ones based.
880    user_id_t strtab_id = symtab_hdr->sh_link + 1;
881
882    Section *symtab = section_list->FindSectionByID(symtab_id).get();
883    Section *strtab = section_list->FindSectionByID(strtab_id).get();
884    unsigned num_symbols = 0;
885    if (symtab && strtab)
886    {
887        DataExtractor symtab_data;
888        DataExtractor strtab_data;
889        if (ReadSectionData(symtab, symtab_data) &&
890            ReadSectionData(strtab, strtab_data))
891        {
892            num_symbols = ParseSymbols(symbol_table, start_id,
893                                       section_list, symtab_hdr,
894                                       symtab_data, strtab_data);
895        }
896    }
897
898    return num_symbols;
899}
900
901size_t
902ObjectFileELF::ParseDynamicSymbols()
903{
904    if (m_dynamic_symbols.size())
905        return m_dynamic_symbols.size();
906
907    user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
908    if (!dyn_id)
909        return 0;
910
911    SectionList *section_list = GetSectionList();
912    if (!section_list)
913        return 0;
914
915    Section *dynsym = section_list->FindSectionByID(dyn_id).get();
916    if (!dynsym)
917        return 0;
918
919    ELFDynamic symbol;
920    DataExtractor dynsym_data;
921    if (ReadSectionData(dynsym, dynsym_data))
922    {
923        const lldb::offset_t section_size = dynsym_data.GetByteSize();
924        lldb::offset_t cursor = 0;
925
926        while (cursor < section_size)
927        {
928            if (!symbol.Parse(dynsym_data, &cursor))
929                break;
930
931            m_dynamic_symbols.push_back(symbol);
932        }
933    }
934
935    return m_dynamic_symbols.size();
936}
937
938const ELFDynamic *
939ObjectFileELF::FindDynamicSymbol(unsigned tag)
940{
941    if (!ParseDynamicSymbols())
942        return NULL;
943
944    SectionList *section_list = GetSectionList();
945    if (!section_list)
946        return 0;
947
948    DynamicSymbolCollIter I = m_dynamic_symbols.begin();
949    DynamicSymbolCollIter E = m_dynamic_symbols.end();
950    for ( ; I != E; ++I)
951    {
952        ELFDynamic *symbol = &*I;
953
954        if (symbol->d_tag == tag)
955            return symbol;
956    }
957
958    return NULL;
959}
960
961Section *
962ObjectFileELF::PLTSection()
963{
964    const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
965    SectionList *section_list = GetSectionList();
966
967    if (symbol && section_list)
968    {
969        addr_t addr = symbol->d_ptr;
970        return section_list->FindSectionContainingFileAddress(addr).get();
971    }
972
973    return NULL;
974}
975
976unsigned
977ObjectFileELF::PLTRelocationType()
978{
979    const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
980
981    if (symbol)
982        return symbol->d_val;
983
984    return 0;
985}
986
987static unsigned
988ParsePLTRelocations(Symtab *symbol_table,
989                    user_id_t start_id,
990                    unsigned rel_type,
991                    const ELFHeader *hdr,
992                    const ELFSectionHeader *rel_hdr,
993                    const ELFSectionHeader *plt_hdr,
994                    const ELFSectionHeader *sym_hdr,
995                    const lldb::SectionSP &plt_section_sp,
996                    DataExtractor &rel_data,
997                    DataExtractor &symtab_data,
998                    DataExtractor &strtab_data)
999{
1000    ELFRelocation rel(rel_type);
1001    ELFSymbol symbol;
1002    lldb::offset_t offset = 0;
1003    const elf_xword plt_entsize = plt_hdr->sh_entsize;
1004    const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
1005
1006    typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1007    reloc_info_fn reloc_type;
1008    reloc_info_fn reloc_symbol;
1009
1010    if (hdr->Is32Bit())
1011    {
1012        reloc_type = ELFRelocation::RelocType32;
1013        reloc_symbol = ELFRelocation::RelocSymbol32;
1014    }
1015    else
1016    {
1017        reloc_type = ELFRelocation::RelocType64;
1018        reloc_symbol = ELFRelocation::RelocSymbol64;
1019    }
1020
1021    unsigned slot_type = hdr->GetRelocationJumpSlotType();
1022    unsigned i;
1023    for (i = 0; i < num_relocations; ++i)
1024    {
1025        if (rel.Parse(rel_data, &offset) == false)
1026            break;
1027
1028        if (reloc_type(rel) != slot_type)
1029            continue;
1030
1031        lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
1032        uint64_t plt_index = (i + 1) * plt_entsize;
1033
1034        if (!symbol.Parse(symtab_data, &symbol_offset))
1035            break;
1036
1037        const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1038        bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
1039
1040        Symbol jump_symbol(
1041            i + start_id,    // Symbol table index
1042            symbol_name,     // symbol name.
1043            is_mangled,      // is the symbol name mangled?
1044            eSymbolTypeTrampoline, // Type of this symbol
1045            false,           // Is this globally visible?
1046            false,           // Is this symbol debug info?
1047            true,            // Is this symbol a trampoline?
1048            true,            // Is this symbol artificial?
1049            plt_section_sp,  // Section in which this symbol is defined or null.
1050            plt_index,       // Offset in section or symbol value.
1051            plt_entsize,     // Size in bytes of this symbol.
1052            true,            // Size is valid
1053            0);              // Symbol flags.
1054
1055        symbol_table->AddSymbol(jump_symbol);
1056    }
1057
1058    return i;
1059}
1060
1061unsigned
1062ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1063                                      user_id_t start_id,
1064                                      const ELFSectionHeader *rel_hdr,
1065                                      user_id_t rel_id)
1066{
1067    assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1068
1069    // The link field points to the asscoiated symbol table.  The info field
1070    // points to the section holding the plt.
1071    user_id_t symtab_id = rel_hdr->sh_link;
1072    user_id_t plt_id = rel_hdr->sh_info;
1073
1074    if (!symtab_id || !plt_id)
1075        return 0;
1076
1077    // Section ID's are ones based;
1078    symtab_id++;
1079    plt_id++;
1080
1081    const ELFSectionHeader *plt_hdr = GetSectionHeaderByIndex(plt_id);
1082    if (!plt_hdr)
1083        return 0;
1084
1085    const ELFSectionHeader *sym_hdr = GetSectionHeaderByIndex(symtab_id);
1086    if (!sym_hdr)
1087        return 0;
1088
1089    SectionList *section_list = GetSectionList();
1090    if (!section_list)
1091        return 0;
1092
1093    Section *rel_section = section_list->FindSectionByID(rel_id).get();
1094    if (!rel_section)
1095        return 0;
1096
1097    SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1098    if (!plt_section_sp)
1099        return 0;
1100
1101    Section *symtab = section_list->FindSectionByID(symtab_id).get();
1102    if (!symtab)
1103        return 0;
1104
1105    Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1106    if (!strtab)
1107        return 0;
1108
1109    DataExtractor rel_data;
1110    if (!ReadSectionData(rel_section, rel_data))
1111        return 0;
1112
1113    DataExtractor symtab_data;
1114    if (!ReadSectionData(symtab, symtab_data))
1115        return 0;
1116
1117    DataExtractor strtab_data;
1118    if (!ReadSectionData(strtab, strtab_data))
1119        return 0;
1120
1121    unsigned rel_type = PLTRelocationType();
1122    if (!rel_type)
1123        return 0;
1124
1125    return ParsePLTRelocations (symbol_table,
1126                                start_id,
1127                                rel_type,
1128                                &m_header,
1129                                rel_hdr,
1130                                plt_hdr,
1131                                sym_hdr,
1132                                plt_section_sp,
1133                                rel_data,
1134                                symtab_data,
1135                                strtab_data);
1136}
1137
1138Symtab *
1139ObjectFileELF::GetSymtab()
1140{
1141    if (m_symtab_ap.get())
1142        return m_symtab_ap.get();
1143
1144    Symtab *symbol_table = new Symtab(this);
1145    m_symtab_ap.reset(symbol_table);
1146
1147    Mutex::Locker locker(symbol_table->GetMutex());
1148
1149    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1150        return symbol_table;
1151
1152    // Locate and parse all linker symbol tables.
1153    uint64_t symbol_id = 0;
1154    for (SectionHeaderCollIter I = m_section_headers.begin();
1155         I != m_section_headers.end(); ++I)
1156    {
1157        if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM)
1158        {
1159            const ELFSectionHeader &symtab_header = *I;
1160            user_id_t section_id = SectionIndex(I);
1161            symbol_id += ParseSymbolTable(symbol_table, symbol_id,
1162                                          &symtab_header, section_id);
1163        }
1164    }
1165
1166    // Synthesize trampoline symbols to help navigate the PLT.
1167    Section *reloc_section = PLTSection();
1168    if (reloc_section)
1169    {
1170        user_id_t reloc_id = reloc_section->GetID();
1171        const ELFSectionHeader *reloc_header = GetSectionHeaderByIndex(reloc_id);
1172        assert(reloc_header);
1173
1174        ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
1175    }
1176
1177    return symbol_table;
1178}
1179
1180//===----------------------------------------------------------------------===//
1181// Dump
1182//
1183// Dump the specifics of the runtime file container (such as any headers
1184// segments, sections, etc).
1185//----------------------------------------------------------------------
1186void
1187ObjectFileELF::Dump(Stream *s)
1188{
1189    DumpELFHeader(s, m_header);
1190    s->EOL();
1191    DumpELFProgramHeaders(s);
1192    s->EOL();
1193    DumpELFSectionHeaders(s);
1194    s->EOL();
1195    SectionList *section_list = GetSectionList();
1196    if (section_list)
1197        section_list->Dump(s, NULL, true, UINT32_MAX);
1198    Symtab *symtab = GetSymtab();
1199    if (symtab)
1200        symtab->Dump(s, NULL, eSortOrderNone);
1201    s->EOL();
1202    DumpDependentModules(s);
1203    s->EOL();
1204}
1205
1206//----------------------------------------------------------------------
1207// DumpELFHeader
1208//
1209// Dump the ELF header to the specified output stream
1210//----------------------------------------------------------------------
1211void
1212ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
1213{
1214    s->PutCString("ELF Header\n");
1215    s->Printf("e_ident[EI_MAG0   ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1216    s->Printf("e_ident[EI_MAG1   ] = 0x%2.2x '%c'\n",
1217              header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1218    s->Printf("e_ident[EI_MAG2   ] = 0x%2.2x '%c'\n",
1219              header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1220    s->Printf("e_ident[EI_MAG3   ] = 0x%2.2x '%c'\n",
1221              header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
1222
1223    s->Printf("e_ident[EI_CLASS  ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1224    s->Printf("e_ident[EI_DATA   ] = 0x%2.2x ", header.e_ident[EI_DATA]);
1225    DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1226    s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1227    s->Printf ("e_ident[EI_PAD    ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1228
1229    s->Printf("e_type      = 0x%4.4x ", header.e_type);
1230    DumpELFHeader_e_type(s, header.e_type);
1231    s->Printf("\ne_machine   = 0x%4.4x\n", header.e_machine);
1232    s->Printf("e_version   = 0x%8.8x\n", header.e_version);
1233    s->Printf("e_entry     = 0x%8.8" PRIx64 "\n", header.e_entry);
1234    s->Printf("e_phoff     = 0x%8.8" PRIx64 "\n", header.e_phoff);
1235    s->Printf("e_shoff     = 0x%8.8" PRIx64 "\n", header.e_shoff);
1236    s->Printf("e_flags     = 0x%8.8x\n", header.e_flags);
1237    s->Printf("e_ehsize    = 0x%4.4x\n", header.e_ehsize);
1238    s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1239    s->Printf("e_phnum     = 0x%4.4x\n", header.e_phnum);
1240    s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1241    s->Printf("e_shnum     = 0x%4.4x\n", header.e_shnum);
1242    s->Printf("e_shstrndx  = 0x%4.4x\n", header.e_shstrndx);
1243}
1244
1245//----------------------------------------------------------------------
1246// DumpELFHeader_e_type
1247//
1248// Dump an token value for the ELF header member e_type
1249//----------------------------------------------------------------------
1250void
1251ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
1252{
1253    switch (e_type)
1254    {
1255    case ET_NONE:   *s << "ET_NONE"; break;
1256    case ET_REL:    *s << "ET_REL"; break;
1257    case ET_EXEC:   *s << "ET_EXEC"; break;
1258    case ET_DYN:    *s << "ET_DYN"; break;
1259    case ET_CORE:   *s << "ET_CORE"; break;
1260    default:
1261        break;
1262    }
1263}
1264
1265//----------------------------------------------------------------------
1266// DumpELFHeader_e_ident_EI_DATA
1267//
1268// Dump an token value for the ELF header member e_ident[EI_DATA]
1269//----------------------------------------------------------------------
1270void
1271ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
1272{
1273    switch (ei_data)
1274    {
1275    case ELFDATANONE:   *s << "ELFDATANONE"; break;
1276    case ELFDATA2LSB:   *s << "ELFDATA2LSB - Little Endian"; break;
1277    case ELFDATA2MSB:   *s << "ELFDATA2MSB - Big Endian"; break;
1278    default:
1279        break;
1280    }
1281}
1282
1283
1284//----------------------------------------------------------------------
1285// DumpELFProgramHeader
1286//
1287// Dump a single ELF program header to the specified output stream
1288//----------------------------------------------------------------------
1289void
1290ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
1291{
1292    DumpELFProgramHeader_p_type(s, ph.p_type);
1293    s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1294    s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags);
1295
1296    DumpELFProgramHeader_p_flags(s, ph.p_flags);
1297    s->Printf(") %8.8" PRIx64, ph.p_align);
1298}
1299
1300//----------------------------------------------------------------------
1301// DumpELFProgramHeader_p_type
1302//
1303// Dump an token value for the ELF program header member p_type which
1304// describes the type of the program header
1305// ----------------------------------------------------------------------
1306void
1307ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
1308{
1309    const int kStrWidth = 10;
1310    switch (p_type)
1311    {
1312    CASE_AND_STREAM(s, PT_NULL      , kStrWidth);
1313    CASE_AND_STREAM(s, PT_LOAD      , kStrWidth);
1314    CASE_AND_STREAM(s, PT_DYNAMIC   , kStrWidth);
1315    CASE_AND_STREAM(s, PT_INTERP    , kStrWidth);
1316    CASE_AND_STREAM(s, PT_NOTE      , kStrWidth);
1317    CASE_AND_STREAM(s, PT_SHLIB     , kStrWidth);
1318    CASE_AND_STREAM(s, PT_PHDR      , kStrWidth);
1319    default:
1320        s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1321        break;
1322    }
1323}
1324
1325
1326//----------------------------------------------------------------------
1327// DumpELFProgramHeader_p_flags
1328//
1329// Dump an token value for the ELF program header member p_flags
1330//----------------------------------------------------------------------
1331void
1332ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
1333{
1334    *s  << ((p_flags & PF_X) ? "PF_X" : "    ")
1335        << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1336        << ((p_flags & PF_W) ? "PF_W" : "    ")
1337        << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1338        << ((p_flags & PF_R) ? "PF_R" : "    ");
1339}
1340
1341//----------------------------------------------------------------------
1342// DumpELFProgramHeaders
1343//
1344// Dump all of the ELF program header to the specified output stream
1345//----------------------------------------------------------------------
1346void
1347ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1348{
1349    if (ParseProgramHeaders())
1350    {
1351        s->PutCString("Program Headers\n");
1352        s->PutCString("IDX  p_type     p_offset p_vaddr  p_paddr  "
1353                      "p_filesz p_memsz  p_flags                   p_align\n");
1354        s->PutCString("==== ---------- -------- -------- -------- "
1355                      "-------- -------- ------------------------- --------\n");
1356
1357        uint32_t idx = 0;
1358        for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1359             I != m_program_headers.end(); ++I, ++idx)
1360        {
1361            s->Printf("[%2u] ", idx);
1362            ObjectFileELF::DumpELFProgramHeader(s, *I);
1363            s->EOL();
1364        }
1365    }
1366}
1367
1368//----------------------------------------------------------------------
1369// DumpELFSectionHeader
1370//
1371// Dump a single ELF section header to the specified output stream
1372//----------------------------------------------------------------------
1373void
1374ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh)
1375{
1376    s->Printf("%8.8x ", sh.sh_name);
1377    DumpELFSectionHeader_sh_type(s, sh.sh_type);
1378    s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
1379    DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
1380    s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr, sh.sh_offset, sh.sh_size);
1381    s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
1382    s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
1383}
1384
1385//----------------------------------------------------------------------
1386// DumpELFSectionHeader_sh_type
1387//
1388// Dump an token value for the ELF section header member sh_type which
1389// describes the type of the section
1390//----------------------------------------------------------------------
1391void
1392ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
1393{
1394    const int kStrWidth = 12;
1395    switch (sh_type)
1396    {
1397    CASE_AND_STREAM(s, SHT_NULL     , kStrWidth);
1398    CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1399    CASE_AND_STREAM(s, SHT_SYMTAB   , kStrWidth);
1400    CASE_AND_STREAM(s, SHT_STRTAB   , kStrWidth);
1401    CASE_AND_STREAM(s, SHT_RELA     , kStrWidth);
1402    CASE_AND_STREAM(s, SHT_HASH     , kStrWidth);
1403    CASE_AND_STREAM(s, SHT_DYNAMIC  , kStrWidth);
1404    CASE_AND_STREAM(s, SHT_NOTE     , kStrWidth);
1405    CASE_AND_STREAM(s, SHT_NOBITS   , kStrWidth);
1406    CASE_AND_STREAM(s, SHT_REL      , kStrWidth);
1407    CASE_AND_STREAM(s, SHT_SHLIB    , kStrWidth);
1408    CASE_AND_STREAM(s, SHT_DYNSYM   , kStrWidth);
1409    CASE_AND_STREAM(s, SHT_LOPROC   , kStrWidth);
1410    CASE_AND_STREAM(s, SHT_HIPROC   , kStrWidth);
1411    CASE_AND_STREAM(s, SHT_LOUSER   , kStrWidth);
1412    CASE_AND_STREAM(s, SHT_HIUSER   , kStrWidth);
1413    default:
1414        s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1415        break;
1416    }
1417}
1418
1419//----------------------------------------------------------------------
1420// DumpELFSectionHeader_sh_flags
1421//
1422// Dump an token value for the ELF section header member sh_flags
1423//----------------------------------------------------------------------
1424void
1425ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
1426{
1427    *s  << ((sh_flags & SHF_WRITE) ? "WRITE" : "     ")
1428        << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1429        << ((sh_flags & SHF_ALLOC) ? "ALLOC" : "     ")
1430        << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1431        << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : "         ");
1432}
1433
1434//----------------------------------------------------------------------
1435// DumpELFSectionHeaders
1436//
1437// Dump all of the ELF section header to the specified output stream
1438//----------------------------------------------------------------------
1439void
1440ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1441{
1442    if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1443        return;
1444
1445    s->PutCString("Section Headers\n");
1446    s->PutCString("IDX  name     type         flags                            "
1447                  "addr     offset   size     link     info     addralgn "
1448                  "entsize  Name\n");
1449    s->PutCString("==== -------- ------------ -------------------------------- "
1450                  "-------- -------- -------- -------- -------- -------- "
1451                  "-------- ====================\n");
1452
1453    uint32_t idx = 0;
1454    for (SectionHeaderCollConstIter I = m_section_headers.begin();
1455         I != m_section_headers.end(); ++I, ++idx)
1456    {
1457        s->Printf("[%2u] ", idx);
1458        ObjectFileELF::DumpELFSectionHeader(s, *I);
1459        const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
1460        if (section_name)
1461            *s << ' ' << section_name << "\n";
1462    }
1463}
1464
1465void
1466ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1467{
1468    size_t num_modules = ParseDependentModules();
1469
1470    if (num_modules > 0)
1471    {
1472        s->PutCString("Dependent Modules:\n");
1473        for (unsigned i = 0; i < num_modules; ++i)
1474        {
1475            const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1476            s->Printf("   %s\n", spec.GetFilename().GetCString());
1477        }
1478    }
1479}
1480
1481bool
1482ObjectFileELF::GetArchitecture (ArchSpec &arch)
1483{
1484    if (!ParseHeader())
1485        return false;
1486
1487    arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
1488    arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1489    arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
1490    return true;
1491}
1492
1493ObjectFile::Type
1494ObjectFileELF::CalculateType()
1495{
1496    switch (m_header.e_type)
1497    {
1498        case llvm::ELF::ET_NONE:
1499            // 0 - No file type
1500            return eTypeUnknown;
1501
1502        case llvm::ELF::ET_REL:
1503            // 1 - Relocatable file
1504            return eTypeObjectFile;
1505
1506        case llvm::ELF::ET_EXEC:
1507            // 2 - Executable file
1508            return eTypeExecutable;
1509
1510        case llvm::ELF::ET_DYN:
1511            // 3 - Shared object file
1512            return eTypeSharedLibrary;
1513
1514        case ET_CORE:
1515            // 4 - Core file
1516            return eTypeCoreFile;
1517
1518        default:
1519            break;
1520    }
1521    return eTypeUnknown;
1522}
1523
1524ObjectFile::Strata
1525ObjectFileELF::CalculateStrata()
1526{
1527    switch (m_header.e_type)
1528    {
1529        case llvm::ELF::ET_NONE:
1530            // 0 - No file type
1531            return eStrataUnknown;
1532
1533        case llvm::ELF::ET_REL:
1534            // 1 - Relocatable file
1535            return eStrataUnknown;
1536
1537        case llvm::ELF::ET_EXEC:
1538            // 2 - Executable file
1539            // TODO: is there any way to detect that an executable is a kernel
1540            // related executable by inspecting the program headers, section
1541            // headers, symbols, or any other flag bits???
1542            return eStrataUser;
1543
1544        case llvm::ELF::ET_DYN:
1545            // 3 - Shared object file
1546            // TODO: is there any way to detect that an shared library is a kernel
1547            // related executable by inspecting the program headers, section
1548            // headers, symbols, or any other flag bits???
1549            return eStrataUnknown;
1550
1551        case ET_CORE:
1552            // 4 - Core file
1553            // TODO: is there any way to detect that an core file is a kernel
1554            // related executable by inspecting the program headers, section
1555            // headers, symbols, or any other flag bits???
1556            return eStrataUnknown;
1557
1558        default:
1559            break;
1560    }
1561    return eStrataUnknown;
1562}
1563
1564