[Lldb-commits] [lldb] 116b103 - Revert "Revert "Improve the detection of iOS/tvOS/watchOS simulator binaries in""

Adrian Prantl via lldb-commits lldb-commits at lists.llvm.org
Wed Jul 1 11:06:37 PDT 2020


Author: Adrian Prantl
Date: 2020-07-01T11:06:15-07:00
New Revision: 116b1033738f9a409e502e270dbf1c9e04f5b1ad

URL: https://github.com/llvm/llvm-project/commit/116b1033738f9a409e502e270dbf1c9e04f5b1ad
DIFF: https://github.com/llvm/llvm-project/commit/116b1033738f9a409e502e270dbf1c9e04f5b1ad.diff

LOG: Revert "Revert "Improve the detection of iOS/tvOS/watchOS simulator binaries in""

This reverts commit 98c3a38a1967ece4e70891aa188c51e29ca0f8d3.

Added: 
    

Modified: 
    lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
    lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
    lldb/tools/debugserver/source/DNB.cpp
    lldb/tools/debugserver/source/MacOSX/MachProcess.h
    lldb/tools/debugserver/source/MacOSX/MachProcess.mm

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 6f3e8b637cf2..7b0d6f343c03 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -681,11 +681,16 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
         loaded_module_list.AppendIfNeeded(image_module_sp);
       }
 
-      // macCatalyst support:
-      // Update the module's platform with the DYLD info.
+      // To support macCatalyst and legacy iOS simulator,
+      // 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)
+      auto &dyld_triple = dyld_spec.GetTriple();
+      if ((dyld_triple.getEnvironment() == llvm::Triple::MacABI &&
+           dyld_triple.getOS() == llvm::Triple::IOS) ||
+          (dyld_triple.getEnvironment() == llvm::Triple::Simulator &&
+           (dyld_triple.getOS() == llvm::Triple::IOS ||
+            dyld_triple.getOS() == llvm::Triple::TvOS ||
+            dyld_triple.getOS() == llvm::Triple::WatchOS)))
         image_module_sp->MergeArchitecture(dyld_spec);
     }
   }
@@ -748,13 +753,23 @@ 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");
+  if (os_env == llvm::Triple::MacABI && os_type == llvm::Triple::IOS) {
+    llvm::Triple triple(llvm::Twine(arch_spec.GetArchitectureName()) +
+                        "-apple-ios" + min_version_os_sdk + "-macabi");
     ArchSpec maccatalyst_spec(triple);
     if (arch_spec.IsCompatibleMatch(maccatalyst_spec))
       arch_spec.MergeFrom(maccatalyst_spec);
   }
+  if (os_env == llvm::Triple::Simulator &&
+      (os_type == llvm::Triple::IOS || os_type == llvm::Triple::TvOS ||
+       os_type == llvm::Triple::WatchOS)) {
+    llvm::Triple triple(llvm::Twine(arch_spec.GetArchitectureName()) +
+                        "-apple-" + llvm::Triple::getOSTypeName(os_type) +
+                        min_version_os_sdk + "-simulator");
+    ArchSpec sim_spec(triple);
+    if (arch_spec.IsCompatibleMatch(sim_spec))
+      arch_spec.MergeFrom(sim_spec);
+  }
   return arch_spec;
 }
 

diff  --git a/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py b/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
index 4cc7ea6b8656..c12e920e3b82 100644
--- a/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
+++ b/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
@@ -12,10 +12,23 @@ class TestSimulatorPlatformLaunching(TestBase):
     mydir = TestBase.compute_mydir(__file__)
     NO_DEBUG_INFO_TESTCASE = True
 
