]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait.c
MFC r314450,r313439:
[FreeBSD/stable/10.git] / contrib / netbsd-tests / kernel / arch / amd64 / t_ptrace_wait.c
1 /*      $NetBSD: t_ptrace_wait.c,v 1.11 2017/01/18 05:14:34 kamil Exp $ */
2
3 /*-
4  * Copyright (c) 2016 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 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: t_ptrace_wait.c,v 1.11 2017/01/18 05:14:34 kamil Exp $");
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/ptrace.h>
35 #include <sys/resource.h>
36 #include <sys/stat.h>
37 #include <sys/sysctl.h>
38 #include <sys/wait.h>
39 #include <machine/reg.h>
40 #include <x86/dbregs.h>
41 #include <err.h>
42 #include <errno.h>
43 #include <sched.h>
44 #include <signal.h>
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <strings.h>
49 #include <unistd.h>
50
51 #include <atf-c.h>
52
53 #include "h_macros.h"
54
55 #include "../../t_ptrace_wait.h"
56
57
58 #if defined(HAVE_GPREGS)
59 ATF_TC(regs1);
60 ATF_TC_HEAD(regs1, tc)
61 {
62         atf_tc_set_md_var(tc, "descr",
63             "Call PT_GETREGS and iterate over General Purpose registers");
64 }
65
66 ATF_TC_BODY(regs1, tc)
67 {
68         const int exitval = 5;
69         const int sigval = SIGSTOP;
70         pid_t child, wpid;
71 #if defined(TWAIT_HAVE_STATUS)
72         int status;
73 #endif
74         struct reg r;
75
76         printf("Before forking process PID=%d\n", getpid());
77         ATF_REQUIRE((child = fork()) != -1);
78         if (child == 0) {
79                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
80                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
81
82                 printf("Before raising %s from child\n", strsignal(sigval));
83                 FORKEE_ASSERT(raise(sigval) == 0);
84
85                 printf("Before exiting of the child process\n");
86                 _exit(exitval);
87         }
88         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
89
90         printf("Before calling %s() for the child\n", TWAIT_FNAME);
91         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
92
93         validate_status_stopped(status, sigval);
94
95         printf("Call GETREGS for the child process\n");
96         ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
97
98         printf("RAX=%#" PRIxREGISTER "\n", r.regs[_REG_RAX]);
99         printf("RBX=%#" PRIxREGISTER "\n", r.regs[_REG_RBX]);
100         printf("RCX=%#" PRIxREGISTER "\n", r.regs[_REG_RCX]);
101         printf("RDX=%#" PRIxREGISTER "\n", r.regs[_REG_RDX]);
102
103         printf("RDI=%#" PRIxREGISTER "\n", r.regs[_REG_RDI]);
104         printf("RSI=%#" PRIxREGISTER "\n", r.regs[_REG_RSI]);
105
106         printf("GS=%#" PRIxREGISTER "\n", r.regs[_REG_GS]);
107         printf("FS=%#" PRIxREGISTER "\n", r.regs[_REG_FS]);
108         printf("ES=%#" PRIxREGISTER "\n", r.regs[_REG_ES]);
109         printf("DS=%#" PRIxREGISTER "\n", r.regs[_REG_DS]);
110         printf("CS=%#" PRIxREGISTER "\n", r.regs[_REG_CS]);
111         printf("SS=%#" PRIxREGISTER "\n", r.regs[_REG_SS]);
112
113         printf("RSP=%#" PRIxREGISTER "\n", r.regs[_REG_RSP]);
114         printf("RIP=%#" PRIxREGISTER "\n", r.regs[_REG_RIP]);
115
116         printf("RFLAGS=%#" PRIxREGISTER "\n", r.regs[_REG_RFLAGS]);
117
118         printf("R8=%#" PRIxREGISTER "\n", r.regs[_REG_R8]);
119         printf("R9=%#" PRIxREGISTER "\n", r.regs[_REG_R9]);
120         printf("R10=%#" PRIxREGISTER "\n", r.regs[_REG_R10]);
121         printf("R11=%#" PRIxREGISTER "\n", r.regs[_REG_R11]);
122         printf("R12=%#" PRIxREGISTER "\n", r.regs[_REG_R12]);
123         printf("R13=%#" PRIxREGISTER "\n", r.regs[_REG_R13]);
124         printf("R14=%#" PRIxREGISTER "\n", r.regs[_REG_R14]);
125         printf("R15=%#" PRIxREGISTER "\n", r.regs[_REG_R15]);
126
127         printf("Before resuming the child process where it left off and "
128             "without signal to be sent\n");
129         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
130
131         printf("Before calling %s() for the child\n", TWAIT_FNAME);
132         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
133
134         validate_status_exited(status, exitval);
135
136         printf("Before calling %s() for the child\n", TWAIT_FNAME);
137         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
138 }
139 #endif
140
141 #if defined(__HAVE_PTRACE_WATCHPOINTS)
142 ATF_TC(watchpoint_count);
143 ATF_TC_HEAD(watchpoint_count, tc)
144 {
145         atf_tc_set_md_var(tc, "descr",
146             "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints");
147 }
148
149 ATF_TC_BODY(watchpoint_count, tc)
150 {
151         const int exitval = 5;
152         const int sigval = SIGSTOP;
153         pid_t child, wpid;
154 #if defined(TWAIT_HAVE_STATUS)
155         int status;
156 #endif
157         int N;
158
159         printf("Before forking process PID=%d\n", getpid());
160         ATF_REQUIRE((child = fork()) != -1);
161         if (child == 0) {
162                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
163                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
164
165                 printf("Before raising %s from child\n", strsignal(sigval));
166                 FORKEE_ASSERT(raise(sigval) == 0);
167
168                 printf("Before exiting of the child process\n");
169                 _exit(exitval);
170         }
171         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
172
173         printf("Before calling %s() for the child\n", TWAIT_FNAME);
174         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
175
176         validate_status_stopped(status, sigval);
177
178         printf("Call GETREGS for the child process\n");
179         ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
180         printf("Reported %d watchpoints\n", N);
181
182         ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
183
184         printf("Before resuming the child process where it left off and "
185             "without signal to be sent\n");
186         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
187
188         printf("Before calling %s() for the child\n", TWAIT_FNAME);
189         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
190
191         validate_status_exited(status, exitval);
192
193         printf("Before calling %s() for the child\n", TWAIT_FNAME);
194         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
195 }
196 #endif
197
198 #if defined(__HAVE_PTRACE_WATCHPOINTS)
199 ATF_TC(watchpoint_read);
200 ATF_TC_HEAD(watchpoint_read, tc)
201 {
202         atf_tc_set_md_var(tc, "descr",
203             "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints");
204 }
205
206 ATF_TC_BODY(watchpoint_read, tc)
207 {
208         const int exitval = 5;
209         const int sigval = SIGSTOP;
210         pid_t child, wpid;
211 #if defined(TWAIT_HAVE_STATUS)
212         int status;
213 #endif
214         int i, N;
215         struct ptrace_watchpoint pw;
216         int len = sizeof(pw);
217
218         printf("Before forking process PID=%d\n", getpid());
219         ATF_REQUIRE((child = fork()) != -1);
220         if (child == 0) {
221                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
222                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
223
224                 printf("Before raising %s from child\n", strsignal(sigval));
225                 FORKEE_ASSERT(raise(sigval) == 0);
226
227                 printf("Before exiting of the child process\n");
228                 _exit(exitval);
229         }
230         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
231
232         printf("Before calling %s() for the child\n", TWAIT_FNAME);
233         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
234
235         validate_status_stopped(status, sigval);
236
237         printf("Call GETREGS for the child process\n");
238         ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
239
240         ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
241
242         for (i = 0; i < N; i++) {
243                 printf("Before reading watchpoint %d\n", i);
244                 pw.pw_index = i;
245                 ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1);
246
247                 printf("struct ptrace {\n");
248                 printf("\t.pw_index=%d\n", pw.pw_index);
249                 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
250                 printf("\t.pw_type=%#x\n", pw.pw_type);
251                 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
252                 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
253                 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
254                 printf("}\n");
255         }
256
257         printf("Before resuming the child process where it left off and "
258             "without signal to be sent\n");
259         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
260
261         printf("Before calling %s() for the child\n", TWAIT_FNAME);
262         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
263
264         validate_status_exited(status, exitval);
265
266         printf("Before calling %s() for the child\n", TWAIT_FNAME);
267         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
268 }
269 #endif
270
271 #if defined(__HAVE_PTRACE_WATCHPOINTS)
272 ATF_TC(watchpoint_write_unmodified);
273 ATF_TC_HEAD(watchpoint_write_unmodified, tc)
274 {
275         atf_tc_set_md_var(tc, "descr",
276             "Call PT_COUNT_WATCHPOINTS and assert functional write of "
277             "unmodified data");
278 }
279
280 ATF_TC_BODY(watchpoint_write_unmodified, tc)
281 {
282         const int exitval = 5;
283         const int sigval = SIGSTOP;
284         pid_t child, wpid;
285 #if defined(TWAIT_HAVE_STATUS)
286         int status;
287 #endif
288         int i, N;
289         struct ptrace_watchpoint pw;
290         int len = sizeof(pw);
291
292         printf("Before forking process PID=%d\n", getpid());
293         ATF_REQUIRE((child = fork()) != -1);
294         if (child == 0) {
295                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
296                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
297
298                 printf("Before raising %s from child\n", strsignal(sigval));
299                 FORKEE_ASSERT(raise(sigval) == 0);
300
301                 printf("Before exiting of the child process\n");
302                 _exit(exitval);
303         }
304         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
305
306         printf("Before calling %s() for the child\n", TWAIT_FNAME);
307         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
308
309         validate_status_stopped(status, sigval);
310
311         printf("Call GETREGS for the child process\n");
312         ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
313
314         ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
315
316         for (i = 0; i < N; i++) {
317                 printf("Before reading watchpoint %d\n", i);
318                 pw.pw_index = i;
319                 ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1);
320
321                 printf("struct ptrace {\n");
322                 printf("\t.pw_index=%d\n", pw.pw_index);
323                 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
324                 printf("\t.pw_type=%#x\n", pw.pw_type);
325                 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
326                 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
327                 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
328                 printf("}\n");
329
330                 printf("Before writing watchpoint %d (unmodified)\n", i);
331                 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len)
332                     != -1);
333         }
334
335         printf("Before resuming the child process where it left off and "
336             "without signal to be sent\n");
337         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
338
339         printf("Before calling %s() for the child\n", TWAIT_FNAME);
340         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
341
342         validate_status_exited(status, exitval);
343
344         printf("Before calling %s() for the child\n", TWAIT_FNAME);
345         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
346 }
347 #endif
348
349 #if defined(__HAVE_PTRACE_WATCHPOINTS)
350 ATF_TC(watchpoint_trap_code0);
351 ATF_TC_HEAD(watchpoint_trap_code0, tc)
352 {
353         atf_tc_set_md_var(tc, "descr",
354             "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 0");
355 }
356
357 ATF_TC_BODY(watchpoint_trap_code0, tc)
358 {
359         const int exitval = 5;
360         const int sigval = SIGSTOP;
361         pid_t child, wpid;
362 #if defined(TWAIT_HAVE_STATUS)
363         int status;
364 #endif
365         const int i = 0;
366         struct ptrace_watchpoint pw;
367         int len = sizeof(pw);
368         int watchme = 1234;
369         struct ptrace_siginfo info;
370         memset(&info, 0, sizeof(info));
371
372         printf("Before forking process PID=%d\n", getpid());
373         ATF_REQUIRE((child = fork()) != -1);
374         if (child == 0) {
375                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
376                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
377
378                 printf("Before raising %s from child\n", strsignal(sigval));
379                 FORKEE_ASSERT(raise(sigval) == 0);
380
381                 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
382
383                 printf("Before exiting of the child process\n");
384                 _exit(exitval);
385         }
386         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
387
388         printf("Before calling %s() for the child\n", TWAIT_FNAME);
389         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
390
391         validate_status_stopped(status, sigval);
392
393         printf("Preparing code watchpoint trap %d\n", i);
394
395         pw.pw_index = i;
396         pw.pw_lwpid = 0;
397         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
398         pw.pw_md.md_address = (void *)check_happy;
399         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
400         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
401
402         printf("struct ptrace {\n");
403         printf("\t.pw_index=%d\n", pw.pw_index);
404         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
405         printf("\t.pw_type=%#x\n", pw.pw_type);
406         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
407         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
408         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
409         printf("}\n");
410
411         printf("Before writing watchpoint %d\n", i);
412         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
413
414         printf("Before resuming the child process where it left off "
415             "and without signal to be sent\n");
416         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
417
418         printf("Before calling %s() for the child\n", TWAIT_FNAME);
419         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
420
421         validate_status_stopped(status, SIGTRAP);
422
423         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
424         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
425
426         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
427         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
428             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
429             info.psi_siginfo.si_errno);
430
431         printf("Before checking siginfo_t\n");
432         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
433         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
434         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0);
435         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
436
437         pw.pw_md.md_address = NULL;
438         printf("Before writing watchpoint %d (disable it)\n", i);
439         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
440
441         printf("Before resuming the child process where it left off and "
442             "without signal to be sent\n");
443         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
444
445         printf("Before calling %s() for the child\n", TWAIT_FNAME);
446         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
447
448         validate_status_exited(status, exitval);
449
450         printf("Before calling %s() for the child\n", TWAIT_FNAME);
451         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
452 }
453 #endif
454
455 #if defined(__HAVE_PTRACE_WATCHPOINTS)
456 ATF_TC(watchpoint_trap_code1);
457 ATF_TC_HEAD(watchpoint_trap_code1, tc)
458 {
459         atf_tc_set_md_var(tc, "descr",
460             "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 1");
461 }
462
463 ATF_TC_BODY(watchpoint_trap_code1, tc)
464 {
465         const int exitval = 5;
466         const int sigval = SIGSTOP;
467         pid_t child, wpid;
468 #if defined(TWAIT_HAVE_STATUS)
469         int status;
470 #endif
471         const int i = 1;
472         struct ptrace_watchpoint pw;
473         int len = sizeof(pw);
474         int watchme = 1234;
475         struct ptrace_siginfo info;
476         memset(&info, 0, sizeof(info));
477
478         printf("Before forking process PID=%d\n", getpid());
479         ATF_REQUIRE((child = fork()) != -1);
480         if (child == 0) {
481                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
482                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
483
484                 printf("Before raising %s from child\n", strsignal(sigval));
485                 FORKEE_ASSERT(raise(sigval) == 0);
486
487                 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
488
489                 printf("Before exiting of the child process\n");
490                 _exit(exitval);
491         }
492         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
493
494         printf("Before calling %s() for the child\n", TWAIT_FNAME);
495         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
496
497         validate_status_stopped(status, sigval);
498
499         printf("Preparing code watchpoint trap %d\n", i);
500
501         pw.pw_index = i;
502         pw.pw_lwpid = 0;
503         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
504         pw.pw_md.md_address = (void *)check_happy;
505         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
506         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
507
508         printf("struct ptrace {\n");
509         printf("\t.pw_index=%d\n", pw.pw_index);
510         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
511         printf("\t.pw_type=%d\n", pw.pw_type);
512         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
513         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
514         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
515         printf("}\n");
516
517         printf("Before writing watchpoint %d\n", i);
518         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
519
520         printf("Before resuming the child process where it left off "
521             "and without signal to be sent\n");
522         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
523
524         printf("Before calling %s() for the child\n", TWAIT_FNAME);
525         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
526
527         validate_status_stopped(status, SIGTRAP);
528
529         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
530         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
531
532         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
533         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
534             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
535             info.psi_siginfo.si_errno);
536
537         printf("Before checking siginfo_t\n");
538         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
539         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
540         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1);
541         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
542
543         pw.pw_md.md_address = NULL;
544         printf("Before writing watchpoint %d (disable it)\n", i);
545         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
546
547         printf("Before resuming the child process where it left off and "
548             "without signal to be sent\n");
549         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
550
551         printf("Before calling %s() for the child\n", TWAIT_FNAME);
552         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
553
554         validate_status_exited(status, exitval);
555
556         printf("Before calling %s() for the child\n", TWAIT_FNAME);
557         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
558 }
559 #endif
560
561 #if defined(__HAVE_PTRACE_WATCHPOINTS)
562 ATF_TC(watchpoint_trap_code2);
563 ATF_TC_HEAD(watchpoint_trap_code2, tc)
564 {
565         atf_tc_set_md_var(tc, "descr",
566             "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 2");
567 }
568
569 ATF_TC_BODY(watchpoint_trap_code2, tc)
570 {
571         const int exitval = 5;
572         const int sigval = SIGSTOP;
573         pid_t child, wpid;
574 #if defined(TWAIT_HAVE_STATUS)
575         int status;
576 #endif
577         const int i = 2;
578         struct ptrace_watchpoint pw;
579         int len = sizeof(pw);
580         int watchme = 1234;
581         struct ptrace_siginfo info;
582         memset(&info, 0, sizeof(info));
583
584         printf("Before forking process PID=%d\n", getpid());
585         ATF_REQUIRE((child = fork()) != -1);
586         if (child == 0) {
587                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
588                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
589
590                 printf("Before raising %s from child\n", strsignal(sigval));
591                 FORKEE_ASSERT(raise(sigval) == 0);
592
593                 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
594
595                 printf("Before exiting of the child process\n");
596                 _exit(exitval);
597         }
598         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
599
600         printf("Before calling %s() for the child\n", TWAIT_FNAME);
601         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
602
603         validate_status_stopped(status, sigval);
604
605         printf("Preparing code watchpoint trap %d\n", i);
606
607         pw.pw_index = i;
608         pw.pw_lwpid = 0;
609         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
610         pw.pw_md.md_address = (void *)check_happy;
611         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
612         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
613
614         printf("struct ptrace {\n");
615         printf("\t.pw_index=%d\n", pw.pw_index);
616         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
617         printf("\t.pw_type=%#x\n", pw.pw_type);
618         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
619         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
620         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
621         printf("}\n");
622
623         printf("Before writing watchpoint %d\n", i);
624         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
625
626         printf("Before resuming the child process where it left off "
627             "and without signal to be sent\n");
628         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
629
630         printf("Before calling %s() for the child\n", TWAIT_FNAME);
631         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
632
633         validate_status_stopped(status, SIGTRAP);
634
635         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
636         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
637
638         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
639         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
640             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
641             info.psi_siginfo.si_errno);
642
643         printf("Before checking siginfo_t\n");
644         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
645         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
646         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2);
647         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
648
649         pw.pw_md.md_address = NULL;
650         printf("Before writing watchpoint %d (disable it)\n", i);
651         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
652
653         printf("Before resuming the child process where it left off and "
654             "without signal to be sent\n");
655         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
656
657         printf("Before calling %s() for the child\n", TWAIT_FNAME);
658         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
659
660         validate_status_exited(status, exitval);
661
662         printf("Before calling %s() for the child\n", TWAIT_FNAME);
663         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
664 }
665 #endif
666
667 #if defined(__HAVE_PTRACE_WATCHPOINTS)
668 ATF_TC(watchpoint_trap_code3);
669 ATF_TC_HEAD(watchpoint_trap_code3, tc)
670 {
671         atf_tc_set_md_var(tc, "descr",
672             "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 3");
673 }
674
675 ATF_TC_BODY(watchpoint_trap_code3, tc)
676 {
677         const int exitval = 5;
678         const int sigval = SIGSTOP;
679         pid_t child, wpid;
680 #if defined(TWAIT_HAVE_STATUS)
681         int status;
682 #endif
683         const int i = 3;
684         struct ptrace_watchpoint pw;
685         int len = sizeof(pw);
686         int watchme = 1234;
687         struct ptrace_siginfo info;
688         memset(&info, 0, sizeof(info));
689
690         printf("Before forking process PID=%d\n", getpid());
691         ATF_REQUIRE((child = fork()) != -1);
692         if (child == 0) {
693                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
694                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
695
696                 printf("Before raising %s from child\n", strsignal(sigval));
697                 FORKEE_ASSERT(raise(sigval) == 0);
698
699                 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
700
701                 printf("Before exiting of the child process\n");
702                 _exit(exitval);
703         }
704         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
705
706         printf("Before calling %s() for the child\n", TWAIT_FNAME);
707         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
708
709         validate_status_stopped(status, sigval);
710
711         printf("Preparing code watchpoint trap %d\n", i);
712
713         pw.pw_index = i;
714         pw.pw_lwpid = 0;
715         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
716         pw.pw_md.md_address = (void *)check_happy;
717         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
718         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
719
720         printf("struct ptrace {\n");
721         printf("\t.pw_index=%d\n", pw.pw_index);
722         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
723         printf("\t.pw_type=%#x\n", pw.pw_type);
724         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
725         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
726         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
727         printf("}\n");
728
729         printf("Before writing watchpoint %d\n", i);
730         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
731
732         printf("Before resuming the child process where it left off "
733             "and without signal to be sent\n");
734         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
735
736         printf("Before calling %s() for the child\n", TWAIT_FNAME);
737         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
738
739         validate_status_stopped(status, SIGTRAP);
740
741         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
742         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
743
744         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
745         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
746             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
747             info.psi_siginfo.si_errno);
748
749         printf("Before checking siginfo_t\n");
750         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
751         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
752         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3);
753         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
754
755         pw.pw_md.md_address = NULL;
756         printf("Before writing watchpoint %d (disable it)\n", i);
757         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
758
759         printf("Before resuming the child process where it left off and "
760             "without signal to be sent\n");
761         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
762
763         printf("Before calling %s() for the child\n", TWAIT_FNAME);
764         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
765
766         validate_status_exited(status, exitval);
767
768         printf("Before calling %s() for the child\n", TWAIT_FNAME);
769         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
770 }
771 #endif
772
773 #if defined(__HAVE_PTRACE_WATCHPOINTS)
774 ATF_TC(watchpoint_trap_data_write0);
775 ATF_TC_HEAD(watchpoint_trap_data_write0, tc)
776 {
777         atf_tc_set_md_var(tc, "descr",
778             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0");
779 }
780
781 ATF_TC_BODY(watchpoint_trap_data_write0, tc)
782 {
783         const int exitval = 5;
784         const int sigval = SIGSTOP;
785         pid_t child, wpid;
786 #if defined(TWAIT_HAVE_STATUS)
787         int status;
788 #endif
789         const int i = 0;
790         struct ptrace_watchpoint pw;
791         int len = sizeof(pw);
792         int watchme = 1234;
793         struct ptrace_siginfo info;
794         memset(&info, 0, sizeof(info));
795
796         printf("Before forking process PID=%d\n", getpid());
797         ATF_REQUIRE((child = fork()) != -1);
798         if (child == 0) {
799                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
800                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
801
802                 printf("Before raising %s from child\n", strsignal(sigval));
803                 FORKEE_ASSERT(raise(sigval) == 0);
804
805                 ++watchme;
806
807                 printf("Before exiting of the child process\n");
808                 _exit(exitval);
809         }
810         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
811
812         printf("Before calling %s() for the child\n", TWAIT_FNAME);
813         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
814
815         validate_status_stopped(status, sigval);
816
817         printf("Preparing code watchpoint trap %d\n", i);
818
819         pw.pw_index = 0;
820         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
821         pw.pw_md.md_address = &watchme;
822         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
823         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
824
825         printf("struct ptrace {\n");
826         printf("\t.pw_index=%d\n", pw.pw_index);
827         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
828         printf("\t.pw_type=%#x\n", pw.pw_type);
829         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
830         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
831         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
832         printf("}\n");
833
834         printf("Before writing watchpoint %d\n", i);
835         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
836
837         printf("Before resuming the child process where it left off "
838             "and without signal to be sent\n");
839         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
840
841         printf("Before calling %s() for the child\n", TWAIT_FNAME);
842         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
843
844         validate_status_stopped(status, SIGTRAP);
845
846         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
847         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
848
849         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
850         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
851             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
852             info.psi_siginfo.si_errno);
853
854         printf("Before checking siginfo_t\n");
855         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
856         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
857         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0);
858         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
859
860         printf("Before resuming the child process where it left off and "
861             "without signal to be sent\n");
862         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
863
864         printf("Before calling %s() for the child\n", TWAIT_FNAME);
865         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
866
867         validate_status_exited(status, exitval);
868
869         printf("Before calling %s() for the child\n", TWAIT_FNAME);
870         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
871 }
872 #endif
873
874 #if defined(__HAVE_PTRACE_WATCHPOINTS)
875 ATF_TC(watchpoint_trap_data_write1);
876 ATF_TC_HEAD(watchpoint_trap_data_write1, tc)
877 {
878         atf_tc_set_md_var(tc, "descr",
879             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1");
880 }
881
882 ATF_TC_BODY(watchpoint_trap_data_write1, tc)
883 {
884         const int exitval = 5;
885         const int sigval = SIGSTOP;
886         pid_t child, wpid;
887 #if defined(TWAIT_HAVE_STATUS)
888         int status;
889 #endif
890         const int i = 1;
891         struct ptrace_watchpoint pw;
892         int len = sizeof(pw);
893         int watchme = 1234;
894         struct ptrace_siginfo info;
895         memset(&info, 0, sizeof(info));
896
897         printf("Before forking process PID=%d\n", getpid());
898         ATF_REQUIRE((child = fork()) != -1);
899         if (child == 0) {
900                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
901                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
902
903                 printf("Before raising %s from child\n", strsignal(sigval));
904                 FORKEE_ASSERT(raise(sigval) == 0);
905
906                 ++watchme;
907
908                 printf("Before exiting of the child process\n");
909                 _exit(exitval);
910         }
911         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
912
913         printf("Before calling %s() for the child\n", TWAIT_FNAME);
914         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
915
916         validate_status_stopped(status, sigval);
917
918         printf("Preparing code watchpoint trap %d\n", i);
919
920         pw.pw_index = i;
921         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
922         pw.pw_md.md_address = &watchme;
923         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
924         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
925
926         printf("struct ptrace {\n");
927         printf("\t.pw_index=%d\n", pw.pw_index);
928         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
929         printf("\t.pw_type=%#x\n", pw.pw_type);
930         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
931         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
932         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
933         printf("}\n");
934
935         printf("Before writing watchpoint %d\n", i);
936         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
937
938         printf("Before resuming the child process where it left off "
939             "and without signal to be sent\n");
940         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
941
942         printf("Before calling %s() for the child\n", TWAIT_FNAME);
943         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
944
945         validate_status_stopped(status, SIGTRAP);
946
947         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
948         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
949
950         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
951         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
952             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
953             info.psi_siginfo.si_errno);
954
955         printf("Before checking siginfo_t\n");
956         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
957         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
958         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1);
959         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
960
961         printf("Before resuming the child process where it left off and "
962             "without signal to be sent\n");
963         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
964
965         printf("Before calling %s() for the child\n", TWAIT_FNAME);
966         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
967
968         validate_status_exited(status, exitval);
969
970         printf("Before calling %s() for the child\n", TWAIT_FNAME);
971         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
972 }
973 #endif
974
975 #if defined(__HAVE_PTRACE_WATCHPOINTS)
976 ATF_TC(watchpoint_trap_data_write2);
977 ATF_TC_HEAD(watchpoint_trap_data_write2, tc)
978 {
979         atf_tc_set_md_var(tc, "descr",
980             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2");
981 }
982
983 ATF_TC_BODY(watchpoint_trap_data_write2, tc)
984 {
985         const int exitval = 5;
986         const int sigval = SIGSTOP;
987         pid_t child, wpid;
988 #if defined(TWAIT_HAVE_STATUS)
989         int status;
990 #endif
991         const int i = 2;
992         struct ptrace_watchpoint pw;
993         int len = sizeof(pw);
994         int watchme = 1234;
995         struct ptrace_siginfo info;
996         memset(&info, 0, sizeof(info));
997
998         printf("Before forking process PID=%d\n", getpid());
999         ATF_REQUIRE((child = fork()) != -1);
1000         if (child == 0) {
1001                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1002                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1003
1004                 printf("Before raising %s from child\n", strsignal(sigval));
1005                 FORKEE_ASSERT(raise(sigval) == 0);
1006
1007                 ++watchme;
1008
1009                 printf("Before exiting of the child process\n");
1010                 _exit(exitval);
1011         }
1012         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1013
1014         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1015         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1016
1017         validate_status_stopped(status, sigval);
1018
1019         printf("Preparing code watchpoint trap %d\n", i);
1020
1021         pw.pw_index = i;
1022         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
1023         pw.pw_md.md_address = &watchme;
1024         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
1025         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1026
1027         printf("struct ptrace {\n");
1028         printf("\t.pw_index=%d\n", pw.pw_index);
1029         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1030         printf("\t.pw_type=%#x\n", pw.pw_type);
1031         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1032         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1033         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1034         printf("}\n");
1035
1036         printf("Before writing watchpoint %d\n", i);
1037         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1038
1039         printf("Before resuming the child process where it left off "
1040             "and without signal to be sent\n");
1041         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1042
1043         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1044         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1045
1046         validate_status_stopped(status, SIGTRAP);
1047
1048         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1049         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1050
1051         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1052         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1053             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1054             info.psi_siginfo.si_errno);
1055
1056         printf("Before checking siginfo_t\n");
1057         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1058         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1059         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2);
1060         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1061
1062         printf("Before resuming the child process where it left off and "
1063             "without signal to be sent\n");
1064         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1065
1066         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1067         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1068
1069         validate_status_exited(status, exitval);
1070
1071         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1072         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1073 }
1074 #endif
1075
1076
1077 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1078 ATF_TC(watchpoint_trap_data_write3);
1079 ATF_TC_HEAD(watchpoint_trap_data_write3, tc)
1080 {
1081         atf_tc_set_md_var(tc, "descr",
1082             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3");
1083 }
1084
1085 ATF_TC_BODY(watchpoint_trap_data_write3, tc)
1086 {
1087         const int exitval = 5;
1088         const int sigval = SIGSTOP;
1089         pid_t child, wpid;
1090 #if defined(TWAIT_HAVE_STATUS)
1091         int status;
1092 #endif
1093         const int i = 3;
1094         struct ptrace_watchpoint pw;
1095         int len = sizeof(pw);
1096         int watchme = 1234;
1097         struct ptrace_siginfo info;
1098         memset(&info, 0, sizeof(info));
1099
1100         printf("Before forking process PID=%d\n", getpid());
1101         ATF_REQUIRE((child = fork()) != -1);
1102         if (child == 0) {
1103                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1104                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1105
1106                 printf("Before raising %s from child\n", strsignal(sigval));
1107                 FORKEE_ASSERT(raise(sigval) == 0);
1108
1109                 ++watchme;
1110
1111                 printf("Before exiting of the child process\n");
1112                 _exit(exitval);
1113         }
1114         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1115
1116         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1117         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1118
1119         validate_status_stopped(status, sigval);
1120
1121         printf("Preparing code watchpoint trap %d\n", i);
1122
1123         pw.pw_index = i;
1124         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
1125         pw.pw_md.md_address = &watchme;
1126         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
1127         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1128
1129         printf("struct ptrace {\n");
1130         printf("\t.pw_index=%d\n", pw.pw_index);
1131         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1132         printf("\t.pw_type=%#x\n", pw.pw_type);
1133         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1134         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1135         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1136         printf("}\n");
1137
1138         printf("Before writing watchpoint %d\n", i);
1139         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1140
1141         printf("Before resuming the child process where it left off "
1142             "and without signal to be sent\n");
1143         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1144
1145         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1146         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1147
1148         validate_status_stopped(status, SIGTRAP);
1149
1150         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1151         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1152
1153         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1154         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1155             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1156             info.psi_siginfo.si_errno);
1157
1158         printf("Before checking siginfo_t\n");
1159         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1160         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1161         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3);
1162         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1163
1164         printf("Before resuming the child process where it left off and "
1165             "without signal to be sent\n");
1166         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1167
1168         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1169         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1170
1171         validate_status_exited(status, exitval);
1172
1173         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1174         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1175 }
1176 #endif
1177
1178 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1179 ATF_TC(watchpoint_trap_data_rw0);
1180 ATF_TC_HEAD(watchpoint_trap_data_rw0, tc)
1181 {
1182         atf_tc_set_md_var(tc, "descr",
1183             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0");
1184 }
1185
1186 ATF_TC_BODY(watchpoint_trap_data_rw0, tc)
1187 {
1188         const int exitval = 5;
1189         const int sigval = SIGSTOP;
1190         pid_t child, wpid;
1191 #if defined(TWAIT_HAVE_STATUS)
1192         int status;
1193 #endif
1194         const int i = 0;
1195         struct ptrace_watchpoint pw;
1196         int len = sizeof(pw);
1197         int watchme = 1234;
1198         struct ptrace_siginfo info;
1199         memset(&info, 0, sizeof(info));
1200
1201         printf("Before forking process PID=%d\n", getpid());
1202         ATF_REQUIRE((child = fork()) != -1);
1203         if (child == 0) {
1204                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1205                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1206
1207                 printf("Before raising %s from child\n", strsignal(sigval));
1208                 FORKEE_ASSERT(raise(sigval) == 0);
1209
1210                 printf("watchme=%d\n", watchme);
1211
1212                 printf("Before exiting of the child process\n");
1213                 _exit(exitval);
1214         }
1215         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1216
1217         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1218         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1219
1220         validate_status_stopped(status, sigval);
1221
1222         printf("Preparing code watchpoint trap %d\n", i);
1223
1224         pw.pw_index = i;
1225         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
1226         pw.pw_md.md_address = &watchme;
1227         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1228         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1229
1230         printf("struct ptrace {\n");
1231         printf("\t.pw_index=%d\n", pw.pw_index);
1232         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1233         printf("\t.pw_type=%#x\n", pw.pw_type);
1234         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1235         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1236         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1237         printf("}\n");
1238
1239         printf("Before writing watchpoint %d\n", i);
1240         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1241
1242         printf("Before resuming the child process where it left off "
1243             "and without signal to be sent\n");
1244         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1245
1246         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1247         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1248
1249         validate_status_stopped(status, SIGTRAP);
1250
1251         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1252         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1253
1254         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1255         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1256             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1257             info.psi_siginfo.si_errno);
1258
1259         printf("Before checking siginfo_t\n");
1260         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1261         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1262         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0);
1263         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1264
1265         printf("Before resuming the child process where it left off and "
1266             "without signal to be sent\n");
1267         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1268
1269         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1270         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1271
1272         validate_status_exited(status, exitval);
1273
1274         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1275         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1276 }
1277 #endif
1278
1279 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1280 ATF_TC(watchpoint_trap_data_rw1);
1281 ATF_TC_HEAD(watchpoint_trap_data_rw1, tc)
1282 {
1283         atf_tc_set_md_var(tc, "descr",
1284             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1");
1285 }
1286
1287 ATF_TC_BODY(watchpoint_trap_data_rw1, tc)
1288 {
1289         const int exitval = 5;
1290         const int sigval = SIGSTOP;
1291         pid_t child, wpid;
1292 #if defined(TWAIT_HAVE_STATUS)
1293         int status;
1294 #endif
1295         const int i = 1;
1296         struct ptrace_watchpoint pw;
1297         int len = sizeof(pw);
1298         int watchme = 1234;
1299         struct ptrace_siginfo info;
1300         memset(&info, 0, sizeof(info));
1301
1302         printf("Before forking process PID=%d\n", getpid());
1303         ATF_REQUIRE((child = fork()) != -1);
1304         if (child == 0) {
1305                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1306                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1307
1308                 printf("Before raising %s from child\n", strsignal(sigval));
1309                 FORKEE_ASSERT(raise(sigval) == 0);
1310
1311                 printf("watchme=%d\n", watchme);
1312
1313                 printf("Before exiting of the child process\n");
1314                 _exit(exitval);
1315         }
1316         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1317
1318         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1319         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1320
1321         validate_status_stopped(status, sigval);
1322
1323         printf("Preparing code watchpoint trap %d\n", i);
1324
1325         pw.pw_index = i;
1326         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
1327         pw.pw_md.md_address = &watchme;
1328         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1329         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1330
1331         printf("struct ptrace {\n");
1332         printf("\t.pw_index=%d\n", pw.pw_index);
1333         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1334         printf("\t.pw_type=%#x\n", pw.pw_type);
1335         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1336         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1337         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1338         printf("}\n");
1339
1340         printf("Before writing watchpoint %d\n", i);
1341         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1342
1343         printf("Before resuming the child process where it left off "
1344             "and without signal to be sent\n");
1345         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1346
1347         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1348         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1349
1350         validate_status_stopped(status, SIGTRAP);
1351
1352         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1353         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1354
1355         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1356         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1357             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1358             info.psi_siginfo.si_errno);
1359
1360         printf("Before checking siginfo_t\n");
1361         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1362         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1363         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1);
1364         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1365
1366         printf("Before resuming the child process where it left off and "
1367             "without signal to be sent\n");
1368         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1369
1370         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1371         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1372
1373         validate_status_exited(status, exitval);
1374
1375         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1376         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1377 }
1378 #endif
1379
1380 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1381 ATF_TC(watchpoint_trap_data_rw2);
1382 ATF_TC_HEAD(watchpoint_trap_data_rw2, tc)
1383 {
1384         atf_tc_set_md_var(tc, "descr",
1385             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2");
1386 }
1387
1388 ATF_TC_BODY(watchpoint_trap_data_rw2, tc)
1389 {
1390         const int exitval = 5;
1391         const int sigval = SIGSTOP;
1392         pid_t child, wpid;
1393 #if defined(TWAIT_HAVE_STATUS)
1394         int status;
1395 #endif
1396         const int i = 2;
1397         struct ptrace_watchpoint pw;
1398         int len = sizeof(pw);
1399         int watchme = 1234;
1400         struct ptrace_siginfo info;
1401         memset(&info, 0, sizeof(info));
1402
1403         printf("Before forking process PID=%d\n", getpid());
1404         ATF_REQUIRE((child = fork()) != -1);
1405         if (child == 0) {
1406                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1407                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1408
1409                 printf("Before raising %s from child\n", strsignal(sigval));
1410                 FORKEE_ASSERT(raise(sigval) == 0);
1411
1412                 printf("watchme=%d\n", watchme);
1413
1414                 printf("Before exiting of the child process\n");
1415                 _exit(exitval);
1416         }
1417         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1418
1419         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1420         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1421
1422         validate_status_stopped(status, sigval);
1423
1424         printf("Preparing code watchpoint trap %d\n", i);
1425
1426         pw.pw_index = i;
1427         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
1428         pw.pw_md.md_address = &watchme;
1429         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1430         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1431
1432         printf("struct ptrace {\n");
1433         printf("\t.pw_index=%d\n", pw.pw_index);
1434         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1435         printf("\t.pw_type=%#x\n", pw.pw_type);
1436         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1437         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1438         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1439         printf("}\n");
1440
1441         printf("Before writing watchpoint %d\n", i);
1442         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1443
1444         printf("Before resuming the child process where it left off "
1445             "and without signal to be sent\n");
1446         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1447
1448         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1449         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1450
1451         validate_status_stopped(status, SIGTRAP);
1452
1453         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1454         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1455
1456         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1457         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1458             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1459             info.psi_siginfo.si_errno);
1460
1461         printf("Before checking siginfo_t\n");
1462         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1463         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1464         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2);
1465         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1466
1467         printf("Before resuming the child process where it left off and "
1468             "without signal to be sent\n");
1469         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1470
1471         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1472         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1473
1474         validate_status_exited(status, exitval);
1475
1476         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1477         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1478 }
1479 #endif
1480
1481 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1482 ATF_TC(watchpoint_trap_data_rw3);
1483 ATF_TC_HEAD(watchpoint_trap_data_rw3, tc)
1484 {
1485         atf_tc_set_md_var(tc, "descr",
1486             "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3");
1487 }
1488
1489 ATF_TC_BODY(watchpoint_trap_data_rw3, tc)
1490 {
1491         const int exitval = 5;
1492         const int sigval = SIGSTOP;
1493         pid_t child, wpid;
1494 #if defined(TWAIT_HAVE_STATUS)
1495         int status;
1496 #endif
1497         const int i = 3;
1498         struct ptrace_watchpoint pw;
1499         int len = sizeof(pw);
1500         int watchme = 1234;
1501         struct ptrace_siginfo info;
1502         memset(&info, 0, sizeof(info));
1503
1504         printf("Before forking process PID=%d\n", getpid());
1505         ATF_REQUIRE((child = fork()) != -1);
1506         if (child == 0) {
1507                 printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1508                 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1509
1510                 printf("Before raising %s from child\n", strsignal(sigval));
1511                 FORKEE_ASSERT(raise(sigval) == 0);
1512
1513                 printf("watchme=%d\n", watchme);
1514
1515                 printf("Before exiting of the child process\n");
1516                 _exit(exitval);
1517         }
1518         printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1519
1520         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1521         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1522
1523         validate_status_stopped(status, sigval);
1524
1525         printf("Preparing code watchpoint trap %d\n", i);
1526
1527         pw.pw_index = i;
1528         pw.pw_type = PTRACE_PW_TYPE_DBREGS;
1529         pw.pw_md.md_address = &watchme;
1530         pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1531         pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1532
1533         printf("struct ptrace {\n");
1534         printf("\t.pw_index=%d\n", pw.pw_index);
1535         printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1536         printf("\t.pw_type=%#x\n", pw.pw_type);
1537         printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1538         printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1539         printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1540         printf("}\n");
1541
1542         printf("Before writing watchpoint %d\n", i);
1543         ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1544
1545         printf("Before resuming the child process where it left off "
1546             "and without signal to be sent\n");
1547         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1548
1549         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1550         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1551
1552         validate_status_stopped(status, SIGTRAP);
1553
1554         printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1555         ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1556
1557         printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1558         printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1559             info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1560             info.psi_siginfo.si_errno);
1561
1562         printf("Before checking siginfo_t\n");
1563         ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1564         ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1565         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3);
1566         ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1567
1568         printf("Before resuming the child process where it left off and "
1569             "without signal to be sent\n");
1570         ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1571
1572         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1573         TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1574
1575         validate_status_exited(status, exitval);
1576
1577         printf("Before calling %s() for the child\n", TWAIT_FNAME);
1578         TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1579 }
1580 #endif
1581
1582 ATF_TP_ADD_TCS(tp)
1583 {
1584         setvbuf(stdout, NULL, _IONBF, 0);
1585         setvbuf(stderr, NULL, _IONBF, 0);
1586
1587         ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
1588
1589         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_count);
1590         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_read);
1591         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_write_unmodified);
1592         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code0);
1593         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code1);
1594         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code2);
1595         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code3);
1596         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write0);
1597         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write1);
1598         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write2);
1599         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write3);
1600         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw0);
1601         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw1);
1602         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw2);
1603         ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw3);
1604
1605         return atf_no_error();
1606 }