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