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)
59ATF_TC(regs1);
60ATF_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
66ATF_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)
142ATF_TC(watchpoint_count);
143ATF_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
149ATF_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)
199ATF_TC(watchpoint_read);
200ATF_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
206ATF_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)
272ATF_TC(watchpoint_write_unmodified);
273ATF_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
280ATF_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)
350ATF_TC(watchpoint_trap_code0);
351ATF_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
357ATF_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)
456ATF_TC(watchpoint_trap_code1);
457ATF_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
463ATF_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)
562ATF_TC(watchpoint_trap_code2);
563ATF_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
569ATF_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)
668ATF_TC(watchpoint_trap_code3);
669ATF_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
675ATF_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)
774ATF_TC(watchpoint_trap_data_write0);
775ATF_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
781ATF_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)
875ATF_TC(watchpoint_trap_data_write1);
876ATF_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
882ATF_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)
976ATF_TC(watchpoint_trap_data_write2);
977ATF_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
983ATF_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)
1078ATF_TC(watchpoint_trap_data_write3);
1079ATF_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
1085ATF_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)
1179ATF_TC(watchpoint_trap_data_rw0);
1180ATF_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
1186ATF_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)
1280ATF_TC(watchpoint_trap_data_rw1);
1281ATF_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
1287ATF_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)
1381ATF_TC(watchpoint_trap_data_rw2);
1382ATF_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
1388ATF_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)
1482ATF_TC(watchpoint_trap_data_rw3);
1483ATF_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
1489ATF_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
1582ATF_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}
1607