1 //===-- ModuleList.h --------------------------------------------*- 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 #ifndef LLDB_CORE_MODULELIST_H
10 #define LLDB_CORE_MODULELIST_H
11 
12 #include "lldb/Core/Address.h"
13 #include "lldb/Core/ModuleSpec.h"
14 #include "lldb/Core/UserSettingsController.h"
15 #include "lldb/Utility/FileSpec.h"
16 #include "lldb/Utility/Iterable.h"
17 #include "lldb/Utility/Status.h"
18 #include "lldb/lldb-enumerations.h"
19 #include "lldb/lldb-forward.h"
20 #include "lldb/lldb-types.h"
21 
22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/Support/RWMutex.h"
24 
25 #include <functional>
26 #include <list>
27 #include <mutex>
28 #include <vector>
29 
30 #include <cstddef>
31 #include <cstdint>
32 
33 namespace lldb_private {
34 class ConstString;
35 class FileSpecList;
36 class Function;
37 class Log;
38 class Module;
39 class RegularExpression;
40 class Stream;
41 class SymbolContext;
42 class SymbolContextList;
43 class SymbolFile;
44 class Target;
45 class TypeList;
46 class UUID;
47 class VariableList;
48 struct ModuleFunctionSearchOptions;
49 
50 class ModuleListProperties : public Properties {
51   mutable llvm::sys::RWMutex m_symlink_paths_mutex;
52   PathMappingList m_symlink_paths;
53 
54   void UpdateSymlinkMappings();
55 
56 public:
57   ModuleListProperties();
58 
59   FileSpec GetClangModulesCachePath() const;
60   bool SetClangModulesCachePath(const FileSpec &path);
61   bool GetEnableExternalLookup() const;
62   bool SetEnableExternalLookup(bool new_value);
63   bool GetEnableLLDBIndexCache() const;
64   bool SetEnableLLDBIndexCache(bool new_value);
65   uint64_t GetLLDBIndexCacheMaxByteSize();
66   uint64_t GetLLDBIndexCacheMaxPercent();
67   uint64_t GetLLDBIndexCacheExpirationDays();
68   FileSpec GetLLDBIndexCachePath() const;
69   bool SetLLDBIndexCachePath(const FileSpec &path);
70 
71   bool GetLoadSymbolOnDemand();
72 
73   PathMappingList GetSymlinkMappings() const;
74 };
75 
76 /// \class ModuleList ModuleList.h "lldb/Core/ModuleList.h"
77 /// A collection class for Module objects.
78 ///
79 /// Modules in the module collection class are stored as reference counted
80 /// shared pointers to Module objects.
81 class ModuleList {
82 public:
83   class Notifier {
84   public:
85     virtual ~Notifier() = default;
86 
87     virtual void NotifyModuleAdded(const ModuleList &module_list,
88                                    const lldb::ModuleSP &module_sp) = 0;
89     virtual void NotifyModuleRemoved(const ModuleList &module_list,
90                                      const lldb::ModuleSP &module_sp) = 0;
91     virtual void NotifyModuleUpdated(const ModuleList &module_list,
92                                      const lldb::ModuleSP &old_module_sp,
93                                      const lldb::ModuleSP &new_module_sp) = 0;
94     virtual void NotifyWillClearList(const ModuleList &module_list) = 0;
95 
96     virtual void NotifyModulesRemoved(lldb_private::ModuleList &module_list) = 0;
97   };
98 
99   /// Default constructor.
100   ///
101   /// Creates an empty list of Module objects.
102   ModuleList();
103 
104   /// Copy Constructor.
105   ///
106   /// Creates a new module list object with a copy of the modules from \a rhs.
107   ///
108   /// \param[in] rhs
109   ///     Another module list object.
110   ModuleList(const ModuleList &rhs);
111 
112   ModuleList(ModuleList::Notifier *notifier);
113 
114   /// Destructor.
115   ~ModuleList();
116 
117   /// Assignment operator.
118   ///
119   /// Copies the module list from \a rhs into this list.
120   ///
121   /// \param[in] rhs
122   ///     Another module list object.
123   ///
124   /// \return
125   ///     A const reference to this object.
126   const ModuleList &operator=(const ModuleList &rhs);
127 
128   /// Append a module to the module list.
129   ///
130   /// \param[in] module_sp
131   ///     A shared pointer to a module to add to this collection.
132   ///
133   /// \param[in] notify
134   ///     If true, and a notifier function is set, the notifier function
135   ///     will be called.  Defaults to true.
136   ///
137   ///     When this ModuleList is the Target's ModuleList, the notifier
138   ///     function is Target::ModulesDidLoad -- the call to
139   ///     ModulesDidLoad may be deferred when adding multiple Modules
140   ///     to the Target, but it must be called at the end,
141   ///     before resuming execution.
142   void Append(const lldb::ModuleSP &module_sp, bool notify = true);
143 
144   /// Append a module to the module list and remove any equivalent modules.
145   /// Equivalent modules are ones whose file, platform file and architecture
146   /// matches.
147   ///
148   /// Replaces the module to the collection.
149   ///
150   /// \param[in] module_sp
151   ///     A shared pointer to a module to replace in this collection.
152   ///
153   /// \param[in] old_modules
154   ///     Optional pointer to a vector which, if provided, will have shared
155   ///     pointers to the replaced module(s) appended to it.
156   void ReplaceEquivalent(
157       const lldb::ModuleSP &module_sp,
158       llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules = nullptr);
159 
160   /// Append a module to the module list, if it is not already there.
161   ///
162   /// \param[in] notify
163   ///     If true, and a notifier function is set, the notifier function
164   ///     will be called.  Defaults to true.
165   ///
166   ///     When this ModuleList is the Target's ModuleList, the notifier
167   ///     function is Target::ModulesDidLoad -- the call to
168   ///     ModulesDidLoad may be deferred when adding multiple Modules
169   ///     to the Target, but it must be called at the end,
170   ///     before resuming execution.
171   bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify = true);
172 
173   void Append(const ModuleList &module_list);
174 
175   bool AppendIfNeeded(const ModuleList &module_list);
176 
177   bool ReplaceModule(const lldb::ModuleSP &old_module_sp,
178                      const lldb::ModuleSP &new_module_sp);
179 
180   /// Clear the object's state.
181   ///
182   /// Clears the list of modules and releases a reference to each module
183   /// object and if the reference count goes to zero, the module will be
184   /// deleted.
185   void Clear();
186 
187   /// Clear the object's state.
188   ///
189   /// Clears the list of modules and releases a reference to each module
190   /// object and if the reference count goes to zero, the module will be
191   /// deleted. Also release all memory that might be held by any collection
192   /// classes (like std::vector)
193   void Destroy();
194 
195   /// Dump the description of each module contained in this list.
196   ///
197   /// Dump the description of each module contained in this list to the
198   /// supplied stream \a s.
199   ///
200   /// \param[in] s
201   ///     The stream to which to dump the object description.
202   ///
203   /// \see Module::Dump(Stream *) const
204   void Dump(Stream *s) const;
205 
206   void LogUUIDAndPaths(Log *log, const char *prefix_cstr);
207 
208   std::recursive_mutex &GetMutex() const { return m_modules_mutex; }
209 
210   size_t GetIndexForModule(const Module *module) const;
211 
212   /// Get the module shared pointer for the module at index \a idx.
213   ///
214   /// \param[in] idx
215   ///     An index into this module collection.
216   ///
217   /// \return
218   ///     A shared pointer to a Module which can contain NULL if
219   ///     \a idx is out of range.
220   ///
221   /// \see ModuleList::GetSize()
222   lldb::ModuleSP GetModuleAtIndex(size_t idx) const;
223 
224   /// Get the module shared pointer for the module at index \a idx without
225   /// acquiring the ModuleList mutex.  This MUST already have been acquired
226   /// with ModuleList::GetMutex and locked for this call to be safe.
227   ///
228   /// \param[in] idx
229   ///     An index into this module collection.
230   ///
231   /// \return
232   ///     A shared pointer to a Module which can contain NULL if
233   ///     \a idx is out of range.
234   ///
235   /// \see ModuleList::GetSize()
236   lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const;
237 
238   /// Get the module pointer for the module at index \a idx.
239   ///
240   /// \param[in] idx
241   ///     An index into this module collection.
242   ///
243   /// \return
244   ///     A pointer to a Module which can by nullptr if \a idx is out
245   ///     of range.
246   ///
247   /// \see ModuleList::GetSize()
248   Module *GetModulePointerAtIndex(size_t idx) const;
249 
250   /// Find compile units by partial or full path.
251   ///
252   /// Finds all compile units that match \a path in all of the modules and
253   /// returns the results in \a sc_list.
254   ///
255   /// \param[in] path
256   ///     The name of the compile unit we are looking for.
257   ///
258   /// \param[out] sc_list
259   ///     A symbol context list that gets filled in with all of the
260   ///     matches.
261   void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const;
262 
263   /// \see Module::FindFunctions ()
264   void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask,
265                      const ModuleFunctionSearchOptions &options,
266                      SymbolContextList &sc_list) const;
267 
268   /// \see Module::FindFunctionSymbols ()
269   void FindFunctionSymbols(ConstString name,
270                            lldb::FunctionNameType name_type_mask,
271                            SymbolContextList &sc_list);
272 
273   /// \see Module::FindFunctions ()
274   void FindFunctions(const RegularExpression &name,
275                      const ModuleFunctionSearchOptions &options,
276                      SymbolContextList &sc_list);
277 
278   /// Find global and static variables by name.
279   ///
280   /// \param[in] name
281   ///     The name of the global or static variable we are looking
282   ///     for.
283   ///
284   /// \param[in] max_matches
285   ///     Allow the number of matches to be limited to \a
286   ///     max_matches. Specify UINT32_MAX to get all possible matches.
287   ///
288   /// \param[in] variable_list
289   ///     A list of variables that gets the matches appended to.
290   void FindGlobalVariables(ConstString name, size_t max_matches,
291                            VariableList &variable_list) const;
292 
293   /// Find global and static variables by regular expression.
294   ///
295   /// \param[in] regex
296   ///     A regular expression to use when matching the name.
297   ///
298   /// \param[in] max_matches
299   ///     Allow the number of matches to be limited to \a
300   ///     max_matches. Specify UINT32_MAX to get all possible matches.
301   ///
302   /// \param[in] variable_list
303   ///     A list of variables that gets the matches appended to.
304   void FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
305                            VariableList &variable_list) const;
306 
307   /// Finds the first module whose file specification matches \a file_spec.
308   ///
309   /// \param[in] module_spec
310   ///     A file specification object to match against the Module's
311   ///     file specifications. If \a file_spec does not have
312   ///     directory information, matches will occur by matching only
313   ///     the basename of any modules in this list. If this value is
314   ///     NULL, then file specifications won't be compared when
315   ///     searching for matching modules.
316   ///
317   /// \param[out] matching_module_list
318   ///     A module list that gets filled in with any modules that
319   ///     match the search criteria.
320   void FindModules(const ModuleSpec &module_spec,
321                    ModuleList &matching_module_list) const;
322 
323   lldb::ModuleSP FindModule(const Module *module_ptr) const;
324 
325   // Find a module by UUID
326   //
327   // The UUID value for a module is extracted from the ObjectFile and is the
328   // MD5 checksum, or a smarter object file equivalent, so finding modules by
329   // UUID values is very efficient and accurate.
330   lldb::ModuleSP FindModule(const UUID &uuid) const;
331 
332   lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const;
333 
334   void FindSymbolsWithNameAndType(ConstString name,
335                                   lldb::SymbolType symbol_type,
336                                   SymbolContextList &sc_list) const;
337 
338   void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
339                                        lldb::SymbolType symbol_type,
340                                        SymbolContextList &sc_list) const;
341 
342   /// Find types by name.
343   ///
344   /// \param[in] search_first
345   ///     If non-null, this module will be searched before any other
346   ///     modules.
347   ///
348   /// \param[in] name
349   ///     The name of the type we are looking for.
350   ///
351   /// \param[in] max_matches
352   ///     Allow the number of matches to be limited to \a
353   ///     max_matches. Specify UINT32_MAX to get all possible matches.
354   ///
355   /// \param[out] types
356   ///     A type list gets populated with any matches.
357   ///
358   void FindTypes(Module *search_first, ConstString name,
359                  bool name_is_fully_qualified, size_t max_matches,
360                  llvm::DenseSet<SymbolFile *> &searched_symbol_files,
361                  TypeList &types) const;
362 
363   bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const;
364 
365   /// Find addresses by file/line
366   ///
367   /// \param[in] target_sp
368   ///     The target the addresses are desired for.
369   ///
370   /// \param[in] file
371   ///     Source file to locate.
372   ///
373   /// \param[in] line
374   ///     Source line to locate.
375   ///
376   /// \param[in] function
377   ///     Optional filter function. Addresses within this function will be
378   ///     added to the 'local' list. All others will be added to the 'extern'
379   ///     list.
380   ///
381   /// \param[out] output_local
382   ///     All matching addresses within 'function'
383   ///
384   /// \param[out] output_extern
385   ///     All matching addresses not within 'function'
386   void FindAddressesForLine(const lldb::TargetSP target_sp,
387                             const FileSpec &file, uint32_t line,
388                             Function *function,
389                             std::vector<Address> &output_local,
390                             std::vector<Address> &output_extern);
391 
392   /// Remove a module from the module list.
393   ///
394   /// \param[in] module_sp
395   ///     A shared pointer to a module to remove from this collection.
396   ///
397   /// \param[in] notify
398   ///     If true, and a notifier function is set, the notifier function
399   ///     will be called.  Defaults to true.
400   ///
401   ///     When this ModuleList is the Target's ModuleList, the notifier
402   ///     function is Target::ModulesDidUnload -- the call to
403   ///     ModulesDidUnload may be deferred when removing multiple Modules
404   ///     from the Target, but it must be called at the end,
405   ///     before resuming execution.
406   bool Remove(const lldb::ModuleSP &module_sp, bool notify = true);
407 
408   size_t Remove(ModuleList &module_list);
409 
410   bool RemoveIfOrphaned(const Module *module_ptr);
411 
412   size_t RemoveOrphans(bool mandatory);
413 
414   bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) const;
415 
416   /// \copydoc Module::ResolveSymbolContextForAddress (const Address
417   /// &,uint32_t,SymbolContext&)
418   uint32_t ResolveSymbolContextForAddress(const Address &so_addr,
419                                           lldb::SymbolContextItem resolve_scope,
420                                           SymbolContext &sc) const;
421 
422   /// \copydoc Module::ResolveSymbolContextForFilePath (const char
423   /// *,uint32_t,bool,uint32_t,SymbolContextList&)
424   uint32_t ResolveSymbolContextForFilePath(
425       const char *file_path, uint32_t line, bool check_inlines,
426       lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const;
427 
428   /// \copydoc Module::ResolveSymbolContextsForFileSpec (const FileSpec
429   /// &,uint32_t,bool,uint32_t,SymbolContextList&)
430   uint32_t ResolveSymbolContextsForFileSpec(
431       const FileSpec &file_spec, uint32_t line, bool check_inlines,
432       lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const;
433 
434   /// Gets the size of the module list.
435   ///
436   /// \return
437   ///     The number of modules in the module list.
438   size_t GetSize() const;
439   bool IsEmpty() const { return !GetSize(); }
440 
441   bool LoadScriptingResourcesInTarget(Target *target, std::list<Status> &errors,
442                                       Stream *feedback_stream = nullptr,
443                                       bool continue_on_error = true);
444 
445   static ModuleListProperties &GetGlobalModuleListProperties();
446 
447   static bool ModuleIsInCache(const Module *module_ptr);
448 
449   static Status
450   GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
451                   const FileSpecList *module_search_paths_ptr,
452                   llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
453                   bool *did_create_ptr, bool always_create = false);
454 
455   static bool RemoveSharedModule(lldb::ModuleSP &module_sp);
456 
457   static void FindSharedModules(const ModuleSpec &module_spec,
458                                 ModuleList &matching_module_list);
459 
460   static size_t RemoveOrphanSharedModules(bool mandatory);
461 
462   static bool RemoveSharedModuleIfOrphaned(const Module *module_ptr);
463 
464   void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const
465                    &callback) const;
466 
467 protected:
468   // Class typedefs.
469   typedef std::vector<lldb::ModuleSP>
470       collection; ///< The module collection type.
471 
472   void AppendImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
473 
474   bool RemoveImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
475 
476   collection::iterator RemoveImpl(collection::iterator pos,
477                                   bool use_notifier = true);
478 
479   void ClearImpl(bool use_notifier = true);
480 
481   // Member variables.
482   collection m_modules; ///< The collection of modules.
483   mutable std::recursive_mutex m_modules_mutex;
484 
485   Notifier *m_notifier = nullptr;
486 
487 public:
488   typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter,
489                                  std::recursive_mutex>
490       ModuleIterable;
491   ModuleIterable Modules() const {
492     return ModuleIterable(m_modules, GetMutex());
493   }
494 
495   typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter>
496       ModuleIterableNoLocking;
497   ModuleIterableNoLocking ModulesNoLocking() const {
498     return ModuleIterableNoLocking(m_modules);
499   }
500 };
501 
502 } // namespace lldb_private
503 
504 #endif // LLDB_CORE_MODULELIST_H
505