blob: c1d032c0b3799fb077fc8fb5026621d69aee42bc [file] [log] [blame]
Chris Lattner30fdc8d2010-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"
Greg Clayton9191db42013-10-21 18:40:51 +000013#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "lldb/Core/Section.h"
15#include "lldb/Core/Stream.h"
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Symbol/ObjectFile.h"
17#include "lldb/Symbol/Symtab.h"
Michael Sartainbf43d1a2013-07-03 16:35:41 +000018#include "lldb/Symbol/Function.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Target/Process.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000020#include "lldb/Target/Target.h"
Michael Sartaina7499c92013-07-01 19:45:50 +000021#include "lldb/Symbol/SymbolVendor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
26
27Symbol::Symbol() :
Stephen Wilson71c21d12011-04-11 19:41:40 +000028 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000029 m_uid (UINT32_MAX),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030 m_type_data (0),
31 m_type_data_resolved (false),
32 m_is_synthetic (false),
33 m_is_debug (false),
34 m_is_external (false),
35 m_size_is_sibling (false),
36 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +000037 m_size_is_valid (false),
Greg Clayton3d51b9f2012-11-27 01:52:16 +000038 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +000039 m_type (eSymbolTypeInvalid),
Greg Claytond8c3d4b2013-06-19 21:50:28 +000040 m_mangled (),
41 m_addr_range (),
42 m_flags ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043{
44}
45
46Symbol::Symbol
47(
Greg Clayton81c22f62011-10-19 18:09:39 +000048 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049 const char *name,
50 bool name_is_mangled,
51 SymbolType type,
52 bool external,
53 bool is_debug,
54 bool is_trampoline,
55 bool is_artificial,
Greg Claytone72dfb32012-02-24 01:59:29 +000056 const lldb::SectionSP &section_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057 addr_t offset,
Greg Claytonc7bece562013-01-25 18:06:21 +000058 addr_t size,
Greg Clayton9594f4c2013-04-13 23:17:23 +000059 bool size_is_valid,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060 uint32_t flags
61) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000062 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000063 m_uid (symID),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064 m_type_data (0),
65 m_type_data_resolved (false),
66 m_is_synthetic (is_artificial),
67 m_is_debug (is_debug),
68 m_is_external (external),
69 m_size_is_sibling (false),
70 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +000071 m_size_is_valid (size_is_valid || size > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +000072 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +000073 m_type (type),
Greg Claytond8c3d4b2013-06-19 21:50:28 +000074 m_mangled (ConstString(name), name_is_mangled),
75 m_addr_range (section_sp, offset, size),
76 m_flags (flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077{
78}
79
80Symbol::Symbol
81(
Greg Clayton81c22f62011-10-19 18:09:39 +000082 uint32_t symID,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083 const char *name,
84 bool name_is_mangled,
85 SymbolType type,
86 bool external,
87 bool is_debug,
88 bool is_trampoline,
89 bool is_artificial,
90 const AddressRange &range,
Greg Clayton9594f4c2013-04-13 23:17:23 +000091 bool size_is_valid,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092 uint32_t flags
93) :
Stephen Wilson71c21d12011-04-11 19:41:40 +000094 SymbolContextScope (),
Greg Clayton81c22f62011-10-19 18:09:39 +000095 m_uid (symID),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096 m_type_data (0),
97 m_type_data_resolved (false),
98 m_is_synthetic (is_artificial),
99 m_is_debug (is_debug),
100 m_is_external (external),
101 m_size_is_sibling (false),
102 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +0000103 m_size_is_valid (size_is_valid || range.GetByteSize() > 0),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000104 m_demangled_is_synthesized (false),
Greg Clayton01575f82011-11-22 21:20:33 +0000105 m_type (type),
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000106 m_mangled (ConstString(name), name_is_mangled),
107 m_addr_range (range),
108 m_flags (flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109{
110}
111
112Symbol::Symbol(const Symbol& rhs):
Stephen Wilson71c21d12011-04-11 19:41:40 +0000113 SymbolContextScope (rhs),
Greg Clayton81c22f62011-10-19 18:09:39 +0000114 m_uid (rhs.m_uid),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115 m_type_data (rhs.m_type_data),
116 m_type_data_resolved (rhs.m_type_data_resolved),
117 m_is_synthetic (rhs.m_is_synthetic),
118 m_is_debug (rhs.m_is_debug),
119 m_is_external (rhs.m_is_external),
120 m_size_is_sibling (rhs.m_size_is_sibling),
121 m_size_is_synthesized (false),
Greg Clayton3046e662013-07-10 01:23:25 +0000122 m_size_is_valid (rhs.m_size_is_valid),
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000123 m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
Greg Clayton01575f82011-11-22 21:20:33 +0000124 m_type (rhs.m_type),
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000125 m_mangled (rhs.m_mangled),
126 m_addr_range (rhs.m_addr_range),
127 m_flags (rhs.m_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128{
129}
130
131const Symbol&
132Symbol::operator= (const Symbol& rhs)
133{
134 if (this != &rhs)
135 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000136 SymbolContextScope::operator= (rhs);
Greg Clayton81c22f62011-10-19 18:09:39 +0000137 m_uid = rhs.m_uid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000138 m_type_data = rhs.m_type_data;
139 m_type_data_resolved = rhs.m_type_data_resolved;
140 m_is_synthetic = rhs.m_is_synthetic;
141 m_is_debug = rhs.m_is_debug;
142 m_is_external = rhs.m_is_external;
143 m_size_is_sibling = rhs.m_size_is_sibling;
144 m_size_is_synthesized = rhs.m_size_is_sibling;
Greg Clayton3046e662013-07-10 01:23:25 +0000145 m_size_is_valid = rhs.m_size_is_valid;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000146 m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
Greg Clayton01575f82011-11-22 21:20:33 +0000147 m_type = rhs.m_type;
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000148 m_mangled = rhs.m_mangled;
Greg Clayton01575f82011-11-22 21:20:33 +0000149 m_addr_range = rhs.m_addr_range;
Greg Claytond8c3d4b2013-06-19 21:50:28 +0000150 m_flags = rhs.m_flags;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151 }
152 return *this;
153}
154
Greg Clayton81c22f62011-10-19 18:09:39 +0000155void
156Symbol::Clear()
157{
158 m_uid = UINT32_MAX;
159 m_mangled.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000160 m_type_data = 0;
161 m_type_data_resolved = false;
162 m_is_synthetic = false;
163 m_is_debug = false;
164 m_is_external = false;
165 m_size_is_sibling = false;
166 m_size_is_synthesized = false;
Greg Clayton3046e662013-07-10 01:23:25 +0000167 m_size_is_valid = false;
Greg Clayton3d51b9f2012-11-27 01:52:16 +0000168 m_demangled_is_synthesized = false;
Greg Clayton01575f82011-11-22 21:20:33 +0000169 m_type = eSymbolTypeInvalid;
Greg Clayton81c22f62011-10-19 18:09:39 +0000170 m_flags = 0;
Greg Clayton01575f82011-11-22 21:20:33 +0000171 m_addr_range.Clear();
Greg Clayton81c22f62011-10-19 18:09:39 +0000172}
173
Greg Claytone7612132012-03-07 21:03:09 +0000174bool
175Symbol::ValueIsAddress() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176{
Ed Masted4612ad2014-04-20 13:17:36 +0000177 return m_addr_range.GetBaseAddress().GetSection().get() != nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178}
179
Greg Clayton9191db42013-10-21 18:40:51 +0000180ConstString
181Symbol::GetReExportedSymbolName() const
182{
183 if (m_type == eSymbolTypeReExported)
184 {
185 // For eSymbolTypeReExported, the "const char *" from a ConstString
186 // is used as the offset in the address range base address. We can
187 // then make this back into a string that is the re-exported name.
188 intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
189 if (str_ptr != 0)
190 return ConstString((const char *)str_ptr);
191 else
192 return GetName();
193 }
194 return ConstString();
195}
196
197FileSpec
198Symbol::GetReExportedSymbolSharedLibrary() const
199{
200 if (m_type == eSymbolTypeReExported)
201 {
202 // For eSymbolTypeReExported, the "const char *" from a ConstString
203 // is used as the offset in the address range base address. We can
204 // then make this back into a string that is the re-exported name.
205 intptr_t str_ptr = m_addr_range.GetByteSize();
206 if (str_ptr != 0)
207 return FileSpec((const char *)str_ptr, false);
208 }
209 return FileSpec();
210}
211
Greg Clayton60038be2015-02-14 00:51:13 +0000212void
Greg Clayton9191db42013-10-21 18:40:51 +0000213Symbol::SetReExportedSymbolName(const ConstString &name)
214{
Greg Clayton60038be2015-02-14 00:51:13 +0000215 SetType (eSymbolTypeReExported);
216 // For eSymbolTypeReExported, the "const char *" from a ConstString
217 // is used as the offset in the address range base address.
218 m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +0000219}
220
221bool
222Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
223{
224 if (m_type == eSymbolTypeReExported)
225 {
226 // For eSymbolTypeReExported, the "const char *" from a ConstString
227 // is used as the offset in the address range base address.
Greg Clayton60038be2015-02-14 00:51:13 +0000228 m_addr_range.SetByteSize((uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +0000229 return true;
230 }
231 return false;
232
233}
234
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235uint32_t
236Symbol::GetSiblingIndex() const
237{
238 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
239}
240
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241bool
242Symbol::IsTrampoline () const
243{
244 return m_type == eSymbolTypeTrampoline;
245}
246
Matt Kopec00049b82013-02-27 20:13:38 +0000247bool
248Symbol::IsIndirect () const
249{
250 return m_type == eSymbolTypeResolver;
251}
252
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000254Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000255{
Greg Claytonc4a8a762012-05-15 18:43:44 +0000256 s->Printf("id = {0x%8.8x}", m_uid);
Greg Claytond9dc52d2011-09-24 05:04:40 +0000257
Greg Claytone72dfb32012-02-24 01:59:29 +0000258 if (m_addr_range.GetBaseAddress().GetSection())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000259 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000260 if (ValueIsAddress())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000261 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000262 const lldb::addr_t byte_size = GetByteSize();
263 if (byte_size > 0)
Greg Claytonc9800662010-09-10 01:30:46 +0000264 {
265 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000266 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000267 }
268 else
269 {
270 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000271 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000272 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000273 }
274 else
Daniel Malead01b2952012-11-29 21:49:15 +0000275 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000276 }
277 else
278 {
279 if (m_size_is_sibling)
Daniel Malead01b2952012-11-29 21:49:15 +0000280 s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000281 else
Daniel Malead01b2952012-11-29 21:49:15 +0000282 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000283 }
Greg Clayton6b2bd932012-02-01 08:09:32 +0000284 if (m_mangled.GetDemangledName())
285 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
286 if (m_mangled.GetMangledName())
287 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
288
Greg Clayton0c5cd902010-06-28 21:30:43 +0000289}
290
291void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000292Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293{
Greg Clayton2d9ce192015-02-25 17:22:05 +0000294 s->Printf("[%5u] %6u %c%c%c %-15s ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295 index,
296 GetID(),
297 m_is_debug ? 'D' : ' ',
298 m_is_synthetic ? 'S' : ' ',
299 m_is_external ? 'X' : ' ',
300 GetTypeAsString());
301
Greg Claytone7612132012-03-07 21:03:09 +0000302 // Make sure the size of the symbol is up to date before dumping
303 GetByteSize();
304
305 if (ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306 {
Ed Masted4612ad2014-04-20 13:17:36 +0000307 if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308 s->Printf("%*s", 18, "");
309
310 s->PutChar(' ');
311
Greg Claytonf5e56de2010-09-14 23:36:40 +0000312 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 s->Printf("%*s", 18, "");
314
315 const char *format = m_size_is_sibling ?
316 " Sibling -> [%5llu] 0x%8.8x %s\n":
Daniel Malead01b2952012-11-29 21:49:15 +0000317 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 s->Printf( format,
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000319 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000320 m_flags,
321 m_mangled.GetName().AsCString(""));
322 }
Greg Clayton9191db42013-10-21 18:40:51 +0000323 else if (m_type == eSymbolTypeReExported)
324 {
325 s->Printf (" 0x%8.8x %s",
326 m_flags,
327 m_mangled.GetName().AsCString(""));
328
329 ConstString reexport_name = GetReExportedSymbolName();
330 intptr_t shlib = m_addr_range.GetByteSize();
331 if (shlib)
332 s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
333 else
334 s->Printf(" -> %s\n", reexport_name.GetCString());
335 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 else
337 {
338 const char *format = m_size_is_sibling ?
Daniel Malead01b2952012-11-29 21:49:15 +0000339 "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n":
340 "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341 s->Printf( format,
342 m_addr_range.GetBaseAddress().GetOffset(),
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000343 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 m_flags,
345 m_mangled.GetName().AsCString(""));
346 }
347}
348
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349uint32_t
350Symbol::GetPrologueByteSize ()
351{
Matt Kopec00049b82013-02-27 20:13:38 +0000352 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 {
354 if (!m_type_data_resolved)
355 {
356 m_type_data_resolved = true;
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000357
358 const Address &base_address = m_addr_range.GetBaseAddress();
359 Function *function = base_address.CalculateSymbolContextFunction();
360 if (function)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000362 // Functions have line entries which can also potentially have end of prologue information.
363 // So if this symbol points to a function, use the prologue information from there.
364 m_type_data = function->GetPrologueByteSize();
365 }
366 else
367 {
368 ModuleSP module_sp (base_address.GetModule());
369 SymbolContext sc;
370 if (module_sp)
Michael Sartaina7499c92013-07-01 19:45:50 +0000371 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000372 uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (base_address,
373 eSymbolContextLineEntry,
374 sc);
375 if (resolved_flags & eSymbolContextLineEntry)
Michael Sartaina7499c92013-07-01 19:45:50 +0000376 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000377 // Default to the end of the first line entry.
378 m_type_data = sc.line_entry.range.GetByteSize();
Michael Sartaina7499c92013-07-01 19:45:50 +0000379
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000380 // Set address for next line.
381 Address addr (base_address);
382 addr.Slide (m_type_data);
383
384 // Check the first few instructions and look for one that has a line number that is
385 // different than the first entry. This is also done in Function::GetPrologueByteSize().
386 uint16_t total_offset = m_type_data;
387 for (int idx = 0; idx < 6; ++idx)
Michael Sartaina7499c92013-07-01 19:45:50 +0000388 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000389 SymbolContext sc_temp;
390 resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp);
391 // Make sure we got line number information...
392 if (!(resolved_flags & eSymbolContextLineEntry))
393 break;
394
395 // If this line number is different than our first one, use it and we're done.
396 if (sc_temp.line_entry.line != sc.line_entry.line)
397 {
398 m_type_data = total_offset;
399 break;
400 }
401
402 // Slide addr up to the next line address.
403 addr.Slide (sc_temp.line_entry.range.GetByteSize());
404 total_offset += sc_temp.line_entry.range.GetByteSize();
405 // If we've gone too far, bail out.
406 if (total_offset >= m_addr_range.GetByteSize())
407 break;
Michael Sartaina7499c92013-07-01 19:45:50 +0000408 }
409
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000410 // Sanity check - this may be a function in the middle of code that has debug information, but
411 // not for this symbol. So the line entries surrounding us won't lie inside our function.
412 // In that case, the line entry will be bigger than we are, so we do that quick check and
413 // if that is true, we just return 0.
414 if (m_type_data >= m_addr_range.GetByteSize())
415 m_type_data = 0;
Michael Sartaina7499c92013-07-01 19:45:50 +0000416 }
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000417 else
418 {
419 // TODO: expose something in Process to figure out the
420 // size of a function prologue.
Michael Sartaina7499c92013-07-01 19:45:50 +0000421 m_type_data = 0;
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000422 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000423 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424 }
425 }
426 return m_type_data;
427 }
428 return 0;
429}
430
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431bool
432Symbol::Compare(const ConstString& name, SymbolType type) const
433{
Jim Inghamc30ee562011-10-29 00:54:12 +0000434 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
436 return false;
437}
438
439#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
440
441const char *
442Symbol::GetTypeAsString() const
443{
444 switch (m_type)
445 {
446 ENUM_TO_CSTRING(Invalid);
447 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448 ENUM_TO_CSTRING(Code);
Greg Clayton9191db42013-10-21 18:40:51 +0000449 ENUM_TO_CSTRING(Resolver);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450 ENUM_TO_CSTRING(Data);
451 ENUM_TO_CSTRING(Trampoline);
452 ENUM_TO_CSTRING(Runtime);
453 ENUM_TO_CSTRING(Exception);
454 ENUM_TO_CSTRING(SourceFile);
455 ENUM_TO_CSTRING(HeaderFile);
456 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457 ENUM_TO_CSTRING(CommonBlock);
458 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 ENUM_TO_CSTRING(Local);
460 ENUM_TO_CSTRING(Param);
461 ENUM_TO_CSTRING(Variable);
462 ENUM_TO_CSTRING(VariableType);
463 ENUM_TO_CSTRING(LineEntry);
464 ENUM_TO_CSTRING(LineHeader);
465 ENUM_TO_CSTRING(ScopeBegin);
466 ENUM_TO_CSTRING(ScopeEnd);
467 ENUM_TO_CSTRING(Additional);
468 ENUM_TO_CSTRING(Compiler);
469 ENUM_TO_CSTRING(Instrumentation);
470 ENUM_TO_CSTRING(Undefined);
Greg Clayton456809c2011-12-03 02:30:59 +0000471 ENUM_TO_CSTRING(ObjCClass);
472 ENUM_TO_CSTRING(ObjCMetaClass);
473 ENUM_TO_CSTRING(ObjCIVar);
Greg Clayton9191db42013-10-21 18:40:51 +0000474 ENUM_TO_CSTRING(ReExported);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 default:
476 break;
477 }
478 return "<unknown SymbolType>";
479}
480
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000481void
482Symbol::CalculateSymbolContext (SymbolContext *sc)
483{
484 // Symbols can reconstruct the symbol and the module in the symbol context
485 sc->symbol = this;
Greg Claytone7612132012-03-07 21:03:09 +0000486 if (ValueIsAddress())
487 sc->module_sp = GetAddress().GetModule();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000488 else
489 sc->module_sp.reset();
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000490}
491
Greg Claytone72dfb32012-02-24 01:59:29 +0000492ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000493Symbol::CalculateSymbolContextModule ()
494{
Greg Claytone7612132012-03-07 21:03:09 +0000495 if (ValueIsAddress())
496 return GetAddress().GetModule();
Greg Claytone72dfb32012-02-24 01:59:29 +0000497 return ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000498}
499
500Symbol *
501Symbol::CalculateSymbolContextSymbol ()
502{
503 return this;
504}
505
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000506void
507Symbol::DumpSymbolContext (Stream *s)
508{
509 bool dumped_module = false;
Greg Claytone7612132012-03-07 21:03:09 +0000510 if (ValueIsAddress())
511 {
512 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000513 if (module_sp)
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000514 {
515 dumped_module = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000516 module_sp->DumpSymbolContext(s);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000517 }
518 }
519 if (dumped_module)
520 s->PutCString(", ");
521
522 s->Printf("Symbol{0x%8.8x}", GetID());
523}
524
Greg Claytonda171f12012-03-02 03:01:16 +0000525lldb::addr_t
526Symbol::GetByteSize () const
527{
Greg Clayton3046e662013-07-10 01:23:25 +0000528 return m_addr_range.GetByteSize();
Greg Claytonda171f12012-03-02 03:01:16 +0000529}
530
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000531
532Symbol *
533Symbol::ResolveReExportedSymbolInModuleSpec (Target &target,
534 ConstString &reexport_name,
535 ModuleSpec &module_spec,
Sean Callanan25ea6a12014-05-23 02:30:48 +0000536 ModuleList &seen_modules) const
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000537{
538 ModuleSP module_sp;
539 if (module_spec.GetFileSpec())
540 {
541 // Try searching for the module file spec first using the full path
542 module_sp = target.GetImages().FindFirstModule(module_spec);
543 if (!module_sp)
544 {
545 // Next try and find the module by basename in case environment
546 // variables or other runtime trickery causes shared libraries
547 // to be loaded from alternate paths
548 module_spec.GetFileSpec().GetDirectory().Clear();
549 module_sp = target.GetImages().FindFirstModule(module_spec);
550 }
551 }
552
553 if (module_sp)
554 {
555 // There should not be cycles in the reexport list, but we don't want to crash if there are so make sure
556 // we haven't seen this before:
557 if (!seen_modules.AppendIfNeeded(module_sp))
558 return nullptr;
559
560 lldb_private::SymbolContextList sc_list;
561 module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list);
562 const size_t num_scs = sc_list.GetSize();
563 if (num_scs > 0)
564 {
565 for (size_t i=0; i<num_scs; ++i)
566 {
567 lldb_private::SymbolContext sc;
568 if (sc_list.GetContextAtIndex(i, sc))
569 {
570 if (sc.symbol->IsExternal())
571 return sc.symbol;
572 }
573 }
574 }
575 // If we didn't find the symbol in this module, it may be because this module re-exports some
576 // whole other library. We have to search those as well:
577 seen_modules.Append(module_sp);
578
579 FileSpecList reexported_libraries = module_sp->GetObjectFile()->GetReExportedLibraries();
580 size_t num_reexported_libraries = reexported_libraries.GetSize();
581 for (size_t idx = 0; idx < num_reexported_libraries; idx++)
582 {
583 ModuleSpec reexported_module_spec;
584 reexported_module_spec.GetFileSpec() = reexported_libraries.GetFileSpecAtIndex(idx);
585 Symbol *result_symbol = ResolveReExportedSymbolInModuleSpec(target,
586 reexport_name,
587 reexported_module_spec,
588 seen_modules);
589 if (result_symbol)
590 return result_symbol;
591 }
592 }
593 return nullptr;
594}
595
Greg Clayton9191db42013-10-21 18:40:51 +0000596Symbol *
Sean Callanan25ea6a12014-05-23 02:30:48 +0000597Symbol::ResolveReExportedSymbol (Target &target) const
Greg Clayton9191db42013-10-21 18:40:51 +0000598{
599 ConstString reexport_name (GetReExportedSymbolName());
600 if (reexport_name)
601 {
602 ModuleSpec module_spec;
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000603 ModuleList seen_modules;
Greg Clayton9191db42013-10-21 18:40:51 +0000604 module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary();
605 if (module_spec.GetFileSpec())
606 {
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000607 return ResolveReExportedSymbolInModuleSpec(target, reexport_name, module_spec, seen_modules);
Greg Clayton9191db42013-10-21 18:40:51 +0000608 }
609 }
Ed Masted4612ad2014-04-20 13:17:36 +0000610 return nullptr;
Greg Clayton9191db42013-10-21 18:40:51 +0000611}
Greg Clayton44d93782014-01-27 23:43:24 +0000612
Sean Callanan25ea6a12014-05-23 02:30:48 +0000613lldb::addr_t
614Symbol::ResolveCallableAddress(Target &target) const
615{
616 if (GetType() == lldb::eSymbolTypeUndefined)
617 return LLDB_INVALID_ADDRESS;
618
619 Address func_so_addr;
620
Jason Molenda9aae9fc2014-10-15 03:05:38 +0000621 bool is_indirect = IsIndirect();
Sean Callanan25ea6a12014-05-23 02:30:48 +0000622 if (GetType() == eSymbolTypeReExported)
623 {
624 Symbol *reexported_symbol = ResolveReExportedSymbol(target);
625 if (reexported_symbol)
626 {
627 func_so_addr = reexported_symbol->GetAddress();
628 is_indirect = reexported_symbol->IsIndirect();
629 }
630 }
631 else
632 {
633 func_so_addr = GetAddress();
634 is_indirect = IsIndirect();
635 }
636
637 if (func_so_addr.IsValid())
638 {
639 if (!target.GetProcessSP() && is_indirect)
640 {
641 // can't resolve indirect symbols without calling a function...
642 return LLDB_INVALID_ADDRESS;
643 }
644
645 lldb::addr_t load_addr = func_so_addr.GetCallableLoadAddress (&target, is_indirect);
646
647 if (load_addr != LLDB_INVALID_ADDRESS)
648 {
649 return load_addr;
650 }
651 }
652
653 return LLDB_INVALID_ADDRESS;
654}
655
Greg Clayton44d93782014-01-27 23:43:24 +0000656
657lldb::DisassemblerSP
658Symbol::GetInstructions (const ExecutionContext &exe_ctx,
659 const char *flavor,
660 bool prefer_file_cache)
661{
662 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
663 if (module_sp)
664 {
665 const bool prefer_file_cache = false;
666 return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
Ed Masted4612ad2014-04-20 13:17:36 +0000667 nullptr,
Greg Clayton44d93782014-01-27 23:43:24 +0000668 flavor,
669 exe_ctx,
670 m_addr_range,
671 prefer_file_cache);
672 }
673 return lldb::DisassemblerSP();
674}
675
676bool
677Symbol::GetDisassembly (const ExecutionContext &exe_ctx,
678 const char *flavor,
679 bool prefer_file_cache,
680 Stream &strm)
681{
682 lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
683 if (disassembler_sp)
684 {
685 const bool show_address = true;
686 const bool show_bytes = false;
687 disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
688 return true;
689 }
690 return false;
691}