ObjectFileELF.cpp revision 7940069905bee0b2e5f0661bf37c9f906ddf8603
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
238/*
239 * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
240 *
241 *   COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
242 *   code or tables extracted from it, as desired without restriction.
243 */
244static uint32_t
245calc_gnu_debuglink_crc32(const void *buf, size_t size)
246{
247    static const uint32_t g_crc32_tab[] =
248    {
249        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
250        0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
251        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
252        0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
253        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
254        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
255        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
256        0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
257        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
258        0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
259        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
260        0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
261        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
262        0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
263        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
264        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
265        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
266        0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
267        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
268        0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
269        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
270        0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
271        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
272        0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
273        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
274        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
275        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
276        0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
277        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
278        0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
279        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
280        0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
281        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
282        0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
283        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
284        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
285        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
286        0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
287        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
288        0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
289        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
290        0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
291        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
292    };
293    const uint8_t *p = (const uint8_t *)buf;
294    uint32_t crc;
295
296    crc = ~0U;
297    while (size--)
298        crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
299    return crc ^ ~0U;
300}
301
302size_t
303ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
304                                        lldb::DataBufferSP& data_sp,
305                                        lldb::offset_t data_offset,
306                                        lldb::offset_t file_offset,
307                                        lldb::offset_t length,
308                                        lldb_private::ModuleSpecList &specs)
309{
310    const size_t initial_count = specs.GetSize();
311
312    if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
313    {
314        DataExtractor data;
315        data.SetData(data_sp);
316        elf::ELFHeader header;
317        if (header.Parse(data, &data_offset))
318        {
319            if (data_sp)
320            {
321                ModuleSpec spec;
322                spec.GetFileSpec() = file;
323                spec.GetArchitecture().SetArchitecture(eArchTypeELF,
324                                                       header.e_machine,
325                                                       LLDB_INVALID_CPUTYPE);
326                if (spec.GetArchitecture().IsValid())
327                {
328                    // We could parse the ABI tag information (in .note, .notes, or .note.ABI-tag) to get the
329                    // machine information. However, this info isn't guaranteed to exist or be correct. Details:
330                    //  http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
331                    // Instead of passing potentially incorrect information down the pipeline, grab
332                    // the host information and use it.
333                    spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString());
334                    spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString());
335
336                    // Try to get the UUID from the section list. Usually that's at the end, so
337                    // map the file in if we don't have it already.
338                    size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
339                    if (section_header_end > data_sp->GetByteSize())
340                    {
341                        data_sp = file.MemoryMapFileContents (file_offset, section_header_end);
342                        data.SetData(data_sp);
343                    }
344
345                    uint32_t gnu_debuglink_crc = 0;
346                    std::string gnu_debuglink_file;
347                    SectionHeaderColl section_headers;
348                    lldb_private::UUID &uuid = spec.GetUUID();
349                    GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc);
350
351                    if (!uuid.IsValid())
352                    {
353                        if (!gnu_debuglink_crc)
354                        {
355                            // Need to map entire file into memory to calculate the crc.
356                            data_sp = file.MemoryMapFileContents (file_offset, SIZE_MAX);
357                            data.SetData(data_sp);
358                            gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
359                        }
360                        if (gnu_debuglink_crc)
361                        {
362                            // Use 4 bytes of crc from the .gnu_debuglink section.
363                            uint32_t uuidt[4] = { gnu_debuglink_crc, 0, 0, 0 };
364                            uuid.SetBytes (uuidt, sizeof(uuidt));
365                        }
366                    }
367
368                    specs.Append(spec);
369                }
370            }
371        }
372    }
373
374    return specs.GetSize() - initial_count;
375}
376
377//------------------------------------------------------------------
378// PluginInterface protocol
379//------------------------------------------------------------------
380lldb_private::ConstString
381ObjectFileELF::GetPluginName()
382{
383    return GetPluginNameStatic();
384}
385
386uint32_t
387ObjectFileELF::GetPluginVersion()
388{
389    return m_plugin_version;
390}
391//------------------------------------------------------------------
392// ObjectFile protocol
393//------------------------------------------------------------------
394
395ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
396                              DataBufferSP& data_sp,
397                              lldb::offset_t data_offset,
398                              const FileSpec* file,
399                              lldb::offset_t file_offset,
400                              lldb::offset_t length) :
401    ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
402    m_header(),
403    m_program_headers(),
404    m_section_headers(),
405    m_filespec_ap()
406{
407    if (file)
408        m_file = *file;
409    ::memset(&m_header, 0, sizeof(m_header));
410    m_gnu_debuglink_crc = 0;
411    m_gnu_debuglink_file.clear();
412}
413
414ObjectFileELF::~ObjectFileELF()
415{
416}
417
418bool
419ObjectFileELF::IsExecutable() const
420{
421    return m_header.e_entry != 0;
422}
423
424ByteOrder
425ObjectFileELF::GetByteOrder() const
426{
427    if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
428        return eByteOrderBig;
429    if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
430        return eByteOrderLittle;
431    return eByteOrderInvalid;
432}
433
434uint32_t
435ObjectFileELF::GetAddressByteSize() const
436{
437    return m_data.GetAddressByteSize();
438}
439
440size_t
441ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
442{
443    return std::distance(m_section_headers.begin(), I) + 1u;
444}
445
446size_t
447ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
448{
449    return std::distance(m_section_headers.begin(), I) + 1u;
450}
451
452bool
453ObjectFileELF::ParseHeader()
454{
455    lldb::offset_t offset = 0;
456    return m_header.Parse(m_data, &offset);
457}
458
459bool
460ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
461{
462    // Need to parse the section list to get the UUIDs, so make sure that's been done.
463    if (!ParseSectionHeaders())
464        return false;
465
466    if (m_uuid.IsValid())
467    {
468        // We have the full build id uuid.
469        *uuid = m_uuid;
470        return true;
471    }
472    else
473    {
474        if (!m_gnu_debuglink_crc)
475            m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
476        if (m_gnu_debuglink_crc)
477        {
478            // Use 4 bytes of crc from the .gnu_debuglink section.
479            uint32_t uuidt[4] = { m_gnu_debuglink_crc, 0, 0, 0 };
480            uuid->SetBytes (uuidt, sizeof(uuidt));
481            return true;
482        }
483    }
484
485    return false;
486}
487
488lldb_private::FileSpecList
489ObjectFileELF::GetDebugSymbolFilePaths()
490{
491    FileSpecList file_spec_list;
492
493    if (!m_gnu_debuglink_file.empty())
494    {
495        FileSpec file_spec (m_gnu_debuglink_file.c_str(), false);
496        file_spec_list.Append (file_spec);
497    }
498    return file_spec_list;
499}
500
501uint32_t
502ObjectFileELF::GetDependentModules(FileSpecList &files)
503{
504    size_t num_modules = ParseDependentModules();
505    uint32_t num_specs = 0;
506
507    for (unsigned i = 0; i < num_modules; ++i)
508    {
509        if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
510            num_specs++;
511    }
512
513    return num_specs;
514}
515
516Address
517ObjectFileELF::GetImageInfoAddress()
518{
519    if (!ParseDynamicSymbols())
520        return Address();
521
522    SectionList *section_list = GetSectionList();
523    if (!section_list)
524        return Address();
525
526    // Find the SHT_DYNAMIC (.dynamic) section.
527    SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
528    if (!dynsym_section_sp)
529        return Address();
530    assert (dynsym_section_sp->GetObjectFile() == this);
531
532    user_id_t dynsym_id = dynsym_section_sp->GetID();
533    const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
534    if (!dynsym_hdr)
535        return Address();
536
537    for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
538    {
539        ELFDynamic &symbol = m_dynamic_symbols[i];
540
541        if (symbol.d_tag == DT_DEBUG)
542        {
543            // Compute the offset as the number of previous entries plus the
544            // size of d_tag.
545            addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
546            return Address(dynsym_section_sp, offset);
547        }
548    }
549
550    return Address();
551}
552
553lldb_private::Address
554ObjectFileELF::GetEntryPointAddress ()
555{
556    if (m_entry_point_address.IsValid())
557        return m_entry_point_address;
558
559    if (!ParseHeader() || !IsExecutable())
560        return m_entry_point_address;
561
562    SectionList *section_list = GetSectionList();
563    addr_t offset = m_header.e_entry;
564
565    if (!section_list)
566        m_entry_point_address.SetOffset(offset);
567    else
568        m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
569    return m_entry_point_address;
570}
571
572//----------------------------------------------------------------------
573// ParseDependentModules
574//----------------------------------------------------------------------
575size_t
576ObjectFileELF::ParseDependentModules()
577{
578    if (m_filespec_ap.get())
579        return m_filespec_ap->GetSize();
580
581    m_filespec_ap.reset(new FileSpecList());
582
583    if (!ParseSectionHeaders())
584        return 0;
585
586    SectionList *section_list = GetSectionList();
587    if (!section_list)
588        return 0;
589
590    // Find the SHT_DYNAMIC section.
591    Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
592    if (!dynsym)
593        return 0;
594    assert (dynsym->GetObjectFile() == this);
595
596    const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
597    if (!header)
598        return 0;
599    // sh_link: section header index of string table used by entries in the section.
600    Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
601    if (!dynstr)
602        return 0;
603
604    DataExtractor dynsym_data;
605    DataExtractor dynstr_data;
606    if (ReadSectionData(dynsym, dynsym_data) &&
607        ReadSectionData(dynstr, dynstr_data))
608    {
609        ELFDynamic symbol;
610        const lldb::offset_t section_size = dynsym_data.GetByteSize();
611        lldb::offset_t offset = 0;
612
613        // The only type of entries we are concerned with are tagged DT_NEEDED,
614        // yielding the name of a required library.
615        while (offset < section_size)
616        {
617            if (!symbol.Parse(dynsym_data, &offset))
618                break;
619
620            if (symbol.d_tag != DT_NEEDED)
621                continue;
622
623            uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
624            const char *lib_name = dynstr_data.PeekCStr(str_index);
625            m_filespec_ap->Append(FileSpec(lib_name, true));
626        }
627    }
628
629    return m_filespec_ap->GetSize();
630}
631
632//----------------------------------------------------------------------
633// ParseProgramHeaders
634//----------------------------------------------------------------------
635size_t
636ObjectFileELF::ParseProgramHeaders()
637{
638    // We have already parsed the program headers
639    if (!m_program_headers.empty())
640        return m_program_headers.size();
641
642    // If there are no program headers to read we are done.
643    if (m_header.e_phnum == 0)
644        return 0;
645
646    m_program_headers.resize(m_header.e_phnum);
647    if (m_program_headers.size() != m_header.e_phnum)
648        return 0;
649
650    const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
651    const elf_off ph_offset = m_header.e_phoff;
652    DataExtractor data;
653    if (GetData (ph_offset, ph_size, data) != ph_size)
654        return 0;
655
656    uint32_t idx;
657    lldb::offset_t offset;
658    for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
659    {
660        if (m_program_headers[idx].Parse(data, &offset) == false)
661            break;
662    }
663
664    if (idx < m_program_headers.size())
665        m_program_headers.resize(idx);
666
667    return m_program_headers.size();
668}
669
670static bool
671ParseNoteGNUBuildID(DataExtractor &data, lldb_private::UUID &uuid)
672{
673    // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
674    // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
675    struct
676    {
677        uint32_t name_len;  // Length of note name
678        uint32_t desc_len;  // Length of note descriptor
679        uint32_t type;      // Type of note (1 is ABI_TAG, 3 is BUILD_ID)
680    } notehdr;
681    lldb::offset_t offset = 0;
682    static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
683
684    while (true)
685    {
686        if (data.GetU32 (&offset, &notehdr, 3) == NULL)
687            return false;
688
689        notehdr.name_len = llvm::RoundUpToAlignment (notehdr.name_len, 4);
690        notehdr.desc_len = llvm::RoundUpToAlignment (notehdr.desc_len, 4);
691
692        lldb::offset_t offset_next_note = offset + notehdr.name_len + notehdr.desc_len;
693
694        // 16 bytes is UUID|MD5, 20 bytes is SHA1
695        if ((notehdr.type == g_gnu_build_id) && (notehdr.name_len == 4) &&
696            (notehdr.desc_len == 16 || notehdr.desc_len == 20))
697        {
698            char name[4];
699            if (data.GetU8 (&offset, name, 4) == NULL)
700                return false;
701            if (!strcmp(name, "GNU"))
702            {
703                uint8_t uuidbuf[20];
704                if (data.GetU8 (&offset, &uuidbuf, notehdr.desc_len) == NULL)
705                    return false;
706                uuid.SetBytes (uuidbuf, notehdr.desc_len);
707                return true;
708            }
709        }
710        offset = offset_next_note;
711    }
712    return false;
713}
714
715//----------------------------------------------------------------------
716// GetSectionHeaderInfo
717//----------------------------------------------------------------------
718size_t
719ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
720                                    lldb_private::DataExtractor &object_data,
721                                    const elf::ELFHeader &header,
722                                    lldb_private::UUID &uuid,
723                                    std::string &gnu_debuglink_file,
724                                    uint32_t &gnu_debuglink_crc)
725{
726    // We have already parsed the section headers
727    if (!section_headers.empty())
728        return section_headers.size();
729
730    // If there are no section headers we are done.
731    if (header.e_shnum == 0)
732        return 0;
733
734    section_headers.resize(header.e_shnum);
735    if (section_headers.size() != header.e_shnum)
736        return 0;
737
738    const size_t sh_size = header.e_shnum * header.e_shentsize;
739    const elf_off sh_offset = header.e_shoff;
740    DataExtractor sh_data;
741    if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
742        return 0;
743
744    uint32_t idx;
745    lldb::offset_t offset;
746    for (idx = 0, offset = 0; idx < header.e_shnum; ++idx)
747    {
748        if (section_headers[idx].Parse(sh_data, &offset) == false)
749            break;
750    }
751    if (idx < section_headers.size())
752        section_headers.resize(idx);
753
754    const unsigned strtab_idx = header.e_shstrndx;
755    if (strtab_idx && strtab_idx < section_headers.size())
756    {
757        const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
758        const size_t byte_size = sheader.sh_size;
759        const Elf64_Off offset = sheader.sh_offset;
760        lldb_private::DataExtractor shstr_data;
761
762        if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
763        {
764            for (SectionHeaderCollIter I = section_headers.begin();
765                 I != section_headers.end(); ++I)
766            {
767                static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
768                const ELFSectionHeaderInfo &header = *I;
769                const uint64_t section_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
770                ConstString name(shstr_data.PeekCStr(I->sh_name));
771
772                I->section_name = name;
773
774                if (name == g_sect_name_gnu_debuglink)
775                {
776                    DataExtractor data;
777                    if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
778                    {
779                        lldb::offset_t gnu_debuglink_offset = 0;
780                        gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
781                        gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
782                        data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
783                    }
784                }
785
786                if (header.sh_type == SHT_NOTE && !uuid.IsValid())
787                {
788                    DataExtractor data;
789                    if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
790                    {
791                        ParseNoteGNUBuildID (data, uuid);
792                    }
793                }
794            }
795
796            return section_headers.size();
797        }
798    }
799
800    section_headers.clear();
801    return 0;
802}
803
804//----------------------------------------------------------------------
805// ParseSectionHeaders
806//----------------------------------------------------------------------
807size_t
808ObjectFileELF::ParseSectionHeaders()
809{
810    return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
811}
812
813const ObjectFileELF::ELFSectionHeaderInfo *
814ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
815{
816    if (!ParseSectionHeaders() || !id)
817        return NULL;
818
819    if (--id < m_section_headers.size())
820        return &m_section_headers[id];
821
822    return NULL;
823}
824
825void
826ObjectFileELF::CreateSections(SectionList &unified_section_list)
827{
828    if (!m_sections_ap.get() && ParseSectionHeaders())
829    {
830        m_sections_ap.reset(new SectionList());
831
832        for (SectionHeaderCollIter I = m_section_headers.begin();
833             I != m_section_headers.end(); ++I)
834        {
835            const ELFSectionHeaderInfo &header = *I;
836
837            ConstString& name = I->section_name;
838            const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
839            const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
840
841            static ConstString g_sect_name_text (".text");
842            static ConstString g_sect_name_data (".data");
843            static ConstString g_sect_name_bss (".bss");
844            static ConstString g_sect_name_tdata (".tdata");
845            static ConstString g_sect_name_tbss (".tbss");
846            static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
847            static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
848            static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
849            static ConstString g_sect_name_dwarf_debug_info (".debug_info");
850            static ConstString g_sect_name_dwarf_debug_line (".debug_line");
851            static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
852            static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
853            static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
854            static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
855            static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
856            static ConstString g_sect_name_dwarf_debug_str (".debug_str");
857            static ConstString g_sect_name_eh_frame (".eh_frame");
858
859            SectionType sect_type = eSectionTypeOther;
860
861            bool is_thread_specific = false;
862
863            if      (name == g_sect_name_text)                  sect_type = eSectionTypeCode;
864            else if (name == g_sect_name_data)                  sect_type = eSectionTypeData;
865            else if (name == g_sect_name_bss)                   sect_type = eSectionTypeZeroFill;
866            else if (name == g_sect_name_tdata)
867            {
868                sect_type = eSectionTypeData;
869                is_thread_specific = true;
870            }
871            else if (name == g_sect_name_tbss)
872            {
873                sect_type = eSectionTypeZeroFill;
874                is_thread_specific = true;
875            }
876            // .debug_abbrev – Abbreviations used in the .debug_info section
877            // .debug_aranges – Lookup table for mapping addresses to compilation units
878            // .debug_frame – Call frame information
879            // .debug_info – The core DWARF information section
880            // .debug_line – Line number information
881            // .debug_loc – Location lists used in DW_AT_location attributes
882            // .debug_macinfo – Macro information
883            // .debug_pubnames – Lookup table for mapping object and function names to compilation units
884            // .debug_pubtypes – Lookup table for mapping type names to compilation units
885            // .debug_ranges – Address ranges used in DW_AT_ranges attributes
886            // .debug_str – String table used in .debug_info
887            // MISSING? .debug-index http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
888            // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
889            else if (name == g_sect_name_dwarf_debug_abbrev)    sect_type = eSectionTypeDWARFDebugAbbrev;
890            else if (name == g_sect_name_dwarf_debug_aranges)   sect_type = eSectionTypeDWARFDebugAranges;
891            else if (name == g_sect_name_dwarf_debug_frame)     sect_type = eSectionTypeDWARFDebugFrame;
892            else if (name == g_sect_name_dwarf_debug_info)      sect_type = eSectionTypeDWARFDebugInfo;
893            else if (name == g_sect_name_dwarf_debug_line)      sect_type = eSectionTypeDWARFDebugLine;
894            else if (name == g_sect_name_dwarf_debug_loc)       sect_type = eSectionTypeDWARFDebugLoc;
895            else if (name == g_sect_name_dwarf_debug_macinfo)   sect_type = eSectionTypeDWARFDebugMacInfo;
896            else if (name == g_sect_name_dwarf_debug_pubnames)  sect_type = eSectionTypeDWARFDebugPubNames;
897            else if (name == g_sect_name_dwarf_debug_pubtypes)  sect_type = eSectionTypeDWARFDebugPubTypes;
898            else if (name == g_sect_name_dwarf_debug_ranges)    sect_type = eSectionTypeDWARFDebugRanges;
899            else if (name == g_sect_name_dwarf_debug_str)       sect_type = eSectionTypeDWARFDebugStr;
900            else if (name == g_sect_name_eh_frame)              sect_type = eSectionTypeEHFrame;
901
902            switch (header.sh_type)
903            {
904                case SHT_SYMTAB:
905                    assert (sect_type == eSectionTypeOther);
906                    sect_type = eSectionTypeELFSymbolTable;
907                    break;
908                case SHT_DYNSYM:
909                    assert (sect_type == eSectionTypeOther);
910                    sect_type = eSectionTypeELFDynamicSymbols;
911                    break;
912                case SHT_RELA:
913                case SHT_REL:
914                    assert (sect_type == eSectionTypeOther);
915                    sect_type = eSectionTypeELFRelocationEntries;
916                    break;
917                case SHT_DYNAMIC:
918                    assert (sect_type == eSectionTypeOther);
919                    sect_type = eSectionTypeELFDynamicLinkInfo;
920                    break;
921            }
922
923            SectionSP section_sp (new Section(GetModule(),        // Module to which this section belongs.
924                                              this,               // ObjectFile to which this section belongs and should read section data from.
925                                              SectionIndex(I),    // Section ID.
926                                              name,               // Section name.
927                                              sect_type,          // Section type.
928                                              header.sh_addr,     // VM address.
929                                              vm_size,            // VM size in bytes of this section.
930                                              header.sh_offset,   // Offset of this section in the file.
931                                              file_size,          // Size of the section as found in the file.
932                                              header.sh_flags));  // Flags for this section.
933
934            if (is_thread_specific)
935                section_sp->SetIsThreadSpecific (is_thread_specific);
936            m_sections_ap->AddSection(section_sp);
937        }
938    }
939
940    if (m_sections_ap.get())
941    {
942        if (GetType() == eTypeDebugInfo)
943        {
944            static const SectionType g_sections[] =
945            {
946                eSectionTypeDWARFDebugAranges,
947                eSectionTypeDWARFDebugInfo,
948                eSectionTypeDWARFDebugAbbrev,
949                eSectionTypeDWARFDebugFrame,
950                eSectionTypeDWARFDebugLine,
951                eSectionTypeDWARFDebugStr,
952                eSectionTypeDWARFDebugLoc,
953                eSectionTypeDWARFDebugMacInfo,
954                eSectionTypeDWARFDebugPubNames,
955                eSectionTypeDWARFDebugPubTypes,
956                eSectionTypeDWARFDebugRanges,
957                eSectionTypeELFSymbolTable,
958            };
959            SectionList *elf_section_list = m_sections_ap.get();
960            for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
961            {
962                SectionType section_type = g_sections[idx];
963                SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
964                if (section_sp)
965                {
966                    SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
967                    if (module_section_sp)
968                        unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
969                    else
970                        unified_section_list.AddSection (section_sp);
971                }
972            }
973        }
974        else
975        {
976            unified_section_list = *m_sections_ap;
977        }
978    }
979}
980
981// private
982unsigned
983ObjectFileELF::ParseSymbols (Symtab *symtab,
984                             user_id_t start_id,
985                             SectionList *section_list,
986                             const size_t num_symbols,
987                             const DataExtractor &symtab_data,
988                             const DataExtractor &strtab_data)
989{
990    ELFSymbol symbol;
991    lldb::offset_t offset = 0;
992
993    static ConstString text_section_name(".text");
994    static ConstString init_section_name(".init");
995    static ConstString fini_section_name(".fini");
996    static ConstString ctors_section_name(".ctors");
997    static ConstString dtors_section_name(".dtors");
998
999    static ConstString data_section_name(".data");
1000    static ConstString rodata_section_name(".rodata");
1001    static ConstString rodata1_section_name(".rodata1");
1002    static ConstString data2_section_name(".data1");
1003    static ConstString bss_section_name(".bss");
1004
1005    //StreamFile strm(stdout, false);
1006    unsigned i;
1007    for (i = 0; i < num_symbols; ++i)
1008    {
1009        if (symbol.Parse(symtab_data, &offset) == false)
1010            break;
1011
1012        const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1013
1014        // No need to add symbols that have no names
1015        if (symbol_name == NULL || symbol_name[0] == '\0')
1016            continue;
1017
1018        //symbol.Dump (&strm, i, &strtab_data, section_list);
1019
1020        SectionSP symbol_section_sp;
1021        SymbolType symbol_type = eSymbolTypeInvalid;
1022        Elf64_Half symbol_idx = symbol.st_shndx;
1023
1024        switch (symbol_idx)
1025        {
1026        case SHN_ABS:
1027            symbol_type = eSymbolTypeAbsolute;
1028            break;
1029        case SHN_UNDEF:
1030            symbol_type = eSymbolTypeUndefined;
1031            break;
1032        default:
1033            symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
1034            break;
1035        }
1036
1037        // If a symbol is undefined do not process it further even if it has a STT type
1038        if (symbol_type != eSymbolTypeUndefined)
1039        {
1040            switch (symbol.getType())
1041            {
1042            default:
1043            case STT_NOTYPE:
1044                // The symbol's type is not specified.
1045                break;
1046
1047            case STT_OBJECT:
1048                // The symbol is associated with a data object, such as a variable,
1049                // an array, etc.
1050                symbol_type = eSymbolTypeData;
1051                break;
1052
1053            case STT_FUNC:
1054                // The symbol is associated with a function or other executable code.
1055                symbol_type = eSymbolTypeCode;
1056                break;
1057
1058            case STT_SECTION:
1059                // The symbol is associated with a section. Symbol table entries of
1060                // this type exist primarily for relocation and normally have
1061                // STB_LOCAL binding.
1062                break;
1063
1064            case STT_FILE:
1065                // Conventionally, the symbol's name gives the name of the source
1066                // file associated with the object file. A file symbol has STB_LOCAL
1067                // binding, its section index is SHN_ABS, and it precedes the other
1068                // STB_LOCAL symbols for the file, if it is present.
1069                symbol_type = eSymbolTypeSourceFile;
1070                break;
1071
1072            case STT_GNU_IFUNC:
1073                // The symbol is associated with an indirect function. The actual
1074                // function will be resolved if it is referenced.
1075                symbol_type = eSymbolTypeResolver;
1076                break;
1077            }
1078        }
1079
1080        if (symbol_type == eSymbolTypeInvalid)
1081        {
1082            if (symbol_section_sp)
1083            {
1084                const ConstString &sect_name = symbol_section_sp->GetName();
1085                if (sect_name == text_section_name ||
1086                    sect_name == init_section_name ||
1087                    sect_name == fini_section_name ||
1088                    sect_name == ctors_section_name ||
1089                    sect_name == dtors_section_name)
1090                {
1091                    symbol_type = eSymbolTypeCode;
1092                }
1093                else if (sect_name == data_section_name ||
1094                         sect_name == data2_section_name ||
1095                         sect_name == rodata_section_name ||
1096                         sect_name == rodata1_section_name ||
1097                         sect_name == bss_section_name)
1098                {
1099                    symbol_type = eSymbolTypeData;
1100                }
1101            }
1102        }
1103
1104        // If the symbol section we've found has no data (SHT_NOBITS), then check the module section
1105        // list. This can happen if we're parsing the debug file and it has no .text section, for example.
1106        if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
1107        {
1108            ModuleSP module_sp(GetModule());
1109            if (module_sp)
1110            {
1111                SectionList *module_section_list = module_sp->GetSectionList();
1112                if (module_section_list && module_section_list != section_list)
1113                {
1114                    const ConstString &sect_name = symbol_section_sp->GetName();
1115                    lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name));
1116                    if (section_sp && section_sp->GetFileSize())
1117                    {
1118                        symbol_section_sp = section_sp;
1119                    }
1120                }
1121            }
1122        }
1123
1124        uint64_t symbol_value = symbol.st_value;
1125        if (symbol_section_sp)
1126            symbol_value -= symbol_section_sp->GetFileAddress();
1127        bool is_global = symbol.getBinding() == STB_GLOBAL;
1128        uint32_t flags = symbol.st_other << 8 | symbol.st_info;
1129        bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
1130        Symbol dc_symbol(
1131            i + start_id,       // ID is the original symbol table index.
1132            symbol_name,        // Symbol name.
1133            is_mangled,         // Is the symbol name mangled?
1134            symbol_type,        // Type of this symbol
1135            is_global,          // Is this globally visible?
1136            false,              // Is this symbol debug info?
1137            false,              // Is this symbol a trampoline?
1138            false,              // Is this symbol artificial?
1139            symbol_section_sp,  // Section in which this symbol is defined or null.
1140            symbol_value,       // Offset in section or symbol value.
1141            symbol.st_size,     // Size in bytes of this symbol.
1142            true,               // Size is valid
1143            flags);             // Symbol flags.
1144        symtab->AddSymbol(dc_symbol);
1145    }
1146
1147    return i;
1148}
1149
1150unsigned
1151ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
1152{
1153    if (symtab->GetObjectFile() != this)
1154    {
1155        // If the symbol table section is owned by a different object file, have it do the
1156        // parsing.
1157        ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
1158        return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
1159    }
1160
1161    // Get section list for this object file.
1162    SectionList *section_list = m_sections_ap.get();
1163    if (!section_list)
1164        return 0;
1165
1166    user_id_t symtab_id = symtab->GetID();
1167    const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
1168    assert(symtab_hdr->sh_type == SHT_SYMTAB ||
1169           symtab_hdr->sh_type == SHT_DYNSYM);
1170
1171    // sh_link: section header index of associated string table.
1172    // Section ID's are ones based.
1173    user_id_t strtab_id = symtab_hdr->sh_link + 1;
1174    Section *strtab = section_list->FindSectionByID(strtab_id).get();
1175
1176    unsigned num_symbols = 0;
1177    if (symtab && strtab)
1178    {
1179        assert (symtab->GetObjectFile() == this);
1180        assert (strtab->GetObjectFile() == this);
1181
1182        DataExtractor symtab_data;
1183        DataExtractor strtab_data;
1184        if (ReadSectionData(symtab, symtab_data) &&
1185            ReadSectionData(strtab, strtab_data))
1186        {
1187            size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
1188
1189            num_symbols = ParseSymbols(symbol_table, start_id,
1190                                       section_list, num_symbols,
1191                                       symtab_data, strtab_data);
1192        }
1193    }
1194
1195    return num_symbols;
1196}
1197
1198size_t
1199ObjectFileELF::ParseDynamicSymbols()
1200{
1201    if (m_dynamic_symbols.size())
1202        return m_dynamic_symbols.size();
1203
1204    SectionList *section_list = GetSectionList();
1205    if (!section_list)
1206        return 0;
1207
1208    // Find the SHT_DYNAMIC section.
1209    Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
1210    if (!dynsym)
1211        return 0;
1212    assert (dynsym->GetObjectFile() == this);
1213
1214    ELFDynamic symbol;
1215    DataExtractor dynsym_data;
1216    if (ReadSectionData(dynsym, dynsym_data))
1217    {
1218        const lldb::offset_t section_size = dynsym_data.GetByteSize();
1219        lldb::offset_t cursor = 0;
1220
1221        while (cursor < section_size)
1222        {
1223            if (!symbol.Parse(dynsym_data, &cursor))
1224                break;
1225
1226            m_dynamic_symbols.push_back(symbol);
1227        }
1228    }
1229
1230    return m_dynamic_symbols.size();
1231}
1232
1233const ELFDynamic *
1234ObjectFileELF::FindDynamicSymbol(unsigned tag)
1235{
1236    if (!ParseDynamicSymbols())
1237        return NULL;
1238
1239    DynamicSymbolCollIter I = m_dynamic_symbols.begin();
1240    DynamicSymbolCollIter E = m_dynamic_symbols.end();
1241    for ( ; I != E; ++I)
1242    {
1243        ELFDynamic *symbol = &*I;
1244
1245        if (symbol->d_tag == tag)
1246            return symbol;
1247    }
1248
1249    return NULL;
1250}
1251
1252unsigned
1253ObjectFileELF::PLTRelocationType()
1254{
1255    const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
1256
1257    if (symbol)
1258        return symbol->d_val;
1259
1260    return 0;
1261}
1262
1263static unsigned
1264ParsePLTRelocations(Symtab *symbol_table,
1265                    user_id_t start_id,
1266                    unsigned rel_type,
1267                    const ELFHeader *hdr,
1268                    const ELFSectionHeader *rel_hdr,
1269                    const ELFSectionHeader *plt_hdr,
1270                    const ELFSectionHeader *sym_hdr,
1271                    const lldb::SectionSP &plt_section_sp,
1272                    DataExtractor &rel_data,
1273                    DataExtractor &symtab_data,
1274                    DataExtractor &strtab_data)
1275{
1276    ELFRelocation rel(rel_type);
1277    ELFSymbol symbol;
1278    lldb::offset_t offset = 0;
1279    const elf_xword plt_entsize = plt_hdr->sh_entsize;
1280    const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
1281
1282    typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1283    reloc_info_fn reloc_type;
1284    reloc_info_fn reloc_symbol;
1285
1286    if (hdr->Is32Bit())
1287    {
1288        reloc_type = ELFRelocation::RelocType32;
1289        reloc_symbol = ELFRelocation::RelocSymbol32;
1290    }
1291    else
1292    {
1293        reloc_type = ELFRelocation::RelocType64;
1294        reloc_symbol = ELFRelocation::RelocSymbol64;
1295    }
1296
1297    unsigned slot_type = hdr->GetRelocationJumpSlotType();
1298    unsigned i;
1299    for (i = 0; i < num_relocations; ++i)
1300    {
1301        if (rel.Parse(rel_data, &offset) == false)
1302            break;
1303
1304        if (reloc_type(rel) != slot_type)
1305            continue;
1306
1307        lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
1308        uint64_t plt_index = (i + 1) * plt_entsize;
1309
1310        if (!symbol.Parse(symtab_data, &symbol_offset))
1311            break;
1312
1313        const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1314        bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
1315
1316        Symbol jump_symbol(
1317            i + start_id,    // Symbol table index
1318            symbol_name,     // symbol name.
1319            is_mangled,      // is the symbol name mangled?
1320            eSymbolTypeTrampoline, // Type of this symbol
1321            false,           // Is this globally visible?
1322            false,           // Is this symbol debug info?
1323            true,            // Is this symbol a trampoline?
1324            true,            // Is this symbol artificial?
1325            plt_section_sp,  // Section in which this symbol is defined or null.
1326            plt_index,       // Offset in section or symbol value.
1327            plt_entsize,     // Size in bytes of this symbol.
1328            true,            // Size is valid
1329            0);              // Symbol flags.
1330
1331        symbol_table->AddSymbol(jump_symbol);
1332    }
1333
1334    return i;
1335}
1336
1337unsigned
1338ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1339                                      user_id_t start_id,
1340                                      const ELFSectionHeaderInfo *rel_hdr,
1341                                      user_id_t rel_id)
1342{
1343    assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1344
1345    // The link field points to the associated symbol table. The info field
1346    // points to the section holding the plt.
1347    user_id_t symtab_id = rel_hdr->sh_link;
1348    user_id_t plt_id = rel_hdr->sh_info;
1349
1350    if (!symtab_id || !plt_id)
1351        return 0;
1352
1353    // Section ID's are ones based;
1354    symtab_id++;
1355    plt_id++;
1356
1357    const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
1358    if (!plt_hdr)
1359        return 0;
1360
1361    const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
1362    if (!sym_hdr)
1363        return 0;
1364
1365    SectionList *section_list = m_sections_ap.get();
1366    if (!section_list)
1367        return 0;
1368
1369    Section *rel_section = section_list->FindSectionByID(rel_id).get();
1370    if (!rel_section)
1371        return 0;
1372
1373    SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1374    if (!plt_section_sp)
1375        return 0;
1376
1377    Section *symtab = section_list->FindSectionByID(symtab_id).get();
1378    if (!symtab)
1379        return 0;
1380
1381    // sh_link points to associated string table.
1382    Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1383    if (!strtab)
1384        return 0;
1385
1386    DataExtractor rel_data;
1387    if (!ReadSectionData(rel_section, rel_data))
1388        return 0;
1389
1390    DataExtractor symtab_data;
1391    if (!ReadSectionData(symtab, symtab_data))
1392        return 0;
1393
1394    DataExtractor strtab_data;
1395    if (!ReadSectionData(strtab, strtab_data))
1396        return 0;
1397
1398    unsigned rel_type = PLTRelocationType();
1399    if (!rel_type)
1400        return 0;
1401
1402    return ParsePLTRelocations (symbol_table,
1403                                start_id,
1404                                rel_type,
1405                                &m_header,
1406                                rel_hdr,
1407                                plt_hdr,
1408                                sym_hdr,
1409                                plt_section_sp,
1410                                rel_data,
1411                                symtab_data,
1412                                strtab_data);
1413}
1414
1415Symtab *
1416ObjectFileELF::GetSymtab()
1417{
1418    ModuleSP module_sp(GetModule());
1419    if (!module_sp)
1420        return NULL;
1421
1422    // We always want to use the main object file so we (hopefully) only have one cached copy
1423    // of our symtab, dynamic sections, etc.
1424    ObjectFile *module_obj_file = module_sp->GetObjectFile();
1425    if (module_obj_file && module_obj_file != this)
1426        return module_obj_file->GetSymtab();
1427
1428    if (m_symtab_ap.get() == NULL)
1429    {
1430        SectionList *section_list = GetSectionList();
1431        if (!section_list)
1432            return NULL;
1433
1434        uint64_t symbol_id = 0;
1435        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1436
1437        m_symtab_ap.reset(new Symtab(this));
1438
1439        // Sharable objects and dynamic executables usually have 2 distinct symbol
1440        // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
1441        // version of the symtab that only contains global symbols. The information found
1442        // in the dynsym is therefore also found in the symtab, while the reverse is not
1443        // necessarily true.
1444        Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
1445        if (!symtab)
1446        {
1447            // The symtab section is non-allocable and can be stripped, so if it doesn't exist
1448            // then use the dynsym section which should always be there.
1449            symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
1450        }
1451        if (symtab)
1452            symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
1453
1454        // Synthesize trampoline symbols to help navigate the PLT.
1455        const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
1456        if (symbol)
1457        {
1458            addr_t addr = symbol->d_ptr;
1459            Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
1460            if (reloc_section)
1461            {
1462                user_id_t reloc_id = reloc_section->GetID();
1463                const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
1464                assert(reloc_header);
1465
1466                ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
1467            }
1468        }
1469    }
1470    return m_symtab_ap.get();
1471}
1472
1473bool
1474ObjectFileELF::IsStripped ()
1475{
1476    // TODO: determine this for ELF
1477    return false;
1478}
1479
1480//===----------------------------------------------------------------------===//
1481// Dump
1482//
1483// Dump the specifics of the runtime file container (such as any headers
1484// segments, sections, etc).
1485//----------------------------------------------------------------------
1486void
1487ObjectFileELF::Dump(Stream *s)
1488{
1489    DumpELFHeader(s, m_header);
1490    s->EOL();
1491    DumpELFProgramHeaders(s);
1492    s->EOL();
1493    DumpELFSectionHeaders(s);
1494    s->EOL();
1495    SectionList *section_list = GetSectionList();
1496    if (section_list)
1497        section_list->Dump(s, NULL, true, UINT32_MAX);
1498    Symtab *symtab = GetSymtab();
1499    if (symtab)
1500        symtab->Dump(s, NULL, eSortOrderNone);
1501    s->EOL();
1502    DumpDependentModules(s);
1503    s->EOL();
1504}
1505
1506//----------------------------------------------------------------------
1507// DumpELFHeader
1508//
1509// Dump the ELF header to the specified output stream
1510//----------------------------------------------------------------------
1511void
1512ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
1513{
1514    s->PutCString("ELF Header\n");
1515    s->Printf("e_ident[EI_MAG0   ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1516    s->Printf("e_ident[EI_MAG1   ] = 0x%2.2x '%c'\n",
1517              header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1518    s->Printf("e_ident[EI_MAG2   ] = 0x%2.2x '%c'\n",
1519              header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1520    s->Printf("e_ident[EI_MAG3   ] = 0x%2.2x '%c'\n",
1521              header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
1522
1523    s->Printf("e_ident[EI_CLASS  ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1524    s->Printf("e_ident[EI_DATA   ] = 0x%2.2x ", header.e_ident[EI_DATA]);
1525    DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1526    s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1527    s->Printf ("e_ident[EI_PAD    ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1528
1529    s->Printf("e_type      = 0x%4.4x ", header.e_type);
1530    DumpELFHeader_e_type(s, header.e_type);
1531    s->Printf("\ne_machine   = 0x%4.4x\n", header.e_machine);
1532    s->Printf("e_version   = 0x%8.8x\n", header.e_version);
1533    s->Printf("e_entry     = 0x%8.8" PRIx64 "\n", header.e_entry);
1534    s->Printf("e_phoff     = 0x%8.8" PRIx64 "\n", header.e_phoff);
1535    s->Printf("e_shoff     = 0x%8.8" PRIx64 "\n", header.e_shoff);
1536    s->Printf("e_flags     = 0x%8.8x\n", header.e_flags);
1537    s->Printf("e_ehsize    = 0x%4.4x\n", header.e_ehsize);
1538    s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1539    s->Printf("e_phnum     = 0x%4.4x\n", header.e_phnum);
1540    s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1541    s->Printf("e_shnum     = 0x%4.4x\n", header.e_shnum);
1542    s->Printf("e_shstrndx  = 0x%4.4x\n", header.e_shstrndx);
1543}
1544
1545//----------------------------------------------------------------------
1546// DumpELFHeader_e_type
1547//
1548// Dump an token value for the ELF header member e_type
1549//----------------------------------------------------------------------
1550void
1551ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
1552{
1553    switch (e_type)
1554    {
1555    case ET_NONE:   *s << "ET_NONE"; break;
1556    case ET_REL:    *s << "ET_REL"; break;
1557    case ET_EXEC:   *s << "ET_EXEC"; break;
1558    case ET_DYN:    *s << "ET_DYN"; break;
1559    case ET_CORE:   *s << "ET_CORE"; break;
1560    default:
1561        break;
1562    }
1563}
1564
1565//----------------------------------------------------------------------
1566// DumpELFHeader_e_ident_EI_DATA
1567//
1568// Dump an token value for the ELF header member e_ident[EI_DATA]
1569//----------------------------------------------------------------------
1570void
1571ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
1572{
1573    switch (ei_data)
1574    {
1575    case ELFDATANONE:   *s << "ELFDATANONE"; break;
1576    case ELFDATA2LSB:   *s << "ELFDATA2LSB - Little Endian"; break;
1577    case ELFDATA2MSB:   *s << "ELFDATA2MSB - Big Endian"; break;
1578    default:
1579        break;
1580    }
1581}
1582
1583
1584//----------------------------------------------------------------------
1585// DumpELFProgramHeader
1586//
1587// Dump a single ELF program header to the specified output stream
1588//----------------------------------------------------------------------
1589void
1590ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
1591{
1592    DumpELFProgramHeader_p_type(s, ph.p_type);
1593    s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1594    s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags);
1595
1596    DumpELFProgramHeader_p_flags(s, ph.p_flags);
1597    s->Printf(") %8.8" PRIx64, ph.p_align);
1598}
1599
1600//----------------------------------------------------------------------
1601// DumpELFProgramHeader_p_type
1602//
1603// Dump an token value for the ELF program header member p_type which
1604// describes the type of the program header
1605// ----------------------------------------------------------------------
1606void
1607ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
1608{
1609    const int kStrWidth = 15;
1610    switch (p_type)
1611    {
1612    CASE_AND_STREAM(s, PT_NULL        , kStrWidth);
1613    CASE_AND_STREAM(s, PT_LOAD        , kStrWidth);
1614    CASE_AND_STREAM(s, PT_DYNAMIC     , kStrWidth);
1615    CASE_AND_STREAM(s, PT_INTERP      , kStrWidth);
1616    CASE_AND_STREAM(s, PT_NOTE        , kStrWidth);
1617    CASE_AND_STREAM(s, PT_SHLIB       , kStrWidth);
1618    CASE_AND_STREAM(s, PT_PHDR        , kStrWidth);
1619    CASE_AND_STREAM(s, PT_TLS         , kStrWidth);
1620    CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
1621    default:
1622        s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1623        break;
1624    }
1625}
1626
1627
1628//----------------------------------------------------------------------
1629// DumpELFProgramHeader_p_flags
1630//
1631// Dump an token value for the ELF program header member p_flags
1632//----------------------------------------------------------------------
1633void
1634ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
1635{
1636    *s  << ((p_flags & PF_X) ? "PF_X" : "    ")
1637        << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1638        << ((p_flags & PF_W) ? "PF_W" : "    ")
1639        << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1640        << ((p_flags & PF_R) ? "PF_R" : "    ");
1641}
1642
1643//----------------------------------------------------------------------
1644// DumpELFProgramHeaders
1645//
1646// Dump all of the ELF program header to the specified output stream
1647//----------------------------------------------------------------------
1648void
1649ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1650{
1651    if (ParseProgramHeaders())
1652    {
1653        s->PutCString("Program Headers\n");
1654        s->PutCString("IDX  p_type          p_offset p_vaddr  p_paddr  "
1655                      "p_filesz p_memsz  p_flags                   p_align\n");
1656        s->PutCString("==== --------------- -------- -------- -------- "
1657                      "-------- -------- ------------------------- --------\n");
1658
1659        uint32_t idx = 0;
1660        for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1661             I != m_program_headers.end(); ++I, ++idx)
1662        {
1663            s->Printf("[%2u] ", idx);
1664            ObjectFileELF::DumpELFProgramHeader(s, *I);
1665            s->EOL();
1666        }
1667    }
1668}
1669
1670//----------------------------------------------------------------------
1671// DumpELFSectionHeader
1672//
1673// Dump a single ELF section header to the specified output stream
1674//----------------------------------------------------------------------
1675void
1676ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
1677{
1678    s->Printf("%8.8x ", sh.sh_name);
1679    DumpELFSectionHeader_sh_type(s, sh.sh_type);
1680    s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
1681    DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
1682    s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr, sh.sh_offset, sh.sh_size);
1683    s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
1684    s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
1685}
1686
1687//----------------------------------------------------------------------
1688// DumpELFSectionHeader_sh_type
1689//
1690// Dump an token value for the ELF section header member sh_type which
1691// describes the type of the section
1692//----------------------------------------------------------------------
1693void
1694ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
1695{
1696    const int kStrWidth = 12;
1697    switch (sh_type)
1698    {
1699    CASE_AND_STREAM(s, SHT_NULL     , kStrWidth);
1700    CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1701    CASE_AND_STREAM(s, SHT_SYMTAB   , kStrWidth);
1702    CASE_AND_STREAM(s, SHT_STRTAB   , kStrWidth);
1703    CASE_AND_STREAM(s, SHT_RELA     , kStrWidth);
1704    CASE_AND_STREAM(s, SHT_HASH     , kStrWidth);
1705    CASE_AND_STREAM(s, SHT_DYNAMIC  , kStrWidth);
1706    CASE_AND_STREAM(s, SHT_NOTE     , kStrWidth);
1707    CASE_AND_STREAM(s, SHT_NOBITS   , kStrWidth);
1708    CASE_AND_STREAM(s, SHT_REL      , kStrWidth);
1709    CASE_AND_STREAM(s, SHT_SHLIB    , kStrWidth);
1710    CASE_AND_STREAM(s, SHT_DYNSYM   , kStrWidth);
1711    CASE_AND_STREAM(s, SHT_LOPROC   , kStrWidth);
1712    CASE_AND_STREAM(s, SHT_HIPROC   , kStrWidth);
1713    CASE_AND_STREAM(s, SHT_LOUSER   , kStrWidth);
1714    CASE_AND_STREAM(s, SHT_HIUSER   , kStrWidth);
1715    default:
1716        s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1717        break;
1718    }
1719}
1720
1721//----------------------------------------------------------------------
1722// DumpELFSectionHeader_sh_flags
1723//
1724// Dump an token value for the ELF section header member sh_flags
1725//----------------------------------------------------------------------
1726void
1727ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
1728{
1729    *s  << ((sh_flags & SHF_WRITE) ? "WRITE" : "     ")
1730        << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1731        << ((sh_flags & SHF_ALLOC) ? "ALLOC" : "     ")
1732        << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1733        << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : "         ");
1734}
1735
1736//----------------------------------------------------------------------
1737// DumpELFSectionHeaders
1738//
1739// Dump all of the ELF section header to the specified output stream
1740//----------------------------------------------------------------------
1741void
1742ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1743{
1744    if (!ParseSectionHeaders())
1745        return;
1746
1747    s->PutCString("Section Headers\n");
1748    s->PutCString("IDX  name     type         flags                            "
1749                  "addr     offset   size     link     info     addralgn "
1750                  "entsize  Name\n");
1751    s->PutCString("==== -------- ------------ -------------------------------- "
1752                  "-------- -------- -------- -------- -------- -------- "
1753                  "-------- ====================\n");
1754
1755    uint32_t idx = 0;
1756    for (SectionHeaderCollConstIter I = m_section_headers.begin();
1757         I != m_section_headers.end(); ++I, ++idx)
1758    {
1759        s->Printf("[%2u] ", idx);
1760        ObjectFileELF::DumpELFSectionHeader(s, *I);
1761        const char* section_name = I->section_name.AsCString("");
1762        if (section_name)
1763            *s << ' ' << section_name << "\n";
1764    }
1765}
1766
1767void
1768ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1769{
1770    size_t num_modules = ParseDependentModules();
1771
1772    if (num_modules > 0)
1773    {
1774        s->PutCString("Dependent Modules:\n");
1775        for (unsigned i = 0; i < num_modules; ++i)
1776        {
1777            const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1778            s->Printf("   %s\n", spec.GetFilename().GetCString());
1779        }
1780    }
1781}
1782
1783bool
1784ObjectFileELF::GetArchitecture (ArchSpec &arch)
1785{
1786    if (!ParseHeader())
1787        return false;
1788
1789    arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
1790    arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1791    arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
1792    return true;
1793}
1794
1795ObjectFile::Type
1796ObjectFileELF::CalculateType()
1797{
1798    switch (m_header.e_type)
1799    {
1800        case llvm::ELF::ET_NONE:
1801            // 0 - No file type
1802            return eTypeUnknown;
1803
1804        case llvm::ELF::ET_REL:
1805            // 1 - Relocatable file
1806            return eTypeObjectFile;
1807
1808        case llvm::ELF::ET_EXEC:
1809            // 2 - Executable file
1810            return eTypeExecutable;
1811
1812        case llvm::ELF::ET_DYN:
1813            // 3 - Shared object file
1814            return eTypeSharedLibrary;
1815
1816        case ET_CORE:
1817            // 4 - Core file
1818            return eTypeCoreFile;
1819
1820        default:
1821            break;
1822    }
1823    return eTypeUnknown;
1824}
1825
1826ObjectFile::Strata
1827ObjectFileELF::CalculateStrata()
1828{
1829    switch (m_header.e_type)
1830    {
1831        case llvm::ELF::ET_NONE:
1832            // 0 - No file type
1833            return eStrataUnknown;
1834
1835        case llvm::ELF::ET_REL:
1836            // 1 - Relocatable file
1837            return eStrataUnknown;
1838
1839        case llvm::ELF::ET_EXEC:
1840            // 2 - Executable file
1841            // TODO: is there any way to detect that an executable is a kernel
1842            // related executable by inspecting the program headers, section
1843            // headers, symbols, or any other flag bits???
1844            return eStrataUser;
1845
1846        case llvm::ELF::ET_DYN:
1847            // 3 - Shared object file
1848            // TODO: is there any way to detect that an shared library is a kernel
1849            // related executable by inspecting the program headers, section
1850            // headers, symbols, or any other flag bits???
1851            return eStrataUnknown;
1852
1853        case ET_CORE:
1854            // 4 - Core file
1855            // TODO: is there any way to detect that an core file is a kernel
1856            // related executable by inspecting the program headers, section
1857            // headers, symbols, or any other flag bits???
1858            return eStrataUnknown;
1859
1860        default:
1861            break;
1862    }
1863    return eStrataUnknown;
1864}
1865
1866