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