[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