Module Name: src
Committed By: kamil
Date: Mon May 4 22:05:29 UTC 2020
Modified Files:
src/tests/lib/libc/sys: t_ptrace_wait.c
Added Files:
src/tests/lib/libc/sys: t_ptrace_bytetransfer_wait.h
Log Message:
Move byte transfer tests out of t_ptrace_wait.c to t_ptrace_bytetransfer_wait.h
The same tests are now included with the preprocessor in t_ptrace_wait.c.
No functional change intended.
To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/tests/lib/libc/sys/t_ptrace_bytetransfer_wait.h
cvs rdiff -u -r1.177 -r1.178 src/tests/lib/libc/sys/t_ptrace_wait.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/tests/lib/libc/sys/t_ptrace_wait.c
diff -u src/tests/lib/libc/sys/t_ptrace_wait.c:1.177 src/tests/lib/libc/sys/t_ptrace_wait.c:1.178
--- src/tests/lib/libc/sys/t_ptrace_wait.c:1.177 Mon May 4 21:55:12 2020
+++ src/tests/lib/libc/sys/t_ptrace_wait.c Mon May 4 22:05:28 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: t_ptrace_wait.c,v 1.177 2020/05/04 21:55:12 kamil Exp $ */
+/* $NetBSD: t_ptrace_wait.c,v 1.178 2020/05/04 22:05:28 kamil Exp $ */
/*-
* Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ptrace_wait.c,v 1.177 2020/05/04 21:55:12 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace_wait.c,v 1.178 2020/05/04 22:05:28 kamil Exp $");
#define __LEGACY_PT_LWPINFO
@@ -4194,826 +4194,6 @@ TRACEME_VFORK_FORK_TEST(traceme_vfork_vf
/// ----------------------------------------------------------------------------
-enum bytes_transfer_type {
- BYTES_TRANSFER_DATA,
- BYTES_TRANSFER_DATAIO,
- BYTES_TRANSFER_TEXT,
- BYTES_TRANSFER_TEXTIO,
- BYTES_TRANSFER_AUXV
-};
-
-static int __used
-bytes_transfer_dummy(int a, int b, int c, int d)
-{
- int e, f, g, h;
-
- a *= 4;
- b += 3;
- c -= 2;
- d /= 1;
-
- e = strtol("10", NULL, 10);
- f = strtol("20", NULL, 10);
- g = strtol("30", NULL, 10);
- h = strtol("40", NULL, 10);
-
- return (a + b * c - d) + (e * f - g / h);
-}
-
-static void
-bytes_transfer(int operation, size_t size, enum bytes_transfer_type type)
-{
- const int exitval = 5;
- const int sigval = SIGSTOP;
- pid_t child, wpid;
- bool skip = false;
-
- int lookup_me = 0;
- uint8_t lookup_me8 = 0;
- uint16_t lookup_me16 = 0;
- uint32_t lookup_me32 = 0;
- uint64_t lookup_me64 = 0;
-
- int magic = 0x13579246;
- uint8_t magic8 = 0xab;
- uint16_t magic16 = 0x1234;
- uint32_t magic32 = 0x98765432;
- uint64_t magic64 = 0xabcdef0123456789;
-
- struct ptrace_io_desc io;
-#if defined(TWAIT_HAVE_STATUS)
- int status;
-#endif
- /* 513 is just enough, for the purposes of ATF it's good enough */
- AuxInfo ai[513], *aip;
-
- ATF_REQUIRE(size < sizeof(ai));
-
- /* Prepare variables for .TEXT transfers */
- switch (type) {
- case BYTES_TRANSFER_TEXT:
- memcpy(&magic, bytes_transfer_dummy, sizeof(magic));
- break;
- case BYTES_TRANSFER_TEXTIO:
- switch (size) {
- case 8:
- memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8));
- break;
- case 16:
- memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16));
- break;
- case 32:
- memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32));
- break;
- case 64:
- memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64));
- break;
- }
- break;
- default:
- break;
- }
-
- /* Prepare variables for PIOD and AUXV transfers */
- switch (type) {
- case BYTES_TRANSFER_TEXTIO:
- case BYTES_TRANSFER_DATAIO:
- io.piod_op = operation;
- switch (size) {
- case 8:
- io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
- (void *)bytes_transfer_dummy :
- &lookup_me8;
- io.piod_addr = &lookup_me8;
- io.piod_len = sizeof(lookup_me8);
- break;
- case 16:
- io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
- (void *)bytes_transfer_dummy :
- &lookup_me16;
- io.piod_addr = &lookup_me16;
- io.piod_len = sizeof(lookup_me16);
- break;
- case 32:
- io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
- (void *)bytes_transfer_dummy :
- &lookup_me32;
- io.piod_addr = &lookup_me32;
- io.piod_len = sizeof(lookup_me32);
- break;
- case 64:
- io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
- (void *)bytes_transfer_dummy :
- &lookup_me64;
- io.piod_addr = &lookup_me64;
- io.piod_len = sizeof(lookup_me64);
- break;
- default:
- break;
- }
- break;
- case BYTES_TRANSFER_AUXV:
- io.piod_op = operation;
- io.piod_offs = 0;
- io.piod_addr = ai;
- io.piod_len = size;
- break;
- default:
- break;
- }
-
- DPRINTF("Before forking process PID=%d\n", getpid());
- SYSCALL_REQUIRE((child = fork()) != -1);
- if (child == 0) {
- DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
- FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
-
- switch (type) {
- case BYTES_TRANSFER_DATA:
- switch (operation) {
- case PT_READ_D:
- case PT_READ_I:
- lookup_me = magic;
- break;
- default:
- break;
- }
- break;
- case BYTES_TRANSFER_DATAIO:
- switch (operation) {
- case PIOD_READ_D:
- case PIOD_READ_I:
- switch (size) {
- case 8:
- lookup_me8 = magic8;
- break;
- case 16:
- lookup_me16 = magic16;
- break;
- case 32:
- lookup_me32 = magic32;
- break;
- case 64:
- lookup_me64 = magic64;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- default:
- break;
- }
-
- DPRINTF("Before raising %s from child\n", strsignal(sigval));
- FORKEE_ASSERT(raise(sigval) == 0);
-
- /* Handle PIOD and PT separately as operation values overlap */
- switch (type) {
- case BYTES_TRANSFER_DATA:
- switch (operation) {
- case PT_WRITE_D:
- case PT_WRITE_I:
- FORKEE_ASSERT_EQ(lookup_me, magic);
- break;
- default:
- break;
- }
- break;
- case BYTES_TRANSFER_DATAIO:
- switch (operation) {
- case PIOD_WRITE_D:
- case PIOD_WRITE_I:
- switch (size) {
- case 8:
- FORKEE_ASSERT_EQ(lookup_me8, magic8);
- break;
- case 16:
- FORKEE_ASSERT_EQ(lookup_me16, magic16);
- break;
- case 32:
- FORKEE_ASSERT_EQ(lookup_me32, magic32);
- break;
- case 64:
- FORKEE_ASSERT_EQ(lookup_me64, magic64);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- break;
- case BYTES_TRANSFER_TEXT:
- FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy,
- sizeof(magic)) == 0);
- break;
- case BYTES_TRANSFER_TEXTIO:
- switch (size) {
- case 8:
- FORKEE_ASSERT(memcmp(&magic8,
- bytes_transfer_dummy,
- sizeof(magic8)) == 0);
- break;
- case 16:
- FORKEE_ASSERT(memcmp(&magic16,
- bytes_transfer_dummy,
- sizeof(magic16)) == 0);
- break;
- case 32:
- FORKEE_ASSERT(memcmp(&magic32,
- bytes_transfer_dummy,
- sizeof(magic32)) == 0);
- break;
- case 64:
- FORKEE_ASSERT(memcmp(&magic64,
- bytes_transfer_dummy,
- sizeof(magic64)) == 0);
- break;
- }
- break;
- default:
- break;
- }
-
- DPRINTF("Before exiting of the child process\n");
- _exit(exitval);
- }
- DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
-
- validate_status_stopped(status, sigval);
-
- /* Check PaX MPROTECT */
- if (!can_we_write_to_text(child)) {
- switch (type) {
- case BYTES_TRANSFER_TEXTIO:
- switch (operation) {
- case PIOD_WRITE_D:
- case PIOD_WRITE_I:
- skip = true;
- break;
- default:
- break;
- }
- break;
- case BYTES_TRANSFER_TEXT:
- switch (operation) {
- case PT_WRITE_D:
- case PT_WRITE_I:
- skip = true;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
-
- /* Bailout cleanly killing the child process */
- if (skip) {
- SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
- child);
-
- validate_status_signaled(status, SIGKILL, 0);
-
- atf_tc_skip("PaX MPROTECT setup prevents writes to .text");
- }
-
- DPRINTF("Calling operation to transfer bytes between child=%d and "
- "parent=%d\n", child, getpid());
-
- switch (type) {
- case BYTES_TRANSFER_TEXTIO:
- case BYTES_TRANSFER_DATAIO:
- case BYTES_TRANSFER_AUXV:
- switch (operation) {
- case PIOD_WRITE_D:
- case PIOD_WRITE_I:
- switch (size) {
- case 8:
- lookup_me8 = magic8;
- break;
- case 16:
- lookup_me16 = magic16;
- break;
- case 32:
- lookup_me32 = magic32;
- break;
- case 64:
- lookup_me64 = magic64;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
- switch (operation) {
- case PIOD_READ_D:
- case PIOD_READ_I:
- switch (size) {
- case 8:
- ATF_REQUIRE_EQ(lookup_me8, magic8);
- break;
- case 16:
- ATF_REQUIRE_EQ(lookup_me16, magic16);
- break;
- case 32:
- ATF_REQUIRE_EQ(lookup_me32, magic32);
- break;
- case 64:
- ATF_REQUIRE_EQ(lookup_me64, magic64);
- break;
- default:
- break;
- }
- break;
- case PIOD_READ_AUXV:
- DPRINTF("Asserting that AUXV length (%zu) is > 0\n",
- io.piod_len);
- ATF_REQUIRE(io.piod_len > 0);
- for (aip = ai; aip->a_type != AT_NULL; aip++)
- DPRINTF("a_type=%#llx a_v=%#llx\n",
- (long long int)aip->a_type,
- (long long int)aip->a_v);
- break;
- default:
- break;
- }
- break;
- case BYTES_TRANSFER_TEXT:
- switch (operation) {
- case PT_READ_D:
- case PT_READ_I:
- errno = 0;
- lookup_me = ptrace(operation, child,
- bytes_transfer_dummy, 0);
- ATF_REQUIRE_EQ(lookup_me, magic);
- SYSCALL_REQUIRE_ERRNO(errno, 0);
- break;
- case PT_WRITE_D:
- case PT_WRITE_I:
- SYSCALL_REQUIRE(ptrace(operation, child,
- bytes_transfer_dummy, magic)
- != -1);
- break;
- default:
- break;
- }
- break;
- case BYTES_TRANSFER_DATA:
- switch (operation) {
- case PT_READ_D:
- case PT_READ_I:
- errno = 0;
- lookup_me = ptrace(operation, child, &lookup_me, 0);
- ATF_REQUIRE_EQ(lookup_me, magic);
- SYSCALL_REQUIRE_ERRNO(errno, 0);
- break;
- case PT_WRITE_D:
- case PT_WRITE_I:
- lookup_me = magic;
- SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me,
- magic) != -1);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- DPRINTF("Before resuming the child process where it left off and "
- "without signal to be sent\n");
- SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
-
- validate_status_exited(status, exitval);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
-}
-
-#define BYTES_TRANSFER(test, operation, size, type) \
-ATF_TC(test); \
-ATF_TC_HEAD(test, tc) \
-{ \
- atf_tc_set_md_var(tc, "descr", \
- "Verify bytes transfer operation" #operation " and size " #size \
- " of type " #type); \
-} \
- \
-ATF_TC_BODY(test, tc) \
-{ \
- \
- bytes_transfer(operation, size, BYTES_TRANSFER_##type); \
-}
-
-// DATA
-
-BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO)
-
-BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO)
-
-BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO)
-
-BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO)
-
-BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA)
-BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA)
-BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA)
-BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA)
-
-// TEXT
-
-BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO)
-
-BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO)
-
-BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO)
-
-BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO)
-BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO)
-
-BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT)
-BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT)
-BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT)
-BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT)
-
-// AUXV
-
-BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV)
-
-/// ----------------------------------------------------------------------------
-
-static void
-bytes_transfer_alignment(const char *operation)
-{
- const int exitval = 5;
- const int sigval = SIGSTOP;
- pid_t child, wpid;
-#if defined(TWAIT_HAVE_STATUS)
- int status;
-#endif
- char *buffer;
- int vector;
- size_t len;
- size_t i;
- int op;
-
- struct ptrace_io_desc io;
- struct ptrace_siginfo info;
-
- memset(&io, 0, sizeof(io));
- memset(&info, 0, sizeof(info));
-
- /* Testing misaligned byte transfer crossing page boundaries */
- len = sysconf(_SC_PAGESIZE) * 2;
- buffer = malloc(len);
- ATF_REQUIRE(buffer != NULL);
-
- /* Initialize the buffer with random data */
- for (i = 0; i < len; i++)
- buffer[i] = i & 0xff;
-
- DPRINTF("Before forking process PID=%d\n", getpid());
- SYSCALL_REQUIRE((child = fork()) != -1);
- if (child == 0) {
- DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
- FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
-
- DPRINTF("Before raising %s from child\n", strsignal(sigval));
- FORKEE_ASSERT(raise(sigval) == 0);
-
- DPRINTF("Before exiting of the child process\n");
- _exit(exitval);
- }
- DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
-
- validate_status_stopped(status, sigval);
-
- DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
- SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
- != -1);
-
- DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
- DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
- "si_errno=%#x\n",
- info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
- info.psi_siginfo.si_errno);
-
- ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
- ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
-
- if (strcmp(operation, "PT_READ_I") == 0 ||
- strcmp(operation, "PT_READ_D") == 0) {
- if (strcmp(operation, "PT_READ_I"))
- op = PT_READ_I;
- else
- op = PT_READ_D;
-
- for (i = 0; i <= (len - sizeof(int)); i++) {
- errno = 0;
- vector = ptrace(op, child, buffer + i, 0);
- ATF_REQUIRE_EQ(errno, 0);
- ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
- }
- } else if (strcmp(operation, "PT_WRITE_I") == 0 ||
- strcmp(operation, "PT_WRITE_D") == 0) {
- if (strcmp(operation, "PT_WRITE_I"))
- op = PT_WRITE_I;
- else
- op = PT_WRITE_D;
-
- for (i = 0; i <= (len - sizeof(int)); i++) {
- memcpy(&vector, buffer + i, sizeof(int));
- SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector)
- != -1);
- }
- } else if (strcmp(operation, "PIOD_READ_I") == 0 ||
- strcmp(operation, "PIOD_READ_D") == 0) {
- if (strcmp(operation, "PIOD_READ_I"))
- op = PIOD_READ_I;
- else
- op = PIOD_READ_D;
-
- io.piod_op = op;
- io.piod_addr = &vector;
- io.piod_len = sizeof(int);
-
- for (i = 0; i <= (len - sizeof(int)); i++) {
- io.piod_offs = buffer + i;
-
- SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
- != -1);
- ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
- }
- } else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
- strcmp(operation, "PIOD_WRITE_D") == 0) {
- if (strcmp(operation, "PIOD_WRITE_I"))
- op = PIOD_WRITE_I;
- else
- op = PIOD_WRITE_D;
-
- io.piod_op = op;
- io.piod_addr = &vector;
- io.piod_len = sizeof(int);
-
- for (i = 0; i <= (len - sizeof(int)); i++) {
- io.piod_offs = buffer + i;
-
- SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
- != -1);
- }
- } else if (strcmp(operation, "PIOD_READ_AUXV") == 0) {
- io.piod_op = PIOD_READ_AUXV;
- io.piod_addr = &vector;
- io.piod_len = sizeof(int);
-
- errno = 0;
- i = 0;
- /* Read the whole AUXV vector, it has no clear length */
- while (io.piod_len > 0) {
- io.piod_offs = (void *)(intptr_t)i;
- SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
- != -1 || (io.piod_len == 0 && i > 0));
- ++i;
- }
- }
-
- DPRINTF("Before resuming the child process where it left off "
- "and without signal to be sent\n");
- SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
- child);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
-}
-
-#define BYTES_TRANSFER_ALIGNMENT(test, operation) \
-ATF_TC(test); \
-ATF_TC_HEAD(test, tc) \
-{ \
- atf_tc_set_md_var(tc, "descr", \
- "Verify bytes transfer for potentially misaligned " \
- "operation " operation); \
-} \
- \
-ATF_TC_BODY(test, tc) \
-{ \
- \
- bytes_transfer_alignment(operation); \
-}
-
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I")
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D")
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I")
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D")
-
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I")
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D")
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I")
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D")
-
-BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV")
-
-/// ----------------------------------------------------------------------------
-
-static void
-bytes_transfer_eof(const char *operation)
-{
- const int exitval = 5;
- const int sigval = SIGSTOP;
- pid_t child, wpid;
-#if defined(TWAIT_HAVE_STATUS)
- int status;
-#endif
- FILE *fp;
- char *p;
- int vector;
- int op;
-
- struct ptrace_io_desc io;
- struct ptrace_siginfo info;
-
- memset(&io, 0, sizeof(io));
- memset(&info, 0, sizeof(info));
-
- vector = 0;
-
- fp = tmpfile();
- ATF_REQUIRE(fp != NULL);
-
- p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0);
- ATF_REQUIRE(p != MAP_FAILED);
-
- DPRINTF("Before forking process PID=%d\n", getpid());
- SYSCALL_REQUIRE((child = fork()) != -1);
- if (child == 0) {
- DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
- FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
-
- DPRINTF("Before raising %s from child\n", strsignal(sigval));
- FORKEE_ASSERT(raise(sigval) == 0);
-
- DPRINTF("Before exiting of the child process\n");
- _exit(exitval);
- }
- DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
-
- validate_status_stopped(status, sigval);
-
- DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
- SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
- != -1);
-
- DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
- DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
- "si_errno=%#x\n",
- info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
- info.psi_siginfo.si_errno);
-
- ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
- ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
-
- if (strcmp(operation, "PT_READ_I") == 0 ||
- strcmp(operation, "PT_READ_D") == 0) {
- if (strcmp(operation, "PT_READ_I"))
- op = PT_READ_I;
- else
- op = PT_READ_D;
-
- errno = 0;
- SYSCALL_REQUIRE(ptrace(op, child, p, 0) == -1);
- ATF_REQUIRE_EQ(errno, EINVAL);
- } else if (strcmp(operation, "PT_WRITE_I") == 0 ||
- strcmp(operation, "PT_WRITE_D") == 0) {
- if (strcmp(operation, "PT_WRITE_I"))
- op = PT_WRITE_I;
- else
- op = PT_WRITE_D;
-
- errno = 0;
- SYSCALL_REQUIRE(ptrace(op, child, p, vector) == -1);
- ATF_REQUIRE_EQ(errno, EINVAL);
- } else if (strcmp(operation, "PIOD_READ_I") == 0 ||
- strcmp(operation, "PIOD_READ_D") == 0) {
- if (strcmp(operation, "PIOD_READ_I"))
- op = PIOD_READ_I;
- else
- op = PIOD_READ_D;
-
- io.piod_op = op;
- io.piod_addr = &vector;
- io.piod_len = sizeof(int);
- io.piod_offs = p;
-
- errno = 0;
- SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
- ATF_REQUIRE_EQ(errno, EINVAL);
- } else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
- strcmp(operation, "PIOD_WRITE_D") == 0) {
- if (strcmp(operation, "PIOD_WRITE_I"))
- op = PIOD_WRITE_I;
- else
- op = PIOD_WRITE_D;
-
- io.piod_op = op;
- io.piod_addr = &vector;
- io.piod_len = sizeof(int);
- io.piod_offs = p;
-
- errno = 0;
- SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
- ATF_REQUIRE_EQ(errno, EINVAL);
- }
-
- DPRINTF("Before resuming the child process where it left off "
- "and without signal to be sent\n");
- SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
- child);
-
- DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
- TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
-}
-
-#define BYTES_TRANSFER_EOF(test, operation) \
-ATF_TC(test); \
-ATF_TC_HEAD(test, tc) \
-{ \
- atf_tc_set_md_var(tc, "descr", \
- "Verify bytes EOF byte transfer for the " operation \
- " operation"); \
-} \
- \
-ATF_TC_BODY(test, tc) \
-{ \
- \
- bytes_transfer_eof(operation); \
-}
-
-BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_i, "PT_READ_I")
-BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_d, "PT_READ_D")
-BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_i, "PT_WRITE_I")
-BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_d, "PT_WRITE_D")
-
-BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_i, "PIOD_READ_I")
-BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_d, "PIOD_READ_D")
-BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_i, "PIOD_WRITE_I")
-BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_d, "PIOD_WRITE_D")
-
-/// ----------------------------------------------------------------------------
-
static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG};
static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER;
@@ -8390,6 +7570,7 @@ THREAD_CONCURRENT_TEST(thread_concurrent
#include "t_ptrace_syscall_wait.h"
#include "t_ptrace_step_wait.h"
#include "t_ptrace_kill_wait.h"
+#include "t_ptrace_bytetransfer_wait.h"
/// ----------------------------------------------------------------------------
@@ -8984,6 +8165,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
ATF_TP_ADD_TCS_PTRACE_WAIT_KILL();
+ ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER();
ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
Added files:
Index: src/tests/lib/libc/sys/t_ptrace_bytetransfer_wait.h
diff -u /dev/null src/tests/lib/libc/sys/t_ptrace_bytetransfer_wait.h:1.1
--- /dev/null Mon May 4 22:05:29 2020
+++ src/tests/lib/libc/sys/t_ptrace_bytetransfer_wait.h Mon May 4 22:05:28 2020
@@ -0,0 +1,907 @@
+/* $NetBSD: t_ptrace_bytetransfer_wait.h,v 1.1 2020/05/04 22:05:28 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+enum bytes_transfer_type {
+ BYTES_TRANSFER_DATA,
+ BYTES_TRANSFER_DATAIO,
+ BYTES_TRANSFER_TEXT,
+ BYTES_TRANSFER_TEXTIO,
+ BYTES_TRANSFER_AUXV
+};
+
+static int __used
+bytes_transfer_dummy(int a, int b, int c, int d)
+{
+ int e, f, g, h;
+
+ a *= 4;
+ b += 3;
+ c -= 2;
+ d /= 1;
+
+ e = strtol("10", NULL, 10);
+ f = strtol("20", NULL, 10);
+ g = strtol("30", NULL, 10);
+ h = strtol("40", NULL, 10);
+
+ return (a + b * c - d) + (e * f - g / h);
+}
+
+static void
+bytes_transfer(int operation, size_t size, enum bytes_transfer_type type)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+ bool skip = false;
+
+ int lookup_me = 0;
+ uint8_t lookup_me8 = 0;
+ uint16_t lookup_me16 = 0;
+ uint32_t lookup_me32 = 0;
+ uint64_t lookup_me64 = 0;
+
+ int magic = 0x13579246;
+ uint8_t magic8 = 0xab;
+ uint16_t magic16 = 0x1234;
+ uint32_t magic32 = 0x98765432;
+ uint64_t magic64 = 0xabcdef0123456789;
+
+ struct ptrace_io_desc io;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ /* 513 is just enough, for the purposes of ATF it's good enough */
+ AuxInfo ai[513], *aip;
+
+ ATF_REQUIRE(size < sizeof(ai));
+
+ /* Prepare variables for .TEXT transfers */
+ switch (type) {
+ case BYTES_TRANSFER_TEXT:
+ memcpy(&magic, bytes_transfer_dummy, sizeof(magic));
+ break;
+ case BYTES_TRANSFER_TEXTIO:
+ switch (size) {
+ case 8:
+ memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8));
+ break;
+ case 16:
+ memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16));
+ break;
+ case 32:
+ memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32));
+ break;
+ case 64:
+ memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64));
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Prepare variables for PIOD and AUXV transfers */
+ switch (type) {
+ case BYTES_TRANSFER_TEXTIO:
+ case BYTES_TRANSFER_DATAIO:
+ io.piod_op = operation;
+ switch (size) {
+ case 8:
+ io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
+ (void *)bytes_transfer_dummy :
+ &lookup_me8;
+ io.piod_addr = &lookup_me8;
+ io.piod_len = sizeof(lookup_me8);
+ break;
+ case 16:
+ io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
+ (void *)bytes_transfer_dummy :
+ &lookup_me16;
+ io.piod_addr = &lookup_me16;
+ io.piod_len = sizeof(lookup_me16);
+ break;
+ case 32:
+ io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
+ (void *)bytes_transfer_dummy :
+ &lookup_me32;
+ io.piod_addr = &lookup_me32;
+ io.piod_len = sizeof(lookup_me32);
+ break;
+ case 64:
+ io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
+ (void *)bytes_transfer_dummy :
+ &lookup_me64;
+ io.piod_addr = &lookup_me64;
+ io.piod_len = sizeof(lookup_me64);
+ break;
+ default:
+ break;
+ }
+ break;
+ case BYTES_TRANSFER_AUXV:
+ io.piod_op = operation;
+ io.piod_offs = 0;
+ io.piod_addr = ai;
+ io.piod_len = size;
+ break;
+ default:
+ break;
+ }
+
+ DPRINTF("Before forking process PID=%d\n", getpid());
+ SYSCALL_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
+ FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+ switch (type) {
+ case BYTES_TRANSFER_DATA:
+ switch (operation) {
+ case PT_READ_D:
+ case PT_READ_I:
+ lookup_me = magic;
+ break;
+ default:
+ break;
+ }
+ break;
+ case BYTES_TRANSFER_DATAIO:
+ switch (operation) {
+ case PIOD_READ_D:
+ case PIOD_READ_I:
+ switch (size) {
+ case 8:
+ lookup_me8 = magic8;
+ break;
+ case 16:
+ lookup_me16 = magic16;
+ break;
+ case 32:
+ lookup_me32 = magic32;
+ break;
+ case 64:
+ lookup_me64 = magic64;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+
+ DPRINTF("Before raising %s from child\n", strsignal(sigval));
+ FORKEE_ASSERT(raise(sigval) == 0);
+
+ /* Handle PIOD and PT separately as operation values overlap */
+ switch (type) {
+ case BYTES_TRANSFER_DATA:
+ switch (operation) {
+ case PT_WRITE_D:
+ case PT_WRITE_I:
+ FORKEE_ASSERT_EQ(lookup_me, magic);
+ break;
+ default:
+ break;
+ }
+ break;
+ case BYTES_TRANSFER_DATAIO:
+ switch (operation) {
+ case PIOD_WRITE_D:
+ case PIOD_WRITE_I:
+ switch (size) {
+ case 8:
+ FORKEE_ASSERT_EQ(lookup_me8, magic8);
+ break;
+ case 16:
+ FORKEE_ASSERT_EQ(lookup_me16, magic16);
+ break;
+ case 32:
+ FORKEE_ASSERT_EQ(lookup_me32, magic32);
+ break;
+ case 64:
+ FORKEE_ASSERT_EQ(lookup_me64, magic64);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case BYTES_TRANSFER_TEXT:
+ FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy,
+ sizeof(magic)) == 0);
+ break;
+ case BYTES_TRANSFER_TEXTIO:
+ switch (size) {
+ case 8:
+ FORKEE_ASSERT(memcmp(&magic8,
+ bytes_transfer_dummy,
+ sizeof(magic8)) == 0);
+ break;
+ case 16:
+ FORKEE_ASSERT(memcmp(&magic16,
+ bytes_transfer_dummy,
+ sizeof(magic16)) == 0);
+ break;
+ case 32:
+ FORKEE_ASSERT(memcmp(&magic32,
+ bytes_transfer_dummy,
+ sizeof(magic32)) == 0);
+ break;
+ case 64:
+ FORKEE_ASSERT(memcmp(&magic64,
+ bytes_transfer_dummy,
+ sizeof(magic64)) == 0);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ DPRINTF("Before exiting of the child process\n");
+ _exit(exitval);
+ }
+ DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_stopped(status, sigval);
+
+ /* Check PaX MPROTECT */
+ if (!can_we_write_to_text(child)) {
+ switch (type) {
+ case BYTES_TRANSFER_TEXTIO:
+ switch (operation) {
+ case PIOD_WRITE_D:
+ case PIOD_WRITE_I:
+ skip = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ case BYTES_TRANSFER_TEXT:
+ switch (operation) {
+ case PT_WRITE_D:
+ case PT_WRITE_I:
+ skip = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Bailout cleanly killing the child process */
+ if (skip) {
+ SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
+ child);
+
+ validate_status_signaled(status, SIGKILL, 0);
+
+ atf_tc_skip("PaX MPROTECT setup prevents writes to .text");
+ }
+
+ DPRINTF("Calling operation to transfer bytes between child=%d and "
+ "parent=%d\n", child, getpid());
+
+ switch (type) {
+ case BYTES_TRANSFER_TEXTIO:
+ case BYTES_TRANSFER_DATAIO:
+ case BYTES_TRANSFER_AUXV:
+ switch (operation) {
+ case PIOD_WRITE_D:
+ case PIOD_WRITE_I:
+ switch (size) {
+ case 8:
+ lookup_me8 = magic8;
+ break;
+ case 16:
+ lookup_me16 = magic16;
+ break;
+ case 32:
+ lookup_me32 = magic32;
+ break;
+ case 64:
+ lookup_me64 = magic64;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
+ switch (operation) {
+ case PIOD_READ_D:
+ case PIOD_READ_I:
+ switch (size) {
+ case 8:
+ ATF_REQUIRE_EQ(lookup_me8, magic8);
+ break;
+ case 16:
+ ATF_REQUIRE_EQ(lookup_me16, magic16);
+ break;
+ case 32:
+ ATF_REQUIRE_EQ(lookup_me32, magic32);
+ break;
+ case 64:
+ ATF_REQUIRE_EQ(lookup_me64, magic64);
+ break;
+ default:
+ break;
+ }
+ break;
+ case PIOD_READ_AUXV:
+ DPRINTF("Asserting that AUXV length (%zu) is > 0\n",
+ io.piod_len);
+ ATF_REQUIRE(io.piod_len > 0);
+ for (aip = ai; aip->a_type != AT_NULL; aip++)
+ DPRINTF("a_type=%#llx a_v=%#llx\n",
+ (long long int)aip->a_type,
+ (long long int)aip->a_v);
+ break;
+ default:
+ break;
+ }
+ break;
+ case BYTES_TRANSFER_TEXT:
+ switch (operation) {
+ case PT_READ_D:
+ case PT_READ_I:
+ errno = 0;
+ lookup_me = ptrace(operation, child,
+ bytes_transfer_dummy, 0);
+ ATF_REQUIRE_EQ(lookup_me, magic);
+ SYSCALL_REQUIRE_ERRNO(errno, 0);
+ break;
+ case PT_WRITE_D:
+ case PT_WRITE_I:
+ SYSCALL_REQUIRE(ptrace(operation, child,
+ bytes_transfer_dummy, magic)
+ != -1);
+ break;
+ default:
+ break;
+ }
+ break;
+ case BYTES_TRANSFER_DATA:
+ switch (operation) {
+ case PT_READ_D:
+ case PT_READ_I:
+ errno = 0;
+ lookup_me = ptrace(operation, child, &lookup_me, 0);
+ ATF_REQUIRE_EQ(lookup_me, magic);
+ SYSCALL_REQUIRE_ERRNO(errno, 0);
+ break;
+ case PT_WRITE_D:
+ case PT_WRITE_I:
+ lookup_me = magic;
+ SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me,
+ magic) != -1);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ DPRINTF("Before resuming the child process where it left off and "
+ "without signal to be sent\n");
+ SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_exited(status, exitval);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+
+#define BYTES_TRANSFER(test, operation, size, type) \
+ATF_TC(test); \
+ATF_TC_HEAD(test, tc) \
+{ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Verify bytes transfer operation" #operation " and size " #size \
+ " of type " #type); \
+} \
+ \
+ATF_TC_BODY(test, tc) \
+{ \
+ \
+ bytes_transfer(operation, size, BYTES_TRANSFER_##type); \
+}
+
+// DATA
+
+BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO)
+
+BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO)
+
+BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO)
+
+BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO)
+
+BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA)
+BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA)
+BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA)
+BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA)
+
+// TEXT
+
+BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO)
+
+BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO)
+
+BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO)
+
+BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO)
+BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO)
+
+BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT)
+BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT)
+BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT)
+BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT)
+
+// AUXV
+
+BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV)
+
+/// ----------------------------------------------------------------------------
+
+static void
+bytes_transfer_alignment(const char *operation)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ char *buffer;
+ int vector;
+ size_t len;
+ size_t i;
+ int op;
+
+ struct ptrace_io_desc io;
+ struct ptrace_siginfo info;
+
+ memset(&io, 0, sizeof(io));
+ memset(&info, 0, sizeof(info));
+
+ /* Testing misaligned byte transfer crossing page boundaries */
+ len = sysconf(_SC_PAGESIZE) * 2;
+ buffer = malloc(len);
+ ATF_REQUIRE(buffer != NULL);
+
+ /* Initialize the buffer with random data */
+ for (i = 0; i < len; i++)
+ buffer[i] = i & 0xff;
+
+ DPRINTF("Before forking process PID=%d\n", getpid());
+ SYSCALL_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
+ FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+ DPRINTF("Before raising %s from child\n", strsignal(sigval));
+ FORKEE_ASSERT(raise(sigval) == 0);
+
+ DPRINTF("Before exiting of the child process\n");
+ _exit(exitval);
+ }
+ DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_stopped(status, sigval);
+
+ DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
+ SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
+ != -1);
+
+ DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
+ DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
+ "si_errno=%#x\n",
+ info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
+ info.psi_siginfo.si_errno);
+
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
+
+ if (strcmp(operation, "PT_READ_I") == 0 ||
+ strcmp(operation, "PT_READ_D") == 0) {
+ if (strcmp(operation, "PT_READ_I"))
+ op = PT_READ_I;
+ else
+ op = PT_READ_D;
+
+ for (i = 0; i <= (len - sizeof(int)); i++) {
+ errno = 0;
+ vector = ptrace(op, child, buffer + i, 0);
+ ATF_REQUIRE_EQ(errno, 0);
+ ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
+ }
+ } else if (strcmp(operation, "PT_WRITE_I") == 0 ||
+ strcmp(operation, "PT_WRITE_D") == 0) {
+ if (strcmp(operation, "PT_WRITE_I"))
+ op = PT_WRITE_I;
+ else
+ op = PT_WRITE_D;
+
+ for (i = 0; i <= (len - sizeof(int)); i++) {
+ memcpy(&vector, buffer + i, sizeof(int));
+ SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector)
+ != -1);
+ }
+ } else if (strcmp(operation, "PIOD_READ_I") == 0 ||
+ strcmp(operation, "PIOD_READ_D") == 0) {
+ if (strcmp(operation, "PIOD_READ_I"))
+ op = PIOD_READ_I;
+ else
+ op = PIOD_READ_D;
+
+ io.piod_op = op;
+ io.piod_addr = &vector;
+ io.piod_len = sizeof(int);
+
+ for (i = 0; i <= (len - sizeof(int)); i++) {
+ io.piod_offs = buffer + i;
+
+ SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
+ != -1);
+ ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
+ }
+ } else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
+ strcmp(operation, "PIOD_WRITE_D") == 0) {
+ if (strcmp(operation, "PIOD_WRITE_I"))
+ op = PIOD_WRITE_I;
+ else
+ op = PIOD_WRITE_D;
+
+ io.piod_op = op;
+ io.piod_addr = &vector;
+ io.piod_len = sizeof(int);
+
+ for (i = 0; i <= (len - sizeof(int)); i++) {
+ io.piod_offs = buffer + i;
+
+ SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
+ != -1);
+ }
+ } else if (strcmp(operation, "PIOD_READ_AUXV") == 0) {
+ io.piod_op = PIOD_READ_AUXV;
+ io.piod_addr = &vector;
+ io.piod_len = sizeof(int);
+
+ errno = 0;
+ i = 0;
+ /* Read the whole AUXV vector, it has no clear length */
+ while (io.piod_len > 0) {
+ io.piod_offs = (void *)(intptr_t)i;
+ SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
+ != -1 || (io.piod_len == 0 && i > 0));
+ ++i;
+ }
+ }
+
+ DPRINTF("Before resuming the child process where it left off "
+ "and without signal to be sent\n");
+ SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
+ child);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+
+#define BYTES_TRANSFER_ALIGNMENT(test, operation) \
+ATF_TC(test); \
+ATF_TC_HEAD(test, tc) \
+{ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Verify bytes transfer for potentially misaligned " \
+ "operation " operation); \
+} \
+ \
+ATF_TC_BODY(test, tc) \
+{ \
+ \
+ bytes_transfer_alignment(operation); \
+}
+
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I")
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D")
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I")
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D")
+
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I")
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D")
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I")
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D")
+
+BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV")
+
+/// ----------------------------------------------------------------------------
+
+static void
+bytes_transfer_eof(const char *operation)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ FILE *fp;
+ char *p;
+ int vector;
+ int op;
+
+ struct ptrace_io_desc io;
+ struct ptrace_siginfo info;
+
+ memset(&io, 0, sizeof(io));
+ memset(&info, 0, sizeof(info));
+
+ vector = 0;
+
+ fp = tmpfile();
+ ATF_REQUIRE(fp != NULL);
+
+ p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0);
+ ATF_REQUIRE(p != MAP_FAILED);
+
+ DPRINTF("Before forking process PID=%d\n", getpid());
+ SYSCALL_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
+ FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+ DPRINTF("Before raising %s from child\n", strsignal(sigval));
+ FORKEE_ASSERT(raise(sigval) == 0);
+
+ DPRINTF("Before exiting of the child process\n");
+ _exit(exitval);
+ }
+ DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+ validate_status_stopped(status, sigval);
+
+ DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
+ SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
+ != -1);
+
+ DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
+ DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
+ "si_errno=%#x\n",
+ info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
+ info.psi_siginfo.si_errno);
+
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
+ ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
+
+ if (strcmp(operation, "PT_READ_I") == 0 ||
+ strcmp(operation, "PT_READ_D") == 0) {
+ if (strcmp(operation, "PT_READ_I"))
+ op = PT_READ_I;
+ else
+ op = PT_READ_D;
+
+ errno = 0;
+ SYSCALL_REQUIRE(ptrace(op, child, p, 0) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ } else if (strcmp(operation, "PT_WRITE_I") == 0 ||
+ strcmp(operation, "PT_WRITE_D") == 0) {
+ if (strcmp(operation, "PT_WRITE_I"))
+ op = PT_WRITE_I;
+ else
+ op = PT_WRITE_D;
+
+ errno = 0;
+ SYSCALL_REQUIRE(ptrace(op, child, p, vector) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ } else if (strcmp(operation, "PIOD_READ_I") == 0 ||
+ strcmp(operation, "PIOD_READ_D") == 0) {
+ if (strcmp(operation, "PIOD_READ_I"))
+ op = PIOD_READ_I;
+ else
+ op = PIOD_READ_D;
+
+ io.piod_op = op;
+ io.piod_addr = &vector;
+ io.piod_len = sizeof(int);
+ io.piod_offs = p;
+
+ errno = 0;
+ SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ } else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
+ strcmp(operation, "PIOD_WRITE_D") == 0) {
+ if (strcmp(operation, "PIOD_WRITE_I"))
+ op = PIOD_WRITE_I;
+ else
+ op = PIOD_WRITE_D;
+
+ io.piod_op = op;
+ io.piod_addr = &vector;
+ io.piod_len = sizeof(int);
+ io.piod_offs = p;
+
+ errno = 0;
+ SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ }
+
+ DPRINTF("Before resuming the child process where it left off "
+ "and without signal to be sent\n");
+ SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
+ child);
+
+ DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+
+#define BYTES_TRANSFER_EOF(test, operation) \
+ATF_TC(test); \
+ATF_TC_HEAD(test, tc) \
+{ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Verify bytes EOF byte transfer for the " operation \
+ " operation"); \
+} \
+ \
+ATF_TC_BODY(test, tc) \
+{ \
+ \
+ bytes_transfer_eof(operation); \
+}
+
+BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_i, "PT_READ_I")
+BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_d, "PT_READ_D")
+BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_i, "PT_WRITE_I")
+BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_d, "PT_WRITE_D")
+
+BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_i, "PIOD_READ_I")
+BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_d, "PIOD_READ_D")
+BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_i, "PIOD_WRITE_I")
+BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_d, "PIOD_WRITE_D")
+
+
+#define ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER() \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_read_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_read_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_write_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_write_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); \
+ ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d);