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%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     Log *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     Log *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             for (uint32_t i=0; i<match_count; ++i)
471             {
472                 lldb::ValueObjectSP valobj_sp;
473                 TargetSP target_sp (target.GetSP());
474                 valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
475                 if (valobj_sp)
476                     sb_value_list.Append(SBValue(valobj_sp));
477             }
478         }
479     }
480 
481     return sb_value_list;
482 }
483 
484 lldb::SBValue
485 SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name)
486 {
487     SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
488     if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
489         return sb_value_list.GetValueAtIndex(0);
490     return SBValue();
491 }
492 
493 lldb::SBType
494 SBModule::FindFirstType (const char *name_cstr)
495 {
496     SBType sb_type;
497     ModuleSP module_sp (GetSP ());
498     if (name_cstr && module_sp)
499     {
500         SymbolContext sc;
501         const bool exact_match = false;
502         ConstString name(name_cstr);
503 
504         sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
505 
506         if (!sb_type.IsValid())
507             sb_type = SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
508     }
509     return sb_type;
510 }
511 
512 lldb::SBType
513 SBModule::GetBasicType(lldb::BasicType type)
514 {
515     ModuleSP module_sp (GetSP ());
516     if (module_sp)
517         return SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
518     return SBType();
519 }
520 
521 lldb::SBTypeList
522 SBModule::FindTypes (const char *type)
523 {
524     SBTypeList retval;
525 
526     ModuleSP module_sp (GetSP ());
527     if (type && module_sp)
528     {
529         SymbolContext sc;
530         TypeList type_list;
531         const bool exact_match = false;
532         ConstString name(type);
533         const uint32_t num_matches = module_sp->FindTypes (sc,
534                                                            name,
535                                                            exact_match,
536                                                            UINT32_MAX,
537                                                            type_list);
538 
539         if (num_matches > 0)
540         {
541             for (size_t idx = 0; idx < num_matches; idx++)
542             {
543                 TypeSP type_sp (type_list.GetTypeAtIndex(idx));
544                 if (type_sp)
545                     retval.Append(SBType(type_sp));
546             }
547         }
548         else
549         {
550             SBType sb_type(ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
551             if (sb_type.IsValid())
552                 retval.Append(sb_type);
553         }
554     }
555 
556     return retval;
557 }
558 
559 
560 SBSection
561 SBModule::FindSection (const char *sect_name)
562 {
563     SBSection sb_section;
564 
565     ModuleSP module_sp (GetSP ());
566     if (sect_name && module_sp)
567     {
568         ObjectFile *objfile = module_sp->GetObjectFile();
569         if (objfile)
570         {
571             SectionList *section_list = objfile->GetSectionList();
572             if (section_list)
573             {
574                 ConstString const_sect_name(sect_name);
575                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
576                 if (section_sp)
577                 {
578                     sb_section.SetSP (section_sp);
579                 }
580             }
581         }
582     }
583     return sb_section;
584 }
585 
586 lldb::ByteOrder
587 SBModule::GetByteOrder ()
588 {
589     ModuleSP module_sp (GetSP ());
590     if (module_sp)
591         return module_sp->GetArchitecture().GetByteOrder();
592     return eByteOrderInvalid;
593 }
594 
595 const char *
596 SBModule::GetTriple ()
597 {
598     ModuleSP module_sp (GetSP ());
599     if (module_sp)
600     {
601         std::string triple (module_sp->GetArchitecture().GetTriple().str());
602         // Unique the string so we don't run into ownership issues since
603         // the const strings put the string into the string pool once and
604         // the strings never comes out
605         ConstString const_triple (triple.c_str());
606         return const_triple.GetCString();
607     }
608     return NULL;
609 }
610 
611 uint32_t
612 SBModule::GetAddressByteSize()
613 {
614     ModuleSP module_sp (GetSP ());
615     if (module_sp)
616         return module_sp->GetArchitecture().GetAddressByteSize();
617     return sizeof(void*);
618 }
619 
620 
621 uint32_t
622 SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
623 {
624     ModuleSP module_sp (GetSP ());
625     if (module_sp)
626         return module_sp->GetVersion(versions, num_versions);
627     else
628     {
629         if (versions && num_versions)
630         {
631             for (uint32_t i=0; i<num_versions; ++i)
632                 versions[i] = UINT32_MAX;
633         }
634         return 0;
635     }
636 }
637 
638