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