[Lldb-commits] [lldb] 682532c - Support v2 of 'main bin spec' Mach-O LC_NOTE in corefiles

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 22 00:07:08 PST 2021


Author: Jason Molenda
Date: 2021-12-22T00:02:27-08:00
New Revision: 682532ca575b8b6c4d3e2104a7526743ff9446a9

URL: https://github.com/llvm/llvm-project/commit/682532ca575b8b6c4d3e2104a7526743ff9446a9
DIFF: https://github.com/llvm/llvm-project/commit/682532ca575b8b6c4d3e2104a7526743ff9446a9.diff

LOG: Support v2 of 'main bin spec' Mach-O LC_NOTE in corefiles

Version 2 of 'main bin spec' LC_NOTE allows for the specification
of a slide of where the binary is loaded in the corefile virtual
address space.  It also adds a (currently unused) platform field
for the main binary.

Some corefile creators will only have a UUID and an offset to be
applied to the binary.

Changed TestFirmwareCorefiles.py to test this new form of
'main bin spec' with a slide, and also to run on both x86_64
and arm64 macOS systems.

Differential Revision: https://reviews.llvm.org/D116094
rdar://85938455

Added: 
    

Modified: 
    lldb/include/lldb/Symbol/ObjectFile.h
    lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
    lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
    lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py
    lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index bfc5d382dbf98..8bf047cd45141 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -527,11 +527,15 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
   /// binary is exactly which removes ambiguity when there are multiple
   /// binaries present in the captured memory pages.
   ///
-  /// \param[out] address
-  ///   If the address of the binary is specified, this will be set.
-  ///   This is an address is the virtual address space of the core file
-  ///   memory segments; it is not an offset into the object file.
-  ///   If no address is available, will be set to LLDB_INVALID_ADDRESS.
+  /// \param[out] value
+  ///   The address or offset (slide) where the binary is loaded in memory.
+  ///   LLDB_INVALID_ADDRESS for unspecified.  If an offset is given,
+  ///   this offset should be added to the binary's file address to get
+  ///   the load address.
+  ///
+  /// \param[out] value_is_offset
+  ///   Specifies if \b value is a load address, or an offset to calculate
+  ///   the load address.
   ///
   /// \param[out] uuid
   ///   If the uuid of the binary is specified, this will be set.
@@ -543,9 +547,11 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
   ///
   /// \return
   ///   Returns true if either address or uuid has been set.
-  virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &address, UUID &uuid,
+  virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &value,
+                                         bool &value_is_offset, UUID &uuid,
                                          ObjectFile::BinaryType &type) {
-    address = LLDB_INVALID_ADDRESS;
+    value = LLDB_INVALID_ADDRESS;
+    value_is_offset = false;
     uuid.Clear();
     return false;
   }

diff  --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index e0087dbd4941e..7668b68650b4d 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5620,10 +5620,15 @@ addr_t ObjectFileMachO::GetAddressMask() {
   return mask;
 }
 
-bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid,
+bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
+                                                bool &value_is_offset,
+                                                UUID &uuid,
                                                 ObjectFile::BinaryType &type) {
-  address = LLDB_INVALID_ADDRESS;
+  value = LLDB_INVALID_ADDRESS;
+  value_is_offset = false;
   uuid.Clear();
+  uint32_t log2_pagesize = 0; // not currently passed up to caller
+  uint32_t platform = 0;      // not currently passed up to caller
   ModuleSP module_sp(GetModule());
   if (module_sp) {
     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
@@ -5641,6 +5646,26 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid,
         uint64_t fileoff = m_data.GetU64_unchecked(&offset);
         uint64_t size = m_data.GetU64_unchecked(&offset);
 
+        // struct main_bin_spec
+        // {
+        //     uint32_t version;       // currently 2
+        //     uint32_t type;          // 0 == unspecified, 1 == kernel,
+        //                             // 2 == user process,
+        //                             // 3 == standalone binary
+        //     uint64_t address;       // UINT64_MAX if address not specified
+        //     uint64_t slide;         // slide, UINT64_MAX if unspecified
+        //                             // 0 if no slide needs to be applied to
+        //                             // file address
+        //     uuid_t   uuid;          // all zero's if uuid not specified
+        //     uint32_t log2_pagesize; // process page size in log base 2,
+        //                             // e.g. 4k pages are 12.
+        //                             // 0 for unspecified
+        //     uint32_t platform;      // The Mach-O platform for this corefile.
+        //                             // 0 for unspecified.
+        //                             // The values are defined in
+        //                             // <mach-o/loader.h>, PLATFORM_*.
+        // } __attribute((packed));
+
         // "main bin spec" (main binary specification) data payload is
         // formatted:
         //    uint32_t version       [currently 1]
@@ -5656,14 +5681,25 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid,
         if (strcmp("main bin spec", data_owner) == 0 && size >= 32) {
           offset = fileoff;
           uint32_t version;
-          if (m_data.GetU32(&offset, &version, 1) != nullptr && version == 1) {
+          if (m_data.GetU32(&offset, &version, 1) != nullptr && version <= 2) {
             uint32_t binspec_type = 0;
             uuid_t raw_uuid;
             memset(raw_uuid, 0, sizeof(uuid_t));
 
-            if (m_data.GetU32(&offset, &binspec_type, 1) &&
-                m_data.GetU64(&offset, &address, 1) &&
-                m_data.CopyData(offset, sizeof(uuid_t), raw_uuid) != 0) {
+            if (!m_data.GetU32(&offset, &binspec_type, 1))
+              return false;
+            if (!m_data.GetU64(&offset, &value, 1))
+              return false;
+            uint64_t slide = LLDB_INVALID_ADDRESS;
+            if (version > 1 && !m_data.GetU64(&offset, &slide, 1))
+              return false;
+            if (value == LLDB_INVALID_ADDRESS &&
+                slide != LLDB_INVALID_ADDRESS) {
+              value = slide;
+              value_is_offset = true;
+            }
+
+            if (m_data.CopyData(offset, sizeof(uuid_t), raw_uuid) != 0) {
               uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t));
               // convert the "main bin spec" type into our
               // ObjectFile::BinaryType enum
@@ -5681,6 +5717,10 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid,
                 type = eBinaryTypeStandalone;
                 break;
               }
+              if (!m_data.GetU32(&offset, &log2_pagesize, 1))
+                return false;
+              if (version > 1 && !m_data.GetU32(&offset, &platform, 1))
+                return false;
               return true;
             }
           }
@@ -7006,7 +7046,17 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
   for (const MachOCorefileImageEntry &image : image_infos.all_image_infos) {
     ModuleSpec module_spec;
     module_spec.GetUUID() = image.uuid;
-    module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
+    if (image.filename.empty()) {
+      char namebuf[80];
+      if (image.load_address != LLDB_INVALID_ADDRESS)
+        snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64,
+                 image.load_address);
+      else
+        snprintf(namebuf, sizeof(namebuf), "mem-image+0x%" PRIx64, image.slide);
+      module_spec.GetFileSpec() = FileSpec(namebuf);
+    } else {
+      module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
+    }
     if (image.currently_executing) {
       Symbols::DownloadObjectAndSymbolFile(module_spec, true);
       if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {

diff  --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 084b0ac110ba1..c666ef32b85e7 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -120,7 +120,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
 
   lldb::addr_t GetAddressMask() override;
 
-  bool GetCorefileMainBinaryInfo(lldb::addr_t &address,
+  bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset,
                                  lldb_private::UUID &uuid,
                                  ObjectFile::BinaryType &type) override;
 

diff  --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 6aed04565eb01..4b3e244dcb23f 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -184,7 +184,8 @@ bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) {
 // Try to load a file with that UUID into lldb, and if we have a load
 // address, set it correctly.  Else assume that the binary was loaded
 // with no slide.
-static bool load_standalone_binary(UUID uuid, addr_t addr, Target &target) {
+static bool load_standalone_binary(UUID uuid, addr_t value,
+                                   bool value_is_offset, Target &target) {
   if (uuid.IsValid()) {
     ModuleSpec module_spec;
     module_spec.GetUUID() = uuid;
@@ -205,18 +206,34 @@ static bool load_standalone_binary(UUID uuid, addr_t addr, Target &target) {
       }
     }
 
-    if (module_sp.get() && module_sp->GetObjectFile()) {
+    // If we couldn't find the binary anywhere else, as a last resort,
+    // read it out of memory in the corefile.
+    if (!module_sp.get() && value != LLDB_INVALID_ADDRESS && !value_is_offset) {
+      char namebuf[80];
+      snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64, value);
+      module_sp =
+          target.GetProcessSP()->ReadModuleFromMemory(FileSpec(namebuf), value);
+    }
+
+    if (module_sp.get()) {
       target.SetArchitecture(module_sp->GetObjectFile()->GetArchitecture());
       target.GetImages().AppendIfNeeded(module_sp, false);
 
-      Address base_addr = module_sp->GetObjectFile()->GetBaseAddress();
-      addr_t slide = 0;
-      if (addr != LLDB_INVALID_ADDRESS && base_addr.IsValid()) {
-        addr_t file_load_addr = base_addr.GetFileAddress();
-        slide = addr - file_load_addr;
-      }
       bool changed = false;
-      module_sp->SetLoadAddress(target, slide, true, changed);
+      if (module_sp->GetObjectFile()) {
+        if (value != LLDB_INVALID_ADDRESS) {
+          module_sp->SetLoadAddress(target, value, value_is_offset, changed);
+        } else {
+          // No address/offset/slide, load the binary at file address,
+          // offset 0.
+          const bool value_is_slide = true;
+          module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+        }
+      } else {
+        // In-memory image, load at its true address, offset 0.
+        const bool value_is_slide = true;
+        module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+      }
 
       ModuleList added_module;
       added_module.Append(module_sp, false);
@@ -316,33 +333,38 @@ Status ProcessMachCore::DoLoadCore() {
 
   bool found_main_binary_definitively = false;
 
-  addr_t objfile_binary_addr;
+  addr_t objfile_binary_value;
+  bool objfile_binary_value_is_offset;
   UUID objfile_binary_uuid;
   ObjectFile::BinaryType type;
-  if (core_objfile->GetCorefileMainBinaryInfo(objfile_binary_addr,
+  if (core_objfile->GetCorefileMainBinaryInfo(objfile_binary_value,
+                                              objfile_binary_value_is_offset,
                                               objfile_binary_uuid, type)) {
     if (log) {
       log->Printf(
           "ProcessMachCore::DoLoadCore: using binary hint from 'main bin spec' "
-          "LC_NOTE with UUID %s address 0x%" PRIx64 " and type %d",
-          objfile_binary_uuid.GetAsString().c_str(), objfile_binary_addr, type);
+          "LC_NOTE with UUID %s value 0x%" PRIx64
+          " value is offset %d and type %d",
+          objfile_binary_uuid.GetAsString().c_str(), objfile_binary_value,
+          objfile_binary_value_is_offset, type);
     }
-    if (objfile_binary_addr != LLDB_INVALID_ADDRESS) {
+    if (objfile_binary_value != LLDB_INVALID_ADDRESS &&
+        !objfile_binary_value_is_offset) {
       if (type == ObjectFile::eBinaryTypeUser) {
-        m_dyld_addr = objfile_binary_addr;
+        m_dyld_addr = objfile_binary_value;
         m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
         found_main_binary_definitively = true;
       }
       if (type == ObjectFile::eBinaryTypeKernel) {
-        m_mach_kernel_addr = objfile_binary_addr;
+        m_mach_kernel_addr = objfile_binary_value;
         m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
         found_main_binary_definitively = true;
       }
     }
     if (!found_main_binary_definitively) {
       // ObjectFile::eBinaryTypeStandalone, undeclared types
-      if (load_standalone_binary(objfile_binary_uuid, objfile_binary_addr,
-                                 GetTarget())) {
+      if (load_standalone_binary(objfile_binary_uuid, objfile_binary_value,
+                                 objfile_binary_value_is_offset, GetTarget())) {
         found_main_binary_definitively = true;
         m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
       }
@@ -388,17 +410,21 @@ Status ProcessMachCore::DoLoadCore() {
       m_mach_kernel_addr = ident_binary_addr;
       found_main_binary_definitively = true;
     } else if (ident_uuid.IsValid()) {
-      if (load_standalone_binary(ident_uuid, ident_binary_addr, GetTarget())) {
+      // We have no address specified, only a UUID.  Load it at the file
+      // address.
+      const bool value_is_offset = false;
+      if (load_standalone_binary(ident_uuid, ident_binary_addr, value_is_offset,
+                                 GetTarget())) {
         found_main_binary_definitively = true;
         m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
       }
     }
   }
 
+  bool did_load_extra_binaries = core_objfile->LoadCoreFileImages(*this);
   // If we have a "all image infos" LC_NOTE, try to load all of the
   // binaries listed, and set their Section load addresses in the Target.
-  if (found_main_binary_definitively == false &&
-      core_objfile->LoadCoreFileImages(*this)) {
+  if (found_main_binary_definitively == false && did_load_extra_binaries) {
     m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
     found_main_binary_definitively = true;
   }

diff  --git a/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py b/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py
index a28b01bb1789e..6600c6344c7dc 100644
--- a/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py
+++ b/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py
@@ -16,26 +16,174 @@ class TestFirmwareCorefiles(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
 
-    def initial_setup(self):
+    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
+    @skipIf(archs=no_match(['x86_64', 'arm64', 'arm64e', 'aarch64']))
+    @skipIfRemote
+    @skipUnlessDarwin
+    def test_lc_note_version_string(self):
+        self.build()
+        aout_exe_basename = "a.out"
+        aout_exe = self.getBuildArtifact(aout_exe_basename)
+        verstr_corefile = self.getBuildArtifact("verstr.core")
+        verstr_corefile_addr = self.getBuildArtifact("verstr-addr.core")
+        create_corefile = self.getBuildArtifact("create-empty-corefile")
+        slide = 0x70000000000
+        call(create_corefile + " version-string " + verstr_corefile + " " + aout_exe + " 0xffffffffffffffff 0xffffffffffffffff", shell=True)
+        call(create_corefile + " version-string " + verstr_corefile_addr + " " + aout_exe + (" 0x%x" % slide) + " 0xffffffffffffffff", shell=True)
+
+        if self.TraceOn():
+            self.runCmd("log enable lldb dyld host")
+            self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
+
+        # Register the a.out binary with this UUID in lldb's global module
+        # cache, then throw the Target away.
+        target = self.dbg.CreateTarget(aout_exe)
+        self.dbg.DeleteTarget(target)
+
+        # First, try the "kern ver str" corefile
+        target = self.dbg.CreateTarget('')
+        err = lldb.SBError()
+        if self.TraceOn():
+            self.runCmd("script print('loading corefile %s')" % verstr_corefile)
+        process = target.LoadCore(verstr_corefile)
+        self.assertEqual(process.IsValid(), True)
+        if self.TraceOn():
+            self.runCmd("image list")
+            self.runCmd("target mod dump sections")
+        self.assertEqual(target.GetNumModules(), 1)
+        fspec = target.GetModuleAtIndex(0).GetFileSpec()
+        self.assertEqual(fspec.GetFilename(), aout_exe_basename)
+        self.dbg.DeleteTarget(target)
+
+        # Second, try the "kern ver str" corefile where it loads at an address
+        target = self.dbg.CreateTarget('')
+        err = lldb.SBError()
+        if self.TraceOn():
+            self.runCmd("script print('loading corefile %s')" % verstr_corefile_addr)
+        process = target.LoadCore(verstr_corefile_addr)
+        self.assertEqual(process.IsValid(), True)
+        if self.TraceOn():
+            self.runCmd("image list")
+            self.runCmd("target mod dump sections")
+        self.assertEqual(target.GetNumModules(), 1)
+        fspec = target.GetModuleAtIndex(0).GetFileSpec()
+        self.assertEqual(fspec.GetFilename(), aout_exe_basename)
+        main_sym = target.GetModuleAtIndex(0).FindSymbol("main", lldb.eSymbolTypeAny)
+        main_addr = main_sym.GetStartAddress()
+        self.assertGreater(main_addr.GetLoadAddress(target), slide)
+        self.assertNotEqual(main_addr.GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS)
+        self.dbg.DeleteTarget(target)
+
+    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
+    @skipIf(archs=no_match(['x86_64', 'arm64', 'arm64e', 'aarch64']))
+    @skipIfRemote
+    @skipUnlessDarwin
+    def test_lc_note_main_bin_spec(self):
+        self.build()
+        aout_exe_basename = "a.out"
+        aout_exe = self.getBuildArtifact(aout_exe_basename)
+        create_corefile = self.getBuildArtifact("create-empty-corefile")
+        binspec_corefile = self.getBuildArtifact("binspec.core")
+        binspec_corefile_addr = self.getBuildArtifact("binspec-addr.core")
+        binspec_corefile_slideonly = self.getBuildArtifact("binspec-addr-slideonly.core")
+
+        slide = 0x70000000000
+
+        ### Create our corefile
+        # 0xffffffffffffffff means load address unknown
+        call(create_corefile + " main-bin-spec " + binspec_corefile + " " + aout_exe + " 0xffffffffffffffff 0xffffffffffffffff", shell=True)
+        call(create_corefile + " main-bin-spec " + binspec_corefile_addr + " " + aout_exe + (" 0x%x" % slide) + " 0xffffffffffffffff", shell=True)
+        call(create_corefile + " main-bin-spec " + binspec_corefile_slideonly + " " + aout_exe + " 0xffffffffffffffff" + (" 0x%x" % slide), shell=True)
+
+        if self.TraceOn():
+            self.runCmd("log enable lldb dyld host")
+            self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
+
+        # Register the a.out binary with this UUID in lldb's global module
+        # cache, then throw the Target away.
+        target = self.dbg.CreateTarget(aout_exe)
+        self.dbg.DeleteTarget(target)
+
+        # First, try the "main bin spec" corefile
+        target = self.dbg.CreateTarget('')
+        if self.TraceOn():
+            self.runCmd("script print('loading corefile %s')" % binspec_corefile)
+        process = target.LoadCore(binspec_corefile)
+        self.assertEqual(process.IsValid(), True)
+        if self.TraceOn():
+            self.runCmd("image list")
+            self.runCmd("target mod dump sections")
+        self.assertEqual(target.GetNumModules(), 1)
+        fspec = target.GetModuleAtIndex(0).GetFileSpec()
+        self.assertEqual(fspec.GetFilename(), aout_exe_basename)
+        self.dbg.DeleteTarget(target)
+
+        # Second, try the "main bin spec" corefile where it loads at an address
+        target = self.dbg.CreateTarget('')
+        if self.TraceOn():
+            self.runCmd("script print('loading corefile %s')" % binspec_corefile_addr)
+        process = target.LoadCore(binspec_corefile_addr)
+        self.assertEqual(process.IsValid(), True)
+        if self.TraceOn():
+            self.runCmd("image list")
+            self.runCmd("target mod dump sections")
+        self.assertEqual(target.GetNumModules(), 1)
+        fspec = target.GetModuleAtIndex(0).GetFileSpec()
+        self.assertEqual(fspec.GetFilename(), aout_exe_basename)
+        main_sym = target.GetModuleAtIndex(0).FindSymbol("main", lldb.eSymbolTypeAny)
+        main_addr = main_sym.GetStartAddress()
+        self.assertGreater(main_addr.GetLoadAddress(target), slide)
+        self.assertNotEqual(main_addr.GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS)
+        self.dbg.DeleteTarget(target)
+
+        # Third, try the "main bin spec" corefile where it loads at a slide
+        target = self.dbg.CreateTarget('')
+        if self.TraceOn():
+            self.runCmd("script print('loading corefile %s')" % binspec_corefile_slideonly)
+        process = target.LoadCore(binspec_corefile_slideonly)
+        self.assertEqual(process.IsValid(), True)
+        if self.TraceOn():
+            self.runCmd("image list")
+            self.runCmd("target mod dump sections")
+        self.assertEqual(target.GetNumModules(), 1)
+        fspec = target.GetModuleAtIndex(0).GetFileSpec()
+        self.assertEqual(fspec.GetFilename(), aout_exe_basename)
+        main_sym = target.GetModuleAtIndex(0).FindSymbol("main", lldb.eSymbolTypeAny)
+        main_addr = main_sym.GetStartAddress()
+        self.assertGreater(main_addr.GetLoadAddress(target), slide)
+        self.assertNotEqual(main_addr.GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS)
+        self.dbg.DeleteTarget(target)
+
+    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
+    @skipIf(archs=no_match(['x86_64', 'arm64', 'arm64e', 'aarch64']))
+    @skipIfRemote
+    @skipUnlessDarwin
+    def test_lc_note_main_bin_spec_os_plugin(self):
+
         self.build()
-        self.aout_exe = self.getBuildArtifact("a.out")
-        self.aout_exe_basename = "a.out"
-        self.create_corefile = self.getBuildArtifact("create-empty-corefile")
-        self.dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")
-        self.verstr_corefile = self.getBuildArtifact("verstr.core")
-        self.verstr_corefile_addr = self.getBuildArtifact("verstr-addr.core")
-        self.binspec_corefile = self.getBuildArtifact("binspec.core")
-        self.binspec_corefile_addr = self.getBuildArtifact("binspec-addr.core")
+        aout_exe = self.getBuildArtifact("a.out")
+        aout_exe_basename = "a.out"
+        create_corefile = self.getBuildArtifact("create-empty-corefile")
+        binspec_corefile_addr = self.getBuildArtifact("binspec-addr.core")
+
+        slide = 0x70000000000
+
+        ### Create our corefile
+        # 0xffffffffffffffff means load address unknown
+        call(create_corefile + " main-bin-spec " + binspec_corefile_addr + " " + aout_exe + (" 0x%x" % slide) + " 0xffffffffffffffff", shell=True)
 
         ## We can hook in our dsym-for-uuid shell script to lldb with this env
         ## var instead of requiring a defaults write.
-        os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = self.dsym_for_uuid
+        dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")
+        os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = dsym_for_uuid
+        if self.TraceOn():
+            print("Setting env var LLDB_APPLE_DSYMFORUUID_EXECUTABLE=" + dsym_for_uuid)
         self.addTearDownHook(lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None))
 
         self.runCmd("settings set target.load-script-from-symbol-file true")
         self.addTearDownHook(lambda: self.runCmd("settings set target.load-script-from-symbol-file false"))
 
-        dsym_python_dir = '%s.dSYM/Contents/Resources/Python' % (self.aout_exe)
+        dsym_python_dir = os.path.join('%s.dSYM' % aout_exe, 'Contents', 'Resources', 'Python')
         os.makedirs(dsym_python_dir)
         python_os_plugin_path = os.path.join(self.getSourceDir(),
                                              'operating_system.py')
@@ -43,14 +191,14 @@ def initial_setup(self):
                 'def __lldb_init_module(debugger, internal_dict):',
                 '  debugger.HandleCommand(\'settings set target.process.python-os-plugin-path %s\')' % python_os_plugin_path,
                 ]
-        with open(dsym_python_dir + "/a_out.py", "w") as writer:
+        with open(os.path.join(dsym_python_dir, "a_out.py"), "w") as writer:
             for l in python_init:
                 writer.write(l + '\n')
 
         dwarfdump_uuid_regex = re.compile(
             'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
         dwarfdump_cmd_output = subprocess.check_output(
-                ('/usr/bin/dwarfdump --uuid "%s"' % self.aout_exe), shell=True).decode("utf-8")
+                ('/usr/bin/dwarfdump --uuid "%s"' % aout_exe), shell=True).decode("utf-8")
         aout_uuid = None
         for line in dwarfdump_cmd_output.splitlines():
             match = dwarfdump_uuid_regex.search(line)
@@ -58,7 +206,7 @@ def initial_setup(self):
                 aout_uuid = match.group(1)
         self.assertNotEqual(aout_uuid, None, "Could not get uuid of built a.out")
 
-        ###  Create our dsym-for-uuid shell script which returns self.aout_exe
+        ###  Create our dsym-for-uuid shell script which returns aout_exe
         shell_cmds = [
                 '#! /bin/sh',
                 '# the last argument is the uuid',
@@ -78,8 +226,8 @@ def initial_setup(self):
                 '  exit 1',
                 'fi',
                 '  uuid=%s' % aout_uuid,
-                '  bin=%s' % self.aout_exe,
-                '  dsym=%s.dSYM/Contents/Resources/DWARF/%s' % (self.aout_exe, os.path.basename(self.aout_exe)),
+                '  bin=%s' % aout_exe,
+                '  dsym=%s.dSYM/Contents/Resources/DWARF/%s' % (aout_exe, os.path.basename(aout_exe)),
                 'echo "<dict><key>$uuid</key><dict>"',
                 '',
                 'echo "<key>DBGDSYMPath</key><string>$dsym</string>"',
@@ -88,30 +236,11 @@ def initial_setup(self):
                 'exit $ret'
                 ]
 
-        with open(self.dsym_for_uuid, "w") as writer:
+        with open(dsym_for_uuid, "w") as writer:
             for l in shell_cmds:
                 writer.write(l + '\n')
 
-        os.chmod(self.dsym_for_uuid, 0o755)
-
-        self.slide = 0x70000000000
-
-        ### Create our corefile
-        # 0xffffffffffffffff means load address unknown
-        retcode = call(self.create_corefile + " version-string " + self.verstr_corefile + " " + self.aout_exe + " 0xffffffffffffffff", shell=True)
-        retcode = call(self.create_corefile + " version-string " + self.verstr_corefile_addr + " " + self.aout_exe + (" 0x%x" % self.slide), shell=True)
-        retcode = call(self.create_corefile + " main-bin-spec " + self.binspec_corefile + " " + self.aout_exe + " 0xffffffffffffffff", shell=True)
-        retcode = call(self.create_corefile + " main-bin-spec " + self.binspec_corefile_addr + " " + self.aout_exe + (" 0x%x" % self.slide), shell=True)
-
-    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
-    @skipIf(archs=no_match(['x86_64']))
-    @skipUnlessDarwin
-    def test_lc_note_version_string(self):
-        self.initial_setup()
-
-        if self.TraceOn():
-            self.runCmd("log enable lldb dyld host")
-            self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
+        os.chmod(dsym_for_uuid, 0o755)
 
         ### Now run lldb on the corefile
         ### which will give us a UUID
@@ -119,135 +248,35 @@ def test_lc_note_version_string(self):
         ### which gives us a binary and dSYM
         ### which lldb should load!
 
-        # First, try the "kern ver str" corefile
-        self.target = self.dbg.CreateTarget('')
-        err = lldb.SBError()
-        if self.TraceOn():
-            self.runCmd("script print('loading corefile %s')" % self.verstr_corefile)
-        self.process = self.target.LoadCore(self.verstr_corefile)
-        self.assertEqual(self.process.IsValid(), True)
-        if self.TraceOn():
-            self.runCmd("image list")
-            self.runCmd("target mod dump sections")
-        self.assertEqual(self.target.GetNumModules(), 1)
-        fspec = self.target.GetModuleAtIndex(0).GetFileSpec()
-        self.assertEqual(fspec.GetFilename(), self.aout_exe_basename)
-        self.process.Kill()
-        self.process = None
-        self.target.Clear()
-        self.target = None
-        self.dbg.MemoryPressureDetected()
-
-        # Second, try the "kern ver str" corefile where it loads at an address
-        self.target = self.dbg.CreateTarget('')
-        err = lldb.SBError()
-        if self.TraceOn():
-            self.runCmd("script print('loading corefile %s')" % self.verstr_corefile_addr)
-        self.process = self.target.LoadCore(self.verstr_corefile_addr)
-        self.assertEqual(self.process.IsValid(), True)
-        if self.TraceOn():
-            self.runCmd("image list")
-            self.runCmd("target mod dump sections")
-        self.assertEqual(self.target.GetNumModules(), 1)
-        fspec = self.target.GetModuleAtIndex(0).GetFileSpec()
-        self.assertEqual(fspec.GetFilename(), self.aout_exe_basename)
-        main_sym = self.target.GetModuleAtIndex(0).FindSymbol("main", lldb.eSymbolTypeAny)
-        main_addr = main_sym.GetStartAddress()
-        self.assertGreater(main_addr.GetLoadAddress(self.target), self.slide)
-        self.assertNotEqual(main_addr.GetLoadAddress(self.target), lldb.LLDB_INVALID_ADDRESS)
-        self.process.Kill()
-        self.process = None
-        self.target.Clear()
-        self.target = None
-        self.dbg.MemoryPressureDetected()
-
-    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
-    @skipIf(archs=no_match(['x86_64']))
-    @skipUnlessDarwin
-    def test_lc_note_main_bin_spec(self):
-        self.initial_setup()
-
-        if self.TraceOn():
-            self.runCmd("log enable lldb dyld host")
-            self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
-
-        # Third, try the "main bin spec" corefile
-        self.target = self.dbg.CreateTarget('')
-        if self.TraceOn():
-            self.runCmd("script print('loading corefile %s')" % self.binspec_corefile)
-        self.process = self.target.LoadCore(self.binspec_corefile)
-        self.assertEqual(self.process.IsValid(), True)
-        if self.TraceOn():
-            self.runCmd("image list")
-            self.runCmd("target mod dump sections")
-        self.assertEqual(self.target.GetNumModules(), 1)
-        fspec = self.target.GetModuleAtIndex(0).GetFileSpec()
-        self.assertEqual(fspec.GetFilename(), self.aout_exe_basename)
-        self.process.Kill()
-        self.process = None
-        self.target.Clear()
-        self.target = None
-        self.dbg.MemoryPressureDetected()
-
-        # Fourth, try the "main bin spec" corefile where it loads at an address
-        self.target = self.dbg.CreateTarget('')
-        if self.TraceOn():
-            self.runCmd("script print('loading corefile %s')" % self.binspec_corefile_addr)
-        self.process = self.target.LoadCore(self.binspec_corefile_addr)
-        self.assertEqual(self.process.IsValid(), True)
-        if self.TraceOn():
-            self.runCmd("image list")
-            self.runCmd("target mod dump sections")
-        self.assertEqual(self.target.GetNumModules(), 1)
-        fspec = self.target.GetModuleAtIndex(0).GetFileSpec()
-        self.assertEqual(fspec.GetFilename(), self.aout_exe_basename)
-        main_sym = self.target.GetModuleAtIndex(0).FindSymbol("main", lldb.eSymbolTypeAny)
-        main_addr = main_sym.GetStartAddress()
-        self.assertGreater(main_addr.GetLoadAddress(self.target), self.slide)
-        self.assertNotEqual(main_addr.GetLoadAddress(self.target), lldb.LLDB_INVALID_ADDRESS)
-        self.process.Kill()
-        self.process = None
-        self.target.Clear()
-        self.target = None
-        self.dbg.MemoryPressureDetected()
-
-    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
-    @skipIf(archs=no_match(['x86_64']))
-    @skipUnlessDarwin
-    def test_lc_note_main_bin_spec_os_plugin(self):
-        self.initial_setup()
-
         if self.TraceOn():
             self.runCmd("log enable lldb dyld host")
             self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
         # Now load the binary and confirm that we load the OS plugin.
-        self.target = self.dbg.CreateTarget('')
+        target = self.dbg.CreateTarget('')
 
         if self.TraceOn():
-            self.runCmd("script print('loading corefile %s with OS plugin')" % self.binspec_corefile_addr)
-        self.process = self.target.LoadCore(self.binspec_corefile_addr)
-        self.assertEqual(self.process.IsValid(), True)
+            self.runCmd("script print('loading corefile %s with OS plugin')" % binspec_corefile_addr)
+
+        process = target.LoadCore(binspec_corefile_addr)
+        self.assertEqual(process.IsValid(), True)
         if self.TraceOn():
             self.runCmd("image list")
             self.runCmd("target mod dump sections")
             self.runCmd("thread list")
-        self.assertEqual(self.target.GetNumModules(), 1)
-        fspec = self.target.GetModuleAtIndex(0).GetFileSpec()
-        self.assertEqual(fspec.GetFilename(), self.aout_exe_basename)
+        self.assertEqual(target.GetNumModules(), 1)
+        fspec = target.GetModuleAtIndex(0).GetFileSpec()
+        self.assertEqual(fspec.GetFilename(), aout_exe_basename)
 
         # Verify our OS plug-in threads showed up
-        thread = self.process.GetThreadByID(0x111111111)
+        thread = process.GetThreadByID(0x111111111)
         self.assertTrue(thread.IsValid(), 
                 "Make sure there is a thread 0x111111111 after we load the python OS plug-in")
-        thread = self.process.GetThreadByID(0x222222222)
+        thread = process.GetThreadByID(0x222222222)
         self.assertTrue(thread.IsValid(), 
                 "Make sure there is a thread 0x222222222 after we load the python OS plug-in")
-        thread = self.process.GetThreadByID(0x333333333)
+        thread = process.GetThreadByID(0x333333333)
         self.assertTrue(thread.IsValid(), 
                 "Make sure there is a thread 0x333333333 after we load the python OS plug-in")
 
-        self.process.Kill()
-        self.process = None
-        self.target.Clear()
-        self.target = None
-        self.dbg.MemoryPressureDetected()
+        self.runCmd("settings clear target.process.python-os-plugin-path")
+        self.dbg.DeleteTarget(target)

diff  --git a/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp b/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp
index 2845fd453150e..8bd6aaabecd63 100644
--- a/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp
+++ b/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp
@@ -20,9 +20,10 @@ struct main_bin_spec_payload {
   uint32_t version;
   uint32_t type;
   uint64_t address;
+  uint64_t slide;
   uuid_t uuid;
   uint32_t log2_pagesize;
-  uint32_t unused;
+  uint32_t platform;
 };
 
 union uint32_buf {
@@ -49,33 +50,36 @@ void add_uint32(std::vector<uint8_t> &buf, uint32_t val) {
     buf.push_back(conv.bytebuf[i]);
 }
 
-std::vector<uint8_t> x86_lc_thread_load_command() {
+std::vector<uint8_t> lc_thread_load_command(cpu_type_t cputype) {
   std::vector<uint8_t> data;
-  add_uint32(data, LC_THREAD);                // thread_command.cmd
-  add_uint32(data, 184);                      // thread_command.cmdsize
-  add_uint32(data, x86_THREAD_STATE64);       // thread_command.flavor
-  add_uint32(data, x86_THREAD_STATE64_COUNT); // thread_command.count
-  add_uint64(data, 0x0000000000000000);       // rax
-  add_uint64(data, 0x0000000000000400);       // rbx
-  add_uint64(data, 0x0000000000000000);       // rcx
-  add_uint64(data, 0x0000000000000000);       // rdx
-  add_uint64(data, 0x0000000000000000);       // rdi
-  add_uint64(data, 0x0000000000000000);       // rsi
-  add_uint64(data, 0xffffff9246e2ba20);       // rbp
-  add_uint64(data, 0xffffff9246e2ba10);       // rsp
-  add_uint64(data, 0x0000000000000000);       // r8
-  add_uint64(data, 0x0000000000000000);       // r9
-  add_uint64(data, 0x0000000000000000);       // r10
-  add_uint64(data, 0x0000000000000000);       // r11
-  add_uint64(data, 0xffffff7f96ce5fe1);       // r12
-  add_uint64(data, 0x0000000000000000);       // r13
-  add_uint64(data, 0x0000000000000000);       // r14
-  add_uint64(data, 0xffffff9246e2bac0);       // r15
-  add_uint64(data, 0xffffff8015a8f6d0);       // rip
-  add_uint64(data, 0x0000000000011111);       // rflags
-  add_uint64(data, 0x0000000000022222);       // cs
-  add_uint64(data, 0x0000000000033333);       // fs
-  add_uint64(data, 0x0000000000044444);       // gs
+  // Emit an LC_THREAD register context appropriate for the cputype
+  // of the binary we're embedded.  The tests in this case do not
+  // use the register values, so 0's are fine, lldb needs to see at
+  // least one LC_THREAD in the corefile.
+#if defined(__x86_64__)
+  if (cputype == CPU_TYPE_X86_64) {
+    add_uint32(data, LC_THREAD); // thread_command.cmd
+    add_uint32(data,
+               16 + (x86_THREAD_STATE64_COUNT * 4)); // thread_command.cmdsize
+    add_uint32(data, x86_THREAD_STATE64);            // thread_command.flavor
+    add_uint32(data, x86_THREAD_STATE64_COUNT);      // thread_command.count
+    for (int i = 0; i < x86_THREAD_STATE64_COUNT; i++) {
+      add_uint32(data, 0); // whatever, just some empty register values
+    }
+  }
+#endif
+#if defined(__arm64__) || defined(__aarch64__)
+  if (cputype == CPU_TYPE_ARM64) {
+    add_uint32(data, LC_THREAD); // thread_command.cmd
+    add_uint32(data,
+               16 + (ARM_THREAD_STATE64_COUNT * 4)); // thread_command.cmdsize
+    add_uint32(data, ARM_THREAD_STATE64);            // thread_command.flavor
+    add_uint32(data, ARM_THREAD_STATE64_COUNT);      // thread_command.count
+    for (int i = 0; i < ARM_THREAD_STATE64_COUNT; i++) {
+      add_uint32(data, 0); // whatever, just some empty register values
+    }
+  }
+#endif
   return data;
 }
 
@@ -121,7 +125,8 @@ void add_lc_note_kern_ver_str_load_command(
 
 void add_lc_note_main_bin_spec_load_command(
     std::vector<std::vector<uint8_t>> &loadcmds, std::vector<uint8_t> &payload,
-    int payload_file_offset, std::string uuidstr, uint64_t address) {
+    int payload_file_offset, std::string uuidstr, uint64_t address,
+    uint64_t slide) {
   std::vector<uint8_t> loadcmd_data;
 
   add_uint32(loadcmd_data, LC_NOTE); // note_command.cmd
@@ -145,15 +150,16 @@ void add_lc_note_main_bin_spec_load_command(
   loadcmds.push_back(loadcmd_data);
 
   // Now write the "main bin spec" payload.
-  add_uint32(payload, 1);          // version
+  add_uint32(payload, 2);          // version
   add_uint32(payload, 3);          // type == 3 [ firmware, standalone, etc ]
   add_uint64(payload, address);    // load address
+  add_uint64(payload, slide);      // slide
   uuid_t uuid;
   uuid_parse(uuidstr.c_str(), uuid);
   for (int i = 0; i < sizeof(uuid_t); i++)
     payload.push_back(uuid[i]);
   add_uint32(payload, 0); // log2_pagesize unspecified
-  add_uint32(payload, 0); // unused
+  add_uint32(payload, 0); // platform unspecified
 }
 
 void add_lc_segment(std::vector<std::vector<uint8_t>> &loadcmds,
@@ -179,7 +185,8 @@ void add_lc_segment(std::vector<std::vector<uint8_t>> &loadcmds,
   loadcmds.push_back(loadcmd_data);
 }
 
-std::string get_uuid_from_binary(const char *fn) {
+std::string get_uuid_from_binary(const char *fn, cpu_type_t &cputype,
+                                 cpu_subtype_t &cpusubtype) {
   FILE *f = fopen(fn, "r");
   if (f == nullptr) {
     fprintf(stderr, "Unable to open binary '%s' to get uuid\n", fn);
@@ -213,9 +220,9 @@ std::string get_uuid_from_binary(const char *fn) {
       fprintf(stderr, "error reading mach header from input file\n");
       exit(1);
     }
-    if (mh.cputype != CPU_TYPE_X86_64) {
+    if (mh.cputype != CPU_TYPE_X86_64 && mh.cputype != CPU_TYPE_ARM64) {
       fprintf(stderr,
-              "This tool creates an x86_64 corefile but "
+              "This tool creates an x86_64/arm64 corefile but "
               "the supplied binary '%s' is cputype 0x%x\n",
               fn, (uint32_t)mh.cputype);
       exit(1);
@@ -223,15 +230,17 @@ std::string get_uuid_from_binary(const char *fn) {
     num_of_load_cmds = mh.ncmds;
     size_of_load_cmds = mh.sizeofcmds;
     file_offset += sizeof(struct mach_header);
+    cputype = mh.cputype;
+    cpusubtype = mh.cpusubtype;
   } else {
     struct mach_header_64 mh;
     if (::fread(&mh, 1, sizeof(mh), f) != sizeof(mh)) {
       fprintf(stderr, "error reading mach header from input file\n");
       exit(1);
     }
-    if (mh.cputype != CPU_TYPE_X86_64) {
+    if (mh.cputype != CPU_TYPE_X86_64 && mh.cputype != CPU_TYPE_ARM64) {
       fprintf(stderr,
-              "This tool creates an x86_64 corefile but "
+              "This tool creates an x86_64/arm64 corefile but "
               "the supplied binary '%s' is cputype 0x%x\n",
               fn, (uint32_t)mh.cputype);
       exit(1);
@@ -239,6 +248,8 @@ std::string get_uuid_from_binary(const char *fn) {
     num_of_load_cmds = mh.ncmds;
     size_of_load_cmds = mh.sizeofcmds;
     file_offset += sizeof(struct mach_header_64);
+    cputype = mh.cputype;
+    cpusubtype = mh.cpusubtype;
   }
 
   off_t load_cmds_offset = file_offset;
@@ -269,12 +280,15 @@ std::string get_uuid_from_binary(const char *fn) {
 }
 
 int main(int argc, char **argv) {
-  if (argc != 5) {
-    fprintf(stderr,
-            "usage: create-empty-corefile version-string|main-bin-spec "
-            "<output-core-name> <binary-to-copy-uuid-from> <address>\n");
+  if (argc != 6) {
+    fprintf(
+        stderr,
+        "usage: create-empty-corefile version-string|main-bin-spec "
+        "<output-core-name> <binary-to-copy-uuid-from> <address> <slide>\n");
     fprintf(stderr,
             "     <address> is base 16, 0xffffffffffffffff means unknown\n");
+    fprintf(stderr,
+            "     <slide> is base 16, 0xffffffffffffffff means unknown\n");
     fprintf(
         stderr,
         "Create a Mach-O corefile with an either LC_NOTE 'kern ver str' or \n");
@@ -289,7 +303,9 @@ int main(int argc, char **argv) {
     exit(1);
   }
 
-  std::string uuid = get_uuid_from_binary(argv[3]);
+  cpu_type_t cputype;
+  cpu_subtype_t cpusubtype;
+  std::string uuid = get_uuid_from_binary(argv[3], cputype, cpusubtype);
 
   // An array of load commands (in the form of byte arrays)
   std::vector<std::vector<uint8_t>> load_commands;
@@ -304,15 +320,22 @@ int main(int argc, char **argv) {
     exit(1);
   }
 
+  errno = 0;
+  uint64_t slide = strtoull(argv[5], NULL, 16);
+  if (errno != 0) {
+    fprintf(stderr, "Unable to parse slide %s as base 16", argv[4]);
+    exit(1);
+  }
+
   // First add all the load commands / payload so we can figure out how large
   // the load commands will actually be.
-  load_commands.push_back(x86_lc_thread_load_command());
+  load_commands.push_back(lc_thread_load_command(cputype));
   if (strcmp(argv[1], "version-string") == 0)
     add_lc_note_kern_ver_str_load_command(load_commands, payload, 0, uuid,
                                           address);
   else
     add_lc_note_main_bin_spec_load_command(load_commands, payload, 0, uuid,
-                                           address);
+                                           address, slide);
   add_lc_segment(load_commands, payload, 0);
 
   int size_of_load_commands = 0;
@@ -327,22 +350,22 @@ int main(int argc, char **argv) {
   load_commands.clear();
   payload.clear();
 
-  load_commands.push_back(x86_lc_thread_load_command());
+  load_commands.push_back(lc_thread_load_command(cputype));
 
   if (strcmp(argv[1], "version-string") == 0)
     add_lc_note_kern_ver_str_load_command(
         load_commands, payload, header_and_load_cmd_room, uuid, address);
   else
     add_lc_note_main_bin_spec_load_command(
-        load_commands, payload, header_and_load_cmd_room, uuid, address);
+        load_commands, payload, header_and_load_cmd_room, uuid, address, slide);
 
   add_lc_segment(load_commands, payload, header_and_load_cmd_room);
 
   struct mach_header_64 mh;
   mh.magic = MH_MAGIC_64;
-  mh.cputype = CPU_TYPE_X86_64;
+  mh.cputype = cputype;
 
-  mh.cpusubtype = CPU_SUBTYPE_X86_64_ALL;
+  mh.cpusubtype = cpusubtype;
   mh.filetype = MH_CORE;
   mh.ncmds = load_commands.size();
   mh.sizeofcmds = size_of_load_commands;


        


More information about the lldb-commits mailing list