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