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