diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5007,8 +5007,8 @@ 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 @@ 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 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -1057,20 +1057,6 @@ 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 @@ 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 different, 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 --- a/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py +++ b/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py @@ -6,7 +6,6 @@ import unittest2 -@skipIfDarwin # rdar://problem/64552748 class TestSimulatorPlatformLaunching(TestBase): mydir = TestBase.compute_mydir(__file__) @@ -41,14 +40,16 @@ 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 @@ # 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 --- a/lldb/unittests/Utility/ArchSpecTest.cpp +++ b/lldb/unittests/Utility/ArchSpecTest.cpp @@ -305,6 +305,25 @@ 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");