]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Core/ModuleSpec.h
Merge ^/head r294777 through r294960.
[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 // C Includes
14 // C++ Includes
15 #include <vector>
16
17 // Other libraries and framework includes
18 // Project includes
19 #include "lldb/Core/ArchSpec.h"
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Core/UUID.h"
22 #include "lldb/Host/FileSpec.h"
23 #include "lldb/Host/Mutex.h"
24 #include "lldb/Target/PathMappingList.h"
25
26 namespace lldb_private {
27
28 class ModuleSpec
29 {
30 public:
31     ModuleSpec () :
32         m_file (),
33         m_platform_file (),
34         m_symbol_file (),
35         m_arch (),
36         m_uuid (),
37         m_object_name (),
38         m_object_offset (0),
39         m_object_size (0),
40         m_object_mod_time (),
41         m_source_mappings ()
42     {
43     }
44
45     ModuleSpec (const FileSpec &file_spec) :
46         m_file (file_spec),
47         m_platform_file (),
48         m_symbol_file (),
49         m_arch (),
50         m_uuid (),
51         m_object_name (),
52         m_object_offset (0),
53         m_object_size (file_spec.GetByteSize ()),
54         m_object_mod_time (),
55         m_source_mappings ()
56     {
57     }
58
59     ModuleSpec (const FileSpec &file_spec, const ArchSpec &arch) :
60         m_file (file_spec),
61         m_platform_file (),
62         m_symbol_file (),
63         m_arch (arch),
64         m_uuid (),
65         m_object_name (),
66         m_object_offset (0),
67         m_object_size (file_spec.GetByteSize ()),
68         m_object_mod_time (),
69         m_source_mappings ()
70     {
71     }
72     
73     ModuleSpec (const ModuleSpec &rhs) :
74         m_file (rhs.m_file),
75         m_platform_file (rhs.m_platform_file),
76         m_symbol_file (rhs.m_symbol_file),
77         m_arch (rhs.m_arch),
78         m_uuid (rhs.m_uuid),
79         m_object_name (rhs.m_object_name),
80         m_object_offset (rhs.m_object_offset),
81         m_object_size (rhs.m_object_size),
82         m_object_mod_time (rhs.m_object_mod_time),
83         m_source_mappings (rhs.m_source_mappings)
84     {
85     }
86
87     ModuleSpec &
88     operator = (const ModuleSpec &rhs)
89     {
90         if (this != &rhs)
91         {
92             m_file = rhs.m_file;
93             m_platform_file = rhs.m_platform_file;
94             m_symbol_file = rhs.m_symbol_file;
95             m_arch = rhs.m_arch;
96             m_uuid = rhs.m_uuid;
97             m_object_name = rhs.m_object_name;
98             m_object_offset = rhs.m_object_offset;
99             m_object_size = rhs.m_object_size;
100             m_object_mod_time = rhs.m_object_mod_time;
101             m_source_mappings = rhs.m_source_mappings;
102         }
103         return *this;
104     }
105
106     FileSpec *
107     GetFileSpecPtr ()
108     {
109         return (m_file ? &m_file : nullptr);
110     }
111
112     const FileSpec *
113     GetFileSpecPtr () const
114     {
115         return (m_file ? &m_file : nullptr);
116     }
117     
118     FileSpec &
119     GetFileSpec ()
120     {
121         return m_file;
122     }
123
124     const FileSpec &
125     GetFileSpec () const
126     {
127         return m_file;
128     }
129
130     FileSpec *
131     GetPlatformFileSpecPtr ()
132     {
133         return (m_platform_file ? &m_platform_file : nullptr);
134     }
135
136     const FileSpec *
137     GetPlatformFileSpecPtr () const
138     {
139         return (m_platform_file ? &m_platform_file : nullptr);
140     }
141
142     FileSpec &
143     GetPlatformFileSpec ()
144     {
145         return m_platform_file;
146     }
147
148     const FileSpec &
149     GetPlatformFileSpec () const
150     {
151         return m_platform_file;
152     }
153
154     FileSpec *
155     GetSymbolFileSpecPtr ()
156     {
157         return (m_symbol_file ? &m_symbol_file : nullptr);
158     }
159     
160     const FileSpec *
161     GetSymbolFileSpecPtr () const
162     {
163         return (m_symbol_file ? &m_symbol_file : nullptr);
164     }
165     
166     FileSpec &
167     GetSymbolFileSpec ()
168     {
169         return m_symbol_file;
170     }
171     
172     const FileSpec &
173     GetSymbolFileSpec () const
174     {
175         return m_symbol_file;
176     }
177
178     ArchSpec *
179     GetArchitecturePtr ()
180     {
181         return (m_arch.IsValid() ? &m_arch : nullptr);
182     }
183     
184     const ArchSpec *
185     GetArchitecturePtr () const
186     {
187         return (m_arch.IsValid() ? &m_arch : nullptr);
188     }
189     
190     ArchSpec &
191     GetArchitecture ()
192     {
193         return m_arch;
194     }
195     
196     const ArchSpec &
197     GetArchitecture () const
198     {
199         return m_arch;
200     }
201
202     UUID *
203     GetUUIDPtr ()
204     {
205         return (m_uuid.IsValid() ? &m_uuid : nullptr);
206     }
207     
208     const UUID *
209     GetUUIDPtr () const
210     {
211         return (m_uuid.IsValid() ? &m_uuid : nullptr);
212     }
213     
214     UUID &
215     GetUUID ()
216     {
217         return m_uuid;
218     }
219     
220     const UUID &
221     GetUUID () const
222     {
223         return m_uuid;
224     }
225
226     ConstString &
227     GetObjectName ()
228     {
229         return m_object_name;
230     }
231
232     const ConstString &
233     GetObjectName () const
234     {
235         return m_object_name;
236     }
237
238     uint64_t
239     GetObjectOffset () const
240     {
241         return m_object_offset;
242     }
243
244     void
245     SetObjectOffset (uint64_t object_offset)
246     {
247         m_object_offset = object_offset;
248     }
249
250     uint64_t
251     GetObjectSize () const
252     {
253         return m_object_size;
254     }
255
256     void
257     SetObjectSize (uint64_t object_size)
258     {
259         m_object_size = object_size;
260     }
261
262     TimeValue &
263     GetObjectModificationTime ()
264     {
265         return m_object_mod_time;
266     }
267     
268     const TimeValue &
269     GetObjectModificationTime () const
270     {
271         return m_object_mod_time;
272     }
273
274     PathMappingList &
275     GetSourceMappingList () const
276     {
277         return m_source_mappings;
278     }
279
280     void
281     Clear ()
282     {
283         m_file.Clear();
284         m_platform_file.Clear();
285         m_symbol_file.Clear();
286         m_arch.Clear();
287         m_uuid.Clear();
288         m_object_name.Clear();
289         m_object_offset = 0;
290         m_object_size = 0;
291         m_source_mappings.Clear(false);
292         m_object_mod_time.Clear();
293     }
294
295     explicit operator bool () const
296     {
297         if (m_file)
298             return true;
299         if (m_platform_file)
300             return true;
301         if (m_symbol_file)
302             return true;
303         if (m_arch.IsValid())
304             return true;
305         if (m_uuid.IsValid())
306             return true;
307         if (m_object_name)
308             return true;
309         if (m_object_size)
310             return true;
311         if (m_object_mod_time.IsValid())
312             return true;
313         return false;
314     }
315
316     void
317     Dump (Stream &strm) const
318     {
319         bool dumped_something = false;
320         if (m_file)
321         {
322             strm.PutCString("file = '");
323             strm << m_file;
324             strm.PutCString("'");
325             dumped_something = true;
326         }
327         if (m_platform_file)
328         {
329             if (dumped_something)
330                 strm.PutCString(", ");
331             strm.PutCString("platform_file = '");
332             strm << m_platform_file;
333             strm.PutCString("'");
334             dumped_something = true;
335         }
336         if (m_symbol_file)
337         {
338             if (dumped_something)
339                 strm.PutCString(", ");
340             strm.PutCString("symbol_file = '");
341             strm << m_symbol_file;
342             strm.PutCString("'");
343             dumped_something = true;
344         }
345         if (m_arch.IsValid())
346         {
347             if (dumped_something)
348                 strm.PutCString(", ");
349             strm.Printf("arch = ");
350             m_arch.DumpTriple(strm);
351             dumped_something = true;
352         }
353         if (m_uuid.IsValid())
354         {
355             if (dumped_something)
356                 strm.PutCString(", ");
357             strm.PutCString("uuid = ");
358             m_uuid.Dump(&strm);
359             dumped_something = true;
360         }
361         if (m_object_name)
362         {
363             if (dumped_something)
364                 strm.PutCString(", ");
365             strm.Printf("object_name = %s", m_object_name.GetCString());
366             dumped_something = true;
367         }
368         if (m_object_offset > 0)
369         {
370             if (dumped_something)
371                 strm.PutCString(", ");
372             strm.Printf("object_offset = %" PRIu64, m_object_offset);
373             dumped_something = true;
374         }
375         if (m_object_size > 0)
376         {
377             if (dumped_something)
378                 strm.PutCString(", ");
379             strm.Printf("object size = %" PRIu64, m_object_size);
380             dumped_something = true;
381         }
382         if (m_object_mod_time.IsValid())
383         {
384             if (dumped_something)
385                 strm.PutCString(", ");
386             strm.Printf("object_mod_time = 0x%" PRIx64, m_object_mod_time.GetAsSecondsSinceJan1_1970());
387         }
388     }
389
390     bool
391     Matches (const ModuleSpec &match_module_spec, bool exact_arch_match) const
392     {
393         if (match_module_spec.GetUUIDPtr() && match_module_spec.GetUUID() != GetUUID())
394             return false;
395         if (match_module_spec.GetObjectName() && match_module_spec.GetObjectName() != GetObjectName())
396             return false;
397         if (match_module_spec.GetFileSpecPtr())
398         {
399             const FileSpec &fspec = match_module_spec.GetFileSpec();
400             if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false))
401                 return false;
402         }
403         if (GetPlatformFileSpec() && match_module_spec.GetPlatformFileSpecPtr())
404         {
405             const FileSpec &fspec = match_module_spec.GetPlatformFileSpec();
406             if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false))
407                 return false;
408             
409         }
410         // Only match the symbol file spec if there is one in this ModuleSpec
411         if (GetSymbolFileSpec() && match_module_spec.GetSymbolFileSpecPtr())
412         {
413             const FileSpec &fspec = match_module_spec.GetSymbolFileSpec();
414             if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false))
415                 return false;
416             
417         }
418         if (match_module_spec.GetArchitecturePtr())
419         {
420             if (exact_arch_match)
421             {
422                 if (!GetArchitecture().IsExactMatch(match_module_spec.GetArchitecture()))
423                     return false;
424             }
425             else
426             {
427                 if (!GetArchitecture().IsCompatibleMatch(match_module_spec.GetArchitecture()))
428                     return false;
429             }
430         }
431         return true;
432     }
433
434 protected:
435     FileSpec m_file;
436     FileSpec m_platform_file;
437     FileSpec m_symbol_file;
438     ArchSpec m_arch;
439     UUID m_uuid;
440     ConstString m_object_name;
441     uint64_t m_object_offset;
442     uint64_t m_object_size;
443     TimeValue m_object_mod_time;
444     mutable PathMappingList m_source_mappings;
445 };
446
447 class ModuleSpecList
448 {
449 public:
450     ModuleSpecList () :
451         m_specs(),
452         m_mutex(Mutex::eMutexTypeRecursive) 
453     {
454     }
455
456     ModuleSpecList (const ModuleSpecList &rhs) :
457         m_specs(),
458         m_mutex(Mutex::eMutexTypeRecursive)
459     {
460         Mutex::Locker lhs_locker(m_mutex);
461         Mutex::Locker rhs_locker(rhs.m_mutex);
462         m_specs = rhs.m_specs;
463     }
464
465     ~ModuleSpecList() = default;
466
467     ModuleSpecList &
468     operator = (const ModuleSpecList &rhs)
469     {
470         if (this != &rhs)
471         {
472             Mutex::Locker lhs_locker(m_mutex);
473             Mutex::Locker rhs_locker(rhs.m_mutex);
474             m_specs = rhs.m_specs;
475         }
476         return *this;
477     }
478
479     size_t
480     GetSize() const
481     {
482         Mutex::Locker locker(m_mutex);
483         return m_specs.size();
484     }
485
486     void
487     Clear ()
488     {
489         Mutex::Locker locker(m_mutex);
490         m_specs.clear();
491     }
492
493     void
494     Append (const ModuleSpec &spec)
495     {
496         Mutex::Locker locker(m_mutex);
497         m_specs.push_back (spec);
498     }
499
500     void
501     Append (const ModuleSpecList &rhs)
502     {
503         Mutex::Locker lhs_locker(m_mutex);
504         Mutex::Locker rhs_locker(rhs.m_mutex);
505         m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end());
506     }
507
508     // The index "i" must be valid and this can't be used in
509     // multi-threaded code as no mutex lock is taken.
510     ModuleSpec &
511     GetModuleSpecRefAtIndex (size_t i)
512     {
513         return m_specs[i];
514     }
515
516     bool
517     GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const
518     {
519         Mutex::Locker locker(m_mutex);
520         if (i < m_specs.size())
521         {
522             module_spec = m_specs[i];
523             return true;
524         }
525         module_spec.Clear();
526         return false;
527     }
528
529     bool
530     FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
531     {
532         Mutex::Locker locker(m_mutex);
533         bool exact_arch_match = true;
534         for (auto spec: m_specs)
535         {
536             if (spec.Matches(module_spec, exact_arch_match))
537             {
538                 match_module_spec = spec;
539                 return true;
540             }
541         }
542         
543         // If there was an architecture, retry with a compatible arch
544         if (module_spec.GetArchitecturePtr())
545         {
546             exact_arch_match = false;
547             for (auto spec: m_specs)
548             {
549                 if (spec.Matches(module_spec, exact_arch_match))
550                 {
551                     match_module_spec = spec;
552                     return true;
553                 }
554             }
555         }
556         match_module_spec.Clear();
557         return false;
558     }
559     
560     size_t
561     FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const
562     {
563         Mutex::Locker locker(m_mutex);
564         bool exact_arch_match = true;
565         const size_t initial_match_count = matching_list.GetSize();
566         for (auto spec: m_specs)
567         {
568             if (spec.Matches(module_spec, exact_arch_match))
569                 matching_list.Append (spec);
570         }
571         
572         // If there was an architecture, retry with a compatible arch if no matches were found
573         if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize()))
574         {
575             exact_arch_match = false;
576             for (auto spec: m_specs)
577             {
578                 if (spec.Matches(module_spec, exact_arch_match))
579                     matching_list.Append (spec);
580             }
581         }
582         return matching_list.GetSize() - initial_match_count;
583     }
584
585     void
586     Dump (Stream &strm)
587     {
588         Mutex::Locker locker(m_mutex);
589         uint32_t idx = 0;
590         for (auto spec: m_specs)
591         {
592             strm.Printf("[%u] ", idx);
593             spec.Dump (strm);
594             strm.EOL();
595             ++idx;
596         }
597     }
598
599 protected:
600     typedef std::vector<ModuleSpec> collection; ///< The module collection type.
601     collection m_specs; ///< The collection of modules.
602     mutable Mutex m_mutex;
603 };
604
605 } // namespace lldb_private
606
607 #endif // liblldb_ModuleSpec_h_