1*5f761d3cSEnji Cooper /* $NetBSD: t_ptrace_wait.c,v 1.11 2017/01/18 05:14:34 kamil Exp $ */
263d1fd59SEnji Cooper
363d1fd59SEnji Cooper /*-
463d1fd59SEnji Cooper * Copyright (c) 2016 The NetBSD Foundation, Inc.
563d1fd59SEnji Cooper * All rights reserved.
663d1fd59SEnji Cooper *
763d1fd59SEnji Cooper * Redistribution and use in source and binary forms, with or without
863d1fd59SEnji Cooper * modification, are permitted provided that the following conditions
963d1fd59SEnji Cooper * are met:
1063d1fd59SEnji Cooper * 1. Redistributions of source code must retain the above copyright
1163d1fd59SEnji Cooper * notice, this list of conditions and the following disclaimer.
1263d1fd59SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
1363d1fd59SEnji Cooper * notice, this list of conditions and the following disclaimer in the
1463d1fd59SEnji Cooper * documentation and/or other materials provided with the distribution.
1563d1fd59SEnji Cooper *
1663d1fd59SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1763d1fd59SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1863d1fd59SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1963d1fd59SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2063d1fd59SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2163d1fd59SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2263d1fd59SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2363d1fd59SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2463d1fd59SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2563d1fd59SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2663d1fd59SEnji Cooper * POSSIBILITY OF SUCH DAMAGE.
2763d1fd59SEnji Cooper */
2863d1fd59SEnji Cooper
2963d1fd59SEnji Cooper #include <sys/cdefs.h>
30*5f761d3cSEnji Cooper __RCSID("$NetBSD: t_ptrace_wait.c,v 1.11 2017/01/18 05:14:34 kamil Exp $");
3163d1fd59SEnji Cooper
3263d1fd59SEnji Cooper #include <sys/param.h>
3363d1fd59SEnji Cooper #include <sys/types.h>
3463d1fd59SEnji Cooper #include <sys/ptrace.h>
3563d1fd59SEnji Cooper #include <sys/resource.h>
3663d1fd59SEnji Cooper #include <sys/stat.h>
3763d1fd59SEnji Cooper #include <sys/sysctl.h>
3863d1fd59SEnji Cooper #include <sys/wait.h>
3963d1fd59SEnji Cooper #include <machine/reg.h>
4063d1fd59SEnji Cooper #include <x86/dbregs.h>
4163d1fd59SEnji Cooper #include <err.h>
4263d1fd59SEnji Cooper #include <errno.h>
4363d1fd59SEnji Cooper #include <sched.h>
4463d1fd59SEnji Cooper #include <signal.h>
4563d1fd59SEnji Cooper #include <stdint.h>
4663d1fd59SEnji Cooper #include <stdio.h>
4763d1fd59SEnji Cooper #include <stdlib.h>
4863d1fd59SEnji Cooper #include <strings.h>
4963d1fd59SEnji Cooper #include <unistd.h>
5063d1fd59SEnji Cooper
5163d1fd59SEnji Cooper #include <atf-c.h>
5263d1fd59SEnji Cooper
5363d1fd59SEnji Cooper #include "h_macros.h"
5463d1fd59SEnji Cooper
5563d1fd59SEnji Cooper #include "../../t_ptrace_wait.h"
5663d1fd59SEnji Cooper
5763d1fd59SEnji Cooper
5863d1fd59SEnji Cooper #if defined(HAVE_GPREGS)
5963d1fd59SEnji Cooper ATF_TC(regs1);
ATF_TC_HEAD(regs1,tc)6063d1fd59SEnji Cooper ATF_TC_HEAD(regs1, tc)
6163d1fd59SEnji Cooper {
6263d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
6363d1fd59SEnji Cooper "Call PT_GETREGS and iterate over General Purpose registers");
6463d1fd59SEnji Cooper }
6563d1fd59SEnji Cooper
ATF_TC_BODY(regs1,tc)6663d1fd59SEnji Cooper ATF_TC_BODY(regs1, tc)
6763d1fd59SEnji Cooper {
6863d1fd59SEnji Cooper const int exitval = 5;
6963d1fd59SEnji Cooper const int sigval = SIGSTOP;
7063d1fd59SEnji Cooper pid_t child, wpid;
7163d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
7263d1fd59SEnji Cooper int status;
7363d1fd59SEnji Cooper #endif
7463d1fd59SEnji Cooper struct reg r;
7563d1fd59SEnji Cooper
7663d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
7763d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
7863d1fd59SEnji Cooper if (child == 0) {
7963d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
8063d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
8163d1fd59SEnji Cooper
8263d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
8363d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
8463d1fd59SEnji Cooper
8563d1fd59SEnji Cooper printf("Before exiting of the child process\n");
8663d1fd59SEnji Cooper _exit(exitval);
8763d1fd59SEnji Cooper }
8863d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
8963d1fd59SEnji Cooper
9063d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
9163d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
9263d1fd59SEnji Cooper
9363d1fd59SEnji Cooper validate_status_stopped(status, sigval);
9463d1fd59SEnji Cooper
9563d1fd59SEnji Cooper printf("Call GETREGS for the child process\n");
9663d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
9763d1fd59SEnji Cooper
9863d1fd59SEnji Cooper printf("RAX=%#" PRIxREGISTER "\n", r.regs[_REG_RAX]);
9963d1fd59SEnji Cooper printf("RBX=%#" PRIxREGISTER "\n", r.regs[_REG_RBX]);
10063d1fd59SEnji Cooper printf("RCX=%#" PRIxREGISTER "\n", r.regs[_REG_RCX]);
10163d1fd59SEnji Cooper printf("RDX=%#" PRIxREGISTER "\n", r.regs[_REG_RDX]);
10263d1fd59SEnji Cooper
10363d1fd59SEnji Cooper printf("RDI=%#" PRIxREGISTER "\n", r.regs[_REG_RDI]);
10463d1fd59SEnji Cooper printf("RSI=%#" PRIxREGISTER "\n", r.regs[_REG_RSI]);
10563d1fd59SEnji Cooper
10663d1fd59SEnji Cooper printf("GS=%#" PRIxREGISTER "\n", r.regs[_REG_GS]);
10763d1fd59SEnji Cooper printf("FS=%#" PRIxREGISTER "\n", r.regs[_REG_FS]);
10863d1fd59SEnji Cooper printf("ES=%#" PRIxREGISTER "\n", r.regs[_REG_ES]);
10963d1fd59SEnji Cooper printf("DS=%#" PRIxREGISTER "\n", r.regs[_REG_DS]);
11063d1fd59SEnji Cooper printf("CS=%#" PRIxREGISTER "\n", r.regs[_REG_CS]);
11163d1fd59SEnji Cooper printf("SS=%#" PRIxREGISTER "\n", r.regs[_REG_SS]);
11263d1fd59SEnji Cooper
11363d1fd59SEnji Cooper printf("RSP=%#" PRIxREGISTER "\n", r.regs[_REG_RSP]);
11463d1fd59SEnji Cooper printf("RIP=%#" PRIxREGISTER "\n", r.regs[_REG_RIP]);
11563d1fd59SEnji Cooper
11663d1fd59SEnji Cooper printf("RFLAGS=%#" PRIxREGISTER "\n", r.regs[_REG_RFLAGS]);
11763d1fd59SEnji Cooper
11863d1fd59SEnji Cooper printf("R8=%#" PRIxREGISTER "\n", r.regs[_REG_R8]);
11963d1fd59SEnji Cooper printf("R9=%#" PRIxREGISTER "\n", r.regs[_REG_R9]);
12063d1fd59SEnji Cooper printf("R10=%#" PRIxREGISTER "\n", r.regs[_REG_R10]);
12163d1fd59SEnji Cooper printf("R11=%#" PRIxREGISTER "\n", r.regs[_REG_R11]);
12263d1fd59SEnji Cooper printf("R12=%#" PRIxREGISTER "\n", r.regs[_REG_R12]);
12363d1fd59SEnji Cooper printf("R13=%#" PRIxREGISTER "\n", r.regs[_REG_R13]);
12463d1fd59SEnji Cooper printf("R14=%#" PRIxREGISTER "\n", r.regs[_REG_R14]);
12563d1fd59SEnji Cooper printf("R15=%#" PRIxREGISTER "\n", r.regs[_REG_R15]);
12663d1fd59SEnji Cooper
12763d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
12863d1fd59SEnji Cooper "without signal to be sent\n");
12963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13063d1fd59SEnji Cooper
13163d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
13263d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13363d1fd59SEnji Cooper
13463d1fd59SEnji Cooper validate_status_exited(status, exitval);
13563d1fd59SEnji Cooper
13663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
13763d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13863d1fd59SEnji Cooper }
13963d1fd59SEnji Cooper #endif
14063d1fd59SEnji Cooper
14163d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
14263d1fd59SEnji Cooper ATF_TC(watchpoint_count);
ATF_TC_HEAD(watchpoint_count,tc)14363d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_count, tc)
14463d1fd59SEnji Cooper {
14563d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
14663d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints");
14763d1fd59SEnji Cooper }
14863d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_count,tc)14963d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_count, tc)
15063d1fd59SEnji Cooper {
15163d1fd59SEnji Cooper const int exitval = 5;
15263d1fd59SEnji Cooper const int sigval = SIGSTOP;
15363d1fd59SEnji Cooper pid_t child, wpid;
15463d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
15563d1fd59SEnji Cooper int status;
15663d1fd59SEnji Cooper #endif
15763d1fd59SEnji Cooper int N;
15863d1fd59SEnji Cooper
15963d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
16063d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
16163d1fd59SEnji Cooper if (child == 0) {
16263d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
16363d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16463d1fd59SEnji Cooper
16563d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
16663d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
16763d1fd59SEnji Cooper
16863d1fd59SEnji Cooper printf("Before exiting of the child process\n");
16963d1fd59SEnji Cooper _exit(exitval);
17063d1fd59SEnji Cooper }
17163d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17263d1fd59SEnji Cooper
17363d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
17463d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17563d1fd59SEnji Cooper
17663d1fd59SEnji Cooper validate_status_stopped(status, sigval);
17763d1fd59SEnji Cooper
17863d1fd59SEnji Cooper printf("Call GETREGS for the child process\n");
17963d1fd59SEnji Cooper ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
18063d1fd59SEnji Cooper printf("Reported %d watchpoints\n", N);
18163d1fd59SEnji Cooper
18263d1fd59SEnji Cooper ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
18363d1fd59SEnji Cooper
18463d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
18563d1fd59SEnji Cooper "without signal to be sent\n");
18663d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18763d1fd59SEnji Cooper
18863d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
18963d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19063d1fd59SEnji Cooper
19163d1fd59SEnji Cooper validate_status_exited(status, exitval);
19263d1fd59SEnji Cooper
19363d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
19463d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19563d1fd59SEnji Cooper }
19663d1fd59SEnji Cooper #endif
19763d1fd59SEnji Cooper
19863d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
19963d1fd59SEnji Cooper ATF_TC(watchpoint_read);
ATF_TC_HEAD(watchpoint_read,tc)20063d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_read, tc)
20163d1fd59SEnji Cooper {
20263d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
20363d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints");
20463d1fd59SEnji Cooper }
20563d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_read,tc)20663d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_read, tc)
20763d1fd59SEnji Cooper {
20863d1fd59SEnji Cooper const int exitval = 5;
20963d1fd59SEnji Cooper const int sigval = SIGSTOP;
21063d1fd59SEnji Cooper pid_t child, wpid;
21163d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
21263d1fd59SEnji Cooper int status;
21363d1fd59SEnji Cooper #endif
21463d1fd59SEnji Cooper int i, N;
21563d1fd59SEnji Cooper struct ptrace_watchpoint pw;
21663d1fd59SEnji Cooper int len = sizeof(pw);
21763d1fd59SEnji Cooper
21863d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
21963d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
22063d1fd59SEnji Cooper if (child == 0) {
22163d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
22263d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22363d1fd59SEnji Cooper
22463d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
22563d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
22663d1fd59SEnji Cooper
22763d1fd59SEnji Cooper printf("Before exiting of the child process\n");
22863d1fd59SEnji Cooper _exit(exitval);
22963d1fd59SEnji Cooper }
23063d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23163d1fd59SEnji Cooper
23263d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
23363d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23463d1fd59SEnji Cooper
23563d1fd59SEnji Cooper validate_status_stopped(status, sigval);
23663d1fd59SEnji Cooper
23763d1fd59SEnji Cooper printf("Call GETREGS for the child process\n");
23863d1fd59SEnji Cooper ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
23963d1fd59SEnji Cooper
24063d1fd59SEnji Cooper ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
24163d1fd59SEnji Cooper
24263d1fd59SEnji Cooper for (i = 0; i < N; i++) {
24363d1fd59SEnji Cooper printf("Before reading watchpoint %d\n", i);
24463d1fd59SEnji Cooper pw.pw_index = i;
24563d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1);
24663d1fd59SEnji Cooper
24763d1fd59SEnji Cooper printf("struct ptrace {\n");
24863d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
24963d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
250*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
25163d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
25263d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
25363d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
25463d1fd59SEnji Cooper printf("}\n");
25563d1fd59SEnji Cooper }
25663d1fd59SEnji Cooper
25763d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
25863d1fd59SEnji Cooper "without signal to be sent\n");
25963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26063d1fd59SEnji Cooper
26163d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
26263d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26363d1fd59SEnji Cooper
26463d1fd59SEnji Cooper validate_status_exited(status, exitval);
26563d1fd59SEnji Cooper
26663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
26763d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26863d1fd59SEnji Cooper }
26963d1fd59SEnji Cooper #endif
27063d1fd59SEnji Cooper
27163d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
27263d1fd59SEnji Cooper ATF_TC(watchpoint_write_unmodified);
ATF_TC_HEAD(watchpoint_write_unmodified,tc)27363d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_write_unmodified, tc)
27463d1fd59SEnji Cooper {
27563d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
27663d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and assert functional write of "
27763d1fd59SEnji Cooper "unmodified data");
27863d1fd59SEnji Cooper }
27963d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_write_unmodified,tc)28063d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_write_unmodified, tc)
28163d1fd59SEnji Cooper {
28263d1fd59SEnji Cooper const int exitval = 5;
28363d1fd59SEnji Cooper const int sigval = SIGSTOP;
28463d1fd59SEnji Cooper pid_t child, wpid;
28563d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
28663d1fd59SEnji Cooper int status;
28763d1fd59SEnji Cooper #endif
28863d1fd59SEnji Cooper int i, N;
28963d1fd59SEnji Cooper struct ptrace_watchpoint pw;
29063d1fd59SEnji Cooper int len = sizeof(pw);
29163d1fd59SEnji Cooper
29263d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
29363d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
29463d1fd59SEnji Cooper if (child == 0) {
29563d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
29663d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29763d1fd59SEnji Cooper
29863d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
29963d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
30063d1fd59SEnji Cooper
30163d1fd59SEnji Cooper printf("Before exiting of the child process\n");
30263d1fd59SEnji Cooper _exit(exitval);
30363d1fd59SEnji Cooper }
30463d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30563d1fd59SEnji Cooper
30663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
30763d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30863d1fd59SEnji Cooper
30963d1fd59SEnji Cooper validate_status_stopped(status, sigval);
31063d1fd59SEnji Cooper
31163d1fd59SEnji Cooper printf("Call GETREGS for the child process\n");
31263d1fd59SEnji Cooper ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
31363d1fd59SEnji Cooper
31463d1fd59SEnji Cooper ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
31563d1fd59SEnji Cooper
31663d1fd59SEnji Cooper for (i = 0; i < N; i++) {
31763d1fd59SEnji Cooper printf("Before reading watchpoint %d\n", i);
31863d1fd59SEnji Cooper pw.pw_index = i;
31963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1);
32063d1fd59SEnji Cooper
32163d1fd59SEnji Cooper printf("struct ptrace {\n");
32263d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
32363d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
324*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
32563d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
32663d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
32763d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
32863d1fd59SEnji Cooper printf("}\n");
32963d1fd59SEnji Cooper
33063d1fd59SEnji Cooper printf("Before writing watchpoint %d (unmodified)\n", i);
33163d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len)
33263d1fd59SEnji Cooper != -1);
33363d1fd59SEnji Cooper }
33463d1fd59SEnji Cooper
33563d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
33663d1fd59SEnji Cooper "without signal to be sent\n");
33763d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33863d1fd59SEnji Cooper
33963d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
34063d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34163d1fd59SEnji Cooper
34263d1fd59SEnji Cooper validate_status_exited(status, exitval);
34363d1fd59SEnji Cooper
34463d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
34563d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34663d1fd59SEnji Cooper }
34763d1fd59SEnji Cooper #endif
34863d1fd59SEnji Cooper
34963d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
35063d1fd59SEnji Cooper ATF_TC(watchpoint_trap_code0);
ATF_TC_HEAD(watchpoint_trap_code0,tc)35163d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_code0, tc)
35263d1fd59SEnji Cooper {
35363d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
35463d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 0");
35563d1fd59SEnji Cooper }
35663d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_code0,tc)35763d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_code0, tc)
35863d1fd59SEnji Cooper {
35963d1fd59SEnji Cooper const int exitval = 5;
36063d1fd59SEnji Cooper const int sigval = SIGSTOP;
36163d1fd59SEnji Cooper pid_t child, wpid;
36263d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
36363d1fd59SEnji Cooper int status;
36463d1fd59SEnji Cooper #endif
36563d1fd59SEnji Cooper const int i = 0;
36663d1fd59SEnji Cooper struct ptrace_watchpoint pw;
36763d1fd59SEnji Cooper int len = sizeof(pw);
36863d1fd59SEnji Cooper int watchme = 1234;
369*5f761d3cSEnji Cooper struct ptrace_siginfo info;
370*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
37163d1fd59SEnji Cooper
37263d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
37363d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
37463d1fd59SEnji Cooper if (child == 0) {
37563d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
37663d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37763d1fd59SEnji Cooper
37863d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
37963d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
38063d1fd59SEnji Cooper
38163d1fd59SEnji Cooper printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
38263d1fd59SEnji Cooper
38363d1fd59SEnji Cooper printf("Before exiting of the child process\n");
38463d1fd59SEnji Cooper _exit(exitval);
38563d1fd59SEnji Cooper }
38663d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38763d1fd59SEnji Cooper
38863d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
38963d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39063d1fd59SEnji Cooper
39163d1fd59SEnji Cooper validate_status_stopped(status, sigval);
39263d1fd59SEnji Cooper
39363d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
39463d1fd59SEnji Cooper
39563d1fd59SEnji Cooper pw.pw_index = i;
39663d1fd59SEnji Cooper pw.pw_lwpid = 0;
397*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
39863d1fd59SEnji Cooper pw.pw_md.md_address = (void *)check_happy;
39963d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
40063d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
40163d1fd59SEnji Cooper
40263d1fd59SEnji Cooper printf("struct ptrace {\n");
40363d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
40463d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
405*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
40663d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
40763d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
40863d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
40963d1fd59SEnji Cooper printf("}\n");
41063d1fd59SEnji Cooper
41163d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
41263d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
41363d1fd59SEnji Cooper
41463d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
41563d1fd59SEnji Cooper "and without signal to be sent\n");
41663d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41763d1fd59SEnji Cooper
41863d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
41963d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42063d1fd59SEnji Cooper
42163d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
42263d1fd59SEnji Cooper
423*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
424*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
425*5f761d3cSEnji Cooper
426*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
427*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
428*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
429*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
430*5f761d3cSEnji Cooper
431*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
432*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
433*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
434*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0);
435*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
436*5f761d3cSEnji Cooper
43763d1fd59SEnji Cooper pw.pw_md.md_address = NULL;
43863d1fd59SEnji Cooper printf("Before writing watchpoint %d (disable it)\n", i);
43963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
44063d1fd59SEnji Cooper
44163d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
44263d1fd59SEnji Cooper "without signal to be sent\n");
44363d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44463d1fd59SEnji Cooper
44563d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
44663d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44763d1fd59SEnji Cooper
44863d1fd59SEnji Cooper validate_status_exited(status, exitval);
44963d1fd59SEnji Cooper
45063d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
45163d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
45263d1fd59SEnji Cooper }
45363d1fd59SEnji Cooper #endif
45463d1fd59SEnji Cooper
45563d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
45663d1fd59SEnji Cooper ATF_TC(watchpoint_trap_code1);
ATF_TC_HEAD(watchpoint_trap_code1,tc)45763d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_code1, tc)
45863d1fd59SEnji Cooper {
45963d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
46063d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 1");
46163d1fd59SEnji Cooper }
46263d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_code1,tc)46363d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_code1, tc)
46463d1fd59SEnji Cooper {
46563d1fd59SEnji Cooper const int exitval = 5;
46663d1fd59SEnji Cooper const int sigval = SIGSTOP;
46763d1fd59SEnji Cooper pid_t child, wpid;
46863d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
46963d1fd59SEnji Cooper int status;
47063d1fd59SEnji Cooper #endif
47163d1fd59SEnji Cooper const int i = 1;
47263d1fd59SEnji Cooper struct ptrace_watchpoint pw;
47363d1fd59SEnji Cooper int len = sizeof(pw);
47463d1fd59SEnji Cooper int watchme = 1234;
475*5f761d3cSEnji Cooper struct ptrace_siginfo info;
476*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
47763d1fd59SEnji Cooper
47863d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
47963d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
48063d1fd59SEnji Cooper if (child == 0) {
48163d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
48263d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48363d1fd59SEnji Cooper
48463d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
48563d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
48663d1fd59SEnji Cooper
48763d1fd59SEnji Cooper printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
48863d1fd59SEnji Cooper
48963d1fd59SEnji Cooper printf("Before exiting of the child process\n");
49063d1fd59SEnji Cooper _exit(exitval);
49163d1fd59SEnji Cooper }
49263d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49363d1fd59SEnji Cooper
49463d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
49563d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49663d1fd59SEnji Cooper
49763d1fd59SEnji Cooper validate_status_stopped(status, sigval);
49863d1fd59SEnji Cooper
49963d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
50063d1fd59SEnji Cooper
50163d1fd59SEnji Cooper pw.pw_index = i;
50263d1fd59SEnji Cooper pw.pw_lwpid = 0;
503*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
50463d1fd59SEnji Cooper pw.pw_md.md_address = (void *)check_happy;
50563d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
50663d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
50763d1fd59SEnji Cooper
50863d1fd59SEnji Cooper printf("struct ptrace {\n");
50963d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
51063d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
511*5f761d3cSEnji Cooper printf("\t.pw_type=%d\n", pw.pw_type);
51263d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
51363d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
51463d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
51563d1fd59SEnji Cooper printf("}\n");
51663d1fd59SEnji Cooper
51763d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
51863d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
51963d1fd59SEnji Cooper
52063d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
52163d1fd59SEnji Cooper "and without signal to be sent\n");
52263d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52363d1fd59SEnji Cooper
52463d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
52563d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52663d1fd59SEnji Cooper
52763d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
52863d1fd59SEnji Cooper
529*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
530*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
531*5f761d3cSEnji Cooper
532*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
533*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
534*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
535*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
536*5f761d3cSEnji Cooper
537*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
538*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
539*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
540*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1);
541*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
542*5f761d3cSEnji Cooper
54363d1fd59SEnji Cooper pw.pw_md.md_address = NULL;
54463d1fd59SEnji Cooper printf("Before writing watchpoint %d (disable it)\n", i);
54563d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
54663d1fd59SEnji Cooper
54763d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
54863d1fd59SEnji Cooper "without signal to be sent\n");
54963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55063d1fd59SEnji Cooper
55163d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
55263d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55363d1fd59SEnji Cooper
55463d1fd59SEnji Cooper validate_status_exited(status, exitval);
55563d1fd59SEnji Cooper
55663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
55763d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55863d1fd59SEnji Cooper }
55963d1fd59SEnji Cooper #endif
56063d1fd59SEnji Cooper
56163d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
56263d1fd59SEnji Cooper ATF_TC(watchpoint_trap_code2);
ATF_TC_HEAD(watchpoint_trap_code2,tc)56363d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_code2, tc)
56463d1fd59SEnji Cooper {
56563d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
56663d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 2");
56763d1fd59SEnji Cooper }
56863d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_code2,tc)56963d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_code2, tc)
57063d1fd59SEnji Cooper {
57163d1fd59SEnji Cooper const int exitval = 5;
57263d1fd59SEnji Cooper const int sigval = SIGSTOP;
57363d1fd59SEnji Cooper pid_t child, wpid;
57463d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
57563d1fd59SEnji Cooper int status;
57663d1fd59SEnji Cooper #endif
57763d1fd59SEnji Cooper const int i = 2;
57863d1fd59SEnji Cooper struct ptrace_watchpoint pw;
57963d1fd59SEnji Cooper int len = sizeof(pw);
58063d1fd59SEnji Cooper int watchme = 1234;
581*5f761d3cSEnji Cooper struct ptrace_siginfo info;
582*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
58363d1fd59SEnji Cooper
58463d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
58563d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
58663d1fd59SEnji Cooper if (child == 0) {
58763d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
58863d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58963d1fd59SEnji Cooper
59063d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
59163d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
59263d1fd59SEnji Cooper
59363d1fd59SEnji Cooper printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
59463d1fd59SEnji Cooper
59563d1fd59SEnji Cooper printf("Before exiting of the child process\n");
59663d1fd59SEnji Cooper _exit(exitval);
59763d1fd59SEnji Cooper }
59863d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59963d1fd59SEnji Cooper
60063d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
60163d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60263d1fd59SEnji Cooper
60363d1fd59SEnji Cooper validate_status_stopped(status, sigval);
60463d1fd59SEnji Cooper
60563d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
60663d1fd59SEnji Cooper
60763d1fd59SEnji Cooper pw.pw_index = i;
60863d1fd59SEnji Cooper pw.pw_lwpid = 0;
609*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
61063d1fd59SEnji Cooper pw.pw_md.md_address = (void *)check_happy;
61163d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
61263d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
61363d1fd59SEnji Cooper
61463d1fd59SEnji Cooper printf("struct ptrace {\n");
61563d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
61663d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
617*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
61863d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
61963d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
62063d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
62163d1fd59SEnji Cooper printf("}\n");
62263d1fd59SEnji Cooper
62363d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
62463d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
62563d1fd59SEnji Cooper
62663d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
62763d1fd59SEnji Cooper "and without signal to be sent\n");
62863d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62963d1fd59SEnji Cooper
63063d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
63163d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63263d1fd59SEnji Cooper
63363d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
63463d1fd59SEnji Cooper
635*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
636*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
637*5f761d3cSEnji Cooper
638*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
639*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
640*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
641*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
642*5f761d3cSEnji Cooper
643*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
644*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
645*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
646*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2);
647*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
648*5f761d3cSEnji Cooper
64963d1fd59SEnji Cooper pw.pw_md.md_address = NULL;
65063d1fd59SEnji Cooper printf("Before writing watchpoint %d (disable it)\n", i);
65163d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
65263d1fd59SEnji Cooper
65363d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
65463d1fd59SEnji Cooper "without signal to be sent\n");
65563d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65663d1fd59SEnji Cooper
65763d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
65863d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65963d1fd59SEnji Cooper
66063d1fd59SEnji Cooper validate_status_exited(status, exitval);
66163d1fd59SEnji Cooper
66263d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
66363d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66463d1fd59SEnji Cooper }
66563d1fd59SEnji Cooper #endif
66663d1fd59SEnji Cooper
66763d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
66863d1fd59SEnji Cooper ATF_TC(watchpoint_trap_code3);
ATF_TC_HEAD(watchpoint_trap_code3,tc)66963d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_code3, tc)
67063d1fd59SEnji Cooper {
67163d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
67263d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 3");
67363d1fd59SEnji Cooper }
67463d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_code3,tc)67563d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_code3, tc)
67663d1fd59SEnji Cooper {
67763d1fd59SEnji Cooper const int exitval = 5;
67863d1fd59SEnji Cooper const int sigval = SIGSTOP;
67963d1fd59SEnji Cooper pid_t child, wpid;
68063d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
68163d1fd59SEnji Cooper int status;
68263d1fd59SEnji Cooper #endif
68363d1fd59SEnji Cooper const int i = 3;
68463d1fd59SEnji Cooper struct ptrace_watchpoint pw;
68563d1fd59SEnji Cooper int len = sizeof(pw);
68663d1fd59SEnji Cooper int watchme = 1234;
687*5f761d3cSEnji Cooper struct ptrace_siginfo info;
688*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
68963d1fd59SEnji Cooper
69063d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
69163d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
69263d1fd59SEnji Cooper if (child == 0) {
69363d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
69463d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69563d1fd59SEnji Cooper
69663d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
69763d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
69863d1fd59SEnji Cooper
69963d1fd59SEnji Cooper printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
70063d1fd59SEnji Cooper
70163d1fd59SEnji Cooper printf("Before exiting of the child process\n");
70263d1fd59SEnji Cooper _exit(exitval);
70363d1fd59SEnji Cooper }
70463d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70563d1fd59SEnji Cooper
70663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
70763d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70863d1fd59SEnji Cooper
70963d1fd59SEnji Cooper validate_status_stopped(status, sigval);
71063d1fd59SEnji Cooper
71163d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
71263d1fd59SEnji Cooper
71363d1fd59SEnji Cooper pw.pw_index = i;
71463d1fd59SEnji Cooper pw.pw_lwpid = 0;
715*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
71663d1fd59SEnji Cooper pw.pw_md.md_address = (void *)check_happy;
71763d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
71863d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
71963d1fd59SEnji Cooper
72063d1fd59SEnji Cooper printf("struct ptrace {\n");
72163d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
72263d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
723*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
72463d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
72563d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
72663d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
72763d1fd59SEnji Cooper printf("}\n");
72863d1fd59SEnji Cooper
72963d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
73063d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
73163d1fd59SEnji Cooper
73263d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
73363d1fd59SEnji Cooper "and without signal to be sent\n");
73463d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
73563d1fd59SEnji Cooper
73663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
73763d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73863d1fd59SEnji Cooper
73963d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
74063d1fd59SEnji Cooper
741*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
742*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
743*5f761d3cSEnji Cooper
744*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
745*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
746*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
747*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
748*5f761d3cSEnji Cooper
749*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
750*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
751*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
752*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3);
753*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
754*5f761d3cSEnji Cooper
75563d1fd59SEnji Cooper pw.pw_md.md_address = NULL;
75663d1fd59SEnji Cooper printf("Before writing watchpoint %d (disable it)\n", i);
75763d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
75863d1fd59SEnji Cooper
75963d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
76063d1fd59SEnji Cooper "without signal to be sent\n");
76163d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
76263d1fd59SEnji Cooper
76363d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
76463d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
76563d1fd59SEnji Cooper
76663d1fd59SEnji Cooper validate_status_exited(status, exitval);
76763d1fd59SEnji Cooper
76863d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
76963d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
77063d1fd59SEnji Cooper }
77163d1fd59SEnji Cooper #endif
77263d1fd59SEnji Cooper
77363d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
77463d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_write0);
ATF_TC_HEAD(watchpoint_trap_data_write0,tc)77563d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_write0, tc)
77663d1fd59SEnji Cooper {
77763d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
77863d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0");
77963d1fd59SEnji Cooper }
78063d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_write0,tc)78163d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_write0, tc)
78263d1fd59SEnji Cooper {
78363d1fd59SEnji Cooper const int exitval = 5;
78463d1fd59SEnji Cooper const int sigval = SIGSTOP;
78563d1fd59SEnji Cooper pid_t child, wpid;
78663d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
78763d1fd59SEnji Cooper int status;
78863d1fd59SEnji Cooper #endif
78963d1fd59SEnji Cooper const int i = 0;
79063d1fd59SEnji Cooper struct ptrace_watchpoint pw;
79163d1fd59SEnji Cooper int len = sizeof(pw);
79263d1fd59SEnji Cooper int watchme = 1234;
793*5f761d3cSEnji Cooper struct ptrace_siginfo info;
794*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
79563d1fd59SEnji Cooper
79663d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
79763d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
79863d1fd59SEnji Cooper if (child == 0) {
79963d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
80063d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
80163d1fd59SEnji Cooper
80263d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
80363d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
80463d1fd59SEnji Cooper
80563d1fd59SEnji Cooper ++watchme;
80663d1fd59SEnji Cooper
80763d1fd59SEnji Cooper printf("Before exiting of the child process\n");
80863d1fd59SEnji Cooper _exit(exitval);
80963d1fd59SEnji Cooper }
81063d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
81163d1fd59SEnji Cooper
81263d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
81363d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
81463d1fd59SEnji Cooper
81563d1fd59SEnji Cooper validate_status_stopped(status, sigval);
81663d1fd59SEnji Cooper
81763d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
81863d1fd59SEnji Cooper
81963d1fd59SEnji Cooper pw.pw_index = 0;
820*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
82163d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
82263d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
82363d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
82463d1fd59SEnji Cooper
82563d1fd59SEnji Cooper printf("struct ptrace {\n");
82663d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
82763d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
828*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
82963d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
83063d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
83163d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
83263d1fd59SEnji Cooper printf("}\n");
83363d1fd59SEnji Cooper
83463d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
83563d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
83663d1fd59SEnji Cooper
83763d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
83863d1fd59SEnji Cooper "and without signal to be sent\n");
83963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
84063d1fd59SEnji Cooper
84163d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
84263d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
84363d1fd59SEnji Cooper
84463d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
84563d1fd59SEnji Cooper
846*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
847*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
848*5f761d3cSEnji Cooper
849*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
850*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
851*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
852*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
853*5f761d3cSEnji Cooper
854*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
855*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
856*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
857*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0);
858*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
859*5f761d3cSEnji Cooper
86063d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
86163d1fd59SEnji Cooper "without signal to be sent\n");
86263d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
86363d1fd59SEnji Cooper
86463d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
86563d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
86663d1fd59SEnji Cooper
86763d1fd59SEnji Cooper validate_status_exited(status, exitval);
86863d1fd59SEnji Cooper
86963d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
87063d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
87163d1fd59SEnji Cooper }
87263d1fd59SEnji Cooper #endif
87363d1fd59SEnji Cooper
87463d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
87563d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_write1);
ATF_TC_HEAD(watchpoint_trap_data_write1,tc)87663d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_write1, tc)
87763d1fd59SEnji Cooper {
87863d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
87963d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1");
88063d1fd59SEnji Cooper }
88163d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_write1,tc)88263d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_write1, tc)
88363d1fd59SEnji Cooper {
88463d1fd59SEnji Cooper const int exitval = 5;
88563d1fd59SEnji Cooper const int sigval = SIGSTOP;
88663d1fd59SEnji Cooper pid_t child, wpid;
88763d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
88863d1fd59SEnji Cooper int status;
88963d1fd59SEnji Cooper #endif
89063d1fd59SEnji Cooper const int i = 1;
89163d1fd59SEnji Cooper struct ptrace_watchpoint pw;
89263d1fd59SEnji Cooper int len = sizeof(pw);
89363d1fd59SEnji Cooper int watchme = 1234;
894*5f761d3cSEnji Cooper struct ptrace_siginfo info;
895*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
89663d1fd59SEnji Cooper
89763d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
89863d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
89963d1fd59SEnji Cooper if (child == 0) {
90063d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
90163d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
90263d1fd59SEnji Cooper
90363d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
90463d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
90563d1fd59SEnji Cooper
90663d1fd59SEnji Cooper ++watchme;
90763d1fd59SEnji Cooper
90863d1fd59SEnji Cooper printf("Before exiting of the child process\n");
90963d1fd59SEnji Cooper _exit(exitval);
91063d1fd59SEnji Cooper }
91163d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
91263d1fd59SEnji Cooper
91363d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
91463d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
91563d1fd59SEnji Cooper
91663d1fd59SEnji Cooper validate_status_stopped(status, sigval);
91763d1fd59SEnji Cooper
91863d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
91963d1fd59SEnji Cooper
92063d1fd59SEnji Cooper pw.pw_index = i;
921*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
92263d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
92363d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
92463d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
92563d1fd59SEnji Cooper
92663d1fd59SEnji Cooper printf("struct ptrace {\n");
92763d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
92863d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
929*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
93063d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
93163d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
93263d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
93363d1fd59SEnji Cooper printf("}\n");
93463d1fd59SEnji Cooper
93563d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
93663d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
93763d1fd59SEnji Cooper
93863d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
93963d1fd59SEnji Cooper "and without signal to be sent\n");
94063d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
94163d1fd59SEnji Cooper
94263d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
94363d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
94463d1fd59SEnji Cooper
94563d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
94663d1fd59SEnji Cooper
947*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
948*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
949*5f761d3cSEnji Cooper
950*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
951*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
952*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
953*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
954*5f761d3cSEnji Cooper
955*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
956*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
957*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
958*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1);
959*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
960*5f761d3cSEnji Cooper
96163d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
96263d1fd59SEnji Cooper "without signal to be sent\n");
96363d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
96463d1fd59SEnji Cooper
96563d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
96663d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
96763d1fd59SEnji Cooper
96863d1fd59SEnji Cooper validate_status_exited(status, exitval);
96963d1fd59SEnji Cooper
97063d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
97163d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
97263d1fd59SEnji Cooper }
97363d1fd59SEnji Cooper #endif
97463d1fd59SEnji Cooper
97563d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
97663d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_write2);
ATF_TC_HEAD(watchpoint_trap_data_write2,tc)97763d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_write2, tc)
97863d1fd59SEnji Cooper {
97963d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
98063d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2");
98163d1fd59SEnji Cooper }
98263d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_write2,tc)98363d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_write2, tc)
98463d1fd59SEnji Cooper {
98563d1fd59SEnji Cooper const int exitval = 5;
98663d1fd59SEnji Cooper const int sigval = SIGSTOP;
98763d1fd59SEnji Cooper pid_t child, wpid;
98863d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
98963d1fd59SEnji Cooper int status;
99063d1fd59SEnji Cooper #endif
99163d1fd59SEnji Cooper const int i = 2;
99263d1fd59SEnji Cooper struct ptrace_watchpoint pw;
99363d1fd59SEnji Cooper int len = sizeof(pw);
99463d1fd59SEnji Cooper int watchme = 1234;
995*5f761d3cSEnji Cooper struct ptrace_siginfo info;
996*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
99763d1fd59SEnji Cooper
99863d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
99963d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
100063d1fd59SEnji Cooper if (child == 0) {
100163d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
100263d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
100363d1fd59SEnji Cooper
100463d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
100563d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
100663d1fd59SEnji Cooper
100763d1fd59SEnji Cooper ++watchme;
100863d1fd59SEnji Cooper
100963d1fd59SEnji Cooper printf("Before exiting of the child process\n");
101063d1fd59SEnji Cooper _exit(exitval);
101163d1fd59SEnji Cooper }
101263d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
101363d1fd59SEnji Cooper
101463d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
101563d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
101663d1fd59SEnji Cooper
101763d1fd59SEnji Cooper validate_status_stopped(status, sigval);
101863d1fd59SEnji Cooper
101963d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
102063d1fd59SEnji Cooper
102163d1fd59SEnji Cooper pw.pw_index = i;
1022*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
102363d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
102463d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
102563d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
102663d1fd59SEnji Cooper
102763d1fd59SEnji Cooper printf("struct ptrace {\n");
102863d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
102963d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1030*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
103163d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
103263d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
103363d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
103463d1fd59SEnji Cooper printf("}\n");
103563d1fd59SEnji Cooper
103663d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
103763d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
103863d1fd59SEnji Cooper
103963d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
104063d1fd59SEnji Cooper "and without signal to be sent\n");
104163d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
104263d1fd59SEnji Cooper
104363d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
104463d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
104563d1fd59SEnji Cooper
104663d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
104763d1fd59SEnji Cooper
1048*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1049*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1050*5f761d3cSEnji Cooper
1051*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1052*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1053*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1054*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
1055*5f761d3cSEnji Cooper
1056*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
1057*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1058*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1059*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2);
1060*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1061*5f761d3cSEnji Cooper
106263d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
106363d1fd59SEnji Cooper "without signal to be sent\n");
106463d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
106563d1fd59SEnji Cooper
106663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
106763d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
106863d1fd59SEnji Cooper
106963d1fd59SEnji Cooper validate_status_exited(status, exitval);
107063d1fd59SEnji Cooper
107163d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
107263d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
107363d1fd59SEnji Cooper }
107463d1fd59SEnji Cooper #endif
107563d1fd59SEnji Cooper
107663d1fd59SEnji Cooper
107763d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
107863d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_write3);
ATF_TC_HEAD(watchpoint_trap_data_write3,tc)107963d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_write3, tc)
108063d1fd59SEnji Cooper {
108163d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
108263d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3");
108363d1fd59SEnji Cooper }
108463d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_write3,tc)108563d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_write3, tc)
108663d1fd59SEnji Cooper {
108763d1fd59SEnji Cooper const int exitval = 5;
108863d1fd59SEnji Cooper const int sigval = SIGSTOP;
108963d1fd59SEnji Cooper pid_t child, wpid;
109063d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
109163d1fd59SEnji Cooper int status;
109263d1fd59SEnji Cooper #endif
109363d1fd59SEnji Cooper const int i = 3;
109463d1fd59SEnji Cooper struct ptrace_watchpoint pw;
109563d1fd59SEnji Cooper int len = sizeof(pw);
109663d1fd59SEnji Cooper int watchme = 1234;
1097*5f761d3cSEnji Cooper struct ptrace_siginfo info;
1098*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
109963d1fd59SEnji Cooper
110063d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
110163d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
110263d1fd59SEnji Cooper if (child == 0) {
110363d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
110463d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
110563d1fd59SEnji Cooper
110663d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
110763d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
110863d1fd59SEnji Cooper
110963d1fd59SEnji Cooper ++watchme;
111063d1fd59SEnji Cooper
111163d1fd59SEnji Cooper printf("Before exiting of the child process\n");
111263d1fd59SEnji Cooper _exit(exitval);
111363d1fd59SEnji Cooper }
111463d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
111563d1fd59SEnji Cooper
111663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
111763d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
111863d1fd59SEnji Cooper
111963d1fd59SEnji Cooper validate_status_stopped(status, sigval);
112063d1fd59SEnji Cooper
112163d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
112263d1fd59SEnji Cooper
112363d1fd59SEnji Cooper pw.pw_index = i;
1124*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
112563d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
112663d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
112763d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
112863d1fd59SEnji Cooper
112963d1fd59SEnji Cooper printf("struct ptrace {\n");
113063d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
113163d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1132*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
113363d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
113463d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
113563d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
113663d1fd59SEnji Cooper printf("}\n");
113763d1fd59SEnji Cooper
113863d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
113963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
114063d1fd59SEnji Cooper
114163d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
114263d1fd59SEnji Cooper "and without signal to be sent\n");
114363d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
114463d1fd59SEnji Cooper
114563d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
114663d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
114763d1fd59SEnji Cooper
114863d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
114963d1fd59SEnji Cooper
1150*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1151*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1152*5f761d3cSEnji Cooper
1153*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1154*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1155*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1156*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
1157*5f761d3cSEnji Cooper
1158*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
1159*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1160*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1161*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3);
1162*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1163*5f761d3cSEnji Cooper
116463d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
116563d1fd59SEnji Cooper "without signal to be sent\n");
116663d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
116763d1fd59SEnji Cooper
116863d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
116963d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
117063d1fd59SEnji Cooper
117163d1fd59SEnji Cooper validate_status_exited(status, exitval);
117263d1fd59SEnji Cooper
117363d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
117463d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
117563d1fd59SEnji Cooper }
117663d1fd59SEnji Cooper #endif
117763d1fd59SEnji Cooper
117863d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
117963d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_rw0);
ATF_TC_HEAD(watchpoint_trap_data_rw0,tc)118063d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_rw0, tc)
118163d1fd59SEnji Cooper {
118263d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
118363d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0");
118463d1fd59SEnji Cooper }
118563d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_rw0,tc)118663d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_rw0, tc)
118763d1fd59SEnji Cooper {
118863d1fd59SEnji Cooper const int exitval = 5;
118963d1fd59SEnji Cooper const int sigval = SIGSTOP;
119063d1fd59SEnji Cooper pid_t child, wpid;
119163d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
119263d1fd59SEnji Cooper int status;
119363d1fd59SEnji Cooper #endif
119463d1fd59SEnji Cooper const int i = 0;
119563d1fd59SEnji Cooper struct ptrace_watchpoint pw;
119663d1fd59SEnji Cooper int len = sizeof(pw);
119763d1fd59SEnji Cooper int watchme = 1234;
1198*5f761d3cSEnji Cooper struct ptrace_siginfo info;
1199*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
120063d1fd59SEnji Cooper
120163d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
120263d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
120363d1fd59SEnji Cooper if (child == 0) {
120463d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
120563d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
120663d1fd59SEnji Cooper
120763d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
120863d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
120963d1fd59SEnji Cooper
121063d1fd59SEnji Cooper printf("watchme=%d\n", watchme);
121163d1fd59SEnji Cooper
121263d1fd59SEnji Cooper printf("Before exiting of the child process\n");
121363d1fd59SEnji Cooper _exit(exitval);
121463d1fd59SEnji Cooper }
121563d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
121663d1fd59SEnji Cooper
121763d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
121863d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
121963d1fd59SEnji Cooper
122063d1fd59SEnji Cooper validate_status_stopped(status, sigval);
122163d1fd59SEnji Cooper
122263d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
122363d1fd59SEnji Cooper
122463d1fd59SEnji Cooper pw.pw_index = i;
1225*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
122663d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
122763d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
122863d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
122963d1fd59SEnji Cooper
123063d1fd59SEnji Cooper printf("struct ptrace {\n");
123163d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
123263d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1233*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
123463d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
123563d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
123663d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
123763d1fd59SEnji Cooper printf("}\n");
123863d1fd59SEnji Cooper
123963d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
124063d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
124163d1fd59SEnji Cooper
124263d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
124363d1fd59SEnji Cooper "and without signal to be sent\n");
124463d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
124563d1fd59SEnji Cooper
124663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
124763d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
124863d1fd59SEnji Cooper
124963d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
125063d1fd59SEnji Cooper
1251*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1252*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1253*5f761d3cSEnji Cooper
1254*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1255*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1256*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1257*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
1258*5f761d3cSEnji Cooper
1259*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
1260*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1261*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1262*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0);
1263*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1264*5f761d3cSEnji Cooper
126563d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
126663d1fd59SEnji Cooper "without signal to be sent\n");
126763d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
126863d1fd59SEnji Cooper
126963d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
127063d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
127163d1fd59SEnji Cooper
127263d1fd59SEnji Cooper validate_status_exited(status, exitval);
127363d1fd59SEnji Cooper
127463d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
127563d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
127663d1fd59SEnji Cooper }
127763d1fd59SEnji Cooper #endif
127863d1fd59SEnji Cooper
127963d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
128063d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_rw1);
ATF_TC_HEAD(watchpoint_trap_data_rw1,tc)128163d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_rw1, tc)
128263d1fd59SEnji Cooper {
128363d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
128463d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1");
128563d1fd59SEnji Cooper }
128663d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_rw1,tc)128763d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_rw1, tc)
128863d1fd59SEnji Cooper {
128963d1fd59SEnji Cooper const int exitval = 5;
129063d1fd59SEnji Cooper const int sigval = SIGSTOP;
129163d1fd59SEnji Cooper pid_t child, wpid;
129263d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
129363d1fd59SEnji Cooper int status;
129463d1fd59SEnji Cooper #endif
129563d1fd59SEnji Cooper const int i = 1;
129663d1fd59SEnji Cooper struct ptrace_watchpoint pw;
129763d1fd59SEnji Cooper int len = sizeof(pw);
129863d1fd59SEnji Cooper int watchme = 1234;
1299*5f761d3cSEnji Cooper struct ptrace_siginfo info;
1300*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
130163d1fd59SEnji Cooper
130263d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
130363d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
130463d1fd59SEnji Cooper if (child == 0) {
130563d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
130663d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
130763d1fd59SEnji Cooper
130863d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
130963d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
131063d1fd59SEnji Cooper
131163d1fd59SEnji Cooper printf("watchme=%d\n", watchme);
131263d1fd59SEnji Cooper
131363d1fd59SEnji Cooper printf("Before exiting of the child process\n");
131463d1fd59SEnji Cooper _exit(exitval);
131563d1fd59SEnji Cooper }
131663d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
131763d1fd59SEnji Cooper
131863d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
131963d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
132063d1fd59SEnji Cooper
132163d1fd59SEnji Cooper validate_status_stopped(status, sigval);
132263d1fd59SEnji Cooper
132363d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
132463d1fd59SEnji Cooper
132563d1fd59SEnji Cooper pw.pw_index = i;
1326*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
132763d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
132863d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
132963d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
133063d1fd59SEnji Cooper
133163d1fd59SEnji Cooper printf("struct ptrace {\n");
133263d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
133363d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1334*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
133563d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
133663d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
133763d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
133863d1fd59SEnji Cooper printf("}\n");
133963d1fd59SEnji Cooper
134063d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
134163d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
134263d1fd59SEnji Cooper
134363d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
134463d1fd59SEnji Cooper "and without signal to be sent\n");
134563d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
134663d1fd59SEnji Cooper
134763d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
134863d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
134963d1fd59SEnji Cooper
135063d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
135163d1fd59SEnji Cooper
1352*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1353*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1354*5f761d3cSEnji Cooper
1355*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1356*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1357*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1358*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
1359*5f761d3cSEnji Cooper
1360*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
1361*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1362*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1363*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1);
1364*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1365*5f761d3cSEnji Cooper
136663d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
136763d1fd59SEnji Cooper "without signal to be sent\n");
136863d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
136963d1fd59SEnji Cooper
137063d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
137163d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
137263d1fd59SEnji Cooper
137363d1fd59SEnji Cooper validate_status_exited(status, exitval);
137463d1fd59SEnji Cooper
137563d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
137663d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
137763d1fd59SEnji Cooper }
137863d1fd59SEnji Cooper #endif
137963d1fd59SEnji Cooper
138063d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
138163d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_rw2);
ATF_TC_HEAD(watchpoint_trap_data_rw2,tc)138263d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_rw2, tc)
138363d1fd59SEnji Cooper {
138463d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
138563d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2");
138663d1fd59SEnji Cooper }
138763d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_rw2,tc)138863d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_rw2, tc)
138963d1fd59SEnji Cooper {
139063d1fd59SEnji Cooper const int exitval = 5;
139163d1fd59SEnji Cooper const int sigval = SIGSTOP;
139263d1fd59SEnji Cooper pid_t child, wpid;
139363d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
139463d1fd59SEnji Cooper int status;
139563d1fd59SEnji Cooper #endif
139663d1fd59SEnji Cooper const int i = 2;
139763d1fd59SEnji Cooper struct ptrace_watchpoint pw;
139863d1fd59SEnji Cooper int len = sizeof(pw);
139963d1fd59SEnji Cooper int watchme = 1234;
1400*5f761d3cSEnji Cooper struct ptrace_siginfo info;
1401*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
140263d1fd59SEnji Cooper
140363d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
140463d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
140563d1fd59SEnji Cooper if (child == 0) {
140663d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
140763d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
140863d1fd59SEnji Cooper
140963d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
141063d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
141163d1fd59SEnji Cooper
141263d1fd59SEnji Cooper printf("watchme=%d\n", watchme);
141363d1fd59SEnji Cooper
141463d1fd59SEnji Cooper printf("Before exiting of the child process\n");
141563d1fd59SEnji Cooper _exit(exitval);
141663d1fd59SEnji Cooper }
141763d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
141863d1fd59SEnji Cooper
141963d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
142063d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
142163d1fd59SEnji Cooper
142263d1fd59SEnji Cooper validate_status_stopped(status, sigval);
142363d1fd59SEnji Cooper
142463d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
142563d1fd59SEnji Cooper
142663d1fd59SEnji Cooper pw.pw_index = i;
1427*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
142863d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
142963d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
143063d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
143163d1fd59SEnji Cooper
143263d1fd59SEnji Cooper printf("struct ptrace {\n");
143363d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
143463d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1435*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
143663d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
143763d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
143863d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
143963d1fd59SEnji Cooper printf("}\n");
144063d1fd59SEnji Cooper
144163d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
144263d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
144363d1fd59SEnji Cooper
144463d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
144563d1fd59SEnji Cooper "and without signal to be sent\n");
144663d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
144763d1fd59SEnji Cooper
144863d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
144963d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
145063d1fd59SEnji Cooper
145163d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
145263d1fd59SEnji Cooper
1453*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1454*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1455*5f761d3cSEnji Cooper
1456*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1457*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1458*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1459*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
1460*5f761d3cSEnji Cooper
1461*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
1462*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1463*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1464*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2);
1465*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1466*5f761d3cSEnji Cooper
146763d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
146863d1fd59SEnji Cooper "without signal to be sent\n");
146963d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
147063d1fd59SEnji Cooper
147163d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
147263d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
147363d1fd59SEnji Cooper
147463d1fd59SEnji Cooper validate_status_exited(status, exitval);
147563d1fd59SEnji Cooper
147663d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
147763d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
147863d1fd59SEnji Cooper }
147963d1fd59SEnji Cooper #endif
148063d1fd59SEnji Cooper
148163d1fd59SEnji Cooper #if defined(__HAVE_PTRACE_WATCHPOINTS)
148263d1fd59SEnji Cooper ATF_TC(watchpoint_trap_data_rw3);
ATF_TC_HEAD(watchpoint_trap_data_rw3,tc)148363d1fd59SEnji Cooper ATF_TC_HEAD(watchpoint_trap_data_rw3, tc)
148463d1fd59SEnji Cooper {
148563d1fd59SEnji Cooper atf_tc_set_md_var(tc, "descr",
148663d1fd59SEnji Cooper "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3");
148763d1fd59SEnji Cooper }
148863d1fd59SEnji Cooper
ATF_TC_BODY(watchpoint_trap_data_rw3,tc)148963d1fd59SEnji Cooper ATF_TC_BODY(watchpoint_trap_data_rw3, tc)
149063d1fd59SEnji Cooper {
149163d1fd59SEnji Cooper const int exitval = 5;
149263d1fd59SEnji Cooper const int sigval = SIGSTOP;
149363d1fd59SEnji Cooper pid_t child, wpid;
149463d1fd59SEnji Cooper #if defined(TWAIT_HAVE_STATUS)
149563d1fd59SEnji Cooper int status;
149663d1fd59SEnji Cooper #endif
149763d1fd59SEnji Cooper const int i = 3;
149863d1fd59SEnji Cooper struct ptrace_watchpoint pw;
149963d1fd59SEnji Cooper int len = sizeof(pw);
150063d1fd59SEnji Cooper int watchme = 1234;
1501*5f761d3cSEnji Cooper struct ptrace_siginfo info;
1502*5f761d3cSEnji Cooper memset(&info, 0, sizeof(info));
150363d1fd59SEnji Cooper
150463d1fd59SEnji Cooper printf("Before forking process PID=%d\n", getpid());
150563d1fd59SEnji Cooper ATF_REQUIRE((child = fork()) != -1);
150663d1fd59SEnji Cooper if (child == 0) {
150763d1fd59SEnji Cooper printf("Before calling PT_TRACE_ME from child %d\n", getpid());
150863d1fd59SEnji Cooper FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
150963d1fd59SEnji Cooper
151063d1fd59SEnji Cooper printf("Before raising %s from child\n", strsignal(sigval));
151163d1fd59SEnji Cooper FORKEE_ASSERT(raise(sigval) == 0);
151263d1fd59SEnji Cooper
151363d1fd59SEnji Cooper printf("watchme=%d\n", watchme);
151463d1fd59SEnji Cooper
151563d1fd59SEnji Cooper printf("Before exiting of the child process\n");
151663d1fd59SEnji Cooper _exit(exitval);
151763d1fd59SEnji Cooper }
151863d1fd59SEnji Cooper printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
151963d1fd59SEnji Cooper
152063d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
152163d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
152263d1fd59SEnji Cooper
152363d1fd59SEnji Cooper validate_status_stopped(status, sigval);
152463d1fd59SEnji Cooper
152563d1fd59SEnji Cooper printf("Preparing code watchpoint trap %d\n", i);
152663d1fd59SEnji Cooper
152763d1fd59SEnji Cooper pw.pw_index = i;
1528*5f761d3cSEnji Cooper pw.pw_type = PTRACE_PW_TYPE_DBREGS;
152963d1fd59SEnji Cooper pw.pw_md.md_address = &watchme;
153063d1fd59SEnji Cooper pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
153163d1fd59SEnji Cooper pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
153263d1fd59SEnji Cooper
153363d1fd59SEnji Cooper printf("struct ptrace {\n");
153463d1fd59SEnji Cooper printf("\t.pw_index=%d\n", pw.pw_index);
153563d1fd59SEnji Cooper printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1536*5f761d3cSEnji Cooper printf("\t.pw_type=%#x\n", pw.pw_type);
153763d1fd59SEnji Cooper printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
153863d1fd59SEnji Cooper printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
153963d1fd59SEnji Cooper printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
154063d1fd59SEnji Cooper printf("}\n");
154163d1fd59SEnji Cooper
154263d1fd59SEnji Cooper printf("Before writing watchpoint %d\n", i);
154363d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
154463d1fd59SEnji Cooper
154563d1fd59SEnji Cooper printf("Before resuming the child process where it left off "
154663d1fd59SEnji Cooper "and without signal to be sent\n");
154763d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
154863d1fd59SEnji Cooper
154963d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
155063d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
155163d1fd59SEnji Cooper
155263d1fd59SEnji Cooper validate_status_stopped(status, SIGTRAP);
155363d1fd59SEnji Cooper
1554*5f761d3cSEnji Cooper printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1555*5f761d3cSEnji Cooper ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1556*5f761d3cSEnji Cooper
1557*5f761d3cSEnji Cooper printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
1558*5f761d3cSEnji Cooper printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1559*5f761d3cSEnji Cooper info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1560*5f761d3cSEnji Cooper info.psi_siginfo.si_errno);
1561*5f761d3cSEnji Cooper
1562*5f761d3cSEnji Cooper printf("Before checking siginfo_t\n");
1563*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1564*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT);
1565*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3);
1566*5f761d3cSEnji Cooper ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED);
1567*5f761d3cSEnji Cooper
156863d1fd59SEnji Cooper printf("Before resuming the child process where it left off and "
156963d1fd59SEnji Cooper "without signal to be sent\n");
157063d1fd59SEnji Cooper ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
157163d1fd59SEnji Cooper
157263d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
157363d1fd59SEnji Cooper TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
157463d1fd59SEnji Cooper
157563d1fd59SEnji Cooper validate_status_exited(status, exitval);
157663d1fd59SEnji Cooper
157763d1fd59SEnji Cooper printf("Before calling %s() for the child\n", TWAIT_FNAME);
157863d1fd59SEnji Cooper TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
157963d1fd59SEnji Cooper }
158063d1fd59SEnji Cooper #endif
158163d1fd59SEnji Cooper
ATF_TP_ADD_TCS(tp)158263d1fd59SEnji Cooper ATF_TP_ADD_TCS(tp)
158363d1fd59SEnji Cooper {
158463d1fd59SEnji Cooper setvbuf(stdout, NULL, _IONBF, 0);
158563d1fd59SEnji Cooper setvbuf(stderr, NULL, _IONBF, 0);
158663d1fd59SEnji Cooper
158763d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
158863d1fd59SEnji Cooper
158963d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_count);
159063d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_read);
159163d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_write_unmodified);
159263d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code0);
159363d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code1);
159463d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code2);
159563d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code3);
159663d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write0);
159763d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write1);
159863d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write2);
159963d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write3);
160063d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw0);
160163d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw1);
160263d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw2);
160363d1fd59SEnji Cooper ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw3);
160463d1fd59SEnji Cooper
160563d1fd59SEnji Cooper return atf_no_error();
160663d1fd59SEnji Cooper }
1607