friss updated this revision to Diff 277657.
friss added a comment.
Herald added a subscriber: mgorny.

I went ahead and updated all unittests to use only in-memory modules.
This required tweaking both ObjectFileELF and ObjectFilePECOFF a little.


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,28 @@
   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(TestFile &&RHS) : Buffer(std::move(RHS.Buffer)) {
+    RHS.Buffer = llvm::None;
   }
 
-  ~TestFile();
+  ~TestFile() = default;
 
-  llvm::StringRef name() { return *Name; }
+  ModuleSpec moduleSpec() {
+    return ModuleSpec(FileSpec(), UUID(), dataBuffer());
+  }
 
 private:
-  TestFile(llvm::StringRef Name, llvm::FileRemover &&Remover)
-      : Name(std::string(Name)) {
-    Remover.releaseFile();
-  }
+  TestFile(std::string &&Buffer) : Buffer(Buffer) {}
+
   void operator=(const TestFile &) = delete;
 
-  llvm::Optional<std::string> Name;
+  lldb::DataBufferSP dataBuffer() {
+    auto *buffer = reinterpret_cast<const uint8_t *>(Buffer->data());
+    return std::make_shared<DataBufferUnowned>(const_cast<uint8_t *>(buffer),
+                                               Buffer->size());
+  }
+
+  llvm::Optional<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) {
@@ -55,11 +48,3 @@
   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,289 @@
+//===-- 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 anythign try 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
+  - Name:            .comment
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x0000000000000001
+    EntSize:         0x0000000000000001
+  - Name:            .note.GNU-stack
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+  - Name:            .eh_frame
+    Type:            SHT_X86_64_UNWIND
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    0x0000000000000008
+  - Name:            .rela.eh_frame
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x0000000000000008
+    Info:            .eh_frame
+    Relocations:
+      - Offset:          0x0000000000000020
+        Symbol:          .text
+        Type:            R_X86_64_PC32
+  - Name:            .llvm_addrsig
+    Type:            SHT_LLVM_ADDRSIG
+    Flags:           [ SHF_EXCLUDE ]
+    Link:            .symtab
+    AddressAlign:    0x0000000000000001
+    Symbols:         [  ]
+Symbols:
+  - Name:            '-'
+    Type:            STT_FILE
+    Index:           SHN_ABS
+  - Name:            .text
+    Type:            STT_SECTION
+    Section:         .text
+  - Name:            main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Size:            0x000000000000000F
+...
+)");
+  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
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  8192
+    VirtualSize:     68
+  - Name:            .pdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  12288
+    VirtualSize:     60
+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:           4
+  sizeofcmds:      360
+  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:          2
+    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
+      - sectname:        __compact_unwind
+        segname:         __LD
+        addr:            0x0000000000000018
+        size:            32
+        offset:          0x000001A0
+        align:           3
+        reloff:          0x000001C0
+        nreloc:          1
+        flags:           0x02000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        relocations:
+          - address:         0x00000000
+            symbolnum:       1
+            pcrel:           false
+            length:          3
+            extern:          false
+            type:            0
+            scattered:       false
+            value:           0
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         24
+    platform:        1
+    minos:           659200
+    sdk:             720896
+    ntools:          0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          456
+    nsyms:           3
+    stroff:          504
+    strsize:         20
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       2
+    iextdefsym:      2
+    nextdefsym:      1
+    iundefsym:       3
+    nundefsym:       0
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+LinkEditData:
+  NameList:
+    - n_strx:          13
+      n_type:          0x0E
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+    - n_strx:          7
+      n_type:          0x0E
+      n_sect:          2
+      n_desc:          0
+      n_value:         24
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+  StringTable:
+    - ''
+    - _main
+    - ltmp1
+    - ltmp0
+    - ''
+...
+)");
+  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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to