1 //===-- SBModule.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/SBModule.h"
11 #include "lldb/API/SBAddress.h"
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBSymbolContextList.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/StreamString.h"
18 #include "lldb/Core/ValueObjectList.h"
19 #include "lldb/Core/ValueObjectVariable.h"
20 #include "lldb/Symbol/SymbolVendor.h"
21 #include "lldb/Symbol/VariableList.h"
22 #include "lldb/Target/Target.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 
28 SBModule::SBModule () :
29     m_opaque_sp ()
30 {
31 }
32 
33 SBModule::SBModule (const lldb::ModuleSP& module_sp) :
34     m_opaque_sp (module_sp)
35 {
36 }
37 
38 SBModule::SBModule(const SBModule &rhs) :
39     m_opaque_sp (rhs.m_opaque_sp)
40 {
41 }
42 
43 const SBModule &
44 SBModule::operator = (const SBModule &rhs)
45 {
46     if (this != &rhs)
47         m_opaque_sp = rhs.m_opaque_sp;
48     return *this;
49 }
50 
51 SBModule::~SBModule ()
52 {
53 }
54 
55 bool
56 SBModule::IsValid () const
57 {
58     return m_opaque_sp.get() != NULL;
59 }
60 
61 SBFileSpec
62 SBModule::GetFileSpec () const
63 {
64     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
65 
66     SBFileSpec file_spec;
67     if (m_opaque_sp)
68         file_spec.SetFileSpec(m_opaque_sp->GetFileSpec());
69 
70     if (log)
71     {
72         log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
73         m_opaque_sp.get(), file_spec.get());
74     }
75 
76     return file_spec;
77 }
78 
79 lldb::SBFileSpec
80 SBModule::GetPlatformFileSpec () const
81 {
82     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
83 
84     SBFileSpec file_spec;
85     if (m_opaque_sp)
86         file_spec.SetFileSpec(m_opaque_sp->GetPlatformFileSpec());
87 
88     if (log)
89     {
90         log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
91                      m_opaque_sp.get(), file_spec.get());
92     }
93 
94     return file_spec;
95 
96 }
97 
98 bool
99 SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
100 {
101     bool result = false;
102     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
103 
104     if (m_opaque_sp)
105     {
106         m_opaque_sp->SetPlatformFileSpec(*platform_file);
107         result = true;
108     }
109 
110     if (log)
111     {
112         log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i",
113                      m_opaque_sp.get(),
114                      platform_file.get(),
115                      platform_file->GetDirectory().GetCString(),
116                      platform_file->GetDirectory() ? "/" : "",
117                      platform_file->GetFilename().GetCString(),
118                      result);
119     }
120     return result;
121 }
122 
123 
124 
125 const uint8_t *
126 SBModule::GetUUIDBytes () const
127 {
128     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
129 
130     const uint8_t *uuid_bytes = NULL;
131     if (m_opaque_sp)
132         uuid_bytes = (const uint8_t *)m_opaque_sp->GetUUID().GetBytes();
133 
134     if (log)
135     {
136         if (uuid_bytes)
137         {
138             StreamString s;
139             m_opaque_sp->GetUUID().Dump (&s);
140             log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", m_opaque_sp.get(), s.GetData());
141         }
142         else
143             log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", m_opaque_sp.get());
144     }
145     return uuid_bytes;
146 }
147 
148 
149 const char *
150 SBModule::GetUUIDString () const
151 {
152     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
153 
154     static char uuid_string[80];
155     const char * uuid_c_string = NULL;
156     if (m_opaque_sp)
157         uuid_c_string = (const char *)m_opaque_sp->GetUUID().GetAsCString(uuid_string, sizeof(uuid_string));
158 
159     if (log)
160     {
161         if (uuid_c_string)
162         {
163             StreamString s;
164             m_opaque_sp->GetUUID().Dump (&s);
165             log->Printf ("SBModule(%p)::GetUUIDString () => %s", m_opaque_sp.get(), s.GetData());
166         }
167         else
168             log->Printf ("SBModule(%p)::GetUUIDString () => NULL", m_opaque_sp.get());
169     }
170     return uuid_c_string;
171 }
172 
173 
174 bool
175 SBModule::operator == (const SBModule &rhs) const
176 {
177     if (m_opaque_sp)
178         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
179     return false;
180 }
181 
182 bool
183 SBModule::operator != (const SBModule &rhs) const
184 {
185     if (m_opaque_sp)
186         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
187     return false;
188 }
189 
190 lldb::ModuleSP &
191 SBModule::operator *()
192 {
193     return m_opaque_sp;
194 }
195 
196 lldb_private::Module *
197 SBModule::operator ->()
198 {
199     return m_opaque_sp.get();
200 }
201 
202 const lldb_private::Module *
203 SBModule::operator ->() const
204 {
205     return m_opaque_sp.get();
206 }
207 
208 lldb_private::Module *
209 SBModule::get()
210 {
211     return m_opaque_sp.get();
212 }
213 
214 const lldb_private::Module *
215 SBModule::get() const
216 {
217     return m_opaque_sp.get();
218 }
219 
220 
221 void
222 SBModule::SetModule (const lldb::ModuleSP& module_sp)
223 {
224     m_opaque_sp = module_sp;
225 }
226 
227 
228 bool
229 SBModule::ResolveFileAddress (lldb::addr_t vm_addr, SBAddress& addr)
230 {
231     if (m_opaque_sp && addr.IsValid())
232         return m_opaque_sp->ResolveFileAddress (vm_addr, addr.ref());
233 
234     if (addr.IsValid())
235         addr->Clear();
236     return false;
237 }
238 
239 SBSymbolContext
240 SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
241 {
242     SBSymbolContext sb_sc;
243     if (m_opaque_sp && addr.IsValid())
244         m_opaque_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
245     return sb_sc;
246 }
247 
248 bool
249 SBModule::GetDescription (SBStream &description)
250 {
251     if (m_opaque_sp)
252     {
253         description.ref();
254         m_opaque_sp->GetDescription (description.get());
255     }
256     else
257         description.Printf ("No value");
258 
259     return true;
260 }
261 
262 size_t
263 SBModule::GetNumSymbols ()
264 {
265     if (m_opaque_sp)
266     {
267         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
268         if (obj_file)
269         {
270             Symtab *symtab = obj_file->GetSymtab();
271             if (symtab)
272                 return symtab->GetNumSymbols();
273         }
274     }
275     return 0;
276 }
277 
278 SBSymbol
279 SBModule::GetSymbolAtIndex (size_t idx)
280 {
281     SBSymbol sb_symbol;
282     if (m_opaque_sp)
283     {
284         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
285         if (obj_file)
286         {
287             Symtab *symtab = obj_file->GetSymtab();
288             if (symtab)
289                 sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
290         }
291     }
292     return sb_symbol;
293 }
294 
295 uint32_t
296 SBModule::FindFunctions (const char *name,
297                          uint32_t name_type_mask,
298                          bool append,
299                          lldb::SBSymbolContextList& sc_list)
300 {
301     if (!append)
302         sc_list.Clear();
303     if (m_opaque_sp)
304     {
305         const bool symbols_ok = true;
306         return m_opaque_sp->FindFunctions (ConstString(name),
307                                            name_type_mask,
308                                            symbols_ok,
309                                            append,
310                                            *sc_list);
311     }
312     return 0;
313 }
314 
315 
316 SBValueList
317 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
318 {
319     SBValueList sb_value_list;
320     if (m_opaque_sp)
321     {
322         VariableList variable_list;
323         const uint32_t match_count = m_opaque_sp->FindGlobalVariables (ConstString (name),
324                                                                        false,
325                                                                        max_matches,
326                                                                        variable_list);
327 
328         if (match_count > 0)
329         {
330             ValueObjectList &value_object_list = sb_value_list.ref();
331             for (uint32_t i=0; i<match_count; ++i)
332             {
333                 lldb::ValueObjectSP valobj_sp;
334                 if (target.IsValid())
335                     valobj_sp = ValueObjectVariable::Create (target.get(), variable_list.GetVariableAtIndex(i));
336                 else
337                     valobj_sp = ValueObjectVariable::Create (NULL, variable_list.GetVariableAtIndex(i));
338                 if (valobj_sp)
339                     value_object_list.Append(valobj_sp);
340             }
341         }
342     }
343 
344     return sb_value_list;
345 }
346 
347 lldb::SBType
348 SBModule::FindFirstType (const char* name_cstr)
349 {
350     SBType sb_type;
351     if (IsValid())
352     {
353         SymbolContext sc;
354         TypeList type_list;
355         uint32_t num_matches = 0;
356         ConstString name(name_cstr);
357 
358         num_matches = m_opaque_sp->FindTypes(sc,
359                                              name,
360                                              false,
361                                              1,
362                                              type_list);
363 
364         if (num_matches)
365             sb_type = lldb::SBType(type_list.GetTypeAtIndex(0));
366     }
367     return sb_type;
368 }
369 
370 lldb::SBTypeList
371 SBModule::FindTypes (const char* type)
372 {
373 
374     SBTypeList retval;
375 
376     if (IsValid())
377     {
378         SymbolContext sc;
379         TypeList type_list;
380         uint32_t num_matches = 0;
381         ConstString name(type);
382 
383         num_matches = m_opaque_sp->FindTypes(sc,
384                                              name,
385                                              false,
386                                              UINT32_MAX,
387                                              type_list);
388 
389         for (size_t idx = 0; idx < num_matches; idx++)
390         {
391             TypeSP type_sp (type_list.GetTypeAtIndex(idx));
392             if (type_sp)
393                 retval.Append(SBType(type_sp));
394         }
395     }
396 
397     return retval;
398 }
399