blob: 1045332f0feff1c665e8569454af33ea528debda [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
Michael Sartain9f4517a2013-07-03 01:52:14 +0000238/*
239 * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
240 *
241 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
242 * code or tables extracted from it, as desired without restriction.
243 */
244static uint32_t
245calc_gnu_debuglink_crc32(const void *buf, size_t size)
246{
247 static const uint32_t g_crc32_tab[] =
248 {
249 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
250 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
251 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
252 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
253 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
254 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
255 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
256 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
257 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
258 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
259 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
260 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
261 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
262 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
263 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
264 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
265 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
266 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
267 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
268 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
269 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
270 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
271 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
272 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
273 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
274 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
275 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
276 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
277 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
278 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
279 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
280 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
281 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
282 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
283 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
284 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
285 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
286 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
287 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
288 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
289 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
290 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
291 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
292 };
293 const uint8_t *p = (const uint8_t *)buf;
294 uint32_t crc;
295
296 crc = ~0U;
297 while (size--)
298 crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
299 return crc ^ ~0U;
300}
301
Greg Claytonf4d6de62013-04-24 22:29:28 +0000302size_t
303ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
304 lldb::DataBufferSP& data_sp,
305 lldb::offset_t data_offset,
306 lldb::offset_t file_offset,
307 lldb::offset_t length,
308 lldb_private::ModuleSpecList &specs)
309{
Michael Sartain9f0013d2013-05-17 00:20:21 +0000310 const size_t initial_count = specs.GetSize();
Michael Sartainc836ae72013-05-23 20:57:03 +0000311
Michael Sartain9f0013d2013-05-17 00:20:21 +0000312 if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
313 {
314 DataExtractor data;
315 data.SetData(data_sp);
316 elf::ELFHeader header;
317 if (header.Parse(data, &data_offset))
318 {
319 if (data_sp)
320 {
321 ModuleSpec spec;
322 spec.GetFileSpec() = file;
323 spec.GetArchitecture().SetArchitecture(eArchTypeELF,
324 header.e_machine,
325 LLDB_INVALID_CPUTYPE);
326 if (spec.GetArchitecture().IsValid())
327 {
Michael Sartainc836ae72013-05-23 20:57:03 +0000328 // We could parse the ABI tag information (in .note, .notes, or .note.ABI-tag) to get the
Michael Sartaina7499c92013-07-01 19:45:50 +0000329 // machine information. However, this info isn't guaranteed to exist or be correct. Details:
Michael Sartainc836ae72013-05-23 20:57:03 +0000330 // http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
331 // Instead of passing potentially incorrect information down the pipeline, grab
332 // the host information and use it.
333 spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString());
334 spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString());
Michael Sartaina7499c92013-07-01 19:45:50 +0000335
336 // Try to get the UUID from the section list. Usually that's at the end, so
337 // map the file in if we don't have it already.
338 size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
339 if (section_header_end > data_sp->GetByteSize())
340 {
341 data_sp = file.MemoryMapFileContents (file_offset, section_header_end);
342 data.SetData(data_sp);
343 }
344
Michael Sartain9f4517a2013-07-03 01:52:14 +0000345 uint32_t gnu_debuglink_crc = 0;
Michael Sartaina7499c92013-07-01 19:45:50 +0000346 std::string gnu_debuglink_file;
347 SectionHeaderColl section_headers;
Michael Sartain9f4517a2013-07-03 01:52:14 +0000348 lldb_private::UUID &uuid = spec.GetUUID();
349 GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc);
350
351 if (!uuid.IsValid())
352 {
353 if (!gnu_debuglink_crc)
354 {
355 // Need to map entire file into memory to calculate the crc.
356 data_sp = file.MemoryMapFileContents (file_offset, SIZE_MAX);
357 data.SetData(data_sp);
358 gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
359 }
360 if (gnu_debuglink_crc)
361 {
362 // Use 4 bytes of crc from the .gnu_debuglink section.
363 uint32_t uuidt[4] = { gnu_debuglink_crc, 0, 0, 0 };
364 uuid.SetBytes (uuidt, sizeof(uuidt));
365 }
366 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000367
Michael Sartain9f0013d2013-05-17 00:20:21 +0000368 specs.Append(spec);
369 }
370 }
371 }
372 }
Michael Sartainc836ae72013-05-23 20:57:03 +0000373
Michael Sartain9f0013d2013-05-17 00:20:21 +0000374 return specs.GetSize() - initial_count;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000375}
376
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000377//------------------------------------------------------------------
378// PluginInterface protocol
379//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +0000380lldb_private::ConstString
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000381ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000383 return GetPluginNameStatic();
384}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000386uint32_t
387ObjectFileELF::GetPluginVersion()
388{
389 return m_plugin_version;
390}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000391//------------------------------------------------------------------
392// ObjectFile protocol
393//------------------------------------------------------------------
394
Greg Claytone72dfb32012-02-24 01:59:29 +0000395ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000396 DataBufferSP& data_sp,
397 lldb::offset_t data_offset,
Greg Claytone72dfb32012-02-24 01:59:29 +0000398 const FileSpec* file,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000399 lldb::offset_t file_offset,
400 lldb::offset_t length) :
401 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytone72dfb32012-02-24 01:59:29 +0000402 m_header(),
403 m_program_headers(),
404 m_section_headers(),
Michael Sartaina7499c92013-07-01 19:45:50 +0000405 m_filespec_ap()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406{
407 if (file)
408 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000409 ::memset(&m_header, 0, sizeof(m_header));
Michael Sartaina7499c92013-07-01 19:45:50 +0000410 m_gnu_debuglink_crc = 0;
411 m_gnu_debuglink_file.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412}
413
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414ObjectFileELF::~ObjectFileELF()
415{
416}
417
Jim Ingham5aee1622010-08-09 23:31:02 +0000418bool
419ObjectFileELF::IsExecutable() const
420{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000421 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000422}
423
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000425ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426{
427 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
428 return eByteOrderBig;
429 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
430 return eByteOrderLittle;
431 return eByteOrderInvalid;
432}
433
Greg Claytonc7bece562013-01-25 18:06:21 +0000434uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000435ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436{
437 return m_data.GetAddressByteSize();
438}
439
Greg Claytonc7bece562013-01-25 18:06:21 +0000440size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000441ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442{
Greg Claytonc7bece562013-01-25 18:06:21 +0000443 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000444}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445
Greg Claytonc7bece562013-01-25 18:06:21 +0000446size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000447ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
448{
Greg Claytonc7bece562013-01-25 18:06:21 +0000449 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450}
451
452bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000453ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454{
Filipe Cabecinhas22b40f72013-05-16 23:29:36 +0000455 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000456 return m_header.Parse(m_data, &offset);
457}
458
459bool
Greg Clayton60830262011-02-04 18:53:10 +0000460ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000461{
Michael Sartaina7499c92013-07-01 19:45:50 +0000462 // Need to parse the section list to get the UUIDs, so make sure that's been done.
463 if (!ParseSectionHeaders())
464 return false;
465
Michael Sartainc836ae72013-05-23 20:57:03 +0000466 if (m_uuid.IsValid())
467 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000468 // We have the full build id uuid.
Michael Sartainc836ae72013-05-23 20:57:03 +0000469 *uuid = m_uuid;
470 return true;
471 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000472 else
473 {
Michael Sartain9f4517a2013-07-03 01:52:14 +0000474 if (!m_gnu_debuglink_crc)
475 m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
Michael Sartaina7499c92013-07-01 19:45:50 +0000476 if (m_gnu_debuglink_crc)
477 {
478 // Use 4 bytes of crc from the .gnu_debuglink section.
479 uint32_t uuidt[4] = { m_gnu_debuglink_crc, 0, 0, 0 };
480 uuid->SetBytes (uuidt, sizeof(uuidt));
481 return true;
482 }
483 }
484
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485 return false;
486}
487
Michael Sartaina7499c92013-07-01 19:45:50 +0000488lldb_private::FileSpecList
489ObjectFileELF::GetDebugSymbolFilePaths()
490{
491 FileSpecList file_spec_list;
492
493 if (!m_gnu_debuglink_file.empty())
494 {
495 FileSpec file_spec (m_gnu_debuglink_file.c_str(), false);
496 file_spec_list.Append (file_spec);
497 }
498 return file_spec_list;
499}
500
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000502ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000503{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000504 size_t num_modules = ParseDependentModules();
505 uint32_t num_specs = 0;
506
507 for (unsigned i = 0; i < num_modules; ++i)
508 {
509 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
510 num_specs++;
511 }
512
513 return num_specs;
514}
515
Stephen Wilson499b40e2011-03-30 16:07:05 +0000516user_id_t
517ObjectFileELF::GetSectionIndexByType(unsigned type)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000518{
519 if (!ParseSectionHeaders())
Stephen Wilson499b40e2011-03-30 16:07:05 +0000520 return 0;
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000521
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000522 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
523 sh_pos != m_section_headers.end(); ++sh_pos)
524 {
Stephen Wilson499b40e2011-03-30 16:07:05 +0000525 if (sh_pos->sh_type == type)
526 return SectionIndex(sh_pos);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000527 }
528
Stephen Wilson499b40e2011-03-30 16:07:05 +0000529 return 0;
530}
531
532Address
533ObjectFileELF::GetImageInfoAddress()
534{
535 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000536 return Address();
537
538 SectionList *section_list = GetSectionList();
539 if (!section_list)
540 return Address();
541
Stephen Wilson499b40e2011-03-30 16:07:05 +0000542 user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
543 if (!dynsym_id)
544 return Address();
545
Michael Sartaina7499c92013-07-01 19:45:50 +0000546 const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000547 if (!dynsym_hdr)
548 return Address();
549
Greg Claytone72dfb32012-02-24 01:59:29 +0000550 SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
551 if (dynsym_section_sp)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000552 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000553 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000554 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000555 ELFDynamic &symbol = m_dynamic_symbols[i];
556
557 if (symbol.d_tag == DT_DEBUG)
558 {
559 // Compute the offset as the number of previous entries plus the
560 // size of d_tag.
561 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
562 return Address(dynsym_section_sp, offset);
563 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000564 }
565 }
566
567 return Address();
568}
569
Jim Ingham672e6f52011-03-07 23:44:08 +0000570lldb_private::Address
571ObjectFileELF::GetEntryPointAddress ()
572{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000573 SectionList *sections;
574 addr_t offset;
Jim Ingham672e6f52011-03-07 23:44:08 +0000575
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000576 if (m_entry_point_address.IsValid())
577 return m_entry_point_address;
578
579 if (!ParseHeader() || !IsExecutable())
580 return m_entry_point_address;
581
582 sections = GetSectionList();
583 offset = m_header.e_entry;
584
585 if (!sections)
586 {
587 m_entry_point_address.SetOffset(offset);
588 return m_entry_point_address;
589 }
590
591 m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
592
593 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000594}
595
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000596//----------------------------------------------------------------------
597// ParseDependentModules
598//----------------------------------------------------------------------
599size_t
600ObjectFileELF::ParseDependentModules()
601{
602 if (m_filespec_ap.get())
603 return m_filespec_ap->GetSize();
604
605 m_filespec_ap.reset(new FileSpecList());
606
Michael Sartaina7499c92013-07-01 19:45:50 +0000607 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000608 return 0;
609
610 // Locate the dynamic table.
611 user_id_t dynsym_id = 0;
612 user_id_t dynstr_id = 0;
Greg Clayton450e3f32010-10-12 02:24:53 +0000613 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
614 sh_pos != m_section_headers.end(); ++sh_pos)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000615 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000616 if (sh_pos->sh_type == SHT_DYNAMIC)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000617 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000618 dynsym_id = SectionIndex(sh_pos);
619 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000620 break;
621 }
622 }
623
624 if (!(dynsym_id && dynstr_id))
625 return 0;
626
627 SectionList *section_list = GetSectionList();
628 if (!section_list)
629 return 0;
630
631 // Resolve and load the dynamic table entries and corresponding string
632 // table.
633 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
634 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
635 if (!(dynsym && dynstr))
636 return 0;
637
638 DataExtractor dynsym_data;
639 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000640 if (ReadSectionData(dynsym, dynsym_data) &&
641 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000642 {
643 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000644 const lldb::offset_t section_size = dynsym_data.GetByteSize();
645 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000646
647 // The only type of entries we are concerned with are tagged DT_NEEDED,
648 // yielding the name of a required library.
649 while (offset < section_size)
650 {
651 if (!symbol.Parse(dynsym_data, &offset))
652 break;
653
654 if (symbol.d_tag != DT_NEEDED)
655 continue;
656
657 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
658 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000659 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000660 }
661 }
662
663 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664}
665
666//----------------------------------------------------------------------
667// ParseProgramHeaders
668//----------------------------------------------------------------------
669size_t
670ObjectFileELF::ParseProgramHeaders()
671{
672 // We have already parsed the program headers
673 if (!m_program_headers.empty())
674 return m_program_headers.size();
675
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000676 // If there are no program headers to read we are done.
677 if (m_header.e_phnum == 0)
678 return 0;
679
680 m_program_headers.resize(m_header.e_phnum);
681 if (m_program_headers.size() != m_header.e_phnum)
682 return 0;
683
684 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000685 const elf_off ph_offset = m_header.e_phoff;
686 DataExtractor data;
687 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000688 return 0;
689
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000690 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000691 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000692 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000693 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000694 if (m_program_headers[idx].Parse(data, &offset) == false)
695 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 }
697
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000698 if (idx < m_program_headers.size())
699 m_program_headers.resize(idx);
700
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701 return m_program_headers.size();
702}
703
Michael Sartainc836ae72013-05-23 20:57:03 +0000704static bool
Michael Sartaina7499c92013-07-01 19:45:50 +0000705ParseNoteGNUBuildID(DataExtractor &data, lldb_private::UUID &uuid)
Michael Sartainc836ae72013-05-23 20:57:03 +0000706{
707 // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
708 // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
709 struct
710 {
711 uint32_t name_len; // Length of note name
712 uint32_t desc_len; // Length of note descriptor
713 uint32_t type; // Type of note (1 is ABI_TAG, 3 is BUILD_ID)
714 } notehdr;
715 lldb::offset_t offset = 0;
716 static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
717
718 while (true)
719 {
720 if (data.GetU32 (&offset, &notehdr, 3) == NULL)
721 return false;
722
723 notehdr.name_len = llvm::RoundUpToAlignment (notehdr.name_len, 4);
724 notehdr.desc_len = llvm::RoundUpToAlignment (notehdr.desc_len, 4);
725
726 lldb::offset_t offset_next_note = offset + notehdr.name_len + notehdr.desc_len;
727
728 // 16 bytes is UUID|MD5, 20 bytes is SHA1
729 if ((notehdr.type == g_gnu_build_id) && (notehdr.name_len == 4) &&
730 (notehdr.desc_len == 16 || notehdr.desc_len == 20))
731 {
732 char name[4];
733 if (data.GetU8 (&offset, name, 4) == NULL)
734 return false;
735 if (!strcmp(name, "GNU"))
736 {
737 uint8_t uuidbuf[20];
738 if (data.GetU8 (&offset, &uuidbuf, notehdr.desc_len) == NULL)
739 return false;
740 uuid.SetBytes (uuidbuf, notehdr.desc_len);
741 return true;
742 }
743 }
744 offset = offset_next_note;
745 }
746 return false;
747}
Michael Sartaina7499c92013-07-01 19:45:50 +0000748
749//----------------------------------------------------------------------
750// GetSectionHeaderInfo
751//----------------------------------------------------------------------
752size_t
753ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
754 lldb_private::DataExtractor &object_data,
755 const elf::ELFHeader &header,
756 lldb_private::UUID &uuid,
757 std::string &gnu_debuglink_file,
758 uint32_t &gnu_debuglink_crc)
759{
760 // We have already parsed the section headers
761 if (!section_headers.empty())
762 return section_headers.size();
763
764 // If there are no section headers we are done.
765 if (header.e_shnum == 0)
766 return 0;
767
768 section_headers.resize(header.e_shnum);
769 if (section_headers.size() != header.e_shnum)
770 return 0;
771
772 const size_t sh_size = header.e_shnum * header.e_shentsize;
773 const elf_off sh_offset = header.e_shoff;
774 DataExtractor sh_data;
775 if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
776 return 0;
777
778 uint32_t idx;
779 lldb::offset_t offset;
780 for (idx = 0, offset = 0; idx < header.e_shnum; ++idx)
781 {
782 if (section_headers[idx].Parse(sh_data, &offset) == false)
783 break;
784 }
785 if (idx < section_headers.size())
786 section_headers.resize(idx);
787
788 const unsigned strtab_idx = header.e_shstrndx;
789 if (strtab_idx && strtab_idx < section_headers.size())
790 {
791 const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
792 const size_t byte_size = sheader.sh_size;
793 const Elf64_Off offset = sheader.sh_offset;
794 lldb_private::DataExtractor shstr_data;
795
796 if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
797 {
798 for (SectionHeaderCollIter I = section_headers.begin();
799 I != section_headers.end(); ++I)
800 {
801 static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
802 const ELFSectionHeaderInfo &header = *I;
803 const uint64_t section_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
804 ConstString name(shstr_data.PeekCStr(I->sh_name));
805
806 I->section_name = name;
807
808 if (name == g_sect_name_gnu_debuglink)
809 {
810 DataExtractor data;
811 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
812 {
813 lldb::offset_t gnu_debuglink_offset = 0;
814 gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
815 gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
816 data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
817 }
818 }
819
820 if (header.sh_type == SHT_NOTE && !uuid.IsValid())
821 {
822 DataExtractor data;
823 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
824 {
825 ParseNoteGNUBuildID (data, uuid);
826 }
827 }
828 }
829
830 return section_headers.size();
831 }
832 }
833
834 section_headers.clear();
835 return 0;
836}
837
838//----------------------------------------------------------------------
839// ParseSectionHeaders
840//----------------------------------------------------------------------
841size_t
842ObjectFileELF::ParseSectionHeaders()
843{
844 return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
845}
846
847lldb::user_id_t
848ObjectFileELF::GetSectionIndexByName(const char *name)
849{
850 if (!ParseSectionHeaders())
851 return 0;
852
853 // Search the collection of section headers for one with a matching name.
854 for (SectionHeaderCollIter I = m_section_headers.begin();
855 I != m_section_headers.end(); ++I)
856 {
857 const char *sectionName = I->section_name.AsCString();
858
859 if (!sectionName)
860 return 0;
861
862 if (strcmp(name, sectionName) != 0)
863 continue;
864
865 return SectionIndex(I);
866 }
867
868 return 0;
869}
870
871const ObjectFileELF::ELFSectionHeaderInfo *
872ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
873{
874 if (!ParseSectionHeaders() || !id)
875 return NULL;
876
877 if (--id < m_section_headers.size())
878 return &m_section_headers[id];
879
880 return NULL;
881}
882
883
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000884SectionList *
885ObjectFileELF::GetSectionList()
886{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000887 if (m_sections_ap.get())
888 return m_sections_ap.get();
889
Michael Sartaina7499c92013-07-01 19:45:50 +0000890 if (ParseSectionHeaders())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000891 {
892 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000893
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000894 for (SectionHeaderCollIter I = m_section_headers.begin();
895 I != m_section_headers.end(); ++I)
896 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000897 const ELFSectionHeaderInfo &header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000898
Michael Sartaina7499c92013-07-01 19:45:50 +0000899 ConstString& name = I->section_name;
Greg Clayton47037bc2012-03-27 02:40:46 +0000900 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
901 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000902
Greg Clayton4ceb9982010-07-21 22:54:26 +0000903 static ConstString g_sect_name_text (".text");
904 static ConstString g_sect_name_data (".data");
905 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +0000906 static ConstString g_sect_name_tdata (".tdata");
907 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +0000908 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
909 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
910 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
911 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
912 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
913 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
914 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
915 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
916 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
917 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
918 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
919 static ConstString g_sect_name_eh_frame (".eh_frame");
920
921 SectionType sect_type = eSectionTypeOther;
922
Greg Clayton741f3f92012-03-27 21:10:07 +0000923 bool is_thread_specific = false;
Michael Sartaina7499c92013-07-01 19:45:50 +0000924
Greg Clayton4ceb9982010-07-21 22:54:26 +0000925 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
926 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
927 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +0000928 else if (name == g_sect_name_tdata)
929 {
930 sect_type = eSectionTypeData;
931 is_thread_specific = true;
932 }
933 else if (name == g_sect_name_tbss)
934 {
935 sect_type = eSectionTypeZeroFill;
936 is_thread_specific = true;
937 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000938 // .debug_abbrev – Abbreviations used in the .debug_info section
939 // .debug_aranges – Lookup table for mapping addresses to compilation units
940 // .debug_frame – Call frame information
941 // .debug_info – The core DWARF information section
942 // .debug_line – Line number information
943 // .debug_loc – Location lists used in DW_AT_location attributes
944 // .debug_macinfo – Macro information
945 // .debug_pubnames – Lookup table for mapping object and function names to compilation units
946 // .debug_pubtypes – Lookup table for mapping type names to compilation units
947 // .debug_ranges – Address ranges used in DW_AT_ranges attributes
948 // .debug_str – String table used in .debug_info
949 // MISSING? .debug-index http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
950 // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
Greg Clayton4ceb9982010-07-21 22:54:26 +0000951 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
952 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
953 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
954 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
955 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
956 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
957 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
958 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
959 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
960 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
961 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
962 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
Michael Sartaina7499c92013-07-01 19:45:50 +0000963
964 switch (header.sh_type)
Michael Sartainc836ae72013-05-23 20:57:03 +0000965 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000966 case SHT_SYMTAB:
967 assert (sect_type == eSectionTypeOther);
968 sect_type = eSectionTypeELFSymbolTable;
969 break;
970 case SHT_DYNSYM:
971 assert (sect_type == eSectionTypeOther);
972 sect_type = eSectionTypeELFDynamicSymbols;
973 break;
974 case SHT_RELA:
975 case SHT_REL:
976 assert (sect_type == eSectionTypeOther);
977 sect_type = eSectionTypeELFRelocationEntries;
978 break;
979 case SHT_DYNAMIC:
980 assert (sect_type == eSectionTypeOther);
981 sect_type = eSectionTypeELFDynamicLinkInfo;
982 break;
Michael Sartainc836ae72013-05-23 20:57:03 +0000983 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000984
Greg Clayton741f3f92012-03-27 21:10:07 +0000985 SectionSP section_sp(new Section(
Greg Clayton4ceb9982010-07-21 22:54:26 +0000986 GetModule(), // Module to which this section belongs.
Michael Sartaina7499c92013-07-01 19:45:50 +0000987 this, // ObjectFile to which this section belongs and should read section data from.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000988 SectionIndex(I), // Section ID.
989 name, // Section name.
990 sect_type, // Section type.
991 header.sh_addr, // VM address.
Greg Clayton47037bc2012-03-27 02:40:46 +0000992 vm_size, // VM size in bytes of this section.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000993 header.sh_offset, // Offset of this section in the file.
Greg Clayton47037bc2012-03-27 02:40:46 +0000994 file_size, // Size of the section as found in the file.
Greg Clayton4ceb9982010-07-21 22:54:26 +0000995 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000996
Greg Clayton741f3f92012-03-27 21:10:07 +0000997 if (is_thread_specific)
998 section_sp->SetIsThreadSpecific (is_thread_specific);
999 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001000 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001001
Sean Callanan56775362012-06-08 02:16:08 +00001002 m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001003 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001004
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001005 return m_sections_ap.get();
1006}
1007
Michael Sartaina7499c92013-07-01 19:45:50 +00001008unsigned
1009ObjectFileELF::ParseSymbols(Symtab *symtab,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001010 user_id_t start_id,
1011 SectionList *section_list,
Michael Sartaina7499c92013-07-01 19:45:50 +00001012 const ELFSectionHeaderInfo *symtab_shdr,
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001013 const DataExtractor &symtab_data,
1014 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001016 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001017 lldb::offset_t offset = 0;
1018 const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001019
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001020 static ConstString text_section_name(".text");
1021 static ConstString init_section_name(".init");
1022 static ConstString fini_section_name(".fini");
1023 static ConstString ctors_section_name(".ctors");
1024 static ConstString dtors_section_name(".dtors");
1025
1026 static ConstString data_section_name(".data");
1027 static ConstString rodata_section_name(".rodata");
1028 static ConstString rodata1_section_name(".rodata1");
1029 static ConstString data2_section_name(".data1");
1030 static ConstString bss_section_name(".bss");
1031
Greg Clayton9594f4c2013-04-13 23:17:23 +00001032 //StreamFile strm(stdout, false);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001033 unsigned i;
1034 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001036 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037 break;
Greg Clayton9594f4c2013-04-13 23:17:23 +00001038
1039 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1040
1041 // No need to add symbols that have no names
1042 if (symbol_name == NULL || symbol_name[0] == '\0')
1043 continue;
1044
1045 //symbol.Dump (&strm, i, &strtab_data, section_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046
Greg Claytone72dfb32012-02-24 01:59:29 +00001047 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001049 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001051 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 {
1053 case SHN_ABS:
1054 symbol_type = eSymbolTypeAbsolute;
1055 break;
1056 case SHN_UNDEF:
1057 symbol_type = eSymbolTypeUndefined;
1058 break;
1059 default:
Greg Claytone72dfb32012-02-24 01:59:29 +00001060 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061 break;
1062 }
1063
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001064 // If a symbol is undefined do not process it further even if it has a STT type
1065 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001067 switch (symbol.getType())
1068 {
1069 default:
1070 case STT_NOTYPE:
1071 // The symbol's type is not specified.
1072 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001074 case STT_OBJECT:
1075 // The symbol is associated with a data object, such as a variable,
1076 // an array, etc.
1077 symbol_type = eSymbolTypeData;
1078 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001080 case STT_FUNC:
1081 // The symbol is associated with a function or other executable code.
1082 symbol_type = eSymbolTypeCode;
1083 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001084
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001085 case STT_SECTION:
1086 // The symbol is associated with a section. Symbol table entries of
1087 // this type exist primarily for relocation and normally have
1088 // STB_LOCAL binding.
1089 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001091 case STT_FILE:
1092 // Conventionally, the symbol's name gives the name of the source
1093 // file associated with the object file. A file symbol has STB_LOCAL
1094 // binding, its section index is SHN_ABS, and it precedes the other
1095 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001096 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001097 break;
Matt Kopec00049b82013-02-27 20:13:38 +00001098
1099 case STT_GNU_IFUNC:
1100 // The symbol is associated with an indirect function. The actual
1101 // function will be resolved if it is referenced.
1102 symbol_type = eSymbolTypeResolver;
1103 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001104 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001105 }
1106
1107 if (symbol_type == eSymbolTypeInvalid)
1108 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001109 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001111 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001112 if (sect_name == text_section_name ||
1113 sect_name == init_section_name ||
1114 sect_name == fini_section_name ||
1115 sect_name == ctors_section_name ||
1116 sect_name == dtors_section_name)
1117 {
1118 symbol_type = eSymbolTypeCode;
1119 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001120 else if (sect_name == data_section_name ||
1121 sect_name == data2_section_name ||
1122 sect_name == rodata_section_name ||
1123 sect_name == rodata1_section_name ||
1124 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125 {
1126 symbol_type = eSymbolTypeData;
1127 }
1128 }
1129 }
1130
Michael Sartaina7499c92013-07-01 19:45:50 +00001131 // If the symbol section we've found has no data (SHT_NOBITS), then check the module
1132 // for the main object file and use the section there if it has data. This can happen
1133 // if we're parsing the debug file and the it has no .text section, for example.
1134 if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
1135 {
1136 ModuleSP module_sp(GetModule());
1137 if (module_sp)
1138 {
1139 ObjectFile *obj_file = module_sp->GetObjectFile();
1140 // Check if we've got a different object file than ourselves.
1141 if (obj_file && (obj_file != this))
1142 {
1143 const ConstString &sect_name = symbol_section_sp->GetName();
1144 SectionList *obj_file_section_list = obj_file->GetSectionList();
1145 lldb::SectionSP section_sp (obj_file_section_list->FindSectionByName (sect_name));
1146 if (section_sp && section_sp->GetFileSize())
1147 {
1148 symbol_section_sp = section_sp;
1149 }
1150 }
1151 }
1152 }
1153
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +00001155 if (symbol_section_sp)
1156 symbol_value -= symbol_section_sp->GetFileAddress();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001157 bool is_global = symbol.getBinding() == STB_GLOBAL;
1158 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +00001159 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001160 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +00001161 i + start_id, // ID is the original symbol table index.
1162 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001163 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +00001164 symbol_type, // Type of this symbol
1165 is_global, // Is this globally visible?
1166 false, // Is this symbol debug info?
1167 false, // Is this symbol a trampoline?
1168 false, // Is this symbol artificial?
1169 symbol_section_sp, // Section in which this symbol is defined or null.
1170 symbol_value, // Offset in section or symbol value.
1171 symbol.st_size, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001172 true, // Size is valid
Greg Claytone72dfb32012-02-24 01:59:29 +00001173 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 symtab->AddSymbol(dc_symbol);
1175 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001176
1177 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001178}
1179
Stephen Wilson499b40e2011-03-30 16:07:05 +00001180unsigned
Michael Sartaina7499c92013-07-01 19:45:50 +00001181ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, user_id_t symtab_id)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001182{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001183 // Parse in the section list if needed.
1184 SectionList *section_list = GetSectionList();
1185 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001186 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001187
Michael Sartaina7499c92013-07-01 19:45:50 +00001188 const ELFSectionHeaderInfo *symtab_hdr = &m_section_headers[symtab_id - 1];
1189 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
1190 symtab_hdr->sh_type == SHT_DYNSYM);
1191
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001192 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001193 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001194
1195 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1196 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001197 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001198 if (symtab && strtab)
1199 {
1200 DataExtractor symtab_data;
1201 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001202 if (ReadSectionData(symtab, symtab_data) &&
1203 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001204 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001205 num_symbols = ParseSymbols(symbol_table, start_id,
1206 section_list, symtab_hdr,
1207 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001208 }
1209 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001210
1211 return num_symbols;
1212}
1213
1214size_t
1215ObjectFileELF::ParseDynamicSymbols()
1216{
1217 if (m_dynamic_symbols.size())
1218 return m_dynamic_symbols.size();
1219
1220 user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
1221 if (!dyn_id)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001222 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001223
1224 SectionList *section_list = GetSectionList();
1225 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001226 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001227
1228 Section *dynsym = section_list->FindSectionByID(dyn_id).get();
1229 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001230 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001231
1232 ELFDynamic symbol;
1233 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001234 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001235 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001236 const lldb::offset_t section_size = dynsym_data.GetByteSize();
1237 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001238
1239 while (cursor < section_size)
1240 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001241 if (!symbol.Parse(dynsym_data, &cursor))
1242 break;
1243
1244 m_dynamic_symbols.push_back(symbol);
1245 }
1246 }
1247
1248 return m_dynamic_symbols.size();
1249}
1250
1251const ELFDynamic *
1252ObjectFileELF::FindDynamicSymbol(unsigned tag)
1253{
1254 if (!ParseDynamicSymbols())
1255 return NULL;
1256
Stephen Wilson499b40e2011-03-30 16:07:05 +00001257 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
1258 DynamicSymbolCollIter E = m_dynamic_symbols.end();
1259 for ( ; I != E; ++I)
1260 {
1261 ELFDynamic *symbol = &*I;
1262
1263 if (symbol->d_tag == tag)
1264 return symbol;
1265 }
1266
1267 return NULL;
1268}
1269
Stephen Wilson499b40e2011-03-30 16:07:05 +00001270unsigned
1271ObjectFileELF::PLTRelocationType()
1272{
1273 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
1274
1275 if (symbol)
1276 return symbol->d_val;
1277
1278 return 0;
1279}
1280
1281static unsigned
1282ParsePLTRelocations(Symtab *symbol_table,
1283 user_id_t start_id,
1284 unsigned rel_type,
1285 const ELFHeader *hdr,
1286 const ELFSectionHeader *rel_hdr,
1287 const ELFSectionHeader *plt_hdr,
1288 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00001289 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001290 DataExtractor &rel_data,
1291 DataExtractor &symtab_data,
1292 DataExtractor &strtab_data)
1293{
1294 ELFRelocation rel(rel_type);
1295 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001296 lldb::offset_t offset = 0;
1297 const elf_xword plt_entsize = plt_hdr->sh_entsize;
1298 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001299
1300 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1301 reloc_info_fn reloc_type;
1302 reloc_info_fn reloc_symbol;
1303
Greg Claytond091afe2012-11-12 22:53:16 +00001304 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +00001305 {
1306 reloc_type = ELFRelocation::RelocType32;
1307 reloc_symbol = ELFRelocation::RelocSymbol32;
1308 }
1309 else
1310 {
1311 reloc_type = ELFRelocation::RelocType64;
1312 reloc_symbol = ELFRelocation::RelocSymbol64;
1313 }
1314
1315 unsigned slot_type = hdr->GetRelocationJumpSlotType();
1316 unsigned i;
1317 for (i = 0; i < num_relocations; ++i)
1318 {
1319 if (rel.Parse(rel_data, &offset) == false)
1320 break;
1321
1322 if (reloc_type(rel) != slot_type)
1323 continue;
1324
Greg Claytonc7bece562013-01-25 18:06:21 +00001325 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001326 uint64_t plt_index = (i + 1) * plt_entsize;
1327
1328 if (!symbol.Parse(symtab_data, &symbol_offset))
1329 break;
1330
1331 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001332 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001333
1334 Symbol jump_symbol(
1335 i + start_id, // Symbol table index
1336 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001337 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001338 eSymbolTypeTrampoline, // Type of this symbol
1339 false, // Is this globally visible?
1340 false, // Is this symbol debug info?
1341 true, // Is this symbol a trampoline?
1342 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001343 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001344 plt_index, // Offset in section or symbol value.
1345 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001346 true, // Size is valid
Stephen Wilson499b40e2011-03-30 16:07:05 +00001347 0); // Symbol flags.
1348
1349 symbol_table->AddSymbol(jump_symbol);
1350 }
1351
1352 return i;
1353}
1354
1355unsigned
1356ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1357 user_id_t start_id,
Michael Sartaina7499c92013-07-01 19:45:50 +00001358 const ELFSectionHeaderInfo *rel_hdr,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001359 user_id_t rel_id)
1360{
1361 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1362
Michael Sartaina7499c92013-07-01 19:45:50 +00001363 // The link field points to the associated symbol table. The info field
Stephen Wilson499b40e2011-03-30 16:07:05 +00001364 // points to the section holding the plt.
1365 user_id_t symtab_id = rel_hdr->sh_link;
1366 user_id_t plt_id = rel_hdr->sh_info;
1367
1368 if (!symtab_id || !plt_id)
1369 return 0;
1370
1371 // Section ID's are ones based;
1372 symtab_id++;
1373 plt_id++;
1374
Michael Sartaina7499c92013-07-01 19:45:50 +00001375 const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001376 if (!plt_hdr)
1377 return 0;
1378
Michael Sartaina7499c92013-07-01 19:45:50 +00001379 const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001380 if (!sym_hdr)
1381 return 0;
1382
1383 SectionList *section_list = GetSectionList();
1384 if (!section_list)
1385 return 0;
1386
1387 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1388 if (!rel_section)
1389 return 0;
1390
Greg Claytone72dfb32012-02-24 01:59:29 +00001391 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1392 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001393 return 0;
1394
1395 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1396 if (!symtab)
1397 return 0;
1398
1399 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1400 if (!strtab)
1401 return 0;
1402
1403 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001404 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001405 return 0;
1406
1407 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001408 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001409 return 0;
1410
1411 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001412 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001413 return 0;
1414
1415 unsigned rel_type = PLTRelocationType();
1416 if (!rel_type)
1417 return 0;
1418
Greg Claytone72dfb32012-02-24 01:59:29 +00001419 return ParsePLTRelocations (symbol_table,
1420 start_id,
1421 rel_type,
1422 &m_header,
1423 rel_hdr,
1424 plt_hdr,
1425 sym_hdr,
1426 plt_section_sp,
1427 rel_data,
1428 symtab_data,
1429 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001430}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001431
1432Symtab *
Michael Sartaina7499c92013-07-01 19:45:50 +00001433ObjectFileELF::GetSymtab(uint32_t flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434{
Michael Sartaina7499c92013-07-01 19:45:50 +00001435 ModuleSP module_sp(GetModule());
1436 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001437 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001438 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1439
1440 bool from_unified_section_list = !!(flags & eSymtabFromUnifiedSectionList);
1441 SectionList *section_list = from_unified_section_list ? module_sp->GetUnifiedSectionList() : GetSectionList();
1442 if (!section_list)
1443 return NULL;
1444
1445 // If we're doing the unified section list and it has been modified, then clear our
1446 // cache and reload the symbols. If needed, we could check on only the sections that
1447 // we use to create the symbol table...
1448 std::unique_ptr<lldb_private::Symtab> &symtab_ap = from_unified_section_list ? m_symtab_unified_ap : m_symtab_ap;
1449 if (from_unified_section_list && (m_symtab_unified_revisionid != section_list->GetRevisionID()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001450 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001451 symtab_ap.reset();
1452 m_symtab_unified_revisionid = section_list->GetRevisionID();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001453 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001454 else if (symtab_ap.get())
1455 {
1456 return symtab_ap.get();
1457 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001458
Michael Sartaina7499c92013-07-01 19:45:50 +00001459 Symtab *symbol_table = new Symtab(this);
1460 symtab_ap.reset(symbol_table);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001461
Michael Sartaina7499c92013-07-01 19:45:50 +00001462 // Sharable objects and dynamic executables usually have 2 distinct symbol
1463 // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
1464 // version of the symtab that only contains global symbols. The information found
1465 // in the dynsym is therefore also found in the symtab, while the reverse is not
1466 // necessarily true.
1467 Section *section_sym = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
1468 if (!section_sym)
1469 {
1470 // The symtab section is non-allocable and can be stripped, so if it doesn't exist
1471 // then use the dynsym section which should always be there.
1472 section_sym = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
1473 }
1474
1475 uint64_t symbol_id = 0;
1476 if (section_sym)
1477 {
1478 user_id_t section_id = section_sym->GetID();
1479 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section_sym->GetObjectFile());
1480
1481 symbol_id += obj_file_elf->ParseSymbolTable (symbol_table, symbol_id, section_id);
1482 }
1483
1484 Section *section = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
1485 if (section)
1486 {
1487 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section->GetObjectFile());
1488
1489 // Synthesize trampoline symbols to help navigate the PLT.
1490 const ELFDynamic *symbol = obj_file_elf->FindDynamicSymbol(DT_JMPREL);
1491 if (symbol)
1492 {
1493 addr_t addr = symbol->d_ptr;
1494 Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
1495 if (reloc_section)
1496 {
1497 user_id_t reloc_id = reloc_section->GetID();
1498 const ELFSectionHeaderInfo *reloc_header = obj_file_elf->GetSectionHeaderByIndex(reloc_id);
1499 assert(reloc_header);
1500
1501 obj_file_elf->ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
1502 }
1503 }
1504 }
1505
1506 return symbol_table;
1507 }
1508 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001509}
1510
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001511//===----------------------------------------------------------------------===//
1512// Dump
1513//
1514// Dump the specifics of the runtime file container (such as any headers
1515// segments, sections, etc).
1516//----------------------------------------------------------------------
1517void
1518ObjectFileELF::Dump(Stream *s)
1519{
1520 DumpELFHeader(s, m_header);
1521 s->EOL();
1522 DumpELFProgramHeaders(s);
1523 s->EOL();
1524 DumpELFSectionHeaders(s);
1525 s->EOL();
1526 SectionList *section_list = GetSectionList();
1527 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001528 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001529 Symtab *symtab = GetSymtab();
1530 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001531 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001532 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001533 DumpDependentModules(s);
1534 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001535}
1536
1537//----------------------------------------------------------------------
1538// DumpELFHeader
1539//
1540// Dump the ELF header to the specified output stream
1541//----------------------------------------------------------------------
1542void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001543ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001544{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001545 s->PutCString("ELF Header\n");
1546 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1547 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1548 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1549 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1550 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1551 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1552 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001553
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001554 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1555 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001556 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1557 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1558 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1559
1560 s->Printf("e_type = 0x%4.4x ", header.e_type);
1561 DumpELFHeader_e_type(s, header.e_type);
1562 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1563 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001564 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1565 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1566 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001567 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1568 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1569 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1570 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1571 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1572 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1573 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1574}
1575
1576//----------------------------------------------------------------------
1577// DumpELFHeader_e_type
1578//
1579// Dump an token value for the ELF header member e_type
1580//----------------------------------------------------------------------
1581void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001582ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001583{
1584 switch (e_type)
1585 {
1586 case ET_NONE: *s << "ET_NONE"; break;
1587 case ET_REL: *s << "ET_REL"; break;
1588 case ET_EXEC: *s << "ET_EXEC"; break;
1589 case ET_DYN: *s << "ET_DYN"; break;
1590 case ET_CORE: *s << "ET_CORE"; break;
1591 default:
1592 break;
1593 }
1594}
1595
1596//----------------------------------------------------------------------
1597// DumpELFHeader_e_ident_EI_DATA
1598//
1599// Dump an token value for the ELF header member e_ident[EI_DATA]
1600//----------------------------------------------------------------------
1601void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001602ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001603{
1604 switch (ei_data)
1605 {
1606 case ELFDATANONE: *s << "ELFDATANONE"; break;
1607 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1608 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1609 default:
1610 break;
1611 }
1612}
1613
1614
1615//----------------------------------------------------------------------
1616// DumpELFProgramHeader
1617//
1618// Dump a single ELF program header to the specified output stream
1619//----------------------------------------------------------------------
1620void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001621ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001622{
1623 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001624 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1625 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 +00001626
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001627 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001628 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001629}
1630
1631//----------------------------------------------------------------------
1632// DumpELFProgramHeader_p_type
1633//
1634// Dump an token value for the ELF program header member p_type which
1635// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001636// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001637void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001638ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001639{
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001640 const int kStrWidth = 15;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001641 switch (p_type)
1642 {
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001643 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1644 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1645 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1646 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1647 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1648 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1649 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1650 CASE_AND_STREAM(s, PT_TLS , kStrWidth);
1651 CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001652 default:
1653 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1654 break;
1655 }
1656}
1657
1658
1659//----------------------------------------------------------------------
1660// DumpELFProgramHeader_p_flags
1661//
1662// Dump an token value for the ELF program header member p_flags
1663//----------------------------------------------------------------------
1664void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001665ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001666{
1667 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1668 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1669 << ((p_flags & PF_W) ? "PF_W" : " ")
1670 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1671 << ((p_flags & PF_R) ? "PF_R" : " ");
1672}
1673
1674//----------------------------------------------------------------------
1675// DumpELFProgramHeaders
1676//
1677// Dump all of the ELF program header to the specified output stream
1678//----------------------------------------------------------------------
1679void
1680ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1681{
1682 if (ParseProgramHeaders())
1683 {
1684 s->PutCString("Program Headers\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001685 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001686 "p_filesz p_memsz p_flags p_align\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001687 s->PutCString("==== --------------- -------- -------- -------- "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001688 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689
1690 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001691 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1692 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001693 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001694 s->Printf("[%2u] ", idx);
1695 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001696 s->EOL();
1697 }
1698 }
1699}
1700
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001701//----------------------------------------------------------------------
1702// DumpELFSectionHeader
1703//
1704// Dump a single ELF section header to the specified output stream
1705//----------------------------------------------------------------------
1706void
Michael Sartaina7499c92013-07-01 19:45:50 +00001707ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001708{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001709 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001710 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001711 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001712 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001713 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 +00001714 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001715 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001716}
1717
1718//----------------------------------------------------------------------
1719// DumpELFSectionHeader_sh_type
1720//
1721// Dump an token value for the ELF section header member sh_type which
1722// describes the type of the section
1723//----------------------------------------------------------------------
1724void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001725ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001726{
1727 const int kStrWidth = 12;
1728 switch (sh_type)
1729 {
1730 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1731 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1732 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1733 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1734 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1735 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1736 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1737 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1738 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1739 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1740 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1741 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1742 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1743 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1744 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1745 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1746 default:
1747 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1748 break;
1749 }
1750}
1751
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001752//----------------------------------------------------------------------
1753// DumpELFSectionHeader_sh_flags
1754//
1755// Dump an token value for the ELF section header member sh_flags
1756//----------------------------------------------------------------------
1757void
Greg Claytonc7bece562013-01-25 18:06:21 +00001758ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001759{
1760 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1761 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1762 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1763 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1764 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1765}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001766
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001767//----------------------------------------------------------------------
1768// DumpELFSectionHeaders
1769//
1770// Dump all of the ELF section header to the specified output stream
1771//----------------------------------------------------------------------
1772void
1773ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1774{
Michael Sartaina7499c92013-07-01 19:45:50 +00001775 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001776 return;
1777
1778 s->PutCString("Section Headers\n");
1779 s->PutCString("IDX name type flags "
1780 "addr offset size link info addralgn "
1781 "entsize Name\n");
1782 s->PutCString("==== -------- ------------ -------------------------------- "
1783 "-------- -------- -------- -------- -------- -------- "
1784 "-------- ====================\n");
1785
1786 uint32_t idx = 0;
1787 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1788 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001789 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001790 s->Printf("[%2u] ", idx);
1791 ObjectFileELF::DumpELFSectionHeader(s, *I);
Michael Sartaina7499c92013-07-01 19:45:50 +00001792 const char* section_name = I->section_name.AsCString("");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001793 if (section_name)
1794 *s << ' ' << section_name << "\n";
1795 }
1796}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001797
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001798void
1799ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1800{
1801 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001802
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001803 if (num_modules > 0)
1804 {
1805 s->PutCString("Dependent Modules:\n");
1806 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001807 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001808 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1809 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001810 }
1811 }
1812}
1813
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001814bool
Greg Clayton514487e2011-02-15 21:59:32 +00001815ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001816{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001817 if (!ParseHeader())
1818 return false;
1819
Greg Claytone0d378b2011-03-24 21:19:54 +00001820 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001821 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1822 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001823 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001824}
1825
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001826ObjectFile::Type
1827ObjectFileELF::CalculateType()
1828{
1829 switch (m_header.e_type)
1830 {
1831 case llvm::ELF::ET_NONE:
1832 // 0 - No file type
1833 return eTypeUnknown;
1834
1835 case llvm::ELF::ET_REL:
1836 // 1 - Relocatable file
1837 return eTypeObjectFile;
1838
1839 case llvm::ELF::ET_EXEC:
1840 // 2 - Executable file
1841 return eTypeExecutable;
1842
1843 case llvm::ELF::ET_DYN:
1844 // 3 - Shared object file
1845 return eTypeSharedLibrary;
1846
1847 case ET_CORE:
1848 // 4 - Core file
1849 return eTypeCoreFile;
1850
1851 default:
1852 break;
1853 }
1854 return eTypeUnknown;
1855}
1856
1857ObjectFile::Strata
1858ObjectFileELF::CalculateStrata()
1859{
1860 switch (m_header.e_type)
1861 {
1862 case llvm::ELF::ET_NONE:
1863 // 0 - No file type
1864 return eStrataUnknown;
1865
1866 case llvm::ELF::ET_REL:
1867 // 1 - Relocatable file
1868 return eStrataUnknown;
1869
1870 case llvm::ELF::ET_EXEC:
1871 // 2 - Executable file
1872 // TODO: is there any way to detect that an executable is a kernel
1873 // related executable by inspecting the program headers, section
1874 // headers, symbols, or any other flag bits???
1875 return eStrataUser;
1876
1877 case llvm::ELF::ET_DYN:
1878 // 3 - Shared object file
1879 // TODO: is there any way to detect that an shared library is a kernel
1880 // related executable by inspecting the program headers, section
1881 // headers, symbols, or any other flag bits???
1882 return eStrataUnknown;
1883
1884 case ET_CORE:
1885 // 4 - Core file
1886 // TODO: is there any way to detect that an core file is a kernel
1887 // related executable by inspecting the program headers, section
1888 // headers, symbols, or any other flag bits???
1889 return eStrataUnknown;
1890
1891 default:
1892 break;
1893 }
1894 return eStrataUnknown;
1895}
1896