blob: df764889a134b989ba6dcd6f80d386157bd5adbc [file] [log] [blame]
Greg Clayton596ba272010-07-07 21:52:01 +00001//===-- ObjectFileELF64.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 "ObjectFileELF64.h"
11
12#include <cassert>
13
14#include <algorithm>
15
16#include "lldb/Core/DataBuffer.h"
17#include "lldb/Core/Error.h"
18#include "lldb/Core/FileSpecList.h"
19#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/Section.h"
21#include "lldb/Core/Stream.h"
22
23#define CASE_AND_STREAM(s, def, width) \
24 case def: s->Printf("%-*s", width, #def); break;
25
26using namespace lldb;
27using namespace lldb_private;
28
29void
30ObjectFileELF64::Initialize()
31{
32 PluginManager::RegisterPlugin(GetPluginNameStatic(),
33 GetPluginDescriptionStatic(),
34 CreateInstance);
35}
36
37void
38ObjectFileELF64::Terminate()
39{
40 PluginManager::UnregisterPlugin(CreateInstance);
41}
42
43const char *
44ObjectFileELF64::GetPluginNameStatic()
45{
46 return "object-file.elf64";
47}
48
49const char *
50ObjectFileELF64::GetPluginDescriptionStatic()
51{
52 return "ELF object file reader (64-bit).";
53}
54
55ObjectFile *
56ObjectFileELF64::CreateInstance(Module *module,
57 DataBufferSP &dataSP,
58 const FileSpec *file, addr_t offset,
59 addr_t length)
60{
61 if (ObjectFileELF64::MagicBytesMatch(dataSP))
62 {
63 std::auto_ptr<ObjectFile> objfile_ap(
64 new ObjectFileELF64(module, dataSP, file, offset, length));
65 if (objfile_ap->ParseHeader())
66 return objfile_ap.release();
67 }
68 return NULL;
69}
70
71bool
72ObjectFileELF64::MagicBytesMatch(DataBufferSP& data_sp)
73{
74 if (data_sp && data_sp->GetByteSize() > EI_PAD)
75 {
76 const uint8_t* magic = data_sp->GetBytes();
77 if (magic != NULL)
78 {
79 bool have_magic = (magic[EI_MAG0] == 0x7f &&
80 magic[EI_MAG1] == 'E' &&
81 magic[EI_MAG2] == 'L' &&
82 magic[EI_MAG3] == 'F');
83
84 bool have_64bit = magic[EI_CLASS] == ELFCLASS64;
85
86 return have_magic && have_64bit;
87 }
88 }
89 return false;
90}
91
92ObjectFileELF64::ObjectFileELF64(Module* module, DataBufferSP& dataSP,
93 const FileSpec* file, addr_t offset,
94 addr_t length)
95 : ObjectFile(module, file, offset, length, dataSP),
96 m_header(),
97 m_program_headers(),
98 m_section_headers(),
99 m_sections_ap(),
100 m_symtab_ap(),
101 m_filespec_ap(),
102 m_shstr_data()
103{
104 if (file)
105 m_file = *file;
106 ::memset(&m_header, 0, sizeof(m_header));
107}
108
109
110ObjectFileELF64::~ObjectFileELF64()
111{
112}
113
114ByteOrder
115ObjectFileELF64::GetByteOrder() const
116{
117 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
118 return eByteOrderBig;
119 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
120 return eByteOrderLittle;
121 return eByteOrderInvalid;
122}
123
124size_t
125ObjectFileELF64::GetAddressByteSize() const
126{
127 return m_data.GetAddressByteSize();
128}
129
130unsigned
131ObjectFileELF64::SectionIndex(const SectionHeaderCollIter &I)
132{
133 return std::distance(m_section_headers.begin(), I) + 1;
134}
135
136unsigned
137ObjectFileELF64::SectionIndex(const SectionHeaderCollConstIter &I) const
138{
139 return std::distance(m_section_headers.begin(), I) + 1;
140}
141
142bool
143ObjectFileELF64::ParseHeader()
144{
145 m_data.SetAddressByteSize(8);
146 uint32_t offset = GetOffset();
147 if (m_data.GetU8(&offset, m_header.e_ident, EI_NIDENT) == NULL)
148 return false;
149
150 m_data.SetByteOrder(GetByteOrder());
151
152 // Read e_type and e_machine.
153 if (m_data.GetU16(&offset, &m_header.e_type, 2) == NULL)
154 return false;
155
156 // Read e_version.
157 if (m_data.GetU32(&offset, &m_header.e_version, 1) == NULL)
158 return false;
159
160 // Read e_entry, e_phoff and e_shoff.
161 if (m_data.GetU64(&offset, &m_header.e_entry, 3) == NULL)
162 return false;
163
164 // Read e_flags.
165 if (m_data.GetU32(&offset, &m_header.e_flags, 1) == NULL)
166 return false;
167
168 // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and e_shstrndx.
169 if (m_data.GetU16(&offset, &m_header.e_ehsize, 6) == NULL)
170 return false;
171
172 return true;
173}
174
175bool
176ObjectFileELF64::GetUUID(UUID* uuid)
177{
178 // FIXME: Return MD5 sum here. See comment in ObjectFile.h.
179 return false;
180}
181
182uint32_t
183ObjectFileELF64::GetDependentModules(FileSpecList &files)
184{
185 size_t num_modules = ParseDependentModules();
186 uint32_t num_specs = 0;
187
188 for (unsigned i = 0; i < num_modules; ++i)
189 {
190 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
191 num_specs++;
192 }
193
194 return num_specs;
195}
196
197//----------------------------------------------------------------------
198// ParseDependentModules
199//----------------------------------------------------------------------
200size_t
201ObjectFileELF64::ParseDependentModules()
202{
203 if (m_filespec_ap.get())
204 return m_filespec_ap->GetSize();
205
206 m_filespec_ap.reset(new FileSpecList());
207
208 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
209 return 0;
210
211 // Locate the dynamic table.
212 user_id_t dynsym_id = 0;
213 user_id_t dynstr_id = 0;
214 for (SectionHeaderCollIter I = m_section_headers.begin();
215 I != m_section_headers.end(); ++I)
216 {
217 if (I->sh_type == SHT_DYNAMIC)
218 {
219 dynsym_id = SectionIndex(I);
220 dynstr_id = I->sh_link + 1; // Section ID's are 1 based.
221 break;
222 }
223 }
224
225 if (!(dynsym_id && dynstr_id))
226 return 0;
227
228 SectionList *section_list = GetSectionList();
229 if (!section_list)
230 return 0;
231
232 // Resolve and load the dynamic table entries and corresponding string
233 // table.
234 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
235 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
236 if (!(dynsym && dynstr))
237 return 0;
238
239 DataExtractor dynsym_data;
240 DataExtractor dynstr_data;
241 if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data) &&
242 dynstr->ReadSectionDataFromObjectFile(this, dynstr_data))
243 {
244 Elf64_Dyn symbol;
245 const unsigned num_syms = dynsym_data.GetByteSize() / sizeof(Elf64_Dyn);
246 unsigned offset = 0;
247
248 // The only type of entries we are concerned with are tagged DT_NEEDED,
249 // yielding the name of a required library.
250 for (unsigned i = 0; i < num_syms; ++i)
251 {
252 if (!dynsym_data.ValidOffsetForDataOfSize(offset, sizeof(Elf64_Dyn)))
253 break;
254
255 symbol.d_tag = dynsym_data.GetU64(&offset);
256 symbol.d_un.d_val = dynsym_data.GetU64(&offset);
257
258 if (symbol.d_tag != DT_NEEDED)
259 continue;
260
261 const char *lib_name = dynstr_data.PeekCStr(symbol.d_un.d_val);
262 m_filespec_ap->Append(FileSpec(lib_name));
263 }
264 }
265
266 return m_filespec_ap->GetSize();
267}
268
269//----------------------------------------------------------------------
270// ParseProgramHeaders
271//----------------------------------------------------------------------
272size_t
273ObjectFileELF64::ParseProgramHeaders()
274{
275 // We have already parsed the program headers
276 if (!m_program_headers.empty())
277 return m_program_headers.size();
278
279 // If there are no program headers to read we are done.
280 if (m_header.e_phnum == 0)
281 return 0;
282
283 m_program_headers.resize(m_header.e_phnum);
284 if (m_program_headers.size() != m_header.e_phnum)
285 return 0;
286
287 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
288 const Elf64_Off ph_offset = m_offset + m_header.e_phoff;
289 DataBufferSP buffer_sp(m_file.ReadFileContents(ph_offset, ph_size));
290
291 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != ph_size)
292 return 0;
293
294 DataExtractor data(buffer_sp, m_data.GetByteOrder(),
295 m_data.GetAddressByteSize());
296
297 uint32_t idx;
298 uint32_t offset;
299 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
300 {
301 if (data.GetU32(&offset, &m_program_headers[idx], 8) == NULL)
302 return 0;
303 }
304
305 if (idx < m_program_headers.size())
306 m_program_headers.resize(idx);
307
308 return m_program_headers.size();
309}
310
311//----------------------------------------------------------------------
312// ParseSectionHeaders
313//----------------------------------------------------------------------
314size_t
315ObjectFileELF64::ParseSectionHeaders()
316{
317 // We have already parsed the section headers
318 if (!m_section_headers.empty())
319 return m_section_headers.size();
320
321 // If there are no section headers we are done.
322 if (m_header.e_shnum == 0)
323 return 0;
324
325 m_section_headers.resize(m_header.e_shnum);
326 if (m_section_headers.size() != m_header.e_shnum)
327 return 0;
328
329 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
330 const Elf64_Off sh_offset = m_offset + m_header.e_shoff;
331 DataBufferSP buffer_sp(m_file.ReadFileContents(sh_offset, sh_size));
332
333 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != sh_size)
334 return 0;
335
336 DataExtractor data(buffer_sp,
337 m_data.GetByteOrder(),
338 m_data.GetAddressByteSize());
339
340 uint32_t idx;
341 uint32_t offset;
342 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
343 {
344 // Read sh_name and sh_type.
345 if (data.GetU32(&offset, &m_section_headers[idx].sh_name, 2) == NULL)
346 break;
347
348 // Read sh_flags, sh_addr, sh_offset and sh_size.
349 if (data.GetU64(&offset, &m_section_headers[idx].sh_flags, 4) == NULL)
350 break;
351
352 // Read sh_link and sh_info.
353 if (data.GetU32(&offset, &m_section_headers[idx].sh_link, 2) == NULL)
354 break;
355
356 // Read sh_addralign and sh_entsize.
357 if (data.GetU64(&offset, &m_section_headers[idx].sh_addralign, 2) == NULL)
358 break;
359 }
360 if (idx < m_section_headers.size())
361 m_section_headers.resize(idx);
362
363 return m_section_headers.size();
364}
365
366size_t
367ObjectFileELF64::GetSectionHeaderStringTable()
368{
369 if (m_shstr_data.GetByteSize() == 0)
370 {
371 if (m_header.e_shstrndx && m_header.e_shstrndx < m_section_headers.size())
372 {
373 const Elf64_Shdr &sheader = m_section_headers[m_header.e_shstrndx];
374 const size_t byte_size = sheader.sh_size;
375 const Elf64_Off offset = m_offset + sheader.sh_offset;
376 DataBufferSP buffer_sp(m_file.ReadFileContents(offset, byte_size));
377
378 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size)
379 return 0;
380
381 m_shstr_data.SetData(buffer_sp);
382 }
383 }
384 return m_shstr_data.GetByteSize();
385}
386
387uint32_t
388ObjectFileELF64::GetSectionIndexByName(const char *name)
389{
390 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
391 return UINT32_MAX;
392
393 // Search the collection of section headers for one with a matching name.
394 for (SectionHeaderCollIter I = m_section_headers.begin();
395 I != m_section_headers.end(); ++I)
396 {
397 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
398
399 if (!sectionName)
400 return UINT32_MAX;
401
402 if (strcmp(name, sectionName) != 0)
403 continue;
404
405 return SectionIndex(I);
406 }
407
408 return UINT32_MAX;
409}
410
411SectionList *
412ObjectFileELF64::GetSectionList()
413{
414 if (m_sections_ap.get())
415 return m_sections_ap.get();
416
417 if (ParseSectionHeaders() && GetSectionHeaderStringTable())
418 {
419 m_sections_ap.reset(new SectionList());
420
421 for (SectionHeaderCollIter I = m_section_headers.begin();
422 I != m_section_headers.end(); ++I)
423 {
424 const Elf64_Shdr &header = *I;
425
426 ConstString name(m_shstr_data.PeekCStr(header.sh_name));
427 uint64_t size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
428
429 SectionSP section(new Section(
430 0, // Parent section.
431 GetModule(), // Module to which this section belongs.
432 SectionIndex(I), // Section ID.
433 name, // Section name.
434 eSectionTypeOther, // FIXME: Fill in as appropriate.
435 header.sh_addr, // VM address.
436 header.sh_size, // VM size in bytes of this section.
437 header.sh_offset, // Offset of this section in the file.
438 size, // Size of the section as found in the file.
439 header.sh_flags)); // Flags for this section.
440
441 m_sections_ap->AddSection(section);
442 }
443 }
444
445 return m_sections_ap.get();
446}
447
448static void
449ParseSymbols(Symtab *symtab, SectionList *section_list,
450 const Elf64_Shdr &symtab_shdr,
451 const DataExtractor &symtab_data,
452 const DataExtractor &strtab_data)
453{
454 assert (sizeof(Elf64_Sym) == symtab_shdr.sh_entsize);
455 const unsigned numSymbols = symtab_data.GetByteSize() / sizeof(Elf64_Sym);
456 unsigned offset = 0;
457 Elf64_Sym symbol;
458
459 static ConstString text_section_name(".text");
460 static ConstString init_section_name(".init");
461 static ConstString fini_section_name(".fini");
462 static ConstString ctors_section_name(".ctors");
463 static ConstString dtors_section_name(".dtors");
464
465 static ConstString data_section_name(".data");
466 static ConstString rodata_section_name(".rodata");
467 static ConstString rodata1_section_name(".rodata1");
468 static ConstString data2_section_name(".data1");
469 static ConstString bss_section_name(".bss");
470
471 for (unsigned i = 0; i < numSymbols; ++i)
472 {
473 if (!symtab_data.ValidOffsetForDataOfSize(offset, sizeof(Elf64_Sym)))
474 break;
475
476 symbol.st_name = symtab_data.GetU32(&offset);
477 symbol.st_info = symtab_data.GetU8(&offset);
478 symbol.st_other = symtab_data.GetU8(&offset);
479 symbol.st_shndx = symtab_data.GetU16(&offset);
480 symbol.st_value = symtab_data.GetU64(&offset);
481 symbol.st_size = symtab_data.GetU64(&offset);
482
483 Section *symbol_section = NULL;
484 SymbolType symbol_type = eSymbolTypeInvalid;
485 Elf64_Half symbol_idx = symbol.st_shndx;
486
487 switch (symbol_idx)
488 {
489 case SHN_ABS:
490 symbol_type = eSymbolTypeAbsolute;
491 break;
492 case SHN_UNDEF:
493 symbol_type = eSymbolTypeUndefined;
494 break;
495 default:
496 symbol_section = section_list->GetSectionAtIndex(symbol_idx).get();
497 break;
498 }
499
500 switch (ELF_ST_TYPE(symbol.st_info))
501 {
502 default:
503 case STT_NOTYPE:
504 // The symbol's type is not specified.
505 break;
506
507 case STT_OBJECT:
508 // The symbol is associated with a data object, such as a variable,
509 // an array, etc.
510 symbol_type = eSymbolTypeData;
511 break;
512
513 case STT_FUNC:
514 // The symbol is associated with a function or other executable code.
515 symbol_type = eSymbolTypeCode;
516 break;
517
518 case STT_SECTION:
519 // The symbol is associated with a section. Symbol table entries of
520 // this type exist primarily for relocation and normally have
521 // STB_LOCAL binding.
522 break;
523
524 case STT_FILE:
525 // Conventionally, the symbol's name gives the name of the source
526 // file associated with the object file. A file symbol has STB_LOCAL
527 // binding, its section index is SHN_ABS, and it precedes the other
528 // STB_LOCAL symbols for the file, if it is present.
529 symbol_type = eSymbolTypeObjectFile;
530 break;
531 }
532
533 if (symbol_type == eSymbolTypeInvalid)
534 {
535 if (symbol_section)
536 {
537 const ConstString &sect_name = symbol_section->GetName();
538 if (sect_name == text_section_name ||
539 sect_name == init_section_name ||
540 sect_name == fini_section_name ||
541 sect_name == ctors_section_name ||
542 sect_name == dtors_section_name)
543 {
544 symbol_type = eSymbolTypeCode;
545 }
546 else if (sect_name == data_section_name ||
547 sect_name == data2_section_name ||
548 sect_name == rodata_section_name ||
549 sect_name == rodata1_section_name ||
550 sect_name == bss_section_name)
551 {
552 symbol_type = eSymbolTypeData;
553 }
554 }
555 }
556
557 uint64_t symbol_value = symbol.st_value;
558 if (symbol_section != NULL)
559 symbol_value -= symbol_section->GetFileAddress();
560 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
561 bool is_global = ELF_ST_BIND(symbol.st_info) == STB_GLOBAL;
562 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
563
564 Symbol dc_symbol(
565 i, // ID is the original symbol table index.
566 symbol_name, // symbol name.
567 false, // Is the symbol name mangled?
568 symbol_type, // type of this symbol
569 is_global, // Is this globally visible?
570 false, // Is this symbol debug info?
571 false, // Is this symbol a trampoline?
572 false, // Is this symbol artificial?
573 symbol_section, // Section in which this symbol is defined or null.
574 symbol_value, // Offset in section or symbol value.
575 symbol.st_size, // size in bytes of this symbol.
576 flags); // Symbol flags.
577 symtab->AddSymbol(dc_symbol);
578 }
579}
580
581void
582ObjectFileELF64::ParseSymbolTable(Symtab *symbol_table,
583 const Elf64_Shdr &symtab_hdr,
584 user_id_t symtab_id)
585{
586 assert(symtab_hdr.sh_type == SHT_SYMTAB ||
587 symtab_hdr.sh_type == SHT_DYNSYM);
588
589 // Parse in the section list if needed.
590 SectionList *section_list = GetSectionList();
591 if (!section_list)
592 return;
593
594 // Section ID's are ones based.
595 user_id_t strtab_id = symtab_hdr.sh_link + 1;
596
597 Section *symtab = section_list->FindSectionByID(symtab_id).get();
598 Section *strtab = section_list->FindSectionByID(strtab_id).get();
599 if (symtab && strtab)
600 {
601 DataExtractor symtab_data;
602 DataExtractor strtab_data;
603 if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) &&
604 strtab->ReadSectionDataFromObjectFile(this, strtab_data))
605 {
606 ParseSymbols(symbol_table, section_list, symtab_hdr,
607 symtab_data, strtab_data);
608 }
609 }
610}
611
612Symtab *
613ObjectFileELF64::GetSymtab()
614{
615 if (m_symtab_ap.get())
616 return m_symtab_ap.get();
617
618 Symtab *symbol_table = new Symtab(this);
619 m_symtab_ap.reset(symbol_table);
620
621 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
622 return symbol_table;
623
624 // Locate and parse all linker symbol tables.
625 for (SectionHeaderCollIter I = m_section_headers.begin();
626 I != m_section_headers.end(); ++I)
627 {
628 if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM)
629 {
630 const Elf64_Shdr &symtab_section = *I;
631 user_id_t section_id = SectionIndex(I);
632 ParseSymbolTable(symbol_table, symtab_section, section_id);
633 }
634 }
635
636 return symbol_table;
637}
638
639//===----------------------------------------------------------------------===//
640// Dump
641//
642// Dump the specifics of the runtime file container (such as any headers
643// segments, sections, etc).
644// ----------------------------------------------------------------------
645void
646ObjectFileELF64::Dump(Stream *s)
647{
648 DumpELFHeader(s, m_header);
649 s->EOL();
650 DumpELFProgramHeaders(s);
651 s->EOL();
652 DumpELFSectionHeaders(s);
653 s->EOL();
654 SectionList *section_list = GetSectionList();
655 if (section_list)
656 section_list->Dump(s, NULL, true);
657 Symtab *symtab = GetSymtab();
658 if (symtab)
659 symtab->Dump(s, NULL);
660 s->EOL();
661 DumpDependentModules(s);
662 s->EOL();
663}
664
665//----------------------------------------------------------------------
666// DumpELFHeader
667//
668// Dump the ELF header to the specified output stream
669//----------------------------------------------------------------------
670void
671ObjectFileELF64::DumpELFHeader(Stream *s, const Elf64_Ehdr& header)
672{
673
674 s->PutCString("ELF Header\n");
675 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
676 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
677 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
678 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
679 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
680 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
681 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
682
683 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
684 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
685 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
686 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
687 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
688
689 s->Printf("e_type = 0x%4.4x ", header.e_type);
690 DumpELFHeader_e_type(s, header.e_type);
691 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
692 s->Printf("e_version = 0x%8.8x\n", header.e_version);
693 s->Printf("e_entry = 0x%8.8x\n", header.e_entry);
694 s->Printf("e_phoff = 0x%8.8x\n", header.e_phoff);
695 s->Printf("e_shoff = 0x%8.8x\n", header.e_shoff);
696 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
697 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
698 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
699 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
700 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
701 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
702 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
703}
704
705//----------------------------------------------------------------------
706// DumpELFHeader_e_type
707//
708// Dump an token value for the ELF header member e_type
709//----------------------------------------------------------------------
710void
711ObjectFileELF64::DumpELFHeader_e_type(Stream *s, Elf64_Half e_type)
712{
713 switch (e_type)
714 {
715 case ET_NONE: *s << "ET_NONE"; break;
716 case ET_REL: *s << "ET_REL"; break;
717 case ET_EXEC: *s << "ET_EXEC"; break;
718 case ET_DYN: *s << "ET_DYN"; break;
719 case ET_CORE: *s << "ET_CORE"; break;
720 default:
721 break;
722 }
723}
724
725//----------------------------------------------------------------------
726// DumpELFHeader_e_ident_EI_DATA
727//
728// Dump an token value for the ELF header member e_ident[EI_DATA]
729//----------------------------------------------------------------------
730void
731ObjectFileELF64::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
732{
733 switch (ei_data)
734 {
735 case ELFDATANONE: *s << "ELFDATANONE"; break;
736 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
737 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
738 default:
739 break;
740 }
741}
742
743
744//----------------------------------------------------------------------
745// DumpELFProgramHeader
746//
747// Dump a single ELF program header to the specified output stream
748//----------------------------------------------------------------------
749void
750ObjectFileELF64::DumpELFProgramHeader(Stream *s, const Elf64_Phdr &ph)
751{
752 DumpELFProgramHeader_p_type(s, ph.p_type);
753 s->Printf(" %8.8x %8.8x %8.8x %8.8x %8.8x %8.8x (",
754 ph.p_offset, ph.p_vaddr, ph.p_paddr, ph.p_filesz, ph.p_memsz,
755 ph.p_flags);
756 DumpELFProgramHeader_p_flags(s, ph.p_flags);
757 s->Printf(") %8.8x", ph.p_align);
758}
759
760//----------------------------------------------------------------------
761// DumpELFProgramHeader_p_type
762//
763// Dump an token value for the ELF program header member p_type which
764// describes the type of the program header
765// ----------------------------------------------------------------------
766void
767ObjectFileELF64::DumpELFProgramHeader_p_type(Stream *s, Elf64_Word p_type)
768{
769 const int kStrWidth = 10;
770 switch (p_type)
771 {
772 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
773 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
774 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
775 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
776 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
777 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
778 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
779 default:
780 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
781 break;
782 }
783}
784
785
786//----------------------------------------------------------------------
787// DumpELFProgramHeader_p_flags
788//
789// Dump an token value for the ELF program header member p_flags
790//----------------------------------------------------------------------
791void
792ObjectFileELF64::DumpELFProgramHeader_p_flags(Stream *s, Elf64_Word p_flags)
793{
794 *s << ((p_flags & PF_X) ? "PF_X" : " ")
795 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
796 << ((p_flags & PF_W) ? "PF_W" : " ")
797 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
798 << ((p_flags & PF_R) ? "PF_R" : " ");
799}
800
801//----------------------------------------------------------------------
802// DumpELFProgramHeaders
803//
804// Dump all of the ELF program header to the specified output stream
805//----------------------------------------------------------------------
806void
807ObjectFileELF64::DumpELFProgramHeaders(Stream *s)
808{
809 if (ParseProgramHeaders())
810 {
811 s->PutCString("Program Headers\n");
812 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
813 "p_filesz p_memsz p_flags p_align\n");
814 s->PutCString("==== ---------- -------- -------- -------- "
815 "-------- -------- ------------------------- --------\n");
816
817 uint32_t idx = 0;
818 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
819 I != m_program_headers.end(); ++I, ++idx)
820 {
821 s->Printf("[%2u] ", idx);
822 ObjectFileELF64::DumpELFProgramHeader(s, *I);
823 s->EOL();
824 }
825 }
826}
827
828//----------------------------------------------------------------------
829// DumpELFSectionHeader
830//
831// Dump a single ELF section header to the specified output stream
832//----------------------------------------------------------------------
833void
834ObjectFileELF64::DumpELFSectionHeader(Stream *s, const Elf64_Shdr &sh)
835{
836 s->Printf("%8.8x ", sh.sh_name);
837 DumpELFSectionHeader_sh_type(s, sh.sh_type);
838 s->Printf(" %8.8x (", sh.sh_flags);
839 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
840 s->Printf(") %8.8x %8.8x %8.8x %8.8x %8.8x %8.8x %8.8x",
841 sh.sh_addr, sh.sh_offset, sh.sh_size, sh.sh_link, sh.sh_info,
842 sh.sh_addralign, sh.sh_entsize);
843}
844
845//----------------------------------------------------------------------
846// DumpELFSectionHeader_sh_type
847//
848// Dump an token value for the ELF section header member sh_type which
849// describes the type of the section
850//----------------------------------------------------------------------
851void
852ObjectFileELF64::DumpELFSectionHeader_sh_type(Stream *s, Elf64_Word sh_type)
853{
854 const int kStrWidth = 12;
855 switch (sh_type)
856 {
857 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
858 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
859 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
860 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
861 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
862 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
863 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
864 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
865 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
866 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
867 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
868 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
869 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
870 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
871 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
872 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
873 default:
874 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
875 break;
876 }
877}
878
879//----------------------------------------------------------------------
880// DumpELFSectionHeader_sh_flags
881//
882// Dump an token value for the ELF section header member sh_flags
883//----------------------------------------------------------------------
884void
885ObjectFileELF64::DumpELFSectionHeader_sh_flags(Stream *s, Elf64_Word sh_flags)
886{
887 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
888 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
889 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
890 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
891 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
892}
893
894//----------------------------------------------------------------------
895// DumpELFSectionHeaders
896//
897// Dump all of the ELF section header to the specified output stream
898//----------------------------------------------------------------------
899void
900ObjectFileELF64::DumpELFSectionHeaders(Stream *s)
901{
902 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
903 return;
904
905 s->PutCString("Section Headers\n");
906 s->PutCString("IDX name type flags "
907 "addr offset size link info addralgn "
908 "entsize Name\n");
909 s->PutCString("==== -------- ------------ -------------------------------- "
910 "-------- -------- -------- -------- -------- -------- "
911 "-------- ====================\n");
912
913 uint32_t idx = 0;
914 for (SectionHeaderCollConstIter I = m_section_headers.begin();
915 I != m_section_headers.end(); ++I, ++idx)
916 {
917 s->Printf("[%2u] ", idx);
918 ObjectFileELF64::DumpELFSectionHeader(s, *I);
919 const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
920 if (section_name)
921 *s << ' ' << section_name << "\n";
922 }
923}
924
925void
926ObjectFileELF64::DumpDependentModules(lldb_private::Stream *s)
927{
928 size_t num_modules = ParseDependentModules();
929
930 if (num_modules > 0)
931 {
932 s->PutCString("Dependent Modules:\n");
933 for (unsigned i = 0; i < num_modules; ++i)
934 {
935 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
936 s->Printf(" %s\n", spec.GetFilename().GetCString());
937 }
938 }
939}
940
941bool
942ObjectFileELF64::GetTargetTriple(ConstString &target_triple)
943{
944 static ConstString g_target_triple;
945
946 if (g_target_triple)
947 {
948 target_triple = g_target_triple;
949 return true;
950 }
951
952 std::string triple;
953 switch (m_header.e_machine)
954 {
955 default:
956 assert(false && "Unexpected machine type.");
957 break;
958 case EM_SPARC: triple.assign("sparc-"); break;
959 case EM_386: triple.assign("i386-"); break;
960 case EM_68K: triple.assign("68k-"); break;
961 case EM_88K: triple.assign("88k-"); break;
962 case EM_860: triple.assign("i860-"); break;
963 case EM_MIPS: triple.assign("mips-"); break;
964 case EM_PPC: triple.assign("powerpc-"); break;
965 case EM_PPC64: triple.assign("powerpc64-"); break;
966 case EM_ARM: triple.assign("arm-"); break;
967 case EM_X86_64: triple.assign("x86_64-"); break;
968 }
969 // TODO: determine if there is a vendor in the ELF? Default to "linux" for now
970 triple += "linux-";
971 // TODO: determine if there is an OS in the ELF? Default to "gnu" for now
972 triple += "gnu";
973 g_target_triple.SetCString(triple.c_str());
974 target_triple = g_target_triple;
975
976 return true;
977}
978
979//------------------------------------------------------------------
980// PluginInterface protocol
981//------------------------------------------------------------------
982const char *
983ObjectFileELF64::GetPluginName()
984{
985 return "ObjectFileELF64";
986}
987
988const char *
989ObjectFileELF64::GetShortPluginName()
990{
991 return GetPluginNameStatic();
992}
993
994uint32_t
995ObjectFileELF64::GetPluginVersion()
996{
997 return 1;
998}
999
1000void
1001ObjectFileELF64::GetPluginCommandHelp (const char *command, Stream *strm)
1002{
1003}
1004
1005Error
1006ObjectFileELF64::ExecutePluginCommand (Args &command, Stream *strm)
1007{
1008 Error error;
1009 error.SetErrorString("No plug-in commands are currently supported.");
1010 return error;
1011}
1012
1013Log *
1014ObjectFileELF64::EnablePluginLogging (Stream *strm, Args &command)
1015{
1016 return NULL;
1017}