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         const bool add_image_to_target = true;
54         const bool load_image_sections_in_target = true;
55         m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(),
56                                                         header_addr,
57                                                         add_image_to_target,
58                                                         load_image_sections_in_target);
59     }
60 }
61 
62 const SBModule &
63 SBModule::operator = (const SBModule &rhs)
64 {
65     if (this != &rhs)
66         m_opaque_sp = rhs.m_opaque_sp;
67     return *this;
68 }
69 
70 SBModule::~SBModule ()
71 {
72 }
73 
74 bool
75 SBModule::IsValid () const
76 {
77     return m_opaque_sp.get() != NULL;
78 }
79 
80 void
81 SBModule::Clear()
82 {
83     m_opaque_sp.reset();
84 }
85 
86 SBFileSpec
87 SBModule::GetFileSpec () const
88 {
89     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
90 
91     SBFileSpec file_spec;
92     ModuleSP module_sp (GetSP ());
93     if (module_sp)
94         file_spec.SetFileSpec(module_sp->GetFileSpec());
95 
96     if (log)
97     {
98         log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
99         module_sp.get(), file_spec.get());
100     }
101 
102     return file_spec;
103 }
104 
105 lldb::SBFileSpec
106 SBModule::GetPlatformFileSpec () const
107 {
108     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
109 
110     SBFileSpec file_spec;
111     ModuleSP module_sp (GetSP ());
112     if (module_sp)
113         file_spec.SetFileSpec(module_sp->GetPlatformFileSpec());
114 
115     if (log)
116     {
117         log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
118                      module_sp.get(), file_spec.get());
119     }
120 
121     return file_spec;
122 
123 }
124 
125 bool
126 SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
127 {
128     bool result = false;
129     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
130 
131     ModuleSP module_sp (GetSP ());
132     if (module_sp)
133     {
134         module_sp->SetPlatformFileSpec(*platform_file);
135         result = true;
136     }
137 
138     if (log)
139     {
140         log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i",
141                      module_sp.get(),
142                      platform_file.get(),
143                      platform_file->GetDirectory().GetCString(),
144                      platform_file->GetDirectory() ? "/" : "",
145                      platform_file->GetFilename().GetCString(),
146                      result);
147     }
148     return result;
149 }
150 
151 
152 
153 const uint8_t *
154 SBModule::GetUUIDBytes () const
155 {
156     LogSP 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     LogSP 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             ValueObjectList &value_object_list = sb_value_list.ref();
469             for (uint32_t i=0; i<match_count; ++i)
470             {
471                 lldb::ValueObjectSP valobj_sp;
472                 TargetSP target_sp (target.GetSP());
473                 valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
474                 if (valobj_sp)
475                     value_object_list.Append(valobj_sp);
476             }
477         }
478     }
479 
480     return sb_value_list;
481 }
482 
483 lldb::SBType
484 SBModule::FindFirstType (const char *name_cstr)
485 {
486     SBType sb_type;
487     ModuleSP module_sp (GetSP ());
488     if (name_cstr && module_sp)
489     {
490         SymbolContext sc;
491         const bool exact_match = false;
492         ConstString name(name_cstr);
493 
494         sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
495 
496         if (!sb_type.IsValid())
497             sb_type = SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
498     }
499     return sb_type;
500 }
501 
502 lldb::SBType
503 SBModule::GetBasicType(lldb::BasicType type)
504 {
505     ModuleSP module_sp (GetSP ());
506     if (module_sp)
507         return SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
508     return SBType();
509 }
510 
511 lldb::SBTypeList
512 SBModule::FindTypes (const char *type)
513 {
514     SBTypeList retval;
515 
516     ModuleSP module_sp (GetSP ());
517     if (type && module_sp)
518     {
519         SymbolContext sc;
520         TypeList type_list;
521         const bool exact_match = false;
522         ConstString name(type);
523         const uint32_t num_matches = module_sp->FindTypes (sc,
524                                                            name,
525                                                            exact_match,
526                                                            UINT32_MAX,
527                                                            type_list);
528 
529         if (num_matches > 0)
530         {
531             for (size_t idx = 0; idx < num_matches; idx++)
532             {
533                 TypeSP type_sp (type_list.GetTypeAtIndex(idx));
534                 if (type_sp)
535                     retval.Append(SBType(type_sp));
536             }
537         }
538         else
539         {
540             SBType sb_type(ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
541             if (sb_type.IsValid())
542                 retval.Append(sb_type);
543         }
544     }
545 
546     return retval;
547 }
548 
549 
550 SBSection
551 SBModule::FindSection (const char *sect_name)
552 {
553     SBSection sb_section;
554 
555     ModuleSP module_sp (GetSP ());
556     if (sect_name && module_sp)
557     {
558         ObjectFile *objfile = module_sp->GetObjectFile();
559         if (objfile)
560         {
561             SectionList *section_list = objfile->GetSectionList();
562             if (section_list)
563             {
564                 ConstString const_sect_name(sect_name);
565                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
566                 if (section_sp)
567                 {
568                     sb_section.SetSP (section_sp);
569                 }
570             }
571         }
572     }
573     return sb_section;
574 }
575 
576 lldb::ByteOrder
577 SBModule::GetByteOrder ()
578 {
579     ModuleSP module_sp (GetSP ());
580     if (module_sp)
581         return module_sp->GetArchitecture().GetByteOrder();
582     return eByteOrderInvalid;
583 }
584 
585 const char *
586 SBModule::GetTriple ()
587 {
588     ModuleSP module_sp (GetSP ());
589     if (module_sp)
590     {
591         std::string triple (module_sp->GetArchitecture().GetTriple().str());
592         // Unique the string so we don't run into ownership issues since
593         // the const strings put the string into the string pool once and
594         // the strings never comes out
595         ConstString const_triple (triple.c_str());
596         return const_triple.GetCString();
597     }
598     return NULL;
599 }
600 
601 uint32_t
602 SBModule::GetAddressByteSize()
603 {
604     ModuleSP module_sp (GetSP ());
605     if (module_sp)
606         return module_sp->GetArchitecture().GetAddressByteSize();
607     return sizeof(void*);
608 }
609 
610 
611 uint32_t
612 SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
613 {
614     ModuleSP module_sp (GetSP ());
615     if (module_sp)
616         return module_sp->GetVersion(versions, num_versions);
617     else
618     {
619         if (versions && num_versions)
620         {
621             for (uint32_t i=0; i<num_versions; ++i)
622                 versions[i] = UINT32_MAX;
623         }
624         return 0;
625     }
626 }
627 
628