1 //===-- SBFunction.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/API/SBFunction.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/Log.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 SBFunction::SBFunction() : m_opaque_ptr(NULL) {} 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 34 const SBFunction &SBFunction::operator=(const SBFunction &rhs) { 35 m_opaque_ptr = rhs.m_opaque_ptr; 36 return *this; 37 } 38 39 SBFunction::~SBFunction() { m_opaque_ptr = NULL; } 40 41 bool SBFunction::IsValid() const { return m_opaque_ptr != NULL; } 42 43 const char *SBFunction::GetName() const { 44 const char *cstr = NULL; 45 if (m_opaque_ptr) 46 cstr = m_opaque_ptr->GetName().AsCString(); 47 48 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 49 if (log) { 50 if (cstr) 51 log->Printf("SBFunction(%p)::GetName () => \"%s\"", 52 static_cast<void *>(m_opaque_ptr), cstr); 53 else 54 log->Printf("SBFunction(%p)::GetName () => NULL", 55 static_cast<void *>(m_opaque_ptr)); 56 } 57 return cstr; 58 } 59 60 const char *SBFunction::GetDisplayName() const { 61 const char *cstr = NULL; 62 if (m_opaque_ptr) 63 cstr = m_opaque_ptr->GetMangled() 64 .GetDisplayDemangledName(m_opaque_ptr->GetLanguage()) 65 .AsCString(); 66 67 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 68 if (log) { 69 if (cstr) 70 log->Printf("SBFunction(%p)::GetDisplayName () => \"%s\"", 71 static_cast<void *>(m_opaque_ptr), cstr); 72 else 73 log->Printf("SBFunction(%p)::GetDisplayName () => NULL", 74 static_cast<void *>(m_opaque_ptr)); 75 } 76 return cstr; 77 } 78 79 const char *SBFunction::GetMangledName() const { 80 const char *cstr = NULL; 81 if (m_opaque_ptr) 82 cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString(); 83 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 84 if (log) { 85 if (cstr) 86 log->Printf("SBFunction(%p)::GetMangledName () => \"%s\"", 87 static_cast<void *>(m_opaque_ptr), cstr); 88 else 89 log->Printf("SBFunction(%p)::GetMangledName () => NULL", 90 static_cast<void *>(m_opaque_ptr)); 91 } 92 return cstr; 93 } 94 95 bool SBFunction::operator==(const SBFunction &rhs) const { 96 return m_opaque_ptr == rhs.m_opaque_ptr; 97 } 98 99 bool SBFunction::operator!=(const SBFunction &rhs) const { 100 return m_opaque_ptr != rhs.m_opaque_ptr; 101 } 102 103 bool SBFunction::GetDescription(SBStream &s) { 104 if (m_opaque_ptr) { 105 s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s", 106 m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString()); 107 Type *func_type = m_opaque_ptr->GetType(); 108 if (func_type) 109 s.Printf(", type = %s", func_type->GetName().AsCString()); 110 return true; 111 } 112 s.Printf("No value"); 113 return false; 114 } 115 116 SBInstructionList SBFunction::GetInstructions(SBTarget target) { 117 return GetInstructions(target, NULL); 118 } 119 120 SBInstructionList SBFunction::GetInstructions(SBTarget target, 121 const char *flavor) { 122 SBInstructionList sb_instructions; 123 if (m_opaque_ptr) { 124 ExecutionContext exe_ctx; 125 TargetSP target_sp(target.GetSP()); 126 std::unique_lock<std::recursive_mutex> lock; 127 if (target_sp) { 128 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 129 target_sp->CalculateExecutionContext(exe_ctx); 130 exe_ctx.SetProcessSP(target_sp->GetProcessSP()); 131 } 132 ModuleSP module_sp( 133 m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); 134 if (module_sp) { 135 const bool prefer_file_cache = false; 136 sb_instructions.SetDisassembler(Disassembler::DisassembleRange( 137 module_sp->GetArchitecture(), NULL, flavor, exe_ctx, 138 m_opaque_ptr->GetAddressRange(), prefer_file_cache)); 139 } 140 } 141 return sb_instructions; 142 } 143 144 lldb_private::Function *SBFunction::get() { return m_opaque_ptr; } 145 146 void SBFunction::reset(lldb_private::Function *lldb_object_ptr) { 147 m_opaque_ptr = lldb_object_ptr; 148 } 149 150 SBAddress SBFunction::GetStartAddress() { 151 SBAddress addr; 152 if (m_opaque_ptr) 153 addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 154 return addr; 155 } 156 157 SBAddress SBFunction::GetEndAddress() { 158 SBAddress addr; 159 if (m_opaque_ptr) { 160 addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize(); 161 if (byte_size > 0) { 162 addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); 163 addr->Slide(byte_size); 164 } 165 } 166 return addr; 167 } 168 169 const char *SBFunction::GetArgumentName(uint32_t arg_idx) { 170 if (m_opaque_ptr) { 171 Block &block = m_opaque_ptr->GetBlock(true); 172 VariableListSP variable_list_sp = block.GetBlockVariableList(true); 173 if (variable_list_sp) { 174 VariableList arguments; 175 variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, 176 arguments, true); 177 lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx); 178 if (variable_sp) 179 return variable_sp->GetName().GetCString(); 180 } 181 } 182 return nullptr; 183 } 184 185 uint32_t SBFunction::GetPrologueByteSize() { 186 if (m_opaque_ptr) 187 return m_opaque_ptr->GetPrologueByteSize(); 188 return 0; 189 } 190 191 SBType SBFunction::GetType() { 192 SBType sb_type; 193 if (m_opaque_ptr) { 194 Type *function_type = m_opaque_ptr->GetType(); 195 if (function_type) 196 sb_type.ref().SetType(function_type->shared_from_this()); 197 } 198 return sb_type; 199 } 200 201 SBBlock SBFunction::GetBlock() { 202 SBBlock sb_block; 203 if (m_opaque_ptr) 204 sb_block.SetPtr(&m_opaque_ptr->GetBlock(true)); 205 return sb_block; 206 } 207 208 lldb::LanguageType SBFunction::GetLanguage() { 209 if (m_opaque_ptr) { 210 if (m_opaque_ptr->GetCompileUnit()) 211 return m_opaque_ptr->GetCompileUnit()->GetLanguage(); 212 } 213 return lldb::eLanguageTypeUnknown; 214 } 215 216 bool SBFunction::GetIsOptimized() { 217 if (m_opaque_ptr) { 218 if (m_opaque_ptr->GetCompileUnit()) 219 return m_opaque_ptr->GetCompileUnit()->GetIsOptimized(); 220 } 221 return false; 222 } 223