blob: b16a2cda10f707d5497b746aebcd4a66913d3f24 [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>
Tamas Berghammer9fa11472015-10-27 10:43:27 +000014#include <unordered_map>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015
Stephen Wilson2ab0a582011-01-15 00:08:44 +000016#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Core/DataBuffer.h"
18#include "lldb/Core/Error.h"
Stephen Wilsonf325ba92010-07-13 23:07:23 +000019#include "lldb/Core/FileSpecList.h"
Ed Mastec113ff82013-12-02 17:49:13 +000020#include "lldb/Core/Log.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000021#include "lldb/Core/Module.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000022#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/PluginManager.h"
24#include "lldb/Core/Section.h"
25#include "lldb/Core/Stream.h"
Todd Fiala4339f3a2014-03-25 19:29:09 +000026#include "lldb/Core/Timer.h"
Ashok Thirumurthi35729bb2013-09-24 15:34:13 +000027#include "lldb/Symbol/DWARFCallFrameInfo.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000028#include "lldb/Symbol/SymbolContext.h"
Steve Pucci9e02dac2014-02-06 19:02:19 +000029#include "lldb/Target/SectionLoadList.h"
Ed Maste54803652013-10-11 17:39:07 +000030#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
Stephen Wilson499b40e2011-03-30 16:07:05 +000032#include "llvm/ADT/PointerUnion.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000033#include "llvm/ADT/StringRef.h"
Zachary Turner736d4d82014-06-25 05:42:32 +000034#include "llvm/Support/MathExtras.h"
Stephen Wilson499b40e2011-03-30 16:07:05 +000035
Stephen Wilsonf325ba92010-07-13 23:07:23 +000036#define CASE_AND_STREAM(s, def, width) \
37 case def: s->Printf("%-*s", width, #def); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039using namespace lldb;
40using namespace lldb_private;
Stephen Wilsonf325ba92010-07-13 23:07:23 +000041using namespace elf;
42using namespace llvm::ELF;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043
Stephen Wilson499b40e2011-03-30 16:07:05 +000044namespace {
Todd Fialab91de782014-06-27 16:52:49 +000045
46// ELF note owner definitions
47const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";
48const char *const LLDB_NT_OWNER_GNU = "GNU";
49const char *const LLDB_NT_OWNER_NETBSD = "NetBSD";
Todd Fialacfee9632014-07-16 15:03:10 +000050const char *const LLDB_NT_OWNER_CSR = "csr";
Tamas Berghammerdb037d92015-03-18 10:36:27 +000051const char *const LLDB_NT_OWNER_ANDROID = "Android";
Greg Claytonb704b692015-10-28 18:04:38 +000052const char *const LLDB_NT_OWNER_CORE = "CORE";
53const char *const LLDB_NT_OWNER_LINUX = "LINUX";
Todd Fialab91de782014-06-27 16:52:49 +000054
55// ELF note type definitions
56const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01;
57const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4;
58
59const elf_word LLDB_NT_GNU_ABI_TAG = 0x01;
60const elf_word LLDB_NT_GNU_ABI_SIZE = 16;
61
62const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03;
63
64const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01;
65const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4;
66
67// GNU ABI note OS constants
68const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
69const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
70const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
71
Greg Claytonb704b692015-10-28 18:04:38 +000072// LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants
73#define NT_PRSTATUS 1
74#define NT_PRFPREG 2
75#define NT_PRPSINFO 3
76#define NT_TASKSTRUCT 4
77#define NT_AUXV 6
78#define NT_SIGINFO 0x53494749
79#define NT_FILE 0x46494c45
80#define NT_PRXFPREG 0x46e62b7f
81#define NT_PPC_VMX 0x100
82#define NT_PPC_SPE 0x101
83#define NT_PPC_VSX 0x102
84#define NT_386_TLS 0x200
85#define NT_386_IOPERM 0x201
86#define NT_X86_XSTATE 0x202
87#define NT_S390_HIGH_GPRS 0x300
88#define NT_S390_TIMER 0x301
89#define NT_S390_TODCMP 0x302
90#define NT_S390_TODPREG 0x303
91#define NT_S390_CTRS 0x304
92#define NT_S390_PREFIX 0x305
93#define NT_S390_LAST_BREAK 0x306
94#define NT_S390_SYSTEM_CALL 0x307
95#define NT_S390_TDB 0x308
96#define NT_S390_VXRS_LOW 0x309
97#define NT_S390_VXRS_HIGH 0x30a
98#define NT_ARM_VFP 0x400
99#define NT_ARM_TLS 0x401
100#define NT_ARM_HW_BREAK 0x402
101#define NT_ARM_HW_WATCH 0x403
102#define NT_ARM_SYSTEM_CALL 0x404
103#define NT_METAG_CBUF 0x500
104#define NT_METAG_RPIPE 0x501
105#define NT_METAG_TLS 0x502
106
Stephen Wilson499b40e2011-03-30 16:07:05 +0000107//===----------------------------------------------------------------------===//
108/// @class ELFRelocation
109/// @brief Generic wrapper for ELFRel and ELFRela.
110///
111/// This helper class allows us to parse both ELFRel and ELFRela relocation
112/// entries in a generic manner.
113class ELFRelocation
114{
115public:
116
117 /// Constructs an ELFRelocation entry with a personality as given by @p
118 /// type.
119 ///
120 /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
121 ELFRelocation(unsigned type);
Ed Maste81b4c5f2016-01-04 01:43:47 +0000122
Stephen Wilson499b40e2011-03-30 16:07:05 +0000123 ~ELFRelocation();
124
125 bool
Greg Claytonc7bece562013-01-25 18:06:21 +0000126 Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
Stephen Wilson499b40e2011-03-30 16:07:05 +0000127
128 static unsigned
129 RelocType32(const ELFRelocation &rel);
130
131 static unsigned
132 RelocType64(const ELFRelocation &rel);
133
134 static unsigned
135 RelocSymbol32(const ELFRelocation &rel);
136
137 static unsigned
138 RelocSymbol64(const ELFRelocation &rel);
139
Andrew MacPherson17220c12014-03-05 10:12:43 +0000140 static unsigned
141 RelocOffset32(const ELFRelocation &rel);
142
143 static unsigned
144 RelocOffset64(const ELFRelocation &rel);
145
146 static unsigned
147 RelocAddend32(const ELFRelocation &rel);
148
149 static unsigned
150 RelocAddend64(const ELFRelocation &rel);
151
Stephen Wilson499b40e2011-03-30 16:07:05 +0000152private:
153 typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion;
154
155 RelocUnion reloc;
156};
157
158ELFRelocation::ELFRelocation(unsigned type)
Ed Maste81b4c5f2016-01-04 01:43:47 +0000159{
Andrew MacPherson17220c12014-03-05 10:12:43 +0000160 if (type == DT_REL || type == SHT_REL)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000161 reloc = new ELFRel();
Andrew MacPherson17220c12014-03-05 10:12:43 +0000162 else if (type == DT_RELA || type == SHT_RELA)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000163 reloc = new ELFRela();
164 else {
165 assert(false && "unexpected relocation type");
166 reloc = static_cast<ELFRel*>(NULL);
167 }
168}
169
170ELFRelocation::~ELFRelocation()
171{
172 if (reloc.is<ELFRel*>())
173 delete reloc.get<ELFRel*>();
174 else
Ed Maste81b4c5f2016-01-04 01:43:47 +0000175 delete reloc.get<ELFRela*>();
Stephen Wilson499b40e2011-03-30 16:07:05 +0000176}
177
178bool
Greg Claytonc7bece562013-01-25 18:06:21 +0000179ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
Stephen Wilson499b40e2011-03-30 16:07:05 +0000180{
181 if (reloc.is<ELFRel*>())
182 return reloc.get<ELFRel*>()->Parse(data, offset);
183 else
184 return reloc.get<ELFRela*>()->Parse(data, offset);
185}
186
187unsigned
188ELFRelocation::RelocType32(const ELFRelocation &rel)
189{
190 if (rel.reloc.is<ELFRel*>())
191 return ELFRel::RelocType32(*rel.reloc.get<ELFRel*>());
192 else
193 return ELFRela::RelocType32(*rel.reloc.get<ELFRela*>());
194}
195
196unsigned
197ELFRelocation::RelocType64(const ELFRelocation &rel)
198{
199 if (rel.reloc.is<ELFRel*>())
200 return ELFRel::RelocType64(*rel.reloc.get<ELFRel*>());
201 else
202 return ELFRela::RelocType64(*rel.reloc.get<ELFRela*>());
203}
204
205unsigned
206ELFRelocation::RelocSymbol32(const ELFRelocation &rel)
207{
208 if (rel.reloc.is<ELFRel*>())
209 return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel*>());
210 else
211 return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela*>());
212}
213
214unsigned
215ELFRelocation::RelocSymbol64(const ELFRelocation &rel)
216{
217 if (rel.reloc.is<ELFRel*>())
218 return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel*>());
219 else
220 return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela*>());
221}
222
Andrew MacPherson17220c12014-03-05 10:12:43 +0000223unsigned
224ELFRelocation::RelocOffset32(const ELFRelocation &rel)
225{
226 if (rel.reloc.is<ELFRel*>())
227 return rel.reloc.get<ELFRel*>()->r_offset;
228 else
229 return rel.reloc.get<ELFRela*>()->r_offset;
230}
231
232unsigned
233ELFRelocation::RelocOffset64(const ELFRelocation &rel)
234{
235 if (rel.reloc.is<ELFRel*>())
236 return rel.reloc.get<ELFRel*>()->r_offset;
237 else
238 return rel.reloc.get<ELFRela*>()->r_offset;
239}
240
241unsigned
242ELFRelocation::RelocAddend32(const ELFRelocation &rel)
243{
244 if (rel.reloc.is<ELFRel*>())
245 return 0;
246 else
247 return rel.reloc.get<ELFRela*>()->r_addend;
248}
249
250unsigned
251ELFRelocation::RelocAddend64(const ELFRelocation &rel)
252{
253 if (rel.reloc.is<ELFRel*>())
254 return 0;
255 else
256 return rel.reloc.get<ELFRela*>()->r_addend;
257}
258
Stephen Wilson499b40e2011-03-30 16:07:05 +0000259} // end anonymous namespace
260
Ed Mastec113ff82013-12-02 17:49:13 +0000261bool
262ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset)
263{
264 // Read all fields.
265 if (data.GetU32(offset, &n_namesz, 3) == NULL)
266 return false;
267
268 // The name field is required to be nul-terminated, and n_namesz
269 // includes the terminating nul in observed implementations (contrary
270 // to the ELF-64 spec). A special case is needed for cores generated
271 // by some older Linux versions, which write a note named "CORE"
272 // without a nul terminator and n_namesz = 4.
273 if (n_namesz == 4)
274 {
275 char buf[4];
276 if (data.ExtractBytes (*offset, 4, data.GetByteOrder(), buf) != 4)
277 return false;
278 if (strncmp (buf, "CORE", 4) == 0)
279 {
280 n_name = "CORE";
281 *offset += 4;
282 return true;
283 }
284 }
285
286 const char *cstr = data.GetCStr(offset, llvm::RoundUpToAlignment (n_namesz, 4));
287 if (cstr == NULL)
288 {
289 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
290 if (log)
291 log->Printf("Failed to parse note name lacking nul terminator");
292
293 return false;
294 }
295 n_name = cstr;
296 return true;
297}
298
Matthew Gardiner5f675792014-08-27 12:09:39 +0000299static uint32_t
300kalimbaVariantFromElfFlags(const elf::elf_word e_flags)
301{
302 const uint32_t dsp_rev = e_flags & 0xFF;
303 uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE;
304 switch(dsp_rev)
305 {
306 // TODO(mg11) Support more variants
307 case 10:
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000308 kal_arch_variant = llvm::Triple::KalimbaSubArch_v3;
Matthew Gardiner5f675792014-08-27 12:09:39 +0000309 break;
310 case 14:
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000311 kal_arch_variant = llvm::Triple::KalimbaSubArch_v4;
312 break;
313 case 17:
314 case 20:
315 kal_arch_variant = llvm::Triple::KalimbaSubArch_v5;
Matthew Gardiner5f675792014-08-27 12:09:39 +0000316 break;
317 default:
Ed Maste81b4c5f2016-01-04 01:43:47 +0000318 break;
Matthew Gardiner5f675792014-08-27 12:09:39 +0000319 }
320 return kal_arch_variant;
321}
322
323static uint32_t
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +0000324mipsVariantFromElfFlags(const elf::elf_word e_flags, uint32_t endian)
325{
326 const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH;
Mohit K. Bhakkade8659b52015-04-23 06:36:20 +0000327 uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +0000328
329 switch (mips_arch)
330 {
Sagar Thakur40fc2e32015-12-15 05:50:55 +0000331 case llvm::ELF::EF_MIPS_ARCH_1:
332 case llvm::ELF::EF_MIPS_ARCH_2:
Mohit K. Bhakkade8659b52015-04-23 06:36:20 +0000333 case llvm::ELF::EF_MIPS_ARCH_32:
334 return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el : ArchSpec::eMIPSSubType_mips32;
335 case llvm::ELF::EF_MIPS_ARCH_32R2:
336 return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el : ArchSpec::eMIPSSubType_mips32r2;
337 case llvm::ELF::EF_MIPS_ARCH_32R6:
338 return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el : ArchSpec::eMIPSSubType_mips32r6;
Mohit K. Bhakkad884fc3e2016-01-12 06:03:01 +0000339 case llvm::ELF::EF_MIPS_ARCH_3:
340 case llvm::ELF::EF_MIPS_ARCH_4:
341 case llvm::ELF::EF_MIPS_ARCH_5:
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +0000342 case llvm::ELF::EF_MIPS_ARCH_64:
Mohit K. Bhakkade8659b52015-04-23 06:36:20 +0000343 return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el : ArchSpec::eMIPSSubType_mips64;
344 case llvm::ELF::EF_MIPS_ARCH_64R2:
345 return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el : ArchSpec::eMIPSSubType_mips64r2;
346 case llvm::ELF::EF_MIPS_ARCH_64R6:
347 return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el : ArchSpec::eMIPSSubType_mips64r6;
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +0000348 default:
349 break;
350 }
351
352 return arch_variant;
353}
354
355static uint32_t
Matthew Gardiner5f675792014-08-27 12:09:39 +0000356subTypeFromElfHeader(const elf::ELFHeader& header)
357{
Mohit K. Bhakkad3df471c2015-03-17 11:43:56 +0000358 if (header.e_machine == llvm::ELF::EM_MIPS)
359 return mipsVariantFromElfFlags (header.e_flags,
360 header.e_ident[EI_DATA]);
361
Matthew Gardiner5f675792014-08-27 12:09:39 +0000362 return
363 llvm::ELF::EM_CSR_KALIMBA == header.e_machine ?
364 kalimbaVariantFromElfFlags(header.e_flags) :
365 LLDB_INVALID_CPUTYPE;
366}
367
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000368//! The kalimba toolchain identifies a code section as being
369//! one with the SHT_PROGBITS set in the section sh_type and the top
370//! bit in the 32-bit address field set.
371static lldb::SectionType
372kalimbaSectionType(
373 const elf::ELFHeader& header,
374 const elf::ELFSectionHeader& sect_hdr)
375{
Matthew Gardiner6e7b0a02014-10-15 08:21:54 +0000376 if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine)
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000377 {
378 return eSectionTypeOther;
379 }
380
Matthew Gardiner6e7b0a02014-10-15 08:21:54 +0000381 if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type)
382 {
383 return eSectionTypeZeroFill;
384 }
385
386 if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type)
387 {
388 const lldb::addr_t KAL_CODE_BIT = 1 << 31;
389 return KAL_CODE_BIT & sect_hdr.sh_addr ?
390 eSectionTypeCode : eSectionTypeData;
391 }
392
393 return eSectionTypeOther;
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000394}
395
Todd Fiala4339f3a2014-03-25 19:29:09 +0000396// Arbitrary constant used as UUID prefix for core files.
397const uint32_t
398ObjectFileELF::g_core_uuid_magic(0xE210C);
399
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000400//------------------------------------------------------------------
401// Static methods.
402//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403void
404ObjectFileELF::Initialize()
405{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000406 PluginManager::RegisterPlugin(GetPluginNameStatic(),
407 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000408 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000409 CreateMemoryInstance,
410 GetModuleSpecifications);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411}
412
413void
414ObjectFileELF::Terminate()
415{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000416 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417}
418
Greg Clayton57abc5d2013-05-10 21:47:16 +0000419lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420ObjectFileELF::GetPluginNameStatic()
421{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000422 static ConstString g_name("elf");
423 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424}
425
426const char *
427ObjectFileELF::GetPluginDescriptionStatic()
428{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000429 return "ELF object file reader.";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430}
431
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432ObjectFile *
Greg Claytone72dfb32012-02-24 01:59:29 +0000433ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
434 DataBufferSP &data_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000435 lldb::offset_t data_offset,
436 const lldb_private::FileSpec* file,
437 lldb::offset_t file_offset,
438 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000440 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441 {
Greg Clayton736888c2015-02-23 23:47:09 +0000442 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton5ce9c562013-02-06 17:22:03 +0000443 data_offset = 0;
444 }
445
446 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
447 {
448 const uint8_t *magic = data_sp->GetBytes() + data_offset;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000449 if (ELFHeader::MagicBytesMatch(magic))
450 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000451 // Update the data to contain the entire file if it doesn't already
Andrew Kaylor213f6722013-02-07 21:30:54 +0000452 if (data_sp->GetByteSize() < length) {
Greg Clayton736888c2015-02-23 23:47:09 +0000453 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton64ff6c72013-02-07 21:49:54 +0000454 data_offset = 0;
455 magic = data_sp->GetBytes();
Andrew Kaylor213f6722013-02-07 21:30:54 +0000456 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000457 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
458 if (address_size == 4 || address_size == 8)
459 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000460 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 +0000461 ArchSpec spec;
462 if (objfile_ap->GetArchitecture(spec) &&
463 objfile_ap->SetModulesArchitecture(spec))
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000464 return objfile_ap.release();
465 }
466 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 }
468 return NULL;
469}
470
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000471
Greg Claytonc9660542012-02-05 02:38:54 +0000472ObjectFile*
Ed Maste81b4c5f2016-01-04 01:43:47 +0000473ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
474 DataBufferSP& data_sp,
475 const lldb::ProcessSP &process_sp,
Greg Claytone72dfb32012-02-24 01:59:29 +0000476 lldb::addr_t header_addr)
Greg Claytonc9660542012-02-05 02:38:54 +0000477{
Andrew MacPherson17220c12014-03-05 10:12:43 +0000478 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT))
479 {
480 const uint8_t *magic = data_sp->GetBytes();
481 if (ELFHeader::MagicBytesMatch(magic))
482 {
483 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
484 if (address_size == 4 || address_size == 8)
485 {
486 std::auto_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
487 ArchSpec spec;
488 if (objfile_ap->GetArchitecture(spec) &&
489 objfile_ap->SetModulesArchitecture(spec))
490 return objfile_ap.release();
491 }
492 }
493 }
Greg Claytonc9660542012-02-05 02:38:54 +0000494 return NULL;
495}
496
Michael Sartain9f0013d2013-05-17 00:20:21 +0000497bool
498ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,
499 lldb::addr_t data_offset,
500 lldb::addr_t data_length)
501{
502 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
503 {
504 const uint8_t *magic = data_sp->GetBytes() + data_offset;
505 return ELFHeader::MagicBytesMatch(magic);
506 }
507 return false;
508}
Greg Claytonc9660542012-02-05 02:38:54 +0000509
Michael Sartain9f4517a2013-07-03 01:52:14 +0000510/*
511 * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
512 *
513 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
514 * code or tables extracted from it, as desired without restriction.
515 */
516static uint32_t
Todd Fiala4339f3a2014-03-25 19:29:09 +0000517calc_crc32(uint32_t crc, const void *buf, size_t size)
Michael Sartain9f4517a2013-07-03 01:52:14 +0000518{
519 static const uint32_t g_crc32_tab[] =
520 {
521 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
522 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
523 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
524 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
525 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
526 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
527 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
528 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
529 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
530 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
531 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
532 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
533 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
534 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
535 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
536 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
537 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
538 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
539 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
540 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
541 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
542 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
543 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
544 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
545 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
546 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
547 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
548 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
549 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
550 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
551 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
552 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
553 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
554 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
555 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
556 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
557 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
558 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
559 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
560 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
561 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
562 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
563 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
Ed Maste81b4c5f2016-01-04 01:43:47 +0000564 };
Michael Sartain9f4517a2013-07-03 01:52:14 +0000565 const uint8_t *p = (const uint8_t *)buf;
Michael Sartain9f4517a2013-07-03 01:52:14 +0000566
Todd Fiala4339f3a2014-03-25 19:29:09 +0000567 crc = crc ^ ~0U;
Michael Sartain9f4517a2013-07-03 01:52:14 +0000568 while (size--)
569 crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
570 return crc ^ ~0U;
571}
572
Todd Fiala4339f3a2014-03-25 19:29:09 +0000573static uint32_t
574calc_gnu_debuglink_crc32(const void *buf, size_t size)
575{
576 return calc_crc32(0U, buf, size);
577}
578
579uint32_t
580ObjectFileELF::CalculateELFNotesSegmentsCRC32 (const ProgramHeaderColl& program_headers,
581 DataExtractor& object_data)
582{
583 typedef ProgramHeaderCollConstIter Iter;
584
585 uint32_t core_notes_crc = 0;
586
587 for (Iter I = program_headers.begin(); I != program_headers.end(); ++I)
588 {
589 if (I->p_type == llvm::ELF::PT_NOTE)
590 {
591 const elf_off ph_offset = I->p_offset;
592 const size_t ph_size = I->p_filesz;
593
594 DataExtractor segment_data;
595 if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size)
596 {
597 // The ELF program header contained incorrect data,
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000598 // probably corefile is incomplete or corrupted.
Todd Fiala4339f3a2014-03-25 19:29:09 +0000599 break;
600 }
601
602 core_notes_crc = calc_crc32(core_notes_crc,
603 segment_data.GetDataStart(),
604 segment_data.GetByteSize());
605 }
606 }
607
608 return core_notes_crc;
609}
610
Todd Fialab91de782014-06-27 16:52:49 +0000611static const char*
612OSABIAsCString (unsigned char osabi_byte)
613{
614#define _MAKE_OSABI_CASE(x) case x: return #x
615 switch (osabi_byte)
616 {
617 _MAKE_OSABI_CASE(ELFOSABI_NONE);
618 _MAKE_OSABI_CASE(ELFOSABI_HPUX);
619 _MAKE_OSABI_CASE(ELFOSABI_NETBSD);
620 _MAKE_OSABI_CASE(ELFOSABI_GNU);
621 _MAKE_OSABI_CASE(ELFOSABI_HURD);
622 _MAKE_OSABI_CASE(ELFOSABI_SOLARIS);
623 _MAKE_OSABI_CASE(ELFOSABI_AIX);
624 _MAKE_OSABI_CASE(ELFOSABI_IRIX);
625 _MAKE_OSABI_CASE(ELFOSABI_FREEBSD);
626 _MAKE_OSABI_CASE(ELFOSABI_TRU64);
627 _MAKE_OSABI_CASE(ELFOSABI_MODESTO);
628 _MAKE_OSABI_CASE(ELFOSABI_OPENBSD);
629 _MAKE_OSABI_CASE(ELFOSABI_OPENVMS);
630 _MAKE_OSABI_CASE(ELFOSABI_NSK);
631 _MAKE_OSABI_CASE(ELFOSABI_AROS);
632 _MAKE_OSABI_CASE(ELFOSABI_FENIXOS);
633 _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI);
634 _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX);
635 _MAKE_OSABI_CASE(ELFOSABI_ARM);
636 _MAKE_OSABI_CASE(ELFOSABI_STANDALONE);
637 default:
638 return "<unknown-osabi>";
639 }
640#undef _MAKE_OSABI_CASE
641}
642
Ed Mastef6a13122015-06-05 13:03:08 +0000643//
644// WARNING : This function is being deprecated
645// It's functionality has moved to ArchSpec::SetArchitecture
646// This function is only being kept to validate the move.
647//
648// TODO : Remove this function
Todd Fialab91de782014-06-27 16:52:49 +0000649static bool
650GetOsFromOSABI (unsigned char osabi_byte, llvm::Triple::OSType &ostype)
651{
652 switch (osabi_byte)
653 {
654 case ELFOSABI_AIX: ostype = llvm::Triple::OSType::AIX; break;
655 case ELFOSABI_FREEBSD: ostype = llvm::Triple::OSType::FreeBSD; break;
656 case ELFOSABI_GNU: ostype = llvm::Triple::OSType::Linux; break;
657 case ELFOSABI_NETBSD: ostype = llvm::Triple::OSType::NetBSD; break;
658 case ELFOSABI_OPENBSD: ostype = llvm::Triple::OSType::OpenBSD; break;
659 case ELFOSABI_SOLARIS: ostype = llvm::Triple::OSType::Solaris; break;
660 default:
661 ostype = llvm::Triple::OSType::UnknownOS;
662 }
663 return ostype != llvm::Triple::OSType::UnknownOS;
664}
665
Greg Claytonf4d6de62013-04-24 22:29:28 +0000666size_t
667ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
668 lldb::DataBufferSP& data_sp,
669 lldb::offset_t data_offset,
670 lldb::offset_t file_offset,
671 lldb::offset_t length,
672 lldb_private::ModuleSpecList &specs)
673{
Todd Fialab91de782014-06-27 16:52:49 +0000674 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES));
675
Michael Sartain9f0013d2013-05-17 00:20:21 +0000676 const size_t initial_count = specs.GetSize();
Michael Sartainc836ae72013-05-23 20:57:03 +0000677
Michael Sartain9f0013d2013-05-17 00:20:21 +0000678 if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
679 {
680 DataExtractor data;
681 data.SetData(data_sp);
682 elf::ELFHeader header;
683 if (header.Parse(data, &data_offset))
684 {
685 if (data_sp)
686 {
Oleksiy Vyalov63acdfd2015-03-10 01:15:28 +0000687 ModuleSpec spec (file);
Matthew Gardiner5f675792014-08-27 12:09:39 +0000688
689 const uint32_t sub_type = subTypeFromElfHeader(header);
Michael Sartain9f0013d2013-05-17 00:20:21 +0000690 spec.GetArchitecture().SetArchitecture(eArchTypeELF,
691 header.e_machine,
Ed Mastef6a13122015-06-05 13:03:08 +0000692 sub_type,
693 header.e_ident[EI_OSABI]);
Matthew Gardiner5f675792014-08-27 12:09:39 +0000694
Michael Sartain9f0013d2013-05-17 00:20:21 +0000695 if (spec.GetArchitecture().IsValid())
696 {
Todd Fialab91de782014-06-27 16:52:49 +0000697 llvm::Triple::OSType ostype;
Ed Mastef6a13122015-06-05 13:03:08 +0000698 llvm::Triple::VendorType vendor;
699 llvm::Triple::OSType spec_ostype = spec.GetArchitecture ().GetTriple ().getOS ();
Todd Fialab91de782014-06-27 16:52:49 +0000700
701 if (log)
702 log->Printf ("ObjectFileELF::%s file '%s' module OSABI: %s", __FUNCTION__, file.GetPath ().c_str (), OSABIAsCString (header.e_ident[EI_OSABI]));
Ed Mastef6a13122015-06-05 13:03:08 +0000703
704 // SetArchitecture should have set the vendor to unknown
705 vendor = spec.GetArchitecture ().GetTriple ().getVendor ();
706 assert(vendor == llvm::Triple::UnknownVendor);
707
708 //
709 // Validate it is ok to remove GetOsFromOSABI
710 GetOsFromOSABI (header.e_ident[EI_OSABI], ostype);
711 assert(spec_ostype == ostype);
712 if (spec_ostype != llvm::Triple::OSType::UnknownOS)
Todd Fialab91de782014-06-27 16:52:49 +0000713 {
Todd Fialab91de782014-06-27 16:52:49 +0000714 if (log)
715 log->Printf ("ObjectFileELF::%s file '%s' set ELF module OS type from ELF header OSABI.", __FUNCTION__, file.GetPath ().c_str ());
716 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000717
718 // Try to get the UUID from the section list. Usually that's at the end, so
719 // map the file in if we don't have it already.
720 size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize;
721 if (section_header_end > data_sp->GetByteSize())
722 {
Greg Clayton736888c2015-02-23 23:47:09 +0000723 data_sp = file.MemoryMapFileContentsIfLocal (file_offset, section_header_end);
Michael Sartaina7499c92013-07-01 19:45:50 +0000724 data.SetData(data_sp);
725 }
726
Michael Sartain9f4517a2013-07-03 01:52:14 +0000727 uint32_t gnu_debuglink_crc = 0;
Michael Sartaina7499c92013-07-01 19:45:50 +0000728 std::string gnu_debuglink_file;
729 SectionHeaderColl section_headers;
Michael Sartain9f4517a2013-07-03 01:52:14 +0000730 lldb_private::UUID &uuid = spec.GetUUID();
Michael Sartain9f4517a2013-07-03 01:52:14 +0000731
Todd Fialab91de782014-06-27 16:52:49 +0000732 GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ());
733
Todd Fialab91de782014-06-27 16:52:49 +0000734 llvm::Triple &spec_triple = spec.GetArchitecture ().GetTriple ();
Todd Fialab91de782014-06-27 16:52:49 +0000735
736 if (log)
737 log->Printf ("ObjectFileELF::%s file '%s' module set to triple: %s (architecture %s)", __FUNCTION__, file.GetPath ().c_str (), spec_triple.getTriple ().c_str (), spec.GetArchitecture ().GetArchitectureName ());
Todd Fiala4339f3a2014-03-25 19:29:09 +0000738
Michael Sartain9f4517a2013-07-03 01:52:14 +0000739 if (!uuid.IsValid())
740 {
Todd Fiala4339f3a2014-03-25 19:29:09 +0000741 uint32_t core_notes_crc = 0;
742
Michael Sartain9f4517a2013-07-03 01:52:14 +0000743 if (!gnu_debuglink_crc)
744 {
Todd Fiala4339f3a2014-03-25 19:29:09 +0000745 lldb_private::Timer scoped_timer (__PRETTY_FUNCTION__,
746 "Calculating module crc32 %s with size %" PRIu64 " KiB",
747 file.GetLastPathComponent().AsCString(),
748 (file.GetByteSize()-file_offset)/1024);
749
750 // For core files - which usually don't happen to have a gnu_debuglink,
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000751 // and are pretty bulky - calculating whole contents crc32 would be too much of luxury.
Todd Fiala4339f3a2014-03-25 19:29:09 +0000752 // Thus we will need to fallback to something simpler.
753 if (header.e_type == llvm::ELF::ET_CORE)
754 {
755 size_t program_headers_end = header.e_phoff + header.e_phnum * header.e_phentsize;
756 if (program_headers_end > data_sp->GetByteSize())
757 {
Greg Clayton736888c2015-02-23 23:47:09 +0000758 data_sp = file.MemoryMapFileContentsIfLocal(file_offset, program_headers_end);
Todd Fiala4339f3a2014-03-25 19:29:09 +0000759 data.SetData(data_sp);
760 }
761 ProgramHeaderColl program_headers;
762 GetProgramHeaderInfo(program_headers, data, header);
763
764 size_t segment_data_end = 0;
765 for (ProgramHeaderCollConstIter I = program_headers.begin();
766 I != program_headers.end(); ++I)
767 {
Enrico Granataafcbdb12014-03-25 20:53:33 +0000768 segment_data_end = std::max<unsigned long long> (I->p_offset + I->p_filesz, segment_data_end);
Todd Fiala4339f3a2014-03-25 19:29:09 +0000769 }
770
771 if (segment_data_end > data_sp->GetByteSize())
772 {
Greg Clayton736888c2015-02-23 23:47:09 +0000773 data_sp = file.MemoryMapFileContentsIfLocal(file_offset, segment_data_end);
Todd Fiala4339f3a2014-03-25 19:29:09 +0000774 data.SetData(data_sp);
775 }
776
777 core_notes_crc = CalculateELFNotesSegmentsCRC32 (program_headers, data);
778 }
779 else
780 {
781 // Need to map entire file into memory to calculate the crc.
Greg Clayton736888c2015-02-23 23:47:09 +0000782 data_sp = file.MemoryMapFileContentsIfLocal (file_offset, SIZE_MAX);
Todd Fiala4339f3a2014-03-25 19:29:09 +0000783 data.SetData(data_sp);
784 gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
785 }
Michael Sartain9f4517a2013-07-03 01:52:14 +0000786 }
787 if (gnu_debuglink_crc)
788 {
789 // Use 4 bytes of crc from the .gnu_debuglink section.
790 uint32_t uuidt[4] = { gnu_debuglink_crc, 0, 0, 0 };
791 uuid.SetBytes (uuidt, sizeof(uuidt));
792 }
Todd Fiala4339f3a2014-03-25 19:29:09 +0000793 else if (core_notes_crc)
794 {
795 // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it look different form
796 // .gnu_debuglink crc followed by 4 bytes of note segments crc.
797 uint32_t uuidt[4] = { g_core_uuid_magic, core_notes_crc, 0, 0 };
798 uuid.SetBytes (uuidt, sizeof(uuidt));
799 }
Michael Sartain9f4517a2013-07-03 01:52:14 +0000800 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000801
Michael Sartain9f0013d2013-05-17 00:20:21 +0000802 specs.Append(spec);
803 }
804 }
805 }
806 }
Michael Sartainc836ae72013-05-23 20:57:03 +0000807
Michael Sartain9f0013d2013-05-17 00:20:21 +0000808 return specs.GetSize() - initial_count;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000809}
810
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000811//------------------------------------------------------------------
812// PluginInterface protocol
813//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +0000814lldb_private::ConstString
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000815ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000817 return GetPluginNameStatic();
818}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000819
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000820uint32_t
821ObjectFileELF::GetPluginVersion()
822{
823 return m_plugin_version;
824}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000825//------------------------------------------------------------------
826// ObjectFile protocol
827//------------------------------------------------------------------
828
Ed Maste81b4c5f2016-01-04 01:43:47 +0000829ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000830 DataBufferSP& data_sp,
831 lldb::offset_t data_offset,
Ed Maste81b4c5f2016-01-04 01:43:47 +0000832 const FileSpec* file,
Greg Clayton5ce9c562013-02-06 17:22:03 +0000833 lldb::offset_t file_offset,
Ed Maste81b4c5f2016-01-04 01:43:47 +0000834 lldb::offset_t length) :
Greg Clayton5ce9c562013-02-06 17:22:03 +0000835 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytone72dfb32012-02-24 01:59:29 +0000836 m_header(),
Todd Fialab91de782014-06-27 16:52:49 +0000837 m_uuid(),
838 m_gnu_debuglink_file(),
839 m_gnu_debuglink_crc(0),
Greg Claytone72dfb32012-02-24 01:59:29 +0000840 m_program_headers(),
841 m_section_headers(),
Todd Fialab91de782014-06-27 16:52:49 +0000842 m_dynamic_symbols(),
843 m_filespec_ap(),
844 m_entry_point_address(),
845 m_arch_spec()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846{
847 if (file)
848 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000849 ::memset(&m_header, 0, sizeof(m_header));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850}
851
Andrew MacPherson17220c12014-03-05 10:12:43 +0000852ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
Tamas Berghammerf2561842015-06-30 10:41:23 +0000853 DataBufferSP& header_data_sp,
Andrew MacPherson17220c12014-03-05 10:12:43 +0000854 const lldb::ProcessSP &process_sp,
855 addr_t header_addr) :
Tamas Berghammerf2561842015-06-30 10:41:23 +0000856 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Andrew MacPherson17220c12014-03-05 10:12:43 +0000857 m_header(),
Todd Fialab91de782014-06-27 16:52:49 +0000858 m_uuid(),
859 m_gnu_debuglink_file(),
860 m_gnu_debuglink_crc(0),
Andrew MacPherson17220c12014-03-05 10:12:43 +0000861 m_program_headers(),
862 m_section_headers(),
Todd Fialab91de782014-06-27 16:52:49 +0000863 m_dynamic_symbols(),
864 m_filespec_ap(),
865 m_entry_point_address(),
866 m_arch_spec()
Andrew MacPherson17220c12014-03-05 10:12:43 +0000867{
868 ::memset(&m_header, 0, sizeof(m_header));
869}
870
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871ObjectFileELF::~ObjectFileELF()
872{
873}
874
Jim Ingham5aee1622010-08-09 23:31:02 +0000875bool
876ObjectFileELF::IsExecutable() const
877{
Deepak Panickal71f5b502014-07-22 12:01:43 +0000878 return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
Jim Ingham5aee1622010-08-09 23:31:02 +0000879}
880
Steve Pucci9e02dac2014-02-06 19:02:19 +0000881bool
Greg Clayton751caf62014-02-07 22:54:47 +0000882ObjectFileELF::SetLoadAddress (Target &target,
883 lldb::addr_t value,
884 bool value_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000885{
Steve Pucci9e02dac2014-02-06 19:02:19 +0000886 ModuleSP module_sp = GetModule();
887 if (module_sp)
888 {
889 size_t num_loaded_sections = 0;
890 SectionList *section_list = GetSectionList ();
891 if (section_list)
892 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000893 if (!value_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000894 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000895 bool found_offset = false;
896 for (size_t i = 0, count = GetProgramHeaderCount(); i < count; ++i)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000897 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000898 const elf::ELFProgramHeader* header = GetProgramHeaderByIndex(i);
899 if (header == nullptr)
900 continue;
Tamas Berghammerf2561842015-06-30 10:41:23 +0000901
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000902 if (header->p_type != PT_LOAD || header->p_offset != 0)
903 continue;
Ed Maste81b4c5f2016-01-04 01:43:47 +0000904
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000905 value = value - header->p_vaddr;
906 found_offset = true;
907 break;
Steve Pucci9e02dac2014-02-06 19:02:19 +0000908 }
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000909 if (!found_offset)
910 return false;
Greg Clayton751caf62014-02-07 22:54:47 +0000911 }
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000912
913 const size_t num_sections = section_list->GetSize();
914 size_t sect_idx = 0;
915
916 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
Greg Clayton751caf62014-02-07 22:54:47 +0000917 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000918 // Iterate through the object file sections to find all
919 // of the sections that have SHF_ALLOC in their flag bits.
920 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
921 // if (section_sp && !section_sp->IsThreadSpecific())
922 if (section_sp && section_sp->Test(SHF_ALLOC))
923 {
924 lldb::addr_t load_addr = section_sp->GetFileAddress() + value;
925
926 // On 32-bit systems the load address have to fit into 4 bytes. The rest of
927 // the bytes are the overflow from the addition.
928 if (GetAddressByteSize() == 4)
929 load_addr &= 0xFFFFFFFF;
930
931 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
932 ++num_loaded_sections;
933 }
Steve Pucci9e02dac2014-02-06 19:02:19 +0000934 }
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000935 return num_loaded_sections > 0;
Steve Pucci9e02dac2014-02-06 19:02:19 +0000936 }
Steve Pucci9e02dac2014-02-06 19:02:19 +0000937 }
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000938 return false;
Steve Pucci9e02dac2014-02-06 19:02:19 +0000939}
940
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000941ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000942ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000943{
944 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
945 return eByteOrderBig;
946 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
947 return eByteOrderLittle;
948 return eByteOrderInvalid;
949}
950
Greg Claytonc7bece562013-01-25 18:06:21 +0000951uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000952ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000953{
954 return m_data.GetAddressByteSize();
955}
956
Todd Fialafbd703a2014-09-15 22:33:39 +0000957AddressClass
958ObjectFileELF::GetAddressClass (addr_t file_addr)
959{
Tamas Berghammerd00438e2015-07-30 12:38:18 +0000960 Symtab* symtab = GetSymtab();
961 if (!symtab)
962 return eAddressClassUnknown;
Todd Fialafbd703a2014-09-15 22:33:39 +0000963
Tamas Berghammerd00438e2015-07-30 12:38:18 +0000964 // The address class is determined based on the symtab. Ask it from the object file what
965 // contains the symtab information.
966 ObjectFile* symtab_objfile = symtab->GetObjectFile();
967 if (symtab_objfile != nullptr && symtab_objfile != this)
968 return symtab_objfile->GetAddressClass(file_addr);
969
970 auto res = ObjectFile::GetAddressClass (file_addr);
Todd Fialafbd703a2014-09-15 22:33:39 +0000971 if (res != eAddressClassCode)
972 return res;
973
Tamas Berghammer83544cf2015-04-07 10:43:50 +0000974 auto ub = m_address_class_map.upper_bound(file_addr);
975 if (ub == m_address_class_map.begin())
976 {
977 // No entry in the address class map before the address. Return
978 // default address class for an address in a code section.
979 return eAddressClassCode;
980 }
Todd Fialafbd703a2014-09-15 22:33:39 +0000981
Tamas Berghammer83544cf2015-04-07 10:43:50 +0000982 // Move iterator to the address class entry preceding address
983 --ub;
Todd Fialafbd703a2014-09-15 22:33:39 +0000984
Tamas Berghammer83544cf2015-04-07 10:43:50 +0000985 return ub->second;
Todd Fialafbd703a2014-09-15 22:33:39 +0000986}
987
Greg Claytonc7bece562013-01-25 18:06:21 +0000988size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000989ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990{
Greg Claytonc7bece562013-01-25 18:06:21 +0000991 return std::distance(m_section_headers.begin(), I) + 1u;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000992}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993
Greg Claytonc7bece562013-01-25 18:06:21 +0000994size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000995ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
996{
Greg Claytonc7bece562013-01-25 18:06:21 +0000997 return std::distance(m_section_headers.begin(), I) + 1u;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000998}
999
1000bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001001ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002{
Filipe Cabecinhas22b40f72013-05-16 23:29:36 +00001003 lldb::offset_t offset = 0;
Tamas Berghammerf2561842015-06-30 10:41:23 +00001004 if (!m_header.Parse(m_data, &offset))
1005 return false;
1006
1007 if (!IsInMemory())
1008 return true;
1009
1010 // For in memory object files m_data might not contain the full object file. Try to load it
1011 // until the end of the "Section header table" what is at the end of the ELF file.
1012 addr_t file_size = m_header.e_shoff + m_header.e_shnum * m_header.e_shentsize;
1013 if (m_data.GetByteSize() < file_size)
1014 {
1015 ProcessSP process_sp (m_process_wp.lock());
1016 if (!process_sp)
1017 return false;
1018
1019 DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size);
1020 if (!data_sp)
1021 return false;
1022 m_data.SetData(data_sp, 0, file_size);
1023 }
1024
1025 return true;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001026}
1027
1028bool
Greg Clayton60830262011-02-04 18:53:10 +00001029ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001030{
Michael Sartaina7499c92013-07-01 19:45:50 +00001031 // Need to parse the section list to get the UUIDs, so make sure that's been done.
Todd Fiala4339f3a2014-03-25 19:29:09 +00001032 if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
Michael Sartaina7499c92013-07-01 19:45:50 +00001033 return false;
1034
Michael Sartainc836ae72013-05-23 20:57:03 +00001035 if (m_uuid.IsValid())
1036 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001037 // We have the full build id uuid.
Michael Sartainc836ae72013-05-23 20:57:03 +00001038 *uuid = m_uuid;
1039 return true;
1040 }
Todd Fiala4339f3a2014-03-25 19:29:09 +00001041 else if (GetType() == ObjectFile::eTypeCoreFile)
1042 {
1043 uint32_t core_notes_crc = 0;
1044
1045 if (!ParseProgramHeaders())
1046 return false;
1047
1048 core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
1049
1050 if (core_notes_crc)
1051 {
1052 // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
1053 // look different form .gnu_debuglink crc - followed by 4 bytes of note
1054 // segments crc.
1055 uint32_t uuidt[4] = { g_core_uuid_magic, core_notes_crc, 0, 0 };
1056 m_uuid.SetBytes (uuidt, sizeof(uuidt));
1057 }
1058 }
1059 else
Michael Sartaina7499c92013-07-01 19:45:50 +00001060 {
Michael Sartain9f4517a2013-07-03 01:52:14 +00001061 if (!m_gnu_debuglink_crc)
1062 m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
Michael Sartaina7499c92013-07-01 19:45:50 +00001063 if (m_gnu_debuglink_crc)
1064 {
1065 // Use 4 bytes of crc from the .gnu_debuglink section.
1066 uint32_t uuidt[4] = { m_gnu_debuglink_crc, 0, 0, 0 };
Todd Fiala4339f3a2014-03-25 19:29:09 +00001067 m_uuid.SetBytes (uuidt, sizeof(uuidt));
Michael Sartaina7499c92013-07-01 19:45:50 +00001068 }
1069 }
1070
Todd Fiala4339f3a2014-03-25 19:29:09 +00001071 if (m_uuid.IsValid())
1072 {
1073 *uuid = m_uuid;
1074 return true;
1075 }
1076
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077 return false;
1078}
1079
Michael Sartaina7499c92013-07-01 19:45:50 +00001080lldb_private::FileSpecList
1081ObjectFileELF::GetDebugSymbolFilePaths()
1082{
1083 FileSpecList file_spec_list;
1084
1085 if (!m_gnu_debuglink_file.empty())
1086 {
1087 FileSpec file_spec (m_gnu_debuglink_file.c_str(), false);
1088 file_spec_list.Append (file_spec);
1089 }
1090 return file_spec_list;
1091}
1092
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001094ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001096 size_t num_modules = ParseDependentModules();
1097 uint32_t num_specs = 0;
1098
1099 for (unsigned i = 0; i < num_modules; ++i)
1100 {
1101 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
1102 num_specs++;
1103 }
1104
1105 return num_specs;
1106}
1107
Stephen Wilson499b40e2011-03-30 16:07:05 +00001108Address
Ed Maste54803652013-10-11 17:39:07 +00001109ObjectFileELF::GetImageInfoAddress(Target *target)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001110{
1111 if (!ParseDynamicSymbols())
Stephen Wilson2ab0a582011-01-15 00:08:44 +00001112 return Address();
1113
1114 SectionList *section_list = GetSectionList();
1115 if (!section_list)
1116 return Address();
1117
Greg Clayton3046e662013-07-10 01:23:25 +00001118 // Find the SHT_DYNAMIC (.dynamic) section.
1119 SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
1120 if (!dynsym_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00001121 return Address();
Greg Clayton3046e662013-07-10 01:23:25 +00001122 assert (dynsym_section_sp->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001123
Greg Clayton3046e662013-07-10 01:23:25 +00001124 user_id_t dynsym_id = dynsym_section_sp->GetID();
Michael Sartaina7499c92013-07-01 19:45:50 +00001125 const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00001126 if (!dynsym_hdr)
1127 return Address();
1128
Greg Clayton3046e662013-07-10 01:23:25 +00001129 for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
Stephen Wilson2ab0a582011-01-15 00:08:44 +00001130 {
Greg Clayton3046e662013-07-10 01:23:25 +00001131 ELFDynamic &symbol = m_dynamic_symbols[i];
Greg Claytone72dfb32012-02-24 01:59:29 +00001132
Ed Maste54803652013-10-11 17:39:07 +00001133 if (symbol.d_tag == DT_DEBUG)
Greg Clayton3046e662013-07-10 01:23:25 +00001134 {
1135 // Compute the offset as the number of previous entries plus the
1136 // size of d_tag.
1137 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
1138 return Address(dynsym_section_sp, offset);
Stephen Wilson2ab0a582011-01-15 00:08:44 +00001139 }
Bhushan D. Attarde1bcc7ba2015-09-15 05:45:29 +00001140 // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP exists in non-PIE.
1141 else if ((symbol.d_tag == DT_MIPS_RLD_MAP || symbol.d_tag == DT_MIPS_RLD_MAP_REL) && target)
Ed Maste54803652013-10-11 17:39:07 +00001142 {
1143 addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
1144 addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
1145 if (dyn_base == LLDB_INVALID_ADDRESS)
1146 return Address();
Bhushan D. Attarde1bcc7ba2015-09-15 05:45:29 +00001147
Ed Maste54803652013-10-11 17:39:07 +00001148 Error error;
Bhushan D. Attarde1bcc7ba2015-09-15 05:45:29 +00001149 if (symbol.d_tag == DT_MIPS_RLD_MAP)
1150 {
1151 // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
1152 Address addr;
1153 if (target->ReadPointerFromMemory(dyn_base + offset, false, error, addr))
1154 return addr;
1155 }
1156 if (symbol.d_tag == DT_MIPS_RLD_MAP_REL)
1157 {
1158 // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer, relative to the address of the tag.
1159 uint64_t rel_offset;
1160 rel_offset = target->ReadUnsignedIntegerFromMemory(dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
1161 if (error.Success() && rel_offset != UINT64_MAX)
1162 {
1163 Address addr;
1164 addr_t debug_ptr_address = dyn_base + (offset - GetAddressByteSize()) + rel_offset;
1165 addr.SetOffset (debug_ptr_address);
1166 return addr;
1167 }
1168 }
Ed Maste54803652013-10-11 17:39:07 +00001169 }
Stephen Wilson2ab0a582011-01-15 00:08:44 +00001170 }
1171
1172 return Address();
1173}
1174
Jim Ingham672e6f52011-03-07 23:44:08 +00001175lldb_private::Address
Ed Maste81b4c5f2016-01-04 01:43:47 +00001176ObjectFileELF::GetEntryPointAddress ()
Jim Ingham672e6f52011-03-07 23:44:08 +00001177{
Stephen Wilsond126c8c2011-03-08 04:12:15 +00001178 if (m_entry_point_address.IsValid())
1179 return m_entry_point_address;
1180
1181 if (!ParseHeader() || !IsExecutable())
1182 return m_entry_point_address;
1183
Greg Clayton3046e662013-07-10 01:23:25 +00001184 SectionList *section_list = GetSectionList();
1185 addr_t offset = m_header.e_entry;
Stephen Wilsond126c8c2011-03-08 04:12:15 +00001186
Ed Maste81b4c5f2016-01-04 01:43:47 +00001187 if (!section_list)
Stephen Wilsond126c8c2011-03-08 04:12:15 +00001188 m_entry_point_address.SetOffset(offset);
Greg Clayton3046e662013-07-10 01:23:25 +00001189 else
1190 m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
Stephen Wilsond126c8c2011-03-08 04:12:15 +00001191 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00001192}
1193
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001194//----------------------------------------------------------------------
1195// ParseDependentModules
1196//----------------------------------------------------------------------
1197size_t
1198ObjectFileELF::ParseDependentModules()
1199{
1200 if (m_filespec_ap.get())
1201 return m_filespec_ap->GetSize();
1202
1203 m_filespec_ap.reset(new FileSpecList());
1204
Michael Sartaina7499c92013-07-01 19:45:50 +00001205 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001206 return 0;
1207
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001208 SectionList *section_list = GetSectionList();
1209 if (!section_list)
1210 return 0;
1211
Greg Clayton3046e662013-07-10 01:23:25 +00001212 // Find the SHT_DYNAMIC section.
1213 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
1214 if (!dynsym)
1215 return 0;
1216 assert (dynsym->GetObjectFile() == this);
1217
1218 const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
1219 if (!header)
1220 return 0;
1221 // sh_link: section header index of string table used by entries in the section.
1222 Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
1223 if (!dynstr)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001224 return 0;
1225
1226 DataExtractor dynsym_data;
1227 DataExtractor dynstr_data;
Greg Claytonc9660542012-02-05 02:38:54 +00001228 if (ReadSectionData(dynsym, dynsym_data) &&
1229 ReadSectionData(dynstr, dynstr_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001230 {
1231 ELFDynamic symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001232 const lldb::offset_t section_size = dynsym_data.GetByteSize();
1233 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001234
1235 // The only type of entries we are concerned with are tagged DT_NEEDED,
1236 // yielding the name of a required library.
1237 while (offset < section_size)
1238 {
1239 if (!symbol.Parse(dynsym_data, &offset))
1240 break;
1241
1242 if (symbol.d_tag != DT_NEEDED)
1243 continue;
1244
1245 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
1246 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +00001247 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001248 }
1249 }
1250
1251 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001252}
1253
1254//----------------------------------------------------------------------
Todd Fiala4339f3a2014-03-25 19:29:09 +00001255// GetProgramHeaderInfo
1256//----------------------------------------------------------------------
1257size_t
1258ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
1259 DataExtractor &object_data,
1260 const ELFHeader &header)
1261{
1262 // We have already parsed the program headers
1263 if (!program_headers.empty())
1264 return program_headers.size();
1265
1266 // If there are no program headers to read we are done.
1267 if (header.e_phnum == 0)
1268 return 0;
1269
1270 program_headers.resize(header.e_phnum);
1271 if (program_headers.size() != header.e_phnum)
1272 return 0;
1273
1274 const size_t ph_size = header.e_phnum * header.e_phentsize;
1275 const elf_off ph_offset = header.e_phoff;
1276 DataExtractor data;
1277 if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
1278 return 0;
1279
1280 uint32_t idx;
1281 lldb::offset_t offset;
1282 for (idx = 0, offset = 0; idx < header.e_phnum; ++idx)
1283 {
1284 if (program_headers[idx].Parse(data, &offset) == false)
1285 break;
1286 }
1287
1288 if (idx < program_headers.size())
1289 program_headers.resize(idx);
1290
1291 return program_headers.size();
1292
1293}
1294
1295//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296// ParseProgramHeaders
1297//----------------------------------------------------------------------
1298size_t
1299ObjectFileELF::ParseProgramHeaders()
1300{
Todd Fiala4339f3a2014-03-25 19:29:09 +00001301 return GetProgramHeaderInfo(m_program_headers, m_data, m_header);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302}
1303
Todd Fialab91de782014-06-27 16:52:49 +00001304lldb_private::Error
1305ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid)
Michael Sartainc836ae72013-05-23 20:57:03 +00001306{
Todd Fialab91de782014-06-27 16:52:49 +00001307 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES));
1308 Error error;
1309
Michael Sartainc836ae72013-05-23 20:57:03 +00001310 lldb::offset_t offset = 0;
Michael Sartainc836ae72013-05-23 20:57:03 +00001311
1312 while (true)
1313 {
Todd Fialab91de782014-06-27 16:52:49 +00001314 // Parse the note header. If this fails, bail out.
Greg Claytonb704b692015-10-28 18:04:38 +00001315 const lldb::offset_t note_offset = offset;
Ed Mastec113ff82013-12-02 17:49:13 +00001316 ELFNote note = ELFNote();
1317 if (!note.Parse(data, &offset))
Michael Sartainc836ae72013-05-23 20:57:03 +00001318 {
Todd Fialab91de782014-06-27 16:52:49 +00001319 // We're done.
1320 return error;
Michael Sartainc836ae72013-05-23 20:57:03 +00001321 }
Todd Fialab91de782014-06-27 16:52:49 +00001322
Todd Fialab91de782014-06-27 16:52:49 +00001323 if (log)
1324 log->Printf ("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, __FUNCTION__, note.n_name.c_str (), note.n_type);
1325
1326 // Process FreeBSD ELF notes.
1327 if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
1328 (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&
1329 (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE))
1330 {
Todd Fialab91de782014-06-27 16:52:49 +00001331 // Pull out the min version info.
1332 uint32_t version_info;
1333 if (data.GetU32 (&offset, &version_info, 1) == nullptr)
1334 {
1335 error.SetErrorString ("failed to read FreeBSD ABI note payload");
1336 return error;
1337 }
1338
1339 // Convert the version info into a major/minor number.
1340 const uint32_t version_major = version_info / 100000;
1341 const uint32_t version_minor = (version_info / 1000) % 100;
1342
1343 char os_name[32];
1344 snprintf (os_name, sizeof (os_name), "freebsd%" PRIu32 ".%" PRIu32, version_major, version_minor);
1345
1346 // Set the elf OS version to FreeBSD. Also clear the vendor.
1347 arch_spec.GetTriple ().setOSName (os_name);
1348 arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
1349
1350 if (log)
1351 log->Printf ("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_major, version_minor, static_cast<uint32_t> (version_info % 1000));
1352 }
1353 // Process GNU ELF notes.
1354 else if (note.n_name == LLDB_NT_OWNER_GNU)
1355 {
1356 switch (note.n_type)
1357 {
1358 case LLDB_NT_GNU_ABI_TAG:
1359 if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE)
1360 {
Todd Fialab91de782014-06-27 16:52:49 +00001361 // Pull out the min OS version supporting the ABI.
1362 uint32_t version_info[4];
1363 if (data.GetU32 (&offset, &version_info[0], note.n_descsz / 4) == nullptr)
1364 {
1365 error.SetErrorString ("failed to read GNU ABI note payload");
1366 return error;
1367 }
1368
1369 // Set the OS per the OS field.
1370 switch (version_info[0])
1371 {
1372 case LLDB_NT_GNU_ABI_OS_LINUX:
1373 arch_spec.GetTriple ().setOS (llvm::Triple::OSType::Linux);
1374 arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
1375 if (log)
1376 log->Printf ("ObjectFileELF::%s detected Linux, min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]);
1377 // FIXME we have the minimal version number, we could be propagating that. version_info[1] = OS Major, version_info[2] = OS Minor, version_info[3] = Revision.
1378 break;
1379 case LLDB_NT_GNU_ABI_OS_HURD:
1380 arch_spec.GetTriple ().setOS (llvm::Triple::OSType::UnknownOS);
1381 arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
1382 if (log)
1383 log->Printf ("ObjectFileELF::%s detected Hurd (unsupported), min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]);
1384 break;
1385 case LLDB_NT_GNU_ABI_OS_SOLARIS:
1386 arch_spec.GetTriple ().setOS (llvm::Triple::OSType::Solaris);
1387 arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
1388 if (log)
1389 log->Printf ("ObjectFileELF::%s detected Solaris, min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[1], version_info[2], version_info[3]);
1390 break;
1391 default:
1392 if (log)
1393 log->Printf ("ObjectFileELF::%s unrecognized OS in note, id %" PRIu32 ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, __FUNCTION__, version_info[0], version_info[1], version_info[2], version_info[3]);
1394 break;
1395 }
1396 }
1397 break;
1398
1399 case LLDB_NT_GNU_BUILD_ID_TAG:
1400 // Only bother processing this if we don't already have the uuid set.
1401 if (!uuid.IsValid())
1402 {
Todd Fialab91de782014-06-27 16:52:49 +00001403 // 16 bytes is UUID|MD5, 20 bytes is SHA1
1404 if ((note.n_descsz == 16 || note.n_descsz == 20))
1405 {
1406 uint8_t uuidbuf[20];
1407 if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == nullptr)
1408 {
1409 error.SetErrorString ("failed to read GNU_BUILD_ID note payload");
1410 return error;
1411 }
1412
1413 // Save the build id as the UUID for the module.
1414 uuid.SetBytes (uuidbuf, note.n_descsz);
1415 }
1416 }
1417 break;
1418 }
1419 }
1420 // Process NetBSD ELF notes.
1421 else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
1422 (note.n_type == LLDB_NT_NETBSD_ABI_TAG) &&
1423 (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE))
1424 {
Todd Fialab91de782014-06-27 16:52:49 +00001425 // Pull out the min version info.
1426 uint32_t version_info;
1427 if (data.GetU32 (&offset, &version_info, 1) == nullptr)
1428 {
1429 error.SetErrorString ("failed to read NetBSD ABI note payload");
1430 return error;
1431 }
1432
1433 // Set the elf OS version to NetBSD. Also clear the vendor.
1434 arch_spec.GetTriple ().setOS (llvm::Triple::OSType::NetBSD);
1435 arch_spec.GetTriple ().setVendor (llvm::Triple::VendorType::UnknownVendor);
1436
1437 if (log)
1438 log->Printf ("ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32, __FUNCTION__, version_info);
1439 }
Todd Fialacfee9632014-07-16 15:03:10 +00001440 // Process CSR kalimba notes
1441 else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) &&
1442 (note.n_name == LLDB_NT_OWNER_CSR))
1443 {
Todd Fialacfee9632014-07-16 15:03:10 +00001444 arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
1445 arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR);
1446
1447 // TODO At some point the description string could be processed.
1448 // It could provide a steer towards the kalimba variant which
1449 // this ELF targets.
1450 if(note.n_descsz)
1451 {
1452 const char *cstr = data.GetCStr(&offset, llvm::RoundUpToAlignment (note.n_descsz, 4));
1453 (void)cstr;
1454 }
1455 }
Tamas Berghammerdb037d92015-03-18 10:36:27 +00001456 else if (note.n_name == LLDB_NT_OWNER_ANDROID)
1457 {
1458 arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1459 arch_spec.GetTriple().setEnvironment(llvm::Triple::EnvironmentType::Android);
1460 }
Greg Claytonb704b692015-10-28 18:04:38 +00001461 else if (note.n_name == LLDB_NT_OWNER_LINUX)
1462 {
1463 // This is sometimes found in core files and usually contains extended register info
1464 arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1465 }
1466 else if (note.n_name == LLDB_NT_OWNER_CORE)
1467 {
1468 // Parse the NT_FILE to look for stuff in paths to shared libraries
1469 // As the contents look like:
1470 // count = 0x000000000000000a (10)
1471 // page_size = 0x0000000000001000 (4096)
1472 // Index start end file_ofs path
1473 // ===== ------------------ ------------------ ------------------ -------------------------------------
1474 // [ 0] 0x0000000000400000 0x0000000000401000 0x0000000000000000 /tmp/a.out
1475 // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out
1476 // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
1477 // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so
1478 // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so
1479 // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so
1480 // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so
1481 // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
1482 // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so
1483 // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
1484 if (note.n_type == NT_FILE)
1485 {
1486 uint64_t count = data.GetU64(&offset);
1487 offset += 8 + 3*8*count; // Skip page size and all start/end/file_ofs
1488 for (size_t i=0; i<count; ++i)
1489 {
1490 llvm::StringRef path(data.GetCStr(&offset));
1491 if (path.startswith("/lib/x86_64-linux-gnu"))
1492 {
1493 arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1494 break;
1495 }
1496 }
1497 }
1498 }
Todd Fialab91de782014-06-27 16:52:49 +00001499
Greg Claytonb704b692015-10-28 18:04:38 +00001500 // Calculate the offset of the next note just in case "offset" has been used
1501 // to poke at the contents of the note data
1502 offset = note_offset + note.GetByteSize();
Michael Sartainc836ae72013-05-23 20:57:03 +00001503 }
Todd Fialab91de782014-06-27 16:52:49 +00001504
1505 return error;
Michael Sartainc836ae72013-05-23 20:57:03 +00001506}
Michael Sartaina7499c92013-07-01 19:45:50 +00001507
Todd Fialab91de782014-06-27 16:52:49 +00001508
Michael Sartaina7499c92013-07-01 19:45:50 +00001509//----------------------------------------------------------------------
1510// GetSectionHeaderInfo
1511//----------------------------------------------------------------------
1512size_t
1513ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
1514 lldb_private::DataExtractor &object_data,
1515 const elf::ELFHeader &header,
1516 lldb_private::UUID &uuid,
1517 std::string &gnu_debuglink_file,
Todd Fialab91de782014-06-27 16:52:49 +00001518 uint32_t &gnu_debuglink_crc,
1519 ArchSpec &arch_spec)
Michael Sartaina7499c92013-07-01 19:45:50 +00001520{
Todd Fiala6477ea82014-07-11 15:13:33 +00001521 // Don't reparse the section headers if we already did that.
1522 if (!section_headers.empty())
1523 return section_headers.size();
1524
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001525 // Only initialize the arch_spec to okay defaults if they're not already set.
Todd Fialab91de782014-06-27 16:52:49 +00001526 // We'll refine this with note data as we parse the notes.
1527 if (arch_spec.GetTriple ().getOS () == llvm::Triple::OSType::UnknownOS)
1528 {
Ed Mastef6a13122015-06-05 13:03:08 +00001529 llvm::Triple::OSType ostype;
1530 llvm::Triple::OSType spec_ostype;
Matthew Gardiner5f675792014-08-27 12:09:39 +00001531 const uint32_t sub_type = subTypeFromElfHeader(header);
Ed Mastef6a13122015-06-05 13:03:08 +00001532 arch_spec.SetArchitecture (eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]);
1533 //
1534 // Validate if it is ok to remove GetOsFromOSABI
1535 GetOsFromOSABI (header.e_ident[EI_OSABI], ostype);
1536 spec_ostype = arch_spec.GetTriple ().getOS ();
1537 assert(spec_ostype == ostype);
Todd Fialab91de782014-06-27 16:52:49 +00001538 }
1539
Jaydeep Patil501a7812015-07-16 03:51:55 +00001540 if (arch_spec.GetMachine() == llvm::Triple::mips || arch_spec.GetMachine() == llvm::Triple::mipsel
1541 || arch_spec.GetMachine() == llvm::Triple::mips64 || arch_spec.GetMachine() == llvm::Triple::mips64el)
1542 {
1543 switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE)
1544 {
Ed Maste81b4c5f2016-01-04 01:43:47 +00001545 case llvm::ELF::EF_MIPS_MICROMIPS:
1546 arch_spec.SetFlags (ArchSpec::eMIPSAse_micromips);
Jaydeep Patil501a7812015-07-16 03:51:55 +00001547 break;
Ed Maste81b4c5f2016-01-04 01:43:47 +00001548 case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
1549 arch_spec.SetFlags (ArchSpec::eMIPSAse_mips16);
Jaydeep Patil501a7812015-07-16 03:51:55 +00001550 break;
Ed Maste81b4c5f2016-01-04 01:43:47 +00001551 case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
1552 arch_spec.SetFlags (ArchSpec::eMIPSAse_mdmx);
Jaydeep Patil501a7812015-07-16 03:51:55 +00001553 break;
Ed Maste81b4c5f2016-01-04 01:43:47 +00001554 default:
Jaydeep Patil501a7812015-07-16 03:51:55 +00001555 break;
1556 }
1557 }
1558
Michael Sartaina7499c92013-07-01 19:45:50 +00001559 // If there are no section headers we are done.
1560 if (header.e_shnum == 0)
1561 return 0;
1562
Todd Fialab91de782014-06-27 16:52:49 +00001563 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES));
1564
Michael Sartaina7499c92013-07-01 19:45:50 +00001565 section_headers.resize(header.e_shnum);
1566 if (section_headers.size() != header.e_shnum)
1567 return 0;
1568
1569 const size_t sh_size = header.e_shnum * header.e_shentsize;
1570 const elf_off sh_offset = header.e_shoff;
1571 DataExtractor sh_data;
1572 if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
1573 return 0;
1574
1575 uint32_t idx;
1576 lldb::offset_t offset;
1577 for (idx = 0, offset = 0; idx < header.e_shnum; ++idx)
1578 {
1579 if (section_headers[idx].Parse(sh_data, &offset) == false)
1580 break;
1581 }
1582 if (idx < section_headers.size())
1583 section_headers.resize(idx);
1584
1585 const unsigned strtab_idx = header.e_shstrndx;
1586 if (strtab_idx && strtab_idx < section_headers.size())
1587 {
1588 const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
1589 const size_t byte_size = sheader.sh_size;
1590 const Elf64_Off offset = sheader.sh_offset;
1591 lldb_private::DataExtractor shstr_data;
1592
1593 if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
1594 {
1595 for (SectionHeaderCollIter I = section_headers.begin();
1596 I != section_headers.end(); ++I)
1597 {
1598 static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink");
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001599 const ELFSectionHeaderInfo &sheader = *I;
1600 const uint64_t section_size = sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size;
Michael Sartaina7499c92013-07-01 19:45:50 +00001601 ConstString name(shstr_data.PeekCStr(I->sh_name));
1602
1603 I->section_name = name;
1604
Jaydeep Patil501a7812015-07-16 03:51:55 +00001605 if (arch_spec.GetMachine() == llvm::Triple::mips || arch_spec.GetMachine() == llvm::Triple::mipsel
1606 || arch_spec.GetMachine() == llvm::Triple::mips64 || arch_spec.GetMachine() == llvm::Triple::mips64el)
1607 {
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001608 uint32_t arch_flags = arch_spec.GetFlags ();
1609 DataExtractor data;
1610 if (sheader.sh_type == SHT_MIPS_ABIFLAGS)
Jaydeep Patil501a7812015-07-16 03:51:55 +00001611 {
Ed Maste81b4c5f2016-01-04 01:43:47 +00001612
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001613 if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
Jaydeep Patil501a7812015-07-16 03:51:55 +00001614 {
1615 lldb::offset_t ase_offset = 12; // MIPS ABI Flags Version: 0
Jaydeep Patil501a7812015-07-16 03:51:55 +00001616 arch_flags |= data.GetU32 (&ase_offset);
Jaydeep Patil501a7812015-07-16 03:51:55 +00001617 }
1618 }
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001619 // Settings appropriate ArchSpec ABI Flags
1620 if (header.e_flags & llvm::ELF::EF_MIPS_ABI2)
Ed Maste81b4c5f2016-01-04 01:43:47 +00001621 {
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001622 arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
1623 }
1624 else if (header.e_flags & llvm::ELF::EF_MIPS_ABI_O32)
1625 {
Ed Maste81b4c5f2016-01-04 01:43:47 +00001626 arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001627 }
1628 arch_spec.SetFlags (arch_flags);
Jaydeep Patil501a7812015-07-16 03:51:55 +00001629 }
1630
Michael Sartaina7499c92013-07-01 19:45:50 +00001631 if (name == g_sect_name_gnu_debuglink)
1632 {
1633 DataExtractor data;
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001634 if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
Michael Sartaina7499c92013-07-01 19:45:50 +00001635 {
1636 lldb::offset_t gnu_debuglink_offset = 0;
1637 gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
1638 gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4);
1639 data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
1640 }
1641 }
1642
Todd Fialab91de782014-06-27 16:52:49 +00001643 // Process ELF note section entries.
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001644 bool is_note_header = (sheader.sh_type == SHT_NOTE);
Tamas Berghammerdb037d92015-03-18 10:36:27 +00001645
1646 // The section header ".note.android.ident" is stored as a
1647 // PROGBITS type header but it is actually a note header.
1648 static ConstString g_sect_name_android_ident (".note.android.ident");
1649 if (!is_note_header && name == g_sect_name_android_ident)
1650 is_note_header = true;
1651
1652 if (is_note_header)
Michael Sartaina7499c92013-07-01 19:45:50 +00001653 {
Todd Fialab91de782014-06-27 16:52:49 +00001654 // Allow notes to refine module info.
Michael Sartaina7499c92013-07-01 19:45:50 +00001655 DataExtractor data;
Mohit K. Bhakkad9514a382015-09-09 10:32:20 +00001656 if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
Michael Sartaina7499c92013-07-01 19:45:50 +00001657 {
Todd Fialab91de782014-06-27 16:52:49 +00001658 Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid);
1659 if (error.Fail ())
1660 {
1661 if (log)
1662 log->Printf ("ObjectFileELF::%s ELF note processing failed: %s", __FUNCTION__, error.AsCString ());
1663 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001664 }
1665 }
1666 }
1667
Todd Fiala7df337f2015-10-13 23:41:19 +00001668 // Make any unknown triple components to be unspecified unknowns.
1669 if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
1670 arch_spec.GetTriple().setVendorName (llvm::StringRef());
1671 if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
1672 arch_spec.GetTriple().setOSName (llvm::StringRef());
1673
Michael Sartaina7499c92013-07-01 19:45:50 +00001674 return section_headers.size();
1675 }
1676 }
1677
1678 section_headers.clear();
1679 return 0;
1680}
1681
Ashok Thirumurthi4822d922013-07-11 20:39:00 +00001682size_t
1683ObjectFileELF::GetProgramHeaderCount()
1684{
1685 return ParseProgramHeaders();
1686}
1687
1688const elf::ELFProgramHeader *
1689ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id)
1690{
1691 if (!id || !ParseProgramHeaders())
1692 return NULL;
1693
1694 if (--id < m_program_headers.size())
1695 return &m_program_headers[id];
1696
1697 return NULL;
1698}
1699
Ed Maste81b4c5f2016-01-04 01:43:47 +00001700DataExtractor
Ashok Thirumurthi4822d922013-07-11 20:39:00 +00001701ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id)
1702{
1703 const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id);
1704 if (segment_header == NULL)
1705 return DataExtractor();
1706 return DataExtractor(m_data, segment_header->p_offset, segment_header->p_filesz);
1707}
1708
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00001709std::string
1710ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const
1711{
Bruce Mitchener0b6ba7c2015-07-04 05:16:58 +00001712 size_t pos = symbol_name.find('@');
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00001713 return symbol_name.substr(0, pos).str();
1714}
1715
Michael Sartaina7499c92013-07-01 19:45:50 +00001716//----------------------------------------------------------------------
1717// ParseSectionHeaders
1718//----------------------------------------------------------------------
1719size_t
1720ObjectFileELF::ParseSectionHeaders()
1721{
Todd Fialab91de782014-06-27 16:52:49 +00001722 return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec);
Michael Sartaina7499c92013-07-01 19:45:50 +00001723}
1724
Michael Sartaina7499c92013-07-01 19:45:50 +00001725const ObjectFileELF::ELFSectionHeaderInfo *
1726ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
1727{
Ashok Thirumurthi4822d922013-07-11 20:39:00 +00001728 if (!id || !ParseSectionHeaders())
Michael Sartaina7499c92013-07-01 19:45:50 +00001729 return NULL;
1730
1731 if (--id < m_section_headers.size())
1732 return &m_section_headers[id];
1733
1734 return NULL;
1735}
1736
Tamas Berghammer85fadd92015-05-08 09:40:05 +00001737lldb::user_id_t
1738ObjectFileELF::GetSectionIndexByName(const char* name)
1739{
1740 if (!name || !name[0] || !ParseSectionHeaders())
1741 return 0;
1742 for (size_t i = 1; i < m_section_headers.size(); ++i)
1743 if (m_section_headers[i].section_name == ConstString(name))
1744 return i;
1745 return 0;
1746}
1747
Greg Clayton3046e662013-07-10 01:23:25 +00001748void
1749ObjectFileELF::CreateSections(SectionList &unified_section_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001750{
Greg Clayton3046e662013-07-10 01:23:25 +00001751 if (!m_sections_ap.get() && ParseSectionHeaders())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001752 {
1753 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001754
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001755 for (SectionHeaderCollIter I = m_section_headers.begin();
1756 I != m_section_headers.end(); ++I)
1757 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001758 const ELFSectionHeaderInfo &header = *I;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001759
Michael Sartaina7499c92013-07-01 19:45:50 +00001760 ConstString& name = I->section_name;
Greg Clayton47037bc2012-03-27 02:40:46 +00001761 const uint64_t file_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
1762 const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001763
Greg Clayton4ceb9982010-07-21 22:54:26 +00001764 static ConstString g_sect_name_text (".text");
1765 static ConstString g_sect_name_data (".data");
1766 static ConstString g_sect_name_bss (".bss");
Greg Clayton741f3f92012-03-27 21:10:07 +00001767 static ConstString g_sect_name_tdata (".tdata");
1768 static ConstString g_sect_name_tbss (".tbss");
Greg Clayton4ceb9982010-07-21 22:54:26 +00001769 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001770 static ConstString g_sect_name_dwarf_debug_addr (".debug_addr");
Greg Clayton4ceb9982010-07-21 22:54:26 +00001771 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
1772 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
1773 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
1774 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
1775 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
1776 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
Siva Chandrad8335e92015-12-16 00:22:08 +00001777 static ConstString g_sect_name_dwarf_debug_macro (".debug_macro");
Greg Clayton4ceb9982010-07-21 22:54:26 +00001778 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
1779 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
1780 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
1781 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001782 static ConstString g_sect_name_dwarf_debug_str_offsets (".debug_str_offsets");
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001783 static ConstString g_sect_name_dwarf_debug_abbrev_dwo (".debug_abbrev.dwo");
1784 static ConstString g_sect_name_dwarf_debug_info_dwo (".debug_info.dwo");
1785 static ConstString g_sect_name_dwarf_debug_line_dwo (".debug_line.dwo");
Siva Chandrad8335e92015-12-16 00:22:08 +00001786 static ConstString g_sect_name_dwarf_debug_macro_dwo (".debug_macro.dwo");
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001787 static ConstString g_sect_name_dwarf_debug_loc_dwo (".debug_loc.dwo");
1788 static ConstString g_sect_name_dwarf_debug_str_dwo (".debug_str.dwo");
1789 static ConstString g_sect_name_dwarf_debug_str_offsets_dwo (".debug_str_offsets.dwo");
Greg Clayton4ceb9982010-07-21 22:54:26 +00001790 static ConstString g_sect_name_eh_frame (".eh_frame");
Tamas Berghammer648f3c72015-09-30 13:50:14 +00001791 static ConstString g_sect_name_arm_exidx (".ARM.exidx");
1792 static ConstString g_sect_name_arm_extab (".ARM.extab");
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001793 static ConstString g_sect_name_go_symtab (".gosymtab");
Greg Clayton4ceb9982010-07-21 22:54:26 +00001794
1795 SectionType sect_type = eSectionTypeOther;
1796
Greg Clayton741f3f92012-03-27 21:10:07 +00001797 bool is_thread_specific = false;
Michael Sartaina7499c92013-07-01 19:45:50 +00001798
Greg Clayton4ceb9982010-07-21 22:54:26 +00001799 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
1800 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
1801 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
Greg Clayton741f3f92012-03-27 21:10:07 +00001802 else if (name == g_sect_name_tdata)
1803 {
1804 sect_type = eSectionTypeData;
Ed Maste81b4c5f2016-01-04 01:43:47 +00001805 is_thread_specific = true;
Greg Clayton741f3f92012-03-27 21:10:07 +00001806 }
1807 else if (name == g_sect_name_tbss)
1808 {
Ed Maste81b4c5f2016-01-04 01:43:47 +00001809 sect_type = eSectionTypeZeroFill;
1810 is_thread_specific = true;
Greg Clayton741f3f92012-03-27 21:10:07 +00001811 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001812 // .debug_abbrev – Abbreviations used in the .debug_info section
1813 // .debug_aranges – Lookup table for mapping addresses to compilation units
1814 // .debug_frame – Call frame information
1815 // .debug_info – The core DWARF information section
1816 // .debug_line – Line number information
1817 // .debug_loc – Location lists used in DW_AT_location attributes
1818 // .debug_macinfo – Macro information
1819 // .debug_pubnames – Lookup table for mapping object and function names to compilation units
1820 // .debug_pubtypes – Lookup table for mapping type names to compilation units
1821 // .debug_ranges – Address ranges used in DW_AT_ranges attributes
1822 // .debug_str – String table used in .debug_info
Michael Sartain3cf443d2013-07-17 00:26:30 +00001823 // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
1824 // MISSING? .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
Michael Sartaina7499c92013-07-01 19:45:50 +00001825 // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001826 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
1827 else if (name == g_sect_name_dwarf_debug_addr) sect_type = eSectionTypeDWARFDebugAddr;
1828 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
1829 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
1830 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
1831 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
1832 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
1833 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
Siva Chandrad8335e92015-12-16 00:22:08 +00001834 else if (name == g_sect_name_dwarf_debug_macro) sect_type = eSectionTypeDWARFDebugMacro;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001835 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
1836 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
1837 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
1838 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
1839 else if (name == g_sect_name_dwarf_debug_str_offsets) sect_type = eSectionTypeDWARFDebugStrOffsets;
1840 else if (name == g_sect_name_dwarf_debug_abbrev_dwo) sect_type = eSectionTypeDWARFDebugAbbrev;
1841 else if (name == g_sect_name_dwarf_debug_info_dwo) sect_type = eSectionTypeDWARFDebugInfo;
1842 else if (name == g_sect_name_dwarf_debug_line_dwo) sect_type = eSectionTypeDWARFDebugLine;
Siva Chandrad8335e92015-12-16 00:22:08 +00001843 else if (name == g_sect_name_dwarf_debug_macro_dwo) sect_type = eSectionTypeDWARFDebugMacro;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001844 else if (name == g_sect_name_dwarf_debug_loc_dwo) sect_type = eSectionTypeDWARFDebugLoc;
1845 else if (name == g_sect_name_dwarf_debug_str_dwo) sect_type = eSectionTypeDWARFDebugStr;
1846 else if (name == g_sect_name_dwarf_debug_str_offsets_dwo) sect_type = eSectionTypeDWARFDebugStrOffsets;
1847 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
Tamas Berghammer648f3c72015-09-30 13:50:14 +00001848 else if (name == g_sect_name_arm_exidx) sect_type = eSectionTypeARMexidx;
1849 else if (name == g_sect_name_arm_extab) sect_type = eSectionTypeARMextab;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001850 else if (name == g_sect_name_go_symtab) sect_type = eSectionTypeGoSymtab;
Michael Sartaina7499c92013-07-01 19:45:50 +00001851
1852 switch (header.sh_type)
Michael Sartainc836ae72013-05-23 20:57:03 +00001853 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001854 case SHT_SYMTAB:
1855 assert (sect_type == eSectionTypeOther);
1856 sect_type = eSectionTypeELFSymbolTable;
1857 break;
1858 case SHT_DYNSYM:
1859 assert (sect_type == eSectionTypeOther);
1860 sect_type = eSectionTypeELFDynamicSymbols;
1861 break;
1862 case SHT_RELA:
1863 case SHT_REL:
1864 assert (sect_type == eSectionTypeOther);
1865 sect_type = eSectionTypeELFRelocationEntries;
1866 break;
1867 case SHT_DYNAMIC:
1868 assert (sect_type == eSectionTypeOther);
1869 sect_type = eSectionTypeELFDynamicLinkInfo;
1870 break;
Michael Sartainc836ae72013-05-23 20:57:03 +00001871 }
Michael Sartaina7499c92013-07-01 19:45:50 +00001872
Matthew Gardinerf03e6d842014-09-29 08:02:24 +00001873 if (eSectionTypeOther == sect_type)
1874 {
1875 // the kalimba toolchain assumes that ELF section names are free-form. It does
Bruce Mitchenere171da52015-07-22 00:16:02 +00001876 // support linkscripts which (can) give rise to various arbitrarily named
Ed Maste81b4c5f2016-01-04 01:43:47 +00001877 // sections being "Code" or "Data".
Matthew Gardinerf03e6d842014-09-29 08:02:24 +00001878 sect_type = kalimbaSectionType(m_header, header);
1879 }
1880
1881 const uint32_t target_bytes_size =
Ed Maste81b4c5f2016-01-04 01:43:47 +00001882 (eSectionTypeData == sect_type || eSectionTypeZeroFill == sect_type) ?
Matthew Gardinerf03e6d842014-09-29 08:02:24 +00001883 m_arch_spec.GetDataByteSize() :
1884 eSectionTypeCode == sect_type ?
1885 m_arch_spec.GetCodeByteSize() : 1;
1886
Zachary Turner736d4d82014-06-25 05:42:32 +00001887 elf::elf_xword log2align = (header.sh_addralign==0)
1888 ? 0
1889 : llvm::Log2_64(header.sh_addralign);
Greg Clayton3046e662013-07-10 01:23:25 +00001890 SectionSP section_sp (new Section(GetModule(), // Module to which this section belongs.
1891 this, // ObjectFile to which this section belongs and should read section data from.
1892 SectionIndex(I), // Section ID.
1893 name, // Section name.
1894 sect_type, // Section type.
1895 header.sh_addr, // VM address.
1896 vm_size, // VM size in bytes of this section.
1897 header.sh_offset, // Offset of this section in the file.
1898 file_size, // Size of the section as found in the file.
Zachary Turner736d4d82014-06-25 05:42:32 +00001899 log2align, // Alignment of the section
Matthew Gardinerf03e6d842014-09-29 08:02:24 +00001900 header.sh_flags, // Flags for this section.
1901 target_bytes_size));// Number of host bytes per target byte
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001902
Greg Clayton741f3f92012-03-27 21:10:07 +00001903 if (is_thread_specific)
1904 section_sp->SetIsThreadSpecific (is_thread_specific);
1905 m_sections_ap->AddSection(section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001906 }
1907 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001908
Greg Clayton3046e662013-07-10 01:23:25 +00001909 if (m_sections_ap.get())
1910 {
1911 if (GetType() == eTypeDebugInfo)
1912 {
1913 static const SectionType g_sections[] =
1914 {
Greg Clayton3046e662013-07-10 01:23:25 +00001915 eSectionTypeDWARFDebugAbbrev,
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001916 eSectionTypeDWARFDebugAddr,
1917 eSectionTypeDWARFDebugAranges,
Greg Clayton3046e662013-07-10 01:23:25 +00001918 eSectionTypeDWARFDebugFrame,
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001919 eSectionTypeDWARFDebugInfo,
Greg Clayton3046e662013-07-10 01:23:25 +00001920 eSectionTypeDWARFDebugLine,
Greg Clayton3046e662013-07-10 01:23:25 +00001921 eSectionTypeDWARFDebugLoc,
1922 eSectionTypeDWARFDebugMacInfo,
1923 eSectionTypeDWARFDebugPubNames,
1924 eSectionTypeDWARFDebugPubTypes,
1925 eSectionTypeDWARFDebugRanges,
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001926 eSectionTypeDWARFDebugStr,
1927 eSectionTypeDWARFDebugStrOffsets,
Greg Clayton3046e662013-07-10 01:23:25 +00001928 eSectionTypeELFSymbolTable,
1929 };
1930 SectionList *elf_section_list = m_sections_ap.get();
1931 for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
1932 {
1933 SectionType section_type = g_sections[idx];
1934 SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
1935 if (section_sp)
1936 {
1937 SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
1938 if (module_section_sp)
1939 unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
1940 else
1941 unified_section_list.AddSection (section_sp);
1942 }
1943 }
1944 }
1945 else
1946 {
1947 unified_section_list = *m_sections_ap;
1948 }
1949 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001950}
1951
Stephane Sezer9187e732015-09-11 18:56:59 +00001952// Find the arm/aarch64 mapping symbol character in the given symbol name. Mapping symbols have the
Tamas Berghammerc7776e42015-09-11 10:04:00 +00001953// form of "$<char>[.<any>]*". Additionally we recognize cases when the mapping symbol prefixed by
1954// an arbitrary string because if a symbol prefix added to each symbol in the object file with
1955// objcopy then the mapping symbols are also prefixed.
1956static char
1957FindArmAarch64MappingSymbol(const char* symbol_name)
1958{
1959 if (!symbol_name)
1960 return '\0';
1961
1962 const char* dollar_pos = ::strchr(symbol_name, '$');
1963 if (!dollar_pos || dollar_pos[1] == '\0')
1964 return '\0';
1965
1966 if (dollar_pos[2] == '\0' || dollar_pos[2] == '.')
1967 return dollar_pos[1];
1968 return '\0';
1969}
1970
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00001971#define STO_MIPS_ISA (3 << 6)
1972#define STO_MICROMIPS (2 << 6)
1973#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER) & STO_MIPS_ISA) == STO_MICROMIPS)
1974
Greg Clayton3046e662013-07-10 01:23:25 +00001975// private
Michael Sartaina7499c92013-07-01 19:45:50 +00001976unsigned
Greg Clayton3046e662013-07-10 01:23:25 +00001977ObjectFileELF::ParseSymbols (Symtab *symtab,
1978 user_id_t start_id,
1979 SectionList *section_list,
1980 const size_t num_symbols,
1981 const DataExtractor &symtab_data,
1982 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001983{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001984 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00001985 lldb::offset_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001986
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001987 static ConstString text_section_name(".text");
1988 static ConstString init_section_name(".init");
1989 static ConstString fini_section_name(".fini");
1990 static ConstString ctors_section_name(".ctors");
1991 static ConstString dtors_section_name(".dtors");
1992
1993 static ConstString data_section_name(".data");
1994 static ConstString rodata_section_name(".rodata");
1995 static ConstString rodata1_section_name(".rodata1");
1996 static ConstString data2_section_name(".data1");
1997 static ConstString bss_section_name(".bss");
Justin Hibbits6256a0e2014-10-31 02:34:28 +00001998 static ConstString opd_section_name(".opd"); // For ppc64
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001999
Tamas Berghammerc9627ae2015-07-13 09:54:41 +00002000 // On Android the oatdata and the oatexec symbols in system@framework@boot.oat covers the full
2001 // .text section what causes issues with displaying unusable symbol name to the user and very
2002 // slow unwinding speed because the instruction emulation based unwind plans try to emulate all
2003 // instructions in these symbols. Don't add these symbols to the symbol list as they have no
2004 // use for the debugger and they are causing a lot of trouble.
2005 // Filtering can't be restricted to Android because this special object file don't contain the
2006 // note section specifying the environment to Android but the custom extension and file name
2007 // makes it highly unlikely that this will collide with anything else.
2008 bool skip_oatdata_oatexec = m_file.GetFilename() == ConstString("system@framework@boot.oat");
2009
Tamas Berghammer9fa11472015-10-27 10:43:27 +00002010 ArchSpec arch;
2011 GetArchitecture(arch);
2012
2013 // Local cache to avoid doing a FindSectionByName for each symbol. The "const char*" key must
2014 // came from a ConstString object so they can be compared by pointer
2015 std::unordered_map<const char*, lldb::SectionSP> section_name_to_section;
2016
Stephen Wilson499b40e2011-03-30 16:07:05 +00002017 unsigned i;
2018 for (i = 0; i < num_symbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002019 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002020 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002021 break;
Ed Maste81b4c5f2016-01-04 01:43:47 +00002022
Greg Clayton9594f4c2013-04-13 23:17:23 +00002023 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
2024
Andrew MacPherson17220c12014-03-05 10:12:43 +00002025 // No need to add non-section symbols that have no names
2026 if (symbol.getType() != STT_SECTION &&
2027 (symbol_name == NULL || symbol_name[0] == '\0'))
Greg Clayton9594f4c2013-04-13 23:17:23 +00002028 continue;
2029
Tamas Berghammerc9627ae2015-07-13 09:54:41 +00002030 // Skipping oatdata and oatexec sections if it is requested. See details above the
2031 // definition of skip_oatdata_oatexec for the reasons.
2032 if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 || ::strcmp(symbol_name, "oatexec") == 0))
2033 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002034
Greg Claytone72dfb32012-02-24 01:59:29 +00002035 SectionSP symbol_section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002036 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002037 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002038
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002039 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002040 {
2041 case SHN_ABS:
2042 symbol_type = eSymbolTypeAbsolute;
2043 break;
2044 case SHN_UNDEF:
2045 symbol_type = eSymbolTypeUndefined;
2046 break;
2047 default:
Greg Claytone72dfb32012-02-24 01:59:29 +00002048 symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002049 break;
2050 }
2051
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002052 // If a symbol is undefined do not process it further even if it has a STT type
2053 if (symbol_type != eSymbolTypeUndefined)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002054 {
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002055 switch (symbol.getType())
2056 {
2057 default:
2058 case STT_NOTYPE:
2059 // The symbol's type is not specified.
2060 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002061
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002062 case STT_OBJECT:
2063 // The symbol is associated with a data object, such as a variable,
2064 // an array, etc.
2065 symbol_type = eSymbolTypeData;
2066 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002067
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002068 case STT_FUNC:
2069 // The symbol is associated with a function or other executable code.
2070 symbol_type = eSymbolTypeCode;
2071 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002072
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002073 case STT_SECTION:
2074 // The symbol is associated with a section. Symbol table entries of
2075 // this type exist primarily for relocation and normally have
2076 // STB_LOCAL binding.
2077 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002078
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002079 case STT_FILE:
2080 // Conventionally, the symbol's name gives the name of the source
2081 // file associated with the object file. A file symbol has STB_LOCAL
2082 // binding, its section index is SHN_ABS, and it precedes the other
2083 // STB_LOCAL symbols for the file, if it is present.
Greg Clayton9594f4c2013-04-13 23:17:23 +00002084 symbol_type = eSymbolTypeSourceFile;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002085 break;
Matt Kopec00049b82013-02-27 20:13:38 +00002086
2087 case STT_GNU_IFUNC:
2088 // The symbol is associated with an indirect function. The actual
2089 // function will be resolved if it is referenced.
2090 symbol_type = eSymbolTypeResolver;
2091 break;
Matt Kopec92dd5cf2013-02-12 18:30:30 +00002092 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002093 }
2094
2095 if (symbol_type == eSymbolTypeInvalid)
2096 {
Greg Claytone72dfb32012-02-24 01:59:29 +00002097 if (symbol_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002098 {
Greg Claytone72dfb32012-02-24 01:59:29 +00002099 const ConstString &sect_name = symbol_section_sp->GetName();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002100 if (sect_name == text_section_name ||
2101 sect_name == init_section_name ||
2102 sect_name == fini_section_name ||
2103 sect_name == ctors_section_name ||
2104 sect_name == dtors_section_name)
2105 {
2106 symbol_type = eSymbolTypeCode;
2107 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002108 else if (sect_name == data_section_name ||
2109 sect_name == data2_section_name ||
2110 sect_name == rodata_section_name ||
2111 sect_name == rodata1_section_name ||
2112 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002113 {
2114 symbol_type = eSymbolTypeData;
2115 }
2116 }
2117 }
2118
Todd Fialafbd703a2014-09-15 22:33:39 +00002119 int64_t symbol_value_offset = 0;
2120 uint32_t additional_flags = 0;
Todd Fiala1a088662014-09-15 16:27:44 +00002121
Tamas Berghammer9fa11472015-10-27 10:43:27 +00002122 if (arch.IsValid())
Todd Fiala1a088662014-09-15 16:27:44 +00002123 {
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002124 if (arch.GetMachine() == llvm::Triple::arm)
Todd Fialafbd703a2014-09-15 22:33:39 +00002125 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002126 if (symbol.getBinding() == STB_LOCAL)
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002127 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002128 char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
Tamas Berghammerb52bbd12015-04-17 09:36:59 +00002129 if (symbol_type == eSymbolTypeCode)
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002130 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002131 switch (mapping_symbol)
Tamas Berghammerb52bbd12015-04-17 09:36:59 +00002132 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002133 case 'a':
2134 // $a[.<any>]* - marks an ARM instruction sequence
2135 m_address_class_map[symbol.st_value] = eAddressClassCode;
2136 break;
2137 case 'b':
2138 case 't':
2139 // $b[.<any>]* - marks a THUMB BL instruction sequence
2140 // $t[.<any>]* - marks a THUMB instruction sequence
2141 m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
2142 break;
2143 case 'd':
2144 // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2145 m_address_class_map[symbol.st_value] = eAddressClassData;
2146 break;
Tamas Berghammerb52bbd12015-04-17 09:36:59 +00002147 }
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002148 }
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002149 if (mapping_symbol)
2150 continue;
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002151 }
2152 }
2153 else if (arch.GetMachine() == llvm::Triple::aarch64)
2154 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002155 if (symbol.getBinding() == STB_LOCAL)
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002156 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002157 char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
Tamas Berghammerb52bbd12015-04-17 09:36:59 +00002158 if (symbol_type == eSymbolTypeCode)
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002159 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002160 switch (mapping_symbol)
Tamas Berghammerb52bbd12015-04-17 09:36:59 +00002161 {
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002162 case 'x':
2163 // $x[.<any>]* - marks an A64 instruction sequence
2164 m_address_class_map[symbol.st_value] = eAddressClassCode;
2165 break;
2166 case 'd':
2167 // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2168 m_address_class_map[symbol.st_value] = eAddressClassData;
2169 break;
Tamas Berghammerb52bbd12015-04-17 09:36:59 +00002170 }
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002171 }
Tamas Berghammerc7776e42015-09-11 10:04:00 +00002172 if (mapping_symbol)
2173 continue;
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002174 }
2175 }
2176
2177 if (arch.GetMachine() == llvm::Triple::arm)
2178 {
Aidan Dodds5f2d0c32015-05-28 15:37:01 +00002179 if (symbol_type == eSymbolTypeCode)
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002180 {
Aidan Dodds5f2d0c32015-05-28 15:37:01 +00002181 if (symbol.st_value & 1)
2182 {
2183 // Subtracting 1 from the address effectively unsets
2184 // the low order bit, which results in the address
2185 // actually pointing to the beginning of the symbol.
2186 // This delta will be used below in conjunction with
2187 // symbol.st_value to produce the final symbol_value
2188 // that we store in the symtab.
2189 symbol_value_offset = -1;
Aidan Dodds5f2d0c32015-05-28 15:37:01 +00002190 m_address_class_map[symbol.st_value^1] = eAddressClassCodeAlternateISA;
2191 }
2192 else
2193 {
2194 // This address is ARM
2195 m_address_class_map[symbol.st_value] = eAddressClassCode;
2196 }
Tamas Berghammer83544cf2015-04-07 10:43:50 +00002197 }
Todd Fialafbd703a2014-09-15 22:33:39 +00002198 }
Jaydeep Patil44d07fc2015-09-22 06:36:56 +00002199
2200 /*
2201 * MIPS:
2202 * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for MIPS).
2203 * This allows processer to switch between microMIPS and MIPS without any need
2204 * for special mode-control register. However, apart from .debug_line, none of
2205 * the ELF/DWARF sections set the ISA bit (for symbol or section). Use st_other
2206 * flag to check whether the symbol is microMIPS and then set the address class
2207 * accordingly.
2208 */
2209 const llvm::Triple::ArchType llvm_arch = arch.GetMachine();
2210 if (llvm_arch == llvm::Triple::mips || llvm_arch == llvm::Triple::mipsel
2211 || llvm_arch == llvm::Triple::mips64 || llvm_arch == llvm::Triple::mips64el)
2212 {
2213 if (IS_MICROMIPS(symbol.st_other))
2214 m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
2215 else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode))
2216 {
2217 symbol.st_value = symbol.st_value & (~1ull);
2218 m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
2219 }
2220 else
2221 {
2222 if (symbol_type == eSymbolTypeCode)
2223 m_address_class_map[symbol.st_value] = eAddressClassCode;
2224 else if (symbol_type == eSymbolTypeData)
2225 m_address_class_map[symbol.st_value] = eAddressClassData;
2226 else
2227 m_address_class_map[symbol.st_value] = eAddressClassUnknown;
2228 }
2229 }
Todd Fiala1a088662014-09-15 16:27:44 +00002230 }
2231
Tamas Berghammerd00438e2015-07-30 12:38:18 +00002232 // symbol_value_offset may contain 0 for ARM symbols or -1 for
2233 // THUMB symbols. See above for more details.
2234 uint64_t symbol_value = symbol.st_value + symbol_value_offset;
2235 if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile)
2236 symbol_value -= symbol_section_sp->GetFileAddress();
2237
2238 if (symbol_section_sp)
Michael Sartaina7499c92013-07-01 19:45:50 +00002239 {
2240 ModuleSP module_sp(GetModule());
2241 if (module_sp)
2242 {
Greg Clayton3046e662013-07-10 01:23:25 +00002243 SectionList *module_section_list = module_sp->GetSectionList();
2244 if (module_section_list && module_section_list != section_list)
Michael Sartaina7499c92013-07-01 19:45:50 +00002245 {
2246 const ConstString &sect_name = symbol_section_sp->GetName();
Tamas Berghammer9fa11472015-10-27 10:43:27 +00002247 auto section_it = section_name_to_section.find(sect_name.GetCString());
2248 if (section_it == section_name_to_section.end())
2249 section_it = section_name_to_section.emplace(
2250 sect_name.GetCString(),
2251 module_section_list->FindSectionByName (sect_name)).first;
2252 if (section_it->second && section_it->second->GetFileSize())
2253 symbol_section_sp = section_it->second;
Michael Sartaina7499c92013-07-01 19:45:50 +00002254 }
2255 }
2256 }
2257
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002258 bool is_global = symbol.getBinding() == STB_GLOBAL;
Todd Fialafbd703a2014-09-15 22:33:39 +00002259 uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
Greg Clayton47037bc2012-03-27 02:40:46 +00002260 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Todd Fialafbd703a2014-09-15 22:33:39 +00002261
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00002262 llvm::StringRef symbol_ref(symbol_name);
2263
2264 // Symbol names may contain @VERSION suffixes. Find those and strip them temporarily.
2265 size_t version_pos = symbol_ref.find('@');
2266 bool has_suffix = version_pos != llvm::StringRef::npos;
2267 llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
2268 Mangled mangled(ConstString(symbol_bare), is_mangled);
2269
2270 // Now append the suffix back to mangled and unmangled names. Only do it if the
Bruce Mitchenere171da52015-07-22 00:16:02 +00002271 // demangling was successful (string is not empty).
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00002272 if (has_suffix)
2273 {
2274 llvm::StringRef suffix = symbol_ref.substr(version_pos);
2275
2276 llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
2277 if (! mangled_name.empty())
2278 mangled.SetMangledName( ConstString((mangled_name + suffix).str()) );
2279
Greg Claytonddaf6a72015-07-08 22:32:23 +00002280 ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeUnknown);
2281 llvm::StringRef demangled_name = demangled.GetStringRef();
2282 if (!demangled_name.empty())
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00002283 mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) );
2284 }
2285
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002286 Symbol dc_symbol(
Greg Claytone72dfb32012-02-24 01:59:29 +00002287 i + start_id, // ID is the original symbol table index.
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00002288 mangled,
Greg Claytone72dfb32012-02-24 01:59:29 +00002289 symbol_type, // Type of this symbol
2290 is_global, // Is this globally visible?
2291 false, // Is this symbol debug info?
2292 false, // Is this symbol a trampoline?
2293 false, // Is this symbol artificial?
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00002294 AddressRange(
2295 symbol_section_sp, // Section in which this symbol is defined or null.
2296 symbol_value, // Offset in section or symbol value.
2297 symbol.st_size), // Size in bytes of this symbol.
Tamas Berghammerdcad4242016-01-18 11:49:18 +00002298 symbol.st_size != 0, // Size is valid if it is not 0
Tamas Berghammer44ff9cce2015-06-24 11:27:32 +00002299 has_suffix, // Contains linker annotations?
2300 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002301 symtab->AddSymbol(dc_symbol);
2302 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00002303 return i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002304}
2305
Stephen Wilson499b40e2011-03-30 16:07:05 +00002306unsigned
Tamas Berghammerdcad4242016-01-18 11:49:18 +00002307ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002308{
Greg Clayton3046e662013-07-10 01:23:25 +00002309 if (symtab->GetObjectFile() != this)
2310 {
2311 // If the symbol table section is owned by a different object file, have it do the
2312 // parsing.
2313 ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
2314 return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
2315 }
2316
2317 // Get section list for this object file.
2318 SectionList *section_list = m_sections_ap.get();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002319 if (!section_list)
Stephen Wilson499b40e2011-03-30 16:07:05 +00002320 return 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002321
Greg Clayton3046e662013-07-10 01:23:25 +00002322 user_id_t symtab_id = symtab->GetID();
2323 const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
Ed Maste81b4c5f2016-01-04 01:43:47 +00002324 assert(symtab_hdr->sh_type == SHT_SYMTAB ||
Michael Sartaina7499c92013-07-01 19:45:50 +00002325 symtab_hdr->sh_type == SHT_DYNSYM);
2326
Greg Clayton3046e662013-07-10 01:23:25 +00002327 // sh_link: section header index of associated string table.
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002328 // Section ID's are ones based.
Stephen Wilson499b40e2011-03-30 16:07:05 +00002329 user_id_t strtab_id = symtab_hdr->sh_link + 1;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002330 Section *strtab = section_list->FindSectionByID(strtab_id).get();
Greg Clayton3046e662013-07-10 01:23:25 +00002331
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002332 if (symtab && strtab)
2333 {
Greg Clayton3046e662013-07-10 01:23:25 +00002334 assert (symtab->GetObjectFile() == this);
2335 assert (strtab->GetObjectFile() == this);
2336
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002337 DataExtractor symtab_data;
2338 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00002339 if (ReadSectionData(symtab, symtab_data) &&
2340 ReadSectionData(strtab, strtab_data))
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002341 {
Greg Clayton3046e662013-07-10 01:23:25 +00002342 size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
2343
Arnaud A. de Grandmaison62e5f4d2014-03-22 20:23:26 +00002344 return ParseSymbols(symbol_table, start_id, section_list,
2345 num_symbols, symtab_data, strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002346 }
2347 }
Stephen Wilson499b40e2011-03-30 16:07:05 +00002348
Arnaud A. de Grandmaison62e5f4d2014-03-22 20:23:26 +00002349 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00002350}
2351
2352size_t
2353ObjectFileELF::ParseDynamicSymbols()
2354{
2355 if (m_dynamic_symbols.size())
2356 return m_dynamic_symbols.size();
2357
Stephen Wilson499b40e2011-03-30 16:07:05 +00002358 SectionList *section_list = GetSectionList();
2359 if (!section_list)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00002360 return 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00002361
Greg Clayton3046e662013-07-10 01:23:25 +00002362 // Find the SHT_DYNAMIC section.
2363 Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00002364 if (!dynsym)
Bill Wendlinged24dcc2012-04-03 07:50:11 +00002365 return 0;
Greg Clayton3046e662013-07-10 01:23:25 +00002366 assert (dynsym->GetObjectFile() == this);
Stephen Wilson499b40e2011-03-30 16:07:05 +00002367
2368 ELFDynamic symbol;
2369 DataExtractor dynsym_data;
Greg Claytonc9660542012-02-05 02:38:54 +00002370 if (ReadSectionData(dynsym, dynsym_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00002371 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002372 const lldb::offset_t section_size = dynsym_data.GetByteSize();
2373 lldb::offset_t cursor = 0;
Stephen Wilson499b40e2011-03-30 16:07:05 +00002374
2375 while (cursor < section_size)
2376 {
Stephen Wilson499b40e2011-03-30 16:07:05 +00002377 if (!symbol.Parse(dynsym_data, &cursor))
2378 break;
2379
2380 m_dynamic_symbols.push_back(symbol);
2381 }
2382 }
2383
2384 return m_dynamic_symbols.size();
2385}
2386
2387const ELFDynamic *
2388ObjectFileELF::FindDynamicSymbol(unsigned tag)
2389{
2390 if (!ParseDynamicSymbols())
2391 return NULL;
2392
Stephen Wilson499b40e2011-03-30 16:07:05 +00002393 DynamicSymbolCollIter I = m_dynamic_symbols.begin();
2394 DynamicSymbolCollIter E = m_dynamic_symbols.end();
2395 for ( ; I != E; ++I)
2396 {
2397 ELFDynamic *symbol = &*I;
2398
2399 if (symbol->d_tag == tag)
2400 return symbol;
2401 }
2402
2403 return NULL;
2404}
2405
Stephen Wilson499b40e2011-03-30 16:07:05 +00002406unsigned
2407ObjectFileELF::PLTRelocationType()
2408{
Michael Sartainf7899542013-08-22 21:25:53 +00002409 // DT_PLTREL
2410 // This member specifies the type of relocation entry to which the
2411 // procedure linkage table refers. The d_val member holds DT_REL or
2412 // DT_RELA, as appropriate. All relocations in a procedure linkage table
2413 // must use the same relocation.
Stephen Wilson499b40e2011-03-30 16:07:05 +00002414 const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
2415
2416 if (symbol)
2417 return symbol->d_val;
2418
2419 return 0;
2420}
2421
Tamas Berghammer85fadd92015-05-08 09:40:05 +00002422// Returns the size of the normal plt entries and the offset of the first normal plt entry. The
Bruce Mitchenere171da52015-07-22 00:16:02 +00002423// 0th entry in the plt table is usually a resolution entry which have different size in some
Tamas Berghammer85fadd92015-05-08 09:40:05 +00002424// architectures then the rest of the plt entries.
2425static std::pair<uint64_t, uint64_t>
2426GetPltEntrySizeAndOffset(const ELFSectionHeader* rel_hdr, const ELFSectionHeader* plt_hdr)
2427{
2428 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
2429
2430 // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes.
2431 // So round the entsize up by the alignment if addralign is set.
2432 elf_xword plt_entsize = plt_hdr->sh_addralign ?
2433 llvm::RoundUpToAlignment (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
2434
2435 if (plt_entsize == 0)
2436 {
2437 // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the size of the plt
2438 // entries based on the number of entries and the size of the plt section with the
Bruce Mitchenere171da52015-07-22 00:16:02 +00002439 // assumption that the size of the 0th entry is at least as big as the size of the normal
2440 // entries and it isn't much bigger then that.
Tamas Berghammer85fadd92015-05-08 09:40:05 +00002441 if (plt_hdr->sh_addralign)
2442 plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign / (num_relocations + 1) * plt_hdr->sh_addralign;
2443 else
2444 plt_entsize = plt_hdr->sh_size / (num_relocations + 1);
2445 }
2446
2447 elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize;
2448
2449 return std::make_pair(plt_entsize, plt_offset);
2450}
2451
Stephen Wilson499b40e2011-03-30 16:07:05 +00002452static unsigned
2453ParsePLTRelocations(Symtab *symbol_table,
2454 user_id_t start_id,
2455 unsigned rel_type,
2456 const ELFHeader *hdr,
2457 const ELFSectionHeader *rel_hdr,
2458 const ELFSectionHeader *plt_hdr,
2459 const ELFSectionHeader *sym_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00002460 const lldb::SectionSP &plt_section_sp,
Stephen Wilson499b40e2011-03-30 16:07:05 +00002461 DataExtractor &rel_data,
2462 DataExtractor &symtab_data,
2463 DataExtractor &strtab_data)
2464{
2465 ELFRelocation rel(rel_type);
2466 ELFSymbol symbol;
Greg Claytonc7bece562013-01-25 18:06:21 +00002467 lldb::offset_t offset = 0;
Tamas Berghammer85fadd92015-05-08 09:40:05 +00002468
2469 uint64_t plt_offset, plt_entsize;
2470 std::tie(plt_entsize, plt_offset) = GetPltEntrySizeAndOffset(rel_hdr, plt_hdr);
Greg Claytonc7bece562013-01-25 18:06:21 +00002471 const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00002472
2473 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
2474 reloc_info_fn reloc_type;
2475 reloc_info_fn reloc_symbol;
2476
Greg Claytond091afe2012-11-12 22:53:16 +00002477 if (hdr->Is32Bit())
Stephen Wilson499b40e2011-03-30 16:07:05 +00002478 {
2479 reloc_type = ELFRelocation::RelocType32;
2480 reloc_symbol = ELFRelocation::RelocSymbol32;
2481 }
2482 else
2483 {
2484 reloc_type = ELFRelocation::RelocType64;
2485 reloc_symbol = ELFRelocation::RelocSymbol64;
2486 }
2487
2488 unsigned slot_type = hdr->GetRelocationJumpSlotType();
2489 unsigned i;
2490 for (i = 0; i < num_relocations; ++i)
2491 {
2492 if (rel.Parse(rel_data, &offset) == false)
2493 break;
2494
2495 if (reloc_type(rel) != slot_type)
2496 continue;
2497
Greg Claytonc7bece562013-01-25 18:06:21 +00002498 lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00002499 if (!symbol.Parse(symtab_data, &symbol_offset))
2500 break;
2501
2502 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Greg Clayton47037bc2012-03-27 02:40:46 +00002503 bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
Tamas Berghammer85fadd92015-05-08 09:40:05 +00002504 uint64_t plt_index = plt_offset + i * plt_entsize;
Stephen Wilson499b40e2011-03-30 16:07:05 +00002505
2506 Symbol jump_symbol(
2507 i + start_id, // Symbol table index
2508 symbol_name, // symbol name.
Greg Clayton47037bc2012-03-27 02:40:46 +00002509 is_mangled, // is the symbol name mangled?
Stephen Wilson499b40e2011-03-30 16:07:05 +00002510 eSymbolTypeTrampoline, // Type of this symbol
2511 false, // Is this globally visible?
2512 false, // Is this symbol debug info?
2513 true, // Is this symbol a trampoline?
2514 true, // Is this symbol artificial?
Greg Claytone72dfb32012-02-24 01:59:29 +00002515 plt_section_sp, // Section in which this symbol is defined or null.
Stephen Wilson499b40e2011-03-30 16:07:05 +00002516 plt_index, // Offset in section or symbol value.
2517 plt_entsize, // Size in bytes of this symbol.
Greg Clayton9594f4c2013-04-13 23:17:23 +00002518 true, // Size is valid
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00002519 false, // Contains linker annotations?
Stephen Wilson499b40e2011-03-30 16:07:05 +00002520 0); // Symbol flags.
2521
2522 symbol_table->AddSymbol(jump_symbol);
2523 }
2524
2525 return i;
2526}
2527
2528unsigned
2529ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
2530 user_id_t start_id,
Michael Sartaina7499c92013-07-01 19:45:50 +00002531 const ELFSectionHeaderInfo *rel_hdr,
Stephen Wilson499b40e2011-03-30 16:07:05 +00002532 user_id_t rel_id)
2533{
2534 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
2535
Greg Clayton3046e662013-07-10 01:23:25 +00002536 // The link field points to the associated symbol table. The info field
Stephen Wilson499b40e2011-03-30 16:07:05 +00002537 // points to the section holding the plt.
2538 user_id_t symtab_id = rel_hdr->sh_link;
2539 user_id_t plt_id = rel_hdr->sh_info;
2540
Tamas Berghammer85fadd92015-05-08 09:40:05 +00002541 // If the link field doesn't point to the appropriate symbol name table then
2542 // try to find it by name as some compiler don't fill in the link fields.
2543 if (!symtab_id)
2544 symtab_id = GetSectionIndexByName(".dynsym");
2545 if (!plt_id)
2546 plt_id = GetSectionIndexByName(".plt");
2547
Stephen Wilson499b40e2011-03-30 16:07:05 +00002548 if (!symtab_id || !plt_id)
2549 return 0;
2550
2551 // Section ID's are ones based;
2552 symtab_id++;
2553 plt_id++;
2554
Michael Sartaina7499c92013-07-01 19:45:50 +00002555 const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00002556 if (!plt_hdr)
2557 return 0;
2558
Michael Sartaina7499c92013-07-01 19:45:50 +00002559 const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
Stephen Wilson499b40e2011-03-30 16:07:05 +00002560 if (!sym_hdr)
2561 return 0;
2562
Greg Clayton3046e662013-07-10 01:23:25 +00002563 SectionList *section_list = m_sections_ap.get();
Stephen Wilson499b40e2011-03-30 16:07:05 +00002564 if (!section_list)
2565 return 0;
2566
2567 Section *rel_section = section_list->FindSectionByID(rel_id).get();
2568 if (!rel_section)
2569 return 0;
2570
Greg Claytone72dfb32012-02-24 01:59:29 +00002571 SectionSP plt_section_sp (section_list->FindSectionByID(plt_id));
2572 if (!plt_section_sp)
Stephen Wilson499b40e2011-03-30 16:07:05 +00002573 return 0;
2574
2575 Section *symtab = section_list->FindSectionByID(symtab_id).get();
2576 if (!symtab)
2577 return 0;
2578
Greg Clayton3046e662013-07-10 01:23:25 +00002579 // sh_link points to associated string table.
Stephen Wilson499b40e2011-03-30 16:07:05 +00002580 Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
2581 if (!strtab)
2582 return 0;
2583
2584 DataExtractor rel_data;
Greg Claytonc9660542012-02-05 02:38:54 +00002585 if (!ReadSectionData(rel_section, rel_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00002586 return 0;
2587
2588 DataExtractor symtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00002589 if (!ReadSectionData(symtab, symtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00002590 return 0;
2591
2592 DataExtractor strtab_data;
Greg Claytonc9660542012-02-05 02:38:54 +00002593 if (!ReadSectionData(strtab, strtab_data))
Stephen Wilson499b40e2011-03-30 16:07:05 +00002594 return 0;
2595
2596 unsigned rel_type = PLTRelocationType();
2597 if (!rel_type)
2598 return 0;
2599
Ed Maste81b4c5f2016-01-04 01:43:47 +00002600 return ParsePLTRelocations (symbol_table,
2601 start_id,
Greg Claytone72dfb32012-02-24 01:59:29 +00002602 rel_type,
Ed Maste81b4c5f2016-01-04 01:43:47 +00002603 &m_header,
2604 rel_hdr,
2605 plt_hdr,
Greg Claytone72dfb32012-02-24 01:59:29 +00002606 sym_hdr,
Ed Maste81b4c5f2016-01-04 01:43:47 +00002607 plt_section_sp,
2608 rel_data,
2609 symtab_data,
Greg Claytone72dfb32012-02-24 01:59:29 +00002610 strtab_data);
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002611}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002612
Andrew MacPherson17220c12014-03-05 10:12:43 +00002613unsigned
2614ObjectFileELF::RelocateSection(Symtab* symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
2615 const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
2616 DataExtractor &rel_data, DataExtractor &symtab_data,
2617 DataExtractor &debug_data, Section* rel_section)
2618{
2619 ELFRelocation rel(rel_hdr->sh_type);
2620 lldb::addr_t offset = 0;
2621 const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
2622 typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
2623 reloc_info_fn reloc_type;
2624 reloc_info_fn reloc_symbol;
2625
2626 if (hdr->Is32Bit())
2627 {
2628 reloc_type = ELFRelocation::RelocType32;
2629 reloc_symbol = ELFRelocation::RelocSymbol32;
2630 }
2631 else
2632 {
2633 reloc_type = ELFRelocation::RelocType64;
2634 reloc_symbol = ELFRelocation::RelocSymbol64;
2635 }
2636
2637 for (unsigned i = 0; i < num_relocations; ++i)
2638 {
2639 if (rel.Parse(rel_data, &offset) == false)
2640 break;
2641
2642 Symbol* symbol = NULL;
2643
2644 if (hdr->Is32Bit())
2645 {
2646 switch (reloc_type(rel)) {
2647 case R_386_32:
2648 case R_386_PC32:
2649 default:
2650 assert(false && "unexpected relocation type");
2651 }
2652 } else {
2653 switch (reloc_type(rel)) {
2654 case R_X86_64_64:
2655 {
2656 symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2657 if (symbol)
2658 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00002659 addr_t value = symbol->GetAddressRef().GetFileAddress();
Andrew MacPherson17220c12014-03-05 10:12:43 +00002660 DataBufferSP& data_buffer_sp = debug_data.GetSharedDataBuffer();
2661 uint64_t* dst = reinterpret_cast<uint64_t*>(data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset64(rel));
2662 *dst = value + ELFRelocation::RelocAddend64(rel);
2663 }
2664 break;
2665 }
2666 case R_X86_64_32:
2667 case R_X86_64_32S:
2668 {
2669 symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2670 if (symbol)
2671 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00002672 addr_t value = symbol->GetAddressRef().GetFileAddress();
Andrew MacPherson17220c12014-03-05 10:12:43 +00002673 value += ELFRelocation::RelocAddend32(rel);
2674 assert((reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) ||
2675 (reloc_type(rel) == R_X86_64_32S &&
2676 ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN)));
2677 uint32_t truncated_addr = (value & 0xFFFFFFFF);
2678 DataBufferSP& data_buffer_sp = debug_data.GetSharedDataBuffer();
2679 uint32_t* dst = reinterpret_cast<uint32_t*>(data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel));
2680 *dst = truncated_addr;
2681 }
2682 break;
2683 }
2684 case R_X86_64_PC32:
2685 default:
2686 assert(false && "unexpected relocation type");
2687 }
2688 }
2689 }
2690
2691 return 0;
2692}
2693
2694unsigned
2695ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, user_id_t rel_id)
2696{
2697 assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
2698
2699 // Parse in the section list if needed.
2700 SectionList *section_list = GetSectionList();
2701 if (!section_list)
2702 return 0;
2703
2704 // Section ID's are ones based.
2705 user_id_t symtab_id = rel_hdr->sh_link + 1;
2706 user_id_t debug_id = rel_hdr->sh_info + 1;
2707
2708 const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
2709 if (!symtab_hdr)
2710 return 0;
2711
2712 const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
2713 if (!debug_hdr)
2714 return 0;
2715
2716 Section *rel = section_list->FindSectionByID(rel_id).get();
2717 if (!rel)
2718 return 0;
2719
2720 Section *symtab = section_list->FindSectionByID(symtab_id).get();
2721 if (!symtab)
2722 return 0;
2723
2724 Section *debug = section_list->FindSectionByID(debug_id).get();
2725 if (!debug)
2726 return 0;
2727
2728 DataExtractor rel_data;
2729 DataExtractor symtab_data;
2730 DataExtractor debug_data;
2731
2732 if (ReadSectionData(rel, rel_data) &&
2733 ReadSectionData(symtab, symtab_data) &&
2734 ReadSectionData(debug, debug_data))
2735 {
2736 RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr, debug_hdr,
2737 rel_data, symtab_data, debug_data, debug);
2738 }
2739
2740 return 0;
2741}
2742
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002743Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00002744ObjectFileELF::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002745{
Michael Sartaina7499c92013-07-01 19:45:50 +00002746 ModuleSP module_sp(GetModule());
Greg Clayton3046e662013-07-10 01:23:25 +00002747 if (!module_sp)
2748 return NULL;
Michael Sartaina7499c92013-07-01 19:45:50 +00002749
Greg Clayton3046e662013-07-10 01:23:25 +00002750 // We always want to use the main object file so we (hopefully) only have one cached copy
2751 // of our symtab, dynamic sections, etc.
2752 ObjectFile *module_obj_file = module_sp->GetObjectFile();
2753 if (module_obj_file && module_obj_file != this)
2754 return module_obj_file->GetSymtab();
2755
2756 if (m_symtab_ap.get() == NULL)
2757 {
Pavel Labath783cbdc2015-03-04 10:28:15 +00002758 SectionList *section_list = module_sp->GetSectionList();
Michael Sartaina7499c92013-07-01 19:45:50 +00002759 if (!section_list)
2760 return NULL;
2761
Greg Clayton3046e662013-07-10 01:23:25 +00002762 uint64_t symbol_id = 0;
2763 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Stephen Wilson499b40e2011-03-30 16:07:05 +00002764
Michael Sartaina7499c92013-07-01 19:45:50 +00002765 // Sharable objects and dynamic executables usually have 2 distinct symbol
2766 // tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
2767 // version of the symtab that only contains global symbols. The information found
2768 // in the dynsym is therefore also found in the symtab, while the reverse is not
2769 // necessarily true.
Greg Clayton3046e662013-07-10 01:23:25 +00002770 Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
2771 if (!symtab)
Michael Sartaina7499c92013-07-01 19:45:50 +00002772 {
2773 // The symtab section is non-allocable and can be stripped, so if it doesn't exist
2774 // then use the dynsym section which should always be there.
Greg Clayton3046e662013-07-10 01:23:25 +00002775 symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
Michael Sartaina7499c92013-07-01 19:45:50 +00002776 }
Greg Clayton3046e662013-07-10 01:23:25 +00002777 if (symtab)
Tamas Berghammerd00438e2015-07-30 12:38:18 +00002778 {
2779 m_symtab_ap.reset(new Symtab(symtab->GetObjectFile()));
Greg Clayton3046e662013-07-10 01:23:25 +00002780 symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
Tamas Berghammerd00438e2015-07-30 12:38:18 +00002781 }
Michael Sartaina7499c92013-07-01 19:45:50 +00002782
Michael Sartainf7899542013-08-22 21:25:53 +00002783 // DT_JMPREL
2784 // If present, this entry's d_ptr member holds the address of relocation
2785 // entries associated solely with the procedure linkage table. Separating
2786 // these relocation entries lets the dynamic linker ignore them during
2787 // process initialization, if lazy binding is enabled. If this entry is
2788 // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
2789 // also be present.
Greg Clayton3046e662013-07-10 01:23:25 +00002790 const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
2791 if (symbol)
Michael Sartaina7499c92013-07-01 19:45:50 +00002792 {
Michael Sartainf7899542013-08-22 21:25:53 +00002793 // Synthesize trampoline symbols to help navigate the PLT.
Greg Clayton3046e662013-07-10 01:23:25 +00002794 addr_t addr = symbol->d_ptr;
2795 Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
Ed Maste81b4c5f2016-01-04 01:43:47 +00002796 if (reloc_section)
Michael Sartaina7499c92013-07-01 19:45:50 +00002797 {
Greg Clayton3046e662013-07-10 01:23:25 +00002798 user_id_t reloc_id = reloc_section->GetID();
2799 const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
2800 assert(reloc_header);
Ed Maste81b4c5f2016-01-04 01:43:47 +00002801
Tamas Berghammerd00438e2015-07-30 12:38:18 +00002802 if (m_symtab_ap == nullptr)
2803 m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile()));
Michael Sartaina7499c92013-07-01 19:45:50 +00002804
Greg Clayton3046e662013-07-10 01:23:25 +00002805 ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
Michael Sartaina7499c92013-07-01 19:45:50 +00002806 }
2807 }
Ed Maste81b4c5f2016-01-04 01:43:47 +00002808
Tamas Berghammerd00438e2015-07-30 12:38:18 +00002809 // If we still don't have any symtab then create an empty instance to avoid do the section
2810 // lookup next time.
2811 if (m_symtab_ap == nullptr)
2812 m_symtab_ap.reset(new Symtab(this));
Ed Maste81b4c5f2016-01-04 01:43:47 +00002813
Tamas Berghammer2480fe02015-06-24 12:31:25 +00002814 m_symtab_ap->CalculateSymbolSizes();
Michael Sartaina7499c92013-07-01 19:45:50 +00002815 }
Andrew MacPherson17220c12014-03-05 10:12:43 +00002816
2817 for (SectionHeaderCollIter I = m_section_headers.begin();
2818 I != m_section_headers.end(); ++I)
2819 {
2820 if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL)
2821 {
2822 if (CalculateType() == eTypeObjectFile)
2823 {
2824 const char *section_name = I->section_name.AsCString("");
2825 if (strstr(section_name, ".rela.debug") ||
2826 strstr(section_name, ".rel.debug"))
2827 {
2828 const ELFSectionHeader &reloc_header = *I;
2829 user_id_t reloc_id = SectionIndex(I);
2830 RelocateDebugSections(&reloc_header, reloc_id);
2831 }
2832 }
2833 }
2834 }
Greg Clayton3046e662013-07-10 01:23:25 +00002835 return m_symtab_ap.get();
2836}
2837
Ashok Thirumurthi35729bb2013-09-24 15:34:13 +00002838Symbol *
2839ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
2840{
2841 if (!m_symtab_ap.get())
2842 return nullptr; // GetSymtab() should be called first.
2843
2844 const SectionList *section_list = GetSectionList();
2845 if (!section_list)
2846 return nullptr;
2847
2848 if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
2849 {
2850 AddressRange range;
2851 if (eh_frame->GetAddressRange (so_addr, range))
2852 {
2853 const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
2854 Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
2855 if (symbol)
2856 return symbol;
2857
2858 // Note that a (stripped) symbol won't be found by GetSymtab()...
2859 lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
2860 if (eh_sym_section_sp.get())
2861 {
2862 addr_t section_base = eh_sym_section_sp->GetFileAddress();
2863 addr_t offset = file_addr - section_base;
2864 uint64_t symbol_id = m_symtab_ap->GetNumSymbols();
2865
2866 Symbol eh_symbol(
2867 symbol_id, // Symbol table index.
2868 "???", // Symbol name.
2869 false, // Is the symbol name mangled?
2870 eSymbolTypeCode, // Type of this symbol.
2871 true, // Is this globally visible?
2872 false, // Is this symbol debug info?
2873 false, // Is this symbol a trampoline?
2874 true, // Is this symbol artificial?
2875 eh_sym_section_sp, // Section in which this symbol is defined or null.
2876 offset, // Offset in section or symbol value.
2877 range.GetByteSize(), // Size in bytes of this symbol.
2878 true, // Size is valid.
Pavel Labathc6ae7ea2015-03-04 10:25:22 +00002879 false, // Contains linker annotations?
Ashok Thirumurthi35729bb2013-09-24 15:34:13 +00002880 0); // Symbol flags.
2881 if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
2882 return m_symtab_ap->SymbolAtIndex(symbol_id);
2883 }
2884 }
2885 }
2886 return nullptr;
2887}
2888
2889
Greg Clayton3046e662013-07-10 01:23:25 +00002890bool
2891ObjectFileELF::IsStripped ()
2892{
2893 // TODO: determine this for ELF
2894 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002895}
2896
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002897//===----------------------------------------------------------------------===//
2898// Dump
2899//
2900// Dump the specifics of the runtime file container (such as any headers
2901// segments, sections, etc).
2902//----------------------------------------------------------------------
2903void
2904ObjectFileELF::Dump(Stream *s)
2905{
2906 DumpELFHeader(s, m_header);
2907 s->EOL();
2908 DumpELFProgramHeaders(s);
2909 s->EOL();
2910 DumpELFSectionHeaders(s);
2911 s->EOL();
2912 SectionList *section_list = GetSectionList();
2913 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +00002914 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002915 Symtab *symtab = GetSymtab();
2916 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +00002917 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002918 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002919 DumpDependentModules(s);
2920 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002921}
2922
2923//----------------------------------------------------------------------
2924// DumpELFHeader
2925//
2926// Dump the ELF header to the specified output stream
2927//----------------------------------------------------------------------
2928void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002929ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002930{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002931 s->PutCString("ELF Header\n");
2932 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
2933 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
2934 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
2935 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
2936 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
2937 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
2938 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002939
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002940 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
2941 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002942 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
2943 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
2944 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
2945
2946 s->Printf("e_type = 0x%4.4x ", header.e_type);
2947 DumpELFHeader_e_type(s, header.e_type);
2948 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
2949 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Daniel Malead01b2952012-11-29 21:49:15 +00002950 s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
2951 s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
2952 s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002953 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
2954 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
2955 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
2956 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
2957 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
2958 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
2959 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
2960}
2961
2962//----------------------------------------------------------------------
2963// DumpELFHeader_e_type
2964//
2965// Dump an token value for the ELF header member e_type
2966//----------------------------------------------------------------------
2967void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002968ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002969{
2970 switch (e_type)
2971 {
2972 case ET_NONE: *s << "ET_NONE"; break;
2973 case ET_REL: *s << "ET_REL"; break;
2974 case ET_EXEC: *s << "ET_EXEC"; break;
2975 case ET_DYN: *s << "ET_DYN"; break;
2976 case ET_CORE: *s << "ET_CORE"; break;
2977 default:
2978 break;
2979 }
2980}
2981
2982//----------------------------------------------------------------------
2983// DumpELFHeader_e_ident_EI_DATA
2984//
2985// Dump an token value for the ELF header member e_ident[EI_DATA]
2986//----------------------------------------------------------------------
2987void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00002988ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002989{
2990 switch (ei_data)
2991 {
2992 case ELFDATANONE: *s << "ELFDATANONE"; break;
2993 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
2994 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
2995 default:
2996 break;
2997 }
2998}
2999
3000
3001//----------------------------------------------------------------------
3002// DumpELFProgramHeader
3003//
3004// Dump a single ELF program header to the specified output stream
3005//----------------------------------------------------------------------
3006void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003007ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003008{
3009 DumpELFProgramHeader_p_type(s, ph.p_type);
Daniel Malead01b2952012-11-29 21:49:15 +00003010 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
3011 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 +00003012
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003013 DumpELFProgramHeader_p_flags(s, ph.p_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00003014 s->Printf(") %8.8" PRIx64, ph.p_align);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003015}
3016
3017//----------------------------------------------------------------------
3018// DumpELFProgramHeader_p_type
3019//
3020// Dump an token value for the ELF program header member p_type which
3021// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003022// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003023void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003024ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003025{
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00003026 const int kStrWidth = 15;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003027 switch (p_type)
3028 {
Filipe Cabecinhas477d86d2013-05-23 23:01:14 +00003029 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
3030 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
3031 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
3032 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
3033 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
3034 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
3035 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
3036 CASE_AND_STREAM(s, PT_TLS , kStrWidth);
3037 CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003038 default:
3039 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
3040 break;
3041 }
3042}
3043
3044
3045//----------------------------------------------------------------------
3046// DumpELFProgramHeader_p_flags
3047//
3048// Dump an token value for the ELF program header member p_flags
3049//----------------------------------------------------------------------
3050void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003051ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003052{
3053 *s << ((p_flags & PF_X) ? "PF_X" : " ")
3054 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
3055 << ((p_flags & PF_W) ? "PF_W" : " ")
3056 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
3057 << ((p_flags & PF_R) ? "PF_R" : " ");
3058}
3059
3060//----------------------------------------------------------------------
3061// DumpELFProgramHeaders
3062//
3063// Dump all of the ELF program header to the specified output stream
3064//----------------------------------------------------------------------
3065void
3066ObjectFileELF::DumpELFProgramHeaders(Stream *s)
3067{
Ed Maste3a8ab6e2015-02-23 15:33:11 +00003068 if (!ParseProgramHeaders())
3069 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003070
Ed Maste3a8ab6e2015-02-23 15:33:11 +00003071 s->PutCString("Program Headers\n");
3072 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
3073 "p_filesz p_memsz p_flags p_align\n");
3074 s->PutCString("==== --------------- -------- -------- -------- "
3075 "-------- -------- ------------------------- --------\n");
3076
3077 uint32_t idx = 0;
3078 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
3079 I != m_program_headers.end(); ++I, ++idx)
3080 {
3081 s->Printf("[%2u] ", idx);
3082 ObjectFileELF::DumpELFProgramHeader(s, *I);
3083 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003084 }
3085}
3086
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003087//----------------------------------------------------------------------
3088// DumpELFSectionHeader
3089//
3090// Dump a single ELF section header to the specified output stream
3091//----------------------------------------------------------------------
3092void
Michael Sartaina7499c92013-07-01 19:45:50 +00003093ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003094{
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003095 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003096 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Daniel Malead01b2952012-11-29 21:49:15 +00003097 s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003098 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Daniel Malead01b2952012-11-29 21:49:15 +00003099 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 +00003100 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
Daniel Malead01b2952012-11-29 21:49:15 +00003101 s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003102}
3103
3104//----------------------------------------------------------------------
3105// DumpELFSectionHeader_sh_type
3106//
3107// Dump an token value for the ELF section header member sh_type which
3108// describes the type of the section
3109//----------------------------------------------------------------------
3110void
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003111ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003112{
3113 const int kStrWidth = 12;
3114 switch (sh_type)
3115 {
3116 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
3117 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
3118 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
3119 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
3120 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
3121 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
3122 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
3123 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
3124 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
3125 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
3126 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
3127 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
3128 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
3129 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
3130 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
3131 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
3132 default:
3133 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
3134 break;
3135 }
3136}
3137
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003138//----------------------------------------------------------------------
3139// DumpELFSectionHeader_sh_flags
3140//
3141// Dump an token value for the ELF section header member sh_flags
3142//----------------------------------------------------------------------
3143void
Greg Claytonc7bece562013-01-25 18:06:21 +00003144ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003145{
3146 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
3147 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
3148 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
3149 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
3150 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
3151}
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003152
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003153//----------------------------------------------------------------------
3154// DumpELFSectionHeaders
3155//
3156// Dump all of the ELF section header to the specified output stream
3157//----------------------------------------------------------------------
3158void
3159ObjectFileELF::DumpELFSectionHeaders(Stream *s)
3160{
Michael Sartaina7499c92013-07-01 19:45:50 +00003161 if (!ParseSectionHeaders())
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003162 return;
3163
3164 s->PutCString("Section Headers\n");
3165 s->PutCString("IDX name type flags "
3166 "addr offset size link info addralgn "
3167 "entsize Name\n");
3168 s->PutCString("==== -------- ------------ -------------------------------- "
3169 "-------- -------- -------- -------- -------- -------- "
3170 "-------- ====================\n");
3171
3172 uint32_t idx = 0;
3173 for (SectionHeaderCollConstIter I = m_section_headers.begin();
3174 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003175 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003176 s->Printf("[%2u] ", idx);
3177 ObjectFileELF::DumpELFSectionHeader(s, *I);
Michael Sartaina7499c92013-07-01 19:45:50 +00003178 const char* section_name = I->section_name.AsCString("");
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003179 if (section_name)
3180 *s << ' ' << section_name << "\n";
3181 }
3182}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003183
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003184void
3185ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
3186{
3187 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003188
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003189 if (num_modules > 0)
3190 {
3191 s->PutCString("Dependent Modules:\n");
3192 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003193 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003194 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
3195 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003196 }
3197 }
3198}
3199
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003200bool
Greg Clayton514487e2011-02-15 21:59:32 +00003201ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003202{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00003203 if (!ParseHeader())
3204 return false;
3205
Todd Fiala09512ec2014-07-11 15:43:51 +00003206 if (m_section_headers.empty())
3207 {
3208 // Allow elf notes to be parsed which may affect the detected architecture.
3209 ParseSectionHeaders();
3210 }
Todd Fialab91de782014-06-27 16:52:49 +00003211
Greg Claytonb704b692015-10-28 18:04:38 +00003212 if (CalculateType() == eTypeCoreFile && m_arch_spec.TripleOSIsUnspecifiedUnknown())
3213 {
3214 // Core files don't have section headers yet they have PT_NOTE program headers
3215 // that might shed more light on the architecture
3216 if (ParseProgramHeaders())
3217 {
3218 for (size_t i = 0, count = GetProgramHeaderCount(); i < count; ++i)
3219 {
3220 const elf::ELFProgramHeader* header = GetProgramHeaderByIndex(i);
3221 if (header && header->p_type == PT_NOTE && header->p_offset != 0 && header->p_filesz > 0)
3222 {
3223 DataExtractor data;
3224 if (data.SetData (m_data, header->p_offset, header->p_filesz) == header->p_filesz)
3225 {
3226 lldb_private::UUID uuid;
3227 RefineModuleDetailsFromNote (data, m_arch_spec, uuid);
3228 }
3229 }
3230 }
3231 }
3232 }
Todd Fialab91de782014-06-27 16:52:49 +00003233 arch = m_arch_spec;
Stephen Wilsonf325ba92010-07-13 23:07:23 +00003234 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003235}
3236
Greg Clayton9e00b6a652011-07-09 00:41:34 +00003237ObjectFile::Type
3238ObjectFileELF::CalculateType()
3239{
3240 switch (m_header.e_type)
3241 {
3242 case llvm::ELF::ET_NONE:
3243 // 0 - No file type
3244 return eTypeUnknown;
3245
3246 case llvm::ELF::ET_REL:
3247 // 1 - Relocatable file
3248 return eTypeObjectFile;
3249
3250 case llvm::ELF::ET_EXEC:
3251 // 2 - Executable file
3252 return eTypeExecutable;
3253
3254 case llvm::ELF::ET_DYN:
3255 // 3 - Shared object file
3256 return eTypeSharedLibrary;
3257
3258 case ET_CORE:
3259 // 4 - Core file
3260 return eTypeCoreFile;
3261
3262 default:
3263 break;
3264 }
3265 return eTypeUnknown;
3266}
3267
3268ObjectFile::Strata
3269ObjectFileELF::CalculateStrata()
3270{
3271 switch (m_header.e_type)
3272 {
Ed Maste81b4c5f2016-01-04 01:43:47 +00003273 case llvm::ELF::ET_NONE:
Greg Clayton9e00b6a652011-07-09 00:41:34 +00003274 // 0 - No file type
3275 return eStrataUnknown;
3276
3277 case llvm::ELF::ET_REL:
3278 // 1 - Relocatable file
3279 return eStrataUnknown;
3280
3281 case llvm::ELF::ET_EXEC:
3282 // 2 - Executable file
3283 // TODO: is there any way to detect that an executable is a kernel
Ed Maste81b4c5f2016-01-04 01:43:47 +00003284 // related executable by inspecting the program headers, section
Greg Clayton9e00b6a652011-07-09 00:41:34 +00003285 // headers, symbols, or any other flag bits???
3286 return eStrataUser;
3287
3288 case llvm::ELF::ET_DYN:
3289 // 3 - Shared object file
3290 // TODO: is there any way to detect that an shared library is a kernel
Ed Maste81b4c5f2016-01-04 01:43:47 +00003291 // related executable by inspecting the program headers, section
Greg Clayton9e00b6a652011-07-09 00:41:34 +00003292 // headers, symbols, or any other flag bits???
3293 return eStrataUnknown;
3294
3295 case ET_CORE:
3296 // 4 - Core file
3297 // TODO: is there any way to detect that an core file is a kernel
Ed Maste81b4c5f2016-01-04 01:43:47 +00003298 // related executable by inspecting the program headers, section
Greg Clayton9e00b6a652011-07-09 00:41:34 +00003299 // headers, symbols, or any other flag bits???
3300 return eStrataUnknown;
3301
3302 default:
3303 break;
3304 }
3305 return eStrataUnknown;
3306}
3307