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