[Lldb-commits] [lldb] 05df9cc - Correctly detect legacy iOS simulator Mach-O objectfiles

Adrian Prantl via lldb-commits lldb-commits at lists.llvm.org
Thu Aug 6 12:41:02 PDT 2020


Author: Adrian Prantl
Date: 2020-08-06T12:40:45-07:00
New Revision: 05df9cc70367a60cb34bee773389ab2522984f8b

URL: https://github.com/llvm/llvm-project/commit/05df9cc70367a60cb34bee773389ab2522984f8b
DIFF: https://github.com/llvm/llvm-project/commit/05df9cc70367a60cb34bee773389ab2522984f8b.diff

LOG: Correctly detect legacy iOS simulator Mach-O objectfiles

The code in ObjectFileMachO didn't disambiguate between ios and
ios-simulator object files for Mach-O objects using the legacy
ambiguous LC_VERSION_MIN load commands. This used to not matter before
taught ArchSpec that ios and ios-simulator are no longer compatible.

rdar://problem/66545307

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

Added: 
    

Modified: 
    lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/source/Utility/ArchSpec.cpp
    lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
    lldb/unittests/Utility/ArchSpecTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 383cc5b59a37..e7701c350ff5 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5007,8 +5007,8 @@ void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
 
     struct version_min_command version_min;
     switch (load_cmd.cmd) {
-    case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
     case llvm::MachO::LC_VERSION_MIN_MACOSX:
+    case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
     case llvm::MachO::LC_VERSION_MIN_TVOS:
     case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
       if (load_cmd.cmdsize != sizeof(version_min))
@@ -5024,7 +5024,19 @@ void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
 
       auto triple = base_triple;
       triple.setOSName(os.str());
-      os_name.clear();
+
+      // Disambiguate legacy simulator platforms.
+      if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
+          (base_triple.getArch() == llvm::Triple::x86_64 ||
+           base_triple.getArch() == llvm::Triple::x86)) {
+        // The combination of legacy LC_VERSION_MIN load command and
+        // x86 architecture always indicates a simulator environment.
+        // The combination of LC_VERSION_MIN and arm architecture only
+        // appears for native binaries. Back-deploying simulator
+        // binaries on Apple Silicon Macs use the modern unambigous
+        // LC_BUILD_VERSION load commands; no special handling required.
+        triple.setEnvironment(llvm::Triple::Simulator);
+      }
       add_triple(triple);
       break;
     }

diff  --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp
index 6e4f1b5326dd..9cbd5df3a7b6 100644
--- a/lldb/source/Utility/ArchSpec.cpp
+++ b/lldb/source/Utility/ArchSpec.cpp
@@ -1057,20 +1057,6 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
       return true;
   }
 
-  if (lhs_triple_os != rhs_triple_os) {
-    const bool rhs_os_specified = rhs.TripleOSWasSpecified();
-    const bool lhs_os_specified = TripleOSWasSpecified();
-    // Both architectures had the OS specified, so if they aren't equal then
-    // we return false
-    if (rhs_os_specified && lhs_os_specified)
-      return false;
-
-    // Only fail if both os types are not unknown
-    if (lhs_triple_os != llvm::Triple::UnknownOS &&
-        rhs_triple_os != llvm::Triple::UnknownOS)
-      return false;
-  }
-
   // x86_64-apple-ios-macabi and x86_64-apple-ios are not compatible.
   if (lhs_triple_os == llvm::Triple::IOS &&
       rhs_triple_os == llvm::Triple::IOS &&
@@ -1079,6 +1065,19 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
       lhs_triple_env != rhs_triple_env)
     return false;
 
+  if (lhs_triple_os != rhs_triple_os) {
+    const bool lhs_os_specified = TripleOSWasSpecified();
+    const bool rhs_os_specified = rhs.TripleOSWasSpecified();
+    // If both OS types are specified and 
diff erent, fail.
+    if (lhs_os_specified && rhs_os_specified)
+      return false;
+
+    // If the pair of os+env is both unspecified, match any other os+env combo.
+    if (!exact_match && ((!lhs_os_specified && !lhs_triple.hasEnvironment()) ||
+                         (!rhs_os_specified && !rhs_triple.hasEnvironment())))
+      return true;
+  }
+
   return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env);
 }
 

