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
33namespace lldb_private {
34class ConstString;
35class FileSpecList;
36class Function;
37class Log;
38class Module;
39class RegularExpression;
40class Stream;
41class SymbolContext;
42class SymbolContextList;
43class SymbolFile;
44class Target;
45class TypeList;
46class UUID;
47class VariableList;
48struct ModuleFunctionSearchOptions;
49
50class ModuleListProperties : public Properties {
51  mutable llvm::sys::RWMutex m_symlink_paths_mutex;
52  PathMappingList m_symlink_paths;
53
54  void UpdateSymlinkMappings();
55
56public:
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.
82class ModuleList {
83public:
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 using a type-matching object that contains all search
344  /// parameters.
345  ///
346  /// \param[in] search_first
347  ///     If non-null, this module will be searched before any other
348  ///     modules.
349  ///
350  /// \param[in] query
351  ///     A type matching object that contains all of the details of the type
352  ///     search.
353  ///
354  /// \param[in] results
355  ///     Any matching types will be populated into the \a results object using
356  ///     TypeMap::InsertUnique(...).
357  void FindTypes(Module *search_first, const TypeQuery &query,
358                 lldb_private::TypeResults &results) const;
359
360  bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const;
361
362  /// Find addresses by file/line
363  ///
364  /// \param[in] target_sp
365  ///     The target the addresses are desired for.
366  ///
367  /// \param[in] file
368  ///     Source file to locate.
369  ///
370  /// \param[in] line
371  ///     Source line to locate.
372  ///
373  /// \param[in] function
374  ///     Optional filter function. Addresses within this function will be
375  ///     added to the 'local' list. All others will be added to the 'extern'
376  ///     list.
377  ///
378  /// \param[out] output_local
379  ///     All matching addresses within 'function'
380  ///
381  /// \param[out] output_extern
382  ///     All matching addresses not within 'function'
383  void FindAddressesForLine(const lldb::TargetSP target_sp,
384                            const FileSpec &file, uint32_t line,
385                            Function *function,
386                            std::vector<Address> &output_local,
387                            std::vector<Address> &output_extern);
388
389  /// Remove a module from the module list.
390  ///
391  /// \param[in] module_sp
392  ///     A shared pointer to a module to remove from this collection.
393  ///
394  /// \param[in] notify
395  ///     If true, and a notifier function is set, the notifier function
396  ///     will be called.  Defaults to true.
397  ///
398  ///     When this ModuleList is the Target's ModuleList, the notifier
399  ///     function is Target::ModulesDidUnload -- the call to
400  ///     ModulesDidUnload may be deferred when removing multiple Modules
401  ///     from the Target, but it must be called at the end,
402  ///     before resuming execution.
403  bool Remove(const lldb::ModuleSP &module_sp, bool notify = true);
404
405  size_t Remove(ModuleList &module_list);
406
407  bool RemoveIfOrphaned(const Module *module_ptr);
408
409  size_t RemoveOrphans(bool mandatory);
410
411  bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) const;
412
413  /// \copydoc Module::ResolveSymbolContextForAddress (const Address
414  /// &,uint32_t,SymbolContext&)
415  uint32_t ResolveSymbolContextForAddress(const Address &so_addr,
416                                          lldb::SymbolContextItem resolve_scope,
417                                          SymbolContext &sc) const;
418
419  /// \copydoc Module::ResolveSymbolContextForFilePath (const char
420  /// *,uint32_t,bool,uint32_t,SymbolContextList&)
421  uint32_t ResolveSymbolContextForFilePath(
422      const char *file_path, uint32_t line, bool check_inlines,
423      lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const;
424
425  /// \copydoc Module::ResolveSymbolContextsForFileSpec (const FileSpec
426  /// &,uint32_t,bool,uint32_t,SymbolContextList&)
427  uint32_t ResolveSymbolContextsForFileSpec(
428      const FileSpec &file_spec, uint32_t line, bool check_inlines,
429      lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const;
430
431  /// Gets the size of the module list.
432  ///
433  /// \return
434  ///     The number of modules in the module list.
435  size_t GetSize() const;
436  bool IsEmpty() const { return !GetSize(); }
437
438  bool LoadScriptingResourcesInTarget(Target *target, std::list<Status> &errors,
439                                      Stream &feedback_stream,
440                                      bool continue_on_error = true);
441
442  static ModuleListProperties &GetGlobalModuleListProperties();
443
444  static bool ModuleIsInCache(const Module *module_ptr);
445
446  static Status
447  GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
448                  const FileSpecList *module_search_paths_ptr,
449                  llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
450                  bool *did_create_ptr, bool always_create = false);
451
452  static bool RemoveSharedModule(lldb::ModuleSP &module_sp);
453
454  static void FindSharedModules(const ModuleSpec &module_spec,
455                                ModuleList &matching_module_list);
456
457  static lldb::ModuleSP FindSharedModule(const UUID &uuid);
458
459  static size_t RemoveOrphanSharedModules(bool mandatory);
460
461  static bool RemoveSharedModuleIfOrphaned(const Module *module_ptr);
462
463  /// Applies 'callback' to each module in this ModuleList.
464  /// If 'callback' returns false, iteration terminates.
465  /// The 'module_sp' passed to 'callback' is guaranteed to
466  /// be non-null.
467  ///
468  /// This function is thread-safe.
469  void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const
470                   &callback) const;
471
472  /// Returns true if 'callback' returns true for one of the modules
473  /// in this ModuleList.
474  ///
475  /// This function is thread-safe.
476  bool AnyOf(
477      std::function<bool(lldb_private::Module &module)> const &callback) const;
478
479  /// Atomically swaps the contents of this module list with \a other.
480  void Swap(ModuleList &other);
481
482protected:
483  // Class typedefs.
484  typedef std::vector<lldb::ModuleSP>
485      collection; ///< The module collection type.
486
487  void AppendImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
488
489  bool RemoveImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
490
491  collection::iterator RemoveImpl(collection::iterator pos,
492                                  bool use_notifier = true);
493
494  void ClearImpl(bool use_notifier = true);
495
496  // Member variables.
497  collection m_modules; ///< The collection of modules.
498  mutable std::recursive_mutex m_modules_mutex;
499
500  Notifier *m_notifier = nullptr;
501
502public:
503  typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter,
504                                 std::recursive_mutex>
505      ModuleIterable;
506  ModuleIterable Modules() const {
507    return ModuleIterable(m_modules, GetMutex());
508  }
509
510  typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter>
511      ModuleIterableNoLocking;
512  ModuleIterableNoLocking ModulesNoLocking() const {
513    return ModuleIterableNoLocking(m_modules);
514  }
515};
516
517} // namespace lldb_private
518
519#endif // LLDB_CORE_MODULELIST_H
520