1 //===-- 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 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 
21 Symbol::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 
39 Symbol::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 
71 Symbol::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 
101 Symbol::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 
119 const Symbol&
120 Symbol::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 
142 AddressRange &
143 Symbol::GetAddressRangeRef()
144 {
145     return m_addr_range;
146 }
147 
148 const AddressRange &
149 Symbol::GetAddressRangeRef() const
150 {
151     return m_addr_range;
152 }
153 
154 AddressRange *
155 Symbol::GetAddressRangePtr()
156 {
157     if (m_addr_range.GetBaseAddress().GetSection())
158         return &m_addr_range;
159     return NULL;
160 }
161 
162 const AddressRange *
163 Symbol::GetAddressRangePtr() const
164 {
165     if (m_addr_range.GetBaseAddress().GetSection())
166         return &m_addr_range;
167     return NULL;
168 }
169 
170 bool
171 Symbol::GetSizeIsSibling() const
172 {
173     return m_size_is_sibling;
174 }
175 
176 bool
177 Symbol::GetSizeIsSynthesized() const
178 {
179     return m_size_is_synthesized;
180 }
181 
182 uint32_t
183 Symbol::GetSiblingIndex() const
184 {
185     return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
186 }
187 
188 uint32_t
189 Symbol::GetFlags() const
190 {
191     return m_flags;
192 }
193 
194 void
195 Symbol::SetFlags (uint32_t flags)
196 {
197     m_flags = flags;
198 }
199 
200 SymbolType
201 Symbol::GetType() const
202 {
203     return m_type;
204 }
205 
206 void
207 Symbol::SetType(SymbolType type)
208 {
209     m_type = type;
210 }
211 
212 bool
213 Symbol::IsSynthetic () const
214 {
215     return m_is_synthetic;
216 }
217 
218 void
219 Symbol::SetIsSynthetic (bool b)
220 {
221     m_is_synthetic = b;
222 }
223 
224 void
225 Symbol::SetSizeIsSynthesized(bool b)
226 {
227     m_size_is_synthesized = b;
228 }
229 
230 
231 bool
232 Symbol::IsDebug() const
233 {
234     return m_is_debug;
235 }
236 
237 void
238 Symbol::SetDebug (bool b)
239 {
240     m_is_debug = b;
241 }
242 
243 bool
244 Symbol::IsExternal() const
245 {
246     return m_is_external;
247 }
248 
249 void
250 Symbol::SetExternal(bool b)
251 {
252     m_is_external = b;
253 }
254 
255 bool
256 Symbol::IsTrampoline () const
257 {
258     return m_type == eSymbolTypeTrampoline;
259 }
260 
261 uint32_t
262 Symbol::GetByteSize() const
263 {
264     return m_addr_range.GetByteSize();
265 }
266 
267 void
268 Symbol::SetByteSize (uint32_t size)
269 {
270     m_addr_range.SetByteSize(size);
271 }
272 
273 void
274 Symbol::SetSizeIsSibling (bool b)
275 {
276     m_size_is_sibling = b;
277 }
278 
279 void
280 Symbol::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 
325 const Mangled&
326 Symbol::GetMangled() const
327 {
328     return m_mangled;
329 }
330 
331 Mangled&
332 Symbol::GetMangled()
333 {
334     return m_mangled;
335 }
336 
337 Address &
338 Symbol::GetValue()
339 {
340     return m_addr_range.GetBaseAddress();
341 }
342 
343 const Address &
344 Symbol::GetValue() const
345 {
346     return m_addr_range.GetBaseAddress();
347 }
348 
349 void
350 Symbol::SetValue (Address &value)
351 {
352     m_addr_range.GetBaseAddress() = value;
353 }
354 
355 Function *
356 Symbol::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 
372 uint32_t
373 Symbol::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 
399 void
400 Symbol::SetValue (const AddressRange &range)
401 {
402     m_addr_range = range;
403 }
404 
405 
406 void
407 Symbol::SetValue(addr_t value)
408 {
409     m_addr_range.GetBaseAddress().SetSection(NULL);
410     m_addr_range.GetBaseAddress().SetOffset(value);
411 }
412 
413 
414 bool
415 Symbol::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 
424 const char *
425 Symbol::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 
464