summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2022-08-08 11:54:43 +0200
committerEugene Syromyatnikov <evgsyr@gmail.com>2022-08-11 14:34:17 +0200
commit07da2c35fd20e1d9af9acd3401f3be7699486b67 (patch)
tree39d7be071eca802100bb67b500c67fbcd6ea0c11
parente926431fdaf4e75a73e8777ac6179dabe02b48d9 (diff)
downloadstrace-07da2c35fd20e1d9af9acd3401f3be7699486b67.tar.gz
arch_prctl: decode ARCH_GET_XCOMP_SUPP, ARCH_{GET,REQ}_XCOMP{,_GUEST}_PERM
* src/xlat/archvals.in (ARCH_GET_XCOMP_SUPP, ARCH_GET_XCOMP_PERM, ARCH_REQ_XCOMP_PERM): New constants, introduced by Linux commit v5.16-rc1~195^2~21. (ARCH_GET_XCOMP_GUEST_PERM, ARCH_REQ_XCOMP_GUEST_PERM): New constants, introduced by Linux commit v5.17-rc1~15^2~70. * src/xlat/x86_xfeature_bits.in: New file. * src/xlat/x86_xfeatures.in: Likewise. * src/prctl.c [X86_64 || X32 || I386]: Include "xlat/x86_xfeature_bits.h", "xlat/x86_xfeatures.h". * tests/.gitignore: Add arch_prctl, arch_prctl-Xabbrev, arch_prctl-Xraw, arch_prctl-Xverbose, arch_prctl-success, arch_prctl-success-Xabbrev, arch_prctl-success-Xraw, and arch_prctl-success-Xverbose. * tests/Makefile.am (check_PROGRAMS): Add arch_prctl-success, arch_prctl-success-Xabbrev, arch_prctl-success-Xraw, and arch_prctl-success-Xverbose. * tests/arch_prctl.c: New file. * tests/arch_prctl-Xabbrev.c: Likewise. * tests/arch_prctl-Xraw.c: Likewise. * tests/arch_prctl-Xverbose.c: Likewise. * tests/arch_prctl-success.c: Likewise. * tests/arch_prctl-success-Xabbrev.c: Likewise. * tests/arch_prctl-success-Xraw.c: Likewise. * tests/arch_prctl-success-Xverbose.c: Likewise. * tests/arch_prctl.sh: Likewise. * tests/gen_tests.in (arch_prctl, arch_prctl-Xabbrev, arch_prctl-Xraw, arch_prctl-Xverbose, arch_prctl-success, arch_prctl-success-Xabbrev, arch_prctl-success-Xraw, arch_prctl-success-Xverbose): New tests. * tests/prctl-success.sh (PRCTL_SYSCALL, PRCTL_MARKER_RE): New vaiables. Handle "ARCH_PRCTL_INJECT_RETVALS" in addition to "PRCTL_INJECT_RETVALS", set PRCTL_SYSCALL and PRCTL_MARKER_RE accordingly; use $PRCTL_SYSCALL and $PRCTL_MARKER_RE in run_strace and sed calls. * tests/pure_executables.list: Add arch_prctl, arch_prctl-Xabbrev, arch_prctl-Xraw, and arch_prctl-Xverbose. * NEWS: Mention it.
-rw-r--r--NEWS2
-rw-r--r--src/prctl.c56
-rw-r--r--src/xlat/archvals.in24
-rw-r--r--src/xlat/x86_xfeature_bits.in21
-rw-r--r--src/xlat/x86_xfeatures.in18
-rw-r--r--tests/.gitignore8
-rw-r--r--tests/Makefile.am5
-rw-r--r--tests/arch_prctl-Xabbrev.c2
-rw-r--r--tests/arch_prctl-Xraw.c2
-rw-r--r--tests/arch_prctl-Xverbose.c2
-rw-r--r--tests/arch_prctl-success-Xabbrev.c2
-rw-r--r--tests/arch_prctl-success-Xraw.c2
-rw-r--r--tests/arch_prctl-success-Xverbose.c2
-rw-r--r--tests/arch_prctl-success.c2
-rw-r--r--tests/arch_prctl.c323
-rw-r--r--tests/arch_prctl.sh16
-rw-r--r--tests/gen_tests.in8
-rw-r--r--tests/prctl-success.sh23
-rwxr-xr-xtests/pure_executables.list4
19 files changed, 506 insertions, 16 deletions
diff --git a/NEWS b/NEWS
index c54f57a7c..5bd64ce02 100644
--- a/NEWS
+++ b/NEWS
@@ -15,7 +15,7 @@ Noteworthy changes in release ?.?? (????-??-??)
INET_DIAG_PROTOCOL, INET_DIAG_REQ_PROTOCOL, INET_DIAG_SHUTDOWN,
INET_DIAG_SK_BPF_STORAGES, INET_DIAG_SOCKOPT, and INET_DIAG_ULP_INFO
NETLINK_SOCK_DIAG netlink attributes.
- * Enhanced decoding of prctl syscall.
+ * Enhanced decoding of arch_prctl and prctl syscalls.
* Enhanced siginfo_t decoding.
* Updated decoding of struct rtnl_link_stats64.
* Updated lists of DEVCONF_*, FAN_MARK_*, GPIO_V2_LINE_FLAG_*, IORING_*,
diff --git a/src/prctl.c b/src/prctl.c
index cf281d8ae..97f42fe15 100644
--- a/src/prctl.c
+++ b/src/prctl.c
@@ -637,6 +637,8 @@ SYS_FUNC(prctl)
#if defined X86_64 || defined X32 || defined I386
# include "xlat/archvals.h"
+# include "xlat/x86_xfeature_bits.h"
+# include "xlat/x86_xfeatures.h"
SYS_FUNC(arch_prctl)
{
@@ -657,6 +659,60 @@ SYS_FUNC(arch_prctl)
case ARCH_GET_CPUID: /* has no arguments */
return RVAL_DECODED;
+
+ case ARCH_GET_XCOMP_SUPP:
+ case ARCH_GET_XCOMP_PERM:
+ case ARCH_GET_XCOMP_GUEST_PERM:
+ if (entering(tcp)) {
+ tprint_arg_next();
+ } else {
+ uint64_t val;
+
+ if (umove_or_printaddr(tcp, addr, &val))
+ return 0;
+
+ /* XFEATURE_MASK_* macros are not publicly exposed */
+ tprint_indirect_begin();
+ printflags_ex(val, "XFEATURE_MASK_???",
+ xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW
+ ? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE,
+ x86_xfeatures, NULL);
+ tprint_indirect_end();
+ }
+
+ return 0;
+
+ case ARCH_REQ_XCOMP_PERM:
+ case ARCH_REQ_XCOMP_GUEST_PERM:
+ if (entering(tcp)) {
+ /* XFEATURE_* enum is not publicly exposed */
+ tprint_arg_next();
+ printxvals_ex(addr, "XFEATURE_???",
+ xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW
+ ? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE,
+ x86_xfeature_bits, NULL);
+ } else {
+ if (tcp->u_rval <= 0)
+ return 0;
+
+ tcp->auxstr = sprintflags_ex("", x86_xfeatures,
+ (kernel_ulong_t) tcp->u_rval, '\0',
+ XLAT_STYLE_DEFAULT | SPFF_AUXSTR_MODE);
+
+ return RVAL_HEX | RVAL_STR;
+ }
+
+ return 0;
+
+ /* default handling: print arg2 in hexadecimal on entering */
+ case ARCH_SET_GS:
+ case ARCH_SET_FS:
+ case ARCH_SET_CPUID:
+ case ARCH_MAP_VDSO_X32:
+ case ARCH_MAP_VDSO_32:
+ case ARCH_MAP_VDSO_64:
+ default:
+ break;
}
tprint_arg_next();
diff --git a/src/xlat/archvals.in b/src/xlat/archvals.in
index 1dbbb8d00..b50ce32d6 100644
--- a/src/xlat/archvals.in
+++ b/src/xlat/archvals.in
@@ -1,9 +1,15 @@
-ARCH_SET_GS 0x1001
-ARCH_SET_FS 0x1002
-ARCH_GET_FS 0x1003
-ARCH_GET_GS 0x1004
-ARCH_GET_CPUID 0x1011
-ARCH_SET_CPUID 0x1012
-ARCH_MAP_VDSO_X32 0x2001
-ARCH_MAP_VDSO_32 0x2002
-ARCH_MAP_VDSO_64 0x2003
+#sorted
+ARCH_SET_GS 0x1001
+ARCH_SET_FS 0x1002
+ARCH_GET_FS 0x1003
+ARCH_GET_GS 0x1004
+ARCH_GET_CPUID 0x1011
+ARCH_SET_CPUID 0x1012
+ARCH_GET_XCOMP_SUPP 0x1021
+ARCH_GET_XCOMP_PERM 0x1022
+ARCH_REQ_XCOMP_PERM 0x1023
+ARCH_GET_XCOMP_GUEST_PERM 0x1024
+ARCH_REQ_XCOMP_GUEST_PERM 0x1025
+ARCH_MAP_VDSO_X32 0x2001
+ARCH_MAP_VDSO_32 0x2002
+ARCH_MAP_VDSO_64 0x2003
diff --git a/src/xlat/x86_xfeature_bits.in b/src/xlat/x86_xfeature_bits.in
new file mode 100644
index 000000000..208a4c33e
--- /dev/null
+++ b/src/xlat/x86_xfeature_bits.in
@@ -0,0 +1,21 @@
+#value_indexed
+/* From arch/x86/include/asm/fpu/types.h */
+XFEATURE_FP 0
+XFEATURE_SSE 1
+XFEATURE_YMM 2
+XFEATURE_BNDREGS 3
+XFEATURE_BNDCSR 4
+XFEATURE_OPMASK 5
+XFEATURE_ZMM_Hi256 6
+XFEATURE_Hi16_ZMM 7
+XFEATURE_PT_UNIMPLEMENTED_SO_FAR 8
+XFEATURE_PKRU 9
+XFEATURE_PASID 10
+/* XFEATURE_RSRVD_COMP_11 11 */
+/* XFEATURE_RSRVD_COMP_12 12 */
+/* XFEATURE_RSRVD_COMP_13 13 */
+/* XFEATURE_RSRVD_COMP_14 14 */
+XFEATURE_LBR 15
+/* XFEATURE_RSRVD_COMP_16 16 */
+XFEATURE_XTILE_CFG 17
+XFEATURE_XTILE_DATA 18
diff --git a/src/xlat/x86_xfeatures.in b/src/xlat/x86_xfeatures.in
new file mode 100644
index 000000000..ef81ff3fb
--- /dev/null
+++ b/src/xlat/x86_xfeatures.in
@@ -0,0 +1,18 @@
+/* From arch/x86/include/asm/fpu/types.h */
+XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
+XFEATURE_MASK_FP (1 << XFEATURE_FP)
+XFEATURE_MASK_SSE (1 << XFEATURE_SSE)
+XFEATURE_MASK_YMM (1 << XFEATURE_YMM)
+XFEATURE_MASK_BNDREGS (1 << XFEATURE_BNDREGS)
+XFEATURE_MASK_BNDCSR (1 << XFEATURE_BNDCSR)
+XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK | XFEATURE_MASK_ZMM_Hi256 | XFEATURE_MASK_Hi16_ZMM)
+XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK)
+XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256)
+XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM)
+XFEATURE_MASK_PT (1 << XFEATURE_PT_UNIMPLEMENTED_SO_FAR)
+XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU)
+XFEATURE_MASK_PASID (1 << XFEATURE_PASID)
+XFEATURE_MASK_LBR (1 << XFEATURE_LBR)
+XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILE_DATA | XFEATURE_MASK_XTILE_CFG)
+XFEATURE_MASK_XTILE_CFG (1 << XFEATURE_XTILE_CFG)
+XFEATURE_MASK_XTILE_DATA (1 << XFEATURE_XTILE_DATA)
diff --git a/tests/.gitignore b/tests/.gitignore
index 653002ac1..361f74655 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -23,6 +23,14 @@ aio
aio_pgetevents
alarm
answer
+arch_prctl
+arch_prctl-Xabbrev
+arch_prctl-Xraw
+arch_prctl-Xverbose
+arch_prctl-success
+arch_prctl-success-Xabbrev
+arch_prctl-success-Xraw
+arch_prctl-success-Xverbose
at_fdcwd-pathmax
attach-f-p
attach-f-p-cmd
diff --git a/tests/Makefile.am b/tests/Makefile.am
index df5cf6313..7d08c0523 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -99,6 +99,10 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
$(secontext_EXECUTABLES) \
_newselect-P \
answer \
+ arch_prctl-success \
+ arch_prctl-success-Xabbrev \
+ arch_prctl-success-Xraw \
+ arch_prctl-success-Xverbose \
attach-f-p \
attach-f-p-cmd \
attach-p-cmd-cmd \
@@ -633,6 +637,7 @@ EXTRA_DIST = \
GPL-2.0-or-later \
PTRACE_SEIZE.sh \
accept_compat.h \
+ arch_prctl.sh \
attach-p-cmd.h \
caps-abbrev.awk \
caps.awk \
diff --git a/tests/arch_prctl-Xabbrev.c b/tests/arch_prctl-Xabbrev.c
new file mode 100644
index 000000000..3f4c7626c
--- /dev/null
+++ b/tests/arch_prctl-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "arch_prctl.c"
diff --git a/tests/arch_prctl-Xraw.c b/tests/arch_prctl-Xraw.c
new file mode 100644
index 000000000..8068cb53c
--- /dev/null
+++ b/tests/arch_prctl-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "arch_prctl.c"
diff --git a/tests/arch_prctl-Xverbose.c b/tests/arch_prctl-Xverbose.c
new file mode 100644
index 000000000..bab799a66
--- /dev/null
+++ b/tests/arch_prctl-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "arch_prctl.c"
diff --git a/tests/arch_prctl-success-Xabbrev.c b/tests/arch_prctl-success-Xabbrev.c
new file mode 100644
index 000000000..2572ff845
--- /dev/null
+++ b/tests/arch_prctl-success-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "arch_prctl-success.c"
diff --git a/tests/arch_prctl-success-Xraw.c b/tests/arch_prctl-success-Xraw.c
new file mode 100644
index 000000000..f685c369b
--- /dev/null
+++ b/tests/arch_prctl-success-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "arch_prctl-success.c"
diff --git a/tests/arch_prctl-success-Xverbose.c b/tests/arch_prctl-success-Xverbose.c
new file mode 100644
index 000000000..e8e0afc81
--- /dev/null
+++ b/tests/arch_prctl-success-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "arch_prctl-success.c"
diff --git a/tests/arch_prctl-success.c b/tests/arch_prctl-success.c
new file mode 100644
index 000000000..02b6e39b0
--- /dev/null
+++ b/tests/arch_prctl-success.c
@@ -0,0 +1,2 @@
+#define INJECT_RETVAL
+#include "arch_prctl.c"
diff --git a/tests/arch_prctl.c b/tests/arch_prctl.c
new file mode 100644
index 000000000..08ba31ac1
--- /dev/null
+++ b/tests/arch_prctl.c
@@ -0,0 +1,323 @@
+/*
+ * Check decoding of arch_prctl syscall.
+ *
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+
+#ifdef __NR_arch_prctl
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <linux/prctl.h>
+
+# define XLAT_MACROS_ONLY
+# include "xlat/archvals.h"
+# undef XLAT_MACROS_ONLY
+
+# include "xlat.h"
+# include "xlat/x86_xfeature_bits.h"
+# include "xlat/x86_xfeatures.h"
+
+# ifdef INJECT_RETVAL
+# define INJ_STR " (INJECTED)\n"
+# else
+# define INJ_STR "\n"
+# endif
+
+# define ARRAY_END(a_) ((a_) + ARRAY_SIZE(a_))
+
+static long
+sys_arch_prctl(unsigned int cmd, kernel_ulong_t arg)
+{
+ return syscall(__NR_arch_prctl, cmd, arg, (unsigned long) -3U,
+ (unsigned long) -4U,
+ (unsigned long) -5U);
+}
+
+static long
+arch_prctl_marker(void)
+{
+ return sys_arch_prctl(-1U, (unsigned long) -2U);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const kernel_ulong_t dummy = (kernel_ulong_t) 0xbadfaceddeadbeefULL;
+ const char *errstr;
+ long rc;
+
+ arch_prctl_marker();
+
+# ifdef INJECT_RETVAL
+ unsigned long num_skip;
+ long inject_retval;
+ bool locked = false;
+
+ if (argc < 3)
+ error_msg_and_fail("Usage: %s NUM_SKIP INJECT_RETVAL", argv[0]);
+
+ num_skip = strtoul(argv[1], NULL, 0);
+ inject_retval = strtol(argv[2], NULL, 0);
+
+ for (size_t i = 0; i < num_skip; i++) {
+ if (arch_prctl_marker() != inject_retval)
+ continue;
+
+ locked = true;
+ break;
+ }
+
+ if (!locked)
+ error_msg_and_fail("Have not locked on arch_prctl(-1, -2)"
+ " returning %ld", inject_retval);
+# endif /* INJECT_RETVAL */
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, u64_p);
+
+ /* Unknown commands */
+ static const uint32_t unk_cmds[] = {
+ 0, 0x1,
+ 0x1000, 0x1005,
+ 0x1010, 0x1013,
+ 0x1020, 0x1026,
+ 0x1030, 0x1031,
+ 0x1100, 0x1101,
+ 0x2000, 0x2004,
+ 0x2010, 0x2011,
+ 0x2100, 0x2101,
+ 0x3000, 0x3001,
+ 0xdeadc0de };
+
+ for (size_t i = 0; i < ARRAY_SIZE(unk_cmds); i++) {
+ rc = sys_arch_prctl(unk_cmds[i], 0);
+ printf("arch_prctl(" XLAT_UNKNOWN_FMT("%#x", "ARCH_???")
+ ", 0) = %s" INJ_STR,
+ unk_cmds[i], sprintrc(rc));
+
+ rc = sys_arch_prctl(unk_cmds[i], (kernel_ulong_t) dummy);
+ printf("arch_prctl(" XLAT_UNKNOWN_FMT("%#x", "ARCH_???")
+ ", %#llx) = %s" INJ_STR,
+ unk_cmds[i], (unsigned long long) dummy, sprintrc(rc));
+
+ rc = sys_arch_prctl(unk_cmds[i], (uintptr_t) u64_p);
+ printf("arch_prctl(" XLAT_UNKNOWN_FMT("%#x", "ARCH_???")
+ ", %p) = %s" INJ_STR,
+ unk_cmds[i], u64_p, sprintrc(rc));
+ }
+
+ /* Default decoding */
+ static const struct strval32 def_cmds[] = {
+ { ARG_XLAT_KNOWN(0x1001, "ARCH_SET_GS") },
+# ifdef INJECT_RETVAL
+ { ARG_XLAT_KNOWN(0x1002, "ARCH_SET_FS") },
+# endif
+ { ARG_XLAT_KNOWN(0x1012, "ARCH_SET_CPUID") },
+ { ARG_XLAT_KNOWN(0x2001, "ARCH_MAP_VDSO_X32") },
+ { ARG_XLAT_KNOWN(0x2002, "ARCH_MAP_VDSO_32") },
+ { ARG_XLAT_KNOWN(0x2003, "ARCH_MAP_VDSO_64") },
+ };
+
+ for (const struct strval32 *p = def_cmds; p < ARRAY_END(def_cmds); p++)
+ {
+ rc = sys_arch_prctl(p->val, (kernel_ulong_t) dummy);
+ printf("arch_prctl(%s, %#llx) = %s" INJ_STR,
+ p->str, (unsigned long long) dummy, sprintrc(rc));
+
+ rc = sys_arch_prctl(p->val, (uintptr_t) u64_p);
+ printf("arch_prctl(%s, %p) = %s" INJ_STR,
+ p->str, u64_p, sprintrc(rc));
+
+ rc = sys_arch_prctl(p->val, 0);
+ printf("arch_prctl(%s, 0) = %s" INJ_STR, p->str, sprintrc(rc));
+ }
+
+ /* ARCH_GET_GS, ARCH_GET_FS */
+ static const struct strval32 kptr_cmds[] = {
+# ifdef INJECT_RETVAL
+ { ARG_XLAT_KNOWN(0x1003, "ARCH_GET_FS") },
+# endif
+ { ARG_XLAT_KNOWN(0x1004, "ARCH_GET_GS") },
+ };
+ TAIL_ALLOC_OBJECT_CONST_PTR(kernel_ulong_t, kulong_p);
+ const kernel_ulong_t ptrs[] = {
+ (kernel_ulong_t) 0xdeadfacecafebeefULL,
+ (uintptr_t) (kulong_p + 1),
+ (uintptr_t) kulong_p ,
+ 0
+ };
+
+ for (const struct strval32 *p = kptr_cmds; p < ARRAY_END(kptr_cmds);
+ p++) {
+ rc = sys_arch_prctl(p->val, 0);
+ printf("arch_prctl(%s, NULL) = %s" INJ_STR,
+ p->str, sprintrc(rc));
+
+ rc = sys_arch_prctl(p->val, (uintptr_t) (kulong_p + 1));
+ printf("arch_prctl(%s, %p) = %s" INJ_STR,
+ p->str, kulong_p + 1, sprintrc(rc));
+
+ for (size_t j = 0; j < ARRAY_SIZE(ptrs); j++) {
+ *kulong_p = ptrs[j];
+ uint32_t wr_cmd = p->val == ARCH_GET_GS ? ARCH_SET_GS
+ : ARCH_SET_FS;
+# if !XLAT_RAW
+ const char *wr_str = p->val == ARCH_GET_GS
+ ? "ARCH_SET_GS" : "ARCH_SET_FS";
+# endif
+ rc = sys_arch_prctl(wr_cmd, *kulong_p);
+ printf("arch_prctl(" XLAT_FMT ", %#llx) = %s" INJ_STR,
+ XLAT_SEL(wr_cmd, wr_str),
+ (unsigned long long) *kulong_p, sprintrc(rc));
+
+ rc = sys_arch_prctl(p->val, (uintptr_t) kulong_p);
+ errstr = sprintrc(rc);
+ printf("arch_prctl(%s, ", p->str);
+ if (rc >= 0) {
+ if (*kulong_p) {
+ printf("[%#llx]",
+ (unsigned long long) *kulong_p);
+ } else {
+ printf("[NULL]");
+ }
+ } else {
+ printf("%p", kulong_p);
+ }
+ printf(") = %s" INJ_STR, errstr);
+ }
+ }
+
+ /* ARCH_GET_CPUID */
+ rc = sys_arch_prctl(ARCH_GET_CPUID, 0xdeadc0de);
+ printf("arch_prctl(" XLAT_FMT ") = %s" INJ_STR,
+ XLAT_ARGS(ARCH_GET_CPUID), sprintrc(rc));
+
+ /* xfeature mask get */
+ static const struct strval32 xfget_cmds[] = {
+ { ARG_XLAT_KNOWN(0x1021, "ARCH_GET_XCOMP_SUPP") },
+ { ARG_XLAT_KNOWN(0x1022, "ARCH_GET_XCOMP_PERM") },
+ { ARG_XLAT_KNOWN(0x1024, "ARCH_GET_XCOMP_GUEST_PERM") },
+ };
+ static const struct strval64 xfget_vals[] = {
+ { ARG_STR(0) },
+ { ARG_XLAT_UNKNOWN(0x1, "XFEATURE_MASK_FP") },
+ { ARG_XLAT_UNKNOWN(0x2, "XFEATURE_MASK_SSE") },
+ { ARG_XLAT_UNKNOWN(0x3, "XFEATURE_MASK_FPSSE") },
+ { ARG_XLAT_UNKNOWN(0x20, "XFEATURE_MASK_OPMASK") },
+ { ARG_XLAT_UNKNOWN(0xc0, "XFEATURE_MASK_ZMM_Hi256"
+ "|XFEATURE_MASK_Hi16_ZMM") },
+ { ARG_XLAT_UNKNOWN(0xe0, "XFEATURE_MASK_AVX512") },
+ { ARG_XLAT_UNKNOWN(0x20000, "XFEATURE_MASK_XTILE_CFG") },
+ { ARG_XLAT_UNKNOWN(0x40000, "XFEATURE_MASK_XTILE_DATA") },
+ { ARG_XLAT_UNKNOWN(0x60000, "XFEATURE_MASK_XTILE") },
+ { ARG_XLAT_UNKNOWN(0xbadfaced,
+ "XFEATURE_MASK_FP|XFEATURE_MASK_YMM"
+ "|XFEATURE_MASK_BNDREGS|XFEATURE_MASK_AVX512"
+ "|XFEATURE_MASK_PASID|XFEATURE_MASK_LBR"
+ "|XFEATURE_MASK_XTILE|0xbad92800") },
+ { ARG_XLAT_UNKNOWN(0x687ff,
+ "XFEATURE_MASK_FPSSE|XFEATURE_MASK_YMM"
+ "|XFEATURE_MASK_BNDREGS|XFEATURE_MASK_BNDCSR"
+ "|XFEATURE_MASK_AVX512|XFEATURE_MASK_PT"
+ "|XFEATURE_MASK_PKRU|XFEATURE_MASK_PASID"
+ "|XFEATURE_MASK_LBR|XFEATURE_MASK_XTILE") },
+ { ARG_XLAT_UNKNOWN(0xfffffffffff97800, "XFEATURE_MASK_???") },
+ };
+
+ for (const struct strval32 *p = xfget_cmds; p < ARRAY_END(xfget_cmds);
+ p++) {
+ rc = sys_arch_prctl(p->val, 0);
+ printf("arch_prctl(%s, NULL) = %s" INJ_STR,
+ p->str, sprintrc(rc));
+
+ rc = sys_arch_prctl(p->val, (uintptr_t) (u64_p + 1));
+ printf("arch_prctl(%s, %p) = %s" INJ_STR,
+ p->str, u64_p + 1, sprintrc(rc));
+
+ for (const struct strval64 *q = xfget_vals;
+ q < ARRAY_END(xfget_vals); q++) {
+ *u64_p = q->val;
+ rc = sys_arch_prctl(p->val, (uintptr_t) u64_p);
+ errstr = sprintrc(rc);
+ printf("arch_prctl(%s, ", p->str);
+ if (rc >= 0) {
+# ifdef INJECT_RETVAL
+ printf("[%s]", q->str);
+# else
+ if (*u64_p) {
+ printf("[%#llx" NRAW(" /* "),
+ (unsigned long long) *u64_p);
+# if !XLAT_RAW
+ printflags(x86_xfeatures, *u64_p, NULL);
+# endif
+ printf(NRAW(" */") "]");
+ } else {
+ printf("[0]");
+ }
+# endif
+ } else {
+ printf("%p", u64_p);
+ }
+ printf(") = %s" INJ_STR, errstr);
+ }
+ }
+
+ /* xfeature in arg, xfeature mask in ret */
+ static const struct strval32 xfreq_cmds[] = {
+ { ARG_XLAT_KNOWN(0x1023, "ARCH_REQ_XCOMP_PERM") },
+ { ARG_XLAT_KNOWN(0x1025, "ARCH_REQ_XCOMP_GUEST_PERM") },
+ };
+ static const struct strval32 xfreq_vals[] = {
+ { ARG_XLAT_UNKNOWN(0, "XFEATURE_FP") },
+ { ARG_XLAT_UNKNOWN(0x8, "XFEATURE_PT_UNIMPLEMENTED_SO_FAR") },
+ { ARG_XLAT_UNKNOWN(0xb, "XFEATURE_???") },
+ { ARG_XLAT_UNKNOWN(0xc, "XFEATURE_???") },
+ { ARG_XLAT_UNKNOWN(0xd, "XFEATURE_???") },
+ { ARG_XLAT_UNKNOWN(0xe, "XFEATURE_???") },
+ { ARG_XLAT_UNKNOWN(0xf, "XFEATURE_LBR") },
+ { ARG_XLAT_UNKNOWN(0x10, "XFEATURE_???") },
+ { ARG_XLAT_UNKNOWN(0x11, "XFEATURE_XTILE_CFG") },
+ { ARG_XLAT_UNKNOWN(0x12, "XFEATURE_XTILE_DATA") },
+ { ARG_XLAT_UNKNOWN(0x13, "XFEATURE_???") },
+ { ARG_XLAT_UNKNOWN(0xdeadface, "XFEATURE_???") },
+ };
+
+ for (const struct strval32 *p = xfreq_cmds; p < ARRAY_END(xfreq_cmds);
+ p++) {
+ for (const struct strval32 *q = xfreq_vals;
+ q < ARRAY_END(xfreq_vals); q++) {
+ rc = sys_arch_prctl(p->val, q->val);
+ errstr = sprintrc(rc);
+ printf("arch_prctl(%s, %s) = ", p->str, q->str);
+ if (rc > 0) {
+ printf("%#lx", rc);
+# if !XLAT_RAW
+ if (rc & x86_xfeatures->flags_mask) {
+ printf(" (");
+ printflags(x86_xfeatures, rc, NULL);
+ printf(")");
+ }
+# endif
+ printf(INJ_STR);
+ } else {
+ printf("%s" INJ_STR, errstr);
+ }
+ }
+ }
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_arch_prctl")
+
+#endif
diff --git a/tests/arch_prctl.sh b/tests/arch_prctl.sh
new file mode 100644
index 000000000..ddab7e25a
--- /dev/null
+++ b/tests/arch_prctl.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Check arch_prctl syscall decoding.
+#
+# Copyright (c) 20212-2022 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+check_prog sed
+run_prog > /dev/null
+run_strace -earch_prctl "$@" $args > "$EXP"
+sed '0,/^arch_prctl(0xffffffff\( \/\* ARCH_??? \*\/\)\?, 0xfffffffe) *= -1 /d' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index bb21a9d80..4bb63227f 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -20,6 +20,14 @@ adjtimex -a15
aio -a14 -e trace=io_setup,io_submit,io_getevents,io_cancel,io_destroy
aio_pgetevents -e trace=io_pgetevents
alarm -a10
+arch_prctl +arch_prctl.sh -a27
+arch_prctl-Xabbrev +arch_prctl.sh -a27 -Xabbrev
+arch_prctl-Xraw +arch_prctl.sh -a17 -Xraw
+arch_prctl-Xverbose +arch_prctl.sh -a32 -Xverbose
+arch_prctl-success +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a27
+arch_prctl-success-Xabbrev +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a27 -Xabbrev
+arch_prctl-success-Xraw +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a17 -Xraw
+arch_prctl-success-Xverbose +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a32 -Xverbose
at_fdcwd-pathmax -a36 --trace=openat -y -P sample
bpf -a20
bpf-obj_get_info_by_fd -a20 -y -e trace=bpf
diff --git a/tests/prctl-success.sh b/tests/prctl-success.sh
index 2ab26023c..0d5301501 100644
--- a/tests/prctl-success.sh
+++ b/tests/prctl-success.sh
@@ -12,8 +12,10 @@
. "${srcdir=.}/scno_tampering.sh"
-: ${PRCTL_INJECT_START=256}
-: ${PRCTL_INJECT_RETVALS=42}
+: "${PRCTL_INJECT_START=256}"
+: "${PRCTL_INJECT_RETVALS=42}"
+: "${PRCTL_SYSCALL=prctl}"
+: "${PRCTL_MARKER_RE='prctl(0xffffffff\( \/\* PR_??? \*\/\)\?, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb)'}"
check_prog sed
@@ -21,7 +23,16 @@ check_prog sed
# at the beginning of the argument list.
while [ "$#" -gt 0 ]; do
case "$1" in
- PRCTL_INJECT_RETVALS=*) PRCTL_INJECT_RETVALS="${1#PRCTL_INJECT_RETVALS=}"; ;;
+ ARCH_PRCTL_INJECT_RETVALS=*)
+ PRCTL_INJECT_RETVALS="${1#ARCH_PRCTL_INJECT_RETVALS=}"
+ PRCTL_SYSCALL=arch_prctl
+ PRCTL_MARKER_RE='arch_prctl(0xffffffff\( \/\* ARCH_??? \*\/\)\?, 0xfffffffe)'
+ ;;
+ PRCTL_INJECT_RETVALS=*)
+ PRCTL_INJECT_RETVALS="${1#PRCTL_INJECT_RETVALS=}"
+ PRCTL_SYSCALL=prctl
+ PRCTL_MARKER_RE='prctl(0xffffffff\( \/\* PR_??? \*\/\)\?, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb)'
+ ;;
*) break; ;;
esac
@@ -48,9 +59,9 @@ for i in $(echo "$PRCTL_INJECT_RETVALS"); do
sed_match="-1 ${i#error=}"
fi
- run_strace -a80 "$@" -e trace=prctl \
- -e inject=prctl:"${inj_str}":when="${PRCTL_INJECT_START}+" \
+ run_strace -a80 "$@" -e trace="${PRCTL_SYSCALL}" \
+ -e inject="${PRCTL_SYSCALL}":"${inj_str}":when="${PRCTL_INJECT_START}+" \
"../$NAME" "${PRCTL_INJECT_START}" "${ret_val}" > "$EXP.$i"
- sed '0,/^prctl(0xffffffff\( \/\* PR_??? \*\/\)\?, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb) *= '"${sed_match}"' /d' < "$LOG" > "$OUT.$i"
+ sed '0,/^'"${PRCTL_MARKER_RE}"' *= '"${sed_match}"' /d' < "$LOG" > "$OUT.$i"
match_diff "$OUT.$i" "$EXP.$i"
done
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 3577499cc..471a97e1e 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -15,6 +15,10 @@ adjtimex
aio
aio_pgetevents
alarm
+arch_prctl
+arch_prctl-Xabbrev
+arch_prctl-Xraw
+arch_prctl-Xverbose
at_fdcwd-pathmax
bpf
bpf-v