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