blob: 63551d25e604982c54dd7f7d1aad43ff4433a19e [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"
13#include "lldb/Core/Section.h"
14#include "lldb/Core/Stream.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Symbol/ObjectFile.h"
16#include "lldb/Symbol/Symtab.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Target/Process.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000018#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
20using namespace lldb;
21using namespace lldb_private;
22
23
24Symbol::Symbol() :
Stephen Wilson71c21d12011-04-11 19:41:40 +000025 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000026 m_uid (UINT32_MAX),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027 m_mangled (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028 m_type_data (0),
29 m_type_data_resolved (false),
30 m_is_synthetic (false),
31 m_is_debug (false),
32 m_is_external (false),
33 m_size_is_sibling (false),
34 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +000035 m_calculated_size (false),
Greg Clayton3d51b9f2012-11-27 01:52:16 +000036 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +000037 m_type (eSymbolTypeInvalid),
38 m_flags (),
39 m_addr_range ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040{
41}
42
43Symbol::Symbol
44(
Greg Clayton81c22f62011-10-19 18:09:39 +000045 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 const char *name,
47 bool name_is_mangled,
48 SymbolType type,
49 bool external,
50 bool is_debug,
51 bool is_trampoline,
52 bool is_artificial,
Greg Claytone72dfb32012-02-24 01:59:29 +000053 const lldb::SectionSP &section_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054 addr_t offset,
Greg Claytonc7bece562013-01-25 18:06:21 +000055 addr_t size,
Greg Clayton9594f4c2013-04-13 23:17:23 +000056 bool size_is_valid,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057 uint32_t flags
58) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000059 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000060 m_uid (symID),
Greg Clayton037520e2012-07-18 23:18:10 +000061 m_mangled (ConstString(name), name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062 m_type_data (0),
63 m_type_data_resolved (false),
64 m_is_synthetic (is_artificial),
65 m_is_debug (is_debug),
66 m_is_external (external),
67 m_size_is_sibling (false),
68 m_size_is_synthesized (false),
Greg Clayton9594f4c2013-04-13 23:17:23 +000069 m_calculated_size (size_is_valid || size > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +000070 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +000071 m_type (type),
72 m_flags (flags),
Greg Claytone72dfb32012-02-24 01:59:29 +000073 m_addr_range (section_sp, offset, size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074{
75}
76
77Symbol::Symbol
78(
Greg Clayton81c22f62011-10-19 18:09:39 +000079 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080 const char *name,
81 bool name_is_mangled,
82 SymbolType type,
83 bool external,
84 bool is_debug,
85 bool is_trampoline,
86 bool is_artificial,
87 const AddressRange &range,
Greg Clayton9594f4c2013-04-13 23:17:23 +000088 bool size_is_valid,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089 uint32_t flags
90) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000091 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000092 m_uid (symID),
Greg Clayton037520e2012-07-18 23:18:10 +000093 m_mangled (ConstString(name), name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094 m_type_data (0),
95 m_type_data_resolved (false),
96 m_is_synthetic (is_artificial),
97 m_is_debug (is_debug),
98 m_is_external (external),
99 m_size_is_sibling (false),
100 m_size_is_synthesized (false),
Greg Clayton9594f4c2013-04-13 23:17:23 +0000101 m_calculated_size (size_is_valid || range.GetByteSize() > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000102 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +0000103 m_type (type),
104 m_flags (flags),
105 m_addr_range (range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106{
107}
108
109Symbol::Symbol(const Symbol& rhs):
Stephen Wilson71c21d12011-04-11 19:41:40 +0000110 SymbolContextScope (rhs),
Greg Clayton81c22f62011-10-19 18:09:39 +0000111 m_uid (rhs.m_uid),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 m_mangled (rhs.m_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113 m_type_data (rhs.m_type_data),
114 m_type_data_resolved (rhs.m_type_data_resolved),
115 m_is_synthetic (rhs.m_is_synthetic),
116 m_is_debug (rhs.m_is_debug),
117 m_is_external (rhs.m_is_external),
118 m_size_is_sibling (rhs.m_size_is_sibling),
119 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +0000120 m_calculated_size (rhs.m_calculated_size),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000121 m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
Greg Clayton01575f82011-11-22 21:20:33 +0000122 m_type (rhs.m_type),
123 m_flags (rhs.m_flags),
124 m_addr_range (rhs.m_addr_range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125{
126}
127
128const Symbol&
129Symbol::operator= (const Symbol& rhs)
130{
131 if (this != &rhs)
132 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000133 SymbolContextScope::operator= (rhs);
Greg Clayton81c22f62011-10-19 18:09:39 +0000134 m_uid = rhs.m_uid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135 m_mangled = rhs.m_mangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136 m_type_data = rhs.m_type_data;
137 m_type_data_resolved = rhs.m_type_data_resolved;
138 m_is_synthetic = rhs.m_is_synthetic;
139 m_is_debug = rhs.m_is_debug;
140 m_is_external = rhs.m_is_external;
141 m_size_is_sibling = rhs.m_size_is_sibling;
142 m_size_is_synthesized = rhs.m_size_is_sibling;
Greg Claytonda171f12012-03-02 03:01:16 +0000143 m_calculated_size = rhs.m_calculated_size;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000144 m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
Greg Clayton01575f82011-11-22 21:20:33 +0000145 m_type = rhs.m_type;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146 m_flags = rhs.m_flags;
Greg Clayton01575f82011-11-22 21:20:33 +0000147 m_addr_range = rhs.m_addr_range;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148 }
149 return *this;
150}
151
Greg Clayton81c22f62011-10-19 18:09:39 +0000152void
153Symbol::Clear()
154{
155 m_uid = UINT32_MAX;
156 m_mangled.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000157 m_type_data = 0;
158 m_type_data_resolved = false;
159 m_is_synthetic = false;
160 m_is_debug = false;
161 m_is_external = false;
162 m_size_is_sibling = false;
163 m_size_is_synthesized = false;
Greg Claytonda171f12012-03-02 03:01:16 +0000164 m_calculated_size = false;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000165 m_demangled_is_synthesized = false;
Greg Clayton01575f82011-11-22 21:20:33 +0000166 m_type = eSymbolTypeInvalid;
Greg Clayton81c22f62011-10-19 18:09:39 +0000167 m_flags = 0;
Greg Clayton01575f82011-11-22 21:20:33 +0000168 m_addr_range.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000169}
170
Greg Claytone7612132012-03-07 21:03:09 +0000171bool
172Symbol::ValueIsAddress() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173{
Greg Claytone7612132012-03-07 21:03:09 +0000174 return m_addr_range.GetBaseAddress().GetSection().get() != NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175}
176
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177uint32_t
178Symbol::GetSiblingIndex() const
179{
180 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
181}
182
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183bool
184Symbol::IsTrampoline () const
185{
186 return m_type == eSymbolTypeTrampoline;
187}
188
Matt Kopec00049b82013-02-27 20:13:38 +0000189bool
190Symbol::IsIndirect () const
191{
192 return m_type == eSymbolTypeResolver;
193}
194
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000196Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000197{
Greg Claytonc4a8a762012-05-15 18:43:44 +0000198 s->Printf("id = {0x%8.8x}", m_uid);
Greg Claytond9dc52d2011-09-24 05:04:40 +0000199
Greg Claytone72dfb32012-02-24 01:59:29 +0000200 if (m_addr_range.GetBaseAddress().GetSection())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000201 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000202 if (ValueIsAddress())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000203 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000204 const lldb::addr_t byte_size = GetByteSize();
205 if (byte_size > 0)
Greg Claytonc9800662010-09-10 01:30:46 +0000206 {
207 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000208 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000209 }
210 else
211 {
212 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000213 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000214 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000215 }
216 else
Daniel Malead01b2952012-11-29 21:49:15 +0000217 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000218 }
219 else
220 {
221 if (m_size_is_sibling)
Daniel Malead01b2952012-11-29 21:49:15 +0000222 s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000223 else
Daniel Malead01b2952012-11-29 21:49:15 +0000224 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000225 }
Greg Clayton6b2bd932012-02-01 08:09:32 +0000226 if (m_mangled.GetDemangledName())
227 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
228 if (m_mangled.GetMangledName())
229 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
230
Greg Clayton0c5cd902010-06-28 21:30:43 +0000231}
232
233void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000234Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235{
236// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
237// s->Indent();
238// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
239 s->Printf("[%5u] %6u %c%c%c %-12s ",
240 index,
241 GetID(),
242 m_is_debug ? 'D' : ' ',
243 m_is_synthetic ? 'S' : ' ',
244 m_is_external ? 'X' : ' ',
245 GetTypeAsString());
246
Greg Claytone7612132012-03-07 21:03:09 +0000247 // Make sure the size of the symbol is up to date before dumping
248 GetByteSize();
249
250 if (ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251 {
252 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
253 s->Printf("%*s", 18, "");
254
255 s->PutChar(' ');
256
Greg Claytonf5e56de2010-09-14 23:36:40 +0000257 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 s->Printf("%*s", 18, "");
259
260 const char *format = m_size_is_sibling ?
261 " Sibling -> [%5llu] 0x%8.8x %s\n":
Daniel Malead01b2952012-11-29 21:49:15 +0000262 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 s->Printf( format,
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000264 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265 m_flags,
266 m_mangled.GetName().AsCString(""));
267 }
268 else
269 {
270 const char *format = m_size_is_sibling ?
Daniel Malead01b2952012-11-29 21:49:15 +0000271 "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n":
272 "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273 s->Printf( format,
274 m_addr_range.GetBaseAddress().GetOffset(),
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000275 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276 m_flags,
277 m_mangled.GetName().AsCString(""));
278 }
279}
280
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281uint32_t
282Symbol::GetPrologueByteSize ()
283{
Matt Kopec00049b82013-02-27 20:13:38 +0000284 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285 {
286 if (!m_type_data_resolved)
287 {
288 m_type_data_resolved = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000289 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +0000291 if (module_sp && module_sp->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
292 eSymbolContextLineEntry,
293 sc))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 {
295 m_type_data = sc.line_entry.range.GetByteSize();
Jim Inghamc8ff80d2012-07-24 01:31:19 +0000296 // Sanity check - this may be a function in the middle of code that has debug information, but
297 // not for this symbol. So the line entries surrounding us won't lie inside our function.
298 // In that case, the line entry will be bigger than we are, so we do that quick check and
299 // if that is true, we just return 0.
300 if (m_type_data >= m_addr_range.GetByteSize())
301 m_type_data = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302 }
303 else
304 {
305 // TODO: expose something in Process to figure out the
306 // size of a function prologue.
307 }
308 }
309 return m_type_data;
310 }
311 return 0;
312}
313
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314bool
315Symbol::Compare(const ConstString& name, SymbolType type) const
316{
Jim Inghamc30ee562011-10-29 00:54:12 +0000317 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
319 return false;
320}
321
322#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
323
324const char *
325Symbol::GetTypeAsString() const
326{
327 switch (m_type)
328 {
329 ENUM_TO_CSTRING(Invalid);
330 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 ENUM_TO_CSTRING(Code);
332 ENUM_TO_CSTRING(Data);
333 ENUM_TO_CSTRING(Trampoline);
334 ENUM_TO_CSTRING(Runtime);
335 ENUM_TO_CSTRING(Exception);
336 ENUM_TO_CSTRING(SourceFile);
337 ENUM_TO_CSTRING(HeaderFile);
338 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339 ENUM_TO_CSTRING(CommonBlock);
340 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341 ENUM_TO_CSTRING(Local);
342 ENUM_TO_CSTRING(Param);
343 ENUM_TO_CSTRING(Variable);
344 ENUM_TO_CSTRING(VariableType);
345 ENUM_TO_CSTRING(LineEntry);
346 ENUM_TO_CSTRING(LineHeader);
347 ENUM_TO_CSTRING(ScopeBegin);
348 ENUM_TO_CSTRING(ScopeEnd);
349 ENUM_TO_CSTRING(Additional);
350 ENUM_TO_CSTRING(Compiler);
351 ENUM_TO_CSTRING(Instrumentation);
352 ENUM_TO_CSTRING(Undefined);
Greg Clayton456809c2011-12-03 02:30:59 +0000353 ENUM_TO_CSTRING(ObjCClass);
354 ENUM_TO_CSTRING(ObjCMetaClass);
355 ENUM_TO_CSTRING(ObjCIVar);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356 default:
357 break;
358 }
359 return "<unknown SymbolType>";
360}
361
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000362
363void
364Symbol::CalculateSymbolContext (SymbolContext *sc)
365{
366 // Symbols can reconstruct the symbol and the module in the symbol context
367 sc->symbol = this;
Greg Claytone7612132012-03-07 21:03:09 +0000368 if (ValueIsAddress())
369 sc->module_sp = GetAddress().GetModule();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000370 else
371 sc->module_sp.reset();
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000372}
373
Greg Claytone72dfb32012-02-24 01:59:29 +0000374ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000375Symbol::CalculateSymbolContextModule ()
376{
Greg Claytone7612132012-03-07 21:03:09 +0000377 if (ValueIsAddress())
378 return GetAddress().GetModule();
Greg Claytone72dfb32012-02-24 01:59:29 +0000379 return ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000380}
381
382Symbol *
383Symbol::CalculateSymbolContextSymbol ()
384{
385 return this;
386}
387
388
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000389void
390Symbol::DumpSymbolContext (Stream *s)
391{
392 bool dumped_module = false;
Greg Claytone7612132012-03-07 21:03:09 +0000393 if (ValueIsAddress())
394 {
395 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000396 if (module_sp)
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000397 {
398 dumped_module = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000399 module_sp->DumpSymbolContext(s);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000400 }
401 }
402 if (dumped_module)
403 s->PutCString(", ");
404
405 s->Printf("Symbol{0x%8.8x}", GetID());
406}
407
408
Greg Claytonda171f12012-03-02 03:01:16 +0000409lldb::addr_t
410Symbol::GetByteSize () const
411{
412 addr_t byte_size = m_addr_range.GetByteSize();
413 if (byte_size == 0 && !m_calculated_size)
414 {
415 const_cast<Symbol*>(this)->m_calculated_size = true;
Greg Claytone7612132012-03-07 21:03:09 +0000416 if (ValueIsAddress())
Greg Claytonda171f12012-03-02 03:01:16 +0000417 {
Greg Claytone7612132012-03-07 21:03:09 +0000418 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytonda171f12012-03-02 03:01:16 +0000419 if (module_sp)
420 {
421 ObjectFile *objfile = module_sp->GetObjectFile();
422 if (objfile)
423 {
424 Symtab *symtab = objfile->GetSymtab();
425 if (symtab)
426 {
Greg Claytone7612132012-03-07 21:03:09 +0000427 const_cast<Symbol*>(this)->SetByteSize (symtab->CalculateSymbolSize (const_cast<Symbol *>(this)));
Greg Claytonda171f12012-03-02 03:01:16 +0000428 byte_size = m_addr_range.GetByteSize();
429 }
430 }
431 }
432 }
433 }
434 return byte_size;
435}
436