t_ptrace_wait.c revision 1.188
1/*	$NetBSD: t_ptrace_wait.c,v 1.188 2020/05/05 00:50:39 kamil Exp $	*/
2
3/*-
4 * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__RCSID("$NetBSD: t_ptrace_wait.c,v 1.188 2020/05/05 00:50:39 kamil Exp $");
31
32#define __LEGACY_PT_LWPINFO
33
34#include <sys/param.h>
35#include <sys/types.h>
36#include <sys/exec_elf.h>
37#include <sys/mman.h>
38#include <sys/ptrace.h>
39#include <sys/resource.h>
40#include <sys/stat.h>
41#include <sys/syscall.h>
42#include <sys/sysctl.h>
43#include <sys/uio.h>
44#include <sys/wait.h>
45#include <machine/reg.h>
46#include <assert.h>
47#include <elf.h>
48#include <err.h>
49#include <errno.h>
50#include <fcntl.h>
51#include <lwp.h>
52#include <pthread.h>
53#include <sched.h>
54#include <signal.h>
55#include <spawn.h>
56#include <stdint.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <strings.h>
60#include <time.h>
61#include <unistd.h>
62
63#if defined(__i386__) || defined(__x86_64__)
64#include <cpuid.h>
65#include <x86/cpu_extended_state.h>
66#include <x86/specialreg.h>
67#endif
68
69#include <libelf.h>
70#include <gelf.h>
71
72#include <atf-c.h>
73
74#ifdef ENABLE_TESTS
75
76/* Assumptions in the kernel code that must be kept. */
77__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) ==
78    sizeof(((siginfo_t *)0)->si_pe_report_event));
79__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
80    sizeof(((siginfo_t *)0)->si_pe_other_pid));
81__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) ==
82    sizeof(((siginfo_t *)0)->si_pe_lwp));
83__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
84    sizeof(((struct ptrace_state *)0)->pe_lwp));
85
86#include "h_macros.h"
87
88#include "t_ptrace_wait.h"
89#include "msg.h"
90
91#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
92    strerror(errno))
93#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
94    "%d(%s) != %d", res, strerror(res), exp)
95
96static int debug = 0;
97
98#define DPRINTF(a, ...)	do  \
99	if (debug) \
100	printf("%s() %d.%d %s:%d " a, \
101	__func__, getpid(), _lwp_self(), __FILE__, __LINE__,  ##__VA_ARGS__); \
102    while (/*CONSTCOND*/0)
103
104/// ----------------------------------------------------------------------------
105
106static void
107ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
108{
109	const int exitval = 5;
110	const int sigval = SIGINT;
111	const int sigfaked = SIGTRAP;
112	const int sicodefaked = TRAP_BRKPT;
113	pid_t child, wpid;
114	struct sigaction sa;
115#if defined(TWAIT_HAVE_STATUS)
116	int status;
117#endif
118	struct ptrace_siginfo info;
119	memset(&info, 0, sizeof(info));
120
121	DPRINTF("Before forking process PID=%d\n", getpid());
122	SYSCALL_REQUIRE((child = fork()) != -1);
123	if (child == 0) {
124		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
125		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
126
127		sa.sa_sigaction = sah;
128		sa.sa_flags = SA_SIGINFO;
129		sigemptyset(&sa.sa_mask);
130
131		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
132		    != -1);
133
134		DPRINTF("Before raising %s from child\n", strsignal(sigval));
135		FORKEE_ASSERT(raise(sigval) == 0);
136
137		FORKEE_ASSERT_EQ(*signal_caught, 1);
138
139		DPRINTF("Before exiting of the child process\n");
140		_exit(exitval);
141	}
142	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
143
144	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
145	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
146
147	validate_status_stopped(status, sigval);
148
149	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
150	SYSCALL_REQUIRE(
151	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
152
153	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
154	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
155	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
156	    info.psi_siginfo.si_errno);
157
158	if (faked) {
159		DPRINTF("Before setting new faked signal to signo=%d "
160		    "si_code=%d\n", sigfaked, sicodefaked);
161		info.psi_siginfo.si_signo = sigfaked;
162		info.psi_siginfo.si_code = sicodefaked;
163	}
164
165	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
166	SYSCALL_REQUIRE(
167	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
168
169	if (faked) {
170		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
171		    "child\n");
172		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
173		    sizeof(info)) != -1);
174
175		DPRINTF("Before checking siginfo_t\n");
176		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
177		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
178	}
179
180	DPRINTF("Before resuming the child process where it left off and "
181	    "without signal to be sent\n");
182	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
183	    faked ? sigfaked : sigval) != -1);
184
185	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
186	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
187
188	validate_status_exited(status, exitval);
189
190	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
191	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
192}
193
194#define PTRACE_SIGINFO(test, faked)					\
195ATF_TC(test);								\
196ATF_TC_HEAD(test, tc)							\
197{									\
198	atf_tc_set_md_var(tc, "descr",					\
199	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
200	    "with%s setting signal to new value", faked ? "" : "out");	\
201}									\
202									\
203static int test##_caught = 0;						\
204									\
205static void								\
206test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
207{									\
208	if (faked) {							\
209		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
210		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
211		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
212	} else {							\
213		FORKEE_ASSERT_EQ(sig, SIGINT);				\
214		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
215		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
216	}								\
217									\
218	++ test##_caught;						\
219}									\
220									\
221ATF_TC_BODY(test, tc)							\
222{									\
223									\
224	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
225}
226
227PTRACE_SIGINFO(siginfo_set_unmodified, false)
228PTRACE_SIGINFO(siginfo_set_faked, true)
229
230/// ----------------------------------------------------------------------------
231
232static void
233user_va0_disable(int operation)
234{
235	pid_t child, wpid;
236#if defined(TWAIT_HAVE_STATUS)
237	int status;
238#endif
239	const int sigval = SIGSTOP;
240	int rv;
241
242	struct ptrace_siginfo info;
243
244	if (get_user_va0_disable() == 0)
245		atf_tc_skip("vm.user_va0_disable is set to 0");
246
247	memset(&info, 0, sizeof(info));
248
249	DPRINTF("Before forking process PID=%d\n", getpid());
250	SYSCALL_REQUIRE((child = fork()) != -1);
251	if (child == 0) {
252		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
253		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
254
255		DPRINTF("Before raising %s from child\n", strsignal(sigval));
256		FORKEE_ASSERT(raise(sigval) == 0);
257
258		/* NOTREACHED */
259		FORKEE_ASSERTX(0 && "This shall not be reached");
260		__unreachable();
261	}
262	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
263
264	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
265	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
266
267	validate_status_stopped(status, sigval);
268
269	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
270		"child\n");
271	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
272		sizeof(info)) != -1);
273
274	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
275	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
276		"si_errno=%#x\n",
277		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
278		info.psi_siginfo.si_errno);
279
280	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
281	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
282
283	DPRINTF("Before resuming the child process in PC=0x0 "
284	    "and without signal to be sent\n");
285	errno = 0;
286	rv = ptrace(operation, child, (void *)0, 0);
287	ATF_REQUIRE_EQ(errno, EINVAL);
288	ATF_REQUIRE_EQ(rv, -1);
289
290	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
291
292	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
293	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
294	validate_status_signaled(status, SIGKILL, 0);
295
296	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
297	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
298}
299
300#define USER_VA0_DISABLE(test, operation)				\
301ATF_TC(test);								\
302ATF_TC_HEAD(test, tc)							\
303{									\
304	atf_tc_set_md_var(tc, "descr",					\
305	    "Verify behavior of " #operation " with PC set to 0x0");	\
306}									\
307									\
308ATF_TC_BODY(test, tc)							\
309{									\
310									\
311	user_va0_disable(operation);					\
312}
313
314USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
315USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
316USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
317
318/// ----------------------------------------------------------------------------
319
320/*
321 * Parse the core file and find the requested note.  If the reading or parsing
322 * fails, the test is failed.  If the note is found, it is read onto buf, up to
323 * buf_len.  The actual length of the note is returned (which can be greater
324 * than buf_len, indicating that it has been truncated).  If the note is not
325 * found, -1 is returned.
326 *
327 * If the note_name ends in '*', then we find the first note that matches
328 * the note_name prefix up to the '*' character, e.g.:
329 *
330 *	NetBSD-CORE@*
331 *
332 * finds the first note whose name prefix matches "NetBSD-CORE@".
333 */
334static ssize_t core_find_note(const char *core_path,
335    const char *note_name, uint64_t note_type, void *buf, size_t buf_len)
336{
337	int core_fd;
338	Elf *core_elf;
339	size_t core_numhdr, i;
340	ssize_t ret = -1;
341	size_t name_len = strlen(note_name);
342	bool prefix_match = false;
343
344	if (note_name[name_len - 1] == '*') {
345		prefix_match = true;
346		name_len--;
347	} else {
348		/* note: we assume note name will be null-terminated */
349		name_len++;
350	}
351
352	SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1);
353	SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE);
354	SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL)));
355
356	SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0);
357	for (i = 0; i < core_numhdr && ret == -1; i++) {
358		GElf_Phdr core_hdr;
359		size_t offset;
360		SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr));
361		if (core_hdr.p_type != PT_NOTE)
362		    continue;
363
364		for (offset = core_hdr.p_offset;
365		    offset < core_hdr.p_offset + core_hdr.p_filesz;) {
366			Elf64_Nhdr note_hdr;
367			char name_buf[64];
368
369			switch (gelf_getclass(core_elf)) {
370			case ELFCLASS64:
371				SYSCALL_REQUIRE(pread(core_fd, &note_hdr,
372				    sizeof(note_hdr), offset)
373				    == sizeof(note_hdr));
374				offset += sizeof(note_hdr);
375				break;
376			case ELFCLASS32:
377				{
378				Elf32_Nhdr tmp_hdr;
379				SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr,
380				    sizeof(tmp_hdr), offset)
381				    == sizeof(tmp_hdr));
382				offset += sizeof(tmp_hdr);
383				note_hdr.n_namesz = tmp_hdr.n_namesz;
384				note_hdr.n_descsz = tmp_hdr.n_descsz;
385				note_hdr.n_type = tmp_hdr.n_type;
386				}
387				break;
388			}
389
390			/* indicates end of notes */
391			if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0)
392				break;
393			if (((prefix_match &&
394			      note_hdr.n_namesz > name_len) ||
395			     (!prefix_match &&
396			      note_hdr.n_namesz == name_len)) &&
397			    note_hdr.n_namesz <= sizeof(name_buf)) {
398				SYSCALL_REQUIRE(pread(core_fd, name_buf,
399				    note_hdr.n_namesz, offset)
400				    == (ssize_t)(size_t)note_hdr.n_namesz);
401
402				if (!strncmp(note_name, name_buf, name_len) &&
403				    note_hdr.n_type == note_type)
404					ret = note_hdr.n_descsz;
405			}
406
407			offset += note_hdr.n_namesz;
408			/* fix to alignment */
409			offset = roundup(offset, core_hdr.p_align);
410
411			/* if name & type matched above */
412			if (ret != -1) {
413				ssize_t read_len = MIN(buf_len,
414				    note_hdr.n_descsz);
415				SYSCALL_REQUIRE(pread(core_fd, buf,
416				    read_len, offset) == read_len);
417				break;
418			}
419
420			offset += note_hdr.n_descsz;
421			/* fix to alignment */
422			offset = roundup(offset, core_hdr.p_align);
423		}
424	}
425
426	elf_end(core_elf);
427	close(core_fd);
428
429	return ret;
430}
431
432ATF_TC(core_dump_procinfo);
433ATF_TC_HEAD(core_dump_procinfo, tc)
434{
435	atf_tc_set_md_var(tc, "descr",
436		"Trigger a core dump and verify its contents.");
437}
438
439ATF_TC_BODY(core_dump_procinfo, tc)
440{
441	const int exitval = 5;
442	pid_t child, wpid;
443#if defined(TWAIT_HAVE_STATUS)
444	const int sigval = SIGTRAP;
445	int status;
446#endif
447	char core_path[] = "/tmp/core.XXXXXX";
448	int core_fd;
449	struct netbsd_elfcore_procinfo procinfo;
450
451	DPRINTF("Before forking process PID=%d\n", getpid());
452	SYSCALL_REQUIRE((child = fork()) != -1);
453	if (child == 0) {
454		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
455		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
456
457		DPRINTF("Before triggering SIGTRAP\n");
458		trigger_trap();
459
460		DPRINTF("Before exiting of the child process\n");
461		_exit(exitval);
462	}
463	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
464
465	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
466	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
467
468	validate_status_stopped(status, sigval);
469
470	SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1);
471	close(core_fd);
472
473	DPRINTF("Call DUMPCORE for the child process\n");
474	SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path))
475	    != -1);
476
477	DPRINTF("Read core file\n");
478	ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE",
479	    ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)),
480	    sizeof(procinfo));
481
482	ATF_CHECK_EQ(procinfo.cpi_version, 1);
483	ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo));
484	ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP);
485	ATF_CHECK_EQ(procinfo.cpi_pid, child);
486	ATF_CHECK_EQ(procinfo.cpi_ppid, getpid());
487	ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child));
488	ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child));
489	ATF_CHECK_EQ(procinfo.cpi_ruid, getuid());
490	ATF_CHECK_EQ(procinfo.cpi_euid, geteuid());
491	ATF_CHECK_EQ(procinfo.cpi_rgid, getgid());
492	ATF_CHECK_EQ(procinfo.cpi_egid, getegid());
493	ATF_CHECK_EQ(procinfo.cpi_nlwps, 1);
494	ATF_CHECK(procinfo.cpi_siglwp > 0);
495
496	unlink(core_path);
497
498	DPRINTF("Before resuming the child process where it left off and "
499	    "without signal to be sent\n");
500	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
501
502	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
503	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
504
505	validate_status_exited(status, exitval);
506
507	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
508	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
509}
510
511/// ----------------------------------------------------------------------------
512
513#include "t_ptrace_register_wait.h"
514#include "t_ptrace_syscall_wait.h"
515#include "t_ptrace_step_wait.h"
516#include "t_ptrace_kill_wait.h"
517#include "t_ptrace_bytetransfer_wait.h"
518#include "t_ptrace_clone_wait.h"
519#include "t_ptrace_fork_wait.h"
520#include "t_ptrace_signal_wait.h"
521#include "t_ptrace_eventmask_wait.h"
522#include "t_ptrace_lwp_wait.h"
523#include "t_ptrace_exec_wait.h"
524#include "t_ptrace_topology_wait.h"
525#include "t_ptrace_threads_wait.h"
526
527/// ----------------------------------------------------------------------------
528
529#include "t_ptrace_amd64_wait.h"
530#include "t_ptrace_i386_wait.h"
531#include "t_ptrace_x86_wait.h"
532
533/// ----------------------------------------------------------------------------
534
535#else
536ATF_TC(dummy);
537ATF_TC_HEAD(dummy, tc)
538{
539	atf_tc_set_md_var(tc, "descr", "A dummy test");
540}
541
542ATF_TC_BODY(dummy, tc)
543{
544
545	// Dummy, skipped
546	// The ATF framework requires at least a single defined test.
547}
548#endif
549
550ATF_TP_ADD_TCS(tp)
551{
552	setvbuf(stdout, NULL, _IONBF, 0);
553	setvbuf(stderr, NULL, _IONBF, 0);
554
555#ifdef ENABLE_TESTS
556	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
557	ATF_TP_ADD_TC(tp, siginfo_set_faked);
558
559	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
560	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
561	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
562
563	ATF_TP_ADD_TC(tp, core_dump_procinfo);
564
565	ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER();
566	ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
567	ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
568	ATF_TP_ADD_TCS_PTRACE_WAIT_KILL();
569	ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER();
570	ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE();
571	ATF_TP_ADD_TCS_PTRACE_WAIT_FORK();
572	ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL();
573	ATF_TP_ADD_TCS_PTRACE_WAIT_EVENTMASK();
574	ATF_TP_ADD_TCS_PTRACE_WAIT_LWP();
575	ATF_TP_ADD_TCS_PTRACE_WAIT_EXEC();
576	ATF_TP_ADD_TCS_PTRACE_WAIT_TOPOLOGY();
577	ATF_TP_ADD_TCS_PTRACE_WAIT_THREADS();
578
579	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
580	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
581	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
582
583#else
584	ATF_TP_ADD_TC(tp, dummy);
585#endif
586
587	return atf_no_error();
588}
589