mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 23:49:22 +08:00
[lldb][NFC] Change ObjectFile argument type (#171574)
The ObjectFile plugin interface accepts an optional DataBufferSP argument. If the caller has the contents of the binary, it can provide this in that DataBufferSP. The ObjectFile subclasses in their CreateInstance methods will fill in the DataBufferSP with the actual binary contents if it is not set. ObjectFile base class creates an ivar DataExtractor from the DataBufferSP passed in. My next patch will be a caller that creates a VirtualDataExtractor with the binary data, and needs to pass that in to the ObjectFile plugin, instead of the bag-of-bytes DataBufferSP. It builds on the previous patch changing ObjectFile's ivar from DataExtractor to DataExtractorSP so I could pass in a subclass in the shared ptr. And it will be using the VirtualDataExtractor that Jonas added in https://github.com/llvm/llvm-project/pull/168802 No behavior is changed by the patch; we're simply moving the creation of the DataExtractor to the caller, instead of a DataBuffer that is immediately used to set up the ObjectFile DataExtractor. The patch is a bit complicated because all of the ObjectFile subclasses have to initialize their DataExtractor to pass in to the base class. I ran the testsuite on macOS and on AArch64 Ubutnu. (btw David, I ran it under qemu on my M4 mac with SME-no-SVE again, Ubuntu 25.10, checked lshw(1) cpu capabilities, and qemu doesn't seem to be virtualizing the SME, that explains why the testsuite passes) rdar://148939795 --------- Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
This commit is contained in:
@@ -49,9 +49,10 @@ public:
|
||||
}
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static lldb_private::ObjectFile *CreateMemoryInstance(
|
||||
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
|
||||
|
||||
@@ -97,10 +97,10 @@ public:
|
||||
/// Attempts to parse the object header.
|
||||
///
|
||||
/// This function is used as a test to see if a given plug-in instance can
|
||||
/// parse the header data already contained in ObjectContainer::m_data. If
|
||||
/// an object file parser does not recognize that magic bytes in a header,
|
||||
/// false should be returned and the next plug-in can attempt to parse an
|
||||
/// object file.
|
||||
/// parse the header data already contained in
|
||||
/// ObjectContainer::m_extractor_sp. If an object file parser does not
|
||||
/// recognize that magic bytes in a header, false should be returned and the
|
||||
/// next plug-in can attempt to parse an object file.
|
||||
///
|
||||
/// \return
|
||||
/// Returns \b true if the header was parsed successfully, \b
|
||||
@@ -140,7 +140,7 @@ protected:
|
||||
lldb::addr_t m_length;
|
||||
|
||||
/// The data for this object file so things can be parsed lazily.
|
||||
DataExtractor m_data;
|
||||
lldb::DataExtractorSP m_extractor_sp;
|
||||
|
||||
private:
|
||||
ObjectContainer(const ObjectContainer &) = delete;
|
||||
|
||||
@@ -105,10 +105,10 @@ public:
|
||||
/// more than one architecture or object.
|
||||
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr,
|
||||
lldb::offset_t file_offset, lldb::offset_t length,
|
||||
lldb::DataBufferSP data_sp, lldb::offset_t data_offset);
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset);
|
||||
|
||||
ObjectFile(const lldb::ModuleSP &module_sp, const lldb::ProcessSP &process_sp,
|
||||
lldb::addr_t header_addr, lldb::DataBufferSP data_sp);
|
||||
lldb::addr_t header_addr, lldb::DataExtractorSP extractor_sp);
|
||||
|
||||
/// Destructor.
|
||||
///
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
static lldb::ObjectFileSP
|
||||
FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file_spec,
|
||||
lldb::offset_t file_offset, lldb::offset_t file_size,
|
||||
lldb::DataBufferSP &data_sp, lldb::offset_t &data_offset);
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t &data_offset);
|
||||
|
||||
/// Find a ObjectFile plug-in that can parse a file in memory.
|
||||
///
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef LLDB_UTILITY_DATAEXTRACTOR_H
|
||||
#define LLDB_UTILITY_DATAEXTRACTOR_H
|
||||
|
||||
#include "lldb/Utility/DataBuffer.h"
|
||||
#include "lldb/Utility/Endian.h"
|
||||
#include "lldb/lldb-defines.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
@@ -90,10 +91,10 @@ public:
|
||||
|
||||
/// Construct with shared data.
|
||||
///
|
||||
/// Copies the data shared pointer which adds a reference to the contained
|
||||
/// in \a data_sp. The shared data reference is reference counted to ensure
|
||||
/// the data lives as long as anyone still has a valid shared pointer to the
|
||||
/// data in \a data_sp.
|
||||
/// Copies the data shared pointer which adds a reference to the data
|
||||
/// contained in \a data_sp. The shared data reference is reference counted to
|
||||
/// ensure the data lives as long as anyone still has a valid shared pointer
|
||||
/// to the data in \a data_sp.
|
||||
///
|
||||
/// \param[in] data_sp
|
||||
/// A shared pointer to data.
|
||||
@@ -109,6 +110,18 @@ public:
|
||||
DataExtractor(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order,
|
||||
uint32_t addr_size, uint32_t target_byte_size = 1);
|
||||
|
||||
/// Construct with shared data, but byte-order & addr-size are unspecified.
|
||||
///
|
||||
/// Copies the data shared pointer which adds a reference to the data
|
||||
/// contained in \a data_sp. The shared data reference is reference counted to
|
||||
/// ensure the data lives as long as anyone still has a valid shared pointer
|
||||
/// to the data in \a data_sp.
|
||||
///
|
||||
/// \param[in] data_sp
|
||||
/// A shared pointer to data.
|
||||
DataExtractor(const lldb::DataBufferSP &data_sp,
|
||||
uint32_t target_byte_size = 1);
|
||||
|
||||
/// Construct with a subset of \a data.
|
||||
///
|
||||
/// Initialize this object with a subset of the data bytes in \a data. If \a
|
||||
@@ -807,6 +820,8 @@ public:
|
||||
|
||||
lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; }
|
||||
|
||||
bool HasData() { return m_start && m_end && m_end - m_start > 0; }
|
||||
|
||||
/// Peek at a C string at \a offset.
|
||||
///
|
||||
/// Peeks at a string in the contained data. No verification is done to make
|
||||
|
||||
@@ -49,12 +49,10 @@ typedef size_t (*ObjectFileGetModuleSpecifications)(
|
||||
const FileSpec &file, lldb::DataBufferSP &data_sp,
|
||||
lldb::offset_t data_offset, lldb::offset_t file_offset,
|
||||
lldb::offset_t length, ModuleSpecList &module_specs);
|
||||
typedef ObjectFile *(*ObjectFileCreateInstance)(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
typedef ObjectFile *(*ObjectFileCreateInstance)(
|
||||
const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
typedef ObjectFile *(*ObjectFileCreateMemoryInstance)(
|
||||
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
|
||||
const lldb::ProcessSP &process_sp, lldb::addr_t offset);
|
||||
|
||||
@@ -1206,10 +1206,12 @@ ObjectFile *Module::GetObjectFile() {
|
||||
m_did_load_objfile = true;
|
||||
// FindPlugin will modify its data_sp argument. Do not let it
|
||||
// modify our m_data_sp member.
|
||||
auto data_sp = m_data_sp;
|
||||
DataExtractorSP extractor_sp;
|
||||
if (m_data_sp)
|
||||
extractor_sp = std::make_shared<DataExtractor>(m_data_sp);
|
||||
m_objfile_sp = ObjectFile::FindPlugin(
|
||||
shared_from_this(), &m_file, m_object_offset,
|
||||
file_size - m_object_offset, data_sp, data_offset);
|
||||
file_size - m_object_offset, extractor_sp, data_offset);
|
||||
if (m_objfile_sp) {
|
||||
// Once we get the object file, update our module with the object
|
||||
// file's architecture since it might differ in vendor/os if some
|
||||
|
||||
@@ -41,7 +41,7 @@ void ObjectFileJIT::Terminate() {
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
@@ -70,7 +70,8 @@ size_t ObjectFileJIT::GetModuleSpecifications(
|
||||
|
||||
ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp,
|
||||
const ObjectFileJITDelegateSP &delegate_sp)
|
||||
: ObjectFile(module_sp, nullptr, 0, 0, DataBufferSP(), 0), m_delegate_wp() {
|
||||
: ObjectFile(module_sp, nullptr, 0, 0, DataExtractorSP(), 0),
|
||||
m_delegate_wp() {
|
||||
if (delegate_sp) {
|
||||
m_delegate_wp = delegate_sp;
|
||||
m_data_nsp->SetByteOrder(delegate_sp->GetByteOrder());
|
||||
|
||||
@@ -68,21 +68,19 @@ void ObjectContainerBSDArchive::Object::Dump() const {
|
||||
ObjectContainerBSDArchive::Archive::Archive(const lldb_private::ArchSpec &arch,
|
||||
const llvm::sys::TimePoint<> &time,
|
||||
lldb::offset_t file_offset,
|
||||
lldb_private::DataExtractor &data,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
ArchiveType archive_type)
|
||||
: m_arch(arch), m_modification_time(time), m_file_offset(file_offset),
|
||||
m_objects(), m_data(data), m_archive_type(archive_type) {}
|
||||
m_objects(), m_extractor_sp(extractor_sp), m_archive_type(archive_type) {}
|
||||
|
||||
Log *l = GetLog(LLDBLog::Object);
|
||||
ObjectContainerBSDArchive::Archive::~Archive() = default;
|
||||
|
||||
size_t ObjectContainerBSDArchive::Archive::ParseObjects() {
|
||||
DataExtractor &data = m_data;
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> mem_buffer =
|
||||
llvm::MemoryBuffer::getMemBuffer(
|
||||
llvm::StringRef((const char *)data.GetDataStart(),
|
||||
data.GetByteSize()),
|
||||
llvm::StringRef((const char *)m_extractor_sp->GetDataStart(),
|
||||
m_extractor_sp->GetByteSize()),
|
||||
llvm::StringRef(),
|
||||
/*RequiresNullTerminator=*/false);
|
||||
|
||||
@@ -221,9 +219,9 @@ ObjectContainerBSDArchive::Archive::shared_ptr
|
||||
ObjectContainerBSDArchive::Archive::ParseAndCacheArchiveForFile(
|
||||
const FileSpec &file, const ArchSpec &arch,
|
||||
const llvm::sys::TimePoint<> &time, lldb::offset_t file_offset,
|
||||
DataExtractor &data, ArchiveType archive_type) {
|
||||
DataExtractorSP extractor_sp, ArchiveType archive_type) {
|
||||
shared_ptr archive_sp(
|
||||
new Archive(arch, time, file_offset, data, archive_type));
|
||||
new Archive(arch, time, file_offset, extractor_sp, archive_type));
|
||||
if (archive_sp) {
|
||||
const size_t num_objects = archive_sp->ParseObjects();
|
||||
if (num_objects > 0) {
|
||||
@@ -368,16 +366,17 @@ ObjectContainerBSDArchive::~ObjectContainerBSDArchive() = default;
|
||||
|
||||
bool ObjectContainerBSDArchive::ParseHeader() {
|
||||
if (m_archive_sp.get() == nullptr) {
|
||||
if (m_data.GetByteSize() > 0) {
|
||||
if (m_extractor_sp->GetByteSize() > 0) {
|
||||
ModuleSP module_sp(GetModule());
|
||||
if (module_sp) {
|
||||
m_archive_sp = Archive::ParseAndCacheArchiveForFile(
|
||||
m_file, module_sp->GetArchitecture(),
|
||||
module_sp->GetModificationTime(), m_offset, m_data, m_archive_type);
|
||||
module_sp->GetModificationTime(), m_offset, m_extractor_sp,
|
||||
m_archive_type);
|
||||
}
|
||||
// Clear the m_data that contains the entire archive data and let our
|
||||
// m_archive_sp hold onto the data.
|
||||
m_data.Clear();
|
||||
// Clear the m_extractor_sp that contains the entire archive data and let
|
||||
// our m_archive_sp hold onto the data.
|
||||
m_extractor_sp = std::make_shared<DataExtractor>();
|
||||
}
|
||||
}
|
||||
return m_archive_sp.get() != nullptr;
|
||||
@@ -416,14 +415,18 @@ ObjectFileSP ObjectContainerBSDArchive::GetObjectFile(const FileSpec *file) {
|
||||
child_data_sp->GetByteSize() != object->file_size)
|
||||
return ObjectFileSP();
|
||||
lldb::offset_t data_offset = 0;
|
||||
DataExtractorSP extractor_sp =
|
||||
std::make_shared<DataExtractor>(child_data_sp);
|
||||
return ObjectFile::FindPlugin(
|
||||
module_sp, &child, m_offset + object->file_offset,
|
||||
object->file_size, child_data_sp, data_offset);
|
||||
object->file_size, extractor_sp, data_offset);
|
||||
}
|
||||
lldb::offset_t data_offset = object->file_offset;
|
||||
DataExtractorSP extractor_sp =
|
||||
std::make_shared<DataExtractor>(m_archive_sp->GetData());
|
||||
return ObjectFile::FindPlugin(
|
||||
module_sp, file, m_offset + object->file_offset, object->file_size,
|
||||
m_archive_sp->GetData().GetSharedDataBuffer(), data_offset);
|
||||
extractor_sp, data_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,9 +441,10 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications(
|
||||
// We have data, which means this is the first 512 bytes of the file Check to
|
||||
// see if the magic bytes match and if they do, read the entire table of
|
||||
// contents for the archive and cache it
|
||||
DataExtractor data;
|
||||
data.SetData(data_sp, data_offset, data_sp->GetByteSize());
|
||||
ArchiveType archive_type = ObjectContainerBSDArchive::MagicBytesMatch(data);
|
||||
DataExtractorSP extractor_sp = std::make_shared<DataExtractor>();
|
||||
extractor_sp->SetData(data_sp, data_offset, data_sp->GetByteSize());
|
||||
ArchiveType archive_type =
|
||||
ObjectContainerBSDArchive::MagicBytesMatch(*extractor_sp.get());
|
||||
if (!file || !data_sp || archive_type == ArchiveType::Invalid)
|
||||
return 0;
|
||||
|
||||
@@ -455,9 +459,10 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications(
|
||||
data_sp =
|
||||
FileSystem::Instance().CreateDataBuffer(file, file_size, file_offset);
|
||||
if (data_sp) {
|
||||
data.SetData(data_sp, 0, data_sp->GetByteSize());
|
||||
extractor_sp->SetData(data_sp);
|
||||
archive_sp = Archive::ParseAndCacheArchiveForFile(
|
||||
file, ArchSpec(), file_mod_time, file_offset, data, archive_type);
|
||||
file, ArchSpec(), file_mod_time, file_offset, extractor_sp,
|
||||
archive_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#include "lldb/Symbol/ObjectContainer.h"
|
||||
#include "lldb/Utility/ArchSpec.h"
|
||||
#include "lldb/Utility/ConstString.h"
|
||||
#include "lldb/Utility/DataExtractor.h"
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
#include "lldb/Utility/NonNullSharedPtr.h"
|
||||
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Support/Chrono.h"
|
||||
@@ -59,7 +61,8 @@ public:
|
||||
lldb::offset_t length,
|
||||
lldb_private::ModuleSpecList &specs);
|
||||
|
||||
static ArchiveType MagicBytesMatch(const lldb_private::DataExtractor &data);
|
||||
static ArchiveType
|
||||
MagicBytesMatch(const lldb_private::DataExtractor &extractor);
|
||||
|
||||
// Member Functions
|
||||
bool ParseHeader() override;
|
||||
@@ -81,11 +84,11 @@ protected:
|
||||
|
||||
void Clear();
|
||||
|
||||
lldb::offset_t ExtractFromThin(const lldb_private::DataExtractor &data,
|
||||
lldb::offset_t ExtractFromThin(const lldb_private::DataExtractor &extractor,
|
||||
lldb::offset_t offset,
|
||||
llvm::StringRef stringTable);
|
||||
|
||||
lldb::offset_t Extract(const lldb_private::DataExtractor &data,
|
||||
lldb::offset_t Extract(const lldb_private::DataExtractor &extractor,
|
||||
lldb::offset_t offset);
|
||||
/// Object name in the archive.
|
||||
lldb_private::ConstString ar_name;
|
||||
@@ -112,7 +115,7 @@ protected:
|
||||
|
||||
Archive(const lldb_private::ArchSpec &arch,
|
||||
const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
|
||||
lldb_private::DataExtractor &data, ArchiveType archive_type);
|
||||
lldb::DataExtractorSP extractor_sp, ArchiveType archive_type);
|
||||
|
||||
~Archive();
|
||||
|
||||
@@ -127,7 +130,7 @@ protected:
|
||||
static Archive::shared_ptr ParseAndCacheArchiveForFile(
|
||||
const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch,
|
||||
const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
|
||||
lldb_private::DataExtractor &data, ArchiveType archive_type);
|
||||
lldb::DataExtractorSP extractor_sp, ArchiveType archive_type);
|
||||
|
||||
size_t GetNumObjects() const { return m_objects.size(); }
|
||||
|
||||
@@ -154,7 +157,8 @@ protected:
|
||||
|
||||
bool HasNoExternalReferences() const;
|
||||
|
||||
lldb_private::DataExtractor &GetData() { return m_data; }
|
||||
lldb_private::DataExtractor &GetData() { return *m_extractor_sp.get(); }
|
||||
lldb::DataExtractorSP &GetDataSP() { return m_extractor_sp; }
|
||||
|
||||
ArchiveType GetArchiveType() { return m_archive_type; }
|
||||
|
||||
@@ -166,9 +170,9 @@ protected:
|
||||
lldb::offset_t m_file_offset;
|
||||
std::vector<Object> m_objects;
|
||||
ObjectNameToIndexMap m_object_name_to_index_map;
|
||||
lldb_private::DataExtractor m_data; ///< The data for this object container
|
||||
///so we don't lose data if the .a files
|
||||
///gets modified
|
||||
/// The data for this object container so we don't lose data if the .a files
|
||||
/// gets modified.
|
||||
lldb::DataExtractorSP m_extractor_sp;
|
||||
ArchiveType m_archive_type;
|
||||
};
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ ObjectContainer *ObjectContainerMachOFileset::CreateInstance(
|
||||
if (!data_sp)
|
||||
return {};
|
||||
|
||||
DataExtractor data;
|
||||
data.SetData(data_sp, data_offset, length);
|
||||
if (!MagicBytesMatch(data))
|
||||
DataExtractor extractor;
|
||||
extractor.SetData(data_sp, data_offset, length);
|
||||
if (!MagicBytesMatch(extractor))
|
||||
return {};
|
||||
|
||||
auto container_up = std::make_unique<ObjectContainerMachOFileset>(
|
||||
@@ -96,45 +96,45 @@ static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
|
||||
}
|
||||
}
|
||||
|
||||
static std::optional<mach_header> ParseMachOHeader(DataExtractor &data) {
|
||||
static std::optional<mach_header> ParseMachOHeader(DataExtractor &extractor) {
|
||||
lldb::offset_t offset = 0;
|
||||
mach_header header;
|
||||
header.magic = data.GetU32(&offset);
|
||||
header.magic = extractor.GetU32(&offset);
|
||||
switch (header.magic) {
|
||||
case MH_MAGIC:
|
||||
data.SetByteOrder(endian::InlHostByteOrder());
|
||||
data.SetAddressByteSize(4);
|
||||
extractor.SetByteOrder(endian::InlHostByteOrder());
|
||||
extractor.SetAddressByteSize(4);
|
||||
break;
|
||||
case MH_MAGIC_64:
|
||||
data.SetByteOrder(endian::InlHostByteOrder());
|
||||
data.SetAddressByteSize(8);
|
||||
extractor.SetByteOrder(endian::InlHostByteOrder());
|
||||
extractor.SetAddressByteSize(8);
|
||||
break;
|
||||
case MH_CIGAM:
|
||||
data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
|
||||
? eByteOrderLittle
|
||||
: eByteOrderBig);
|
||||
data.SetAddressByteSize(4);
|
||||
extractor.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
|
||||
? eByteOrderLittle
|
||||
: eByteOrderBig);
|
||||
extractor.SetAddressByteSize(4);
|
||||
break;
|
||||
case MH_CIGAM_64:
|
||||
data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
|
||||
? eByteOrderLittle
|
||||
: eByteOrderBig);
|
||||
data.SetAddressByteSize(8);
|
||||
extractor.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
|
||||
? eByteOrderLittle
|
||||
: eByteOrderBig);
|
||||
extractor.SetAddressByteSize(8);
|
||||
break;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
header.cputype = data.GetU32(&offset);
|
||||
header.cpusubtype = data.GetU32(&offset);
|
||||
header.filetype = data.GetU32(&offset);
|
||||
header.ncmds = data.GetU32(&offset);
|
||||
header.sizeofcmds = data.GetU32(&offset);
|
||||
header.cputype = extractor.GetU32(&offset);
|
||||
header.cpusubtype = extractor.GetU32(&offset);
|
||||
header.filetype = extractor.GetU32(&offset);
|
||||
header.ncmds = extractor.GetU32(&offset);
|
||||
header.sizeofcmds = extractor.GetU32(&offset);
|
||||
return header;
|
||||
}
|
||||
|
||||
static bool
|
||||
ParseFileset(DataExtractor &data, mach_header header,
|
||||
ParseFileset(DataExtractor &extractor, mach_header header,
|
||||
std::vector<ObjectContainerMachOFileset::Entry> &entries,
|
||||
std::optional<lldb::addr_t> load_addr = std::nullopt) {
|
||||
lldb::offset_t offset = MachHeaderSizeFromMagic(header.magic);
|
||||
@@ -142,14 +142,15 @@ ParseFileset(DataExtractor &data, mach_header header,
|
||||
for (uint32_t i = 0; i < header.ncmds; ++i) {
|
||||
const lldb::offset_t load_cmd_offset = offset;
|
||||
load_command lc = {};
|
||||
if (data.GetU32(&offset, &lc.cmd, 2) == nullptr)
|
||||
if (extractor.GetU32(&offset, &lc.cmd, 2) == nullptr)
|
||||
break;
|
||||
|
||||
// If we know the load address we can compute the slide.
|
||||
if (load_addr) {
|
||||
if (lc.cmd == llvm::MachO::LC_SEGMENT_64) {
|
||||
segment_command_64 segment;
|
||||
data.CopyData(load_cmd_offset, sizeof(segment_command_64), &segment);
|
||||
extractor.CopyData(load_cmd_offset, sizeof(segment_command_64),
|
||||
&segment);
|
||||
if (llvm::StringRef(segment.segname) == "__TEXT")
|
||||
slide = *load_addr - segment.vmaddr;
|
||||
}
|
||||
@@ -157,9 +158,10 @@ ParseFileset(DataExtractor &data, mach_header header,
|
||||
|
||||
if (lc.cmd == LC_FILESET_ENTRY) {
|
||||
fileset_entry_command entry;
|
||||
data.CopyData(load_cmd_offset, sizeof(fileset_entry_command), &entry);
|
||||
extractor.CopyData(load_cmd_offset, sizeof(fileset_entry_command),
|
||||
&entry);
|
||||
lldb::offset_t entry_id_offset = load_cmd_offset + entry.entry_id.offset;
|
||||
if (const char *id = data.GetCStr(&entry_id_offset))
|
||||
if (const char *id = extractor.GetCStr(&entry_id_offset))
|
||||
entries.emplace_back(entry.vmaddr + slide, entry.fileoff,
|
||||
std::string(id));
|
||||
}
|
||||
@@ -171,9 +173,9 @@ ParseFileset(DataExtractor &data, mach_header header,
|
||||
}
|
||||
|
||||
bool ObjectContainerMachOFileset::ParseHeader(
|
||||
DataExtractor &data, const lldb_private::FileSpec &file,
|
||||
DataExtractor &extractor, const lldb_private::FileSpec &file,
|
||||
lldb::offset_t file_offset, std::vector<Entry> &entries) {
|
||||
std::optional<mach_header> header = ParseMachOHeader(data);
|
||||
std::optional<mach_header> header = ParseMachOHeader(extractor);
|
||||
|
||||
if (!header)
|
||||
return false;
|
||||
@@ -181,13 +183,13 @@ bool ObjectContainerMachOFileset::ParseHeader(
|
||||
const size_t header_size = MachHeaderSizeFromMagic(header->magic);
|
||||
const size_t header_and_lc_size = header_size + header->sizeofcmds;
|
||||
|
||||
if (data.GetByteSize() < header_and_lc_size) {
|
||||
if (extractor.GetByteSize() < header_and_lc_size) {
|
||||
DataBufferSP data_sp =
|
||||
ObjectFile::MapFileData(file, header_and_lc_size, file_offset);
|
||||
data.SetData(data_sp);
|
||||
extractor.SetData(data_sp);
|
||||
}
|
||||
|
||||
return ParseFileset(data, *header, entries);
|
||||
return ParseFileset(extractor, *header, entries);
|
||||
}
|
||||
|
||||
bool ObjectContainerMachOFileset::ParseHeader() {
|
||||
@@ -197,24 +199,24 @@ bool ObjectContainerMachOFileset::ParseHeader() {
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
||||
|
||||
std::optional<mach_header> header = ParseMachOHeader(m_data);
|
||||
std::optional<mach_header> header = ParseMachOHeader(*m_extractor_sp.get());
|
||||
if (!header)
|
||||
return false;
|
||||
|
||||
const size_t header_size = MachHeaderSizeFromMagic(header->magic);
|
||||
const size_t header_and_lc_size = header_size + header->sizeofcmds;
|
||||
|
||||
if (m_data.GetByteSize() < header_and_lc_size) {
|
||||
if (m_extractor_sp->GetByteSize() < header_and_lc_size) {
|
||||
ProcessSP process_sp(m_process_wp.lock());
|
||||
DataBufferSP data_sp =
|
||||
process_sp
|
||||
? ObjectFile::ReadMemory(process_sp, m_memory_addr,
|
||||
header_and_lc_size)
|
||||
: ObjectFile::MapFileData(m_file, header_and_lc_size, m_offset);
|
||||
m_data.SetData(data_sp);
|
||||
m_extractor_sp->SetData(data_sp);
|
||||
}
|
||||
|
||||
return ParseFileset(m_data, *header, m_entries, m_memory_addr);
|
||||
return ParseFileset(*m_extractor_sp.get(), *header, m_entries, m_memory_addr);
|
||||
}
|
||||
|
||||
size_t ObjectContainerMachOFileset::GetModuleSpecifications(
|
||||
@@ -223,12 +225,12 @@ size_t ObjectContainerMachOFileset::GetModuleSpecifications(
|
||||
lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
|
||||
const size_t initial_count = specs.GetSize();
|
||||
|
||||
DataExtractor data;
|
||||
data.SetData(data_sp, data_offset, data_sp->GetByteSize());
|
||||
DataExtractor extractor;
|
||||
extractor.SetData(data_sp, data_offset, data_sp->GetByteSize());
|
||||
|
||||
if (MagicBytesMatch(data)) {
|
||||
if (MagicBytesMatch(extractor)) {
|
||||
std::vector<Entry> entries;
|
||||
if (ParseHeader(data, file, file_offset, entries)) {
|
||||
if (ParseHeader(extractor, file, file_offset, entries)) {
|
||||
for (const Entry &entry : entries) {
|
||||
const lldb::offset_t entry_offset = entry.fileoff + file_offset;
|
||||
if (ObjectFile::GetModuleSpecifications(
|
||||
@@ -245,14 +247,15 @@ size_t ObjectContainerMachOFileset::GetModuleSpecifications(
|
||||
bool ObjectContainerMachOFileset::MagicBytesMatch(DataBufferSP data_sp,
|
||||
lldb::addr_t data_offset,
|
||||
lldb::addr_t data_length) {
|
||||
DataExtractor data;
|
||||
data.SetData(data_sp, data_offset, data_length);
|
||||
return MagicBytesMatch(data);
|
||||
DataExtractor extractor;
|
||||
extractor.SetData(data_sp, data_offset, data_length);
|
||||
return MagicBytesMatch(extractor);
|
||||
}
|
||||
|
||||
bool ObjectContainerMachOFileset::MagicBytesMatch(const DataExtractor &data) {
|
||||
bool ObjectContainerMachOFileset::MagicBytesMatch(
|
||||
const DataExtractor &extractor) {
|
||||
lldb::offset_t offset = 0;
|
||||
uint32_t magic = data.GetU32(&offset);
|
||||
uint32_t magic = extractor.GetU32(&offset);
|
||||
switch (magic) {
|
||||
case MH_MAGIC:
|
||||
case MH_CIGAM:
|
||||
@@ -264,7 +267,7 @@ bool ObjectContainerMachOFileset::MagicBytesMatch(const DataExtractor &data) {
|
||||
}
|
||||
offset += 4; // cputype
|
||||
offset += 4; // cpusubtype
|
||||
uint32_t filetype = data.GetU32(&offset);
|
||||
uint32_t filetype = extractor.GetU32(&offset);
|
||||
return filetype == MH_FILESET;
|
||||
}
|
||||
|
||||
@@ -282,11 +285,11 @@ ObjectContainerMachOFileset::GetObjectFile(const lldb_private::FileSpec *file) {
|
||||
if (!entry)
|
||||
return {};
|
||||
|
||||
DataBufferSP data_sp;
|
||||
DataExtractorSP extractor_sp;
|
||||
lldb::offset_t data_offset = 0;
|
||||
return ObjectFile::FindPlugin(module_sp, file, m_offset + entry->fileoff,
|
||||
m_data.GetByteSize() - entry->fileoff, data_sp,
|
||||
data_offset);
|
||||
m_extractor_sp->GetByteSize() - entry->fileoff,
|
||||
extractor_sp, data_offset);
|
||||
}
|
||||
|
||||
ObjectContainerMachOFileset::Entry *
|
||||
|
||||
@@ -74,51 +74,51 @@ ObjectContainerUniversalMachO::ObjectContainerUniversalMachO(
|
||||
ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO() = default;
|
||||
|
||||
bool ObjectContainerUniversalMachO::ParseHeader() {
|
||||
bool success = ParseHeader(m_data, m_header, m_fat_archs);
|
||||
bool success = ParseHeader(*m_extractor_sp.get(), m_header, m_fat_archs);
|
||||
// We no longer need any data, we parsed all we needed to parse and cached it
|
||||
// in m_header and m_fat_archs
|
||||
m_data.Clear();
|
||||
m_extractor_sp = std::make_shared<DataExtractor>();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ObjectContainerUniversalMachO::ParseHeader(
|
||||
lldb_private::DataExtractor &data, llvm::MachO::fat_header &header,
|
||||
lldb_private::DataExtractor &extractor, llvm::MachO::fat_header &header,
|
||||
std::vector<FatArch> &fat_archs) {
|
||||
// Store the file offset for this universal file as we could have a universal
|
||||
// .o file in a BSD archive, or be contained in another kind of object.
|
||||
lldb::offset_t offset = 0;
|
||||
data.SetByteOrder(eByteOrderBig);
|
||||
header.magic = data.GetU32(&offset);
|
||||
extractor.SetByteOrder(eByteOrderBig);
|
||||
header.magic = extractor.GetU32(&offset);
|
||||
fat_archs.clear();
|
||||
|
||||
// Universal mach-o files always have their headers in big endian.
|
||||
if (header.magic == FAT_MAGIC || header.magic == FAT_MAGIC_64) {
|
||||
const bool is_fat64 = header.magic == FAT_MAGIC_64;
|
||||
data.SetAddressByteSize(is_fat64 ? 8 : 4);
|
||||
extractor.SetAddressByteSize(is_fat64 ? 8 : 4);
|
||||
|
||||
header.nfat_arch = data.GetU32(&offset);
|
||||
header.nfat_arch = extractor.GetU32(&offset);
|
||||
|
||||
// Now we should have enough data for all of the fat headers, so lets index
|
||||
// them so we know how many architectures that this universal binary
|
||||
// contains.
|
||||
for (uint32_t arch_idx = 0; arch_idx < header.nfat_arch; ++arch_idx) {
|
||||
if (data.ValidOffsetForDataOfSize(offset, sizeof(fat_arch))) {
|
||||
if (extractor.ValidOffsetForDataOfSize(offset, sizeof(fat_arch))) {
|
||||
if (is_fat64) {
|
||||
fat_arch_64 arch;
|
||||
arch.cputype = data.GetU32(&offset);
|
||||
arch.cpusubtype = data.GetU32(&offset);
|
||||
arch.offset = data.GetU64(&offset);
|
||||
arch.size = data.GetU64(&offset);
|
||||
arch.align = data.GetU32(&offset);
|
||||
arch.reserved = data.GetU32(&offset);
|
||||
arch.cputype = extractor.GetU32(&offset);
|
||||
arch.cpusubtype = extractor.GetU32(&offset);
|
||||
arch.offset = extractor.GetU64(&offset);
|
||||
arch.size = extractor.GetU64(&offset);
|
||||
arch.align = extractor.GetU32(&offset);
|
||||
arch.reserved = extractor.GetU32(&offset);
|
||||
fat_archs.emplace_back(arch);
|
||||
} else {
|
||||
fat_arch arch;
|
||||
arch.cputype = data.GetU32(&offset);
|
||||
arch.cpusubtype = data.GetU32(&offset);
|
||||
arch.offset = data.GetU32(&offset);
|
||||
arch.size = data.GetU32(&offset);
|
||||
arch.align = data.GetU32(&offset);
|
||||
arch.cputype = extractor.GetU32(&offset);
|
||||
arch.cpusubtype = extractor.GetU32(&offset);
|
||||
arch.offset = extractor.GetU32(&offset);
|
||||
arch.size = extractor.GetU32(&offset);
|
||||
arch.align = extractor.GetU32(&offset);
|
||||
fat_archs.emplace_back(arch);
|
||||
}
|
||||
}
|
||||
@@ -177,11 +177,11 @@ ObjectContainerUniversalMachO::GetObjectFile(const FileSpec *file) {
|
||||
}
|
||||
|
||||
if (arch_idx < m_header.nfat_arch) {
|
||||
DataBufferSP data_sp;
|
||||
DataExtractorSP extractor_sp;
|
||||
lldb::offset_t data_offset = 0;
|
||||
return ObjectFile::FindPlugin(
|
||||
module_sp, file, m_offset + m_fat_archs[arch_idx].GetOffset(),
|
||||
m_fat_archs[arch_idx].GetSize(), data_sp, data_offset);
|
||||
m_fat_archs[arch_idx].GetSize(), extractor_sp, data_offset);
|
||||
}
|
||||
}
|
||||
return ObjectFileSP();
|
||||
@@ -193,13 +193,13 @@ size_t ObjectContainerUniversalMachO::GetModuleSpecifications(
|
||||
lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
|
||||
const size_t initial_count = specs.GetSize();
|
||||
|
||||
DataExtractor data;
|
||||
data.SetData(data_sp, data_offset, data_sp->GetByteSize());
|
||||
DataExtractor extractor;
|
||||
extractor.SetData(data_sp, data_offset, data_sp->GetByteSize());
|
||||
|
||||
if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
|
||||
if (ObjectContainerUniversalMachO::MagicBytesMatch(extractor)) {
|
||||
llvm::MachO::fat_header header;
|
||||
std::vector<FatArch> fat_archs;
|
||||
if (ParseHeader(data, header, fat_archs)) {
|
||||
if (ParseHeader(extractor, header, fat_archs)) {
|
||||
for (const FatArch &fat_arch : fat_archs) {
|
||||
const lldb::offset_t slice_file_offset =
|
||||
fat_arch.GetOffset() + file_offset;
|
||||
|
||||
@@ -57,29 +57,35 @@ void ObjectFileBreakpad::Terminate() {
|
||||
PluginManager::UnregisterPlugin(CreateInstance);
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFileBreakpad::CreateInstance(
|
||||
const ModuleSP &module_sp, DataBufferSP data_sp, offset_t data_offset,
|
||||
const FileSpec *file, offset_t file_offset, offset_t length) {
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
ObjectFile *ObjectFileBreakpad::CreateInstance(const ModuleSP &module_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
offset_t file_offset,
|
||||
offset_t length) {
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
auto text = toStringRef(data_sp->GetData());
|
||||
auto text = toStringRef(extractor_sp->GetSharedDataBuffer()->GetData());
|
||||
std::optional<Header> header = Header::parse(text);
|
||||
if (!header)
|
||||
return nullptr;
|
||||
|
||||
// Update the data to contain the entire file if it doesn't already
|
||||
if (data_sp->GetByteSize() < length) {
|
||||
if (extractor_sp->GetByteSize() < length) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
|
||||
return new ObjectFileBreakpad(module_sp, data_sp, data_offset, file,
|
||||
return new ObjectFileBreakpad(module_sp, extractor_sp, data_offset, file,
|
||||
file_offset, length, std::move(header->arch),
|
||||
std::move(header->uuid));
|
||||
}
|
||||
@@ -104,12 +110,12 @@ size_t ObjectFileBreakpad::GetModuleSpecifications(
|
||||
}
|
||||
|
||||
ObjectFileBreakpad::ObjectFileBreakpad(const ModuleSP &module_sp,
|
||||
DataBufferSP &data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset,
|
||||
const FileSpec *file, offset_t offset,
|
||||
offset_t length, ArchSpec arch,
|
||||
UUID uuid)
|
||||
: ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
|
||||
: ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset),
|
||||
m_arch(std::move(arch)), m_uuid(std::move(uuid)) {}
|
||||
|
||||
bool ObjectFileBreakpad::ParseHeader() {
|
||||
|
||||
@@ -26,10 +26,12 @@ public:
|
||||
return "Breakpad object file reader.";
|
||||
}
|
||||
|
||||
static ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
static ObjectFile *CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::WritableDataBufferSP data_sp,
|
||||
@@ -94,9 +96,10 @@ private:
|
||||
UUID m_uuid;
|
||||
|
||||
ObjectFileBreakpad(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataBufferSP &data_sp, lldb::offset_t data_offset,
|
||||
const FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length, ArchSpec arch, UUID uuid);
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length,
|
||||
ArchSpec arch, UUID uuid);
|
||||
};
|
||||
|
||||
} // namespace breakpad
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/ModuleSpec.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Utility/DataExtractor.h"
|
||||
#include "lldb/Utility/LLDBLog.h"
|
||||
|
||||
#include "llvm/Support/Error.h"
|
||||
@@ -44,41 +45,45 @@ void ObjectFileCOFF::Terminate() {
|
||||
}
|
||||
|
||||
lldb_private::ObjectFile *
|
||||
ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset, const FileSpec *file,
|
||||
offset_t file_offset, offset_t length) {
|
||||
Log *log = GetLog(LLDBLog::Object);
|
||||
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp) {
|
||||
LLDB_LOG(log,
|
||||
"Failed to create ObjectFileCOFF instance: cannot read file {0}",
|
||||
file->GetPath());
|
||||
return nullptr;
|
||||
}
|
||||
extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
|
||||
assert(data_sp && "must have mapped file at this point");
|
||||
assert(extractor_sp && extractor_sp->HasData() &&
|
||||
"must have mapped file at this point");
|
||||
|
||||
if (!IsCOFFObjectFile(data_sp))
|
||||
if (!IsCOFFObjectFile(extractor_sp->GetSharedDataBuffer()))
|
||||
return nullptr;
|
||||
|
||||
if (data_sp->GetByteSize() < length) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (extractor_sp->GetByteSize() < length) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp) {
|
||||
LLDB_LOG(log,
|
||||
"Failed to create ObjectFileCOFF instance: cannot read file {0}",
|
||||
file->GetPath());
|
||||
return nullptr;
|
||||
}
|
||||
extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
MemoryBufferRef buffer{toStringRef(data_sp->GetData()),
|
||||
file->GetFilename().GetStringRef()};
|
||||
MemoryBufferRef buffer{
|
||||
toStringRef(extractor_sp->GetSharedDataBuffer()->GetData()),
|
||||
file->GetFilename().GetStringRef()};
|
||||
|
||||
Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
|
||||
if (!binary) {
|
||||
@@ -93,8 +98,8 @@ ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
file->GetPath());
|
||||
|
||||
return new ObjectFileCOFF(unique_dyn_cast<COFFObjectFile>(std::move(*binary)),
|
||||
module_sp, data_sp, data_offset, file, file_offset,
|
||||
length);
|
||||
module_sp, extractor_sp, data_offset, file,
|
||||
file_offset, length);
|
||||
}
|
||||
|
||||
lldb_private::ObjectFile *ObjectFileCOFF::CreateMemoryInstance(
|
||||
|
||||
@@ -24,11 +24,13 @@ class ObjectFileCOFF : public lldb_private::ObjectFile {
|
||||
lldb_private::UUID m_uuid;
|
||||
|
||||
ObjectFileCOFF(std::unique_ptr<llvm::object::COFFObjectFile> object,
|
||||
const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length)
|
||||
: ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
|
||||
m_object(std::move(object)) {}
|
||||
const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t file_offset,
|
||||
lldb::offset_t length)
|
||||
: ObjectFile(module_sp, file, file_offset, length, extractor_sp,
|
||||
data_offset),
|
||||
m_object(std::move(object)) {}
|
||||
|
||||
public:
|
||||
~ObjectFileCOFF() override;
|
||||
@@ -42,9 +44,10 @@ public:
|
||||
}
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateMemoryInstance(const lldb::ModuleSP &module_sp,
|
||||
|
||||
@@ -387,21 +387,25 @@ void ObjectFileELF::Terminate() {
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length) {
|
||||
bool mapped_writable = false;
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileDataWritable(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP buffer_sp = MapFileDataWritable(*file, length, file_offset);
|
||||
if (!buffer_sp)
|
||||
return nullptr;
|
||||
extractor_sp = std::make_shared<DataExtractor>();
|
||||
extractor_sp->SetData(buffer_sp, data_offset, buffer_sp->GetByteSize());
|
||||
data_offset = 0;
|
||||
mapped_writable = true;
|
||||
}
|
||||
|
||||
assert(data_sp);
|
||||
assert(extractor_sp && extractor_sp->HasData());
|
||||
|
||||
DataBufferSP data_sp = extractor_sp->GetSharedDataBuffer();
|
||||
|
||||
if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset))
|
||||
return nullptr;
|
||||
@@ -418,6 +422,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
data_offset = 0;
|
||||
mapped_writable = true;
|
||||
magic = data_sp->GetBytes();
|
||||
extractor_sp->SetData(data_sp);
|
||||
}
|
||||
|
||||
// If we didn't map the data as writable take ownership of the buffer.
|
||||
@@ -426,12 +431,14 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
data_sp->GetByteSize());
|
||||
data_offset = 0;
|
||||
magic = data_sp->GetBytes();
|
||||
extractor_sp->SetData(data_sp);
|
||||
}
|
||||
|
||||
unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
|
||||
if (address_size == 4 || address_size == 8) {
|
||||
extractor_sp->SetAddressByteSize(address_size);
|
||||
std::unique_ptr<ObjectFileELF> objfile_up(new ObjectFileELF(
|
||||
module_sp, data_sp, data_offset, file, file_offset, length));
|
||||
module_sp, extractor_sp, data_offset, file, file_offset, length));
|
||||
ArchSpec spec = objfile_up->GetArchitecture();
|
||||
if (spec && objfile_up->SetModulesArchitecture(spec))
|
||||
return objfile_up.release();
|
||||
@@ -718,10 +725,11 @@ size_t ObjectFileELF::GetModuleSpecifications(
|
||||
// ObjectFile protocol
|
||||
|
||||
ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp, lldb::offset_t data_offset,
|
||||
const FileSpec *file, lldb::offset_t file_offset,
|
||||
lldb::offset_t length)
|
||||
: ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length)
|
||||
: ObjectFile(module_sp, file, file_offset, length, extractor_sp,
|
||||
data_offset) {
|
||||
if (file)
|
||||
m_file = *file;
|
||||
}
|
||||
@@ -730,7 +738,8 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP header_data_sp,
|
||||
const lldb::ProcessSP &process_sp,
|
||||
addr_t header_addr)
|
||||
: ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
|
||||
: ObjectFile(module_sp, process_sp, header_addr,
|
||||
std::make_shared<DataExtractor>(header_data_sp)) {}
|
||||
|
||||
bool ObjectFileELF::IsExecutable() const {
|
||||
return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
|
||||
@@ -2046,10 +2055,11 @@ std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
|
||||
// Construct ObjectFileELF object from decompressed buffer
|
||||
DataBufferSP gdd_data_buf(
|
||||
new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
|
||||
DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(gdd_data_buf);
|
||||
auto fspec = GetFileSpec().CopyByAppendingPathComponent(
|
||||
llvm::StringRef("gnu_debugdata"));
|
||||
m_gnu_debug_data_object_file.reset(new ObjectFileELF(
|
||||
GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
|
||||
GetModule(), extractor_sp, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
|
||||
|
||||
// This line is essential; otherwise a breakpoint can be set but not hit.
|
||||
m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo);
|
||||
|
||||
@@ -69,9 +69,10 @@ public:
|
||||
}
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static lldb_private::ObjectFile *CreateMemoryInstance(
|
||||
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
|
||||
@@ -165,9 +166,10 @@ protected:
|
||||
uint64_t Offset);
|
||||
|
||||
private:
|
||||
ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length);
|
||||
ObjectFileELF(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
ObjectFileELF(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataBufferSP header_data_sp,
|
||||
|
||||
@@ -36,32 +36,37 @@ void ObjectFileJSON::Terminate() {
|
||||
PluginManager::UnregisterPlugin(CreateInstance);
|
||||
}
|
||||
|
||||
ObjectFile *
|
||||
ObjectFileJSON::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
offset_t data_offset, const FileSpec *file,
|
||||
offset_t file_offset, offset_t length) {
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
ObjectFile *ObjectFileJSON::CreateInstance(const ModuleSP &module_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
offset_t file_offset,
|
||||
offset_t length) {
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
|
||||
if (!MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
|
||||
if (!MagicBytesMatch(extractor_sp->GetSharedDataBuffer(), 0,
|
||||
extractor_sp->GetByteSize()))
|
||||
return nullptr;
|
||||
|
||||
// Update the data to contain the entire file if it doesn't already.
|
||||
if (data_sp->GetByteSize() < length) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (extractor_sp->GetByteSize() < length) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
extractor_sp->SetData(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
|
||||
Log *log = GetLog(LLDBLog::Symbols);
|
||||
|
||||
auto text =
|
||||
llvm::StringRef(reinterpret_cast<const char *>(data_sp->GetBytes()));
|
||||
auto text = llvm::StringRef(reinterpret_cast<const char *>(
|
||||
extractor_sp->GetSharedDataBuffer()->GetBytes()));
|
||||
|
||||
Expected<json::Value> json = json::parse(text);
|
||||
if (!json) {
|
||||
@@ -90,9 +95,10 @@ ObjectFileJSON::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ObjectFileJSON(module_sp, data_sp, data_offset, file, file_offset,
|
||||
length, std::move(arch), std::move(uuid), type,
|
||||
std::move(body.symbols), std::move(body.sections));
|
||||
return new ObjectFileJSON(module_sp, extractor_sp, data_offset, file,
|
||||
file_offset, length, std::move(arch),
|
||||
std::move(uuid), type, std::move(body.symbols),
|
||||
std::move(body.sections));
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFileJSON::CreateMemoryInstance(const ModuleSP &module_sp,
|
||||
@@ -146,13 +152,14 @@ size_t ObjectFileJSON::GetModuleSpecifications(
|
||||
return 1;
|
||||
}
|
||||
|
||||
ObjectFileJSON::ObjectFileJSON(const ModuleSP &module_sp, DataBufferSP &data_sp,
|
||||
ObjectFileJSON::ObjectFileJSON(const ModuleSP &module_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset, const FileSpec *file,
|
||||
offset_t offset, offset_t length, ArchSpec arch,
|
||||
UUID uuid, Type type,
|
||||
std::vector<JSONSymbol> symbols,
|
||||
std::vector<JSONSection> sections)
|
||||
: ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
|
||||
: ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset),
|
||||
m_arch(std::move(arch)), m_uuid(std::move(uuid)), m_type(type),
|
||||
m_symbols(std::move(symbols)), m_sections(std::move(sections)) {}
|
||||
|
||||
|
||||
@@ -26,10 +26,12 @@ public:
|
||||
return "JSON object file reader.";
|
||||
}
|
||||
|
||||
static ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
static ObjectFile *CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::WritableDataBufferSP data_sp,
|
||||
@@ -111,10 +113,11 @@ private:
|
||||
std::vector<JSONSymbol> m_symbols;
|
||||
std::vector<JSONSection> m_sections;
|
||||
|
||||
ObjectFileJSON(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length, ArchSpec arch,
|
||||
UUID uuid, Type type, std::vector<JSONSymbol> symbols,
|
||||
ObjectFileJSON(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length, ArchSpec arch, UUID uuid, Type type,
|
||||
std::vector<JSONSymbol> symbols,
|
||||
std::vector<JSONSection> sections);
|
||||
};
|
||||
|
||||
|
||||
@@ -781,30 +781,33 @@ void ObjectFileMachO::Terminate() {
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length) {
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
data_offset = 0;
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
}
|
||||
|
||||
if (!ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
|
||||
if (!ObjectFileMachO::MagicBytesMatch(extractor_sp->GetSharedDataBuffer(),
|
||||
data_offset, length))
|
||||
return nullptr;
|
||||
|
||||
// Update the data to contain the entire file if it doesn't already
|
||||
if (data_sp->GetByteSize() < length) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (extractor_sp->GetByteSize() < length) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
data_offset = 0;
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
}
|
||||
auto objfile_up = std::make_unique<ObjectFileMachO>(
|
||||
module_sp, data_sp, data_offset, file, file_offset, length);
|
||||
module_sp, extractor_sp, data_offset, file, file_offset, length);
|
||||
if (!objfile_up || !objfile_up->ParseHeader())
|
||||
return nullptr;
|
||||
|
||||
@@ -925,12 +928,13 @@ bool ObjectFileMachO::MagicBytesMatch(DataBufferSP data_sp,
|
||||
}
|
||||
|
||||
ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length)
|
||||
: ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
|
||||
: ObjectFile(module_sp, file, file_offset, length, extractor_sp,
|
||||
data_offset),
|
||||
m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
|
||||
m_thread_context_offsets_valid(false), m_reexported_dylibs(),
|
||||
m_allow_assembly_emulation_unwind_plans(true) {
|
||||
@@ -942,7 +946,8 @@ ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
|
||||
lldb::WritableDataBufferSP header_data_sp,
|
||||
const lldb::ProcessSP &process_sp,
|
||||
lldb::addr_t header_addr)
|
||||
: ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
|
||||
: ObjectFile(module_sp, process_sp, header_addr,
|
||||
std::make_shared<DataExtractor>(header_data_sp)),
|
||||
m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
|
||||
m_thread_context_offsets_valid(false), m_reexported_dylibs(),
|
||||
m_allow_assembly_emulation_unwind_plans(true) {
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
// will export the ObjectFile protocol
|
||||
class ObjectFileMachO : public lldb_private::ObjectFile {
|
||||
public:
|
||||
ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
ObjectFileMachO(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length);
|
||||
@@ -47,9 +48,10 @@ public:
|
||||
}
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static lldb_private::ObjectFile *CreateMemoryInstance(
|
||||
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
|
||||
|
||||
@@ -35,7 +35,7 @@ void ObjectFileMinidump::Terminate() {
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFileMinidump::CreateInstance(
|
||||
const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length) {
|
||||
return nullptr;
|
||||
|
||||
@@ -39,9 +39,10 @@ public:
|
||||
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length);
|
||||
CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static lldb_private::ObjectFile *CreateMemoryInstance(
|
||||
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
|
||||
|
||||
@@ -91,12 +91,14 @@ bool ObjectFilePDB::initPDBFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
ObjectFile *
|
||||
ObjectFilePDB::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
offset_t data_offset, const FileSpec *file,
|
||||
offset_t file_offset, offset_t length) {
|
||||
ObjectFile *ObjectFilePDB::CreateInstance(const ModuleSP &module_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
offset_t file_offset,
|
||||
offset_t length) {
|
||||
auto objfile_up = std::make_unique<ObjectFilePDB>(
|
||||
module_sp, data_sp, data_offset, file, file_offset, length);
|
||||
module_sp, extractor_sp, data_offset, file, file_offset, length);
|
||||
if (!objfile_up->initPDBFile())
|
||||
return nullptr;
|
||||
return objfile_up.release();
|
||||
@@ -158,10 +160,11 @@ size_t ObjectFilePDB::GetModuleSpecifications(
|
||||
return specs.GetSize() - initial_count;
|
||||
}
|
||||
|
||||
ObjectFilePDB::ObjectFilePDB(const ModuleSP &module_sp, DataBufferSP &data_sp,
|
||||
ObjectFilePDB::ObjectFilePDB(const ModuleSP &module_sp,
|
||||
DataExtractorSP &extractor_sp,
|
||||
offset_t data_offset, const FileSpec *file,
|
||||
offset_t offset, offset_t length)
|
||||
: ObjectFile(module_sp, file, offset, length, data_sp, data_offset) {}
|
||||
: ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset) {}
|
||||
|
||||
std::unique_ptr<PDBFile>
|
||||
ObjectFilePDB::loadPDBFile(std::string PdbPath,
|
||||
|
||||
@@ -30,10 +30,12 @@ public:
|
||||
static std::unique_ptr<llvm::pdb::PDBFile>
|
||||
loadPDBFile(std::string PdbPath, llvm::BumpPtrAllocator &Allocator);
|
||||
|
||||
static ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
static ObjectFile *CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::WritableDataBufferSP data_sp,
|
||||
@@ -89,9 +91,10 @@ public:
|
||||
|
||||
llvm::pdb::PDBFile &GetPDBFile() { return *m_file_up; }
|
||||
|
||||
ObjectFilePDB(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length);
|
||||
ObjectFilePDB(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP &extractor_sp, lldb::offset_t data_offset,
|
||||
const FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
private:
|
||||
UUID m_uuid;
|
||||
|
||||
@@ -203,29 +203,31 @@ llvm::StringRef ObjectFilePECOFF::GetPluginDescriptionStatic() {
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFilePECOFF::CreateInstance(
|
||||
const lldb::ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
const lldb::ModuleSP &module_sp, DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file_p,
|
||||
lldb::offset_t file_offset, lldb::offset_t length) {
|
||||
FileSpec file = file_p ? *file_p : FileSpec();
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileData(file, length, file_offset);
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP data_sp = MapFileData(file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
data_offset = 0;
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
}
|
||||
|
||||
if (!ObjectFilePECOFF::MagicBytesMatch(data_sp))
|
||||
if (!ObjectFilePECOFF::MagicBytesMatch(extractor_sp->GetSharedDataBuffer()))
|
||||
return nullptr;
|
||||
|
||||
// Update the data to contain the entire file if it doesn't already
|
||||
if (data_sp->GetByteSize() < length) {
|
||||
data_sp = MapFileData(file, length, file_offset);
|
||||
if (extractor_sp->GetByteSize() < length) {
|
||||
DataBufferSP data_sp = MapFileData(file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
}
|
||||
|
||||
auto objfile_up = std::make_unique<ObjectFilePECOFF>(
|
||||
module_sp, data_sp, data_offset, file_p, file_offset, length);
|
||||
module_sp, extractor_sp, data_offset, file_p, file_offset, length);
|
||||
if (!objfile_up || !objfile_up->ParseHeader())
|
||||
return nullptr;
|
||||
|
||||
@@ -416,12 +418,13 @@ bool ObjectFilePECOFF::CreateBinary() {
|
||||
}
|
||||
|
||||
ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length)
|
||||
: ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
|
||||
: ObjectFile(module_sp, file, file_offset, length, extractor_sp,
|
||||
data_offset),
|
||||
m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
|
||||
m_image_base(LLDB_INVALID_ADDRESS), m_entry_point_address(),
|
||||
m_deps_filespec() {}
|
||||
@@ -430,7 +433,8 @@ ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
|
||||
WritableDataBufferSP header_data_sp,
|
||||
const lldb::ProcessSP &process_sp,
|
||||
addr_t header_addr)
|
||||
: ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
|
||||
: ObjectFile(module_sp, process_sp, header_addr,
|
||||
std::make_shared<DataExtractor>(header_data_sp)),
|
||||
m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
|
||||
m_image_base(LLDB_INVALID_ADDRESS), m_entry_point_address(),
|
||||
m_deps_filespec() {}
|
||||
|
||||
@@ -44,7 +44,8 @@ public:
|
||||
MachineWcemIpsv2 = 0x169
|
||||
};
|
||||
|
||||
ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
@@ -66,10 +67,12 @@ public:
|
||||
|
||||
static llvm::StringRef GetPluginDescriptionStatic();
|
||||
|
||||
static ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length);
|
||||
static ObjectFile *CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file,
|
||||
lldb::offset_t offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static lldb_private::ObjectFile *CreateMemoryInstance(
|
||||
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Utility/ArchSpec.h"
|
||||
#include "lldb/Utility/DataBufferHeap.h"
|
||||
#include "lldb/Utility/DataExtractor.h"
|
||||
#include "lldb/Utility/FileSpecList.h"
|
||||
#include "lldb/Utility/LLDBLog.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
@@ -53,28 +54,31 @@ void ObjectFileXCOFF::Terminate() {
|
||||
}
|
||||
|
||||
ObjectFile *ObjectFileXCOFF::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length) {
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
data_offset = 0;
|
||||
extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
|
||||
}
|
||||
if (!ObjectFileXCOFF::MagicBytesMatch(data_sp, data_offset, length))
|
||||
if (!ObjectFileXCOFF::MagicBytesMatch(extractor_sp->GetSharedDataBuffer(),
|
||||
data_offset, length))
|
||||
return nullptr;
|
||||
// Update the data to contain the entire file if it doesn't already
|
||||
if (data_sp->GetByteSize() < length) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (extractor_sp->GetByteSize() < length) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp)
|
||||
return nullptr;
|
||||
data_offset = 0;
|
||||
extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
|
||||
}
|
||||
auto objfile_up = std::make_unique<ObjectFileXCOFF>(
|
||||
module_sp, data_sp, data_offset, file, file_offset, length);
|
||||
module_sp, extractor_sp, data_offset, file, file_offset, length);
|
||||
if (!objfile_up)
|
||||
return nullptr;
|
||||
|
||||
@@ -159,12 +163,12 @@ static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic) {
|
||||
bool ObjectFileXCOFF::MagicBytesMatch(DataBufferSP &data_sp,
|
||||
lldb::addr_t data_offset,
|
||||
lldb::addr_t data_length) {
|
||||
lldb_private::DataExtractor data;
|
||||
data.SetData(data_sp, data_offset, data_length);
|
||||
lldb_private::DataExtractor extractor;
|
||||
extractor.SetData(data_sp, data_offset, data_length);
|
||||
// Need to set this as XCOFF is only compatible with Big Endian
|
||||
data.SetByteOrder(eByteOrderBig);
|
||||
extractor.SetByteOrder(eByteOrderBig);
|
||||
lldb::offset_t offset = 0;
|
||||
uint16_t magic = data.GetU16(&offset);
|
||||
uint16_t magic = extractor.GetU16(&offset);
|
||||
return XCOFFHeaderSizeFromMagic(magic) != 0;
|
||||
}
|
||||
|
||||
@@ -394,12 +398,13 @@ ObjectFileXCOFF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
|
||||
}
|
||||
|
||||
ObjectFileXCOFF::ObjectFileXCOFF(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP data_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length)
|
||||
: ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
|
||||
: ObjectFile(module_sp, file, file_offset, length, extractor_sp,
|
||||
data_offset) {
|
||||
if (file)
|
||||
m_file = *file;
|
||||
}
|
||||
@@ -408,4 +413,6 @@ ObjectFileXCOFF::ObjectFileXCOFF(const lldb::ModuleSP &module_sp,
|
||||
DataBufferSP header_data_sp,
|
||||
const lldb::ProcessSP &process_sp,
|
||||
addr_t header_addr)
|
||||
: ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
|
||||
: ObjectFile(
|
||||
module_sp, process_sp, header_addr,
|
||||
std::make_shared<lldb_private::DataExtractor>(header_data_sp)) {}
|
||||
|
||||
@@ -38,9 +38,10 @@ public:
|
||||
}
|
||||
|
||||
static lldb_private::ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static lldb_private::ObjectFile *CreateMemoryInstance(
|
||||
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
|
||||
@@ -88,7 +89,8 @@ public:
|
||||
|
||||
ObjectFile::Strata CalculateStrata() override;
|
||||
|
||||
ObjectFileXCOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
ObjectFileXCOFF(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const lldb_private::FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
@@ -139,24 +139,27 @@ void ObjectFileWasm::Terminate() {
|
||||
PluginManager::UnregisterPlugin(CreateInstance);
|
||||
}
|
||||
|
||||
ObjectFile *
|
||||
ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
offset_t data_offset, const FileSpec *file,
|
||||
offset_t file_offset, offset_t length) {
|
||||
ObjectFile *ObjectFileWasm::CreateInstance(const ModuleSP &module_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
offset_t file_offset,
|
||||
offset_t length) {
|
||||
Log *log = GetLog(LLDBLog::Object);
|
||||
|
||||
if (!data_sp) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp) {
|
||||
LLDB_LOGF(log, "Failed to create ObjectFileWasm instance for file %s",
|
||||
file->GetPath().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
|
||||
assert(data_sp);
|
||||
if (!ValidateModuleHeader(data_sp)) {
|
||||
assert(extractor_sp);
|
||||
if (!ValidateModuleHeader(extractor_sp->GetSharedDataBuffer())) {
|
||||
LLDB_LOGF(log,
|
||||
"Failed to create ObjectFileWasm instance: invalid Wasm header");
|
||||
return nullptr;
|
||||
@@ -164,19 +167,20 @@ ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
|
||||
// Update the data to contain the entire file if it doesn't contain it
|
||||
// already.
|
||||
if (data_sp->GetByteSize() < length) {
|
||||
data_sp = MapFileData(*file, length, file_offset);
|
||||
if (extractor_sp->GetByteSize() < length) {
|
||||
DataBufferSP data_sp = MapFileData(*file, length, file_offset);
|
||||
if (!data_sp) {
|
||||
LLDB_LOGF(log,
|
||||
"Failed to create ObjectFileWasm instance: cannot read file %s",
|
||||
file->GetPath().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
extractor_sp = std::make_shared<DataExtractor>(data_sp);
|
||||
data_offset = 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<ObjectFileWasm> objfile_up(new ObjectFileWasm(
|
||||
module_sp, data_sp, data_offset, file, file_offset, length));
|
||||
module_sp, extractor_sp, data_offset, file, file_offset, length));
|
||||
ArchSpec spec = objfile_up->GetArchitecture();
|
||||
if (spec && objfile_up->SetModulesArchitecture(spec)) {
|
||||
LLDB_LOGF(log,
|
||||
@@ -282,10 +286,11 @@ size_t ObjectFileWasm::GetModuleSpecifications(
|
||||
return 1;
|
||||
}
|
||||
|
||||
ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp, DataBufferSP data_sp,
|
||||
ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp,
|
||||
DataExtractorSP extractor_sp,
|
||||
offset_t data_offset, const FileSpec *file,
|
||||
offset_t offset, offset_t length)
|
||||
: ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
|
||||
: ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset),
|
||||
m_arch("wasm32-unknown-unknown-wasm") {
|
||||
m_data_nsp->SetAddressByteSize(4);
|
||||
}
|
||||
@@ -294,7 +299,8 @@ ObjectFileWasm::ObjectFileWasm(const lldb::ModuleSP &module_sp,
|
||||
lldb::WritableDataBufferSP header_data_sp,
|
||||
const lldb::ProcessSP &process_sp,
|
||||
lldb::addr_t header_addr)
|
||||
: ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
|
||||
: ObjectFile(module_sp, process_sp, header_addr,
|
||||
std::make_shared<DataExtractor>(header_data_sp)),
|
||||
m_arch("wasm32-unknown-unknown-wasm") {}
|
||||
|
||||
bool ObjectFileWasm::ParseHeader() {
|
||||
@@ -781,7 +787,7 @@ DataExtractor ObjectFileWasm::ReadImageData(offset_t offset, uint32_t size) {
|
||||
offset, data_up->GetBytes(), data_up->GetByteSize(), readmem_error);
|
||||
if (bytes_read > 0) {
|
||||
DataBufferSP buffer_sp(data_up.release());
|
||||
data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
|
||||
data.SetData(buffer_sp);
|
||||
}
|
||||
} else if (offset < m_data_nsp->GetByteSize()) {
|
||||
size = std::min(static_cast<uint64_t>(size),
|
||||
|
||||
@@ -30,10 +30,12 @@ public:
|
||||
return "WebAssembly object file reader.";
|
||||
}
|
||||
|
||||
static ObjectFile *
|
||||
CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t length);
|
||||
static ObjectFile *CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t length);
|
||||
|
||||
static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
|
||||
lldb::WritableDataBufferSP data_sp,
|
||||
@@ -112,9 +114,10 @@ public:
|
||||
std::optional<FileSpec> GetExternalDebugInfoFileSpec();
|
||||
|
||||
private:
|
||||
ObjectFileWasm(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
|
||||
lldb::offset_t data_offset, const FileSpec *file,
|
||||
lldb::offset_t offset, lldb::offset_t length);
|
||||
ObjectFileWasm(const lldb::ModuleSP &module_sp,
|
||||
lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
|
||||
const FileSpec *file, lldb::offset_t offset,
|
||||
lldb::offset_t length);
|
||||
ObjectFileWasm(const lldb::ModuleSP &module_sp,
|
||||
lldb::WritableDataBufferSP header_data_sp,
|
||||
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
|
||||
|
||||
@@ -162,7 +162,8 @@ bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
|
||||
InvalidateIfNeeded(false);
|
||||
|
||||
DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
|
||||
DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
|
||||
DataExtractor extractor;
|
||||
extractor.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
|
||||
|
||||
// If our register context and our register info disagree, which should never
|
||||
// happen, don't overwrite past the end of the buffer.
|
||||
@@ -176,11 +177,12 @@ bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
|
||||
if (dst == nullptr)
|
||||
return false;
|
||||
|
||||
if (data.CopyByteOrderedData(0, // src offset
|
||||
reg_info->byte_size, // src length
|
||||
dst, // dst
|
||||
reg_info->byte_size, // dst length
|
||||
m_reg_data.GetByteOrder())) // dst byte order
|
||||
if (extractor.CopyByteOrderedData(
|
||||
0, // src offset
|
||||
reg_info->byte_size, // src length
|
||||
dst, // dst
|
||||
reg_info->byte_size, // dst length
|
||||
m_reg_data.GetByteOrder())) // dst byte order
|
||||
{
|
||||
SetRegisterIsValid(reg, true);
|
||||
return true;
|
||||
|
||||
@@ -231,7 +231,7 @@ size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
|
||||
lldb::DataExtractorSP data_extractor_sp =
|
||||
GetInterface().ReadMemoryAtAddress(addr, size, error);
|
||||
|
||||
if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail())
|
||||
if (!data_extractor_sp || !data_extractor_sp->HasData() || error.Fail())
|
||||
return 0;
|
||||
|
||||
offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
|
||||
@@ -252,7 +252,7 @@ size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
|
||||
lldb::DataExtractorSP data_extractor_sp = std::make_shared<DataExtractor>(
|
||||
buf, size, GetByteOrder(), GetAddressByteSize());
|
||||
|
||||
if (!data_extractor_sp || !data_extractor_sp->GetByteSize())
|
||||
if (!data_extractor_sp || !data_extractor_sp->HasData())
|
||||
return 0;
|
||||
|
||||
lldb::offset_t bytes_written =
|
||||
|
||||
@@ -1934,11 +1934,11 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
|
||||
}
|
||||
|
||||
const lldb::offset_t file_offset = 0;
|
||||
DataBufferSP dwo_file_data_sp;
|
||||
DataExtractorSP dwo_file_extractor_sp;
|
||||
lldb::offset_t dwo_file_data_offset = 0;
|
||||
ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(
|
||||
GetObjectFile()->GetModule(), &dwo_file, file_offset,
|
||||
FileSystem::Instance().GetByteSize(dwo_file), dwo_file_data_sp,
|
||||
FileSystem::Instance().GetByteSize(dwo_file), dwo_file_extractor_sp,
|
||||
dwo_file_data_offset);
|
||||
if (dwo_obj_file == nullptr) {
|
||||
unit.SetDwoError(Status::FromErrorStringWithFormatv(
|
||||
@@ -4474,12 +4474,12 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
|
||||
}
|
||||
if (FileSystem::Instance().Exists(dwp_filespec)) {
|
||||
LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
|
||||
DataBufferSP dwp_file_data_sp;
|
||||
DataExtractorSP dwp_file_extractor_sp;
|
||||
lldb::offset_t dwp_file_data_offset = 0;
|
||||
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
|
||||
GetObjectFile()->GetModule(), &dwp_filespec, 0,
|
||||
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
|
||||
dwp_file_data_offset);
|
||||
FileSystem::Instance().GetByteSize(dwp_filespec),
|
||||
dwp_file_extractor_sp, dwp_file_data_offset);
|
||||
if (dwp_obj_file) {
|
||||
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
|
||||
*this, dwp_obj_file, DIERef::k_file_index_mask);
|
||||
|
||||
@@ -47,12 +47,12 @@ llvm::StringRef SymbolVendorELF::GetPluginDescriptionStatic() {
|
||||
// If this is needed elsewhere, it can be exported/moved.
|
||||
static bool IsDwpSymbolFile(const lldb::ModuleSP &module_sp,
|
||||
const FileSpec &file_spec) {
|
||||
DataBufferSP dwp_file_data_sp;
|
||||
DataExtractorSP dwp_file_extractor_sp;
|
||||
lldb::offset_t dwp_file_data_offset = 0;
|
||||
// Try to create an ObjectFile from the file_spec.
|
||||
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
|
||||
module_sp, &file_spec, 0, FileSystem::Instance().GetByteSize(file_spec),
|
||||
dwp_file_data_sp, dwp_file_data_offset);
|
||||
dwp_file_extractor_sp, dwp_file_data_offset);
|
||||
// The presence of a debug_cu_index section is the key identifying feature of
|
||||
// a DWP file. Make sure we don't fill in the section list on dwp_obj_file
|
||||
// (by calling GetSectionList(false)) as this function could be called before
|
||||
@@ -120,11 +120,11 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
dsym_fspec = unstripped_spec.GetFileSpec();
|
||||
}
|
||||
|
||||
DataBufferSP dsym_file_data_sp;
|
||||
DataExtractorSP dsym_file_extractor_sp;
|
||||
lldb::offset_t dsym_file_data_offset = 0;
|
||||
ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
|
||||
module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
|
||||
dsym_file_data_sp, dsym_file_data_offset);
|
||||
dsym_file_extractor_sp, dsym_file_data_offset);
|
||||
if (!dsym_objfile_sp)
|
||||
return nullptr;
|
||||
// This objfile is for debugging purposes. Sadly, ObjectFileELF won't
|
||||
|
||||
@@ -148,12 +148,12 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
const size_t pos = dsym_root.find("/Contents/Resources/");
|
||||
dsym_root = pos != std::string::npos ? dsym_root.substr(0, pos) : "";
|
||||
|
||||
DataBufferSP dsym_file_data_sp;
|
||||
DataExtractorSP dsym_file_extractor_sp;
|
||||
lldb::offset_t dsym_file_data_offset = 0;
|
||||
dsym_objfile_sp =
|
||||
ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
|
||||
FileSystem::Instance().GetByteSize(dsym_fspec),
|
||||
dsym_file_data_sp, dsym_file_data_offset);
|
||||
dsym_file_extractor_sp, dsym_file_data_offset);
|
||||
// Important to save the dSYM FileSpec so we don't call
|
||||
// PluginManager::LocateExecutableSymbolFile a second time while trying to
|
||||
// add the symbol ObjectFile to this Module.
|
||||
|
||||
@@ -90,11 +90,11 @@ SymbolVendorPECOFF::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
if (!dsym_fspec)
|
||||
return nullptr;
|
||||
|
||||
DataBufferSP dsym_file_data_sp;
|
||||
DataExtractorSP dsym_file_extractor_sp;
|
||||
lldb::offset_t dsym_file_data_offset = 0;
|
||||
ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
|
||||
module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
|
||||
dsym_file_data_sp, dsym_file_data_offset);
|
||||
dsym_file_extractor_sp, dsym_file_data_offset);
|
||||
if (!dsym_objfile_sp)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -90,11 +90,11 @@ SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
|
||||
if (!sym_fspec)
|
||||
return nullptr;
|
||||
|
||||
DataBufferSP sym_file_data_sp;
|
||||
DataExtractorSP sym_file_extractor_sp;
|
||||
lldb::offset_t sym_file_data_offset = 0;
|
||||
ObjectFileSP sym_objfile_sp = ObjectFile::FindPlugin(
|
||||
module_sp, &sym_fspec, 0, FileSystem::Instance().GetByteSize(sym_fspec),
|
||||
sym_file_data_sp, sym_file_data_offset);
|
||||
sym_file_extractor_sp, sym_file_data_offset);
|
||||
if (!sym_objfile_sp)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -23,11 +23,13 @@ ObjectContainer::ObjectContainer(const lldb::ModuleSP &module_sp,
|
||||
lldb::offset_t data_offset)
|
||||
: ModuleChild(module_sp),
|
||||
m_file(), // This file can be different than the module's file spec
|
||||
m_offset(file_offset), m_length(length) {
|
||||
m_offset(file_offset), m_length(length),
|
||||
m_extractor_sp(std::make_shared<DataExtractor>()) {
|
||||
if (file)
|
||||
m_file = *file;
|
||||
if (data_sp)
|
||||
m_data.SetData(data_sp, data_offset, length);
|
||||
if (data_sp) {
|
||||
m_extractor_sp->SetData(data_sp, data_offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectContainerSP ObjectContainer::FindPlugin(const lldb::ModuleSP &module_sp,
|
||||
|
||||
@@ -49,10 +49,12 @@ CreateObjectFromContainer(const lldb::ModuleSP &module_sp, const FileSpec *file,
|
||||
return {};
|
||||
}
|
||||
|
||||
ObjectFileSP
|
||||
ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
|
||||
lldb::offset_t file_offset, lldb::offset_t file_size,
|
||||
DataBufferSP &data_sp, lldb::offset_t &data_offset) {
|
||||
ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
|
||||
const FileSpec *file,
|
||||
lldb::offset_t file_offset,
|
||||
lldb::offset_t file_size,
|
||||
DataExtractorSP extractor_sp,
|
||||
lldb::offset_t &data_offset) {
|
||||
LLDB_SCOPED_TIMERF(
|
||||
"ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
|
||||
"0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
|
||||
@@ -66,14 +68,14 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
|
||||
if (!file)
|
||||
return {};
|
||||
|
||||
if (!data_sp) {
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
const bool file_exists = FileSystem::Instance().Exists(*file);
|
||||
// We have an object name which most likely means we have a .o file in
|
||||
// a static archive (.a file). Try and see if we have a cached archive
|
||||
// first without reading any data first
|
||||
if (file_exists && module_sp->GetObjectName()) {
|
||||
ObjectFileSP object_file_sp = CreateObjectFromContainer(
|
||||
module_sp, file, file_offset, file_size, data_sp, data_offset);
|
||||
module_sp, file, file_offset, file_size, DataBufferSP(), data_offset);
|
||||
if (object_file_sp)
|
||||
return object_file_sp;
|
||||
}
|
||||
@@ -82,13 +84,15 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
|
||||
// container plug-ins can use these bytes to see if they can parse this
|
||||
// file.
|
||||
if (file_size > 0) {
|
||||
data_sp = FileSystem::Instance().CreateDataBuffer(
|
||||
DataBufferSP buffer_sp = FileSystem::Instance().CreateDataBuffer(
|
||||
file->GetPath(), g_initial_bytes_to_read, file_offset);
|
||||
extractor_sp = std::make_shared<DataExtractor>();
|
||||
extractor_sp->SetData(buffer_sp, data_offset, buffer_sp->GetByteSize());
|
||||
data_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data_sp || data_sp->GetByteSize() == 0) {
|
||||
if (!extractor_sp || !extractor_sp->HasData()) {
|
||||
// Check for archive file with format "/path/to/archive.a(object.o)"
|
||||
llvm::SmallString<256> path_with_object;
|
||||
module_sp->GetFileSpec().GetPath(path_with_object);
|
||||
@@ -110,18 +114,20 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
|
||||
// (like BSD archives caching the contained objects within an
|
||||
// file).
|
||||
ObjectFileSP object_file_sp = CreateObjectFromContainer(
|
||||
module_sp, file, file_offset, file_size, data_sp, data_offset);
|
||||
module_sp, file, file_offset, file_size,
|
||||
extractor_sp->GetSharedDataBuffer(), data_offset);
|
||||
if (object_file_sp)
|
||||
return object_file_sp;
|
||||
// We failed to find any cached object files in the container plug-
|
||||
// ins, so lets read the first 512 bytes and try again below...
|
||||
data_sp = FileSystem::Instance().CreateDataBuffer(
|
||||
DataBufferSP buffer_sp = FileSystem::Instance().CreateDataBuffer(
|
||||
archive_file.GetPath(), g_initial_bytes_to_read, file_offset);
|
||||
extractor_sp = std::make_shared<DataExtractor>(buffer_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data_sp && data_sp->GetByteSize() > 0) {
|
||||
if (extractor_sp && extractor_sp->HasData()) {
|
||||
// Check if this is a normal object file by iterating through all
|
||||
// object file plugin instances.
|
||||
ObjectFileCreateInstance callback;
|
||||
@@ -129,7 +135,7 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
|
||||
(callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) !=
|
||||
nullptr;
|
||||
++idx) {
|
||||
ObjectFileSP object_file_sp(callback(module_sp, data_sp, data_offset,
|
||||
ObjectFileSP object_file_sp(callback(module_sp, extractor_sp, data_offset,
|
||||
file, file_offset, file_size));
|
||||
if (object_file_sp.get())
|
||||
return object_file_sp;
|
||||
@@ -138,8 +144,9 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
|
||||
// Check if this is a object container by iterating through all object
|
||||
// container plugin instances and then trying to get an object file
|
||||
// from the container.
|
||||
DataBufferSP buffer_sp = extractor_sp->GetSharedDataBuffer();
|
||||
ObjectFileSP object_file_sp = CreateObjectFromContainer(
|
||||
module_sp, file, file_offset, file_size, data_sp, data_offset);
|
||||
module_sp, file, file_offset, file_size, buffer_sp, data_offset);
|
||||
if (object_file_sp)
|
||||
return object_file_sp;
|
||||
}
|
||||
@@ -185,12 +192,12 @@ ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
|
||||
}
|
||||
|
||||
bool ObjectFile::IsObjectFile(lldb_private::FileSpec file_spec) {
|
||||
DataBufferSP data_sp;
|
||||
DataExtractorSP extractor_sp;
|
||||
offset_t data_offset = 0;
|
||||
ModuleSP module_sp = std::make_shared<Module>(file_spec);
|
||||
return static_cast<bool>(ObjectFile::FindPlugin(
|
||||
module_sp, &file_spec, 0, FileSystem::Instance().GetByteSize(file_spec),
|
||||
data_sp, data_offset));
|
||||
extractor_sp, data_offset));
|
||||
}
|
||||
|
||||
size_t ObjectFile::GetModuleSpecifications(const FileSpec &file,
|
||||
@@ -250,7 +257,8 @@ size_t ObjectFile::GetModuleSpecifications(
|
||||
ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
|
||||
const FileSpec *file_spec_ptr,
|
||||
lldb::offset_t file_offset, lldb::offset_t length,
|
||||
lldb::DataBufferSP data_sp, lldb::offset_t data_offset)
|
||||
lldb::DataExtractorSP extractor_sp,
|
||||
lldb::offset_t data_offset)
|
||||
: ModuleChild(module_sp),
|
||||
m_file(), // This file could be different from the original module's file
|
||||
m_type(eTypeInvalid), m_strata(eStrataInvalid),
|
||||
@@ -260,8 +268,13 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
|
||||
m_symtab_once_up(new llvm::once_flag()) {
|
||||
if (file_spec_ptr)
|
||||
m_file = *file_spec_ptr;
|
||||
if (data_sp)
|
||||
m_data_nsp->SetData(data_sp, data_offset, length);
|
||||
if (extractor_sp && extractor_sp->HasData()) {
|
||||
m_data_nsp = extractor_sp;
|
||||
// The offset & length fields may be specifying a subset of the
|
||||
// total data buffer.
|
||||
m_data_nsp->SetData(extractor_sp->GetSharedDataBuffer(), data_offset,
|
||||
length);
|
||||
}
|
||||
Log *log = GetLog(LLDBLog::Object);
|
||||
LLDB_LOGF(log,
|
||||
"%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
|
||||
@@ -274,14 +287,14 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
|
||||
|
||||
ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
|
||||
const ProcessSP &process_sp, lldb::addr_t header_addr,
|
||||
DataBufferSP header_data_sp)
|
||||
DataExtractorSP header_extractor_sp)
|
||||
: ModuleChild(module_sp), m_file(), m_type(eTypeInvalid),
|
||||
m_strata(eStrataInvalid), m_file_offset(0), m_length(0),
|
||||
m_data_nsp(std::make_shared<DataExtractor>()), m_process_wp(process_sp),
|
||||
m_memory_addr(header_addr), m_sections_up(), m_symtab_up(),
|
||||
m_symtab_once_up(new llvm::once_flag()) {
|
||||
if (header_data_sp)
|
||||
m_data_nsp->SetData(header_data_sp, 0, header_data_sp->GetByteSize());
|
||||
if (header_extractor_sp && header_extractor_sp->HasData())
|
||||
m_data_nsp = header_extractor_sp;
|
||||
Log *log = GetLog(LLDBLog::Object);
|
||||
LLDB_LOGF(log,
|
||||
"%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
|
||||
|
||||
@@ -43,11 +43,11 @@ SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
|
||||
ObjectFileSP sym_objfile_sp;
|
||||
FileSpec sym_spec = module_sp->GetSymbolFileFileSpec();
|
||||
if (sym_spec && sym_spec != module_sp->GetObjectFile()->GetFileSpec()) {
|
||||
DataBufferSP data_sp;
|
||||
DataExtractorSP extractor_sp;
|
||||
offset_t data_offset = 0;
|
||||
sym_objfile_sp = ObjectFile::FindPlugin(
|
||||
module_sp, &sym_spec, 0, FileSystem::Instance().GetByteSize(sym_spec),
|
||||
data_sp, data_offset);
|
||||
extractor_sp, data_offset);
|
||||
}
|
||||
if (!sym_objfile_sp)
|
||||
sym_objfile_sp = module_sp->GetObjectFile()->shared_from_this();
|
||||
|
||||
@@ -149,6 +149,15 @@ DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
|
||||
SetData(data_sp);
|
||||
}
|
||||
|
||||
// Make a shared pointer reference to the shared data in "data_sp".
|
||||
DataExtractor::DataExtractor(const DataBufferSP &data_sp,
|
||||
uint32_t target_byte_size)
|
||||
: m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
|
||||
m_data_sp(data_sp), m_target_byte_size(target_byte_size) {
|
||||
if (data_sp)
|
||||
SetData(data_sp);
|
||||
}
|
||||
|
||||
// Initialize this object with a subset of the data bytes in "data". If "data"
|
||||
// contains shared data, then a reference to this shared data will added and
|
||||
// the shared data will stay around as long as any object contains a reference
|
||||
|
||||
Reference in New Issue
Block a user