Home | History | Annotate | Download | only in Core
      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 
     19 namespace lldb_private {
     20 
     21 class ModuleSpec
     22 {
     23 public:
     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         if (m_object_name)
    355         {
    356             if (dumped_something)
    357                 strm.PutCString(", ");
    358             strm.Printf("object_name = %s", m_object_name.GetCString());
    359             dumped_something = true;
    360         }
    361         if (m_object_offset > 0)
    362         {
    363             if (dumped_something)
    364                 strm.PutCString(", ");
    365             strm.Printf("object_offset = 0x%" PRIx64, m_object_offset);
    366             dumped_something = true;
    367         }
    368         if (m_object_mod_time.IsValid())
    369         {
    370             if (dumped_something)
    371                 strm.PutCString(", ");
    372             strm.Printf("object_mod_time = 0x%" PRIx64, m_object_mod_time.GetAsSecondsSinceJan1_1970());
    373             dumped_something = true;
    374         }
    375     }
    376 
    377     bool
    378     Matches (const ModuleSpec &match_module_spec, bool exact_arch_match) const
    379     {
    380         if (match_module_spec.GetUUIDPtr() && match_module_spec.GetUUID() != GetUUID())
    381             return false;
    382         if (match_module_spec.GetObjectName() && match_module_spec.GetObjectName() != GetObjectName())
    383             return false;
    384         if (match_module_spec.GetFileSpecPtr())
    385         {
    386             const FileSpec &fspec = match_module_spec.GetFileSpec();
    387             if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false))
    388                 return false;
    389         }
    390         if (match_module_spec.GetPlatformFileSpecPtr())
    391         {
    392             const FileSpec &fspec = match_module_spec.GetPlatformFileSpec();
    393             if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false))
    394                 return false;
    395 
    396         }
    397         if (match_module_spec.GetSymbolFileSpecPtr())
    398         {
    399             const FileSpec &fspec = match_module_spec.GetSymbolFileSpec();
    400             if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false))
    401                 return false;
    402 
    403         }
    404         if (match_module_spec.GetArchitecturePtr())
    405         {
    406             if (exact_arch_match)
    407             {
    408                 if (!GetArchitecture().IsExactMatch(match_module_spec.GetArchitecture()))
    409                     return false;
    410             }
    411             else
    412             {
    413                 if (!GetArchitecture().IsCompatibleMatch(match_module_spec.GetArchitecture()))
    414                     return false;
    415             }
    416         }
    417         return true;
    418     }
    419 
    420 protected:
    421     FileSpec m_file;
    422     FileSpec m_platform_file;
    423     FileSpec m_symbol_file;
    424     ArchSpec m_arch;
    425     UUID m_uuid;
    426     ConstString m_object_name;
    427     uint64_t m_object_offset;
    428     TimeValue m_object_mod_time;
    429     mutable PathMappingList m_source_mappings;
    430 };
    431 
    432 class ModuleSpecList
    433 {
    434 public:
    435     ModuleSpecList () :
    436         m_specs(),
    437         m_mutex(Mutex::eMutexTypeRecursive)
    438     {
    439     }
    440 
    441     ModuleSpecList (const ModuleSpecList &rhs) :
    442         m_specs(),
    443         m_mutex(Mutex::eMutexTypeRecursive)
    444     {
    445         Mutex::Locker lhs_locker(m_mutex);
    446         Mutex::Locker rhs_locker(rhs.m_mutex);
    447         m_specs = rhs.m_specs;
    448     }
    449 
    450     ~ModuleSpecList ()
    451     {
    452     }
    453 
    454     ModuleSpecList &
    455     operator = (const ModuleSpecList &rhs)
    456     {
    457         if (this != &rhs)
    458         {
    459             Mutex::Locker lhs_locker(m_mutex);
    460             Mutex::Locker rhs_locker(rhs.m_mutex);
    461             m_specs = rhs.m_specs;
    462         }
    463         return *this;
    464     }
    465 
    466     size_t
    467     GetSize() const
    468     {
    469         Mutex::Locker locker(m_mutex);
    470         return m_specs.size();
    471     }
    472 
    473     void
    474     Clear ()
    475     {
    476         Mutex::Locker locker(m_mutex);
    477         m_specs.clear();
    478     }
    479 
    480     void
    481     Append (const ModuleSpec &spec)
    482     {
    483         Mutex::Locker locker(m_mutex);
    484         m_specs.push_back (spec);
    485     }
    486 
    487     void
    488     Append (const ModuleSpecList &rhs)
    489     {
    490         Mutex::Locker lhs_locker(m_mutex);
    491         Mutex::Locker rhs_locker(rhs.m_mutex);
    492         m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end());
    493     }
    494 
    495     // The index "i" must be valid and this can't be used in
    496     // multi-threaded code as no mutex lock is taken.
    497     ModuleSpec &
    498     GetModuleSpecRefAtIndex (size_t i)
    499     {
    500         return m_specs[i];
    501     }
    502     bool
    503     GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const
    504     {
    505         Mutex::Locker locker(m_mutex);
    506         if (i < m_specs.size())
    507         {
    508             module_spec = m_specs[i];
    509             return true;
    510         }
    511         module_spec.Clear();
    512         return false;
    513     }
    514 
    515 
    516     bool
    517     FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
    518     {
    519         Mutex::Locker locker(m_mutex);
    520         bool exact_arch_match = true;
    521         for (auto spec: m_specs)
    522         {
    523             if (spec.Matches(module_spec, exact_arch_match))
    524             {
    525                 match_module_spec = spec;
    526                 return true;
    527             }
    528         }
    529 
    530         // If there was an architecture, retry with a compatible arch
    531         if (module_spec.GetArchitecturePtr())
    532         {
    533             exact_arch_match = false;
    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         match_module_spec.Clear();
    544         return false;
    545     }
    546 
    547     size_t
    548     FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const
    549     {
    550         Mutex::Locker locker(m_mutex);
    551         bool exact_arch_match = true;
    552         const size_t initial_match_count = matching_list.GetSize();
    553         for (auto spec: m_specs)
    554         {
    555             if (spec.Matches(module_spec, exact_arch_match))
    556                 matching_list.Append (spec);
    557         }
    558 
    559         // If there was an architecture, retry with a compatible arch if no matches were found
    560         if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize()))
    561         {
    562             exact_arch_match = false;
    563             for (auto spec: m_specs)
    564             {
    565                 if (spec.Matches(module_spec, exact_arch_match))
    566                     matching_list.Append (spec);
    567             }
    568         }
    569         return matching_list.GetSize() - initial_match_count;
    570     }
    571 
    572     void
    573     Dump (Stream &strm)
    574     {
    575         Mutex::Locker locker(m_mutex);
    576         uint32_t idx = 0;
    577         for (auto spec: m_specs)
    578         {
    579             strm.Printf("[%u] ", idx);
    580             spec.Dump (strm);
    581             strm.EOL();
    582             ++idx;
    583         }
    584     }
    585 
    586 protected:
    587     typedef std::vector<ModuleSpec> collection; ///< The module collection type.
    588     collection m_specs; ///< The collection of modules.
    589     mutable Mutex m_mutex;
    590 };
    591 
    592 } // namespace lldb_private
    593 
    594 #endif  // liblldb_ModuleSpec_h_
    595