summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2020-03-29 20:43:15 +0200
committerEugene Syromyatnikov <evgsyr@gmail.com>2022-09-02 17:55:13 +0200
commit3411f6febeea2ab38bf93d1b4cdc4750af7116a5 (patch)
treebf3f76a94fe2d5ef89be292edbd6a88bdc4e2e54
parentd0878c0b75e223a465cc11e879328fd31db5efc6 (diff)
downloadstrace-3411f6febeea2ab38bf93d1b4cdc4750af7116a5.tar.gz
powerpc: decode spu_run and spu_create syscalls
-rw-r--r--src/Makefile.am1
-rw-r--r--src/linux/powerpc/syscallent.h4
-rw-r--r--src/linux/powerpc64/syscallent.h4
-rw-r--r--src/pathtrace.c6
-rw-r--r--src/spu.c131
-rw-r--r--src/xlat/spu_create_flags.in6
-rw-r--r--src/xlat/spu_run_events.in5
-rw-r--r--src/xlat/spu_run_status_flags.in9
-rw-r--r--tests/.gitignore16
-rw-r--r--tests/Makefile.am16
-rw-r--r--tests/gen_tests.in16
-rw-r--r--tests/spu_create-success-P-Xabbrev.c2
-rw-r--r--tests/spu_create-success-P-Xraw.c2
-rw-r--r--tests/spu_create-success-P-Xverbose.c2
-rw-r--r--tests/spu_create-success-P.c2
-rw-r--r--tests/spu_create-success-Xabbrev.c2
-rw-r--r--tests/spu_create-success-Xraw.c2
-rw-r--r--tests/spu_create-success-Xverbose.c2
-rw-r--r--tests/spu_create-success-y-P-Xabbrev.c3
-rw-r--r--tests/spu_create-success-y-P-Xraw.c2
-rw-r--r--tests/spu_create-success-y-P-Xverbose.c2
-rw-r--r--tests/spu_create-success-y-P.c2
-rw-r--r--tests/spu_create-success-y-Xabbrev.c3
-rw-r--r--tests/spu_create-success-y-Xraw.c2
-rw-r--r--tests/spu_create-success-y-Xverbose.c2
-rw-r--r--tests/spu_create-success-y.c6
-rw-r--r--tests/spu_create-success.c168
27 files changed, 414 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 03da75f5f..e9fffa8c9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -339,6 +339,7 @@ libstrace_a_SOURCES = \
socketcall.c \
socketutils.c \
sparc.c \
+ spu.c \
sram_alloc.c \
stage_output.c \
stat.c \
diff --git a/src/linux/powerpc/syscallent.h b/src/linux/powerpc/syscallent.h
index c8f954be4..ef04a176a 100644
--- a/src/linux/powerpc/syscallent.h
+++ b/src/linux/powerpc/syscallent.h
@@ -285,8 +285,8 @@
[275] = { 0, TD, SEN(inotify_init), "inotify_init" },
[276] = { 3, TD|TF, SEN(inotify_add_watch), "inotify_add_watch" },
[277] = { 2, TD, SEN(inotify_rm_watch), "inotify_rm_watch" },
-[278] = { 3, 0, SEN(printargs), "spu_run" },
-[279] = { 4, 0, SEN(printargs), "spu_create" },
+[278] = { 3, TD, SEN(spu_run), "spu_run" },
+[279] = { 4, TD|TF, SEN(spu_create), "spu_create" },
[280] = { 6, TD, SEN(pselect6_time32), "pselect6" },
[281] = { 5, TD, SEN(ppoll_time32), "ppoll" },
[282] = { 1, 0, SEN(unshare), "unshare" },
diff --git a/src/linux/powerpc64/syscallent.h b/src/linux/powerpc64/syscallent.h
index 64f4c3ad5..da8402f83 100644
--- a/src/linux/powerpc64/syscallent.h
+++ b/src/linux/powerpc64/syscallent.h
@@ -280,8 +280,8 @@
[275] = { 0, TD, SEN(inotify_init), "inotify_init" },
[276] = { 3, TD|TF, SEN(inotify_add_watch), "inotify_add_watch" },
[277] = { 2, TD, SEN(inotify_rm_watch), "inotify_rm_watch" },
-[278] = { 3, 0, SEN(printargs), "spu_run" },
-[279] = { 4, 0, SEN(printargs), "spu_create" },
+[278] = { 3, TD, SEN(spu_run), "spu_run" },
+[279] = { 4, TD|TF, SEN(spu_create), "spu_create" },
[280] = { 6, TD, SEN(pselect6_time64), "pselect6" },
[281] = { 5, TD, SEN(ppoll_time64), "ppoll" },
[282] = { 1, 0, SEN(unshare), "unshare" },
diff --git a/src/pathtrace.c b/src/pathtrace.c
index f94f2e60d..8f03f6f46 100644
--- a/src/pathtrace.c
+++ b/src/pathtrace.c
@@ -403,6 +403,12 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set)
return false;
}
+ case SEN_spu_create:
+ /* path, x, x, maybe fd */
+ return upathmatch(tcp, tcp->u_arg[0], set) ||
+ ((tcp->u_arg[1] & 0x10 /* SPU_CREATE_AFFINITY_SPU */)
+ && fdmatch(tcp, tcp->u_arg[3], set));
+
case SEN_accept4:
case SEN_accept:
case SEN_bpf:
diff --git a/src/spu.c b/src/spu.c
new file mode 100644
index 000000000..fc9dd6356
--- /dev/null
+++ b/src/spu.c
@@ -0,0 +1,131 @@
+/*
+ * PowerPC SPU-specific syscalls decoders.
+ *
+ * Copyright (c) 2018-2022 Eugene Syromyatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+
+#if defined POWERPC || defined POWERPC64
+
+# include "xstring.h"
+
+/* defined in arch/powerpc/include/asm/spu.h */
+# include "xlat/spu_create_flags.h"
+# include "xlat/spu_run_events.h"
+# include "xlat/spu_run_status_flags.h"
+
+SYS_FUNC(spu_create)
+{
+ kernel_ulong_t pathname = tcp->u_arg[0];
+ unsigned int flags = tcp->u_arg[1];
+ unsigned short mode = tcp->u_arg[2];
+ int neighbor_fd = tcp->u_arg[3];
+
+ /* pathname */
+ printpath(tcp, pathname);
+
+ /* flags */
+ tprint_arg_next();
+ printflags_ex(flags, "SPU_CREATE_???",
+ xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW
+ ? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE,
+ spu_create_flags, NULL);
+
+ /* mode */
+ tprint_arg_next();
+ print_numeric_umode_t(mode);
+
+ /* neighbor_fd */
+ if (flags & SPU_CREATE_AFFINITY_SPU) {
+ tprint_arg_next();
+ printfd(tcp, neighbor_fd);
+ }
+
+ return RVAL_DECODED | RVAL_FD;
+}
+
+static const char *
+sprint_spu_status(unsigned long status)
+{
+ enum {
+ SPU_STOP_STATUS_SHIFT = 16,
+ SPU_STOP_STATUS_MASK = 0x3fff,
+
+ SPU_STATUS_MASK = (1 << SPU_STOP_STATUS_SHIFT) - 1,
+ SPU_STOP_MASK_SHIFTED = SPU_STOP_STATUS_MASK
+ << SPU_STOP_STATUS_SHIFT,
+ };
+
+ static char outstr[spu_run_status_flags_flags_strsz
+ + sizeof("|0x3fff<<SPU_STOP_STATUS_SHIFT|")
+ + sizeof(status) * 2 + 2];
+
+ const unsigned long st = status & spu_run_status_flags->flags_mask;
+ unsigned long stop = 0;
+ const char *flags;
+ char *p = outstr;
+
+ flags = sprintflags_ex("", spu_run_status_flags, status, '\0',
+ XLAT_STYLE_DEFAULT | SPFF_AUXSTR_MODE);
+
+ if (!flags && !(status - st))
+ return NULL;
+
+ if (flags)
+ p = xappendstr(outstr, p, "%s|", flags);
+
+ if (st & SPU_STATUS_STOPPED_BY_STOP) {
+ stop = status & SPU_STOP_MASK_SHIFTED;
+ p = xappendstr(outstr, p, "|%#lx<<SPU_STOP_STATUS_SHIFT",
+ stop >> SPU_STOP_STATUS_SHIFT);
+ }
+
+ if (status - st - stop)
+ p = xappendstr(outstr, p, "|%#lx", status - st - stop);
+
+ return outstr;
+}
+
+SYS_FUNC(spu_run)
+{
+ uint32_t val;
+
+ if (entering(tcp)) {
+ /* fd */
+ printfd(tcp, tcp->u_arg[0]);
+
+ /* [in, out] uint32_t *npc */
+ tprint_arg_next();
+ if (printnum_int(tcp, tcp->u_arg[1], "%#x"))
+ set_tcb_priv_ulong(tcp, 1);
+
+ return 0;
+ }
+
+ if (!syserror(tcp) && get_tcb_priv_ulong(tcp)) {
+ tprint_value_changed();
+ printnum_int(tcp, tcp->u_arg[1], "%#x");
+ }
+
+ /* [out] uint32_t *event */
+ tprint_arg_next();
+ if (!umove_or_printaddr(tcp, tcp->u_arg[2], &val)) {
+ tprint_indirect_begin();
+ printflags_ex(val, "SPE_EVENT_???",
+ xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW
+ ? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE,
+ spu_run_events, NULL);
+ tprint_indirect_end();
+ }
+
+ if (!syserror(tcp))
+ tcp->auxstr = sprint_spu_status(tcp->u_rval);
+
+ return RVAL_HEX | RVAL_STR;
+}
+
+#endif /* POWERPC || POWERPC64 */
diff --git a/src/xlat/spu_create_flags.in b/src/xlat/spu_create_flags.in
new file mode 100644
index 000000000..3a1464861
--- /dev/null
+++ b/src/xlat/spu_create_flags.in
@@ -0,0 +1,6 @@
+SPU_CREATE_EVENTS_ENABLED 0x1
+SPU_CREATE_GANG 0x2
+SPU_CREATE_NOSCHED 0x4
+SPU_CREATE_ISOLATE 0x8
+SPU_CREATE_AFFINITY_SPU 0x10
+SPU_CREATE_AFFINITY_MEM 0x20
diff --git a/src/xlat/spu_run_events.in b/src/xlat/spu_run_events.in
new file mode 100644
index 000000000..e9c221191
--- /dev/null
+++ b/src/xlat/spu_run_events.in
@@ -0,0 +1,5 @@
+SPE_EVENT_DMA_ALIGNMENT 0x8
+SPE_EVENT_SPE_ERROR 0x10
+SPE_EVENT_SPE_DATA_SEGMENT 0x20
+SPE_EVENT_SPE_DATA_STORAGE 0x40
+SPE_EVENT_INVALID_DMA 0x800
diff --git a/src/xlat/spu_run_status_flags.in b/src/xlat/spu_run_status_flags.in
new file mode 100644
index 000000000..fd4965f6a
--- /dev/null
+++ b/src/xlat/spu_run_status_flags.in
@@ -0,0 +1,9 @@
+SPU_STATUS_STOPPED_BY_STOP 0x2
+SPU_STATUS_STOPPED_BY_HALT 0x4
+SPU_STATUS_WAITING_FOR_CHANNEL 0x8
+SPU_STATUS_SINGLE_STEP 0x10
+SPU_STATUS_INVALID_INSTR 0x20
+SPU_STATUS_INVALID_CH 0x40
+SPU_STATUS_ISOLATED_STATE 0x80
+SPU_STATUS_ISOLATED_LOAD_STATUS 0x200
+SPU_STATUS_ISOLATED_EXIT_STATUS 0x400
diff --git a/tests/.gitignore b/tests/.gitignore
index 62c0844be..f654f2551 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -981,6 +981,22 @@ sockopt-sol_socket-success-Xraw
sockopt-sol_socket-success-Xverbose
sockopt-timestamp
splice
+spu_create-success
+spu_create-success-Xabbrev
+spu_create-success-Xraw
+spu_create-success-Xverbose
+spu_create-success-P
+spu_create-success-P-Xabbrev
+spu_create-success-P-Xraw
+spu_create-success-P-Xverbose
+spu_create-success-y
+spu_create-success-y-Xabbrev
+spu_create-success-y-Xraw
+spu_create-success-y-Xverbose
+spu_create-success-y-P
+spu_create-success-y-P-Xabbrev
+spu_create-success-y-P-Xraw
+spu_create-success-y-P-Xverbose
stack-fcall
stack-fcall-attach
stack-fcall-mangled
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d61419974..3c5f8e2e6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -364,6 +364,22 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
sockopt-sol_socket-success-Xabbrev \
sockopt-sol_socket-success-Xraw \
sockopt-sol_socket-success-Xverbose \
+ spu_create-success \
+ spu_create-success-Xabbrev \
+ spu_create-success-Xraw \
+ spu_create-success-Xverbose \
+ spu_create-success-P \
+ spu_create-success-P-Xabbrev \
+ spu_create-success-P-Xraw \
+ spu_create-success-P-Xverbose \
+ spu_create-success-y \
+ spu_create-success-y-Xabbrev \
+ spu_create-success-y-Xraw \
+ spu_create-success-y-Xverbose \
+ spu_create-success-y-P \
+ spu_create-success-y-P-Xabbrev \
+ spu_create-success-y-P-Xraw \
+ spu_create-success-y-P-Xverbose \
stack-fcall \
stack-fcall-attach \
stack-fcall-mangled \
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 5a7074dd8..b0e1d7620 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -959,6 +959,22 @@ sockopt-sol_socket-success-Xraw -einject=getsockopt,setsockopt:retval=42 -etrac
sockopt-sol_socket-success-Xverbose -einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xverbose
sockopt-timestamp -e trace=recvmsg
splice
+spu_create-success -einject=spu_create:retval=7 -etrace=spu_create -a23 </dev/null 7>/dev/full
+spu_create-success-Xabbrev -einject=spu_create:retval=7 -etrace=spu_create -a23 -Xabbrev </dev/null 7>/dev/full
+spu_create-success-Xraw -einject=spu_create:retval=7 -etrace=spu_create -a23 -Xraw </dev/null 7>/dev/full
+spu_create-success-Xverbose -einject=spu_create:retval=7 -etrace=spu_create -a23 -Xverbose </dev/null 7>/dev/full
+spu_create-success-P -einject=spu_create:retval=7 -etrace=spu_create -a23 -P/dev/full </dev/null 7>/dev/full
+spu_create-success-P-Xabbrev -einject=spu_create:retval=7 -etrace=spu_create -a23 -P/dev/full -Xabbrev </dev/null 7>/dev/full
+spu_create-success-P-Xraw -einject=spu_create:retval=7 -etrace=spu_create -a23 -P/dev/full -Xraw </dev/null 7>/dev/full
+spu_create-success-P-Xverbose -einject=spu_create:retval=7 -etrace=spu_create -a23 -P/dev/full -Xverbose </dev/null 7>/dev/full
+spu_create-success-y -einject=spu_create:retval=7 -etrace=spu_create -a23 -y </dev/null 7>/dev/full
+spu_create-success-y-Xabbrev -einject=spu_create:retval=23 -etrace=spu_create -a23 -y -Xabbrev </dev/null 7>/dev/full
+spu_create-success-y-Xraw -einject=spu_create:retval=7 -etrace=spu_create -a23 -y -Xraw </dev/null 7>/dev/full
+spu_create-success-y-Xverbose -einject=spu_create:retval=7 -etrace=spu_create -a23 -y -Xverbose </dev/null 7>/dev/full
+spu_create-success-y-P -einject=spu_create:retval=7 -etrace=spu_create -a23 -y -P/dev/full </dev/null 7>/dev/full
+spu_create-success-y-P-Xabbrev -einject=spu_create:retval=23 -etrace=spu_create -a23 -y -P/dev/full -Xabbrev </dev/null 7>/dev/full
+spu_create-success-y-P-Xraw -einject=spu_create:retval=7 -etrace=spu_create -a23 -y -P/dev/full -Xraw </dev/null 7>/dev/full
+spu_create-success-y-P-Xverbose -einject=spu_create:retval=7 -etrace=spu_create -a23 -y -P/dev/full -Xverbose </dev/null 7>/dev/full
stat -a30 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
stat64 -a32 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
statfs -a17
diff --git a/tests/spu_create-success-P-Xabbrev.c b/tests/spu_create-success-P-Xabbrev.c
new file mode 100644
index 000000000..df2222f2e
--- /dev/null
+++ b/tests/spu_create-success-P-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "spu_create-success-P.c"
diff --git a/tests/spu_create-success-P-Xraw.c b/tests/spu_create-success-P-Xraw.c
new file mode 100644
index 000000000..a8b2657b0
--- /dev/null
+++ b/tests/spu_create-success-P-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "spu_create-success-P.c"
diff --git a/tests/spu_create-success-P-Xverbose.c b/tests/spu_create-success-P-Xverbose.c
new file mode 100644
index 000000000..a976b27ab
--- /dev/null
+++ b/tests/spu_create-success-P-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "spu_create-success-P.c"
diff --git a/tests/spu_create-success-P.c b/tests/spu_create-success-P.c
new file mode 100644
index 000000000..ab3827082
--- /dev/null
+++ b/tests/spu_create-success-P.c
@@ -0,0 +1,2 @@
+#define PATH_FILTER 1
+#include "spu_create-success.c"
diff --git a/tests/spu_create-success-Xabbrev.c b/tests/spu_create-success-Xabbrev.c
new file mode 100644
index 000000000..1b5b2e68c
--- /dev/null
+++ b/tests/spu_create-success-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "spu_create-success.c"
diff --git a/tests/spu_create-success-Xraw.c b/tests/spu_create-success-Xraw.c
new file mode 100644
index 000000000..ee1291328
--- /dev/null
+++ b/tests/spu_create-success-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "spu_create-success.c"
diff --git a/tests/spu_create-success-Xverbose.c b/tests/spu_create-success-Xverbose.c
new file mode 100644
index 000000000..d2e71f853
--- /dev/null
+++ b/tests/spu_create-success-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "spu_create-success.c"
diff --git a/tests/spu_create-success-y-P-Xabbrev.c b/tests/spu_create-success-y-P-Xabbrev.c
new file mode 100644
index 000000000..40f86758d
--- /dev/null
+++ b/tests/spu_create-success-y-P-Xabbrev.c
@@ -0,0 +1,3 @@
+#define XLAT_ABBREV 1
+#define RVAL_STR ""
+#include "spu_create-success-y-P.c"
diff --git a/tests/spu_create-success-y-P-Xraw.c b/tests/spu_create-success-y-P-Xraw.c
new file mode 100644
index 000000000..7c4354ac6
--- /dev/null
+++ b/tests/spu_create-success-y-P-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "spu_create-success-y-P.c"
diff --git a/tests/spu_create-success-y-P-Xverbose.c b/tests/spu_create-success-y-P-Xverbose.c
new file mode 100644
index 000000000..46f84e946
--- /dev/null
+++ b/tests/spu_create-success-y-P-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "spu_create-success-y-P.c"
diff --git a/tests/spu_create-success-y-P.c b/tests/spu_create-success-y-P.c
new file mode 100644
index 000000000..2c01cc49d
--- /dev/null
+++ b/tests/spu_create-success-y-P.c
@@ -0,0 +1,2 @@
+#define PATH_FILTER 1
+#include "spu_create-success-y.c"
diff --git a/tests/spu_create-success-y-Xabbrev.c b/tests/spu_create-success-y-Xabbrev.c
new file mode 100644
index 000000000..1352601a3
--- /dev/null
+++ b/tests/spu_create-success-y-Xabbrev.c
@@ -0,0 +1,3 @@
+#define XLAT_ABBREV 1
+#define RVAL_STR ""
+#include "spu_create-success-y.c"
diff --git a/tests/spu_create-success-y-Xraw.c b/tests/spu_create-success-y-Xraw.c
new file mode 100644
index 000000000..b86ab1ab2
--- /dev/null
+++ b/tests/spu_create-success-y-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "spu_create-success-y.c"
diff --git a/tests/spu_create-success-y-Xverbose.c b/tests/spu_create-success-y-Xverbose.c
new file mode 100644
index 000000000..8011a2075
--- /dev/null
+++ b/tests/spu_create-success-y-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "spu_create-success-y.c"
diff --git a/tests/spu_create-success-y.c b/tests/spu_create-success-y.c
new file mode 100644
index 000000000..7c63e3cf4
--- /dev/null
+++ b/tests/spu_create-success-y.c
@@ -0,0 +1,6 @@
+#define FD0_STR "<" FD0_PATH ">"
+#define FD7_STR "<" FD7_PATH ">"
+#ifndef RVAL_STR
+# define RVAL_STR FD7_STR
+#endif
+#include "spu_create-success.c"
diff --git a/tests/spu_create-success.c b/tests/spu_create-success.c
new file mode 100644
index 000000000..0fe15a9d5
--- /dev/null
+++ b/tests/spu_create-success.c
@@ -0,0 +1,168 @@
+/*
+ * Check decoding of spu_create syscall.
+ *
+ * Copyright (c) 2022 Eugene Syromyatnikov <evgsyr@gmail.com>.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+
+#ifdef __NR_spu_create
+
+# include <fcntl.h>
+# include <inttypes.h>
+# include <stdint.h>
+# include <stdio.h>
+# include <string.h>
+# include <unistd.h>
+
+# define ARR_ITEM(arr_, idx_) ((arr_)[(idx_) % ARRAY_SIZE(arr_)])
+
+# define FD0_PATH "/dev/null"
+# define FD7_PATH "/dev/full"
+
+# define PATH2_STR "0123456789abcdefghijklmnopqrstuvwxyz"
+
+# ifndef FD0_STR
+# define FD0_STR ""
+# endif
+
+# ifndef FD7_STR
+# define FD7_STR ""
+# endif
+
+# ifndef RVAL_STR
+# define RVAL_STR ""
+# endif
+
+# ifndef PATH_FILTER
+# define PATH_FILTER 0
+# endif
+
+struct valstrflag {
+ unsigned int val;
+ const char *str;
+ bool flag;
+};
+
+enum { CLOSED_FD = 23 };
+
+static const char *errstr;
+
+static long
+sys_spu_create(const void *const pathname, const unsigned int flags,
+ const unsigned short mode, const int neighbor_fd)
+{
+ static const kernel_ulong_t fill =
+ (kernel_ulong_t) 0xbeefface00000000ULL;
+ kernel_ulong_t arg1 = (uintptr_t) pathname;
+ kernel_ulong_t arg2 = fill | flags;
+ kernel_ulong_t arg3 = fill | 0xdead0000U | mode;
+ kernel_ulong_t arg4 = fill | (unsigned int) neighbor_fd;
+ kernel_ulong_t arg5 = fill | 0xdecaffed;
+ kernel_ulong_t arg6 = fill | 0xdeefaced;
+
+ long rc = syscall(__NR_spu_create, arg1, arg2, arg3, arg4, arg5, arg6);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
+int
+main(void)
+{
+ close(CLOSED_FD);
+
+ /* NULL/zero args */
+ sys_spu_create(NULL, 0, 0, 0);
+ if (!PATH_FILTER) {
+ printf("spu_create(NULL, 0, 000) = %s" RVAL_STR " (INJECTED)\n",
+ errstr);
+ }
+
+ static const struct valstrflag flags[] = {
+ { ARG_STR(0) },
+ { ARG_STR(0x1) NRAW(" /* SPU_CREATE_EVENTS_ENABLED */") },
+ { ARG_STR(0x10) NRAW(" /* SPU_CREATE_AFFINITY_SPU */"), true },
+ { ARG_STR(0x40) NRAW(" /* SPU_CREATE_??? */") },
+ { ARG_STR(0xbeef) NRAW(" /* SPU_CREATE_EVENTS_ENABLED"
+ "|SPU_CREATE_GANG|SPU_CREATE_NOSCHED"
+ "|SPU_CREATE_ISOLATE"
+ "|SPU_CREATE_AFFINITY_MEM|0xbec0 */") },
+ { ARG_STR(0xcafe) NRAW(" /* SPU_CREATE_GANG|SPU_CREATE_NOSCHED"
+ "|SPU_CREATE_ISOLATE"
+ "|SPU_CREATE_AFFINITY_SPU"
+ "|SPU_CREATE_AFFINITY_MEM|0xcac0 */"),
+ true },
+ { ARG_STR(0xfacedec0) NRAW(" /* SPU_CREATE_??? */") },
+ };
+ static const struct strval16 modes[] = {
+ { ARG_STR(000) },
+ { ARG_STR(0755) },
+ { ARG_STR(04000) },
+ };
+ static const struct valstrflag fds[] = {
+ { 0, FD0_STR },
+ { 7, FD7_STR, true },
+ { CLOSED_FD, "" },
+ { 0xdeadbeef, "" },
+ };
+
+ TAIL_ALLOC_OBJECT_VAR_ARR(char, path0, 1);
+ TAIL_ALLOC_OBJECT_VAR_ARR(char, path1, 3);
+ TAIL_ALLOC_OBJECT_VAR_ARR(char, path2, 37);
+ TAIL_ALLOC_OBJECT_VAR_ARR(char, path3, sizeof(FD7_PATH));
+
+ path0[0] = '\0';
+ memcpy(path1, "\r\n\t", 3);
+ memcpy(path2, PATH2_STR, 37);
+ strcpy(path3, FD7_PATH);
+
+ const struct {
+ const char *val;
+ const char *str;
+ bool flag;
+ } paths[] = {
+ { path0 + 1, NULL },
+ { path0, "\"\"" },
+ { path1, NULL },
+ { path2, "\"" PATH2_STR "\"" },
+ { path3, "\"" FD7_PATH "\"", true },
+ };
+ const size_t iters = 4 * MAX(MAX(MAX(ARRAY_SIZE(flags), ARRAY_SIZE(fds)),
+ ARRAY_SIZE(modes)), ARRAY_SIZE(paths));
+
+ for (size_t i = 0; i < iters; i++) {
+ sys_spu_create(ARR_ITEM(paths, i).val, ARR_ITEM(flags, i).val,
+ ARR_ITEM(modes, i).val, ARR_ITEM(fds, i).val);
+
+ if (PATH_FILTER && !ARR_ITEM(paths, i).flag
+ && (!ARR_ITEM(flags, i).flag || !ARR_ITEM(fds, i).flag))
+ continue;
+
+ printf("spu_create(");
+ if (ARR_ITEM(paths, i).str)
+ printf("%s", ARR_ITEM(paths, i).str);
+ else
+ printf("%p", ARR_ITEM(paths, i).val);
+ printf(", %s, %s",
+ ARR_ITEM(flags, i).str, ARR_ITEM(modes, i).str);
+ if (ARR_ITEM(flags, i).flag) {
+ printf(", %d%s",
+ ARR_ITEM(fds, i).val, ARR_ITEM(fds, i).str);
+ }
+ printf(") = %s" RVAL_STR " (INJECTED)\n", errstr);
+ }
+
+ puts("+++ exited with 0 +++");
+
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_spu_create")
+
+#endif