mirror of
https://github.com/opnsense/src.git
synced 2026-02-28 12:20:54 -05:00
607 lines
15 KiB
C++
607 lines
15 KiB
C++
//===-- 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_
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
#include <vector>
|
|
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
#include "lldb/Core/ArchSpec.h"
|
|
#include "lldb/Core/Stream.h"
|
|
#include "lldb/Core/UUID.h"
|
|
#include "lldb/Host/FileSpec.h"
|
|
#include "lldb/Host/Mutex.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_size (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_size (file_spec.GetByteSize ()),
|
|
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_size (file_spec.GetByteSize ()),
|
|
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_size (rhs.m_object_size),
|
|
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_size = rhs.m_object_size;
|
|
m_object_mod_time = rhs.m_object_mod_time;
|
|
m_source_mappings = rhs.m_source_mappings;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
FileSpec *
|
|
GetFileSpecPtr ()
|
|
{
|
|
return (m_file ? &m_file : nullptr);
|
|
}
|
|
|
|
const FileSpec *
|
|
GetFileSpecPtr () const
|
|
{
|
|
return (m_file ? &m_file : nullptr);
|
|
}
|
|
|
|
FileSpec &
|
|
GetFileSpec ()
|
|
{
|
|
return m_file;
|
|
}
|
|
|
|
const FileSpec &
|
|
GetFileSpec () const
|
|
{
|
|
return m_file;
|
|
}
|
|
|
|
FileSpec *
|
|
GetPlatformFileSpecPtr ()
|
|
{
|
|
return (m_platform_file ? &m_platform_file : nullptr);
|
|
}
|
|
|
|
const FileSpec *
|
|
GetPlatformFileSpecPtr () const
|
|
{
|
|
return (m_platform_file ? &m_platform_file : nullptr);
|
|
}
|
|
|
|
FileSpec &
|
|
GetPlatformFileSpec ()
|
|
{
|
|
return m_platform_file;
|
|
}
|
|
|
|
const FileSpec &
|
|
GetPlatformFileSpec () const
|
|
{
|
|
return m_platform_file;
|
|
}
|
|
|
|
FileSpec *
|
|
GetSymbolFileSpecPtr ()
|
|
{
|
|
return (m_symbol_file ? &m_symbol_file : nullptr);
|
|
}
|
|
|
|
const FileSpec *
|
|
GetSymbolFileSpecPtr () const
|
|
{
|
|
return (m_symbol_file ? &m_symbol_file : nullptr);
|
|
}
|
|
|
|
FileSpec &
|
|
GetSymbolFileSpec ()
|
|
{
|
|
return m_symbol_file;
|
|
}
|
|
|
|
const FileSpec &
|
|
GetSymbolFileSpec () const
|
|
{
|
|
return m_symbol_file;
|
|
}
|
|
|
|
ArchSpec *
|
|
GetArchitecturePtr ()
|
|
{
|
|
return (m_arch.IsValid() ? &m_arch : nullptr);
|
|
}
|
|
|
|
const ArchSpec *
|
|
GetArchitecturePtr () const
|
|
{
|
|
return (m_arch.IsValid() ? &m_arch : nullptr);
|
|
}
|
|
|
|
ArchSpec &
|
|
GetArchitecture ()
|
|
{
|
|
return m_arch;
|
|
}
|
|
|
|
const ArchSpec &
|
|
GetArchitecture () const
|
|
{
|
|
return m_arch;
|
|
}
|
|
|
|
UUID *
|
|
GetUUIDPtr ()
|
|
{
|
|
return (m_uuid.IsValid() ? &m_uuid : nullptr);
|
|
}
|
|
|
|
const UUID *
|
|
GetUUIDPtr () const
|
|
{
|
|
return (m_uuid.IsValid() ? &m_uuid : nullptr);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
uint64_t
|
|
GetObjectSize () const
|
|
{
|
|
return m_object_size;
|
|
}
|
|
|
|
void
|
|
SetObjectSize (uint64_t object_size)
|
|
{
|
|
m_object_size = object_size;
|
|
}
|
|
|
|
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_object_size = 0;
|
|
m_source_mappings.Clear(false);
|
|
m_object_mod_time.Clear();
|
|
}
|
|
|
|
explicit 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_size)
|
|
return true;
|
|
if (m_object_mod_time.IsValid())
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void
|
|
Dump (Stream &strm) const
|
|
{
|
|
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 = ");
|
|
m_arch.DumpTriple(strm);
|
|
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 = %" PRIu64, m_object_offset);
|
|
dumped_something = true;
|
|
}
|
|
if (m_object_size > 0)
|
|
{
|
|
if (dumped_something)
|
|
strm.PutCString(", ");
|
|
strm.Printf("object size = %" PRIu64, m_object_size);
|
|
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());
|
|
}
|
|
}
|
|
|
|
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 (GetPlatformFileSpec() && match_module_spec.GetPlatformFileSpecPtr())
|
|
{
|
|
const FileSpec &fspec = match_module_spec.GetPlatformFileSpec();
|
|
if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false))
|
|
return false;
|
|
|
|
}
|
|
// Only match the symbol file spec if there is one in this ModuleSpec
|
|
if (GetSymbolFileSpec() && 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;
|
|
uint64_t m_object_size;
|
|
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() = default;
|
|
|
|
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_
|