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