1""" 2Test basics of linux core file debugging. 3""" 4 5from __future__ import division, print_function 6 7import shutil 8import struct 9import os 10 11import lldb 12from lldbsuite.test.decorators import * 13from lldbsuite.test.lldbtest import * 14from lldbsuite.test import lldbutil 15 16 17class LinuxCoreTestCase(TestBase): 18 NO_DEBUG_INFO_TESTCASE = True 19 20 mydir = TestBase.compute_mydir(__file__) 21 22 _aarch64_pid = 37688 23 _aarch64_pac_pid = 387 24 _i386_pid = 32306 25 _x86_64_pid = 32259 26 _s390x_pid = 1045 27 _ppc64le_pid = 28147 28 29 _aarch64_regions = 4 30 _i386_regions = 4 31 _x86_64_regions = 5 32 _s390x_regions = 2 33 _ppc64le_regions = 2 34 35 @skipIfLLVMTargetMissing("AArch64") 36 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 37 def test_aarch64(self): 38 """Test that lldb can read the process information from an aarch64 linux core file.""" 39 self.do_test("linux-aarch64", self._aarch64_pid, 40 self._aarch64_regions, "a.out") 41 42 @skipIfLLVMTargetMissing("X86") 43 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 44 def test_i386(self): 45 """Test that lldb can read the process information from an i386 linux core file.""" 46 self.do_test("linux-i386", self._i386_pid, self._i386_regions, "a.out") 47 48 @skipIfLLVMTargetMissing("PowerPC") 49 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 50 def test_ppc64le(self): 51 """Test that lldb can read the process information from an ppc64le linux core file.""" 52 self.do_test("linux-ppc64le", self._ppc64le_pid, self._ppc64le_regions, 53 "linux-ppc64le.ou") 54 55 @skipIfLLVMTargetMissing("X86") 56 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 57 def test_x86_64(self): 58 """Test that lldb can read the process information from an x86_64 linux core file.""" 59 self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions, 60 "a.out") 61 62 @skipIfLLVMTargetMissing("SystemZ") 63 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 64 def test_s390x(self): 65 """Test that lldb can read the process information from an s390x linux core file.""" 66 self.do_test("linux-s390x", self._s390x_pid, self._s390x_regions, 67 "a.out") 68 69 @skipIfLLVMTargetMissing("X86") 70 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 71 def test_same_pid_running(self): 72 """Test that we read the information from the core correctly even if we have a running 73 process with the same PID around""" 74 exe_file = self.getBuildArtifact("linux-x86_64-pid.out") 75 core_file = self.getBuildArtifact("linux-x86_64-pid.core") 76 shutil.copyfile("linux-x86_64.out", exe_file) 77 shutil.copyfile("linux-x86_64.core", core_file) 78 with open(core_file, "r+b") as f: 79 # These are offsets into the NT_PRSTATUS and NT_PRPSINFO structures in the note 80 # segment of the core file. If you update the file, these offsets may need updating 81 # as well. (Notes can be viewed with readelf --notes.) 82 for pid_offset in [0x1c4, 0x320]: 83 f.seek(pid_offset) 84 self.assertEqual( 85 struct.unpack( 86 "<I", 87 f.read(4))[0], 88 self._x86_64_pid) 89 90 # We insert our own pid, and make sure the test still 91 # works. 92 f.seek(pid_offset) 93 f.write(struct.pack("<I", os.getpid())) 94 self.do_test(self.getBuildArtifact("linux-x86_64-pid"), os.getpid(), 95 self._x86_64_regions, "a.out") 96 97 @skipIfLLVMTargetMissing("X86") 98 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 99 def test_two_cores_same_pid(self): 100 """Test that we handle the situation if we have two core files with the same PID 101 around""" 102 alttarget = self.dbg.CreateTarget("altmain.out") 103 altprocess = alttarget.LoadCore("altmain.core") 104 self.assertTrue(altprocess, PROCESS_IS_VALID) 105 self.assertEqual(altprocess.GetNumThreads(), 1) 106 self.assertEqual(altprocess.GetProcessID(), self._x86_64_pid) 107 108 altframe = altprocess.GetSelectedThread().GetFrameAtIndex(0) 109 self.assertEqual(altframe.GetFunctionName(), "_start") 110 self.assertEqual( 111 altframe.GetLineEntry().GetLine(), 112 line_number( 113 "altmain.c", 114 "Frame _start")) 115 116 error = lldb.SBError() 117 F = altprocess.ReadCStringFromMemory( 118 altframe.FindVariable("F").GetValueAsUnsigned(), 256, error) 119 self.assertTrue(error.Success()) 120 self.assertEqual(F, "_start") 121 122 # without destroying this process, run the test which opens another core file with the 123 # same pid 124 self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions, 125 "a.out") 126 127 128 @skipIfLLVMTargetMissing("X86") 129 @skipIfWindows 130 @skipIfReproducer 131 def test_read_memory(self): 132 """Test that we are able to read as many bytes as available""" 133 target = self.dbg.CreateTarget("linux-x86_64.out") 134 process = target.LoadCore("linux-x86_64.core") 135 self.assertTrue(process, PROCESS_IS_VALID) 136 137 error = lldb.SBError() 138 bytesread = process.ReadMemory(0x400ff0, 20, error) 139 140 # read only 16 bytes without zero bytes filling 141 self.assertEqual(len(bytesread), 16) 142 self.dbg.DeleteTarget(target) 143 144 @skipIfLLVMTargetMissing("X86") 145 def test_FPR_SSE(self): 146 # check x86_64 core file 147 target = self.dbg.CreateTarget(None) 148 self.assertTrue(target, VALID_TARGET) 149 process = target.LoadCore("linux-fpr_sse_x86_64.core") 150 151 values = {} 152 values["fctrl"] = "0x037f" 153 values["fstat"] = "0x0000" 154 values["ftag"] = "0x00ff" 155 values["fop"] = "0x0000" 156 values["fiseg"] = "0x00000000" 157 values["fioff"] = "0x0040011e" 158 values["foseg"] = "0x00000000" 159 values["fooff"] = "0x00000000" 160 values["mxcsr"] = "0x00001f80" 161 values["mxcsrmask"] = "0x0000ffff" 162 values["st0"] = "{0x99 0xf7 0xcf 0xfb 0x84 0x9a 0x20 0x9a 0xfd 0x3f}" 163 values["st1"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0x3f}" 164 values["st2"] = "{0xfe 0x8a 0x1b 0xcd 0x4b 0x78 0x9a 0xd4 0x00 0x40}" 165 values["st3"] = "{0xac 0x79 0xcf 0xd1 0xf7 0x17 0x72 0xb1 0xfe 0x3f}" 166 values["st4"] = "{0xbc 0xf0 0x17 0x5c 0x29 0x3b 0xaa 0xb8 0xff 0x3f}" 167 values["st5"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0x3f}" 168 values["st6"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 169 values["st7"] = "{0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40}" 170 values["xmm0"] = "{0x29 0x31 0x64 0x46 0x29 0x31 0x64 0x46 0x29 0x31 0x64 0x46 0x29 0x31 0x64 0x46}" 171 values["xmm1"] = "{0x9c 0xed 0x86 0x64 0x9c 0xed 0x86 0x64 0x9c 0xed 0x86 0x64 0x9c 0xed 0x86 0x64}" 172 values["xmm2"] = "{0x07 0xc2 0x1f 0xd7 0x07 0xc2 0x1f 0xd7 0x07 0xc2 0x1f 0xd7 0x07 0xc2 0x1f 0xd7}" 173 values["xmm3"] = "{0xa2 0x20 0x48 0x25 0xa2 0x20 0x48 0x25 0xa2 0x20 0x48 0x25 0xa2 0x20 0x48 0x25}" 174 values["xmm4"] = "{0xeb 0x5a 0xa8 0xc4 0xeb 0x5a 0xa8 0xc4 0xeb 0x5a 0xa8 0xc4 0xeb 0x5a 0xa8 0xc4}" 175 values["xmm5"] = "{0x49 0x41 0x20 0x0b 0x49 0x41 0x20 0x0b 0x49 0x41 0x20 0x0b 0x49 0x41 0x20 0x0b}" 176 values["xmm6"] = "{0xf8 0xf1 0x8b 0x4f 0xf8 0xf1 0x8b 0x4f 0xf8 0xf1 0x8b 0x4f 0xf8 0xf1 0x8b 0x4f}" 177 values["xmm7"] = "{0x13 0xf1 0x30 0xcd 0x13 0xf1 0x30 0xcd 0x13 0xf1 0x30 0xcd 0x13 0xf1 0x30 0xcd}" 178 179 for regname, value in values.items(): 180 self.expect("register read {}".format(regname), 181 substrs=["{} = {}".format(regname, value)]) 182 183 # now check i386 core file 184 target = self.dbg.CreateTarget(None) 185 self.assertTrue(target, VALID_TARGET) 186 process = target.LoadCore("linux-fpr_sse_i386.core") 187 188 values["fioff"] = "0x080480cc" 189 190 for regname, value in values.items(): 191 self.expect("register read {}".format(regname), 192 substrs=["{} = {}".format(regname, value)]) 193 194 @skipIfLLVMTargetMissing("X86") 195 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 196 def test_i386_sysroot(self): 197 """Test that lldb can find the exe for an i386 linux core file using the sysroot.""" 198 199 # Copy linux-i386.out to tmp_sysroot/home/labath/test/a.out (since it was compiled as 200 # /home/labath/test/a.out) 201 tmp_sysroot = os.path.join( 202 self.getBuildDir(), "lldb_i386_mock_sysroot") 203 executable = os.path.join( 204 tmp_sysroot, "home", "labath", "test", "a.out") 205 lldbutil.mkdir_p(os.path.dirname(executable)) 206 shutil.copyfile("linux-i386.out", executable) 207 208 # Set sysroot and load core 209 self.runCmd("platform select remote-linux --sysroot '%s'" % 210 tmp_sysroot) 211 target = self.dbg.CreateTarget(None) 212 self.assertTrue(target, VALID_TARGET) 213 process = target.LoadCore("linux-i386.core") 214 215 # Check that we found a.out from the sysroot 216 self.check_all(process, self._i386_pid, self._i386_regions, "a.out") 217 218 self.dbg.DeleteTarget(target) 219 220 @skipIfLLVMTargetMissing("X86") 221 @skipIfWindows 222 @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented. 223 def test_x86_64_sysroot(self): 224 """Test that sysroot has more priority then local filesystem.""" 225 226 # Copy wrong executable to the location outside of sysroot 227 exe_outside = os.path.join(self.getBuildDir(), "bin", "a.out") 228 lldbutil.mkdir_p(os.path.dirname(exe_outside)) 229 shutil.copyfile("altmain.out", exe_outside) 230 231 # Copy correct executable to the location inside sysroot 232 tmp_sysroot = os.path.join(self.getBuildDir(), "mock_sysroot") 233 exe_inside = os.path.join( 234 tmp_sysroot, os.path.relpath(exe_outside, "/")) 235 lldbutil.mkdir_p(os.path.dirname(exe_inside)) 236 shutil.copyfile("linux-x86_64.out", exe_inside) 237 238 # Prepare patched core file 239 core_file = os.path.join(self.getBuildDir(), "patched.core") 240 with open("linux-x86_64.core", "rb") as f: 241 core = f.read() 242 core = replace_path(core, "/test" * 817 + "/a.out", exe_outside) 243 with open(core_file, "wb") as f: 244 f.write(core) 245 246 # Set sysroot and load core 247 self.runCmd("platform select remote-linux --sysroot '%s'" % 248 tmp_sysroot) 249 target = self.dbg.CreateTarget(None) 250 self.assertTrue(target, VALID_TARGET) 251 process = target.LoadCore(core_file) 252 253 # Check that we found executable from the sysroot 254 mod_path = str(target.GetModuleAtIndex(0).GetFileSpec()) 255 self.assertEqual(mod_path, exe_inside) 256 self.check_all(process, self._x86_64_pid, 257 self._x86_64_regions, "a.out") 258 259 self.dbg.DeleteTarget(target) 260 261 @skipIfLLVMTargetMissing("AArch64") 262 def test_aarch64_pac(self): 263 """Test that lldb can unwind stack for AArch64 elf core file with PAC enabled.""" 264 265 target = self.dbg.CreateTarget("linux-aarch64-pac.out") 266 self.assertTrue(target, VALID_TARGET) 267 process = target.LoadCore("linux-aarch64-pac.core") 268 269 self.check_all(process, self._aarch64_pac_pid, self._aarch64_regions, "a.out") 270 271 self.dbg.DeleteTarget(target) 272 273 @skipIfLLVMTargetMissing("AArch64") 274 @expectedFailureAll(archs=["aarch64"], oslist=["freebsd"], 275 bugnumber="llvm.org/pr49415") 276 def test_aarch64_regs(self): 277 # check 64 bit ARM core files 278 target = self.dbg.CreateTarget(None) 279 self.assertTrue(target, VALID_TARGET) 280 process = target.LoadCore("linux-aarch64-neon.core") 281 282 values = {} 283 values["x1"] = "0x000000000000002f" 284 values["w1"] = "0x0000002f" 285 values["fp"] = "0x0000007fc5dd7f20" 286 values["lr"] = "0x0000000000400180" 287 values["sp"] = "0x0000007fc5dd7f00" 288 values["pc"] = "0x000000000040014c" 289 values["v0"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 290 values["v1"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xf8 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 291 values["v2"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 292 values["v3"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 293 values["v4"] = "{0x00 0x00 0x90 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 294 values["v5"] = "{0x00 0x00 0xb0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 295 values["v6"] = "{0x00 0x00 0xd0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 296 values["v7"] = "{0x00 0x00 0xf0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 297 values["v8"] = "{0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11}" 298 values["v27"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 299 values["v28"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 300 values["v31"] = "{0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30}" 301 values["s2"] = "0" 302 values["s3"] = "0" 303 values["s4"] = "4.5" 304 values["s5"] = "5.5" 305 values["s6"] = "6.5" 306 values["s7"] = "7.5" 307 values["s8"] = "1.14437e-28" 308 values["s30"] = "0" 309 values["s31"] = "6.40969e-10" 310 values["d0"] = "0.5" 311 values["d1"] = "1.5" 312 values["d2"] = "2.5" 313 values["d3"] = "3.5" 314 values["d4"] = "5.35161536149201e-315" 315 values["d5"] = "5.36197666906508e-315" 316 values["d6"] = "5.37233797663815e-315" 317 values["d7"] = "5.38269928421123e-315" 318 values["d8"] = "1.80107573659442e-226" 319 values["d30"] = "0" 320 values["d31"] = "1.39804328609529e-76" 321 values["fpsr"] = "0x00000000" 322 values["fpcr"] = "0x00000000" 323 324 for regname, value in values.items(): 325 self.expect("register read {}".format(regname), 326 substrs=["{} = {}".format(regname, value)]) 327 328 self.expect("register read --all") 329 330 @skipIfLLVMTargetMissing("AArch64") 331 @expectedFailureAll(archs=["aarch64"], oslist=["freebsd"], 332 bugnumber="llvm.org/pr49415") 333 def test_aarch64_sve_regs_fpsimd(self): 334 # check 64 bit ARM core files 335 target = self.dbg.CreateTarget(None) 336 self.assertTrue(target, VALID_TARGET) 337 process = target.LoadCore("linux-aarch64-sve-fpsimd.core") 338 339 values = {} 340 values["x1"] = "0x000000000000002f" 341 values["w1"] = "0x0000002f" 342 values["fp"] = "0x0000ffffcbad8d50" 343 values["lr"] = "0x0000000000400180" 344 values["sp"] = "0x0000ffffcbad8d30" 345 values["pc"] = "0x000000000040014c" 346 values["cpsr"] = "0x00001000" 347 values["v0"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 348 values["v1"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xf8 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 349 values["v2"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 350 values["v3"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 351 values["v4"] = "{0x00 0x00 0x90 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 352 values["v5"] = "{0x00 0x00 0xb0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 353 values["v6"] = "{0x00 0x00 0xd0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 354 values["v7"] = "{0x00 0x00 0xf0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 355 values["v8"] = "{0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11}" 356 values["v27"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 357 values["v28"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 358 values["v31"] = "{0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30}" 359 values["s2"] = "0" 360 values["s3"] = "0" 361 values["s4"] = "4.5" 362 values["s5"] = "5.5" 363 values["s6"] = "6.5" 364 values["s7"] = "7.5" 365 values["s8"] = "1.14437e-28" 366 values["s30"] = "0" 367 values["s31"] = "6.40969e-10" 368 values["d0"] = "0.5" 369 values["d1"] = "1.5" 370 values["d2"] = "2.5" 371 values["d3"] = "3.5" 372 values["d4"] = "5.35161536149201e-315" 373 values["d5"] = "5.36197666906508e-315" 374 values["d6"] = "5.37233797663815e-315" 375 values["d7"] = "5.38269928421123e-315" 376 values["d8"] = "1.80107573659442e-226" 377 values["d30"] = "0" 378 values["d31"] = "1.39804328609529e-76" 379 values["fpsr"] = "0x00000000" 380 values["fpcr"] = "0x00000000" 381 values["vg"] = "0x0000000000000004" 382 values["z0"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 383 values["z1"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xf8 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 384 values["z2"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 385 values["z3"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 386 values["z4"] = "{0x00 0x00 0x90 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 387 values["z5"] = "{0x00 0x00 0xb0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 388 values["z6"] = "{0x00 0x00 0xd0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 389 values["z7"] = "{0x00 0x00 0xf0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 390 values["z8"] = "{0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 391 values["z27"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 392 values["z28"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 393 values["z31"] = "{0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 394 values["p0"] = "{0x00 0x00 0x00 0x00}" 395 values["p1"] = "{0x00 0x00 0x00 0x00}" 396 values["p2"] = "{0x00 0x00 0x00 0x00}" 397 values["p4"] = "{0x00 0x00 0x00 0x00}" 398 values["p3"] = "{0x00 0x00 0x00 0x00}" 399 values["p6"] = "{0x00 0x00 0x00 0x00}" 400 values["p5"] = "{0x00 0x00 0x00 0x00}" 401 values["p7"] = "{0x00 0x00 0x00 0x00}" 402 values["p8"] = "{0x00 0x00 0x00 0x00}" 403 values["p9"] = "{0x00 0x00 0x00 0x00}" 404 values["p11"] = "{0x00 0x00 0x00 0x00}" 405 values["p10"] = "{0x00 0x00 0x00 0x00}" 406 values["p12"] = "{0x00 0x00 0x00 0x00}" 407 values["p13"] = "{0x00 0x00 0x00 0x00}" 408 values["p14"] = "{0x00 0x00 0x00 0x00}" 409 values["p15"] = "{0x00 0x00 0x00 0x00}" 410 values["ffr"] = "{0x00 0x00 0x00 0x00}" 411 412 for regname, value in values.items(): 413 self.expect("register read {}".format(regname), 414 substrs=["{} = {}".format(regname, value)]) 415 416 self.expect("register read --all") 417 418 @skipIfLLVMTargetMissing("AArch64") 419 def test_aarch64_sve_regs_full(self): 420 # check 64 bit ARM core files 421 target = self.dbg.CreateTarget(None) 422 self.assertTrue(target, VALID_TARGET) 423 process = target.LoadCore("linux-aarch64-sve-full.core") 424 425 values = {} 426 values["fp"] = "0x0000fffffc1ff4f0" 427 values["lr"] = "0x0000000000400170" 428 values["sp"] = "0x0000fffffc1ff4d0" 429 values["pc"] = "0x000000000040013c" 430 values["v0"] = "{0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40}" 431 values["v1"] = "{0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41}" 432 values["v2"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 433 values["v3"] = "{0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41}" 434 values["s0"] = "7.5" 435 values["s1"] = "11.5" 436 values["s2"] = "0" 437 values["s3"] = "15.5" 438 values["d0"] = "65536.0158538818" 439 values["d1"] = "1572864.25476074" 440 values["d2"] = "0" 441 values["d3"] = "25165828.0917969" 442 values["vg"] = "0x0000000000000004" 443 values["z0"] = "{0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40 0x00 0x00 0xf0 0x40}" 444 values["z1"] = "{0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41 0x00 0x00 0x38 0x41}" 445 values["z2"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 446 values["z3"] = "{0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41 0x00 0x00 0x78 0x41}" 447 values["p0"] = "{0x11 0x11 0x11 0x11}" 448 values["p1"] = "{0x11 0x11 0x11 0x11}" 449 values["p2"] = "{0x00 0x00 0x00 0x00}" 450 values["p3"] = "{0x11 0x11 0x11 0x11}" 451 values["p4"] = "{0x00 0x00 0x00 0x00}" 452 453 for regname, value in values.items(): 454 self.expect("register read {}".format(regname), 455 substrs=["{} = {}".format(regname, value)]) 456 457 self.expect("register read --all") 458 459 @skipIfLLVMTargetMissing("AArch64") 460 def test_aarch64_pac_regs(self): 461 # Test AArch64/Linux Pointer Authenication register read 462 target = self.dbg.CreateTarget(None) 463 self.assertTrue(target, VALID_TARGET) 464 process = target.LoadCore("linux-aarch64-pac.core") 465 466 values = {"data_mask": "0x007f00000000000", "code_mask": "0x007f00000000000"} 467 468 for regname, value in values.items(): 469 self.expect("register read {}".format(regname), 470 substrs=["{} = {}".format(regname, value)]) 471 472 self.expect("register read --all") 473 474 @skipIfLLVMTargetMissing("ARM") 475 def test_arm_core(self): 476 # check 32 bit ARM core file 477 target = self.dbg.CreateTarget(None) 478 self.assertTrue(target, VALID_TARGET) 479 process = target.LoadCore("linux-arm.core") 480 481 values = {} 482 values["r0"] = "0x00000000" 483 values["r1"] = "0x00000001" 484 values["r2"] = "0x00000002" 485 values["r3"] = "0x00000003" 486 values["r4"] = "0x00000004" 487 values["r5"] = "0x00000005" 488 values["r6"] = "0x00000006" 489 values["r7"] = "0x00000007" 490 values["r8"] = "0x00000008" 491 values["r9"] = "0x00000009" 492 values["r10"] = "0x0000000a" 493 values["r11"] = "0x0000000b" 494 values["r12"] = "0x0000000c" 495 values["sp"] = "0x0000000d" 496 values["lr"] = "0x0000000e" 497 values["pc"] = "0x0000000f" 498 values["cpsr"] = "0x00000010" 499 for regname, value in values.items(): 500 self.expect("register read {}".format(regname), 501 substrs=["{} = {}".format(regname, value)]) 502 503 self.expect("register read --all") 504 505 def check_memory_regions(self, process, region_count): 506 region_list = process.GetMemoryRegions() 507 self.assertEqual(region_list.GetSize(), region_count) 508 509 region = lldb.SBMemoryRegionInfo() 510 511 # Check we have the right number of regions. 512 self.assertEqual(region_list.GetSize(), region_count) 513 514 # Check that getting a region beyond the last in the list fails. 515 self.assertFalse( 516 region_list.GetMemoryRegionAtIndex( 517 region_count, region)) 518 519 # Check each region is valid. 520 for i in range(region_list.GetSize()): 521 # Check we can actually get this region. 522 self.assertTrue(region_list.GetMemoryRegionAtIndex(i, region)) 523 524 # Every region in the list should be mapped. 525 self.assertTrue(region.IsMapped()) 526 527 # Test the address at the start of a region returns it's enclosing 528 # region. 529 begin_address = region.GetRegionBase() 530 region_at_begin = lldb.SBMemoryRegionInfo() 531 error = process.GetMemoryRegionInfo(begin_address, region_at_begin) 532 self.assertEqual(region, region_at_begin) 533 534 # Test an address in the middle of a region returns it's enclosing 535 # region. 536 middle_address = (region.GetRegionBase() + 537 region.GetRegionEnd()) // 2 538 region_at_middle = lldb.SBMemoryRegionInfo() 539 error = process.GetMemoryRegionInfo( 540 middle_address, region_at_middle) 541 self.assertEqual(region, region_at_middle) 542 543 # Test the address at the end of a region returns it's enclosing 544 # region. 545 end_address = region.GetRegionEnd() - 1 546 region_at_end = lldb.SBMemoryRegionInfo() 547 error = process.GetMemoryRegionInfo(end_address, region_at_end) 548 self.assertEqual(region, region_at_end) 549 550 # Check that quering the end address does not return this region but 551 # the next one. 552 next_region = lldb.SBMemoryRegionInfo() 553 error = process.GetMemoryRegionInfo( 554 region.GetRegionEnd(), next_region) 555 self.assertNotEqual(region, next_region) 556 self.assertEqual( 557 region.GetRegionEnd(), 558 next_region.GetRegionBase()) 559 560 # Check that query beyond the last region returns an unmapped region 561 # that ends at LLDB_INVALID_ADDRESS 562 last_region = lldb.SBMemoryRegionInfo() 563 region_list.GetMemoryRegionAtIndex(region_count - 1, last_region) 564 end_region = lldb.SBMemoryRegionInfo() 565 error = process.GetMemoryRegionInfo( 566 last_region.GetRegionEnd(), end_region) 567 self.assertFalse(end_region.IsMapped()) 568 self.assertEqual( 569 last_region.GetRegionEnd(), 570 end_region.GetRegionBase()) 571 self.assertEqual(end_region.GetRegionEnd(), lldb.LLDB_INVALID_ADDRESS) 572 573 def check_state(self, process): 574 with open(os.devnull) as devnul: 575 # sanitize test output 576 self.dbg.SetOutputFileHandle(devnul, False) 577 self.dbg.SetErrorFileHandle(devnul, False) 578 579 self.assertTrue(process.is_stopped) 580 581 # Process.Continue 582 error = process.Continue() 583 self.assertFalse(error.Success()) 584 self.assertTrue(process.is_stopped) 585 586 # Thread.StepOut 587 thread = process.GetSelectedThread() 588 thread.StepOut() 589 self.assertTrue(process.is_stopped) 590 591 # command line 592 self.dbg.HandleCommand('s') 593 self.assertTrue(process.is_stopped) 594 self.dbg.HandleCommand('c') 595 self.assertTrue(process.is_stopped) 596 597 # restore file handles 598 self.dbg.SetOutputFileHandle(None, False) 599 self.dbg.SetErrorFileHandle(None, False) 600 601 def check_stack(self, process, pid, thread_name): 602 thread = process.GetSelectedThread() 603 self.assertTrue(thread) 604 self.assertEqual(thread.GetThreadID(), pid) 605 self.assertEqual(thread.GetName(), thread_name) 606 backtrace = ["bar", "foo", "_start"] 607 self.assertEqual(thread.GetNumFrames(), len(backtrace)) 608 for i in range(len(backtrace)): 609 frame = thread.GetFrameAtIndex(i) 610 self.assertTrue(frame) 611 self.assertEqual(frame.GetFunctionName(), backtrace[i]) 612 self.assertEqual(frame.GetLineEntry().GetLine(), 613 line_number("main.c", "Frame " + backtrace[i])) 614 self.assertEqual( 615 frame.FindVariable("F").GetValueAsUnsigned(), ord( 616 backtrace[i][0])) 617 618 def check_all(self, process, pid, region_count, thread_name): 619 self.assertTrue(process, PROCESS_IS_VALID) 620 self.assertEqual(process.GetNumThreads(), 1) 621 self.assertEqual(process.GetProcessID(), pid) 622 623 self.check_state(process) 624 625 self.check_stack(process, pid, thread_name) 626 627 self.check_memory_regions(process, region_count) 628 629 def do_test(self, filename, pid, region_count, thread_name): 630 target = self.dbg.CreateTarget(filename + ".out") 631 process = target.LoadCore(filename + ".core") 632 633 self.check_all(process, pid, region_count, thread_name) 634 635 self.dbg.DeleteTarget(target) 636 637 638def replace_path(binary, replace_from, replace_to): 639 src = replace_from.encode() 640 dst = replace_to.encode() 641 dst += b"\0" * (len(src) - len(dst)) 642 return binary.replace(src, dst) 643