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 "lldb/API/SBProcess.h" 11 #include "lldb/API/SBStream.h" 12 #include "lldb/Core/Disassembler.h" 13 #include "lldb/Core/Module.h" 14 #include "lldb/Symbol/CompileUnit.h" 15 #include "lldb/Symbol/Function.h" 16 #include "lldb/Symbol/Type.h" 17 #include "lldb/Symbol/VariableList.h" 18 #include "lldb/Target/ExecutionContext.h" 19 #include "lldb/Target/Target.h" 20 #include "lldb/Utility/Log.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 SBFunction::SBFunction() : m_opaque_ptr(NULL) {} 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 33 const SBFunction &SBFunction::operator=(const SBFunction &rhs) { 34 m_opaque_ptr = rhs.m_opaque_ptr; 35 return *this; 36 } 37 38 SBFunction::~SBFunction() { m_opaque_ptr = NULL; } 39 40 bool SBFunction::IsValid() const { return m_opaque_ptr != NULL; } 41 42 const char *SBFunction::GetName() const { 43 const char *cstr = NULL; 44 if (m_opaque_ptr) 45 cstr = m_opaque_ptr->GetName().AsCString(); 46 47 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 48 if (log) { 49 if (cstr) 50 log->Printf("SBFunction(%p)::GetName () => \"%s\"", 51 static_cast<void *>(m_opaque_ptr), cstr); 52 else 53 log->Printf("SBFunction(%p)::GetName () => NULL", 54 static_cast<void *>(m_opaque_ptr)); 55 } 56 return cstr; 57 } 58 59 const char *SBFunction::GetDisplayName() const { 60 const char *cstr = NULL; 61 if (m_opaque_ptr) 62 cstr = m_opaque_ptr->GetMangled() 63 .GetDisplayDemangledName(m_opaque_ptr->GetLanguage()) 64 .AsCString(); 65 66 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 67 if (log) { 68 if (cstr) 69 log->Printf("SBFunction(%p)::GetDisplayName () => \"%s\"", 70 static_cast<void *>(m_opaque_ptr), cstr); 71 else 72 log->Printf("SBFunction(%p)::GetDisplayName () => NULL", 73 static_cast<void *>(m_opaque_ptr)); 74 } 75 return cstr; 76 } 77 78 const char *SBFunction::GetMangledName() const { 79 const char *cstr = NULL; 80 if (m_opaque_ptr) 81 cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString(); 82 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 83 if (log) { 84 if (cstr) 85 log->Printf("SBFunction(%p)::GetMangledName () => \"%s\"", 86 static_cast<void *>(m_opaque_ptr), cstr); 87 else 88 log->Printf("SBFunction(%p)::GetMangledName () => NULL", 89 static_cast<void *>(m_opaque_ptr)); 90 } 91 return cstr; 92 } 93 94 bool SBFunction::operator==(const SBFunction &rhs) const { 95 return m_opaque_ptr == rhs.m_opaque_ptr; 96 } 97 98 bool SBFunction::operator!=(const SBFunction &rhs) const { 99 return m_opaque_ptr != rhs.m_opaque_ptr; 100 } 101 102 bool SBFunction::GetDescription(SBStream &s) { 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 return GetInstructions(target, NULL); 117 } 118 119 SBInstructionList SBFunction::GetInstructions(SBTarget target, 120 const char *flavor) { 121 SBInstructionList sb_instructions; 122 if (m_opaque_ptr) { 123 ExecutionContext exe_ctx; 124 TargetSP target_sp(target.GetSP()); 125 std::unique_lock<std::recursive_mutex> lock; 126 if (target_sp) { 127 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 128 target_sp->CalculateExecutionContext(exe_ctx); 129 exe_ctx.SetProcessSP(target_sp->GetProcessSP()); 130 } 131 ModuleSP module_sp( 132 m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); 133 if (module_sp) { 134 const bool prefer_file_cache = false; 135 sb_instructions.SetDisassembler(Disassembler::DisassembleRange( 136 module_sp->GetArchitecture(), NULL, flavor, exe_ctx, 137 m_opaque_ptr->GetAddressRange(), prefer_file_cache)); 138 } 139 } 140 return sb_instructions; 141 } 142 143 lldb_private::Function *SBFunction::get() { return m_opaque_ptr; } 144 145 void SBFunction::reset(lldb_private::Function *lldb_object_ptr) { 146 m_opaque_ptr = lldb_object_ptr; 147 } 148 149 SBAddress SBFunction::GetStartAddress() { 150 SBAddress addr; 151 if (m_opaque_ptr) 152 addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 153 return addr; 154 } 155 156 SBAddress SBFunction::GetEndAddress() { 157 SBAddress addr; 158 if (m_opaque_ptr) { 159 addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize(); 160 if (byte_size > 0) { 161 addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 162 addr->Slide(byte_size); 163 } 164 } 165 return addr; 166 } 167 168 const char *SBFunction::GetArgumentName(uint32_t arg_idx) { 169 if (m_opaque_ptr) { 170 Block &block = m_opaque_ptr->GetBlock(true); 171 VariableListSP variable_list_sp = block.GetBlockVariableList(true); 172 if (variable_list_sp) { 173 VariableList arguments; 174 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, 175 arguments, true); 176 lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx); 177 if (variable_sp) 178 return variable_sp->GetName().GetCString(); 179 } 180 } 181 return nullptr; 182 } 183 184 uint32_t SBFunction::GetPrologueByteSize() { 185 if (m_opaque_ptr) 186 return m_opaque_ptr->GetPrologueByteSize(); 187 return 0; 188 } 189 190 SBType SBFunction::GetType() { 191 SBType sb_type; 192 if (m_opaque_ptr) { 193 Type *function_type = m_opaque_ptr->GetType(); 194 if (function_type) 195 sb_type.ref().SetType(function_type->shared_from_this()); 196 } 197 return sb_type; 198 } 199 200 SBBlock SBFunction::GetBlock() { 201 SBBlock sb_block; 202 if (m_opaque_ptr) 203 sb_block.SetPtr(&m_opaque_ptr->GetBlock(true)); 204 return sb_block; 205 } 206 207 lldb::LanguageType SBFunction::GetLanguage() { 208 if (m_opaque_ptr) { 209 if (m_opaque_ptr->GetCompileUnit()) 210 return m_opaque_ptr->GetCompileUnit()->GetLanguage(); 211 } 212 return lldb::eLanguageTypeUnknown; 213 } 214 215 bool SBFunction::GetIsOptimized() { 216 if (m_opaque_ptr) { 217 if (m_opaque_ptr->GetCompileUnit()) 218 return m_opaque_ptr->GetCompileUnit()->GetIsOptimized(); 219 } 220 return false; 221 } 222