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 void
62 SBModule::Clear()
63 {
64     m_opaque_sp.reset();
65 }
66 
67 SBFileSpec
68 SBModule::GetFileSpec () const
69 {
70     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
71 
72     SBFileSpec file_spec;
73     if (m_opaque_sp)
74         file_spec.SetFileSpec(m_opaque_sp->GetFileSpec());
75 
76     if (log)
77     {
78         log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
79         m_opaque_sp.get(), file_spec.get());
80     }
81 
82     return file_spec;
83 }
84 
85 lldb::SBFileSpec
86 SBModule::GetPlatformFileSpec () const
87 {
88     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
89 
90     SBFileSpec file_spec;
91     if (m_opaque_sp)
92         file_spec.SetFileSpec(m_opaque_sp->GetPlatformFileSpec());
93 
94     if (log)
95     {
96         log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
97                      m_opaque_sp.get(), file_spec.get());
98     }
99 
100     return file_spec;
101 
102 }
103 
104 bool
105 SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
106 {
107     bool result = false;
108     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
109 
110     if (m_opaque_sp)
111     {
112         m_opaque_sp->SetPlatformFileSpec(*platform_file);
113         result = true;
114     }
115 
116     if (log)
117     {
118         log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i",
119                      m_opaque_sp.get(),
120                      platform_file.get(),
121                      platform_file->GetDirectory().GetCString(),
122                      platform_file->GetDirectory() ? "/" : "",
123                      platform_file->GetFilename().GetCString(),
124                      result);
125     }
126     return result;
127 }
128 
129 
130 
131 const uint8_t *
132 SBModule::GetUUIDBytes () const
133 {
134     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
135 
136     const uint8_t *uuid_bytes = NULL;
137     if (m_opaque_sp)
138         uuid_bytes = (const uint8_t *)m_opaque_sp->GetUUID().GetBytes();
139 
140     if (log)
141     {
142         if (uuid_bytes)
143         {
144             StreamString s;
145             m_opaque_sp->GetUUID().Dump (&s);
146             log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", m_opaque_sp.get(), s.GetData());
147         }
148         else
149             log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", m_opaque_sp.get());
150     }
151     return uuid_bytes;
152 }
153 
154 
155 const char *
156 SBModule::GetUUIDString () const
157 {
158     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
159 
160     static char uuid_string[80];
161     const char * uuid_c_string = NULL;
162     if (m_opaque_sp)
163         uuid_c_string = (const char *)m_opaque_sp->GetUUID().GetAsCString(uuid_string, sizeof(uuid_string));
164 
165     if (log)
166     {
167         if (uuid_c_string)
168         {
169             StreamString s;
170             m_opaque_sp->GetUUID().Dump (&s);
171             log->Printf ("SBModule(%p)::GetUUIDString () => %s", m_opaque_sp.get(), s.GetData());
172         }
173         else
174             log->Printf ("SBModule(%p)::GetUUIDString () => NULL", m_opaque_sp.get());
175     }
176     return uuid_c_string;
177 }
178 
179 
180 bool
181 SBModule::operator == (const SBModule &rhs) const
182 {
183     if (m_opaque_sp)
184         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
185     return false;
186 }
187 
188 bool
189 SBModule::operator != (const SBModule &rhs) const
190 {
191     if (m_opaque_sp)
192         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
193     return false;
194 }
195 
196 lldb::ModuleSP &
197 SBModule::operator *()
198 {
199     return m_opaque_sp;
200 }
201 
202 lldb_private::Module *
203 SBModule::operator ->()
204 {
205     return m_opaque_sp.get();
206 }
207 
208 const lldb_private::Module *
209 SBModule::operator ->() const
210 {
211     return m_opaque_sp.get();
212 }
213 
214 lldb_private::Module *
215 SBModule::get()
216 {
217     return m_opaque_sp.get();
218 }
219 
220 const lldb_private::Module *
221 SBModule::get() const
222 {
223     return m_opaque_sp.get();
224 }
225 
226 const lldb::ModuleSP &
227 SBModule::get_sp() const
228 {
229     return m_opaque_sp;
230 }
231 
232 void
233 SBModule::SetModule (const lldb::ModuleSP& module_sp)
234 {
235     m_opaque_sp = module_sp;
236 }
237 
238 
239 SBAddress
240 SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
241 {
242     lldb::SBAddress sb_addr;
243     if (m_opaque_sp)
244     {
245         Address addr;
246         if (m_opaque_sp->ResolveFileAddress (vm_addr, addr))
247             sb_addr.ref() = addr;
248     }
249     return sb_addr;
250 }
251 
252 SBSymbolContext
253 SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
254 {
255     SBSymbolContext sb_sc;
256     if (m_opaque_sp && addr.IsValid())
257         m_opaque_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
258     return sb_sc;
259 }
260 
261 bool
262 SBModule::GetDescription (SBStream &description)
263 {
264     Stream &strm = description.ref();
265 
266     if (m_opaque_sp)
267     {
268         m_opaque_sp->GetDescription (&strm);
269     }
270     else
271         strm.PutCString ("No value");
272 
273     return true;
274 }
275 
276 size_t
277 SBModule::GetNumSymbols ()
278 {
279     if (m_opaque_sp)
280     {
281         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
282         if (obj_file)
283         {
284             Symtab *symtab = obj_file->GetSymtab();
285             if (symtab)
286                 return symtab->GetNumSymbols();
287         }
288     }
289     return 0;
290 }
291 
292 SBSymbol
293 SBModule::GetSymbolAtIndex (size_t idx)
294 {
295     SBSymbol sb_symbol;
296     if (m_opaque_sp)
297     {
298         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
299         if (obj_file)
300         {
301             Symtab *symtab = obj_file->GetSymtab();
302             if (symtab)
303                 sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
304         }
305     }
306     return sb_symbol;
307 }
308 
309 size_t
310 SBModule::GetNumSections ()
311 {
312     if (m_opaque_sp)
313     {
314         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
315         if (obj_file)
316         {
317             SectionList *section_list = obj_file->GetSectionList ();
318             if (section_list)
319                 return section_list->GetSize();
320         }
321     }
322     return 0;
323 }
324 
325 SBSection
326 SBModule::GetSectionAtIndex (size_t idx)
327 {
328     SBSection sb_section;
329     if (m_opaque_sp)
330     {
331         ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
332         if (obj_file)
333         {
334             SectionList *section_list = obj_file->GetSectionList ();
335 
336             if (section_list)
337                 sb_section.SetSection(section_list->GetSectionAtIndex (idx).get());
338         }
339     }
340     return sb_section;
341 }
342 
343 uint32_t
344 SBModule::FindFunctions (const char *name,
345                          uint32_t name_type_mask,
346                          bool append,
347                          lldb::SBSymbolContextList& sc_list)
348 {
349     if (!append)
350         sc_list.Clear();
351     if (name && m_opaque_sp)
352     {
353         const bool symbols_ok = true;
354         return m_opaque_sp->FindFunctions (ConstString(name),
355                                            NULL,
356                                            name_type_mask,
357                                            symbols_ok,
358                                            append,
359                                            *sc_list);
360     }
361     return 0;
362 }
363 
364 
365 SBValueList
366 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
367 {
368     SBValueList sb_value_list;
369     if (name && m_opaque_sp)
370     {
371         VariableList variable_list;
372         const uint32_t match_count = m_opaque_sp->FindGlobalVariables (ConstString (name),
373                                                                        NULL,
374                                                                        false,
375                                                                        max_matches,
376                                                                        variable_list);
377 
378         if (match_count > 0)
379         {
380             ValueObjectList &value_object_list = sb_value_list.ref();
381             for (uint32_t i=0; i<match_count; ++i)
382             {
383                 lldb::ValueObjectSP valobj_sp;
384                 if (target.IsValid())
385                     valobj_sp = ValueObjectVariable::Create (target.get(), variable_list.GetVariableAtIndex(i));
386                 else
387                     valobj_sp = ValueObjectVariable::Create (NULL, variable_list.GetVariableAtIndex(i));
388                 if (valobj_sp)
389                     value_object_list.Append(valobj_sp);
390             }
391         }
392     }
393 
394     return sb_value_list;
395 }
396 
397 lldb::SBType
398 SBModule::FindFirstType (const char *name_cstr)
399 {
400     SBType sb_type;
401     if (name_cstr && IsValid())
402     {
403         SymbolContext sc;
404         TypeList type_list;
405         uint32_t num_matches = 0;
406         ConstString name(name_cstr);
407 
408         num_matches = m_opaque_sp->FindTypes(sc,
409                                              name,
410                                              NULL,
411                                              false,
412                                              1,
413                                              type_list);
414 
415         if (num_matches)
416             sb_type = lldb::SBType(type_list.GetTypeAtIndex(0));
417     }
418     return sb_type;
419 }
420 
421 lldb::SBTypeList
422 SBModule::FindTypes (const char *type)
423 {
424 
425     SBTypeList retval;
426 
427     if (type && IsValid())
428     {
429         SymbolContext sc;
430         TypeList type_list;
431         uint32_t num_matches = 0;
432         ConstString name(type);
433 
434         num_matches = m_opaque_sp->FindTypes(sc,
435                                              name,
436                                              NULL,
437                                              false,
438                                              UINT32_MAX,
439                                              type_list);
440 
441         for (size_t idx = 0; idx < num_matches; idx++)
442         {
443             TypeSP type_sp (type_list.GetTypeAtIndex(idx));
444             if (type_sp)
445                 retval.Append(SBType(type_sp));
446         }
447     }
448 
449     return retval;
450 }
451 
452 
453 SBSection
454 SBModule::FindSection (const char *sect_name)
455 {
456     SBSection sb_section;
457 
458     if (sect_name && IsValid())
459     {
460         ObjectFile *objfile = m_opaque_sp->GetObjectFile();
461         if (objfile)
462         {
463             SectionList *section_list = objfile->GetSectionList();
464             if (section_list)
465             {
466                 ConstString const_sect_name(sect_name);
467                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
468                 if (section_sp)
469                 {
470                     sb_section.SetSection(section_sp.get());
471                 }
472             }
473         }
474     }
475     return sb_section;
476 }
477 
478