1 //===-- SBModule.cpp --------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBModule.h"
10 #include "lldb/API/SBAddress.h"
11 #include "lldb/API/SBFileSpec.h"
12 #include "lldb/API/SBModuleSpec.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/Section.h"
18 #include "lldb/Core/ValueObjectList.h"
19 #include "lldb/Core/ValueObjectVariable.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/SymbolFile.h"
22 #include "lldb/Symbol/SymbolVendor.h"
23 #include "lldb/Symbol/Symtab.h"
24 #include "lldb/Symbol/TypeSystem.h"
25 #include "lldb/Symbol/VariableList.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Utility/Log.h"
28 #include "lldb/Utility/StreamString.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 SBModule::SBModule() : m_opaque_sp() {}
34 
35 SBModule::SBModule(const lldb::ModuleSP &module_sp) : m_opaque_sp(module_sp) {}
36 
37 SBModule::SBModule(const SBModuleSpec &module_spec) : m_opaque_sp() {
38   ModuleSP module_sp;
39   Status error = ModuleList::GetSharedModule(*module_spec.m_opaque_up,
40                                              module_sp, NULL, NULL, NULL);
41   if (module_sp)
42     SetSP(module_sp);
43 }
44 
45 SBModule::SBModule(const SBModule &rhs) : m_opaque_sp(rhs.m_opaque_sp) {}
46 
47 SBModule::SBModule(lldb::SBProcess &process, lldb::addr_t header_addr)
48     : m_opaque_sp() {
49   ProcessSP process_sp(process.GetSP());
50   if (process_sp) {
51     m_opaque_sp = process_sp->ReadModuleFromMemory(FileSpec(), header_addr);
52     if (m_opaque_sp) {
53       Target &target = process_sp->GetTarget();
54       bool changed = false;
55       m_opaque_sp->SetLoadAddress(target, 0, true, changed);
56       target.GetImages().Append(m_opaque_sp);
57     }
58   }
59 }
60 
61 const SBModule &SBModule::operator=(const SBModule &rhs) {
62   if (this != &rhs)
63     m_opaque_sp = rhs.m_opaque_sp;
64   return *this;
65 }
66 
67 SBModule::~SBModule() {}
68 
69 bool SBModule::IsValid() const { return m_opaque_sp.get() != NULL; }
70 
71 void SBModule::Clear() { m_opaque_sp.reset(); }
72 
73 SBFileSpec SBModule::GetFileSpec() const {
74   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
75 
76   SBFileSpec file_spec;
77   ModuleSP module_sp(GetSP());
78   if (module_sp)
79     file_spec.SetFileSpec(module_sp->GetFileSpec());
80 
81   if (log)
82     log->Printf("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
83                 static_cast<void *>(module_sp.get()),
84                 static_cast<const void *>(file_spec.get()));
85 
86   return file_spec;
87 }
88 
89 lldb::SBFileSpec SBModule::GetPlatformFileSpec() const {
90   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
91 
92   SBFileSpec file_spec;
93   ModuleSP module_sp(GetSP());
94   if (module_sp)
95     file_spec.SetFileSpec(module_sp->GetPlatformFileSpec());
96 
97   if (log)
98     log->Printf("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
99                 static_cast<void *>(module_sp.get()),
100                 static_cast<const void *>(file_spec.get()));
101 
102   return file_spec;
103 }
104 
105 bool SBModule::SetPlatformFileSpec(const lldb::SBFileSpec &platform_file) {
106   bool result = false;
107   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
108 
109   ModuleSP module_sp(GetSP());
110   if (module_sp) {
111     module_sp->SetPlatformFileSpec(*platform_file);
112     result = true;
113   }
114 
115   if (log)
116     log->Printf("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s)) => %i",
117                 static_cast<void *>(module_sp.get()),
118                 static_cast<const void *>(platform_file.get()),
119                 platform_file->GetPath().c_str(), result);
120   return result;
121 }
122 
123 lldb::SBFileSpec SBModule::GetRemoteInstallFileSpec() {
124   SBFileSpec sb_file_spec;
125   ModuleSP module_sp(GetSP());
126   if (module_sp)
127     sb_file_spec.SetFileSpec(module_sp->GetRemoteInstallFileSpec());
128   return sb_file_spec;
129 }
130 
131 bool SBModule::SetRemoteInstallFileSpec(lldb::SBFileSpec &file) {
132   ModuleSP module_sp(GetSP());
133   if (module_sp) {
134     module_sp->SetRemoteInstallFileSpec(file.ref());
135     return true;
136   }
137   return false;
138 }
139 
140 const uint8_t *SBModule::GetUUIDBytes() const {
141   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
142 
143   const uint8_t *uuid_bytes = NULL;
144   ModuleSP module_sp(GetSP());
145   if (module_sp)
146     uuid_bytes = module_sp->GetUUID().GetBytes().data();
147 
148   if (log) {
149     if (uuid_bytes) {
150       StreamString s;
151       module_sp->GetUUID().Dump(&s);
152       log->Printf("SBModule(%p)::GetUUIDBytes () => %s",
153                   static_cast<void *>(module_sp.get()), s.GetData());
154     } else
155       log->Printf("SBModule(%p)::GetUUIDBytes () => NULL",
156                   static_cast<void *>(module_sp.get()));
157   }
158   return uuid_bytes;
159 }
160 
161 const char *SBModule::GetUUIDString() const {
162   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
163 
164   const char *uuid_cstr = NULL;
165   ModuleSP module_sp(GetSP());
166   if (module_sp) {
167     // We are going to return a "const char *" value through the public API, so
168     // we need to constify it so it gets added permanently the string pool and
169     // then we don't need to worry about the lifetime of the string as it will
170     // never go away once it has been put into the ConstString string pool
171     uuid_cstr = ConstString(module_sp->GetUUID().GetAsString()).GetCString();
172   }
173 
174   if (uuid_cstr && uuid_cstr[0]) {
175     if (log)
176       log->Printf("SBModule(%p)::GetUUIDString () => %s",
177                   static_cast<void *>(module_sp.get()), uuid_cstr);
178     return uuid_cstr;
179   }
180 
181   if (log)
182     log->Printf("SBModule(%p)::GetUUIDString () => NULL",
183                 static_cast<void *>(module_sp.get()));
184   return NULL;
185 }
186 
187 bool SBModule::operator==(const SBModule &rhs) const {
188   if (m_opaque_sp)
189     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
190   return false;
191 }
192 
193 bool SBModule::operator!=(const SBModule &rhs) const {
194   if (m_opaque_sp)
195     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
196   return false;
197 }
198 
199 ModuleSP SBModule::GetSP() const { return m_opaque_sp; }
200 
201 void SBModule::SetSP(const ModuleSP &module_sp) { m_opaque_sp = module_sp; }
202 
203 SBAddress SBModule::ResolveFileAddress(lldb::addr_t vm_addr) {
204   lldb::SBAddress sb_addr;
205   ModuleSP module_sp(GetSP());
206   if (module_sp) {
207     Address addr;
208     if (module_sp->ResolveFileAddress(vm_addr, addr))
209       sb_addr.ref() = addr;
210   }
211   return sb_addr;
212 }
213 
214 SBSymbolContext
215 SBModule::ResolveSymbolContextForAddress(const SBAddress &addr,
216                                          uint32_t resolve_scope) {
217   SBSymbolContext sb_sc;
218   ModuleSP module_sp(GetSP());
219   SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
220   if (module_sp && addr.IsValid())
221     module_sp->ResolveSymbolContextForAddress(addr.ref(), scope, *sb_sc);
222   return sb_sc;
223 }
224 
225 bool SBModule::GetDescription(SBStream &description) {
226   Stream &strm = description.ref();
227 
228   ModuleSP module_sp(GetSP());
229   if (module_sp) {
230     module_sp->GetDescription(&strm);
231   } else
232     strm.PutCString("No value");
233 
234   return true;
235 }
236 
237 uint32_t SBModule::GetNumCompileUnits() {
238   ModuleSP module_sp(GetSP());
239   if (module_sp) {
240     return module_sp->GetNumCompileUnits();
241   }
242   return 0;
243 }
244 
245 SBCompileUnit SBModule::GetCompileUnitAtIndex(uint32_t index) {
246   SBCompileUnit sb_cu;
247   ModuleSP module_sp(GetSP());
248   if (module_sp) {
249     CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(index);
250     sb_cu.reset(cu_sp.get());
251   }
252   return sb_cu;
253 }
254 
255 SBSymbolContextList
256 SBModule::FindCompileUnits(const SBFileSpec &sb_file_spec) {
257   SBSymbolContextList sb_sc_list;
258   const ModuleSP module_sp(GetSP());
259   if (sb_file_spec.IsValid() && module_sp) {
260     const bool append = true;
261     module_sp->FindCompileUnits(*sb_file_spec, append, *sb_sc_list);
262   }
263   return sb_sc_list;
264 }
265 
266 static Symtab *GetUnifiedSymbolTable(const lldb::ModuleSP &module_sp) {
267   if (module_sp) {
268     SymbolVendor *symbols = module_sp->GetSymbolVendor();
269     if (symbols)
270       return symbols->GetSymtab();
271   }
272   return NULL;
273 }
274 
275 size_t SBModule::GetNumSymbols() {
276   ModuleSP module_sp(GetSP());
277   if (module_sp) {
278     Symtab *symtab = GetUnifiedSymbolTable(module_sp);
279     if (symtab)
280       return symtab->GetNumSymbols();
281   }
282   return 0;
283 }
284 
285 SBSymbol SBModule::GetSymbolAtIndex(size_t idx) {
286   SBSymbol sb_symbol;
287   ModuleSP module_sp(GetSP());
288   Symtab *symtab = GetUnifiedSymbolTable(module_sp);
289   if (symtab)
290     sb_symbol.SetSymbol(symtab->SymbolAtIndex(idx));
291   return sb_symbol;
292 }
293 
294 lldb::SBSymbol SBModule::FindSymbol(const char *name,
295                                     lldb::SymbolType symbol_type) {
296   SBSymbol sb_symbol;
297   if (name && name[0]) {
298     ModuleSP module_sp(GetSP());
299     Symtab *symtab = GetUnifiedSymbolTable(module_sp);
300     if (symtab)
301       sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(
302           ConstString(name), symbol_type, Symtab::eDebugAny,
303           Symtab::eVisibilityAny));
304   }
305   return sb_symbol;
306 }
307 
308 lldb::SBSymbolContextList SBModule::FindSymbols(const char *name,
309                                                 lldb::SymbolType symbol_type) {
310   SBSymbolContextList sb_sc_list;
311   if (name && name[0]) {
312     ModuleSP module_sp(GetSP());
313     Symtab *symtab = GetUnifiedSymbolTable(module_sp);
314     if (symtab) {
315       std::vector<uint32_t> matching_symbol_indexes;
316       const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(
317           ConstString(name), symbol_type, matching_symbol_indexes);
318       if (num_matches) {
319         SymbolContext sc;
320         sc.module_sp = module_sp;
321         SymbolContextList &sc_list = *sb_sc_list;
322         for (size_t i = 0; i < num_matches; ++i) {
323           sc.symbol = symtab->SymbolAtIndex(matching_symbol_indexes[i]);
324           if (sc.symbol)
325             sc_list.Append(sc);
326         }
327       }
328     }
329   }
330   return sb_sc_list;
331 }
332 
333 size_t SBModule::GetNumSections() {
334   ModuleSP module_sp(GetSP());
335   if (module_sp) {
336     // Give the symbol vendor a chance to add to the unified section list.
337     module_sp->GetSymbolVendor();
338     SectionList *section_list = module_sp->GetSectionList();
339     if (section_list)
340       return section_list->GetSize();
341   }
342   return 0;
343 }
344 
345 SBSection SBModule::GetSectionAtIndex(size_t idx) {
346   SBSection sb_section;
347   ModuleSP module_sp(GetSP());
348   if (module_sp) {
349     // Give the symbol vendor a chance to add to the unified section list.
350     module_sp->GetSymbolVendor();
351     SectionList *section_list = module_sp->GetSectionList();
352 
353     if (section_list)
354       sb_section.SetSP(section_list->GetSectionAtIndex(idx));
355   }
356   return sb_section;
357 }
358 
359 lldb::SBSymbolContextList SBModule::FindFunctions(const char *name,
360                                                   uint32_t name_type_mask) {
361   lldb::SBSymbolContextList sb_sc_list;
362   ModuleSP module_sp(GetSP());
363   if (name && module_sp) {
364     const bool append = true;
365     const bool symbols_ok = true;
366     const bool inlines_ok = true;
367     FunctionNameType type = static_cast<FunctionNameType>(name_type_mask);
368     module_sp->FindFunctions(ConstString(name), NULL, type, symbols_ok,
369                              inlines_ok, append, *sb_sc_list);
370   }
371   return sb_sc_list;
372 }
373 
374 SBValueList SBModule::FindGlobalVariables(SBTarget &target, const char *name,
375                                           uint32_t max_matches) {
376   SBValueList sb_value_list;
377   ModuleSP module_sp(GetSP());
378   if (name && module_sp) {
379     VariableList variable_list;
380     const uint32_t match_count = module_sp->FindGlobalVariables(
381         ConstString(name), NULL, max_matches, variable_list);
382 
383     if (match_count > 0) {
384       for (uint32_t i = 0; i < match_count; ++i) {
385         lldb::ValueObjectSP valobj_sp;
386         TargetSP target_sp(target.GetSP());
387         valobj_sp = ValueObjectVariable::Create(
388             target_sp.get(), variable_list.GetVariableAtIndex(i));
389         if (valobj_sp)
390           sb_value_list.Append(SBValue(valobj_sp));
391       }
392     }
393   }
394 
395   return sb_value_list;
396 }
397 
398 lldb::SBValue SBModule::FindFirstGlobalVariable(lldb::SBTarget &target,
399                                                 const char *name) {
400   SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
401   if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
402     return sb_value_list.GetValueAtIndex(0);
403   return SBValue();
404 }
405 
406 lldb::SBType SBModule::FindFirstType(const char *name_cstr) {
407   SBType sb_type;
408   ModuleSP module_sp(GetSP());
409   if (name_cstr && module_sp) {
410     SymbolContext sc;
411     const bool exact_match = false;
412     ConstString name(name_cstr);
413 
414     sb_type = SBType(module_sp->FindFirstType(sc, name, exact_match));
415 
416     if (!sb_type.IsValid()) {
417       TypeSystem *type_system =
418           module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
419       if (type_system)
420         sb_type = SBType(type_system->GetBuiltinTypeByName(name));
421     }
422   }
423   return sb_type;
424 }
425 
426 lldb::SBType SBModule::GetBasicType(lldb::BasicType type) {
427   ModuleSP module_sp(GetSP());
428   if (module_sp) {
429     TypeSystem *type_system =
430         module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
431     if (type_system)
432       return SBType(type_system->GetBasicTypeFromAST(type));
433   }
434   return SBType();
435 }
436 
437 lldb::SBTypeList SBModule::FindTypes(const char *type) {
438   SBTypeList retval;
439 
440   ModuleSP module_sp(GetSP());
441   if (type && module_sp) {
442     TypeList type_list;
443     const bool exact_match = false;
444     ConstString name(type);
445     llvm::DenseSet<SymbolFile *> searched_symbol_files;
446     const uint32_t num_matches = module_sp->FindTypes(
447         name, exact_match, UINT32_MAX, searched_symbol_files, type_list);
448 
449     if (num_matches > 0) {
450       for (size_t idx = 0; idx < num_matches; idx++) {
451         TypeSP type_sp(type_list.GetTypeAtIndex(idx));
452         if (type_sp)
453           retval.Append(SBType(type_sp));
454       }
455     } else {
456       TypeSystem *type_system =
457           module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
458       if (type_system) {
459         CompilerType compiler_type = type_system->GetBuiltinTypeByName(name);
460         if (compiler_type)
461           retval.Append(SBType(compiler_type));
462       }
463     }
464   }
465 
466   return retval;
467 }
468 
469 lldb::SBType SBModule::GetTypeByID(lldb::user_id_t uid) {
470   ModuleSP module_sp(GetSP());
471   if (module_sp) {
472     SymbolVendor *vendor = module_sp->GetSymbolVendor();
473     if (vendor) {
474       Type *type_ptr = vendor->ResolveTypeUID(uid);
475       if (type_ptr)
476         return SBType(type_ptr->shared_from_this());
477     }
478   }
479   return SBType();
480 }
481 
482 lldb::SBTypeList SBModule::GetTypes(uint32_t type_mask) {
483   SBTypeList sb_type_list;
484 
485   ModuleSP module_sp(GetSP());
486   if (!module_sp)
487     return sb_type_list;
488   SymbolVendor *vendor = module_sp->GetSymbolVendor();
489   if (!vendor)
490     return sb_type_list;
491 
492   TypeClass type_class = static_cast<TypeClass>(type_mask);
493   TypeList type_list;
494   vendor->GetTypes(NULL, type_class, type_list);
495   sb_type_list.m_opaque_up->Append(type_list);
496   return sb_type_list;
497 }
498 
499 SBSection SBModule::FindSection(const char *sect_name) {
500   SBSection sb_section;
501 
502   ModuleSP module_sp(GetSP());
503   if (sect_name && module_sp) {
504     // Give the symbol vendor a chance to add to the unified section list.
505     module_sp->GetSymbolVendor();
506     SectionList *section_list = module_sp->GetSectionList();
507     if (section_list) {
508       ConstString const_sect_name(sect_name);
509       SectionSP section_sp(section_list->FindSectionByName(const_sect_name));
510       if (section_sp) {
511         sb_section.SetSP(section_sp);
512       }
513     }
514   }
515   return sb_section;
516 }
517 
518 lldb::ByteOrder SBModule::GetByteOrder() {
519   ModuleSP module_sp(GetSP());
520   if (module_sp)
521     return module_sp->GetArchitecture().GetByteOrder();
522   return eByteOrderInvalid;
523 }
524 
525 const char *SBModule::GetTriple() {
526   ModuleSP module_sp(GetSP());
527   if (module_sp) {
528     std::string triple(module_sp->GetArchitecture().GetTriple().str());
529     // Unique the string so we don't run into ownership issues since the const
530     // strings put the string into the string pool once and the strings never
531     // comes out
532     ConstString const_triple(triple.c_str());
533     return const_triple.GetCString();
534   }
535   return NULL;
536 }
537 
538 uint32_t SBModule::GetAddressByteSize() {
539   ModuleSP module_sp(GetSP());
540   if (module_sp)
541     return module_sp->GetArchitecture().GetAddressByteSize();
542   return sizeof(void *);
543 }
544 
545 uint32_t SBModule::GetVersion(uint32_t *versions, uint32_t num_versions) {
546   llvm::VersionTuple version;
547   if (ModuleSP module_sp = GetSP())
548     version = module_sp->GetVersion();
549   uint32_t result = 0;
550   if (!version.empty())
551     ++result;
552   if (version.getMinor())
553     ++result;
554   if(version.getSubminor())
555     ++result;
556 
557   if (!versions)
558     return result;
559 
560   if (num_versions > 0)
561     versions[0] = version.empty() ? UINT32_MAX : version.getMajor();
562   if (num_versions > 1)
563     versions[1] = version.getMinor().getValueOr(UINT32_MAX);
564   if (num_versions > 2)
565     versions[2] = version.getSubminor().getValueOr(UINT32_MAX);
566   for (uint32_t i = 3; i < num_versions; ++i)
567     versions[i] = UINT32_MAX;
568   return result;
569 }
570 
571 lldb::SBFileSpec SBModule::GetSymbolFileSpec() const {
572   lldb::SBFileSpec sb_file_spec;
573   ModuleSP module_sp(GetSP());
574   if (module_sp) {
575     SymbolVendor *symbol_vendor_ptr = module_sp->GetSymbolVendor();
576     if (symbol_vendor_ptr)
577       sb_file_spec.SetFileSpec(symbol_vendor_ptr->GetMainFileSpec());
578   }
579   return sb_file_spec;
580 }
581 
582 lldb::SBAddress SBModule::GetObjectFileHeaderAddress() const {
583   lldb::SBAddress sb_addr;
584   ModuleSP module_sp(GetSP());
585   if (module_sp) {
586     ObjectFile *objfile_ptr = module_sp->GetObjectFile();
587     if (objfile_ptr)
588       sb_addr.ref() = objfile_ptr->GetBaseAddress();
589   }
590   return sb_addr;
591 }
592 
593 lldb::SBAddress SBModule::GetObjectFileEntryPointAddress() const {
594   lldb::SBAddress sb_addr;
595   ModuleSP module_sp(GetSP());
596   if (module_sp) {
597     ObjectFile *objfile_ptr = module_sp->GetObjectFile();
598     if (objfile_ptr)
599       sb_addr.ref() = objfile_ptr->GetEntryPointAddress();
600   }
601   return sb_addr;
602 }
603