blob: 0fe0ceb57d7c0d28a6726bb596049174e6de2496 [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,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056 uint32_t flags
57) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000058 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000059 m_uid (symID),
Greg Clayton037520e2012-07-18 23:18:10 +000060 m_mangled (ConstString(name), name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061 m_type_data (0),
62 m_type_data_resolved (false),
63 m_is_synthetic (is_artificial),
64 m_is_debug (is_debug),
65 m_is_external (external),
66 m_size_is_sibling (false),
67 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +000068 m_calculated_size (size > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +000069 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +000070 m_type (type),
71 m_flags (flags),
Greg Claytone72dfb32012-02-24 01:59:29 +000072 m_addr_range (section_sp, offset, size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073{
74}
75
76Symbol::Symbol
77(
Greg Clayton81c22f62011-10-19 18:09:39 +000078 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079 const char *name,
80 bool name_is_mangled,
81 SymbolType type,
82 bool external,
83 bool is_debug,
84 bool is_trampoline,
85 bool is_artificial,
86 const AddressRange &range,
87 uint32_t flags
88) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000089 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000090 m_uid (symID),
Greg Clayton037520e2012-07-18 23:18:10 +000091 m_mangled (ConstString(name), name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092 m_type_data (0),
93 m_type_data_resolved (false),
94 m_is_synthetic (is_artificial),
95 m_is_debug (is_debug),
96 m_is_external (external),
97 m_size_is_sibling (false),
98 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +000099 m_calculated_size (range.GetByteSize() > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000100 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +0000101 m_type (type),
102 m_flags (flags),
103 m_addr_range (range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104{
105}
106
107Symbol::Symbol(const Symbol& rhs):
Stephen Wilson71c21d12011-04-11 19:41:40 +0000108 SymbolContextScope (rhs),
Greg Clayton81c22f62011-10-19 18:09:39 +0000109 m_uid (rhs.m_uid),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 m_mangled (rhs.m_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111 m_type_data (rhs.m_type_data),
112 m_type_data_resolved (rhs.m_type_data_resolved),
113 m_is_synthetic (rhs.m_is_synthetic),
114 m_is_debug (rhs.m_is_debug),
115 m_is_external (rhs.m_is_external),
116 m_size_is_sibling (rhs.m_size_is_sibling),
117 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +0000118 m_calculated_size (rhs.m_calculated_size),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000119 m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
Greg Clayton01575f82011-11-22 21:20:33 +0000120 m_type (rhs.m_type),
121 m_flags (rhs.m_flags),
122 m_addr_range (rhs.m_addr_range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123{
124}
125
126const Symbol&
127Symbol::operator= (const Symbol& rhs)
128{
129 if (this != &rhs)
130 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000131 SymbolContextScope::operator= (rhs);
Greg Clayton81c22f62011-10-19 18:09:39 +0000132 m_uid = rhs.m_uid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133 m_mangled = rhs.m_mangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134 m_type_data = rhs.m_type_data;
135 m_type_data_resolved = rhs.m_type_data_resolved;
136 m_is_synthetic = rhs.m_is_synthetic;
137 m_is_debug = rhs.m_is_debug;
138 m_is_external = rhs.m_is_external;
139 m_size_is_sibling = rhs.m_size_is_sibling;
140 m_size_is_synthesized = rhs.m_size_is_sibling;
Greg Claytonda171f12012-03-02 03:01:16 +0000141 m_calculated_size = rhs.m_calculated_size;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000142 m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
Greg Clayton01575f82011-11-22 21:20:33 +0000143 m_type = rhs.m_type;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144 m_flags = rhs.m_flags;
Greg Clayton01575f82011-11-22 21:20:33 +0000145 m_addr_range = rhs.m_addr_range;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146 }
147 return *this;
148}
149
Greg Clayton81c22f62011-10-19 18:09:39 +0000150void
151Symbol::Clear()
152{
153 m_uid = UINT32_MAX;
154 m_mangled.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000155 m_type_data = 0;
156 m_type_data_resolved = false;
157 m_is_synthetic = false;
158 m_is_debug = false;
159 m_is_external = false;
160 m_size_is_sibling = false;
161 m_size_is_synthesized = false;
Greg Claytonda171f12012-03-02 03:01:16 +0000162 m_calculated_size = false;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000163 m_demangled_is_synthesized = false;
Greg Clayton01575f82011-11-22 21:20:33 +0000164 m_type = eSymbolTypeInvalid;
Greg Clayton81c22f62011-10-19 18:09:39 +0000165 m_flags = 0;
Greg Clayton01575f82011-11-22 21:20:33 +0000166 m_addr_range.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000167}
168
Greg Claytone7612132012-03-07 21:03:09 +0000169bool
170Symbol::ValueIsAddress() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171{
Greg Claytone7612132012-03-07 21:03:09 +0000172 return m_addr_range.GetBaseAddress().GetSection().get() != NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173}
174
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175uint32_t
176Symbol::GetSiblingIndex() const
177{
178 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
179}
180
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181bool
182Symbol::IsTrampoline () const
183{
184 return m_type == eSymbolTypeTrampoline;
185}
186
Matt Kopec00049b82013-02-27 20:13:38 +0000187bool
188Symbol::IsIndirect () const
189{
190 return m_type == eSymbolTypeResolver;
191}
192
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000194Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000195{
Greg Claytonc4a8a762012-05-15 18:43:44 +0000196 s->Printf("id = {0x%8.8x}", m_uid);
Greg Claytond9dc52d2011-09-24 05:04:40 +0000197
Greg Claytone72dfb32012-02-24 01:59:29 +0000198 if (m_addr_range.GetBaseAddress().GetSection())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000199 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000200 if (ValueIsAddress())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000201 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000202 const lldb::addr_t byte_size = GetByteSize();
203 if (byte_size > 0)
Greg Claytonc9800662010-09-10 01:30:46 +0000204 {
205 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000206 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000207 }
208 else
209 {
210 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000211 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000212 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000213 }
214 else
Daniel Malead01b2952012-11-29 21:49:15 +0000215 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000216 }
217 else
218 {
219 if (m_size_is_sibling)
Daniel Malead01b2952012-11-29 21:49:15 +0000220 s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000221 else
Daniel Malead01b2952012-11-29 21:49:15 +0000222 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000223 }
Greg Clayton6b2bd932012-02-01 08:09:32 +0000224 if (m_mangled.GetDemangledName())
225 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
226 if (m_mangled.GetMangledName())
227 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
228
Greg Clayton0c5cd902010-06-28 21:30:43 +0000229}
230
231void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000232Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000233{
234// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
235// s->Indent();
236// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
237 s->Printf("[%5u] %6u %c%c%c %-12s ",
238 index,
239 GetID(),
240 m_is_debug ? 'D' : ' ',
241 m_is_synthetic ? 'S' : ' ',
242 m_is_external ? 'X' : ' ',
243 GetTypeAsString());
244
Greg Claytone7612132012-03-07 21:03:09 +0000245 // Make sure the size of the symbol is up to date before dumping
246 GetByteSize();
247
248 if (ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 {
250 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
251 s->Printf("%*s", 18, "");
252
253 s->PutChar(' ');
254
Greg Claytonf5e56de2010-09-14 23:36:40 +0000255 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256 s->Printf("%*s", 18, "");
257
258 const char *format = m_size_is_sibling ?
259 " Sibling -> [%5llu] 0x%8.8x %s\n":
Daniel Malead01b2952012-11-29 21:49:15 +0000260 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261 s->Printf( format,
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000262 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 m_flags,
264 m_mangled.GetName().AsCString(""));
265 }
266 else
267 {
268 const char *format = m_size_is_sibling ?
Daniel Malead01b2952012-11-29 21:49:15 +0000269 "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n":
270 "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271 s->Printf( format,
272 m_addr_range.GetBaseAddress().GetOffset(),
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000273 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274 m_flags,
275 m_mangled.GetName().AsCString(""));
276 }
277}
278
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279uint32_t
280Symbol::GetPrologueByteSize ()
281{
Matt Kopec00049b82013-02-27 20:13:38 +0000282 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 {
284 if (!m_type_data_resolved)
285 {
286 m_type_data_resolved = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000287 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +0000289 if (module_sp && module_sp->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
290 eSymbolContextLineEntry,
291 sc))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000292 {
293 m_type_data = sc.line_entry.range.GetByteSize();
Jim Inghamc8ff80d2012-07-24 01:31:19 +0000294 // Sanity check - this may be a function in the middle of code that has debug information, but
295 // not for this symbol. So the line entries surrounding us won't lie inside our function.
296 // In that case, the line entry will be bigger than we are, so we do that quick check and
297 // if that is true, we just return 0.
298 if (m_type_data >= m_addr_range.GetByteSize())
299 m_type_data = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 }
301 else
302 {
303 // TODO: expose something in Process to figure out the
304 // size of a function prologue.
305 }
306 }
307 return m_type_data;
308 }
309 return 0;
310}
311
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312bool
313Symbol::Compare(const ConstString& name, SymbolType type) const
314{
Jim Inghamc30ee562011-10-29 00:54:12 +0000315 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
317 return false;
318}
319
320#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
321
322const char *
323Symbol::GetTypeAsString() const
324{
325 switch (m_type)
326 {
327 ENUM_TO_CSTRING(Invalid);
328 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329 ENUM_TO_CSTRING(Code);
330 ENUM_TO_CSTRING(Data);
331 ENUM_TO_CSTRING(Trampoline);
332 ENUM_TO_CSTRING(Runtime);
333 ENUM_TO_CSTRING(Exception);
334 ENUM_TO_CSTRING(SourceFile);
335 ENUM_TO_CSTRING(HeaderFile);
336 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 ENUM_TO_CSTRING(CommonBlock);
338 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339 ENUM_TO_CSTRING(Local);
340 ENUM_TO_CSTRING(Param);
341 ENUM_TO_CSTRING(Variable);
342 ENUM_TO_CSTRING(VariableType);
343 ENUM_TO_CSTRING(LineEntry);
344 ENUM_TO_CSTRING(LineHeader);
345 ENUM_TO_CSTRING(ScopeBegin);
346 ENUM_TO_CSTRING(ScopeEnd);
347 ENUM_TO_CSTRING(Additional);
348 ENUM_TO_CSTRING(Compiler);
349 ENUM_TO_CSTRING(Instrumentation);
350 ENUM_TO_CSTRING(Undefined);
Greg Clayton456809c2011-12-03 02:30:59 +0000351 ENUM_TO_CSTRING(ObjCClass);
352 ENUM_TO_CSTRING(ObjCMetaClass);
353 ENUM_TO_CSTRING(ObjCIVar);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354 default:
355 break;
356 }
357 return "<unknown SymbolType>";
358}
359
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000360
361void
362Symbol::CalculateSymbolContext (SymbolContext *sc)
363{
364 // Symbols can reconstruct the symbol and the module in the symbol context
365 sc->symbol = this;
Greg Claytone7612132012-03-07 21:03:09 +0000366 if (ValueIsAddress())
367 sc->module_sp = GetAddress().GetModule();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000368 else
369 sc->module_sp.reset();
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000370}
371
Greg Claytone72dfb32012-02-24 01:59:29 +0000372ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000373Symbol::CalculateSymbolContextModule ()
374{
Greg Claytone7612132012-03-07 21:03:09 +0000375 if (ValueIsAddress())
376 return GetAddress().GetModule();
Greg Claytone72dfb32012-02-24 01:59:29 +0000377 return ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000378}
379
380Symbol *
381Symbol::CalculateSymbolContextSymbol ()
382{
383 return this;
384}
385
386
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000387void
388Symbol::DumpSymbolContext (Stream *s)
389{
390 bool dumped_module = false;
Greg Claytone7612132012-03-07 21:03:09 +0000391 if (ValueIsAddress())
392 {
393 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000394 if (module_sp)
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000395 {
396 dumped_module = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000397 module_sp->DumpSymbolContext(s);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000398 }
399 }
400 if (dumped_module)
401 s->PutCString(", ");
402
403 s->Printf("Symbol{0x%8.8x}", GetID());
404}
405
406
Greg Claytonda171f12012-03-02 03:01:16 +0000407lldb::addr_t
408Symbol::GetByteSize () const
409{
410 addr_t byte_size = m_addr_range.GetByteSize();
411 if (byte_size == 0 && !m_calculated_size)
412 {
413 const_cast<Symbol*>(this)->m_calculated_size = true;
Greg Claytone7612132012-03-07 21:03:09 +0000414 if (ValueIsAddress())
Greg Claytonda171f12012-03-02 03:01:16 +0000415 {
Greg Claytone7612132012-03-07 21:03:09 +0000416 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytonda171f12012-03-02 03:01:16 +0000417 if (module_sp)
418 {
419 ObjectFile *objfile = module_sp->GetObjectFile();
420 if (objfile)
421 {
422 Symtab *symtab = objfile->GetSymtab();
423 if (symtab)
424 {
Greg Claytone7612132012-03-07 21:03:09 +0000425 const_cast<Symbol*>(this)->SetByteSize (symtab->CalculateSymbolSize (const_cast<Symbol *>(this)));
Greg Claytonda171f12012-03-02 03:01:16 +0000426 byte_size = m_addr_range.GetByteSize();
427 }
428 }
429 }
430 }
431 }
432 return byte_size;
433}
434