diff  --git a/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py b/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
index 9b5aed1ed619..26264868d893 100644
--- a/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
+++ b/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py
@@ -6,7 +6,6 @@
 import unittest2
 
 
- at skipIfDarwin # rdar://problem/64552748
 class TestSimulatorPlatformLaunching(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
@@ -41,14 +40,16 @@ def check_debugserver(self, log, expected_platform, expected_version):
 
 
     def run_with(self, arch, os, vers, env, expected_load_command):
-        self.build(dictionary={'TRIPLE': arch+'-apple-'+os+vers+'-'+env})
+        env_list = [env] if env else []
+        triple = '-'.join([arch, 'apple', os + vers] + env_list)
+        self.build(dictionary={'TRIPLE': triple})
         self.check_load_commands(expected_load_command)
         log = self.getBuildArtifact('packets.log')
         self.expect("log enable gdb-remote packets -f "+log)
         lldbutil.run_to_source_breakpoint(self, "break here",
                                           lldb.SBFileSpec("hello.c"))
-        self.expect('image list -b -t',
-                    patterns=['a\.out '+arch+'-apple-'+os+vers+'.*-'+env])
+        triple_re = '-'.join([arch, 'apple', os + vers+'.*'] + env_list)
+        self.expect('image list -b -t', patterns=['a\.out '+triple_re])
         self.check_debugserver(log, os+env, vers)
 
     @skipUnlessDarwin
@@ -101,6 +102,13 @@ def test_watchos_armv7k(self):
     # macOS, however, these legacy load commands are never generated.
     #
         
+    @skipUnlessDarwin
+    @skipIfDarwinEmbedded
+    def test_lc_version_min_macosx(self):
+        """Test running a back-deploying non-simulator MacOS X binary"""
+        self.run_with(arch=self.getArchitecture(),
+                      os='macosx', vers='10.9', env='',
+                      expected_load_command='LC_VERSION_MIN_MACOSX')
     @skipUnlessDarwin
     @skipIfDarwinEmbedded
     @apple_simulator_test('iphone')

diff  --git a/lldb/unittests/Utility/ArchSpecTest.cpp b/lldb/unittests/Utility/ArchSpecTest.cpp
index ad0a8ac18cd1..1ef646acdefb 100644
--- a/lldb/unittests/Utility/ArchSpecTest.cpp
+++ b/lldb/unittests/Utility/ArchSpecTest.cpp
@@ -305,6 +305,25 @@ TEST(ArchSpecTest, Compatibility) {
     ArchSpec B("x86_64-apple-ios-simulator");
     ASSERT_FALSE(A.IsExactMatch(B));
     ASSERT_FALSE(A.IsCompatibleMatch(B));
+    ASSERT_FALSE(B.IsExactMatch(A));
+    ASSERT_FALSE(B.IsCompatibleMatch(A));
+  }
+  {
+    ArchSpec A("x86_64-apple-ios");
+    ArchSpec B("x86_64-apple-ios-simulator");
+    ASSERT_FALSE(A.IsExactMatch(B));
+    ASSERT_FALSE(A.IsCompatibleMatch(B));
+    ASSERT_FALSE(B.IsExactMatch(A));
+    ASSERT_FALSE(B.IsCompatibleMatch(A));
+  }
+  {
+    // FIXME: This is surprisingly not equivalent to "x86_64-*-*".
+    ArchSpec A("x86_64");
+    ArchSpec B("x86_64-apple-ios-simulator");
+    ASSERT_FALSE(A.IsExactMatch(B));
+    ASSERT_TRUE(A.IsCompatibleMatch(B));
+    ASSERT_FALSE(B.IsExactMatch(A));
+    ASSERT_TRUE(B.IsCompatibleMatch(A));
   }
   {
     ArchSpec A("arm64-apple-ios");


        


More information about the lldb-commits mailing list