-    def run_with(self, arch, platform, os, env):
-        self.build(dictionary={'TRIPLE': arch+'-apple-'+os+'-'+env, 'ARCH': arch})
+    def check_load_commands(self, expected_load_command):
+        """sanity check the built binary for the expected number of load commands"""
+        load_cmds = subprocess.check_output(
+            ['otool', '-l', self.getBuildArtifact()]
+        ).decode("utf-8")
+        found = 0
+        for line in load_cmds.split('\n'):
+            if expected_load_command in line:
+              found += 1
+        self.assertEquals(found, 1, "wrong load command")
+
+
+    def run_with(self, arch, os, env, expected_load_command):
+        self.build(dictionary={'TRIPLE': arch+'-apple-'+os+'-'+env})
         lldbutil.run_to_source_breakpoint(self, "break here",
                                           lldb.SBFileSpec("hello.c"))
+        self.check_load_commands(expected_load_command)
         self.expect('image list -b -t',
                     patterns=['a\.out '+arch+'-apple-'+os+'.*-'+env])
 
@@ -26,7 +39,7 @@ def test_ios(self):
         """Test running an iOS simulator binary"""
         self.run_with(arch=self.getArchitecture(),
                       os='ios', env='simulator',
-                      platform='iphonesimulator')
+                      expected_load_command='LC_BUILD_VERSION')
 
     @skipUnlessDarwin
     @skipIfDarwinEmbedded
@@ -35,13 +48,101 @@ def test_tvos(self):
         """Test running an tvOS simulator binary"""
         self.run_with(arch=self.getArchitecture(),
                       os='tvos', env='simulator',
-                      platform='appletvsimulator')
+                      expected_load_command='LC_BUILD_VERSION')
 
     @skipUnlessDarwin
     @skipIfDarwinEmbedded
     @apple_simulator_test('watch')
-    def test_watchos(self):
+    @skipIfDarwin # rdar://problem/64552748
+    @skipIf(archs=['arm64','arm64e'])
+    def test_watchos_i386(self):
         """Test running a 32-bit watchOS simulator binary"""
         self.run_with(arch='i386',
                       os='watchos', env='simulator',
-                      platform='watchsimulator')
+                      expected_load_command='LC_BUILD_VERSION')
+
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    @apple_simulator_test('watch')
+    @skipIfDarwin # rdar://problem/64552748
+    @skipIf(archs=['i386','x86_64'])
+    def test_watchos_armv7k(self):
+        """Test running a 32-bit watchOS simulator binary"""
+        self.run_with(arch='armv7k',
+                      os='watchos', env='simulator',
+                      expected_load_command='LC_BUILD_VERSION')
+
+
+    #
+    # Back-deployment tests.
+    #
+    # Older Mach-O versions used less expressive load commands, such
+    # as LC_VERSION_MIN_IPHONEOS that wouldn't distinguish between ios
+    # and ios-simulator.  When targeting a simulator on Apple Silicon
+    # macOS, however, these legacy load commands are never generated.
+    #
+        
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    @apple_simulator_test('iphone')
+    @skipIf(archs=['arm64','arm64e'])
+    def test_lc_version_min_iphoneos(self):
+        """Test running a back-deploying iOS simulator binary
+           with a legacy iOS load command"""
+        self.run_with(arch=self.getArchitecture(),
+                      os='ios11.0', env='simulator',
+                      expected_load_command='LC_VERSION_MIN_IPHONEOS')
+
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    @apple_simulator_test('iphone')
+    @skipIf(archs=['i386','x86_64'])
+    def test_ios_backdeploy_apple_silicon(self):
+        """Test running a back-deploying iOS simulator binary"""
+        self.run_with(arch=self.getArchitecture(),
+                      os='ios11.0', env='simulator',
+                      expected_load_command='LC_BUILD_VERSION')
+
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    @apple_simulator_test('appletv')
+    @skipIf(archs=['arm64','arm64e'])
+    def test_lc_version_min_tvos(self):
+        """Test running a back-deploying tvOS simulator binary
+           with a legacy tvOS load command"""
+        self.run_with(arch=self.getArchitecture(),
+                      os='tvos11.0', env='simulator',
+                      expected_load_command='LC_VERSION_MIN_TVOS')
+
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    @apple_simulator_test('appletv')
+    @skipIf(archs=['i386','x86_64'])
+    def test_tvos_backdeploy_apple_silicon(self):
+        """Test running a back-deploying tvOS simulator binary"""
+        self.run_with(arch=self.getArchitecture(),
+                      os='tvos11.0', env='simulator',
+                      expected_load_command='LC_BUILD_VERSION')
+
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    @apple_simulator_test('watch')
+    @skipIf(archs=['arm64','arm64e'])
+    @skipIfDarwin # rdar://problem/64552748
+    def test_lc_version_min_watchos(self):
+        """Test running a back-deploying watchOS simulator binary
+           with a legacy watchOS load command"""
+        self.run_with(arch='i386',
+                      os='watchos4.0', env='simulator',
+                      expected_load_command='LC_VERSION_MIN_WATCHOS')
+
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    @apple_simulator_test('watch')
+    @skipIf(archs=['arm64','arm64e'])
+    @skipIfDarwin # rdar://problem/64552748
+    def test_watchos_backdeploy_apple_silicon(self):
+        """Test running a back-deploying watchOS simulator binary"""
+        self.run_with(arch='armv7k',
+                      os='watchos4.0', env='simulator',
+                      expected_load_command='LC_BUILD_VERSION')

