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