forked from OSchip/llvm-project
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
This commit is contained in:
parent
128bf458ab
commit
05df9cc703
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import json
|
|||
import unittest2
|
||||
|
||||
|
||||
@skipIfDarwin # rdar://problem/64552748
|
||||
class TestSimulatorPlatformLaunching(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
@ -41,14 +40,16 @@ class TestSimulatorPlatformLaunching(TestBase):
|
|||
|
||||
|
||||
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 @@ class TestSimulatorPlatformLaunching(TestBase):
|
|||
# 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')
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue