blob: bd8246b8b64eef9f11e1f5346cb48a20606bb966 [file] [log] [blame]
Chris Lattner24943d22010-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 Claytoneea26402010-09-14 23:36:40 +000016#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017
18using namespace lldb;
19using namespace lldb_private;
20
21
22Symbol::Symbol() :
Greg Clayton4fb08152010-08-30 18:11:35 +000023 SymbolContextScope (),
Chris Lattner24943d22010-06-08 16:52:24 +000024 UserID (),
25 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) :
Greg Clayton4fb08152010-08-30 18:11:35 +000056 SymbolContextScope (),
Chris Lattner24943d22010-06-08 16:52:24 +000057 UserID (symID),
58 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) :
Greg Clayton4fb08152010-08-30 18:11:35 +000087 SymbolContextScope (),
Chris Lattner24943d22010-06-08 16:52:24 +000088 UserID (symID),
89 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):
Greg Clayton4fb08152010-08-30 18:11:35 +0000106 SymbolContextScope (rhs),
Chris Lattner24943d22010-06-08 16:52:24 +0000107 UserID (rhs),
108 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 Clayton4fb08152010-08-30 18:11:35 +0000129 SymbolContextScope::operator= (rhs);
Chris Lattner24943d22010-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 Lattner24943d22010-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 Lattner24943d22010-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 Lattner24943d22010-06-08 16:52:24 +0000170bool
171Symbol::IsTrampoline () const
172{
173 return m_type == eSymbolTypeTrampoline;
174}
175
Chris Lattner24943d22010-06-08 16:52:24 +0000176void
Greg Claytoneea26402010-09-14 23:36:40 +0000177Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton12bec712010-06-28 21:30:43 +0000178{
Greg Claytonc67b7d12010-09-10 01:30:46 +0000179 *s << "id = " << (const UserID&)*this << ", name = \"" << m_mangled.GetName() << '"';
Greg Clayton12bec712010-06-28 21:30:43 +0000180 const Section *section = m_addr_range.GetBaseAddress().GetSection();
181 if (section != NULL)
182 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000183 if (m_addr_range.GetBaseAddress().IsSectionOffset())
Greg Clayton12bec712010-06-28 21:30:43 +0000184 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000185 if (m_addr_range.GetByteSize() > 0)
186 {
187 s->PutCString (", range = ");
Greg Claytoneea26402010-09-14 23:36:40 +0000188 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000189 }
190 else
191 {
192 s->PutCString (", address = ");
Greg Claytoneea26402010-09-14 23:36:40 +0000193 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc67b7d12010-09-10 01:30:46 +0000194 }
Greg Clayton12bec712010-06-28 21:30:43 +0000195 }
196 else
197 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000198 if (m_size_is_sibling)
199 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
200 else
201 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton12bec712010-06-28 21:30:43 +0000202 }
203 }
204}
205
206void
Greg Claytoneea26402010-09-14 23:36:40 +0000207Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner24943d22010-06-08 16:52:24 +0000208{
209// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
210// s->Indent();
211// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
212 s->Printf("[%5u] %6u %c%c%c %-12s ",
213 index,
214 GetID(),
215 m_is_debug ? 'D' : ' ',
216 m_is_synthetic ? 'S' : ' ',
217 m_is_external ? 'X' : ' ',
218 GetTypeAsString());
219
220 const Section *section = m_addr_range.GetBaseAddress().GetSection();
221 if (section != NULL)
222 {
223 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
224 s->Printf("%*s", 18, "");
225
226 s->PutChar(' ');
227
Greg Claytoneea26402010-09-14 23:36:40 +0000228 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner24943d22010-06-08 16:52:24 +0000229 s->Printf("%*s", 18, "");
230
231 const char *format = m_size_is_sibling ?
232 " Sibling -> [%5llu] 0x%8.8x %s\n":
233 " 0x%16.16llx 0x%8.8x %s\n";
234 s->Printf( format,
235 m_addr_range.GetByteSize(),
236 m_flags,
237 m_mangled.GetName().AsCString(""));
238 }
239 else
240 {
241 const char *format = m_size_is_sibling ?
242 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
243 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
244 s->Printf( format,
245 m_addr_range.GetBaseAddress().GetOffset(),
246 m_addr_range.GetByteSize(),
247 m_flags,
248 m_mangled.GetName().AsCString(""));
249 }
250}
251
Chris Lattner24943d22010-06-08 16:52:24 +0000252Function *
253Symbol::GetFunction ()
254{
255 if (m_function == NULL && !m_searched_for_function)
256 {
257 m_searched_for_function = true;
258 Module *module = m_addr_range.GetBaseAddress().GetModule();
259 if (module)
260 {
261 SymbolContext sc;
262 if (module->ResolveSymbolContextForAddress(m_addr_range.GetBaseAddress(), eSymbolContextFunction, sc))
263 m_function = sc.function;
264 }
265 }
266 return m_function;
267}
268
269uint32_t
270Symbol::GetPrologueByteSize ()
271{
Greg Clayton7c36fa02010-09-11 03:13:28 +0000272 if (m_type == eSymbolTypeCode)
Chris Lattner24943d22010-06-08 16:52:24 +0000273 {
274 if (!m_type_data_resolved)
275 {
276 m_type_data_resolved = true;
277 Module *module = m_addr_range.GetBaseAddress().GetModule();
278 SymbolContext sc;
279 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
280 eSymbolContextLineEntry,
281 sc))
282 {
283 m_type_data = sc.line_entry.range.GetByteSize();
284 }
285 else
286 {
287 // TODO: expose something in Process to figure out the
288 // size of a function prologue.
289 }
290 }
291 return m_type_data;
292 }
293 return 0;
294}
295
296void
Chris Lattner24943d22010-06-08 16:52:24 +0000297Symbol::SetValue(addr_t value)
298{
299 m_addr_range.GetBaseAddress().SetSection(NULL);
300 m_addr_range.GetBaseAddress().SetOffset(value);
301}
302
303
304bool
305Symbol::Compare(const ConstString& name, SymbolType type) const
306{
307 if (m_type == eSymbolTypeAny || m_type == type)
308 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
309 return false;
310}
311
312#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
313
314const char *
315Symbol::GetTypeAsString() const
316{
317 switch (m_type)
318 {
319 ENUM_TO_CSTRING(Invalid);
320 ENUM_TO_CSTRING(Absolute);
321 ENUM_TO_CSTRING(Extern);
322 ENUM_TO_CSTRING(Code);
323 ENUM_TO_CSTRING(Data);
324 ENUM_TO_CSTRING(Trampoline);
325 ENUM_TO_CSTRING(Runtime);
326 ENUM_TO_CSTRING(Exception);
327 ENUM_TO_CSTRING(SourceFile);
328 ENUM_TO_CSTRING(HeaderFile);
329 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner24943d22010-06-08 16:52:24 +0000330 ENUM_TO_CSTRING(CommonBlock);
331 ENUM_TO_CSTRING(Block);
Chris Lattner24943d22010-06-08 16:52:24 +0000332 ENUM_TO_CSTRING(Local);
333 ENUM_TO_CSTRING(Param);
334 ENUM_TO_CSTRING(Variable);
335 ENUM_TO_CSTRING(VariableType);
336 ENUM_TO_CSTRING(LineEntry);
337 ENUM_TO_CSTRING(LineHeader);
338 ENUM_TO_CSTRING(ScopeBegin);
339 ENUM_TO_CSTRING(ScopeEnd);
340 ENUM_TO_CSTRING(Additional);
341 ENUM_TO_CSTRING(Compiler);
342 ENUM_TO_CSTRING(Instrumentation);
343 ENUM_TO_CSTRING(Undefined);
344 default:
345 break;
346 }
347 return "<unknown SymbolType>";
348}
349
Greg Clayton4fb08152010-08-30 18:11:35 +0000350
351void
352Symbol::CalculateSymbolContext (SymbolContext *sc)
353{
354 // Symbols can reconstruct the symbol and the module in the symbol context
355 sc->symbol = this;
356 const AddressRange *range = GetAddressRangePtr();
357 if (range)
358 {
359 Module *module = range->GetBaseAddress().GetModule ();
360 if (module)
361 {
362 sc->module_sp = module->GetSP();
363 return;
364 }
365 }
366 sc->module_sp.reset();
367}
368
369void
370Symbol::DumpSymbolContext (Stream *s)
371{
372 bool dumped_module = false;
373 const AddressRange *range = GetAddressRangePtr();
374 if (range)
375 {
376 Module *module = range->GetBaseAddress().GetModule ();
377 if (module)
378 {
379 dumped_module = true;
380 module->DumpSymbolContext(s);
381 }
382 }
383 if (dumped_module)
384 s->PutCString(", ");
385
386 s->Printf("Symbol{0x%8.8x}", GetID());
387}
388
389