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