1 //===-- SBSymbol.cpp --------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBSymbol.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/Core/Disassembler.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Symbol/Symbol.h"
15 #include "lldb/Target/ExecutionContext.h"
16 #include "lldb/Target/Target.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 SBSymbol::SBSymbol() : m_opaque_ptr(NULL) {
22   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSymbol);
23 }
24 
25 SBSymbol::SBSymbol(lldb_private::Symbol *lldb_object_ptr)
26     : m_opaque_ptr(lldb_object_ptr) {}
27 
28 SBSymbol::SBSymbol(const lldb::SBSymbol &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {
29   LLDB_RECORD_CONSTRUCTOR(SBSymbol, (const lldb::SBSymbol &), rhs);
30 }
31 
32 const SBSymbol &SBSymbol::operator=(const SBSymbol &rhs) {
33   LLDB_RECORD_METHOD(const lldb::SBSymbol &,
34                      SBSymbol, operator=,(const lldb::SBSymbol &), rhs);
35 
36   m_opaque_ptr = rhs.m_opaque_ptr;
37   return *this;
38 }
39 
40 SBSymbol::~SBSymbol() { m_opaque_ptr = NULL; }
41 
42 void SBSymbol::SetSymbol(lldb_private::Symbol *lldb_object_ptr) {
43   m_opaque_ptr = lldb_object_ptr;
44 }
45 
46 bool SBSymbol::IsValid() const {
47   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSymbol, IsValid);
48 
49   return m_opaque_ptr != NULL;
50 }
51 
52 const char *SBSymbol::GetName() const {
53   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBSymbol, GetName);
54 
55   const char *name = NULL;
56   if (m_opaque_ptr)
57     name = m_opaque_ptr->GetName().AsCString();
58 
59   return name;
60 }
61 
62 const char *SBSymbol::GetDisplayName() const {
63   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBSymbol, GetDisplayName);
64 
65   const char *name = NULL;
66   if (m_opaque_ptr)
67     name = m_opaque_ptr->GetMangled()
68                .GetDisplayDemangledName(m_opaque_ptr->GetLanguage())
69                .AsCString();
70 
71   return name;
72 }
73 
74 const char *SBSymbol::GetMangledName() const {
75   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBSymbol, GetMangledName);
76 
77   const char *name = NULL;
78   if (m_opaque_ptr)
79     name = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
80   return name;
81 }
82 
83 bool SBSymbol::operator==(const SBSymbol &rhs) const {
84   LLDB_RECORD_METHOD_CONST(bool, SBSymbol, operator==,(const lldb::SBSymbol &),
85                            rhs);
86 
87   return m_opaque_ptr == rhs.m_opaque_ptr;
88 }
89 
90 bool SBSymbol::operator!=(const SBSymbol &rhs) const {
91   LLDB_RECORD_METHOD_CONST(bool, SBSymbol, operator!=,(const lldb::SBSymbol &),
92                            rhs);
93 
94   return m_opaque_ptr != rhs.m_opaque_ptr;
95 }
96 
97 bool SBSymbol::GetDescription(SBStream &description) {
98   LLDB_RECORD_METHOD(bool, SBSymbol, GetDescription, (lldb::SBStream &),
99                      description);
100 
101   Stream &strm = description.ref();
102 
103   if (m_opaque_ptr) {
104     m_opaque_ptr->GetDescription(&strm, lldb::eDescriptionLevelFull, NULL);
105   } else
106     strm.PutCString("No value");
107 
108   return true;
109 }
110 
111 SBInstructionList SBSymbol::GetInstructions(SBTarget target) {
112   LLDB_RECORD_METHOD(lldb::SBInstructionList, SBSymbol, GetInstructions,
113                      (lldb::SBTarget), target);
114 
115   return LLDB_RECORD_RESULT(GetInstructions(target, NULL));
116 }
117 
118 SBInstructionList SBSymbol::GetInstructions(SBTarget target,
119                                             const char *flavor_string) {
120   LLDB_RECORD_METHOD(lldb::SBInstructionList, SBSymbol, GetInstructions,
121                      (lldb::SBTarget, const char *), target, flavor_string);
122 
123   SBInstructionList sb_instructions;
124   if (m_opaque_ptr) {
125     ExecutionContext exe_ctx;
126     TargetSP target_sp(target.GetSP());
127     std::unique_lock<std::recursive_mutex> lock;
128     if (target_sp) {
129       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
130 
131       target_sp->CalculateExecutionContext(exe_ctx);
132     }
133     if (m_opaque_ptr->ValueIsAddress()) {
134       const Address &symbol_addr = m_opaque_ptr->GetAddressRef();
135       ModuleSP module_sp = symbol_addr.GetModule();
136       if (module_sp) {
137         AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize());
138         const bool prefer_file_cache = false;
139         sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
140             module_sp->GetArchitecture(), NULL, flavor_string, exe_ctx,
141             symbol_range, prefer_file_cache));
142       }
143     }
144   }
145   return LLDB_RECORD_RESULT(sb_instructions);
146 }
147 
148 lldb_private::Symbol *SBSymbol::get() { return m_opaque_ptr; }
149 
150 void SBSymbol::reset(lldb_private::Symbol *symbol) { m_opaque_ptr = symbol; }
151 
152 SBAddress SBSymbol::GetStartAddress() {
153   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBSymbol, GetStartAddress);
154 
155   SBAddress addr;
156   if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) {
157     addr.SetAddress(&m_opaque_ptr->GetAddressRef());
158   }
159   return LLDB_RECORD_RESULT(addr);
160 }
161 
162 SBAddress SBSymbol::GetEndAddress() {
163   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBSymbol, GetEndAddress);
164 
165   SBAddress addr;
166   if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) {
167     lldb::addr_t range_size = m_opaque_ptr->GetByteSize();
168     if (range_size > 0) {
169       addr.SetAddress(&m_opaque_ptr->GetAddressRef());
170       addr->Slide(m_opaque_ptr->GetByteSize());
171     }
172   }
173   return LLDB_RECORD_RESULT(addr);
174 }
175 
176 uint32_t SBSymbol::GetPrologueByteSize() {
177   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBSymbol, GetPrologueByteSize);
178 
179   if (m_opaque_ptr)
180     return m_opaque_ptr->GetPrologueByteSize();
181   return 0;
182 }
183 
184 SymbolType SBSymbol::GetType() {
185   LLDB_RECORD_METHOD_NO_ARGS(lldb::SymbolType, SBSymbol, GetType);
186 
187   if (m_opaque_ptr)
188     return m_opaque_ptr->GetType();
189   return eSymbolTypeInvalid;
190 }
191 
192 bool SBSymbol::IsExternal() {
193   LLDB_RECORD_METHOD_NO_ARGS(bool, SBSymbol, IsExternal);
194 
195   if (m_opaque_ptr)
196     return m_opaque_ptr->IsExternal();
197   return false;
198 }
199 
200 bool SBSymbol::IsSynthetic() {
201   LLDB_RECORD_METHOD_NO_ARGS(bool, SBSymbol, IsSynthetic);
202 
203   if (m_opaque_ptr)
204     return m_opaque_ptr->IsSynthetic();
205   return false;
206 }
207