blob: e176df6b9e71bd0a0279d15c84d7d41d22190e02 [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"
16
17using namespace lldb;
18using namespace lldb_private;
19
20
21Symbol::Symbol() :
Greg Clayton4fb08152010-08-30 18:11:35 +000022 SymbolContextScope (),
Chris Lattner24943d22010-06-08 16:52:24 +000023 UserID (),
24 m_mangled (),
25 m_type (eSymbolTypeInvalid),
26 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),
34 m_addr_range (),
35 m_flags (),
36 m_function (NULL)
37{
38}
39
40Symbol::Symbol
41(
42 user_id_t symID,
43 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) :
Greg Clayton4fb08152010-08-30 18:11:35 +000055 SymbolContextScope (),
Chris Lattner24943d22010-06-08 16:52:24 +000056 UserID (symID),
57 m_mangled (name, name_is_mangled),
58 m_type (type),
59 m_type_data (0),
60 m_type_data_resolved (false),
61 m_is_synthetic (is_artificial),
62 m_is_debug (is_debug),
63 m_is_external (external),
64 m_size_is_sibling (false),
65 m_size_is_synthesized (false),
66 m_searched_for_function (false),
67 m_addr_range (section, offset, size),
68 m_flags (flags),
69 m_function (NULL)
70{
71}
72
73Symbol::Symbol
74(
75 user_id_t symID,
76 const char *name,
77 bool name_is_mangled,
78 SymbolType type,
79 bool external,
80 bool is_debug,
81 bool is_trampoline,
82 bool is_artificial,
83 const AddressRange &range,
84 uint32_t flags
85) :
Greg Clayton4fb08152010-08-30 18:11:35 +000086 SymbolContextScope (),
Chris Lattner24943d22010-06-08 16:52:24 +000087 UserID (symID),
88 m_mangled (name, name_is_mangled),
89 m_type (type),
90 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),
97 m_searched_for_function (false),
98 m_addr_range (range),
99 m_flags (flags),
100 m_function (NULL)
101{
102}
103
104Symbol::Symbol(const Symbol& rhs):
Greg Clayton4fb08152010-08-30 18:11:35 +0000105 SymbolContextScope (rhs),
Chris Lattner24943d22010-06-08 16:52:24 +0000106 UserID (rhs),
107 m_mangled (rhs.m_mangled),
108 m_type (rhs.m_type),
109 m_type_data (rhs.m_type_data),
110 m_type_data_resolved (rhs.m_type_data_resolved),
111 m_is_synthetic (rhs.m_is_synthetic),
112 m_is_debug (rhs.m_is_debug),
113 m_is_external (rhs.m_is_external),
114 m_size_is_sibling (rhs.m_size_is_sibling),
115 m_size_is_synthesized (false),
116 m_searched_for_function (false),
117 m_addr_range (rhs.m_addr_range),
118 m_flags (rhs.m_flags),
119 m_function (NULL)
120{
121}
122
123const Symbol&
124Symbol::operator= (const Symbol& rhs)
125{
126 if (this != &rhs)
127 {
Greg Clayton4fb08152010-08-30 18:11:35 +0000128 SymbolContextScope::operator= (rhs);
Chris Lattner24943d22010-06-08 16:52:24 +0000129 UserID::operator= (rhs);
130 m_mangled = rhs.m_mangled;
131 m_type = rhs.m_type;
132 m_type_data = rhs.m_type_data;
133 m_type_data_resolved = rhs.m_type_data_resolved;
134 m_is_synthetic = rhs.m_is_synthetic;
135 m_is_debug = rhs.m_is_debug;
136 m_is_external = rhs.m_is_external;
137 m_size_is_sibling = rhs.m_size_is_sibling;
138 m_size_is_synthesized = rhs.m_size_is_sibling;
139 m_searched_for_function = rhs.m_searched_for_function;
140 m_addr_range = rhs.m_addr_range;
141 m_flags = rhs.m_flags;
142 m_function = rhs.m_function;
143 }
144 return *this;
145}
146
Chris Lattner24943d22010-06-08 16:52:24 +0000147AddressRange *
148Symbol::GetAddressRangePtr()
149{
150 if (m_addr_range.GetBaseAddress().GetSection())
151 return &m_addr_range;
152 return NULL;
153}
154
155const AddressRange *
156Symbol::GetAddressRangePtr() const
157{
158 if (m_addr_range.GetBaseAddress().GetSection())
159 return &m_addr_range;
160 return NULL;
161}
162
Chris Lattner24943d22010-06-08 16:52:24 +0000163uint32_t
164Symbol::GetSiblingIndex() const
165{
166 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
167}
168
Chris Lattner24943d22010-06-08 16:52:24 +0000169bool
170Symbol::IsTrampoline () const
171{
172 return m_type == eSymbolTypeTrampoline;
173}
174
Chris Lattner24943d22010-06-08 16:52:24 +0000175void
Greg Clayton12bec712010-06-28 21:30:43 +0000176Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Process *process) const
177{
Greg Claytonc67b7d12010-09-10 01:30:46 +0000178 *s << "id = " << (const UserID&)*this << ", name = \"" << m_mangled.GetName() << '"';
Greg Clayton12bec712010-06-28 21:30:43 +0000179 const Section *section = m_addr_range.GetBaseAddress().GetSection();
180 if (section != NULL)
181 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000182 if (m_addr_range.GetBaseAddress().IsSectionOffset())
Greg Clayton12bec712010-06-28 21:30:43 +0000183 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000184 if (m_addr_range.GetByteSize() > 0)
185 {
186 s->PutCString (", range = ");
187 m_addr_range.Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
188 }
189 else
190 {
191 s->PutCString (", address = ");
192 m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
193 }
Greg Clayton12bec712010-06-28 21:30:43 +0000194 }
195 else
196 {
Greg Claytonc67b7d12010-09-10 01:30:46 +0000197 if (m_size_is_sibling)
198 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
199 else
200 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton12bec712010-06-28 21:30:43 +0000201 }
202 }
203}
204
205void
Chris Lattner24943d22010-06-08 16:52:24 +0000206Symbol::Dump(Stream *s, Process *process, uint32_t index) const
207{
208// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
209// s->Indent();
210// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
211 s->Printf("[%5u] %6u %c%c%c %-12s ",
212 index,
213 GetID(),
214 m_is_debug ? 'D' : ' ',
215 m_is_synthetic ? 'S' : ' ',
216 m_is_external ? 'X' : ' ',
217 GetTypeAsString());
218
219 const Section *section = m_addr_range.GetBaseAddress().GetSection();
220 if (section != NULL)
221 {
222 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
223 s->Printf("%*s", 18, "");
224
225 s->PutChar(' ');
226
227 if (!m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress))
228 s->Printf("%*s", 18, "");
229
230 const char *format = m_size_is_sibling ?
231 " Sibling -> [%5llu] 0x%8.8x %s\n":
232 " 0x%16.16llx 0x%8.8x %s\n";
233 s->Printf( format,
234 m_addr_range.GetByteSize(),
235 m_flags,
236 m_mangled.GetName().AsCString(""));
237 }
238 else
239 {
240 const char *format = m_size_is_sibling ?
241 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
242 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
243 s->Printf( format,
244 m_addr_range.GetBaseAddress().GetOffset(),
245 m_addr_range.GetByteSize(),
246 m_flags,
247 m_mangled.GetName().AsCString(""));
248 }
249}
250
Chris Lattner24943d22010-06-08 16:52:24 +0000251Function *
252Symbol::GetFunction ()
253{
254 if (m_function == NULL && !m_searched_for_function)
255 {
256 m_searched_for_function = true;
257 Module *module = m_addr_range.GetBaseAddress().GetModule();
258 if (module)
259 {
260 SymbolContext sc;
261 if (module->ResolveSymbolContextForAddress(m_addr_range.GetBaseAddress(), eSymbolContextFunction, sc))
262 m_function = sc.function;
263 }
264 }
265 return m_function;
266}
267
268uint32_t
269Symbol::GetPrologueByteSize ()
270{
Greg Clayton7c36fa02010-09-11 03:13:28 +0000271 if (m_type == eSymbolTypeCode)
Chris Lattner24943d22010-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 Lattner24943d22010-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{
306 if (m_type == eSymbolTypeAny || m_type == type)
307 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);
320 ENUM_TO_CSTRING(Extern);
321 ENUM_TO_CSTRING(Code);
322 ENUM_TO_CSTRING(Data);
323 ENUM_TO_CSTRING(Trampoline);
324 ENUM_TO_CSTRING(Runtime);
325 ENUM_TO_CSTRING(Exception);
326 ENUM_TO_CSTRING(SourceFile);
327 ENUM_TO_CSTRING(HeaderFile);
328 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner24943d22010-06-08 16:52:24 +0000329 ENUM_TO_CSTRING(CommonBlock);
330 ENUM_TO_CSTRING(Block);
Chris Lattner24943d22010-06-08 16:52:24 +0000331 ENUM_TO_CSTRING(Local);
332 ENUM_TO_CSTRING(Param);
333 ENUM_TO_CSTRING(Variable);
334 ENUM_TO_CSTRING(VariableType);
335 ENUM_TO_CSTRING(LineEntry);
336 ENUM_TO_CSTRING(LineHeader);
337 ENUM_TO_CSTRING(ScopeBegin);
338 ENUM_TO_CSTRING(ScopeEnd);
339 ENUM_TO_CSTRING(Additional);
340 ENUM_TO_CSTRING(Compiler);
341 ENUM_TO_CSTRING(Instrumentation);
342 ENUM_TO_CSTRING(Undefined);
343 default:
344 break;
345 }
346 return "<unknown SymbolType>";
347}
348
Greg Clayton4fb08152010-08-30 18:11:35 +0000349
350void
351Symbol::CalculateSymbolContext (SymbolContext *sc)
352{
353 // Symbols can reconstruct the symbol and the module in the symbol context
354 sc->symbol = this;
355 const AddressRange *range = GetAddressRangePtr();
356 if (range)
357 {
358 Module *module = range->GetBaseAddress().GetModule ();
359 if (module)
360 {
361 sc->module_sp = module->GetSP();
362 return;
363 }
364 }
365 sc->module_sp.reset();
366}
367
368void
369Symbol::DumpSymbolContext (Stream *s)
370{
371 bool dumped_module = false;
372 const AddressRange *range = GetAddressRangePtr();
373 if (range)
374 {
375 Module *module = range->GetBaseAddress().GetModule ();
376 if (module)
377 {
378 dumped_module = true;
379 module->DumpSymbolContext(s);
380 }
381 }
382 if (dumped_module)
383 s->PutCString(", ");
384
385 s->Printf("Symbol{0x%8.8x}", GetID());
386}
387
388