1 //===-- SBFunction.cpp ----------------------------------------------------===//
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/SBFunction.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBProcess.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/Core/Disassembler.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Symbol/CompileUnit.h"
16 #include "lldb/Symbol/Function.h"
17 #include "lldb/Symbol/Type.h"
18 #include "lldb/Symbol/VariableList.h"
19 #include "lldb/Target/ExecutionContext.h"
20 #include "lldb/Target/Target.h"
21
22 using namespace lldb;
23 using namespace lldb_private;
24
SBFunction()25 SBFunction::SBFunction() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFunction); }
26
SBFunction(lldb_private::Function * lldb_object_ptr)27 SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr)
28 : m_opaque_ptr(lldb_object_ptr) {}
29
SBFunction(const lldb::SBFunction & rhs)30 SBFunction::SBFunction(const lldb::SBFunction &rhs)
31 : m_opaque_ptr(rhs.m_opaque_ptr) {
32 LLDB_RECORD_CONSTRUCTOR(SBFunction, (const lldb::SBFunction &), rhs);
33 }
34
operator =(const SBFunction & rhs)35 const SBFunction &SBFunction::operator=(const SBFunction &rhs) {
36 LLDB_RECORD_METHOD(const lldb::SBFunction &,
37 SBFunction, operator=,(const lldb::SBFunction &), rhs);
38
39 m_opaque_ptr = rhs.m_opaque_ptr;
40 return LLDB_RECORD_RESULT(*this);
41 }
42
~SBFunction()43 SBFunction::~SBFunction() { m_opaque_ptr = nullptr; }
44
IsValid() const45 bool SBFunction::IsValid() const {
46 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, IsValid);
47 return this->operator bool();
48 }
operator bool() const49 SBFunction::operator bool() const {
50 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, operator bool);
51
52 return m_opaque_ptr != nullptr;
53 }
54
GetName() const55 const char *SBFunction::GetName() const {
56 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetName);
57
58 const char *cstr = nullptr;
59 if (m_opaque_ptr)
60 cstr = m_opaque_ptr->GetName().AsCString();
61
62 return cstr;
63 }
64
GetDisplayName() const65 const char *SBFunction::GetDisplayName() const {
66 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetDisplayName);
67
68 const char *cstr = nullptr;
69 if (m_opaque_ptr)
70 cstr = m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString();
71
72 return cstr;
73 }
74
GetMangledName() const75 const char *SBFunction::GetMangledName() const {
76 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetMangledName);
77
78 const char *cstr = nullptr;
79 if (m_opaque_ptr)
80 cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
81 return cstr;
82 }
83
operator ==(const SBFunction & rhs) const84 bool SBFunction::operator==(const SBFunction &rhs) const {
85 LLDB_RECORD_METHOD_CONST(
86 bool, SBFunction, operator==,(const lldb::SBFunction &), rhs);
87
88 return m_opaque_ptr == rhs.m_opaque_ptr;
89 }
90
operator !=(const SBFunction & rhs) const91 bool SBFunction::operator!=(const SBFunction &rhs) const {
92 LLDB_RECORD_METHOD_CONST(
93 bool, SBFunction, operator!=,(const lldb::SBFunction &), rhs);
94
95 return m_opaque_ptr != rhs.m_opaque_ptr;
96 }
97
GetDescription(SBStream & s)98 bool SBFunction::GetDescription(SBStream &s) {
99 LLDB_RECORD_METHOD(bool, SBFunction, GetDescription, (lldb::SBStream &), s);
100
101 if (m_opaque_ptr) {
102 s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
103 m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString());
104 Type *func_type = m_opaque_ptr->GetType();
105 if (func_type)
106 s.Printf(", type = %s", func_type->GetName().AsCString());
107 return true;
108 }
109 s.Printf("No value");
110 return false;
111 }
112
GetInstructions(SBTarget target)113 SBInstructionList SBFunction::GetInstructions(SBTarget target) {
114 LLDB_RECORD_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
115 (lldb::SBTarget), target);
116
117 return LLDB_RECORD_RESULT(GetInstructions(target, nullptr));
118 }
119
GetInstructions(SBTarget target,const char * flavor)120 SBInstructionList SBFunction::GetInstructions(SBTarget target,
121 const char *flavor) {
122 LLDB_RECORD_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
123 (lldb::SBTarget, const char *), target, flavor);
124
125 SBInstructionList sb_instructions;
126 if (m_opaque_ptr) {
127 TargetSP target_sp(target.GetSP());
128 std::unique_lock<std::recursive_mutex> lock;
129 ModuleSP module_sp(
130 m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
131 if (target_sp && module_sp) {
132 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
133 const bool force_live_memory = true;
134 sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
135 module_sp->GetArchitecture(), nullptr, flavor, *target_sp,
136 m_opaque_ptr->GetAddressRange(), force_live_memory));
137 }
138 }
139 return LLDB_RECORD_RESULT(sb_instructions);
140 }
141
get()142 lldb_private::Function *SBFunction::get() { return m_opaque_ptr; }
143
reset(lldb_private::Function * lldb_object_ptr)144 void SBFunction::reset(lldb_private::Function *lldb_object_ptr) {
145 m_opaque_ptr = lldb_object_ptr;
146 }
147
GetStartAddress()148 SBAddress SBFunction::GetStartAddress() {
149 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetStartAddress);
150
151 SBAddress addr;
152 if (m_opaque_ptr)
153 addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
154 return LLDB_RECORD_RESULT(addr);
155 }
156
GetEndAddress()157 SBAddress SBFunction::GetEndAddress() {
158 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetEndAddress);
159
160 SBAddress addr;
161 if (m_opaque_ptr) {
162 addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
163 if (byte_size > 0) {
164 addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
165 addr->Slide(byte_size);
166 }
167 }
168 return LLDB_RECORD_RESULT(addr);
169 }
170
GetArgumentName(uint32_t arg_idx)171 const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
172 LLDB_RECORD_METHOD(const char *, SBFunction, GetArgumentName, (uint32_t),
173 arg_idx);
174
175 if (m_opaque_ptr) {
176 Block &block = m_opaque_ptr->GetBlock(true);
177 VariableListSP variable_list_sp = block.GetBlockVariableList(true);
178 if (variable_list_sp) {
179 VariableList arguments;
180 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
181 arguments, true);
182 lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
183 if (variable_sp)
184 return variable_sp->GetName().GetCString();
185 }
186 }
187 return nullptr;
188 }
189
GetPrologueByteSize()190 uint32_t SBFunction::GetPrologueByteSize() {
191 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBFunction, GetPrologueByteSize);
192
193 if (m_opaque_ptr)
194 return m_opaque_ptr->GetPrologueByteSize();
195 return 0;
196 }
197
GetType()198 SBType SBFunction::GetType() {
199 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBType, SBFunction, GetType);
200
201 SBType sb_type;
202 if (m_opaque_ptr) {
203 Type *function_type = m_opaque_ptr->GetType();
204 if (function_type)
205 sb_type.ref().SetType(function_type->shared_from_this());
206 }
207 return LLDB_RECORD_RESULT(sb_type);
208 }
209
GetBlock()210 SBBlock SBFunction::GetBlock() {
211 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBFunction, GetBlock);
212
213 SBBlock sb_block;
214 if (m_opaque_ptr)
215 sb_block.SetPtr(&m_opaque_ptr->GetBlock(true));
216 return LLDB_RECORD_RESULT(sb_block);
217 }
218
GetLanguage()219 lldb::LanguageType SBFunction::GetLanguage() {
220 LLDB_RECORD_METHOD_NO_ARGS(lldb::LanguageType, SBFunction, GetLanguage);
221
222 if (m_opaque_ptr) {
223 if (m_opaque_ptr->GetCompileUnit())
224 return m_opaque_ptr->GetCompileUnit()->GetLanguage();
225 }
226 return lldb::eLanguageTypeUnknown;
227 }
228
GetIsOptimized()229 bool SBFunction::GetIsOptimized() {
230 LLDB_RECORD_METHOD_NO_ARGS(bool, SBFunction, GetIsOptimized);
231
232 if (m_opaque_ptr) {
233 if (m_opaque_ptr->GetCompileUnit())
234 return m_opaque_ptr->GetCompileUnit()->GetIsOptimized();
235 }
236 return false;
237 }
238
239 namespace lldb_private {
240 namespace repro {
241
242 template <>
RegisterMethods(Registry & R)243 void RegisterMethods<SBFunction>(Registry &R) {
244 LLDB_REGISTER_CONSTRUCTOR(SBFunction, ());
245 LLDB_REGISTER_CONSTRUCTOR(SBFunction, (const lldb::SBFunction &));
246 LLDB_REGISTER_METHOD(const lldb::SBFunction &,
247 SBFunction, operator=,(const lldb::SBFunction &));
248 LLDB_REGISTER_METHOD_CONST(bool, SBFunction, IsValid, ());
249 LLDB_REGISTER_METHOD_CONST(bool, SBFunction, operator bool, ());
250 LLDB_REGISTER_METHOD_CONST(const char *, SBFunction, GetName, ());
251 LLDB_REGISTER_METHOD_CONST(const char *, SBFunction, GetDisplayName, ());
252 LLDB_REGISTER_METHOD_CONST(const char *, SBFunction, GetMangledName, ());
253 LLDB_REGISTER_METHOD_CONST(
254 bool, SBFunction, operator==,(const lldb::SBFunction &));
255 LLDB_REGISTER_METHOD_CONST(
256 bool, SBFunction, operator!=,(const lldb::SBFunction &));
257 LLDB_REGISTER_METHOD(bool, SBFunction, GetDescription, (lldb::SBStream &));
258 LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
259 (lldb::SBTarget));
260 LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
261 (lldb::SBTarget, const char *));
262 LLDB_REGISTER_METHOD(lldb::SBAddress, SBFunction, GetStartAddress, ());
263 LLDB_REGISTER_METHOD(lldb::SBAddress, SBFunction, GetEndAddress, ());
264 LLDB_REGISTER_METHOD(const char *, SBFunction, GetArgumentName, (uint32_t));
265 LLDB_REGISTER_METHOD(uint32_t, SBFunction, GetPrologueByteSize, ());
266 LLDB_REGISTER_METHOD(lldb::SBType, SBFunction, GetType, ());
267 LLDB_REGISTER_METHOD(lldb::SBBlock, SBFunction, GetBlock, ());
268 LLDB_REGISTER_METHOD(lldb::LanguageType, SBFunction, GetLanguage, ());
269 LLDB_REGISTER_METHOD(bool, SBFunction, GetIsOptimized, ());
270 }
271
272 }
273 }
274