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() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFunction); } 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_RECORD_CONSTRUCTOR(SBFunction, (const lldb::SBFunction &), rhs); 33 } 34 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 43 SBFunction::~SBFunction() { m_opaque_ptr = nullptr; } 44 45 bool SBFunction::IsValid() const { 46 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, IsValid); 47 return this->operator bool(); 48 } 49 SBFunction::operator bool() const { 50 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, operator bool); 51 52 return m_opaque_ptr != nullptr; 53 } 54 55 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 65 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 75 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 84 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 91 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 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 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 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 142 lldb_private::Function *SBFunction::get() { return m_opaque_ptr; } 143 144 void SBFunction::reset(lldb_private::Function *lldb_object_ptr) { 145 m_opaque_ptr = lldb_object_ptr; 146 } 147 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 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 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 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 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 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 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 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 <> 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