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