blob: 7bdacfe14cdea434206351d5dc572a5becbf4e96 [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"
Ed Maste54803652013-10-11 17:39:07 +000027#include "lldb/Target/Target.h"
Greg Clayton64195a22011-02-23 00:35:02 +000028#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
Stephen Wilson499b40e2011-03-30 16:07:05 +000030#include "llvm/ADT/PointerUnion.h"
31
Stephen Wilsonf325ba92010-07-13 23:07:23 +000032#define CASE_AND_STREAM(s, def, width) \
33 case def: s->Printf("%-*s", width, #def); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035using namespace lldb;
36using namespace lldb_private;
Stephen Wilsonf325ba92010-07-13 23:07:23 +000037using namespace elf;
38using namespace llvm::ELF;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
Stephen Wilson499b40e2011-03-30 16:07:05 +000040namespace {
41//===----------------------------------------------------------------------===//
42/// @class ELFRelocation
43/// @brief Generic wrapper for ELFRel and ELFRela.
44///
45/// This helper class allows us to parse both ELFRel and ELFRela relocation
46/// entries in a generic manner.
47class ELFRelocation
48{
49public:
50
51 /// Constructs an ELFRelocation entry with a personality as given by @p
52 /// type.
53 ///
54 /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
55 ELFRelocation(unsigned type);
56
57 ~ELFRelocation();
58
59 bool
Greg Claytonc7bece562013-01-25 18:06:21 +000060 Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
Stephen Wilson499b40e2011-03-30 16:07:05 +000061
62 static unsigned
63 RelocType32(const ELFRelocation &rel);
64
65 static unsigned
66 RelocType64(const ELFRelocation &rel);
67
68 static unsigned
69 RelocSymbol32(const ELFRelocation &rel);
70
71 static unsigned
72 RelocSymbol64(const ELFRelocation &rel);
73
74private:
75 typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion;
76
77 RelocUnion reloc;
78};
79
80ELFRelocation::ELFRelocation(unsigned type)
81{
82 if (type == DT_REL)
83 reloc = new ELFRel();
84 else if (type == DT_RELA)
85 reloc = new ELFRela();
86 else {
87 assert(false && "unexpected relocation type");
88 reloc = static_cast<ELFRel*>(NULL);
89 }
90}
91
92ELFRelocation::~ELFRelocation()
93{
94 if (reloc.is<ELFRel*>())
95 delete reloc.get<ELFRel*>();
96 else
97 delete reloc.get<ELFRela*>();
98}
99
100bool
Greg Claytonc7bece562013-01-25 18:06:21 +0000101ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000102{
103 if (reloc.is<ELFRel*>())
104 return reloc.get<ELFRel*>()->Parse(data, offset);
105 else
106 return reloc.get<ELFRela*>()->Parse(data, offset);
107}
108
109unsigned
110ELFRelocation::RelocType32(const ELFRelocation &rel)
111{
112 if (rel.reloc.is<ELFRel*>())
113 return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>());
114 else
115 return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>());
116}
117
118unsigned
119ELFRelocation::RelocType64(const ELFRelocation &rel)
120{
121 if (rel.reloc.is<ELFRel*>())
122 return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>());
123 else
124 return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>());
125}
126
127unsigned
128ELFRelocation::RelocSymbol32(const ELFRelocation &rel)
129{
130 if (rel.reloc.is<ELFRel*>())
131 return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>());
132 else
133 return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>());
134}
135
136unsigned
137ELFRelocation::RelocSymbol64(const ELFRelocation &rel)
138{
139 if (rel.reloc.is<ELFRel*>())
140 return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>());
141 else
142 return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>());
143}
144
145} // end anonymous namespace
146
Ed Mastec113ff82013-12-02 17:49:13 +0000147bool
148ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset)
149{
150 // Read all fields.
151 if (data.GetU32(offset, &n_namesz, 3) == NULL)
152 return false;
153
154 // The name field is required to be nul-terminated, and n_namesz
155 // includes the terminating nul in observed implementations (contrary
156 // to the ELF-64 spec). A special case is needed for cores generated
157 // by some older Linux versions, which write a note named "CORE"
158 // without a nul terminator and n_namesz = 4.
159 if (n_namesz == 4)
160 {
161 char buf[4];
162 if (data.ExtractBytes (*offset, 4, data.GetByteOrder(), buf) != 4)
163 return false;
164 if (strncmp (buf, "CORE", 4) == 0)
165 {
166 n_name = "CORE";
167 *offset += 4;
168 return true;
169 }
170 }
171
172 const char *cstr = data.GetCStr(offset, llvm::RoundUpToAlignment (n_namesz, 4));
173 if (cstr == NULL)
174 {
175 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
176 if (log)
177 log->Printf("Failed to parse note name lacking nul terminator");
178
179 return false;
180 }
181 n_name = cstr;
182 return true;
183}
184
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000185//------------------------------------------------------------------
186// Static methods.
187//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188void
189ObjectFileELF::Initialize()
190{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000191 PluginManager::RegisterPlugin(GetPluginNameStatic(),
192 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000193 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000194 CreateMemoryInstance,
195 GetModuleSpecifications);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196}
197
198void
199ObjectFileELF::Terminate()
200{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000201 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000202}
203
Greg Clayton57abc5d2013-05-10 21:47:16 +0000204lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205ObjectFileELF::GetPluginNameStatic()
206{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000207 static ConstString g_name("elf");
208 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209}
210
211const char *
212ObjectFileELF::GetPluginDescriptionStatic()
213{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000214 return "ELF object file reader.";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215}
216
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217ObjectFile *
Greg Claytone72dfb32012-02-24 01:59:29 +0000218ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
219 DataBufferSP &data_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000220 lldb::offset_t data_offset,
221 const lldb_private::FileSpec* file,
222 lldb::offset_t file_offset,
223 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000225 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000227 data_sp = file->MemoryMapFileContents(file_offset, length);
228 data_offset = 0;
229 }
230
231 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
232 {
233 const uint8_t *magic = data_sp->GetBytes() + data_offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000234 if (ELFHeader::MagicBytesMatch(magic))
235 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000236 // Update the data to contain the entire file if it doesn't already
Andrew Kaylor213f6722013-02-07 21:30:54 +0000237 if (data_sp->GetByteSize() < length) {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000238 data_sp = file->MemoryMapFileContents(file_offset, length);
Greg Clayton64ff6c72013-02-07 21:49:54 +0000239 data_offset = 0;
240 magic = data_sp->GetBytes();
Andrew Kaylor213f6722013-02-07 21:30:54 +0000241 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000242 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
243 if (address_size == 4 || address_size == 8)
244 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000245 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 +0000246 ArchSpec spec;
247 if (objfile_ap->GetArchitecture(spec) &&
248 objfile_ap->SetModulesArchitecture(spec))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000249 return objfile_ap.release();
250 }
251 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 }
253 return NULL;
254}
255
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000256
Greg Claytonc9660542012-02-05 02:38:54 +0000257ObjectFile*
Greg Claytone72dfb32012-02-24 01:59:29 +0000258ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
259 DataBufferSP& data_sp,
260 const lldb::ProcessSP &process_sp,
261 lldb::addr_t header_addr)
Greg Claytonc9660542012-02-05 02:38:54 +0000262{
263 return NULL;
264}
265
Michael Sartain9f0013d2013-05-17 00:20:21 +0000266bool
267ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,
268 lldb::addr_t data_offset,
269 lldb::addr_t data_length)
270{
271 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
272 {
273 const uint8_t *magic = data_sp->GetBytes() + data_offset;
274 return ELFHeader::MagicBytesMatch(magic);
275 }
276 return false;
277}
Greg Claytonc9660542012-02-05 02:38:54 +0000278
Michael Sartain9f4517a2013-07-03 01:52:14 +0000279/*
280 * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
281 *
282 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
283 * code or tables extracted from it, as desired without restriction.
284 */
285static uint32_t
286calc_gnu_debuglink_crc32(const void *buf, size_t size)
287{
288 static const uint32_t g_crc32_tab[] =
289 {
290 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
291 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
292 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
293 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
294 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
295 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
296 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
297 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
298 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
299 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
300 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
301 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
302 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
303 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
304 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
305 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
306 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
307 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
308 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
309 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
310 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
311 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
312 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
313 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
314 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
315 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
316 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
317 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
318 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
319 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
320 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
321 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
322 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
323 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
324 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
325 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
326 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
327 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
328 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
329 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
330 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
331 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
332 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
333 };
334 const uint8_t *p = (const uint8_t *)buf;
335 uint32_t crc;
336
337 crc = ~0U;
338 while (size--)
339 crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
340 return crc ^ ~0U;
341}
342
Greg Claytonf4d6de62013-04-24 22:29:28 +0000343size_t
344ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
345 lldb::DataBufferSP& data_sp,
346 lldb::offset_t data_offset,
347 lldb::offset_t file_offset,
348 lldb::offset_t length,
349 lldb_private::ModuleSpecList &specs)
350{
Michael Sartain9f0013d2013-05-17 00:20:21 +0000351 const size_t initial_count = specs.GetSize();
Michael Sartainc836ae72013-05-23 20:57:03 +0000352
Michael Sartain9f0013d2013-05-17 00:20:21 +0000353 if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
354 {
355 DataExtractor data;
356 data.SetData(data_sp);
357 elf::ELFHeader header;
358 if (header.Parse(data, &data_offset))
359 {
360 if (data_sp)
361 {
362 ModuleSpec spec;
363 spec.GetFileSpec() = file;
364 spec.GetArchitecture().SetArchitecture(eArchTypeELF,
365 header.e_machine,
366 LLDB_INVALID_CPUTYPE);
367 if (spec.GetArchitecture().IsValid())
368 {
Michael Sartainc836ae72013-05-23 20:57:03 +0000369 // We could parse the ABI tag information (in .note, .notes, or .note.ABI-tag) to get the
Michael Sartaina7499c92013-07-01 19:45:50 +0000370 // machine information. However, this info isn't guaranteed to exist or be correct. Details:
Michael Sartainc836ae72013-05-23 20:57:03 +0000371 // http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
372 // Instead of passing potentially incorrect information down the pipeline, grab
373 // the host information and use it.
374 spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString());
375 spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString());
Michael Sartaina7499c92013-07-01 19:45:50 +0000376
377 // Try to get the UUID from the section list. Usually that's at the end, so
378 // map the file in if we don't have it already.
379 size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
380 if (section_header_end > data_sp->GetByteSize())
381 {
382 data_sp = file.MemoryMapFileContents (file_offset, section_header_end);
383 data.SetData(data_sp);
384 }
385
Michael Sartain9f4517a2013-07-03 01:52:14 +0000386 uint32_t gnu_debuglink_crc = 0;
Michael Sartaina7499c92013-07-01 19:45:50 +0000387 std::string gnu_debuglink_file;
388 SectionHeaderColl section_headers;
Michael Sartain9f4517a2013-07-03 01:52:14 +0000389 lldb_private::UUID &uuid = spec.GetUUID();
390 GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc);
391
392 if (!uuid.IsValid())
393 {
394 if (!gnu_debuglink_crc)
395 {
396 // Need to map entire file into memory to calculate the crc.
397 data_sp = file.MemoryMapFileContents (file_offset, SIZE_MAX);
398 data.SetData(data_sp);
399 gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
400 }
401 if (gnu_debuglink_crc)
402 {
403 // Use 4 bytes of crc from the .gnu_debuglink section.
404 uint32_t uuidt[4] = { gnu_debuglink_crc, 0, 0, 0 };
405 uuid.SetBytes (uuidt, sizeof(uuidt));
406 }
407 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000408
Michael Sartain9f0013d2013-05-17 00:20:21 +0000409 specs.Append(spec);
410 }
411 }
412 }
413 }
Michael Sartainc836ae72013-05-23 20:57:03 +0000414
Michael Sartain9f0013d2013-05-17 00:20:21 +0000415 return specs.GetSize() - initial_count;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000416}
417
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000418//------------------------------------------------------------------
419// PluginInterface protocol
420//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +0000421lldb_private::ConstString
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000422ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000424 return GetPluginNameStatic();
425}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000427uint32_t
428ObjectFileELF::GetPluginVersion()
429{
430 return m_plugin_version;
431}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000432//------------------------------------------------------------------
433// ObjectFile protocol
434//------------------------------------------------------------------
435
Greg Claytone72dfb32012-02-24 01:59:29 +0000436ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000437 DataBufferSP& data_sp,
438 lldb::offset_t data_offset,
Greg Claytone72dfb32012-02-24 01:59:29 +0000439 const FileSpec* file,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000440 lldb::offset_t file_offset,
441 lldb::offset_t length) :
442 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytone72dfb32012-02-24 01:59:29 +0000443 m_header(),
444 m_program_headers(),
445 m_section_headers(),
Michael Sartaina7499c92013-07-01 19:45:50 +0000446 m_filespec_ap()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447{
448 if (file)
449 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000450 ::memset(&m_header, 0, sizeof(m_header));
Michael Sartaina7499c92013-07-01 19:45:50 +0000451 m_gnu_debuglink_crc = 0;
452 m_gnu_debuglink_file.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453}
454
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455ObjectFileELF::~ObjectFileELF()
456{
457}
458
Jim Ingham5aee1622010-08-09 23:31:02 +0000459bool
460ObjectFileELF::IsExecutable() const
461{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000462 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000463}
464
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000466ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467{
468 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
469 return eByteOrderBig;
470 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
471 return eByteOrderLittle;
472 return eByteOrderInvalid;
473}
474
Greg Claytonc7bece562013-01-25 18:06:21 +0000475uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000476ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477{
478 return m_data.GetAddressByteSize();
479}
480
Greg Claytonc7bece562013-01-25 18:06:21 +0000481size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000482ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483{
Greg Claytonc7bece562013-01-25 18:06:21 +0000484 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000485}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486
Greg Claytonc7bece562013-01-25 18:06:21 +0000487size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000488ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
489{
Greg Claytonc7bece562013-01-25 18:06:21 +0000490 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491}
492
493bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000494ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495{
Filipe Cabecinhas22b40f72013-05-16 23:29:36 +0000496 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000497 return m_header.Parse(m_data, &offset);
498}
499
500bool
Greg Clayton60830262011-02-04 18:53:10 +0000501ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000502{
Michael Sartaina7499c92013-07-01 19:45:50 +0000503 // Need to parse the section list to get the UUIDs, so make sure that's been done.
504 if (!ParseSectionHeaders())
505 return false;
506
Michael Sartainc836ae72013-05-23 20:57:03 +0000507 if (m_uuid.IsValid())
508 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000509 // We have the full build id uuid.
Michael Sartainc836ae72013-05-23 20:57:03 +0000510 *uuid = m_uuid;
511 return true;
512 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000513 else
514 {
Michael Sartain9f4517a2013-07-03 01:52:14 +0000515 if (!m_gnu_debuglink_crc)
516 m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
Michael Sartaina7499c92013-07-01 19:45:50 +0000517 if (m_gnu_debuglink_crc)
518 {
519 // Use 4 bytes of crc from the .gnu_debuglink section.
520 uint32_t uuidt[4] = { m_gnu_debuglink_crc, 0, 0, 0 };
521 uuid->SetBytes (uuidt, sizeof(uuidt));
522 return true;
523 }
524 }
525
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526 return false;
527}
528
Michael Sartaina7499c92013-07-01 19:45:50 +0000529lldb_private::FileSpecList
530ObjectFileELF::GetDebugSymbolFilePaths()
531{
532 FileSpecList file_spec_list;
533
534 if (!m_gnu_debuglink_file.empty())
535 {
536 FileSpec file_spec (m_gnu_debuglink_file.c_str(), false);
537 file_spec_list.Append (file_spec);
538 }
539 return file_spec_list;
540}
541
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000542uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000543ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000545 size_t num_modules = ParseDependentModules();
546 uint32_t num_specs = 0;
547
548 for (unsigned i = 0; i < num_modules; ++i)
549 {
550 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
551 num_specs++;
552 }
553
554 return num_specs;
555}
556
Stephen Wilson499b40e2011-03-30 16:07:05 +0000557Address
Ed Maste54803652013-10-11 17:39:07 +0000558ObjectFileELF::GetImageInfoAddress(Target *target)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000559{
560 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000561 return Address();
562
563 SectionList *section_list = GetSectionList();
564 if (!section_list)
565 return Address();
566
Greg Clayton3046e662013-07-10 01:23:25 +0000567 // Find the SHT_DYNAMIC (.dynamic) section.
568 SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
569 if (!dynsym_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000570 return Address();
Greg Clayton3046e662013-07-10 01:23:25 +0000571 assert (dynsym_section_sp->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000572
Greg Clayton3046e662013-07-10 01:23:25 +0000573 user_id_t dynsym_id = dynsym_section_sp->GetID();
Michael Sartaina7499c92013-07-01 19:45:50 +0000574 const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000575 if (!dynsym_hdr)
576 return Address();
577
Greg Clayton3046e662013-07-10 01:23:25 +0000578 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000579 {
Greg Clayton3046e662013-07-10 01:23:25 +0000580 ELFDynamic &symbol = m_dynamic_symbols[i];
Greg Claytone72dfb32012-02-24 01:59:29 +0000581
Ed Maste54803652013-10-11 17:39:07 +0000582 if (symbol.d_tag == DT_DEBUG)
Greg Clayton3046e662013-07-10 01:23:25 +0000583 {
584 // Compute the offset as the number of previous entries plus the
585 // size of d_tag.
586 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
587 return Address(dynsym_section_sp, offset);
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000588 }
Ed Maste54803652013-10-11 17:39:07 +0000589 else if (symbol.d_tag == DT_MIPS_RLD_MAP && target)
590 {
591 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
592 addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
593 if (dyn_base == LLDB_INVALID_ADDRESS)
594 return Address();
595 Address addr;
596 Error error;
597 if (target->ReadPointerFromMemory(dyn_base + offset, false, error, addr))
598 return addr;
599 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000600 }
601
602 return Address();
603}
604
Jim Ingham672e6f52011-03-07 23:44:08 +0000605lldb_private::Address
606ObjectFileELF::GetEntryPointAddress ()
607{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000608 if (m_entry_point_address.IsValid())
609 return m_entry_point_address;
610
611 if (!ParseHeader() || !IsExecutable())
612 return m_entry_point_address;
613
Greg Clayton3046e662013-07-10 01:23:25 +0000614 SectionList *section_list = GetSectionList();
615 addr_t offset = m_header.e_entry;
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000616
Greg Clayton3046e662013-07-10 01:23:25 +0000617 if (!section_list)
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000618 m_entry_point_address.SetOffset(offset);
Greg Clayton3046e662013-07-10 01:23:25 +0000619 else
620 m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000621 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000622}
623
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000624//----------------------------------------------------------------------
625// ParseDependentModules
626//----------------------------------------------------------------------
627size_t
628ObjectFileELF::ParseDependentModules()
629{
630 if (m_filespec_ap.get())
631 return m_filespec_ap->GetSize();
632
633 m_filespec_ap.reset(new FileSpecList());
634
Michael Sartaina7499c92013-07-01 19:45:50 +0000635 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000636 return 0;
637
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000638 SectionList *section_list = GetSectionList();
639 if (!section_list)
640 return 0;
641
Greg Clayton3046e662013-07-10 01:23:25 +0000642 // Find the SHT_DYNAMIC section.
643 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
644 if (!dynsym)
645 return 0;
646 assert (dynsym->GetObjectFile() == this);
647
648 const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
649 if (!header)
650 return 0;
651 // sh_link: section header index of string table used by entries in the section.
652 Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
653 if (!dynstr)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000654 return 0;
655
656 DataExtractor dynsym_data;
657 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +0000658 if (ReadSectionData(dynsym, dynsym_data) &&
659 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000660 {
661 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +0000662 const lldb::offset_t section_size = dynsym_data.GetByteSize();
663 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000664
665 // The only type of entries we are concerned with are tagged DT_NEEDED,
666 // yielding the name of a required library.
667 while (offset < section_size)
668 {
669 if (!symbol.Parse(dynsym_data, &offset))
670 break;
671
672 if (symbol.d_tag != DT_NEEDED)
673 continue;
674
675 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
676 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000677 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000678 }
679 }
680
681 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000682}
683
684//----------------------------------------------------------------------
685// ParseProgramHeaders
686//----------------------------------------------------------------------
687size_t
688ObjectFileELF::ParseProgramHeaders()
689{
690 // We have already parsed the program headers
691 if (!m_program_headers.empty())
692 return m_program_headers.size();
693
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000694 // If there are no program headers to read we are done.
695 if (m_header.e_phnum == 0)
696 return 0;
697
698 m_program_headers.resize(m_header.e_phnum);
699 if (m_program_headers.size() != m_header.e_phnum)
700 return 0;
701
702 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
Greg Clayton44435ed2012-01-12 05:25:17 +0000703 const elf_off ph_offset = m_header.e_phoff;
704 DataExtractor data;
705 if (GetData (ph_offset, ph_size, data) != ph_size)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000706 return 0;
707
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000708 uint32_t idx;
Greg Claytonc7bece562013-01-25 18:06:21 +0000709 lldb::offset_t offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000710 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000712 if (m_program_headers[idx].Parse(data, &offset) == false)
713 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714 }
715
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000716 if (idx < m_program_headers.size())
717 m_program_headers.resize(idx);
718
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719 return m_program_headers.size();
720}
721
Michael Sartainc836ae72013-05-23 20:57:03 +0000722static bool
Michael Sartaina7499c92013-07-01 19:45:50 +0000723ParseNoteGNUBuildID(DataExtractor &data, lldb_private::UUID &uuid)
Michael Sartainc836ae72013-05-23 20:57:03 +0000724{
725 // Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
726 // BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
Michael Sartainc836ae72013-05-23 20:57:03 +0000727 lldb::offset_t offset = 0;
728 static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
729
730 while (true)
731 {
Ed Mastec113ff82013-12-02 17:49:13 +0000732 ELFNote note = ELFNote();
733 if (!note.Parse(data, &offset))
Michael Sartainc836ae72013-05-23 20:57:03 +0000734 return false;
735
Michael Sartainc836ae72013-05-23 20:57:03 +0000736 // 16 bytes is UUID|MD5, 20 bytes is SHA1
Ed Mastec113ff82013-12-02 17:49:13 +0000737 if (note.n_name == "GNU" && (note.n_type == g_gnu_build_id) &&
738 (note.n_descsz == 16 || note.n_descsz == 20))
Michael Sartainc836ae72013-05-23 20:57:03 +0000739 {
Ed Mastec113ff82013-12-02 17:49:13 +0000740 uint8_t uuidbuf[20];
741 if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == NULL)
Michael Sartainc836ae72013-05-23 20:57:03 +0000742 return false;
Ed Mastec113ff82013-12-02 17:49:13 +0000743 uuid.SetBytes (uuidbuf, note.n_descsz);
744 return true;
Michael Sartainc836ae72013-05-23 20:57:03 +0000745 }
Ed Mastec113ff82013-12-02 17:49:13 +0000746 offset += llvm::RoundUpToAlignment(note.n_descsz, 4);
Michael Sartainc836ae72013-05-23 20:57:03 +0000747 }
748 return false;
749}
Michael Sartaina7499c92013-07-01 19:45:50 +0000750
751//----------------------------------------------------------------------
752// GetSectionHeaderInfo
753//----------------------------------------------------------------------
754size_t
755ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
756 lldb_private::DataExtractor &object_data,
757 const elf::ELFHeader &header,
758 lldb_private::UUID &uuid,
759 std::string &gnu_debuglink_file,
760 uint32_t &gnu_debuglink_crc)
761{
762 // We have already parsed the section headers
763 if (!section_headers.empty())
764 return section_headers.size();
765
766 // If there are no section headers we are done.
767 if (header.e_shnum == 0)
768 return 0;
769
770 section_headers.resize(header.e_shnum);
771 if (section_headers.size() != header.e_shnum)
772 return 0;
773
774 const size_t sh_size = header.e_shnum * header.e_shentsize;
775 const elf_off sh_offset = header.e_shoff;
776 DataExtractor sh_data;
777 if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
778 return 0;
779
780 uint32_t idx;
781 lldb::offset_t offset;
782 for (idx = 0, offset = 0; idx < header.e_shnum; ++idx)
783 {
784 if (section_headers[idx].Parse(sh_data, &offset) == false)
785 break;
786 }
787 if (idx < section_headers.size())
788 section_headers.resize(idx);
789
790 const unsigned strtab_idx = header.e_shstrndx;
791 if (strtab_idx && strtab_idx < section_headers.size())
792 {
793 const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
794 const size_t byte_size = sheader.sh_size;
795 const Elf64_Off offset = sheader.sh_offset;
796 lldb_private::DataExtractor shstr_data;
797
798 if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
799 {
800 for (SectionHeaderCollIter I = section_headers.begin();
801 I != section_headers.end(); ++I)
802 {
803 static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
804 const ELFSectionHeaderInfo &header = *I;
805 const uint64_t section_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
806 ConstString name(shstr_data.PeekCStr(I->sh_name));
807
808 I->section_name = name;
809
810 if (name == g_sect_name_gnu_debuglink)
811 {
812 DataExtractor data;
813 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
814 {
815 lldb::offset_t gnu_debuglink_offset = 0;
816 gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
817 gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
818 data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
819 }
820 }
821
822 if (header.sh_type == SHT_NOTE && !uuid.IsValid())
823 {
824 DataExtractor data;
825 if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size))
826 {
827 ParseNoteGNUBuildID (data, uuid);
828 }
829 }
830 }
831
832 return section_headers.size();
833 }
834 }
835
836 section_headers.clear();
837 return 0;
838}
839
Ashok Thirumurthi4822d922013-07-11 20:39:00 +0000840size_t
841ObjectFileELF::GetProgramHeaderCount()
842{
843 return ParseProgramHeaders();
844}
845
846const elf::ELFProgramHeader *
847ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id)
848{
849 if (!id || !ParseProgramHeaders())
850 return NULL;
851
852 if (--id < m_program_headers.size())
853 return &m_program_headers[id];
854
855 return NULL;
856}
857
858DataExtractor
859ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id)
860{
861 const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id);
862 if (segment_header == NULL)
863 return DataExtractor();
864 return DataExtractor(m_data, segment_header->p_offset, segment_header->p_filesz);
865}
866
Michael Sartaina7499c92013-07-01 19:45:50 +0000867//----------------------------------------------------------------------
868// ParseSectionHeaders
869//----------------------------------------------------------------------
870size_t
871ObjectFileELF::ParseSectionHeaders()
872{
873 return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
874}
875
Michael Sartaina7499c92013-07-01 19:45:50 +0000876const ObjectFileELF::ELFSectionHeaderInfo *
877ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
878{
Ashok Thirumurthi4822d922013-07-11 20:39:00 +0000879 if (!id || !ParseSectionHeaders())
Michael Sartaina7499c92013-07-01 19:45:50 +0000880 return NULL;
881
882 if (--id < m_section_headers.size())
883 return &m_section_headers[id];
884
885 return NULL;
886}
887
Greg Clayton3046e662013-07-10 01:23:25 +0000888void
889ObjectFileELF::CreateSections(SectionList &unified_section_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000890{
Greg Clayton3046e662013-07-10 01:23:25 +0000891 if (!m_sections_ap.get() && ParseSectionHeaders())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892 {
893 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000894
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000895 for (SectionHeaderCollIter I = m_section_headers.begin();
896 I != m_section_headers.end(); ++I)
897 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000898 const ELFSectionHeaderInfo &header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000899
Michael Sartaina7499c92013-07-01 19:45:50 +0000900 ConstString& name = I->section_name;
Greg Clayton47037bc2012-03-27 02:40:46 +0000901 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
902 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000903
Greg Clayton4ceb9982010-07-21 22:54:26 +0000904 static ConstString g_sect_name_text (".text");
905 static ConstString g_sect_name_data (".data");
906 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +0000907 static ConstString g_sect_name_tdata (".tdata");
908 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +0000909 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
910 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
911 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
912 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
913 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
914 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
915 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
916 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
917 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
918 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
919 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
920 static ConstString g_sect_name_eh_frame (".eh_frame");
921
922 SectionType sect_type = eSectionTypeOther;
923
Greg Clayton741f3f92012-03-27 21:10:07 +0000924 bool is_thread_specific = false;
Michael Sartaina7499c92013-07-01 19:45:50 +0000925
Greg Clayton4ceb9982010-07-21 22:54:26 +0000926 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
927 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
928 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +0000929 else if (name == g_sect_name_tdata)
930 {
931 sect_type = eSectionTypeData;
932 is_thread_specific = true;
933 }
934 else if (name == g_sect_name_tbss)
935 {
936 sect_type = eSectionTypeZeroFill;
937 is_thread_specific = true;
938 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000939 // .debug_abbrev – Abbreviations used in the .debug_info section
940 // .debug_aranges – Lookup table for mapping addresses to compilation units
941 // .debug_frame – Call frame information
942 // .debug_info – The core DWARF information section
943 // .debug_line – Line number information
944 // .debug_loc – Location lists used in DW_AT_location attributes
945 // .debug_macinfo – Macro information
946 // .debug_pubnames – Lookup table for mapping object and function names to compilation units
947 // .debug_pubtypes – Lookup table for mapping type names to compilation units
948 // .debug_ranges – Address ranges used in DW_AT_ranges attributes
949 // .debug_str – String table used in .debug_info
Michael Sartain3cf443d2013-07-17 00:26:30 +0000950 // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
951 // MISSING? .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
Michael Sartaina7499c92013-07-01 19:45:50 +0000952 // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
Greg Clayton4ceb9982010-07-21 22:54:26 +0000953 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
954 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
955 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
956 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
957 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
958 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
959 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
960 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
961 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
962 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
963 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
964 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
Michael Sartaina7499c92013-07-01 19:45:50 +0000965
966 switch (header.sh_type)
Michael Sartainc836ae72013-05-23 20:57:03 +0000967 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000968 case SHT_SYMTAB:
969 assert (sect_type == eSectionTypeOther);
970 sect_type = eSectionTypeELFSymbolTable;
971 break;
972 case SHT_DYNSYM:
973 assert (sect_type == eSectionTypeOther);
974 sect_type = eSectionTypeELFDynamicSymbols;
975 break;
976 case SHT_RELA:
977 case SHT_REL:
978 assert (sect_type == eSectionTypeOther);
979 sect_type = eSectionTypeELFRelocationEntries;
980 break;
981 case SHT_DYNAMIC:
982 assert (sect_type == eSectionTypeOther);
983 sect_type = eSectionTypeELFDynamicLinkInfo;
984 break;
Michael Sartainc836ae72013-05-23 20:57:03 +0000985 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000986
Greg Clayton3046e662013-07-10 01:23:25 +0000987 SectionSP section_sp (new Section(GetModule(), // Module to which this section belongs.
988 this, // ObjectFile to which this section belongs and should read section data from.
989 SectionIndex(I), // Section ID.
990 name, // Section name.
991 sect_type, // Section type.
992 header.sh_addr, // VM address.
993 vm_size, // VM size in bytes of this section.
994 header.sh_offset, // Offset of this section in the file.
995 file_size, // Size of the section as found in the file.
996 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000997
Greg Clayton741f3f92012-03-27 21:10:07 +0000998 if (is_thread_specific)
999 section_sp->SetIsThreadSpecific (is_thread_specific);
1000 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001 }
1002 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001003
Greg Clayton3046e662013-07-10 01:23:25 +00001004 if (m_sections_ap.get())
1005 {
1006 if (GetType() == eTypeDebugInfo)
1007 {
1008 static const SectionType g_sections[] =
1009 {
1010 eSectionTypeDWARFDebugAranges,
1011 eSectionTypeDWARFDebugInfo,
1012 eSectionTypeDWARFDebugAbbrev,
1013 eSectionTypeDWARFDebugFrame,
1014 eSectionTypeDWARFDebugLine,
1015 eSectionTypeDWARFDebugStr,
1016 eSectionTypeDWARFDebugLoc,
1017 eSectionTypeDWARFDebugMacInfo,
1018 eSectionTypeDWARFDebugPubNames,
1019 eSectionTypeDWARFDebugPubTypes,
1020 eSectionTypeDWARFDebugRanges,
1021 eSectionTypeELFSymbolTable,
1022 };
1023 SectionList *elf_section_list = m_sections_ap.get();
1024 for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
1025 {
1026 SectionType section_type = g_sections[idx];
1027 SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
1028 if (section_sp)
1029 {
1030 SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
1031 if (module_section_sp)
1032 unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
1033 else
1034 unified_section_list.AddSection (section_sp);
1035 }
1036 }
1037 }
1038 else
1039 {
1040 unified_section_list = *m_sections_ap;
1041 }
1042 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043}
1044
Greg Clayton3046e662013-07-10 01:23:25 +00001045// private
Michael Sartaina7499c92013-07-01 19:45:50 +00001046unsigned
Greg Clayton3046e662013-07-10 01:23:25 +00001047ObjectFileELF::ParseSymbols (Symtab *symtab,
1048 user_id_t start_id,
1049 SectionList *section_list,
1050 const size_t num_symbols,
1051 const DataExtractor &symtab_data,
1052 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001054 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001055 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001056
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057 static ConstString text_section_name(".text");
1058 static ConstString init_section_name(".init");
1059 static ConstString fini_section_name(".fini");
1060 static ConstString ctors_section_name(".ctors");
1061 static ConstString dtors_section_name(".dtors");
1062
1063 static ConstString data_section_name(".data");
1064 static ConstString rodata_section_name(".rodata");
1065 static ConstString rodata1_section_name(".rodata1");
1066 static ConstString data2_section_name(".data1");
1067 static ConstString bss_section_name(".bss");
1068
Greg Clayton9594f4c2013-04-13 23:17:23 +00001069 //StreamFile strm(stdout, false);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001070 unsigned i;
1071 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001073 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 break;
Greg Clayton9594f4c2013-04-13 23:17:23 +00001075
1076 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
1077
1078 // No need to add symbols that have no names
1079 if (symbol_name == NULL || symbol_name[0] == '\0')
1080 continue;
1081
1082 //symbol.Dump (&strm, i, &strtab_data, section_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083
Greg Claytone72dfb32012-02-24 01:59:29 +00001084 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001085 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001086 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001088 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089 {
1090 case SHN_ABS:
1091 symbol_type = eSymbolTypeAbsolute;
1092 break;
1093 case SHN_UNDEF:
1094 symbol_type = eSymbolTypeUndefined;
1095 break;
1096 default:
Greg Claytone72dfb32012-02-24 01:59:29 +00001097 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001098 break;
1099 }
1100
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001101 // If a symbol is undefined do not process it further even if it has a STT type
1102 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001103 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001104 switch (symbol.getType())
1105 {
1106 default:
1107 case STT_NOTYPE:
1108 // The symbol's type is not specified.
1109 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001111 case STT_OBJECT:
1112 // The symbol is associated with a data object, such as a variable,
1113 // an array, etc.
1114 symbol_type = eSymbolTypeData;
1115 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001117 case STT_FUNC:
1118 // The symbol is associated with a function or other executable code.
1119 symbol_type = eSymbolTypeCode;
1120 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001121
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001122 case STT_SECTION:
1123 // The symbol is associated with a section. Symbol table entries of
1124 // this type exist primarily for relocation and normally have
1125 // STB_LOCAL binding.
1126 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001128 case STT_FILE:
1129 // Conventionally, the symbol's name gives the name of the source
1130 // file associated with the object file. A file symbol has STB_LOCAL
1131 // binding, its section index is SHN_ABS, and it precedes the other
1132 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001133 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001134 break;
Matt Kopec00049b82013-02-27 20:13:38 +00001135
1136 case STT_GNU_IFUNC:
1137 // The symbol is associated with an indirect function. The actual
1138 // function will be resolved if it is referenced.
1139 symbol_type = eSymbolTypeResolver;
1140 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00001141 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001142 }
1143
1144 if (symbol_type == eSymbolTypeInvalid)
1145 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001146 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001148 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149 if (sect_name == text_section_name ||
1150 sect_name == init_section_name ||
1151 sect_name == fini_section_name ||
1152 sect_name == ctors_section_name ||
1153 sect_name == dtors_section_name)
1154 {
1155 symbol_type = eSymbolTypeCode;
1156 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001157 else if (sect_name == data_section_name ||
1158 sect_name == data2_section_name ||
1159 sect_name == rodata_section_name ||
1160 sect_name == rodata1_section_name ||
1161 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162 {
1163 symbol_type = eSymbolTypeData;
1164 }
1165 }
1166 }
1167
Greg Clayton3046e662013-07-10 01:23:25 +00001168 // If the symbol section we've found has no data (SHT_NOBITS), then check the module section
1169 // 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 +00001170 if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
1171 {
1172 ModuleSP module_sp(GetModule());
1173 if (module_sp)
1174 {
Greg Clayton3046e662013-07-10 01:23:25 +00001175 SectionList *module_section_list = module_sp->GetSectionList();
1176 if (module_section_list && module_section_list != section_list)
Michael Sartaina7499c92013-07-01 19:45:50 +00001177 {
1178 const ConstString &sect_name = symbol_section_sp->GetName();
Greg Clayton3046e662013-07-10 01:23:25 +00001179 lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name));
Michael Sartaina7499c92013-07-01 19:45:50 +00001180 if (section_sp && section_sp->GetFileSize())
1181 {
1182 symbol_section_sp = section_sp;
1183 }
1184 }
1185 }
1186 }
1187
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001188 uint64_t symbol_value = symbol.st_value;
Greg Claytone72dfb32012-02-24 01:59:29 +00001189 if (symbol_section_sp)
1190 symbol_value -= symbol_section_sp->GetFileAddress();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001191 bool is_global = symbol.getBinding() == STB_GLOBAL;
1192 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Greg Clayton47037bc2012-03-27 02:40:46 +00001193 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001194 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +00001195 i + start_id, // ID is the original symbol table index.
1196 symbol_name, // Symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001197 is_mangled, // Is the symbol name mangled?
Greg Claytone72dfb32012-02-24 01:59:29 +00001198 symbol_type, // Type of this symbol
1199 is_global, // Is this globally visible?
1200 false, // Is this symbol debug info?
1201 false, // Is this symbol a trampoline?
1202 false, // Is this symbol artificial?
1203 symbol_section_sp, // Section in which this symbol is defined or null.
1204 symbol_value, // Offset in section or symbol value.
1205 symbol.st_size, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001206 true, // Size is valid
Greg Claytone72dfb32012-02-24 01:59:29 +00001207 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001208 symtab->AddSymbol(dc_symbol);
1209 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001210
1211 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212}
1213
Stephen Wilson499b40e2011-03-30 16:07:05 +00001214unsigned
Greg Clayton3046e662013-07-10 01:23:25 +00001215ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001216{
Greg Clayton3046e662013-07-10 01:23:25 +00001217 if (symtab->GetObjectFile() != this)
1218 {
1219 // If the symbol table section is owned by a different object file, have it do the
1220 // parsing.
1221 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
1222 return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
1223 }
1224
1225 // Get section list for this object file.
1226 SectionList *section_list = m_sections_ap.get();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001227 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001228 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001229
Greg Clayton3046e662013-07-10 01:23:25 +00001230 user_id_t symtab_id = symtab->GetID();
1231 const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
Michael Sartaina7499c92013-07-01 19:45:50 +00001232 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
1233 symtab_hdr->sh_type == SHT_DYNSYM);
1234
Greg Clayton3046e662013-07-10 01:23:25 +00001235 // sh_link: section header index of associated string table.
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001236 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001237 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001238 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Greg Clayton3046e662013-07-10 01:23:25 +00001239
Stephen Wilson499b40e2011-03-30 16:07:05 +00001240 unsigned num_symbols = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001241 if (symtab && strtab)
1242 {
Greg Clayton3046e662013-07-10 01:23:25 +00001243 assert (symtab->GetObjectFile() == this);
1244 assert (strtab->GetObjectFile() == this);
1245
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001246 DataExtractor symtab_data;
1247 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001248 if (ReadSectionData(symtab, symtab_data) &&
1249 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001250 {
Greg Clayton3046e662013-07-10 01:23:25 +00001251 size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
1252
Stephen Wilson499b40e2011-03-30 16:07:05 +00001253 num_symbols = ParseSymbols(symbol_table, start_id,
Greg Clayton3046e662013-07-10 01:23:25 +00001254 section_list, num_symbols,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001255 symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001256 }
1257 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00001258
1259 return num_symbols;
1260}
1261
1262size_t
1263ObjectFileELF::ParseDynamicSymbols()
1264{
1265 if (m_dynamic_symbols.size())
1266 return m_dynamic_symbols.size();
1267
Stephen Wilson499b40e2011-03-30 16:07:05 +00001268 SectionList *section_list = GetSectionList();
1269 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001270 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001271
Greg Clayton3046e662013-07-10 01:23:25 +00001272 // Find the SHT_DYNAMIC section.
1273 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001274 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00001275 return 0;
Greg Clayton3046e662013-07-10 01:23:25 +00001276 assert (dynsym->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001277
1278 ELFDynamic symbol;
1279 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001280 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001281 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001282 const lldb::offset_t section_size = dynsym_data.GetByteSize();
1283 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001284
1285 while (cursor < section_size)
1286 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00001287 if (!symbol.Parse(dynsym_data, &cursor))
1288 break;
1289
1290 m_dynamic_symbols.push_back(symbol);
1291 }
1292 }
1293
1294 return m_dynamic_symbols.size();
1295}
1296
1297const ELFDynamic *
1298ObjectFileELF::FindDynamicSymbol(unsigned tag)
1299{
1300 if (!ParseDynamicSymbols())
1301 return NULL;
1302
Stephen Wilson499b40e2011-03-30 16:07:05 +00001303 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
1304 DynamicSymbolCollIter E = m_dynamic_symbols.end();
1305 for ( ; I != E; ++I)
1306 {
1307 ELFDynamic *symbol = &*I;
1308
1309 if (symbol->d_tag == tag)
1310 return symbol;
1311 }
1312
1313 return NULL;
1314}
1315
Stephen Wilson499b40e2011-03-30 16:07:05 +00001316unsigned
1317ObjectFileELF::PLTRelocationType()
1318{
Michael Sartainf7899542013-08-22 21:25:53 +00001319 // DT_PLTREL
1320 // This member specifies the type of relocation entry to which the
1321 // procedure linkage table refers. The d_val member holds DT_REL or
1322 // DT_RELA, as appropriate. All relocations in a procedure linkage table
1323 // must use the same relocation.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001324 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
1325
1326 if (symbol)
1327 return symbol->d_val;
1328
1329 return 0;
1330}
1331
1332static unsigned
1333ParsePLTRelocations(Symtab *symbol_table,
1334 user_id_t start_id,
1335 unsigned rel_type,
1336 const ELFHeader *hdr,
1337 const ELFSectionHeader *rel_hdr,
1338 const ELFSectionHeader *plt_hdr,
1339 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00001340 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001341 DataExtractor &rel_data,
1342 DataExtractor &symtab_data,
1343 DataExtractor &strtab_data)
1344{
1345 ELFRelocation rel(rel_type);
1346 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001347 lldb::offset_t offset = 0;
Michael Sartainf7899542013-08-22 21:25:53 +00001348 // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes.
1349 // So round the entsize up by the alignment if addralign is set.
1350 const elf_xword plt_entsize = plt_hdr->sh_addralign ?
1351 llvm::RoundUpToAlignment (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
Greg Claytonc7bece562013-01-25 18:06:21 +00001352 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001353
1354 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
1355 reloc_info_fn reloc_type;
1356 reloc_info_fn reloc_symbol;
1357
Greg Claytond091afe2012-11-12 22:53:16 +00001358 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +00001359 {
1360 reloc_type = ELFRelocation::RelocType32;
1361 reloc_symbol = ELFRelocation::RelocSymbol32;
1362 }
1363 else
1364 {
1365 reloc_type = ELFRelocation::RelocType64;
1366 reloc_symbol = ELFRelocation::RelocSymbol64;
1367 }
1368
1369 unsigned slot_type = hdr->GetRelocationJumpSlotType();
1370 unsigned i;
1371 for (i = 0; i < num_relocations; ++i)
1372 {
1373 if (rel.Parse(rel_data, &offset) == false)
1374 break;
1375
1376 if (reloc_type(rel) != slot_type)
1377 continue;
1378
Greg Claytonc7bece562013-01-25 18:06:21 +00001379 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001380 uint64_t plt_index = (i + 1) * plt_entsize;
1381
1382 if (!symbol.Parse(symtab_data, &symbol_offset))
1383 break;
1384
1385 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00001386 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Stephen Wilson499b40e2011-03-30 16:07:05 +00001387
1388 Symbol jump_symbol(
1389 i + start_id, // Symbol table index
1390 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00001391 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00001392 eSymbolTypeTrampoline, // Type of this symbol
1393 false, // Is this globally visible?
1394 false, // Is this symbol debug info?
1395 true, // Is this symbol a trampoline?
1396 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00001397 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001398 plt_index, // Offset in section or symbol value.
1399 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00001400 true, // Size is valid
Stephen Wilson499b40e2011-03-30 16:07:05 +00001401 0); // Symbol flags.
1402
1403 symbol_table->AddSymbol(jump_symbol);
1404 }
1405
1406 return i;
1407}
1408
1409unsigned
1410ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
1411 user_id_t start_id,
Michael Sartaina7499c92013-07-01 19:45:50 +00001412 const ELFSectionHeaderInfo *rel_hdr,
Stephen Wilson499b40e2011-03-30 16:07:05 +00001413 user_id_t rel_id)
1414{
1415 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
1416
Greg Clayton3046e662013-07-10 01:23:25 +00001417 // The link field points to the associated symbol table. The info field
Stephen Wilson499b40e2011-03-30 16:07:05 +00001418 // points to the section holding the plt.
1419 user_id_t symtab_id = rel_hdr->sh_link;
1420 user_id_t plt_id = rel_hdr->sh_info;
1421
1422 if (!symtab_id || !plt_id)
1423 return 0;
1424
1425 // Section ID's are ones based;
1426 symtab_id++;
1427 plt_id++;
1428
Michael Sartaina7499c92013-07-01 19:45:50 +00001429 const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001430 if (!plt_hdr)
1431 return 0;
1432
Michael Sartaina7499c92013-07-01 19:45:50 +00001433 const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001434 if (!sym_hdr)
1435 return 0;
1436
Greg Clayton3046e662013-07-10 01:23:25 +00001437 SectionList *section_list = m_sections_ap.get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00001438 if (!section_list)
1439 return 0;
1440
1441 Section *rel_section = section_list->FindSectionByID(rel_id).get();
1442 if (!rel_section)
1443 return 0;
1444
Greg Claytone72dfb32012-02-24 01:59:29 +00001445 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
1446 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001447 return 0;
1448
1449 Section *symtab = section_list->FindSectionByID(symtab_id).get();
1450 if (!symtab)
1451 return 0;
1452
Greg Clayton3046e662013-07-10 01:23:25 +00001453 // sh_link points to associated string table.
Stephen Wilson499b40e2011-03-30 16:07:05 +00001454 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
1455 if (!strtab)
1456 return 0;
1457
1458 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001459 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001460 return 0;
1461
1462 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001463 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001464 return 0;
1465
1466 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001467 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00001468 return 0;
1469
1470 unsigned rel_type = PLTRelocationType();
1471 if (!rel_type)
1472 return 0;
1473
Greg Claytone72dfb32012-02-24 01:59:29 +00001474 return ParsePLTRelocations (symbol_table,
1475 start_id,
1476 rel_type,
1477 &m_header,
1478 rel_hdr,
1479 plt_hdr,
1480 sym_hdr,
1481 plt_section_sp,
1482 rel_data,
1483 symtab_data,
1484 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001485}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001486
1487Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001488ObjectFileELF::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001489{
Michael Sartaina7499c92013-07-01 19:45:50 +00001490 ModuleSP module_sp(GetModule());
Greg Clayton3046e662013-07-10 01:23:25 +00001491 if (!module_sp)
1492 return NULL;
Michael Sartaina7499c92013-07-01 19:45:50 +00001493
Greg Clayton3046e662013-07-10 01:23:25 +00001494 // We always want to use the main object file so we (hopefully) only have one cached copy
1495 // of our symtab, dynamic sections, etc.
1496 ObjectFile *module_obj_file = module_sp->GetObjectFile();
1497 if (module_obj_file && module_obj_file != this)
1498 return module_obj_file->GetSymtab();
1499
1500 if (m_symtab_ap.get() == NULL)
1501 {
1502 SectionList *section_list = GetSectionList();
Michael Sartaina7499c92013-07-01 19:45:50 +00001503 if (!section_list)
1504 return NULL;
1505
Greg Clayton3046e662013-07-10 01:23:25 +00001506 uint64_t symbol_id = 0;
1507 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Stephen Wilson499b40e2011-03-30 16:07:05 +00001508
Greg Clayton3046e662013-07-10 01:23:25 +00001509 m_symtab_ap.reset(new Symtab(this));
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001510
Michael Sartaina7499c92013-07-01 19:45:50 +00001511 // Sharable objects and dynamic executables usually have 2 distinct symbol
1512 // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
1513 // version of the symtab that only contains global symbols. The information found
1514 // in the dynsym is therefore also found in the symtab, while the reverse is not
1515 // necessarily true.
Greg Clayton3046e662013-07-10 01:23:25 +00001516 Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
1517 if (!symtab)
Michael Sartaina7499c92013-07-01 19:45:50 +00001518 {
1519 // The symtab section is non-allocable and can be stripped, so if it doesn't exist
1520 // then use the dynsym section which should always be there.
Greg Clayton3046e662013-07-10 01:23:25 +00001521 symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
Michael Sartaina7499c92013-07-01 19:45:50 +00001522 }
Greg Clayton3046e662013-07-10 01:23:25 +00001523 if (symtab)
1524 symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
Michael Sartaina7499c92013-07-01 19:45:50 +00001525
Michael Sartainf7899542013-08-22 21:25:53 +00001526 // DT_JMPREL
1527 // If present, this entry's d_ptr member holds the address of relocation
1528 // entries associated solely with the procedure linkage table. Separating
1529 // these relocation entries lets the dynamic linker ignore them during
1530 // process initialization, if lazy binding is enabled. If this entry is
1531 // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
1532 // also be present.
Greg Clayton3046e662013-07-10 01:23:25 +00001533 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
1534 if (symbol)
Michael Sartaina7499c92013-07-01 19:45:50 +00001535 {
Michael Sartainf7899542013-08-22 21:25:53 +00001536 // Synthesize trampoline symbols to help navigate the PLT.
Greg Clayton3046e662013-07-10 01:23:25 +00001537 addr_t addr = symbol->d_ptr;
1538 Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
1539 if (reloc_section)
Michael Sartaina7499c92013-07-01 19:45:50 +00001540 {
Greg Clayton3046e662013-07-10 01:23:25 +00001541 user_id_t reloc_id = reloc_section->GetID();
1542 const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
1543 assert(reloc_header);
Michael Sartaina7499c92013-07-01 19:45:50 +00001544
Greg Clayton3046e662013-07-10 01:23:25 +00001545 ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
Michael Sartaina7499c92013-07-01 19:45:50 +00001546 }
1547 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001548 }
Greg Clayton3046e662013-07-10 01:23:25 +00001549 return m_symtab_ap.get();
1550}
1551
Ashok Thirumurthi35729bb2013-09-24 15:34:13 +00001552Symbol *
1553ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
1554{
1555 if (!m_symtab_ap.get())
1556 return nullptr; // GetSymtab() should be called first.
1557
1558 const SectionList *section_list = GetSectionList();
1559 if (!section_list)
1560 return nullptr;
1561
1562 if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
1563 {
1564 AddressRange range;
1565 if (eh_frame->GetAddressRange (so_addr, range))
1566 {
1567 const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
1568 Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
1569 if (symbol)
1570 return symbol;
1571
1572 // Note that a (stripped) symbol won't be found by GetSymtab()...
1573 lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
1574 if (eh_sym_section_sp.get())
1575 {
1576 addr_t section_base = eh_sym_section_sp->GetFileAddress();
1577 addr_t offset = file_addr - section_base;
1578 uint64_t symbol_id = m_symtab_ap->GetNumSymbols();
1579
1580 Symbol eh_symbol(
1581 symbol_id, // Symbol table index.
1582 "???", // Symbol name.
1583 false, // Is the symbol name mangled?
1584 eSymbolTypeCode, // Type of this symbol.
1585 true, // Is this globally visible?
1586 false, // Is this symbol debug info?
1587 false, // Is this symbol a trampoline?
1588 true, // Is this symbol artificial?
1589 eh_sym_section_sp, // Section in which this symbol is defined or null.
1590 offset, // Offset in section or symbol value.
1591 range.GetByteSize(), // Size in bytes of this symbol.
1592 true, // Size is valid.
1593 0); // Symbol flags.
1594 if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
1595 return m_symtab_ap->SymbolAtIndex(symbol_id);
1596 }
1597 }
1598 }
1599 return nullptr;
1600}
1601
1602
Greg Clayton3046e662013-07-10 01:23:25 +00001603bool
1604ObjectFileELF::IsStripped ()
1605{
1606 // TODO: determine this for ELF
1607 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608}
1609
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001610//===----------------------------------------------------------------------===//
1611// Dump
1612//
1613// Dump the specifics of the runtime file container (such as any headers
1614// segments, sections, etc).
1615//----------------------------------------------------------------------
1616void
1617ObjectFileELF::Dump(Stream *s)
1618{
1619 DumpELFHeader(s, m_header);
1620 s->EOL();
1621 DumpELFProgramHeaders(s);
1622 s->EOL();
1623 DumpELFSectionHeaders(s);
1624 s->EOL();
1625 SectionList *section_list = GetSectionList();
1626 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00001627 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001628 Symtab *symtab = GetSymtab();
1629 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00001630 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001631 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001632 DumpDependentModules(s);
1633 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001634}
1635
1636//----------------------------------------------------------------------
1637// DumpELFHeader
1638//
1639// Dump the ELF header to the specified output stream
1640//----------------------------------------------------------------------
1641void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001642ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001643{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001644 s->PutCString("ELF Header\n");
1645 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
1646 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
1647 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
1648 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
1649 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
1650 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
1651 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001652
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001653 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
1654 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001655 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
1656 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
1657 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
1658
1659 s->Printf("e_type = 0x%4.4x ", header.e_type);
1660 DumpELFHeader_e_type(s, header.e_type);
1661 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
1662 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00001663 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
1664 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
1665 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001666 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
1667 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
1668 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
1669 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
1670 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
1671 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
1672 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
1673}
1674
1675//----------------------------------------------------------------------
1676// DumpELFHeader_e_type
1677//
1678// Dump an token value for the ELF header member e_type
1679//----------------------------------------------------------------------
1680void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001681ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001682{
1683 switch (e_type)
1684 {
1685 case ET_NONE: *s << "ET_NONE"; break;
1686 case ET_REL: *s << "ET_REL"; break;
1687 case ET_EXEC: *s << "ET_EXEC"; break;
1688 case ET_DYN: *s << "ET_DYN"; break;
1689 case ET_CORE: *s << "ET_CORE"; break;
1690 default:
1691 break;
1692 }
1693}
1694
1695//----------------------------------------------------------------------
1696// DumpELFHeader_e_ident_EI_DATA
1697//
1698// Dump an token value for the ELF header member e_ident[EI_DATA]
1699//----------------------------------------------------------------------
1700void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001701ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001702{
1703 switch (ei_data)
1704 {
1705 case ELFDATANONE: *s << "ELFDATANONE"; break;
1706 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
1707 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
1708 default:
1709 break;
1710 }
1711}
1712
1713
1714//----------------------------------------------------------------------
1715// DumpELFProgramHeader
1716//
1717// Dump a single ELF program header to the specified output stream
1718//----------------------------------------------------------------------
1719void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001720ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001721{
1722 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001723 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
1724 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 +00001725
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001726 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001727 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001728}
1729
1730//----------------------------------------------------------------------
1731// DumpELFProgramHeader_p_type
1732//
1733// Dump an token value for the ELF program header member p_type which
1734// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001735// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001736void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001737ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001738{
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001739 const int kStrWidth = 15;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001740 switch (p_type)
1741 {
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001742 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
1743 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
1744 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
1745 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
1746 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
1747 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
1748 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
1749 CASE_AND_STREAM(s, PT_TLS , kStrWidth);
1750 CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001751 default:
1752 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
1753 break;
1754 }
1755}
1756
1757
1758//----------------------------------------------------------------------
1759// DumpELFProgramHeader_p_flags
1760//
1761// Dump an token value for the ELF program header member p_flags
1762//----------------------------------------------------------------------
1763void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001764ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001765{
1766 *s << ((p_flags & PF_X) ? "PF_X" : " ")
1767 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
1768 << ((p_flags & PF_W) ? "PF_W" : " ")
1769 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
1770 << ((p_flags & PF_R) ? "PF_R" : " ");
1771}
1772
1773//----------------------------------------------------------------------
1774// DumpELFProgramHeaders
1775//
1776// Dump all of the ELF program header to the specified output stream
1777//----------------------------------------------------------------------
1778void
1779ObjectFileELF::DumpELFProgramHeaders(Stream *s)
1780{
1781 if (ParseProgramHeaders())
1782 {
1783 s->PutCString("Program Headers\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001784 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001785 "p_filesz p_memsz p_flags p_align\n");
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00001786 s->PutCString("==== --------------- -------- -------- -------- "
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001787 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001788
1789 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001790 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
1791 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001792 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001793 s->Printf("[%2u] ", idx);
1794 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001795 s->EOL();
1796 }
1797 }
1798}
1799
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001800//----------------------------------------------------------------------
1801// DumpELFSectionHeader
1802//
1803// Dump a single ELF section header to the specified output stream
1804//----------------------------------------------------------------------
1805void
Michael Sartaina7499c92013-07-01 19:45:50 +00001806ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001807{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001808 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001809 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00001810 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001811 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00001812 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 +00001813 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00001814 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001815}
1816
1817//----------------------------------------------------------------------
1818// DumpELFSectionHeader_sh_type
1819//
1820// Dump an token value for the ELF section header member sh_type which
1821// describes the type of the section
1822//----------------------------------------------------------------------
1823void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001824ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001825{
1826 const int kStrWidth = 12;
1827 switch (sh_type)
1828 {
1829 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
1830 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
1831 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
1832 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
1833 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
1834 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
1835 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
1836 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
1837 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
1838 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
1839 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
1840 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
1841 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
1842 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
1843 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
1844 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
1845 default:
1846 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
1847 break;
1848 }
1849}
1850
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001851//----------------------------------------------------------------------
1852// DumpELFSectionHeader_sh_flags
1853//
1854// Dump an token value for the ELF section header member sh_flags
1855//----------------------------------------------------------------------
1856void
Greg Claytonc7bece562013-01-25 18:06:21 +00001857ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001858{
1859 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
1860 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
1861 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
1862 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
1863 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
1864}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001865
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001866//----------------------------------------------------------------------
1867// DumpELFSectionHeaders
1868//
1869// Dump all of the ELF section header to the specified output stream
1870//----------------------------------------------------------------------
1871void
1872ObjectFileELF::DumpELFSectionHeaders(Stream *s)
1873{
Michael Sartaina7499c92013-07-01 19:45:50 +00001874 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001875 return;
1876
1877 s->PutCString("Section Headers\n");
1878 s->PutCString("IDX name type flags "
1879 "addr offset size link info addralgn "
1880 "entsize Name\n");
1881 s->PutCString("==== -------- ------------ -------------------------------- "
1882 "-------- -------- -------- -------- -------- -------- "
1883 "-------- ====================\n");
1884
1885 uint32_t idx = 0;
1886 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1887 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001888 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001889 s->Printf("[%2u] ", idx);
1890 ObjectFileELF::DumpELFSectionHeader(s, *I);
Michael Sartaina7499c92013-07-01 19:45:50 +00001891 const char* section_name = I->section_name.AsCString("");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001892 if (section_name)
1893 *s << ' ' << section_name << "\n";
1894 }
1895}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001896
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001897void
1898ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1899{
1900 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001901
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001902 if (num_modules > 0)
1903 {
1904 s->PutCString("Dependent Modules:\n");
1905 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001906 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001907 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1908 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001909 }
1910 }
1911}
1912
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001913bool
Greg Clayton514487e2011-02-15 21:59:32 +00001914ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001915{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001916 if (!ParseHeader())
1917 return false;
1918
Greg Claytone0d378b2011-03-24 21:19:54 +00001919 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001920 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1921 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001922 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001923}
1924
Greg Clayton9e00b6a652011-07-09 00:41:34 +00001925ObjectFile::Type
1926ObjectFileELF::CalculateType()
1927{
1928 switch (m_header.e_type)
1929 {
1930 case llvm::ELF::ET_NONE:
1931 // 0 - No file type
1932 return eTypeUnknown;
1933
1934 case llvm::ELF::ET_REL:
1935 // 1 - Relocatable file
1936 return eTypeObjectFile;
1937
1938 case llvm::ELF::ET_EXEC:
1939 // 2 - Executable file
1940 return eTypeExecutable;
1941
1942 case llvm::ELF::ET_DYN:
1943 // 3 - Shared object file
1944 return eTypeSharedLibrary;
1945
1946 case ET_CORE:
1947 // 4 - Core file
1948 return eTypeCoreFile;
1949
1950 default:
1951 break;
1952 }
1953 return eTypeUnknown;
1954}
1955
1956ObjectFile::Strata
1957ObjectFileELF::CalculateStrata()
1958{
1959 switch (m_header.e_type)
1960 {
1961 case llvm::ELF::ET_NONE:
1962 // 0 - No file type
1963 return eStrataUnknown;
1964
1965 case llvm::ELF::ET_REL:
1966 // 1 - Relocatable file
1967 return eStrataUnknown;
1968
1969 case llvm::ELF::ET_EXEC:
1970 // 2 - Executable file
1971 // TODO: is there any way to detect that an executable is a kernel
1972 // related executable by inspecting the program headers, section
1973 // headers, symbols, or any other flag bits???
1974 return eStrataUser;
1975
1976 case llvm::ELF::ET_DYN:
1977 // 3 - Shared object file
1978 // TODO: is there any way to detect that an shared library is a kernel
1979 // related executable by inspecting the program headers, section
1980 // headers, symbols, or any other flag bits???
1981 return eStrataUnknown;
1982
1983 case ET_CORE:
1984 // 4 - Core file
1985 // TODO: is there any way to detect that an core file is a kernel
1986 // related executable by inspecting the program headers, section
1987 // headers, symbols, or any other flag bits???
1988 return eStrataUnknown;
1989
1990 default:
1991 break;
1992 }
1993 return eStrataUnknown;
1994}
1995