diff  --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index b87ef5768a96..af13a8f8208b 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -1392,10 +1392,14 @@ const char *DNBGetDeploymentInfo(nub_process_t pid,
                                  uint32_t& minor_version,
                                  uint32_t& patch_version) {
   MachProcessSP procSP;
-  if (GetProcessSP(pid, procSP))
-    return procSP->GetDeploymentInfo(lc, load_command_address,
-                                     major_version, minor_version,
-                                     patch_version);
+  if (GetProcessSP(pid, procSP)) {
+    // FIXME: This doesn't correct for older ios simulator and macCatalyst.
+    auto info = procSP->GetDeploymentInfo(lc, load_command_address);
+    major_version = info.major_version;
+    minor_version = info.minor_version;
+    patch_version = info.patch_version;
+    return procSP->GetPlatformString(info.platform);
+  }
   return nullptr;
 }
 

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index e62051fbe011..c749dd8426c5 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -230,10 +230,22 @@ class MachProcess {
                          uint64_t plo_pthread_tsd_base_address_offset,
                          uint64_t plo_pthread_tsd_base_offset,
                          uint64_t plo_pthread_tsd_entry_size);
-  const char *
-  GetDeploymentInfo(const struct load_command&, uint64_t load_command_address,
-                    uint32_t& major_version, uint32_t& minor_version,
-                    uint32_t& patch_version);
+
+  struct DeploymentInfo {
+    DeploymentInfo() = default;
+    operator bool() { return platform > 0; }
+    /// The Mach-O platform type;
+    unsigned char platform = 0;
+    /// Pre-LC_BUILD_VERSION files don't disambiguate between ios and ios
+    /// simulator.
+    bool maybe_simulator = false;
+    uint32_t major_version = 0;
+    uint32_t minor_version = 0;
+    uint32_t patch_version = 0;
+  };
+  DeploymentInfo GetDeploymentInfo(const struct load_command &,
+                                   uint64_t load_command_address);
+  static const char *GetPlatformString(unsigned char platform);
   bool GetMachOInformationFromMemory(uint32_t platform,
                                      nub_addr_t mach_o_header_addr,
                                      int wordsize,

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index 74d20be42e31..af9ae752f72b 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -601,88 +601,78 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
       plo_pthread_tsd_entry_size);
 }
 
