blob: 27780a939add2b7e57f527e5c07a4b072fca85bc [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() :
23 UserID (),
Stephen Wilson71c21d12011-04-11 19:41:40 +000024 SymbolContextScope (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025 m_mangled (),
26 m_type (eSymbolTypeInvalid),
27 m_type_data (0),
28 m_type_data_resolved (false),
29 m_is_synthetic (false),
30 m_is_debug (false),
31 m_is_external (false),
32 m_size_is_sibling (false),
33 m_size_is_synthesized (false),
34 m_searched_for_function (false),
35 m_addr_range (),
36 m_flags (),
37 m_function (NULL)
38{
39}
40
41Symbol::Symbol
42(
43 user_id_t symID,
44 const char *name,
45 bool name_is_mangled,
46 SymbolType type,
47 bool external,
48 bool is_debug,
49 bool is_trampoline,
50 bool is_artificial,
51 const Section* section,
52 addr_t offset,
53 uint32_t size,
54 uint32_t flags
55) :
56 UserID (symID),
Stephen Wilson71c21d12011-04-11 19:41:40 +000057 SymbolContextScope (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058 m_mangled (name, name_is_mangled),
59 m_type (type),
60 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),
67 m_searched_for_function (false),
68 m_addr_range (section, offset, size),
69 m_flags (flags),
70 m_function (NULL)
71{
72}
73
74Symbol::Symbol
75(
76 user_id_t symID,
77 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) :
87 UserID (symID),
Stephen Wilson71c21d12011-04-11 19:41:40 +000088 SymbolContextScope (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089 m_mangled (name, name_is_mangled),
90 m_type (type),
91 m_type_data (0),
92 m_type_data_resolved (false),
93 m_is_synthetic (is_artificial),
94 m_is_debug (is_debug),
95 m_is_external (external),
96 m_size_is_sibling (false),
97 m_size_is_synthesized (false),
98 m_searched_for_function (false),
99 m_addr_range (range),
100 m_flags (flags),
101 m_function (NULL)
102{
103}
104
105Symbol::Symbol(const Symbol& rhs):
106 UserID (rhs),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000107 SymbolContextScope (rhs),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108 m_mangled (rhs.m_mangled),
109 m_type (rhs.m_type),
110 m_type_data (rhs.m_type_data),
111 m_type_data_resolved (rhs.m_type_data_resolved),
112 m_is_synthetic (rhs.m_is_synthetic),
113 m_is_debug (rhs.m_is_debug),
114 m_is_external (rhs.m_is_external),
115 m_size_is_sibling (rhs.m_size_is_sibling),
116 m_size_is_synthesized (false),
117 m_searched_for_function (false),
118 m_addr_range (rhs.m_addr_range),
119 m_flags (rhs.m_flags),
120 m_function (NULL)
121{
122}
123
124const Symbol&
125Symbol::operator= (const Symbol& rhs)
126{
127 if (this != &rhs)
128 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000129 SymbolContextScope::operator= (rhs);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 UserID::operator= (rhs);
131 m_mangled = rhs.m_mangled;
132 m_type = rhs.m_type;
133 m_type_data = rhs.m_type_data;
134 m_type_data_resolved = rhs.m_type_data_resolved;
135 m_is_synthetic = rhs.m_is_synthetic;
136 m_is_debug = rhs.m_is_debug;
137 m_is_external = rhs.m_is_external;
138 m_size_is_sibling = rhs.m_size_is_sibling;
139 m_size_is_synthesized = rhs.m_size_is_sibling;
140 m_searched_for_function = rhs.m_searched_for_function;
141 m_addr_range = rhs.m_addr_range;
142 m_flags = rhs.m_flags;
143 m_function = rhs.m_function;
144 }
145 return *this;
146}
147
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148AddressRange *
149Symbol::GetAddressRangePtr()
150{
151 if (m_addr_range.GetBaseAddress().GetSection())
152 return &m_addr_range;
153 return NULL;
154}
155
156const AddressRange *
157Symbol::GetAddressRangePtr() const
158{
159 if (m_addr_range.GetBaseAddress().GetSection())
160 return &m_addr_range;
161 return NULL;
162}
163
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164uint32_t
165Symbol::GetSiblingIndex() const
166{
167 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
168}
169
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170bool
171Symbol::IsTrampoline () const
172{
173 return m_type == eSymbolTypeTrampoline;
174}
175
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000177Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000178{
Greg Claytonc9800662010-09-10 01:30:46 +0000179 *s << "id = " << (const UserID&)*this << ", name = \"" << m_mangled.GetName() << '"';
Greg Claytond9dc52d2011-09-24 05:04:40 +0000180
Greg Clayton0c5cd902010-06-28 21:30:43 +0000181 const Section *section = m_addr_range.GetBaseAddress().GetSection();
182 if (section != NULL)
183 {
Greg Claytonc9800662010-09-10 01:30:46 +0000184 if (m_addr_range.GetBaseAddress().IsSectionOffset())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000185 {
Greg Claytonc9800662010-09-10 01:30:46 +0000186 if (m_addr_range.GetByteSize() > 0)
187 {
188 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000189 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000190 }
191 else
192 {
193 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000194 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000195 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000196 }
197 else
Greg Claytond9dc52d2011-09-24 05:04:40 +0000198 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
199 }
200 else
201 {
202 if (m_size_is_sibling)
203 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
204 else
205 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000206 }
207}
208
209void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000210Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211{
212// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
213// s->Indent();
214// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
215 s->Printf("[%5u] %6u %c%c%c %-12s ",
216 index,
217 GetID(),
218 m_is_debug ? 'D' : ' ',
219 m_is_synthetic ? 'S' : ' ',
220 m_is_external ? 'X' : ' ',
221 GetTypeAsString());
222
223 const Section *section = m_addr_range.GetBaseAddress().GetSection();
224 if (section != NULL)
225 {
226 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
227 s->Printf("%*s", 18, "");
228
229 s->PutChar(' ');
230
Greg Claytonf5e56de2010-09-14 23:36:40 +0000231 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 s->Printf("%*s", 18, "");
233
234 const char *format = m_size_is_sibling ?
235 " Sibling -> [%5llu] 0x%8.8x %s\n":
236 " 0x%16.16llx 0x%8.8x %s\n";
237 s->Printf( format,
238 m_addr_range.GetByteSize(),
239 m_flags,
240 m_mangled.GetName().AsCString(""));
241 }
242 else
243 {
244 const char *format = m_size_is_sibling ?
245 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
246 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
247 s->Printf( format,
248 m_addr_range.GetBaseAddress().GetOffset(),
249 m_addr_range.GetByteSize(),
250 m_flags,
251 m_mangled.GetName().AsCString(""));
252 }
253}
254
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255Function *
256Symbol::GetFunction ()
257{
258 if (m_function == NULL && !m_searched_for_function)
259 {
260 m_searched_for_function = true;
261 Module *module = m_addr_range.GetBaseAddress().GetModule();
262 if (module)
263 {
264 SymbolContext sc;
265 if (module->ResolveSymbolContextForAddress(m_addr_range.GetBaseAddress(), eSymbolContextFunction, sc))
266 m_function = sc.function;
267 }
268 }
269 return m_function;
270}
271
272uint32_t
273Symbol::GetPrologueByteSize ()
274{
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000275 if (m_type == eSymbolTypeCode)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276 {
277 if (!m_type_data_resolved)
278 {
279 m_type_data_resolved = true;
280 Module *module = m_addr_range.GetBaseAddress().GetModule();
281 SymbolContext sc;
282 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
283 eSymbolContextLineEntry,
284 sc))
285 {
286 m_type_data = sc.line_entry.range.GetByteSize();
287 }
288 else
289 {
290 // TODO: expose something in Process to figure out the
291 // size of a function prologue.
292 }
293 }
294 return m_type_data;
295 }
296 return 0;
297}
298
299void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300Symbol::SetValue(addr_t value)
301{
302 m_addr_range.GetBaseAddress().SetSection(NULL);
303 m_addr_range.GetBaseAddress().SetOffset(value);
304}
305
306
307bool
308Symbol::Compare(const ConstString& name, SymbolType type) const
309{
310 if (m_type == eSymbolTypeAny || m_type == type)
311 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
312 return false;
313}
314
315#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
316
317const char *
318Symbol::GetTypeAsString() const
319{
320 switch (m_type)
321 {
322 ENUM_TO_CSTRING(Invalid);
323 ENUM_TO_CSTRING(Absolute);
324 ENUM_TO_CSTRING(Extern);
325 ENUM_TO_CSTRING(Code);
326 ENUM_TO_CSTRING(Data);
327 ENUM_TO_CSTRING(Trampoline);
328 ENUM_TO_CSTRING(Runtime);
329 ENUM_TO_CSTRING(Exception);
330 ENUM_TO_CSTRING(SourceFile);
331 ENUM_TO_CSTRING(HeaderFile);
332 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 ENUM_TO_CSTRING(CommonBlock);
334 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335 ENUM_TO_CSTRING(Local);
336 ENUM_TO_CSTRING(Param);
337 ENUM_TO_CSTRING(Variable);
338 ENUM_TO_CSTRING(VariableType);
339 ENUM_TO_CSTRING(LineEntry);
340 ENUM_TO_CSTRING(LineHeader);
341 ENUM_TO_CSTRING(ScopeBegin);
342 ENUM_TO_CSTRING(ScopeEnd);
343 ENUM_TO_CSTRING(Additional);
344 ENUM_TO_CSTRING(Compiler);
345 ENUM_TO_CSTRING(Instrumentation);
346 ENUM_TO_CSTRING(Undefined);
347 default:
348 break;
349 }
350 return "<unknown SymbolType>";
351}
352
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000353
354void
355Symbol::CalculateSymbolContext (SymbolContext *sc)
356{
357 // Symbols can reconstruct the symbol and the module in the symbol context
358 sc->symbol = this;
359 const AddressRange *range = GetAddressRangePtr();
360 if (range)
361 {
362 Module *module = range->GetBaseAddress().GetModule ();
363 if (module)
364 {
Greg Claytona2eee182011-09-17 07:23:18 +0000365 sc->module_sp = module;
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000366 return;
367 }
368 }
369 sc->module_sp.reset();
370}
371
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000372Module *
373Symbol::CalculateSymbolContextModule ()
374{
375 const AddressRange *range = GetAddressRangePtr();
376 if (range)
377 return range->GetBaseAddress().GetModule ();
378 return NULL;
379}
380
381Symbol *
382Symbol::CalculateSymbolContextSymbol ()
383{
384 return this;
385}
386
387
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000388void
389Symbol::DumpSymbolContext (Stream *s)
390{
391 bool dumped_module = false;
392 const AddressRange *range = GetAddressRangePtr();
393 if (range)
394 {
395 Module *module = range->GetBaseAddress().GetModule ();
396 if (module)
397 {
398 dumped_module = true;
399 module->DumpSymbolContext(s);
400 }
401 }
402 if (dumped_module)
403 s->PutCString(", ");
404
405 s->Printf("Symbol{0x%8.8x}", GetID());
406}
407
408