blob: 8b2bd20aaf6c1e3f4cddf3d32e8805e2c6a9bf0c [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,
55 uint32_t size,
56 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000188Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000189{
Greg Claytonc4a8a762012-05-15 18:43:44 +0000190 s->Printf("id = {0x%8.8x}", m_uid);
Greg Claytond9dc52d2011-09-24 05:04:40 +0000191
Greg Claytone72dfb32012-02-24 01:59:29 +0000192 if (m_addr_range.GetBaseAddress().GetSection())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000193 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000194 if (ValueIsAddress())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000195 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000196 const lldb::addr_t byte_size = GetByteSize();
197 if (byte_size > 0)
Greg Claytonc9800662010-09-10 01:30:46 +0000198 {
199 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000200 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000201 }
202 else
203 {
204 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000205 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000206 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000207 }
208 else
Greg Claytond9dc52d2011-09-24 05:04:40 +0000209 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
210 }
211 else
212 {
213 if (m_size_is_sibling)
214 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
215 else
216 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000217 }
Greg Clayton6b2bd932012-02-01 08:09:32 +0000218 if (m_mangled.GetDemangledName())
219 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
220 if (m_mangled.GetMangledName())
221 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
222
Greg Clayton0c5cd902010-06-28 21:30:43 +0000223}
224
225void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000226Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227{
228// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
229// s->Indent();
230// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
231 s->Printf("[%5u] %6u %c%c%c %-12s ",
232 index,
233 GetID(),
234 m_is_debug ? 'D' : ' ',
235 m_is_synthetic ? 'S' : ' ',
236 m_is_external ? 'X' : ' ',
237 GetTypeAsString());
238
Greg Claytone7612132012-03-07 21:03:09 +0000239 // Make sure the size of the symbol is up to date before dumping
240 GetByteSize();
241
242 if (ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 {
244 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
245 s->Printf("%*s", 18, "");
246
247 s->PutChar(' ');
248
Greg Claytonf5e56de2010-09-14 23:36:40 +0000249 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250 s->Printf("%*s", 18, "");
251
252 const char *format = m_size_is_sibling ?
253 " Sibling -> [%5llu] 0x%8.8x %s\n":
254 " 0x%16.16llx 0x%8.8x %s\n";
255 s->Printf( format,
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000256 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257 m_flags,
258 m_mangled.GetName().AsCString(""));
259 }
260 else
261 {
262 const char *format = m_size_is_sibling ?
263 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
264 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
265 s->Printf( format,
266 m_addr_range.GetBaseAddress().GetOffset(),
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000267 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268 m_flags,
269 m_mangled.GetName().AsCString(""));
270 }
271}
272
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273uint32_t
274Symbol::GetPrologueByteSize ()
275{
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000276 if (m_type == eSymbolTypeCode)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277 {
278 if (!m_type_data_resolved)
279 {
280 m_type_data_resolved = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000281 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +0000283 if (module_sp && module_sp->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
284 eSymbolContextLineEntry,
285 sc))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000286 {
287 m_type_data = sc.line_entry.range.GetByteSize();
Jim Inghamc8ff80d2012-07-24 01:31:19 +0000288 // Sanity check - this may be a function in the middle of code that has debug information, but
289 // not for this symbol. So the line entries surrounding us won't lie inside our function.
290 // In that case, the line entry will be bigger than we are, so we do that quick check and
291 // if that is true, we just return 0.
292 if (m_type_data >= m_addr_range.GetByteSize())
293 m_type_data = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 }
295 else
296 {
297 // TODO: expose something in Process to figure out the
298 // size of a function prologue.
299 }
300 }
301 return m_type_data;
302 }
303 return 0;
304}
305
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306bool
307Symbol::Compare(const ConstString& name, SymbolType type) const
308{
Jim Inghamc30ee562011-10-29 00:54:12 +0000309 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
311 return false;
312}
313
314#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
315
316const char *
317Symbol::GetTypeAsString() const
318{
319 switch (m_type)
320 {
321 ENUM_TO_CSTRING(Invalid);
322 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323 ENUM_TO_CSTRING(Code);
324 ENUM_TO_CSTRING(Data);
325 ENUM_TO_CSTRING(Trampoline);
326 ENUM_TO_CSTRING(Runtime);
327 ENUM_TO_CSTRING(Exception);
328 ENUM_TO_CSTRING(SourceFile);
329 ENUM_TO_CSTRING(HeaderFile);
330 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 ENUM_TO_CSTRING(CommonBlock);
332 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 ENUM_TO_CSTRING(Local);
334 ENUM_TO_CSTRING(Param);
335 ENUM_TO_CSTRING(Variable);
336 ENUM_TO_CSTRING(VariableType);
337 ENUM_TO_CSTRING(LineEntry);
338 ENUM_TO_CSTRING(LineHeader);
339 ENUM_TO_CSTRING(ScopeBegin);
340 ENUM_TO_CSTRING(ScopeEnd);
341 ENUM_TO_CSTRING(Additional);
342 ENUM_TO_CSTRING(Compiler);
343 ENUM_TO_CSTRING(Instrumentation);
344 ENUM_TO_CSTRING(Undefined);
Greg Clayton456809c2011-12-03 02:30:59 +0000345 ENUM_TO_CSTRING(ObjCClass);
346 ENUM_TO_CSTRING(ObjCMetaClass);
347 ENUM_TO_CSTRING(ObjCIVar);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 default:
349 break;
350 }
351 return "<unknown SymbolType>";
352}
353
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000354
355void
356Symbol::CalculateSymbolContext (SymbolContext *sc)
357{
358 // Symbols can reconstruct the symbol and the module in the symbol context
359 sc->symbol = this;
Greg Claytone7612132012-03-07 21:03:09 +0000360 if (ValueIsAddress())
361 sc->module_sp = GetAddress().GetModule();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000362 else
363 sc->module_sp.reset();
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000364}
365
Greg Claytone72dfb32012-02-24 01:59:29 +0000366ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000367Symbol::CalculateSymbolContextModule ()
368{
Greg Claytone7612132012-03-07 21:03:09 +0000369 if (ValueIsAddress())
370 return GetAddress().GetModule();
Greg Claytone72dfb32012-02-24 01:59:29 +0000371 return ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000372}
373
374Symbol *
375Symbol::CalculateSymbolContextSymbol ()
376{
377 return this;
378}
379
380
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000381void
382Symbol::DumpSymbolContext (Stream *s)
383{
384 bool dumped_module = false;
Greg Claytone7612132012-03-07 21:03:09 +0000385 if (ValueIsAddress())
386 {
387 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000388 if (module_sp)
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000389 {
390 dumped_module = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000391 module_sp->DumpSymbolContext(s);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000392 }
393 }
394 if (dumped_module)
395 s->PutCString(", ");
396
397 s->Printf("Symbol{0x%8.8x}", GetID());
398}
399
400
Greg Claytonda171f12012-03-02 03:01:16 +0000401lldb::addr_t
402Symbol::GetByteSize () const
403{
404 addr_t byte_size = m_addr_range.GetByteSize();
405 if (byte_size == 0 && !m_calculated_size)
406 {
407 const_cast<Symbol*>(this)->m_calculated_size = true;
Greg Claytone7612132012-03-07 21:03:09 +0000408 if (ValueIsAddress())
Greg Claytonda171f12012-03-02 03:01:16 +0000409 {
Greg Claytone7612132012-03-07 21:03:09 +0000410 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytonda171f12012-03-02 03:01:16 +0000411 if (module_sp)
412 {
413 ObjectFile *objfile = module_sp->GetObjectFile();
414 if (objfile)
415 {
416 Symtab *symtab = objfile->GetSymtab();
417 if (symtab)
418 {
Greg Claytone7612132012-03-07 21:03:09 +0000419 const_cast<Symbol*>(this)->SetByteSize (symtab->CalculateSymbolSize (const_cast<Symbol *>(this)));
Greg Claytonda171f12012-03-02 03:01:16 +0000420 byte_size = m_addr_range.GetByteSize();
421 }
422 }
423 }
424 }
425 }
426 return byte_size;
427}
428