blob: 0ce96b972d841f313ed754201694450a4d0d939d [file] [log] [blame]
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001//===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===//
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002//
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
Stephen Wilsonf325ba92010-07-13 23:07:23 +000012#include <cassert>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include <algorithm>
14
Stephen Wilson2ab0a582011-01-15 00:08:44 +000015#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/DataBuffer.h"
17#include "lldb/Core/Error.h"
Stephen Wilsonf325ba92010-07-13 23:07:23 +000018#include "lldb/Core/FileSpecList.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000019#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/PluginManager.h"
21#include "lldb/Core/Section.h"
22#include "lldb/Core/Stream.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000023#include "lldb/Symbol/SymbolContext.h"
Greg Clayton64195a22011-02-23 00:35:02 +000024#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025
Stephen Wilson499b40e2011-03-30 16:07:05 +000026#include "llvm/ADT/PointerUnion.h"
27
Stephen Wilsonf325ba92010-07-13 23:07:23 +000028#define CASE_AND_STREAM(s, def, width) \
29 case def: s->Printf("%-*s", width, #def); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031using namespace lldb;
32using namespace lldb_private;
Stephen Wilsonf325ba92010-07-13 23:07:23 +000033using namespace elf;
34using namespace llvm::ELF;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Stephen Wilson499b40e2011-03-30 16:07:05 +000036namespace {
37//===----------------------------------------------------------------------===//
38/// @class ELFRelocation
39/// @brief Generic wrapper for ELFRel and ELFRela.
40///
41/// This helper class allows us to parse both ELFRel and ELFRela relocation
42/// entries in a generic manner.
43class ELFRelocation
44{
45public:
46
47 /// Constructs an ELFRelocation entry with a personality as given by @p
48 /// type.
49 ///
50 /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
51 ELFRelocation(unsigned type);
52
53 ~ELFRelocation();
54
55 bool
Greg Claytonc7bece562013-01-25 18:06:21 +000056 Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
Stephen Wilson499b40e2011-03-30 16:07:05 +000057
58 static unsigned
59 RelocType32(const ELFRelocation &rel);
60
61 static unsigned
62 RelocType64(const ELFRelocation &rel);
63
64 static unsigned
65 RelocSymbol32(const ELFRelocation &rel);
66
67 static unsigned
68 RelocSymbol64(const ELFRelocation &rel);
69
70private:
71 typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion;
72
73 RelocUnion reloc;
74};
75
76ELFRelocation::ELFRelocation(unsigned type)
77{
78 if (type == DT_REL)
79 reloc = new ELFRel();
80 else if (type == DT_RELA)
81 reloc = new ELFRela();
82 else {
83 assert(false && "unexpected relocation type");
84 reloc = static_cast<ELFRel*>(NULL);
85 }
86}
87
88ELFRelocation::~ELFRelocation()
89{
90 if (reloc.is<ELFRel*>())
91 delete reloc.get<ELFRel*>();
92 else
93 delete reloc.get<ELFRela*>();
94}
95
96bool
Greg Claytonc7bece562013-01-25 18:06:21 +000097ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Stephen Wilson499b40e2011-03-30 16:07:05 +000098{
99 if (reloc.is<ELFRel*>())
100 return reloc.get<ELFRel*>()->Parse(data, offset);
101 else
102 return reloc.get<ELFRela*>()->Parse(data, offset);
103}
104
105unsigned
106ELFRelocation::RelocType32(const ELFRelocation &rel)
107{
108 if (rel.reloc.is<ELFRel*>())
109 return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>());
110 else
111 return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>());
112}
113
114unsigned
115ELFRelocation::RelocType64(const ELFRelocation &rel)
116{
117 if (rel.reloc.is<ELFRel*>())
118 return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>());
119 else
120 return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>());
121}
122
123unsigned
124ELFRelocation::RelocSymbol32(const ELFRelocation &rel)
125{
126 if (rel.reloc.is<ELFRel*>())
127 return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>());
128 else
129 return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>());
130}
131
132unsigned
133ELFRelocation::RelocSymbol64(const ELFRelocation &rel)
134{
135 if (rel.reloc.is<ELFRel*>())
136 return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>());
137 else
138 return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>());
139}
140
141} // end anonymous namespace
142
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000143//------------------------------------------------------------------
144// Static methods.
145//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146void
147ObjectFileELF::Initialize()
148{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000149 PluginManager::RegisterPlugin(GetPluginNameStatic(),
150 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000151 CreateInstance,
152 CreateMemoryInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153}
154
155void
156ObjectFileELF::Terminate()
157{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000158 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159}
160
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161const char *
162ObjectFileELF::GetPluginNameStatic()
163{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000164 return "object-file.elf";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165}
166
167const char *
168ObjectFileELF::GetPluginDescriptionStatic()
169{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000170 return "ELF object file reader.";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171}
172
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173ObjectFile *
Greg Claytone72dfb32012-02-24 01:59:29 +0000174ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
175 DataBufferSP &data_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000176 lldb::offset_t data_offset,
177 const lldb_private::FileSpec* file,
178 lldb::offset_t file_offset,
179 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000181 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000183 data_sp = file->MemoryMapFileContents(file_offset, length);
184 data_offset = 0;
185 }
186
187 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
188 {
189 const uint8_t *magic = data_sp->GetBytes() + data_offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000190 if (ELFHeader::MagicBytesMatch(magic))
191 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000192 // Update the data to contain the entire file if it doesn't already
Andrew Kaylor213f6722013-02-07 21:30:54 +0000193 if (data_sp->GetByteSize() < length) {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000194 data_sp = file->MemoryMapFileContents(file_offset, length);
Greg Clayton64ff6c72013-02-07 21:49:54 +0000195 data_offset = 0;
196 magic = data_sp->GetBytes();
Andrew Kaylor213f6722013-02-07 21:30:54 +0000197 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000198 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
199 if (address_size == 4 || address_size == 8)
200 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000201 std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, data_offset, file, file_offset, length));
Stephen Wilson3f4200fd2011-02-24 19:16:15 +0000202 ArchSpec spec;
203 if (objfile_ap->GetArchitecture(spec) &&
204 objfile_ap->SetModulesArchitecture(spec))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000205 return objfile_ap.release();
206 }
207 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208 }
209 return NULL;
210}
211
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000212
Greg Claytonc9660542012-02-05 02:38:54 +0000213ObjectFile*
Greg Claytone72dfb32012-02-24 01:59:29 +0000214ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
215 DataBufferSP& data_sp,
216 const lldb::ProcessSP &process_sp,
217 lldb::addr_t header_addr)
Greg Claytonc9660542012-02-05 02:38:54 +0000218{
219 return NULL;
220}
221
222
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000223//------------------------------------------------------------------
224// PluginInterface protocol
225//------------------------------------------------------------------
226const char *
227ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000229 return "ObjectFileELF";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000230}
231
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000232const char *
233ObjectFileELF::GetShortPluginName()
234{
235 return GetPluginNameStatic();
236}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000238uint32_t
239ObjectFileELF::GetPluginVersion()
240{
241 return m_plugin_version;
242}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000243//------------------------------------------------------------------
244// ObjectFile protocol
245//------------------------------------------------------------------
246
Greg Claytone72dfb32012-02-24 01:59:29 +0000247ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000248 DataBufferSP& data_sp,
249 lldb::offset_t data_offset,
Greg Claytone72dfb32012-02-24 01:59:29 +0000250 const FileSpec* file,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000251 lldb::offset_t file_offset,
252 lldb::offset_t length) :
253 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytone72dfb32012-02-24 01:59:29 +0000254 m_header(),
255 m_program_headers(),
256 m_section_headers(),
Greg Claytone72dfb32012-02-24 01:59:29 +0000257 m_filespec_ap(),
258 m_shstr_data()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259{
260 if (file)
261 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000262 ::memset(&m_header, 0, sizeof(m_header));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263}
264
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265ObjectFileELF::~ObjectFileELF()
266{
267}
268
Jim Ingham5aee1622010-08-09 23:31:02 +0000269bool
270ObjectFileELF::IsExecutable() const
271{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000272 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000273}
274
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000276ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277{
278 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
279 return eByteOrderBig;
280 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
281 return eByteOrderLittle;
282 return eByteOrderInvalid;
283}
284
Greg Claytonc7bece562013-01-25 18:06:21 +0000285uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000286ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000287{
288 return m_data.GetAddressByteSize();
289}
290
Greg Claytonc7bece562013-01-25 18:06:21 +0000291size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000292ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293{
Greg Claytonc7bece562013-01-25 18:06:21 +0000294 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000295}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296
Greg Claytonc7bece562013-01-25 18:06:21 +0000297size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000298ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
299{
Greg Claytonc7bece562013-01-25 18:06:21 +0000300 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301}
302
303bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000304ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000305{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000306 lldb::offset_t offset = GetFileOffset();
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000307 return m_header.Parse(m_data, &offset);
308}
309
310bool
Greg Clayton60830262011-02-04 18:53:10 +0000311ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000312{
313 // FIXME: Return MD5 sum here. See comment in ObjectFile.h.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 return false;
315}
316
317uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000318ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000320 size_t num_modules = ParseDependentModules();
321 uint32_t num_specs = 0;
322
323 for (unsigned i = 0; i < num_modules; ++i)
324 {
325 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
326 num_specs++;
327 }
328
329 return num_specs;
330}
331
Stephen Wilson499b40e2011-03-30 16:07:05 +0000332user_id_t
333ObjectFileELF::GetSectionIndexByType(unsigned type)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000334{
335 if (!ParseSectionHeaders())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000336 return 0;
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000337
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000338 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
339 sh_pos != m_section_headers.end(); ++sh_pos)
340 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000341 if (sh_pos->sh_type == type)
342 return SectionIndex(sh_pos);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000343 }
344
Stephen Wilson499b40e2011-03-30 16:07:05 +0000345 return 0;
346}
347
348Address
349ObjectFileELF::GetImageInfoAddress()
350{
351 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000352 return Address();
353
354 SectionList *section_list = GetSectionList();
355 if (!section_list)
356 return Address();
357
Stephen Wilson499b40e2011-03-30 16:07:05 +0000358 user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
359 if (!dynsym_id)
360 return Address();
361
362 const ELFSectionHeader *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
363 if (!dynsym_hdr)
364 return Address();
365
Greg Claytone72dfb32012-02-24 01:59:29 +0000366 SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
367 if (dynsym_section_sp)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000368 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000369 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000370 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000371 ELFDynamic &symbol = m_dynamic_symbols[i];
372
373 if (symbol.d_tag == DT_DEBUG)
374 {
375 // Compute the offset as the number of previous entries plus the
376 // size of d_tag.
377 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
378 return Address(dynsym_section_sp, offset);
379 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000380 }
381 }
382
383 return Address();
384}
385
Jim Ingham672e6f52011-03-07 23:44:08 +0000386lldb_private::Address
387ObjectFileELF::GetEntryPointAddress ()
388{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000389 SectionList *sections;
390 addr_t offset;
Jim Ingham672e6f52011-03-07 23:44:08 +0000391
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000392 if (m_entry_point_address.IsValid())
393 return m_entry_point_address;
394
395 if (!ParseHeader() || !IsExecutable())
396 return m_entry_point_address;
397
398 sections = GetSectionList();
399 offset = m_header.e_entry;
400
401 if (!sections)
402 {
403 m_entry_point_address.SetOffset(offset);
404 return m_entry_point_address;
405 }
406
407 m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
408
409 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000410}
411
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000412//----------------------------------------------------------------------
413// ParseDependentModules
414//----------------------------------------------------------------------
415size_t
416ObjectFileELF::ParseDependentModules()
417{
418 if (m_filespec_ap.get())
419 return m_filespec_ap->GetSize();
420
421 m_filespec_ap.reset(new FileSpecList());
422
423 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
424 return 0;
425
426 // Locate the dynamic table.
427 user_id_t dynsym_id = 0;
428 user_id_t dynstr_id = 0;
Greg Clayton450e3f32010-10-12 02:24:53 +0000429 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
430 sh_pos != m_section_headers.end(); ++sh_pos)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000431 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000432 if (sh_pos->sh_type == SHT_DYNAMIC)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000433 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000434 dynsym_id = SectionIndex(sh_pos);
435 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000436 break;
437 }
438 }
439
440 if (!(dynsym_id && dynstr_id))
441 return 0;
442
443 SectionList *section_list = GetSectionList();
444 if (!section_list)
445 return 0;
446
447 // Resolve and load the dynamic table entries and corresponding string
448 // table.
449 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
450 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
451 if (!(dynsym && dynstr))
452 return 0;
453
454 DataExtractor dynsym_data;
455 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000456 if (ReadSectionData(dynsym, dynsym_data) &&
457 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000458 {
459 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000460 const lldb::offset_t section_size = dynsym_data.GetByteSize();
461 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000462
463 // The only type of entries we are concerned with are tagged DT_NEEDED,
464 // yielding the name of a required library.
465 while (offset < section_size)
466 {
467 if (!symbol.Parse(dynsym_data, &offset))
468 break;
469
470 if (symbol.d_tag != DT_NEEDED)
471 continue;
472
473 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
474 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000475 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000476 }
477 }
478
479 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480}
481
482//----------------------------------------------------------------------
483// ParseProgramHeaders
484//----------------------------------------------------------------------
485size_t
486ObjectFileELF::ParseProgramHeaders()
487{
488 // We have already parsed the program headers
489 if (!m_program_headers.empty())
490 return m_program_headers.size();
491
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000492 // If there are no program headers to read we are done.
493 if (m_header.e_phnum == 0)
494 return 0;
495
496 m_program_headers.resize(m_header.e_phnum);
497 if (m_program_headers.size() != m_header.e_phnum)
498 return 0;
499
500 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000501 const elf_off ph_offset = m_header.e_phoff;
502 DataExtractor data;
503 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000504 return 0;
505
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000506 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000507 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000508 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000509 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000510 if (m_program_headers[idx].Parse(data, &offset) == false)
511 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512 }
513
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000514 if (idx < m_program_headers.size())
515 m_program_headers.resize(idx);
516
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 return m_program_headers.size();
518}
519
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520//----------------------------------------------------------------------
521// ParseSectionHeaders
522//----------------------------------------------------------------------
523size_t
524ObjectFileELF::ParseSectionHeaders()
525{
526 // We have already parsed the section headers
527 if (!m_section_headers.empty())
528 return m_section_headers.size();
529
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000530 // If there are no section headers we are done.
531 if (m_header.e_shnum == 0)
532 return 0;
533
534 m_section_headers.resize(m_header.e_shnum);
535 if (m_section_headers.size() != m_header.e_shnum)
536 return 0;
537
538 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000539 const elf_off sh_offset = m_header.e_shoff;
540 DataExtractor data;
541 if (GetData (sh_offset, sh_size, data) != sh_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000542 return 0;
543
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000544 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000545 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000546 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000547 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000548 if (m_section_headers[idx].Parse(data, &offset) == false)
549 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000551 if (idx < m_section_headers.size())
552 m_section_headers.resize(idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553
554 return m_section_headers.size();
555}
556
557size_t
558ObjectFileELF::GetSectionHeaderStringTable()
559{
560 if (m_shstr_data.GetByteSize() == 0)
561 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000562 const unsigned strtab_idx = m_header.e_shstrndx;
563
564 if (strtab_idx && strtab_idx < m_section_headers.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000565 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000566 const ELFSectionHeader &sheader = m_section_headers[strtab_idx];
567 const size_t byte_size = sheader.sh_size;
Greg Clayton44435ed2012-01-12 05:25:17 +0000568 const Elf64_Off offset = sheader.sh_offset;
569 m_shstr_data.SetData (m_data, offset, byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000570
Greg Clayton44435ed2012-01-12 05:25:17 +0000571 if (m_shstr_data.GetByteSize() != byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000572 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000573 }
574 }
575 return m_shstr_data.GetByteSize();
576}
577
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000578lldb::user_id_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579ObjectFileELF::GetSectionIndexByName(const char *name)
580{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000581 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
582 return 0;
583
584 // Search the collection of section headers for one with a matching name.
585 for (SectionHeaderCollIter I = m_section_headers.begin();
586 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000587 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000588 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
589
590 if (!sectionName)
591 return 0;
592
593 if (strcmp(name, sectionName) != 0)
594 continue;
595
596 return SectionIndex(I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597 }
598
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000599 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600}
601
Stephen Wilson499b40e2011-03-30 16:07:05 +0000602const elf::ELFSectionHeader *
603ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
604{
605 if (!ParseSectionHeaders() || !id)
606 return NULL;
607
608 if (--id < m_section_headers.size())
609 return &m_section_headers[id];
610
611 return NULL;
612}
613
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614SectionList *
615ObjectFileELF::GetSectionList()
616{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000617 if (m_sections_ap.get())
618 return m_sections_ap.get();
619
620 if (ParseSectionHeaders() && GetSectionHeaderStringTable())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621 {
622 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000624 for (SectionHeaderCollIter I = m_section_headers.begin();
625 I != m_section_headers.end(); ++I)
626 {
627 const ELFSectionHeader &header = *I;
628
629 ConstString name(m_shstr_data.PeekCStr(header.sh_name));
Greg Clayton47037bc2012-03-27 02:40:46 +0000630 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
631 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000632
Greg Clayton4ceb9982010-07-21 22:54:26 +0000633 static ConstString g_sect_name_text (".text");
634 static ConstString g_sect_name_data (".data");
635 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +0000636 static ConstString g_sect_name_tdata (".tdata");
637 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +0000638 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
639 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
640 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
641 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
642 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
643 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
644 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
645 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
646 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
647 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
648 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
649 static ConstString g_sect_name_eh_frame (".eh_frame");
650
651 SectionType sect_type = eSectionTypeOther;
652
Greg Clayton741f3f92012-03-27 21:10:07 +0000653 bool is_thread_specific = false;
654
Greg Clayton4ceb9982010-07-21 22:54:26 +0000655 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
656 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
657 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +0000658 else if (name == g_sect_name_tdata)
659 {
660 sect_type = eSectionTypeData;
661 is_thread_specific = true;
662 }
663 else if (name == g_sect_name_tbss)
664 {
665 sect_type = eSectionTypeZeroFill;
666 is_thread_specific = true;
667 }
Greg Clayton4ceb9982010-07-21 22:54:26 +0000668 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
669 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
670 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
671 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
672 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
673 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
674 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
675 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
676 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
677 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
678 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
679 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
680
681
Greg Clayton741f3f92012-03-27 21:10:07 +0000682 SectionSP section_sp(new Section(
Greg Clayton4ceb9982010-07-21 22:54:26 +0000683 GetModule(), // Module to which this section belongs.
684 SectionIndex(I), // Section ID.
685 name, // Section name.
686 sect_type, // Section type.
687 header.sh_addr, // VM address.
Greg Clayton47037bc2012-03-27 02:40:46 +0000688 vm_size, // VM size in bytes of this section.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000689 header.sh_offset, // Offset of this section in the file.
Greg Clayton47037bc2012-03-27 02:40:46 +0000690 file_size, // Size of the section as found in the file.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000691 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000692
Greg Clayton741f3f92012-03-27 21:10:07 +0000693 if (is_thread_specific)
694 section_sp->SetIsThreadSpecific (is_thread_specific);
695 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 }
Sean Callanan56775362012-06-08 02:16:08 +0000697
698 m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000699 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000700
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701 return m_sections_ap.get();
702}
703
Stephen Wilson499b40e2011-03-30 16:07:05 +0000704static unsigned
705ParseSymbols(Symtab *symtab,
706 user_id_t start_id,
707 SectionList *section_list,
708 const ELFSectionHeader *symtab_shdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000709 const DataExtractor &symtab_data,
710 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000712 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000713 lldb::offset_t offset = 0;
714 const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000715
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716 static ConstString text_section_name(".text");
717 static ConstString init_section_name(".init");
718 static ConstString fini_section_name(".fini");
719 static ConstString ctors_section_name(".ctors");
720 static ConstString dtors_section_name(".dtors");
721
722 static ConstString data_section_name(".data");
723 static ConstString rodata_section_name(".rodata");
724 static ConstString rodata1_section_name(".rodata1");
725 static ConstString data2_section_name(".data1");
726 static ConstString bss_section_name(".bss");
727
Greg Clayton9594f4c2013-04-13 23:17:23 +0000728 //StreamFile strm(stdout, false);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000729 unsigned i;
730 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000732 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 break;
Greg Clayton9594f4c2013-04-13 23:17:23 +0000734
735 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
736
737 // No need to add symbols that have no names
738 if (symbol_name == NULL || symbol_name[0] == '\0')
739 continue;
740
741 //symbol.Dump (&strm, i, &strtab_data, section_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000742
Greg Claytone72dfb32012-02-24 01:59:29 +0000743 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000744 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000745 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000746
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000747 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000748 {
749 case SHN_ABS:
750 symbol_type = eSymbolTypeAbsolute;
751 break;
752 case SHN_UNDEF:
753 symbol_type = eSymbolTypeUndefined;
754 break;
755 default:
Greg Claytone72dfb32012-02-24 01:59:29 +0000756 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 break;
758 }
759
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000760 // If a symbol is undefined do not process it further even if it has a STT type
761 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000763 switch (symbol.getType())
764 {
765 default:
766 case STT_NOTYPE:
767 // The symbol's type is not specified.
768 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000770 case STT_OBJECT:
771 // The symbol is associated with a data object, such as a variable,
772 // an array, etc.
773 symbol_type = eSymbolTypeData;
774 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000775
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000776 case STT_FUNC:
777 // The symbol is associated with a function or other executable code.
778 symbol_type = eSymbolTypeCode;
779 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000780
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000781 case STT_SECTION:
782 // The symbol is associated with a section. Symbol table entries of
783 // this type exist primarily for relocation and normally have
784 // STB_LOCAL binding.
785 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000786
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000787 case STT_FILE:
788 // Conventionally, the symbol's name gives the name of the source
789 // file associated with the object file. A file symbol has STB_LOCAL
790 // binding, its section index is SHN_ABS, and it precedes the other
791 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +0000792 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000793 break;
Matt Kopec00049b82013-02-27 20:13:38 +0000794
795 case STT_GNU_IFUNC:
796 // The symbol is associated with an indirect function. The actual
797 // function will be resolved if it is referenced.
798 symbol_type = eSymbolTypeResolver;
799 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000800 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801 }
802
803 if (symbol_type == eSymbolTypeInvalid)
804 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000805 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000806 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000807 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000808 if (sect_name == text_section_name ||
809 sect_name == init_section_name ||
810 sect_name == fini_section_name ||
811 sect_name == ctors_section_name ||
812 sect_name == dtors_section_name)
813 {
814 symbol_type = eSymbolTypeCode;
815 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000816 else if (sect_name == data_section_name ||
817 sect_name == data2_section_name ||
818 sect_name == rodata_section_name ||
819 sect_name == rodata1_section_name ||
820 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821 {
822 symbol_type = eSymbolTypeData;
823 }
824 }
825 }
826
827 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +0000828 if (symbol_section_sp)
829 symbol_value -= symbol_section_sp->GetFileAddress();
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000830 bool is_global = symbol.getBinding() == STB_GLOBAL;
831 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +0000832 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000833 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +0000834 i + start_id, // ID is the original symbol table index.
835 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +0000836 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +0000837 symbol_type, // Type of this symbol
838 is_global, // Is this globally visible?
839 false, // Is this symbol debug info?
840 false, // Is this symbol a trampoline?
841 false, // Is this symbol artificial?
842 symbol_section_sp, // Section in which this symbol is defined or null.
843 symbol_value, // Offset in section or symbol value.
844 symbol.st_size, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +0000845 true, // Size is valid
Greg Claytone72dfb32012-02-24 01:59:29 +0000846 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000847 symtab->AddSymbol(dc_symbol);
848 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000849
850 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851}
852
Stephen Wilson499b40e2011-03-30 16:07:05 +0000853unsigned
854ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
855 const ELFSectionHeader *symtab_hdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000856 user_id_t symtab_id)
857{
Stephen Wilson499b40e2011-03-30 16:07:05 +0000858 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
859 symtab_hdr->sh_type == SHT_DYNSYM);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000860
861 // Parse in the section list if needed.
862 SectionList *section_list = GetSectionList();
863 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000864 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000865
866 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +0000867 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000868
869 Section *symtab = section_list->FindSectionByID(symtab_id).get();
870 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +0000871 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000872 if (symtab && strtab)
873 {
874 DataExtractor symtab_data;
875 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000876 if (ReadSectionData(symtab, symtab_data) &&
877 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000878 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000879 num_symbols = ParseSymbols(symbol_table, start_id,
880 section_list, symtab_hdr,
881 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000882 }
883 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000884
885 return num_symbols;
886}
887
888size_t
889ObjectFileELF::ParseDynamicSymbols()
890{
891 if (m_dynamic_symbols.size())
892 return m_dynamic_symbols.size();
893
894 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
895 if (!dyn_id)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000896 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000897
898 SectionList *section_list = GetSectionList();
899 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000900 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000901
902 Section *dynsym = section_list->FindSectionByID(dyn_id).get();
903 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000904 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000905
906 ELFDynamic symbol;
907 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000908 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +0000909 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000910 const lldb::offset_t section_size = dynsym_data.GetByteSize();
911 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000912
913 while (cursor < section_size)
914 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000915 if (!symbol.Parse(dynsym_data, &cursor))
916 break;
917
918 m_dynamic_symbols.push_back(symbol);
919 }
920 }
921
922 return m_dynamic_symbols.size();
923}
924
925const ELFDynamic *
926ObjectFileELF::FindDynamicSymbol(unsigned tag)
927{
928 if (!ParseDynamicSymbols())
929 return NULL;
930
931 SectionList *section_list = GetSectionList();
932 if (!section_list)
933 return 0;
934
935 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
936 DynamicSymbolCollIter E = m_dynamic_symbols.end();
937 for ( ; I != E; ++I)
938 {
939 ELFDynamic *symbol = &*I;
940
941 if (symbol->d_tag == tag)
942 return symbol;
943 }
944
945 return NULL;
946}
947
948Section *
949ObjectFileELF::PLTSection()
950{
951 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
952 SectionList *section_list = GetSectionList();
953
954 if (symbol && section_list)
955 {
956 addr_t addr = symbol->d_ptr;
957 return section_list->FindSectionContainingFileAddress(addr).get();
958 }
959
960 return NULL;
961}
962
963unsigned
964ObjectFileELF::PLTRelocationType()
965{
966 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
967
968 if (symbol)
969 return symbol->d_val;
970
971 return 0;
972}
973
974static unsigned
975ParsePLTRelocations(Symtab *symbol_table,
976 user_id_t start_id,
977 unsigned rel_type,
978 const ELFHeader *hdr,
979 const ELFSectionHeader *rel_hdr,
980 const ELFSectionHeader *plt_hdr,
981 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +0000982 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +0000983 DataExtractor &rel_data,
984 DataExtractor &symtab_data,
985 DataExtractor &strtab_data)
986{
987 ELFRelocation rel(rel_type);
988 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000989 lldb::offset_t offset = 0;
990 const elf_xword plt_entsize = plt_hdr->sh_entsize;
991 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000992
993 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
994 reloc_info_fn reloc_type;
995 reloc_info_fn reloc_symbol;
996
Greg Claytond091afe2012-11-12 22:53:16 +0000997 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000998 {
999 reloc_type = ELFRelocation::RelocType32;
1000 reloc_symbol = ELFRelocation::RelocSymbol32;
1001 }
1002 else
1003 {
1004 reloc_type = ELFRelocation::RelocType64;
1005 reloc_symbol = ELFRelocation::RelocSymbol64;
1006 }
1007
1008 unsigned slot_type = hdr->GetRelocationJumpSlotType();
1009 unsigned i;
1010 for (i = 0; i < num_relocations; ++i)
1011 {
1012 if (rel.Parse(rel_data, &offset) == false)
1013 break;
1014
1015 if (reloc_type(rel) != slot_type)
1016 continue;
1017
Greg Claytonc7bece562013-01-25 18:06:21 +00001018 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001019 uint64_t plt_index = (i + 1) * plt_entsize;
1020
1021 if (!symbol.Parse(symtab_data, &symbol_offset))
1022 break;
1023
1024 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001025 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001026
1027 Symbol jump_symbol(
1028 i + start_id, // Symbol table index
1029 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001030 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001031 eSymbolTypeTrampoline, // Type of this symbol
1032 false, // Is this globally visible?
1033 false, // Is this symbol debug info?
1034 true, // Is this symbol a trampoline?
1035 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001036 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001037 plt_index, // Offset in section or symbol value.
1038 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001039 true, // Size is valid
Stephen Wilson499b40e2011-03-30 16:07:05 +00001040 0); // Symbol flags.
1041
1042 symbol_table->AddSymbol(jump_symbol);
1043 }
1044
1045 return i;
1046}
1047
1048unsigned
1049ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1050 user_id_t start_id,
1051 const ELFSectionHeader *rel_hdr,
1052 user_id_t rel_id)
1053{
1054 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1055
1056 // The link field points to the asscoiated symbol table. The info field
1057 // points to the section holding the plt.
1058 user_id_t symtab_id = rel_hdr->sh_link;
1059 user_id_t plt_id = rel_hdr->sh_info;
1060
1061 if (!symtab_id || !plt_id)
1062 return 0;
1063
1064 // Section ID's are ones based;
1065 symtab_id++;
1066 plt_id++;
1067
1068 const ELFSectionHeader *plt_hdr = GetSectionHeaderByIndex(plt_id);
1069 if (!plt_hdr)
1070 return 0;
1071
1072 const ELFSectionHeader *sym_hdr = GetSectionHeaderByIndex(symtab_id);
1073 if (!sym_hdr)
1074 return 0;
1075
1076 SectionList *section_list = GetSectionList();
1077 if (!section_list)
1078 return 0;
1079
1080 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1081 if (!rel_section)
1082 return 0;
1083
Greg Claytone72dfb32012-02-24 01:59:29 +00001084 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1085 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001086 return 0;
1087
1088 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1089 if (!symtab)
1090 return 0;
1091
1092 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1093 if (!strtab)
1094 return 0;
1095
1096 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001097 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001098 return 0;
1099
1100 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001101 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001102 return 0;
1103
1104 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001105 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001106 return 0;
1107
1108 unsigned rel_type = PLTRelocationType();
1109 if (!rel_type)
1110 return 0;
1111
Greg Claytone72dfb32012-02-24 01:59:29 +00001112 return ParsePLTRelocations (symbol_table,
1113 start_id,
1114 rel_type,
1115 &m_header,
1116 rel_hdr,
1117 plt_hdr,
1118 sym_hdr,
1119 plt_section_sp,
1120 rel_data,
1121 symtab_data,
1122 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001123}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001124
1125Symtab *
1126ObjectFileELF::GetSymtab()
1127{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001128 if (m_symtab_ap.get())
1129 return m_symtab_ap.get();
1130
1131 Symtab *symbol_table = new Symtab(this);
1132 m_symtab_ap.reset(symbol_table);
1133
Stephen Wilson499b40e2011-03-30 16:07:05 +00001134 Mutex::Locker locker(symbol_table->GetMutex());
Greg Clayton8087ca22010-10-08 04:20:14 +00001135
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001136 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1137 return symbol_table;
1138
1139 // Locate and parse all linker symbol tables.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001140 uint64_t symbol_id = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001141 for (SectionHeaderCollIter I = m_section_headers.begin();
1142 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143 {
Peter Collingbourneb4aabeb2011-06-03 20:39:58 +00001144 if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001146 const ELFSectionHeader &symtab_header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001147 user_id_t section_id = SectionIndex(I);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001148 symbol_id += ParseSymbolTable(symbol_table, symbol_id,
1149 &symtab_header, section_id);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 }
1151 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001152
1153 // Synthesize trampoline symbols to help navigate the PLT.
1154 Section *reloc_section = PLTSection();
1155 if (reloc_section)
1156 {
1157 user_id_t reloc_id = reloc_section->GetID();
1158 const ELFSectionHeader *reloc_header = GetSectionHeaderByIndex(reloc_id);
1159 assert(reloc_header);
1160
1161 ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
1162 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001163
1164 return symbol_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001165}
1166
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167//===----------------------------------------------------------------------===//
1168// Dump
1169//
1170// Dump the specifics of the runtime file container (such as any headers
1171// segments, sections, etc).
1172//----------------------------------------------------------------------
1173void
1174ObjectFileELF::Dump(Stream *s)
1175{
1176 DumpELFHeader(s, m_header);
1177 s->EOL();
1178 DumpELFProgramHeaders(s);
1179 s->EOL();
1180 DumpELFSectionHeaders(s);
1181 s->EOL();
1182 SectionList *section_list = GetSectionList();
1183 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001184 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185 Symtab *symtab = GetSymtab();
1186 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001187 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001188 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001189 DumpDependentModules(s);
1190 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191}
1192
1193//----------------------------------------------------------------------
1194// DumpELFHeader
1195//
1196// Dump the ELF header to the specified output stream
1197//----------------------------------------------------------------------
1198void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001199ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001201 s->PutCString("ELF Header\n");
1202 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1203 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1204 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1205 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1206 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1207 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1208 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001210 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1211 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1213 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1214 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1215
1216 s->Printf("e_type = 0x%4.4x ", header.e_type);
1217 DumpELFHeader_e_type(s, header.e_type);
1218 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1219 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001220 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1221 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1222 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001223 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1224 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1225 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1226 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1227 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1228 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1229 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1230}
1231
1232//----------------------------------------------------------------------
1233// DumpELFHeader_e_type
1234//
1235// Dump an token value for the ELF header member e_type
1236//----------------------------------------------------------------------
1237void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001238ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001239{
1240 switch (e_type)
1241 {
1242 case ET_NONE: *s << "ET_NONE"; break;
1243 case ET_REL: *s << "ET_REL"; break;
1244 case ET_EXEC: *s << "ET_EXEC"; break;
1245 case ET_DYN: *s << "ET_DYN"; break;
1246 case ET_CORE: *s << "ET_CORE"; break;
1247 default:
1248 break;
1249 }
1250}
1251
1252//----------------------------------------------------------------------
1253// DumpELFHeader_e_ident_EI_DATA
1254//
1255// Dump an token value for the ELF header member e_ident[EI_DATA]
1256//----------------------------------------------------------------------
1257void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001258ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259{
1260 switch (ei_data)
1261 {
1262 case ELFDATANONE: *s << "ELFDATANONE"; break;
1263 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1264 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1265 default:
1266 break;
1267 }
1268}
1269
1270
1271//----------------------------------------------------------------------
1272// DumpELFProgramHeader
1273//
1274// Dump a single ELF program header to the specified output stream
1275//----------------------------------------------------------------------
1276void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001277ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001278{
1279 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001280 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1281 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001282
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001283 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001284 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001285}
1286
1287//----------------------------------------------------------------------
1288// DumpELFProgramHeader_p_type
1289//
1290// Dump an token value for the ELF program header member p_type which
1291// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001292// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001293void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001294ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295{
1296 const int kStrWidth = 10;
1297 switch (p_type)
1298 {
1299 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1300 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1301 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1302 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1303 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1304 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1305 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1306 default:
1307 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1308 break;
1309 }
1310}
1311
1312
1313//----------------------------------------------------------------------
1314// DumpELFProgramHeader_p_flags
1315//
1316// Dump an token value for the ELF program header member p_flags
1317//----------------------------------------------------------------------
1318void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001319ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001320{
1321 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1322 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1323 << ((p_flags & PF_W) ? "PF_W" : " ")
1324 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1325 << ((p_flags & PF_R) ? "PF_R" : " ");
1326}
1327
1328//----------------------------------------------------------------------
1329// DumpELFProgramHeaders
1330//
1331// Dump all of the ELF program header to the specified output stream
1332//----------------------------------------------------------------------
1333void
1334ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1335{
1336 if (ParseProgramHeaders())
1337 {
1338 s->PutCString("Program Headers\n");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001339 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
1340 "p_filesz p_memsz p_flags p_align\n");
1341 s->PutCString("==== ---------- -------- -------- -------- "
1342 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001343
1344 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001345 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1346 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001347 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001348 s->Printf("[%2u] ", idx);
1349 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350 s->EOL();
1351 }
1352 }
1353}
1354
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001355//----------------------------------------------------------------------
1356// DumpELFSectionHeader
1357//
1358// Dump a single ELF section header to the specified output stream
1359//----------------------------------------------------------------------
1360void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001361ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001362{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001363 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001364 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001365 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001366 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001367 s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr, sh.sh_offset, sh.sh_size);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001368 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001369 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001370}
1371
1372//----------------------------------------------------------------------
1373// DumpELFSectionHeader_sh_type
1374//
1375// Dump an token value for the ELF section header member sh_type which
1376// describes the type of the section
1377//----------------------------------------------------------------------
1378void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001379ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380{
1381 const int kStrWidth = 12;
1382 switch (sh_type)
1383 {
1384 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1385 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1386 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1387 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1388 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1389 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1390 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1391 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1392 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1393 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1394 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1395 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1396 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1397 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1398 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1399 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1400 default:
1401 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1402 break;
1403 }
1404}
1405
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001406//----------------------------------------------------------------------
1407// DumpELFSectionHeader_sh_flags
1408//
1409// Dump an token value for the ELF section header member sh_flags
1410//----------------------------------------------------------------------
1411void
Greg Claytonc7bece562013-01-25 18:06:21 +00001412ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001413{
1414 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1415 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1416 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1417 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1418 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1419}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001420
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001421//----------------------------------------------------------------------
1422// DumpELFSectionHeaders
1423//
1424// Dump all of the ELF section header to the specified output stream
1425//----------------------------------------------------------------------
1426void
1427ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1428{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001429 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1430 return;
1431
1432 s->PutCString("Section Headers\n");
1433 s->PutCString("IDX name type flags "
1434 "addr offset size link info addralgn "
1435 "entsize Name\n");
1436 s->PutCString("==== -------- ------------ -------------------------------- "
1437 "-------- -------- -------- -------- -------- -------- "
1438 "-------- ====================\n");
1439
1440 uint32_t idx = 0;
1441 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1442 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001443 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001444 s->Printf("[%2u] ", idx);
1445 ObjectFileELF::DumpELFSectionHeader(s, *I);
1446 const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
1447 if (section_name)
1448 *s << ' ' << section_name << "\n";
1449 }
1450}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001451
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001452void
1453ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1454{
1455 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001456
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001457 if (num_modules > 0)
1458 {
1459 s->PutCString("Dependent Modules:\n");
1460 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001461 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001462 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1463 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001464 }
1465 }
1466}
1467
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001468bool
Greg Clayton514487e2011-02-15 21:59:32 +00001469ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001470{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001471 if (!ParseHeader())
1472 return false;
1473
Greg Claytone0d378b2011-03-24 21:19:54 +00001474 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001475 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1476 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001477 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001478}
1479
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001480ObjectFile::Type
1481ObjectFileELF::CalculateType()
1482{
1483 switch (m_header.e_type)
1484 {
1485 case llvm::ELF::ET_NONE:
1486 // 0 - No file type
1487 return eTypeUnknown;
1488
1489 case llvm::ELF::ET_REL:
1490 // 1 - Relocatable file
1491 return eTypeObjectFile;
1492
1493 case llvm::ELF::ET_EXEC:
1494 // 2 - Executable file
1495 return eTypeExecutable;
1496
1497 case llvm::ELF::ET_DYN:
1498 // 3 - Shared object file
1499 return eTypeSharedLibrary;
1500
1501 case ET_CORE:
1502 // 4 - Core file
1503 return eTypeCoreFile;
1504
1505 default:
1506 break;
1507 }
1508 return eTypeUnknown;
1509}
1510
1511ObjectFile::Strata
1512ObjectFileELF::CalculateStrata()
1513{
1514 switch (m_header.e_type)
1515 {
1516 case llvm::ELF::ET_NONE:
1517 // 0 - No file type
1518 return eStrataUnknown;
1519
1520 case llvm::ELF::ET_REL:
1521 // 1 - Relocatable file
1522 return eStrataUnknown;
1523
1524 case llvm::ELF::ET_EXEC:
1525 // 2 - Executable file
1526 // TODO: is there any way to detect that an executable is a kernel
1527 // related executable by inspecting the program headers, section
1528 // headers, symbols, or any other flag bits???
1529 return eStrataUser;
1530
1531 case llvm::ELF::ET_DYN:
1532 // 3 - Shared object file
1533 // TODO: is there any way to detect that an shared library is a kernel
1534 // related executable by inspecting the program headers, section
1535 // headers, symbols, or any other flag bits???
1536 return eStrataUnknown;
1537
1538 case ET_CORE:
1539 // 4 - Core file
1540 // TODO: is there any way to detect that an core file is a kernel
1541 // related executable by inspecting the program headers, section
1542 // headers, symbols, or any other flag bits???
1543 return eStrataUnknown;
1544
1545 default:
1546 break;
1547 }
1548 return eStrataUnknown;
1549}
1550