xref: /freebsd-src/contrib/llvm-project/lldb/source/API/SBFunction.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 "lldb/API/SBAddressRange.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 #include "lldb/Utility/Instrumentation.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 SBFunction::SBFunction() { LLDB_INSTRUMENT_VA(this); }
27 
28 SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr)
29     : m_opaque_ptr(lldb_object_ptr) {}
30 
31 SBFunction::SBFunction(const lldb::SBFunction &rhs)
32     : m_opaque_ptr(rhs.m_opaque_ptr) {
33   LLDB_INSTRUMENT_VA(this, rhs);
34 }
35 
36 const SBFunction &SBFunction::operator=(const SBFunction &rhs) {
37   LLDB_INSTRUMENT_VA(this, rhs);
38 
39   m_opaque_ptr = rhs.m_opaque_ptr;
40   return *this;
41 }
42 
43 SBFunction::~SBFunction() { m_opaque_ptr = nullptr; }
44 
45 bool SBFunction::IsValid() const {
46   LLDB_INSTRUMENT_VA(this);
47   return this->operator bool();
48 }
49 SBFunction::operator bool() const {
50   LLDB_INSTRUMENT_VA(this);
51 
52   return m_opaque_ptr != nullptr;
53 }
54 
55 const char *SBFunction::GetName() const {
56   LLDB_INSTRUMENT_VA(this);
57 
58   if (m_opaque_ptr)
59     return m_opaque_ptr->GetName().AsCString();
60 
61   return nullptr;
62 }
63 
64 const char *SBFunction::GetDisplayName() const {
65   LLDB_INSTRUMENT_VA(this);
66 
67   if (m_opaque_ptr)
68     return m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString();
69 
70   return nullptr;
71 }
72 
73 const char *SBFunction::GetMangledName() const {
74   LLDB_INSTRUMENT_VA(this);
75 
76   if (m_opaque_ptr)
77     return m_opaque_ptr->GetMangled().GetMangledName().AsCString();
78   return nullptr;
79 }
80 
81 bool SBFunction::operator==(const SBFunction &rhs) const {
82   LLDB_INSTRUMENT_VA(this, rhs);
83 
84   return m_opaque_ptr == rhs.m_opaque_ptr;
85 }
86 
87 bool SBFunction::operator!=(const SBFunction &rhs) const {
88   LLDB_INSTRUMENT_VA(this, rhs);
89 
90   return m_opaque_ptr != rhs.m_opaque_ptr;
91 }
92 
93 bool SBFunction::GetDescription(SBStream &s) {
94   LLDB_INSTRUMENT_VA(this, s);
95 
96   if (m_opaque_ptr) {
97     s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
98              m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString());
99     Type *func_type = m_opaque_ptr->GetType();
100     if (func_type)
101       s.Printf(", type = %s", func_type->GetName().AsCString());
102     return true;
103   }
104   s.Printf("No value");
105   return false;
106 }
107 
108 SBInstructionList SBFunction::GetInstructions(SBTarget target) {
109   LLDB_INSTRUMENT_VA(this, target);
110 
111   return GetInstructions(target, nullptr);
112 }
113 
114 SBInstructionList SBFunction::GetInstructions(SBTarget target,
115                                               const char *flavor) {
116   LLDB_INSTRUMENT_VA(this, target, flavor);
117 
118   SBInstructionList sb_instructions;
119   if (m_opaque_ptr) {
120     TargetSP target_sp(target.GetSP());
121     std::unique_lock<std::recursive_mutex> lock;
122     ModuleSP module_sp(
123         m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
124     if (target_sp && module_sp) {
125       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
126       const bool force_live_memory = true;
127       sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
128           module_sp->GetArchitecture(), nullptr, flavor, *target_sp,
129           m_opaque_ptr->GetAddressRange(), force_live_memory));
130     }
131   }
132   return sb_instructions;
133 }
134 
135 lldb_private::Function *SBFunction::get() { return m_opaque_ptr; }
136 
137 void SBFunction::reset(lldb_private::Function *lldb_object_ptr) {
138   m_opaque_ptr = lldb_object_ptr;
139 }
140 
141 SBAddress SBFunction::GetStartAddress() {
142   LLDB_INSTRUMENT_VA(this);
143 
144   SBAddress addr;
145   if (m_opaque_ptr)
146     addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
147   return addr;
148 }
149 
150 SBAddress SBFunction::GetEndAddress() {
151   LLDB_INSTRUMENT_VA(this);
152 
153   SBAddress addr;
154   if (m_opaque_ptr) {
155     addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
156     if (byte_size > 0) {
157       addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
158       addr->Slide(byte_size);
159     }
160   }
161   return addr;
162 }
163 
164 lldb::SBAddressRangeList SBFunction::GetRanges() {
165   LLDB_INSTRUMENT_VA(this);
166 
167   lldb::SBAddressRangeList ranges;
168   if (m_opaque_ptr) {
169     lldb::SBAddressRange range;
170     (*range.m_opaque_up) = m_opaque_ptr->GetAddressRange();
171     ranges.Append(std::move(range));
172   }
173 
174   return ranges;
175 }
176 
177 const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
178   LLDB_INSTRUMENT_VA(this, arg_idx);
179 
180   if (!m_opaque_ptr)
181     return nullptr;
182 
183   Block &block = m_opaque_ptr->GetBlock(true);
184   VariableListSP variable_list_sp = block.GetBlockVariableList(true);
185   if (!variable_list_sp)
186     return nullptr;
187 
188   VariableList arguments;
189   variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
190                                              arguments, true);
191   lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
192   if (!variable_sp)
193     return nullptr;
194 
195   return variable_sp->GetName().GetCString();
196 }
197 
198 uint32_t SBFunction::GetPrologueByteSize() {
199   LLDB_INSTRUMENT_VA(this);
200 
201   if (m_opaque_ptr)
202     return m_opaque_ptr->GetPrologueByteSize();
203   return 0;
204 }
205 
206 SBType SBFunction::GetType() {
207   LLDB_INSTRUMENT_VA(this);
208 
209   SBType sb_type;
210   if (m_opaque_ptr) {
211     Type *function_type = m_opaque_ptr->GetType();
212     if (function_type)
213       sb_type.ref().SetType(function_type->shared_from_this());
214   }
215   return sb_type;
216 }
217 
218 SBBlock SBFunction::GetBlock() {
219   LLDB_INSTRUMENT_VA(this);
220 
221   SBBlock sb_block;
222   if (m_opaque_ptr)
223     sb_block.SetPtr(&m_opaque_ptr->GetBlock(true));
224   return sb_block;
225 }
226 
227 lldb::LanguageType SBFunction::GetLanguage() {
228   LLDB_INSTRUMENT_VA(this);
229 
230   if (m_opaque_ptr) {
231     if (m_opaque_ptr->GetCompileUnit())
232       return m_opaque_ptr->GetCompileUnit()->GetLanguage();
233   }
234   return lldb::eLanguageTypeUnknown;
235 }
236 
237 bool SBFunction::GetIsOptimized() {
238   LLDB_INSTRUMENT_VA(this);
239 
240   if (m_opaque_ptr) {
241     if (m_opaque_ptr->GetCompileUnit())
242       return m_opaque_ptr->GetCompileUnit()->GetIsOptimized();
243   }
244   return false;
245 }
246