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