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