1254721Semaste//===-- Symbol.cpp ----------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Symbol/Symbol.h"
11254721Semaste
12254721Semaste#include "lldb/Core/Module.h"
13263363Semaste#include "lldb/Core/ModuleSpec.h"
14254721Semaste#include "lldb/Core/Section.h"
15254721Semaste#include "lldb/Core/Stream.h"
16254721Semaste#include "lldb/Symbol/ObjectFile.h"
17254721Semaste#include "lldb/Symbol/Symtab.h"
18254721Semaste#include "lldb/Symbol/Function.h"
19254721Semaste#include "lldb/Target/Process.h"
20254721Semaste#include "lldb/Target/Target.h"
21254721Semaste#include "lldb/Symbol/SymbolVendor.h"
22254721Semaste
23254721Semasteusing namespace lldb;
24254721Semasteusing namespace lldb_private;
25254721Semaste
26254721Semaste
27254721SemasteSymbol::Symbol() :
28254721Semaste    SymbolContextScope (),
29254721Semaste    m_uid (UINT32_MAX),
30254721Semaste    m_type_data (0),
31254721Semaste    m_type_data_resolved (false),
32254721Semaste    m_is_synthetic (false),
33254721Semaste    m_is_debug (false),
34254721Semaste    m_is_external (false),
35254721Semaste    m_size_is_sibling (false),
36254721Semaste    m_size_is_synthesized (false),
37254721Semaste    m_size_is_valid (false),
38254721Semaste    m_demangled_is_synthesized (false),
39254721Semaste    m_type (eSymbolTypeInvalid),
40254721Semaste    m_mangled (),
41254721Semaste    m_addr_range (),
42254721Semaste    m_flags ()
43254721Semaste{
44254721Semaste}
45254721Semaste
46254721SemasteSymbol::Symbol
47254721Semaste(
48254721Semaste    uint32_t symID,
49254721Semaste    const char *name,
50254721Semaste    bool name_is_mangled,
51254721Semaste    SymbolType type,
52254721Semaste    bool external,
53254721Semaste    bool is_debug,
54254721Semaste    bool is_trampoline,
55254721Semaste    bool is_artificial,
56254721Semaste    const lldb::SectionSP &section_sp,
57254721Semaste    addr_t offset,
58254721Semaste    addr_t size,
59254721Semaste    bool size_is_valid,
60254721Semaste    uint32_t flags
61254721Semaste) :
62254721Semaste    SymbolContextScope (),
63254721Semaste    m_uid (symID),
64254721Semaste    m_type_data (0),
65254721Semaste    m_type_data_resolved (false),
66254721Semaste    m_is_synthetic (is_artificial),
67254721Semaste    m_is_debug (is_debug),
68254721Semaste    m_is_external (external),
69254721Semaste    m_size_is_sibling (false),
70254721Semaste    m_size_is_synthesized (false),
71254721Semaste    m_size_is_valid (size_is_valid || size > 0),
72254721Semaste    m_demangled_is_synthesized (false),
73254721Semaste    m_type (type),
74254721Semaste    m_mangled (ConstString(name), name_is_mangled),
75254721Semaste    m_addr_range (section_sp, offset, size),
76254721Semaste    m_flags (flags)
77254721Semaste{
78254721Semaste}
79254721Semaste
80254721SemasteSymbol::Symbol
81254721Semaste(
82254721Semaste    uint32_t symID,
83254721Semaste    const char *name,
84254721Semaste    bool name_is_mangled,
85254721Semaste    SymbolType type,
86254721Semaste    bool external,
87254721Semaste    bool is_debug,
88254721Semaste    bool is_trampoline,
89254721Semaste    bool is_artificial,
90254721Semaste    const AddressRange &range,
91254721Semaste    bool size_is_valid,
92254721Semaste    uint32_t flags
93254721Semaste) :
94254721Semaste    SymbolContextScope (),
95254721Semaste    m_uid (symID),
96254721Semaste    m_type_data (0),
97254721Semaste    m_type_data_resolved (false),
98254721Semaste    m_is_synthetic (is_artificial),
99254721Semaste    m_is_debug (is_debug),
100254721Semaste    m_is_external (external),
101254721Semaste    m_size_is_sibling (false),
102254721Semaste    m_size_is_synthesized (false),
103254721Semaste    m_size_is_valid (size_is_valid || range.GetByteSize() > 0),
104254721Semaste    m_demangled_is_synthesized (false),
105254721Semaste    m_type (type),
106254721Semaste    m_mangled (ConstString(name), name_is_mangled),
107254721Semaste    m_addr_range (range),
108254721Semaste    m_flags (flags)
109254721Semaste{
110254721Semaste}
111254721Semaste
112254721SemasteSymbol::Symbol(const Symbol& rhs):
113254721Semaste    SymbolContextScope (rhs),
114254721Semaste    m_uid (rhs.m_uid),
115254721Semaste    m_type_data (rhs.m_type_data),
116254721Semaste    m_type_data_resolved (rhs.m_type_data_resolved),
117254721Semaste    m_is_synthetic (rhs.m_is_synthetic),
118254721Semaste    m_is_debug (rhs.m_is_debug),
119254721Semaste    m_is_external (rhs.m_is_external),
120254721Semaste    m_size_is_sibling (rhs.m_size_is_sibling),
121254721Semaste    m_size_is_synthesized (false),
122254721Semaste    m_size_is_valid (rhs.m_size_is_valid),
123254721Semaste    m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
124254721Semaste    m_type (rhs.m_type),
125254721Semaste    m_mangled (rhs.m_mangled),
126254721Semaste    m_addr_range (rhs.m_addr_range),
127254721Semaste    m_flags (rhs.m_flags)
128254721Semaste{
129254721Semaste}
130254721Semaste
131254721Semasteconst Symbol&
132254721SemasteSymbol::operator= (const Symbol& rhs)
133254721Semaste{
134254721Semaste    if (this != &rhs)
135254721Semaste    {
136254721Semaste        SymbolContextScope::operator= (rhs);
137254721Semaste        m_uid = rhs.m_uid;
138254721Semaste        m_type_data = rhs.m_type_data;
139254721Semaste        m_type_data_resolved = rhs.m_type_data_resolved;
140254721Semaste        m_is_synthetic = rhs.m_is_synthetic;
141254721Semaste        m_is_debug = rhs.m_is_debug;
142254721Semaste        m_is_external = rhs.m_is_external;
143254721Semaste        m_size_is_sibling = rhs.m_size_is_sibling;
144254721Semaste        m_size_is_synthesized = rhs.m_size_is_sibling;
145254721Semaste        m_size_is_valid = rhs.m_size_is_valid;
146254721Semaste        m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
147254721Semaste        m_type = rhs.m_type;
148254721Semaste        m_mangled = rhs.m_mangled;
149254721Semaste        m_addr_range = rhs.m_addr_range;
150254721Semaste        m_flags = rhs.m_flags;
151254721Semaste    }
152254721Semaste    return *this;
153254721Semaste}
154254721Semaste
155254721Semastevoid
156254721SemasteSymbol::Clear()
157254721Semaste{
158254721Semaste    m_uid = UINT32_MAX;
159254721Semaste    m_mangled.Clear();
160254721Semaste    m_type_data = 0;
161254721Semaste    m_type_data_resolved = false;
162254721Semaste    m_is_synthetic = false;
163254721Semaste    m_is_debug = false;
164254721Semaste    m_is_external = false;
165254721Semaste    m_size_is_sibling = false;
166254721Semaste    m_size_is_synthesized = false;
167254721Semaste    m_size_is_valid = false;
168254721Semaste    m_demangled_is_synthesized = false;
169254721Semaste    m_type = eSymbolTypeInvalid;
170254721Semaste    m_flags = 0;
171254721Semaste    m_addr_range.Clear();
172254721Semaste}
173254721Semaste
174254721Semastebool
175254721SemasteSymbol::ValueIsAddress() const
176254721Semaste{
177254721Semaste    return m_addr_range.GetBaseAddress().GetSection().get() != NULL;
178254721Semaste}
179254721Semaste
180263363SemasteConstString
181263363SemasteSymbol::GetReExportedSymbolName() const
182263363Semaste{
183263363Semaste    if (m_type == eSymbolTypeReExported)
184263363Semaste    {
185263363Semaste        // For eSymbolTypeReExported, the "const char *" from a ConstString
186263363Semaste        // is used as the offset in the address range base address. We can
187263363Semaste        // then make this back into a string that is the re-exported name.
188263363Semaste        intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
189263363Semaste        if (str_ptr != 0)
190263363Semaste            return ConstString((const char *)str_ptr);
191263363Semaste        else
192263363Semaste            return GetName();
193263363Semaste    }
194263363Semaste    return ConstString();
195263363Semaste}
196263363Semaste
197263363SemasteFileSpec
198263363SemasteSymbol::GetReExportedSymbolSharedLibrary() const
199263363Semaste{
200263363Semaste    if (m_type == eSymbolTypeReExported)
201263363Semaste    {
202263363Semaste        // For eSymbolTypeReExported, the "const char *" from a ConstString
203263363Semaste        // is used as the offset in the address range base address. We can
204263363Semaste        // then make this back into a string that is the re-exported name.
205263363Semaste        intptr_t str_ptr = m_addr_range.GetByteSize();
206263363Semaste        if (str_ptr != 0)
207263363Semaste            return FileSpec((const char *)str_ptr, false);
208263363Semaste    }
209263363Semaste    return FileSpec();
210263363Semaste}
211263363Semaste
212263363Semastebool
213263363SemasteSymbol::SetReExportedSymbolName(const ConstString &name)
214263363Semaste{
215263363Semaste    if (m_type == eSymbolTypeReExported)
216263363Semaste    {
217263363Semaste        // For eSymbolTypeReExported, the "const char *" from a ConstString
218263363Semaste        // is used as the offset in the address range base address.
219263363Semaste        m_addr_range.GetBaseAddress().SetOffset((intptr_t)name.GetCString());
220263363Semaste        return true;
221263363Semaste    }
222263363Semaste    return false;
223263363Semaste
224263363Semaste}
225263363Semaste
226263363Semastebool
227263363SemasteSymbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
228263363Semaste{
229263363Semaste    if (m_type == eSymbolTypeReExported)
230263363Semaste    {
231263363Semaste        // For eSymbolTypeReExported, the "const char *" from a ConstString
232263363Semaste        // is used as the offset in the address range base address.
233263363Semaste        m_addr_range.SetByteSize((intptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
234263363Semaste        return true;
235263363Semaste    }
236263363Semaste    return false;
237263363Semaste
238263363Semaste}
239263363Semaste
240254721Semasteuint32_t
241254721SemasteSymbol::GetSiblingIndex() const
242254721Semaste{
243254721Semaste    return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
244254721Semaste}
245254721Semaste
246254721Semastebool
247254721SemasteSymbol::IsTrampoline () const
248254721Semaste{
249254721Semaste    return m_type == eSymbolTypeTrampoline;
250254721Semaste}
251254721Semaste
252254721Semastebool
253254721SemasteSymbol::IsIndirect () const
254254721Semaste{
255254721Semaste    return m_type == eSymbolTypeResolver;
256254721Semaste}
257254721Semaste
258254721Semastevoid
259254721SemasteSymbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
260254721Semaste{
261254721Semaste    s->Printf("id = {0x%8.8x}", m_uid);
262254721Semaste
263254721Semaste    if (m_addr_range.GetBaseAddress().GetSection())
264254721Semaste    {
265254721Semaste        if (ValueIsAddress())
266254721Semaste        {
267254721Semaste            const lldb::addr_t byte_size = GetByteSize();
268254721Semaste            if (byte_size > 0)
269254721Semaste            {
270254721Semaste                s->PutCString (", range = ");
271254721Semaste                m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
272254721Semaste            }
273254721Semaste            else
274254721Semaste            {
275254721Semaste                s->PutCString (", address = ");
276254721Semaste                m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
277254721Semaste            }
278254721Semaste        }
279254721Semaste        else
280254721Semaste            s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
281254721Semaste    }
282254721Semaste    else
283254721Semaste    {
284254721Semaste        if (m_size_is_sibling)
285254721Semaste            s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
286254721Semaste        else
287254721Semaste            s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
288254721Semaste    }
289254721Semaste    if (m_mangled.GetDemangledName())
290254721Semaste        s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
291254721Semaste    if (m_mangled.GetMangledName())
292254721Semaste        s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString());
293254721Semaste
294254721Semaste}
295254721Semaste
296254721Semastevoid
297254721SemasteSymbol::Dump(Stream *s, Target *target, uint32_t index) const
298254721Semaste{
299254721Semaste//  s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
300254721Semaste//  s->Indent();
301254721Semaste//  s->Printf("Symbol[%5u] %6u %c%c %-12s ",
302254721Semaste    s->Printf("[%5u] %6u %c%c%c %-12s ",
303254721Semaste              index,
304254721Semaste              GetID(),
305254721Semaste              m_is_debug ? 'D' : ' ',
306254721Semaste              m_is_synthetic ? 'S' : ' ',
307254721Semaste              m_is_external ? 'X' : ' ',
308254721Semaste              GetTypeAsString());
309254721Semaste
310254721Semaste    // Make sure the size of the symbol is up to date before dumping
311254721Semaste    GetByteSize();
312254721Semaste
313254721Semaste    if (ValueIsAddress())
314254721Semaste    {
315254721Semaste        if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress))
316254721Semaste            s->Printf("%*s", 18, "");
317254721Semaste
318254721Semaste        s->PutChar(' ');
319254721Semaste
320254721Semaste        if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress))
321254721Semaste            s->Printf("%*s", 18, "");
322254721Semaste
323254721Semaste        const char *format = m_size_is_sibling ?
324254721Semaste                            " Sibling -> [%5llu] 0x%8.8x %s\n":
325254721Semaste                            " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
326254721Semaste        s->Printf(  format,
327254721Semaste                    GetByteSize(),
328254721Semaste                    m_flags,
329254721Semaste                    m_mangled.GetName().AsCString(""));
330254721Semaste    }
331263363Semaste    else if (m_type == eSymbolTypeReExported)
332263363Semaste    {
333263363Semaste        s->Printf ("                                                         0x%8.8x %s",
334263363Semaste                   m_flags,
335263363Semaste                   m_mangled.GetName().AsCString(""));
336263363Semaste
337263363Semaste        ConstString reexport_name = GetReExportedSymbolName();
338263363Semaste        intptr_t shlib = m_addr_range.GetByteSize();
339263363Semaste        if (shlib)
340263363Semaste            s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
341263363Semaste        else
342263363Semaste            s->Printf(" -> %s\n", reexport_name.GetCString());
343263363Semaste    }
344254721Semaste    else
345254721Semaste    {
346254721Semaste        const char *format = m_size_is_sibling ?
347254721Semaste                            "0x%16.16" PRIx64 "                    Sibling -> [%5llu] 0x%8.8x %s\n":
348254721Semaste                            "0x%16.16" PRIx64 "                    0x%16.16" PRIx64 " 0x%8.8x %s\n";
349254721Semaste        s->Printf(  format,
350254721Semaste                    m_addr_range.GetBaseAddress().GetOffset(),
351254721Semaste                    GetByteSize(),
352254721Semaste                    m_flags,
353254721Semaste                    m_mangled.GetName().AsCString(""));
354254721Semaste    }
355254721Semaste}
356254721Semaste
357254721Semasteuint32_t
358254721SemasteSymbol::GetPrologueByteSize ()
359254721Semaste{
360254721Semaste    if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
361254721Semaste    {
362254721Semaste        if (!m_type_data_resolved)
363254721Semaste        {
364254721Semaste            m_type_data_resolved = true;
365254721Semaste
366254721Semaste            const Address &base_address = m_addr_range.GetBaseAddress();
367254721Semaste            Function *function = base_address.CalculateSymbolContextFunction();
368254721Semaste            if (function)
369254721Semaste            {
370254721Semaste                // Functions have line entries which can also potentially have end of prologue information.
371254721Semaste                // So if this symbol points to a function, use the prologue information from there.
372254721Semaste                m_type_data = function->GetPrologueByteSize();
373254721Semaste            }
374254721Semaste            else
375254721Semaste            {
376254721Semaste                ModuleSP module_sp (base_address.GetModule());
377254721Semaste                SymbolContext sc;
378254721Semaste                if (module_sp)
379254721Semaste                {
380254721Semaste                    uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (base_address,
381254721Semaste                                                                                         eSymbolContextLineEntry,
382254721Semaste                                                                                         sc);
383254721Semaste                    if (resolved_flags & eSymbolContextLineEntry)
384254721Semaste                    {
385254721Semaste                        // Default to the end of the first line entry.
386254721Semaste                        m_type_data = sc.line_entry.range.GetByteSize();
387254721Semaste
388254721Semaste                        // Set address for next line.
389254721Semaste                        Address addr (base_address);
390254721Semaste                        addr.Slide (m_type_data);
391254721Semaste
392254721Semaste                        // Check the first few instructions and look for one that has a line number that is
393254721Semaste                        // different than the first entry. This is also done in Function::GetPrologueByteSize().
394254721Semaste                        uint16_t total_offset = m_type_data;
395254721Semaste                        for (int idx = 0; idx < 6; ++idx)
396254721Semaste                        {
397254721Semaste                            SymbolContext sc_temp;
398254721Semaste                            resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp);
399254721Semaste                            // Make sure we got line number information...
400254721Semaste                            if (!(resolved_flags & eSymbolContextLineEntry))
401254721Semaste                                break;
402254721Semaste
403254721Semaste                            // If this line number is different than our first one, use it and we're done.
404254721Semaste                            if (sc_temp.line_entry.line != sc.line_entry.line)
405254721Semaste                            {
406254721Semaste                                m_type_data = total_offset;
407254721Semaste                                break;
408254721Semaste                            }
409254721Semaste
410254721Semaste                            // Slide addr up to the next line address.
411254721Semaste                            addr.Slide (sc_temp.line_entry.range.GetByteSize());
412254721Semaste                            total_offset += sc_temp.line_entry.range.GetByteSize();
413254721Semaste                            // If we've gone too far, bail out.
414254721Semaste                            if (total_offset >= m_addr_range.GetByteSize())
415254721Semaste                                break;
416254721Semaste                        }
417254721Semaste
418254721Semaste                        // Sanity check - this may be a function in the middle of code that has debug information, but
419254721Semaste                        // not for this symbol.  So the line entries surrounding us won't lie inside our function.
420254721Semaste                        // In that case, the line entry will be bigger than we are, so we do that quick check and
421254721Semaste                        // if that is true, we just return 0.
422254721Semaste                        if (m_type_data >= m_addr_range.GetByteSize())
423254721Semaste                            m_type_data = 0;
424254721Semaste                    }
425254721Semaste                    else
426254721Semaste                    {
427254721Semaste                        // TODO: expose something in Process to figure out the
428254721Semaste                        // size of a function prologue.
429254721Semaste                        m_type_data = 0;
430254721Semaste                    }
431254721Semaste                }
432254721Semaste            }
433254721Semaste        }
434254721Semaste        return m_type_data;
435254721Semaste    }
436254721Semaste    return 0;
437254721Semaste}
438254721Semaste
439254721Semastebool
440254721SemasteSymbol::Compare(const ConstString& name, SymbolType type) const
441254721Semaste{
442254721Semaste    if (type == eSymbolTypeAny || m_type == type)
443254721Semaste        return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name;
444254721Semaste    return false;
445254721Semaste}
446254721Semaste
447254721Semaste#define ENUM_TO_CSTRING(x)  case eSymbolType##x: return #x;
448254721Semaste
449254721Semasteconst char *
450254721SemasteSymbol::GetTypeAsString() const
451254721Semaste{
452254721Semaste    switch (m_type)
453254721Semaste    {
454254721Semaste    ENUM_TO_CSTRING(Invalid);
455254721Semaste    ENUM_TO_CSTRING(Absolute);
456254721Semaste    ENUM_TO_CSTRING(Code);
457263363Semaste    ENUM_TO_CSTRING(Resolver);
458254721Semaste    ENUM_TO_CSTRING(Data);
459254721Semaste    ENUM_TO_CSTRING(Trampoline);
460254721Semaste    ENUM_TO_CSTRING(Runtime);
461254721Semaste    ENUM_TO_CSTRING(Exception);
462254721Semaste    ENUM_TO_CSTRING(SourceFile);
463254721Semaste    ENUM_TO_CSTRING(HeaderFile);
464254721Semaste    ENUM_TO_CSTRING(ObjectFile);
465254721Semaste    ENUM_TO_CSTRING(CommonBlock);
466254721Semaste    ENUM_TO_CSTRING(Block);
467254721Semaste    ENUM_TO_CSTRING(Local);
468254721Semaste    ENUM_TO_CSTRING(Param);
469254721Semaste    ENUM_TO_CSTRING(Variable);
470254721Semaste    ENUM_TO_CSTRING(VariableType);
471254721Semaste    ENUM_TO_CSTRING(LineEntry);
472254721Semaste    ENUM_TO_CSTRING(LineHeader);
473254721Semaste    ENUM_TO_CSTRING(ScopeBegin);
474254721Semaste    ENUM_TO_CSTRING(ScopeEnd);
475254721Semaste    ENUM_TO_CSTRING(Additional);
476254721Semaste    ENUM_TO_CSTRING(Compiler);
477254721Semaste    ENUM_TO_CSTRING(Instrumentation);
478254721Semaste    ENUM_TO_CSTRING(Undefined);
479254721Semaste    ENUM_TO_CSTRING(ObjCClass);
480254721Semaste    ENUM_TO_CSTRING(ObjCMetaClass);
481254721Semaste    ENUM_TO_CSTRING(ObjCIVar);
482263363Semaste    ENUM_TO_CSTRING(ReExported);
483254721Semaste    default:
484254721Semaste        break;
485254721Semaste    }
486254721Semaste    return "<unknown SymbolType>";
487254721Semaste}
488254721Semaste
489254721Semastevoid
490254721SemasteSymbol::CalculateSymbolContext (SymbolContext *sc)
491254721Semaste{
492254721Semaste    // Symbols can reconstruct the symbol and the module in the symbol context
493254721Semaste    sc->symbol = this;
494254721Semaste    if (ValueIsAddress())
495254721Semaste        sc->module_sp = GetAddress().GetModule();
496254721Semaste    else
497254721Semaste        sc->module_sp.reset();
498254721Semaste}
499254721Semaste
500254721SemasteModuleSP
501254721SemasteSymbol::CalculateSymbolContextModule ()
502254721Semaste{
503254721Semaste    if (ValueIsAddress())
504254721Semaste        return GetAddress().GetModule();
505254721Semaste    return ModuleSP();
506254721Semaste}
507254721Semaste
508254721SemasteSymbol *
509254721SemasteSymbol::CalculateSymbolContextSymbol ()
510254721Semaste{
511254721Semaste    return this;
512254721Semaste}
513254721Semaste
514254721Semastevoid
515254721SemasteSymbol::DumpSymbolContext (Stream *s)
516254721Semaste{
517254721Semaste    bool dumped_module = false;
518254721Semaste    if (ValueIsAddress())
519254721Semaste    {
520254721Semaste        ModuleSP module_sp (GetAddress().GetModule());
521254721Semaste        if (module_sp)
522254721Semaste        {
523254721Semaste            dumped_module = true;
524254721Semaste            module_sp->DumpSymbolContext(s);
525254721Semaste        }
526254721Semaste    }
527254721Semaste    if (dumped_module)
528254721Semaste        s->PutCString(", ");
529254721Semaste
530254721Semaste    s->Printf("Symbol{0x%8.8x}", GetID());
531254721Semaste}
532254721Semaste
533254721Semastelldb::addr_t
534254721SemasteSymbol::GetByteSize () const
535254721Semaste{
536254721Semaste    return m_addr_range.GetByteSize();
537254721Semaste}
538254721Semaste
539263363SemasteSymbol *
540263363SemasteSymbol::ResolveReExportedSymbol (Target &target)
541263363Semaste{
542263363Semaste    ConstString reexport_name (GetReExportedSymbolName());
543263363Semaste    if (reexport_name)
544263363Semaste    {
545263363Semaste        ModuleSpec module_spec;
546263363Semaste        ModuleSP module_sp;
547263363Semaste        module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary();
548263363Semaste        if (module_spec.GetFileSpec())
549263363Semaste        {
550263363Semaste            // Try searching for the module file spec first using the full path
551263363Semaste            module_sp = target.GetImages().FindFirstModule(module_spec);
552263363Semaste            if (!module_sp)
553263363Semaste            {
554263363Semaste                // Next try and find the module by basename in case environment
555263363Semaste                // variables or other runtime trickery causes shared libraries
556263363Semaste                // to be loaded from alternate paths
557263363Semaste                module_spec.GetFileSpec().GetDirectory().Clear();
558263363Semaste                module_sp = target.GetImages().FindFirstModule(module_spec);
559263363Semaste            }
560263363Semaste        }
561263363Semaste
562263363Semaste        if (module_sp)
563263363Semaste        {
564263363Semaste            lldb_private::SymbolContextList sc_list;
565263363Semaste            module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list);
566263363Semaste            const size_t num_scs = sc_list.GetSize();
567263363Semaste            if (num_scs > 0)
568263363Semaste            {
569263363Semaste                for (size_t i=0; i<num_scs; ++i)
570263363Semaste                {
571263363Semaste                    lldb_private::SymbolContext sc;
572263363Semaste                    if (sc_list.GetContextAtIndex(i, sc))
573263363Semaste                    {
574263363Semaste                        if (sc.symbol->IsExternal())
575263363Semaste                            return sc.symbol;
576263363Semaste                    }
577263363Semaste                }
578263363Semaste            }
579263363Semaste        }
580263363Semaste    }
581263363Semaste    return NULL;
582263363Semaste}
583269024Semaste
584269024Semaste
585269024Semastelldb::DisassemblerSP
586269024SemasteSymbol::GetInstructions (const ExecutionContext &exe_ctx,
587269024Semaste                         const char *flavor,
588269024Semaste                         bool prefer_file_cache)
589269024Semaste{
590269024Semaste    ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
591269024Semaste    if (module_sp)
592269024Semaste    {
593269024Semaste        const bool prefer_file_cache = false;
594269024Semaste        return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
595269024Semaste                                               NULL,
596269024Semaste                                               flavor,
597269024Semaste                                               exe_ctx,
598269024Semaste                                               m_addr_range,
599269024Semaste                                               prefer_file_cache);
600269024Semaste    }
601269024Semaste    return lldb::DisassemblerSP();
602269024Semaste}
603269024Semaste
604269024Semastebool
605269024SemasteSymbol::GetDisassembly (const ExecutionContext &exe_ctx,
606269024Semaste                        const char *flavor,
607269024Semaste                        bool prefer_file_cache,
608269024Semaste                        Stream &strm)
609269024Semaste{
610269024Semaste    lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
611269024Semaste    if (disassembler_sp)
612269024Semaste    {
613269024Semaste        const bool show_address = true;
614269024Semaste        const bool show_bytes = false;
615269024Semaste        disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
616269024Semaste        return true;
617269024Semaste    }
618269024Semaste    return false;
619269024Semaste}
620