Upstream macCatalyst support in debugserver and the macOS dynamic loader
authorAdrian Prantl <aprantl@apple.com>
Wed, 4 Sep 2019 17:23:15 +0000 (17:23 +0000)
committerAdrian Prantl <aprantl@apple.com>
Wed, 4 Sep 2019 17:23:15 +0000 (17:23 +0000)
plugin.

Unfortunately the test is currently XFAILed because of missing changes
to the clang driver.

Differential Revision: https://reviews.llvm.org/D67124

llvm-svn: 370931

21 files changed:
lldb/include/lldb/Core/Module.h
lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
lldb/include/lldb/Target/Process.h
lldb/packages/Python/lldbsuite/test/macosx/macabi/Makefile [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/macosx/macabi/TestMacABImacOSFramework.py [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/macosx/macabi/dylib.mk [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.c [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.h [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/macosx/macabi/main.c [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/make/Makefile.rules
lldb/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py
lldb/source/Core/Module.cpp
lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/tools/debugserver/source/MacOSX/MachProcess.mm

index bc57906..146bbe8 100644 (file)
@@ -895,6 +895,9 @@ public:
   bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const;
   bool RemapSourceFile(const char *, std::string &) const = delete;
 
+  /// Update the ArchSpec to a more specific variant.
+  bool MergeArchitecture(const ArchSpec &arch_spec);
+
   /// \class LookupInfo Module.h "lldb/Core/Module.h"
   /// A class that encapsulates name lookup information.
   ///
index d49e27a..217ca5b 100644 (file)
@@ -27,6 +27,7 @@ private:
 
 public:
   static llvm::VersionTuple GetOSVersion();
+  static llvm::VersionTuple GetMacCatalystVersion();
   static bool GetOSBuildString(std::string &s);
   static bool GetOSKernelDescription(std::string &s);
   static FileSpec GetProgramFileSpec();
index 9bc9e4a..f91e492 100644 (file)
@@ -1196,6 +1196,9 @@ public:
   ///     VersionTuple is returner.
   virtual llvm::VersionTuple GetHostOSVersion() { return llvm::VersionTuple(); }
 
+  /// \return the macCatalyst version of the host OS.
+  virtual llvm::VersionTuple GetHostMacCatalystVersion() { return {}; }
+
   /// Get the target object pointer for this module.
   ///
   /// \return
diff --git a/lldb/packages/Python/lldbsuite/test/macosx/macabi/Makefile b/lldb/packages/Python/lldbsuite/test/macosx/macabi/Makefile
new file mode 100644 (file)
index 0000000..f035d91
--- /dev/null
@@ -0,0 +1,18 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+LD_EXTRAS := -L. -lfoo
+
+TRIPLE := x86_64-apple-ios13.0-macabi
+CFLAGS_EXTRAS := -target $(TRIPLE)
+
+all: libfoo.dylib a.out
+
+lib%.dylib: %.c
+       $(MAKE) MAKE_DSYM=YES CC=$(CC) \
+               ARCH=$(ARCH) DSYMUTIL=$(DSYMUTIL) \
+               BASENAME=$(shell basename $< .c) \
+               TRIPLE=x86_64-apple-macosx10.15 SDKROOT=$(SDKROOT) \
+               VPATH=$(SRCDIR) -I $(SRCDIR) -f $(SRCDIR)/dylib.mk all
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/macosx/macabi/TestMacABImacOSFramework.py b/lldb/packages/Python/lldbsuite/test/macosx/macabi/TestMacABImacOSFramework.py
new file mode 100644 (file)
index 0000000..23b2677
--- /dev/null
@@ -0,0 +1,28 @@
+# TestMacABImacOSFramework.py
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import os
+import unittest2
+
+
+class TestMacABImacOSFramework(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipIf(macos_version=["<", "10.15"])
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    # There is a Clang driver change missing on llvm.org.
+    @expectedFailureAll(bugnumber="rdar://problem/54986190>")
+    def test_macabi(self):
+        """Test the x86_64-apple-ios-macabi target linked against a macos dylib"""
+        self.build()
+        lldbutil.run_to_source_breakpoint(self, "break here",
+                                          lldb.SBFileSpec('main.c'))
+        self.expect("image list -t -b",
+                    patterns=["x86_64.*-apple-ios.*-macabi a\.out",
+                              "x86_64.*-apple-macosx.* libfoo.dylib[^(]"])
+        self.expect("fr v s", "Hello MacABI")
+        self.expect("p s", "Hello MacABI")
diff --git a/lldb/packages/Python/lldbsuite/test/macosx/macabi/dylib.mk b/lldb/packages/Python/lldbsuite/test/macosx/macabi/dylib.mk
new file mode 100644 (file)
index 0000000..6f2c17a
--- /dev/null
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+DYLIB_ONLY := YES
+DYLIB_NAME := $(BASENAME)
+DYLIB_C_SOURCES := $(DYLIB_NAME).c
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.c b/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.c
new file mode 100644 (file)
index 0000000..9c29d59
--- /dev/null
@@ -0,0 +1,8 @@
+#include "foo.h"
+
+void stop() {}
+
+int foo() {
+  stop();
+  return 0;
+}
diff --git a/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.h b/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.h
new file mode 100644 (file)
index 0000000..5d5f8f0
--- /dev/null
@@ -0,0 +1 @@
+int foo();
diff --git a/lldb/packages/Python/lldbsuite/test/macosx/macabi/main.c b/lldb/packages/Python/lldbsuite/test/macosx/macabi/main.c
new file mode 100644 (file)
index 0000000..92069d9
--- /dev/null
@@ -0,0 +1,5 @@
+#include "foo.h"
+int main() {
+  const char *s = "Hello MacABI!";
+  return foo(); // break here
+}
index ecfed7e..784307b 100644 (file)
@@ -88,6 +88,7 @@ ifneq "$(TRIPLE)" ""
        triple_os_and_version =$(shell echo $(word 3, $(triple_space)) | sed 's/\([a-z]*\)\(.*\)/\1 \2/')
        TRIPLE_OS =$(word 1, $(triple_os_and_version))
        TRIPLE_VERSION =$(word 2, $(triple_os_and_version))
+       TRIPLE_ENV =$(word 4, $(triple_space))
        ifeq "$(TRIPLE_VENDOR)" "apple"
                ifeq "$(TRIPLE_OS)" "ios"
                        CODESIGN := codesign
@@ -100,11 +101,19 @@ ifneq "$(TRIPLE)" ""
                                        endif
                                        ARCH_CFLAGS :=-mios-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
                                else
-                                       SDKROOT = $(shell xcrun --sdk iphonesimulator --show-sdk-path)
+                                       ifeq "$(TRIPLE_ENV)" "macabi"
+                                               SDKROOT = $(shell xcrun --sdk macosx --show-sdk-path)
+                                       else
+                                               SDKROOT = $(shell xcrun --sdk iphonesimulator --show-sdk-path)
+                                       endif
                                        ifeq "$(TRIPLE_VERSION)" ""
                                                TRIPLE_VERSION =$(shell echo $(notdir $(SDKROOT)) | sed -e 's/.*\([0-9]\.[0-9]\).*/\1/')
                                        endif
-                                       ARCH_CFLAGS :=-mios-simulator-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
+                                       ifeq "$(TRIPLE_ENV)" "macabi"
+                                               ARCH_CFLAGS :=-mios-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
+                                       else
+                                               ARCH_CFLAGS :=-mios-simulator-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
+                                       endif
                                endif
                        endif
                endif
index 464cdce..832096a 100644 (file)
@@ -24,6 +24,7 @@ class TestGdbRemoteHostInfo(GdbRemoteTestCaseBase):
         "os_build",
         "os_kernel",
         "os_version",
+        "maccatalyst_version",
         "ptrsize",
         "triple",
         "vendor",
index c0dea3e..491ce93 100644 (file)
@@ -1634,6 +1634,26 @@ bool Module::RemapSourceFile(llvm::StringRef path,
   return m_source_mappings.RemapPath(path, new_path);
 }
 
+bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
+  if (!arch_spec.IsValid())
+    return false;
+  LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES),
+           "module has arch %s, merging/replacing with arch %s",
+           m_arch.GetTriple().getTriple().c_str(),
+           arch_spec.GetTriple().getTriple().c_str());
+  if (!m_arch.IsCompatibleMatch(arch_spec)) {
+    // The new architecture is different, we just need to replace it.
+    return SetArchitecture(arch_spec);
+  }
+
+  // Merge bits from arch_spec into "merged_arch" and set our architecture.
+  ArchSpec merged_arch(m_arch);
+  merged_arch.MergeFrom(arch_spec);
+  // SetArchitecture() is a no-op if m_arch is already valid.
+  m_arch = ArchSpec();
+  return SetArchitecture(merged_arch);
+}
+
 llvm::VersionTuple Module::GetVersion() {
   if (ObjectFile *obj_file = GetObjectFile())
     return obj_file->GetVersion();
index 506c722..3f3f301 100644 (file)
@@ -71,23 +71,32 @@ bool HostInfoMacOSX::GetOSKernelDescription(std::string &s) {
   return false;
 }
 
+static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
+  @autoreleasepool {
+    NSDictionary *version_info =
+      [NSDictionary dictionaryWithContentsOfFile:
+       @"/System/Library/CoreServices/SystemVersion.plist"];
+    NSString *version_value = [version_info objectForKey: Key];
+    const char *version_str = [version_value UTF8String];
+    version.tryParse(version_str);
+  }
+}
+
 llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
   static llvm::VersionTuple g_version;
+  if (g_version.empty())
+    ParseOSVersion(g_version, @"ProductVersion");
+  return g_version;
+}
 
-  if (g_version.empty()) {
-    @autoreleasepool {
-      NSDictionary *version_info = [NSDictionary
-          dictionaryWithContentsOfFile:
-              @"/System/Library/CoreServices/SystemVersion.plist"];
-      NSString *version_value = [version_info objectForKey:@"ProductVersion"];
-      const char *version_str = [version_value UTF8String];
-      g_version.tryParse(version_str);
-    }
-  }
-
+llvm::VersionTuple HostInfoMacOSX::GetMacCatalystVersion() {
+  static llvm::VersionTuple g_version;
+  if (g_version.empty())
+    ParseOSVersion(g_version, @"iOSSupportVersion");
   return g_version;
 }
 
+
 FileSpec HostInfoMacOSX::GetProgramFileSpec() {
   static FileSpec g_program_filespec;
   if (!g_program_filespec) {
index 61afe51..9ec4ae0 100644 (file)
@@ -100,6 +100,18 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
   const ModuleList &target_images = target.GetImages();
   ModuleSpec module_spec(image_info.file_spec);
   module_spec.GetUUID() = image_info.uuid;
+
+  // macCatalyst support: Request matching os/environment.
+  {
+    auto &target_triple = target.GetArchitecture().GetTriple();
+    if (target_triple.getOS() == llvm::Triple::IOS &&
+        target_triple.getEnvironment() == llvm::Triple::MacABI) {
+      // Request the macCatalyst variant of frameworks that have both
+      // a PLATFORM_MACOS and a PLATFORM_MACCATALYST load command.
+      module_spec.GetArchitecture() = ArchSpec(target_triple);
+    }
+  }
+
   ModuleSP module_sp(target_images.FindFirstModule(module_spec));
 
   if (module_sp && !module_spec.GetUUID().IsValid() &&
@@ -384,6 +396,10 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
         image_infos[i].os_type = llvm::Triple::WatchOS;
       // NEED_BRIDGEOS_TRIPLE else if (os_name == "bridgeos")
       // NEED_BRIDGEOS_TRIPLE   image_infos[i].os_type = llvm::Triple::BridgeOS;
+      else if (os_name == "maccatalyst") {
+        image_infos[i].os_type = llvm::Triple::IOS;
+        image_infos[i].os_env = llvm::Triple::MacABI;
+      }
     }
     if (image->HasKey("min_version_os_sdk")) {
       image_infos[i].min_version_os_sdk =
@@ -654,6 +670,20 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
         target_images.AppendIfNeeded(image_module_sp);
         loaded_module_list.AppendIfNeeded(image_module_sp);
       }
+
+      // macCataylst support:
+      // Update the module's platform with the DYLD info.
+      ArchSpec dyld_spec = image_infos[idx].GetArchitecture();
+      if (dyld_spec.GetTriple().getOS() == llvm::Triple::IOS &&
+          dyld_spec.GetTriple().getEnvironment() == llvm::Triple::MacABI) {
+        image_module_sp->MergeArchitecture(dyld_spec);
+        const auto &target_triple = target.GetArchitecture().GetTriple();
+        // If dyld reports the process as being loaded as MACCATALYST,
+        // force-update the target's architecture to MACCATALYST.
+        if (!(target_triple.getOS() == llvm::Triple::IOS &&
+              target_triple.getEnvironment() == llvm::Triple::MacABI))
+          target.SetArchitecture(dyld_spec);
+      }
     }
   }
 
@@ -711,6 +741,20 @@ void DynamicLoaderDarwin::Segment::PutToLog(Log *log,
   }
 }
 
+lldb_private::ArchSpec DynamicLoaderDarwin::ImageInfo::GetArchitecture() const {
+  // Update the module's platform with the DYLD info.
+  lldb_private::ArchSpec arch_spec(lldb_private::eArchTypeMachO, header.cputype,
+                                   header.cpusubtype);
+  if (os_type == llvm::Triple::IOS && os_env == llvm::Triple::MacABI) {
+    llvm::Triple triple(llvm::Twine("x86_64-apple-ios") + min_version_os_sdk +
+                        "-macabi");
+    ArchSpec maccatalyst_spec(triple);
+    if (arch_spec.IsCompatibleMatch(maccatalyst_spec))
+      arch_spec.MergeFrom(maccatalyst_spec);
+  }
+  return arch_spec;
+}
+
 const DynamicLoaderDarwin::Segment *
 DynamicLoaderDarwin::ImageInfo::FindSegment(ConstString name) const {
   const size_t num_segments = segments.size();
index aac0a5d..f2c78d4 100644 (file)
@@ -95,25 +95,34 @@ protected:
   };
 
   struct ImageInfo {
-    lldb::addr_t address;  // Address of mach header for this dylib
-    lldb::addr_t slide;    // The amount to slide all segments by if there is a
-                           // global slide.
-    lldb::addr_t mod_date; // Modification date for this dylib
-    lldb_private::FileSpec file_spec; // Resolved path for this dylib
-    lldb_private::UUID
-        uuid; // UUID for this dylib if it has one, else all zeros
-    llvm::MachO::mach_header header; // The mach header for this image
-    std::vector<Segment> segments;   // All segment vmaddr and vmsize pairs for
-                                   // this executable (from memory of inferior)
-    uint32_t load_stop_id; // The process stop ID that the sections for this
-                           // image were loaded
-    llvm::Triple::OSType os_type;   // LC_VERSION_MIN_... load command os type
-    std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
-
-    ImageInfo()
-        : address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
-          uuid(), header(), segments(), load_stop_id(0),
-          os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
+    /// Address of mach header for this dylib.
+    lldb::addr_t address = LLDB_INVALID_ADDRESS;
+    /// The amount to slide all segments by if there is a global
+    /// slide.
+    lldb::addr_t slide = 0;
+    /// Modification date for this dylib.
+    lldb::addr_t mod_date = 0;
+    /// Resolved path for this dylib.
+    lldb_private::FileSpec file_spec;
+    /// UUID for this dylib if it has one, else all zeros.
+    lldb_private::UUID uuid;
+    /// The mach header for this image.
+    llvm::MachO::mach_header header;
+    /// All segment vmaddr and vmsize pairs for this executable (from
+    /// memory of inferior).
+    std::vector<Segment> segments;
+    /// The process stop ID that the sections for this image were
+    /// loaded.
+    uint32_t load_stop_id = 0;
+    /// LC_VERSION_MIN_... load command os type.
+    llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS;
+    /// LC_VERSION_MIN_... load command os environment.
+    llvm::Triple::EnvironmentType os_env =
+        llvm::Triple::EnvironmentType::UnknownEnvironment;
+    /// LC_VERSION_MIN_... SDK.
+    std::string min_version_os_sdk;
+
+    ImageInfo() = default;
 
     void Clear(bool load_cmd_data_only) {
       if (!load_cmd_data_only) {
@@ -127,6 +136,7 @@ protected:
       segments.clear();
       load_stop_id = 0;
       os_type = llvm::Triple::OSType::UnknownOS;
+      os_env = llvm::Triple::EnvironmentType::UnknownEnvironment;
       min_version_os_sdk.clear();
     }
 
@@ -135,7 +145,8 @@ protected:
              mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
              uuid == rhs.uuid &&
              memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
-             segments == rhs.segments && os_type == rhs.os_type;
+             segments == rhs.segments && os_type == rhs.os_type &&
+             os_env == rhs.os_env;
     }
 
     bool UUIDValid() const { return uuid.IsValid(); }
@@ -150,10 +161,7 @@ protected:
       return 0;
     }
 
-    lldb_private::ArchSpec GetArchitecture() const {
-      return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
-                                    header.cputype, header.cpusubtype);
-    }
+    lldb_private::ArchSpec GetArchitecture() const;
 
     const Segment *FindSegment(lldb_private::ConstString name) const;
 
index b00ecd7..40a88fb 100644 (file)
@@ -931,6 +931,11 @@ llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
   return m_os_version;
 }
 
+llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
+  GetHostInfo();
+  return m_maccatalyst_version;
+}
+
 bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
   if (GetHostInfo()) {
     if (!m_os_build.empty()) {
@@ -1133,6 +1138,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
         uint32_t sub = 0;
         std::string arch_name;
         std::string os_name;
+        std::string environment;
         std::string vendor_name;
         std::string triple;
         std::string distribution_id;
@@ -1172,7 +1178,11 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
             extractor.GetHexByteString(m_os_kernel);
             ++num_keys_decoded;
           } else if (name.equals("ostype")) {
-            os_name = value;
+            if (value.equals("maccatalyst")) {
+              os_name = "ios";
+              environment = "macabi";
+            } else
+              os_name = value;
             ++num_keys_decoded;
           } else if (name.equals("vendor")) {
             vendor_name = value;
@@ -1196,6 +1206,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
           {
             if (!m_os_version.tryParse(value))
               ++num_keys_decoded;
+          } else if (name.equals("maccatalyst_version")) {
+            if (!m_maccatalyst_version.tryParse(value))
+              ++num_keys_decoded;
           } else if (name.equals("watchpoint_exceptions_received")) {
             m_watchpoints_trigger_after_instruction =
                 llvm::StringSwitch<LazyBool>(value)
@@ -1233,6 +1246,8 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
                     llvm::StringRef(vendor_name));
               if (!os_name.empty())
                 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+              if (!environment.empty())
+                m_host_arch.GetTriple().setEnvironmentName(environment);
             }
           } else {
             std::string triple;
@@ -1985,6 +2000,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
       uint32_t sub = 0;
       std::string arch_name;
       std::string os_name;
+      std::string environment;
       std::string vendor_name;
       std::string triple;
       std::string elf_abi;
@@ -2005,7 +2021,11 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
           extractor.GetHexByteString(triple);
           ++num_keys_decoded;
         } else if (name.equals("ostype")) {
-          os_name = value;
+          if (value.equals("maccatalyst")) {
+            os_name = "ios";
+            environment = "macabi";
+          } else
+            os_name = value;
           ++num_keys_decoded;
         } else if (name.equals("vendor")) {
           vendor_name = value;
@@ -2046,6 +2066,8 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
       } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
                  !vendor_name.empty()) {
         llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
+        if (!environment.empty())
+            triple.setEnvironmentName(environment);
 
         assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
         assert(triple.getObjectFormat() != llvm::Triple::Wasm);
@@ -2077,8 +2099,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
         }
         m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
         m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+        m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
         m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
         m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+        m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
       }
       return true;
     }
