LLDB mainline
ModuleSpec.h
Go to the documentation of this file.
1//===-- ModuleSpec.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_MODULESPEC_H
10#define LLDB_CORE_MODULESPEC_H
11
18#include "lldb/Utility/Stream.h"
19#include "lldb/Utility/UUID.h"
20#include "lldb/lldb-forward.h"
21
22#include "llvm/Support/Chrono.h"
23
24#include <memory>
25#include <mutex>
26#include <vector>
27
28namespace lldb_private {
29
31public:
32 ModuleSpec() = default;
33
34 /// If the \c extractor_sp argument is passed, its contents will be used
35 /// as the module contents instead of trying to read them from
36 /// \c file_spec .
37 ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID(),
39 : m_file(file_spec), m_uuid(uuid), m_object_offset(0),
40 m_extractor_sp(extractor_sp) {
41 if (extractor_sp)
42 m_object_size = extractor_sp->GetByteSize();
43 else if (m_file)
44 m_object_size = FileSystem::Instance().GetByteSize(file_spec);
45 }
46
47 ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch)
48 : m_file(file_spec), m_arch(arch), m_object_offset(0),
49 m_object_size(FileSystem::Instance().GetByteSize(file_spec)) {}
50
51 FileSpec *GetFileSpecPtr() { return (m_file ? &m_file : nullptr); }
52
53 const FileSpec *GetFileSpecPtr() const {
54 return (m_file ? &m_file : nullptr);
55 }
56
58
59 const FileSpec &GetFileSpec() const { return m_file; }
60
64
66 return (m_platform_file ? &m_platform_file : nullptr);
67 }
68
70
71 const FileSpec &GetPlatformFileSpec() const { return m_platform_file; }
72
74 return (m_symbol_file ? &m_symbol_file : nullptr);
75 }
76
78 return (m_symbol_file ? &m_symbol_file : nullptr);
79 }
80
82
83 const FileSpec &GetSymbolFileSpec() const { return m_symbol_file; }
84
86 return (m_arch.IsValid() ? &m_arch : nullptr);
87 }
88
90 return (m_arch.IsValid() ? &m_arch : nullptr);
91 }
92
94
95 const ArchSpec &GetArchitecture() const { return m_arch; }
96
97 UUID *GetUUIDPtr() { return (m_uuid.IsValid() ? &m_uuid : nullptr); }
98
99 const UUID *GetUUIDPtr() const {
100 return (m_uuid.IsValid() ? &m_uuid : nullptr);
101 }
102
103 UUID &GetUUID() { return m_uuid; }
104
105 const UUID &GetUUID() const { return m_uuid; }
106
108
110
111 uint64_t GetObjectOffset() const { return m_object_offset; }
112
113 void SetObjectOffset(uint64_t object_offset) {
114 m_object_offset = object_offset;
115 }
116
117 uint64_t GetObjectSize() const { return m_object_size; }
118
119 void SetObjectSize(uint64_t object_size) { m_object_size = object_size; }
120
121 llvm::sys::TimePoint<> &GetObjectModificationTime() {
122 return m_object_mod_time;
123 }
124
125 const llvm::sys::TimePoint<> &GetObjectModificationTime() const {
126 return m_object_mod_time;
127 }
128
130
132
133 lldb::TargetSP GetTargetSP() const { return m_target_wp.lock(); }
134
135 /// Set the target to be used when resolving a module.
136 ///
137 /// A target can help locate a module specified by a ModuleSpec. The target
138 /// settings, like the executable and debug info search paths, can be
139 /// essential. The target's platform can also be used to locate or download
140 /// the specified module.
141 void SetTarget(lldb::TargetSP target) { m_target_wp = target; }
142
144
145 /// Set the platform to be used when resolving a module.
146 ///
147 /// This is useful when a Target is not yet available (e.g., during target
148 /// creation) but a Platform is. The platform can be used to invoke locate
149 /// module callbacks and other platform-specific module resolution logic.
150 void SetPlatform(lldb::PlatformSP platform) { m_platform_wp = platform; }
151
152 void Clear() {
153 m_file.Clear();
154 m_platform_file.Clear();
155 m_symbol_file.Clear();
156 m_arch.Clear();
157 m_uuid.Clear();
158 m_object_name.Clear();
159 m_object_offset = 0;
160 m_object_size = 0;
161 m_source_mappings.Clear(false);
162 m_object_mod_time = llvm::sys::TimePoint<>();
163 m_target_wp.reset();
164 m_platform_wp.reset();
165 }
166
167 explicit operator bool() const {
168 if (m_file)
169 return true;
170 if (m_platform_file)
171 return true;
172 if (m_symbol_file)
173 return true;
174 if (m_arch.IsValid())
175 return true;
176 if (m_uuid.IsValid())
177 return true;
178 if (m_object_name)
179 return true;
180 if (m_object_size)
181 return true;
182 if (m_object_mod_time != llvm::sys::TimePoint<>())
183 return true;
184 return false;
185 }
186
187 void Dump(Stream &strm) const {
188 bool dumped_something = false;
189 if (m_file) {
190 strm.PutCString("file = '");
191 strm << m_file;
192 strm.PutCString("'");
193 dumped_something = true;
194 }
195 if (m_platform_file) {
196 if (dumped_something)
197 strm.PutCString(", ");
198 strm.PutCString("platform_file = '");
199 strm << m_platform_file;
200 strm.PutCString("'");
201 dumped_something = true;
202 }
203 if (m_symbol_file) {
204 if (dumped_something)
205 strm.PutCString(", ");
206 strm.PutCString("symbol_file = '");
207 strm << m_symbol_file;
208 strm.PutCString("'");
209 dumped_something = true;
210 }
211 if (m_arch.IsValid()) {
212 if (dumped_something)
213 strm.PutCString(", ");
214 strm.Printf("arch = ");
215 m_arch.DumpTriple(strm.AsRawOstream());
216 dumped_something = true;
217 }
218 if (m_uuid.IsValid()) {
219 if (dumped_something)
220 strm.PutCString(", ");
221 strm.PutCString("uuid = ");
222 m_uuid.Dump(strm);
223 dumped_something = true;
224 }
225 if (m_object_name) {
226 if (dumped_something)
227 strm.PutCString(", ");
228 strm.Printf("object_name = %s", m_object_name.GetCString());
229 dumped_something = true;
230 }
231 if (m_object_offset > 0) {
232 if (dumped_something)
233 strm.PutCString(", ");
234 strm.Printf("object_offset = %" PRIu64, m_object_offset);
235 dumped_something = true;
236 }
237 if (m_object_size > 0) {
238 if (dumped_something)
239 strm.PutCString(", ");
240 strm.Printf("object size = %" PRIu64, m_object_size);
241 dumped_something = true;
242 }
243 if (m_object_mod_time != llvm::sys::TimePoint<>()) {
244 if (dumped_something)
245 strm.PutCString(", ");
246 strm.Format("object_mod_time = {0:x+}",
247 uint64_t(llvm::sys::toTimeT(m_object_mod_time)));
248 }
249 }
250
251 bool Matches(const ModuleSpec &match_module_spec,
252 bool exact_arch_match) const {
253 if (match_module_spec.GetUUIDPtr() &&
254 match_module_spec.GetUUID() != GetUUID())
255 return false;
256 if (match_module_spec.GetObjectName() &&
257 match_module_spec.GetObjectName() != GetObjectName())
258 return false;
259 if (!FileSpec::Match(match_module_spec.GetFileSpec(), GetFileSpec()))
260 return false;
261 if (GetPlatformFileSpec() &&
262 !FileSpec::Match(match_module_spec.GetPlatformFileSpec(),
264 return false;
265 }
266 // Only match the symbol file spec if there is one in this ModuleSpec
267 if (GetSymbolFileSpec() &&
268 !FileSpec::Match(match_module_spec.GetSymbolFileSpec(),
270 return false;
271 }
272 if (match_module_spec.GetArchitecturePtr()) {
273 if (exact_arch_match) {
274 if (!GetArchitecture().IsExactMatch(
275 match_module_spec.GetArchitecture()))
276 return false;
277 } else {
278 if (!GetArchitecture().IsCompatibleMatch(
279 match_module_spec.GetArchitecture()))
280 return false;
281 }
282 }
283 return true;
284 }
285
286protected:
293 /// The target used when resolving a module. A target can help locate a module
294 /// specified by a ModuleSpec. The target settings, like the executable and
295 /// debug info search paths, can be essential. The target's platform can also
296 /// be used to locate or download the specified module.
297 std::weak_ptr<Target> m_target_wp;
298 /// The platform used when resolving a module. This is useful when a Target
299 /// is not yet available (e.g., during target creation) but a Platform is.
300 std::weak_ptr<Platform> m_platform_wp;
301 uint64_t m_object_offset = 0;
302 uint64_t m_object_size = 0;
303 llvm::sys::TimePoint<> m_object_mod_time;
306};
307
309public:
310 ModuleSpecList() = default;
311
313 std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex);
314 std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex);
315 m_specs = rhs.m_specs;
316 }
317
318 ~ModuleSpecList() = default;
319
321 if (this != &rhs) {
322 std::lock(m_mutex, rhs.m_mutex);
323 std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex, std::adopt_lock);
324 std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex,
325 std::adopt_lock);
326 m_specs = rhs.m_specs;
327 }
328 return *this;
329 }
330
331 size_t GetSize() const {
332 std::lock_guard<std::recursive_mutex> guard(m_mutex);
333 return m_specs.size();
334 }
335
336 void Clear() {
337 std::lock_guard<std::recursive_mutex> guard(m_mutex);
338 m_specs.clear();
339 }
340
341 void Append(const ModuleSpec &spec) {
342 std::lock_guard<std::recursive_mutex> guard(m_mutex);
343 m_specs.push_back(spec);
344 }
345
346 void Append(const ModuleSpecList &rhs) {
347 std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex);
348 std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex);
349 m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end());
350 }
351
352 // The index "i" must be valid and this can't be used in multi-threaded code
353 // as no mutex lock is taken.
355
356 bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const {
357 std::lock_guard<std::recursive_mutex> guard(m_mutex);
358 if (i < m_specs.size()) {
359 module_spec = m_specs[i];
360 return true;
361 }
362 module_spec.Clear();
363 return false;
364 }
365
366 bool FindMatchingModuleSpec(const ModuleSpec &module_spec,
367 ModuleSpec &match_module_spec) const {
368 std::lock_guard<std::recursive_mutex> guard(m_mutex);
369 bool exact_arch_match = true;
370 for (auto spec : m_specs) {
371 if (spec.Matches(module_spec, exact_arch_match)) {
372 match_module_spec = spec;
373 return true;
374 }
375 }
376
377 // If there was an architecture, retry with a compatible arch
378 if (module_spec.GetArchitecturePtr()) {
379 exact_arch_match = false;
380 for (auto spec : m_specs) {
381 if (spec.Matches(module_spec, exact_arch_match)) {
382 match_module_spec = spec;
383 return true;
384 }
385 }
386 }
387 match_module_spec.Clear();
388 return false;
389 }
390
391 void FindMatchingModuleSpecs(const ModuleSpec &module_spec,
392 ModuleSpecList &matching_list) const {
393 std::lock_guard<std::recursive_mutex> guard(m_mutex);
394 bool exact_arch_match = true;
395 const size_t initial_match_count = matching_list.GetSize();
396 for (auto spec : m_specs) {
397 if (spec.Matches(module_spec, exact_arch_match))
398 matching_list.Append(spec);
399 }
400
401 // If there was an architecture, retry with a compatible arch if no matches
402 // were found
403 if (module_spec.GetArchitecturePtr() &&
404 (initial_match_count == matching_list.GetSize())) {
405 exact_arch_match = false;
406 for (auto spec : m_specs) {
407 if (spec.Matches(module_spec, exact_arch_match))
408 matching_list.Append(spec);
409 }
410 }
411 }
412
413 void Dump(Stream &strm) {
414 std::lock_guard<std::recursive_mutex> guard(m_mutex);
415 uint32_t idx = 0;
416 for (auto spec : m_specs) {
417 strm.Printf("[%u] ", idx);
418 spec.Dump(strm);
419 strm.EOL();
420 ++idx;
421 }
422 }
423
424 typedef std::vector<ModuleSpec> collection;
427
431
432protected:
433 collection m_specs; ///< The collection of modules.
434 mutable std::recursive_mutex m_mutex;
435};
436
437} // namespace lldb_private
438
439#endif // LLDB_CORE_MODULESPEC_H
An architecture specification class.
Definition ArchSpec.h:31
A uniqued constant string class.
Definition ConstString.h:40
A file utility class.
Definition FileSpec.h:57
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
Definition FileSpec.cpp:301
static FileSystem & Instance()
std::recursive_mutex m_mutex
Definition ModuleSpec.h:434
ModuleSpecList & operator=(const ModuleSpecList &rhs)
Definition ModuleSpec.h:320
collection m_specs
The collection of modules.
Definition ModuleSpec.h:433
void Dump(Stream &strm)
Definition ModuleSpec.h:413
std::vector< ModuleSpec > collection
Definition ModuleSpec.h:424
ModuleSpecIterable ModuleSpecs()
Definition ModuleSpec.h:428
bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const
Definition ModuleSpec.h:356
void Append(const ModuleSpec &spec)
Definition ModuleSpec.h:341
bool FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
Definition ModuleSpec.h:366
LockingAdaptedIterable< std::recursive_mutex, collection > ModuleSpecIterable
Definition ModuleSpec.h:426
ModuleSpecList(const ModuleSpecList &rhs)
Definition ModuleSpec.h:312
ModuleSpec & GetModuleSpecRefAtIndex(size_t i)
Definition ModuleSpec.h:354
void Append(const ModuleSpecList &rhs)
Definition ModuleSpec.h:346
void FindMatchingModuleSpecs(const ModuleSpec &module_spec, ModuleSpecList &matching_list) const
Definition ModuleSpec.h:391
PathMappingList & GetSourceMappingList() const
Definition ModuleSpec.h:129
void SetPlatform(lldb::PlatformSP platform)
Set the platform to be used when resolving a module.
Definition ModuleSpec.h:150
const UUID & GetUUID() const
Definition ModuleSpec.h:105
void SetObjectSize(uint64_t object_size)
Definition ModuleSpec.h:119
uint64_t GetObjectOffset() const
Definition ModuleSpec.h:111
lldb::DataExtractorSP m_extractor_sp
Definition ModuleSpec.h:305
void Dump(Stream &strm) const
Definition ModuleSpec.h:187
const ArchSpec * GetArchitecturePtr() const
Definition ModuleSpec.h:89
bool Matches(const ModuleSpec &match_module_spec, bool exact_arch_match) const
Definition ModuleSpec.h:251
ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch)
Definition ModuleSpec.h:47
ConstString & GetObjectName()
Definition ModuleSpec.h:107
std::weak_ptr< Target > m_target_wp
The target used when resolving a module.
Definition ModuleSpec.h:297
FileSpec & GetPlatformFileSpec()
Definition ModuleSpec.h:69
PathMappingList m_source_mappings
Definition ModuleSpec.h:304
const FileSpec * GetSymbolFileSpecPtr() const
Definition ModuleSpec.h:77
FileSpec * GetSymbolFileSpecPtr()
Definition ModuleSpec.h:73
const FileSpec * GetFileSpecPtr() const
Definition ModuleSpec.h:53
const FileSpec & GetPlatformFileSpec() const
Definition ModuleSpec.h:71
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
const FileSpec * GetPlatformFileSpecPtr() const
Definition ModuleSpec.h:65
FileSpec * GetPlatformFileSpecPtr()
Definition ModuleSpec.h:61
lldb::PlatformSP GetPlatformSP() const
Definition ModuleSpec.h:143
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
void SetObjectOffset(uint64_t object_offset)
Definition ModuleSpec.h:113
FileSpec * GetFileSpecPtr()
Definition ModuleSpec.h:51
FileSpec & GetSymbolFileSpec()
Definition ModuleSpec.h:81
const FileSpec & GetFileSpec() const
Definition ModuleSpec.h:59
const ArchSpec & GetArchitecture() const
Definition ModuleSpec.h:95
const UUID * GetUUIDPtr() const
Definition ModuleSpec.h:99
std::weak_ptr< Platform > m_platform_wp
The platform used when resolving a module.
Definition ModuleSpec.h:300
llvm::sys::TimePoint & GetObjectModificationTime()
Definition ModuleSpec.h:121
lldb::DataExtractorSP GetExtractor() const
Definition ModuleSpec.h:131
ArchSpec * GetArchitecturePtr()
Definition ModuleSpec.h:85
void SetTarget(lldb::TargetSP target)
Set the target to be used when resolving a module.
Definition ModuleSpec.h:141
const FileSpec & GetSymbolFileSpec() const
Definition ModuleSpec.h:83
ConstString GetObjectName() const
Definition ModuleSpec.h:109
llvm::sys::TimePoint m_object_mod_time
Definition ModuleSpec.h:303
const llvm::sys::TimePoint & GetObjectModificationTime() const
Definition ModuleSpec.h:125
uint64_t GetObjectSize() const
Definition ModuleSpec.h:117
lldb::TargetSP GetTargetSP() const
Definition ModuleSpec.h:133
ModuleSpec(const FileSpec &file_spec, const UUID &uuid=UUID(), lldb::DataExtractorSP extractor_sp=lldb::DataExtractorSP())
If the extractor_sp argument is passed, its contents will be used as the module contents instead of t...
Definition ModuleSpec.h:37
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Definition Stream.h:364
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:406
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
Represents UUID's of various sizes.
Definition UUID.h:27
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Platform > PlatformSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP