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 "lldb/API/SBAddressRange.h" 11 #include "lldb/API/SBProcess.h" 12 #include "lldb/API/SBStream.h" 13 #include "lldb/Core/AddressRangeListImpl.h" 14 #include "lldb/Core/Disassembler.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Symbol/CompileUnit.h" 17 #include "lldb/Symbol/Function.h" 18 #include "lldb/Symbol/Type.h" 19 #include "lldb/Symbol/VariableList.h" 20 #include "lldb/Target/ExecutionContext.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Utility/Instrumentation.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 SBFunction::SBFunction() { LLDB_INSTRUMENT_VA(this); } 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_INSTRUMENT_VA(this, rhs); 35 } 36 37 const SBFunction &SBFunction::operator=(const SBFunction &rhs) { 38 LLDB_INSTRUMENT_VA(this, rhs); 39 40 m_opaque_ptr = rhs.m_opaque_ptr; 41 return *this; 42 } 43 44 SBFunction::~SBFunction() { m_opaque_ptr = nullptr; } 45 46 bool SBFunction::IsValid() const { 47 LLDB_INSTRUMENT_VA(this); 48 return this->operator bool(); 49 } 50 SBFunction::operator bool() const { 51 LLDB_INSTRUMENT_VA(this); 52 53 return m_opaque_ptr != nullptr; 54 } 55 56 const char *SBFunction::GetName() const { 57 LLDB_INSTRUMENT_VA(this); 58 59 if (m_opaque_ptr) 60 return m_opaque_ptr->GetName().AsCString(); 61 62 return nullptr; 63 } 64 65 const char *SBFunction::GetDisplayName() const { 66 LLDB_INSTRUMENT_VA(this); 67 68 if (m_opaque_ptr) 69 return m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString(); 70 71 return nullptr; 72 } 73 74 const char *SBFunction::GetMangledName() const { 75 LLDB_INSTRUMENT_VA(this); 76 77 if (m_opaque_ptr) 78 return m_opaque_ptr->GetMangled().GetMangledName().AsCString(); 79 return nullptr; 80 } 81 82 bool SBFunction::operator==(const SBFunction &rhs) const { 83 LLDB_INSTRUMENT_VA(this, rhs); 84 85 return m_opaque_ptr == rhs.m_opaque_ptr; 86 } 87 88 bool SBFunction::operator!=(const SBFunction &rhs) const { 89 LLDB_INSTRUMENT_VA(this, rhs); 90 91 return m_opaque_ptr != rhs.m_opaque_ptr; 92 } 93 94 bool SBFunction::GetDescription(SBStream &s) { 95 LLDB_INSTRUMENT_VA(this, s); 96 97 if (m_opaque_ptr) { 98 s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s", 99 m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString()); 100 Type *func_type = m_opaque_ptr->GetType(); 101 if (func_type) 102 s.Printf(", type = %s", func_type->GetName().AsCString()); 103 return true; 104 } 105 s.Printf("No value"); 106 return false; 107 } 108 109 SBInstructionList SBFunction::GetInstructions(SBTarget target) { 110 LLDB_INSTRUMENT_VA(this, target); 111 112 return GetInstructions(target, nullptr); 113 } 114 115 SBInstructionList SBFunction::GetInstructions(SBTarget target, 116 const char *flavor) { 117 LLDB_INSTRUMENT_VA(this, target, flavor); 118 119 SBInstructionList sb_instructions; 120 if (m_opaque_ptr) { 121 TargetSP target_sp(target.GetSP()); 122 std::unique_lock<std::recursive_mutex> lock; 123 ModuleSP module_sp(m_opaque_ptr->GetAddress().GetModule()); 124 if (target_sp && module_sp) { 125 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 126 const bool force_live_memory = true; 127 sb_instructions.SetDisassembler(Disassembler::DisassembleRange( 128 module_sp->GetArchitecture(), nullptr, flavor, 129 target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(), 130 *target_sp, m_opaque_ptr->GetAddressRanges(), force_live_memory)); 131 } 132 } 133 return sb_instructions; 134 } 135 136 lldb_private::Function *SBFunction::get() { return m_opaque_ptr; } 137 138 void SBFunction::reset(lldb_private::Function *lldb_object_ptr) { 139 m_opaque_ptr = lldb_object_ptr; 140 } 141 142 SBAddress SBFunction::GetStartAddress() { 143 LLDB_INSTRUMENT_VA(this); 144 145 SBAddress addr; 146 if (m_opaque_ptr) 147 addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress()); 148 return addr; 149 } 150 151 SBAddress SBFunction::GetEndAddress() { 152 LLDB_INSTRUMENT_VA(this); 153 154 SBAddress addr; 155 if (m_opaque_ptr) { 156 AddressRanges ranges = m_opaque_ptr->GetAddressRanges(); 157 if (!ranges.empty()) { 158 // Return the end of the first range, use GetRanges to get all ranges. 159 addr.SetAddress(ranges.front().GetBaseAddress()); 160 addr->Slide(ranges.front().GetByteSize()); 161 } 162 } 163 return addr; 164 } 165 166 lldb::SBAddressRangeList SBFunction::GetRanges() { 167 LLDB_INSTRUMENT_VA(this); 168 169 lldb::SBAddressRangeList ranges; 170 if (m_opaque_ptr) 171 ranges.ref() = AddressRangeListImpl(m_opaque_ptr->GetAddressRanges()); 172 173 return ranges; 174 } 175 176 const char *SBFunction::GetArgumentName(uint32_t arg_idx) { 177 LLDB_INSTRUMENT_VA(this, arg_idx); 178 179 if (!m_opaque_ptr) 180 return nullptr; 181 182 Block &block = m_opaque_ptr->GetBlock(true); 183 VariableListSP variable_list_sp = block.GetBlockVariableList(true); 184 if (!variable_list_sp) 185 return nullptr; 186 187 VariableList arguments; 188 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, 189 arguments, true); 190 lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx); 191 if (!variable_sp) 192 return nullptr; 193 194 return variable_sp->GetName().GetCString(); 195 } 196 197 uint32_t SBFunction::GetPrologueByteSize() { 198 LLDB_INSTRUMENT_VA(this); 199 200 if (m_opaque_ptr) 201 return m_opaque_ptr->GetPrologueByteSize(); 202 return 0; 203 } 204 205 SBType SBFunction::GetType() { 206 LLDB_INSTRUMENT_VA(this); 207 208 SBType sb_type; 209 if (m_opaque_ptr) { 210 Type *function_type = m_opaque_ptr->GetType(); 211 if (function_type) 212 sb_type.ref().SetType(function_type->shared_from_this()); 213 } 214 return sb_type; 215 } 216 217 SBBlock SBFunction::GetBlock() { 218 LLDB_INSTRUMENT_VA(this); 219 220 SBBlock sb_block; 221 if (m_opaque_ptr) 222 sb_block.SetPtr(&m_opaque_ptr->GetBlock(true)); 223 return sb_block; 224 } 225 226 lldb::LanguageType SBFunction::GetLanguage() { 227 LLDB_INSTRUMENT_VA(this); 228 229 if (m_opaque_ptr) { 230 if (m_opaque_ptr->GetCompileUnit()) 231 return m_opaque_ptr->GetCompileUnit()->GetLanguage(); 232 } 233 return lldb::eLanguageTypeUnknown; 234 } 235 236 bool SBFunction::GetIsOptimized() { 237 LLDB_INSTRUMENT_VA(this); 238 239 if (m_opaque_ptr) { 240 if (m_opaque_ptr->GetCompileUnit()) 241 return m_opaque_ptr->GetCompileUnit()->GetIsOptimized(); 242 } 243 return false; 244 } 245