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