diff options
Diffstat (limited to 'include/lldb/Core/ModuleSpec.h')
-rw-r--r-- | include/lldb/Core/ModuleSpec.h | 594 |
1 files changed, 594 insertions, 0 deletions
diff --git a/include/lldb/Core/ModuleSpec.h b/include/lldb/Core/ModuleSpec.h new file mode 100644 index 000000000000..10e1ea9f17a9 --- /dev/null +++ b/include/lldb/Core/ModuleSpec.h @@ -0,0 +1,594 @@ +//===-- ModuleSpec.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ModuleSpec_h_ +#define liblldb_ModuleSpec_h_ + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/UUID.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Target/PathMappingList.h" + +namespace lldb_private { + +class ModuleSpec +{ +public: + ModuleSpec () : + m_file (), + m_platform_file (), + m_symbol_file (), + m_arch (), + m_uuid (), + m_object_name (), + m_object_offset (0), + m_object_mod_time (), + m_source_mappings () + { + } + + ModuleSpec (const FileSpec &file_spec) : + m_file (file_spec), + m_platform_file (), + m_symbol_file (), + m_arch (), + m_uuid (), + m_object_name (), + m_object_offset (0), + m_object_mod_time (), + m_source_mappings () + { + } + + ModuleSpec (const FileSpec &file_spec, const ArchSpec &arch) : + m_file (file_spec), + m_platform_file (), + m_symbol_file (), + m_arch (arch), + m_uuid (), + m_object_name (), + m_object_offset (0), + m_object_mod_time (), + m_source_mappings () + { + } + + ModuleSpec (const ModuleSpec &rhs) : + m_file (rhs.m_file), + m_platform_file (rhs.m_platform_file), + m_symbol_file (rhs.m_symbol_file), + m_arch (rhs.m_arch), + m_uuid (rhs.m_uuid), + m_object_name (rhs.m_object_name), + m_object_offset (rhs.m_object_offset), + m_object_mod_time (rhs.m_object_mod_time), + m_source_mappings (rhs.m_source_mappings) + { + } + + ModuleSpec & + operator = (const ModuleSpec &rhs) + { + if (this != &rhs) + { + m_file = rhs.m_file; + m_platform_file = rhs.m_platform_file; + m_symbol_file = rhs.m_symbol_file; + m_arch = rhs.m_arch; + m_uuid = rhs.m_uuid; + m_object_name = rhs.m_object_name; + m_object_offset = rhs.m_object_offset; + m_object_mod_time = rhs.m_object_mod_time; + m_source_mappings = rhs.m_source_mappings; + } + return *this; + } + + FileSpec * + GetFileSpecPtr () + { + if (m_file) + return &m_file; + return NULL; + } + + const FileSpec * + GetFileSpecPtr () const + { + if (m_file) + return &m_file; + return NULL; + } + + FileSpec & + GetFileSpec () + { + return m_file; + } + const FileSpec & + GetFileSpec () const + { + return m_file; + } + + FileSpec * + GetPlatformFileSpecPtr () + { + if (m_platform_file) + return &m_platform_file; + return NULL; + } + + const FileSpec * + GetPlatformFileSpecPtr () const + { + if (m_platform_file) + return &m_platform_file; + return NULL; + } + + FileSpec & + GetPlatformFileSpec () + { + return m_platform_file; + } + + const FileSpec & + GetPlatformFileSpec () const + { + return m_platform_file; + } + + FileSpec * + GetSymbolFileSpecPtr () + { + if (m_symbol_file) + return &m_symbol_file; + return NULL; + } + + const FileSpec * + GetSymbolFileSpecPtr () const + { + if (m_symbol_file) + return &m_symbol_file; + return NULL; + } + + FileSpec & + GetSymbolFileSpec () + { + return m_symbol_file; + } + + const FileSpec & + GetSymbolFileSpec () const + { + return m_symbol_file; + } + + + ArchSpec * + GetArchitecturePtr () + { + if (m_arch.IsValid()) + return &m_arch; + return NULL; + } + + const ArchSpec * + GetArchitecturePtr () const + { + if (m_arch.IsValid()) + return &m_arch; + return NULL; + } + + ArchSpec & + GetArchitecture () + { + return m_arch; + } + + const ArchSpec & + GetArchitecture () const + { + return m_arch; + } + + UUID * + GetUUIDPtr () + { + if (m_uuid.IsValid()) + return &m_uuid; + return NULL; + } + + const UUID * + GetUUIDPtr () const + { + if (m_uuid.IsValid()) + return &m_uuid; + return NULL; + } + + UUID & + GetUUID () + { + return m_uuid; + } + + const UUID & + GetUUID () const + { + return m_uuid; + } + + ConstString & + GetObjectName () + { + return m_object_name; + } + + const ConstString & + GetObjectName () const + { + return m_object_name; + } + + uint64_t + GetObjectOffset () const + { + return m_object_offset; + } + + void + SetObjectOffset (uint64_t object_offset) + { + m_object_offset = object_offset; + } + + TimeValue & + GetObjectModificationTime () + { + return m_object_mod_time; + } + + const TimeValue & + GetObjectModificationTime () const + { + return m_object_mod_time; + } + + PathMappingList & + GetSourceMappingList () const + { + return m_source_mappings; + } + + void + Clear () + { + m_file.Clear(); + m_platform_file.Clear(); + m_symbol_file.Clear(); + m_arch.Clear(); + m_uuid.Clear(); + m_object_name.Clear(); + m_object_offset = 0; + m_source_mappings.Clear(false); + m_object_mod_time.Clear(); + } + + + operator bool () const + { + if (m_file) + return true; + if (m_platform_file) + return true; + if (m_symbol_file) + return true; + if (m_arch.IsValid()) + return true; + if (m_uuid.IsValid()) + return true; + if (m_object_name) + return true; + if (m_object_mod_time.IsValid()) + return true; + return false; + } + + void + Dump (Stream &strm) + { + bool dumped_something = false; + if (m_file) + { + strm.PutCString("file = '"); + strm << m_file; + strm.PutCString("'"); + dumped_something = true; + } + if (m_platform_file) + { + if (dumped_something) + strm.PutCString(", "); + strm.PutCString("platform_file = '"); + strm << m_platform_file; + strm.PutCString("'"); + dumped_something = true; + } + if (m_symbol_file) + { + if (dumped_something) + strm.PutCString(", "); + strm.PutCString("symbol_file = '"); + strm << m_symbol_file; + strm.PutCString("'"); + dumped_something = true; + } + if (m_arch.IsValid()) + { + if (dumped_something) + strm.PutCString(", "); + strm.Printf("arch = %s", m_arch.GetTriple().str().c_str()); + dumped_something = true; + } + if (m_uuid.IsValid()) + { + if (dumped_something) + strm.PutCString(", "); + strm.PutCString("uuid = "); + m_uuid.Dump(&strm); + dumped_something = true; + } + if (m_object_name) + { + if (dumped_something) + strm.PutCString(", "); + strm.Printf("object_name = %s", m_object_name.GetCString()); + dumped_something = true; + } + if (m_object_offset > 0) + { + if (dumped_something) + strm.PutCString(", "); + strm.Printf("object_offset = 0x%" PRIx64, m_object_offset); + dumped_something = true; + } + if (m_object_mod_time.IsValid()) + { + if (dumped_something) + strm.PutCString(", "); + strm.Printf("object_mod_time = 0x%" PRIx64, m_object_mod_time.GetAsSecondsSinceJan1_1970()); + dumped_something = true; + } + } + + bool + Matches (const ModuleSpec &match_module_spec, bool exact_arch_match) const + { + if (match_module_spec.GetUUIDPtr() && match_module_spec.GetUUID() != GetUUID()) + return false; + if (match_module_spec.GetObjectName() && match_module_spec.GetObjectName() != GetObjectName()) + return false; + if (match_module_spec.GetFileSpecPtr()) + { + const FileSpec &fspec = match_module_spec.GetFileSpec(); + if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false)) + return false; + } + if (match_module_spec.GetPlatformFileSpecPtr()) + { + const FileSpec &fspec = match_module_spec.GetPlatformFileSpec(); + if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false)) + return false; + + } + if (match_module_spec.GetSymbolFileSpecPtr()) + { + const FileSpec &fspec = match_module_spec.GetSymbolFileSpec(); + if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false)) + return false; + + } + if (match_module_spec.GetArchitecturePtr()) + { + if (exact_arch_match) + { + if (!GetArchitecture().IsExactMatch(match_module_spec.GetArchitecture())) + return false; + } + else + { + if (!GetArchitecture().IsCompatibleMatch(match_module_spec.GetArchitecture())) + return false; + } + } + return true; + } + +protected: + FileSpec m_file; + FileSpec m_platform_file; + FileSpec m_symbol_file; + ArchSpec m_arch; + UUID m_uuid; + ConstString m_object_name; + uint64_t m_object_offset; + TimeValue m_object_mod_time; + mutable PathMappingList m_source_mappings; +}; + +class ModuleSpecList +{ +public: + ModuleSpecList () : + m_specs(), + m_mutex(Mutex::eMutexTypeRecursive) + { + } + + ModuleSpecList (const ModuleSpecList &rhs) : + m_specs(), + m_mutex(Mutex::eMutexTypeRecursive) + { + Mutex::Locker lhs_locker(m_mutex); + Mutex::Locker rhs_locker(rhs.m_mutex); + m_specs = rhs.m_specs; + } + + ~ModuleSpecList () + { + } + + ModuleSpecList & + operator = (const ModuleSpecList &rhs) + { + if (this != &rhs) + { + Mutex::Locker lhs_locker(m_mutex); + Mutex::Locker rhs_locker(rhs.m_mutex); + m_specs = rhs.m_specs; + } + return *this; + } + + size_t + GetSize() const + { + Mutex::Locker locker(m_mutex); + return m_specs.size(); + } + + void + Clear () + { + Mutex::Locker locker(m_mutex); + m_specs.clear(); + } + + void + Append (const ModuleSpec &spec) + { + Mutex::Locker locker(m_mutex); + m_specs.push_back (spec); + } + + void + Append (const ModuleSpecList &rhs) + { + Mutex::Locker lhs_locker(m_mutex); + Mutex::Locker rhs_locker(rhs.m_mutex); + m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end()); + } + + // The index "i" must be valid and this can't be used in + // multi-threaded code as no mutex lock is taken. + ModuleSpec & + GetModuleSpecRefAtIndex (size_t i) + { + return m_specs[i]; + } + bool + GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const + { + Mutex::Locker locker(m_mutex); + if (i < m_specs.size()) + { + module_spec = m_specs[i]; + return true; + } + module_spec.Clear(); + return false; + } + + + bool + FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const + { + Mutex::Locker locker(m_mutex); + bool exact_arch_match = true; + for (auto spec: m_specs) + { + if (spec.Matches(module_spec, exact_arch_match)) + { + match_module_spec = spec; + return true; + } + } + + // If there was an architecture, retry with a compatible arch + if (module_spec.GetArchitecturePtr()) + { + exact_arch_match = false; + for (auto spec: m_specs) + { + if (spec.Matches(module_spec, exact_arch_match)) + { + match_module_spec = spec; + return true; + } + } + } + match_module_spec.Clear(); + return false; + } + + size_t + FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const + { + Mutex::Locker locker(m_mutex); + bool exact_arch_match = true; + const size_t initial_match_count = matching_list.GetSize(); + for (auto spec: m_specs) + { + if (spec.Matches(module_spec, exact_arch_match)) + matching_list.Append (spec); + } + + // If there was an architecture, retry with a compatible arch if no matches were found + if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize())) + { + exact_arch_match = false; + for (auto spec: m_specs) + { + if (spec.Matches(module_spec, exact_arch_match)) + matching_list.Append (spec); + } + } + return matching_list.GetSize() - initial_match_count; + } + + void + Dump (Stream &strm) + { + Mutex::Locker locker(m_mutex); + uint32_t idx = 0; + for (auto spec: m_specs) + { + strm.Printf("[%u] ", idx); + spec.Dump (strm); + strm.EOL(); + ++idx; + } + } + +protected: + typedef std::vector<ModuleSpec> collection; ///< The module collection type. + collection m_specs; ///< The collection of modules. + mutable Mutex m_mutex; +}; + +} // namespace lldb_private + +#endif // liblldb_ModuleSpec_h_ |