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