blob: 2cee5c01da987850f3cacc1bd8f97163c15b80e1 [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
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000753 // If a symbol is undefined do not process it further even if it has a STT type
754 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000755 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000756 switch (symbol.getType())
757 {
758 default:
759 case STT_NOTYPE:
760 // The symbol's type is not specified.
761 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000763 case STT_OBJECT:
764 // The symbol is associated with a data object, such as a variable,
765 // an array, etc.
766 symbol_type = eSymbolTypeData;
767 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000768
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000769 case STT_FUNC:
770 // The symbol is associated with a function or other executable code.
771 symbol_type = eSymbolTypeCode;
772 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000774 case STT_SECTION:
775 // The symbol is associated with a section. Symbol table entries of
776 // this type exist primarily for relocation and normally have
777 // STB_LOCAL binding.
778 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000780 case STT_FILE:
781 // Conventionally, the symbol's name gives the name of the source
782 // file associated with the object file. A file symbol has STB_LOCAL
783 // binding, its section index is SHN_ABS, and it precedes the other
784 // STB_LOCAL symbols for the file, if it is present.
785 symbol_type = eSymbolTypeObjectFile;
786 break;
787 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000788 }
789
790 if (symbol_type == eSymbolTypeInvalid)
791 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000792 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000793 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000794 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795 if (sect_name == text_section_name ||
796 sect_name == init_section_name ||
797 sect_name == fini_section_name ||
798 sect_name == ctors_section_name ||
799 sect_name == dtors_section_name)
800 {
801 symbol_type = eSymbolTypeCode;
802 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000803 else if (sect_name == data_section_name ||
804 sect_name == data2_section_name ||
805 sect_name == rodata_section_name ||
806 sect_name == rodata1_section_name ||
807 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000808 {
809 symbol_type = eSymbolTypeData;
810 }
811 }
812 }
813
814 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +0000815 if (symbol_section_sp)
816 symbol_value -= symbol_section_sp->GetFileAddress();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000817 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000818 bool is_global = symbol.getBinding() == STB_GLOBAL;
819 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +0000820 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000821 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +0000822 i + start_id, // ID is the original symbol table index.
823 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +0000824 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +0000825 symbol_type, // Type of this symbol
826 is_global, // Is this globally visible?
827 false, // Is this symbol debug info?
828 false, // Is this symbol a trampoline?
829 false, // Is this symbol artificial?
830 symbol_section_sp, // Section in which this symbol is defined or null.
831 symbol_value, // Offset in section or symbol value.
832 symbol.st_size, // Size in bytes of this symbol.
833 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834 symtab->AddSymbol(dc_symbol);
835 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000836
837 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838}
839
Stephen Wilson499b40e2011-03-30 16:07:05 +0000840unsigned
841ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
842 const ELFSectionHeader *symtab_hdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000843 user_id_t symtab_id)
844{
Stephen Wilson499b40e2011-03-30 16:07:05 +0000845 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
846 symtab_hdr->sh_type == SHT_DYNSYM);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000847
848 // Parse in the section list if needed.
849 SectionList *section_list = GetSectionList();
850 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000851 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000852
853 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +0000854 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000855
856 Section *symtab = section_list->FindSectionByID(symtab_id).get();
857 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +0000858 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000859 if (symtab && strtab)
860 {
861 DataExtractor symtab_data;
862 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000863 if (ReadSectionData(symtab, symtab_data) &&
864 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000865 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000866 num_symbols = ParseSymbols(symbol_table, start_id,
867 section_list, symtab_hdr,
868 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000869 }
870 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000871
872 return num_symbols;
873}
874
875size_t
876ObjectFileELF::ParseDynamicSymbols()
877{
878 if (m_dynamic_symbols.size())
879 return m_dynamic_symbols.size();
880
881 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
882 if (!dyn_id)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000883 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000884
885 SectionList *section_list = GetSectionList();
886 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000887 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000888
889 Section *dynsym = section_list->FindSectionByID(dyn_id).get();
890 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +0000891 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000892
893 ELFDynamic symbol;
894 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000895 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +0000896 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000897 const lldb::offset_t section_size = dynsym_data.GetByteSize();
898 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000899
900 while (cursor < section_size)
901 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000902 if (!symbol.Parse(dynsym_data, &cursor))
903 break;
904
905 m_dynamic_symbols.push_back(symbol);
906 }
907 }
908
909 return m_dynamic_symbols.size();
910}
911
912const ELFDynamic *
913ObjectFileELF::FindDynamicSymbol(unsigned tag)
914{
915 if (!ParseDynamicSymbols())
916 return NULL;
917
918 SectionList *section_list = GetSectionList();
919 if (!section_list)
920 return 0;
921
922 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
923 DynamicSymbolCollIter E = m_dynamic_symbols.end();
924 for ( ; I != E; ++I)
925 {
926 ELFDynamic *symbol = &*I;
927
928 if (symbol->d_tag == tag)
929 return symbol;
930 }
931
932 return NULL;
933}
934
935Section *
936ObjectFileELF::PLTSection()
937{
938 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
939 SectionList *section_list = GetSectionList();
940
941 if (symbol && section_list)
942 {
943 addr_t addr = symbol->d_ptr;
944 return section_list->FindSectionContainingFileAddress(addr).get();
945 }
946
947 return NULL;
948}
949
950unsigned
951ObjectFileELF::PLTRelocationType()
952{
953 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
954
955 if (symbol)
956 return symbol->d_val;
957
958 return 0;
959}
960
961static unsigned
962ParsePLTRelocations(Symtab *symbol_table,
963 user_id_t start_id,
964 unsigned rel_type,
965 const ELFHeader *hdr,
966 const ELFSectionHeader *rel_hdr,
967 const ELFSectionHeader *plt_hdr,
968 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +0000969 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +0000970 DataExtractor &rel_data,
971 DataExtractor &symtab_data,
972 DataExtractor &strtab_data)
973{
974 ELFRelocation rel(rel_type);
975 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000976 lldb::offset_t offset = 0;
977 const elf_xword plt_entsize = plt_hdr->sh_entsize;
978 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +0000979
980 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
981 reloc_info_fn reloc_type;
982 reloc_info_fn reloc_symbol;
983
Greg Claytond091afe2012-11-12 22:53:16 +0000984 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000985 {
986 reloc_type = ELFRelocation::RelocType32;
987 reloc_symbol = ELFRelocation::RelocSymbol32;
988 }
989 else
990 {
991 reloc_type = ELFRelocation::RelocType64;
992 reloc_symbol = ELFRelocation::RelocSymbol64;
993 }
994
995 unsigned slot_type = hdr->GetRelocationJumpSlotType();
996 unsigned i;
997 for (i = 0; i < num_relocations; ++i)
998 {
999 if (rel.Parse(rel_data, &offset) == false)
1000 break;
1001
1002 if (reloc_type(rel) != slot_type)
1003 continue;
1004
Greg Claytonc7bece562013-01-25 18:06:21 +00001005 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001006 uint64_t plt_index = (i + 1) * plt_entsize;
1007
1008 if (!symbol.Parse(symtab_data, &symbol_offset))
1009 break;
1010
1011 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001012 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001013
1014 Symbol jump_symbol(
1015 i + start_id, // Symbol table index
1016 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001017 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001018 eSymbolTypeTrampoline, // Type of this symbol
1019 false, // Is this globally visible?
1020 false, // Is this symbol debug info?
1021 true, // Is this symbol a trampoline?
1022 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001023 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001024 plt_index, // Offset in section or symbol value.
1025 plt_entsize, // Size in bytes of this symbol.
1026 0); // Symbol flags.
1027
1028 symbol_table->AddSymbol(jump_symbol);
1029 }
1030
1031 return i;
1032}
1033
1034unsigned
1035ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1036 user_id_t start_id,
1037 const ELFSectionHeader *rel_hdr,
1038 user_id_t rel_id)
1039{
1040 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1041
1042 // The link field points to the asscoiated symbol table. The info field
1043 // points to the section holding the plt.
1044 user_id_t symtab_id = rel_hdr->sh_link;
1045 user_id_t plt_id = rel_hdr->sh_info;
1046
1047 if (!symtab_id || !plt_id)
1048 return 0;
1049
1050 // Section ID's are ones based;
1051 symtab_id++;
1052 plt_id++;
1053
1054 const ELFSectionHeader *plt_hdr = GetSectionHeaderByIndex(plt_id);
1055 if (!plt_hdr)
1056 return 0;
1057
1058 const ELFSectionHeader *sym_hdr = GetSectionHeaderByIndex(symtab_id);
1059 if (!sym_hdr)
1060 return 0;
1061
1062 SectionList *section_list = GetSectionList();
1063 if (!section_list)
1064 return 0;
1065
1066 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1067 if (!rel_section)
1068 return 0;
1069
Greg Claytone72dfb32012-02-24 01:59:29 +00001070 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1071 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001072 return 0;
1073
1074 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1075 if (!symtab)
1076 return 0;
1077
1078 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1079 if (!strtab)
1080 return 0;
1081
1082 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001083 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001084 return 0;
1085
1086 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001087 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001088 return 0;
1089
1090 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001091 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001092 return 0;
1093
1094 unsigned rel_type = PLTRelocationType();
1095 if (!rel_type)
1096 return 0;
1097
Greg Claytone72dfb32012-02-24 01:59:29 +00001098 return ParsePLTRelocations (symbol_table,
1099 start_id,
1100 rel_type,
1101 &m_header,
1102 rel_hdr,
1103 plt_hdr,
1104 sym_hdr,
1105 plt_section_sp,
1106 rel_data,
1107 symtab_data,
1108 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001109}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110
1111Symtab *
1112ObjectFileELF::GetSymtab()
1113{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001114 if (m_symtab_ap.get())
1115 return m_symtab_ap.get();
1116
1117 Symtab *symbol_table = new Symtab(this);
1118 m_symtab_ap.reset(symbol_table);
1119
Stephen Wilson499b40e2011-03-30 16:07:05 +00001120 Mutex::Locker locker(symbol_table->GetMutex());
Greg Clayton8087ca22010-10-08 04:20:14 +00001121
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001122 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1123 return symbol_table;
1124
1125 // Locate and parse all linker symbol tables.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001126 uint64_t symbol_id = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001127 for (SectionHeaderCollIter I = m_section_headers.begin();
1128 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129 {
Peter Collingbourneb4aabeb2011-06-03 20:39:58 +00001130 if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001132 const ELFSectionHeader &symtab_header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001133 user_id_t section_id = SectionIndex(I);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001134 symbol_id += ParseSymbolTable(symbol_table, symbol_id,
1135 &symtab_header, section_id);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136 }
1137 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001138
1139 // Synthesize trampoline symbols to help navigate the PLT.
1140 Section *reloc_section = PLTSection();
1141 if (reloc_section)
1142 {
1143 user_id_t reloc_id = reloc_section->GetID();
1144 const ELFSectionHeader *reloc_header = GetSectionHeaderByIndex(reloc_id);
1145 assert(reloc_header);
1146
1147 ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
1148 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001149
1150 return symbol_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001151}
1152
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153//===----------------------------------------------------------------------===//
1154// Dump
1155//
1156// Dump the specifics of the runtime file container (such as any headers
1157// segments, sections, etc).
1158//----------------------------------------------------------------------
1159void
1160ObjectFileELF::Dump(Stream *s)
1161{
1162 DumpELFHeader(s, m_header);
1163 s->EOL();
1164 DumpELFProgramHeaders(s);
1165 s->EOL();
1166 DumpELFSectionHeaders(s);
1167 s->EOL();
1168 SectionList *section_list = GetSectionList();
1169 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001170 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 Symtab *symtab = GetSymtab();
1172 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001173 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001175 DumpDependentModules(s);
1176 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177}
1178
1179//----------------------------------------------------------------------
1180// DumpELFHeader
1181//
1182// Dump the ELF header to the specified output stream
1183//----------------------------------------------------------------------
1184void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001185ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001187 s->PutCString("ELF Header\n");
1188 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1189 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1190 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1191 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1192 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1193 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1194 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001195
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001196 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1197 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001198 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1199 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1200 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1201
1202 s->Printf("e_type = 0x%4.4x ", header.e_type);
1203 DumpELFHeader_e_type(s, header.e_type);
1204 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1205 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001206 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1207 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1208 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1210 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1211 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1212 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1213 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1214 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1215 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1216}
1217
1218//----------------------------------------------------------------------
1219// DumpELFHeader_e_type
1220//
1221// Dump an token value for the ELF header member e_type
1222//----------------------------------------------------------------------
1223void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001224ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001225{
1226 switch (e_type)
1227 {
1228 case ET_NONE: *s << "ET_NONE"; break;
1229 case ET_REL: *s << "ET_REL"; break;
1230 case ET_EXEC: *s << "ET_EXEC"; break;
1231 case ET_DYN: *s << "ET_DYN"; break;
1232 case ET_CORE: *s << "ET_CORE"; break;
1233 default:
1234 break;
1235 }
1236}
1237
1238//----------------------------------------------------------------------
1239// DumpELFHeader_e_ident_EI_DATA
1240//
1241// Dump an token value for the ELF header member e_ident[EI_DATA]
1242//----------------------------------------------------------------------
1243void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001244ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001245{
1246 switch (ei_data)
1247 {
1248 case ELFDATANONE: *s << "ELFDATANONE"; break;
1249 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1250 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1251 default:
1252 break;
1253 }
1254}
1255
1256
1257//----------------------------------------------------------------------
1258// DumpELFProgramHeader
1259//
1260// Dump a single ELF program header to the specified output stream
1261//----------------------------------------------------------------------
1262void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001263ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264{
1265 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001266 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1267 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 +00001268
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001270 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271}
1272
1273//----------------------------------------------------------------------
1274// DumpELFProgramHeader_p_type
1275//
1276// Dump an token value for the ELF program header member p_type which
1277// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001278// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001279void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001280ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281{
1282 const int kStrWidth = 10;
1283 switch (p_type)
1284 {
1285 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1286 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1287 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1288 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1289 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1290 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1291 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1292 default:
1293 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1294 break;
1295 }
1296}
1297
1298
1299//----------------------------------------------------------------------
1300// DumpELFProgramHeader_p_flags
1301//
1302// Dump an token value for the ELF program header member p_flags
1303//----------------------------------------------------------------------
1304void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001305ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001306{
1307 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1308 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1309 << ((p_flags & PF_W) ? "PF_W" : " ")
1310 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1311 << ((p_flags & PF_R) ? "PF_R" : " ");
1312}
1313
1314//----------------------------------------------------------------------
1315// DumpELFProgramHeaders
1316//
1317// Dump all of the ELF program header to the specified output stream
1318//----------------------------------------------------------------------
1319void
1320ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1321{
1322 if (ParseProgramHeaders())
1323 {
1324 s->PutCString("Program Headers\n");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001325 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
1326 "p_filesz p_memsz p_flags p_align\n");
1327 s->PutCString("==== ---------- -------- -------- -------- "
1328 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001329
1330 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001331 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1332 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001333 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001334 s->Printf("[%2u] ", idx);
1335 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001336 s->EOL();
1337 }
1338 }
1339}
1340
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001341//----------------------------------------------------------------------
1342// DumpELFSectionHeader
1343//
1344// Dump a single ELF section header to the specified output stream
1345//----------------------------------------------------------------------
1346void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001347ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001348{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001349 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001351 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001353 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 +00001354 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001355 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356}
1357
1358//----------------------------------------------------------------------
1359// DumpELFSectionHeader_sh_type
1360//
1361// Dump an token value for the ELF section header member sh_type which
1362// describes the type of the section
1363//----------------------------------------------------------------------
1364void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001365ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001366{
1367 const int kStrWidth = 12;
1368 switch (sh_type)
1369 {
1370 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1371 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1372 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1373 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1374 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1375 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1376 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1377 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1378 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1379 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1380 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1381 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1382 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1383 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1384 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1385 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1386 default:
1387 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1388 break;
1389 }
1390}
1391
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001392//----------------------------------------------------------------------
1393// DumpELFSectionHeader_sh_flags
1394//
1395// Dump an token value for the ELF section header member sh_flags
1396//----------------------------------------------------------------------
1397void
Greg Claytonc7bece562013-01-25 18:06:21 +00001398ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001399{
1400 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1401 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1402 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1403 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1404 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1405}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001406
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001407//----------------------------------------------------------------------
1408// DumpELFSectionHeaders
1409//
1410// Dump all of the ELF section header to the specified output stream
1411//----------------------------------------------------------------------
1412void
1413ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1414{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001415 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1416 return;
1417
1418 s->PutCString("Section Headers\n");
1419 s->PutCString("IDX name type flags "
1420 "addr offset size link info addralgn "
1421 "entsize Name\n");
1422 s->PutCString("==== -------- ------------ -------------------------------- "
1423 "-------- -------- -------- -------- -------- -------- "
1424 "-------- ====================\n");
1425
1426 uint32_t idx = 0;
1427 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1428 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001429 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001430 s->Printf("[%2u] ", idx);
1431 ObjectFileELF::DumpELFSectionHeader(s, *I);
1432 const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
1433 if (section_name)
1434 *s << ' ' << section_name << "\n";
1435 }
1436}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001437
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001438void
1439ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1440{
1441 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001442
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001443 if (num_modules > 0)
1444 {
1445 s->PutCString("Dependent Modules:\n");
1446 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001447 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001448 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1449 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001450 }
1451 }
1452}
1453
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001454bool
Greg Clayton514487e2011-02-15 21:59:32 +00001455ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001456{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001457 if (!ParseHeader())
1458 return false;
1459
Greg Claytone0d378b2011-03-24 21:19:54 +00001460 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001461 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1462 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001463 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001464}
1465
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001466ObjectFile::Type
1467ObjectFileELF::CalculateType()
1468{
1469 switch (m_header.e_type)
1470 {
1471 case llvm::ELF::ET_NONE:
1472 // 0 - No file type
1473 return eTypeUnknown;
1474
1475 case llvm::ELF::ET_REL:
1476 // 1 - Relocatable file
1477 return eTypeObjectFile;
1478
1479 case llvm::ELF::ET_EXEC:
1480 // 2 - Executable file
1481 return eTypeExecutable;
1482
1483 case llvm::ELF::ET_DYN:
1484 // 3 - Shared object file
1485 return eTypeSharedLibrary;
1486
1487 case ET_CORE:
1488 // 4 - Core file
1489 return eTypeCoreFile;
1490
1491 default:
1492 break;
1493 }
1494 return eTypeUnknown;
1495}
1496
1497ObjectFile::Strata
1498ObjectFileELF::CalculateStrata()
1499{
1500 switch (m_header.e_type)
1501 {
1502 case llvm::ELF::ET_NONE:
1503 // 0 - No file type
1504 return eStrataUnknown;
1505
1506 case llvm::ELF::ET_REL:
1507 // 1 - Relocatable file
1508 return eStrataUnknown;
1509
1510 case llvm::ELF::ET_EXEC:
1511 // 2 - Executable file
1512 // TODO: is there any way to detect that an executable is a kernel
1513 // related executable by inspecting the program headers, section
1514 // headers, symbols, or any other flag bits???
1515 return eStrataUser;
1516
1517 case llvm::ELF::ET_DYN:
1518 // 3 - Shared object file
1519 // TODO: is there any way to detect that an shared library is a kernel
1520 // related executable by inspecting the program headers, section
1521 // headers, symbols, or any other flag bits???
1522 return eStrataUnknown;
1523
1524 case ET_CORE:
1525 // 4 - Core file
1526 // TODO: is there any way to detect that an core file is a kernel
1527 // related executable by inspecting the program headers, section
1528 // headers, symbols, or any other flag bits???
1529 return eStrataUnknown;
1530
1531 default:
1532 break;
1533 }
1534 return eStrataUnknown;
1535}
1536