t_ptrace_wait.c revision 1.189
11.189Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.189 2020/05/05 00:57:34 kamil Exp $	*/
21.1Skamil
31.1Skamil/*-
41.181Skamil * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
51.1Skamil * All rights reserved.
61.1Skamil *
71.1Skamil * Redistribution and use in source and binary forms, with or without
81.1Skamil * modification, are permitted provided that the following conditions
91.1Skamil * are met:
101.1Skamil * 1. Redistributions of source code must retain the above copyright
111.1Skamil *    notice, this list of conditions and the following disclaimer.
121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright
131.1Skamil *    notice, this list of conditions and the following disclaimer in the
141.1Skamil *    documentation and/or other materials provided with the distribution.
151.1Skamil *
161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Skamil * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Skamil * POSSIBILITY OF SUCH DAMAGE.
271.1Skamil */
281.1Skamil
291.1Skamil#include <sys/cdefs.h>
301.189Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.189 2020/05/05 00:57:34 kamil Exp $");
311.143Skamil
321.143Skamil#define __LEGACY_PT_LWPINFO
331.1Skamil
341.1Skamil#include <sys/param.h>
351.1Skamil#include <sys/types.h>
361.130Smgorny#include <sys/exec_elf.h>
371.39Skamil#include <sys/mman.h>
381.1Skamil#include <sys/ptrace.h>
391.1Skamil#include <sys/resource.h>
401.1Skamil#include <sys/stat.h>
411.1Skamil#include <sys/syscall.h>
421.1Skamil#include <sys/sysctl.h>
431.129Smgorny#include <sys/uio.h>
441.1Skamil#include <sys/wait.h>
451.1Skamil#include <machine/reg.h>
461.132Skamil#include <assert.h>
471.1Skamil#include <elf.h>
481.1Skamil#include <err.h>
491.1Skamil#include <errno.h>
501.130Smgorny#include <fcntl.h>
511.1Skamil#include <lwp.h>
521.77Skamil#include <pthread.h>
531.1Skamil#include <sched.h>
541.1Skamil#include <signal.h>
551.124Skamil#include <spawn.h>
561.1Skamil#include <stdint.h>
571.1Skamil#include <stdio.h>
581.1Skamil#include <stdlib.h>
591.1Skamil#include <strings.h>
601.26Skamil#include <time.h>
611.1Skamil#include <unistd.h>
621.1Skamil
631.121Smgorny#if defined(__i386__) || defined(__x86_64__)
641.121Smgorny#include <cpuid.h>
651.121Smgorny#include <x86/cpu_extended_state.h>
661.129Smgorny#include <x86/specialreg.h>
671.121Smgorny#endif
681.121Smgorny
691.130Smgorny#include <libelf.h>
701.130Smgorny#include <gelf.h>
711.130Smgorny
721.1Skamil#include <atf-c.h>
731.1Skamil
741.165Skamil#ifdef ENABLE_TESTS
751.165Skamil
761.132Skamil/* Assumptions in the kernel code that must be kept. */
771.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) ==
781.171Skamil    sizeof(((siginfo_t *)0)->si_pe_report_event));
791.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
801.171Skamil    sizeof(((siginfo_t *)0)->si_pe_other_pid));
811.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) ==
821.171Skamil    sizeof(((siginfo_t *)0)->si_pe_lwp));
831.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
841.171Skamil    sizeof(((struct ptrace_state *)0)->pe_lwp));
851.132Skamil
861.1Skamil#include "h_macros.h"
871.1Skamil
881.1Skamil#include "t_ptrace_wait.h"
891.1Skamil#include "msg.h"
901.1Skamil
911.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
921.13Schristos    strerror(errno))
931.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
941.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
951.13Schristos
961.152Skamilstatic int debug = 0;
971.13Schristos
981.13Schristos#define DPRINTF(a, ...)	do  \
991.123Skamil	if (debug) \
1001.142Skamil	printf("%s() %d.%d %s:%d " a, \
1011.142Skamil	__func__, getpid(), _lwp_self(), __FILE__, __LINE__,  ##__VA_ARGS__); \
1021.13Schristos    while (/*CONSTCOND*/0)
1031.1Skamil
1041.34Skamil/// ----------------------------------------------------------------------------
1051.34Skamil
1061.83Skamilstatic void
1071.122Skamiluser_va0_disable(int operation)
1081.122Skamil{
1091.122Skamil	pid_t child, wpid;
1101.122Skamil#if defined(TWAIT_HAVE_STATUS)
1111.122Skamil	int status;
1121.122Skamil#endif
1131.122Skamil	const int sigval = SIGSTOP;
1141.122Skamil	int rv;
1151.122Skamil
1161.122Skamil	struct ptrace_siginfo info;
1171.122Skamil
1181.122Skamil	if (get_user_va0_disable() == 0)
1191.122Skamil		atf_tc_skip("vm.user_va0_disable is set to 0");
1201.122Skamil
1211.122Skamil	memset(&info, 0, sizeof(info));
1221.122Skamil
1231.122Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
1241.122Skamil	SYSCALL_REQUIRE((child = fork()) != -1);
1251.122Skamil	if (child == 0) {
1261.122Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1271.122Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1281.122Skamil
1291.122Skamil		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1301.122Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1311.122Skamil
1321.122Skamil		/* NOTREACHED */
1331.122Skamil		FORKEE_ASSERTX(0 && "This shall not be reached");
1341.122Skamil		__unreachable();
1351.122Skamil	}
1361.122Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1371.122Skamil
1381.122Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1391.122Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1401.122Skamil
1411.122Skamil	validate_status_stopped(status, sigval);
1421.122Skamil
1431.122Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1441.122Skamil		"child\n");
1451.122Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1461.122Skamil		sizeof(info)) != -1);
1471.122Skamil
1481.122Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1491.122Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1501.122Skamil		"si_errno=%#x\n",
1511.122Skamil		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1521.122Skamil		info.psi_siginfo.si_errno);
1531.122Skamil
1541.122Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1551.122Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1561.122Skamil
1571.122Skamil	DPRINTF("Before resuming the child process in PC=0x0 "
1581.122Skamil	    "and without signal to be sent\n");
1591.122Skamil	errno = 0;
1601.122Skamil	rv = ptrace(operation, child, (void *)0, 0);
1611.122Skamil	ATF_REQUIRE_EQ(errno, EINVAL);
1621.122Skamil	ATF_REQUIRE_EQ(rv, -1);
1631.122Skamil
1641.122Skamil	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
1651.122Skamil
1661.122Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1671.122Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1681.122Skamil	validate_status_signaled(status, SIGKILL, 0);
1691.122Skamil
1701.122Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1711.122Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1721.122Skamil}
1731.122Skamil
1741.122Skamil#define USER_VA0_DISABLE(test, operation)				\
1751.122SkamilATF_TC(test);								\
1761.122SkamilATF_TC_HEAD(test, tc)							\
1771.122Skamil{									\
1781.122Skamil	atf_tc_set_md_var(tc, "descr",					\
1791.122Skamil	    "Verify behavior of " #operation " with PC set to 0x0");	\
1801.122Skamil}									\
1811.122Skamil									\
1821.122SkamilATF_TC_BODY(test, tc)							\
1831.122Skamil{									\
1841.122Skamil									\
1851.122Skamil	user_va0_disable(operation);					\
1861.122Skamil}
1871.122Skamil
1881.122SkamilUSER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
1891.122SkamilUSER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
1901.122SkamilUSER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
1911.122Skamil
1921.122Skamil/// ----------------------------------------------------------------------------
1931.122Skamil
1941.130Smgorny/*
1951.130Smgorny * Parse the core file and find the requested note.  If the reading or parsing
1961.130Smgorny * fails, the test is failed.  If the note is found, it is read onto buf, up to
1971.130Smgorny * buf_len.  The actual length of the note is returned (which can be greater
1981.130Smgorny * than buf_len, indicating that it has been truncated).  If the note is not
1991.130Smgorny * found, -1 is returned.
2001.172Sthorpej *
2011.172Sthorpej * If the note_name ends in '*', then we find the first note that matches
2021.172Sthorpej * the note_name prefix up to the '*' character, e.g.:
2031.172Sthorpej *
2041.172Sthorpej *	NetBSD-CORE@*
2051.172Sthorpej *
2061.172Sthorpej * finds the first note whose name prefix matches "NetBSD-CORE@".
2071.130Smgorny */
2081.130Smgornystatic ssize_t core_find_note(const char *core_path,
2091.130Smgorny    const char *note_name, uint64_t note_type, void *buf, size_t buf_len)
2101.130Smgorny{
2111.130Smgorny	int core_fd;
2121.130Smgorny	Elf *core_elf;
2131.130Smgorny	size_t core_numhdr, i;
2141.130Smgorny	ssize_t ret = -1;
2151.172Sthorpej	size_t name_len = strlen(note_name);
2161.172Sthorpej	bool prefix_match = false;
2171.172Sthorpej
2181.172Sthorpej	if (note_name[name_len - 1] == '*') {
2191.172Sthorpej		prefix_match = true;
2201.172Sthorpej		name_len--;
2211.172Sthorpej	} else {
2221.172Sthorpej		/* note: we assume note name will be null-terminated */
2231.172Sthorpej		name_len++;
2241.172Sthorpej	}
2251.130Smgorny
2261.130Smgorny	SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1);
2271.130Smgorny	SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE);
2281.130Smgorny	SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL)));
2291.130Smgorny
2301.130Smgorny	SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0);
2311.130Smgorny	for (i = 0; i < core_numhdr && ret == -1; i++) {
2321.130Smgorny		GElf_Phdr core_hdr;
2331.130Smgorny		size_t offset;
2341.130Smgorny		SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr));
2351.130Smgorny		if (core_hdr.p_type != PT_NOTE)
2361.130Smgorny		    continue;
2371.130Smgorny
2381.130Smgorny		for (offset = core_hdr.p_offset;
2391.130Smgorny		    offset < core_hdr.p_offset + core_hdr.p_filesz;) {
2401.130Smgorny			Elf64_Nhdr note_hdr;
2411.130Smgorny			char name_buf[64];
2421.130Smgorny
2431.130Smgorny			switch (gelf_getclass(core_elf)) {
2441.130Smgorny			case ELFCLASS64:
2451.130Smgorny				SYSCALL_REQUIRE(pread(core_fd, &note_hdr,
2461.130Smgorny				    sizeof(note_hdr), offset)
2471.130Smgorny				    == sizeof(note_hdr));
2481.130Smgorny				offset += sizeof(note_hdr);
2491.130Smgorny				break;
2501.130Smgorny			case ELFCLASS32:
2511.130Smgorny				{
2521.130Smgorny				Elf32_Nhdr tmp_hdr;
2531.130Smgorny				SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr,
2541.130Smgorny				    sizeof(tmp_hdr), offset)
2551.130Smgorny				    == sizeof(tmp_hdr));
2561.130Smgorny				offset += sizeof(tmp_hdr);
2571.130Smgorny				note_hdr.n_namesz = tmp_hdr.n_namesz;
2581.130Smgorny				note_hdr.n_descsz = tmp_hdr.n_descsz;
2591.130Smgorny				note_hdr.n_type = tmp_hdr.n_type;
2601.130Smgorny				}
2611.130Smgorny				break;
2621.130Smgorny			}
2631.130Smgorny
2641.130Smgorny			/* indicates end of notes */
2651.130Smgorny			if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0)
2661.130Smgorny				break;
2671.172Sthorpej			if (((prefix_match &&
2681.172Sthorpej			      note_hdr.n_namesz > name_len) ||
2691.172Sthorpej			     (!prefix_match &&
2701.172Sthorpej			      note_hdr.n_namesz == name_len)) &&
2711.130Smgorny			    note_hdr.n_namesz <= sizeof(name_buf)) {
2721.130Smgorny				SYSCALL_REQUIRE(pread(core_fd, name_buf,
2731.130Smgorny				    note_hdr.n_namesz, offset)
2741.131Skamil				    == (ssize_t)(size_t)note_hdr.n_namesz);
2751.130Smgorny
2761.130Smgorny				if (!strncmp(note_name, name_buf, name_len) &&
2771.130Smgorny				    note_hdr.n_type == note_type)
2781.130Smgorny					ret = note_hdr.n_descsz;
2791.130Smgorny			}
2801.130Smgorny
2811.130Smgorny			offset += note_hdr.n_namesz;
2821.130Smgorny			/* fix to alignment */
2831.146Smgorny			offset = roundup(offset, core_hdr.p_align);
2841.130Smgorny
2851.130Smgorny			/* if name & type matched above */
2861.130Smgorny			if (ret != -1) {
2871.130Smgorny				ssize_t read_len = MIN(buf_len,
2881.130Smgorny				    note_hdr.n_descsz);
2891.130Smgorny				SYSCALL_REQUIRE(pread(core_fd, buf,
2901.130Smgorny				    read_len, offset) == read_len);
2911.130Smgorny				break;
2921.130Smgorny			}
2931.130Smgorny
2941.130Smgorny			offset += note_hdr.n_descsz;
2951.146Smgorny			/* fix to alignment */
2961.146Smgorny			offset = roundup(offset, core_hdr.p_align);
2971.130Smgorny		}
2981.130Smgorny	}
2991.130Smgorny
3001.130Smgorny	elf_end(core_elf);
3011.130Smgorny	close(core_fd);
3021.130Smgorny
3031.130Smgorny	return ret;
3041.130Smgorny}
3051.130Smgorny
3061.130SmgornyATF_TC(core_dump_procinfo);
3071.130SmgornyATF_TC_HEAD(core_dump_procinfo, tc)
3081.130Smgorny{
3091.130Smgorny	atf_tc_set_md_var(tc, "descr",
3101.130Smgorny		"Trigger a core dump and verify its contents.");
3111.130Smgorny}
3121.130Smgorny
3131.130SmgornyATF_TC_BODY(core_dump_procinfo, tc)
3141.130Smgorny{
3151.130Smgorny	const int exitval = 5;
3161.130Smgorny	pid_t child, wpid;
3171.130Smgorny#if defined(TWAIT_HAVE_STATUS)
3181.130Smgorny	const int sigval = SIGTRAP;
3191.130Smgorny	int status;
3201.130Smgorny#endif
3211.130Smgorny	char core_path[] = "/tmp/core.XXXXXX";
3221.130Smgorny	int core_fd;
3231.130Smgorny	struct netbsd_elfcore_procinfo procinfo;
3241.130Smgorny
3251.130Smgorny	DPRINTF("Before forking process PID=%d\n", getpid());
3261.130Smgorny	SYSCALL_REQUIRE((child = fork()) != -1);
3271.130Smgorny	if (child == 0) {
3281.130Smgorny		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3291.130Smgorny		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3301.130Smgorny
3311.130Smgorny		DPRINTF("Before triggering SIGTRAP\n");
3321.130Smgorny		trigger_trap();
3331.130Smgorny
3341.130Smgorny		DPRINTF("Before exiting of the child process\n");
3351.130Smgorny		_exit(exitval);
3361.130Smgorny	}
3371.130Smgorny	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3381.130Smgorny
3391.130Smgorny	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3401.130Smgorny	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3411.130Smgorny
3421.130Smgorny	validate_status_stopped(status, sigval);
3431.130Smgorny
3441.130Smgorny	SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1);
3451.130Smgorny	close(core_fd);
3461.130Smgorny
3471.130Smgorny	DPRINTF("Call DUMPCORE for the child process\n");
3481.130Smgorny	SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path))
3491.130Smgorny	    != -1);
3501.130Smgorny
3511.130Smgorny	DPRINTF("Read core file\n");
3521.130Smgorny	ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE",
3531.130Smgorny	    ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)),
3541.130Smgorny	    sizeof(procinfo));
3551.130Smgorny
3561.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_version, 1);
3571.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo));
3581.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP);
3591.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_pid, child);
3601.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_ppid, getpid());
3611.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child));
3621.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child));
3631.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_ruid, getuid());
3641.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_euid, geteuid());
3651.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_rgid, getgid());
3661.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_egid, getegid());
3671.130Smgorny	ATF_CHECK_EQ(procinfo.cpi_nlwps, 1);
3681.173Skamil	ATF_CHECK(procinfo.cpi_siglwp > 0);
3691.130Smgorny
3701.130Smgorny	unlink(core_path);
3711.130Smgorny
3721.130Smgorny	DPRINTF("Before resuming the child process where it left off and "
3731.130Smgorny	    "without signal to be sent\n");
3741.130Smgorny	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3751.130Smgorny
3761.130Smgorny	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3771.130Smgorny	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3781.130Smgorny
3791.130Smgorny	validate_status_exited(status, exitval);
3801.130Smgorny
3811.130Smgorny	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3821.130Smgorny	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3831.130Smgorny}
3841.130Smgorny
3851.130Smgorny/// ----------------------------------------------------------------------------
3861.130Smgorny
3871.174Skamil#include "t_ptrace_register_wait.h"
3881.175Skamil#include "t_ptrace_syscall_wait.h"
3891.176Skamil#include "t_ptrace_step_wait.h"
3901.177Skamil#include "t_ptrace_kill_wait.h"
3911.178Skamil#include "t_ptrace_bytetransfer_wait.h"
3921.179Skamil#include "t_ptrace_clone_wait.h"
3931.180Skamil#include "t_ptrace_fork_wait.h"
3941.181Skamil#include "t_ptrace_signal_wait.h"
3951.183Skamil#include "t_ptrace_eventmask_wait.h"
3961.185Skamil#include "t_ptrace_lwp_wait.h"
3971.186Skamil#include "t_ptrace_exec_wait.h"
3981.187Skamil#include "t_ptrace_topology_wait.h"
3991.188Skamil#include "t_ptrace_threads_wait.h"
4001.189Skamil#include "t_ptrace_siginfo_wait.h"
4011.174Skamil
4021.174Skamil/// ----------------------------------------------------------------------------
4031.174Skamil
4041.1Skamil#include "t_ptrace_amd64_wait.h"
4051.1Skamil#include "t_ptrace_i386_wait.h"
4061.1Skamil#include "t_ptrace_x86_wait.h"
4071.1Skamil
4081.165Skamil/// ----------------------------------------------------------------------------
4091.165Skamil
4101.165Skamil#else
4111.165SkamilATF_TC(dummy);
4121.165SkamilATF_TC_HEAD(dummy, tc)
4131.165Skamil{
4141.165Skamil	atf_tc_set_md_var(tc, "descr", "A dummy test");
4151.165Skamil}
4161.165Skamil
4171.165SkamilATF_TC_BODY(dummy, tc)
4181.165Skamil{
4191.165Skamil
4201.165Skamil	// Dummy, skipped
4211.165Skamil	// The ATF framework requires at least a single defined test.
4221.165Skamil}
4231.165Skamil#endif
4241.165Skamil
4251.1SkamilATF_TP_ADD_TCS(tp)
4261.1Skamil{
4271.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
4281.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
4291.33Skamil
4301.165Skamil#ifdef ENABLE_TESTS
4311.122Skamil	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
4321.122Skamil	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
4331.122Skamil	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
4341.122Skamil
4351.130Smgorny	ATF_TP_ADD_TC(tp, core_dump_procinfo);
4361.130Smgorny
4371.174Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER();
4381.175Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
4391.176Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
4401.177Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_KILL();
4411.178Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER();
4421.179Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE();
4431.180Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_FORK();
4441.181Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL();
4451.183Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_EVENTMASK();
4461.185Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_LWP();
4471.186Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_EXEC();
4481.187Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_TOPOLOGY();
4491.188Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_THREADS();
4501.189Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_SIGINFO();
4511.174Skamil
4521.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
4531.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
4541.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
4551.1Skamil
4561.165Skamil#else
4571.165Skamil	ATF_TP_ADD_TC(tp, dummy);
4581.165Skamil#endif
4591.165Skamil
4601.1Skamil	return atf_no_error();
4611.1Skamil}
462