blob: 5215b081ee9db117c359a996f6c7b9dffedbd4a3 [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
Michael Sartaina7499c92013-07-01 19:45:50 +0000265 // machine information. However, this info isn't guaranteed to exist or be correct. Details:
Michael Sartainc836ae72013-05-23 20:57:03 +0000266 // http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
267 // Instead of passing potentially incorrect information down the pipeline, grab
268 // the host information and use it.
269 spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString());
270 spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString());
Michael Sartaina7499c92013-07-01 19:45:50 +0000271
272 // Try to get the UUID from the section list. Usually that's at the end, so
273 // map the file in if we don't have it already.
274 size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
275 if (section_header_end > data_sp->GetByteSize())
276 {
277 data_sp = file.MemoryMapFileContents (file_offset, section_header_end);
278 data.SetData(data_sp);
279 }
280
281 uint32_t gnu_debuglink_crc;
282 std::string gnu_debuglink_file;
283 SectionHeaderColl section_headers;
284 GetSectionHeaderInfo(section_headers, data, header, spec.GetUUID(), gnu_debuglink_file, gnu_debuglink_crc);
285
Michael Sartain9f0013d2013-05-17 00:20:21 +0000286 specs.Append(spec);
287 }
288 }
289 }
290 }
Michael Sartainc836ae72013-05-23 20:57:03 +0000291
Michael Sartain9f0013d2013-05-17 00:20:21 +0000292 return specs.GetSize() - initial_count;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000293}
294
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000295//------------------------------------------------------------------
296// PluginInterface protocol
297//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +0000298lldb_private::ConstString
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000299ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000301 return GetPluginNameStatic();
302}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000304uint32_t
305ObjectFileELF::GetPluginVersion()
306{
307 return m_plugin_version;
308}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000309//------------------------------------------------------------------
310// ObjectFile protocol
311//------------------------------------------------------------------
312
Greg Claytone72dfb32012-02-24 01:59:29 +0000313ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000314 DataBufferSP& data_sp,
315 lldb::offset_t data_offset,
Greg Claytone72dfb32012-02-24 01:59:29 +0000316 const FileSpec* file,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000317 lldb::offset_t file_offset,
318 lldb::offset_t length) :
319 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytone72dfb32012-02-24 01:59:29 +0000320 m_header(),
321 m_program_headers(),
322 m_section_headers(),
Michael Sartaina7499c92013-07-01 19:45:50 +0000323 m_filespec_ap()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000324{
325 if (file)
326 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000327 ::memset(&m_header, 0, sizeof(m_header));
Michael Sartaina7499c92013-07-01 19:45:50 +0000328 m_gnu_debuglink_crc = 0;
329 m_gnu_debuglink_file.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330}
331
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332ObjectFileELF::~ObjectFileELF()
333{
334}
335
Jim Ingham5aee1622010-08-09 23:31:02 +0000336bool
337ObjectFileELF::IsExecutable() const
338{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000339 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000340}
341
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000343ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344{
345 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
346 return eByteOrderBig;
347 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
348 return eByteOrderLittle;
349 return eByteOrderInvalid;
350}
351
Greg Claytonc7bece562013-01-25 18:06:21 +0000352uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000353ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354{
355 return m_data.GetAddressByteSize();
356}
357
Greg Claytonc7bece562013-01-25 18:06:21 +0000358size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000359ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360{
Greg Claytonc7bece562013-01-25 18:06:21 +0000361 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000362}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363
Greg Claytonc7bece562013-01-25 18:06:21 +0000364size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000365ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
366{
Greg Claytonc7bece562013-01-25 18:06:21 +0000367 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368}
369
370bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000371ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372{
Filipe Cabecinhas22b40f72013-05-16 23:29:36 +0000373 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000374 return m_header.Parse(m_data, &offset);
375}
376
Michael Sartaina7499c92013-07-01 19:45:50 +0000377/*
378 * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
379 *
380 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
381 * code or tables extracted from it, as desired without restriction.
382 */
383static uint32_t
384calc_gnu_debuglink_crc32(const void *buf, size_t size)
385{
386 static const uint32_t g_crc32_tab[] =
387 {
388 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
389 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
390 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
391 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
392 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
393 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
394 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
395 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
396 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
397 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
398 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
399 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
400 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
401 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
402 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
403 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
404 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
405 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
406 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
407 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
408 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
409 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
410 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
411 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
412 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
413 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
414 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
415 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
416 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
417 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
418 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
419 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
420 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
421 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
422 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
423 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
424 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
425 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
426 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
427 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
428 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
429 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
430 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
431 };
432 const uint8_t *p = (const uint8_t *)buf;
433 uint32_t crc;
434
435 crc = ~0U;
436 while (size--)
437 crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
438 return crc ^ ~0U;
439}
440
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000441bool
Greg Clayton60830262011-02-04 18:53:10 +0000442ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000443{
Michael Sartaina7499c92013-07-01 19:45:50 +0000444 // Need to parse the section list to get the UUIDs, so make sure that's been done.
445 if (!ParseSectionHeaders())
446 return false;
447
Michael Sartainc836ae72013-05-23 20:57:03 +0000448 if (m_uuid.IsValid())
449 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000450 // We have the full build id uuid.
Michael Sartainc836ae72013-05-23 20:57:03 +0000451 *uuid = m_uuid;
452 return true;
453 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000454 else
455 {
456 m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
457 if (m_gnu_debuglink_crc)
458 {
459 // Use 4 bytes of crc from the .gnu_debuglink section.
460 uint32_t uuidt[4] = { m_gnu_debuglink_crc, 0, 0, 0 };
461 uuid->SetBytes (uuidt, sizeof(uuidt));
462 return true;
463 }
464 }
465
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466 return false;
467}
468
Michael Sartaina7499c92013-07-01 19:45:50 +0000469lldb_private::FileSpecList
470ObjectFileELF::GetDebugSymbolFilePaths()
471{
472 FileSpecList file_spec_list;
473
474 if (!m_gnu_debuglink_file.empty())
475 {
476 FileSpec file_spec (m_gnu_debuglink_file.c_str(), false);
477 file_spec_list.Append (file_spec);
478 }
479 return file_spec_list;
480}
481
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000483ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000485 size_t num_modules = ParseDependentModules();
486 uint32_t num_specs = 0;
487
488 for (unsigned i = 0; i < num_modules; ++i)
489 {
490 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
491 num_specs++;
492 }
493
494 return num_specs;
495}
496
Stephen Wilson499b40e2011-03-30 16:07:05 +0000497user_id_t
498ObjectFileELF::GetSectionIndexByType(unsigned type)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000499{
500 if (!ParseSectionHeaders())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000501 return 0;
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000502
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000503 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
504 sh_pos != m_section_headers.end(); ++sh_pos)
505 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000506 if (sh_pos->sh_type == type)
507 return SectionIndex(sh_pos);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000508 }
509
Stephen Wilson499b40e2011-03-30 16:07:05 +0000510 return 0;
511}
512
513Address
514ObjectFileELF::GetImageInfoAddress()
515{
516 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000517 return Address();
518
519 SectionList *section_list = GetSectionList();
520 if (!section_list)
521 return Address();
522
Stephen Wilson499b40e2011-03-30 16:07:05 +0000523 user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
524 if (!dynsym_id)
525 return Address();
526
Michael Sartaina7499c92013-07-01 19:45:50 +0000527 const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000528 if (!dynsym_hdr)
529 return Address();
530
Greg Claytone72dfb32012-02-24 01:59:29 +0000531 SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
532 if (dynsym_section_sp)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000533 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000534 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000535 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000536 ELFDynamic &symbol = m_dynamic_symbols[i];
537
538 if (symbol.d_tag == DT_DEBUG)
539 {
540 // Compute the offset as the number of previous entries plus the
541 // size of d_tag.
542 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
543 return Address(dynsym_section_sp, offset);
544 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000545 }
546 }
547
548 return Address();
549}
550
Jim Ingham672e6f52011-03-07 23:44:08 +0000551lldb_private::Address
552ObjectFileELF::GetEntryPointAddress ()
553{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000554 SectionList *sections;
555 addr_t offset;
Jim Ingham672e6f52011-03-07 23:44:08 +0000556
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000557 if (m_entry_point_address.IsValid())
558 return m_entry_point_address;
559
560 if (!ParseHeader() || !IsExecutable())
561 return m_entry_point_address;
562
563 sections = GetSectionList();
564 offset = m_header.e_entry;
565
566 if (!sections)
567 {
568 m_entry_point_address.SetOffset(offset);
569 return m_entry_point_address;
570 }
571
572 m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
573
574 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000575}
576
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000577//----------------------------------------------------------------------
578// ParseDependentModules
579//----------------------------------------------------------------------
580size_t
581ObjectFileELF::ParseDependentModules()
582{
583 if (m_filespec_ap.get())
584 return m_filespec_ap->GetSize();
585
586 m_filespec_ap.reset(new FileSpecList());
587
Michael Sartaina7499c92013-07-01 19:45:50 +0000588 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000589 return 0;
590
591 // Locate the dynamic table.
592 user_id_t dynsym_id = 0;
593 user_id_t dynstr_id = 0;
Greg Clayton450e3f32010-10-12 02:24:53 +0000594 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
595 sh_pos != m_section_headers.end(); ++sh_pos)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000596 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000597 if (sh_pos->sh_type == SHT_DYNAMIC)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000598 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000599 dynsym_id = SectionIndex(sh_pos);
600 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000601 break;
602 }
603 }
604
605 if (!(dynsym_id && dynstr_id))
606 return 0;
607
608 SectionList *section_list = GetSectionList();
609 if (!section_list)
610 return 0;
611
612 // Resolve and load the dynamic table entries and corresponding string
613 // table.
614 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
615 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
616 if (!(dynsym && dynstr))
617 return 0;
618
619 DataExtractor dynsym_data;
620 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000621 if (ReadSectionData(dynsym, dynsym_data) &&
622 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000623 {
624 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000625 const lldb::offset_t section_size = dynsym_data.GetByteSize();
626 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000627
628 // The only type of entries we are concerned with are tagged DT_NEEDED,
629 // yielding the name of a required library.
630 while (offset < section_size)
631 {
632 if (!symbol.Parse(dynsym_data, &offset))
633 break;
634
635 if (symbol.d_tag != DT_NEEDED)
636 continue;
637
638 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
639 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000640 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000641 }
642 }
643
644 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645}
646
647//----------------------------------------------------------------------
648// ParseProgramHeaders
649//----------------------------------------------------------------------
650size_t
651ObjectFileELF::ParseProgramHeaders()
652{
653 // We have already parsed the program headers
654 if (!m_program_headers.empty())
655 return m_program_headers.size();
656
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000657 // If there are no program headers to read we are done.
658 if (m_header.e_phnum == 0)
659 return 0;
660
661 m_program_headers.resize(m_header.e_phnum);
662 if (m_program_headers.size() != m_header.e_phnum)
663 return 0;
664
665 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000666 const elf_off ph_offset = m_header.e_phoff;
667 DataExtractor data;
668 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000669 return 0;
670
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000671 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000672 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000673 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000675 if (m_program_headers[idx].Parse(data, &offset) == false)
676 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000677 }
678
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000679 if (idx < m_program_headers.size())
680 m_program_headers.resize(idx);
681
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000682 return m_program_headers.size();
683}
684
Michael Sartainc836ae72013-05-23 20:57:03 +0000685static bool
Michael Sartaina7499c92013-07-01 19:45:50 +0000686ParseNoteGNUBuildID(DataExtractor &data, lldb_private::UUID &uuid)
Michael Sartainc836ae72013-05-23 20:57:03 +0000687{
688 // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
689 // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
690 struct
691 {
692 uint32_t name_len; // Length of note name
693 uint32_t desc_len; // Length of note descriptor
694 uint32_t type; // Type of note (1 is ABI_TAG, 3 is BUILD_ID)
695 } notehdr;
696 lldb::offset_t offset = 0;
697 static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
698
699 while (true)
700 {
701 if (data.GetU32 (&offset, &notehdr, 3) == NULL)
702 return false;
703
704 notehdr.name_len = llvm::RoundUpToAlignment (notehdr.name_len, 4);
705 notehdr.desc_len = llvm::RoundUpToAlignment (notehdr.desc_len, 4);
706
707 lldb::offset_t offset_next_note = offset + notehdr.name_len + notehdr.desc_len;
708
709 // 16 bytes is UUID|MD5, 20 bytes is SHA1
710 if ((notehdr.type == g_gnu_build_id) && (notehdr.name_len == 4) &&
711 (notehdr.desc_len == 16 || notehdr.desc_len == 20))
712 {
713 char name[4];
714 if (data.GetU8 (&offset, name, 4) == NULL)
715 return false;
716 if (!strcmp(name, "GNU"))
717 {
718 uint8_t uuidbuf[20];
719 if (data.GetU8 (&offset, &uuidbuf, notehdr.desc_len) == NULL)
720 return false;
721 uuid.SetBytes (uuidbuf, notehdr.desc_len);
722 return true;
723 }
724 }
725 offset = offset_next_note;
726 }
727 return false;
728}
Michael Sartaina7499c92013-07-01 19:45:50 +0000729
730//----------------------------------------------------------------------
731// GetSectionHeaderInfo
732//----------------------------------------------------------------------
733size_t
734ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
735 lldb_private::DataExtractor &object_data,
736 const elf::ELFHeader &header,
737 lldb_private::UUID &uuid,
738 std::string &gnu_debuglink_file,
739 uint32_t &gnu_debuglink_crc)
740{
741 // We have already parsed the section headers
742 if (!section_headers.empty())
743 return section_headers.size();
744
745 // If there are no section headers we are done.
746 if (header.e_shnum == 0)
747 return 0;
748
749 section_headers.resize(header.e_shnum);
750 if (section_headers.size() != header.e_shnum)
751 return 0;
752
753 const size_t sh_size = header.e_shnum * header.e_shentsize;
754 const elf_off sh_offset = header.e_shoff;
755 DataExtractor sh_data;
756 if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
757 return 0;
758
759 uint32_t idx;
760 lldb::offset_t offset;
761 for (idx = 0, offset = 0; idx < header.e_shnum; ++idx)
762 {
763 if (section_headers[idx].Parse(sh_data, &offset) == false)
764 break;
765 }
766 if (idx < section_headers.size())
767 section_headers.resize(idx);
768
769 const unsigned strtab_idx = header.e_shstrndx;
770 if (strtab_idx && strtab_idx < section_headers.size())
771 {
772 const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
773 const size_t byte_size = sheader.sh_size;
774 const Elf64_Off offset = sheader.sh_offset;
775 lldb_private::DataExtractor shstr_data;
776
777 if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
778 {
779 for (SectionHeaderCollIter I = section_headers.begin();
780 I != section_headers.end(); ++I)
781 {
782 static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
783 const ELFSectionHeaderInfo &header = *I;
784 const uint64_t section_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
785 ConstString name(shstr_data.PeekCStr(I->sh_name));
786
787 I->section_name = name;
788
789 if (name == g_sect_name_gnu_debuglink)
790 {
791 DataExtractor data;
792 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
793 {
794 lldb::offset_t gnu_debuglink_offset = 0;
795 gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
796 gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
797 data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
798 }
799 }
800
801 if (header.sh_type == SHT_NOTE && !uuid.IsValid())
802 {
803 DataExtractor data;
804 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
805 {
806 ParseNoteGNUBuildID (data, uuid);
807 }
808 }
809 }
810
811 return section_headers.size();
812 }
813 }
814
815 section_headers.clear();
816 return 0;
817}
818
819//----------------------------------------------------------------------
820// ParseSectionHeaders
821//----------------------------------------------------------------------
822size_t
823ObjectFileELF::ParseSectionHeaders()
824{
825 return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
826}
827
828lldb::user_id_t
829ObjectFileELF::GetSectionIndexByName(const char *name)
830{
831 if (!ParseSectionHeaders())
832 return 0;
833
834 // Search the collection of section headers for one with a matching name.
835 for (SectionHeaderCollIter I = m_section_headers.begin();
836 I != m_section_headers.end(); ++I)
837 {
838 const char *sectionName = I->section_name.AsCString();
839
840 if (!sectionName)
841 return 0;
842
843 if (strcmp(name, sectionName) != 0)
844 continue;
845
846 return SectionIndex(I);
847 }
848
849 return 0;
850}
851
852const ObjectFileELF::ELFSectionHeaderInfo *
853ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
854{
855 if (!ParseSectionHeaders() || !id)
856 return NULL;
857
858 if (--id < m_section_headers.size())
859 return &m_section_headers[id];
860
861 return NULL;
862}
863
864
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865SectionList *
866ObjectFileELF::GetSectionList()
867{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000868 if (m_sections_ap.get())
869 return m_sections_ap.get();
870
Michael Sartaina7499c92013-07-01 19:45:50 +0000871 if (ParseSectionHeaders())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000872 {
873 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000875 for (SectionHeaderCollIter I = m_section_headers.begin();
876 I != m_section_headers.end(); ++I)
877 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000878 const ELFSectionHeaderInfo &header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000879
Michael Sartaina7499c92013-07-01 19:45:50 +0000880 ConstString& name = I->section_name;
Greg Clayton47037bc2012-03-27 02:40:46 +0000881 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
882 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000883
Greg Clayton4ceb9982010-07-21 22:54:26 +0000884 static ConstString g_sect_name_text (".text");
885 static ConstString g_sect_name_data (".data");
886 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +0000887 static ConstString g_sect_name_tdata (".tdata");
888 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +0000889 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
890 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
891 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
892 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
893 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
894 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
895 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
896 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
897 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
898 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
899 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
900 static ConstString g_sect_name_eh_frame (".eh_frame");
901
902 SectionType sect_type = eSectionTypeOther;
903
Greg Clayton741f3f92012-03-27 21:10:07 +0000904 bool is_thread_specific = false;
Michael Sartaina7499c92013-07-01 19:45:50 +0000905
Greg Clayton4ceb9982010-07-21 22:54:26 +0000906 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
907 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
908 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +0000909 else if (name == g_sect_name_tdata)
910 {
911 sect_type = eSectionTypeData;
912 is_thread_specific = true;
913 }
914 else if (name == g_sect_name_tbss)
915 {
916 sect_type = eSectionTypeZeroFill;
917 is_thread_specific = true;
918 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000919 // .debug_abbrev – Abbreviations used in the .debug_info section
920 // .debug_aranges – Lookup table for mapping addresses to compilation units
921 // .debug_frame – Call frame information
922 // .debug_info – The core DWARF information section
923 // .debug_line – Line number information
924 // .debug_loc – Location lists used in DW_AT_location attributes
925 // .debug_macinfo – Macro information
926 // .debug_pubnames – Lookup table for mapping object and function names to compilation units
927 // .debug_pubtypes – Lookup table for mapping type names to compilation units
928 // .debug_ranges – Address ranges used in DW_AT_ranges attributes
929 // .debug_str – String table used in .debug_info
930 // MISSING? .debug-index http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
931 // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
Greg Clayton4ceb9982010-07-21 22:54:26 +0000932 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
933 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
934 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
935 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
936 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
937 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
938 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
939 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
940 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
941 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
942 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
943 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
Michael Sartaina7499c92013-07-01 19:45:50 +0000944
945 switch (header.sh_type)
Michael Sartainc836ae72013-05-23 20:57:03 +0000946 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000947 case SHT_SYMTAB:
948 assert (sect_type == eSectionTypeOther);
949 sect_type = eSectionTypeELFSymbolTable;
950 break;
951 case SHT_DYNSYM:
952 assert (sect_type == eSectionTypeOther);
953 sect_type = eSectionTypeELFDynamicSymbols;
954 break;
955 case SHT_RELA:
956 case SHT_REL:
957 assert (sect_type == eSectionTypeOther);
958 sect_type = eSectionTypeELFRelocationEntries;
959 break;
960 case SHT_DYNAMIC:
961 assert (sect_type == eSectionTypeOther);
962 sect_type = eSectionTypeELFDynamicLinkInfo;
963 break;
Michael Sartainc836ae72013-05-23 20:57:03 +0000964 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000965
Greg Clayton741f3f92012-03-27 21:10:07 +0000966 SectionSP section_sp(new Section(
Greg Clayton4ceb9982010-07-21 22:54:26 +0000967 GetModule(), // Module to which this section belongs.
Michael Sartaina7499c92013-07-01 19:45:50 +0000968 this, // ObjectFile to which this section belongs and should read section data from.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000969 SectionIndex(I), // Section ID.
970 name, // Section name.
971 sect_type, // Section type.
972 header.sh_addr, // VM address.
Greg Clayton47037bc2012-03-27 02:40:46 +0000973 vm_size, // VM size in bytes of this section.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000974 header.sh_offset, // Offset of this section in the file.
Greg Clayton47037bc2012-03-27 02:40:46 +0000975 file_size, // Size of the section as found in the file.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000976 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000977
Greg Clayton741f3f92012-03-27 21:10:07 +0000978 if (is_thread_specific)
979 section_sp->SetIsThreadSpecific (is_thread_specific);
980 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000982
Sean Callanan56775362012-06-08 02:16:08 +0000983 m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000985
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000986 return m_sections_ap.get();
987}
988
Michael Sartaina7499c92013-07-01 19:45:50 +0000989unsigned
990ObjectFileELF::ParseSymbols(Symtab *symtab,
Stephen Wilson499b40e2011-03-30 16:07:05 +0000991 user_id_t start_id,
992 SectionList *section_list,
Michael Sartaina7499c92013-07-01 19:45:50 +0000993 const ELFSectionHeaderInfo *symtab_shdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000994 const DataExtractor &symtab_data,
995 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000997 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000998 lldb::offset_t offset = 0;
999 const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001000
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001 static ConstString text_section_name(".text");
1002 static ConstString init_section_name(".init");
1003 static ConstString fini_section_name(".fini");
1004 static ConstString ctors_section_name(".ctors");
1005 static ConstString dtors_section_name(".dtors");
1006
1007 static ConstString data_section_name(".data");
1008 static ConstString rodata_section_name(".rodata");
1009 static ConstString rodata1_section_name(".rodata1");
1010 static ConstString data2_section_name(".data1");
1011 static ConstString bss_section_name(".bss");
1012
Greg Clayton9594f4c2013-04-13 23:17:23 +00001013 //StreamFile strm(stdout, false);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001014 unsigned i;
1015 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001016 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001017 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018 break;
Greg Clayton9594f4c2013-04-13 23:17:23 +00001019
1020 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1021
1022 // No need to add symbols that have no names
1023 if (symbol_name == NULL || symbol_name[0] == '\0')
1024 continue;
1025
1026 //symbol.Dump (&strm, i, &strtab_data, section_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001027
Greg Claytone72dfb32012-02-24 01:59:29 +00001028 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001030 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001032 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 {
1034 case SHN_ABS:
1035 symbol_type = eSymbolTypeAbsolute;
1036 break;
1037 case SHN_UNDEF:
1038 symbol_type = eSymbolTypeUndefined;
1039 break;
1040 default:
Greg Claytone72dfb32012-02-24 01:59:29 +00001041 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 break;
1043 }
1044
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001045 // If a symbol is undefined do not process it further even if it has a STT type
1046 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001048 switch (symbol.getType())
1049 {
1050 default:
1051 case STT_NOTYPE:
1052 // The symbol's type is not specified.
1053 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001055 case STT_OBJECT:
1056 // The symbol is associated with a data object, such as a variable,
1057 // an array, etc.
1058 symbol_type = eSymbolTypeData;
1059 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001061 case STT_FUNC:
1062 // The symbol is associated with a function or other executable code.
1063 symbol_type = eSymbolTypeCode;
1064 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001066 case STT_SECTION:
1067 // The symbol is associated with a section. Symbol table entries of
1068 // this type exist primarily for relocation and normally have
1069 // STB_LOCAL binding.
1070 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001071
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001072 case STT_FILE:
1073 // Conventionally, the symbol's name gives the name of the source
1074 // file associated with the object file. A file symbol has STB_LOCAL
1075 // binding, its section index is SHN_ABS, and it precedes the other
1076 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001077 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001078 break;
Matt Kopec00049b82013-02-27 20:13:38 +00001079
1080 case STT_GNU_IFUNC:
1081 // The symbol is associated with an indirect function. The actual
1082 // function will be resolved if it is referenced.
1083 symbol_type = eSymbolTypeResolver;
1084 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001085 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001086 }
1087
1088 if (symbol_type == eSymbolTypeInvalid)
1089 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001090 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001091 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001092 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093 if (sect_name == text_section_name ||
1094 sect_name == init_section_name ||
1095 sect_name == fini_section_name ||
1096 sect_name == ctors_section_name ||
1097 sect_name == dtors_section_name)
1098 {
1099 symbol_type = eSymbolTypeCode;
1100 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001101 else if (sect_name == data_section_name ||
1102 sect_name == data2_section_name ||
1103 sect_name == rodata_section_name ||
1104 sect_name == rodata1_section_name ||
1105 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106 {
1107 symbol_type = eSymbolTypeData;
1108 }
1109 }
1110 }
1111
Michael Sartaina7499c92013-07-01 19:45:50 +00001112 // If the symbol section we've found has no data (SHT_NOBITS), then check the module
1113 // for the main object file and use the section there if it has data. This can happen
1114 // if we're parsing the debug file and the it has no .text section, for example.
1115 if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
1116 {
1117 ModuleSP module_sp(GetModule());
1118 if (module_sp)
1119 {
1120 ObjectFile *obj_file = module_sp->GetObjectFile();
1121 // Check if we've got a different object file than ourselves.
1122 if (obj_file && (obj_file != this))
1123 {
1124 const ConstString &sect_name = symbol_section_sp->GetName();
1125 SectionList *obj_file_section_list = obj_file->GetSectionList();
1126 lldb::SectionSP section_sp (obj_file_section_list->FindSectionByName (sect_name));
1127 if (section_sp && section_sp->GetFileSize())
1128 {
1129 symbol_section_sp = section_sp;
1130 }
1131 }
1132 }
1133 }
1134
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +00001136 if (symbol_section_sp)
1137 symbol_value -= symbol_section_sp->GetFileAddress();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001138 bool is_global = symbol.getBinding() == STB_GLOBAL;
1139 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +00001140 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001141 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +00001142 i + start_id, // ID is the original symbol table index.
1143 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001144 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +00001145 symbol_type, // Type of this symbol
1146 is_global, // Is this globally visible?
1147 false, // Is this symbol debug info?
1148 false, // Is this symbol a trampoline?
1149 false, // Is this symbol artificial?
1150 symbol_section_sp, // Section in which this symbol is defined or null.
1151 symbol_value, // Offset in section or symbol value.
1152 symbol.st_size, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001153 true, // Size is valid
Greg Claytone72dfb32012-02-24 01:59:29 +00001154 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001155 symtab->AddSymbol(dc_symbol);
1156 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001157
1158 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001159}
1160
Stephen Wilson499b40e2011-03-30 16:07:05 +00001161unsigned
Michael Sartaina7499c92013-07-01 19:45:50 +00001162ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, user_id_t symtab_id)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001163{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001164 // Parse in the section list if needed.
1165 SectionList *section_list = GetSectionList();
1166 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001167 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001168
Michael Sartaina7499c92013-07-01 19:45:50 +00001169 const ELFSectionHeaderInfo *symtab_hdr = &m_section_headers[symtab_id - 1];
1170 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
1171 symtab_hdr->sh_type == SHT_DYNSYM);
1172
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001173 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001174 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001175
1176 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1177 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001178 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001179 if (symtab && strtab)
1180 {
1181 DataExtractor symtab_data;
1182 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001183 if (ReadSectionData(symtab, symtab_data) &&
1184 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001185 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001186 num_symbols = ParseSymbols(symbol_table, start_id,
1187 section_list, symtab_hdr,
1188 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001189 }
1190 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001191
1192 return num_symbols;
1193}
1194
1195size_t
1196ObjectFileELF::ParseDynamicSymbols()
1197{
1198 if (m_dynamic_symbols.size())
1199 return m_dynamic_symbols.size();
1200
1201 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
1202 if (!dyn_id)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001203 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001204
1205 SectionList *section_list = GetSectionList();
1206 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001207 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001208
1209 Section *dynsym = section_list->FindSectionByID(dyn_id).get();
1210 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001211 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001212
1213 ELFDynamic symbol;
1214 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001215 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001216 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001217 const lldb::offset_t section_size = dynsym_data.GetByteSize();
1218 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001219
1220 while (cursor < section_size)
1221 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001222 if (!symbol.Parse(dynsym_data, &cursor))
1223 break;
1224
1225 m_dynamic_symbols.push_back(symbol);
1226 }
1227 }
1228
1229 return m_dynamic_symbols.size();
1230}
1231
1232const ELFDynamic *
1233ObjectFileELF::FindDynamicSymbol(unsigned tag)
1234{
1235 if (!ParseDynamicSymbols())
1236 return NULL;
1237
Stephen Wilson499b40e2011-03-30 16:07:05 +00001238 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
1239 DynamicSymbolCollIter E = m_dynamic_symbols.end();
1240 for ( ; I != E; ++I)
1241 {
1242 ELFDynamic *symbol = &*I;
1243
1244 if (symbol->d_tag == tag)
1245 return symbol;
1246 }
1247
1248 return NULL;
1249}
1250
Stephen Wilson499b40e2011-03-30 16:07:05 +00001251unsigned
1252ObjectFileELF::PLTRelocationType()
1253{
1254 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
1255
1256 if (symbol)
1257 return symbol->d_val;
1258
1259 return 0;
1260}
1261
1262static unsigned
1263ParsePLTRelocations(Symtab *symbol_table,
1264 user_id_t start_id,
1265 unsigned rel_type,
1266 const ELFHeader *hdr,
1267 const ELFSectionHeader *rel_hdr,
1268 const ELFSectionHeader *plt_hdr,
1269 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00001270 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001271 DataExtractor &rel_data,
1272 DataExtractor &symtab_data,
1273 DataExtractor &strtab_data)
1274{
1275 ELFRelocation rel(rel_type);
1276 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001277 lldb::offset_t offset = 0;
1278 const elf_xword plt_entsize = plt_hdr->sh_entsize;
1279 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001280
1281 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1282 reloc_info_fn reloc_type;
1283 reloc_info_fn reloc_symbol;
1284
Greg Claytond091afe2012-11-12 22:53:16 +00001285 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +00001286 {
1287 reloc_type = ELFRelocation::RelocType32;
1288 reloc_symbol = ELFRelocation::RelocSymbol32;
1289 }
1290 else
1291 {
1292 reloc_type = ELFRelocation::RelocType64;
1293 reloc_symbol = ELFRelocation::RelocSymbol64;
1294 }
1295
1296 unsigned slot_type = hdr->GetRelocationJumpSlotType();
1297 unsigned i;
1298 for (i = 0; i < num_relocations; ++i)
1299 {
1300 if (rel.Parse(rel_data, &offset) == false)
1301 break;
1302
1303 if (reloc_type(rel) != slot_type)
1304 continue;
1305
Greg Claytonc7bece562013-01-25 18:06:21 +00001306 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001307 uint64_t plt_index = (i + 1) * plt_entsize;
1308
1309 if (!symbol.Parse(symtab_data, &symbol_offset))
1310 break;
1311
1312 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001313 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001314
1315 Symbol jump_symbol(
1316 i + start_id, // Symbol table index
1317 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001318 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001319 eSymbolTypeTrampoline, // Type of this symbol
1320 false, // Is this globally visible?
1321 false, // Is this symbol debug info?
1322 true, // Is this symbol a trampoline?
1323 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001324 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001325 plt_index, // Offset in section or symbol value.
1326 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001327 true, // Size is valid
Stephen Wilson499b40e2011-03-30 16:07:05 +00001328 0); // Symbol flags.
1329
1330 symbol_table->AddSymbol(jump_symbol);
1331 }
1332
1333 return i;
1334}
1335
1336unsigned
1337ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1338 user_id_t start_id,
Michael Sartaina7499c92013-07-01 19:45:50 +00001339 const ELFSectionHeaderInfo *rel_hdr,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001340 user_id_t rel_id)
1341{
1342 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1343
Michael Sartaina7499c92013-07-01 19:45:50 +00001344 // The link field points to the associated symbol table. The info field
Stephen Wilson499b40e2011-03-30 16:07:05 +00001345 // points to the section holding the plt.
1346 user_id_t symtab_id = rel_hdr->sh_link;
1347 user_id_t plt_id = rel_hdr->sh_info;
1348
1349 if (!symtab_id || !plt_id)
1350 return 0;
1351
1352 // Section ID's are ones based;
1353 symtab_id++;
1354 plt_id++;
1355
Michael Sartaina7499c92013-07-01 19:45:50 +00001356 const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001357 if (!plt_hdr)
1358 return 0;
1359
Michael Sartaina7499c92013-07-01 19:45:50 +00001360 const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001361 if (!sym_hdr)
1362 return 0;
1363
1364 SectionList *section_list = GetSectionList();
1365 if (!section_list)
1366 return 0;
1367
1368 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1369 if (!rel_section)
1370 return 0;
1371
Greg Claytone72dfb32012-02-24 01:59:29 +00001372 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1373 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001374 return 0;
1375
1376 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1377 if (!symtab)
1378 return 0;
1379
1380 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1381 if (!strtab)
1382 return 0;
1383
1384 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001385 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001386 return 0;
1387
1388 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001389 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001390 return 0;
1391
1392 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001393 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001394 return 0;
1395
1396 unsigned rel_type = PLTRelocationType();
1397 if (!rel_type)
1398 return 0;
1399
Greg Claytone72dfb32012-02-24 01:59:29 +00001400 return ParsePLTRelocations (symbol_table,
1401 start_id,
1402 rel_type,
1403 &m_header,
1404 rel_hdr,
1405 plt_hdr,
1406 sym_hdr,
1407 plt_section_sp,
1408 rel_data,
1409 symtab_data,
1410 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001411}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001412
1413Symtab *
Michael Sartaina7499c92013-07-01 19:45:50 +00001414ObjectFileELF::GetSymtab(uint32_t flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001415{
Michael Sartaina7499c92013-07-01 19:45:50 +00001416 ModuleSP module_sp(GetModule());
1417 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001418 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001419 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1420
1421 bool from_unified_section_list = !!(flags & eSymtabFromUnifiedSectionList);
1422 SectionList *section_list = from_unified_section_list ? module_sp->GetUnifiedSectionList() : GetSectionList();
1423 if (!section_list)
1424 return NULL;
1425
1426 // If we're doing the unified section list and it has been modified, then clear our
1427 // cache and reload the symbols. If needed, we could check on only the sections that
1428 // we use to create the symbol table...
1429 std::unique_ptr<lldb_private::Symtab> &symtab_ap = from_unified_section_list ? m_symtab_unified_ap : m_symtab_ap;
1430 if (from_unified_section_list && (m_symtab_unified_revisionid != section_list->GetRevisionID()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001431 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001432 symtab_ap.reset();
1433 m_symtab_unified_revisionid = section_list->GetRevisionID();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001435 else if (symtab_ap.get())
1436 {
1437 return symtab_ap.get();
1438 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001439
Michael Sartaina7499c92013-07-01 19:45:50 +00001440 Symtab *symbol_table = new Symtab(this);
1441 symtab_ap.reset(symbol_table);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001442
Michael Sartaina7499c92013-07-01 19:45:50 +00001443 // Sharable objects and dynamic executables usually have 2 distinct symbol
1444 // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
1445 // version of the symtab that only contains global symbols. The information found
1446 // in the dynsym is therefore also found in the symtab, while the reverse is not
1447 // necessarily true.
1448 Section *section_sym = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
1449 if (!section_sym)
1450 {
1451 // The symtab section is non-allocable and can be stripped, so if it doesn't exist
1452 // then use the dynsym section which should always be there.
1453 section_sym = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
1454 }
1455
1456 uint64_t symbol_id = 0;
1457 if (section_sym)
1458 {
1459 user_id_t section_id = section_sym->GetID();
1460 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section_sym->GetObjectFile());
1461
1462 symbol_id += obj_file_elf->ParseSymbolTable (symbol_table, symbol_id, section_id);
1463 }
1464
1465 Section *section = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
1466 if (section)
1467 {
1468 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section->GetObjectFile());
1469
1470 // Synthesize trampoline symbols to help navigate the PLT.
1471 const ELFDynamic *symbol = obj_file_elf->FindDynamicSymbol(DT_JMPREL);
1472 if (symbol)
1473 {
1474 addr_t addr = symbol->d_ptr;
1475 Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
1476 if (reloc_section)
1477 {
1478 user_id_t reloc_id = reloc_section->GetID();
1479 const ELFSectionHeaderInfo *reloc_header = obj_file_elf->GetSectionHeaderByIndex(reloc_id);
1480 assert(reloc_header);
1481
1482 obj_file_elf->ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
1483 }
1484 }
1485 }
1486
1487 return symbol_table;
1488 }
1489 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001490}
1491
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001492//===----------------------------------------------------------------------===//
1493// Dump
1494//
1495// Dump the specifics of the runtime file container (such as any headers
1496// segments, sections, etc).
1497//----------------------------------------------------------------------
1498void
1499ObjectFileELF::Dump(Stream *s)
1500{
1501 DumpELFHeader(s, m_header);
1502 s->EOL();
1503 DumpELFProgramHeaders(s);
1504 s->EOL();
1505 DumpELFSectionHeaders(s);
1506 s->EOL();
1507 SectionList *section_list = GetSectionList();
1508 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001509 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001510 Symtab *symtab = GetSymtab();
1511 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001512 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001513 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001514 DumpDependentModules(s);
1515 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001516}
1517
1518//----------------------------------------------------------------------
1519// DumpELFHeader
1520//
1521// Dump the ELF header to the specified output stream
1522//----------------------------------------------------------------------
1523void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001524ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001525{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001526 s->PutCString("ELF Header\n");
1527 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1528 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1529 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1530 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1531 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1532 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1533 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001534
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001535 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1536 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001537 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1538 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1539 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1540
1541 s->Printf("e_type = 0x%4.4x ", header.e_type);
1542 DumpELFHeader_e_type(s, header.e_type);
1543 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1544 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001545 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1546 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1547 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001548 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1549 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1550 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1551 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1552 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1553 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1554 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1555}
1556
1557//----------------------------------------------------------------------
1558// DumpELFHeader_e_type
1559//
1560// Dump an token value for the ELF header member e_type
1561//----------------------------------------------------------------------
1562void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001563ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001564{
1565 switch (e_type)
1566 {
1567 case ET_NONE: *s << "ET_NONE"; break;
1568 case ET_REL: *s << "ET_REL"; break;
1569 case ET_EXEC: *s << "ET_EXEC"; break;
1570 case ET_DYN: *s << "ET_DYN"; break;
1571 case ET_CORE: *s << "ET_CORE"; break;
1572 default:
1573 break;
1574 }
1575}
1576
1577//----------------------------------------------------------------------
1578// DumpELFHeader_e_ident_EI_DATA
1579//
1580// Dump an token value for the ELF header member e_ident[EI_DATA]
1581//----------------------------------------------------------------------
1582void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001583ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001584{
1585 switch (ei_data)
1586 {
1587 case ELFDATANONE: *s << "ELFDATANONE"; break;
1588 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1589 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1590 default:
1591 break;
1592 }
1593}
1594
1595
1596//----------------------------------------------------------------------
1597// DumpELFProgramHeader
1598//
1599// Dump a single ELF program header to the specified output stream
1600//----------------------------------------------------------------------
1601void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001602ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001603{
1604 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001605 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1606 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 +00001607
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001609 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001610}
1611
1612//----------------------------------------------------------------------
1613// DumpELFProgramHeader_p_type
1614//
1615// Dump an token value for the ELF program header member p_type which
1616// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001617// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001618void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001619ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001620{
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001621 const int kStrWidth = 15;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001622 switch (p_type)
1623 {
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001624 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1625 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1626 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1627 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1628 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1629 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1630 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1631 CASE_AND_STREAM(s, PT_TLS , kStrWidth);
1632 CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001633 default:
1634 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1635 break;
1636 }
1637}
1638
1639
1640//----------------------------------------------------------------------
1641// DumpELFProgramHeader_p_flags
1642//
1643// Dump an token value for the ELF program header member p_flags
1644//----------------------------------------------------------------------
1645void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001646ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001647{
1648 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1649 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1650 << ((p_flags & PF_W) ? "PF_W" : " ")
1651 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1652 << ((p_flags & PF_R) ? "PF_R" : " ");
1653}
1654
1655//----------------------------------------------------------------------
1656// DumpELFProgramHeaders
1657//
1658// Dump all of the ELF program header to the specified output stream
1659//----------------------------------------------------------------------
1660void
1661ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1662{
1663 if (ParseProgramHeaders())
1664 {
1665 s->PutCString("Program Headers\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001666 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001667 "p_filesz p_memsz p_flags p_align\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001668 s->PutCString("==== --------------- -------- -------- -------- "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001669 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001670
1671 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001672 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1673 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001674 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001675 s->Printf("[%2u] ", idx);
1676 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001677 s->EOL();
1678 }
1679 }
1680}
1681
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001682//----------------------------------------------------------------------
1683// DumpELFSectionHeader
1684//
1685// Dump a single ELF section header to the specified output stream
1686//----------------------------------------------------------------------
1687void
Michael Sartaina7499c92013-07-01 19:45:50 +00001688ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001690 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001691 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001692 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001693 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001694 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 +00001695 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001696 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001697}
1698
1699//----------------------------------------------------------------------
1700// DumpELFSectionHeader_sh_type
1701//
1702// Dump an token value for the ELF section header member sh_type which
1703// describes the type of the section
1704//----------------------------------------------------------------------
1705void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001706ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001707{
1708 const int kStrWidth = 12;
1709 switch (sh_type)
1710 {
1711 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1712 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1713 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1714 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1715 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1716 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1717 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1718 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1719 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1720 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1721 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1722 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1723 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1724 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1725 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1726 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1727 default:
1728 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1729 break;
1730 }
1731}
1732
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001733//----------------------------------------------------------------------
1734// DumpELFSectionHeader_sh_flags
1735//
1736// Dump an token value for the ELF section header member sh_flags
1737//----------------------------------------------------------------------
1738void
Greg Claytonc7bece562013-01-25 18:06:21 +00001739ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001740{
1741 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1742 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1743 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1744 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1745 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1746}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001747
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001748//----------------------------------------------------------------------
1749// DumpELFSectionHeaders
1750//
1751// Dump all of the ELF section header to the specified output stream
1752//----------------------------------------------------------------------
1753void
1754ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1755{
Michael Sartaina7499c92013-07-01 19:45:50 +00001756 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001757 return;
1758
1759 s->PutCString("Section Headers\n");
1760 s->PutCString("IDX name type flags "
1761 "addr offset size link info addralgn "
1762 "entsize Name\n");
1763 s->PutCString("==== -------- ------------ -------------------------------- "
1764 "-------- -------- -------- -------- -------- -------- "
1765 "-------- ====================\n");
1766
1767 uint32_t idx = 0;
1768 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1769 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001770 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001771 s->Printf("[%2u] ", idx);
1772 ObjectFileELF::DumpELFSectionHeader(s, *I);
Michael Sartaina7499c92013-07-01 19:45:50 +00001773 const char* section_name = I->section_name.AsCString("");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001774 if (section_name)
1775 *s << ' ' << section_name << "\n";
1776 }
1777}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001778
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001779void
1780ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1781{
1782 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001783
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001784 if (num_modules > 0)
1785 {
1786 s->PutCString("Dependent Modules:\n");
1787 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001788 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001789 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1790 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001791 }
1792 }
1793}
1794
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001795bool
Greg Clayton514487e2011-02-15 21:59:32 +00001796ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001797{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001798 if (!ParseHeader())
1799 return false;
1800
Greg Claytone0d378b2011-03-24 21:19:54 +00001801 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001802 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1803 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001804 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001805}
1806
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001807ObjectFile::Type
1808ObjectFileELF::CalculateType()
1809{
1810 switch (m_header.e_type)
1811 {
1812 case llvm::ELF::ET_NONE:
1813 // 0 - No file type
1814 return eTypeUnknown;
1815
1816 case llvm::ELF::ET_REL:
1817 // 1 - Relocatable file
1818 return eTypeObjectFile;
1819
1820 case llvm::ELF::ET_EXEC:
1821 // 2 - Executable file
1822 return eTypeExecutable;
1823
1824 case llvm::ELF::ET_DYN:
1825 // 3 - Shared object file
1826 return eTypeSharedLibrary;
1827
1828 case ET_CORE:
1829 // 4 - Core file
1830 return eTypeCoreFile;
1831
1832 default:
1833 break;
1834 }
1835 return eTypeUnknown;
1836}
1837
1838ObjectFile::Strata
1839ObjectFileELF::CalculateStrata()
1840{
1841 switch (m_header.e_type)
1842 {
1843 case llvm::ELF::ET_NONE:
1844 // 0 - No file type
1845 return eStrataUnknown;
1846
1847 case llvm::ELF::ET_REL:
1848 // 1 - Relocatable file
1849 return eStrataUnknown;
1850
1851 case llvm::ELF::ET_EXEC:
1852 // 2 - Executable file
1853 // TODO: is there any way to detect that an executable is a kernel
1854 // related executable by inspecting the program headers, section
1855 // headers, symbols, or any other flag bits???
1856 return eStrataUser;
1857
1858 case llvm::ELF::ET_DYN:
1859 // 3 - Shared object file
1860 // TODO: is there any way to detect that an shared library is a kernel
1861 // related executable by inspecting the program headers, section
1862 // headers, symbols, or any other flag bits???
1863 return eStrataUnknown;
1864
1865 case ET_CORE:
1866 // 4 - Core file
1867 // TODO: is there any way to detect that an core file is a kernel
1868 // related executable by inspecting the program headers, section
1869 // headers, symbols, or any other flag bits???
1870 return eStrataUnknown;
1871
1872 default:
1873 break;
1874 }
1875 return eStrataUnknown;
1876}
1877