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