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