This revision was automatically updated to reflect the committed changes.
Closed by commit rGa4a00ced0cf8: [lldb/Module] Allow for the creation of
memory-only modules (authored by friss).
Changed prior to commit:
https://reviews.llvm.org/D83512?vs=277657&id=277850#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D83512/new/
https://reviews.llvm.org/D83512
Files:
lldb/include/lldb/Core/Module.h
lldb/include/lldb/Core/ModuleSpec.h
lldb/include/lldb/Symbol/ObjectFile.h
lldb/include/lldb/Utility/DataBuffer.h
lldb/source/Core/Module.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
lldb/source/Symbol/ObjectFile.cpp
lldb/unittests/Core/CMakeLists.txt
lldb/unittests/Core/MangledTest.cpp
lldb/unittests/Core/ModuleSpecTest.cpp
lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp
lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
lldb/unittests/Symbol/TestLineEntry.cpp
lldb/unittests/TestingSupport/TestUtilities.cpp
lldb/unittests/TestingSupport/TestUtilities.h
Index: lldb/unittests/TestingSupport/TestUtilities.h
===================================================================
--- lldb/unittests/TestingSupport/TestUtilities.h
+++ lldb/unittests/TestingSupport/TestUtilities.h
@@ -9,6 +9,8 @@
#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_TESTUTILITIES_H
#define LLDB_UNITTESTS_TESTINGSUPPORT_TESTUTILITIES_H
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Utility/DataBuffer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Error.h"
@@ -34,22 +36,24 @@
static llvm::Expected<TestFile> fromYaml(llvm::StringRef Yaml);
static llvm::Expected<TestFile> fromYamlFile(const llvm::Twine &Name);
- TestFile(TestFile &&RHS) : Name(std::move(RHS.Name)) {
- RHS.Name = llvm::None;
+ ~TestFile() = default;
+
+ ModuleSpec moduleSpec() {
+ return ModuleSpec(FileSpec(), UUID(), dataBuffer());
}
- ~TestFile();
+private:
+ TestFile(std::string &&Buffer) : Buffer(std::move(Buffer)) {}
- llvm::StringRef name() { return *Name; }
+ void operator=(const TestFile &) = delete;
-private:
- TestFile(llvm::StringRef Name, llvm::FileRemover &&Remover)
- : Name(std::string(Name)) {
- Remover.releaseFile();
+ lldb::DataBufferSP dataBuffer() {
+ auto *Data = reinterpret_cast<const uint8_t *>(Buffer.data());
+ return std::make_shared<DataBufferUnowned>(const_cast<uint8_t *>(Data),
+ Buffer.size());
}
- void operator=(const TestFile &) = delete;
- llvm::Optional<std::string> Name;
+ std::string Buffer;
};
}
Index: lldb/unittests/TestingSupport/TestUtilities.cpp
===================================================================
--- lldb/unittests/TestingSupport/TestUtilities.cpp
+++ lldb/unittests/TestingSupport/TestUtilities.cpp
@@ -29,21 +29,14 @@
llvm::Expected<TestFile> TestFile::fromYaml(llvm::StringRef Yaml) {
const auto *Info = testing::UnitTest::GetInstance()->current_test_info();
assert(Info);
- llvm::SmallString<128> Name;
- int FD;
- if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
- llvm::Twine(Info->test_case_name()) + "-" + Info->name(), "test", FD,
- Name))
- return llvm::errorCodeToError(EC);
- llvm::FileRemover Remover(Name);
- {
- llvm::raw_fd_ostream OS(FD, /*shouldClose*/ true);
- llvm::yaml::Input YIn(Yaml);
- if (!llvm::yaml::convertYAML(YIn, OS, [](const llvm::Twine &Msg) {}))
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "convertYAML() failed");
- }
- return TestFile(Name, std::move(Remover));
+
+ std::string Buffer;
+ llvm::raw_string_ostream OS(Buffer);
+ llvm::yaml::Input YIn(Yaml);
+ if (!llvm::yaml::convertYAML(YIn, OS, [](const llvm::Twine &Msg) {}))
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "convertYAML() failed");
+ return TestFile(std::move(Buffer));
}
llvm::Expected<TestFile> TestFile::fromYamlFile(const llvm::Twine &Name) {
@@ -54,12 +47,3 @@
return llvm::errorCodeToError(BufferOrError.getError());
return fromYaml(BufferOrError.get()->getBuffer());
}
-
-TestFile::~TestFile() {
- if (!Name)
- return;
- if (std::error_code EC =
- llvm::sys::fs::remove(*Name, /*IgnoreNonExisting*/ false))
- GTEST_LOG_(WARNING) << "Failed to delete `" << Name->c_str()
- << "`: " << EC.message();
-}
Index: lldb/unittests/Symbol/TestLineEntry.cpp
===================================================================
--- lldb/unittests/Symbol/TestLineEntry.cpp
+++ lldb/unittests/Symbol/TestLineEntry.cpp
@@ -49,7 +49,7 @@
auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
m_file.emplace(std::move(*ExpectedFile));
- m_module_sp = std::make_shared<Module>(ModuleSpec(FileSpec(m_file->name())));
+ m_module_sp = std::make_shared<Module>(m_file->moduleSpec());
}
llvm::Expected<LineEntry> LineEntryTest::GetLineEntryForLine(uint32_t line) {
Index: lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
===================================================================
--- lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
+++ lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
@@ -220,8 +220,7 @@
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
- auto module_sp =
- std::make_shared<Module>(ModuleSpec(FileSpec(ExpectedFile->name())));
+ auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
SectionList *list = module_sp->GetSectionList();
ASSERT_NE(nullptr, list);
Index: lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp
===================================================================
--- lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp
+++ lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp
@@ -192,7 +192,7 @@
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
- ModuleSP module_sp = std::make_shared<Module>(ModuleSpec(FileSpec(ExpectedFile->name())));
+ ModuleSP module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
ObjectFile *object_file = module_sp->GetObjectFile();
ASSERT_NE(object_file, nullptr);
Index: lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
===================================================================
--- lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
+++ lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
@@ -91,10 +91,7 @@
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
- ModuleSpec spec{FileSpec(ExpectedFile->name())};
- spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(),
- FileSpec::Style::native);
- auto module_sp = std::make_shared<Module>(spec);
+ auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
SectionList *list = module_sp->GetSectionList();
ASSERT_NE(nullptr, list);
@@ -212,10 +209,7 @@
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
- ModuleSpec spec{FileSpec(ExpectedFile->name())};
- spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(),
- FileSpec::Style::native);
- auto module_sp = std::make_shared<Module>(spec);
+ auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
ASSERT_TRUE(entry_point_addr.GetOffset() & 1);
@@ -277,10 +271,7 @@
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
- ModuleSpec spec{FileSpec(ExpectedFile->name())};
- spec.GetSymbolFileSpec().SetFile(ExpectedFile->name(),
- FileSpec::Style::native);
- auto module_sp = std::make_shared<Module>(spec);
+ auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
auto entry_point_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
ASSERT_EQ(entry_point_addr.GetAddressClass(), AddressClass::eCode);
Index: lldb/unittests/Core/ModuleSpecTest.cpp
===================================================================
--- /dev/null
+++ lldb/unittests/Core/ModuleSpecTest.cpp
@@ -0,0 +1,166 @@
+//===-- ModuleSpecTest.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestingSupport/SubsystemRAII.h"
+#include "TestingSupport/TestUtilities.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Utility/DataBuffer.h"
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
+#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
+
+#include "gtest/gtest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+extern const char *TestMainArgv0;
+
+// This test file intentionally doesn't initialize the FileSystem.
+// Everything in this file should be able to run without requiring
+// any interaction with the FileSystem class; by keeping it
+// uninitialized, it will assert if anything tries to interact with
+// it.
+
+TEST(ModuleSpecTest, InvalidInMemoryBuffer) {
+ uint8_t Invalid[] = "This is not a binary file.";
+ DataBufferSP InvalidBufferSP =
+ std::make_shared<DataBufferUnowned>(Invalid, sizeof(Invalid));
+ ModuleSpec Spec(FileSpec(), UUID(), InvalidBufferSP);
+
+ auto InvalidModuleSP = std::make_shared<Module>(Spec);
+ ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr);
+}
+
+TEST(ModuleSpecTest, InvalidInMemoryBufferValidFile) {
+ uint8_t Invalid[] = "This is not a binary file.";
+ DataBufferSP InvalidBufferSP =
+ std::make_shared<DataBufferUnowned>(Invalid, sizeof(Invalid));
+ ModuleSpec Spec(FileSpec(TestMainArgv0), UUID(), InvalidBufferSP);
+
+ auto InvalidModuleSP = std::make_shared<Module>(Spec);
+ ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr);
+}
+
+TEST(ModuleSpecTest, TestELFFile) {
+ SubsystemRAII<ObjectFileELF> subsystems;
+
+ auto ExpectedFile = TestFile::fromYaml(R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000010
+...
+)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
+
+ auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
+ ObjectFile *OF = M->GetObjectFile();
+
+ ASSERT_EQ(llvm::isa<ObjectFileELF>(OF), true);
+}
+
+TEST(ModuleSpecTest, TestCOFFFile) {
+ SubsystemRAII<ObjectFilePECOFF> subsystems;
+
+ auto ExpectedFile = TestFile::fromYaml(R"(
+--- !COFF
+OptionalHeader:
+ AddressOfEntryPoint: 0
+ ImageBase: 16777216
+ SectionAlignment: 4096
+ FileAlignment: 512
+ MajorOperatingSystemVersion: 6
+ MinorOperatingSystemVersion: 0
+ MajorImageVersion: 0
+ MinorImageVersion: 0
+ MajorSubsystemVersion: 6
+ MinorSubsystemVersion: 0
+ Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
+ DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ]
+ SizeOfStackReserve: 1048576
+ SizeOfStackCommit: 4096
+ SizeOfHeapReserve: 1048576
+ SizeOfHeapCommit: 4096
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ VirtualAddress: 4096
+ VirtualSize: 4096
+symbols: []
+...
+)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
+
+ auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
+ ObjectFile *OF = M->GetObjectFile();
+
+ ASSERT_EQ(llvm::isa<ObjectFilePECOFF>(OF), true);
+}
+
+TEST(ModuleSpecTest, TestMachOFile) {
+ SubsystemRAII<ObjectFileMachO> subsystems;
+
+ auto ExpectedFile = TestFile::fromYaml(R"(
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x0100000C
+ cpusubtype: 0x00000000
+ filetype: 0x00000001
+ ncmds: 1
+ sizeofcmds: 232
+ flags: 0x00002000
+ reserved: 0x00000000
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 232
+ segname: ''
+ vmaddr: 0
+ vmsize: 56
+ fileoff: 392
+ filesize: 56
+ maxprot: 7
+ initprot: 7
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0000000000000000
+ size: 24
+ offset: 0x00000188
+ align: 2
+ reloff: 0x00000000
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x00000000
+ reserved2: 0x00000000
+ reserved3: 0x00000000
+...
+)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
+
+ auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
+ ObjectFile *OF = M->GetObjectFile();
+
+ ASSERT_EQ(llvm::isa<ObjectFileMachO>(OF), true);
+}
Index: lldb/unittests/Core/MangledTest.cpp
===================================================================
--- lldb/unittests/Core/MangledTest.cpp
+++ lldb/unittests/Core/MangledTest.cpp
@@ -165,8 +165,7 @@
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
- ModuleSpec Spec{FileSpec(ExpectedFile->name())};
- auto M = std::make_shared<Module>(Spec);
+ auto M = std::make_shared<Module>(ExpectedFile->moduleSpec());
auto Count = [M](const char *Name, FunctionNameType Type) -> int {
SymbolContextList SymList;
Index: lldb/unittests/Core/CMakeLists.txt
===================================================================
--- lldb/unittests/Core/CMakeLists.txt
+++ lldb/unittests/Core/CMakeLists.txt
@@ -1,6 +1,7 @@
add_lldb_unittest(LLDBCoreTests
CommunicationTest.cpp
MangledTest.cpp
+ ModuleSpecTest.cpp
RichManglingContextTest.cpp
SourceManagerTest.cpp
StreamCallbackTest.cpp
@@ -11,6 +12,8 @@
lldbHost
lldbSymbol
lldbPluginObjectFileELF
+ lldbPluginObjectFileMachO
+ lldbPluginObjectFilePECOFF
lldbPluginSymbolFileSymtab
lldbUtilityHelpers
LLVMTestingSupport
Index: lldb/source/Symbol/ObjectFile.cpp
===================================================================
--- lldb/source/Symbol/ObjectFile.cpp
+++ lldb/source/Symbol/ObjectFile.cpp
@@ -47,8 +47,8 @@
FileSpec archive_file;
ObjectContainerCreateInstance create_object_container_callback;
- const bool file_exists = FileSystem::Instance().Exists(*file);
if (!data_sp) {
+ 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
@@ -207,9 +207,11 @@
size_t ObjectFile::GetModuleSpecifications(const FileSpec &file,
lldb::offset_t file_offset,
lldb::offset_t file_size,
- ModuleSpecList &specs) {
- DataBufferSP data_sp =
- FileSystem::Instance().CreateDataBuffer(file.GetPath(), 512, file_offset);
+ ModuleSpecList &specs,
+ DataBufferSP data_sp) {
+ if (!data_sp)
+ data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath(), 512,
+ file_offset);
if (data_sp) {
if (file_size == 0) {
const lldb::offset_t actual_file_size =
Index: lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -169,8 +169,9 @@
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (DataBufferSP full_sp = MapFileData(file, -1, file_offset))
- data_sp = std::move(full_sp);
+ if (data_sp->GetByteSize() < length)
+ if (DataBufferSP full_sp = MapFileData(file, -1, file_offset))
+ data_sp = std::move(full_sp);
auto binary = llvm::object::createBinary(llvm::MemoryBufferRef(
toStringRef(data_sp->GetData()), file.GetFilename().GetStringRef()));
@@ -539,6 +540,9 @@
if (!size)
return {};
+ if (m_data.ValidOffsetForDataOfSize(offset, size))
+ return DataExtractor(m_data, offset, size);
+
if (m_file) {
// A bit of a hack, but we intend to write to this buffer, so we can't
// mmap it.
@@ -562,13 +566,11 @@
}
DataExtractor ObjectFilePECOFF::ReadImageDataByRVA(uint32_t rva, size_t size) {
- if (m_file) {
- Address addr = GetAddress(rva);
- SectionSP sect = addr.GetSection();
- if (!sect)
- return {};
- rva = sect->GetFileOffset() + addr.GetOffset();
- }
+ Address addr = GetAddress(rva);
+ SectionSP sect = addr.GetSection();
+ if (!sect)
+ return {};
+ rva = sect->GetFileOffset() + addr.GetOffset();
return ReadImageData(rva, size);
}
Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -541,7 +541,8 @@
__FUNCTION__, file.GetPath().c_str());
}
- data_sp = MapFileData(file, -1, file_offset);
+ if (data_sp->GetByteSize() < length)
+ data_sp = MapFileData(file, -1, file_offset);
if (data_sp)
data.SetData(data_sp);
// In case there is header extension in the section #0, the header we
@@ -580,8 +581,7 @@
func_cat,
"Calculating module crc32 %s with size %" PRIu64 " KiB",
file.GetLastPathComponent().AsCString(),
- (FileSystem::Instance().GetByteSize(file) - file_offset) /
- 1024);
+ (length - file_offset) / 1024);
// For core files - which usually don't happen to have a
// gnu_debuglink, and are pretty bulky - calculating whole
Index: lldb/source/Core/Module.cpp
===================================================================
--- lldb/source/Core/Module.cpp
+++ lldb/source/Core/Module.cpp
@@ -147,11 +147,16 @@
: module_spec.GetObjectName().AsCString(""),
module_spec.GetObjectName().IsEmpty() ? "" : ")");
+ auto data_sp = module_spec.GetData();
+ lldb::offset_t file_size = 0;
+ if (data_sp)
+ file_size = data_sp->GetByteSize();
+
// First extract all module specifications from the file using the local file
// path. If there are no specifications, then don't fill anything in
ModuleSpecList modules_specs;
- if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0, 0,
- modules_specs) == 0)
+ if (ObjectFile::GetModuleSpecifications(
+ module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0)
return;
// Now make sure that one of the module specifications matches what we just
@@ -170,11 +175,20 @@
return;
}
- if (module_spec.GetFileSpec())
- m_mod_time = FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
- else if (matching_module_spec.GetFileSpec())
- m_mod_time =
- FileSystem::Instance().GetModificationTime(matching_module_spec.GetFileSpec());
+ // Set m_data_sp if it was initially provided in the ModuleSpec. Note that
+ // we cannot use the data_sp variable here, because it will have been
+ // modified by GetModuleSpecifications().
+ if (auto module_spec_data_sp = module_spec.GetData()) {
+ m_data_sp = module_spec_data_sp;
+ m_mod_time = {};
+ } else {
+ if (module_spec.GetFileSpec())
+ m_mod_time =
+ FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
+ else if (matching_module_spec.GetFileSpec())
+ m_mod_time = FileSystem::Instance().GetModificationTime(
+ matching_module_spec.GetFileSpec());
+ }
// Copy the architecture from the actual spec if we got one back, else use
// the one that was specified
@@ -1110,6 +1124,10 @@
}
bool Module::FileHasChanged() const {
+ // We have provided the DataBuffer for this module to avoid accessing the
+ // filesystem. We never want to reload those files.
+ if (m_data_sp)
+ return false;
if (!m_file_has_changed)
m_file_has_changed =
(FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);
@@ -1229,12 +1247,19 @@
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "Module::GetObjectFile () module = %s",
GetFileSpec().GetFilename().AsCString(""));
- DataBufferSP data_sp;
lldb::offset_t data_offset = 0;
- const lldb::offset_t file_size =
- FileSystem::Instance().GetByteSize(m_file);
+ lldb::offset_t file_size = 0;
+
+ if (m_data_sp)
+ file_size = m_data_sp->GetByteSize();
+ else if (m_file)
+ file_size = FileSystem::Instance().GetByteSize(m_file);
+
if (file_size > m_object_offset) {
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;
m_objfile_sp = ObjectFile::FindPlugin(
shared_from_this(), &m_file, m_object_offset,
file_size - m_object_offset, data_sp, data_offset);
Index: lldb/include/lldb/Utility/DataBuffer.h
===================================================================
--- lldb/include/lldb/Utility/DataBuffer.h
+++ lldb/include/lldb/Utility/DataBuffer.h
@@ -79,6 +79,20 @@
}
};
+class DataBufferUnowned : public DataBuffer {
+public:
+ DataBufferUnowned(uint8_t *bytes, lldb::offset_t size)
+ : m_bytes(bytes), m_size(size) {}
+
+ uint8_t *GetBytes() override { return m_bytes; }
+ const uint8_t *GetBytes() const override { return m_bytes; }
+ lldb::offset_t GetByteSize() const override { return m_size; }
+
+private:
+ uint8_t *m_bytes;
+ lldb::offset_t m_size;
+};
+
} // namespace lldb_private
#endif /// #if defined(__cplusplus)
Index: lldb/include/lldb/Symbol/ObjectFile.h
===================================================================
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -172,10 +172,10 @@
lldb::addr_t header_addr,
lldb::DataBufferSP &file_data_sp);
- static size_t GetModuleSpecifications(const FileSpec &file,
- lldb::offset_t file_offset,
- lldb::offset_t file_size,
- ModuleSpecList &specs);
+ static size_t
+ GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset,
+ lldb::offset_t file_size, ModuleSpecList &specs,
+ lldb::DataBufferSP data_sp = lldb::DataBufferSP());
static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
lldb::DataBufferSP &data_sp,
Index: lldb/include/lldb/Core/ModuleSpec.h
===================================================================
--- lldb/include/lldb/Core/ModuleSpec.h
+++ lldb/include/lldb/Core/ModuleSpec.h
@@ -30,11 +30,19 @@
m_object_name(), m_object_offset(0), m_object_size(0),
m_source_mappings() {}
- ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID())
+ /// If the \param data argument is passed, its contents will be used
+ /// as the module contents instead of trying to read them from
+ /// \param file_spec.
+ ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID(),
+ lldb::DataBufferSP data = lldb::DataBufferSP())
: m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(),
- m_uuid(uuid), m_object_name(), m_object_offset(0),
- m_object_size(FileSystem::Instance().GetByteSize(file_spec)),
- m_source_mappings() {}
+ m_uuid(uuid), m_object_name(), m_object_offset(0), m_source_mappings(),
+ m_data(data) {
+ if (data)
+ m_object_size = data->GetByteSize();
+ else if (m_file)
+ m_object_size = FileSystem::Instance().GetByteSize(file_spec);
+ }
ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch)
: m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(arch),
@@ -42,30 +50,6 @@
m_object_size(FileSystem::Instance().GetByteSize(file_spec)),
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 {
@@ -146,6 +130,8 @@
PathMappingList &GetSourceMappingList() const { return m_source_mappings; }
+ lldb::DataBufferSP GetData() const { return m_data; }
+
void Clear() {
m_file.Clear();
m_platform_file.Clear();
@@ -289,6 +275,7 @@
uint64_t m_object_size;
llvm::sys::TimePoint<> m_object_mod_time;
mutable PathMappingList m_source_mappings;
+ lldb::DataBufferSP m_data = {};
};
class ModuleSpecList {
Index: lldb/include/lldb/Core/Module.h
===================================================================
--- lldb/include/lldb/Core/Module.h
+++ lldb/include/lldb/Core/Module.h
@@ -958,6 +958,12 @@
///by \a m_file.
uint64_t m_object_offset;
llvm::sys::TimePoint<> m_object_mod_time;
+
+ /// DataBuffer containing the module image, if it was provided at
+ /// construction time. Otherwise the data will be retrieved by mapping
+ /// one of the FileSpec members above.
+ lldb::DataBufferSP m_data_sp;
+
lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file
///parser for this module as it may or may
///not be shared with the SymbolFile
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits