https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/178347

In a PR last month I changed the ObjectFile CreateInstance etc methods to 
accept an optional DataExtractorSP instead of a DataBufferSP, and retain the 
extractor in a shared pointer internally in all of the ObjectFile subclasses.  
This is laying the groundwork for using a VirtualDataExtractor for some Mach-O 
binaries on macOS, where the segments of the binary are out-of-order in actual 
memory, and we add a lookup table to make it appear that the TEXT segment is at 
offset 0 in the Extractor, etc.  Working on the actual implementation, I 
realized we were still using DataBufferSP's in ModuleSpec and Module, as well 
as in ObjectFile::GetModuleSpecifications.

I originally was making a much larger NFC change where I had all ObjectFile 
subclasses operating on DataExtractors throughout their implementation, as well 
as in the DWARF parser.  It was a very large patchset.  Many subclasses start 
with their DataExtractor, then create smaller DataExtractors for parts of the 
binary image - the string table, the symbol table, etc., for processing.

After consideration and discussion with Jonas, we agreed that a segment/section 
of a binary will never require a lookup table to access the bytes within it, so 
I changed
VirtualDataExtractor::GetSubsetExtractorSP to (1) require that the Subset be 
contained within a single lookup table entry, and (2) return a simple 
DataExtractor bounded on that byte range.  By doing this, I was able to remove 
all of my very-invasive changes to the ObjectFile subclass internals; it's only 
when they are operating on the entire binary image that care is needed.

One pattern that subclasses like ObjectFileBreakpad use is to take an ArrayRef 
of the DataBuffer for a binary, then create a StringRef of that, then look for 
strings in it.  With a VirtualDataExtractor and out-of-order binary segments, 
with gaps between them, this allows us to search the entire buffer looking for 
a string, and segfault when it gets to an unmapped region of the buffer.  I 
added a VirtualDataExtractor::GetSubsetExtractorSP(0) which gets the largest 
contiguous memory region starting at offset 0 for this use case, and I added a 
comment about what was being done there because I know it is not obvious, and 
people not working on macOS wouldn't be familiar with the requirement.  (when 
we have a ModuleSpec with a DataExtractor, any of the ObjectFile subclasses get 
a shot at Creating, so they all have to be able to iterate on these)

rdar://148939795

>From 0dc3c9968a1759b69bf2f535e08c94517fe19d91 Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Tue, 27 Jan 2026 18:56:14 -0800
Subject: [PATCH] [lldb][NFC] Module, ModuleSpec, GetSectionData use
 DataExtractorSP

In a PR last month I changed the ObjectFile CreateInstance etc
methods to accept an optional DataExtractorSP instead of a DataBufferSP,
and retain the extractor in a shared pointer internally in all of
the ObjectFile subclasses.  This is laying the groundwork for using
a VirtualDataExtractor for some Mach-O binaries on macOS, where the
segments of the binary are out-of-order in actual memory, and we
add a lookup table to make it appear that the TEXT segment is at
offset 0 in the Extractor, etc.  Working on the actual implementation,
I realized we were still using DataBufferSP's in ModuleSpec and
Module, as well as in ObjectFile::GetModuleSpecifications.

I originally was making a much larger NFC change where I had all
ObjectFile subclasses operating on DataExtractors throughout their
implementation, as well as in the DWARF parser.  It was a very large
patchset.  Many subclasses start with their DataExtractor, then
create smaller DataExtractors for parts of the binary image - the
string table, the symbol table, etc., for processing.

After consideration and discussion with Jonas, we agreed that a
segment/section of a binary will never require a lookup table to
access the bytes within it, so I changed
VirtualDataExtractor::GetSubsetExtractorSP to (1) require that the
Subset be contained within a single lookup table entry, and (2)
return a simple DataExtractor bounded on that byte range.  By doing
this, I was able to remove all of my very-invasive changes to the
ObjectFile subclass internals; it's only when they are operating
on the entire binary image that care is needed.

One pattern that subclasses like ObjectFileBreakpad use is to take
an ArrayRef of the DataBuffer for a binary, then create a StringRef
of that, then look for strings in it.  With a VirtualDataExtractor
and out-of-order binary segments, with gaps between them, this
allows us to search the entire buffer looking for a string, and
segfault when it gets to an unmapped region of the buffer.  I added
a VirtualDataExtractor::GetSubsetExtractorSP(0) which gets the
largest contiguous memory region starting at offset 0 for this use
case, and I added a comment about what was being done there because
I know it is not obvious, and people not working on macOS wouldn't
be familiar with the requirement.  (when we have a ModuleSpec with
a DataExtractor, any of the ObjectFile subclasses get a shot at
Creating, so they all have to be able to iterate on these)

rdar://148939795
---
 lldb/include/lldb/Core/Module.h               |  4 +-
 lldb/include/lldb/Core/ModuleSpec.h           | 16 ++--
 lldb/include/lldb/Expression/ObjectFileJIT.h  |  2 +-
 lldb/include/lldb/Host/HostInfoBase.h         |  2 +-
 lldb/include/lldb/Symbol/ObjectFile.h         |  6 +-
 lldb/include/lldb/Target/DynamicLoader.h      | 12 ++-
 lldb/include/lldb/lldb-private-interfaces.h   |  2 +-
 lldb/source/Core/Module.cpp                   | 35 ++++-----
 lldb/source/Expression/ObjectFileJIT.cpp      |  2 +-
 .../Host/macosx/objcxx/HostInfoMacOSX.mm      | 13 ++--
 .../MacOSX-DYLD/DynamicLoaderDarwin.cpp       |  2 +-
 .../MacOSX-DYLD/DynamicLoaderMacOS.cpp        |  9 ++-
 .../MacOSX-DYLD/DynamicLoaderMacOS.h          | 10 ++-
 .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp   |  2 +-
 .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h     |  3 +-
 .../BSD-Archive/ObjectContainerBSDArchive.cpp | 13 ++--
 .../BSD-Archive/ObjectContainerBSDArchive.h   |  2 +-
 .../Big-Archive/ObjectContainerBigArchive.cpp |  2 +-
 .../Big-Archive/ObjectContainerBigArchive.h   |  2 +-
 .../ObjectContainerMachOFileset.cpp           | 13 ++--
 .../ObjectContainerMachOFileset.h             |  2 +-
 .../ObjectContainerUniversalMachO.cpp         | 13 ++--
 .../ObjectContainerUniversalMachO.h           |  2 +-
 .../Breakpad/ObjectFileBreakpad.cpp           | 28 +++++--
 .../ObjectFile/Breakpad/ObjectFileBreakpad.h  |  2 +-
 .../ObjectFile/COFF/ObjectFileCOFF.cpp        | 32 +++++---
 .../Plugins/ObjectFile/COFF/ObjectFileCOFF.h  |  2 +-
 .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp  | 28 ++++---
 .../Plugins/ObjectFile/ELF/ObjectFileELF.h    |  2 +-
 .../ObjectFile/JSON/ObjectFileJSON.cpp        | 17 +++--
 .../Plugins/ObjectFile/JSON/ObjectFileJSON.h  |  2 +-
 .../ObjectFile/Mach-O/ObjectFileMachO.cpp     | 75 ++++++++++---------
 .../ObjectFile/Mach-O/ObjectFileMachO.h       |  8 +-
 .../Minidump/ObjectFileMinidump.cpp           |  2 +-
 .../ObjectFile/Minidump/ObjectFileMinidump.h  |  2 +-
 .../Plugins/ObjectFile/PDB/ObjectFilePDB.cpp  |  2 +-
 .../Plugins/ObjectFile/PDB/ObjectFilePDB.h    |  2 +-
 .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp    | 12 +--
 .../ObjectFile/PECOFF/ObjectFilePECOFF.h      |  2 +-
 .../ObjectFile/XCOFF/ObjectFileXCOFF.cpp      |  5 +-
 .../ObjectFile/XCOFF/ObjectFileXCOFF.h        |  2 +-
 .../ObjectFile/wasm/ObjectFileWasm.cpp        |  4 +-
 .../Plugins/ObjectFile/wasm/ObjectFileWasm.h  |  2 +-
 .../Platform/MacOSX/PlatformDarwinDevice.cpp  |  2 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 21 +++++-
 .../Process/mach-core/ProcessMachCore.cpp     |  6 +-
 .../Process/minidump/ProcessMinidump.cpp      |  9 ++-
 lldb/source/Symbol/ObjectFile.cpp             | 46 +++++++-----
 lldb/unittests/Core/ModuleSpecTest.cpp        |  6 +-
 .../ObjectFile/MachO/TestObjectFileMachO.cpp  |  6 +-
 lldb/unittests/TestingSupport/TestUtilities.h |  3 +-
 51 files changed, 295 insertions(+), 204 deletions(-)

diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 643b9a5c3bf54..10c5982ac3c2b 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -1044,10 +1044,10 @@ class Module : public 
std::enable_shared_from_this<Module>,
   uint64_t m_object_offset = 0;
   llvm::sys::TimePoint<> m_object_mod_time;
 
-  /// DataBuffer containing the module image, if it was provided at
+  /// DataExtractor 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::DataExtractorSP m_extractor_sp;
 
   lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file
                                    /// parser for this module as it may or may
diff --git a/lldb/include/lldb/Core/ModuleSpec.h 
b/lldb/include/lldb/Core/ModuleSpec.h
index 1af5f144169a8..0306dfc280e57 100644
--- a/lldb/include/lldb/Core/ModuleSpec.h
+++ b/lldb/include/lldb/Core/ModuleSpec.h
@@ -12,6 +12,7 @@
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Target/PathMappingList.h"
 #include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/Iterable.h"
 #include "lldb/Utility/Stream.h"
@@ -30,14 +31,15 @@ class ModuleSpec {
 public:
   ModuleSpec() = default;
 
-  /// If the \c data argument is passed, its contents will be used
+  /// If the \c extractor_sp argument is passed, its contents will be used
   /// as the module contents instead of trying to read them from
   /// \c file_spec .
   ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID(),
-             lldb::DataBufferSP data = lldb::DataBufferSP())
-      : m_file(file_spec), m_uuid(uuid), m_object_offset(0), m_data(data) {
-    if (data)
-      m_object_size = data->GetByteSize();
+             lldb::DataExtractorSP extractor_sp = lldb::DataExtractorSP())
+      : m_file(file_spec), m_uuid(uuid), m_object_offset(0),
+        m_extractor_sp(extractor_sp) {
+    if (extractor_sp)
+      m_object_size = extractor_sp->GetByteSize();
     else if (m_file)
       m_object_size = FileSystem::Instance().GetByteSize(file_spec);
   }
@@ -126,7 +128,7 @@ class ModuleSpec {
 
   PathMappingList &GetSourceMappingList() const { return m_source_mappings; }
 
-  lldb::DataBufferSP GetData() const { return m_data; }
+  lldb::DataExtractorSP GetExtractor() const { return m_extractor_sp; }
 
   lldb::TargetSP GetTargetSP() const { return m_target_wp.lock(); }
 
@@ -300,7 +302,7 @@ class ModuleSpec {
   uint64_t m_object_size = 0;
   llvm::sys::TimePoint<> m_object_mod_time;
   mutable PathMappingList m_source_mappings;
-  lldb::DataBufferSP m_data = {};
+  lldb::DataExtractorSP m_extractor_sp = {};
 };
 
 class ModuleSpecList {
diff --git a/lldb/include/lldb/Expression/ObjectFileJIT.h 
b/lldb/include/lldb/Expression/ObjectFileJIT.h
index e3e8c27641698..0694a969ed8d1 100644
--- a/lldb/include/lldb/Expression/ObjectFileJIT.h
+++ b/lldb/include/lldb/Expression/ObjectFileJIT.h
@@ -59,7 +59,7 @@ class ObjectFileJIT : public ObjectFile {
       const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/include/lldb/Host/HostInfoBase.h 
b/lldb/include/lldb/Host/HostInfoBase.h
index a6aaacd9d6feb..670fee19fca3d 100644
--- a/lldb/include/lldb/Host/HostInfoBase.h
+++ b/lldb/include/lldb/Host/HostInfoBase.h
@@ -29,7 +29,7 @@ class FileSpec;
 
 struct SharedCacheImageInfo {
   UUID uuid;
-  lldb::DataBufferSP data_sp;
+  lldb::DataExtractorSP extractor_sp;
 };
 
 namespace {
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h 
b/lldb/include/lldb/Symbol/ObjectFile.h
index 01115a22aeda3..2cdcadd262622 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -177,10 +177,10 @@ class ObjectFile : public 
std::enable_shared_from_this<ObjectFile>,
   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());
+                          lldb::DataExtractorSP = lldb::DataExtractorSP());
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t file_size,
@@ -659,7 +659,7 @@ class ObjectFile : public 
std::enable_shared_from_this<ObjectFile>,
   // This function returns raw file contents. Do not use it if you want
   // transparent decompression of section contents.
   size_t GetData(lldb::offset_t offset, size_t length,
-                 DataExtractor &data) const;
+                 lldb::DataExtractorSP &data_sp) const;
 
   // This function returns raw file contents. Do not use it if you want
   // transparent decompression of section contents.
diff --git a/lldb/include/lldb/Target/DynamicLoader.h 
b/lldb/include/lldb/Target/DynamicLoader.h
index 7f2652bb28727..04fd7556e1068 100644
--- a/lldb/include/lldb/Target/DynamicLoader.h
+++ b/lldb/include/lldb/Target/DynamicLoader.h
@@ -310,12 +310,18 @@ class DynamicLoader : public PluginInterface {
   ///     private shared cache.
   ///     If this information cannot be fetched, eLazyBoolCalculate.
   ///
+  /// \param[out] shared_cache_path
+  ///     A FileSpec representing the shared cache path being run
+  ///     in the inferior process.
+  ///
   /// \return
   ///     Returns false if this DynamicLoader cannot gather information
   ///     about the shared cache / has no concept of a shared cache.
-  virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID 
&uuid,
-                                         LazyBool &using_shared_cache,
-                                         LazyBool &private_shared_cache) {
+  virtual bool
+  GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid,
+                            LazyBool &using_shared_cache,
+                            LazyBool &private_shared_cache,
+                            lldb_private::FileSpec &shared_cache_path) {
     base_address = LLDB_INVALID_ADDRESS;
     uuid.Clear();
     using_shared_cache = eLazyBoolCalculate;
diff --git a/lldb/include/lldb/lldb-private-interfaces.h 
b/lldb/include/lldb/lldb-private-interfaces.h
index 0e02d1ca25746..dbd81b0683f50 100644
--- a/lldb/include/lldb/lldb-private-interfaces.h
+++ b/lldb/include/lldb/lldb-private-interfaces.h
@@ -46,7 +46,7 @@ typedef ObjectContainer 
*(*ObjectContainerCreateMemoryInstance)(
     const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
     const lldb::ProcessSP &process_sp, lldb::addr_t offset);
 typedef size_t (*ObjectFileGetModuleSpecifications)(
-    const FileSpec &file, lldb::DataBufferSP &data_sp,
+    const FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t length, ModuleSpecList &module_specs);
 typedef ObjectFile *(*ObjectFileCreateInstance)(
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 486af1a053344..5cec752b76bb6 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -149,16 +149,17 @@ Module::Module(const ModuleSpec &module_spec)
               module_spec.GetObjectName().AsCString(""),
               module_spec.GetObjectName().IsEmpty() ? "" : ")");
 
-  auto data_sp = module_spec.GetData();
+  auto extractor_sp = module_spec.GetExtractor();
   lldb::offset_t file_size = 0;
-  if (data_sp)
-    file_size = data_sp->GetByteSize();
+  if (extractor_sp)
+    file_size = extractor_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, file_size, modules_specs, data_sp) == 
0)
+  if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0,
+                                          file_size, modules_specs,
+                                          extractor_sp) == 0)
     return;
 
   // Now make sure that one of the module specifications matches what we just
