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/Log.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/Target/ExecutionContext.h"
20 #include "lldb/Target/Target.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 SBFunction::SBFunction () :
26     m_opaque_ptr (NULL)
27 {
28 }
29 
30 SBFunction::SBFunction (lldb_private::Function *lldb_object_ptr) :
31     m_opaque_ptr (lldb_object_ptr)
32 {
33 }
34 
35 SBFunction::SBFunction (const lldb::SBFunction &rhs) :
36     m_opaque_ptr (rhs.m_opaque_ptr)
37 {
38 }
39 
40 const SBFunction &
41 SBFunction::operator = (const SBFunction &rhs)
42 {
43     m_opaque_ptr = rhs.m_opaque_ptr;
44     return *this;
45 }
46 
47 SBFunction::~SBFunction ()
48 {
49     m_opaque_ptr = NULL;
50 }
51 
52 bool
53 SBFunction::IsValid () const
54 {
55     return m_opaque_ptr != NULL;
56 }
57 
58 const char *
59 SBFunction::GetName() const
60 {
61     const char *cstr = NULL;
62     if (m_opaque_ptr)
63         cstr = m_opaque_ptr->GetName().AsCString();
64 
65     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
66     if (log)
67     {
68         if (cstr)
69             log->Printf ("SBFunction(%p)::GetName () => \"%s\"",
70                          static_cast<void*>(m_opaque_ptr), cstr);
71         else
72             log->Printf ("SBFunction(%p)::GetName () => NULL",
73                          static_cast<void*>(m_opaque_ptr));
74     }
75     return cstr;
76 }
77 
78 const char *
79 SBFunction::GetDisplayName() const
80 {
81     const char *cstr = NULL;
82     if (m_opaque_ptr)
83         cstr = m_opaque_ptr->GetMangled().GetDisplayDemangledName(m_opaque_ptr->GetLanguage()).AsCString();
84 
85     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
86     if (log)
87     {
88         if (cstr)
89         log->Printf ("SBFunction(%p)::GetDisplayName () => \"%s\"",
90                      static_cast<void*>(m_opaque_ptr), cstr);
91         else
92         log->Printf ("SBFunction(%p)::GetDisplayName () => NULL",
93                      static_cast<void*>(m_opaque_ptr));
94     }
95     return cstr;
96 }
97 
98 const char *
99 SBFunction::GetMangledName () const
100 {
101     const char *cstr = NULL;
102     if (m_opaque_ptr)
103         cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
104     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
105     if (log)
106     {
107         if (cstr)
108             log->Printf ("SBFunction(%p)::GetMangledName () => \"%s\"",
109                          static_cast<void*>(m_opaque_ptr), cstr);
110         else
111             log->Printf ("SBFunction(%p)::GetMangledName () => NULL",
112                          static_cast<void*>(m_opaque_ptr));
113     }
114     return cstr;
115 }
116 
117 bool
118 SBFunction::operator == (const SBFunction &rhs) const
119 {
120     return m_opaque_ptr == rhs.m_opaque_ptr;
121 }
122 
123 bool
124 SBFunction::operator != (const SBFunction &rhs) const
125 {
126     return m_opaque_ptr != rhs.m_opaque_ptr;
127 }
128 
129 bool
130 SBFunction::GetDescription (SBStream &s)
131 {
132     if (m_opaque_ptr)
133     {
134         s.Printf ("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
135                   m_opaque_ptr->GetID(),
136                   m_opaque_ptr->GetName().AsCString());
137         Type *func_type = m_opaque_ptr->GetType();
138         if (func_type)
139             s.Printf(", type = %s", func_type->GetName().AsCString());
140         return true;
141     }
142     s.Printf ("No value");
143     return false;
144 }
145 
146 SBInstructionList
147 SBFunction::GetInstructions (SBTarget target)
148 {
149     return GetInstructions (target, NULL);
150 }
151 
152 SBInstructionList
153 SBFunction::GetInstructions (SBTarget target, const char *flavor)
154 {
155     SBInstructionList sb_instructions;
156     if (m_opaque_ptr)
157     {
158         Mutex::Locker api_locker;
159         ExecutionContext exe_ctx;
160         TargetSP target_sp (target.GetSP());
161         if (target_sp)
162         {
163             api_locker.Lock (target_sp->GetAPIMutex());
164             target_sp->CalculateExecutionContext (exe_ctx);
165             exe_ctx.SetProcessSP(target_sp->GetProcessSP());
166         }
167         ModuleSP module_sp (m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
168         if (module_sp)
169         {
170             const bool prefer_file_cache = false;
171             sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture(),
172                                                                              NULL,
173                                                                              flavor,
174                                                                              exe_ctx,
175                                                                              m_opaque_ptr->GetAddressRange(),
176                                                                              prefer_file_cache));
177         }
178     }
179     return sb_instructions;
180 }
181 
182 lldb_private::Function *
183 SBFunction::get ()
184 {
185     return m_opaque_ptr;
186 }
187 
188 void
189 SBFunction::reset (lldb_private::Function *lldb_object_ptr)
190 {
191     m_opaque_ptr = lldb_object_ptr;
192 }
193 
194 SBAddress
195 SBFunction::GetStartAddress ()
196 {
197     SBAddress addr;
198     if (m_opaque_ptr)
199         addr.SetAddress (&m_opaque_ptr->GetAddressRange().GetBaseAddress());
200     return addr;
201 }
202 
203 SBAddress
204 SBFunction::GetEndAddress ()
205 {
206     SBAddress addr;
207     if (m_opaque_ptr)
208     {
209         addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
210         if (byte_size > 0)
211         {
212             addr.SetAddress (&m_opaque_ptr->GetAddressRange().GetBaseAddress());
213             addr->Slide (byte_size);
214         }
215     }
216     return addr;
217 }
218 
219 
220 uint32_t
221 SBFunction::GetPrologueByteSize ()
222 {
223     if (m_opaque_ptr)
224         return m_opaque_ptr->GetPrologueByteSize();
225     return 0;
226 }
227 
228 SBType
229 SBFunction::GetType ()
230 {
231     SBType sb_type;
232     if (m_opaque_ptr)
233     {
234         Type *function_type = m_opaque_ptr->GetType();
235         if (function_type)
236             sb_type.ref().SetType (function_type->shared_from_this());
237     }
238     return sb_type;
239 }
240 
241 SBBlock
242 SBFunction::GetBlock ()
243 {
244     SBBlock sb_block;
245     if (m_opaque_ptr)
246         sb_block.SetPtr (&m_opaque_ptr->GetBlock (true));
247     return sb_block;
248 }
249 
250 lldb::LanguageType
251 SBFunction::GetLanguage ()
252 {
253     if (m_opaque_ptr)
254     {
255         if (m_opaque_ptr->GetCompileUnit())
256             return m_opaque_ptr->GetCompileUnit()->GetLanguage();
257     }
258     return lldb::eLanguageTypeUnknown;
259 }
260 
261 
262