blob: f09151c7acfc538a5c93ea19b45ec8facfe53e5f [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 +0000516Address
517ObjectFileELF::GetImageInfoAddress()
518{
519 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000520 return Address();
521
522 SectionList *section_list = GetSectionList();
523 if (!section_list)
524 return Address();
525
Greg Clayton3046e662013-07-10 01:23:25 +0000526 // Find the SHT_DYNAMIC (.dynamic) section.
527 SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
528 if (!dynsym_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000529 return Address();
Greg Clayton3046e662013-07-10 01:23:25 +0000530 assert (dynsym_section_sp->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000531
Greg Clayton3046e662013-07-10 01:23:25 +0000532 user_id_t dynsym_id = dynsym_section_sp->GetID();
Michael Sartaina7499c92013-07-01 19:45:50 +0000533 const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000534 if (!dynsym_hdr)
535 return Address();
536
Greg Clayton3046e662013-07-10 01:23:25 +0000537 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000538 {
Greg Clayton3046e662013-07-10 01:23:25 +0000539 ELFDynamic &symbol = m_dynamic_symbols[i];
Greg Claytone72dfb32012-02-24 01:59:29 +0000540
Greg Clayton3046e662013-07-10 01:23:25 +0000541 if (symbol.d_tag == DT_DEBUG)
542 {
543 // Compute the offset as the number of previous entries plus the
544 // size of d_tag.
545 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
546 return Address(dynsym_section_sp, offset);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000547 }
548 }
549
550 return Address();
551}
552
Jim Ingham672e6f52011-03-07 23:44:08 +0000553lldb_private::Address
554ObjectFileELF::GetEntryPointAddress ()
555{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000556 if (m_entry_point_address.IsValid())
557 return m_entry_point_address;
558
559 if (!ParseHeader() || !IsExecutable())
560 return m_entry_point_address;
561
Greg Clayton3046e662013-07-10 01:23:25 +0000562 SectionList *section_list = GetSectionList();
563 addr_t offset = m_header.e_entry;
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000564
Greg Clayton3046e662013-07-10 01:23:25 +0000565 if (!section_list)
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000566 m_entry_point_address.SetOffset(offset);
Greg Clayton3046e662013-07-10 01:23:25 +0000567 else
568 m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000569 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000570}
571
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000572//----------------------------------------------------------------------
573// ParseDependentModules
574//----------------------------------------------------------------------
575size_t
576ObjectFileELF::ParseDependentModules()
577{
578 if (m_filespec_ap.get())
579 return m_filespec_ap->GetSize();
580
581 m_filespec_ap.reset(new FileSpecList());
582
Michael Sartaina7499c92013-07-01 19:45:50 +0000583 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000584 return 0;
585
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000586 SectionList *section_list = GetSectionList();
587 if (!section_list)
588 return 0;
589
Greg Clayton3046e662013-07-10 01:23:25 +0000590 // Find the SHT_DYNAMIC section.
591 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
592 if (!dynsym)
593 return 0;
594 assert (dynsym->GetObjectFile() == this);
595
596 const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
597 if (!header)
598 return 0;
599 // sh_link: section header index of string table used by entries in the section.
600 Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
601 if (!dynstr)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000602 return 0;
603
604 DataExtractor dynsym_data;
605 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000606 if (ReadSectionData(dynsym, dynsym_data) &&
607 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000608 {
609 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000610 const lldb::offset_t section_size = dynsym_data.GetByteSize();
611 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000612
613 // The only type of entries we are concerned with are tagged DT_NEEDED,
614 // yielding the name of a required library.
615 while (offset < section_size)
616 {
617 if (!symbol.Parse(dynsym_data, &offset))
618 break;
619
620 if (symbol.d_tag != DT_NEEDED)
621 continue;
622
623 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
624 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000625 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000626 }
627 }
628
629 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630}
631
632//----------------------------------------------------------------------
633// ParseProgramHeaders
634//----------------------------------------------------------------------
635size_t
636ObjectFileELF::ParseProgramHeaders()
637{
638 // We have already parsed the program headers
639 if (!m_program_headers.empty())
640 return m_program_headers.size();
641
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000642 // If there are no program headers to read we are done.
643 if (m_header.e_phnum == 0)
644 return 0;
645
646 m_program_headers.resize(m_header.e_phnum);
647 if (m_program_headers.size() != m_header.e_phnum)
648 return 0;
649
650 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000651 const elf_off ph_offset = m_header.e_phoff;
652 DataExtractor data;
653 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000654 return 0;
655
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000656 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000657 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000658 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000660 if (m_program_headers[idx].Parse(data, &offset) == false)
661 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662 }
663
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000664 if (idx < m_program_headers.size())
665 m_program_headers.resize(idx);
666
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667 return m_program_headers.size();
668}
669
Michael Sartainc836ae72013-05-23 20:57:03 +0000670static bool
Michael Sartaina7499c92013-07-01 19:45:50 +0000671ParseNoteGNUBuildID(DataExtractor &data, lldb_private::UUID &uuid)
Michael Sartainc836ae72013-05-23 20:57:03 +0000672{
673 // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
674 // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
675 struct
676 {
677 uint32_t name_len; // Length of note name
678 uint32_t desc_len; // Length of note descriptor
679 uint32_t type; // Type of note (1 is ABI_TAG, 3 is BUILD_ID)
680 } notehdr;
681 lldb::offset_t offset = 0;
682 static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
683
684 while (true)
685 {
686 if (data.GetU32 (&offset, &notehdr, 3) == NULL)
687 return false;
688
689 notehdr.name_len = llvm::RoundUpToAlignment (notehdr.name_len, 4);
690 notehdr.desc_len = llvm::RoundUpToAlignment (notehdr.desc_len, 4);
691
692 lldb::offset_t offset_next_note = offset + notehdr.name_len + notehdr.desc_len;
693
694 // 16 bytes is UUID|MD5, 20 bytes is SHA1
695 if ((notehdr.type == g_gnu_build_id) && (notehdr.name_len == 4) &&
696 (notehdr.desc_len == 16 || notehdr.desc_len == 20))
697 {
698 char name[4];
699 if (data.GetU8 (&offset, name, 4) == NULL)
700 return false;
701 if (!strcmp(name, "GNU"))
702 {
703 uint8_t uuidbuf[20];
704 if (data.GetU8 (&offset, &uuidbuf, notehdr.desc_len) == NULL)
705 return false;
706 uuid.SetBytes (uuidbuf, notehdr.desc_len);
707 return true;
708 }
709 }
710 offset = offset_next_note;
711 }
712 return false;
713}
Michael Sartaina7499c92013-07-01 19:45:50 +0000714
715//----------------------------------------------------------------------
716// GetSectionHeaderInfo
717//----------------------------------------------------------------------
718size_t
719ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
720 lldb_private::DataExtractor &object_data,
721 const elf::ELFHeader &header,
722 lldb_private::UUID &uuid,
723 std::string &gnu_debuglink_file,
724 uint32_t &gnu_debuglink_crc)
725{
726 // We have already parsed the section headers
727 if (!section_headers.empty())
728 return section_headers.size();
729
730 // If there are no section headers we are done.
731 if (header.e_shnum == 0)
732 return 0;
733
734 section_headers.resize(header.e_shnum);
735 if (section_headers.size() != header.e_shnum)
736 return 0;
737
738 const size_t sh_size = header.e_shnum * header.e_shentsize;
739 const elf_off sh_offset = header.e_shoff;
740 DataExtractor sh_data;
741 if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
742 return 0;
743
744 uint32_t idx;
745 lldb::offset_t offset;
746 for (idx = 0, offset = 0; idx < header.e_shnum; ++idx)
747 {
748 if (section_headers[idx].Parse(sh_data, &offset) == false)
749 break;
750 }
751 if (idx < section_headers.size())
752 section_headers.resize(idx);
753
754 const unsigned strtab_idx = header.e_shstrndx;
755 if (strtab_idx && strtab_idx < section_headers.size())
756 {
757 const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
758 const size_t byte_size = sheader.sh_size;
759 const Elf64_Off offset = sheader.sh_offset;
760 lldb_private::DataExtractor shstr_data;
761
762 if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
763 {
764 for (SectionHeaderCollIter I = section_headers.begin();
765 I != section_headers.end(); ++I)
766 {
767 static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
768 const ELFSectionHeaderInfo &header = *I;
769 const uint64_t section_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
770 ConstString name(shstr_data.PeekCStr(I->sh_name));
771
772 I->section_name = name;
773
774 if (name == g_sect_name_gnu_debuglink)
775 {
776 DataExtractor data;
777 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
778 {
779 lldb::offset_t gnu_debuglink_offset = 0;
780 gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
781 gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
782 data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
783 }
784 }
785
786 if (header.sh_type == SHT_NOTE && !uuid.IsValid())
787 {
788 DataExtractor data;
789 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
790 {
791 ParseNoteGNUBuildID (data, uuid);
792 }
793 }
794 }
795
796 return section_headers.size();
797 }
798 }
799
800 section_headers.clear();
801 return 0;
802}
803
Ashok Thirumurthi4822d922013-07-11 20:39:00 +0000804size_t
805ObjectFileELF::GetProgramHeaderCount()
806{
807 return ParseProgramHeaders();
808}
809
810const elf::ELFProgramHeader *
811ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id)
812{
813 if (!id || !ParseProgramHeaders())
814 return NULL;
815
816 if (--id < m_program_headers.size())
817 return &m_program_headers[id];
818
819 return NULL;
820}
821
822DataExtractor
823ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id)
824{
825 const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id);
826 if (segment_header == NULL)
827 return DataExtractor();
828 return DataExtractor(m_data, segment_header->p_offset, segment_header->p_filesz);
829}
830
Michael Sartaina7499c92013-07-01 19:45:50 +0000831//----------------------------------------------------------------------
832// ParseSectionHeaders
833//----------------------------------------------------------------------
834size_t
835ObjectFileELF::ParseSectionHeaders()
836{
837 return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
838}
839
Michael Sartaina7499c92013-07-01 19:45:50 +0000840const ObjectFileELF::ELFSectionHeaderInfo *
841ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
842{
Ashok Thirumurthi4822d922013-07-11 20:39:00 +0000843 if (!id || !ParseSectionHeaders())
Michael Sartaina7499c92013-07-01 19:45:50 +0000844 return NULL;
845
846 if (--id < m_section_headers.size())
847 return &m_section_headers[id];
848
849 return NULL;
850}
851
Greg Clayton3046e662013-07-10 01:23:25 +0000852void
853ObjectFileELF::CreateSections(SectionList &unified_section_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854{
Greg Clayton3046e662013-07-10 01:23:25 +0000855 if (!m_sections_ap.get() && ParseSectionHeaders())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000856 {
857 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000858
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000859 for (SectionHeaderCollIter I = m_section_headers.begin();
860 I != m_section_headers.end(); ++I)
861 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000862 const ELFSectionHeaderInfo &header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000863
Michael Sartaina7499c92013-07-01 19:45:50 +0000864 ConstString& name = I->section_name;
Greg Clayton47037bc2012-03-27 02:40:46 +0000865 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
866 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000867
Greg Clayton4ceb9982010-07-21 22:54:26 +0000868 static ConstString g_sect_name_text (".text");
869 static ConstString g_sect_name_data (".data");
870 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +0000871 static ConstString g_sect_name_tdata (".tdata");
872 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +0000873 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
874 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
875 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
876 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
877 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
878 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
879 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
880 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
881 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
882 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
883 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
884 static ConstString g_sect_name_eh_frame (".eh_frame");
885
886 SectionType sect_type = eSectionTypeOther;
887
Greg Clayton741f3f92012-03-27 21:10:07 +0000888 bool is_thread_specific = false;
Michael Sartaina7499c92013-07-01 19:45:50 +0000889
Greg Clayton4ceb9982010-07-21 22:54:26 +0000890 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
891 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
892 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +0000893 else if (name == g_sect_name_tdata)
894 {
895 sect_type = eSectionTypeData;
896 is_thread_specific = true;
897 }
898 else if (name == g_sect_name_tbss)
899 {
900 sect_type = eSectionTypeZeroFill;
901 is_thread_specific = true;
902 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000903 // .debug_abbrev – Abbreviations used in the .debug_info section
904 // .debug_aranges – Lookup table for mapping addresses to compilation units
905 // .debug_frame – Call frame information
906 // .debug_info – The core DWARF information section
907 // .debug_line – Line number information
908 // .debug_loc – Location lists used in DW_AT_location attributes
909 // .debug_macinfo – Macro information
910 // .debug_pubnames – Lookup table for mapping object and function names to compilation units
911 // .debug_pubtypes – Lookup table for mapping type names to compilation units
912 // .debug_ranges – Address ranges used in DW_AT_ranges attributes
913 // .debug_str – String table used in .debug_info
Michael Sartain3cf443d2013-07-17 00:26:30 +0000914 // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
915 // MISSING? .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
Michael Sartaina7499c92013-07-01 19:45:50 +0000916 // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
Greg Clayton4ceb9982010-07-21 22:54:26 +0000917 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
918 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
919 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
920 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
921 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
922 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
923 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
924 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
925 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
926 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
927 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
928 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
Michael Sartaina7499c92013-07-01 19:45:50 +0000929
930 switch (header.sh_type)
Michael Sartainc836ae72013-05-23 20:57:03 +0000931 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000932 case SHT_SYMTAB:
933 assert (sect_type == eSectionTypeOther);
934 sect_type = eSectionTypeELFSymbolTable;
935 break;
936 case SHT_DYNSYM:
937 assert (sect_type == eSectionTypeOther);
938 sect_type = eSectionTypeELFDynamicSymbols;
939 break;
940 case SHT_RELA:
941 case SHT_REL:
942 assert (sect_type == eSectionTypeOther);
943 sect_type = eSectionTypeELFRelocationEntries;
944 break;
945 case SHT_DYNAMIC:
946 assert (sect_type == eSectionTypeOther);
947 sect_type = eSectionTypeELFDynamicLinkInfo;
948 break;
Michael Sartainc836ae72013-05-23 20:57:03 +0000949 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000950
Greg Clayton3046e662013-07-10 01:23:25 +0000951 SectionSP section_sp (new Section(GetModule(), // Module to which this section belongs.
952 this, // ObjectFile to which this section belongs and should read section data from.
953 SectionIndex(I), // Section ID.
954 name, // Section name.
955 sect_type, // Section type.
956 header.sh_addr, // VM address.
957 vm_size, // VM size in bytes of this section.
958 header.sh_offset, // Offset of this section in the file.
959 file_size, // Size of the section as found in the file.
960 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000961
Greg Clayton741f3f92012-03-27 21:10:07 +0000962 if (is_thread_specific)
963 section_sp->SetIsThreadSpecific (is_thread_specific);
964 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000965 }
966 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000967
Greg Clayton3046e662013-07-10 01:23:25 +0000968 if (m_sections_ap.get())
969 {
970 if (GetType() == eTypeDebugInfo)
971 {
972 static const SectionType g_sections[] =
973 {
974 eSectionTypeDWARFDebugAranges,
975 eSectionTypeDWARFDebugInfo,
976 eSectionTypeDWARFDebugAbbrev,
977 eSectionTypeDWARFDebugFrame,
978 eSectionTypeDWARFDebugLine,
979 eSectionTypeDWARFDebugStr,
980 eSectionTypeDWARFDebugLoc,
981 eSectionTypeDWARFDebugMacInfo,
982 eSectionTypeDWARFDebugPubNames,
983 eSectionTypeDWARFDebugPubTypes,
984 eSectionTypeDWARFDebugRanges,
985 eSectionTypeELFSymbolTable,
986 };
987 SectionList *elf_section_list = m_sections_ap.get();
988 for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
989 {
990 SectionType section_type = g_sections[idx];
991 SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
992 if (section_sp)
993 {
994 SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
995 if (module_section_sp)
996 unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
997 else
998 unified_section_list.AddSection (section_sp);
999 }
1000 }
1001 }
1002 else
1003 {
1004 unified_section_list = *m_sections_ap;
1005 }
1006 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007}
1008
Greg Clayton3046e662013-07-10 01:23:25 +00001009// private
Michael Sartaina7499c92013-07-01 19:45:50 +00001010unsigned
Greg Clayton3046e662013-07-10 01:23:25 +00001011ObjectFileELF::ParseSymbols (Symtab *symtab,
1012 user_id_t start_id,
1013 SectionList *section_list,
1014 const size_t num_symbols,
1015 const DataExtractor &symtab_data,
1016 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001018 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001019 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001020
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001021 static ConstString text_section_name(".text");
1022 static ConstString init_section_name(".init");
1023 static ConstString fini_section_name(".fini");
1024 static ConstString ctors_section_name(".ctors");
1025 static ConstString dtors_section_name(".dtors");
1026
1027 static ConstString data_section_name(".data");
1028 static ConstString rodata_section_name(".rodata");
1029 static ConstString rodata1_section_name(".rodata1");
1030 static ConstString data2_section_name(".data1");
1031 static ConstString bss_section_name(".bss");
1032
Greg Clayton9594f4c2013-04-13 23:17:23 +00001033 //StreamFile strm(stdout, false);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001034 unsigned i;
1035 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001037 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038 break;
Greg Clayton9594f4c2013-04-13 23:17:23 +00001039
1040 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1041
1042 // No need to add symbols that have no names
1043 if (symbol_name == NULL || symbol_name[0] == '\0')
1044 continue;
1045
1046 //symbol.Dump (&strm, i, &strtab_data, section_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047
Greg Claytone72dfb32012-02-24 01:59:29 +00001048 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001050 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001051
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001052 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053 {
1054 case SHN_ABS:
1055 symbol_type = eSymbolTypeAbsolute;
1056 break;
1057 case SHN_UNDEF:
1058 symbol_type = eSymbolTypeUndefined;
1059 break;
1060 default:
Greg Claytone72dfb32012-02-24 01:59:29 +00001061 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062 break;
1063 }
1064
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001065 // If a symbol is undefined do not process it further even if it has a STT type
1066 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001068 switch (symbol.getType())
1069 {
1070 default:
1071 case STT_NOTYPE:
1072 // The symbol's type is not specified.
1073 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001075 case STT_OBJECT:
1076 // The symbol is associated with a data object, such as a variable,
1077 // an array, etc.
1078 symbol_type = eSymbolTypeData;
1079 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001080
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001081 case STT_FUNC:
1082 // The symbol is associated with a function or other executable code.
1083 symbol_type = eSymbolTypeCode;
1084 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001085
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001086 case STT_SECTION:
1087 // The symbol is associated with a section. Symbol table entries of
1088 // this type exist primarily for relocation and normally have
1089 // STB_LOCAL binding.
1090 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001091
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001092 case STT_FILE:
1093 // Conventionally, the symbol's name gives the name of the source
1094 // file associated with the object file. A file symbol has STB_LOCAL
1095 // binding, its section index is SHN_ABS, and it precedes the other
1096 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001097 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001098 break;
Matt Kopec00049b82013-02-27 20:13:38 +00001099
1100 case STT_GNU_IFUNC:
1101 // The symbol is associated with an indirect function. The actual
1102 // function will be resolved if it is referenced.
1103 symbol_type = eSymbolTypeResolver;
1104 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001105 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106 }
1107
1108 if (symbol_type == eSymbolTypeInvalid)
1109 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001110 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001112 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113 if (sect_name == text_section_name ||
1114 sect_name == init_section_name ||
1115 sect_name == fini_section_name ||
1116 sect_name == ctors_section_name ||
1117 sect_name == dtors_section_name)
1118 {
1119 symbol_type = eSymbolTypeCode;
1120 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001121 else if (sect_name == data_section_name ||
1122 sect_name == data2_section_name ||
1123 sect_name == rodata_section_name ||
1124 sect_name == rodata1_section_name ||
1125 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126 {
1127 symbol_type = eSymbolTypeData;
1128 }
1129 }
1130 }
1131
Greg Clayton3046e662013-07-10 01:23:25 +00001132 // If the symbol section we've found has no data (SHT_NOBITS), then check the module section
1133 // list. This can happen if we're parsing the debug file and it has no .text section, for example.
Michael Sartaina7499c92013-07-01 19:45:50 +00001134 if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
1135 {
1136 ModuleSP module_sp(GetModule());
1137 if (module_sp)
1138 {
Greg Clayton3046e662013-07-10 01:23:25 +00001139 SectionList *module_section_list = module_sp->GetSectionList();
1140 if (module_section_list && module_section_list != section_list)
Michael Sartaina7499c92013-07-01 19:45:50 +00001141 {
1142 const ConstString &sect_name = symbol_section_sp->GetName();
Greg Clayton3046e662013-07-10 01:23:25 +00001143 lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name));
Michael Sartaina7499c92013-07-01 19:45:50 +00001144 if (section_sp && section_sp->GetFileSize())
1145 {
1146 symbol_section_sp = section_sp;
1147 }
1148 }
1149 }
1150 }
1151
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +00001153 if (symbol_section_sp)
1154 symbol_value -= symbol_section_sp->GetFileAddress();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001155 bool is_global = symbol.getBinding() == STB_GLOBAL;
1156 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +00001157 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001158 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +00001159 i + start_id, // ID is the original symbol table index.
1160 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001161 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +00001162 symbol_type, // Type of this symbol
1163 is_global, // Is this globally visible?
1164 false, // Is this symbol debug info?
1165 false, // Is this symbol a trampoline?
1166 false, // Is this symbol artificial?
1167 symbol_section_sp, // Section in which this symbol is defined or null.
1168 symbol_value, // Offset in section or symbol value.
1169 symbol.st_size, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001170 true, // Size is valid
Greg Claytone72dfb32012-02-24 01:59:29 +00001171 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 symtab->AddSymbol(dc_symbol);
1173 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001174
1175 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001176}
1177
Stephen Wilson499b40e2011-03-30 16:07:05 +00001178unsigned
Greg Clayton3046e662013-07-10 01:23:25 +00001179ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001180{
Greg Clayton3046e662013-07-10 01:23:25 +00001181 if (symtab->GetObjectFile() != this)
1182 {
1183 // If the symbol table section is owned by a different object file, have it do the
1184 // parsing.
1185 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
1186 return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
1187 }
1188
1189 // Get section list for this object file.
1190 SectionList *section_list = m_sections_ap.get();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001191 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001192 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001193
Greg Clayton3046e662013-07-10 01:23:25 +00001194 user_id_t symtab_id = symtab->GetID();
1195 const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
Michael Sartaina7499c92013-07-01 19:45:50 +00001196 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
1197 symtab_hdr->sh_type == SHT_DYNSYM);
1198
Greg Clayton3046e662013-07-10 01:23:25 +00001199 // sh_link: section header index of associated string table.
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001200 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001201 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001202 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Greg Clayton3046e662013-07-10 01:23:25 +00001203
Stephen Wilson499b40e2011-03-30 16:07:05 +00001204 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001205 if (symtab && strtab)
1206 {
Greg Clayton3046e662013-07-10 01:23:25 +00001207 assert (symtab->GetObjectFile() == this);
1208 assert (strtab->GetObjectFile() == this);
1209
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001210 DataExtractor symtab_data;
1211 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001212 if (ReadSectionData(symtab, symtab_data) &&
1213 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001214 {
Greg Clayton3046e662013-07-10 01:23:25 +00001215 size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
1216
Stephen Wilson499b40e2011-03-30 16:07:05 +00001217 num_symbols = ParseSymbols(symbol_table, start_id,
Greg Clayton3046e662013-07-10 01:23:25 +00001218 section_list, num_symbols,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001219 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001220 }
1221 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001222
1223 return num_symbols;
1224}
1225
1226size_t
1227ObjectFileELF::ParseDynamicSymbols()
1228{
1229 if (m_dynamic_symbols.size())
1230 return m_dynamic_symbols.size();
1231
Stephen Wilson499b40e2011-03-30 16:07:05 +00001232 SectionList *section_list = GetSectionList();
1233 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001234 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001235
Greg Clayton3046e662013-07-10 01:23:25 +00001236 // Find the SHT_DYNAMIC section.
1237 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001238 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001239 return 0;
Greg Clayton3046e662013-07-10 01:23:25 +00001240 assert (dynsym->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001241
1242 ELFDynamic symbol;
1243 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001244 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001245 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001246 const lldb::offset_t section_size = dynsym_data.GetByteSize();
1247 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001248
1249 while (cursor < section_size)
1250 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001251 if (!symbol.Parse(dynsym_data, &cursor))
1252 break;
1253
1254 m_dynamic_symbols.push_back(symbol);
1255 }
1256 }
1257
1258 return m_dynamic_symbols.size();
1259}
1260
1261const ELFDynamic *
1262ObjectFileELF::FindDynamicSymbol(unsigned tag)
1263{
1264 if (!ParseDynamicSymbols())
1265 return NULL;
1266
Stephen Wilson499b40e2011-03-30 16:07:05 +00001267 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
1268 DynamicSymbolCollIter E = m_dynamic_symbols.end();
1269 for ( ; I != E; ++I)
1270 {
1271 ELFDynamic *symbol = &*I;
1272
1273 if (symbol->d_tag == tag)
1274 return symbol;
1275 }
1276
1277 return NULL;
1278}
1279
Stephen Wilson499b40e2011-03-30 16:07:05 +00001280unsigned
1281ObjectFileELF::PLTRelocationType()
1282{
Michael Sartainf7899542013-08-22 21:25:53 +00001283 // DT_PLTREL
1284 // This member specifies the type of relocation entry to which the
1285 // procedure linkage table refers. The d_val member holds DT_REL or
1286 // DT_RELA, as appropriate. All relocations in a procedure linkage table
1287 // must use the same relocation.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001288 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
1289
1290 if (symbol)
1291 return symbol->d_val;
1292
1293 return 0;
1294}
1295
1296static unsigned
1297ParsePLTRelocations(Symtab *symbol_table,
1298 user_id_t start_id,
1299 unsigned rel_type,
1300 const ELFHeader *hdr,
1301 const ELFSectionHeader *rel_hdr,
1302 const ELFSectionHeader *plt_hdr,
1303 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00001304 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001305 DataExtractor &rel_data,
1306 DataExtractor &symtab_data,
1307 DataExtractor &strtab_data)
1308{
1309 ELFRelocation rel(rel_type);
1310 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001311 lldb::offset_t offset = 0;
Michael Sartainf7899542013-08-22 21:25:53 +00001312 // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes.
1313 // So round the entsize up by the alignment if addralign is set.
1314 const elf_xword plt_entsize = plt_hdr->sh_addralign ?
1315 llvm::RoundUpToAlignment (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
Greg Claytonc7bece562013-01-25 18:06:21 +00001316 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001317
1318 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1319 reloc_info_fn reloc_type;
1320 reloc_info_fn reloc_symbol;
1321
Greg Claytond091afe2012-11-12 22:53:16 +00001322 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +00001323 {
1324 reloc_type = ELFRelocation::RelocType32;
1325 reloc_symbol = ELFRelocation::RelocSymbol32;
1326 }
1327 else
1328 {
1329 reloc_type = ELFRelocation::RelocType64;
1330 reloc_symbol = ELFRelocation::RelocSymbol64;
1331 }
1332
1333 unsigned slot_type = hdr->GetRelocationJumpSlotType();
1334 unsigned i;
1335 for (i = 0; i < num_relocations; ++i)
1336 {
1337 if (rel.Parse(rel_data, &offset) == false)
1338 break;
1339
1340 if (reloc_type(rel) != slot_type)
1341 continue;
1342
Greg Claytonc7bece562013-01-25 18:06:21 +00001343 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001344 uint64_t plt_index = (i + 1) * plt_entsize;
1345
1346 if (!symbol.Parse(symtab_data, &symbol_offset))
1347 break;
1348
1349 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001350 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001351
1352 Symbol jump_symbol(
1353 i + start_id, // Symbol table index
1354 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001355 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001356 eSymbolTypeTrampoline, // Type of this symbol
1357 false, // Is this globally visible?
1358 false, // Is this symbol debug info?
1359 true, // Is this symbol a trampoline?
1360 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001361 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001362 plt_index, // Offset in section or symbol value.
1363 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001364 true, // Size is valid
Stephen Wilson499b40e2011-03-30 16:07:05 +00001365 0); // Symbol flags.
1366
1367 symbol_table->AddSymbol(jump_symbol);
1368 }
1369
1370 return i;
1371}
1372
1373unsigned
1374ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1375 user_id_t start_id,
Michael Sartaina7499c92013-07-01 19:45:50 +00001376 const ELFSectionHeaderInfo *rel_hdr,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001377 user_id_t rel_id)
1378{
1379 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1380
Greg Clayton3046e662013-07-10 01:23:25 +00001381 // The link field points to the associated symbol table. The info field
Stephen Wilson499b40e2011-03-30 16:07:05 +00001382 // points to the section holding the plt.
1383 user_id_t symtab_id = rel_hdr->sh_link;
1384 user_id_t plt_id = rel_hdr->sh_info;
1385
1386 if (!symtab_id || !plt_id)
1387 return 0;
1388
1389 // Section ID's are ones based;
1390 symtab_id++;
1391 plt_id++;
1392
Michael Sartaina7499c92013-07-01 19:45:50 +00001393 const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001394 if (!plt_hdr)
1395 return 0;
1396
Michael Sartaina7499c92013-07-01 19:45:50 +00001397 const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001398 if (!sym_hdr)
1399 return 0;
1400
Greg Clayton3046e662013-07-10 01:23:25 +00001401 SectionList *section_list = m_sections_ap.get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001402 if (!section_list)
1403 return 0;
1404
1405 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1406 if (!rel_section)
1407 return 0;
1408
Greg Claytone72dfb32012-02-24 01:59:29 +00001409 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1410 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001411 return 0;
1412
1413 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1414 if (!symtab)
1415 return 0;
1416
Greg Clayton3046e662013-07-10 01:23:25 +00001417 // sh_link points to associated string table.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001418 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1419 if (!strtab)
1420 return 0;
1421
1422 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001423 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001424 return 0;
1425
1426 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001427 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001428 return 0;
1429
1430 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001431 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001432 return 0;
1433
1434 unsigned rel_type = PLTRelocationType();
1435 if (!rel_type)
1436 return 0;
1437
Greg Claytone72dfb32012-02-24 01:59:29 +00001438 return ParsePLTRelocations (symbol_table,
1439 start_id,
1440 rel_type,
1441 &m_header,
1442 rel_hdr,
1443 plt_hdr,
1444 sym_hdr,
1445 plt_section_sp,
1446 rel_data,
1447 symtab_data,
1448 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001449}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001450
1451Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001452ObjectFileELF::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001453{
Michael Sartaina7499c92013-07-01 19:45:50 +00001454 ModuleSP module_sp(GetModule());
Greg Clayton3046e662013-07-10 01:23:25 +00001455 if (!module_sp)
1456 return NULL;
Michael Sartaina7499c92013-07-01 19:45:50 +00001457
Greg Clayton3046e662013-07-10 01:23:25 +00001458 // We always want to use the main object file so we (hopefully) only have one cached copy
1459 // of our symtab, dynamic sections, etc.
1460 ObjectFile *module_obj_file = module_sp->GetObjectFile();
1461 if (module_obj_file && module_obj_file != this)
1462 return module_obj_file->GetSymtab();
1463
1464 if (m_symtab_ap.get() == NULL)
1465 {
1466 SectionList *section_list = GetSectionList();
Michael Sartaina7499c92013-07-01 19:45:50 +00001467 if (!section_list)
1468 return NULL;
1469
Greg Clayton3046e662013-07-10 01:23:25 +00001470 uint64_t symbol_id = 0;
1471 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Stephen Wilson499b40e2011-03-30 16:07:05 +00001472
Greg Clayton3046e662013-07-10 01:23:25 +00001473 m_symtab_ap.reset(new Symtab(this));
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001474
Michael Sartaina7499c92013-07-01 19:45:50 +00001475 // Sharable objects and dynamic executables usually have 2 distinct symbol
1476 // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
1477 // version of the symtab that only contains global symbols. The information found
1478 // in the dynsym is therefore also found in the symtab, while the reverse is not
1479 // necessarily true.
Greg Clayton3046e662013-07-10 01:23:25 +00001480 Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
1481 if (!symtab)
Michael Sartaina7499c92013-07-01 19:45:50 +00001482 {
1483 // The symtab section is non-allocable and can be stripped, so if it doesn't exist
1484 // then use the dynsym section which should always be there.
Greg Clayton3046e662013-07-10 01:23:25 +00001485 symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
Michael Sartaina7499c92013-07-01 19:45:50 +00001486 }
Greg Clayton3046e662013-07-10 01:23:25 +00001487 if (symtab)
1488 symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
Michael Sartaina7499c92013-07-01 19:45:50 +00001489
Michael Sartainf7899542013-08-22 21:25:53 +00001490 // DT_JMPREL
1491 // If present, this entry's d_ptr member holds the address of relocation
1492 // entries associated solely with the procedure linkage table. Separating
1493 // these relocation entries lets the dynamic linker ignore them during
1494 // process initialization, if lazy binding is enabled. If this entry is
1495 // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
1496 // also be present.
Greg Clayton3046e662013-07-10 01:23:25 +00001497 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
1498 if (symbol)
Michael Sartaina7499c92013-07-01 19:45:50 +00001499 {
Michael Sartainf7899542013-08-22 21:25:53 +00001500 // Synthesize trampoline symbols to help navigate the PLT.
Greg Clayton3046e662013-07-10 01:23:25 +00001501 addr_t addr = symbol->d_ptr;
1502 Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
1503 if (reloc_section)
Michael Sartaina7499c92013-07-01 19:45:50 +00001504 {
Greg Clayton3046e662013-07-10 01:23:25 +00001505 user_id_t reloc_id = reloc_section->GetID();
1506 const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
1507 assert(reloc_header);
Michael Sartaina7499c92013-07-01 19:45:50 +00001508
Greg Clayton3046e662013-07-10 01:23:25 +00001509 ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
Michael Sartaina7499c92013-07-01 19:45:50 +00001510 }
1511 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001512 }
Greg Clayton3046e662013-07-10 01:23:25 +00001513 return m_symtab_ap.get();
1514}
1515
1516bool
1517ObjectFileELF::IsStripped ()
1518{
1519 // TODO: determine this for ELF
1520 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001521}
1522
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001523//===----------------------------------------------------------------------===//
1524// Dump
1525//
1526// Dump the specifics of the runtime file container (such as any headers
1527// segments, sections, etc).
1528//----------------------------------------------------------------------
1529void
1530ObjectFileELF::Dump(Stream *s)
1531{
1532 DumpELFHeader(s, m_header);
1533 s->EOL();
1534 DumpELFProgramHeaders(s);
1535 s->EOL();
1536 DumpELFSectionHeaders(s);
1537 s->EOL();
1538 SectionList *section_list = GetSectionList();
1539 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001540 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001541 Symtab *symtab = GetSymtab();
1542 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001543 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001544 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001545 DumpDependentModules(s);
1546 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001547}
1548
1549//----------------------------------------------------------------------
1550// DumpELFHeader
1551//
1552// Dump the ELF header to the specified output stream
1553//----------------------------------------------------------------------
1554void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001555ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001556{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001557 s->PutCString("ELF Header\n");
1558 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1559 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1560 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1561 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1562 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1563 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1564 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001565
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001566 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1567 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001568 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1569 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1570 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1571
1572 s->Printf("e_type = 0x%4.4x ", header.e_type);
1573 DumpELFHeader_e_type(s, header.e_type);
1574 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1575 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001576 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1577 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1578 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001579 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1580 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1581 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1582 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1583 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1584 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1585 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1586}
1587
1588//----------------------------------------------------------------------
1589// DumpELFHeader_e_type
1590//
1591// Dump an token value for the ELF header member e_type
1592//----------------------------------------------------------------------
1593void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001594ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001595{
1596 switch (e_type)
1597 {
1598 case ET_NONE: *s << "ET_NONE"; break;
1599 case ET_REL: *s << "ET_REL"; break;
1600 case ET_EXEC: *s << "ET_EXEC"; break;
1601 case ET_DYN: *s << "ET_DYN"; break;
1602 case ET_CORE: *s << "ET_CORE"; break;
1603 default:
1604 break;
1605 }
1606}
1607
1608//----------------------------------------------------------------------
1609// DumpELFHeader_e_ident_EI_DATA
1610//
1611// Dump an token value for the ELF header member e_ident[EI_DATA]
1612//----------------------------------------------------------------------
1613void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001614ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001615{
1616 switch (ei_data)
1617 {
1618 case ELFDATANONE: *s << "ELFDATANONE"; break;
1619 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1620 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1621 default:
1622 break;
1623 }
1624}
1625
1626
1627//----------------------------------------------------------------------
1628// DumpELFProgramHeader
1629//
1630// Dump a single ELF program header to the specified output stream
1631//----------------------------------------------------------------------
1632void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001633ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001634{
1635 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001636 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1637 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 +00001638
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001639 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001640 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001641}
1642
1643//----------------------------------------------------------------------
1644// DumpELFProgramHeader_p_type
1645//
1646// Dump an token value for the ELF program header member p_type which
1647// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001648// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001649void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001650ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651{
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001652 const int kStrWidth = 15;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001653 switch (p_type)
1654 {
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001655 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1656 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1657 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1658 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1659 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1660 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1661 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1662 CASE_AND_STREAM(s, PT_TLS , kStrWidth);
1663 CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001664 default:
1665 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1666 break;
1667 }
1668}
1669
1670
1671//----------------------------------------------------------------------
1672// DumpELFProgramHeader_p_flags
1673//
1674// Dump an token value for the ELF program header member p_flags
1675//----------------------------------------------------------------------
1676void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001677ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001678{
1679 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1680 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1681 << ((p_flags & PF_W) ? "PF_W" : " ")
1682 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1683 << ((p_flags & PF_R) ? "PF_R" : " ");
1684}
1685
1686//----------------------------------------------------------------------
1687// DumpELFProgramHeaders
1688//
1689// Dump all of the ELF program header to the specified output stream
1690//----------------------------------------------------------------------
1691void
1692ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1693{
1694 if (ParseProgramHeaders())
1695 {
1696 s->PutCString("Program Headers\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001697 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001698 "p_filesz p_memsz p_flags p_align\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001699 s->PutCString("==== --------------- -------- -------- -------- "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001700 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001701
1702 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001703 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1704 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001705 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001706 s->Printf("[%2u] ", idx);
1707 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001708 s->EOL();
1709 }
1710 }
1711}
1712
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001713//----------------------------------------------------------------------
1714// DumpELFSectionHeader
1715//
1716// Dump a single ELF section header to the specified output stream
1717//----------------------------------------------------------------------
1718void
Michael Sartaina7499c92013-07-01 19:45:50 +00001719ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001720{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001721 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001722 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001723 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001724 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001725 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 +00001726 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001727 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001728}
1729
1730//----------------------------------------------------------------------
1731// DumpELFSectionHeader_sh_type
1732//
1733// Dump an token value for the ELF section header member sh_type which
1734// describes the type of the section
1735//----------------------------------------------------------------------
1736void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001737ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001738{
1739 const int kStrWidth = 12;
1740 switch (sh_type)
1741 {
1742 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1743 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1744 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1745 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1746 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1747 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1748 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1749 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1750 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1751 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1752 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1753 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1754 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1755 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1756 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1757 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1758 default:
1759 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1760 break;
1761 }
1762}
1763
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001764//----------------------------------------------------------------------
1765// DumpELFSectionHeader_sh_flags
1766//
1767// Dump an token value for the ELF section header member sh_flags
1768//----------------------------------------------------------------------
1769void
Greg Claytonc7bece562013-01-25 18:06:21 +00001770ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001771{
1772 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1773 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1774 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1775 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1776 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1777}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001778
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001779//----------------------------------------------------------------------
1780// DumpELFSectionHeaders
1781//
1782// Dump all of the ELF section header to the specified output stream
1783//----------------------------------------------------------------------
1784void
1785ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1786{
Michael Sartaina7499c92013-07-01 19:45:50 +00001787 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001788 return;
1789
1790 s->PutCString("Section Headers\n");
1791 s->PutCString("IDX name type flags "
1792 "addr offset size link info addralgn "
1793 "entsize Name\n");
1794 s->PutCString("==== -------- ------------ -------------------------------- "
1795 "-------- -------- -------- -------- -------- -------- "
1796 "-------- ====================\n");
1797
1798 uint32_t idx = 0;
1799 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1800 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001801 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001802 s->Printf("[%2u] ", idx);
1803 ObjectFileELF::DumpELFSectionHeader(s, *I);
Michael Sartaina7499c92013-07-01 19:45:50 +00001804 const char* section_name = I->section_name.AsCString("");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001805 if (section_name)
1806 *s << ' ' << section_name << "\n";
1807 }
1808}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001809
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001810void
1811ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1812{
1813 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001814
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001815 if (num_modules > 0)
1816 {
1817 s->PutCString("Dependent Modules:\n");
1818 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001819 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001820 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1821 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001822 }
1823 }
1824}
1825
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001826bool
Greg Clayton514487e2011-02-15 21:59:32 +00001827ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001828{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001829 if (!ParseHeader())
1830 return false;
1831
Greg Claytone0d378b2011-03-24 21:19:54 +00001832 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001833 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1834 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001835 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001836}
1837
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001838ObjectFile::Type
1839ObjectFileELF::CalculateType()
1840{
1841 switch (m_header.e_type)
1842 {
1843 case llvm::ELF::ET_NONE:
1844 // 0 - No file type
1845 return eTypeUnknown;
1846
1847 case llvm::ELF::ET_REL:
1848 // 1 - Relocatable file
1849 return eTypeObjectFile;
1850
1851 case llvm::ELF::ET_EXEC:
1852 // 2 - Executable file
1853 return eTypeExecutable;
1854
1855 case llvm::ELF::ET_DYN:
1856 // 3 - Shared object file
1857 return eTypeSharedLibrary;
1858
1859 case ET_CORE:
1860 // 4 - Core file
1861 return eTypeCoreFile;
1862
1863 default:
1864 break;
1865 }
1866 return eTypeUnknown;
1867}
1868
1869ObjectFile::Strata
1870ObjectFileELF::CalculateStrata()
1871{
1872 switch (m_header.e_type)
1873 {
1874 case llvm::ELF::ET_NONE:
1875 // 0 - No file type
1876 return eStrataUnknown;
1877
1878 case llvm::ELF::ET_REL:
1879 // 1 - Relocatable file
1880 return eStrataUnknown;
1881
1882 case llvm::ELF::ET_EXEC:
1883 // 2 - Executable file
1884 // TODO: is there any way to detect that an executable is a kernel
1885 // related executable by inspecting the program headers, section
1886 // headers, symbols, or any other flag bits???
1887 return eStrataUser;
1888
1889 case llvm::ELF::ET_DYN:
1890 // 3 - Shared object file
1891 // TODO: is there any way to detect that an shared library is a kernel
1892 // related executable by inspecting the program headers, section
1893 // headers, symbols, or any other flag bits???
1894 return eStrataUnknown;
1895
1896 case ET_CORE:
1897 // 4 - Core file
1898 // TODO: is there any way to detect that an core file is a kernel
1899 // related executable by inspecting the program headers, section
1900 // headers, symbols, or any other flag bits???
1901 return eStrataUnknown;
1902
1903 default:
1904 break;
1905 }
1906 return eStrataUnknown;
1907}
1908