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/SBProcess.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/API/SBSymbolContextList.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/StreamString.h"
19 #include "lldb/Core/ValueObjectList.h"
20 #include "lldb/Core/ValueObjectVariable.h"
21 #include "lldb/Symbol/SymbolVendor.h"
22 #include "lldb/Symbol/VariableList.h"
23 #include "lldb/Target/Target.h"
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 
29 SBModule::SBModule () :
30     m_opaque_sp ()
31 {
32 }
33 
34 SBModule::SBModule (const lldb::ModuleSP& module_sp) :
35     m_opaque_sp (module_sp)
36 {
37 }
38 
39 SBModule::SBModule(const SBModule &rhs) :
40     m_opaque_sp (rhs.m_opaque_sp)
41 {
42 }
43 
44 SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) :
45     m_opaque_sp ()
46 {
47     ProcessSP process_sp (process.GetSP());
48     if (process_sp)
49     {
50         const bool add_image_to_target = true;
51         const bool load_image_sections_in_target = true;
52         m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(),
53                                                         header_addr,
54                                                         add_image_to_target,
55                                                         load_image_sections_in_target);
56     }
57 }
58 
59 const SBModule &
60 SBModule::operator = (const SBModule &rhs)
61 {
62     if (this != &rhs)
63         m_opaque_sp = rhs.m_opaque_sp;
64     return *this;
65 }
66 
67 SBModule::~SBModule ()
68 {
69 }
70 
71 bool
72 SBModule::IsValid () const
73 {
74     return m_opaque_sp.get() != NULL;
75 }
76 
77 void
78 SBModule::Clear()
79 {
80     m_opaque_sp.reset();
81 }
82 
83 SBFileSpec
84 SBModule::GetFileSpec () const
85 {
86     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
87 
88     SBFileSpec file_spec;
89     ModuleSP module_sp (GetSP ());
90     if (module_sp)
91         file_spec.SetFileSpec(module_sp->GetFileSpec());
92 
93     if (log)
94     {
95         log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
96         module_sp.get(), file_spec.get());
97     }
98 
99     return file_spec;
100 }
101 
102 lldb::SBFileSpec
103 SBModule::GetPlatformFileSpec () const
104 {
105     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
106 
107     SBFileSpec file_spec;
108     ModuleSP module_sp (GetSP ());
109     if (module_sp)
110         file_spec.SetFileSpec(module_sp->GetPlatformFileSpec());
111 
112     if (log)
113     {
114         log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
115                      module_sp.get(), file_spec.get());
116     }
117 
118     return file_spec;
119 
120 }
121 
122 bool
123 SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
124 {
125     bool result = false;
126     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
127 
128     ModuleSP module_sp (GetSP ());
129     if (module_sp)
130     {
131         module_sp->SetPlatformFileSpec(*platform_file);
132         result = true;
133     }
134 
135     if (log)
136     {
137         log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i",
138                      module_sp.get(),
139                      platform_file.get(),
140                      platform_file->GetDirectory().GetCString(),
141                      platform_file->GetDirectory() ? "/" : "",
142                      platform_file->GetFilename().GetCString(),
143                      result);
144     }
145     return result;
146 }
147 
148 
149 
150 const uint8_t *
151 SBModule::GetUUIDBytes () const
152 {
153     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
154 
155     const uint8_t *uuid_bytes = NULL;
156     ModuleSP module_sp (GetSP ());
157     if (module_sp)
158         uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes();
159 
160     if (log)
161     {
162         if (uuid_bytes)
163         {
164             StreamString s;
165             module_sp->GetUUID().Dump (&s);
166             log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData());
167         }
168         else
169             log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get());
170     }
171     return uuid_bytes;
172 }
173 
174 
175 const char *
176 SBModule::GetUUIDString () const
177 {
178     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
179 
180     static char uuid_string[80];
181     const char * uuid_c_string = NULL;
182     ModuleSP module_sp (GetSP ());
183     if (module_sp)
184         uuid_c_string = (const char *)module_sp->GetUUID().GetAsCString(uuid_string, sizeof(uuid_string));
185 
186     if (log)
187     {
188         if (uuid_c_string)
189         {
190             StreamString s;
191             module_sp->GetUUID().Dump (&s);
192             log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData());
193         }
194         else
195             log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get());
196     }
197     return uuid_c_string;
198 }
199 
200 
201 bool
202 SBModule::operator == (const SBModule &rhs) const
203 {
204     if (m_opaque_sp)
205         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
206     return false;
207 }
208 
209 bool
210 SBModule::operator != (const SBModule &rhs) const
211 {
212     if (m_opaque_sp)
213         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
214     return false;
215 }
216 
217 ModuleSP
218 SBModule::GetSP () const
219 {
220     return m_opaque_sp;
221 }
222 
223 void
224 SBModule::SetSP (const ModuleSP &module_sp)
225 {
226     m_opaque_sp = module_sp;
227 }
228 
229 SBAddress
230 SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
231 {
232     lldb::SBAddress sb_addr;
233     ModuleSP module_sp (GetSP ());
234     if (module_sp)
235     {
236         Address addr;
237         if (module_sp->ResolveFileAddress (vm_addr, addr))
238             sb_addr.ref() = addr;
239     }
240     return sb_addr;
241 }
242 
243 SBSymbolContext
244 SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
245 {
246     SBSymbolContext sb_sc;
247     ModuleSP module_sp (GetSP ());
248     if (module_sp && addr.IsValid())
249         module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
250     return sb_sc;
251 }
252 
253 bool
254 SBModule::GetDescription (SBStream &description)
255 {
256     Stream &strm = description.ref();
257 
258     ModuleSP module_sp (GetSP ());
259     if (module_sp)
260     {
261         module_sp->GetDescription (&strm);
262     }
263     else
264         strm.PutCString ("No value");
265 
266     return true;
267 }
268 
269 uint32_t
270 SBModule::GetNumCompileUnits()
271 {
272     ModuleSP module_sp (GetSP ());
273     if (module_sp)
274     {
275         return module_sp->GetNumCompileUnits ();
276     }
277     return 0;
278 }
279 
280 SBCompileUnit
281 SBModule::GetCompileUnitAtIndex (uint32_t index)
282 {
283     SBCompileUnit sb_cu;
284     ModuleSP module_sp (GetSP ());
285     if (module_sp)
286     {
287         CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex (index);
288         sb_cu.reset(cu_sp.get());
289     }
290     return sb_cu;
291 }
292 
293 size_t
294 SBModule::GetNumSymbols ()
295 {
296     ModuleSP module_sp (GetSP ());
297     if (module_sp)
298     {
299         ObjectFile *obj_file = module_sp->GetObjectFile();
300         if (obj_file)
301         {
302             Symtab *symtab = obj_file->GetSymtab();
303             if (symtab)
304                 return symtab->GetNumSymbols();
305         }
306     }
307     return 0;
308 }
309 
310 SBSymbol
311 SBModule::GetSymbolAtIndex (size_t idx)
312 {
313     SBSymbol sb_symbol;
314     ModuleSP module_sp (GetSP ());
315     if (module_sp)
316     {
317         ObjectFile *obj_file = module_sp->GetObjectFile();
318         if (obj_file)
319         {
320             Symtab *symtab = obj_file->GetSymtab();
321             if (symtab)
322                 sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
323         }
324     }
325     return sb_symbol;
326 }
327 
328 size_t
329 SBModule::GetNumSections ()
330 {
331     ModuleSP module_sp (GetSP ());
332     if (module_sp)
333     {
334         ObjectFile *obj_file = module_sp->GetObjectFile();
335         if (obj_file)
336         {
337             SectionList *section_list = obj_file->GetSectionList ();
338             if (section_list)
339                 return section_list->GetSize();
340         }
341     }
342     return 0;
343 }
344 
345 SBSection
346 SBModule::GetSectionAtIndex (size_t idx)
347 {
348     SBSection sb_section;
349     ModuleSP module_sp (GetSP ());
350     if (module_sp)
351     {
352         ObjectFile *obj_file = module_sp->GetObjectFile();
353         if (obj_file)
354         {
355             SectionList *section_list = obj_file->GetSectionList ();
356 
357             if (section_list)
358                 sb_section.SetSP(section_list->GetSectionAtIndex (idx));
359         }
360     }
361     return sb_section;
362 }
363 
364 lldb::SBSymbolContextList
365 SBModule::FindFunctions (const char *name,
366                          uint32_t name_type_mask)
367 {
368     lldb::SBSymbolContextList sb_sc_list;
369     ModuleSP module_sp (GetSP ());
370     if (name && module_sp)
371     {
372         const bool append = true;
373         const bool symbols_ok = true;
374         const bool inlines_ok = true;
375         module_sp->FindFunctions (ConstString(name),
376                                   NULL,
377                                   name_type_mask,
378                                   symbols_ok,
379                                   inlines_ok,
380                                   append,
381                                   *sb_sc_list);
382     }
383     return sb_sc_list;
384 }
385 
386 
387 SBValueList
388 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
389 {
390     SBValueList sb_value_list;
391     ModuleSP module_sp (GetSP ());
392     if (name && module_sp)
393     {
394         VariableList variable_list;
395         const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name),
396                                                                      NULL,
397                                                                      false,
398                                                                      max_matches,
399                                                                      variable_list);
400 
401         if (match_count > 0)
402         {
403             ValueObjectList &value_object_list = sb_value_list.ref();
404             for (uint32_t i=0; i<match_count; ++i)
405             {
406                 lldb::ValueObjectSP valobj_sp;
407                 TargetSP target_sp (target.GetSP());
408                 valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
409                 if (valobj_sp)
410                     value_object_list.Append(valobj_sp);
411             }
412         }
413     }
414 
415     return sb_value_list;
416 }
417 
418 lldb::SBType
419 SBModule::FindFirstType (const char *name_cstr)
420 {
421     SBType sb_type;
422     ModuleSP module_sp (GetSP ());
423     if (name_cstr && module_sp)
424     {
425         SymbolContext sc;
426         TypeList type_list;
427         uint32_t num_matches = 0;
428         const bool exact_match = false;
429         ConstString name(name_cstr);
430 
431         num_matches = module_sp->FindTypes (sc,
432                                             name,
433                                             exact_match,
434                                             1,
435                                             type_list);
436 
437         if (num_matches)
438             sb_type = lldb::SBType(type_list.GetTypeAtIndex(0));
439     }
440     return sb_type;
441 }
442 
443 lldb::SBTypeList
444 SBModule::FindTypes (const char *type)
445 {
446 
447     SBTypeList retval;
448 
449     ModuleSP module_sp (GetSP ());
450     if (type && module_sp)
451     {
452         SymbolContext sc;
453         TypeList type_list;
454         const bool exact_match = false;
455         uint32_t num_matches = 0;
456         ConstString name(type);
457 
458         num_matches = module_sp->FindTypes (sc,
459                                             name,
460                                             exact_match,
461                                             UINT32_MAX,
462                                             type_list);
463 
464         for (size_t idx = 0; idx < num_matches; idx++)
465         {
466             TypeSP type_sp (type_list.GetTypeAtIndex(idx));
467             if (type_sp)
468                 retval.Append(SBType(type_sp));
469         }
470     }
471 
472     return retval;
473 }
474 
475 
476 SBSection
477 SBModule::FindSection (const char *sect_name)
478 {
479     SBSection sb_section;
480 
481     ModuleSP module_sp (GetSP ());
482     if (sect_name && module_sp)
483     {
484         ObjectFile *objfile = module_sp->GetObjectFile();
485         if (objfile)
486         {
487             SectionList *section_list = objfile->GetSectionList();
488             if (section_list)
489             {
490                 ConstString const_sect_name(sect_name);
491                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
492                 if (section_sp)
493                 {
494                     sb_section.SetSP (section_sp);
495                 }
496             }
497         }
498     }
499     return sb_section;
500 }
501 
502 lldb::ByteOrder
503 SBModule::GetByteOrder ()
504 {
505     ModuleSP module_sp (GetSP ());
506     if (module_sp)
507         return module_sp->GetArchitecture().GetByteOrder();
508     return eByteOrderInvalid;
509 }
510 
511 const char *
512 SBModule::GetTriple ()
513 {
514     ModuleSP module_sp (GetSP ());
515     if (module_sp)
516     {
517         std::string triple (module_sp->GetArchitecture().GetTriple().str());
518         // Unique the string so we don't run into ownership issues since
519         // the const strings put the string into the string pool once and
520         // the strings never comes out
521         ConstString const_triple (triple.c_str());
522         return const_triple.GetCString();
523     }
524     return NULL;
525 }
526 
527 uint32_t
528 SBModule::GetAddressByteSize()
529 {
530     ModuleSP module_sp (GetSP ());
531     if (module_sp)
532         return module_sp->GetArchitecture().GetAddressByteSize();
533     return sizeof(void*);
534 }
535 
536 
537 uint32_t
538 SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
539 {
540     ModuleSP module_sp (GetSP ());
541     if (module_sp)
542     {
543         ObjectFile *obj_file = module_sp->GetObjectFile();
544         if (obj_file)
545             return obj_file->GetVersion (versions, num_versions);
546     }
547 
548     if (versions && num_versions)
549     {
550         for (uint32_t i=0; i<num_versions; ++i)
551             versions[i] = UINT32_MAX;
552     }
553     return 0;
554 }
555 
556