-/// Determine whether this is running on macOS.
-/// Since debugserver runs on the same machine as the process, we can
-/// just look at the compilation target.
-static bool IsMacOSHost() {
-#if TARGET_OS_OSX == 1
-  return true;
-#else
-  return false;
-#endif
-}
-
-const char *MachProcess::GetDeploymentInfo(const struct load_command& lc,
-                                           uint64_t load_command_address,
-                                           uint32_t& major_version,
-                                           uint32_t& minor_version,
-                                           uint32_t& patch_version) {
+MachProcess::DeploymentInfo
+MachProcess::GetDeploymentInfo(const struct load_command &lc,
+                               uint64_t load_command_address) {
+  DeploymentInfo info;
   uint32_t cmd = lc.cmd & ~LC_REQ_DYLD;
-  bool lc_cmd_known =
-    cmd == LC_VERSION_MIN_IPHONEOS || cmd == LC_VERSION_MIN_MACOSX ||
-    cmd == LC_VERSION_MIN_TVOS || cmd == LC_VERSION_MIN_WATCHOS;
-
-  if (lc_cmd_known) {
+  // Handle the older LC_VERSION load commands, which don't
+  // distinguish between simulator and real hardware.
+  auto handle_version_min = [&](char platform) {
     struct version_min_command vers_cmd;
     if (ReadMemory(load_command_address, sizeof(struct version_min_command),
-                   &vers_cmd) != sizeof(struct version_min_command)) {
-      return nullptr;
-    }
-    major_version = vers_cmd.sdk >> 16;
-    minor_version = (vers_cmd.sdk >> 8) & 0xffu;
-    patch_version = vers_cmd.sdk & 0xffu;
-
-    // Handle the older LC_VERSION load commands, which don't
-    // distinguish between simulator and real hardware.
-    switch (cmd) {
-    case LC_VERSION_MIN_IPHONEOS:
-      return IsMacOSHost() ? "iossimulator": "ios";
-    case LC_VERSION_MIN_MACOSX:
-      return "macosx";
-    case LC_VERSION_MIN_TVOS:
-      return IsMacOSHost() ? "tvossimulator": "tvos";
-    case LC_VERSION_MIN_WATCHOS:
-      return IsMacOSHost() ? "watchossimulator" : "watchos";
-    default:
-      return nullptr;
-    }
-  }
-#if defined (LC_BUILD_VERSION)
-  if (cmd == LC_BUILD_VERSION) {
+                   &vers_cmd) != sizeof(struct version_min_command))
+      return;
+    info.platform = platform;
+    info.major_version = vers_cmd.sdk >> 16;
+    info.minor_version = (vers_cmd.sdk >> 8) & 0xffu;
+    info.patch_version = vers_cmd.sdk & 0xffu;
+    info.maybe_simulator = true;
+  };
+  switch (cmd) {
+  case LC_VERSION_MIN_IPHONEOS:
+    handle_version_min(PLATFORM_IOS);
+    break;
+  case LC_VERSION_MIN_MACOSX:
+    handle_version_min(PLATFORM_MACOS);
+    break;
+  case LC_VERSION_MIN_TVOS:
+    handle_version_min(PLATFORM_TVOS);
+    break;
+  case LC_VERSION_MIN_WATCHOS:
+    handle_version_min(PLATFORM_WATCHOS);
+    break;
+#if defined(LC_BUILD_VERSION)
+  case LC_BUILD_VERSION: {
     struct build_version_command build_vers;
     if (ReadMemory(load_command_address, sizeof(struct build_version_command),
-                   &build_vers) != sizeof(struct build_version_command)) {
-      return nullptr;
-    }
-    major_version = build_vers.sdk >> 16;;
-    minor_version = (build_vers.sdk >> 8) & 0xffu;
-    patch_version = build_vers.sdk & 0xffu;
-
-    switch (build_vers.platform) {
-    case PLATFORM_MACOS:
-      return "macosx";
-    case PLATFORM_MACCATALYST:
-      return "maccatalyst";
-    case PLATFORM_IOS:
-      return "ios";
-    case PLATFORM_IOSSIMULATOR:
-      return "iossimulator";
-    case PLATFORM_TVOS:
-      return "tvos";
-    case PLATFORM_TVOSSIMULATOR:
-      return "tvossimulator";
-    case PLATFORM_WATCHOS:
-      return "watchos";
-    case PLATFORM_WATCHOSSIMULATOR:
-      return "watchossimulator";
-    case PLATFORM_BRIDGEOS:
-      return "bridgeos";
-    case PLATFORM_DRIVERKIT:
-      return "driverkit";
-    }
+                   &build_vers) != sizeof(struct build_version_command))
+      break;
+    info.platform = build_vers.platform;
+    info.major_version = build_vers.sdk >> 16;
+    info.minor_version = (build_vers.sdk >> 8) & 0xffu;
+    info.patch_version = build_vers.sdk & 0xffu;
+    break;
   }
 #endif
