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