blob: 880519955277eec194005010657a78890a53171f [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
212bool
213Symbol::SetReExportedSymbolName(const ConstString &name)
214{
215 if (m_type == eSymbolTypeReExported)
216 {
217 // For eSymbolTypeReExported, the "const char *" from a ConstString
218 // is used as the offset in the address range base address.
219 m_addr_range.GetBaseAddress().SetOffset((intptr_t)name.GetCString());
220 return true;
221 }
222 return false;
223
224}
225
226bool
227Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
228{
229 if (m_type == eSymbolTypeReExported)
230 {
231 // For eSymbolTypeReExported, the "const char *" from a ConstString
232 // is used as the offset in the address range base address.
233 m_addr_range.SetByteSize((intptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
234 return true;
235 }
236 return false;
237
238}
239
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240uint32_t
241Symbol::GetSiblingIndex() const
242{
243 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
244}
245
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246bool
247Symbol::IsTrampoline () const
248{
249 return m_type == eSymbolTypeTrampoline;
250}
251
Matt Kopec00049b82013-02-27 20:13:38 +0000252bool
253Symbol::IsIndirect () const
254{
255 return m_type == eSymbolTypeResolver;
256}
257
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000259Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
Greg Clayton0c5cd902010-06-28 21:30:43 +0000260{
Greg Claytonc4a8a762012-05-15 18:43:44 +0000261 s->Printf("id = {0x%8.8x}", m_uid);
Greg Claytond9dc52d2011-09-24 05:04:40 +0000262
Greg Claytone72dfb32012-02-24 01:59:29 +0000263 if (m_addr_range.GetBaseAddress().GetSection())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000264 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000265 if (ValueIsAddress())
Greg Clayton0c5cd902010-06-28 21:30:43 +0000266 {
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000267 const lldb::addr_t byte_size = GetByteSize();
268 if (byte_size > 0)
Greg Claytonc9800662010-09-10 01:30:46 +0000269 {
270 s->PutCString (", range = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000271 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000272 }
273 else
274 {
275 s->PutCString (", address = ");
Greg Claytonf5e56de2010-09-14 23:36:40 +0000276 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
Greg Claytonc9800662010-09-10 01:30:46 +0000277 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000278 }
279 else
Daniel Malead01b2952012-11-29 21:49:15 +0000280 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000281 }
282 else
283 {
284 if (m_size_is_sibling)
Daniel Malead01b2952012-11-29 21:49:15 +0000285 s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
Greg Claytond9dc52d2011-09-24 05:04:40 +0000286 else
Daniel Malead01b2952012-11-29 21:49:15 +0000287 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
Greg Clayton0c5cd902010-06-28 21:30:43 +0000288 }
Greg Clayton6b2bd932012-02-01 08:09:32 +0000289 if (m_mangled.GetDemangledName())
290 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
291 if (m_mangled.GetMangledName())
292 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
293
Greg Clayton0c5cd902010-06-28 21:30:43 +0000294}
295
296void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000297Symbol::Dump(Stream *s, Target *target, uint32_t index) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298{
299// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
300// s->Indent();
301// s->Printf("Symbol[%5u] %6u %c%c %-12s ",
302 s->Printf("[%5u] %6u %c%c%c %-12s ",
303 index,
304 GetID(),
305 m_is_debug ? 'D' : ' ',
306 m_is_synthetic ? 'S' : ' ',
307 m_is_external ? 'X' : ' ',
308 GetTypeAsString());
309
Greg Claytone7612132012-03-07 21:03:09 +0000310 // Make sure the size of the symbol is up to date before dumping
311 GetByteSize();
312
313 if (ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 {
Ed Masted4612ad2014-04-20 13:17:36 +0000315 if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 s->Printf("%*s", 18, "");
317
318 s->PutChar(' ');
319
Greg Claytonf5e56de2010-09-14 23:36:40 +0000320 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321 s->Printf("%*s", 18, "");
322
323 const char *format = m_size_is_sibling ?
324 " Sibling -> [%5llu] 0x%8.8x %s\n":
Daniel Malead01b2952012-11-29 21:49:15 +0000325 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326 s->Printf( format,
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000327 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 m_flags,
329 m_mangled.GetName().AsCString(""));
330 }
Greg Clayton9191db42013-10-21 18:40:51 +0000331 else if (m_type == eSymbolTypeReExported)
332 {
333 s->Printf (" 0x%8.8x %s",
334 m_flags,
335 m_mangled.GetName().AsCString(""));
336
337 ConstString reexport_name = GetReExportedSymbolName();
338 intptr_t shlib = m_addr_range.GetByteSize();
339 if (shlib)
340 s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
341 else
342 s->Printf(" -> %s\n", reexport_name.GetCString());
343 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 else
345 {
346 const char *format = m_size_is_sibling ?
Daniel Malead01b2952012-11-29 21:49:15 +0000347 "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n":
348 "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 s->Printf( format,
350 m_addr_range.GetBaseAddress().GetOffset(),
Greg Clayton8f89a7b2012-03-07 23:30:39 +0000351 GetByteSize(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352 m_flags,
353 m_mangled.GetName().AsCString(""));
354 }
355}
356
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357uint32_t
358Symbol::GetPrologueByteSize ()
359{
Matt Kopec00049b82013-02-27 20:13:38 +0000360 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 {
362 if (!m_type_data_resolved)
363 {
364 m_type_data_resolved = true;
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000365
366 const Address &base_address = m_addr_range.GetBaseAddress();
367 Function *function = base_address.CalculateSymbolContextFunction();
368 if (function)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000370 // Functions have line entries which can also potentially have end of prologue information.
371 // So if this symbol points to a function, use the prologue information from there.
372 m_type_data = function->GetPrologueByteSize();
373 }
374 else
375 {
376 ModuleSP module_sp (base_address.GetModule());
377 SymbolContext sc;
378 if (module_sp)
Michael Sartaina7499c92013-07-01 19:45:50 +0000379 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000380 uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (base_address,
381 eSymbolContextLineEntry,
382 sc);
383 if (resolved_flags & eSymbolContextLineEntry)
Michael Sartaina7499c92013-07-01 19:45:50 +0000384 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000385 // Default to the end of the first line entry.
386 m_type_data = sc.line_entry.range.GetByteSize();
Michael Sartaina7499c92013-07-01 19:45:50 +0000387
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000388 // Set address for next line.
389 Address addr (base_address);
390 addr.Slide (m_type_data);
391
392 // Check the first few instructions and look for one that has a line number that is
393 // different than the first entry. This is also done in Function::GetPrologueByteSize().
394 uint16_t total_offset = m_type_data;
395 for (int idx = 0; idx < 6; ++idx)
Michael Sartaina7499c92013-07-01 19:45:50 +0000396 {
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000397 SymbolContext sc_temp;
398 resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp);
399 // Make sure we got line number information...
400 if (!(resolved_flags & eSymbolContextLineEntry))
401 break;
402
403 // If this line number is different than our first one, use it and we're done.
404 if (sc_temp.line_entry.line != sc.line_entry.line)
405 {
406 m_type_data = total_offset;
407 break;
408 }
409
410 // Slide addr up to the next line address.
411 addr.Slide (sc_temp.line_entry.range.GetByteSize());
412 total_offset += sc_temp.line_entry.range.GetByteSize();
413 // If we've gone too far, bail out.
414 if (total_offset >= m_addr_range.GetByteSize())
415 break;
Michael Sartaina7499c92013-07-01 19:45:50 +0000416 }
417
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000418 // Sanity check - this may be a function in the middle of code that has debug information, but
419 // not for this symbol. So the line entries surrounding us won't lie inside our function.
420 // In that case, the line entry will be bigger than we are, so we do that quick check and
421 // if that is true, we just return 0.
422 if (m_type_data >= m_addr_range.GetByteSize())
423 m_type_data = 0;
Michael Sartaina7499c92013-07-01 19:45:50 +0000424 }
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000425 else
426 {
427 // TODO: expose something in Process to figure out the
428 // size of a function prologue.
Michael Sartaina7499c92013-07-01 19:45:50 +0000429 m_type_data = 0;
Michael Sartainbf43d1a2013-07-03 16:35:41 +0000430 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000431 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432 }
433 }
434 return m_type_data;
435 }
436 return 0;
437}
438
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439bool
440Symbol::Compare(const ConstString& name, SymbolType type) const
441{
Jim Inghamc30ee562011-10-29 00:54:12 +0000442 if (type == eSymbolTypeAny || m_type == type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
444 return false;
445}
446
447#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x;
448
449const char *
450Symbol::GetTypeAsString() const
451{
452 switch (m_type)
453 {
454 ENUM_TO_CSTRING(Invalid);
455 ENUM_TO_CSTRING(Absolute);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 ENUM_TO_CSTRING(Code);
Greg Clayton9191db42013-10-21 18:40:51 +0000457 ENUM_TO_CSTRING(Resolver);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458 ENUM_TO_CSTRING(Data);
459 ENUM_TO_CSTRING(Trampoline);
460 ENUM_TO_CSTRING(Runtime);
461 ENUM_TO_CSTRING(Exception);
462 ENUM_TO_CSTRING(SourceFile);
463 ENUM_TO_CSTRING(HeaderFile);
464 ENUM_TO_CSTRING(ObjectFile);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465 ENUM_TO_CSTRING(CommonBlock);
466 ENUM_TO_CSTRING(Block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 ENUM_TO_CSTRING(Local);
468 ENUM_TO_CSTRING(Param);
469 ENUM_TO_CSTRING(Variable);
470 ENUM_TO_CSTRING(VariableType);
471 ENUM_TO_CSTRING(LineEntry);
472 ENUM_TO_CSTRING(LineHeader);
473 ENUM_TO_CSTRING(ScopeBegin);
474 ENUM_TO_CSTRING(ScopeEnd);
475 ENUM_TO_CSTRING(Additional);
476 ENUM_TO_CSTRING(Compiler);
477 ENUM_TO_CSTRING(Instrumentation);
478 ENUM_TO_CSTRING(Undefined);
Greg Clayton456809c2011-12-03 02:30:59 +0000479 ENUM_TO_CSTRING(ObjCClass);
480 ENUM_TO_CSTRING(ObjCMetaClass);
481 ENUM_TO_CSTRING(ObjCIVar);
Greg Clayton9191db42013-10-21 18:40:51 +0000482 ENUM_TO_CSTRING(ReExported);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483 default:
484 break;
485 }
486 return "<unknown SymbolType>";
487}
488
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000489void
490Symbol::CalculateSymbolContext (SymbolContext *sc)
491{
492 // Symbols can reconstruct the symbol and the module in the symbol context
493 sc->symbol = this;
Greg Claytone7612132012-03-07 21:03:09 +0000494 if (ValueIsAddress())
495 sc->module_sp = GetAddress().GetModule();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000496 else
497 sc->module_sp.reset();
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000498}
499
Greg Claytone72dfb32012-02-24 01:59:29 +0000500ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000501Symbol::CalculateSymbolContextModule ()
502{
Greg Claytone7612132012-03-07 21:03:09 +0000503 if (ValueIsAddress())
504 return GetAddress().GetModule();
Greg Claytone72dfb32012-02-24 01:59:29 +0000505 return ModuleSP();
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000506}
507
508Symbol *
509Symbol::CalculateSymbolContextSymbol ()
510{
511 return this;
512}
513
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000514void
515Symbol::DumpSymbolContext (Stream *s)
516{
517 bool dumped_module = false;
Greg Claytone7612132012-03-07 21:03:09 +0000518 if (ValueIsAddress())
519 {
520 ModuleSP module_sp (GetAddress().GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000521 if (module_sp)
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000522 {
523 dumped_module = true;
Greg Claytone72dfb32012-02-24 01:59:29 +0000524 module_sp->DumpSymbolContext(s);
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000525 }
526 }
527 if (dumped_module)
528 s->PutCString(", ");
529
530 s->Printf("Symbol{0x%8.8x}", GetID());
531}
532
Greg Claytonda171f12012-03-02 03:01:16 +0000533lldb::addr_t
534Symbol::GetByteSize () const
535{
Greg Clayton3046e662013-07-10 01:23:25 +0000536 return m_addr_range.GetByteSize();
Greg Claytonda171f12012-03-02 03:01:16 +0000537}
538
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000539
540Symbol *
541Symbol::ResolveReExportedSymbolInModuleSpec (Target &target,
542 ConstString &reexport_name,
543 ModuleSpec &module_spec,
Sean Callanan25ea6a12014-05-23 02:30:48 +0000544 ModuleList &seen_modules) const
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000545{
546 ModuleSP module_sp;
547 if (module_spec.GetFileSpec())
548 {
549 // Try searching for the module file spec first using the full path
550 module_sp = target.GetImages().FindFirstModule(module_spec);
551 if (!module_sp)
552 {
553 // Next try and find the module by basename in case environment
554 // variables or other runtime trickery causes shared libraries
555 // to be loaded from alternate paths
556 module_spec.GetFileSpec().GetDirectory().Clear();
557 module_sp = target.GetImages().FindFirstModule(module_spec);
558 }
559 }
560
561 if (module_sp)
562 {
563 // There should not be cycles in the reexport list, but we don't want to crash if there are so make sure
564 // we haven't seen this before:
565 if (!seen_modules.AppendIfNeeded(module_sp))
566 return nullptr;
567
568 lldb_private::SymbolContextList sc_list;
569 module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list);
570 const size_t num_scs = sc_list.GetSize();
571 if (num_scs > 0)
572 {
573 for (size_t i=0; i<num_scs; ++i)
574 {
575 lldb_private::SymbolContext sc;
576 if (sc_list.GetContextAtIndex(i, sc))
577 {
578 if (sc.symbol->IsExternal())
579 return sc.symbol;
580 }
581 }
582 }
583 // If we didn't find the symbol in this module, it may be because this module re-exports some
584 // whole other library. We have to search those as well:
585 seen_modules.Append(module_sp);
586
587 FileSpecList reexported_libraries = module_sp->GetObjectFile()->GetReExportedLibraries();
588 size_t num_reexported_libraries = reexported_libraries.GetSize();
589 for (size_t idx = 0; idx < num_reexported_libraries; idx++)
590 {
591 ModuleSpec reexported_module_spec;
592 reexported_module_spec.GetFileSpec() = reexported_libraries.GetFileSpecAtIndex(idx);
593 Symbol *result_symbol = ResolveReExportedSymbolInModuleSpec(target,
594 reexport_name,
595 reexported_module_spec,
596 seen_modules);
597 if (result_symbol)
598 return result_symbol;
599 }
600 }
601 return nullptr;
602}
603
Greg Clayton9191db42013-10-21 18:40:51 +0000604Symbol *
Sean Callanan25ea6a12014-05-23 02:30:48 +0000605Symbol::ResolveReExportedSymbol (Target &target) const
Greg Clayton9191db42013-10-21 18:40:51 +0000606{
607 ConstString reexport_name (GetReExportedSymbolName());
608 if (reexport_name)
609 {
610 ModuleSpec module_spec;
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000611 ModuleList seen_modules;
Greg Clayton9191db42013-10-21 18:40:51 +0000612 module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary();
613 if (module_spec.GetFileSpec())
614 {
Jim Inghamfbe0b9a2014-05-21 03:58:03 +0000615 return ResolveReExportedSymbolInModuleSpec(target, reexport_name, module_spec, seen_modules);
Greg Clayton9191db42013-10-21 18:40:51 +0000616 }
617 }
Ed Masted4612ad2014-04-20 13:17:36 +0000618 return nullptr;
Greg Clayton9191db42013-10-21 18:40:51 +0000619}
Greg Clayton44d93782014-01-27 23:43:24 +0000620
Sean Callanan25ea6a12014-05-23 02:30:48 +0000621lldb::addr_t
622Symbol::ResolveCallableAddress(Target &target) const
623{
624 if (GetType() == lldb::eSymbolTypeUndefined)
625 return LLDB_INVALID_ADDRESS;
626
627 Address func_so_addr;
628
629 bool is_indirect;
630 if (GetType() == eSymbolTypeReExported)
631 {
632 Symbol *reexported_symbol = ResolveReExportedSymbol(target);
633 if (reexported_symbol)
634 {
635 func_so_addr = reexported_symbol->GetAddress();
636 is_indirect = reexported_symbol->IsIndirect();
637 }
638 }
639 else
640 {
641 func_so_addr = GetAddress();
642 is_indirect = IsIndirect();
643 }
644
645 if (func_so_addr.IsValid())
646 {
647 if (!target.GetProcessSP() && is_indirect)
648 {
649 // can't resolve indirect symbols without calling a function...
650 return LLDB_INVALID_ADDRESS;
651 }
652
653 lldb::addr_t load_addr = func_so_addr.GetCallableLoadAddress (&target, is_indirect);
654
655 if (load_addr != LLDB_INVALID_ADDRESS)
656 {
657 return load_addr;
658 }
659 }
660
661 return LLDB_INVALID_ADDRESS;
662}
663
Greg Clayton44d93782014-01-27 23:43:24 +0000664
665lldb::DisassemblerSP
666Symbol::GetInstructions (const ExecutionContext &exe_ctx,
667 const char *flavor,
668 bool prefer_file_cache)
669{
670 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
671 if (module_sp)
672 {
673 const bool prefer_file_cache = false;
674 return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
Ed Masted4612ad2014-04-20 13:17:36 +0000675 nullptr,
Greg Clayton44d93782014-01-27 23:43:24 +0000676 flavor,
677 exe_ctx,
678 m_addr_range,
679 prefer_file_cache);
680 }
681 return lldb::DisassemblerSP();
682}
683
684bool
685Symbol::GetDisassembly (const ExecutionContext &exe_ctx,
686 const char *flavor,
687 bool prefer_file_cache,
688 Stream &strm)
689{
690 lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
691 if (disassembler_sp)
692 {
693 const bool show_address = true;
694 const bool show_bytes = false;
695 disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
696 return true;
697 }
698 return false;
699}