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