xref: /src/contrib/llvm-project/lldb/source/API/SBFunction.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1cfca06d7SDimitry Andric //===-- SBFunction.cpp ----------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste 
9f034231aSEd Maste #include "lldb/API/SBFunction.h"
10ac9a064cSDimitry Andric #include "lldb/API/SBAddressRange.h"
11f034231aSEd Maste #include "lldb/API/SBProcess.h"
12f034231aSEd Maste #include "lldb/API/SBStream.h"
13f034231aSEd Maste #include "lldb/Core/Disassembler.h"
14f034231aSEd Maste #include "lldb/Core/Module.h"
15f034231aSEd Maste #include "lldb/Symbol/CompileUnit.h"
16f034231aSEd Maste #include "lldb/Symbol/Function.h"
17f034231aSEd Maste #include "lldb/Symbol/Type.h"
18e81d9d49SDimitry Andric #include "lldb/Symbol/VariableList.h"
19f034231aSEd Maste #include "lldb/Target/ExecutionContext.h"
20f034231aSEd Maste #include "lldb/Target/Target.h"
216f8fc217SDimitry Andric #include "lldb/Utility/Instrumentation.h"
22f034231aSEd Maste 
23f034231aSEd Maste using namespace lldb;
24f034231aSEd Maste using namespace lldb_private;
25f034231aSEd Maste 
SBFunction()266f8fc217SDimitry Andric SBFunction::SBFunction() { LLDB_INSTRUMENT_VA(this); }
27f034231aSEd Maste 
SBFunction(lldb_private::Function * lldb_object_ptr)2814f1b3e8SDimitry Andric SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr)
2914f1b3e8SDimitry Andric     : m_opaque_ptr(lldb_object_ptr) {}
30f034231aSEd Maste 
SBFunction(const lldb::SBFunction & rhs)3114f1b3e8SDimitry Andric SBFunction::SBFunction(const lldb::SBFunction &rhs)
325f29bb8aSDimitry Andric     : m_opaque_ptr(rhs.m_opaque_ptr) {
336f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
34f034231aSEd Maste }
35f034231aSEd Maste 
operator =(const SBFunction & rhs)365f29bb8aSDimitry Andric const SBFunction &SBFunction::operator=(const SBFunction &rhs) {
376f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
38f034231aSEd Maste 
395f29bb8aSDimitry Andric   m_opaque_ptr = rhs.m_opaque_ptr;
406f8fc217SDimitry Andric   return *this;
415f29bb8aSDimitry Andric }
425f29bb8aSDimitry Andric 
~SBFunction()435f29bb8aSDimitry Andric SBFunction::~SBFunction() { m_opaque_ptr = nullptr; }
445f29bb8aSDimitry Andric 
IsValid() const455f29bb8aSDimitry Andric bool SBFunction::IsValid() const {
466f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
475f29bb8aSDimitry Andric   return this->operator bool();
485f29bb8aSDimitry Andric }
operator bool() const495f29bb8aSDimitry Andric SBFunction::operator bool() const {
506f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
515f29bb8aSDimitry Andric 
525f29bb8aSDimitry Andric   return m_opaque_ptr != nullptr;
535f29bb8aSDimitry Andric }
54f034231aSEd Maste 
GetName() const5514f1b3e8SDimitry Andric const char *SBFunction::GetName() const {
566f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
575f29bb8aSDimitry Andric 
58f034231aSEd Maste   if (m_opaque_ptr)
597fa27ce4SDimitry Andric     return m_opaque_ptr->GetName().AsCString();
60f034231aSEd Maste 
617fa27ce4SDimitry Andric   return nullptr;
62f034231aSEd Maste }
63f034231aSEd Maste 
GetDisplayName() const6414f1b3e8SDimitry Andric const char *SBFunction::GetDisplayName() const {
656f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
665f29bb8aSDimitry Andric 
67027f1c96SDimitry Andric   if (m_opaque_ptr)
687fa27ce4SDimitry Andric     return m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString();
69027f1c96SDimitry Andric 
707fa27ce4SDimitry Andric   return nullptr;
71027f1c96SDimitry Andric }
72027f1c96SDimitry Andric 
GetMangledName() const7314f1b3e8SDimitry Andric const char *SBFunction::GetMangledName() const {
746f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
755f29bb8aSDimitry Andric 
76f034231aSEd Maste   if (m_opaque_ptr)
777fa27ce4SDimitry Andric     return m_opaque_ptr->GetMangled().GetMangledName().AsCString();
787fa27ce4SDimitry Andric   return nullptr;
79f034231aSEd Maste }
80f034231aSEd Maste 
operator ==(const SBFunction & rhs) const8114f1b3e8SDimitry Andric bool SBFunction::operator==(const SBFunction &rhs) const {
826f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
835f29bb8aSDimitry Andric 
84f034231aSEd Maste   return m_opaque_ptr == rhs.m_opaque_ptr;
85f034231aSEd Maste }
86f034231aSEd Maste 
operator !=(const SBFunction & rhs) const8714f1b3e8SDimitry Andric bool SBFunction::operator!=(const SBFunction &rhs) const {
886f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
895f29bb8aSDimitry Andric 
90f034231aSEd Maste   return m_opaque_ptr != rhs.m_opaque_ptr;
91f034231aSEd Maste }
92f034231aSEd Maste 
GetDescription(SBStream & s)9314f1b3e8SDimitry Andric bool SBFunction::GetDescription(SBStream &s) {
946f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, s);
955f29bb8aSDimitry Andric 
9614f1b3e8SDimitry Andric   if (m_opaque_ptr) {
97f034231aSEd Maste     s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
9814f1b3e8SDimitry Andric              m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString());
99f034231aSEd Maste     Type *func_type = m_opaque_ptr->GetType();
100f034231aSEd Maste     if (func_type)
101f034231aSEd Maste       s.Printf(", type = %s", func_type->GetName().AsCString());
102f034231aSEd Maste     return true;
103f034231aSEd Maste   }
104f034231aSEd Maste   s.Printf("No value");
105f034231aSEd Maste   return false;
106f034231aSEd Maste }
107f034231aSEd Maste 
GetInstructions(SBTarget target)10814f1b3e8SDimitry Andric SBInstructionList SBFunction::GetInstructions(SBTarget target) {
1096f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, target);
1105f29bb8aSDimitry Andric 
1116f8fc217SDimitry Andric   return GetInstructions(target, nullptr);
112f034231aSEd Maste }
113f034231aSEd Maste 
GetInstructions(SBTarget target,const char * flavor)11414f1b3e8SDimitry Andric SBInstructionList SBFunction::GetInstructions(SBTarget target,
11514f1b3e8SDimitry Andric                                               const char *flavor) {
1166f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, target, flavor);
1175f29bb8aSDimitry Andric 
118f034231aSEd Maste   SBInstructionList sb_instructions;
11914f1b3e8SDimitry Andric   if (m_opaque_ptr) {
120f034231aSEd Maste     TargetSP target_sp(target.GetSP());
121f3fbd1c0SDimitry Andric     std::unique_lock<std::recursive_mutex> lock;
12214f1b3e8SDimitry Andric     ModuleSP module_sp(
12314f1b3e8SDimitry Andric         m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
124cfca06d7SDimitry Andric     if (target_sp && module_sp) {
125cfca06d7SDimitry Andric       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
126344a3780SDimitry Andric       const bool force_live_memory = true;
12714f1b3e8SDimitry Andric       sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
128cfca06d7SDimitry Andric           module_sp->GetArchitecture(), nullptr, flavor, *target_sp,
129344a3780SDimitry Andric           m_opaque_ptr->GetAddressRange(), force_live_memory));
130f034231aSEd Maste     }
131f034231aSEd Maste   }
1326f8fc217SDimitry Andric   return sb_instructions;
133f034231aSEd Maste }
134f034231aSEd Maste 
get()13514f1b3e8SDimitry Andric lldb_private::Function *SBFunction::get() { return m_opaque_ptr; }
136f034231aSEd Maste 
reset(lldb_private::Function * lldb_object_ptr)13714f1b3e8SDimitry Andric void SBFunction::reset(lldb_private::Function *lldb_object_ptr) {
138f034231aSEd Maste   m_opaque_ptr = lldb_object_ptr;
139f034231aSEd Maste }
140f034231aSEd Maste 
GetStartAddress()14114f1b3e8SDimitry Andric SBAddress SBFunction::GetStartAddress() {
1426f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1435f29bb8aSDimitry Andric 
144f034231aSEd Maste   SBAddress addr;
145f034231aSEd Maste   if (m_opaque_ptr)
146b60736ecSDimitry Andric     addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
1476f8fc217SDimitry Andric   return addr;
148f034231aSEd Maste }
149f034231aSEd Maste 
GetEndAddress()15014f1b3e8SDimitry Andric SBAddress SBFunction::GetEndAddress() {
1516f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1525f29bb8aSDimitry Andric 
153f034231aSEd Maste   SBAddress addr;
15414f1b3e8SDimitry Andric   if (m_opaque_ptr) {
155f034231aSEd Maste     addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
15614f1b3e8SDimitry Andric     if (byte_size > 0) {
157b60736ecSDimitry Andric       addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
158f034231aSEd Maste       addr->Slide(byte_size);
159f034231aSEd Maste     }
160f034231aSEd Maste   }
1616f8fc217SDimitry Andric   return addr;
162f034231aSEd Maste }
163f034231aSEd Maste 
GetRanges()164ac9a064cSDimitry Andric lldb::SBAddressRangeList SBFunction::GetRanges() {
165ac9a064cSDimitry Andric   LLDB_INSTRUMENT_VA(this);
166ac9a064cSDimitry Andric 
167ac9a064cSDimitry Andric   lldb::SBAddressRangeList ranges;
168ac9a064cSDimitry Andric   if (m_opaque_ptr) {
169ac9a064cSDimitry Andric     lldb::SBAddressRange range;
170ac9a064cSDimitry Andric     (*range.m_opaque_up) = m_opaque_ptr->GetAddressRange();
171ac9a064cSDimitry Andric     ranges.Append(std::move(range));
172ac9a064cSDimitry Andric   }
173ac9a064cSDimitry Andric 
174ac9a064cSDimitry Andric   return ranges;
175ac9a064cSDimitry Andric }
176ac9a064cSDimitry Andric 
GetArgumentName(uint32_t arg_idx)17714f1b3e8SDimitry Andric const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
1786f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, arg_idx);
1795f29bb8aSDimitry Andric 
1807fa27ce4SDimitry Andric   if (!m_opaque_ptr)
1817fa27ce4SDimitry Andric     return nullptr;
1827fa27ce4SDimitry Andric 
183e81d9d49SDimitry Andric   Block &block = m_opaque_ptr->GetBlock(true);
184e81d9d49SDimitry Andric   VariableListSP variable_list_sp = block.GetBlockVariableList(true);
1857fa27ce4SDimitry Andric   if (!variable_list_sp)
1867fa27ce4SDimitry Andric     return nullptr;
1877fa27ce4SDimitry Andric 
188e81d9d49SDimitry Andric   VariableList arguments;
18914f1b3e8SDimitry Andric   variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
19014f1b3e8SDimitry Andric                                              arguments, true);
191e81d9d49SDimitry Andric   lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
1927fa27ce4SDimitry Andric   if (!variable_sp)
193e81d9d49SDimitry Andric     return nullptr;
1947fa27ce4SDimitry Andric 
1957fa27ce4SDimitry Andric   return variable_sp->GetName().GetCString();
196e81d9d49SDimitry Andric }
197f034231aSEd Maste 
GetPrologueByteSize()19814f1b3e8SDimitry Andric uint32_t SBFunction::GetPrologueByteSize() {
1996f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2005f29bb8aSDimitry Andric 
201f034231aSEd Maste   if (m_opaque_ptr)
202f034231aSEd Maste     return m_opaque_ptr->GetPrologueByteSize();
203f034231aSEd Maste   return 0;
204f034231aSEd Maste }
205f034231aSEd Maste 
GetType()20614f1b3e8SDimitry Andric SBType SBFunction::GetType() {
2076f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2085f29bb8aSDimitry Andric 
209f034231aSEd Maste   SBType sb_type;
21014f1b3e8SDimitry Andric   if (m_opaque_ptr) {
211f034231aSEd Maste     Type *function_type = m_opaque_ptr->GetType();
212f034231aSEd Maste     if (function_type)
213f034231aSEd Maste       sb_type.ref().SetType(function_type->shared_from_this());
214f034231aSEd Maste   }
2156f8fc217SDimitry Andric   return sb_type;
216f034231aSEd Maste }
217f034231aSEd Maste 
GetBlock()21814f1b3e8SDimitry Andric SBBlock SBFunction::GetBlock() {
2196f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2205f29bb8aSDimitry Andric 
221f034231aSEd Maste   SBBlock sb_block;
222f034231aSEd Maste   if (m_opaque_ptr)
223f034231aSEd Maste     sb_block.SetPtr(&m_opaque_ptr->GetBlock(true));
2246f8fc217SDimitry Andric   return sb_block;
225f034231aSEd Maste }
226f034231aSEd Maste 
GetLanguage()22714f1b3e8SDimitry Andric lldb::LanguageType SBFunction::GetLanguage() {
2286f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2295f29bb8aSDimitry Andric 
23014f1b3e8SDimitry Andric   if (m_opaque_ptr) {
231205afe67SEd Maste     if (m_opaque_ptr->GetCompileUnit())
232205afe67SEd Maste       return m_opaque_ptr->GetCompileUnit()->GetLanguage();
233205afe67SEd Maste   }
234205afe67SEd Maste   return lldb::eLanguageTypeUnknown;
235205afe67SEd Maste }
236f034231aSEd Maste 
GetIsOptimized()23714f1b3e8SDimitry Andric bool SBFunction::GetIsOptimized() {
2386f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2395f29bb8aSDimitry Andric 
24014f1b3e8SDimitry Andric   if (m_opaque_ptr) {
241e81d9d49SDimitry Andric     if (m_opaque_ptr->GetCompileUnit())
242e81d9d49SDimitry Andric       return m_opaque_ptr->GetCompileUnit()->GetIsOptimized();
243e81d9d49SDimitry Andric   }
244e81d9d49SDimitry Andric   return false;
245e81d9d49SDimitry Andric }
246