blob: 948e5e8a54059828b9daf3887992a93900d5a2af [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"
Ed Mastec113ff82013-12-02 17:49:13 +000019#include "lldb/Core/Log.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000020#include "lldb/Core/Module.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000021#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/PluginManager.h"
23#include "lldb/Core/Section.h"
24#include "lldb/Core/Stream.h"
Ashok Thirumurthi35729bb2013-09-24 15:34:13 +000025#include "lldb/Symbol/DWARFCallFrameInfo.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000026#include "lldb/Symbol/SymbolContext.h"
Steve Pucci9e02dac2014-02-06 19:02:19 +000027#include "lldb/Target/SectionLoadList.h"
Ed Maste54803652013-10-11 17:39:07 +000028#include "lldb/Target/Target.h"
Greg Clayton64195a22011-02-23 00:35:02 +000029#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030
Stephen Wilson499b40e2011-03-30 16:07:05 +000031#include "llvm/ADT/PointerUnion.h"
32
Stephen Wilsonf325ba92010-07-13 23:07:23 +000033#define CASE_AND_STREAM(s, def, width) \
34 case def: s->Printf("%-*s", width, #def); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036using namespace lldb;
37using namespace lldb_private;
Stephen Wilsonf325ba92010-07-13 23:07:23 +000038using namespace elf;
39using namespace llvm::ELF;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040
Stephen Wilson499b40e2011-03-30 16:07:05 +000041namespace {
42//===----------------------------------------------------------------------===//
43/// @class ELFRelocation
44/// @brief Generic wrapper for ELFRel and ELFRela.
45///
46/// This helper class allows us to parse both ELFRel and ELFRela relocation
47/// entries in a generic manner.
48class ELFRelocation
49{
50public:
51
52 /// Constructs an ELFRelocation entry with a personality as given by @p
53 /// type.
54 ///
55 /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
56 ELFRelocation(unsigned type);
57
58 ~ELFRelocation();
59
60 bool
Greg Claytonc7bece562013-01-25 18:06:21 +000061 Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
Stephen Wilson499b40e2011-03-30 16:07:05 +000062
63 static unsigned
64 RelocType32(const ELFRelocation &rel);
65
66 static unsigned
67 RelocType64(const ELFRelocation &rel);
68
69 static unsigned
70 RelocSymbol32(const ELFRelocation &rel);
71
72 static unsigned
73 RelocSymbol64(const ELFRelocation &rel);
74
Andrew MacPherson17220c12014-03-05 10:12:43 +000075 static unsigned
76 RelocOffset32(const ELFRelocation &rel);
77
78 static unsigned
79 RelocOffset64(const ELFRelocation &rel);
80
81 static unsigned
82 RelocAddend32(const ELFRelocation &rel);
83
84 static unsigned
85 RelocAddend64(const ELFRelocation &rel);
86
Stephen Wilson499b40e2011-03-30 16:07:05 +000087private:
88 typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion;
89
90 RelocUnion reloc;
91};
92
93ELFRelocation::ELFRelocation(unsigned type)
94{
Andrew MacPherson17220c12014-03-05 10:12:43 +000095 if (type == DT_REL || type == SHT_REL)
Stephen Wilson499b40e2011-03-30 16:07:05 +000096 reloc = new ELFRel();
Andrew MacPherson17220c12014-03-05 10:12:43 +000097 else if (type == DT_RELA || type == SHT_RELA)
Stephen Wilson499b40e2011-03-30 16:07:05 +000098 reloc = new ELFRela();
99 else {
100 assert(false && "unexpected relocation type");
101 reloc = static_cast<ELFRel*>(NULL);
102 }
103}
104
105ELFRelocation::~ELFRelocation()
106{
107 if (reloc.is<ELFRel*>())
108 delete reloc.get<ELFRel*>();
109 else
110 delete reloc.get<ELFRela*>();
111}
112
113bool
Greg Claytonc7bece562013-01-25 18:06:21 +0000114ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000115{
116 if (reloc.is<ELFRel*>())
117 return reloc.get<ELFRel*>()->Parse(data, offset);
118 else
119 return reloc.get<ELFRela*>()->Parse(data, offset);
120}
121
122unsigned
123ELFRelocation::RelocType32(const ELFRelocation &rel)
124{
125 if (rel.reloc.is<ELFRel*>())
126 return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>());
127 else
128 return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>());
129}
130
131unsigned
132ELFRelocation::RelocType64(const ELFRelocation &rel)
133{
134 if (rel.reloc.is<ELFRel*>())
135 return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>());
136 else
137 return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>());
138}
139
140unsigned
141ELFRelocation::RelocSymbol32(const ELFRelocation &rel)
142{
143 if (rel.reloc.is<ELFRel*>())
144 return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>());
145 else
146 return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>());
147}
148
149unsigned
150ELFRelocation::RelocSymbol64(const ELFRelocation &rel)
151{
152 if (rel.reloc.is<ELFRel*>())
153 return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>());
154 else
155 return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>());
156}
157
Andrew MacPherson17220c12014-03-05 10:12:43 +0000158unsigned
159ELFRelocation::RelocOffset32(const ELFRelocation &rel)
160{
161 if (rel.reloc.is<ELFRel*>())
162 return rel.reloc.get<ELFRel*>()->r_offset;
163 else
164 return rel.reloc.get<ELFRela*>()->r_offset;
165}
166
167unsigned
168ELFRelocation::RelocOffset64(const ELFRelocation &rel)
169{
170 if (rel.reloc.is<ELFRel*>())
171 return rel.reloc.get<ELFRel*>()->r_offset;
172 else
173 return rel.reloc.get<ELFRela*>()->r_offset;
174}
175
176unsigned
177ELFRelocation::RelocAddend32(const ELFRelocation &rel)
178{
179 if (rel.reloc.is<ELFRel*>())
180 return 0;
181 else
182 return rel.reloc.get<ELFRela*>()->r_addend;
183}
184
185unsigned
186ELFRelocation::RelocAddend64(const ELFRelocation &rel)
187{
188 if (rel.reloc.is<ELFRel*>())
189 return 0;
190 else
191 return rel.reloc.get<ELFRela*>()->r_addend;
192}
193
Stephen Wilson499b40e2011-03-30 16:07:05 +0000194} // end anonymous namespace
195
Ed Mastec113ff82013-12-02 17:49:13 +0000196bool
197ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset)
198{
199 // Read all fields.
200 if (data.GetU32(offset, &n_namesz, 3) == NULL)
201 return false;
202
203 // The name field is required to be nul-terminated, and n_namesz
204 // includes the terminating nul in observed implementations (contrary
205 // to the ELF-64 spec). A special case is needed for cores generated
206 // by some older Linux versions, which write a note named "CORE"
207 // without a nul terminator and n_namesz = 4.
208 if (n_namesz == 4)
209 {
210 char buf[4];
211 if (data.ExtractBytes (*offset, 4, data.GetByteOrder(), buf) != 4)
212 return false;
213 if (strncmp (buf, "CORE", 4) == 0)
214 {
215 n_name = "CORE";
216 *offset += 4;
217 return true;
218 }
219 }
220
221 const char *cstr = data.GetCStr(offset, llvm::RoundUpToAlignment (n_namesz, 4));
222 if (cstr == NULL)
223 {
224 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
225 if (log)
226 log->Printf("Failed to parse note name lacking nul terminator");
227
228 return false;
229 }
230 n_name = cstr;
231 return true;
232}
233
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000234//------------------------------------------------------------------
235// Static methods.
236//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237void
238ObjectFileELF::Initialize()
239{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000240 PluginManager::RegisterPlugin(GetPluginNameStatic(),
241 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000242 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000243 CreateMemoryInstance,
244 GetModuleSpecifications);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245}
246
247void
248ObjectFileELF::Terminate()
249{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000250 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251}
252
Greg Clayton57abc5d2013-05-10 21:47:16 +0000253lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254ObjectFileELF::GetPluginNameStatic()
255{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000256 static ConstString g_name("elf");
257 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258}
259
260const char *
261ObjectFileELF::GetPluginDescriptionStatic()
262{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000263 return "ELF object file reader.";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264}
265
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266ObjectFile *
Greg Claytone72dfb32012-02-24 01:59:29 +0000267ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
268 DataBufferSP &data_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000269 lldb::offset_t data_offset,
270 const lldb_private::FileSpec* file,
271 lldb::offset_t file_offset,
272 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000274 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000276 data_sp = file->MemoryMapFileContents(file_offset, length);
277 data_offset = 0;
278 }
279
280 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
281 {
282 const uint8_t *magic = data_sp->GetBytes() + data_offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000283 if (ELFHeader::MagicBytesMatch(magic))
284 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000285 // Update the data to contain the entire file if it doesn't already
Andrew Kaylor213f6722013-02-07 21:30:54 +0000286 if (data_sp->GetByteSize() < length) {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000287 data_sp = file->MemoryMapFileContents(file_offset, length);
Greg Clayton64ff6c72013-02-07 21:49:54 +0000288 data_offset = 0;
289 magic = data_sp->GetBytes();
Andrew Kaylor213f6722013-02-07 21:30:54 +0000290 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000291 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
292 if (address_size == 4 || address_size == 8)
293 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000294 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 +0000295 ArchSpec spec;
296 if (objfile_ap->GetArchitecture(spec) &&
297 objfile_ap->SetModulesArchitecture(spec))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000298 return objfile_ap.release();
299 }
300 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 }
302 return NULL;
303}
304
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000305
Greg Claytonc9660542012-02-05 02:38:54 +0000306ObjectFile*
Greg Claytone72dfb32012-02-24 01:59:29 +0000307ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
308 DataBufferSP& data_sp,
309 const lldb::ProcessSP &process_sp,
310 lldb::addr_t header_addr)
Greg Claytonc9660542012-02-05 02:38:54 +0000311{
Andrew MacPherson17220c12014-03-05 10:12:43 +0000312 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT))
313 {
314 const uint8_t *magic = data_sp->GetBytes();
315 if (ELFHeader::MagicBytesMatch(magic))
316 {
317 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
318 if (address_size == 4 || address_size == 8)
319 {
320 std::auto_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
321 ArchSpec spec;
322 if (objfile_ap->GetArchitecture(spec) &&
323 objfile_ap->SetModulesArchitecture(spec))
324 return objfile_ap.release();
325 }
326 }
327 }
Greg Claytonc9660542012-02-05 02:38:54 +0000328 return NULL;
329}
330
Michael Sartain9f0013d2013-05-17 00:20:21 +0000331bool
332ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,
333 lldb::addr_t data_offset,
334 lldb::addr_t data_length)
335{
336 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
337 {
338 const uint8_t *magic = data_sp->GetBytes() + data_offset;
339 return ELFHeader::MagicBytesMatch(magic);
340 }
341 return false;
342}
Greg Claytonc9660542012-02-05 02:38:54 +0000343
Michael Sartain9f4517a2013-07-03 01:52:14 +0000344/*
345 * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
346 *
347 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
348 * code or tables extracted from it, as desired without restriction.
349 */
350static uint32_t
351calc_gnu_debuglink_crc32(const void *buf, size_t size)
352{
353 static const uint32_t g_crc32_tab[] =
354 {
355 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
356 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
357 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
358 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
359 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
360 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
361 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
362 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
363 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
364 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
365 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
366 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
367 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
368 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
369 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
370 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
371 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
372 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
373 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
374 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
375 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
376 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
377 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
378 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
379 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
380 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
381 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
382 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
383 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
384 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
385 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
386 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
387 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
388 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
389 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
390 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
391 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
392 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
393 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
394 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
395 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
396 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
397 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
398 };
399 const uint8_t *p = (const uint8_t *)buf;
400 uint32_t crc;
401
402 crc = ~0U;
403 while (size--)
404 crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
405 return crc ^ ~0U;
406}
407
Greg Claytonf4d6de62013-04-24 22:29:28 +0000408size_t
409ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
410 lldb::DataBufferSP& data_sp,
411 lldb::offset_t data_offset,
412 lldb::offset_t file_offset,
413 lldb::offset_t length,
414 lldb_private::ModuleSpecList &specs)
415{
Michael Sartain9f0013d2013-05-17 00:20:21 +0000416 const size_t initial_count = specs.GetSize();
Michael Sartainc836ae72013-05-23 20:57:03 +0000417
Michael Sartain9f0013d2013-05-17 00:20:21 +0000418 if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
419 {
420 DataExtractor data;
421 data.SetData(data_sp);
422 elf::ELFHeader header;
423 if (header.Parse(data, &data_offset))
424 {
425 if (data_sp)
426 {
427 ModuleSpec spec;
428 spec.GetFileSpec() = file;
429 spec.GetArchitecture().SetArchitecture(eArchTypeELF,
430 header.e_machine,
431 LLDB_INVALID_CPUTYPE);
432 if (spec.GetArchitecture().IsValid())
433 {
Michael Sartainc836ae72013-05-23 20:57:03 +0000434 // We could parse the ABI tag information (in .note, .notes, or .note.ABI-tag) to get the
Michael Sartaina7499c92013-07-01 19:45:50 +0000435 // machine information. However, this info isn't guaranteed to exist or be correct. Details:
Michael Sartainc836ae72013-05-23 20:57:03 +0000436 // http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
437 // Instead of passing potentially incorrect information down the pipeline, grab
438 // the host information and use it.
439 spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString());
440 spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString());
Michael Sartaina7499c92013-07-01 19:45:50 +0000441
442 // Try to get the UUID from the section list. Usually that's at the end, so
443 // map the file in if we don't have it already.
444 size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
445 if (section_header_end > data_sp->GetByteSize())
446 {
447 data_sp = file.MemoryMapFileContents (file_offset, section_header_end);
448 data.SetData(data_sp);
449 }
450
Michael Sartain9f4517a2013-07-03 01:52:14 +0000451 uint32_t gnu_debuglink_crc = 0;
Michael Sartaina7499c92013-07-01 19:45:50 +0000452 std::string gnu_debuglink_file;
453 SectionHeaderColl section_headers;
Michael Sartain9f4517a2013-07-03 01:52:14 +0000454 lldb_private::UUID &uuid = spec.GetUUID();
455 GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc);
456
457 if (!uuid.IsValid())
458 {
459 if (!gnu_debuglink_crc)
460 {
461 // Need to map entire file into memory to calculate the crc.
462 data_sp = file.MemoryMapFileContents (file_offset, SIZE_MAX);
463 data.SetData(data_sp);
464 gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
465 }
466 if (gnu_debuglink_crc)
467 {
468 // Use 4 bytes of crc from the .gnu_debuglink section.
469 uint32_t uuidt[4] = { gnu_debuglink_crc, 0, 0, 0 };
470 uuid.SetBytes (uuidt, sizeof(uuidt));
471 }
472 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000473
Michael Sartain9f0013d2013-05-17 00:20:21 +0000474 specs.Append(spec);
475 }
476 }
477 }
478 }
Michael Sartainc836ae72013-05-23 20:57:03 +0000479
Michael Sartain9f0013d2013-05-17 00:20:21 +0000480 return specs.GetSize() - initial_count;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000481}
482
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000483//------------------------------------------------------------------
484// PluginInterface protocol
485//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +0000486lldb_private::ConstString
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000487ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000489 return GetPluginNameStatic();
490}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000492uint32_t
493ObjectFileELF::GetPluginVersion()
494{
495 return m_plugin_version;
496}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000497//------------------------------------------------------------------
498// ObjectFile protocol
499//------------------------------------------------------------------
500
Greg Claytone72dfb32012-02-24 01:59:29 +0000501ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000502 DataBufferSP& data_sp,
503 lldb::offset_t data_offset,
Greg Claytone72dfb32012-02-24 01:59:29 +0000504 const FileSpec* file,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000505 lldb::offset_t file_offset,
506 lldb::offset_t length) :
507 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytone72dfb32012-02-24 01:59:29 +0000508 m_header(),
509 m_program_headers(),
510 m_section_headers(),
Michael Sartaina7499c92013-07-01 19:45:50 +0000511 m_filespec_ap()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512{
513 if (file)
514 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000515 ::memset(&m_header, 0, sizeof(m_header));
Michael Sartaina7499c92013-07-01 19:45:50 +0000516 m_gnu_debuglink_crc = 0;
517 m_gnu_debuglink_file.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518}
519
Andrew MacPherson17220c12014-03-05 10:12:43 +0000520ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
521 DataBufferSP& data_sp,
522 const lldb::ProcessSP &process_sp,
523 addr_t header_addr) :
524 ObjectFile(module_sp, process_sp, LLDB_INVALID_ADDRESS, data_sp),
525 m_header(),
526 m_program_headers(),
527 m_section_headers(),
528 m_filespec_ap()
529{
530 ::memset(&m_header, 0, sizeof(m_header));
531}
532
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533ObjectFileELF::~ObjectFileELF()
534{
535}
536
Jim Ingham5aee1622010-08-09 23:31:02 +0000537bool
538ObjectFileELF::IsExecutable() const
539{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000540 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000541}
542
Steve Pucci9e02dac2014-02-06 19:02:19 +0000543bool
Greg Clayton751caf62014-02-07 22:54:47 +0000544ObjectFileELF::SetLoadAddress (Target &target,
545 lldb::addr_t value,
546 bool value_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000547{
Steve Pucci9e02dac2014-02-06 19:02:19 +0000548 ModuleSP module_sp = GetModule();
549 if (module_sp)
550 {
551 size_t num_loaded_sections = 0;
552 SectionList *section_list = GetSectionList ();
553 if (section_list)
554 {
Greg Clayton751caf62014-02-07 22:54:47 +0000555 if (value_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000556 {
Greg Clayton751caf62014-02-07 22:54:47 +0000557 const size_t num_sections = section_list->GetSize();
558 size_t sect_idx = 0;
Sylvestre Ledruf561a012014-02-21 18:08:09 +0000559
Greg Clayton751caf62014-02-07 22:54:47 +0000560 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000561 {
Greg Clayton751caf62014-02-07 22:54:47 +0000562 // Iterate through the object file sections to find all
563 // of the sections that have SHF_ALLOC in their flag bits.
564 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
565 // if (section_sp && !section_sp->IsThreadSpecific())
566 if (section_sp && section_sp->Test(SHF_ALLOC))
567 {
568 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
569 ++num_loaded_sections;
570 }
Steve Pucci9e02dac2014-02-06 19:02:19 +0000571 }
Greg Clayton751caf62014-02-07 22:54:47 +0000572 return num_loaded_sections > 0;
573 }
574 else
575 {
576 // Not sure how to slide an ELF file given the base address
577 // of the ELF file in memory
Steve Pucci9e02dac2014-02-06 19:02:19 +0000578 }
579 }
Steve Pucci9e02dac2014-02-06 19:02:19 +0000580 }
Sylvestre Ledruf561a012014-02-21 18:08:09 +0000581 return false; // If it changed
Steve Pucci9e02dac2014-02-06 19:02:19 +0000582}
583
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000585ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000586{
587 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
588 return eByteOrderBig;
589 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
590 return eByteOrderLittle;
591 return eByteOrderInvalid;
592}
593
Greg Claytonc7bece562013-01-25 18:06:21 +0000594uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000595ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596{
597 return m_data.GetAddressByteSize();
598}
599
Greg Claytonc7bece562013-01-25 18:06:21 +0000600size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000601ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602{
Greg Claytonc7bece562013-01-25 18:06:21 +0000603 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000604}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605
Greg Claytonc7bece562013-01-25 18:06:21 +0000606size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000607ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
608{
Greg Claytonc7bece562013-01-25 18:06:21 +0000609 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610}
611
612bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000613ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614{
Filipe Cabecinhas22b40f72013-05-16 23:29:36 +0000615 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000616 return m_header.Parse(m_data, &offset);
617}
618
619bool
Greg Clayton60830262011-02-04 18:53:10 +0000620ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000621{
Michael Sartaina7499c92013-07-01 19:45:50 +0000622 // Need to parse the section list to get the UUIDs, so make sure that's been done.
623 if (!ParseSectionHeaders())
624 return false;
625
Michael Sartainc836ae72013-05-23 20:57:03 +0000626 if (m_uuid.IsValid())
627 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000628 // We have the full build id uuid.
Michael Sartainc836ae72013-05-23 20:57:03 +0000629 *uuid = m_uuid;
630 return true;
631 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000632 else
633 {
Michael Sartain9f4517a2013-07-03 01:52:14 +0000634 if (!m_gnu_debuglink_crc)
635 m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
Michael Sartaina7499c92013-07-01 19:45:50 +0000636 if (m_gnu_debuglink_crc)
637 {
638 // Use 4 bytes of crc from the .gnu_debuglink section.
639 uint32_t uuidt[4] = { m_gnu_debuglink_crc, 0, 0, 0 };
640 uuid->SetBytes (uuidt, sizeof(uuidt));
641 return true;
642 }
643 }
644
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 return false;
646}
647
Michael Sartaina7499c92013-07-01 19:45:50 +0000648lldb_private::FileSpecList
649ObjectFileELF::GetDebugSymbolFilePaths()
650{
651 FileSpecList file_spec_list;
652
653 if (!m_gnu_debuglink_file.empty())
654 {
655 FileSpec file_spec (m_gnu_debuglink_file.c_str(), false);
656 file_spec_list.Append (file_spec);
657 }
658 return file_spec_list;
659}
660
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000662ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000664 size_t num_modules = ParseDependentModules();
665 uint32_t num_specs = 0;
666
667 for (unsigned i = 0; i < num_modules; ++i)
668 {
669 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
670 num_specs++;
671 }
672
673 return num_specs;
674}
675
Stephen Wilson499b40e2011-03-30 16:07:05 +0000676Address
Ed Maste54803652013-10-11 17:39:07 +0000677ObjectFileELF::GetImageInfoAddress(Target *target)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000678{
679 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000680 return Address();
681
682 SectionList *section_list = GetSectionList();
683 if (!section_list)
684 return Address();
685
Greg Clayton3046e662013-07-10 01:23:25 +0000686 // Find the SHT_DYNAMIC (.dynamic) section.
687 SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
688 if (!dynsym_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000689 return Address();
Greg Clayton3046e662013-07-10 01:23:25 +0000690 assert (dynsym_section_sp->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000691
Greg Clayton3046e662013-07-10 01:23:25 +0000692 user_id_t dynsym_id = dynsym_section_sp->GetID();
Michael Sartaina7499c92013-07-01 19:45:50 +0000693 const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000694 if (!dynsym_hdr)
695 return Address();
696
Greg Clayton3046e662013-07-10 01:23:25 +0000697 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000698 {
Greg Clayton3046e662013-07-10 01:23:25 +0000699 ELFDynamic &symbol = m_dynamic_symbols[i];
Greg Claytone72dfb32012-02-24 01:59:29 +0000700
Ed Maste54803652013-10-11 17:39:07 +0000701 if (symbol.d_tag == DT_DEBUG)
Greg Clayton3046e662013-07-10 01:23:25 +0000702 {
703 // Compute the offset as the number of previous entries plus the
704 // size of d_tag.
705 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
706 return Address(dynsym_section_sp, offset);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000707 }
Ed Maste54803652013-10-11 17:39:07 +0000708 else if (symbol.d_tag == DT_MIPS_RLD_MAP && target)
709 {
710 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
711 addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
712 if (dyn_base == LLDB_INVALID_ADDRESS)
713 return Address();
714 Address addr;
715 Error error;
716 if (target->ReadPointerFromMemory(dyn_base + offset, false, error, addr))
717 return addr;
718 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000719 }
720
721 return Address();
722}
723
Jim Ingham672e6f52011-03-07 23:44:08 +0000724lldb_private::Address
725ObjectFileELF::GetEntryPointAddress ()
726{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000727 if (m_entry_point_address.IsValid())
728 return m_entry_point_address;
729
730 if (!ParseHeader() || !IsExecutable())
731 return m_entry_point_address;
732
Greg Clayton3046e662013-07-10 01:23:25 +0000733 SectionList *section_list = GetSectionList();
734 addr_t offset = m_header.e_entry;
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000735
Greg Clayton3046e662013-07-10 01:23:25 +0000736 if (!section_list)
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000737 m_entry_point_address.SetOffset(offset);
Greg Clayton3046e662013-07-10 01:23:25 +0000738 else
739 m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000740 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000741}
742
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000743//----------------------------------------------------------------------
744// ParseDependentModules
745//----------------------------------------------------------------------
746size_t
747ObjectFileELF::ParseDependentModules()
748{
749 if (m_filespec_ap.get())
750 return m_filespec_ap->GetSize();
751
752 m_filespec_ap.reset(new FileSpecList());
753
Michael Sartaina7499c92013-07-01 19:45:50 +0000754 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000755 return 0;
756
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000757 SectionList *section_list = GetSectionList();
758 if (!section_list)
759 return 0;
760
Greg Clayton3046e662013-07-10 01:23:25 +0000761 // Find the SHT_DYNAMIC section.
762 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
763 if (!dynsym)
764 return 0;
765 assert (dynsym->GetObjectFile() == this);
766
767 const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
768 if (!header)
769 return 0;
770 // sh_link: section header index of string table used by entries in the section.
771 Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
772 if (!dynstr)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000773 return 0;
774
775 DataExtractor dynsym_data;
776 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000777 if (ReadSectionData(dynsym, dynsym_data) &&
778 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000779 {
780 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000781 const lldb::offset_t section_size = dynsym_data.GetByteSize();
782 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000783
784 // The only type of entries we are concerned with are tagged DT_NEEDED,
785 // yielding the name of a required library.
786 while (offset < section_size)
787 {
788 if (!symbol.Parse(dynsym_data, &offset))
789 break;
790
791 if (symbol.d_tag != DT_NEEDED)
792 continue;
793
794 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
795 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000796 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000797 }
798 }
799
800 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801}
802
803//----------------------------------------------------------------------
804// ParseProgramHeaders
805//----------------------------------------------------------------------
806size_t
807ObjectFileELF::ParseProgramHeaders()
808{
809 // We have already parsed the program headers
810 if (!m_program_headers.empty())
811 return m_program_headers.size();
812
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000813 // If there are no program headers to read we are done.
814 if (m_header.e_phnum == 0)
815 return 0;
816
817 m_program_headers.resize(m_header.e_phnum);
818 if (m_program_headers.size() != m_header.e_phnum)
819 return 0;
820
821 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000822 const elf_off ph_offset = m_header.e_phoff;
823 DataExtractor data;
824 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000825 return 0;
826
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000827 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000828 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000829 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000831 if (m_program_headers[idx].Parse(data, &offset) == false)
832 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000833 }
834
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000835 if (idx < m_program_headers.size())
836 m_program_headers.resize(idx);
837
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000838 return m_program_headers.size();
839}
840
Michael Sartainc836ae72013-05-23 20:57:03 +0000841static bool
Michael Sartaina7499c92013-07-01 19:45:50 +0000842ParseNoteGNUBuildID(DataExtractor &data, lldb_private::UUID &uuid)
Michael Sartainc836ae72013-05-23 20:57:03 +0000843{
844 // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
845 // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
Michael Sartainc836ae72013-05-23 20:57:03 +0000846 lldb::offset_t offset = 0;
847 static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
848
849 while (true)
850 {
Ed Mastec113ff82013-12-02 17:49:13 +0000851 ELFNote note = ELFNote();
852 if (!note.Parse(data, &offset))
Michael Sartainc836ae72013-05-23 20:57:03 +0000853 return false;
854
Michael Sartainc836ae72013-05-23 20:57:03 +0000855 // 16 bytes is UUID|MD5, 20 bytes is SHA1
Ed Mastec113ff82013-12-02 17:49:13 +0000856 if (note.n_name == "GNU" && (note.n_type == g_gnu_build_id) &&
857 (note.n_descsz == 16 || note.n_descsz == 20))
Michael Sartainc836ae72013-05-23 20:57:03 +0000858 {
Ed Mastec113ff82013-12-02 17:49:13 +0000859 uint8_t uuidbuf[20];
860 if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == NULL)
Michael Sartainc836ae72013-05-23 20:57:03 +0000861 return false;
Ed Mastec113ff82013-12-02 17:49:13 +0000862 uuid.SetBytes (uuidbuf, note.n_descsz);
863 return true;
Michael Sartainc836ae72013-05-23 20:57:03 +0000864 }
Ed Mastec113ff82013-12-02 17:49:13 +0000865 offset += llvm::RoundUpToAlignment(note.n_descsz, 4);
Michael Sartainc836ae72013-05-23 20:57:03 +0000866 }
867 return false;
868}
Michael Sartaina7499c92013-07-01 19:45:50 +0000869
870//----------------------------------------------------------------------
871// GetSectionHeaderInfo
872//----------------------------------------------------------------------
873size_t
874ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
875 lldb_private::DataExtractor &object_data,
876 const elf::ELFHeader &header,
877 lldb_private::UUID &uuid,
878 std::string &gnu_debuglink_file,
879 uint32_t &gnu_debuglink_crc)
880{
881 // We have already parsed the section headers
882 if (!section_headers.empty())
883 return section_headers.size();
884
885 // If there are no section headers we are done.
886 if (header.e_shnum == 0)
887 return 0;
888
889 section_headers.resize(header.e_shnum);
890 if (section_headers.size() != header.e_shnum)
891 return 0;
892
893 const size_t sh_size = header.e_shnum * header.e_shentsize;
894 const elf_off sh_offset = header.e_shoff;
895 DataExtractor sh_data;
896 if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
897 return 0;
898
899 uint32_t idx;
900 lldb::offset_t offset;
901 for (idx = 0, offset = 0; idx < header.e_shnum; ++idx)
902 {
903 if (section_headers[idx].Parse(sh_data, &offset) == false)
904 break;
905 }
906 if (idx < section_headers.size())
907 section_headers.resize(idx);
908
909 const unsigned strtab_idx = header.e_shstrndx;
910 if (strtab_idx && strtab_idx < section_headers.size())
911 {
912 const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
913 const size_t byte_size = sheader.sh_size;
914 const Elf64_Off offset = sheader.sh_offset;
915 lldb_private::DataExtractor shstr_data;
916
917 if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
918 {
919 for (SectionHeaderCollIter I = section_headers.begin();
920 I != section_headers.end(); ++I)
921 {
922 static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
923 const ELFSectionHeaderInfo &header = *I;
924 const uint64_t section_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
925 ConstString name(shstr_data.PeekCStr(I->sh_name));
926
927 I->section_name = name;
928
929 if (name == g_sect_name_gnu_debuglink)
930 {
931 DataExtractor data;
932 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
933 {
934 lldb::offset_t gnu_debuglink_offset = 0;
935 gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
936 gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
937 data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
938 }
939 }
940
941 if (header.sh_type == SHT_NOTE && !uuid.IsValid())
942 {
943 DataExtractor data;
944 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
945 {
946 ParseNoteGNUBuildID (data, uuid);
947 }
948 }
949 }
950
951 return section_headers.size();
952 }
953 }
954
955 section_headers.clear();
956 return 0;
957}
958
Ashok Thirumurthi4822d922013-07-11 20:39:00 +0000959size_t
960ObjectFileELF::GetProgramHeaderCount()
961{
962 return ParseProgramHeaders();
963}
964
965const elf::ELFProgramHeader *
966ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id)
967{
968 if (!id || !ParseProgramHeaders())
969 return NULL;
970
971 if (--id < m_program_headers.size())
972 return &m_program_headers[id];
973
974 return NULL;
975}
976
977DataExtractor
978ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id)
979{
980 const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id);
981 if (segment_header == NULL)
982 return DataExtractor();
983 return DataExtractor(m_data, segment_header->p_offset, segment_header->p_filesz);
984}
985
Michael Sartaina7499c92013-07-01 19:45:50 +0000986//----------------------------------------------------------------------
987// ParseSectionHeaders
988//----------------------------------------------------------------------
989size_t
990ObjectFileELF::ParseSectionHeaders()
991{
992 return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
993}
994
Michael Sartaina7499c92013-07-01 19:45:50 +0000995const ObjectFileELF::ELFSectionHeaderInfo *
996ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
997{
Ashok Thirumurthi4822d922013-07-11 20:39:00 +0000998 if (!id || !ParseSectionHeaders())
Michael Sartaina7499c92013-07-01 19:45:50 +0000999 return NULL;
1000
1001 if (--id < m_section_headers.size())
1002 return &m_section_headers[id];
1003
1004 return NULL;
1005}
1006
Greg Clayton3046e662013-07-10 01:23:25 +00001007void
1008ObjectFileELF::CreateSections(SectionList &unified_section_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009{
Greg Clayton3046e662013-07-10 01:23:25 +00001010 if (!m_sections_ap.get() && ParseSectionHeaders())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 {
1012 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001014 for (SectionHeaderCollIter I = m_section_headers.begin();
1015 I != m_section_headers.end(); ++I)
1016 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001017 const ELFSectionHeaderInfo &header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001018
Michael Sartaina7499c92013-07-01 19:45:50 +00001019 ConstString& name = I->section_name;
Greg Clayton47037bc2012-03-27 02:40:46 +00001020 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
1021 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001022
Greg Clayton4ceb9982010-07-21 22:54:26 +00001023 static ConstString g_sect_name_text (".text");
1024 static ConstString g_sect_name_data (".data");
1025 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +00001026 static ConstString g_sect_name_tdata (".tdata");
1027 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +00001028 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
1029 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
1030 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
1031 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
1032 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
1033 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
1034 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
1035 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
1036 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
1037 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
1038 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
1039 static ConstString g_sect_name_eh_frame (".eh_frame");
1040
1041 SectionType sect_type = eSectionTypeOther;
1042
Greg Clayton741f3f92012-03-27 21:10:07 +00001043 bool is_thread_specific = false;
Michael Sartaina7499c92013-07-01 19:45:50 +00001044
Greg Clayton4ceb9982010-07-21 22:54:26 +00001045 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
1046 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
1047 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +00001048 else if (name == g_sect_name_tdata)
1049 {
1050 sect_type = eSectionTypeData;
1051 is_thread_specific = true;
1052 }
1053 else if (name == g_sect_name_tbss)
1054 {
1055 sect_type = eSectionTypeZeroFill;
1056 is_thread_specific = true;
1057 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001058 // .debug_abbrev – Abbreviations used in the .debug_info section
1059 // .debug_aranges – Lookup table for mapping addresses to compilation units
1060 // .debug_frame – Call frame information
1061 // .debug_info – The core DWARF information section
1062 // .debug_line – Line number information
1063 // .debug_loc – Location lists used in DW_AT_location attributes
1064 // .debug_macinfo – Macro information
1065 // .debug_pubnames – Lookup table for mapping object and function names to compilation units
1066 // .debug_pubtypes – Lookup table for mapping type names to compilation units
1067 // .debug_ranges – Address ranges used in DW_AT_ranges attributes
1068 // .debug_str – String table used in .debug_info
Michael Sartain3cf443d2013-07-17 00:26:30 +00001069 // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
1070 // MISSING? .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
Michael Sartaina7499c92013-07-01 19:45:50 +00001071 // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
Greg Clayton4ceb9982010-07-21 22:54:26 +00001072 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
1073 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
1074 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
1075 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
1076 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
1077 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
1078 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
1079 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
1080 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
1081 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
1082 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
1083 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
Michael Sartaina7499c92013-07-01 19:45:50 +00001084
1085 switch (header.sh_type)
Michael Sartainc836ae72013-05-23 20:57:03 +00001086 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001087 case SHT_SYMTAB:
1088 assert (sect_type == eSectionTypeOther);
1089 sect_type = eSectionTypeELFSymbolTable;
1090 break;
1091 case SHT_DYNSYM:
1092 assert (sect_type == eSectionTypeOther);
1093 sect_type = eSectionTypeELFDynamicSymbols;
1094 break;
1095 case SHT_RELA:
1096 case SHT_REL:
1097 assert (sect_type == eSectionTypeOther);
1098 sect_type = eSectionTypeELFRelocationEntries;
1099 break;
1100 case SHT_DYNAMIC:
1101 assert (sect_type == eSectionTypeOther);
1102 sect_type = eSectionTypeELFDynamicLinkInfo;
1103 break;
Michael Sartainc836ae72013-05-23 20:57:03 +00001104 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001105
Greg Clayton3046e662013-07-10 01:23:25 +00001106 SectionSP section_sp (new Section(GetModule(), // Module to which this section belongs.
1107 this, // ObjectFile to which this section belongs and should read section data from.
1108 SectionIndex(I), // Section ID.
1109 name, // Section name.
1110 sect_type, // Section type.
1111 header.sh_addr, // VM address.
1112 vm_size, // VM size in bytes of this section.
1113 header.sh_offset, // Offset of this section in the file.
1114 file_size, // Size of the section as found in the file.
1115 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001116
Greg Clayton741f3f92012-03-27 21:10:07 +00001117 if (is_thread_specific)
1118 section_sp->SetIsThreadSpecific (is_thread_specific);
1119 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001120 }
1121 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001122
Greg Clayton3046e662013-07-10 01:23:25 +00001123 if (m_sections_ap.get())
1124 {
1125 if (GetType() == eTypeDebugInfo)
1126 {
1127 static const SectionType g_sections[] =
1128 {
1129 eSectionTypeDWARFDebugAranges,
1130 eSectionTypeDWARFDebugInfo,
1131 eSectionTypeDWARFDebugAbbrev,
1132 eSectionTypeDWARFDebugFrame,
1133 eSectionTypeDWARFDebugLine,
1134 eSectionTypeDWARFDebugStr,
1135 eSectionTypeDWARFDebugLoc,
1136 eSectionTypeDWARFDebugMacInfo,
1137 eSectionTypeDWARFDebugPubNames,
1138 eSectionTypeDWARFDebugPubTypes,
1139 eSectionTypeDWARFDebugRanges,
1140 eSectionTypeELFSymbolTable,
1141 };
1142 SectionList *elf_section_list = m_sections_ap.get();
1143 for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
1144 {
1145 SectionType section_type = g_sections[idx];
1146 SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
1147 if (section_sp)
1148 {
1149 SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
1150 if (module_section_sp)
1151 unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
1152 else
1153 unified_section_list.AddSection (section_sp);
1154 }
1155 }
1156 }
1157 else
1158 {
1159 unified_section_list = *m_sections_ap;
1160 }
1161 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162}
1163
Greg Clayton3046e662013-07-10 01:23:25 +00001164// private
Michael Sartaina7499c92013-07-01 19:45:50 +00001165unsigned
Greg Clayton3046e662013-07-10 01:23:25 +00001166ObjectFileELF::ParseSymbols (Symtab *symtab,
1167 user_id_t start_id,
1168 SectionList *section_list,
1169 const size_t num_symbols,
1170 const DataExtractor &symtab_data,
1171 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001173 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001174 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001175
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001176 static ConstString text_section_name(".text");
1177 static ConstString init_section_name(".init");
1178 static ConstString fini_section_name(".fini");
1179 static ConstString ctors_section_name(".ctors");
1180 static ConstString dtors_section_name(".dtors");
1181
1182 static ConstString data_section_name(".data");
1183 static ConstString rodata_section_name(".rodata");
1184 static ConstString rodata1_section_name(".rodata1");
1185 static ConstString data2_section_name(".data1");
1186 static ConstString bss_section_name(".bss");
1187
Greg Clayton9594f4c2013-04-13 23:17:23 +00001188 //StreamFile strm(stdout, false);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001189 unsigned i;
1190 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001192 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001193 break;
Greg Clayton9594f4c2013-04-13 23:17:23 +00001194
1195 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1196
Andrew MacPherson17220c12014-03-05 10:12:43 +00001197 // No need to add non-section symbols that have no names
1198 if (symbol.getType() != STT_SECTION &&
1199 (symbol_name == NULL || symbol_name[0] == '\0'))
Greg Clayton9594f4c2013-04-13 23:17:23 +00001200 continue;
1201
1202 //symbol.Dump (&strm, i, &strtab_data, section_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001203
Greg Claytone72dfb32012-02-24 01:59:29 +00001204 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001205 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001206 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001207
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001208 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 {
1210 case SHN_ABS:
1211 symbol_type = eSymbolTypeAbsolute;
1212 break;
1213 case SHN_UNDEF:
1214 symbol_type = eSymbolTypeUndefined;
1215 break;
1216 default:
Greg Claytone72dfb32012-02-24 01:59:29 +00001217 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001218 break;
1219 }
1220
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001221 // If a symbol is undefined do not process it further even if it has a STT type
1222 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001223 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001224 switch (symbol.getType())
1225 {
1226 default:
1227 case STT_NOTYPE:
1228 // The symbol's type is not specified.
1229 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001231 case STT_OBJECT:
1232 // The symbol is associated with a data object, such as a variable,
1233 // an array, etc.
1234 symbol_type = eSymbolTypeData;
1235 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001236
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001237 case STT_FUNC:
1238 // The symbol is associated with a function or other executable code.
1239 symbol_type = eSymbolTypeCode;
1240 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001242 case STT_SECTION:
1243 // The symbol is associated with a section. Symbol table entries of
1244 // this type exist primarily for relocation and normally have
1245 // STB_LOCAL binding.
1246 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001248 case STT_FILE:
1249 // Conventionally, the symbol's name gives the name of the source
1250 // file associated with the object file. A file symbol has STB_LOCAL
1251 // binding, its section index is SHN_ABS, and it precedes the other
1252 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001253 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001254 break;
Matt Kopec00049b82013-02-27 20:13:38 +00001255
1256 case STT_GNU_IFUNC:
1257 // The symbol is associated with an indirect function. The actual
1258 // function will be resolved if it is referenced.
1259 symbol_type = eSymbolTypeResolver;
1260 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001261 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 }
1263
1264 if (symbol_type == eSymbolTypeInvalid)
1265 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001266 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001268 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269 if (sect_name == text_section_name ||
1270 sect_name == init_section_name ||
1271 sect_name == fini_section_name ||
1272 sect_name == ctors_section_name ||
1273 sect_name == dtors_section_name)
1274 {
1275 symbol_type = eSymbolTypeCode;
1276 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001277 else if (sect_name == data_section_name ||
1278 sect_name == data2_section_name ||
1279 sect_name == rodata_section_name ||
1280 sect_name == rodata1_section_name ||
1281 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001282 {
1283 symbol_type = eSymbolTypeData;
1284 }
1285 }
1286 }
1287
Greg Clayton3046e662013-07-10 01:23:25 +00001288 // If the symbol section we've found has no data (SHT_NOBITS), then check the module section
1289 // 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 +00001290 if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
1291 {
1292 ModuleSP module_sp(GetModule());
1293 if (module_sp)
1294 {
Greg Clayton3046e662013-07-10 01:23:25 +00001295 SectionList *module_section_list = module_sp->GetSectionList();
1296 if (module_section_list && module_section_list != section_list)
Michael Sartaina7499c92013-07-01 19:45:50 +00001297 {
1298 const ConstString &sect_name = symbol_section_sp->GetName();
Greg Clayton3046e662013-07-10 01:23:25 +00001299 lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name));
Michael Sartaina7499c92013-07-01 19:45:50 +00001300 if (section_sp && section_sp->GetFileSize())
1301 {
1302 symbol_section_sp = section_sp;
1303 }
1304 }
1305 }
1306 }
1307
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001308 uint64_t symbol_value = symbol.st_value;
Andrew MacPherson17220c12014-03-05 10:12:43 +00001309 if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile)
Greg Claytone72dfb32012-02-24 01:59:29 +00001310 symbol_value -= symbol_section_sp->GetFileAddress();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001311 bool is_global = symbol.getBinding() == STB_GLOBAL;
1312 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +00001313 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001314 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +00001315 i + start_id, // ID is the original symbol table index.
1316 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001317 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +00001318 symbol_type, // Type of this symbol
1319 is_global, // Is this globally visible?
1320 false, // Is this symbol debug info?
1321 false, // Is this symbol a trampoline?
1322 false, // Is this symbol artificial?
1323 symbol_section_sp, // Section in which this symbol is defined or null.
1324 symbol_value, // Offset in section or symbol value.
1325 symbol.st_size, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001326 true, // Size is valid
Greg Claytone72dfb32012-02-24 01:59:29 +00001327 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001328 symtab->AddSymbol(dc_symbol);
1329 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001330
1331 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332}
1333
Stephen Wilson499b40e2011-03-30 16:07:05 +00001334unsigned
Greg Clayton3046e662013-07-10 01:23:25 +00001335ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001336{
Greg Clayton3046e662013-07-10 01:23:25 +00001337 if (symtab->GetObjectFile() != this)
1338 {
1339 // If the symbol table section is owned by a different object file, have it do the
1340 // parsing.
1341 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
1342 return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
1343 }
1344
1345 // Get section list for this object file.
1346 SectionList *section_list = m_sections_ap.get();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001347 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001348 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001349
Greg Clayton3046e662013-07-10 01:23:25 +00001350 user_id_t symtab_id = symtab->GetID();
1351 const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
Michael Sartaina7499c92013-07-01 19:45:50 +00001352 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
1353 symtab_hdr->sh_type == SHT_DYNSYM);
1354
Greg Clayton3046e662013-07-10 01:23:25 +00001355 // sh_link: section header index of associated string table.
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001356 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001357 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001358 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Greg Clayton3046e662013-07-10 01:23:25 +00001359
Stephen Wilson499b40e2011-03-30 16:07:05 +00001360 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001361 if (symtab && strtab)
1362 {
Greg Clayton3046e662013-07-10 01:23:25 +00001363 assert (symtab->GetObjectFile() == this);
1364 assert (strtab->GetObjectFile() == this);
1365
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001366 DataExtractor symtab_data;
1367 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001368 if (ReadSectionData(symtab, symtab_data) &&
1369 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001370 {
Greg Clayton3046e662013-07-10 01:23:25 +00001371 size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
1372
Stephen Wilson499b40e2011-03-30 16:07:05 +00001373 num_symbols = ParseSymbols(symbol_table, start_id,
Greg Clayton3046e662013-07-10 01:23:25 +00001374 section_list, num_symbols,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001375 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001376 }
1377 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001378
1379 return num_symbols;
1380}
1381
1382size_t
1383ObjectFileELF::ParseDynamicSymbols()
1384{
1385 if (m_dynamic_symbols.size())
1386 return m_dynamic_symbols.size();
1387
Stephen Wilson499b40e2011-03-30 16:07:05 +00001388 SectionList *section_list = GetSectionList();
1389 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001390 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001391
Greg Clayton3046e662013-07-10 01:23:25 +00001392 // Find the SHT_DYNAMIC section.
1393 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001394 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001395 return 0;
Greg Clayton3046e662013-07-10 01:23:25 +00001396 assert (dynsym->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001397
1398 ELFDynamic symbol;
1399 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001400 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001401 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001402 const lldb::offset_t section_size = dynsym_data.GetByteSize();
1403 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001404
1405 while (cursor < section_size)
1406 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001407 if (!symbol.Parse(dynsym_data, &cursor))
1408 break;
1409
1410 m_dynamic_symbols.push_back(symbol);
1411 }
1412 }
1413
1414 return m_dynamic_symbols.size();
1415}
1416
1417const ELFDynamic *
1418ObjectFileELF::FindDynamicSymbol(unsigned tag)
1419{
1420 if (!ParseDynamicSymbols())
1421 return NULL;
1422
Stephen Wilson499b40e2011-03-30 16:07:05 +00001423 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
1424 DynamicSymbolCollIter E = m_dynamic_symbols.end();
1425 for ( ; I != E; ++I)
1426 {
1427 ELFDynamic *symbol = &*I;
1428
1429 if (symbol->d_tag == tag)
1430 return symbol;
1431 }
1432
1433 return NULL;
1434}
1435
Stephen Wilson499b40e2011-03-30 16:07:05 +00001436unsigned
1437ObjectFileELF::PLTRelocationType()
1438{
Michael Sartainf7899542013-08-22 21:25:53 +00001439 // DT_PLTREL
1440 // This member specifies the type of relocation entry to which the
1441 // procedure linkage table refers. The d_val member holds DT_REL or
1442 // DT_RELA, as appropriate. All relocations in a procedure linkage table
1443 // must use the same relocation.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001444 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
1445
1446 if (symbol)
1447 return symbol->d_val;
1448
1449 return 0;
1450}
1451
1452static unsigned
1453ParsePLTRelocations(Symtab *symbol_table,
1454 user_id_t start_id,
1455 unsigned rel_type,
1456 const ELFHeader *hdr,
1457 const ELFSectionHeader *rel_hdr,
1458 const ELFSectionHeader *plt_hdr,
1459 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00001460 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001461 DataExtractor &rel_data,
1462 DataExtractor &symtab_data,
1463 DataExtractor &strtab_data)
1464{
1465 ELFRelocation rel(rel_type);
1466 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001467 lldb::offset_t offset = 0;
Michael Sartainf7899542013-08-22 21:25:53 +00001468 // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes.
1469 // So round the entsize up by the alignment if addralign is set.
1470 const elf_xword plt_entsize = plt_hdr->sh_addralign ?
1471 llvm::RoundUpToAlignment (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
Greg Claytonc7bece562013-01-25 18:06:21 +00001472 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001473
1474 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1475 reloc_info_fn reloc_type;
1476 reloc_info_fn reloc_symbol;
1477
Greg Claytond091afe2012-11-12 22:53:16 +00001478 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +00001479 {
1480 reloc_type = ELFRelocation::RelocType32;
1481 reloc_symbol = ELFRelocation::RelocSymbol32;
1482 }
1483 else
1484 {
1485 reloc_type = ELFRelocation::RelocType64;
1486 reloc_symbol = ELFRelocation::RelocSymbol64;
1487 }
1488
1489 unsigned slot_type = hdr->GetRelocationJumpSlotType();
1490 unsigned i;
1491 for (i = 0; i < num_relocations; ++i)
1492 {
1493 if (rel.Parse(rel_data, &offset) == false)
1494 break;
1495
1496 if (reloc_type(rel) != slot_type)
1497 continue;
1498
Greg Claytonc7bece562013-01-25 18:06:21 +00001499 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001500 uint64_t plt_index = (i + 1) * plt_entsize;
1501
1502 if (!symbol.Parse(symtab_data, &symbol_offset))
1503 break;
1504
1505 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001506 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001507
1508 Symbol jump_symbol(
1509 i + start_id, // Symbol table index
1510 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001511 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001512 eSymbolTypeTrampoline, // Type of this symbol
1513 false, // Is this globally visible?
1514 false, // Is this symbol debug info?
1515 true, // Is this symbol a trampoline?
1516 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001517 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001518 plt_index, // Offset in section or symbol value.
1519 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001520 true, // Size is valid
Stephen Wilson499b40e2011-03-30 16:07:05 +00001521 0); // Symbol flags.
1522
1523 symbol_table->AddSymbol(jump_symbol);
1524 }
1525
1526 return i;
1527}
1528
1529unsigned
1530ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1531 user_id_t start_id,
Michael Sartaina7499c92013-07-01 19:45:50 +00001532 const ELFSectionHeaderInfo *rel_hdr,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001533 user_id_t rel_id)
1534{
1535 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1536
Greg Clayton3046e662013-07-10 01:23:25 +00001537 // The link field points to the associated symbol table. The info field
Stephen Wilson499b40e2011-03-30 16:07:05 +00001538 // points to the section holding the plt.
1539 user_id_t symtab_id = rel_hdr->sh_link;
1540 user_id_t plt_id = rel_hdr->sh_info;
1541
1542 if (!symtab_id || !plt_id)
1543 return 0;
1544
1545 // Section ID's are ones based;
1546 symtab_id++;
1547 plt_id++;
1548
Michael Sartaina7499c92013-07-01 19:45:50 +00001549 const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001550 if (!plt_hdr)
1551 return 0;
1552
Michael Sartaina7499c92013-07-01 19:45:50 +00001553 const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001554 if (!sym_hdr)
1555 return 0;
1556
Greg Clayton3046e662013-07-10 01:23:25 +00001557 SectionList *section_list = m_sections_ap.get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001558 if (!section_list)
1559 return 0;
1560
1561 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1562 if (!rel_section)
1563 return 0;
1564
Greg Claytone72dfb32012-02-24 01:59:29 +00001565 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1566 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001567 return 0;
1568
1569 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1570 if (!symtab)
1571 return 0;
1572
Greg Clayton3046e662013-07-10 01:23:25 +00001573 // sh_link points to associated string table.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001574 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1575 if (!strtab)
1576 return 0;
1577
1578 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001579 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001580 return 0;
1581
1582 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001583 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001584 return 0;
1585
1586 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001587 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001588 return 0;
1589
1590 unsigned rel_type = PLTRelocationType();
1591 if (!rel_type)
1592 return 0;
1593
Greg Claytone72dfb32012-02-24 01:59:29 +00001594 return ParsePLTRelocations (symbol_table,
1595 start_id,
1596 rel_type,
1597 &m_header,
1598 rel_hdr,
1599 plt_hdr,
1600 sym_hdr,
1601 plt_section_sp,
1602 rel_data,
1603 symtab_data,
1604 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001605}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001606
Andrew MacPherson17220c12014-03-05 10:12:43 +00001607unsigned
1608ObjectFileELF::RelocateSection(Symtab* symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
1609 const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
1610 DataExtractor &rel_data, DataExtractor &symtab_data,
1611 DataExtractor &debug_data, Section* rel_section)
1612{
1613 ELFRelocation rel(rel_hdr->sh_type);
1614 lldb::addr_t offset = 0;
1615 const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
1616 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1617 reloc_info_fn reloc_type;
1618 reloc_info_fn reloc_symbol;
1619
1620 if (hdr->Is32Bit())
1621 {
1622 reloc_type = ELFRelocation::RelocType32;
1623 reloc_symbol = ELFRelocation::RelocSymbol32;
1624 }
1625 else
1626 {
1627 reloc_type = ELFRelocation::RelocType64;
1628 reloc_symbol = ELFRelocation::RelocSymbol64;
1629 }
1630
1631 for (unsigned i = 0; i < num_relocations; ++i)
1632 {
1633 if (rel.Parse(rel_data, &offset) == false)
1634 break;
1635
1636 Symbol* symbol = NULL;
1637
1638 if (hdr->Is32Bit())
1639 {
1640 switch (reloc_type(rel)) {
1641 case R_386_32:
1642 case R_386_PC32:
1643 default:
1644 assert(false && "unexpected relocation type");
1645 }
1646 } else {
1647 switch (reloc_type(rel)) {
1648 case R_X86_64_64:
1649 {
1650 symbol = symtab->FindSymbolByID(reloc_symbol(rel));
1651 if (symbol)
1652 {
1653 addr_t value = symbol->GetAddress().GetFileAddress();
1654 DataBufferSP& data_buffer_sp = debug_data.GetSharedDataBuffer();
1655 uint64_t* dst = reinterpret_cast<uint64_t*>(data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset64(rel));
1656 *dst = value + ELFRelocation::RelocAddend64(rel);
1657 }
1658 break;
1659 }
1660 case R_X86_64_32:
1661 case R_X86_64_32S:
1662 {
1663 symbol = symtab->FindSymbolByID(reloc_symbol(rel));
1664 if (symbol)
1665 {
1666 addr_t value = symbol->GetAddress().GetFileAddress();
1667 value += ELFRelocation::RelocAddend32(rel);
1668 assert((reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) ||
1669 (reloc_type(rel) == R_X86_64_32S &&
1670 ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN)));
1671 uint32_t truncated_addr = (value & 0xFFFFFFFF);
1672 DataBufferSP& data_buffer_sp = debug_data.GetSharedDataBuffer();
1673 uint32_t* dst = reinterpret_cast<uint32_t*>(data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel));
1674 *dst = truncated_addr;
1675 }
1676 break;
1677 }
1678 case R_X86_64_PC32:
1679 default:
1680 assert(false && "unexpected relocation type");
1681 }
1682 }
1683 }
1684
1685 return 0;
1686}
1687
1688unsigned
1689ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, user_id_t rel_id)
1690{
1691 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1692
1693 // Parse in the section list if needed.
1694 SectionList *section_list = GetSectionList();
1695 if (!section_list)
1696 return 0;
1697
1698 // Section ID's are ones based.
1699 user_id_t symtab_id = rel_hdr->sh_link + 1;
1700 user_id_t debug_id = rel_hdr->sh_info + 1;
1701
1702 const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
1703 if (!symtab_hdr)
1704 return 0;
1705
1706 const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
1707 if (!debug_hdr)
1708 return 0;
1709
1710 Section *rel = section_list->FindSectionByID(rel_id).get();
1711 if (!rel)
1712 return 0;
1713
1714 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1715 if (!symtab)
1716 return 0;
1717
1718 Section *debug = section_list->FindSectionByID(debug_id).get();
1719 if (!debug)
1720 return 0;
1721
1722 DataExtractor rel_data;
1723 DataExtractor symtab_data;
1724 DataExtractor debug_data;
1725
1726 if (ReadSectionData(rel, rel_data) &&
1727 ReadSectionData(symtab, symtab_data) &&
1728 ReadSectionData(debug, debug_data))
1729 {
1730 RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr, debug_hdr,
1731 rel_data, symtab_data, debug_data, debug);
1732 }
1733
1734 return 0;
1735}
1736
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001737Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001738ObjectFileELF::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001739{
Michael Sartaina7499c92013-07-01 19:45:50 +00001740 ModuleSP module_sp(GetModule());
Greg Clayton3046e662013-07-10 01:23:25 +00001741 if (!module_sp)
1742 return NULL;
Michael Sartaina7499c92013-07-01 19:45:50 +00001743
Greg Clayton3046e662013-07-10 01:23:25 +00001744 // We always want to use the main object file so we (hopefully) only have one cached copy
1745 // of our symtab, dynamic sections, etc.
1746 ObjectFile *module_obj_file = module_sp->GetObjectFile();
1747 if (module_obj_file && module_obj_file != this)
1748 return module_obj_file->GetSymtab();
1749
1750 if (m_symtab_ap.get() == NULL)
1751 {
1752 SectionList *section_list = GetSectionList();
Michael Sartaina7499c92013-07-01 19:45:50 +00001753 if (!section_list)
1754 return NULL;
1755
Greg Clayton3046e662013-07-10 01:23:25 +00001756 uint64_t symbol_id = 0;
1757 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Stephen Wilson499b40e2011-03-30 16:07:05 +00001758
Greg Clayton3046e662013-07-10 01:23:25 +00001759 m_symtab_ap.reset(new Symtab(this));
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001760
Michael Sartaina7499c92013-07-01 19:45:50 +00001761 // Sharable objects and dynamic executables usually have 2 distinct symbol
1762 // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
1763 // version of the symtab that only contains global symbols. The information found
1764 // in the dynsym is therefore also found in the symtab, while the reverse is not
1765 // necessarily true.
Greg Clayton3046e662013-07-10 01:23:25 +00001766 Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
1767 if (!symtab)
Michael Sartaina7499c92013-07-01 19:45:50 +00001768 {
1769 // The symtab section is non-allocable and can be stripped, so if it doesn't exist
1770 // then use the dynsym section which should always be there.
Greg Clayton3046e662013-07-10 01:23:25 +00001771 symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
Michael Sartaina7499c92013-07-01 19:45:50 +00001772 }
Greg Clayton3046e662013-07-10 01:23:25 +00001773 if (symtab)
1774 symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
Michael Sartaina7499c92013-07-01 19:45:50 +00001775
Michael Sartainf7899542013-08-22 21:25:53 +00001776 // DT_JMPREL
1777 // If present, this entry's d_ptr member holds the address of relocation
1778 // entries associated solely with the procedure linkage table. Separating
1779 // these relocation entries lets the dynamic linker ignore them during
1780 // process initialization, if lazy binding is enabled. If this entry is
1781 // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
1782 // also be present.
Greg Clayton3046e662013-07-10 01:23:25 +00001783 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
1784 if (symbol)
Michael Sartaina7499c92013-07-01 19:45:50 +00001785 {
Michael Sartainf7899542013-08-22 21:25:53 +00001786 // Synthesize trampoline symbols to help navigate the PLT.
Greg Clayton3046e662013-07-10 01:23:25 +00001787 addr_t addr = symbol->d_ptr;
1788 Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
1789 if (reloc_section)
Michael Sartaina7499c92013-07-01 19:45:50 +00001790 {
Greg Clayton3046e662013-07-10 01:23:25 +00001791 user_id_t reloc_id = reloc_section->GetID();
1792 const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
1793 assert(reloc_header);
Michael Sartaina7499c92013-07-01 19:45:50 +00001794
Greg Clayton3046e662013-07-10 01:23:25 +00001795 ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
Michael Sartaina7499c92013-07-01 19:45:50 +00001796 }
1797 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001798 }
Andrew MacPherson17220c12014-03-05 10:12:43 +00001799
1800 for (SectionHeaderCollIter I = m_section_headers.begin();
1801 I != m_section_headers.end(); ++I)
1802 {
1803 if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL)
1804 {
1805 if (CalculateType() == eTypeObjectFile)
1806 {
1807 const char *section_name = I->section_name.AsCString("");
1808 if (strstr(section_name, ".rela.debug") ||
1809 strstr(section_name, ".rel.debug"))
1810 {
1811 const ELFSectionHeader &reloc_header = *I;
1812 user_id_t reloc_id = SectionIndex(I);
1813 RelocateDebugSections(&reloc_header, reloc_id);
1814 }
1815 }
1816 }
1817 }
Greg Clayton3046e662013-07-10 01:23:25 +00001818 return m_symtab_ap.get();
1819}
1820
Ashok Thirumurthi35729bb2013-09-24 15:34:13 +00001821Symbol *
1822ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
1823{
1824 if (!m_symtab_ap.get())
1825 return nullptr; // GetSymtab() should be called first.
1826
1827 const SectionList *section_list = GetSectionList();
1828 if (!section_list)
1829 return nullptr;
1830
1831 if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
1832 {
1833 AddressRange range;
1834 if (eh_frame->GetAddressRange (so_addr, range))
1835 {
1836 const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
1837 Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
1838 if (symbol)
1839 return symbol;
1840
1841 // Note that a (stripped) symbol won't be found by GetSymtab()...
1842 lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
1843 if (eh_sym_section_sp.get())
1844 {
1845 addr_t section_base = eh_sym_section_sp->GetFileAddress();
1846 addr_t offset = file_addr - section_base;
1847 uint64_t symbol_id = m_symtab_ap->GetNumSymbols();
1848
1849 Symbol eh_symbol(
1850 symbol_id, // Symbol table index.
1851 "???", // Symbol name.
1852 false, // Is the symbol name mangled?
1853 eSymbolTypeCode, // Type of this symbol.
1854 true, // Is this globally visible?
1855 false, // Is this symbol debug info?
1856 false, // Is this symbol a trampoline?
1857 true, // Is this symbol artificial?
1858 eh_sym_section_sp, // Section in which this symbol is defined or null.
1859 offset, // Offset in section or symbol value.
1860 range.GetByteSize(), // Size in bytes of this symbol.
1861 true, // Size is valid.
1862 0); // Symbol flags.
1863 if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
1864 return m_symtab_ap->SymbolAtIndex(symbol_id);
1865 }
1866 }
1867 }
1868 return nullptr;
1869}
1870
1871
Greg Clayton3046e662013-07-10 01:23:25 +00001872bool
1873ObjectFileELF::IsStripped ()
1874{
1875 // TODO: determine this for ELF
1876 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001877}
1878
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001879//===----------------------------------------------------------------------===//
1880// Dump
1881//
1882// Dump the specifics of the runtime file container (such as any headers
1883// segments, sections, etc).
1884//----------------------------------------------------------------------
1885void
1886ObjectFileELF::Dump(Stream *s)
1887{
1888 DumpELFHeader(s, m_header);
1889 s->EOL();
1890 DumpELFProgramHeaders(s);
1891 s->EOL();
1892 DumpELFSectionHeaders(s);
1893 s->EOL();
1894 SectionList *section_list = GetSectionList();
1895 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001896 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001897 Symtab *symtab = GetSymtab();
1898 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001899 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001901 DumpDependentModules(s);
1902 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001903}
1904
1905//----------------------------------------------------------------------
1906// DumpELFHeader
1907//
1908// Dump the ELF header to the specified output stream
1909//----------------------------------------------------------------------
1910void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001911ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001912{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001913 s->PutCString("ELF Header\n");
1914 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1915 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1916 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1917 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1918 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1919 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1920 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001921
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001922 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1923 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001924 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1925 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1926 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1927
1928 s->Printf("e_type = 0x%4.4x ", header.e_type);
1929 DumpELFHeader_e_type(s, header.e_type);
1930 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1931 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001932 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1933 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1934 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1936 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1937 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1938 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1939 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1940 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1941 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1942}
1943
1944//----------------------------------------------------------------------
1945// DumpELFHeader_e_type
1946//
1947// Dump an token value for the ELF header member e_type
1948//----------------------------------------------------------------------
1949void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001950ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001951{
1952 switch (e_type)
1953 {
1954 case ET_NONE: *s << "ET_NONE"; break;
1955 case ET_REL: *s << "ET_REL"; break;
1956 case ET_EXEC: *s << "ET_EXEC"; break;
1957 case ET_DYN: *s << "ET_DYN"; break;
1958 case ET_CORE: *s << "ET_CORE"; break;
1959 default:
1960 break;
1961 }
1962}
1963
1964//----------------------------------------------------------------------
1965// DumpELFHeader_e_ident_EI_DATA
1966//
1967// Dump an token value for the ELF header member e_ident[EI_DATA]
1968//----------------------------------------------------------------------
1969void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001970ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001971{
1972 switch (ei_data)
1973 {
1974 case ELFDATANONE: *s << "ELFDATANONE"; break;
1975 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1976 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1977 default:
1978 break;
1979 }
1980}
1981
1982
1983//----------------------------------------------------------------------
1984// DumpELFProgramHeader
1985//
1986// Dump a single ELF program header to the specified output stream
1987//----------------------------------------------------------------------
1988void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001989ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001990{
1991 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001992 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1993 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 +00001994
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001995 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001996 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001997}
1998
1999//----------------------------------------------------------------------
2000// DumpELFProgramHeader_p_type
2001//
2002// Dump an token value for the ELF program header member p_type which
2003// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002004// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002005void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002006ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002007{
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00002008 const int kStrWidth = 15;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002009 switch (p_type)
2010 {
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00002011 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
2012 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
2013 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
2014 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
2015 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
2016 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
2017 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
2018 CASE_AND_STREAM(s, PT_TLS , kStrWidth);
2019 CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002020 default:
2021 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
2022 break;
2023 }
2024}
2025
2026
2027//----------------------------------------------------------------------
2028// DumpELFProgramHeader_p_flags
2029//
2030// Dump an token value for the ELF program header member p_flags
2031//----------------------------------------------------------------------
2032void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002033ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002034{
2035 *s << ((p_flags & PF_X) ? "PF_X" : " ")
2036 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
2037 << ((p_flags & PF_W) ? "PF_W" : " ")
2038 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
2039 << ((p_flags & PF_R) ? "PF_R" : " ");
2040}
2041
2042//----------------------------------------------------------------------
2043// DumpELFProgramHeaders
2044//
2045// Dump all of the ELF program header to the specified output stream
2046//----------------------------------------------------------------------
2047void
2048ObjectFileELF::DumpELFProgramHeaders(Stream *s)
2049{
2050 if (ParseProgramHeaders())
2051 {
2052 s->PutCString("Program Headers\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00002053 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002054 "p_filesz p_memsz p_flags p_align\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00002055 s->PutCString("==== --------------- -------- -------- -------- "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002056 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002057
2058 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002059 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
2060 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002061 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002062 s->Printf("[%2u] ", idx);
2063 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002064 s->EOL();
2065 }
2066 }
2067}
2068
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002069//----------------------------------------------------------------------
2070// DumpELFSectionHeader
2071//
2072// Dump a single ELF section header to the specified output stream
2073//----------------------------------------------------------------------
2074void
Michael Sartaina7499c92013-07-01 19:45:50 +00002075ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002076{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002077 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002078 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00002079 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002080 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00002081 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 +00002082 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00002083 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002084}
2085
2086//----------------------------------------------------------------------
2087// DumpELFSectionHeader_sh_type
2088//
2089// Dump an token value for the ELF section header member sh_type which
2090// describes the type of the section
2091//----------------------------------------------------------------------
2092void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002093ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002094{
2095 const int kStrWidth = 12;
2096 switch (sh_type)
2097 {
2098 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
2099 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
2100 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
2101 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
2102 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
2103 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
2104 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
2105 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
2106 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
2107 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
2108 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
2109 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
2110 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
2111 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
2112 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
2113 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
2114 default:
2115 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
2116 break;
2117 }
2118}
2119
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002120//----------------------------------------------------------------------
2121// DumpELFSectionHeader_sh_flags
2122//
2123// Dump an token value for the ELF section header member sh_flags
2124//----------------------------------------------------------------------
2125void
Greg Claytonc7bece562013-01-25 18:06:21 +00002126ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002127{
2128 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
2129 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
2130 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
2131 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
2132 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
2133}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002134
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002135//----------------------------------------------------------------------
2136// DumpELFSectionHeaders
2137//
2138// Dump all of the ELF section header to the specified output stream
2139//----------------------------------------------------------------------
2140void
2141ObjectFileELF::DumpELFSectionHeaders(Stream *s)
2142{
Michael Sartaina7499c92013-07-01 19:45:50 +00002143 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002144 return;
2145
2146 s->PutCString("Section Headers\n");
2147 s->PutCString("IDX name type flags "
2148 "addr offset size link info addralgn "
2149 "entsize Name\n");
2150 s->PutCString("==== -------- ------------ -------------------------------- "
2151 "-------- -------- -------- -------- -------- -------- "
2152 "-------- ====================\n");
2153
2154 uint32_t idx = 0;
2155 for (SectionHeaderCollConstIter I = m_section_headers.begin();
2156 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002157 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002158 s->Printf("[%2u] ", idx);
2159 ObjectFileELF::DumpELFSectionHeader(s, *I);
Michael Sartaina7499c92013-07-01 19:45:50 +00002160 const char* section_name = I->section_name.AsCString("");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002161 if (section_name)
2162 *s << ' ' << section_name << "\n";
2163 }
2164}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002165
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002166void
2167ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
2168{
2169 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002170
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002171 if (num_modules > 0)
2172 {
2173 s->PutCString("Dependent Modules:\n");
2174 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002175 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002176 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
2177 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002178 }
2179 }
2180}
2181
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002182bool
Greg Clayton514487e2011-02-15 21:59:32 +00002183ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002184{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00002185 if (!ParseHeader())
2186 return false;
2187
Greg Claytone0d378b2011-03-24 21:19:54 +00002188 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00002189 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
2190 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002191 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002192}
2193
Greg Clayton9e00b6a652011-07-09 00:41:34 +00002194ObjectFile::Type
2195ObjectFileELF::CalculateType()
2196{
2197 switch (m_header.e_type)
2198 {
2199 case llvm::ELF::ET_NONE:
2200 // 0 - No file type
2201 return eTypeUnknown;
2202
2203 case llvm::ELF::ET_REL:
2204 // 1 - Relocatable file
2205 return eTypeObjectFile;
2206
2207 case llvm::ELF::ET_EXEC:
2208 // 2 - Executable file
2209 return eTypeExecutable;
2210
2211 case llvm::ELF::ET_DYN:
2212 // 3 - Shared object file
2213 return eTypeSharedLibrary;
2214
2215 case ET_CORE:
2216 // 4 - Core file
2217 return eTypeCoreFile;
2218
2219 default:
2220 break;
2221 }
2222 return eTypeUnknown;
2223}
2224
2225ObjectFile::Strata
2226ObjectFileELF::CalculateStrata()
2227{
2228 switch (m_header.e_type)
2229 {
2230 case llvm::ELF::ET_NONE:
2231 // 0 - No file type
2232 return eStrataUnknown;
2233
2234 case llvm::ELF::ET_REL:
2235 // 1 - Relocatable file
2236 return eStrataUnknown;
2237
2238 case llvm::ELF::ET_EXEC:
2239 // 2 - Executable file
2240 // TODO: is there any way to detect that an executable is a kernel
2241 // related executable by inspecting the program headers, section
2242 // headers, symbols, or any other flag bits???
2243 return eStrataUser;
2244
2245 case llvm::ELF::ET_DYN:
2246 // 3 - Shared object file
2247 // TODO: is there any way to detect that an shared library is a kernel
2248 // related executable by inspecting the program headers, section
2249 // headers, symbols, or any other flag bits???
2250 return eStrataUnknown;
2251
2252 case ET_CORE:
2253 // 4 - Core file
2254 // TODO: is there any way to detect that an core file is a kernel
2255 // related executable by inspecting the program headers, section
2256 // headers, symbols, or any other flag bits???
2257 return eStrataUnknown;
2258
2259 default:
2260 break;
2261 }
2262 return eStrataUnknown;
2263}
2264