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