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