blob: fb01fc176bde337cdc5086fa6942e8a2ab0db597 [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() :
22 UserID (),
23 m_mangled (),
24 m_type (eSymbolTypeInvalid),
25 m_type_data (0),
26 m_type_data_resolved (false),
27 m_is_synthetic (false),
28 m_is_debug (false),
29 m_is_external (false),
30 m_size_is_sibling (false),
31 m_size_is_synthesized (false),
32 m_searched_for_function (false),
33 m_addr_range (),
34 m_flags (),
35 m_function (NULL)
36{
37}
38
39Symbol::Symbol
40(
41 user_id_t symID,
42 const char *name,
43 bool name_is_mangled,
44 SymbolType type,
45 bool external,
46 bool is_debug,
47 bool is_trampoline,
48 bool is_artificial,
49 const Section* section,
50 addr_t offset,
51 uint32_t size,
52 uint32_t flags
53) :
54 UserID (symID),
55 m_mangled (name, name_is_mangled),
56 m_type (type),
57 m_type_data (0),
58 m_type_data_resolved (false),
59 m_is_synthetic (is_artificial),
60 m_is_debug (is_debug),
61 m_is_external (external),
62 m_size_is_sibling (false),
63 m_size_is_synthesized (false),
64 m_searched_for_function (false),
65 m_addr_range (section, offset, size),
66 m_flags (flags),
67 m_function (NULL)
68{
69}
70
71Symbol::Symbol
72(
73 user_id_t symID,
74 const char *name,
75 bool name_is_mangled,
76 SymbolType type,
77 bool external,
78 bool is_debug,
79 bool is_trampoline,
80 bool is_artificial,
81 const AddressRange &range,
82 uint32_t flags
83) :
84 UserID (symID),
85 m_mangled (name, name_is_mangled),
86 m_type (type),
87 m_type_data (0),
88 m_type_data_resolved (false),
89 m_is_synthetic (is_artificial),
90 m_is_debug (is_debug),
91 m_is_external (external),
92 m_size_is_sibling (false),
93 m_size_is_synthesized (false),
94 m_searched_for_function (false),
95 m_addr_range (range),
96 m_flags (flags),
97 m_function (NULL)
98{
99}
100
101Symbol::Symbol(const Symbol& rhs):
102 UserID (rhs),
103 m_mangled (rhs.m_mangled),
104 m_type (rhs.m_type),
105 m_type_data (rhs.m_type_data),
106 m_type_data_resolved (rhs.m_type_data_resolved),
107 m_is_synthetic (rhs.m_is_synthetic),
108 m_is_debug (rhs.m_is_debug),
109 m_is_external (rhs.m_is_external),
110 m_size_is_sibling (rhs.m_size_is_sibling),
111 m_size_is_synthesized (false),
112 m_searched_for_function (false),
113 m_addr_range (rhs.m_addr_range),
114 m_flags (rhs.m_flags),
115 m_function (NULL)
116{
117}
118
119const Symbol&
120Symbol::operator= (const Symbol& rhs)
121{
122 if (this != &rhs)
123 {
124 UserID::operator= (rhs);
125 m_mangled = rhs.m_mangled;
126 m_type = rhs.m_type;
127 m_type_data = rhs.m_type_data;
128 m_type_data_resolved = rhs.m_type_data_resolved;
129 m_is_synthetic = rhs.m_is_synthetic;
130 m_is_debug = rhs.m_is_debug;
131 m_is_external = rhs.m_is_external;
132 m_size_is_sibling = rhs.m_size_is_sibling;
133 m_size_is_synthesized = rhs.m_size_is_sibling;
134 m_searched_for_function = rhs.m_searched_for_function;
135 m_addr_range = rhs.m_addr_range;
136 m_flags = rhs.m_flags;
137 m_function = rhs.m_function;
138 }
139 return *this;
140}
141
142AddressRange &
143Symbol::GetAddressRangeRef()
144{
145 return m_addr_range;
146}
147
148const AddressRange &
149Symbol::GetAddressRangeRef() const
150{
151 return m_addr_range;
152}
153
154AddressRange *
155Symbol::GetAddressRangePtr()
156{
157 if (m_addr_range.GetBaseAddress().GetSection())
158 return &m_addr_range;
159 return NULL;
160}
161
162const AddressRange *
163Symbol::GetAddressRangePtr() const
164{
165 if (m_addr_range.GetBaseAddress().GetSection())
166 return &m_addr_range;
167 return NULL;
168}
169
170bool
171Symbol::GetSizeIsSibling() const
172{
173 return m_size_is_sibling;
174}
175
176bool
177Symbol::GetSizeIsSynthesized() const
178{
179 return m_size_is_synthesized;
180}
181
182uint32_t
183Symbol::GetSiblingIndex() const
184{
185 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
186}
187
188uint32_t
189Symbol::GetFlags() const
190{
191 return m_flags;
192}
193
194void
195Symbol::SetFlags (uint32_t flags)
196{
197 m_flags = flags;
198}
199
200SymbolType
201Symbol::GetType() const
202{
203 return m_type;
204}
205
206void
207Symbol::SetType(SymbolType type)
208{
209 m_type = type;
210}
211
212bool
213Symbol::IsSynthetic () const
214{
215 return m_is_synthetic;
216}
217
218void
219Symbol::SetIsSynthetic (bool b)
220{
221 m_is_synthetic = b;
222}
223
224void
225Symbol::SetSizeIsSynthesized(bool b)
226{
227 m_size_is_synthesized = b;
228}
229
230
231bool
232Symbol::IsDebug() const
233{
234 return m_is_debug;
235}
236
237void
238Symbol::SetDebug (bool b)
239{
240 m_is_debug = b;
241}
242
243bool
244Symbol::IsExternal() const
245{
246 return m_is_external;
247}
248
249void
250Symbol::SetExternal(bool b)
251{
252 m_is_external = b;
253}
254
255bool
256Symbol::IsTrampoline () const
257{
258 return m_type == eSymbolTypeTrampoline;
259}
260
261uint32_t
262Symbol::GetByteSize() const
263{
264 return m_addr_range.GetByteSize();
265}
266
267void
268Symbol::SetByteSize (uint32_t size)
269{
270 m_addr_range.SetByteSize(size);
271}
272
273void
274Symbol::SetSizeIsSibling (bool b)
275{
276 m_size_is_sibling = b;
277}
278
279void
280Symbol::Dump(Stream *s, Process *process, uint32_t index) const
281{
282// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
283// s->Indent();
284// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
285 s->Printf("[%5u] %6u %c%c%c %-12s ",
286 index,
287 GetID(),
288 m_is_debug ? 'D' : ' ',
289 m_is_synthetic ? 'S' : ' ',
290 m_is_external ? 'X' : ' ',
291 GetTypeAsString());
292
293 const Section *section = m_addr_range.GetBaseAddress().GetSection();
294 if (section != NULL)
295 {
296 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
297 s->Printf("%*s", 18, "");
298
299 s->PutChar(' ');
300
301 if (!m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress))
302 s->Printf("%*s", 18, "");
303
304 const char *format = m_size_is_sibling ?
305 " Sibling -> [%5llu] 0x%8.8x %s\n":
306 " 0x%16.16llx 0x%8.8x %s\n";
307 s->Printf( format,
308 m_addr_range.GetByteSize(),
309 m_flags,
310 m_mangled.GetName().AsCString(""));
311 }
312 else
313 {
314 const char *format = m_size_is_sibling ?
315 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
316 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
317 s->Printf( format,
318 m_addr_range.GetBaseAddress().GetOffset(),
319 m_addr_range.GetByteSize(),
320 m_flags,
321 m_mangled.GetName().AsCString(""));
322 }
323}
324
325const Mangled&
326Symbol::GetMangled() const
327{
328 return m_mangled;
329}
330
331Mangled&
332Symbol::GetMangled()
333{
334 return m_mangled;
335}
336
337Address &
338Symbol::GetValue()
339{
340 return m_addr_range.GetBaseAddress();
341}
342
343const Address &
344Symbol::GetValue() const
345{
346 return m_addr_range.GetBaseAddress();
347}
348
349void
350Symbol::SetValue (Address &value)
351{
352 m_addr_range.GetBaseAddress() = value;
353}
354
355Function *
356Symbol::GetFunction ()
357{
358 if (m_function == NULL && !m_searched_for_function)
359 {
360 m_searched_for_function = true;
361 Module *module = m_addr_range.GetBaseAddress().GetModule();
362 if (module)
363 {
364 SymbolContext sc;
365 if (module->ResolveSymbolContextForAddress(m_addr_range.GetBaseAddress(), eSymbolContextFunction, sc))
366 m_function = sc.function;
367 }
368 }
369 return m_function;
370}
371
372uint32_t
373Symbol::GetPrologueByteSize ()
374{
375 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeFunction)
376 {
377 if (!m_type_data_resolved)
378 {
379 m_type_data_resolved = true;
380 Module *module = m_addr_range.GetBaseAddress().GetModule();
381 SymbolContext sc;
382 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
383 eSymbolContextLineEntry,
384 sc))
385 {
386 m_type_data = sc.line_entry.range.GetByteSize();
387 }
388 else
389 {
390 // TODO: expose something in Process to figure out the
391 // size of a function prologue.
392 }
393 }
394 return m_type_data;
395 }
396 return 0;
397}
398
399void
400Symbol::SetValue (const AddressRange &range)
401{
402 m_addr_range = range;
403}
404
405
406void
407Symbol::SetValue(addr_t value)
408{
409 m_addr_range.GetBaseAddress().SetSection(NULL);
410 m_addr_range.GetBaseAddress().SetOffset(value);
411}
412
413
414bool
415Symbol::Compare(const ConstString& name, SymbolType type) const
416{
417 if (m_type == eSymbolTypeAny || m_type == type)
418 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
419 return false;
420}
421
422#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
423
424const char *
425Symbol::GetTypeAsString() const
426{
427 switch (m_type)
428 {
429 ENUM_TO_CSTRING(Invalid);
430 ENUM_TO_CSTRING(Absolute);
431 ENUM_TO_CSTRING(Extern);
432 ENUM_TO_CSTRING(Code);
433 ENUM_TO_CSTRING(Data);
434 ENUM_TO_CSTRING(Trampoline);
435 ENUM_TO_CSTRING(Runtime);
436 ENUM_TO_CSTRING(Exception);
437 ENUM_TO_CSTRING(SourceFile);
438 ENUM_TO_CSTRING(HeaderFile);
439 ENUM_TO_CSTRING(ObjectFile);
440 ENUM_TO_CSTRING(Function);
441 ENUM_TO_CSTRING(FunctionEnd);
442 ENUM_TO_CSTRING(CommonBlock);
443 ENUM_TO_CSTRING(Block);
444 ENUM_TO_CSTRING(Static);
445 ENUM_TO_CSTRING(Global);
446 ENUM_TO_CSTRING(Local);
447 ENUM_TO_CSTRING(Param);
448 ENUM_TO_CSTRING(Variable);
449 ENUM_TO_CSTRING(VariableType);
450 ENUM_TO_CSTRING(LineEntry);
451 ENUM_TO_CSTRING(LineHeader);
452 ENUM_TO_CSTRING(ScopeBegin);
453 ENUM_TO_CSTRING(ScopeEnd);
454 ENUM_TO_CSTRING(Additional);
455 ENUM_TO_CSTRING(Compiler);
456 ENUM_TO_CSTRING(Instrumentation);
457 ENUM_TO_CSTRING(Undefined);
458 default:
459 break;
460 }
461 return "<unknown SymbolType>";
462}
463