xref: /llvm-project/lldb/test/API/macosx/simulator/TestSimulatorPlatform.py (revision 44fc987ed174e32544a577387ab0df6886495e82)
1import lldb
2from lldbsuite.test.lldbtest import *
3from lldbsuite.test.decorators import *
4import lldbsuite.test.lldbutil as lldbutil
5import json
6
7
8class TestSimulatorPlatformLaunching(TestBase):
9    NO_DEBUG_INFO_TESTCASE = True
10
11    def check_load_commands(self, expected_load_command):
12        """sanity check the built binary for the expected number of load commands"""
13        load_cmds = subprocess.check_output(
14            ["otool", "-l", self.getBuildArtifact()]
15        ).decode("utf-8")
16        found = 0
17        for line in load_cmds.split("\n"):
18            if expected_load_command in line:
19                found += 1
20        self.assertEqual(
21            found,
22            1,
23            "wrong number of load commands for {}".format(expected_load_command),
24        )
25
26    def check_debugserver(self, log, expected_platform, expected_version):
27        """scan the debugserver packet log"""
28        process_info = lldbutil.packetlog_get_process_info(log)
29        self.assertIn("ostype", process_info)
30        self.assertEqual(process_info["ostype"], expected_platform)
31        dylib_info = lldbutil.packetlog_get_dylib_info(log)
32        self.assertTrue(dylib_info)
33        aout_info = None
34        for image in dylib_info["images"]:
35            if image["pathname"].endswith("a.out"):
36                aout_info = image
37        self.assertTrue(aout_info)
38        self.assertEqual(aout_info["min_version_os_name"], expected_platform)
39        if expected_version:
40            self.assertEqual(aout_info["min_version_os_sdk"], expected_version)
41
42    @skipIf(bugnumber="rdar://76995109")
43    def run_with(self, arch, os, vers, env, expected_load_command):
44        env_list = [env] if env else []
45        triple = "-".join([arch, "apple", os + vers] + env_list)
46        sdk = lldbutil.get_xcode_sdk(os, env)
47
48        version_min = ""
49        if not vers:
50            vers = lldbutil.get_xcode_sdk_version(sdk)
51        if env == "simulator":
52            version_min = "-m{}-simulator-version-min={}".format(os, vers)
53        elif os == "macosx":
54            version_min = "-m{}-version-min={}".format(os, vers)
55
56        sdk_root = lldbutil.get_xcode_sdk_root(sdk)
57        clang = lldbutil.get_xcode_clang(sdk)
58
59        self.build(
60            dictionary={
61                "ARCH": arch,
62                "ARCH_CFLAGS": "-target {} {}".format(triple, version_min),
63                "SDKROOT": sdk_root,
64            },
65            compiler=clang,
66        )
67
68        self.check_load_commands(expected_load_command)
69        log = self.getBuildArtifact("packets.log")
70        self.expect("log enable gdb-remote packets -f " + log)
71        lldbutil.run_to_source_breakpoint(
72            self, "break here", lldb.SBFileSpec("hello.c")
73        )
74        triple_re = "-".join([arch, "apple", os + vers + ".*"] + env_list)
75        self.expect("image list -b -t", patterns=["a\.out " + triple_re])
76        self.check_debugserver(log, os + env, vers)
77
78    @skipIfAsan
79    @skipUnlessDarwin
80    @skipIfDarwinEmbedded
81    @apple_simulator_test("iphone")
82    @skipIfOutOfTreeDebugserver
83    def test_ios(self):
84        """Test running an iOS simulator binary"""
85        self.run_with(
86            arch=self.getArchitecture(),
87            os="ios",
88            vers="",
89            env="simulator",
90            expected_load_command="LC_BUILD_VERSION",
91        )
92
93    @skipIfAsan
94    @skipUnlessDarwin
95    @skipIfDarwinEmbedded
96    @apple_simulator_test("appletv")
97    @skipIfOutOfTreeDebugserver
98    def test_tvos(self):
99        """Test running an tvOS simulator binary"""
100        self.run_with(
101            arch=self.getArchitecture(),
102            os="tvos",
103            vers="",
104            env="simulator",
105            expected_load_command="LC_BUILD_VERSION",
106        )
107
108    @skipIfAsan
109    @skipUnlessDarwin
110    @skipIfDarwinEmbedded
111    @apple_simulator_test("watch")
112    @skipIfDarwin  # rdar://problem/64552748
113    @skipIf(archs=["arm64", "arm64e"])
114    @skipIfOutOfTreeDebugserver
115    def test_watchos_i386(self):
116        """Test running a 32-bit watchOS simulator binary"""
117        self.run_with(
118            arch="i386",
119            os="watchos",
120            vers="",
121            env="simulator",
122            expected_load_command="LC_BUILD_VERSION",
123        )
124
125    @skipIfAsan
126    @skipUnlessDarwin
127    @skipIfDarwinEmbedded
128    @apple_simulator_test("watch")
129    @skipIfDarwin  # rdar://problem/64552748
130    @skipIf(archs=["i386", "x86_64"])
131    @skipIfOutOfTreeDebugserver
132    def test_watchos_armv7k(self):
133        """Test running a 32-bit watchOS simulator binary"""
134        self.run_with(
135            arch="armv7k",
136            os="watchos",
137            vers="",
138            env="simulator",
139            expected_load_command="LC_BUILD_VERSION",
140        )
141
142    #
143    # Back-deployment tests.
144    #
145    # Older Mach-O versions used less expressive load commands, such
146    # as LC_VERSION_MIN_IPHONEOS that wouldn't distinguish between ios
147    # and ios-simulator.  When targeting a simulator on Apple Silicon
148    # macOS, however, these legacy load commands are never generated.
149    #
150
151    @skipUnlessDarwin
152    @skipIfDarwinEmbedded
153    @skipIfOutOfTreeDebugserver
154    def test_lc_version_min_macosx(self):
155        """Test running a back-deploying non-simulator MacOS X binary"""
156        self.run_with(
157            arch=self.getArchitecture(),
158            os="macosx",
159            vers="10.9",
160            env="",
161            expected_load_command="LC_VERSION_MIN_MACOSX",
162        )
163
164    @skipIfAsan
165    @skipUnlessDarwin
166    @skipIfDarwinEmbedded
167    @apple_simulator_test("iphone")
168    @skipIf(archs=["arm64", "arm64e"])
169    @skipIfOutOfTreeDebugserver
170    def test_lc_version_min_iphoneos(self):
171        """Test running a back-deploying iOS simulator binary
172        with a legacy iOS load command"""
173        self.run_with(
174            arch=self.getArchitecture(),
175            os="ios",
176            vers="11.0",
177            env="simulator",
178            expected_load_command="LC_VERSION_MIN_IPHONEOS",
179        )
180
181    @skipIfAsan
182    @skipUnlessDarwin
183    @skipIfDarwinEmbedded
184    @apple_simulator_test("iphone")
185    @skipIf(archs=["arm64", "arm64e"])
186    @skipIfOutOfTreeDebugserver
187    def test_ios_backdeploy_x86(self):
188        """Test running a back-deploying iOS simulator binary
189        with a legacy iOS load command"""
190        self.run_with(
191            arch=self.getArchitecture(),
192            os="ios",
193            vers="13.0",
194            env="simulator",
195            expected_load_command="LC_BUILD_VERSION",
196        )
197
198    @skipIfAsan
199    @skipUnlessDarwin
200    @skipIfDarwinEmbedded
201    @apple_simulator_test("iphone")
202    @skipIf(archs=["i386", "x86_64"])
203    @skipIfOutOfTreeDebugserver
204    def test_ios_backdeploy_apple_silicon(self):
205        """Test running a back-deploying iOS simulator binary"""
206        self.run_with(
207            arch=self.getArchitecture(),
208            os="ios",
209            vers="11.0",
210            env="simulator",
211            expected_load_command="LC_BUILD_VERSION",
212        )
213
214    @skipIfAsan
215    @skipUnlessDarwin
216    @skipIfDarwinEmbedded
217    @apple_simulator_test("appletv")
218    @skipIf(archs=["arm64", "arm64e"])
219    @skipIfOutOfTreeDebugserver
220    def test_lc_version_min_tvos(self):
221        """Test running a back-deploying tvOS simulator binary
222        with a legacy tvOS load command"""
223        self.run_with(
224            arch=self.getArchitecture(),
225            os="tvos",
226            vers="11.0",
227            env="simulator",
228            expected_load_command="LC_VERSION_MIN_TVOS",
229        )
230
231    @skipIfAsan
232    @skipUnlessDarwin
233    @skipIfDarwinEmbedded
234    @apple_simulator_test("appletv")
235    @skipIf(archs=["i386", "x86_64"])
236    @skipIfOutOfTreeDebugserver
237    def test_tvos_backdeploy_apple_silicon(self):
238        """Test running a back-deploying tvOS simulator binary"""
239        self.run_with(
240            arch=self.getArchitecture(),
241            os="tvos",
242            vers="11.0",
243            env="simulator",
244            expected_load_command="LC_BUILD_VERSION",
245        )
246
247    @skipIfAsan
248    @skipUnlessDarwin
249    @skipIfDarwinEmbedded
250    @apple_simulator_test("watch")
251    @skipIf(archs=["arm64", "arm64e"])
252    @skipIfDarwin  # rdar://problem/64552748
253    @skipIfOutOfTreeDebugserver
254    def test_lc_version_min_watchos(self):
255        """Test running a back-deploying watchOS simulator binary
256        with a legacy watchOS load command"""
257        self.run_with(
258            arch="i386",
259            os="watchos",
260            vers="4.0",
261            env="simulator",
262            expected_load_command="LC_VERSION_MIN_WATCHOS",
263        )
264
265    @skipIfAsan
266    @skipUnlessDarwin
267    @skipIfDarwinEmbedded
268    @apple_simulator_test("watch")
269    @skipIf(archs=["arm64", "arm64e"])
270    @skipIfDarwin  # rdar://problem/64552748
271    @skipIfOutOfTreeDebugserver
272    def test_watchos_backdeploy_apple_silicon(self):
273        """Test running a back-deploying watchOS simulator binary"""
274        self.run_with(
275            arch="armv7k",
276            os="watchos",
277            vers="4.0",
278            env="simulator",
279            expected_load_command="LC_BUILD_VERSION",
280        )
281