blob: 4a1ae8197b8d1bbaed0721fee2ab5fd0f14c4566 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Symbol.cpp ----------------------------------------------*- C++ -*-===//
2//
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 "lldb/Symbol/Symbol.h"
11
12#include "lldb/Core/Module.h"
Greg Clayton9191db42013-10-21 18:40:51 +000013#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "lldb/Core/Section.h"
15#include "lldb/Core/Stream.h"
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Symbol/ObjectFile.h"
17#include "lldb/Symbol/Symtab.h"
Michael Sartainbf43d1a2013-07-03 16:35:41 +000018#include "lldb/Symbol/Function.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Target/Process.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000020#include "lldb/Target/Target.h"
Michael Sartaina7499c92013-07-01 19:45:50 +000021#include "lldb/Symbol/SymbolVendor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
26
27Symbol::Symbol() :
Stephen Wilson71c21d12011-04-11 19:41:40 +000028 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000029 m_uid (UINT32_MAX),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030 m_type_data (0),
31 m_type_data_resolved (false),
32 m_is_synthetic (false),
33 m_is_debug (false),
34 m_is_external (false),
35 m_size_is_sibling (false),
36 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +000037 m_size_is_valid (false),
Greg Clayton3d51b9f2012-11-27 01:52:16 +000038 m_demangled_is_synthesized (false),
Pavel Labathc6ae7ea2015-03-04 10:25:22 +000039 m_contains_linker_annotations (false),
Greg Clayton01575f82011-11-22 21:20:33 +000040 m_type (eSymbolTypeInvalid),
Greg Claytond8c3d4b2013-06-19 21:50:28 +000041 m_mangled (),
42 m_addr_range (),
43 m_flags ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044{
45}
46
47Symbol::Symbol
48(
Greg Clayton81c22f62011-10-19 18:09:39 +000049 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050 const char *name,
51 bool name_is_mangled,
52 SymbolType type,
53 bool external,
54 bool is_debug,
55 bool is_trampoline,
56 bool is_artificial,
Greg Claytone72dfb32012-02-24 01:59:29 +000057 const lldb::SectionSP &section_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058 addr_t offset,
Greg Claytonc7bece562013-01-25 18:06:21 +000059 addr_t size,
Greg Clayton9594f4c2013-04-13 23:17:23 +000060 bool size_is_valid,
Pavel Labathc6ae7ea2015-03-04 10:25:22 +000061 bool contains_linker_annotations,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062 uint32_t flags
63) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000064 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000065 m_uid (symID),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066 m_type_data (0),
67 m_type_data_resolved (false),
68 m_is_synthetic (is_artificial),
69 m_is_debug (is_debug),
70 m_is_external (external),
71 m_size_is_sibling (false),
72 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +000073 m_size_is_valid (size_is_valid || size > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +000074 m_demangled_is_synthesized (false),
Pavel Labathc6ae7ea2015-03-04 10:25:22 +000075 m_contains_linker_annotations (contains_linker_annotations),
Greg Clayton01575f82011-11-22 21:20:33 +000076 m_type (type),
Greg Claytond8c3d4b2013-06-19 21:50:28 +000077 m_mangled (ConstString(name), name_is_mangled),
78 m_addr_range (section_sp, offset, size),
79 m_flags (flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080{
81}
82
83Symbol::Symbol
84(
Greg Clayton81c22f62011-10-19 18:09:39 +000085 uint32_t symID,
Pavel Labathc6ae7ea2015-03-04 10:25:22 +000086 const Mangled &mangled,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087 SymbolType type,
88 bool external,
89 bool is_debug,
90 bool is_trampoline,
91 bool is_artificial,
92 const AddressRange &range,
Greg Clayton9594f4c2013-04-13 23:17:23 +000093 bool size_is_valid,
Pavel Labathc6ae7ea2015-03-04 10:25:22 +000094 bool contains_linker_annotations,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095 uint32_t flags
96) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000097 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000098 m_uid (symID),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 m_type_data (0),
100 m_type_data_resolved (false),
101 m_is_synthetic (is_artificial),
102 m_is_debug (is_debug),
103 m_is_external (external),
104 m_size_is_sibling (false),
105 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +0000106 m_size_is_valid (size_is_valid || range.GetByteSize() > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000107 m_demangled_is_synthesized (false),
Pavel Labathc6ae7ea2015-03-04 10:25:22 +0000108 m_contains_linker_annotations (contains_linker_annotations),
Greg Clayton01575f82011-11-22 21:20:33 +0000109 m_type (type),
Pavel Labathc6ae7ea2015-03-04 10:25:22 +0000110 m_mangled (mangled),
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000111 m_addr_range (range),
112 m_flags (flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113{
114}
115
116Symbol::Symbol(const Symbol& rhs):
Stephen Wilson71c21d12011-04-11 19:41:40 +0000117 SymbolContextScope (rhs),
Greg Clayton81c22f62011-10-19 18:09:39 +0000118 m_uid (rhs.m_uid),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119 m_type_data (rhs.m_type_data),
120 m_type_data_resolved (rhs.m_type_data_resolved),
121 m_is_synthetic (rhs.m_is_synthetic),
122 m_is_debug (rhs.m_is_debug),
123 m_is_external (rhs.m_is_external),
124 m_size_is_sibling (rhs.m_size_is_sibling),
125 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +0000126 m_size_is_valid (rhs.m_size_is_valid),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000127 m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
Pavel Labathc6ae7ea2015-03-04 10:25:22 +0000128 m_contains_linker_annotations (rhs.m_contains_linker_annotations),
Greg Clayton01575f82011-11-22 21:20:33 +0000129 m_type (rhs.m_type),
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000130 m_mangled (rhs.m_mangled),
131 m_addr_range (rhs.m_addr_range),
132 m_flags (rhs.m_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133{
134}
135
136const Symbol&
137Symbol::operator= (const Symbol& rhs)
138{
139 if (this != &rhs)
140 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000141 SymbolContextScope::operator= (rhs);
Greg Clayton81c22f62011-10-19 18:09:39 +0000142 m_uid = rhs.m_uid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143 m_type_data = rhs.m_type_data;
144 m_type_data_resolved = rhs.m_type_data_resolved;
145 m_is_synthetic = rhs.m_is_synthetic;
146 m_is_debug = rhs.m_is_debug;
147 m_is_external = rhs.m_is_external;
148 m_size_is_sibling = rhs.m_size_is_sibling;
149 m_size_is_synthesized = rhs.m_size_is_sibling;
Greg Clayton3046e662013-07-10 01:23:25 +0000150 m_size_is_valid = rhs.m_size_is_valid;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000151 m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
Pavel Labathc6ae7ea2015-03-04 10:25:22 +0000152 m_contains_linker_annotations = rhs.m_contains_linker_annotations;
Greg Clayton01575f82011-11-22 21:20:33 +0000153 m_type = rhs.m_type;
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000154 m_mangled = rhs.m_mangled;
Greg Clayton01575f82011-11-22 21:20:33 +0000155 m_addr_range = rhs.m_addr_range;
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000156 m_flags = rhs.m_flags;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157 }
158 return *this;
159}
160
Greg Clayton81c22f62011-10-19 18:09:39 +0000161void
162Symbol::Clear()
163{
164 m_uid = UINT32_MAX;
165 m_mangled.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000166 m_type_data = 0;
167 m_type_data_resolved = false;
168 m_is_synthetic = false;
169 m_is_debug = false;
170 m_is_external = false;
171 m_size_is_sibling = false;
172 m_size_is_synthesized = false;
Greg Clayton3046e662013-07-10 01:23:25 +0000173 m_size_is_valid = false;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000174 m_demangled_is_synthesized = false;
Pavel Labathc6ae7ea2015-03-04 10:25:22 +0000175 m_contains_linker_annotations = false;
Greg Clayton01575f82011-11-22 21:20:33 +0000176 m_type = eSymbolTypeInvalid;
Greg Clayton81c22f62011-10-19 18:09:39 +0000177 m_flags = 0;
Greg Clayton01575f82011-11-22 21:20:33 +0000178 m_addr_range.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000179}
180
Greg Claytone7612132012-03-07 21:03:09 +0000181bool
182Symbol::ValueIsAddress() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183{
Ed Masted4612ad2014-04-20 13:17:36 +0000184 return m_addr_range.GetBaseAddress().GetSection().get() != nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185}
186
Greg Clayton9191db42013-10-21 18:40:51 +0000187ConstString
188Symbol::GetReExportedSymbolName() const
189{
190 if (m_type == eSymbolTypeReExported)
191 {
192 // For eSymbolTypeReExported, the "const char *" from a ConstString
193 // is used as the offset in the address range base address. We can
194 // then make this back into a string that is the re-exported name.
195 intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
196 if (str_ptr != 0)
197 return ConstString((const char *)str_ptr);
198 else
199 return GetName();
200 }
201 return ConstString();
202}
203
204FileSpec
205Symbol::GetReExportedSymbolSharedLibrary() const
206{
207 if (m_type == eSymbolTypeReExported)
208 {
209 // For eSymbolTypeReExported, the "const char *" from a ConstString
210 // is used as the offset in the address range base address. We can
211 // then make this back into a string that is the re-exported name.
212 intptr_t str_ptr = m_addr_range.GetByteSize();
213 if (str_ptr != 0)
214 return FileSpec((const char *)str_ptr, false);
215 }
216 return FileSpec();
217}
218
Greg Clayton60038be2015-02-14 00:51:13 +0000219void
Greg Clayton9191db42013-10-21 18:40:51 +0000220Symbol::SetReExportedSymbolName(const ConstString &name)
221{
Greg Clayton60038be2015-02-14 00:51:13 +0000222 SetType (eSymbolTypeReExported);
223 // For eSymbolTypeReExported, the "const char *" from a ConstString
224 // is used as the offset in the address range base address.
225 m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +0000226}
227
228bool
229Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
230{
231 if (m_type == eSymbolTypeReExported)
232 {
233 // For eSymbolTypeReExported, the "const char *" from a ConstString
234 // is used as the offset in the address range base address.
Greg Clayton60038be2015-02-14 00:51:13 +0000235 m_addr_range.SetByteSize((uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +0000236 return true;
237 }
238 return false;
239
240}
241
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242uint32_t
243Symbol::GetSiblingIndex() const
244{
Greg Claytonbc63aac2015-02-25 22:41:34 +0000245 return m_size_is_sibling ? m_addr_range.GetByteSize() : UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246}
247
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248bool
249Symbol::IsTrampoline () const
250{
251 return m_type == eSymbolTypeTrampoline;
252}
253
Matt Kopec00049b82013-02-27 20:13:38 +0000254bool
255Symbol::IsIndirect () const
256{
257 return m_type == eSymbolTypeResolver;
258}
259
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000261Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000262{
Greg Claytonc4a8a762012-05-15 18:43:44 +0000263 s->Printf("id = {0x%8.8x}", m_uid);
Greg Claytond9dc52d2011-09-24 05:04:40 +0000264
Greg Claytone72dfb32012-02-24 01:59:29 +0000265 if (m_addr_range.GetBaseAddress().GetSection())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000266 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000267 if (ValueIsAddress())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000268 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000269 const lldb::addr_t byte_size = GetByteSize();
270 if (byte_size > 0)
Greg Claytonc9800662010-09-10 01:30:46 +0000271 {
272 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000273 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000274 }
275 else
276 {
277 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000278 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000279 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000280 }
281 else
Daniel Malead01b2952012-11-29 21:49:15 +0000282 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000283 }
284 else
285 {
286 if (m_size_is_sibling)
Daniel Malead01b2952012-11-29 21:49:15 +0000287 s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000288 else
Daniel Malead01b2952012-11-29 21:49:15 +0000289 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000290 }
Greg Clayton6b2bd932012-02-01 08:09:32 +0000291 if (m_mangled.GetDemangledName())
292 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
293 if (m_mangled.GetMangledName())
294 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
295
Greg Clayton0c5cd902010-06-28 21:30:43 +0000296}
297
298void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000299Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300{
Greg Clayton2d9ce192015-02-25 17:22:05 +0000301 s->Printf("[%5u] %6u %c%c%c %-15s ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302 index,
303 GetID(),
304 m_is_debug ? 'D' : ' ',
305 m_is_synthetic ? 'S' : ' ',
306 m_is_external ? 'X' : ' ',
307 GetTypeAsString());
308
Greg Claytone7612132012-03-07 21:03:09 +0000309 // Make sure the size of the symbol is up to date before dumping
310 GetByteSize();
311
312 if (ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 {
Ed Masted4612ad2014-04-20 13:17:36 +0000314 if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315 s->Printf("%*s", 18, "");
316
317 s->PutChar(' ');
318
Greg Claytonf5e56de2010-09-14 23:36:40 +0000319 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000320 s->Printf("%*s", 18, "");
321
322 const char *format = m_size_is_sibling ?
323 " Sibling -> [%5llu] 0x%8.8x %s\n":
Daniel Malead01b2952012-11-29 21:49:15 +0000324 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 s->Printf( format,
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000326 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 m_flags,
328 m_mangled.GetName().AsCString(""));
329 }
Greg Clayton9191db42013-10-21 18:40:51 +0000330 else if (m_type == eSymbolTypeReExported)
331 {
332 s->Printf (" 0x%8.8x %s",
333 m_flags,
334 m_mangled.GetName().AsCString(""));
335
336 ConstString reexport_name = GetReExportedSymbolName();
337 intptr_t shlib = m_addr_range.GetByteSize();
338 if (shlib)
339 s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
340 else
341 s->Printf(" -> %s\n", reexport_name.GetCString());
342 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 else
344 {
345 const char *format = m_size_is_sibling ?
Daniel Malead01b2952012-11-29 21:49:15 +0000346 "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n":
347 "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 s->Printf( format,
349 m_addr_range.GetBaseAddress().GetOffset(),
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000350 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351 m_flags,
352 m_mangled.GetName().AsCString(""));
353 }
354}
355
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356uint32_t
357Symbol::GetPrologueByteSize ()
358{
Matt Kopec00049b82013-02-27 20:13:38 +0000359 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360 {
361 if (!m_type_data_resolved)
362 {
363 m_type_data_resolved = true;
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000364
365 const Address &base_address = m_addr_range.GetBaseAddress();
366 Function *function = base_address.CalculateSymbolContextFunction();
367 if (function)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000369 // Functions have line entries which can also potentially have end of prologue information.
370 // So if this symbol points to a function, use the prologue information from there.
371 m_type_data = function->GetPrologueByteSize();
372 }
373 else
374 {
375 ModuleSP module_sp (base_address.GetModule());
376 SymbolContext sc;
377 if (module_sp)
Michael Sartaina7499c92013-07-01 19:45:50 +0000378 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000379 uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (base_address,
380 eSymbolContextLineEntry,
381 sc);
382 if (resolved_flags & eSymbolContextLineEntry)
Michael Sartaina7499c92013-07-01 19:45:50 +0000383 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000384 // Default to the end of the first line entry.
385 m_type_data = sc.line_entry.range.GetByteSize();
Michael Sartaina7499c92013-07-01 19:45:50 +0000386
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000387 // Set address for next line.
388 Address addr (base_address);
389 addr.Slide (m_type_data);
390
391 // Check the first few instructions and look for one that has a line number that is
392 // different than the first entry. This is also done in Function::GetPrologueByteSize().
393 uint16_t total_offset = m_type_data;
394 for (int idx = 0; idx < 6; ++idx)
Michael Sartaina7499c92013-07-01 19:45:50 +0000395 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000396 SymbolContext sc_temp;
397 resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp);
398 // Make sure we got line number information...
399 if (!(resolved_flags & eSymbolContextLineEntry))
400 break;
401
402 // If this line number is different than our first one, use it and we're done.
403 if (sc_temp.line_entry.line != sc.line_entry.line)
404 {
405 m_type_data = total_offset;
406 break;
407 }
408
409 // Slide addr up to the next line address.
410 addr.Slide (sc_temp.line_entry.range.GetByteSize());
411 total_offset += sc_temp.line_entry.range.GetByteSize();
412 // If we've gone too far, bail out.
413 if (total_offset >= m_addr_range.GetByteSize())
414 break;
Michael Sartaina7499c92013-07-01 19:45:50 +0000415 }
416
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000417 // Sanity check - this may be a function in the middle of code that has debug information, but
418 // not for this symbol. So the line entries surrounding us won't lie inside our function.
419 // In that case, the line entry will be bigger than we are, so we do that quick check and
420 // if that is true, we just return 0.
421 if (m_type_data >= m_addr_range.GetByteSize())
422 m_type_data = 0;
Michael Sartaina7499c92013-07-01 19:45:50 +0000423 }
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000424 else
425 {
426 // TODO: expose something in Process to figure out the
427 // size of a function prologue.
Michael Sartaina7499c92013-07-01 19:45:50 +0000428 m_type_data = 0;
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000429 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000430 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431 }
432 }
433 return m_type_data;
434 }
435 return 0;
436}
437
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438bool
439Symbol::Compare(const ConstString& name, SymbolType type) const
440{
Jim Inghamc30ee562011-10-29 00:54:12 +0000441 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
443 return false;
444}
445
446#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
447
448const char *
449Symbol::GetTypeAsString() const
450{
451 switch (m_type)
452 {
453 ENUM_TO_CSTRING(Invalid);
454 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455 ENUM_TO_CSTRING(Code);
Greg Clayton9191db42013-10-21 18:40:51 +0000456 ENUM_TO_CSTRING(Resolver);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457 ENUM_TO_CSTRING(Data);
458 ENUM_TO_CSTRING(Trampoline);
459 ENUM_TO_CSTRING(Runtime);
460 ENUM_TO_CSTRING(Exception);
461 ENUM_TO_CSTRING(SourceFile);
462 ENUM_TO_CSTRING(HeaderFile);
463 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 ENUM_TO_CSTRING(CommonBlock);
465 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466 ENUM_TO_CSTRING(Local);
467 ENUM_TO_CSTRING(Param);
468 ENUM_TO_CSTRING(Variable);
469 ENUM_TO_CSTRING(VariableType);
470 ENUM_TO_CSTRING(LineEntry);
471 ENUM_TO_CSTRING(LineHeader);
472 ENUM_TO_CSTRING(ScopeBegin);
473 ENUM_TO_CSTRING(ScopeEnd);
474 ENUM_TO_CSTRING(Additional);
475 ENUM_TO_CSTRING(Compiler);
476 ENUM_TO_CSTRING(Instrumentation);
477 ENUM_TO_CSTRING(Undefined);
Greg Clayton456809c2011-12-03 02:30:59 +0000478 ENUM_TO_CSTRING(ObjCClass);
479 ENUM_TO_CSTRING(ObjCMetaClass);
480 ENUM_TO_CSTRING(ObjCIVar);
Greg Clayton9191db42013-10-21 18:40:51 +0000481 ENUM_TO_CSTRING(ReExported);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482 default:
483 break;
484 }
485 return "<unknown SymbolType>";
486}
487
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000488void
489Symbol::CalculateSymbolContext (SymbolContext *sc)
490{
491 // Symbols can reconstruct the symbol and the module in the symbol context
492 sc->symbol = this;
Greg Claytone7612132012-03-07 21:03:09 +0000493 if (ValueIsAddress())
494 sc->module_sp = GetAddress().GetModule();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000495 else
496 sc->module_sp.reset();
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000497}
498
Greg Claytone72dfb32012-02-24 01:59:29 +0000499ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000500Symbol::CalculateSymbolContextModule ()
501{
Greg Claytone7612132012-03-07 21:03:09 +0000502 if (ValueIsAddress())
503 return GetAddress().GetModule();
Greg Claytone72dfb32012-02-24 01:59:29 +0000504 return ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000505}
506
507Symbol *
508Symbol::CalculateSymbolContextSymbol ()
509{
510 return this;
511}
512
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000513void
514Symbol::DumpSymbolContext (Stream *s)
515{
516 bool dumped_module = false;
Greg Claytone7612132012-03-07 21:03:09 +0000517 if (ValueIsAddress())
518 {
519 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000520 if (module_sp)
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000521 {
522 dumped_module = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000523 module_sp->DumpSymbolContext(s);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000524 }
525 }
526 if (dumped_module)
527 s->PutCString(", ");
528
529 s->Printf("Symbol{0x%8.8x}", GetID());
530}
531
Greg Claytonda171f12012-03-02 03:01:16 +0000532lldb::addr_t
533Symbol::GetByteSize () const
534{
Greg Clayton3046e662013-07-10 01:23:25 +0000535 return m_addr_range.GetByteSize();
Greg Claytonda171f12012-03-02 03:01:16 +0000536}
537
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000538
539Symbol *
540Symbol::ResolveReExportedSymbolInModuleSpec (Target &target,
541 ConstString &reexport_name,
542 ModuleSpec &module_spec,
Sean Callanan25ea6a12014-05-23 02:30:48 +0000543 ModuleList &seen_modules) const
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000544{
545 ModuleSP module_sp;
546 if (module_spec.GetFileSpec())
547 {
548 // Try searching for the module file spec first using the full path
549 module_sp = target.GetImages().FindFirstModule(module_spec);
550 if (!module_sp)
551 {
552 // Next try and find the module by basename in case environment
553 // variables or other runtime trickery causes shared libraries
554 // to be loaded from alternate paths
555 module_spec.GetFileSpec().GetDirectory().Clear();
556 module_sp = target.GetImages().FindFirstModule(module_spec);
557 }
558 }
559
560 if (module_sp)
561 {
562 // There should not be cycles in the reexport list, but we don't want to crash if there are so make sure
563 // we haven't seen this before:
564 if (!seen_modules.AppendIfNeeded(module_sp))
565 return nullptr;
566
567 lldb_private::SymbolContextList sc_list;
568 module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list);
569 const size_t num_scs = sc_list.GetSize();
570 if (num_scs > 0)
571 {
572 for (size_t i=0; i<num_scs; ++i)
573 {
574 lldb_private::SymbolContext sc;
575 if (sc_list.GetContextAtIndex(i, sc))
576 {
577 if (sc.symbol->IsExternal())
578 return sc.symbol;
579 }
580 }
581 }
582 // If we didn't find the symbol in this module, it may be because this module re-exports some
583 // whole other library. We have to search those as well:
584 seen_modules.Append(module_sp);
585
586 FileSpecList reexported_libraries = module_sp->GetObjectFile()->GetReExportedLibraries();
587 size_t num_reexported_libraries = reexported_libraries.GetSize();
588 for (size_t idx = 0; idx < num_reexported_libraries; idx++)
589 {
590 ModuleSpec reexported_module_spec;
591 reexported_module_spec.GetFileSpec() = reexported_libraries.GetFileSpecAtIndex(idx);
592 Symbol *result_symbol = ResolveReExportedSymbolInModuleSpec(target,
593 reexport_name,
594 reexported_module_spec,
595 seen_modules);
596 if (result_symbol)
597 return result_symbol;
598 }
599 }
600 return nullptr;
601}
602
Greg Clayton9191db42013-10-21 18:40:51 +0000603Symbol *
Sean Callanan25ea6a12014-05-23 02:30:48 +0000604Symbol::ResolveReExportedSymbol (Target &target) const
Greg Clayton9191db42013-10-21 18:40:51 +0000605{
606 ConstString reexport_name (GetReExportedSymbolName());
607 if (reexport_name)
608 {
609 ModuleSpec module_spec;
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000610 ModuleList seen_modules;
Greg Clayton9191db42013-10-21 18:40:51 +0000611 module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary();
612 if (module_spec.GetFileSpec())
613 {
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000614 return ResolveReExportedSymbolInModuleSpec(target, reexport_name, module_spec, seen_modules);
Greg Clayton9191db42013-10-21 18:40:51 +0000615 }
616 }
Ed Masted4612ad2014-04-20 13:17:36 +0000617 return nullptr;
Greg Clayton9191db42013-10-21 18:40:51 +0000618}
Greg Clayton44d93782014-01-27 23:43:24 +0000619
Sean Callanan25ea6a12014-05-23 02:30:48 +0000620lldb::addr_t
621Symbol::ResolveCallableAddress(Target &target) const
622{
623 if (GetType() == lldb::eSymbolTypeUndefined)
624 return LLDB_INVALID_ADDRESS;
625
626 Address func_so_addr;
627
Jason Molenda9aae9fc2014-10-15 03:05:38 +0000628 bool is_indirect = IsIndirect();
Sean Callanan25ea6a12014-05-23 02:30:48 +0000629 if (GetType() == eSymbolTypeReExported)
630 {
631 Symbol *reexported_symbol = ResolveReExportedSymbol(target);
632 if (reexported_symbol)
633 {
634 func_so_addr = reexported_symbol->GetAddress();
635 is_indirect = reexported_symbol->IsIndirect();
636 }
637 }
638 else
639 {
640 func_so_addr = GetAddress();
641 is_indirect = IsIndirect();
642 }
643
644 if (func_so_addr.IsValid())
645 {
646 if (!target.GetProcessSP() && is_indirect)
647 {
648 // can't resolve indirect symbols without calling a function...
649 return LLDB_INVALID_ADDRESS;
650 }
651
652 lldb::addr_t load_addr = func_so_addr.GetCallableLoadAddress (&target, is_indirect);
653
654 if (load_addr != LLDB_INVALID_ADDRESS)
655 {
656 return load_addr;
657 }
658 }
659
660 return LLDB_INVALID_ADDRESS;
661}
662
Greg Clayton44d93782014-01-27 23:43:24 +0000663
664lldb::DisassemblerSP
665Symbol::GetInstructions (const ExecutionContext &exe_ctx,
666 const char *flavor,
667 bool prefer_file_cache)
668{
669 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
670 if (module_sp)
671 {
672 const bool prefer_file_cache = false;
673 return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
Ed Masted4612ad2014-04-20 13:17:36 +0000674 nullptr,
Greg Clayton44d93782014-01-27 23:43:24 +0000675 flavor,
676 exe_ctx,
677 m_addr_range,
678 prefer_file_cache);
679 }
680 return lldb::DisassemblerSP();
681}
682
683bool
684Symbol::GetDisassembly (const ExecutionContext &exe_ctx,
685 const char *flavor,
686 bool prefer_file_cache,
687 Stream &strm)
688{
689 lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
690 if (disassembler_sp)
691 {
692 const bool show_address = true;
693 const bool show_bytes = false;
694 disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
695 return true;
696 }
697 return false;
698}