blob: 6c91dd41958b4a6ec90b796a25b5544bbc3d1711 [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
Chris Lattner24943d22010-06-08 16:52:24 +0000142AddressRange *
143Symbol::GetAddressRangePtr()
144{
145 if (m_addr_range.GetBaseAddress().GetSection())
146 return &m_addr_range;
147 return NULL;
148}
149
150const AddressRange *
151Symbol::GetAddressRangePtr() const
152{
153 if (m_addr_range.GetBaseAddress().GetSection())
154 return &m_addr_range;
155 return NULL;
156}
157
Chris Lattner24943d22010-06-08 16:52:24 +0000158uint32_t
159Symbol::GetSiblingIndex() const
160{
161 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
162}
163
Chris Lattner24943d22010-06-08 16:52:24 +0000164bool
165Symbol::IsTrampoline () const
166{
167 return m_type == eSymbolTypeTrampoline;
168}
169
Chris Lattner24943d22010-06-08 16:52:24 +0000170void
Greg Clayton12bec712010-06-28 21:30:43 +0000171Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Process *process) const
172{
173 *s << '"' << m_mangled.GetName() << "\", id = " << (const UserID&)*this;
174 const Section *section = m_addr_range.GetBaseAddress().GetSection();
175 if (section != NULL)
176 {
177 if (m_addr_range.GetByteSize() > 0)
178 {
179 s->PutCString(", range = ");
180 m_addr_range.Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
181 }
182 else
183 {
184 s->PutCString(", address = ");
185 m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
186 }
187 }
188}
189
190void
Chris Lattner24943d22010-06-08 16:52:24 +0000191Symbol::Dump(Stream *s, Process *process, uint32_t index) const
192{
193// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
194// s->Indent();
195// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
196 s->Printf("[%5u] %6u %c%c%c %-12s ",
197 index,
198 GetID(),
199 m_is_debug ? 'D' : ' ',
200 m_is_synthetic ? 'S' : ' ',
201 m_is_external ? 'X' : ' ',
202 GetTypeAsString());
203
204 const Section *section = m_addr_range.GetBaseAddress().GetSection();
205 if (section != NULL)
206 {
207 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
208 s->Printf("%*s", 18, "");
209
210 s->PutChar(' ');
211
212 if (!m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress))
213 s->Printf("%*s", 18, "");
214
215 const char *format = m_size_is_sibling ?
216 " Sibling -> [%5llu] 0x%8.8x %s\n":
217 " 0x%16.16llx 0x%8.8x %s\n";
218 s->Printf( format,
219 m_addr_range.GetByteSize(),
220 m_flags,
221 m_mangled.GetName().AsCString(""));
222 }
223 else
224 {
225 const char *format = m_size_is_sibling ?
226 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
227 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
228 s->Printf( format,
229 m_addr_range.GetBaseAddress().GetOffset(),
230 m_addr_range.GetByteSize(),
231 m_flags,
232 m_mangled.GetName().AsCString(""));
233 }
234}
235
Chris Lattner24943d22010-06-08 16:52:24 +0000236Function *
237Symbol::GetFunction ()
238{
239 if (m_function == NULL && !m_searched_for_function)
240 {
241 m_searched_for_function = true;
242 Module *module = m_addr_range.GetBaseAddress().GetModule();
243 if (module)
244 {
245 SymbolContext sc;
246 if (module->ResolveSymbolContextForAddress(m_addr_range.GetBaseAddress(), eSymbolContextFunction, sc))
247 m_function = sc.function;
248 }
249 }
250 return m_function;
251}
252
253uint32_t
254Symbol::GetPrologueByteSize ()
255{
256 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeFunction)
257 {
258 if (!m_type_data_resolved)
259 {
260 m_type_data_resolved = true;
261 Module *module = m_addr_range.GetBaseAddress().GetModule();
262 SymbolContext sc;
263 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
264 eSymbolContextLineEntry,
265 sc))
266 {
267 m_type_data = sc.line_entry.range.GetByteSize();
268 }
269 else
270 {
271 // TODO: expose something in Process to figure out the
272 // size of a function prologue.
273 }
274 }
275 return m_type_data;
276 }
277 return 0;
278}
279
280void
Chris Lattner24943d22010-06-08 16:52:24 +0000281Symbol::SetValue(addr_t value)
282{
283 m_addr_range.GetBaseAddress().SetSection(NULL);
284 m_addr_range.GetBaseAddress().SetOffset(value);
285}
286
287
288bool
289Symbol::Compare(const ConstString& name, SymbolType type) const
290{
291 if (m_type == eSymbolTypeAny || m_type == type)
292 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
293 return false;
294}
295
296#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
297
298const char *
299Symbol::GetTypeAsString() const
300{
301 switch (m_type)
302 {
303 ENUM_TO_CSTRING(Invalid);
304 ENUM_TO_CSTRING(Absolute);
305 ENUM_TO_CSTRING(Extern);
306 ENUM_TO_CSTRING(Code);
307 ENUM_TO_CSTRING(Data);
308 ENUM_TO_CSTRING(Trampoline);
309 ENUM_TO_CSTRING(Runtime);
310 ENUM_TO_CSTRING(Exception);
311 ENUM_TO_CSTRING(SourceFile);
312 ENUM_TO_CSTRING(HeaderFile);
313 ENUM_TO_CSTRING(ObjectFile);
314 ENUM_TO_CSTRING(Function);
315 ENUM_TO_CSTRING(FunctionEnd);
316 ENUM_TO_CSTRING(CommonBlock);
317 ENUM_TO_CSTRING(Block);
318 ENUM_TO_CSTRING(Static);
319 ENUM_TO_CSTRING(Global);
320 ENUM_TO_CSTRING(Local);
321 ENUM_TO_CSTRING(Param);
322 ENUM_TO_CSTRING(Variable);
323 ENUM_TO_CSTRING(VariableType);
324 ENUM_TO_CSTRING(LineEntry);
325 ENUM_TO_CSTRING(LineHeader);
326 ENUM_TO_CSTRING(ScopeBegin);
327 ENUM_TO_CSTRING(ScopeEnd);
328 ENUM_TO_CSTRING(Additional);
329 ENUM_TO_CSTRING(Compiler);
330 ENUM_TO_CSTRING(Instrumentation);
331 ENUM_TO_CSTRING(Undefined);
332 default:
333 break;
334 }
335 return "<unknown SymbolType>";
336}
337