blob: 5500e236998379d6c9a0f34cde6cb0b1867808bf [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 Clayton5ce9c562013-02-06 17:22:03 +0000201 std::auto_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(),
257 m_sections_ap(),
258 m_symtab_ap(),
259 m_filespec_ap(),
260 m_shstr_data()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261{
262 if (file)
263 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000264 ::memset(&m_header, 0, sizeof(m_header));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265}
266
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267ObjectFileELF::~ObjectFileELF()
268{
269}
270
Jim Ingham5aee1622010-08-09 23:31:02 +0000271bool
272ObjectFileELF::IsExecutable() const
273{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000274 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000275}
276
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000278ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279{
280 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
281 return eByteOrderBig;
282 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
283 return eByteOrderLittle;
284 return eByteOrderInvalid;
285}
286
Greg Claytonc7bece562013-01-25 18:06:21 +0000287uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000288ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289{
290 return m_data.GetAddressByteSize();
291}
292
Greg Claytonc7bece562013-01-25 18:06:21 +0000293size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000294ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295{
Greg Claytonc7bece562013-01-25 18:06:21 +0000296 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000297}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298
Greg Claytonc7bece562013-01-25 18:06:21 +0000299size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000300ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
301{
Greg Claytonc7bece562013-01-25 18:06:21 +0000302 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303}
304
305bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000306ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000308 lldb::offset_t offset = GetFileOffset();
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000309 return m_header.Parse(m_data, &offset);
310}
311
312bool
Greg Clayton60830262011-02-04 18:53:10 +0000313ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000314{
315 // FIXME: Return MD5 sum here. See comment in ObjectFile.h.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 return false;
317}
318
319uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000320ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000322 size_t num_modules = ParseDependentModules();
323 uint32_t num_specs = 0;
324
325 for (unsigned i = 0; i < num_modules; ++i)
326 {
327 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
328 num_specs++;
329 }
330
331 return num_specs;
332}
333
Stephen Wilson499b40e2011-03-30 16:07:05 +0000334user_id_t
335ObjectFileELF::GetSectionIndexByType(unsigned type)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000336{
337 if (!ParseSectionHeaders())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000338 return 0;
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000339
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000340 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
341 sh_pos != m_section_headers.end(); ++sh_pos)
342 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000343 if (sh_pos->sh_type == type)
344 return SectionIndex(sh_pos);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000345 }
346
Stephen Wilson499b40e2011-03-30 16:07:05 +0000347 return 0;
348}
349
350Address
351ObjectFileELF::GetImageInfoAddress()
352{
353 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000354 return Address();
355
356 SectionList *section_list = GetSectionList();
357 if (!section_list)
358 return Address();
359
Stephen Wilson499b40e2011-03-30 16:07:05 +0000360 user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
361 if (!dynsym_id)
362 return Address();
363
364 const ELFSectionHeader *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
365 if (!dynsym_hdr)
366 return Address();
367
Greg Claytone72dfb32012-02-24 01:59:29 +0000368 SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
369 if (dynsym_section_sp)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000370 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000371 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000372 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000373 ELFDynamic &symbol = m_dynamic_symbols[i];
374
375 if (symbol.d_tag == DT_DEBUG)
376 {
377 // Compute the offset as the number of previous entries plus the
378 // size of d_tag.
379 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
380 return Address(dynsym_section_sp, offset);
381 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000382 }
383 }
384
385 return Address();
386}
387
Jim Ingham672e6f52011-03-07 23:44:08 +0000388lldb_private::Address
389ObjectFileELF::GetEntryPointAddress ()
390{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000391 SectionList *sections;
392 addr_t offset;
Jim Ingham672e6f52011-03-07 23:44:08 +0000393
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000394 if (m_entry_point_address.IsValid())
395 return m_entry_point_address;
396
397 if (!ParseHeader() || !IsExecutable())
398 return m_entry_point_address;
399
400 sections = GetSectionList();
401 offset = m_header.e_entry;
402
403 if (!sections)
404 {
405 m_entry_point_address.SetOffset(offset);
406 return m_entry_point_address;
407 }
408
409 m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
410
411 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000412}
413
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000414//----------------------------------------------------------------------
415// ParseDependentModules
416//----------------------------------------------------------------------
417size_t
418ObjectFileELF::ParseDependentModules()
419{
420 if (m_filespec_ap.get())
421 return m_filespec_ap->GetSize();
422
423 m_filespec_ap.reset(new FileSpecList());
424
425 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
426 return 0;
427
428 // Locate the dynamic table.
429 user_id_t dynsym_id = 0;
430 user_id_t dynstr_id = 0;
Greg Clayton450e3f32010-10-12 02:24:53 +0000431 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
432 sh_pos != m_section_headers.end(); ++sh_pos)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000433 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000434 if (sh_pos->sh_type == SHT_DYNAMIC)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000435 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000436 dynsym_id = SectionIndex(sh_pos);
437 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000438 break;
439 }
440 }
441
442 if (!(dynsym_id && dynstr_id))
443 return 0;
444
445 SectionList *section_list = GetSectionList();
446 if (!section_list)
447 return 0;
448
449 // Resolve and load the dynamic table entries and corresponding string
450 // table.
451 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
452 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
453 if (!(dynsym && dynstr))
454 return 0;
455
456 DataExtractor dynsym_data;
457 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000458 if (ReadSectionData(dynsym, dynsym_data) &&
459 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000460 {
461 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000462 const lldb::offset_t section_size = dynsym_data.GetByteSize();
463 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000464
465 // The only type of entries we are concerned with are tagged DT_NEEDED,
466 // yielding the name of a required library.
467 while (offset < section_size)
468 {
469 if (!symbol.Parse(dynsym_data, &offset))
470 break;
471
472 if (symbol.d_tag != DT_NEEDED)
473 continue;
474
475 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
476 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000477 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000478 }
479 }
480
481 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482}
483
484//----------------------------------------------------------------------
485// ParseProgramHeaders
486//----------------------------------------------------------------------
487size_t
488ObjectFileELF::ParseProgramHeaders()
489{
490 // We have already parsed the program headers
491 if (!m_program_headers.empty())
492 return m_program_headers.size();
493
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000494 // If there are no program headers to read we are done.
495 if (m_header.e_phnum == 0)
496 return 0;
497
498 m_program_headers.resize(m_header.e_phnum);
499 if (m_program_headers.size() != m_header.e_phnum)
500 return 0;
501
502 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000503 const elf_off ph_offset = m_header.e_phoff;
504 DataExtractor data;
505 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000506 return 0;
507
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000508 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000509 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000510 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000512 if (m_program_headers[idx].Parse(data, &offset) == false)
513 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 }
515
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000516 if (idx < m_program_headers.size())
517 m_program_headers.resize(idx);
518
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519 return m_program_headers.size();
520}
521
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522//----------------------------------------------------------------------
523// ParseSectionHeaders
524//----------------------------------------------------------------------
525size_t
526ObjectFileELF::ParseSectionHeaders()
527{
528 // We have already parsed the section headers
529 if (!m_section_headers.empty())
530 return m_section_headers.size();
531
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000532 // If there are no section headers we are done.
533 if (m_header.e_shnum == 0)
534 return 0;
535
536 m_section_headers.resize(m_header.e_shnum);
537 if (m_section_headers.size() != m_header.e_shnum)
538 return 0;
539
540 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000541 const elf_off sh_offset = m_header.e_shoff;
542 DataExtractor data;
543 if (GetData (sh_offset, sh_size, data) != sh_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000544 return 0;
545
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000546 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000547 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000548 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000549 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000550 if (m_section_headers[idx].Parse(data, &offset) == false)
551 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000552 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000553 if (idx < m_section_headers.size())
554 m_section_headers.resize(idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555
556 return m_section_headers.size();
557}
558
559size_t
560ObjectFileELF::GetSectionHeaderStringTable()
561{
562 if (m_shstr_data.GetByteSize() == 0)
563 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000564 const unsigned strtab_idx = m_header.e_shstrndx;
565
566 if (strtab_idx && strtab_idx < m_section_headers.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000568 const ELFSectionHeader &sheader = m_section_headers[strtab_idx];
569 const size_t byte_size = sheader.sh_size;
Greg Clayton44435ed2012-01-12 05:25:17 +0000570 const Elf64_Off offset = sheader.sh_offset;
571 m_shstr_data.SetData (m_data, offset, byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000572
Greg Clayton44435ed2012-01-12 05:25:17 +0000573 if (m_shstr_data.GetByteSize() != byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 }
576 }
577 return m_shstr_data.GetByteSize();
578}
579
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000580lldb::user_id_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581ObjectFileELF::GetSectionIndexByName(const char *name)
582{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000583 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
584 return 0;
585
586 // Search the collection of section headers for one with a matching name.
587 for (SectionHeaderCollIter I = m_section_headers.begin();
588 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000590 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
591
592 if (!sectionName)
593 return 0;
594
595 if (strcmp(name, sectionName) != 0)
596 continue;
597
598 return SectionIndex(I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599 }
600
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000601 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602}
603
Stephen Wilson499b40e2011-03-30 16:07:05 +0000604const elf::ELFSectionHeader *
605ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
606{
607 if (!ParseSectionHeaders() || !id)
608 return NULL;
609
610 if (--id < m_section_headers.size())
611 return &m_section_headers[id];
612
613 return NULL;
614}
615
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000616SectionList *
617ObjectFileELF::GetSectionList()
618{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000619 if (m_sections_ap.get())
620 return m_sections_ap.get();
621
622 if (ParseSectionHeaders() && GetSectionHeaderStringTable())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623 {
624 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000626 for (SectionHeaderCollIter I = m_section_headers.begin();
627 I != m_section_headers.end(); ++I)
628 {
629 const ELFSectionHeader &header = *I;
630
631 ConstString name(m_shstr_data.PeekCStr(header.sh_name));
Greg Clayton47037bc2012-03-27 02:40:46 +0000632 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
633 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000634
Greg Clayton4ceb9982010-07-21 22:54:26 +0000635 static ConstString g_sect_name_text (".text");
636 static ConstString g_sect_name_data (".data");
637 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +0000638 static ConstString g_sect_name_tdata (".tdata");
639 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +0000640 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
641 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
642 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
643 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
644 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
645 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
646 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
647 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
648 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
649 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
650 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
651 static ConstString g_sect_name_eh_frame (".eh_frame");
652
653 SectionType sect_type = eSectionTypeOther;
654
Greg Clayton741f3f92012-03-27 21:10:07 +0000655 bool is_thread_specific = false;
656
Greg Clayton4ceb9982010-07-21 22:54:26 +0000657 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
658 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
659 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +0000660 else if (name == g_sect_name_tdata)
661 {
662 sect_type = eSectionTypeData;
663 is_thread_specific = true;
664 }
665 else if (name == g_sect_name_tbss)
666 {
667 sect_type = eSectionTypeZeroFill;
668 is_thread_specific = true;
669 }
Greg Clayton4ceb9982010-07-21 22:54:26 +0000670 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
671 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
672 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
673 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
674 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
675 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
676 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
677 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
678 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
679 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
680 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
681 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
682
683
Greg Clayton741f3f92012-03-27 21:10:07 +0000684 SectionSP section_sp(new Section(
Greg Clayton4ceb9982010-07-21 22:54:26 +0000685 GetModule(), // Module to which this section belongs.
686 SectionIndex(I), // Section ID.
687 name, // Section name.
688 sect_type, // Section type.
689 header.sh_addr, // VM address.
Greg Clayton47037bc2012-03-27 02:40:46 +0000690 vm_size, // VM size in bytes of this section.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000691 header.sh_offset, // Offset of this section in the file.
Greg Clayton47037bc2012-03-27 02:40:46 +0000692 file_size, // Size of the section as found in the file.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000693 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000694
Greg Clayton741f3f92012-03-27 21:10:07 +0000695 if (is_thread_specific)
696 section_sp->SetIsThreadSpecific (is_thread_specific);
697 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698 }
Sean Callanan56775362012-06-08 02:16:08 +0000699
700 m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000702
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703 return m_sections_ap.get();
704}
705
Stephen Wilson499b40e2011-03-30 16:07:05 +0000706static unsigned
707ParseSymbols(Symtab *symtab,
708 user_id_t start_id,
709 SectionList *section_list,
710 const ELFSectionHeader *symtab_shdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000711 const DataExtractor &symtab_data,
712 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000713{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000714 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000715 lldb::offset_t offset = 0;
716 const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000717
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 static ConstString text_section_name(".text");
719 static ConstString init_section_name(".init");
720 static ConstString fini_section_name(".fini");
721 static ConstString ctors_section_name(".ctors");
722 static ConstString dtors_section_name(".dtors");
723
724 static ConstString data_section_name(".data");
725 static ConstString rodata_section_name(".rodata");
726 static ConstString rodata1_section_name(".rodata1");
727 static ConstString data2_section_name(".data1");
728 static ConstString bss_section_name(".bss");
729
Stephen Wilson499b40e2011-03-30 16:07:05 +0000730 unsigned i;
731 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000732 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000733 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734 break;
735
Greg Claytone72dfb32012-02-24 01:59:29 +0000736 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000738 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000740 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000741 {
742 case SHN_ABS:
743 symbol_type = eSymbolTypeAbsolute;
744 break;
745 case SHN_UNDEF:
746 symbol_type = eSymbolTypeUndefined;
747 break;
748 default:
Greg Claytone72dfb32012-02-24 01:59:29 +0000749 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750 break;
751 }
752
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000753 switch (symbol.getType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 {
755 default:
756 case STT_NOTYPE:
757 // The symbol's type is not specified.
758 break;
759
760 case STT_OBJECT:
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000761 // The symbol is associated with a data object, such as a variable,
762 // an array, etc.
763 symbol_type = eSymbolTypeData;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 break;
765
766 case STT_FUNC:
767 // The symbol is associated with a function or other executable code.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000768 symbol_type = eSymbolTypeCode;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769 break;
770
771 case STT_SECTION:
772 // The symbol is associated with a section. Symbol table entries of
773 // this type exist primarily for relocation and normally have
774 // STB_LOCAL binding.
775 break;
776
777 case STT_FILE:
778 // Conventionally, the symbol's name gives the name of the source
779 // file associated with the object file. A file symbol has STB_LOCAL
780 // binding, its section index is SHN_ABS, and it precedes the other
781 // STB_LOCAL symbols for the file, if it is present.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000782 symbol_type = eSymbolTypeObjectFile;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783 break;
784 }
785
786 if (symbol_type == eSymbolTypeInvalid)
787 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000788 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000790 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000791 if (sect_name == text_section_name ||
792 sect_name == init_section_name ||
793 sect_name == fini_section_name ||
794 sect_name == ctors_section_name ||
795 sect_name == dtors_section_name)
796 {
797 symbol_type = eSymbolTypeCode;
798 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000799 else if (sect_name == data_section_name ||
800 sect_name == data2_section_name ||
801 sect_name == rodata_section_name ||
802 sect_name == rodata1_section_name ||
803 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000804 {
805 symbol_type = eSymbolTypeData;
806 }
807 }
808 }
809
810 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +0000811 if (symbol_section_sp)
812 symbol_value -= symbol_section_sp->GetFileAddress();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000813 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000814 bool is_global = symbol.getBinding() == STB_GLOBAL;
815 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +0000816 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000817 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +0000818 i + start_id, // ID is the original symbol table index.
819 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +0000820 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +0000821 symbol_type, // Type of this symbol
822 is_global, // Is this globally visible?
823 false, // Is this symbol debug info?
824 false, // Is this symbol a trampoline?
825 false, // Is this symbol artificial?
826 symbol_section_sp, // Section in which this symbol is defined or null.
827 symbol_value, // Offset in section or symbol value.
828 symbol.st_size, // Size in bytes of this symbol.
829 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 symtab->AddSymbol(dc_symbol);
831 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000832
833 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834}
835
Stephen Wilson499b40e2011-03-30 16:07:05 +0000836unsigned
837ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
838 const ELFSectionHeader *symtab_hdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000839 user_id_t symtab_id)
840{
Stephen Wilson499b40e2011-03-30 16:07:05 +0000841 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
842 symtab_hdr->sh_type == SHT_DYNSYM);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000843
844 // Parse in the section list if needed.
845 SectionList *section_list = GetSectionList();
846 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000847 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000848
849 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +0000850 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000851
852 Section *symtab = section_list->FindSectionByID(symtab_id).get();
853 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +0000854 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000855 if (symtab && strtab)
856 {
857 DataExtractor symtab_data;
858 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000859 if (ReadSectionData(symtab, symtab_data) &&
860 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000861 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000862 num_symbols = ParseSymbols(symbol_table, start_id,
863 section_list, symtab_hdr,
864 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000865 }
866 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000867
868 return num_symbols;
869}
870
871size_t
872ObjectFileELF::ParseDynamicSymbols()
873{
874 if (m_dynamic_symbols.size())
875 return m_dynamic_symbols.size();
876
877 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
878 if (!dyn_id)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000879 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000880
881 SectionList *section_list = GetSectionList();
882 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000883 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000884
885 Section *dynsym = section_list->FindSectionByID(dyn_id).get();
886 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000887 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000888
889 ELFDynamic symbol;
890 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000891 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +0000892 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000893 const lldb::offset_t section_size = dynsym_data.GetByteSize();
894 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000895
896 while (cursor < section_size)
897 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000898 if (!symbol.Parse(dynsym_data, &cursor))
899 break;
900
901 m_dynamic_symbols.push_back(symbol);
902 }
903 }
904
905 return m_dynamic_symbols.size();
906}
907
908const ELFDynamic *
909ObjectFileELF::FindDynamicSymbol(unsigned tag)
910{
911 if (!ParseDynamicSymbols())
912 return NULL;
913
914 SectionList *section_list = GetSectionList();
915 if (!section_list)
916 return 0;
917
918 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
919 DynamicSymbolCollIter E = m_dynamic_symbols.end();
920 for ( ; I != E; ++I)
921 {
922 ELFDynamic *symbol = &*I;
923
924 if (symbol->d_tag == tag)
925 return symbol;
926 }
927
928 return NULL;
929}
930
931Section *
932ObjectFileELF::PLTSection()
933{
934 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
935 SectionList *section_list = GetSectionList();
936
937 if (symbol && section_list)
938 {
939 addr_t addr = symbol->d_ptr;
940 return section_list->FindSectionContainingFileAddress(addr).get();
941 }
942
943 return NULL;
944}
945
946unsigned
947ObjectFileELF::PLTRelocationType()
948{
949 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
950
951 if (symbol)
952 return symbol->d_val;
953
954 return 0;
955}
956
957static unsigned
958ParsePLTRelocations(Symtab *symbol_table,
959 user_id_t start_id,
960 unsigned rel_type,
961 const ELFHeader *hdr,
962 const ELFSectionHeader *rel_hdr,
963 const ELFSectionHeader *plt_hdr,
964 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +0000965 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +0000966 DataExtractor &rel_data,
967 DataExtractor &symtab_data,
968 DataExtractor &strtab_data)
969{
970 ELFRelocation rel(rel_type);
971 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000972 lldb::offset_t offset = 0;
973 const elf_xword plt_entsize = plt_hdr->sh_entsize;
974 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000975
976 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
977 reloc_info_fn reloc_type;
978 reloc_info_fn reloc_symbol;
979
Greg Claytond091afe2012-11-12 22:53:16 +0000980 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000981 {
982 reloc_type = ELFRelocation::RelocType32;
983 reloc_symbol = ELFRelocation::RelocSymbol32;
984 }
985 else
986 {
987 reloc_type = ELFRelocation::RelocType64;
988 reloc_symbol = ELFRelocation::RelocSymbol64;
989 }
990
991 unsigned slot_type = hdr->GetRelocationJumpSlotType();
992 unsigned i;
993 for (i = 0; i < num_relocations; ++i)
994 {
995 if (rel.Parse(rel_data, &offset) == false)
996 break;
997
998 if (reloc_type(rel) != slot_type)
999 continue;
1000
Greg Claytonc7bece562013-01-25 18:06:21 +00001001 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001002 uint64_t plt_index = (i + 1) * plt_entsize;
1003
1004 if (!symbol.Parse(symtab_data, &symbol_offset))
1005 break;
1006
1007 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001008 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001009
1010 Symbol jump_symbol(
1011 i + start_id, // Symbol table index
1012 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001013 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001014 eSymbolTypeTrampoline, // Type of this symbol
1015 false, // Is this globally visible?
1016 false, // Is this symbol debug info?
1017 true, // Is this symbol a trampoline?
1018 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001019 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001020 plt_index, // Offset in section or symbol value.
1021 plt_entsize, // Size in bytes of this symbol.
1022 0); // Symbol flags.
1023
1024 symbol_table->AddSymbol(jump_symbol);
1025 }
1026
1027 return i;
1028}
1029
1030unsigned
1031ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1032 user_id_t start_id,
1033 const ELFSectionHeader *rel_hdr,
1034 user_id_t rel_id)
1035{
1036 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1037
1038 // The link field points to the asscoiated symbol table. The info field
1039 // points to the section holding the plt.
1040 user_id_t symtab_id = rel_hdr->sh_link;
1041 user_id_t plt_id = rel_hdr->sh_info;
1042
1043 if (!symtab_id || !plt_id)
1044 return 0;
1045
1046 // Section ID's are ones based;
1047 symtab_id++;
1048 plt_id++;
1049
1050 const ELFSectionHeader *plt_hdr = GetSectionHeaderByIndex(plt_id);
1051 if (!plt_hdr)
1052 return 0;
1053
1054 const ELFSectionHeader *sym_hdr = GetSectionHeaderByIndex(symtab_id);
1055 if (!sym_hdr)
1056 return 0;
1057
1058 SectionList *section_list = GetSectionList();
1059 if (!section_list)
1060 return 0;
1061
1062 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1063 if (!rel_section)
1064 return 0;
1065
Greg Claytone72dfb32012-02-24 01:59:29 +00001066 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1067 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001068 return 0;
1069
1070 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1071 if (!symtab)
1072 return 0;
1073
1074 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1075 if (!strtab)
1076 return 0;
1077
1078 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001079 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001080 return 0;
1081
1082 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001083 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001084 return 0;
1085
1086 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001087 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001088 return 0;
1089
1090 unsigned rel_type = PLTRelocationType();
1091 if (!rel_type)
1092 return 0;
1093
Greg Claytone72dfb32012-02-24 01:59:29 +00001094 return ParsePLTRelocations (symbol_table,
1095 start_id,
1096 rel_type,
1097 &m_header,
1098 rel_hdr,
1099 plt_hdr,
1100 sym_hdr,
1101 plt_section_sp,
1102 rel_data,
1103 symtab_data,
1104 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001105}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106
1107Symtab *
1108ObjectFileELF::GetSymtab()
1109{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001110 if (m_symtab_ap.get())
1111 return m_symtab_ap.get();
1112
1113 Symtab *symbol_table = new Symtab(this);
1114 m_symtab_ap.reset(symbol_table);
1115
Stephen Wilson499b40e2011-03-30 16:07:05 +00001116 Mutex::Locker locker(symbol_table->GetMutex());
Greg Clayton8087ca22010-10-08 04:20:14 +00001117
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001118 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1119 return symbol_table;
1120
1121 // Locate and parse all linker symbol tables.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001122 uint64_t symbol_id = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001123 for (SectionHeaderCollIter I = m_section_headers.begin();
1124 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125 {
Peter Collingbourneb4aabeb2011-06-03 20:39:58 +00001126 if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001128 const ELFSectionHeader &symtab_header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001129 user_id_t section_id = SectionIndex(I);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001130 symbol_id += ParseSymbolTable(symbol_table, symbol_id,
1131 &symtab_header, section_id);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132 }
1133 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001134
1135 // Synthesize trampoline symbols to help navigate the PLT.
1136 Section *reloc_section = PLTSection();
1137 if (reloc_section)
1138 {
1139 user_id_t reloc_id = reloc_section->GetID();
1140 const ELFSectionHeader *reloc_header = GetSectionHeaderByIndex(reloc_id);
1141 assert(reloc_header);
1142
1143 ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
1144 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001145
1146 return symbol_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147}
1148
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149//===----------------------------------------------------------------------===//
1150// Dump
1151//
1152// Dump the specifics of the runtime file container (such as any headers
1153// segments, sections, etc).
1154//----------------------------------------------------------------------
1155void
1156ObjectFileELF::Dump(Stream *s)
1157{
1158 DumpELFHeader(s, m_header);
1159 s->EOL();
1160 DumpELFProgramHeaders(s);
1161 s->EOL();
1162 DumpELFSectionHeaders(s);
1163 s->EOL();
1164 SectionList *section_list = GetSectionList();
1165 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001166 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 Symtab *symtab = GetSymtab();
1168 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001169 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001170 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001171 DumpDependentModules(s);
1172 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001173}
1174
1175//----------------------------------------------------------------------
1176// DumpELFHeader
1177//
1178// Dump the ELF header to the specified output stream
1179//----------------------------------------------------------------------
1180void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001181ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001183 s->PutCString("ELF Header\n");
1184 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1185 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1186 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1187 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1188 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1189 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1190 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001192 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1193 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001194 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1195 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1196 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1197
1198 s->Printf("e_type = 0x%4.4x ", header.e_type);
1199 DumpELFHeader_e_type(s, header.e_type);
1200 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1201 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001202 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1203 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1204 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001205 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1206 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1207 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1208 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1209 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1210 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1211 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1212}
1213
1214//----------------------------------------------------------------------
1215// DumpELFHeader_e_type
1216//
1217// Dump an token value for the ELF header member e_type
1218//----------------------------------------------------------------------
1219void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001220ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001221{
1222 switch (e_type)
1223 {
1224 case ET_NONE: *s << "ET_NONE"; break;
1225 case ET_REL: *s << "ET_REL"; break;
1226 case ET_EXEC: *s << "ET_EXEC"; break;
1227 case ET_DYN: *s << "ET_DYN"; break;
1228 case ET_CORE: *s << "ET_CORE"; break;
1229 default:
1230 break;
1231 }
1232}
1233
1234//----------------------------------------------------------------------
1235// DumpELFHeader_e_ident_EI_DATA
1236//
1237// Dump an token value for the ELF header member e_ident[EI_DATA]
1238//----------------------------------------------------------------------
1239void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001240ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241{
1242 switch (ei_data)
1243 {
1244 case ELFDATANONE: *s << "ELFDATANONE"; break;
1245 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1246 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1247 default:
1248 break;
1249 }
1250}
1251
1252
1253//----------------------------------------------------------------------
1254// DumpELFProgramHeader
1255//
1256// Dump a single ELF program header to the specified output stream
1257//----------------------------------------------------------------------
1258void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001259ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001260{
1261 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001262 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1263 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 +00001264
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001266 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267}
1268
1269//----------------------------------------------------------------------
1270// DumpELFProgramHeader_p_type
1271//
1272// Dump an token value for the ELF program header member p_type which
1273// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001274// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001276ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001277{
1278 const int kStrWidth = 10;
1279 switch (p_type)
1280 {
1281 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1282 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1283 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1284 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1285 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1286 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1287 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1288 default:
1289 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1290 break;
1291 }
1292}
1293
1294
1295//----------------------------------------------------------------------
1296// DumpELFProgramHeader_p_flags
1297//
1298// Dump an token value for the ELF program header member p_flags
1299//----------------------------------------------------------------------
1300void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001301ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302{
1303 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1304 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1305 << ((p_flags & PF_W) ? "PF_W" : " ")
1306 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1307 << ((p_flags & PF_R) ? "PF_R" : " ");
1308}
1309
1310//----------------------------------------------------------------------
1311// DumpELFProgramHeaders
1312//
1313// Dump all of the ELF program header to the specified output stream
1314//----------------------------------------------------------------------
1315void
1316ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1317{
1318 if (ParseProgramHeaders())
1319 {
1320 s->PutCString("Program Headers\n");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001321 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
1322 "p_filesz p_memsz p_flags p_align\n");
1323 s->PutCString("==== ---------- -------- -------- -------- "
1324 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001325
1326 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001327 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1328 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001329 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001330 s->Printf("[%2u] ", idx);
1331 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332 s->EOL();
1333 }
1334 }
1335}
1336
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001337//----------------------------------------------------------------------
1338// DumpELFSectionHeader
1339//
1340// Dump a single ELF section header to the specified output stream
1341//----------------------------------------------------------------------
1342void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001343ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001344{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001345 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001346 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001347 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001348 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001349 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 +00001350 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001351 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352}
1353
1354//----------------------------------------------------------------------
1355// DumpELFSectionHeader_sh_type
1356//
1357// Dump an token value for the ELF section header member sh_type which
1358// describes the type of the section
1359//----------------------------------------------------------------------
1360void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001361ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001362{
1363 const int kStrWidth = 12;
1364 switch (sh_type)
1365 {
1366 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1367 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1368 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1369 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1370 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1371 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1372 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1373 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1374 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1375 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1376 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1377 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1378 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1379 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1380 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1381 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1382 default:
1383 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1384 break;
1385 }
1386}
1387
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001388//----------------------------------------------------------------------
1389// DumpELFSectionHeader_sh_flags
1390//
1391// Dump an token value for the ELF section header member sh_flags
1392//----------------------------------------------------------------------
1393void
Greg Claytonc7bece562013-01-25 18:06:21 +00001394ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001395{
1396 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1397 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1398 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1399 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1400 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1401}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001402
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403//----------------------------------------------------------------------
1404// DumpELFSectionHeaders
1405//
1406// Dump all of the ELF section header to the specified output stream
1407//----------------------------------------------------------------------
1408void
1409ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1410{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001411 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1412 return;
1413
1414 s->PutCString("Section Headers\n");
1415 s->PutCString("IDX name type flags "
1416 "addr offset size link info addralgn "
1417 "entsize Name\n");
1418 s->PutCString("==== -------- ------------ -------------------------------- "
1419 "-------- -------- -------- -------- -------- -------- "
1420 "-------- ====================\n");
1421
1422 uint32_t idx = 0;
1423 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1424 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001425 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001426 s->Printf("[%2u] ", idx);
1427 ObjectFileELF::DumpELFSectionHeader(s, *I);
1428 const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
1429 if (section_name)
1430 *s << ' ' << section_name << "\n";
1431 }
1432}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001433
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001434void
1435ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1436{
1437 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001438
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001439 if (num_modules > 0)
1440 {
1441 s->PutCString("Dependent Modules:\n");
1442 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001443 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001444 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1445 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001446 }
1447 }
1448}
1449
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001450bool
Greg Clayton514487e2011-02-15 21:59:32 +00001451ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001452{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001453 if (!ParseHeader())
1454 return false;
1455
Greg Claytone0d378b2011-03-24 21:19:54 +00001456 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001457 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1458 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001459 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001460}
1461
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001462ObjectFile::Type
1463ObjectFileELF::CalculateType()
1464{
1465 switch (m_header.e_type)
1466 {
1467 case llvm::ELF::ET_NONE:
1468 // 0 - No file type
1469 return eTypeUnknown;
1470
1471 case llvm::ELF::ET_REL:
1472 // 1 - Relocatable file
1473 return eTypeObjectFile;
1474
1475 case llvm::ELF::ET_EXEC:
1476 // 2 - Executable file
1477 return eTypeExecutable;
1478
1479 case llvm::ELF::ET_DYN:
1480 // 3 - Shared object file
1481 return eTypeSharedLibrary;
1482
1483 case ET_CORE:
1484 // 4 - Core file
1485 return eTypeCoreFile;
1486
1487 default:
1488 break;
1489 }
1490 return eTypeUnknown;
1491}
1492
1493ObjectFile::Strata
1494ObjectFileELF::CalculateStrata()
1495{
1496 switch (m_header.e_type)
1497 {
1498 case llvm::ELF::ET_NONE:
1499 // 0 - No file type
1500 return eStrataUnknown;
1501
1502 case llvm::ELF::ET_REL:
1503 // 1 - Relocatable file
1504 return eStrataUnknown;
1505
1506 case llvm::ELF::ET_EXEC:
1507 // 2 - Executable file
1508 // TODO: is there any way to detect that an executable is a kernel
1509 // related executable by inspecting the program headers, section
1510 // headers, symbols, or any other flag bits???
1511 return eStrataUser;
1512
1513 case llvm::ELF::ET_DYN:
1514 // 3 - Shared object file
1515 // TODO: is there any way to detect that an shared library is a kernel
1516 // related executable by inspecting the program headers, section
1517 // headers, symbols, or any other flag bits???
1518 return eStrataUnknown;
1519
1520 case ET_CORE:
1521 // 4 - Core file
1522 // TODO: is there any way to detect that an core file is a kernel
1523 // related executable by inspecting the program headers, section
1524 // headers, symbols, or any other flag bits???
1525 return eStrataUnknown;
1526
1527 default:
1528 break;
1529 }
1530 return eStrataUnknown;
1531}
1532