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     Log *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     Log *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     Log *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)) => %i",
143                      module_sp.get(),
144                      platform_file.get(),
145                      platform_file->GetPath().c_str(),
146                      result);
147     }
148     return result;
149 }
150 
151 
152 
153 const uint8_t *
154 SBModule::GetUUIDBytes () const
155 {
156     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
157 
158     const uint8_t *uuid_bytes = NULL;
159     ModuleSP module_sp (GetSP ());
160     if (module_sp)
161         uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes();
162 
163     if (log)
164     {
165         if (uuid_bytes)
166         {
167             StreamString s;
168             module_sp->GetUUID().Dump (&s);
169             log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData());
170         }
171         else
172             log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get());
173     }
174     return uuid_bytes;
175 }
176 
177 
178 const char *
179 SBModule::GetUUIDString () const
180 {
181     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
182 
183     static char uuid_string_buffer[80];
184     const char *uuid_c_string = NULL;
185     std::string uuid_string;
186     ModuleSP module_sp (GetSP ());
187     if (module_sp)
188         uuid_string = module_sp->GetUUID().GetAsString();
189 
190     if (!uuid_string.empty())
191     {
192         strncpy (uuid_string_buffer, uuid_string.c_str(), sizeof (uuid_string_buffer));
193         uuid_c_string = uuid_string_buffer;
194     }
195 
196     if (log)
197     {
198         if (!uuid_string.empty())
199         {
200             StreamString s;
201             module_sp->GetUUID().Dump (&s);
202             log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData());
203         }
204         else
205             log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get());
206     }
207     return uuid_c_string;
208 }
209 
210 
211 bool
212 SBModule::operator == (const SBModule &rhs) const
213 {
214     if (m_opaque_sp)
215         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
216     return false;
217 }
218 
219 bool
220 SBModule::operator != (const SBModule &rhs) const
221 {
222     if (m_opaque_sp)
223         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
224     return false;
225 }
226 
227 ModuleSP
228 SBModule::GetSP () const
229 {
230     return m_opaque_sp;
231 }
232 
233 void
234 SBModule::SetSP (const ModuleSP &module_sp)
235 {
236     m_opaque_sp = module_sp;
237 }
238 
239 SBAddress
240 SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
241 {
242     lldb::SBAddress sb_addr;
243     ModuleSP module_sp (GetSP ());
244     if (module_sp)
245     {
246         Address addr;
247         if (module_sp->ResolveFileAddress (vm_addr, addr))
248             sb_addr.ref() = addr;
249     }
250     return sb_addr;
251 }
252 
253 SBSymbolContext
254 SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
255 {
256     SBSymbolContext sb_sc;
257     ModuleSP module_sp (GetSP ());
258     if (module_sp && addr.IsValid())
259         module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
260     return sb_sc;
261 }
262 
263 bool
264 SBModule::GetDescription (SBStream &description)
265 {
266     Stream &strm = description.ref();
267 
268     ModuleSP module_sp (GetSP ());
269     if (module_sp)
270     {
271         module_sp->GetDescription (&strm);
272     }
273     else
274         strm.PutCString ("No value");
275 
276     return true;
277 }
278 
279 uint32_t
280 SBModule::GetNumCompileUnits()
281 {
282     ModuleSP module_sp (GetSP ());
283     if (module_sp)
284     {
285         return module_sp->GetNumCompileUnits ();
286     }
287     return 0;
288 }
289 
290 SBCompileUnit
291 SBModule::GetCompileUnitAtIndex (uint32_t index)
292 {
293     SBCompileUnit sb_cu;
294     ModuleSP module_sp (GetSP ());
295     if (module_sp)
296     {
297         CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex (index);
298         sb_cu.reset(cu_sp.get());
299     }
300     return sb_cu;
301 }
302 
303 static Symtab *
304 GetUnifiedSymbolTable (const lldb::ModuleSP& module_sp)
305 {
306     if (module_sp)
307     {
308         SymbolVendor *symbols = module_sp->GetSymbolVendor();
309         if (symbols)
310             return symbols->GetSymtab();
311     }
312     return NULL;
313 }
314 
315 size_t
316 SBModule::GetNumSymbols ()
317 {
318     ModuleSP module_sp (GetSP ());
319     if (module_sp)
320     {
321         Symtab *symtab = GetUnifiedSymbolTable (module_sp);
322         if (symtab)
323             return symtab->GetNumSymbols();
324     }
325     return 0;
326 }
327 
328 SBSymbol
329 SBModule::GetSymbolAtIndex (size_t idx)
330 {
331     SBSymbol sb_symbol;
332     ModuleSP module_sp (GetSP ());
333     Symtab *symtab = GetUnifiedSymbolTable (module_sp);
334     if (symtab)
335         sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
336     return sb_symbol;
337 }
338 
339 lldb::SBSymbol
340 SBModule::FindSymbol (const char *name,
341                       lldb::SymbolType symbol_type)
342 {
343     SBSymbol sb_symbol;
344     if (name && name[0])
345     {
346         ModuleSP module_sp (GetSP ());
347         Symtab *symtab = GetUnifiedSymbolTable (module_sp);
348         if (symtab)
349             sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(ConstString(name), symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny));
350     }
351     return sb_symbol;
352 }
353 
354 
355 lldb::SBSymbolContextList
356 SBModule::FindSymbols (const char *name, lldb::SymbolType symbol_type)
357 {
358     SBSymbolContextList sb_sc_list;
359     if (name && name[0])
360     {
361         ModuleSP module_sp (GetSP ());
362         Symtab *symtab = GetUnifiedSymbolTable (module_sp);
363         if (symtab)
364         {
365             std::vector<uint32_t> matching_symbol_indexes;
366             const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, matching_symbol_indexes);
367             if (num_matches)
368             {
369                 SymbolContext sc;
370                 sc.module_sp = module_sp;
371                 SymbolContextList &sc_list = *sb_sc_list;
372                 for (size_t i=0; i<num_matches; ++i)
373                 {
374                     sc.symbol = symtab->SymbolAtIndex (matching_symbol_indexes[i]);
375                     if (sc.symbol)
376                         sc_list.Append(sc);
377                 }
378             }
379         }
380     }
381     return sb_sc_list;
382 
383 }
384 
385 
386 
387 size_t
388 SBModule::GetNumSections ()
389 {
390     ModuleSP module_sp (GetSP ());
391     if (module_sp)
392     {
393         // Give the symbol vendor a chance to add to the unified section list.
394         module_sp->GetSymbolVendor();
395         SectionList *section_list = module_sp->GetUnifiedSectionList();
396         if (section_list)
397             return section_list->GetSize();
398     }
399     return 0;
400 }
401 
402 SBSection
403 SBModule::GetSectionAtIndex (size_t idx)
404 {
405     SBSection sb_section;
406     ModuleSP module_sp (GetSP ());
407     if (module_sp)
408     {
409         // Give the symbol vendor a chance to add to the unified section list.
410         module_sp->GetSymbolVendor();
411         SectionList *section_list = module_sp->GetUnifiedSectionList ();
412 
413         if (section_list)
414             sb_section.SetSP(section_list->GetSectionAtIndex (idx));
415     }
416     return sb_section;
417 }
418 
419 lldb::SBSymbolContextList
420 SBModule::FindFunctions (const char *name,
421                          uint32_t name_type_mask)
422 {
423     lldb::SBSymbolContextList sb_sc_list;
424     ModuleSP module_sp (GetSP ());
425     if (name && module_sp)
426     {
427         const bool append = true;
428         const bool symbols_ok = true;
429         const bool inlines_ok = true;
430         module_sp->FindFunctions (ConstString(name),
431                                   NULL,
432                                   name_type_mask,
433                                   symbols_ok,
434                                   inlines_ok,
435                                   append,
436                                   *sb_sc_list);
437     }
438     return sb_sc_list;
439 }
440 
441 
442 SBValueList
443 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
444 {
445     SBValueList sb_value_list;
446     ModuleSP module_sp (GetSP ());
447     if (name && module_sp)
448     {
449         VariableList variable_list;
450         const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name),
451                                                                      NULL,
452                                                                      false,
453                                                                      max_matches,
454                                                                      variable_list);
455 
456         if (match_count > 0)
457         {
458             for (uint32_t i=0; i<match_count; ++i)
459             {
460                 lldb::ValueObjectSP valobj_sp;
461                 TargetSP target_sp (target.GetSP());
462                 valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
463                 if (valobj_sp)
464                     sb_value_list.Append(SBValue(valobj_sp));
465             }
466         }
467     }
468 
469     return sb_value_list;
470 }
471 
472 lldb::SBValue
473 SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name)
474 {
475     SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
476     if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
477         return sb_value_list.GetValueAtIndex(0);
478     return SBValue();
479 }
480 
481 lldb::SBType
482 SBModule::FindFirstType (const char *name_cstr)
483 {
484     SBType sb_type;
485     ModuleSP module_sp (GetSP ());
486     if (name_cstr && module_sp)
487     {
488         SymbolContext sc;
489         const bool exact_match = false;
490         ConstString name(name_cstr);
491 
492         sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
493 
494         if (!sb_type.IsValid())
495             sb_type = SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
496     }
497     return sb_type;
498 }
499 
500 lldb::SBType
501 SBModule::GetBasicType(lldb::BasicType type)
502 {
503     ModuleSP module_sp (GetSP ());
504     if (module_sp)
505         return SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
506     return SBType();
507 }
508 
509 lldb::SBTypeList
510 SBModule::FindTypes (const char *type)
511 {
512     SBTypeList retval;
513 
514     ModuleSP module_sp (GetSP ());
515     if (type && module_sp)
516     {
517         SymbolContext sc;
518         TypeList type_list;
519         const bool exact_match = false;
520         ConstString name(type);
521         const uint32_t num_matches = module_sp->FindTypes (sc,
522                                                            name,
523                                                            exact_match,
524                                                            UINT32_MAX,
525                                                            type_list);
526 
527         if (num_matches > 0)
528         {
529             for (size_t idx = 0; idx < num_matches; idx++)
530             {
531                 TypeSP type_sp (type_list.GetTypeAtIndex(idx));
532                 if (type_sp)
533                     retval.Append(SBType(type_sp));
534             }
535         }
536         else
537         {
538             SBType sb_type(ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
539             if (sb_type.IsValid())
540                 retval.Append(sb_type);
541         }
542     }
543 
544     return retval;
545 }
546 
547 lldb::SBTypeList
548 SBModule::GetTypes (uint32_t type_mask)
549 {
550     SBTypeList sb_type_list;
551 
552     ModuleSP module_sp (GetSP ());
553     if (module_sp)
554     {
555         SymbolVendor* vendor = module_sp->GetSymbolVendor();
556         if (vendor)
557         {
558             TypeList type_list;
559             vendor->GetTypes (NULL, type_mask, type_list);
560             sb_type_list.m_opaque_ap->Append(type_list);
561         }
562     }
563     return sb_type_list;
564 }
565 
566 SBSection
567 SBModule::FindSection (const char *sect_name)
568 {
569     SBSection sb_section;
570 
571     ModuleSP module_sp (GetSP ());
572     if (sect_name && module_sp)
573     {
574         // Give the symbol vendor a chance to add to the unified section list.
575         module_sp->GetSymbolVendor();
576         SectionList *section_list = module_sp->GetUnifiedSectionList();
577         if (section_list)
578         {
579             ConstString const_sect_name(sect_name);
580             SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
581             if (section_sp)
582             {
583                 sb_section.SetSP (section_sp);
584             }
585         }
586     }
587     return sb_section;
588 }
589 
590 lldb::ByteOrder
591 SBModule::GetByteOrder ()
592 {
593     ModuleSP module_sp (GetSP ());
594     if (module_sp)
595         return module_sp->GetArchitecture().GetByteOrder();
596     return eByteOrderInvalid;
597 }
598 
599 const char *
600 SBModule::GetTriple ()
601 {
602     ModuleSP module_sp (GetSP ());
603     if (module_sp)
604     {
605         std::string triple (module_sp->GetArchitecture().GetTriple().str());
606         // Unique the string so we don't run into ownership issues since
607         // the const strings put the string into the string pool once and
608         // the strings never comes out
609         ConstString const_triple (triple.c_str());
610         return const_triple.GetCString();
611     }
612     return NULL;
613 }
614 
615 uint32_t
616 SBModule::GetAddressByteSize()
617 {
618     ModuleSP module_sp (GetSP ());
619     if (module_sp)
620         return module_sp->GetArchitecture().GetAddressByteSize();
621     return sizeof(void*);
622 }
623 
624 
625 uint32_t
626 SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
627 {
628     ModuleSP module_sp (GetSP ());
629     if (module_sp)
630         return module_sp->GetVersion(versions, num_versions);
631     else
632     {
633         if (versions && num_versions)
634         {
635             for (uint32_t i=0; i<num_versions; ++i)
636                 versions[i] = UINT32_MAX;
637         }
638         return 0;
639     }
640 }
641 
642