blob: 9e1febb7e75494428264e9dc0389c9b184c04a0d [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"
Greg Claytonf4d6de62013-04-24 22:29:28 +000020#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/PluginManager.h"
22#include "lldb/Core/Section.h"
23#include "lldb/Core/Stream.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000024#include "lldb/Symbol/SymbolContext.h"
Greg Clayton64195a22011-02-23 00:35:02 +000025#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
Stephen Wilson499b40e2011-03-30 16:07:05 +000027#include "llvm/ADT/PointerUnion.h"
28
Stephen Wilsonf325ba92010-07-13 23:07:23 +000029#define CASE_AND_STREAM(s, def, width) \
30 case def: s->Printf("%-*s", width, #def); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032using namespace lldb;
33using namespace lldb_private;
Stephen Wilsonf325ba92010-07-13 23:07:23 +000034using namespace elf;
35using namespace llvm::ELF;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
Stephen Wilson499b40e2011-03-30 16:07:05 +000037namespace {
38//===----------------------------------------------------------------------===//
39/// @class ELFRelocation
40/// @brief Generic wrapper for ELFRel and ELFRela.
41///
42/// This helper class allows us to parse both ELFRel and ELFRela relocation
43/// entries in a generic manner.
44class ELFRelocation
45{
46public:
47
48 /// Constructs an ELFRelocation entry with a personality as given by @p
49 /// type.
50 ///
51 /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
52 ELFRelocation(unsigned type);
53
54 ~ELFRelocation();
55
56 bool
Greg Claytonc7bece562013-01-25 18:06:21 +000057 Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
Stephen Wilson499b40e2011-03-30 16:07:05 +000058
59 static unsigned
60 RelocType32(const ELFRelocation &rel);
61
62 static unsigned
63 RelocType64(const ELFRelocation &rel);
64
65 static unsigned
66 RelocSymbol32(const ELFRelocation &rel);
67
68 static unsigned
69 RelocSymbol64(const ELFRelocation &rel);
70
71private:
72 typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion;
73
74 RelocUnion reloc;
75};
76
77ELFRelocation::ELFRelocation(unsigned type)
78{
79 if (type == DT_REL)
80 reloc = new ELFRel();
81 else if (type == DT_RELA)
82 reloc = new ELFRela();
83 else {
84 assert(false && "unexpected relocation type");
85 reloc = static_cast<ELFRel*>(NULL);
86 }
87}
88
89ELFRelocation::~ELFRelocation()
90{
91 if (reloc.is<ELFRel*>())
92 delete reloc.get<ELFRel*>();
93 else
94 delete reloc.get<ELFRela*>();
95}
96
97bool
Greg Claytonc7bece562013-01-25 18:06:21 +000098ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Stephen Wilson499b40e2011-03-30 16:07:05 +000099{
100 if (reloc.is<ELFRel*>())
101 return reloc.get<ELFRel*>()->Parse(data, offset);
102 else
103 return reloc.get<ELFRela*>()->Parse(data, offset);
104}
105
106unsigned
107ELFRelocation::RelocType32(const ELFRelocation &rel)
108{
109 if (rel.reloc.is<ELFRel*>())
110 return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>());
111 else
112 return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>());
113}
114
115unsigned
116ELFRelocation::RelocType64(const ELFRelocation &rel)
117{
118 if (rel.reloc.is<ELFRel*>())
119 return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>());
120 else
121 return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>());
122}
123
124unsigned
125ELFRelocation::RelocSymbol32(const ELFRelocation &rel)
126{
127 if (rel.reloc.is<ELFRel*>())
128 return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>());
129 else
130 return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>());
131}
132
133unsigned
134ELFRelocation::RelocSymbol64(const ELFRelocation &rel)
135{
136 if (rel.reloc.is<ELFRel*>())
137 return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>());
138 else
139 return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>());
140}
141
142} // end anonymous namespace
143
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000144//------------------------------------------------------------------
145// Static methods.
146//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147void
148ObjectFileELF::Initialize()
149{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000150 PluginManager::RegisterPlugin(GetPluginNameStatic(),
151 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000152 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000153 CreateMemoryInstance,
154 GetModuleSpecifications);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155}
156
157void
158ObjectFileELF::Terminate()
159{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000160 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161}
162
Greg Clayton57abc5d2013-05-10 21:47:16 +0000163lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164ObjectFileELF::GetPluginNameStatic()
165{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000166 static ConstString g_name("elf");
167 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168}
169
170const char *
171ObjectFileELF::GetPluginDescriptionStatic()
172{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000173 return "ELF object file reader.";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174}
175
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176ObjectFile *
Greg Claytone72dfb32012-02-24 01:59:29 +0000177ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
178 DataBufferSP &data_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000179 lldb::offset_t data_offset,
180 const lldb_private::FileSpec* file,
181 lldb::offset_t file_offset,
182 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000184 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000186 data_sp = file->MemoryMapFileContents(file_offset, length);
187 data_offset = 0;
188 }
189
190 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
191 {
192 const uint8_t *magic = data_sp->GetBytes() + data_offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000193 if (ELFHeader::MagicBytesMatch(magic))
194 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000195 // Update the data to contain the entire file if it doesn't already
Andrew Kaylor213f6722013-02-07 21:30:54 +0000196 if (data_sp->GetByteSize() < length) {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000197 data_sp = file->MemoryMapFileContents(file_offset, length);
Greg Clayton64ff6c72013-02-07 21:49:54 +0000198 data_offset = 0;
199 magic = data_sp->GetBytes();
Andrew Kaylor213f6722013-02-07 21:30:54 +0000200 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000201 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
202 if (address_size == 4 || address_size == 8)
203 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000204 std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, data_offset, file, file_offset, length));
Stephen Wilson3f4200fd2011-02-24 19:16:15 +0000205 ArchSpec spec;
206 if (objfile_ap->GetArchitecture(spec) &&
207 objfile_ap->SetModulesArchitecture(spec))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000208 return objfile_ap.release();
209 }
210 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 }
212 return NULL;
213}
214
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000215
Greg Claytonc9660542012-02-05 02:38:54 +0000216ObjectFile*
Greg Claytone72dfb32012-02-24 01:59:29 +0000217ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
218 DataBufferSP& data_sp,
219 const lldb::ProcessSP &process_sp,
220 lldb::addr_t header_addr)
Greg Claytonc9660542012-02-05 02:38:54 +0000221{
222 return NULL;
223}
224
Michael Sartain9f0013d2013-05-17 00:20:21 +0000225bool
226ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,
227 lldb::addr_t data_offset,
228 lldb::addr_t data_length)
229{
230 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
231 {
232 const uint8_t *magic = data_sp->GetBytes() + data_offset;
233 return ELFHeader::MagicBytesMatch(magic);
234 }
235 return false;
236}
Greg Claytonc9660542012-02-05 02:38:54 +0000237
Greg Claytonf4d6de62013-04-24 22:29:28 +0000238size_t
239ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
240 lldb::DataBufferSP& data_sp,
241 lldb::offset_t data_offset,
242 lldb::offset_t file_offset,
243 lldb::offset_t length,
244 lldb_private::ModuleSpecList &specs)
245{
Michael Sartain9f0013d2013-05-17 00:20:21 +0000246 const size_t initial_count = specs.GetSize();
Michael Sartainc836ae72013-05-23 20:57:03 +0000247
Michael Sartain9f0013d2013-05-17 00:20:21 +0000248 if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
249 {
250 DataExtractor data;
251 data.SetData(data_sp);
252 elf::ELFHeader header;
253 if (header.Parse(data, &data_offset))
254 {
255 if (data_sp)
256 {
257 ModuleSpec spec;
258 spec.GetFileSpec() = file;
259 spec.GetArchitecture().SetArchitecture(eArchTypeELF,
260 header.e_machine,
261 LLDB_INVALID_CPUTYPE);
262 if (spec.GetArchitecture().IsValid())
263 {
Michael Sartainc836ae72013-05-23 20:57:03 +0000264 // We could parse the ABI tag information (in .note, .notes, or .note.ABI-tag) to get the
265 // machine information. However, we'd have to read a good bit of the rest of the file,
266 // and this info isn't guaranteed to exist or be correct. More details here:
267 // http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
268 // Instead of passing potentially incorrect information down the pipeline, grab
269 // the host information and use it.
270 spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString());
271 spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString());
Michael Sartain9f0013d2013-05-17 00:20:21 +0000272 specs.Append(spec);
273 }
274 }
275 }
276 }
Michael Sartainc836ae72013-05-23 20:57:03 +0000277
Michael Sartain9f0013d2013-05-17 00:20:21 +0000278 return specs.GetSize() - initial_count;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000279}
280
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000281//------------------------------------------------------------------
282// PluginInterface protocol
283//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +0000284lldb_private::ConstString
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000285ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000286{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000287 return GetPluginNameStatic();
288}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000290uint32_t
291ObjectFileELF::GetPluginVersion()
292{
293 return m_plugin_version;
294}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000295//------------------------------------------------------------------
296// ObjectFile protocol
297//------------------------------------------------------------------
298
Greg Claytone72dfb32012-02-24 01:59:29 +0000299ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000300 DataBufferSP& data_sp,
301 lldb::offset_t data_offset,
Greg Claytone72dfb32012-02-24 01:59:29 +0000302 const FileSpec* file,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000303 lldb::offset_t file_offset,
304 lldb::offset_t length) :
305 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytone72dfb32012-02-24 01:59:29 +0000306 m_header(),
307 m_program_headers(),
308 m_section_headers(),
Greg Claytone72dfb32012-02-24 01:59:29 +0000309 m_filespec_ap(),
310 m_shstr_data()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311{
312 if (file)
313 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000314 ::memset(&m_header, 0, sizeof(m_header));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315}
316
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317ObjectFileELF::~ObjectFileELF()
318{
319}
320
Jim Ingham5aee1622010-08-09 23:31:02 +0000321bool
322ObjectFileELF::IsExecutable() const
323{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000324 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000325}
326
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000328ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329{
330 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
331 return eByteOrderBig;
332 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
333 return eByteOrderLittle;
334 return eByteOrderInvalid;
335}
336
Greg Claytonc7bece562013-01-25 18:06:21 +0000337uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000338ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339{
340 return m_data.GetAddressByteSize();
341}
342
Greg Claytonc7bece562013-01-25 18:06:21 +0000343size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000344ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345{
Greg Claytonc7bece562013-01-25 18:06:21 +0000346 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000347}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348
Greg Claytonc7bece562013-01-25 18:06:21 +0000349size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000350ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
351{
Greg Claytonc7bece562013-01-25 18:06:21 +0000352 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353}
354
355bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000356ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357{
Filipe Cabecinhas22b40f72013-05-16 23:29:36 +0000358 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000359 return m_header.Parse(m_data, &offset);
360}
361
362bool
Greg Clayton60830262011-02-04 18:53:10 +0000363ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000364{
Michael Sartainc836ae72013-05-23 20:57:03 +0000365 if (m_uuid.IsValid())
366 {
367 *uuid = m_uuid;
368 return true;
369 }
370 // FIXME: Return MD5 sum here. See comment in ObjectFile.h.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371 return false;
372}
373
374uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000375ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000377 size_t num_modules = ParseDependentModules();
378 uint32_t num_specs = 0;
379
380 for (unsigned i = 0; i < num_modules; ++i)
381 {
382 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
383 num_specs++;
384 }
385
386 return num_specs;
387}
388
Stephen Wilson499b40e2011-03-30 16:07:05 +0000389user_id_t
390ObjectFileELF::GetSectionIndexByType(unsigned type)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000391{
392 if (!ParseSectionHeaders())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000393 return 0;
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000394
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000395 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
396 sh_pos != m_section_headers.end(); ++sh_pos)
397 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000398 if (sh_pos->sh_type == type)
399 return SectionIndex(sh_pos);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000400 }
401
Stephen Wilson499b40e2011-03-30 16:07:05 +0000402 return 0;
403}
404
405Address
406ObjectFileELF::GetImageInfoAddress()
407{
408 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000409 return Address();
410
411 SectionList *section_list = GetSectionList();
412 if (!section_list)
413 return Address();
414
Stephen Wilson499b40e2011-03-30 16:07:05 +0000415 user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
416 if (!dynsym_id)
417 return Address();
418
419 const ELFSectionHeader *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
420 if (!dynsym_hdr)
421 return Address();
422
Greg Claytone72dfb32012-02-24 01:59:29 +0000423 SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
424 if (dynsym_section_sp)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000425 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000426 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000427 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000428 ELFDynamic &symbol = m_dynamic_symbols[i];
429
430 if (symbol.d_tag == DT_DEBUG)
431 {
432 // Compute the offset as the number of previous entries plus the
433 // size of d_tag.
434 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
435 return Address(dynsym_section_sp, offset);
436 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000437 }
438 }
439
440 return Address();
441}
442
Jim Ingham672e6f52011-03-07 23:44:08 +0000443lldb_private::Address
444ObjectFileELF::GetEntryPointAddress ()
445{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000446 SectionList *sections;
447 addr_t offset;
Jim Ingham672e6f52011-03-07 23:44:08 +0000448
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000449 if (m_entry_point_address.IsValid())
450 return m_entry_point_address;
451
452 if (!ParseHeader() || !IsExecutable())
453 return m_entry_point_address;
454
455 sections = GetSectionList();
456 offset = m_header.e_entry;
457
458 if (!sections)
459 {
460 m_entry_point_address.SetOffset(offset);
461 return m_entry_point_address;
462 }
463
464 m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
465
466 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000467}
468
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000469//----------------------------------------------------------------------
470// ParseDependentModules
471//----------------------------------------------------------------------
472size_t
473ObjectFileELF::ParseDependentModules()
474{
475 if (m_filespec_ap.get())
476 return m_filespec_ap->GetSize();
477
478 m_filespec_ap.reset(new FileSpecList());
479
480 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
481 return 0;
482
483 // Locate the dynamic table.
484 user_id_t dynsym_id = 0;
485 user_id_t dynstr_id = 0;
Greg Clayton450e3f32010-10-12 02:24:53 +0000486 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
487 sh_pos != m_section_headers.end(); ++sh_pos)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000488 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000489 if (sh_pos->sh_type == SHT_DYNAMIC)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000490 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000491 dynsym_id = SectionIndex(sh_pos);
492 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000493 break;
494 }
495 }
496
497 if (!(dynsym_id && dynstr_id))
498 return 0;
499
500 SectionList *section_list = GetSectionList();
501 if (!section_list)
502 return 0;
503
504 // Resolve and load the dynamic table entries and corresponding string
505 // table.
506 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
507 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
508 if (!(dynsym && dynstr))
509 return 0;
510
511 DataExtractor dynsym_data;
512 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000513 if (ReadSectionData(dynsym, dynsym_data) &&
514 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000515 {
516 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000517 const lldb::offset_t section_size = dynsym_data.GetByteSize();
518 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000519
520 // The only type of entries we are concerned with are tagged DT_NEEDED,
521 // yielding the name of a required library.
522 while (offset < section_size)
523 {
524 if (!symbol.Parse(dynsym_data, &offset))
525 break;
526
527 if (symbol.d_tag != DT_NEEDED)
528 continue;
529
530 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
531 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000532 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000533 }
534 }
535
536 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537}
538
539//----------------------------------------------------------------------
540// ParseProgramHeaders
541//----------------------------------------------------------------------
542size_t
543ObjectFileELF::ParseProgramHeaders()
544{
545 // We have already parsed the program headers
546 if (!m_program_headers.empty())
547 return m_program_headers.size();
548
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000549 // If there are no program headers to read we are done.
550 if (m_header.e_phnum == 0)
551 return 0;
552
553 m_program_headers.resize(m_header.e_phnum);
554 if (m_program_headers.size() != m_header.e_phnum)
555 return 0;
556
557 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000558 const elf_off ph_offset = m_header.e_phoff;
559 DataExtractor data;
560 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000561 return 0;
562
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000563 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000564 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000565 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000567 if (m_program_headers[idx].Parse(data, &offset) == false)
568 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000569 }
570
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000571 if (idx < m_program_headers.size())
572 m_program_headers.resize(idx);
573
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 return m_program_headers.size();
575}
576
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000577//----------------------------------------------------------------------
578// ParseSectionHeaders
579//----------------------------------------------------------------------
580size_t
581ObjectFileELF::ParseSectionHeaders()
582{
583 // We have already parsed the section headers
584 if (!m_section_headers.empty())
585 return m_section_headers.size();
586
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000587 // If there are no section headers we are done.
588 if (m_header.e_shnum == 0)
589 return 0;
590
591 m_section_headers.resize(m_header.e_shnum);
592 if (m_section_headers.size() != m_header.e_shnum)
593 return 0;
594
595 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000596 const elf_off sh_offset = m_header.e_shoff;
597 DataExtractor data;
598 if (GetData (sh_offset, sh_size, data) != sh_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000599 return 0;
600
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000601 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000602 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000603 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000604 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000605 if (m_section_headers[idx].Parse(data, &offset) == false)
606 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000608 if (idx < m_section_headers.size())
609 m_section_headers.resize(idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610
611 return m_section_headers.size();
612}
613
614size_t
615ObjectFileELF::GetSectionHeaderStringTable()
616{
617 if (m_shstr_data.GetByteSize() == 0)
618 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000619 const unsigned strtab_idx = m_header.e_shstrndx;
620
621 if (strtab_idx && strtab_idx < m_section_headers.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000623 const ELFSectionHeader &sheader = m_section_headers[strtab_idx];
624 const size_t byte_size = sheader.sh_size;
Greg Clayton44435ed2012-01-12 05:25:17 +0000625 const Elf64_Off offset = sheader.sh_offset;
626 m_shstr_data.SetData (m_data, offset, byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000627
Greg Clayton44435ed2012-01-12 05:25:17 +0000628 if (m_shstr_data.GetByteSize() != byte_size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000629 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630 }
631 }
632 return m_shstr_data.GetByteSize();
633}
634
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000635lldb::user_id_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636ObjectFileELF::GetSectionIndexByName(const char *name)
637{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000638 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
639 return 0;
640
641 // Search the collection of section headers for one with a matching name.
642 for (SectionHeaderCollIter I = m_section_headers.begin();
643 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000645 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
646
647 if (!sectionName)
648 return 0;
649
650 if (strcmp(name, sectionName) != 0)
651 continue;
652
653 return SectionIndex(I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654 }
655
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000656 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657}
658
Stephen Wilson499b40e2011-03-30 16:07:05 +0000659const elf::ELFSectionHeader *
660ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
661{
662 if (!ParseSectionHeaders() || !id)
663 return NULL;
664
665 if (--id < m_section_headers.size())
666 return &m_section_headers[id];
667
668 return NULL;
669}
670
Michael Sartainc836ae72013-05-23 20:57:03 +0000671static bool
672ParseNoteGNUBuildID(DataExtractor& data, lldb_private::UUID& uuid)
673{
674 // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
675 // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
676 struct
677 {
678 uint32_t name_len; // Length of note name
679 uint32_t desc_len; // Length of note descriptor
680 uint32_t type; // Type of note (1 is ABI_TAG, 3 is BUILD_ID)
681 } notehdr;
682 lldb::offset_t offset = 0;
683 static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
684
685 while (true)
686 {
687 if (data.GetU32 (&offset, &notehdr, 3) == NULL)
688 return false;
689
690 notehdr.name_len = llvm::RoundUpToAlignment (notehdr.name_len, 4);
691 notehdr.desc_len = llvm::RoundUpToAlignment (notehdr.desc_len, 4);
692
693 lldb::offset_t offset_next_note = offset + notehdr.name_len + notehdr.desc_len;
694
695 // 16 bytes is UUID|MD5, 20 bytes is SHA1
696 if ((notehdr.type == g_gnu_build_id) && (notehdr.name_len == 4) &&
697 (notehdr.desc_len == 16 || notehdr.desc_len == 20))
698 {
699 char name[4];
700 if (data.GetU8 (&offset, name, 4) == NULL)
701 return false;
702 if (!strcmp(name, "GNU"))
703 {
704 uint8_t uuidbuf[20];
705 if (data.GetU8 (&offset, &uuidbuf, notehdr.desc_len) == NULL)
706 return false;
707 uuid.SetBytes (uuidbuf, notehdr.desc_len);
708 return true;
709 }
710 }
711 offset = offset_next_note;
712 }
713 return false;
714}
715
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716SectionList *
717ObjectFileELF::GetSectionList()
718{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000719 if (m_sections_ap.get())
720 return m_sections_ap.get();
721
722 if (ParseSectionHeaders() && GetSectionHeaderStringTable())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000723 {
724 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000726 for (SectionHeaderCollIter I = m_section_headers.begin();
727 I != m_section_headers.end(); ++I)
728 {
729 const ELFSectionHeader &header = *I;
730
731 ConstString name(m_shstr_data.PeekCStr(header.sh_name));
Greg Clayton47037bc2012-03-27 02:40:46 +0000732 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
733 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000734
Greg Clayton4ceb9982010-07-21 22:54:26 +0000735 static ConstString g_sect_name_text (".text");
736 static ConstString g_sect_name_data (".data");
737 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +0000738 static ConstString g_sect_name_tdata (".tdata");
739 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +0000740 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
741 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
742 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
743 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
744 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
745 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
746 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
747 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
748 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
749 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
750 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
751 static ConstString g_sect_name_eh_frame (".eh_frame");
752
753 SectionType sect_type = eSectionTypeOther;
754
Greg Clayton741f3f92012-03-27 21:10:07 +0000755 bool is_thread_specific = false;
756
Greg Clayton4ceb9982010-07-21 22:54:26 +0000757 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
758 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
759 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +0000760 else if (name == g_sect_name_tdata)
761 {
762 sect_type = eSectionTypeData;
763 is_thread_specific = true;
764 }
765 else if (name == g_sect_name_tbss)
766 {
767 sect_type = eSectionTypeZeroFill;
768 is_thread_specific = true;
769 }
Greg Clayton4ceb9982010-07-21 22:54:26 +0000770 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
771 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
772 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
773 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
774 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
775 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
776 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
777 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
778 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
779 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
780 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
781 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
Michael Sartainc836ae72013-05-23 20:57:03 +0000782 else if (header.sh_type == SHT_NOTE)
783 {
784 if (!m_uuid.IsValid())
785 {
786 DataExtractor data;
787 if (vm_size && (GetData (header.sh_offset, vm_size, data) == vm_size))
788 {
789 ParseNoteGNUBuildID (data, m_uuid);
790 }
791 }
792 }
Greg Clayton4ceb9982010-07-21 22:54:26 +0000793
Greg Clayton741f3f92012-03-27 21:10:07 +0000794 SectionSP section_sp(new Section(
Greg Clayton4ceb9982010-07-21 22:54:26 +0000795 GetModule(), // Module to which this section belongs.
796 SectionIndex(I), // Section ID.
797 name, // Section name.
798 sect_type, // Section type.
799 header.sh_addr, // VM address.
Greg Clayton47037bc2012-03-27 02:40:46 +0000800 vm_size, // VM size in bytes of this section.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000801 header.sh_offset, // Offset of this section in the file.
Greg Clayton47037bc2012-03-27 02:40:46 +0000802 file_size, // Size of the section as found in the file.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000803 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000804
Greg Clayton741f3f92012-03-27 21:10:07 +0000805 if (is_thread_specific)
806 section_sp->SetIsThreadSpecific (is_thread_specific);
807 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000808 }
Sean Callanan56775362012-06-08 02:16:08 +0000809
810 m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000811 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000812
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000813 return m_sections_ap.get();
814}
815
Stephen Wilson499b40e2011-03-30 16:07:05 +0000816static unsigned
817ParseSymbols(Symtab *symtab,
818 user_id_t start_id,
819 SectionList *section_list,
820 const ELFSectionHeader *symtab_shdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000821 const DataExtractor &symtab_data,
822 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000823{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000824 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000825 lldb::offset_t offset = 0;
826 const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000827
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000828 static ConstString text_section_name(".text");
829 static ConstString init_section_name(".init");
830 static ConstString fini_section_name(".fini");
831 static ConstString ctors_section_name(".ctors");
832 static ConstString dtors_section_name(".dtors");
833
834 static ConstString data_section_name(".data");
835 static ConstString rodata_section_name(".rodata");
836 static ConstString rodata1_section_name(".rodata1");
837 static ConstString data2_section_name(".data1");
838 static ConstString bss_section_name(".bss");
839
Greg Clayton9594f4c2013-04-13 23:17:23 +0000840 //StreamFile strm(stdout, false);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000841 unsigned i;
842 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000844 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845 break;
Greg Clayton9594f4c2013-04-13 23:17:23 +0000846
847 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
848
849 // No need to add symbols that have no names
850 if (symbol_name == NULL || symbol_name[0] == '\0')
851 continue;
852
853 //symbol.Dump (&strm, i, &strtab_data, section_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854
Greg Claytone72dfb32012-02-24 01:59:29 +0000855 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000857 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000858
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000859 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860 {
861 case SHN_ABS:
862 symbol_type = eSymbolTypeAbsolute;
863 break;
864 case SHN_UNDEF:
865 symbol_type = eSymbolTypeUndefined;
866 break;
867 default:
Greg Claytone72dfb32012-02-24 01:59:29 +0000868 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000869 break;
870 }
871
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000872 // If a symbol is undefined do not process it further even if it has a STT type
873 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000875 switch (symbol.getType())
876 {
877 default:
878 case STT_NOTYPE:
879 // The symbol's type is not specified.
880 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000881
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000882 case STT_OBJECT:
883 // The symbol is associated with a data object, such as a variable,
884 // an array, etc.
885 symbol_type = eSymbolTypeData;
886 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000887
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000888 case STT_FUNC:
889 // The symbol is associated with a function or other executable code.
890 symbol_type = eSymbolTypeCode;
891 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000893 case STT_SECTION:
894 // The symbol is associated with a section. Symbol table entries of
895 // this type exist primarily for relocation and normally have
896 // STB_LOCAL binding.
897 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000898
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000899 case STT_FILE:
900 // Conventionally, the symbol's name gives the name of the source
901 // file associated with the object file. A file symbol has STB_LOCAL
902 // binding, its section index is SHN_ABS, and it precedes the other
903 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +0000904 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000905 break;
Matt Kopec00049b82013-02-27 20:13:38 +0000906
907 case STT_GNU_IFUNC:
908 // The symbol is associated with an indirect function. The actual
909 // function will be resolved if it is referenced.
910 symbol_type = eSymbolTypeResolver;
911 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +0000912 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913 }
914
915 if (symbol_type == eSymbolTypeInvalid)
916 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000917 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000918 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000919 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920 if (sect_name == text_section_name ||
921 sect_name == init_section_name ||
922 sect_name == fini_section_name ||
923 sect_name == ctors_section_name ||
924 sect_name == dtors_section_name)
925 {
926 symbol_type = eSymbolTypeCode;
927 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000928 else if (sect_name == data_section_name ||
929 sect_name == data2_section_name ||
930 sect_name == rodata_section_name ||
931 sect_name == rodata1_section_name ||
932 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000933 {
934 symbol_type = eSymbolTypeData;
935 }
936 }
937 }
938
939 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +0000940 if (symbol_section_sp)
941 symbol_value -= symbol_section_sp->GetFileAddress();
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000942 bool is_global = symbol.getBinding() == STB_GLOBAL;
943 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +0000944 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000945 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +0000946 i + start_id, // ID is the original symbol table index.
947 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +0000948 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +0000949 symbol_type, // Type of this symbol
950 is_global, // Is this globally visible?
951 false, // Is this symbol debug info?
952 false, // Is this symbol a trampoline?
953 false, // Is this symbol artificial?
954 symbol_section_sp, // Section in which this symbol is defined or null.
955 symbol_value, // Offset in section or symbol value.
956 symbol.st_size, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +0000957 true, // Size is valid
Greg Claytone72dfb32012-02-24 01:59:29 +0000958 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000959 symtab->AddSymbol(dc_symbol);
960 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000961
962 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963}
964
Stephen Wilson499b40e2011-03-30 16:07:05 +0000965unsigned
966ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
967 const ELFSectionHeader *symtab_hdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000968 user_id_t symtab_id)
969{
Stephen Wilson499b40e2011-03-30 16:07:05 +0000970 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
971 symtab_hdr->sh_type == SHT_DYNSYM);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000972
973 // Parse in the section list if needed.
974 SectionList *section_list = GetSectionList();
975 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000976 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000977
978 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +0000979 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000980
981 Section *symtab = section_list->FindSectionByID(symtab_id).get();
982 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +0000983 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000984 if (symtab && strtab)
985 {
986 DataExtractor symtab_data;
987 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000988 if (ReadSectionData(symtab, symtab_data) &&
989 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000990 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000991 num_symbols = ParseSymbols(symbol_table, start_id,
992 section_list, symtab_hdr,
993 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000994 }
995 }
Stephen Wilson499b40e2011-03-30 16:07:05 +0000996
997 return num_symbols;
998}
999
1000size_t
1001ObjectFileELF::ParseDynamicSymbols()
1002{
1003 if (m_dynamic_symbols.size())
1004 return m_dynamic_symbols.size();
1005
1006 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
1007 if (!dyn_id)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001008 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001009
1010 SectionList *section_list = GetSectionList();
1011 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001012 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001013
1014 Section *dynsym = section_list->FindSectionByID(dyn_id).get();
1015 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001016 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001017
1018 ELFDynamic symbol;
1019 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001020 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001021 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001022 const lldb::offset_t section_size = dynsym_data.GetByteSize();
1023 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001024
1025 while (cursor < section_size)
1026 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001027 if (!symbol.Parse(dynsym_data, &cursor))
1028 break;
1029
1030 m_dynamic_symbols.push_back(symbol);
1031 }
1032 }
1033
1034 return m_dynamic_symbols.size();
1035}
1036
1037const ELFDynamic *
1038ObjectFileELF::FindDynamicSymbol(unsigned tag)
1039{
1040 if (!ParseDynamicSymbols())
1041 return NULL;
1042
1043 SectionList *section_list = GetSectionList();
1044 if (!section_list)
1045 return 0;
1046
1047 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
1048 DynamicSymbolCollIter E = m_dynamic_symbols.end();
1049 for ( ; I != E; ++I)
1050 {
1051 ELFDynamic *symbol = &*I;
1052
1053 if (symbol->d_tag == tag)
1054 return symbol;
1055 }
1056
1057 return NULL;
1058}
1059
1060Section *
1061ObjectFileELF::PLTSection()
1062{
1063 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
1064 SectionList *section_list = GetSectionList();
1065
1066 if (symbol && section_list)
1067 {
1068 addr_t addr = symbol->d_ptr;
1069 return section_list->FindSectionContainingFileAddress(addr).get();
1070 }
1071
1072 return NULL;
1073}
1074
1075unsigned
1076ObjectFileELF::PLTRelocationType()
1077{
1078 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
1079
1080 if (symbol)
1081 return symbol->d_val;
1082
1083 return 0;
1084}
1085
1086static unsigned
1087ParsePLTRelocations(Symtab *symbol_table,
1088 user_id_t start_id,
1089 unsigned rel_type,
1090 const ELFHeader *hdr,
1091 const ELFSectionHeader *rel_hdr,
1092 const ELFSectionHeader *plt_hdr,
1093 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00001094 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001095 DataExtractor &rel_data,
1096 DataExtractor &symtab_data,
1097 DataExtractor &strtab_data)
1098{
1099 ELFRelocation rel(rel_type);
1100 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001101 lldb::offset_t offset = 0;
1102 const elf_xword plt_entsize = plt_hdr->sh_entsize;
1103 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001104
1105 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1106 reloc_info_fn reloc_type;
1107 reloc_info_fn reloc_symbol;
1108
Greg Claytond091afe2012-11-12 22:53:16 +00001109 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +00001110 {
1111 reloc_type = ELFRelocation::RelocType32;
1112 reloc_symbol = ELFRelocation::RelocSymbol32;
1113 }
1114 else
1115 {
1116 reloc_type = ELFRelocation::RelocType64;
1117 reloc_symbol = ELFRelocation::RelocSymbol64;
1118 }
1119
1120 unsigned slot_type = hdr->GetRelocationJumpSlotType();
1121 unsigned i;
1122 for (i = 0; i < num_relocations; ++i)
1123 {
1124 if (rel.Parse(rel_data, &offset) == false)
1125 break;
1126
1127 if (reloc_type(rel) != slot_type)
1128 continue;
1129
Greg Claytonc7bece562013-01-25 18:06:21 +00001130 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001131 uint64_t plt_index = (i + 1) * plt_entsize;
1132
1133 if (!symbol.Parse(symtab_data, &symbol_offset))
1134 break;
1135
1136 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001137 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001138
1139 Symbol jump_symbol(
1140 i + start_id, // Symbol table index
1141 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001142 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001143 eSymbolTypeTrampoline, // Type of this symbol
1144 false, // Is this globally visible?
1145 false, // Is this symbol debug info?
1146 true, // Is this symbol a trampoline?
1147 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001148 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001149 plt_index, // Offset in section or symbol value.
1150 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001151 true, // Size is valid
Stephen Wilson499b40e2011-03-30 16:07:05 +00001152 0); // Symbol flags.
1153
1154 symbol_table->AddSymbol(jump_symbol);
1155 }
1156
1157 return i;
1158}
1159
1160unsigned
1161ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1162 user_id_t start_id,
1163 const ELFSectionHeader *rel_hdr,
1164 user_id_t rel_id)
1165{
1166 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1167
1168 // The link field points to the asscoiated symbol table. The info field
1169 // points to the section holding the plt.
1170 user_id_t symtab_id = rel_hdr->sh_link;
1171 user_id_t plt_id = rel_hdr->sh_info;
1172
1173 if (!symtab_id || !plt_id)
1174 return 0;
1175
1176 // Section ID's are ones based;
1177 symtab_id++;
1178 plt_id++;
1179
1180 const ELFSectionHeader *plt_hdr = GetSectionHeaderByIndex(plt_id);
1181 if (!plt_hdr)
1182 return 0;
1183
1184 const ELFSectionHeader *sym_hdr = GetSectionHeaderByIndex(symtab_id);
1185 if (!sym_hdr)
1186 return 0;
1187
1188 SectionList *section_list = GetSectionList();
1189 if (!section_list)
1190 return 0;
1191
1192 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1193 if (!rel_section)
1194 return 0;
1195
Greg Claytone72dfb32012-02-24 01:59:29 +00001196 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1197 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001198 return 0;
1199
1200 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1201 if (!symtab)
1202 return 0;
1203
1204 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1205 if (!strtab)
1206 return 0;
1207
1208 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001209 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001210 return 0;
1211
1212 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001213 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001214 return 0;
1215
1216 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001217 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001218 return 0;
1219
1220 unsigned rel_type = PLTRelocationType();
1221 if (!rel_type)
1222 return 0;
1223
Greg Claytone72dfb32012-02-24 01:59:29 +00001224 return ParsePLTRelocations (symbol_table,
1225 start_id,
1226 rel_type,
1227 &m_header,
1228 rel_hdr,
1229 plt_hdr,
1230 sym_hdr,
1231 plt_section_sp,
1232 rel_data,
1233 symtab_data,
1234 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001235}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001236
1237Symtab *
1238ObjectFileELF::GetSymtab()
1239{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001240 if (m_symtab_ap.get())
1241 return m_symtab_ap.get();
1242
1243 Symtab *symbol_table = new Symtab(this);
1244 m_symtab_ap.reset(symbol_table);
1245
Stephen Wilson499b40e2011-03-30 16:07:05 +00001246 Mutex::Locker locker(symbol_table->GetMutex());
Greg Clayton8087ca22010-10-08 04:20:14 +00001247
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001248 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1249 return symbol_table;
1250
1251 // Locate and parse all linker symbol tables.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001252 uint64_t symbol_id = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001253 for (SectionHeaderCollIter I = m_section_headers.begin();
1254 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255 {
Peter Collingbourneb4aabeb2011-06-03 20:39:58 +00001256 if (I->sh_type == SHT_SYMTAB || I->sh_type == SHT_DYNSYM)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001258 const ELFSectionHeader &symtab_header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001259 user_id_t section_id = SectionIndex(I);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001260 symbol_id += ParseSymbolTable(symbol_table, symbol_id,
1261 &symtab_header, section_id);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 }
1263 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001264
1265 // Synthesize trampoline symbols to help navigate the PLT.
1266 Section *reloc_section = PLTSection();
1267 if (reloc_section)
1268 {
1269 user_id_t reloc_id = reloc_section->GetID();
1270 const ELFSectionHeader *reloc_header = GetSectionHeaderByIndex(reloc_id);
1271 assert(reloc_header);
1272
1273 ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
1274 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001275
1276 return symbol_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001277}
1278
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001279//===----------------------------------------------------------------------===//
1280// Dump
1281//
1282// Dump the specifics of the runtime file container (such as any headers
1283// segments, sections, etc).
1284//----------------------------------------------------------------------
1285void
1286ObjectFileELF::Dump(Stream *s)
1287{
1288 DumpELFHeader(s, m_header);
1289 s->EOL();
1290 DumpELFProgramHeaders(s);
1291 s->EOL();
1292 DumpELFSectionHeaders(s);
1293 s->EOL();
1294 SectionList *section_list = GetSectionList();
1295 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001296 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001297 Symtab *symtab = GetSymtab();
1298 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001299 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001301 DumpDependentModules(s);
1302 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001303}
1304
1305//----------------------------------------------------------------------
1306// DumpELFHeader
1307//
1308// Dump the ELF header to the specified output stream
1309//----------------------------------------------------------------------
1310void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001311ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001312{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001313 s->PutCString("ELF Header\n");
1314 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1315 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1316 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1317 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1318 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1319 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1320 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001321
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001322 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1323 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001324 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1325 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1326 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1327
1328 s->Printf("e_type = 0x%4.4x ", header.e_type);
1329 DumpELFHeader_e_type(s, header.e_type);
1330 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1331 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001332 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1333 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1334 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001335 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1336 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1337 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1338 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1339 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1340 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1341 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1342}
1343
1344//----------------------------------------------------------------------
1345// DumpELFHeader_e_type
1346//
1347// Dump an token value for the ELF header member e_type
1348//----------------------------------------------------------------------
1349void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001350ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001351{
1352 switch (e_type)
1353 {
1354 case ET_NONE: *s << "ET_NONE"; break;
1355 case ET_REL: *s << "ET_REL"; break;
1356 case ET_EXEC: *s << "ET_EXEC"; break;
1357 case ET_DYN: *s << "ET_DYN"; break;
1358 case ET_CORE: *s << "ET_CORE"; break;
1359 default:
1360 break;
1361 }
1362}
1363
1364//----------------------------------------------------------------------
1365// DumpELFHeader_e_ident_EI_DATA
1366//
1367// Dump an token value for the ELF header member e_ident[EI_DATA]
1368//----------------------------------------------------------------------
1369void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001370ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001371{
1372 switch (ei_data)
1373 {
1374 case ELFDATANONE: *s << "ELFDATANONE"; break;
1375 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1376 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1377 default:
1378 break;
1379 }
1380}
1381
1382
1383//----------------------------------------------------------------------
1384// DumpELFProgramHeader
1385//
1386// Dump a single ELF program header to the specified output stream
1387//----------------------------------------------------------------------
1388void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001389ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001390{
1391 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001392 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1393 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001394
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001395 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001396 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001397}
1398
1399//----------------------------------------------------------------------
1400// DumpELFProgramHeader_p_type
1401//
1402// Dump an token value for the ELF program header member p_type which
1403// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001404// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001405void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001406ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001407{
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001408 const int kStrWidth = 15;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001409 switch (p_type)
1410 {
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001411 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1412 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1413 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1414 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1415 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1416 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1417 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1418 CASE_AND_STREAM(s, PT_TLS , kStrWidth);
1419 CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001420 default:
1421 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1422 break;
1423 }
1424}
1425
1426
1427//----------------------------------------------------------------------
1428// DumpELFProgramHeader_p_flags
1429//
1430// Dump an token value for the ELF program header member p_flags
1431//----------------------------------------------------------------------
1432void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001433ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434{
1435 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1436 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1437 << ((p_flags & PF_W) ? "PF_W" : " ")
1438 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1439 << ((p_flags & PF_R) ? "PF_R" : " ");
1440}
1441
1442//----------------------------------------------------------------------
1443// DumpELFProgramHeaders
1444//
1445// Dump all of the ELF program header to the specified output stream
1446//----------------------------------------------------------------------
1447void
1448ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1449{
1450 if (ParseProgramHeaders())
1451 {
1452 s->PutCString("Program Headers\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001453 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001454 "p_filesz p_memsz p_flags p_align\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001455 s->PutCString("==== --------------- -------- -------- -------- "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001456 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001457
1458 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001459 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1460 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001461 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001462 s->Printf("[%2u] ", idx);
1463 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001464 s->EOL();
1465 }
1466 }
1467}
1468
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001469//----------------------------------------------------------------------
1470// DumpELFSectionHeader
1471//
1472// Dump a single ELF section header to the specified output stream
1473//----------------------------------------------------------------------
1474void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001475ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001476{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001477 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001478 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001479 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001480 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001481 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 +00001482 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001483 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001484}
1485
1486//----------------------------------------------------------------------
1487// DumpELFSectionHeader_sh_type
1488//
1489// Dump an token value for the ELF section header member sh_type which
1490// describes the type of the section
1491//----------------------------------------------------------------------
1492void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001493ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001494{
1495 const int kStrWidth = 12;
1496 switch (sh_type)
1497 {
1498 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1499 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1500 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1501 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1502 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1503 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1504 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1505 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1506 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1507 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1508 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1509 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1510 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1511 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1512 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1513 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1514 default:
1515 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1516 break;
1517 }
1518}
1519
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001520//----------------------------------------------------------------------
1521// DumpELFSectionHeader_sh_flags
1522//
1523// Dump an token value for the ELF section header member sh_flags
1524//----------------------------------------------------------------------
1525void
Greg Claytonc7bece562013-01-25 18:06:21 +00001526ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001527{
1528 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1529 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1530 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1531 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1532 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1533}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001534
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001535//----------------------------------------------------------------------
1536// DumpELFSectionHeaders
1537//
1538// Dump all of the ELF section header to the specified output stream
1539//----------------------------------------------------------------------
1540void
1541ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1542{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001543 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1544 return;
1545
1546 s->PutCString("Section Headers\n");
1547 s->PutCString("IDX name type flags "
1548 "addr offset size link info addralgn "
1549 "entsize Name\n");
1550 s->PutCString("==== -------- ------------ -------------------------------- "
1551 "-------- -------- -------- -------- -------- -------- "
1552 "-------- ====================\n");
1553
1554 uint32_t idx = 0;
1555 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1556 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001557 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001558 s->Printf("[%2u] ", idx);
1559 ObjectFileELF::DumpELFSectionHeader(s, *I);
1560 const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
1561 if (section_name)
1562 *s << ' ' << section_name << "\n";
1563 }
1564}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001565
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001566void
1567ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1568{
1569 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001570
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001571 if (num_modules > 0)
1572 {
1573 s->PutCString("Dependent Modules:\n");
1574 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001575 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001576 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1577 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001578 }
1579 }
1580}
1581
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001582bool
Greg Clayton514487e2011-02-15 21:59:32 +00001583ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001584{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001585 if (!ParseHeader())
1586 return false;
1587
Greg Claytone0d378b2011-03-24 21:19:54 +00001588 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001589 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1590 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001591 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001592}
1593
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001594ObjectFile::Type
1595ObjectFileELF::CalculateType()
1596{
1597 switch (m_header.e_type)
1598 {
1599 case llvm::ELF::ET_NONE:
1600 // 0 - No file type
1601 return eTypeUnknown;
1602
1603 case llvm::ELF::ET_REL:
1604 // 1 - Relocatable file
1605 return eTypeObjectFile;
1606
1607 case llvm::ELF::ET_EXEC:
1608 // 2 - Executable file
1609 return eTypeExecutable;
1610
1611 case llvm::ELF::ET_DYN:
1612 // 3 - Shared object file
1613 return eTypeSharedLibrary;
1614
1615 case ET_CORE:
1616 // 4 - Core file
1617 return eTypeCoreFile;
1618
1619 default:
1620 break;
1621 }
1622 return eTypeUnknown;
1623}
1624
1625ObjectFile::Strata
1626ObjectFileELF::CalculateStrata()
1627{
1628 switch (m_header.e_type)
1629 {
1630 case llvm::ELF::ET_NONE:
1631 // 0 - No file type
1632 return eStrataUnknown;
1633
1634 case llvm::ELF::ET_REL:
1635 // 1 - Relocatable file
1636 return eStrataUnknown;
1637
1638 case llvm::ELF::ET_EXEC:
1639 // 2 - Executable file
1640 // TODO: is there any way to detect that an executable is a kernel
1641 // related executable by inspecting the program headers, section
1642 // headers, symbols, or any other flag bits???
1643 return eStrataUser;
1644
1645 case llvm::ELF::ET_DYN:
1646 // 3 - Shared object file
1647 // TODO: is there any way to detect that an shared library is a kernel
1648 // related executable by inspecting the program headers, section
1649 // headers, symbols, or any other flag bits???
1650 return eStrataUnknown;
1651
1652 case ET_CORE:
1653 // 4 - Core file
1654 // TODO: is there any way to detect that an core file is a kernel
1655 // related executable by inspecting the program headers, section
1656 // headers, symbols, or any other flag bits???
1657 return eStrataUnknown;
1658
1659 default:
1660 break;
1661 }
1662 return eStrataUnknown;
1663}
1664