@@ -177,11 +178,11 @@ Module::Module(const ModuleSpec &module_spec)
     return;
   }
 
-  // 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;
+  // Set m_extractor_sp if it was initially provided in the ModuleSpec. Note
+  // that we cannot use the extractor_sp variable here, because it will have
+  // been modified by GetModuleSpecifications().
+  if (auto module_spec_extractor_sp = module_spec.GetExtractor()) {
+    m_extractor_sp = module_spec_extractor_sp;
     m_mod_time = {};
   } else {
     if (module_spec.GetFileSpec())
@@ -1071,9 +1072,9 @@ void Module::GetDescription(llvm::raw_ostream &s,
 }
 
 bool Module::FileHasChanged() const {
-  // We have provided the DataBuffer for this module to avoid accessing the
+  // We have provided the DataExtractor for this module to avoid accessing the
   // filesystem. We never want to reload those files.
-  if (m_data_sp)
+  if (m_extractor_sp)
     return false;
   if (!m_file_has_changed)
     m_file_has_changed =
@@ -1203,18 +1204,18 @@ ObjectFile *Module::GetObjectFile() {
       lldb::offset_t data_offset = 0;
       lldb::offset_t file_size = 0;
 
-      if (m_data_sp)
-        file_size = m_data_sp->GetByteSize();
+      if (m_extractor_sp)
+        file_size = m_extractor_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.
+        // modify our m_extractor_sp member.
         DataExtractorSP extractor_sp;
-        if (m_data_sp)
-          extractor_sp = std::make_shared<DataExtractor>(m_data_sp);
+        if (m_extractor_sp)
+          extractor_sp = m_extractor_sp;
         m_objfile_sp = ObjectFile::FindPlugin(
             shared_from_this(), &m_file, m_object_offset,
             file_size - m_object_offset, extractor_sp, data_offset);
diff --git a/lldb/source/Expression/ObjectFileJIT.cpp 
b/lldb/source/Expression/ObjectFileJIT.cpp
index 86ebb27562603..5f51617158197 100644
--- a/lldb/source/Expression/ObjectFileJIT.cpp
+++ b/lldb/source/Expression/ObjectFileJIT.cpp
@@ -61,7 +61,7 @@ ObjectFile *ObjectFileJIT::CreateMemoryInstance(const 
lldb::ModuleSP &module_sp,
 }
 
 size_t ObjectFileJIT::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
   // JIT'ed object file can't be read from a file on disk
diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm 
b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 45ba4baae3d33..19d3601e60109 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -11,6 +11,7 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/Args.h"
+#include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Timer.h"
@@ -730,11 +731,13 @@ static bool ResolveAndVerifyCandidateSupportDir(FileSpec 
&path) {
 
   dyld_shared_cache_iterate_text(
       dsc_uuid, ^(const dyld_shared_cache_dylib_text_info *info) {
-        m_images[info->path] = SharedCacheImageInfo{
-            UUID(info->dylibUuid, 16),
-            std::make_shared<DataBufferUnowned>(
-                shared_cache_start + info->textSegmentOffset,
-                shared_cache_size - info->textSegmentOffset)};
+        lldb::DataBufferSP data_sp = std::make_shared<DataBufferUnowned>(
+            shared_cache_start + info->textSegmentOffset,
+            shared_cache_size - info->textSegmentOffset);
+        lldb::DataExtractorSP extractor_sp =
+            std::make_shared<DataExtractor>(data_sp);
+        m_images[info->path] =
+            SharedCacheImageInfo{UUID(info->dylibUuid, 16), extractor_sp};
       });
 }
 
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 316723480eb22..e7128ca875b94 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -138,7 +138,7 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
     if (image_info.uuid &&
         (!module_spec.GetUUID() || module_spec.GetUUID() == image_info.uuid)) {
       ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid,
-                                   image_info.data_sp);
+                                   image_info.extractor_sp);
       module_sp =
           target.GetOrCreateModule(shared_cache_spec, false /* notify */);
     }
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index ce1a0975260c9..7b07d4aa14fc8 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -691,7 +691,7 @@ Status DynamicLoaderMacOS::CanLoadImage() {
 
 bool DynamicLoaderMacOS::GetSharedCacheInformation(
     lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
-    LazyBool &private_shared_cache) {
+    LazyBool &private_shared_cache, FileSpec &shared_cache_path) {
   base_address = LLDB_INVALID_ADDRESS;
   uuid.Clear();
   using_shared_cache = eLazyBoolCalculate;
@@ -726,7 +726,12 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
         private_shared_cache = eLazyBoolYes;
       else
         private_shared_cache = eLazyBoolNo;
-
+      if (info_dict->HasKey("shared_cache_path")) {
+        std::string filepath = info_dict->GetValueForKey("shared_cache_path")
+                                   ->GetStringValue()
+                                   .str();
+        shared_cache_path.SetPath(filepath);
+      }
       return true;
     }
   }
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
index bd2c2e0bac538..9bb50de3eadb3 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
@@ -54,10 +54,12 @@ class DynamicLoaderMacOS : public 
lldb_private::DynamicLoaderDarwin {
 
   lldb_private::Status CanLoadImage() override;
 
-  bool GetSharedCacheInformation(
-      lldb::addr_t &base_address, lldb_private::UUID &uuid,
-      lldb_private::LazyBool &using_shared_cache,
-      lldb_private::LazyBool &private_shared_cache) override;
+  bool
+  GetSharedCacheInformation(lldb::addr_t &base_address,
+                            lldb_private::UUID &uuid,
+                            lldb_private::LazyBool &using_shared_cache,
+                            lldb_private::LazyBool &private_shared_cache,
+                            lldb_private::FileSpec &shared_cache_path) 
override;
 
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index f839948660aa0..1ec91548a1866 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -1071,7 +1071,7 @@ Status DynamicLoaderMacOSXDYLD::CanLoadImage() {
 
 bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
     lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
-    LazyBool &private_shared_cache) {
+    LazyBool &private_shared_cache, FileSpec &shared_cache_filepath) {
   base_address = LLDB_INVALID_ADDRESS;
   uuid.Clear();
   using_shared_cache = eLazyBoolCalculate;
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index ae7451722a8d7..e3f263a08d7df 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -61,7 +61,8 @@ class DynamicLoaderMacOSXDYLD : public 
lldb_private::DynamicLoaderDarwin {
   bool GetSharedCacheInformation(
       lldb::addr_t &base_address, lldb_private::UUID &uuid,
       lldb_private::LazyBool &using_shared_cache,
-      lldb_private::LazyBool &private_shared_cache) override;
+      lldb_private::LazyBool &private_shared_cache,
+      lldb_private::FileSpec &shared_cache_filepath) override;
 
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
diff --git 
a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp 
b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 0adc204ade9db..26729a6224df8 100644
--- 
a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ 
b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -434,18 +434,19 @@ ObjectFileSP 
ObjectContainerBSDArchive::GetObjectFile(const FileSpec *file) {
 }
 
 size_t ObjectContainerBSDArchive::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
 
+  DataExtractorSP data_extractor_sp = extractor_sp->GetSubsetExtractorSP(
+      data_offset,
+      extractor_sp->GetSharedDataBuffer()->GetByteSize() - data_offset);
   // 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
-  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)
+      ObjectContainerBSDArchive::MagicBytesMatch(*data_extractor_sp.get());
+  if (!file || !data_extractor_sp || archive_type == ArchiveType::Invalid)
     return 0;
 
   const size_t initial_count = specs.GetSize();
@@ -456,7 +457,7 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications(
   bool set_archive_arch = false;
   if (!archive_sp) {
     set_archive_arch = true;
-    data_sp =
+    DataBufferSP data_sp =
         FileSystem::Instance().CreateDataBuffer(file, file_size, file_offset);
     if (data_sp) {
       extractor_sp->SetData(data_sp);
diff --git 
a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h 
b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index df78816a1e7f1..be6217b9c7b92 100644
--- 
a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ 
b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -55,7 +55,7 @@ class ObjectContainerBSDArchive : public 
lldb_private::ObjectContainer {
                  lldb::offset_t offset, lldb::offset_t length);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git 
a/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.cpp 
b/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.cpp
index 8a017145267bc..c25add2827fda 100644
--- 
a/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.cpp
+++ 
b/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.cpp
@@ -44,7 +44,7 @@ ObjectContainer *ObjectContainerBigArchive::CreateInstance(
 }
 
 size_t ObjectContainerBigArchive::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
   return 0;
diff --git 
a/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.h 
b/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.h
index 61f2390974d12..a9f899af6b002 100644
--- 
a/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.h
+++ 
b/lldb/source/Plugins/ObjectContainer/Big-Archive/ObjectContainerBigArchive.h
@@ -45,7 +45,7 @@ class ObjectContainerBigArchive : public 
lldb_private::ObjectContainer {
                  lldb::offset_t offset, lldb::offset_t length);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git 
a/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp
 
b/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp
index fb6d35f420e8f..3056c941068b2 100644
--- 
a/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp
+++ 
b/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.cpp
@@ -220,17 +220,18 @@ bool ObjectContainerMachOFileset::ParseHeader() {
 }
 
 size_t ObjectContainerMachOFileset::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
   const size_t initial_count = specs.GetSize();
+  if (!extractor_sp)
+    return initial_count;
 
-  DataExtractor extractor;
-  extractor.SetData(data_sp, data_offset, data_sp->GetByteSize());
-
-  if (MagicBytesMatch(extractor)) {
+  DataExtractorSP data_extractor_sp = extractor_sp->GetSubsetExtractorSP(
+      data_offset, extractor_sp->GetByteSize());
+  if (MagicBytesMatch(*data_extractor_sp)) {
     std::vector<Entry> entries;
-    if (ParseHeader(extractor, file, file_offset, entries)) {
+    if (ParseHeader(*data_extractor_sp, file, file_offset, entries)) {
       for (const Entry &entry : entries) {
         const lldb::offset_t entry_offset = entry.fileoff + file_offset;
         if (ObjectFile::GetModuleSpecifications(
diff --git 
a/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.h
 
b/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.h
index 134c503aac919..f94f07855a0e7 100644
--- 
a/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.h
+++ 
b/lldb/source/Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.h
@@ -49,7 +49,7 @@ class ObjectContainerMachOFileset : public 
lldb_private::ObjectContainer {
       const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git 
a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
 
b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
index 648bcda776feb..215c419a0a9c6 100644
--- 
a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
+++ 
b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
@@ -188,18 +188,19 @@ ObjectContainerUniversalMachO::GetObjectFile(const 
FileSpec *file) {
 }
 
 size_t ObjectContainerUniversalMachO::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
   const size_t initial_count = specs.GetSize();
+  if (!extractor_sp)
+    return initial_count;
 
-  DataExtractor extractor;
-  extractor.SetData(data_sp, data_offset, data_sp->GetByteSize());
-
-  if (ObjectContainerUniversalMachO::MagicBytesMatch(extractor)) {
+  DataExtractorSP data_extractor_sp = extractor_sp->GetSubsetExtractorSP(
+      data_offset, extractor_sp->GetByteSize());
+  if (ObjectContainerUniversalMachO::MagicBytesMatch(*data_extractor_sp)) {
     llvm::MachO::fat_header header;
     std::vector<FatArch> fat_archs;
-    if (ParseHeader(extractor, header, fat_archs)) {
+    if (ParseHeader(*data_extractor_sp, header, fat_archs)) {
       for (const FatArch &fat_arch : fat_archs) {
         const lldb::offset_t slice_file_offset =
             fat_arch.GetOffset() + file_offset;
diff --git 
a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
 
b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
index 20f1f051e07a0..b4d451f740ee4 100644
--- 
a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
+++ 
b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
@@ -40,7 +40,7 @@ class ObjectContainerUniversalMachO : public 
lldb_private::ObjectContainer {
                  lldb::offset_t offset, lldb::offset_t length);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp 
b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index 5ab683ba0dd2a..ae763a02a4dff 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -70,24 +70,30 @@ ObjectFile *ObjectFileBreakpad::CreateInstance(const 
ModuleSP &module_sp,
     extractor_sp = std::make_shared<DataExtractor>(data_sp);
     data_offset = 0;
   }
-  auto text = toStringRef(extractor_sp->GetSharedDataBuffer()->GetData());
+  // If this is opearting on a VirtualDataExtractor, it can have
+  // gaps between valid bytes in the DataBuffer. We extract an
+  // ArrayRef of the raw bytes, and can segfault.
+  DataExtractorSP contiguous_extractor_sp =
+      extractor_sp->GetSubsetExtractorSP(0);
+  auto text =
+      toStringRef(contiguous_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 (extractor_sp->GetByteSize() < length) {
+  if (contiguous_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);
+    contiguous_extractor_sp = std::make_shared<DataExtractor>(data_sp);
     data_offset = 0;
   }
 
-  return new ObjectFileBreakpad(module_sp, extractor_sp, data_offset, file,
-                                file_offset, length, std::move(header->arch),
-                                std::move(header->uuid));
+  return new ObjectFileBreakpad(
+      module_sp, contiguous_extractor_sp, data_offset, file, file_offset,
+      length, std::move(header->arch), std::move(header->uuid));
 }
 
 ObjectFile *ObjectFileBreakpad::CreateMemoryInstance(
@@ -97,9 +103,15 @@ ObjectFile *ObjectFileBreakpad::CreateMemoryInstance(
 }
 
 size_t ObjectFileBreakpad::GetModuleSpecifications(
-    const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+    const FileSpec &file, DataExtractorSP &extractor_sp, offset_t data_offset,
     offset_t file_offset, offset_t length, ModuleSpecList &specs) {
-  auto text = toStringRef(data_sp->GetData());
+  // If this is opearting on a VirtualDataExtractor, it can have
+  // gaps between valid bytes in the DataBuffer. We extract an
+  // ArrayRef of the raw bytes, and can segfault.
+  DataExtractorSP contiguous_extractor_sp =
+      extractor_sp->GetSubsetExtractorSP(0);
+  auto text =
+      toStringRef(contiguous_extractor_sp->GetSharedDataBuffer()->GetData());
   std::optional<Header> header = Header::parse(text);
   if (!header)
     return 0;
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h 
b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index 7f9a05b28101c..c866aa73e0cdf 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -39,7 +39,7 @@ class ObjectFileBreakpad : public ObjectFile {
                                           lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp 
b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp
index dc5b98d217b1e..9eb7ef14d7720 100644
--- a/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp
@@ -66,10 +66,15 @@ ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp,
   assert(extractor_sp && extractor_sp->HasData() &&
          "must have mapped file at this point");
 
-  if (!IsCOFFObjectFile(extractor_sp->GetSharedDataBuffer()))
+  // If this is opearting on a VirtualDataExtractor, it can have
+  // gaps between valid bytes in the DataBuffer. We extract an
+  // ArrayRef of the raw bytes, and can segfault.
+  DataExtractorSP contiguous_extractor_sp =
+      extractor_sp->GetSubsetExtractorSP(0);
+  if (!IsCOFFObjectFile(contiguous_extractor_sp->GetSharedDataBuffer()))
     return nullptr;
 
-  if (extractor_sp->GetByteSize() < length) {
+  if (contiguous_extractor_sp->GetByteSize() < length) {
     DataBufferSP data_sp = MapFileData(*file, length, file_offset);
     if (!data_sp) {
       LLDB_LOG(log,
@@ -77,12 +82,13 @@ ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp,
                file->GetPath());
       return nullptr;
     }
-    extractor_sp = std::make_shared<lldb_private::DataExtractor>(data_sp);
+    contiguous_extractor_sp =
+        std::make_shared<lldb_private::DataExtractor>(data_sp);
     data_offset = 0;
   }
 
   MemoryBufferRef buffer{
-      toStringRef(extractor_sp->GetSharedDataBuffer()->GetData()),
+      toStringRef(contiguous_extractor_sp->GetSharedDataBuffer()->GetData()),
       file->GetFilename().GetStringRef()};
 
   Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
@@ -98,8 +104,8 @@ ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp,
            file->GetPath());
 
   return new 
ObjectFileCOFF(unique_dyn_cast<COFFObjectFile>(std::move(*binary)),
-                            module_sp, extractor_sp, data_offset, file,
-                            file_offset, length);
+                            module_sp, contiguous_extractor_sp, data_offset,
+                            file, file_offset, length);
 }
 
 lldb_private::ObjectFile *ObjectFileCOFF::CreateMemoryInstance(
@@ -110,13 +116,19 @@ lldb_private::ObjectFile 
*ObjectFileCOFF::CreateMemoryInstance(
 }
 
 size_t ObjectFileCOFF::GetModuleSpecifications(
-    const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+    const FileSpec &file, DataExtractorSP &extractor_sp, offset_t data_offset,
     offset_t file_offset, offset_t length, ModuleSpecList &specs) {
-  if (!IsCOFFObjectFile(data_sp))
+  // If this is opearting on a VirtualDataExtractor, it can have
+  // gaps between valid bytes in the DataBuffer. We extract an
+  // ArrayRef of the raw bytes, and can segfault.
+  DataExtractorSP contiguous_extractor_sp =
+      extractor_sp->GetSubsetExtractorSP(0);
+  if (!IsCOFFObjectFile(contiguous_extractor_sp->GetSharedDataBuffer()))
     return 0;
 
-  MemoryBufferRef buffer{toStringRef(data_sp->GetData()),
-                         file.GetFilename().GetStringRef()};
+  MemoryBufferRef buffer{
+      toStringRef(contiguous_extractor_sp->GetSharedDataBuffer()->GetData()),
+      file.GetFilename().GetStringRef()};
   Expected<std::unique_ptr<Binary>> binary = createBinary(buffer);
   if (!binary) {
     Log *log = GetLog(LLDBLog::Object);
diff --git a/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h 
b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h
index eed491d183489..0df6803deb29d 100644
--- a/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h
+++ b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h
@@ -55,7 +55,7 @@ class ObjectFileCOFF : public lldb_private::ObjectFile {
                        const lldb::ProcessSP &process_sp, lldb::addr_t header);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp 
b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 7abe915253924..6fbb5815d374e 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -586,20 +586,21 @@ static bool GetOsFromOSABI(unsigned char osabi_byte,
 }
 
 size_t ObjectFileELF::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
   Log *log = GetLog(LLDBLog::Modules);
 
   const size_t initial_count = specs.GetSize();
 
-  if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
+  if (ObjectFileELF::MagicBytesMatch(extractor_sp->GetSharedDataBuffer(), 0,
+                                     extractor_sp->GetByteSize())) {
     DataExtractor data;
-    data.SetData(data_sp);
+    data.SetData(extractor_sp->GetSharedDataBuffer());
     elf::ELFHeader header;
     lldb::offset_t header_offset = data_offset;
     if (header.Parse(data, &header_offset)) {
-      if (data_sp) {
+      if (extractor_sp) {
         ModuleSpec spec(file);
         // In Android API level 23 and above, bionic dynamic linker is able to
         // load .so file directly from zip file. In that case, .so file is
@@ -640,10 +641,11 @@ size_t ObjectFileELF::GetModuleSpecifications(
                       __FUNCTION__, file.GetPath().c_str());
           }
 
+          DataBufferSP data_sp = extractor_sp->GetSharedDataBuffer();
           // When ELF file does not contain GNU build ID, the later code will
-          // calculate CRC32 with this data_sp file_offset and length. It is
-          // important for Android zip .so file, which is a slice of a file,
-          // to not access the outside of the file slice range.
+          // calculate CRC32 with this extractor_sp file_offset and
+          // length. It is important for Android zip .so file, which is a slice
+          // of a file, to not access the outside of the file slice range.
           if (data_sp->GetByteSize() < length)
             data_sp = MapFileData(file, length, file_offset);
           if (data_sp)
@@ -3017,10 +3019,14 @@ unsigned ObjectFileELF::RelocateDebugSections(const 
ELFSectionHeader *rel_hdr,
   DataExtractor rel_data;
   DataExtractor symtab_data;
   DataExtractor debug_data;
-
-  if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) &&
-      GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) &&
-      GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) {
+  DataExtractorSP rel_data_sp, symtab_data_sp, debug_data_sp;
+
+  if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data_sp) &&
+      GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data_sp) 
&&
+      GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data_sp)) {
+    rel_data = *rel_data_sp;
+    symtab_data = *symtab_data_sp;
+    debug_data = *debug_data_sp;
     ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr,
                      rel_data, symtab_data, debug_data, debug);
   }
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h 
b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index e189543b70cda..4992e9e2482f3 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -79,7 +79,7 @@ class ObjectFileELF : public lldb_private::ObjectFile {
       const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp 
b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp
index c4ae6c48011df..83f2cfcf59a1f 100644
--- a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp
+++ b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp
@@ -109,23 +109,26 @@ ObjectFile *ObjectFileJSON::CreateMemoryInstance(const 
ModuleSP &module_sp,
 }
 
 size_t ObjectFileJSON::GetModuleSpecifications(
-    const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+    const FileSpec &file, DataExtractorSP &extractor_sp, offset_t data_offset,
     offset_t file_offset, offset_t length, ModuleSpecList &specs) {
-  if (!MagicBytesMatch(data_sp, data_offset, data_sp->GetByteSize()))
+  if (!MagicBytesMatch(extractor_sp->GetSharedDataBuffer(), data_offset,
+                       extractor_sp->GetByteSize()))
     return 0;
 
   // 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 (!data_sp)
+  if (extractor_sp->GetByteSize() < length) {
+    DataBufferSP file_data_sp = MapFileData(file, length, file_offset);
+    if (file_data_sp)
+      extractor_sp->SetData(file_data_sp);
+    if (!extractor_sp->HasData())
       return 0;
     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) {
diff --git a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.h 
b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.h
index 8608cc30cb7a5..3ae302adcd2f3 100644
--- a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.h
+++ b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.h
@@ -39,7 +39,7 @@ class ObjectFileJSON : public ObjectFile {
                                           lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index dafb0b961e473..4ef9e4d1e6e2d 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -794,8 +794,7 @@ ObjectFile *ObjectFileMachO::CreateInstance(const 
lldb::ModuleSP &module_sp,
     extractor_sp = std::make_shared<DataExtractor>(data_sp);
   }
 
-  if (!ObjectFileMachO::MagicBytesMatch(extractor_sp->GetSharedDataBuffer(),
-                                        data_offset, length))
+  if (!ObjectFileMachO::MagicBytesMatch(extractor_sp, data_offset, length))
     return nullptr;
 
   // Update the data to contain the entire file if it doesn't already
@@ -817,7 +816,9 @@ ObjectFile *ObjectFileMachO::CreateInstance(const 
lldb::ModuleSP &module_sp,
 ObjectFile *ObjectFileMachO::CreateMemoryInstance(
     const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
     const ProcessSP &process_sp, lldb::addr_t header_addr) {
-  if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
+  DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(data_sp);
+  if (ObjectFileMachO::MagicBytesMatch(extractor_sp, 0,
+                                       extractor_sp->GetByteSize())) {
     std::unique_ptr<ObjectFile> objfile_up(
         new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));
     if (objfile_up.get() && objfile_up->ParseHeader())
@@ -827,29 +828,32 @@ ObjectFile *ObjectFileMachO::CreateMemoryInstance(
 }
 
 size_t ObjectFileMachO::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
   const size_t initial_count = specs.GetSize();
+  if (!extractor_sp || !extractor_sp->HasData())
+    return initial_count;
 
-  if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
-    DataExtractor data;
-    data.SetData(data_sp);
+  if (ObjectFileMachO::MagicBytesMatch(extractor_sp, 0,
+                                       extractor_sp->GetByteSize())) {
     llvm::MachO::mach_header header;
-    if (ParseHeader(data, &data_offset, header)) {
+    if (ParseHeader(extractor_sp, &data_offset, header)) {
       size_t header_and_load_cmds =
           header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
-      if (header_and_load_cmds >= data_sp->GetByteSize()) {
-        data_sp = MapFileData(file, header_and_load_cmds, file_offset);
-        data.SetData(data_sp);
+      if (header_and_load_cmds >= extractor_sp->GetByteSize()) {
+        DataBufferSP file_data_sp =
+            MapFileData(file, header_and_load_cmds, file_offset);
+        if (file_data_sp)
+          extractor_sp->SetData(file_data_sp);
         data_offset = MachHeaderSizeFromMagic(header.magic);
       }
-      if (data_sp) {
+      if (extractor_sp && extractor_sp->HasData()) {
         ModuleSpec base_spec;
         base_spec.GetFileSpec() = file;
         base_spec.SetObjectOffset(file_offset);
         base_spec.SetObjectSize(length);
-        GetAllArchSpecs(header, data, data_offset, base_spec, specs);
+        GetAllArchSpecs(header, *extractor_sp, data_offset, base_spec, specs);
       }
     }
   }
@@ -906,17 +910,15 @@ ConstString ObjectFileMachO::GetSectionNameLLDBNoNlist() {
   return g_section_name_lldb_no_nlist;
 }
 
-bool ObjectFileMachO::MagicBytesMatch(DataBufferSP data_sp,
+bool ObjectFileMachO::MagicBytesMatch(DataExtractorSP extractor_sp,
                                       lldb::addr_t data_offset,
                                       lldb::addr_t data_length) {
-  DataExtractor data;
-  data.SetData(data_sp, data_offset, data_length);
-  lldb::offset_t offset = 0;
-  uint32_t magic = data.GetU32(&offset);
+  lldb::offset_t offset = data_offset;
+  uint32_t magic = extractor_sp->GetU32(&offset);
 
   offset += 4; // cputype
   offset += 4; // cpusubtype
-  uint32_t filetype = data.GetU32(&offset);
+  uint32_t filetype = extractor_sp->GetU32(&offset);
 
   // A fileset has a Mach-O header but is not an
   // individual file and must be handled via an
@@ -955,41 +957,41 @@ ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP 
&module_sp,
   ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
 }
 
-bool ObjectFileMachO::ParseHeader(DataExtractor &data,
+bool ObjectFileMachO::ParseHeader(DataExtractorSP &extractor_sp,
                                   lldb::offset_t *data_offset_ptr,
                                   llvm::MachO::mach_header &header) {
-  data.SetByteOrder(endian::InlHostByteOrder());
+  extractor_sp->SetByteOrder(endian::InlHostByteOrder());
   // Leave magic in the original byte order
-  header.magic = data.GetU32(data_offset_ptr);
+  header.magic = extractor_sp->GetU32(data_offset_ptr);
   bool can_parse = false;
   bool is_64_bit = false;
   switch (header.magic) {
   case MH_MAGIC:
-    data.SetByteOrder(endian::InlHostByteOrder());
-    data.SetAddressByteSize(4);
+    extractor_sp->SetByteOrder(endian::InlHostByteOrder());
+    extractor_sp->SetAddressByteSize(4);
     can_parse = true;
     break;
 
   case MH_MAGIC_64:
-    data.SetByteOrder(endian::InlHostByteOrder());
-    data.SetAddressByteSize(8);
+    extractor_sp->SetByteOrder(endian::InlHostByteOrder());
+    extractor_sp->SetAddressByteSize(8);
     can_parse = true;
     is_64_bit = true;
     break;
 
   case MH_CIGAM:
-    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
-                          ? eByteOrderLittle
-                          : eByteOrderBig);
-    data.SetAddressByteSize(4);
+    extractor_sp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
+                                   ? eByteOrderLittle
+                                   : eByteOrderBig);
+    extractor_sp->SetAddressByteSize(4);
     can_parse = true;
     break;
 
   case MH_CIGAM_64:
-    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
-                          ? eByteOrderLittle
-                          : eByteOrderBig);
-    data.SetAddressByteSize(8);
+    extractor_sp->SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
+                                   ? eByteOrderLittle
+                                   : eByteOrderBig);
+    extractor_sp->SetAddressByteSize(8);
     is_64_bit = true;
     can_parse = true;
     break;
@@ -999,7 +1001,7 @@ bool ObjectFileMachO::ParseHeader(DataExtractor &data,
   }
 
   if (can_parse) {
-    data.GetU32(data_offset_ptr, &header.cputype, 6);
+    extractor_sp->GetU32(data_offset_ptr, &header.cputype, 6);
     if (is_64_bit)
       *data_offset_ptr += 4;
     return true;
@@ -5734,8 +5736,9 @@ void ObjectFileMachO::GetProcessSharedCacheUUID(Process 
*process,
     DynamicLoader *dl = process->GetDynamicLoader();
     LazyBool using_shared_cache;
     LazyBool private_shared_cache;
+    FileSpec sc_filepath;
     dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
-                                  private_shared_cache);
+                                  private_shared_cache, sc_filepath);
   }
   Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
   LLDB_LOGF(
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index b40621473e577..d4c3a1f613ad2 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -58,7 +58,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
       const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
@@ -68,8 +68,8 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
                        lldb_private::SaveCoreOptions &options,
                        lldb_private::Status &error);
 
-  static bool MagicBytesMatch(lldb::DataBufferSP data_sp, lldb::addr_t offset,
-                              lldb::addr_t length);
+  static bool MagicBytesMatch(lldb::DataExtractorSP extractor_sp,
+                              lldb::addr_t offset, lldb::addr_t length);
 
   // LLVM RTTI support
   static char ID;
@@ -156,7 +156,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
 
   bool CanTrustAddressRanges() override;
 
-  static bool ParseHeader(lldb_private::DataExtractor &data,
+  static bool ParseHeader(lldb::DataExtractorSP &data,
                           lldb::offset_t *data_offset_ptr,
                           llvm::MachO::mach_header &header);
 
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp 
b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
index 75ae172dad0da..05f1caa189851 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
@@ -48,7 +48,7 @@ ObjectFile *ObjectFileMinidump::CreateMemoryInstance(
 }
 
 size_t ObjectFileMinidump::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
   specs.Clear();
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h 
b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h
index 8f5da230467d5..63f4e2cd677a4 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h
+++ b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h
@@ -49,7 +49,7 @@ class ObjectFileMinidump : public 
lldb_private::PluginInterface {
       const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp 
b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
index cabd54ffa4b0b..7cebffbb904c2 100644
--- a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
+++ b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
@@ -112,7 +112,7 @@ ObjectFile *ObjectFilePDB::CreateMemoryInstance(const 
ModuleSP &module_sp,
 }
 
 size_t ObjectFilePDB::GetModuleSpecifications(
-    const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+    const FileSpec &file, DataExtractorSP &extractor_sp, offset_t data_offset,
     offset_t file_offset, offset_t length, ModuleSpecList &specs) {
   const size_t initial_count = specs.GetSize();
   ModuleSpec module_spec(file);
diff --git a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h 
b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
index 501701f18d75a..0a10d7e51bdd5 100644
--- a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
+++ b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
@@ -43,7 +43,7 @@ class ObjectFilePDB : public ObjectFile {
                                           lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp 
b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 7fbeea695b933..05b1978232c08 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -251,20 +251,22 @@ ObjectFile *ObjectFilePECOFF::CreateMemoryInstance(
 }
 
 size_t ObjectFilePECOFF::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
   const size_t initial_count = specs.GetSize();
-  if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp))
+  if (!extractor_sp || !extractor_sp->HasData() ||
+      !ObjectFilePECOFF::MagicBytesMatch(extractor_sp->GetSharedDataBuffer()))
     return initial_count;
 
   Log *log = GetLog(LLDBLog::Object);
 
-  if (data_sp->GetByteSize() < length)
+  if (extractor_sp->GetByteSize() < length)
     if (DataBufferSP full_sp = MapFileData(file, -1, file_offset))
-      data_sp = std::move(full_sp);
+      extractor_sp->SetData(std::move(full_sp));
   auto binary = llvm::object::createBinary(llvm::MemoryBufferRef(
-      toStringRef(data_sp->GetData()), file.GetFilename().GetStringRef()));
+      toStringRef(extractor_sp->GetSharedDataBuffer()->GetData()),
+      file.GetFilename().GetStringRef()));
 
   if (!binary) {
     LLDB_LOG_ERROR(log, binary.takeError(),
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h 
b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index d9e26cd167407..d21adae36d603 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -79,7 +79,7 @@ class ObjectFilePECOFF : public lldb_private::ObjectFile {
       const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp 
b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
index bb74a75d93343..ebddf7b82f7cd 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
@@ -128,12 +128,13 @@ ObjectFile *ObjectFileXCOFF::CreateMemoryInstance(
 }
 
 size_t ObjectFileXCOFF::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
   const size_t initial_count = specs.GetSize();
 
-  if (ObjectFileXCOFF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
+  if (ObjectFileXCOFF::MagicBytesMatch(extractor_sp->GetSharedDataBuffer(), 0,
+                                       extractor_sp->GetByteSize())) {
     ArchSpec arch_spec =
         ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE);
     ModuleSpec spec(file, arch_spec);
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h 
b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
index 1d6f250aa4f16..ed05235336ca4 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
@@ -48,7 +48,7 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
       const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp 
b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 72b63fbecd913..b2aeb7bdebf96 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -275,9 +275,9 @@ bool ObjectFileWasm::DecodeSections() {
 }
 
 size_t ObjectFileWasm::GetModuleSpecifications(
-    const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+    const FileSpec &file, DataExtractorSP &extractor_sp, offset_t data_offset,
     offset_t file_offset, offset_t length, ModuleSpecList &specs) {
-  if (!ValidateModuleHeader(data_sp)) {
+  if (!ValidateModuleHeader(extractor_sp->GetSharedDataBuffer())) {
     return 0;
   }
 
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h 
b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
index 85155d64904c1..18e36b22a4641 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -43,7 +43,7 @@ class ObjectFileWasm : public ObjectFile {
                                           lldb::addr_t header_addr);
 
   static size_t GetModuleSpecifications(const FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
+                                        lldb::DataExtractorSP &extractor_sp,
                                         lldb::offset_t data_offset,
                                         lldb::offset_t file_offset,
                                         lldb::offset_t length,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp 
b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
index a72d94ea79c49..a6dc6759c16df 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
@@ -326,7 +326,7 @@ lldb_private::Status 
PlatformDarwinDevice::GetSharedModuleWithLocalCache(
     if (image_info.uuid &&
         (!module_spec.GetUUID() || module_spec.GetUUID() == image_info.uuid)) {
       ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid,
-                                   image_info.data_sp);
+                                   image_info.extractor_sp);
       err = ModuleList::GetSharedModule(shared_cache_spec, module_sp,
                                         old_modules, did_create_ptr);
       if (module_sp) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 4fa92af59f8cd..ab6965bd58204 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -4335,7 +4335,7 @@ StructuredData::ObjectSP 
ProcessGDBRemote::GetDynamicLoaderProcessState() {
 }
 
 StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
-  StructuredData::ObjectSP object_sp;
+  static StructuredData::ObjectSP object_sp;
   StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
 
   if (m_gdb_comm.GetSharedCacheInfoSupported()) {
@@ -4357,9 +4357,22 @@ StructuredData::ObjectSP 
ProcessGDBRemote::GetSharedCacheInfo() {
       StringExtractorGDBRemote::ResponseType response_type =
           response.GetResponseType();
       if (response_type == StringExtractorGDBRemote::eResponse) {
-        if (!response.Empty()) {
-          object_sp = StructuredData::ParseJSON(response.GetStringRef());
-        }
+        if (response.Empty())
+          return {};
+        StructuredData::ObjectSP response_sp =
+            StructuredData::ParseJSON(response.GetStringRef());
+        if (!response_sp)
+          return {};
+        StructuredData::Dictionary *dict = response_sp->GetAsDictionary();
+        if (!dict)
+          return {};
+        if (!dict->HasKey("shared_cache_uuid"))
+          return {};
+        llvm::StringRef uuid_str;
+        if (!dict->GetValueForKeyAsString("shared_cache_uuid", uuid_str, "") ||
+            uuid_str == "00000000-0000-0000-0000-000000000000")
+          return {};
+        object_sp = response_sp;
       }
     }
   }
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp 
b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 83d684e9ca528..2af49dbbe46cd 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -69,11 +69,13 @@ lldb::ProcessSP 
ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
     auto data_sp = FileSystem::Instance().CreateDataBuffer(
         crash_file->GetPath(), header_size, 0);
     if (data_sp && data_sp->GetByteSize() == header_size) {
-      DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
+      DataExtractorSP extractor_sp =
+          std::make_shared<DataExtractor>(data_sp, lldb::eByteOrderLittle, 4);
 
       lldb::offset_t data_offset = 0;
       llvm::MachO::mach_header mach_header;
-      if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) {
+      if (ObjectFileMachO::ParseHeader(extractor_sp, &data_offset,
+                                       mach_header)) {
         if (mach_header.filetype == llvm::MachO::MH_CORE)
           process_sp = std::make_shared<ProcessMachCore>(target_sp, 
listener_sp,
                                                          *crash_file);
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp 
b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index b0b8fae8697f4..08901bf92768f 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -86,11 +86,12 @@ void HashElfTextSection(ModuleSP module_sp, 
std::vector<uint8_t> &breakpad_uuid,
   // The breakpad code has a bug where it might access beyond the end of a
   // .text section by up to 15 bytes, so we must ensure we round up to the
   // next kMDGUIDSize byte boundary.
-  DataExtractor data;
+  DataExtractorSP extractor_sp;
   const size_t text_size = sect_sp->GetFileSize();
   const size_t read_size = std::min<size_t>(
       llvm::alignTo(text_size, kMDGUIDSize), kBreakpadPageSize);
-  sect_sp->GetObjectFile()->GetData(sect_sp->GetFileOffset(), read_size, data);
+  sect_sp->GetObjectFile()->GetData(sect_sp->GetFileOffset(), read_size,
+                                    extractor_sp);
 
   breakpad_uuid.assign(kMDGUIDSize, 0);
   facebook_uuid.assign(kMDGUIDSize, 0);
@@ -105,8 +106,8 @@ void HashElfTextSection(ModuleSP module_sp, 
std::vector<uint8_t> &breakpad_uuid,
   // sources, including the error where it might has an extra 15 bytes past the
   // end of the .text section if the .text section is less than a page size in
   // length.
-  const uint8_t *ptr = data.GetDataStart();
-  const uint8_t *ptr_end = data.GetDataEnd();
+  const uint8_t *ptr = extractor_sp->GetDataStart();
+  const uint8_t *ptr_end = extractor_sp->GetDataEnd();
   while (ptr < ptr_end) {
     for (unsigned i = 0; i < kMDGUIDSize; i++) {
       breakpad_uuid[i] ^= ptr[i];
diff --git a/lldb/source/Symbol/ObjectFile.cpp 
b/lldb/source/Symbol/ObjectFile.cpp
index 85defebeaa999..c44b4fd71262e 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -206,29 +206,34 @@ size_t ObjectFile::GetModuleSpecifications(const FileSpec 
&file,
                                            lldb::offset_t file_offset,
                                            lldb::offset_t file_size,
                                            ModuleSpecList &specs,
-                                           DataBufferSP data_sp) {
-  if (!data_sp)
-    data_sp = FileSystem::Instance().CreateDataBuffer(
+                                           DataExtractorSP extractor_sp) {
+  if (!extractor_sp)
+    extractor_sp = std::make_shared<DataExtractor>();
+  if (!extractor_sp->HasData()) {
+    DataBufferSP file_data_sp = FileSystem::Instance().CreateDataBuffer(
         file.GetPath(), g_initial_bytes_to_read, file_offset);
-  if (data_sp) {
+    if (file_data_sp)
+      extractor_sp->SetData(file_data_sp);
+  }
+  if (extractor_sp->HasData()) {
     if (file_size == 0) {
       const lldb::offset_t actual_file_size =
           FileSystem::Instance().GetByteSize(file);
       if (actual_file_size > file_offset)
         file_size = actual_file_size - file_offset;
     }
-    return ObjectFile::GetModuleSpecifications(file,        // file spec
-                                               data_sp,     // data bytes
-                                               0,           // data offset
-                                               file_offset, // file offset
-                                               file_size,   // file length
+    return ObjectFile::GetModuleSpecifications(file,         // file spec
+                                               extractor_sp, // data bytes
+                                               0,            // data offset
+                                               file_offset,  // file offset
+                                               file_size,    // file length
                                                specs);
   }
   return 0;
 }
 
 size_t ObjectFile::GetModuleSpecifications(
-    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
     lldb::offset_t data_offset, lldb::offset_t file_offset,
     lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
   const size_t initial_count = specs.GetSize();
@@ -240,7 +245,8 @@ size_t ObjectFile::GetModuleSpecifications(
             PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
                 i)) != nullptr;
        ++i) {
-    if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 
0)
+    if (callback(file, extractor_sp, data_offset, file_offset, file_size,
+                 specs) > 0)
       return specs.GetSize() - initial_count;
   }
 
@@ -250,7 +256,8 @@ size_t ObjectFile::GetModuleSpecifications(
             GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) !=
        nullptr;
        ++i) {
-    if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 
0)
+    if (callback(file, extractor_sp, data_offset, file_offset, file_size,
+                 specs) > 0)
       return specs.GetSize() - initial_count;
   }
   return 0;
@@ -490,10 +497,11 @@ WritableDataBufferSP ObjectFile::ReadMemory(const 
ProcessSP &process_sp,
 }
 
 size_t ObjectFile::GetData(lldb::offset_t offset, size_t length,
-                           DataExtractor &data) const {
+                           DataExtractorSP &data_sp) const {
   // The entire file has already been mmap'ed into m_data_nsp, so just copy 
from
   // there as the back mmap buffer will be shared with shared pointers.
-  return data.SetData(*m_data_nsp, offset, length);
+  data_sp = m_data_nsp->GetSubsetExtractorSP(offset, length);
+  return data_sp->GetByteSize();
 }
 
 size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
@@ -581,8 +589,11 @@ size_t ObjectFile::ReadSectionData(Section *section,
 
   // The object file now contains a full mmap'ed copy of the object file
   // data, so just use this
-  return GetData(section->GetFileOffset(), GetSectionDataSize(section),
-                 section_data);
+  DataExtractorSP extractor_sp;
+  size_t ret_size = GetData(section->GetFileOffset(),
+                            GetSectionDataSize(section), extractor_sp);
+  section_data = *extractor_sp;
+  return ret_size;
 }
 
 bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
@@ -707,8 +718,7 @@ ObjectFile::GetLoadableData(Target &target) {
       continue;
     DataExtractor section_data;
     section_sp->GetSectionData(section_data);
-    loadable.Contents = llvm::ArrayRef<uint8_t>(section_data.GetDataStart(),
-                                                section_data.GetByteSize());
+    loadable.Contents = section_data.GetData();
     loadables.push_back(loadable);
   }
   return loadables;
diff --git a/lldb/unittests/Core/ModuleSpecTest.cpp 
b/lldb/unittests/Core/ModuleSpecTest.cpp
index f9e19ed35acc4..373f4a2379efb 100644
--- a/lldb/unittests/Core/ModuleSpecTest.cpp
+++ b/lldb/unittests/Core/ModuleSpecTest.cpp
@@ -34,7 +34,8 @@ 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);
+  ModuleSpec Spec(FileSpec(), UUID(),
+                  std::make_shared<DataExtractor>(InvalidBufferSP));
 
   auto InvalidModuleSP = std::make_shared<Module>(Spec);
   ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr);
@@ -44,7 +45,8 @@ 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);
+  ModuleSpec Spec(FileSpec(TestMainArgv0), UUID(),
+                  std::make_shared<DataExtractor>(InvalidBufferSP));
 
   auto InvalidModuleSP = std::make_shared<Module>(Spec);
   ASSERT_EQ(InvalidModuleSP->GetObjectFile(), nullptr);
diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp 
b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
index 871eca41539d3..3adb642c1108e 100644
--- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
+++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
@@ -33,9 +33,9 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) {
   SharedCacheImageInfo image_info =
       HostInfo::GetSharedCacheImageInfo("/usr/lib/libobjc.A.dylib");
   EXPECT_TRUE(image_info.uuid);
-  EXPECT_TRUE(image_info.data_sp);
+  EXPECT_TRUE(image_info.extractor_sp);
 
-  ModuleSpec spec(FileSpec(), UUID(), image_info.data_sp);
+  ModuleSpec spec(FileSpec(), UUID(), image_info.extractor_sp);
   lldb::ModuleSP module = std::make_shared<Module>(spec);
   ObjectFile *OF = module->GetObjectFile();
   ASSERT_TRUE(llvm::isa<ObjectFileMachO>(OF));
@@ -80,7 +80,7 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) {
 TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) {
   SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(
       "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit");
-  ModuleSpec spec(FileSpec(), UUID(), image_info.data_sp);
+  ModuleSpec spec(FileSpec(), UUID(), image_info.extractor_sp);
   lldb::ModuleSP module = std::make_shared<Module>(spec);
 
   ObjectFile *OF = module->GetObjectFile();
diff --git a/lldb/unittests/TestingSupport/TestUtilities.h 
b/lldb/unittests/TestingSupport/TestUtilities.h
index f05d176618fa0..68b4dbc127a7d 100644
--- a/lldb/unittests/TestingSupport/TestUtilities.h
+++ b/lldb/unittests/TestingSupport/TestUtilities.h
@@ -47,7 +47,8 @@ class TestFile {
   static llvm::Expected<TestFile> fromYamlFile(const llvm::Twine &Name);
 
   ModuleSpec moduleSpec() {
-    return ModuleSpec(FileSpec(), UUID(), dataBuffer());
+    return ModuleSpec(FileSpec(), UUID(),
+                      std::make_shared<DataExtractor>(dataBuffer()));
   }
 
   llvm::Expected<llvm::sys::fs::TempFile> writeToTemporaryFile();

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to