Skip to content

Commit f593edb

Browse files
adrian-prantlmemfrob
authored andcommitted
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
1 parent 502d6b4 commit f593edb

File tree

4 files changed

+58
-20
lines changed

4 files changed

+58
-20
lines changed

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5007,8 +5007,8 @@ void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
50075007

50085008
struct version_min_command version_min;
50095009
switch (load_cmd.cmd) {
5010-
case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
50115010
case llvm::MachO::LC_VERSION_MIN_MACOSX:
5011+
case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
50125012
case llvm::MachO::LC_VERSION_MIN_TVOS:
50135013
case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
50145014
if (load_cmd.cmdsize != sizeof(version_min))
@@ -5024,7 +5024,19 @@ void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,
50245024

50255025
auto triple = base_triple;
50265026
triple.setOSName(os.str());
5027-
os_name.clear();
5027+
5028+
// Disambiguate legacy simulator platforms.
5029+
if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
5030+
(base_triple.getArch() == llvm::Triple::x86_64 ||
5031+
base_triple.getArch() == llvm::Triple::x86)) {
5032+
// The combination of legacy LC_VERSION_MIN load command and
5033+
// x86 architecture always indicates a simulator environment.
5034+
// The combination of LC_VERSION_MIN and arm architecture only
5035+
// appears for native binaries. Back-deploying simulator
5036+
// binaries on Apple Silicon Macs use the modern unambigous
5037+
// LC_BUILD_VERSION load commands; no special handling required.
5038+
triple.setEnvironment(llvm::Triple::Simulator);
5039+
}
50285040
add_triple(triple);
50295041
break;
50305042
}

lldb/source/Utility/ArchSpec.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,20 +1057,6 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
10571057
return true;
10581058
}
10591059

1060-
if (lhs_triple_os != rhs_triple_os) {
1061-
const bool rhs_os_specified = rhs.TripleOSWasSpecified();
1062-
const bool lhs_os_specified = TripleOSWasSpecified();
1063-
// Both architectures had the OS specified, so if they aren't equal then
1064-
// we return false
1065-
if (rhs_os_specified && lhs_os_specified)
1066-
return false;
1067-
1068-
// Only fail if both os types are not unknown
1069-
if (lhs_triple_os != llvm::Triple::UnknownOS &&
1070-
rhs_triple_os != llvm::Triple::UnknownOS)
1071-
return false;
1072-
}
1073-
10741060
// x86_64-apple-ios-macabi and x86_64-apple-ios are not compatible.
10751061
if (lhs_triple_os == llvm::Triple::IOS &&
10761062
rhs_triple_os == llvm::Triple::IOS &&
@@ -1079,6 +1065,19 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
10791065
lhs_triple_env != rhs_triple_env)
10801066
return false;
10811067

1068+
if (lhs_triple_os != rhs_triple_os) {
1069+
const bool lhs_os_specified = TripleOSWasSpecified();
1070+
const bool rhs_os_specified = rhs.TripleOSWasSpecified();
1071+
// If both OS types are specified and different, fail.
1072+
if (lhs_os_specified && rhs_os_specified)
1073+
return false;
1074+
1075+
// If the pair of os+env is both unspecified, match any other os+env combo.
1076+
if (!exact_match && ((!lhs_os_specified && !lhs_triple.hasEnvironment()) ||
1077+
(!rhs_os_specified && !rhs_triple.hasEnvironment())))
1078+
return true;
1079+
}
1080+
10821081
return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env);
10831082
}
10841083

lldb/test/API/macosx/simulator/TestSimulatorPlatform.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import unittest2
77

88

9-
@skipIfDarwin # rdar://problem/64552748
109
class TestSimulatorPlatformLaunching(TestBase):
1110

1211
mydir = TestBase.compute_mydir(__file__)
@@ -41,14 +40,16 @@ def check_debugserver(self, log, expected_platform, expected_version):
4140

4241

4342
def run_with(self, arch, os, vers, env, expected_load_command):
44-
self.build(dictionary={'TRIPLE': arch+'-apple-'+os+vers+'-'+env})
43+
env_list = [env] if env else []
44+
triple = '-'.join([arch, 'apple', os + vers] + env_list)
45+
self.build(dictionary={'TRIPLE': triple})
4546
self.check_load_commands(expected_load_command)
4647
log = self.getBuildArtifact('packets.log')
4748
self.expect("log enable gdb-remote packets -f "+log)
4849
lldbutil.run_to_source_breakpoint(self, "break here",
4950
lldb.SBFileSpec("hello.c"))
50-
self.expect('image list -b -t',
51-
patterns=['a\.out '+arch+'-apple-'+os+vers+'.*-'+env])
51+
triple_re = '-'.join([arch, 'apple', os + vers+'.*'] + env_list)
52+
self.expect('image list -b -t', patterns=['a\.out '+triple_re])
5253
self.check_debugserver(log, os+env, vers)
5354

5455
@skipUnlessDarwin
@@ -101,6 +102,13 @@ def test_watchos_armv7k(self):
101102
# macOS, however, these legacy load commands are never generated.
102103
#
103104

105+
@skipUnlessDarwin
106+
@skipIfDarwinEmbedded
107+
def test_lc_version_min_macosx(self):
108+
"""Test running a back-deploying non-simulator MacOS X binary"""
109+
self.run_with(arch=self.getArchitecture(),
110+
os='macosx', vers='10.9', env='',
111+
expected_load_command='LC_VERSION_MIN_MACOSX')
104112
@skipUnlessDarwin
105113
@skipIfDarwinEmbedded
106114
@apple_simulator_test('iphone')

lldb/unittests/Utility/ArchSpecTest.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,25 @@ TEST(ArchSpecTest, Compatibility) {
305305
ArchSpec B("x86_64-apple-ios-simulator");
306306
ASSERT_FALSE(A.IsExactMatch(B));
307307
ASSERT_FALSE(A.IsCompatibleMatch(B));
308+
ASSERT_FALSE(B.IsExactMatch(A));
309+
ASSERT_FALSE(B.IsCompatibleMatch(A));
310+
}
311+
{
312+
ArchSpec A("x86_64-apple-ios");
313+
ArchSpec B("x86_64-apple-ios-simulator");
314+
ASSERT_FALSE(A.IsExactMatch(B));
315+
ASSERT_FALSE(A.IsCompatibleMatch(B));
316+
ASSERT_FALSE(B.IsExactMatch(A));
317+
ASSERT_FALSE(B.IsCompatibleMatch(A));
318+
}
319+
{
320+
// FIXME: This is surprisingly not equivalent to "x86_64-*-*".
321+
ArchSpec A("x86_64");
322+
ArchSpec B("x86_64-apple-ios-simulator");
323+
ASSERT_FALSE(A.IsExactMatch(B));
324+
ASSERT_TRUE(A.IsCompatibleMatch(B));
325+
ASSERT_FALSE(B.IsExactMatch(A));
326+
ASSERT_TRUE(B.IsCompatibleMatch(A));
308327
}
309328
{
310329
ArchSpec A("arm64-apple-ios");

0 commit comments

Comments
 (0)