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
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;
48
49class ModuleListProperties : public Properties {
50 mutable llvm::sys::RWMutex m_symlink_paths_mutex;
51 PathMappingList m_symlink_paths;
52
53 void UpdateSymlinkMappings();
54
55public:
56 ModuleListProperties();
57
58 FileSpec GetClangModulesCachePath() const;
59 bool SetClangModulesCachePath(const FileSpec &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.
71class ModuleList {
72public:
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
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 /// 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
439 GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
440 const FileSpecList *module_search_paths_ptr,
441 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
442 bool *did_create_ptr, bool always_create = false);
443
444 static bool RemoveSharedModule(lldb::ModuleSP &module_sp);
445
446 static void FindSharedModules(const ModuleSpec &module_spec,
447 ModuleList &matching_module_list);
448
449 static size_t RemoveOrphanSharedModules(bool mandatory);
450
451 static bool RemoveSharedModuleIfOrphaned(const Module *module_ptr);
452
453 void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const
454 &callback) const;
455
456protected:
457 // Class typedefs.
458 typedef std::vector<lldb::ModuleSP>
459 collection; ///< The module collection type.
460
461 void AppendImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
462
463 bool RemoveImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
464
465 collection::iterator RemoveImpl(collection::iterator pos,
466 bool use_notifier = true);
467
468 void ClearImpl(bool use_notifier = true);
469
470 // Member variables.
471 collection m_modules; ///< The collection of modules.
472 mutable std::recursive_mutex m_modules_mutex;
473
474 Notifier *m_notifier;
475
476public:
477 typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter,
478 std::recursive_mutex>
479 ModuleIterable;
480 ModuleIterable Modules() const {
481 return ModuleIterable(m_modules, GetMutex());
482 }
483
484 typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter>
485 ModuleIterableNoLocking;
486 ModuleIterableNoLocking ModulesNoLocking() const {
487 return ModuleIterableNoLocking(m_modules);
488 }
489};
490
491} // namespace lldb_private
492
493#endif // LLDB_CORE_MODULELIST_H
494