130fdc8d8SChris Lattner //===-- SBFunction.cpp ------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 930fdc8d8SChris Lattner #include "lldb/API/SBFunction.h" 1030fdc8d8SChris Lattner #include "lldb/API/SBProcess.h" 11dde9cff3SCaroline Tice #include "lldb/API/SBStream.h" 121d273166SGreg Clayton #include "lldb/Core/Disassembler.h" 131d273166SGreg Clayton #include "lldb/Core/Module.h" 141d273166SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 1530fdc8d8SChris Lattner #include "lldb/Symbol/Function.h" 1605faeb71SGreg Clayton #include "lldb/Symbol/Type.h" 17fe68904fSGreg Clayton #include "lldb/Symbol/VariableList.h" 181d273166SGreg Clayton #include "lldb/Target/ExecutionContext.h" 191d273166SGreg Clayton #include "lldb/Target/Target.h" 206f9e6901SZachary Turner #include "lldb/Utility/Log.h" 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner using namespace lldb; 231d273166SGreg Clayton using namespace lldb_private; 2430fdc8d8SChris Lattner 25b9c1b51eSKate Stone SBFunction::SBFunction() : m_opaque_ptr(NULL) {} 2630fdc8d8SChris Lattner 27b9c1b51eSKate Stone SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr) 28b9c1b51eSKate Stone : m_opaque_ptr(lldb_object_ptr) {} 2930fdc8d8SChris Lattner 30b9c1b51eSKate Stone SBFunction::SBFunction(const lldb::SBFunction &rhs) 31b9c1b51eSKate Stone : m_opaque_ptr(rhs.m_opaque_ptr) {} 32efabb123SGreg Clayton 33b9c1b51eSKate Stone const SBFunction &SBFunction::operator=(const SBFunction &rhs) { 34efabb123SGreg Clayton m_opaque_ptr = rhs.m_opaque_ptr; 35efabb123SGreg Clayton return *this; 36efabb123SGreg Clayton } 37efabb123SGreg Clayton 38b9c1b51eSKate Stone SBFunction::~SBFunction() { m_opaque_ptr = NULL; } 3930fdc8d8SChris Lattner 40b9c1b51eSKate Stone bool SBFunction::IsValid() const { return m_opaque_ptr != NULL; } 4130fdc8d8SChris Lattner 42b9c1b51eSKate Stone const char *SBFunction::GetName() const { 43cfd1acedSGreg Clayton const char *cstr = NULL; 446611103cSGreg Clayton if (m_opaque_ptr) 45ddaf6a72SGreg Clayton cstr = m_opaque_ptr->GetName().AsCString(); 46ceb6b139SCaroline Tice 475160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 48b9c1b51eSKate Stone if (log) { 49cfd1acedSGreg Clayton if (cstr) 50324a1036SSaleem Abdulrasool log->Printf("SBFunction(%p)::GetName () => \"%s\"", 51324a1036SSaleem Abdulrasool static_cast<void *>(m_opaque_ptr), cstr); 52cfd1acedSGreg Clayton else 53324a1036SSaleem Abdulrasool log->Printf("SBFunction(%p)::GetName () => NULL", 54324a1036SSaleem Abdulrasool static_cast<void *>(m_opaque_ptr)); 55cfd1acedSGreg Clayton } 56cfd1acedSGreg Clayton return cstr; 5730fdc8d8SChris Lattner } 5830fdc8d8SChris Lattner 59b9c1b51eSKate Stone const char *SBFunction::GetDisplayName() const { 60c1f705c2SEnrico Granata const char *cstr = NULL; 61c1f705c2SEnrico Granata if (m_opaque_ptr) 62b9c1b51eSKate Stone cstr = m_opaque_ptr->GetMangled() 63b9c1b51eSKate Stone .GetDisplayDemangledName(m_opaque_ptr->GetLanguage()) 64b9c1b51eSKate Stone .AsCString(); 65c1f705c2SEnrico Granata 66c1f705c2SEnrico Granata Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 67b9c1b51eSKate Stone if (log) { 68c1f705c2SEnrico Granata if (cstr) 69c1f705c2SEnrico Granata log->Printf("SBFunction(%p)::GetDisplayName () => \"%s\"", 70c1f705c2SEnrico Granata static_cast<void *>(m_opaque_ptr), cstr); 71c1f705c2SEnrico Granata else 72c1f705c2SEnrico Granata log->Printf("SBFunction(%p)::GetDisplayName () => NULL", 73c1f705c2SEnrico Granata static_cast<void *>(m_opaque_ptr)); 74c1f705c2SEnrico Granata } 75c1f705c2SEnrico Granata return cstr; 76c1f705c2SEnrico Granata } 77c1f705c2SEnrico Granata 78b9c1b51eSKate Stone const char *SBFunction::GetMangledName() const { 79cfd1acedSGreg Clayton const char *cstr = NULL; 806611103cSGreg Clayton if (m_opaque_ptr) 81cfd1acedSGreg Clayton cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString(); 825160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 83b9c1b51eSKate Stone if (log) { 84cfd1acedSGreg Clayton if (cstr) 85324a1036SSaleem Abdulrasool log->Printf("SBFunction(%p)::GetMangledName () => \"%s\"", 86324a1036SSaleem Abdulrasool static_cast<void *>(m_opaque_ptr), cstr); 87cfd1acedSGreg Clayton else 88324a1036SSaleem Abdulrasool log->Printf("SBFunction(%p)::GetMangledName () => NULL", 89324a1036SSaleem Abdulrasool static_cast<void *>(m_opaque_ptr)); 90cfd1acedSGreg Clayton } 91cfd1acedSGreg Clayton return cstr; 9230fdc8d8SChris Lattner } 9330fdc8d8SChris Lattner 94b9c1b51eSKate Stone bool SBFunction::operator==(const SBFunction &rhs) const { 956611103cSGreg Clayton return m_opaque_ptr == rhs.m_opaque_ptr; 9630fdc8d8SChris Lattner } 9730fdc8d8SChris Lattner 98b9c1b51eSKate Stone bool SBFunction::operator!=(const SBFunction &rhs) const { 996611103cSGreg Clayton return m_opaque_ptr != rhs.m_opaque_ptr; 10030fdc8d8SChris Lattner } 101dde9cff3SCaroline Tice 102b9c1b51eSKate Stone bool SBFunction::GetDescription(SBStream &s) { 103b9c1b51eSKate Stone if (m_opaque_ptr) { 104d01b2953SDaniel Malea s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s", 105b9c1b51eSKate Stone m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString()); 10605faeb71SGreg Clayton Type *func_type = m_opaque_ptr->GetType(); 10705faeb71SGreg Clayton if (func_type) 10805faeb71SGreg Clayton s.Printf(", type = %s", func_type->GetName().AsCString()); 109dde9cff3SCaroline Tice return true; 110dde9cff3SCaroline Tice } 11105faeb71SGreg Clayton s.Printf("No value"); 11205faeb71SGreg Clayton return false; 11305faeb71SGreg Clayton } 1141d273166SGreg Clayton 115b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target) { 1160f063ba6SJim Ingham return GetInstructions(target, NULL); 1170f063ba6SJim Ingham } 1180f063ba6SJim Ingham 119b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target, 120b9c1b51eSKate Stone const char *flavor) { 1211d273166SGreg Clayton SBInstructionList sb_instructions; 122b9c1b51eSKate Stone if (m_opaque_ptr) { 1231d273166SGreg Clayton ExecutionContext exe_ctx; 124b9556accSGreg Clayton TargetSP target_sp(target.GetSP()); 125bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 126b9c1b51eSKate Stone if (target_sp) { 127bb19a13cSSaleem Abdulrasool lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 128b9556accSGreg Clayton target_sp->CalculateExecutionContext(exe_ctx); 129b9556accSGreg Clayton exe_ctx.SetProcessSP(target_sp->GetProcessSP()); 1301d273166SGreg Clayton } 131b9c1b51eSKate Stone ModuleSP module_sp( 132b9c1b51eSKate Stone m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); 133b9c1b51eSKate Stone if (module_sp) { 1346b3e6d54SJason Molenda const bool prefer_file_cache = false; 135b9c1b51eSKate Stone sb_instructions.SetDisassembler(Disassembler::DisassembleRange( 136b9c1b51eSKate Stone module_sp->GetArchitecture(), NULL, flavor, exe_ctx, 137b9c1b51eSKate Stone m_opaque_ptr->GetAddressRange(), prefer_file_cache)); 1381d273166SGreg Clayton } 1391d273166SGreg Clayton } 1401d273166SGreg Clayton return sb_instructions; 1411d273166SGreg Clayton } 1421d273166SGreg Clayton 143b9c1b51eSKate Stone lldb_private::Function *SBFunction::get() { return m_opaque_ptr; } 1441d273166SGreg Clayton 145b9c1b51eSKate Stone void SBFunction::reset(lldb_private::Function *lldb_object_ptr) { 14672eff18aSGreg Clayton m_opaque_ptr = lldb_object_ptr; 14772eff18aSGreg Clayton } 14872eff18aSGreg Clayton 149b9c1b51eSKate Stone SBAddress SBFunction::GetStartAddress() { 15093d00df5SGreg Clayton SBAddress addr; 15193d00df5SGreg Clayton if (m_opaque_ptr) 15293d00df5SGreg Clayton addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 15393d00df5SGreg Clayton return addr; 15493d00df5SGreg Clayton } 15593d00df5SGreg Clayton 156b9c1b51eSKate Stone SBAddress SBFunction::GetEndAddress() { 15793d00df5SGreg Clayton SBAddress addr; 158b9c1b51eSKate Stone if (m_opaque_ptr) { 15993d00df5SGreg Clayton addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize(); 160b9c1b51eSKate Stone if (byte_size > 0) { 16193d00df5SGreg Clayton addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 16293d00df5SGreg Clayton addr->Slide(byte_size); 16393d00df5SGreg Clayton } 16493d00df5SGreg Clayton } 16593d00df5SGreg Clayton return addr; 16693d00df5SGreg Clayton } 16793d00df5SGreg Clayton 168b9c1b51eSKate Stone const char *SBFunction::GetArgumentName(uint32_t arg_idx) { 169b9c1b51eSKate Stone if (m_opaque_ptr) { 170fe68904fSGreg Clayton Block &block = m_opaque_ptr->GetBlock(true); 171fe68904fSGreg Clayton VariableListSP variable_list_sp = block.GetBlockVariableList(true); 172b9c1b51eSKate Stone if (variable_list_sp) { 173fe68904fSGreg Clayton VariableList arguments; 174b9c1b51eSKate Stone variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, 175b9c1b51eSKate Stone arguments, true); 176fe68904fSGreg Clayton lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx); 177fe68904fSGreg Clayton if (variable_sp) 178fe68904fSGreg Clayton return variable_sp->GetName().GetCString(); 179fe68904fSGreg Clayton } 180fe68904fSGreg Clayton } 181fe68904fSGreg Clayton return nullptr; 182fe68904fSGreg Clayton } 18393d00df5SGreg Clayton 184b9c1b51eSKate Stone uint32_t SBFunction::GetPrologueByteSize() { 18593d00df5SGreg Clayton if (m_opaque_ptr) 18693d00df5SGreg Clayton return m_opaque_ptr->GetPrologueByteSize(); 18793d00df5SGreg Clayton return 0; 18893d00df5SGreg Clayton } 18993d00df5SGreg Clayton 190b9c1b51eSKate Stone SBType SBFunction::GetType() { 1915569e64eSGreg Clayton SBType sb_type; 192b9c1b51eSKate Stone if (m_opaque_ptr) { 1935569e64eSGreg Clayton Type *function_type = m_opaque_ptr->GetType(); 1945569e64eSGreg Clayton if (function_type) 1955569e64eSGreg Clayton sb_type.ref().SetType(function_type->shared_from_this()); 1965569e64eSGreg Clayton } 1975569e64eSGreg Clayton return sb_type; 1985569e64eSGreg Clayton } 1995569e64eSGreg Clayton 200b9c1b51eSKate Stone SBBlock SBFunction::GetBlock() { 2015569e64eSGreg Clayton SBBlock sb_block; 2025569e64eSGreg Clayton if (m_opaque_ptr) 2035569e64eSGreg Clayton sb_block.SetPtr(&m_opaque_ptr->GetBlock(true)); 2045569e64eSGreg Clayton return sb_block; 2055569e64eSGreg Clayton } 2065569e64eSGreg Clayton 207b9c1b51eSKate Stone lldb::LanguageType SBFunction::GetLanguage() { 208b9c1b51eSKate Stone if (m_opaque_ptr) { 2096cd8e0c9SEnrico Granata if (m_opaque_ptr->GetCompileUnit()) 2106cd8e0c9SEnrico Granata return m_opaque_ptr->GetCompileUnit()->GetLanguage(); 2116cd8e0c9SEnrico Granata } 2126cd8e0c9SEnrico Granata return lldb::eLanguageTypeUnknown; 2136cd8e0c9SEnrico Granata } 2145569e64eSGreg Clayton 215b9c1b51eSKate Stone bool SBFunction::GetIsOptimized() { 216b9c1b51eSKate Stone if (m_opaque_ptr) { 2176ab659a9SJason Molenda if (m_opaque_ptr->GetCompileUnit()) 2186ab659a9SJason Molenda return m_opaque_ptr->GetCompileUnit()->GetIsOptimized(); 2196ab659a9SJason Molenda } 2206ab659a9SJason Molenda return false; 2216ab659a9SJason Molenda } 222