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