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(NULL) { 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 *this; 43 } 44 45 SBFunction::~SBFunction() { m_opaque_ptr = NULL; } 46 47 bool SBFunction::IsValid() const { 48 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, IsValid); 49 50 return m_opaque_ptr != NULL; 51 } 52 53 const char *SBFunction::GetName() const { 54 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetName); 55 56 const char *cstr = NULL; 57 if (m_opaque_ptr) 58 cstr = m_opaque_ptr->GetName().AsCString(); 59 60 return cstr; 61 } 62 63 const char *SBFunction::GetDisplayName() const { 64 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetDisplayName); 65 66 const char *cstr = NULL; 67 if (m_opaque_ptr) 68 cstr = m_opaque_ptr->GetMangled() 69 .GetDisplayDemangledName(m_opaque_ptr->GetLanguage()) 70 .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 = NULL; 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, NULL)); 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 ExecutionContext exe_ctx; 128 TargetSP target_sp(target.GetSP()); 129 std::unique_lock<std::recursive_mutex> lock; 130 if (target_sp) { 131 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 132 target_sp->CalculateExecutionContext(exe_ctx); 133 exe_ctx.SetProcessSP(target_sp->GetProcessSP()); 134 } 135 ModuleSP module_sp( 136 m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); 137 if (module_sp) { 138 const bool prefer_file_cache = false; 139 sb_instructions.SetDisassembler(Disassembler::DisassembleRange( 140 module_sp->GetArchitecture(), NULL, flavor, exe_ctx, 141 m_opaque_ptr->GetAddressRange(), prefer_file_cache)); 142 } 143 } 144 return LLDB_RECORD_RESULT(sb_instructions); 145 } 146 147 lldb_private::Function *SBFunction::get() { return m_opaque_ptr; } 148 149 void SBFunction::reset(lldb_private::Function *lldb_object_ptr) { 150 m_opaque_ptr = lldb_object_ptr; 151 } 152 153 SBAddress SBFunction::GetStartAddress() { 154 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetStartAddress); 155 156 SBAddress addr; 157 if (m_opaque_ptr) 158 addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 159 return LLDB_RECORD_RESULT(addr); 160 } 161 162 SBAddress SBFunction::GetEndAddress() { 163 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetEndAddress); 164 165 SBAddress addr; 166 if (m_opaque_ptr) { 167 addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize(); 168 if (byte_size > 0) { 169 addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 170 addr->Slide(byte_size); 171 } 172 } 173 return LLDB_RECORD_RESULT(addr); 174 } 175 176 const char *SBFunction::GetArgumentName(uint32_t arg_idx) { 177 LLDB_RECORD_METHOD(const char *, SBFunction, GetArgumentName, (uint32_t), 178 arg_idx); 179 180 if (m_opaque_ptr) { 181 Block &block = m_opaque_ptr->GetBlock(true); 182 VariableListSP variable_list_sp = block.GetBlockVariableList(true); 183 if (variable_list_sp) { 184 VariableList arguments; 185 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, 186 arguments, true); 187 lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx); 188 if (variable_sp) 189 return variable_sp->GetName().GetCString(); 190 } 191 } 192 return nullptr; 193 } 194 195 uint32_t SBFunction::GetPrologueByteSize() { 196 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBFunction, GetPrologueByteSize); 197 198 if (m_opaque_ptr) 199 return m_opaque_ptr->GetPrologueByteSize(); 200 return 0; 201 } 202 203 SBType SBFunction::GetType() { 204 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBType, SBFunction, GetType); 205 206 SBType sb_type; 207 if (m_opaque_ptr) { 208 Type *function_type = m_opaque_ptr->GetType(); 209 if (function_type) 210 sb_type.ref().SetType(function_type->shared_from_this()); 211 } 212 return LLDB_RECORD_RESULT(sb_type); 213 } 214 215 SBBlock SBFunction::GetBlock() { 216 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBFunction, GetBlock); 217 218 SBBlock sb_block; 219 if (m_opaque_ptr) 220 sb_block.SetPtr(&m_opaque_ptr->GetBlock(true)); 221 return LLDB_RECORD_RESULT(sb_block); 222 } 223 224 lldb::LanguageType SBFunction::GetLanguage() { 225 LLDB_RECORD_METHOD_NO_ARGS(lldb::LanguageType, SBFunction, GetLanguage); 226 227 if (m_opaque_ptr) { 228 if (m_opaque_ptr->GetCompileUnit()) 229 return m_opaque_ptr->GetCompileUnit()->GetLanguage(); 230 } 231 return lldb::eLanguageTypeUnknown; 232 } 233 234 bool SBFunction::GetIsOptimized() { 235 LLDB_RECORD_METHOD_NO_ARGS(bool, SBFunction, GetIsOptimized); 236 237 if (m_opaque_ptr) { 238 if (m_opaque_ptr->GetCompileUnit()) 239 return m_opaque_ptr->GetCompileUnit()->GetIsOptimized(); 240 } 241 return false; 242 } 243