-  return nullptr;
+  }
+  return info;
+}
+
+const char *MachProcess::GetPlatformString(unsigned char platform) {
+  switch (platform) {
+  case PLATFORM_MACOS:
+    return "macosx";
+  case PLATFORM_MACCATALYST:
+    return "maccatalyst";
+  case PLATFORM_IOS:
+    return "ios";
+  case PLATFORM_IOSSIMULATOR:
+    return "iossimulator";
+  case PLATFORM_TVOS:
+    return "tvos";
+  case PLATFORM_TVOSSIMULATOR:
+    return "tvossimulator";
+  case PLATFORM_WATCHOS:
+    return "watchos";
+  case PLATFORM_WATCHOSSIMULATOR:
+    return "watchossimulator";
+  case PLATFORM_BRIDGEOS:
+    return "bridgeos";
+  case PLATFORM_DRIVERKIT:
+    return "driverkit";
+  }
+  return "";
 }
 
 // Given an address, read the mach-o header and load commands out of memory to
@@ -787,10 +777,36 @@ static bool IsMacOSHost() {
           sizeof(struct uuid_command))
         uuid_copy(inf.uuid, uuidcmd.uuid);
     }
-
-    uint32_t major_version, minor_version, patch_version;
-    if (const char *lc_platform = GetDeploymentInfo(
-            lc, load_cmds_p, major_version, minor_version, patch_version)) {
+    if (DeploymentInfo deployment_info = GetDeploymentInfo(lc, load_cmds_p)) {
+      // Simulator support. If the platform is ambiguous, use the dyld info.
+      if (deployment_info.maybe_simulator) {
+        // If dyld doesn't return a platform, use a heuristic.
+#if (defined(__x86_64__) || defined(__i386__))
+        // If we are running on Intel macOS, it is safe to assume
+        // this is really a back-deploying simulator binary.
+        if (deployment_info.maybe_simulator) {
+          switch (deployment_info.platform) {
+          case PLATFORM_IOS:
+            deployment_info.platform = PLATFORM_IOSSIMULATOR;
+            break;
+          case PLATFORM_TVOS:
+            deployment_info.platform = PLATFORM_TVOSSIMULATOR;
+            break;
+          case PLATFORM_WATCHOS:
+            deployment_info.platform = PLATFORM_WATCHOSSIMULATOR;
+            break;
+          }
+#else
+        // On an Apple Silicon macOS host, there is no
+        // ambiguity. The only binaries that use legacy load
+        // commands are back-deploying native iOS binaries. All
+        // simulator binaries use the newer, unambiguous
+        // LC_BUILD_VERSION load commands.
+        deployment_info.maybe_simulator = false;
+#endif
+        }
+      }
+      const char *lc_platform = GetPlatformString(deployment_info.platform);
       // macCatalyst support.
       //
       // This handles two special cases:
@@ -824,12 +840,15 @@ static bool IsMacOSHost() {
       } else {
         inf.min_version_os_name = lc_platform;
         inf.min_version_os_version = "";
-        inf.min_version_os_version += std::to_string(major_version);
+        inf.min_version_os_version +=
+            std::to_string(deployment_info.major_version);
         inf.min_version_os_version += ".";
-        inf.min_version_os_version += std::to_string(minor_version);
-        if (patch_version != 0) {
+        inf.min_version_os_version +=
+            std::to_string(deployment_info.minor_version);
+        if (deployment_info.patch_version != 0) {
           inf.min_version_os_version += ".";
-          inf.min_version_os_version += std::to_string(patch_version);
+          inf.min_version_os_version +=
+              std::to_string(deployment_info.patch_version);
         }
       }
     }


        


More information about the lldb-commits mailing list