1 /* $NetBSD: t_ptrace_amd64_wait.h,v 1.10 2019/05/10 16:24:35 mgorny Exp $ */ 2 3 /*- 4 * Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #if defined(__x86_64__) 30 31 /// ---------------------------------------------------------------------------- 32 33 ATF_TC(x86_64_regs1); 34 ATF_TC_HEAD(x86_64_regs1, tc) 35 { 36 atf_tc_set_md_var(tc, "descr", 37 "Call PT_GETREGS and iterate over General Purpose registers"); 38 } 39 40 ATF_TC_BODY(x86_64_regs1, tc) 41 { 42 const int exitval = 5; 43 const int sigval = SIGSTOP; 44 pid_t child, wpid; 45 #if defined(TWAIT_HAVE_STATUS) 46 int status; 47 #endif 48 struct reg r; 49 50 DPRINTF("Before forking process PID=%d\n", getpid()); 51 SYSCALL_REQUIRE((child = fork()) != -1); 52 if (child == 0) { 53 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 54 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 55 56 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 57 FORKEE_ASSERT(raise(sigval) == 0); 58 59 DPRINTF("Before exiting of the child process\n"); 60 _exit(exitval); 61 } 62 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 63 64 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 65 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 66 67 validate_status_stopped(status, sigval); 68 69 DPRINTF("Call GETREGS for the child process\n"); 70 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 71 72 DPRINTF("RAX=%#" PRIxREGISTER "\n", r.regs[_REG_RAX]); 73 DPRINTF("RBX=%#" PRIxREGISTER "\n", r.regs[_REG_RBX]); 74 DPRINTF("RCX=%#" PRIxREGISTER "\n", r.regs[_REG_RCX]); 75 DPRINTF("RDX=%#" PRIxREGISTER "\n", r.regs[_REG_RDX]); 76 77 DPRINTF("RDI=%#" PRIxREGISTER "\n", r.regs[_REG_RDI]); 78 DPRINTF("RSI=%#" PRIxREGISTER "\n", r.regs[_REG_RSI]); 79 80 DPRINTF("GS=%#" PRIxREGISTER "\n", r.regs[_REG_GS]); 81 DPRINTF("FS=%#" PRIxREGISTER "\n", r.regs[_REG_FS]); 82 DPRINTF("ES=%#" PRIxREGISTER "\n", r.regs[_REG_ES]); 83 DPRINTF("DS=%#" PRIxREGISTER "\n", r.regs[_REG_DS]); 84 DPRINTF("CS=%#" PRIxREGISTER "\n", r.regs[_REG_CS]); 85 DPRINTF("SS=%#" PRIxREGISTER "\n", r.regs[_REG_SS]); 86 87 DPRINTF("RSP=%#" PRIxREGISTER "\n", r.regs[_REG_RSP]); 88 DPRINTF("RIP=%#" PRIxREGISTER "\n", r.regs[_REG_RIP]); 89 90 DPRINTF("RFLAGS=%#" PRIxREGISTER "\n", r.regs[_REG_RFLAGS]); 91 92 DPRINTF("R8=%#" PRIxREGISTER "\n", r.regs[_REG_R8]); 93 DPRINTF("R9=%#" PRIxREGISTER "\n", r.regs[_REG_R9]); 94 DPRINTF("R10=%#" PRIxREGISTER "\n", r.regs[_REG_R10]); 95 DPRINTF("R11=%#" PRIxREGISTER "\n", r.regs[_REG_R11]); 96 DPRINTF("R12=%#" PRIxREGISTER "\n", r.regs[_REG_R12]); 97 DPRINTF("R13=%#" PRIxREGISTER "\n", r.regs[_REG_R13]); 98 DPRINTF("R14=%#" PRIxREGISTER "\n", r.regs[_REG_R14]); 99 DPRINTF("R15=%#" PRIxREGISTER "\n", r.regs[_REG_R15]); 100 101 DPRINTF("Before resuming the child process where it left off and " 102 "without signal to be sent\n"); 103 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 104 105 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 106 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 107 108 validate_status_exited(status, exitval); 109 110 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 111 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 112 } 113 114 ATF_TC(x86_64_regs_gp_read); 115 ATF_TC_HEAD(x86_64_regs_gp_read, tc) 116 { 117 atf_tc_set_md_var(tc, "descr", 118 "Set general-purpose reg values from debugged program and read " 119 "them via PT_GETREGS, comparing values against expected."); 120 } 121 122 ATF_TC_BODY(x86_64_regs_gp_read, tc) 123 { 124 const int exitval = 5; 125 pid_t child, wpid; 126 #if defined(TWAIT_HAVE_STATUS) 127 const int sigval = SIGTRAP; 128 int status; 129 #endif 130 struct reg gpr; 131 132 const uint64_t rax = 0x0001020304050607; 133 const uint64_t rbx = 0x1011121314151617; 134 const uint64_t rcx = 0x2021222324252627; 135 const uint64_t rdx = 0x3031323334353637; 136 const uint64_t rsi = 0x4041424344454647; 137 const uint64_t rdi = 0x5051525354555657; 138 const uint64_t rsp = 0x6061626364656667; 139 const uint64_t rbp = 0x7071727374757677; 140 141 DPRINTF("Before forking process PID=%d\n", getpid()); 142 SYSCALL_REQUIRE((child = fork()) != -1); 143 if (child == 0) { 144 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 145 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 146 147 DPRINTF("Before running assembly from child\n"); 148 149 __asm__ __volatile__( 150 /* rbp & rbp are a bit tricky, we must not clobber them */ 151 "movq %%rsp, %%r8\n\t" 152 "movq %%rbp, %%r9\n\t" 153 "movq %6, %%rsp\n\t" 154 "movq %7, %%rbp\n\t" 155 "\n\t" 156 "int3\n\t" 157 "\n\t" 158 "movq %%r8, %%rsp\n\t" 159 "movq %%r9, %%rbp\n\t" 160 : 161 : "a"(rax), "b"(rbx), "c"(rcx), "d"(rdx), "S"(rsi), "D"(rdi), 162 "i"(rsp), "i"(rbp) 163 : "%r8", "%r9" 164 ); 165 166 DPRINTF("Before exiting of the child process\n"); 167 _exit(exitval); 168 } 169 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 170 171 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 172 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 173 174 validate_status_stopped(status, sigval); 175 176 DPRINTF("Call GETREGS for the child process\n"); 177 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 178 179 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RAX], rax); 180 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBX], rbx); 181 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RCX], rcx); 182 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDX], rdx); 183 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSI], rsi); 184 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDI], rdi); 185 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSP], rsp); 186 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBP], rbp); 187 188 DPRINTF("Before resuming the child process where it left off and " 189 "without signal to be sent\n"); 190 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 191 192 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 193 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 194 195 validate_status_exited(status, exitval); 196 197 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 198 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 199 } 200 201 ATF_TC(x86_64_regs_gp_write); 202 ATF_TC_HEAD(x86_64_regs_gp_write, tc) 203 { 204 atf_tc_set_md_var(tc, "descr", 205 "Set general-purpose reg values into a debugged program via " 206 "PT_SETREGS and compare the result against expected."); 207 } 208 209 ATF_TC_BODY(x86_64_regs_gp_write, tc) 210 { 211 const int exitval = 5; 212 pid_t child, wpid; 213 #if defined(TWAIT_HAVE_STATUS) 214 const int sigval = SIGTRAP; 215 int status; 216 #endif 217 struct reg gpr; 218 219 const uint64_t rax = 0x0001020304050607; 220 const uint64_t rbx = 0x1011121314151617; 221 const uint64_t rcx = 0x2021222324252627; 222 const uint64_t rdx = 0x3031323334353637; 223 const uint64_t rsi = 0x4041424344454647; 224 const uint64_t rdi = 0x5051525354555657; 225 const uint64_t rsp = 0x6061626364656667; 226 const uint64_t rbp = 0x7071727374757677; 227 228 DPRINTF("Before forking process PID=%d\n", getpid()); 229 SYSCALL_REQUIRE((child = fork()) != -1); 230 if (child == 0) { 231 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 232 uint64_t v_rax, v_rbx, v_rcx, v_rdx, v_rsi, v_rdi, v_rsp, v_rbp; 233 234 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 235 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 236 237 DPRINTF("Before running assembly from child\n"); 238 239 __asm__ __volatile__( 240 /* save rsp & rbp */ 241 "movq %%rsp, %4\n\t" 242 "movq %%rbp, %5\n\t" 243 "\n\t" 244 /* fill registers with clobber pattern */ 245 "movq %8, %%rax\n\t" 246 "movq %8, %%rbx\n\t" 247 "movq %8, %%rcx\n\t" 248 "movq %8, %%rdx\n\t" 249 "movq %8, %%rsp\n\t" 250 "movq %8, %%rbp\n\t" 251 "movq %8, %%rsi\n\t" 252 "movq %8, %%rdi\n\t" 253 "\n\t" 254 "int3\n\t" 255 "\n\t" 256 /* swap saved & current rsp & rbp */ 257 "xchgq %%rsp, %4\n\t" 258 "xchgq %%rbp, %5\n\t" 259 : "=a"(v_rax), "=b"(v_rbx), "=c"(v_rcx), "=d"(v_rdx), "=r"(v_rsp), 260 "=r"(v_rbp), "=S"(v_rsi), "=D"(v_rdi) 261 : "g"(fill) 262 : 263 ); 264 265 FORKEE_ASSERT_EQ(v_rax, rax); 266 FORKEE_ASSERT_EQ(v_rbx, rbx); 267 FORKEE_ASSERT_EQ(v_rcx, rcx); 268 FORKEE_ASSERT_EQ(v_rdx, rdx); 269 FORKEE_ASSERT_EQ(v_rsi, rsi); 270 FORKEE_ASSERT_EQ(v_rdi, rdi); 271 FORKEE_ASSERT_EQ(v_rsp, rsp); 272 FORKEE_ASSERT_EQ(v_rbp, rbp); 273 274 DPRINTF("Before exiting of the child process\n"); 275 _exit(exitval); 276 } 277 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 278 279 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 280 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 281 282 validate_status_stopped(status, sigval); 283 284 DPRINTF("Call GETREGS for the child process\n"); 285 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 286 287 gpr.regs[_REG_RAX] = rax; 288 gpr.regs[_REG_RBX] = rbx; 289 gpr.regs[_REG_RCX] = rcx; 290 gpr.regs[_REG_RDX] = rdx; 291 gpr.regs[_REG_RSI] = rsi; 292 gpr.regs[_REG_RDI] = rdi; 293 gpr.regs[_REG_RSP] = rsp; 294 gpr.regs[_REG_RBP] = rbp; 295 296 DPRINTF("Call SETREGS for the child process\n"); 297 SYSCALL_REQUIRE(ptrace(PT_SETREGS, child, &gpr, 0) != -1); 298 299 DPRINTF("Before resuming the child process where it left off and " 300 "without signal to be sent\n"); 301 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 302 303 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 304 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 305 306 validate_status_exited(status, exitval); 307 308 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 309 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 310 } 311 312 ATF_TC(x86_64_regs_r8_read); 313 ATF_TC_HEAD(x86_64_regs_r8_read, tc) 314 { 315 atf_tc_set_md_var(tc, "descr", 316 "Set r8..r15 reg values from debugged program and read " 317 "them via PT_GETREGS, comparing values against expected."); 318 } 319 320 ATF_TC_BODY(x86_64_regs_r8_read, tc) 321 { 322 const int exitval = 5; 323 pid_t child, wpid; 324 #if defined(TWAIT_HAVE_STATUS) 325 const int sigval = SIGTRAP; 326 int status; 327 #endif 328 struct reg gpr; 329 330 const uint64_t r8[] = { 331 0x0001020304050607, 332 0x1011121314151617, 333 0x2021222324252627, 334 0x3031323334353637, 335 0x4041424344454647, 336 0x5051525354555657, 337 0x6061626364656667, 338 0x7071727374757677, 339 }; 340 341 DPRINTF("Before forking process PID=%d\n", getpid()); 342 SYSCALL_REQUIRE((child = fork()) != -1); 343 if (child == 0) { 344 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 345 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 346 347 DPRINTF("Before running assembly from child\n"); 348 349 __asm__ __volatile__( 350 "movq 0x00(%%rbx), %%r8\n\t" 351 "movq 0x08(%%rbx), %%r9\n\t" 352 "movq 0x10(%%rbx), %%r10\n\t" 353 "movq 0x18(%%rbx), %%r11\n\t" 354 "movq 0x20(%%rbx), %%r12\n\t" 355 "movq 0x28(%%rbx), %%r13\n\t" 356 "movq 0x30(%%rbx), %%r14\n\t" 357 "movq 0x38(%%rbx), %%r15\n\t" 358 "int3\n\t" 359 : 360 : "b"(r8) 361 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 362 ); 363 364 DPRINTF("Before exiting of the child process\n"); 365 _exit(exitval); 366 } 367 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 368 369 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 370 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 371 372 validate_status_stopped(status, sigval); 373 374 DPRINTF("Call GETREGS for the child process\n"); 375 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 376 377 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R8], r8[0]); 378 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R9], r8[1]); 379 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R10], r8[2]); 380 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R11], r8[3]); 381 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R12], r8[4]); 382 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R13], r8[5]); 383 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R14], r8[6]); 384 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R15], r8[7]); 385 386 DPRINTF("Before resuming the child process where it left off and " 387 "without signal to be sent\n"); 388 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 389 390 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 391 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 392 393 validate_status_exited(status, exitval); 394 395 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 396 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 397 } 398 399 ATF_TC(x86_64_regs_r8_write); 400 ATF_TC_HEAD(x86_64_regs_r8_write, tc) 401 { 402 atf_tc_set_md_var(tc, "descr", 403 "Set r8..r15 reg values into a debugged program via " 404 "PT_SETREGS and compare the result against expected."); 405 } 406 407 ATF_TC_BODY(x86_64_regs_r8_write, tc) 408 { 409 const int exitval = 5; 410 pid_t child, wpid; 411 #if defined(TWAIT_HAVE_STATUS) 412 const int sigval = SIGTRAP; 413 int status; 414 #endif 415 struct reg gpr; 416 417 const uint64_t r8[] = { 418 0x0001020304050607, 419 0x1011121314151617, 420 0x2021222324252627, 421 0x3031323334353637, 422 0x4041424344454647, 423 0x5051525354555657, 424 0x6061626364656667, 425 0x7071727374757677, 426 }; 427 428 DPRINTF("Before forking process PID=%d\n", getpid()); 429 SYSCALL_REQUIRE((child = fork()) != -1); 430 if (child == 0) { 431 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 432 uint64_t v_r8[8]; 433 434 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 435 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 436 437 DPRINTF("Before running assembly from child\n"); 438 439 __asm__ __volatile__( 440 /* fill registers with clobber pattern */ 441 "movq %1, %%r8\n\t" 442 "movq %1, %%r9\n\t" 443 "movq %1, %%r10\n\t" 444 "movq %1, %%r11\n\t" 445 "movq %1, %%r12\n\t" 446 "movq %1, %%r13\n\t" 447 "movq %1, %%r14\n\t" 448 "movq %1, %%r15\n\t" 449 "\n\t" 450 "int3\n\t" 451 "\n\t" 452 "movq %%r8, 0x00(%0)\n\t" 453 "movq %%r9, 0x08(%0)\n\t" 454 "movq %%r10, 0x10(%0)\n\t" 455 "movq %%r11, 0x18(%0)\n\t" 456 "movq %%r12, 0x20(%0)\n\t" 457 "movq %%r13, 0x28(%0)\n\t" 458 "movq %%r14, 0x30(%0)\n\t" 459 "movq %%r15, 0x38(%0)\n\t" 460 : 461 : "a"(v_r8), "m"(fill) 462 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 463 ); 464 465 FORKEE_ASSERT_EQ(v_r8[0], r8[0]); 466 FORKEE_ASSERT_EQ(v_r8[1], r8[1]); 467 FORKEE_ASSERT_EQ(v_r8[2], r8[2]); 468 FORKEE_ASSERT_EQ(v_r8[3], r8[3]); 469 FORKEE_ASSERT_EQ(v_r8[4], r8[4]); 470 FORKEE_ASSERT_EQ(v_r8[5], r8[5]); 471 FORKEE_ASSERT_EQ(v_r8[6], r8[6]); 472 FORKEE_ASSERT_EQ(v_r8[7], r8[7]); 473 474 DPRINTF("Before exiting of the child process\n"); 475 _exit(exitval); 476 } 477 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 478 479 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 480 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 481 482 validate_status_stopped(status, sigval); 483 484 DPRINTF("Call GETREGS for the child process\n"); 485 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 486 487 gpr.regs[_REG_R8] = r8[0]; 488 gpr.regs[_REG_R9] = r8[1]; 489 gpr.regs[_REG_R10] = r8[2]; 490 gpr.regs[_REG_R11] = r8[3]; 491 gpr.regs[_REG_R12] = r8[4]; 492 gpr.regs[_REG_R13] = r8[5]; 493 gpr.regs[_REG_R14] = r8[6]; 494 gpr.regs[_REG_R15] = r8[7]; 495 496 DPRINTF("Call SETREGS for the child process\n"); 497 SYSCALL_REQUIRE(ptrace(PT_SETREGS, child, &gpr, 0) != -1); 498 499 DPRINTF("Before resuming the child process where it left off and " 500 "without signal to be sent\n"); 501 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 502 503 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 504 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 505 506 validate_status_exited(status, exitval); 507 508 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 509 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 510 } 511 512 /// ---------------------------------------------------------------------------- 513 514 515 #define ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64() \ 516 ATF_TP_ADD_TC_HAVE_GPREGS(tp, x86_64_regs1); \ 517 ATF_TP_ADD_TC_HAVE_GPREGS(tp, x86_64_regs_gp_read); \ 518 ATF_TP_ADD_TC_HAVE_GPREGS(tp, x86_64_regs_gp_write); \ 519 ATF_TP_ADD_TC_HAVE_GPREGS(tp, x86_64_regs_r8_read); \ 520 ATF_TP_ADD_TC_HAVE_GPREGS(tp, x86_64_regs_r8_write); 521 #else 522 #define ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64() 523 #endif 524