blob: 3a8a333cb75e5e500f66e9c3cb62a254c31d6232 [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 Clayton01575f82011-11-22 21:20:33 +000036 m_type (eSymbolTypeInvalid),
37 m_flags (),
38 m_addr_range ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039{
40}
41
42Symbol::Symbol
43(
Greg Clayton81c22f62011-10-19 18:09:39 +000044 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045 const char *name,
46 bool name_is_mangled,
47 SymbolType type,
48 bool external,
49 bool is_debug,
50 bool is_trampoline,
51 bool is_artificial,
Greg Claytone72dfb32012-02-24 01:59:29 +000052 const lldb::SectionSP &section_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053 addr_t offset,
54 uint32_t size,
55 uint32_t flags
56) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000057 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000058 m_uid (symID),
Greg Clayton037520e2012-07-18 23:18:10 +000059 m_mangled (ConstString(name), name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060 m_type_data (0),
61 m_type_data_resolved (false),
62 m_is_synthetic (is_artificial),
63 m_is_debug (is_debug),
64 m_is_external (external),
65 m_size_is_sibling (false),
66 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +000067 m_calculated_size (size > 0),
Greg Clayton01575f82011-11-22 21:20:33 +000068 m_type (type),
69 m_flags (flags),
Greg Claytone72dfb32012-02-24 01:59:29 +000070 m_addr_range (section_sp, offset, size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071{
72}
73
74Symbol::Symbol
75(
Greg Clayton81c22f62011-10-19 18:09:39 +000076 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077 const char *name,
78 bool name_is_mangled,
79 SymbolType type,
80 bool external,
81 bool is_debug,
82 bool is_trampoline,
83 bool is_artificial,
84 const AddressRange &range,
85 uint32_t flags
86) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000087 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000088 m_uid (symID),
Greg Clayton037520e2012-07-18 23:18:10 +000089 m_mangled (ConstString(name), name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090 m_type_data (0),
91 m_type_data_resolved (false),
92 m_is_synthetic (is_artificial),
93 m_is_debug (is_debug),
94 m_is_external (external),
95 m_size_is_sibling (false),
96 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +000097 m_calculated_size (range.GetByteSize() > 0),
Greg Clayton01575f82011-11-22 21:20:33 +000098 m_type (type),
99 m_flags (flags),
100 m_addr_range (range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101{
102}
103
104Symbol::Symbol(const Symbol& rhs):
Stephen Wilson71c21d12011-04-11 19:41:40 +0000105 SymbolContextScope (rhs),
Greg Clayton81c22f62011-10-19 18:09:39 +0000106 m_uid (rhs.m_uid),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107 m_mangled (rhs.m_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108 m_type_data (rhs.m_type_data),
109 m_type_data_resolved (rhs.m_type_data_resolved),
110 m_is_synthetic (rhs.m_is_synthetic),
111 m_is_debug (rhs.m_is_debug),
112 m_is_external (rhs.m_is_external),
113 m_size_is_sibling (rhs.m_size_is_sibling),
114 m_size_is_synthesized (false),
Greg Claytonda171f12012-03-02 03:01:16 +0000115 m_calculated_size (rhs.m_calculated_size),
Greg Clayton01575f82011-11-22 21:20:33 +0000116 m_type (rhs.m_type),
117 m_flags (rhs.m_flags),
118 m_addr_range (rhs.m_addr_range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119{
120}
121
122const Symbol&
123Symbol::operator= (const Symbol& rhs)
124{
125 if (this != &rhs)
126 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000127 SymbolContextScope::operator= (rhs);
Greg Clayton81c22f62011-10-19 18:09:39 +0000128 m_uid = rhs.m_uid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129 m_mangled = rhs.m_mangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 m_type_data = rhs.m_type_data;
131 m_type_data_resolved = rhs.m_type_data_resolved;
132 m_is_synthetic = rhs.m_is_synthetic;
133 m_is_debug = rhs.m_is_debug;
134 m_is_external = rhs.m_is_external;
135 m_size_is_sibling = rhs.m_size_is_sibling;
136 m_size_is_synthesized = rhs.m_size_is_sibling;
Greg Claytonda171f12012-03-02 03:01:16 +0000137 m_calculated_size = rhs.m_calculated_size;
Greg Clayton01575f82011-11-22 21:20:33 +0000138 m_type = rhs.m_type;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 m_flags = rhs.m_flags;
Greg Clayton01575f82011-11-22 21:20:33 +0000140 m_addr_range = rhs.m_addr_range;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141 }
142 return *this;
143}
144
Greg Clayton81c22f62011-10-19 18:09:39 +0000145void
146Symbol::Clear()
147{
148 m_uid = UINT32_MAX;
149 m_mangled.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000150 m_type_data = 0;
151 m_type_data_resolved = false;
152 m_is_synthetic = false;
153 m_is_debug = false;
154 m_is_external = false;
155 m_size_is_sibling = false;
156 m_size_is_synthesized = false;
Greg Claytonda171f12012-03-02 03:01:16 +0000157 m_calculated_size = false;
Greg Clayton01575f82011-11-22 21:20:33 +0000158 m_type = eSymbolTypeInvalid;
Greg Clayton81c22f62011-10-19 18:09:39 +0000159 m_flags = 0;
Greg Clayton01575f82011-11-22 21:20:33 +0000160 m_addr_range.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000161}
162
Greg Claytone7612132012-03-07 21:03:09 +0000163bool
164Symbol::ValueIsAddress() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165{
Greg Claytone7612132012-03-07 21:03:09 +0000166 return m_addr_range.GetBaseAddress().GetSection().get() != NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167}
168
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169uint32_t
170Symbol::GetSiblingIndex() const
171{
172 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
173}
174
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175bool
176Symbol::IsTrampoline () const
177{
178 return m_type == eSymbolTypeTrampoline;
179}
180
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000182Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000183{
Greg Claytonc4a8a762012-05-15 18:43:44 +0000184 s->Printf("id = {0x%8.8x}", m_uid);
Greg Claytond9dc52d2011-09-24 05:04:40 +0000185
Greg Claytone72dfb32012-02-24 01:59:29 +0000186 if (m_addr_range.GetBaseAddress().GetSection())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000187 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000188 if (ValueIsAddress())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000189 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000190 const lldb::addr_t byte_size = GetByteSize();
191 if (byte_size > 0)
Greg Claytonc9800662010-09-10 01:30:46 +0000192 {
193 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000194 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000195 }
196 else
197 {
198 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000199 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000200 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000201 }
202 else
Greg Claytond9dc52d2011-09-24 05:04:40 +0000203 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
204 }
205 else
206 {
207 if (m_size_is_sibling)
208 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
209 else
210 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000211 }
Greg Clayton6b2bd932012-02-01 08:09:32 +0000212 if (m_mangled.GetDemangledName())
213 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
214 if (m_mangled.GetMangledName())
215 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
216
Greg Clayton0c5cd902010-06-28 21:30:43 +0000217}
218
219void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000220Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221{
222// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
223// s->Indent();
224// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
225 s->Printf("[%5u] %6u %c%c%c %-12s ",
226 index,
227 GetID(),
228 m_is_debug ? 'D' : ' ',
229 m_is_synthetic ? 'S' : ' ',
230 m_is_external ? 'X' : ' ',
231 GetTypeAsString());
232
Greg Claytone7612132012-03-07 21:03:09 +0000233 // Make sure the size of the symbol is up to date before dumping
234 GetByteSize();
235
236 if (ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237 {
238 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
239 s->Printf("%*s", 18, "");
240
241 s->PutChar(' ');
242
Greg Claytonf5e56de2010-09-14 23:36:40 +0000243 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244 s->Printf("%*s", 18, "");
245
246 const char *format = m_size_is_sibling ?
247 " Sibling -> [%5llu] 0x%8.8x %s\n":
248 " 0x%16.16llx 0x%8.8x %s\n";
249 s->Printf( format,
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000250 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251 m_flags,
252 m_mangled.GetName().AsCString(""));
253 }
254 else
255 {
256 const char *format = m_size_is_sibling ?
257 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
258 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
259 s->Printf( format,
260 m_addr_range.GetBaseAddress().GetOffset(),
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000261 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 m_flags,
263 m_mangled.GetName().AsCString(""));
264 }
265}
266
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267uint32_t
268Symbol::GetPrologueByteSize ()
269{
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000270 if (m_type == eSymbolTypeCode)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271 {
272 if (!m_type_data_resolved)
273 {
274 m_type_data_resolved = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000275 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +0000277 if (module_sp && module_sp->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
278 eSymbolContextLineEntry,
279 sc))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000280 {
281 m_type_data = sc.line_entry.range.GetByteSize();
Jim Inghamc8ff80d2012-07-24 01:31:19 +0000282 // Sanity check - this may be a function in the middle of code that has debug information, but
283 // not for this symbol. So the line entries surrounding us won't lie inside our function.
284 // In that case, the line entry will be bigger than we are, so we do that quick check and
285 // if that is true, we just return 0.
286 if (m_type_data >= m_addr_range.GetByteSize())
287 m_type_data = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288 }
289 else
290 {
291 // TODO: expose something in Process to figure out the
292 // size of a function prologue.
293 }
294 }
295 return m_type_data;
296 }
297 return 0;
298}
299
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300bool
301Symbol::Compare(const ConstString& name, SymbolType type) const
302{
Jim Inghamc30ee562011-10-29 00:54:12 +0000303 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
305 return false;
306}
307
308#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
309
310const char *
311Symbol::GetTypeAsString() const
312{
313 switch (m_type)
314 {
315 ENUM_TO_CSTRING(Invalid);
316 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 ENUM_TO_CSTRING(Code);
318 ENUM_TO_CSTRING(Data);
319 ENUM_TO_CSTRING(Trampoline);
320 ENUM_TO_CSTRING(Runtime);
321 ENUM_TO_CSTRING(Exception);
322 ENUM_TO_CSTRING(SourceFile);
323 ENUM_TO_CSTRING(HeaderFile);
324 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 ENUM_TO_CSTRING(CommonBlock);
326 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 ENUM_TO_CSTRING(Local);
328 ENUM_TO_CSTRING(Param);
329 ENUM_TO_CSTRING(Variable);
330 ENUM_TO_CSTRING(VariableType);
331 ENUM_TO_CSTRING(LineEntry);
332 ENUM_TO_CSTRING(LineHeader);
333 ENUM_TO_CSTRING(ScopeBegin);
334 ENUM_TO_CSTRING(ScopeEnd);
335 ENUM_TO_CSTRING(Additional);
336 ENUM_TO_CSTRING(Compiler);
337 ENUM_TO_CSTRING(Instrumentation);
338 ENUM_TO_CSTRING(Undefined);
Greg Clayton456809c2011-12-03 02:30:59 +0000339 ENUM_TO_CSTRING(ObjCClass);
340 ENUM_TO_CSTRING(ObjCMetaClass);
341 ENUM_TO_CSTRING(ObjCIVar);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 default:
343 break;
344 }
345 return "<unknown SymbolType>";
346}
347
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000348
349void
350Symbol::CalculateSymbolContext (SymbolContext *sc)
351{
352 // Symbols can reconstruct the symbol and the module in the symbol context
353 sc->symbol = this;
Greg Claytone7612132012-03-07 21:03:09 +0000354 if (ValueIsAddress())
355 sc->module_sp = GetAddress().GetModule();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000356 else
357 sc->module_sp.reset();
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000358}
359
Greg Claytone72dfb32012-02-24 01:59:29 +0000360ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000361Symbol::CalculateSymbolContextModule ()
362{
Greg Claytone7612132012-03-07 21:03:09 +0000363 if (ValueIsAddress())
364 return GetAddress().GetModule();
Greg Claytone72dfb32012-02-24 01:59:29 +0000365 return ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000366}
367
368Symbol *
369Symbol::CalculateSymbolContextSymbol ()
370{
371 return this;
372}
373
374
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000375void
376Symbol::DumpSymbolContext (Stream *s)
377{
378 bool dumped_module = false;
Greg Claytone7612132012-03-07 21:03:09 +0000379 if (ValueIsAddress())
380 {
381 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000382 if (module_sp)
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000383 {
384 dumped_module = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000385 module_sp->DumpSymbolContext(s);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000386 }
387 }
388 if (dumped_module)
389 s->PutCString(", ");
390
391 s->Printf("Symbol{0x%8.8x}", GetID());
392}
393
394
Greg Claytonda171f12012-03-02 03:01:16 +0000395lldb::addr_t
396Symbol::GetByteSize () const
397{
398 addr_t byte_size = m_addr_range.GetByteSize();
399 if (byte_size == 0 && !m_calculated_size)
400 {
401 const_cast<Symbol*>(this)->m_calculated_size = true;
Greg Claytone7612132012-03-07 21:03:09 +0000402 if (ValueIsAddress())
Greg Claytonda171f12012-03-02 03:01:16 +0000403 {
Greg Claytone7612132012-03-07 21:03:09 +0000404 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytonda171f12012-03-02 03:01:16 +0000405 if (module_sp)
406 {
407 ObjectFile *objfile = module_sp->GetObjectFile();
408 if (objfile)
409 {
410 Symtab *symtab = objfile->GetSymtab();
411 if (symtab)
412 {
Greg Claytone7612132012-03-07 21:03:09 +0000413 const_cast<Symbol*>(this)->SetByteSize (symtab->CalculateSymbolSize (const_cast<Symbol *>(this)));
Greg Claytonda171f12012-03-02 03:01:16 +0000414 byte_size = m_addr_range.GetByteSize();
415 }
416 }
417 }
418 }
419 }
420 return byte_size;
421}
422