blob: 7ea719300bb66149674b3d9c80a3c0e4a3688f23 [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{
178 *s << '"' << m_mangled.GetName() << "\", id = " << (const UserID&)*this;
179 const Section *section = m_addr_range.GetBaseAddress().GetSection();
180 if (section != NULL)
181 {
182 if (m_addr_range.GetByteSize() > 0)
183 {
184 s->PutCString(", range = ");
185 m_addr_range.Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
186 }
187 else
188 {
189 s->PutCString(", address = ");
190 m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
191 }
192 }
193}
194
195void
Chris Lattner24943d22010-06-08 16:52:24 +0000196Symbol::Dump(Stream *s, Process *process, uint32_t index) const
197{
198// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
199// s->Indent();
200// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
201 s->Printf("[%5u] %6u %c%c%c %-12s ",
202 index,
203 GetID(),
204 m_is_debug ? 'D' : ' ',
205 m_is_synthetic ? 'S' : ' ',
206 m_is_external ? 'X' : ' ',
207 GetTypeAsString());
208
209 const Section *section = m_addr_range.GetBaseAddress().GetSection();
210 if (section != NULL)
211 {
212 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
213 s->Printf("%*s", 18, "");
214
215 s->PutChar(' ');
216
217 if (!m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress))
218 s->Printf("%*s", 18, "");
219
220 const char *format = m_size_is_sibling ?
221 " Sibling -> [%5llu] 0x%8.8x %s\n":
222 " 0x%16.16llx 0x%8.8x %s\n";
223 s->Printf( format,
224 m_addr_range.GetByteSize(),
225 m_flags,
226 m_mangled.GetName().AsCString(""));
227 }
228 else
229 {
230 const char *format = m_size_is_sibling ?
231 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
232 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
233 s->Printf( format,
234 m_addr_range.GetBaseAddress().GetOffset(),
235 m_addr_range.GetByteSize(),
236 m_flags,
237 m_mangled.GetName().AsCString(""));
238 }
239}
240
Chris Lattner24943d22010-06-08 16:52:24 +0000241Function *
242Symbol::GetFunction ()
243{
244 if (m_function == NULL && !m_searched_for_function)
245 {
246 m_searched_for_function = true;
247 Module *module = m_addr_range.GetBaseAddress().GetModule();
248 if (module)
249 {
250 SymbolContext sc;
251 if (module->ResolveSymbolContextForAddress(m_addr_range.GetBaseAddress(), eSymbolContextFunction, sc))
252 m_function = sc.function;
253 }
254 }
255 return m_function;
256}
257
258uint32_t
259Symbol::GetPrologueByteSize ()
260{
261 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeFunction)
262 {
263 if (!m_type_data_resolved)
264 {
265 m_type_data_resolved = true;
266 Module *module = m_addr_range.GetBaseAddress().GetModule();
267 SymbolContext sc;
268 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
269 eSymbolContextLineEntry,
270 sc))
271 {
272 m_type_data = sc.line_entry.range.GetByteSize();
273 }
274 else
275 {
276 // TODO: expose something in Process to figure out the
277 // size of a function prologue.
278 }
279 }
280 return m_type_data;
281 }
282 return 0;
283}
284
285void
Chris Lattner24943d22010-06-08 16:52:24 +0000286Symbol::SetValue(addr_t value)
287{
288 m_addr_range.GetBaseAddress().SetSection(NULL);
289 m_addr_range.GetBaseAddress().SetOffset(value);
290}
291
292
293bool
294Symbol::Compare(const ConstString& name, SymbolType type) const
295{
296 if (m_type == eSymbolTypeAny || m_type == type)
297 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
298 return false;
299}
300
301#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
302
303const char *
304Symbol::GetTypeAsString() const
305{
306 switch (m_type)
307 {
308 ENUM_TO_CSTRING(Invalid);
309 ENUM_TO_CSTRING(Absolute);
310 ENUM_TO_CSTRING(Extern);
311 ENUM_TO_CSTRING(Code);
312 ENUM_TO_CSTRING(Data);
313 ENUM_TO_CSTRING(Trampoline);
314 ENUM_TO_CSTRING(Runtime);
315 ENUM_TO_CSTRING(Exception);
316 ENUM_TO_CSTRING(SourceFile);
317 ENUM_TO_CSTRING(HeaderFile);
318 ENUM_TO_CSTRING(ObjectFile);
319 ENUM_TO_CSTRING(Function);
320 ENUM_TO_CSTRING(FunctionEnd);
321 ENUM_TO_CSTRING(CommonBlock);
322 ENUM_TO_CSTRING(Block);
323 ENUM_TO_CSTRING(Static);
324 ENUM_TO_CSTRING(Global);
325 ENUM_TO_CSTRING(Local);
326 ENUM_TO_CSTRING(Param);
327 ENUM_TO_CSTRING(Variable);
328 ENUM_TO_CSTRING(VariableType);
329 ENUM_TO_CSTRING(LineEntry);
330 ENUM_TO_CSTRING(LineHeader);
331 ENUM_TO_CSTRING(ScopeBegin);
332 ENUM_TO_CSTRING(ScopeEnd);
333 ENUM_TO_CSTRING(Additional);
334 ENUM_TO_CSTRING(Compiler);
335 ENUM_TO_CSTRING(Instrumentation);
336 ENUM_TO_CSTRING(Undefined);
337 default:
338 break;
339 }
340 return "<unknown SymbolType>";
341}
342
Greg Clayton4fb08152010-08-30 18:11:35 +0000343
344void
345Symbol::CalculateSymbolContext (SymbolContext *sc)
346{
347 // Symbols can reconstruct the symbol and the module in the symbol context
348 sc->symbol = this;
349 const AddressRange *range = GetAddressRangePtr();
350 if (range)
351 {
352 Module *module = range->GetBaseAddress().GetModule ();
353 if (module)
354 {
355 sc->module_sp = module->GetSP();
356 return;
357 }
358 }
359 sc->module_sp.reset();
360}
361
362void
363Symbol::DumpSymbolContext (Stream *s)
364{
365 bool dumped_module = false;
366 const AddressRange *range = GetAddressRangePtr();
367 if (range)
368 {
369 Module *module = range->GetBaseAddress().GetModule ();
370 if (module)
371 {
372 dumped_module = true;
373 module->DumpSymbolContext(s);
374 }
375 }
376 if (dumped_module)
377 s->PutCString(", ");
378
379 s->Printf("Symbol{0x%8.8x}", GetID());
380}
381
382