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