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 size_t
304 SBModule::GetNumSymbols ()
305 {
306     ModuleSP module_sp (GetSP ());
307     if (module_sp)
308     {
309         ObjectFile *obj_file = module_sp->GetObjectFile();
310         if (obj_file)
311         {
312             Symtab *symtab = obj_file->GetSymtab();
313             if (symtab)
314                 return symtab->GetNumSymbols();
315         }
316     }
317     return 0;
318 }
319 
320 SBSymbol
321 SBModule::GetSymbolAtIndex (size_t idx)
322 {
323     SBSymbol sb_symbol;
324     ModuleSP module_sp (GetSP ());
325     if (module_sp)
326     {
327         ObjectFile *obj_file = module_sp->GetObjectFile();
328         if (obj_file)
329         {
330             Symtab *symtab = obj_file->GetSymtab();
331             if (symtab)
332                 sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
333         }
334     }
335     return sb_symbol;
336 }
337 
338 lldb::SBSymbol
339 SBModule::FindSymbol (const char *name,
340                       lldb::SymbolType symbol_type)
341 {
342     SBSymbol sb_symbol;
343     if (name && name[0])
344     {
345         ModuleSP module_sp (GetSP ());
346         if (module_sp)
347         {
348             ObjectFile *obj_file = module_sp->GetObjectFile();
349             if (obj_file)
350             {
351                 Symtab *symtab = obj_file->GetSymtab();
352                 if (symtab)
353                     sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(ConstString(name), symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny));
354             }
355         }
356     }
357     return sb_symbol;
358 }
359 
360 
361 lldb::SBSymbolContextList
362 SBModule::FindSymbols (const char *name, lldb::SymbolType symbol_type)
363 {
364     SBSymbolContextList sb_sc_list;
365     if (name && name[0])
366     {
367         ModuleSP module_sp (GetSP ());
368         if (module_sp)
369         {
370             ObjectFile *obj_file = module_sp->GetObjectFile();
371             if (obj_file)
372             {
373                 Symtab *symtab = obj_file->GetSymtab();
374                 if (symtab)
375                 {
376                     std::vector<uint32_t> matching_symbol_indexes;
377                     const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, matching_symbol_indexes);
378                     if (num_matches)
379                     {
380                         SymbolContext sc;
381                         sc.module_sp = module_sp;
382                         SymbolContextList &sc_list = *sb_sc_list;
383                         for (size_t i=0; i<num_matches; ++i)
384                         {
385                             sc.symbol = symtab->SymbolAtIndex (matching_symbol_indexes[i]);
386                             if (sc.symbol)
387                                 sc_list.Append(sc);
388                         }
389                     }
390                 }
391             }
392         }
393     }
394     return sb_sc_list;
395 
396 }
397 
398 
399 
400 size_t
401 SBModule::GetNumSections ()
402 {
403     ModuleSP module_sp (GetSP ());
404     if (module_sp)
405     {
406         ObjectFile *obj_file = module_sp->GetObjectFile();
407         if (obj_file)
408         {
409             SectionList *section_list = obj_file->GetSectionList ();
410             if (section_list)
411                 return section_list->GetSize();
412         }
413     }
414     return 0;
415 }
416 
417 SBSection
418 SBModule::GetSectionAtIndex (size_t idx)
419 {
420     SBSection sb_section;
421     ModuleSP module_sp (GetSP ());
422     if (module_sp)
423     {
424         ObjectFile *obj_file = module_sp->GetObjectFile();
425         if (obj_file)
426         {
427             SectionList *section_list = obj_file->GetSectionList ();
428 
429             if (section_list)
430                 sb_section.SetSP(section_list->GetSectionAtIndex (idx));
431         }
432     }
433     return sb_section;
434 }
435 
436 lldb::SBSymbolContextList
437 SBModule::FindFunctions (const char *name,
438                          uint32_t name_type_mask)
439 {
440     lldb::SBSymbolContextList sb_sc_list;
441     ModuleSP module_sp (GetSP ());
442     if (name && module_sp)
443     {
444         const bool append = true;
445         const bool symbols_ok = true;
446         const bool inlines_ok = true;
447         module_sp->FindFunctions (ConstString(name),
448                                   NULL,
449                                   name_type_mask,
450                                   symbols_ok,
451                                   inlines_ok,
452                                   append,
453                                   *sb_sc_list);
454     }
455     return sb_sc_list;
456 }
457 
458 
459 SBValueList
460 SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
461 {
462     SBValueList sb_value_list;
463     ModuleSP module_sp (GetSP ());
464     if (name && module_sp)
465     {
466         VariableList variable_list;
467         const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name),
468                                                                      NULL,
469                                                                      false,
470                                                                      max_matches,
471                                                                      variable_list);
472 
473         if (match_count > 0)
474         {
475             for (uint32_t i=0; i<match_count; ++i)
476             {
477                 lldb::ValueObjectSP valobj_sp;
478                 TargetSP target_sp (target.GetSP());
479                 valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
480                 if (valobj_sp)
481                     sb_value_list.Append(SBValue(valobj_sp));
482             }
483         }
484     }
485 
486     return sb_value_list;
487 }
488 
489 lldb::SBValue
490 SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name)
491 {
492     SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
493     if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
494         return sb_value_list.GetValueAtIndex(0);
495     return SBValue();
496 }
497 
498 lldb::SBType
499 SBModule::FindFirstType (const char *name_cstr)
500 {
501     SBType sb_type;
502     ModuleSP module_sp (GetSP ());
503     if (name_cstr && module_sp)
504     {
505         SymbolContext sc;
506         const bool exact_match = false;
507         ConstString name(name_cstr);
508 
509         sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
510 
511         if (!sb_type.IsValid())
512             sb_type = SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
513     }
514     return sb_type;
515 }
516 
517 lldb::SBType
518 SBModule::GetBasicType(lldb::BasicType type)
519 {
520     ModuleSP module_sp (GetSP ());
521     if (module_sp)
522         return SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
523     return SBType();
524 }
525 
526 lldb::SBTypeList
527 SBModule::FindTypes (const char *type)
528 {
529     SBTypeList retval;
530 
531     ModuleSP module_sp (GetSP ());
532     if (type && module_sp)
533     {
534         SymbolContext sc;
535         TypeList type_list;
536         const bool exact_match = false;
537         ConstString name(type);
538         const uint32_t num_matches = module_sp->FindTypes (sc,
539                                                            name,
540                                                            exact_match,
541                                                            UINT32_MAX,
542                                                            type_list);
543 
544         if (num_matches > 0)
545         {
546             for (size_t idx = 0; idx < num_matches; idx++)
547             {
548                 TypeSP type_sp (type_list.GetTypeAtIndex(idx));
549                 if (type_sp)
550                     retval.Append(SBType(type_sp));
551             }
552         }
553         else
554         {
555             SBType sb_type(ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
556             if (sb_type.IsValid())
557                 retval.Append(sb_type);
558         }
559     }
560 
561     return retval;
562 }
563 
564 lldb::SBTypeList
565 SBModule::GetTypes (uint32_t type_mask)
566 {
567     SBTypeList sb_type_list;
568 
569     ModuleSP module_sp (GetSP ());
570     if (module_sp)
571     {
572         SymbolVendor* vendor = module_sp->GetSymbolVendor();
573         if (vendor)
574         {
575             TypeList type_list;
576             vendor->GetTypes (NULL, type_mask, type_list);
577             sb_type_list.m_opaque_ap->Append(type_list);
578         }
579     }
580     return sb_type_list;
581 }
582 
583 SBSection
584 SBModule::FindSection (const char *sect_name)
585 {
586     SBSection sb_section;
587 
588     ModuleSP module_sp (GetSP ());
589     if (sect_name && module_sp)
590     {
591         ObjectFile *objfile = module_sp->GetObjectFile();
592         if (objfile)
593         {
594             SectionList *section_list = objfile->GetSectionList();
595             if (section_list)
596             {
597                 ConstString const_sect_name(sect_name);
598                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
599                 if (section_sp)
600                 {
601                     sb_section.SetSP (section_sp);
602                 }
603             }
604         }
605     }
606     return sb_section;
607 }
608 
609 lldb::ByteOrder
610 SBModule::GetByteOrder ()
611 {
612     ModuleSP module_sp (GetSP ());
613     if (module_sp)
614         return module_sp->GetArchitecture().GetByteOrder();
615     return eByteOrderInvalid;
616 }
617 
618 const char *
619 SBModule::GetTriple ()
620 {
621     ModuleSP module_sp (GetSP ());
622     if (module_sp)
623     {
624         std::string triple (module_sp->GetArchitecture().GetTriple().str());
625         // Unique the string so we don't run into ownership issues since
626         // the const strings put the string into the string pool once and
627         // the strings never comes out
628         ConstString const_triple (triple.c_str());
629         return const_triple.GetCString();
630     }
631     return NULL;
632 }
633 
634 uint32_t
635 SBModule::GetAddressByteSize()
636 {
637     ModuleSP module_sp (GetSP ());
638     if (module_sp)
639         return module_sp->GetArchitecture().GetAddressByteSize();
640     return sizeof(void*);
641 }
642 
643 
644 uint32_t
645 SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
646 {
647     ModuleSP module_sp (GetSP ());
648     if (module_sp)
649         return module_sp->GetVersion(versions, num_versions);
650     else
651     {
652         if (versions && num_versions)
653         {
654             for (uint32_t i=0; i<num_versions; ++i)
655                 versions[i] = UINT32_MAX;
656         }
657         return 0;
658     }
659 }
660 
661