blob: bd084c8894ff766f27ad61e2ac8fbaed3d57acd8 [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"
15#include "lldb/Target/Process.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000016#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017
18using namespace lldb;
19using namespace lldb_private;
20
21
22Symbol::Symbol() :
Stephen Wilson71c21d12011-04-11 19:41:40 +000023 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000024 m_uid (UINT32_MAX),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025 m_mangled (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026 m_type_data (0),
27 m_type_data_resolved (false),
28 m_is_synthetic (false),
29 m_is_debug (false),
30 m_is_external (false),
31 m_size_is_sibling (false),
32 m_size_is_synthesized (false),
33 m_searched_for_function (false),
Greg Clayton01575f82011-11-22 21:20:33 +000034 m_type (eSymbolTypeInvalid),
35 m_flags (),
36 m_addr_range ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037{
38}
39
40Symbol::Symbol
41(
Greg Clayton81c22f62011-10-19 18:09:39 +000042 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043 const char *name,
44 bool name_is_mangled,
45 SymbolType type,
46 bool external,
47 bool is_debug,
48 bool is_trampoline,
49 bool is_artificial,
50 const Section* section,
51 addr_t offset,
52 uint32_t size,
53 uint32_t flags
54) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000055 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000056 m_uid (symID),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057 m_mangled (name, name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058 m_type_data (0),
59 m_type_data_resolved (false),
60 m_is_synthetic (is_artificial),
61 m_is_debug (is_debug),
62 m_is_external (external),
63 m_size_is_sibling (false),
64 m_size_is_synthesized (false),
65 m_searched_for_function (false),
Greg Clayton01575f82011-11-22 21:20:33 +000066 m_type (type),
67 m_flags (flags),
68 m_addr_range (section, offset, size)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069{
70}
71
72Symbol::Symbol
73(
Greg Clayton81c22f62011-10-19 18:09:39 +000074 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075 const char *name,
76 bool name_is_mangled,
77 SymbolType type,
78 bool external,
79 bool is_debug,
80 bool is_trampoline,
81 bool is_artificial,
82 const AddressRange &range,
83 uint32_t flags
84) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000085 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000086 m_uid (symID),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087 m_mangled (name, name_is_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088 m_type_data (0),
89 m_type_data_resolved (false),
90 m_is_synthetic (is_artificial),
91 m_is_debug (is_debug),
92 m_is_external (external),
93 m_size_is_sibling (false),
94 m_size_is_synthesized (false),
95 m_searched_for_function (false),
Greg Clayton01575f82011-11-22 21:20:33 +000096 m_type (type),
97 m_flags (flags),
98 m_addr_range (range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099{
100}
101
102Symbol::Symbol(const Symbol& rhs):
Stephen Wilson71c21d12011-04-11 19:41:40 +0000103 SymbolContextScope (rhs),
Greg Clayton81c22f62011-10-19 18:09:39 +0000104 m_uid (rhs.m_uid),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 m_mangled (rhs.m_mangled),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106 m_type_data (rhs.m_type_data),
107 m_type_data_resolved (rhs.m_type_data_resolved),
108 m_is_synthetic (rhs.m_is_synthetic),
109 m_is_debug (rhs.m_is_debug),
110 m_is_external (rhs.m_is_external),
111 m_size_is_sibling (rhs.m_size_is_sibling),
112 m_size_is_synthesized (false),
113 m_searched_for_function (false),
Greg Clayton01575f82011-11-22 21:20:33 +0000114 m_type (rhs.m_type),
115 m_flags (rhs.m_flags),
116 m_addr_range (rhs.m_addr_range)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117{
118}
119
120const Symbol&
121Symbol::operator= (const Symbol& rhs)
122{
123 if (this != &rhs)
124 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000125 SymbolContextScope::operator= (rhs);
Greg Clayton81c22f62011-10-19 18:09:39 +0000126 m_uid = rhs.m_uid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127 m_mangled = rhs.m_mangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 m_type_data = rhs.m_type_data;
129 m_type_data_resolved = rhs.m_type_data_resolved;
130 m_is_synthetic = rhs.m_is_synthetic;
131 m_is_debug = rhs.m_is_debug;
132 m_is_external = rhs.m_is_external;
133 m_size_is_sibling = rhs.m_size_is_sibling;
134 m_size_is_synthesized = rhs.m_size_is_sibling;
135 m_searched_for_function = rhs.m_searched_for_function;
Greg Clayton01575f82011-11-22 21:20:33 +0000136 m_type = rhs.m_type;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137 m_flags = rhs.m_flags;
Greg Clayton01575f82011-11-22 21:20:33 +0000138 m_addr_range = rhs.m_addr_range;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 }
140 return *this;
141}
142
Greg Clayton81c22f62011-10-19 18:09:39 +0000143void
144Symbol::Clear()
145{
146 m_uid = UINT32_MAX;
147 m_mangled.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000148 m_type_data = 0;
149 m_type_data_resolved = false;
150 m_is_synthetic = false;
151 m_is_debug = false;
152 m_is_external = false;
153 m_size_is_sibling = false;
154 m_size_is_synthesized = false;
155 m_searched_for_function = false;
Greg Clayton01575f82011-11-22 21:20:33 +0000156 m_type = eSymbolTypeInvalid;
Greg Clayton81c22f62011-10-19 18:09:39 +0000157 m_flags = 0;
Greg Clayton01575f82011-11-22 21:20:33 +0000158 m_addr_range.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000159}
160
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161AddressRange *
162Symbol::GetAddressRangePtr()
163{
164 if (m_addr_range.GetBaseAddress().GetSection())
165 return &m_addr_range;
166 return NULL;
167}
168
169const AddressRange *
170Symbol::GetAddressRangePtr() const
171{
172 if (m_addr_range.GetBaseAddress().GetSection())
173 return &m_addr_range;
174 return NULL;
175}
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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000190Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000191{
Greg Claytonc9800662010-09-10 01:30:46 +0000192 *s << "id = " << (const UserID&)*this << ", name = \"" << m_mangled.GetName() << '"';
Greg Claytond9dc52d2011-09-24 05:04:40 +0000193
Greg Clayton0c5cd902010-06-28 21:30:43 +0000194 const Section *section = m_addr_range.GetBaseAddress().GetSection();
195 if (section != NULL)
196 {
Greg Claytonc9800662010-09-10 01:30:46 +0000197 if (m_addr_range.GetBaseAddress().IsSectionOffset())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000198 {
Greg Claytonc9800662010-09-10 01:30:46 +0000199 if (m_addr_range.GetByteSize() > 0)
200 {
201 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000202 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000203 }
204 else
205 {
206 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000207 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000208 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000209 }
210 else
Greg Claytond9dc52d2011-09-24 05:04:40 +0000211 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
212 }
213 else
214 {
215 if (m_size_is_sibling)
216 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
217 else
218 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000219 }
220}
221
222void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000223Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224{
225// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
226// s->Indent();
227// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
228 s->Printf("[%5u] %6u %c%c%c %-12s ",
229 index,
230 GetID(),
231 m_is_debug ? 'D' : ' ',
232 m_is_synthetic ? 'S' : ' ',
233 m_is_external ? 'X' : ' ',
234 GetTypeAsString());
235
236 const Section *section = m_addr_range.GetBaseAddress().GetSection();
237 if (section != NULL)
238 {
239 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
240 s->Printf("%*s", 18, "");
241
242 s->PutChar(' ');
243
Greg Claytonf5e56de2010-09-14 23:36:40 +0000244 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 s->Printf("%*s", 18, "");
246
247 const char *format = m_size_is_sibling ?
248 " Sibling -> [%5llu] 0x%8.8x %s\n":
249 " 0x%16.16llx 0x%8.8x %s\n";
250 s->Printf( format,
251 m_addr_range.GetByteSize(),
252 m_flags,
253 m_mangled.GetName().AsCString(""));
254 }
255 else
256 {
257 const char *format = m_size_is_sibling ?
258 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
259 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
260 s->Printf( format,
261 m_addr_range.GetBaseAddress().GetOffset(),
262 m_addr_range.GetByteSize(),
263 m_flags,
264 m_mangled.GetName().AsCString(""));
265 }
266}
267
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268uint32_t
269Symbol::GetPrologueByteSize ()
270{
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000271 if (m_type == eSymbolTypeCode)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272 {
273 if (!m_type_data_resolved)
274 {
275 m_type_data_resolved = true;
276 Module *module = m_addr_range.GetBaseAddress().GetModule();
277 SymbolContext sc;
278 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
279 eSymbolContextLineEntry,
280 sc))
281 {
282 m_type_data = sc.line_entry.range.GetByteSize();
283 }
284 else
285 {
286 // TODO: expose something in Process to figure out the
287 // size of a function prologue.
288 }
289 }
290 return m_type_data;
291 }
292 return 0;
293}
294
295void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296Symbol::SetValue(addr_t value)
297{
298 m_addr_range.GetBaseAddress().SetSection(NULL);
299 m_addr_range.GetBaseAddress().SetOffset(value);
300}
301
302
303bool
304Symbol::Compare(const ConstString& name, SymbolType type) const
305{
Jim Inghamc30ee562011-10-29 00:54:12 +0000306 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
308 return false;
309}
310
311#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
312
313const char *
314Symbol::GetTypeAsString() const
315{
316 switch (m_type)
317 {
318 ENUM_TO_CSTRING(Invalid);
319 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000320 ENUM_TO_CSTRING(Code);
321 ENUM_TO_CSTRING(Data);
322 ENUM_TO_CSTRING(Trampoline);
323 ENUM_TO_CSTRING(Runtime);
324 ENUM_TO_CSTRING(Exception);
325 ENUM_TO_CSTRING(SourceFile);
326 ENUM_TO_CSTRING(HeaderFile);
327 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 ENUM_TO_CSTRING(CommonBlock);
329 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330 ENUM_TO_CSTRING(Local);
331 ENUM_TO_CSTRING(Param);
332 ENUM_TO_CSTRING(Variable);
333 ENUM_TO_CSTRING(VariableType);
334 ENUM_TO_CSTRING(LineEntry);
335 ENUM_TO_CSTRING(LineHeader);
336 ENUM_TO_CSTRING(ScopeBegin);
337 ENUM_TO_CSTRING(ScopeEnd);
338 ENUM_TO_CSTRING(Additional);
339 ENUM_TO_CSTRING(Compiler);
340 ENUM_TO_CSTRING(Instrumentation);
341 ENUM_TO_CSTRING(Undefined);
342 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;
354 const AddressRange *range = GetAddressRangePtr();
355 if (range)
356 {
357 Module *module = range->GetBaseAddress().GetModule ();
358 if (module)
359 {
Greg Claytona2eee182011-09-17 07:23:18 +0000360 sc->module_sp = module;
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000361 return;
362 }
363 }
364 sc->module_sp.reset();
365}
366
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000367Module *
368Symbol::CalculateSymbolContextModule ()
369{
370 const AddressRange *range = GetAddressRangePtr();
371 if (range)
372 return range->GetBaseAddress().GetModule ();
373 return NULL;
374}
375
376Symbol *
377Symbol::CalculateSymbolContextSymbol ()
378{
379 return this;
380}
381
382
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000383void
384Symbol::DumpSymbolContext (Stream *s)
385{
386 bool dumped_module = false;
387 const AddressRange *range = GetAddressRangePtr();
388 if (range)
389 {
390 Module *module = range->GetBaseAddress().GetModule ();
391 if (module)
392 {
393 dumped_module = true;
394 module->DumpSymbolContext(s);
395 }
396 }
397 if (dumped_module)
398 s->PutCString(", ");
399
400 s->Printf("Symbol{0x%8.8x}", GetID());
401}
402
403