index de85c9f..daee680 100644 (file)
@@ -248,6 +248,8 @@ public:
 
   llvm::VersionTuple GetOSVersion();
 
+  llvm::VersionTuple GetMacCatalystVersion();
+
   bool GetOSBuildString(std::string &s);
 
   bool GetOSKernelDescription(std::string &s);
@@ -548,6 +550,7 @@ protected:
   ArchSpec m_host_arch;
   ArchSpec m_process_arch;
   llvm::VersionTuple m_os_version;
+  llvm::VersionTuple m_maccatalyst_version;
   std::string m_os_build;
   std::string m_os_kernel;
   std::string m_hostname;
index 7c84bf4..d0ae519 100644 (file)
@@ -260,6 +260,15 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
     response.PutChar(';');
   }
 
+#if defined(__APPLE__)
+  llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();
+  if (!maccatalyst_version.empty()) {
+    response.Format("maccatalyst_version:{0}",
+                    maccatalyst_version.getAsString());
+    response.PutChar(';');
+  }
+#endif
+
   std::string s;
   if (HostInfo::GetOSBuildString(s)) {
     response.PutCString("os_build:");
index 69bcd8a..fee7b3f 100644 (file)
@@ -4320,6 +4320,10 @@ llvm::VersionTuple ProcessGDBRemote::GetHostOSVersion() {
   return m_gdb_comm.GetOSVersion();
 }
 
+llvm::VersionTuple ProcessGDBRemote::GetHostMacCatalystVersion() {
+  return m_gdb_comm.GetMacCatalystVersion();
+}
+
 namespace {
 
 typedef std::vector<std::string> stringVec;
index 1411469..84004c1 100644 (file)
@@ -199,6 +199,7 @@ public:
                            const llvm::Triple &triple) override;
 
   llvm::VersionTuple GetHostOSVersion() override;
+  llvm::VersionTuple GetHostMacCatalystVersion() override;
 
   llvm::Error LoadModules() override;
 
index a53ac9d..652a531 100644 (file)
@@ -762,12 +762,16 @@ bool MachProcess::GetMachOInformationFromMemory(
     uint32_t major_version, minor_version, patch_version;
     if (const char *lc_platform = GetDeploymentInfo(
             lc, load_cmds_p, major_version, minor_version, patch_version)) {
-      // APPLE INTERNAL: macCatalyst support
+      // macCatalyst support.
+      //
       // This handles two special cases:
-      // 1. Zippered frameworks have two deployment info load commands.
-      //    Make sure to select the requested one.
-      // 2. The xctest binary is a pure macOS binary but is launched with
-      //    DYLD_FORCE_PLATFORM=6.
+      //
+      // 1. Frameworks that have both a PLATFORM_MACOS and a
+      //    PLATFORM_MACCATALYST load command.  Make sure to select
+      //    the requested one.
+      //
+      // 2. The xctest binary is a pure macOS binary but is launched
+      //    with DYLD_FORCE_PLATFORM=6.
       if (dyld_platform == PLATFORM_MACCATALYST &&
           inf.mach_header.filetype == MH_EXECUTE &&
           inf.min_version_os_name.empty() &&
@@ -782,10 +786,12 @@ bool MachProcess::GetMachOInformationFromMemory(
         inf.min_version_os_version = GetMacCatalystVersionString();
       } else if (dyld_platform != PLATFORM_MACCATALYST &&
                  inf.min_version_os_name == "macosx") {
-        // This is a zippered binary and the process is not running as
-        // PLATFORM_MACCATALYST. Stick with the macosx load command
-        // that we've already processed, ignore this one, which is
-        // presumed to be a PLATFORM_MACCATALYST one.
+        // This is a binary with both PLATFORM_MACOS and
+        // PLATFORM_MACCATALYST load commands and the process is not
+        // running as PLATFORM_MACCATALYST. Stick with the
+        // "macosx" load command that we've already processed,
+        // ignore this one, which is presumed to be a
+        // PLATFORM_MACCATALYST one.
       } else {
         inf.min_version_os_name = lc_platform;
         inf.min_version_os_version = "";