You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(5) |
Oct
(1) |
Nov
|
Dec
(2) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(3) |
Feb
(1) |
Mar
(62) |
Apr
(29) |
May
(4) |
Jun
|
Jul
(11) |
Aug
(30) |
Sep
(8) |
Oct
(31) |
Nov
(2) |
Dec
(13) |
| 2002 |
Jan
(4) |
Feb
(3) |
Mar
(12) |
Apr
(2) |
May
(7) |
Jun
(2) |
Jul
(7) |
Aug
(5) |
Sep
(4) |
Oct
(8) |
Nov
(5) |
Dec
(17) |
| 2003 |
Jan
(24) |
Feb
(19) |
Mar
(19) |
Apr
(22) |
May
(18) |
Jun
(16) |
Jul
(21) |
Aug
(48) |
Sep
(31) |
Oct
(45) |
Nov
(52) |
Dec
(54) |
| 2004 |
Jan
(71) |
Feb
(60) |
Mar
(54) |
Apr
(50) |
May
(88) |
Jun
(76) |
Jul
(62) |
Aug
(35) |
Sep
(20) |
Oct
(37) |
Nov
(66) |
Dec
(45) |
| 2005 |
Jan
(12) |
Feb
(5) |
Mar
(11) |
Apr
(6) |
May
(6) |
Jun
(6) |
Jul
(29) |
Aug
(61) |
Sep
(17) |
Oct
(45) |
Nov
(34) |
Dec
(17) |
| 2006 |
Jan
(13) |
Feb
(10) |
Mar
(15) |
Apr
(7) |
May
(13) |
Jun
(24) |
Jul
(12) |
Aug
(9) |
Sep
(17) |
Oct
(61) |
Nov
(58) |
Dec
(77) |
| 2007 |
Jan
(67) |
Feb
(61) |
Mar
(54) |
Apr
(93) |
May
(104) |
Jun
(131) |
Jul
(187) |
Aug
(116) |
Sep
(66) |
Oct
(41) |
Nov
(56) |
Dec
(19) |
| 2008 |
Jan
(19) |
Feb
(65) |
Mar
(127) |
Apr
(170) |
May
(137) |
Jun
(160) |
Jul
(168) |
Aug
(139) |
Sep
(104) |
Oct
(51) |
Nov
(69) |
Dec
(126) |
| 2009 |
Jan
(55) |
Feb
(148) |
Mar
(87) |
Apr
(74) |
May
(151) |
Jun
(121) |
Jul
(111) |
Aug
(97) |
Sep
(107) |
Oct
(177) |
Nov
(101) |
Dec
(84) |
| 2010 |
Jan
(55) |
Feb
(45) |
Mar
(114) |
Apr
(140) |
May
(152) |
Jun
(132) |
Jul
(115) |
Aug
(118) |
Sep
(105) |
Oct
(32) |
Nov
(26) |
Dec
(44) |
| 2011 |
Jan
(36) |
Feb
(138) |
Mar
(80) |
Apr
(34) |
May
(52) |
Jun
(72) |
Jul
(27) |
Aug
(119) |
Sep
(77) |
Oct
(71) |
Nov
(58) |
Dec
(50) |
| 2012 |
Jan
(59) |
Feb
(55) |
Mar
(82) |
Apr
(81) |
May
(31) |
Jun
(8) |
Jul
(13) |
Aug
(8) |
Sep
(10) |
Oct
(44) |
Nov
(13) |
Dec
(15) |
| 2013 |
Jan
(28) |
Feb
(72) |
Mar
(35) |
Apr
(14) |
May
(162) |
Jun
(55) |
Jul
(39) |
Aug
(20) |
Sep
(25) |
Oct
(15) |
Nov
(84) |
Dec
(14) |
| 2014 |
Jan
(31) |
Feb
(102) |
Mar
(112) |
Apr
(106) |
May
(105) |
Jun
(87) |
Jul
(36) |
Aug
(112) |
Sep
(31) |
Oct
(23) |
Nov
(68) |
Dec
(42) |
| 2015 |
Jan
(46) |
Feb
(131) |
Mar
(267) |
Apr
(48) |
May
(27) |
Jun
(42) |
Jul
(41) |
Aug
(41) |
Sep
(28) |
Oct
(22) |
Nov
(27) |
Dec
(45) |
| 2016 |
Jan
(55) |
Feb
(55) |
Mar
(363) |
Apr
(125) |
May
(173) |
Jun
(159) |
Jul
(69) |
Aug
(111) |
Sep
(130) |
Oct
(115) |
Nov
(26) |
Dec
(70) |
| 2017 |
Jan
(78) |
Feb
(43) |
Mar
(249) |
Apr
(130) |
May
(35) |
Jun
(436) |
Jul
(293) |
Aug
(423) |
Sep
(81) |
Oct
(16) |
Nov
(35) |
Dec
(110) |
| 2018 |
Jan
(67) |
Feb
(36) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Eugene S. <es...@re...> - 2018-01-22 13:29:11
|
On Mon, Jan 22, 2018 at 02:16:43PM +0100, Heiko Carstens wrote:
> On Thu, Jan 18, 2018 at 07:16:44AM +0100, Eugene Syromyatnikov wrote:
> > +static void
> > +print_sthyi_hypervisor(struct tcb *tcp, struct sthyi_hypervisor *hdr,
> > + uint16_t size, int num, bool mt)
> > +{
> > + CHECK_SIZE(hdr, size, "hypervisor %d structure", num);
> > +
> > + tprintf("/* hypervisor %d */ ", num);
> > + PRINT_FIELD_0X("{", *hdr, infyflg1);
> > + if (!abbrev(tcp) && hdr->infyflg1)
> > + tprintf_comment("%s%s%s%s%#.0x%s",
> > + hdr->infyflg1 & 0x80 ?
> > + "0x80 - guest CPU usage had limiting is using "
> > + "the consumption method" : "",
> > + (hdr->infyflg1 & 0x80) && (hdr->infyflg1 & 0x40) ?
> > + ", " : "",
> > + hdr->infyflg1 & 0x40 ?
> > + "0x40 - LIMITHARD caps use prorated core time "
> ^^
> Here you have two whitespace characters (instead of one) which cause the
> s390_sthyi-v test to fail.
Uhh, sorry, I've overlooked it (on the other side, that's what are tests
for). I'll resend the patch. Thank you for the report!
|
|
From: Heiko C. <hei...@de...> - 2018-01-22 13:16:57
|
On Thu, Jan 18, 2018 at 07:16:44AM +0100, Eugene Syromyatnikov wrote:
> +static void
> +print_sthyi_hypervisor(struct tcb *tcp, struct sthyi_hypervisor *hdr,
> + uint16_t size, int num, bool mt)
> +{
> + CHECK_SIZE(hdr, size, "hypervisor %d structure", num);
> +
> + tprintf("/* hypervisor %d */ ", num);
> + PRINT_FIELD_0X("{", *hdr, infyflg1);
> + if (!abbrev(tcp) && hdr->infyflg1)
> + tprintf_comment("%s%s%s%s%#.0x%s",
> + hdr->infyflg1 & 0x80 ?
> + "0x80 - guest CPU usage had limiting is using "
> + "the consumption method" : "",
> + (hdr->infyflg1 & 0x80) && (hdr->infyflg1 & 0x40) ?
> + ", " : "",
> + hdr->infyflg1 & 0x40 ?
> + "0x40 - LIMITHARD caps use prorated core time "
^^
Here you have two whitespace characters (instead of one) which cause the
s390_sthyi-v test to fail.
|
|
From: Eugene S. <ev...@gm...> - 2018-01-22 12:51:24
|
* configure.ac (AC_CHECK_FUNCS): Add iconv_open.
(AC_CHECK_HEADERS): Add iconv.h.
* tests/s390_sthyi-v.c: New file.
* tests/s390_sthyi.c: Likewise.
* tests/.gitignore: Add s390_sthyi, s390_sthyi-v.
* tests/pure_executables.list: Likewise.
* tests/gen_tests.in (s390_sthyi, s390_sthyi): New tests.
---
configure.ac | 2 +
tests/.gitignore | 2 +
tests/gen_tests.in | 2 +
tests/pure_executables.list | 2 +
tests/s390_sthyi-v.c | 2 +
tests/s390_sthyi.c | 786 ++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 796 insertions(+)
create mode 100644 tests/s390_sthyi-v.c
create mode 100644 tests/s390_sthyi.c
diff --git a/configure.ac b/configure.ac
index d962f19..001dfa8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -287,6 +287,7 @@ AC_CHECK_FUNCS(m4_normalize([
fstatat
ftruncate
futimens
+ iconv_open
if_indextoname
open64
prctl
@@ -394,6 +395,7 @@ AC_CHECK_HEADERS(m4_normalize([
asm/sysmips.h
bluetooth/bluetooth.h
elf.h
+ iconv.h
inttypes.h
linux/bsg.h
linux/cryptouser.h
diff --git a/tests/.gitignore b/tests/.gitignore
index 4c54589..19aa493 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -357,6 +357,8 @@ rt_sigsuspend
rt_sigtimedwait
rt_tgsigqueueinfo
run_expect_termsig
+s390_sthyi
+s390_sthyi-v
sched_get_priority_mxx
sched_rr_get_interval
sched_xetaffinity
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 93b1687..968f6e4 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -303,6 +303,8 @@ rt_sigreturn -esignal='!USR1'
rt_sigsuspend -a20 -esignal=none
rt_sigtimedwait -a38
rt_tgsigqueueinfo -esignal=none
+s390_sthyi -a47
+s390_sthyi-v -e trace=s390_sthyi -a47
sched test_trace_expr times -e/sched
sched_get_priority_mxx -a33 -e trace=sched_get_priority_min,sched_get_priority_max
sched_rr_get_interval -a31
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 8f5ff31..d8b997d 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -296,6 +296,8 @@ rt_sigreturn
rt_sigsuspend
rt_sigtimedwait
rt_tgsigqueueinfo
+s390_sthyi
+s390_sthyi-v
sched_get_priority_mxx
sched_rr_get_interval
sched_xetaffinity
diff --git a/tests/s390_sthyi-v.c b/tests/s390_sthyi-v.c
new file mode 100644
index 0000000..8605520
--- /dev/null
+++ b/tests/s390_sthyi-v.c
@@ -0,0 +1,2 @@
+#define VERBOSE 1
+#include "s390_sthyi.c"
diff --git a/tests/s390_sthyi.c b/tests/s390_sthyi.c
new file mode 100644
index 0000000..8b241dd
--- /dev/null
+++ b/tests/s390_sthyi.c
@@ -0,0 +1,786 @@
+/*
+ * Check decoding of s390_sthyi syscall.
+ *
+ * Copyright (c) 2018 The strace developers.
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "tests.h"
+#include <asm/unistd.h>
+
+#if defined HAVE_ICONV_H && defined HAVE_ICONV_OPEN && defined __NR_s390_sthyi
+
+# include <errno.h>
+# include <iconv.h>
+# include <inttypes.h>
+# include <stdbool.h>
+# include <stdint.h>
+# include <stdio.h>
+# include <unistd.h>
+
+# include <sys/user.h>
+
+# define EBCDIC_MAX_LEN 16
+
+# ifndef VERBOSE
+# define VERBOSE 0
+# endif
+
+static bool
+print_0x8(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ if (!zero && !buf[offs])
+ return false;
+
+ printf("%s=%#02hhx", prefix, buf[offs]);
+
+ return true;
+}
+
+static bool
+print_u8(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ if (!zero && !buf[offs])
+ return false;
+
+ printf("%s=%hhu", prefix, buf[offs]);
+
+ return true;
+}
+
+static bool
+print_u16(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ uint16_t val = *(uint16_t *) (buf + offs);
+
+ if (!zero && !val)
+ return false;
+
+ printf("%s=%" PRIu16, prefix, val);
+
+ return true;
+}
+
+static bool
+print_x32(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ uint32_t val = *(uint32_t *) (buf + offs);
+
+ if (!zero && !val)
+ return false;
+
+ printf("%s=%#" PRIx32, prefix, val);
+
+ return true;
+}
+
+static bool
+print_weight(const char *prefix, unsigned char *buf, unsigned int offs,
+ bool zero)
+{
+ uint32_t val = *(uint32_t *) (buf + offs);
+
+ if (print_x32(prefix, buf, offs, zero)) {
+ if (val)
+ printf(" /* %u %u/65536 cores */",
+ val >> 16, val & 0xFFFF);
+ else
+ printf(" /* unlimited */");
+
+ return true;
+ }
+
+ return false;
+}
+
+static char *
+ebcdic2ascii(unsigned char *ebcdic, size_t size)
+{
+ static char ascii_buf[EBCDIC_MAX_LEN];
+
+ char *ebcdic_pos = (char *) ebcdic;
+ char *ascii_pos = ascii_buf;
+ size_t ebcdic_left = size;
+ size_t ascii_left = size;
+ size_t ret;
+
+ iconv_t cd = iconv_open("ASCII", "EBCDICUS");
+
+ if (size > sizeof(ascii_buf))
+ error_msg_and_fail("ebcdic2ascii: EBCDIC string is too big: "
+ "%zu (maximum is %zu)",
+ size, sizeof(ascii_buf));
+ if (cd == (iconv_t) -1)
+ perror_msg_and_fail("ebcdic2ascii: unable to allocate a "
+ "conversion descriptior for converting "
+ "EBCDIC to ASCII");
+
+ while ((ret = iconv(cd, &ebcdic_pos, &ebcdic_left,
+ &ascii_pos, &ascii_left)) == (size_t) -1) {
+ switch (errno) {
+ case EILSEQ:
+ case EINVAL: /* That one is quite unexpected, actually */
+ if (!ebcdic_left || !ascii_left)
+ goto ebcdic2ascii_end;
+
+ *ascii_pos++ = ' ';
+ ebcdic_pos++;
+ ebcdic_left--;
+
+ break;
+
+ case E2BIG:
+ perror_msg_and_fail("ebcdic2ascii: ran out of "
+ "ASCII buffer unexpectedly");
+ default:
+ perror_msg_and_fail("ebcdic2ascii: unexpected error");
+ }
+ }
+
+ebcdic2ascii_end:
+ iconv_close(cd);
+
+ if (ebcdic_left != ascii_left)
+ error_msg_and_fail("ebcdic2ascii: ASCII string differs in size "
+ "from EBCDIC");
+
+ return ascii_buf;
+}
+
+# if VERBOSE
+static bool
+is_empty(unsigned char *ptr, size_t size)
+{
+ size_t i;
+
+ for (i = 0; !*ptr && i < size; ptr++, i++)
+ ;
+
+ return i == size;
+}
+# endif /* !VERBOSE */
+
+static bool
+print_ebcdic(const char *prefix, unsigned char *addr, unsigned int offs,
+ size_t size, bool zero, bool blank)
+{
+ const char *ascii = ebcdic2ascii(addr + offs, size);
+
+ if (!zero) {
+ size_t i;
+
+ for (i = 0; (addr[offs + i] == (blank ? 64 : 0)) && (i < size);
+ i++)
+ ;
+
+ if (i == size)
+ return false;
+ }
+
+ printf("%s=", prefix);
+ print_quoted_hex((char *) (addr + offs), size);
+ printf(" /* ");
+ print_quoted_memory(ascii, size);
+ printf(" */");
+
+ return true;
+}
+
+static void
+print_hypervisor_header(unsigned char *buf, int level, unsigned int offs_pos,
+ unsigned int len_pos, bool mt)
+{
+ uint16_t offs = *(uint16_t *) (buf + offs_pos);
+ uint16_t hdr_size = *(uint16_t *) (buf + len_pos);
+ unsigned char *cur;
+
+ if (!offs)
+ return;
+ if (hdr_size < 32)
+ error_msg_and_fail("sthyi: hypervisor %d section is too small "
+ "(got %hu, 32 expected)", level, hdr_size);
+
+ cur = buf + offs;
+
+ printf(", /* hypervisor %d */ {infyflg1", level);
+ print_0x8("", cur, 0, true);
+# if VERBOSE
+ if (cur[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[0] & 0x80) {
+ printf("0x80 - guest CPU usage had limiting is using "
+ "the consumption method");
+ printed = true;
+ }
+ if (cur[0] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - LIMITHARD caps use prorated core time "
+ "for capping");
+ printed = true;
+ }
+ if (cur[0] & 0x3F) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[0] & 0x3F);
+ }
+ printf(" */");
+ }
+
+ print_0x8(", infyflg2", cur, 1, false);
+ print_0x8(", infyval1", cur, 2, false);
+ print_0x8(", infyval2", cur, 3, false);
+
+ print_u8(", infytype", cur, 4, true);
+ if (cur[4] == 1)
+ printf(" /* z/VM is the hypervisor */");
+ else
+ printf(" /* unknown hypervisor type */");
+
+ if (cur[5])
+ printf(", reserved_1__=\"\\x%#02hhx\"", cur[5]);
+
+ print_u8(", infycpt", cur, 6, mt);
+ print_u8(", infyiflt", cur, 7, mt);
+# endif /* !VERBOSE */
+
+ print_ebcdic(", infysyid", cur, 8, 8, VERBOSE, true);
+ print_ebcdic(", infyclnm", cur, 16, 8, VERBOSE, true);
+
+ print_u16(", infyscps", cur, 24, VERBOSE);
+ print_u16(", infydcps", cur, 26, VERBOSE);
+ print_u16(", infysifl", cur, 28, VERBOSE);
+ print_u16(", infydifl", cur, 30, VERBOSE);
+
+# if VERBOSE
+ if (hdr_size > 32 && !is_empty(cur + 32, hdr_size - 32)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 32), hdr_size - 32);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+}
+
+static void
+print_guest_header(unsigned char *buf, int level, unsigned int offs_pos,
+ unsigned int len_pos)
+{
+ uint16_t offs = *(uint16_t *) (buf + offs_pos);
+ uint16_t hdr_size = *(uint16_t *) (buf + len_pos);
+ unsigned char *cur;
+
+ if (!offs)
+ return;
+ if (hdr_size < 56)
+ error_msg_and_fail("sthyi: guest %d section is too small "
+ "(got %hu, 56 expected)", level, hdr_size);
+
+ cur = buf + offs;
+
+ printf(", /* guest %d */ {infgflg1", level);
+ print_0x8("", cur, 0, true);
+# if VERBOSE
+ if (cur[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[0] & 0x80) {
+ printf("0x80 - guest is mobility enabled");
+ printed = true;
+ }
+ if (cur[0] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - guest has multiple virtual CPU types");
+ printed = true;
+ }
+ if (cur[0] & 0x20) {
+ if (printed)
+ printf(", ");
+ printf("0x20 - guest CP dispatch type has LIMITHARD "
+ "cap");
+ printed = true;
+ }
+ if (cur[0] & 0x10) {
+ if (printed)
+ printf(", ");
+ printf("0x10 - guest IFL dispatch type has LIMITHARD "
+ "cap");
+ printed = true;
+ }
+ if (cur[0] & 0x08) {
+ if (printed)
+ printf(", ");
+ printf("0x08 - virtual CPs are thread dispatched");
+ printed = true;
+ }
+ if (cur[0] & 0x04) {
+ if (printed)
+ printf(", ");
+ printf("0x04 - virtual IFLs are thread dispatched");
+ printed = true;
+ }
+ if (cur[0] & 0x3) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[0] & 0x3);
+ }
+ printf(" */");
+ }
+
+ print_0x8(", infgflg2", cur, 1, false);
+ print_0x8(", infgval1", cur, 2, false);
+ print_0x8(", infgval2", cur, 3, false);
+# endif /* !VERBOSE */
+
+ print_ebcdic(", infgusid", cur, 4, 8, true, false);
+
+ print_u16(", infgscps", cur, 12, VERBOSE);
+ print_u16(", infgdcps", cur, 14, VERBOSE);
+
+# if VERBOSE
+ print_u8(", infgcpdt", cur, 16, true);
+ if (cur[16] == 0)
+ printf(" /* General Purpose (CP) */");
+ else
+ printf(" /* unknown */");
+
+ if (cur[17] || cur[18] || cur[19])
+ printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ cur[17], cur[18], cur[19]);
+# endif /* !VERBOSE */
+
+ print_weight(", infgcpcc", cur, 20, VERBOSE);
+
+ print_u16(", infgsifl", cur, 24, VERBOSE);
+ print_u16(", infgdifl", cur, 26, VERBOSE);
+
+# if VERBOSE
+ print_u8(", infgifdt", cur, 28, true);
+ if (cur[28] == 0)
+ printf(" /* General Purpose (CP) */");
+ else if (cur[28] == 3)
+ printf(" /* Integrated Facility for Linux (IFL) */");
+ else
+ printf(" /* unknown */");
+
+ if (cur[29] || cur[30] || cur[31])
+ printf(", reserved_2__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ cur[29], cur[30], cur[31]);
+# endif /* !VERBOSE */
+
+ print_weight(", infgifcc", cur, 32, VERBOSE);
+
+ print_0x8(", infgpflg", cur, 36, true);
+# if VERBOSE
+ if (cur[36]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[36] & 0x80) {
+ printf("0x80 - CPU pool's CP virtual type has "
+ "LIMITHARD cap");
+ printed = true;
+ }
+ if (cur[36] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - CPU pool's CP virtual type has "
+ "CAPACITY cap");
+ printed = true;
+ }
+ if (cur[36] & 0x20) {
+ if (printed)
+ printf(", ");
+ printf("0x20 - CPU pool's IFL virtual type has "
+ "LIMITHARD cap");
+ printed = true;
+ }
+ if (cur[36] & 0x10) {
+ if (printed)
+ printf(", ");
+ printf("0x10 - CPU pool's IFL virtual type has "
+ "CAPACITY cap");
+ printed = true;
+ }
+ if (cur[36] & 0x08) {
+ if (printed)
+ printf(", ");
+ printf("0x08 - CPU pool uses prorated core time");
+ printed = true;
+ }
+ if (cur[36] & 0x7) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[36] & 0x7);
+ }
+ printf(" */");
+ }
+
+ if (cur[37] || cur[38] || cur[39])
+ printf(", reserved_3__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ cur[37], cur[38], cur[39]);
+
+ print_ebcdic(", infgpnam", cur, 40, 8, false, true);
+
+ print_weight(", infgpccc", cur, 48, true);
+ print_weight(", infgpicc", cur, 52, true);
+
+ if (hdr_size > 56 && !is_empty(cur + 56, hdr_size - 56)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 56), hdr_size - 56);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+}
+
+static void
+print_sthyi(unsigned char *buf)
+{
+ unsigned char *cur;
+ uint16_t hdr_size;
+ uint16_t offs;
+ bool mt = false;
+
+ hdr_size = *(uint16_t *) (buf + 10);
+ if (hdr_size < 44)
+ error_msg_and_fail("sthyi: header section is too small "
+ "(got %hu, 44 expected)", hdr_size);
+
+ /* INFHFLG1 */
+ print_0x8("{/* header */ {infhflg1", buf, 0, true);
+# if VERBOSE
+ if (buf[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (buf[0] & 0x80) {
+ printf("0x80 - Global Performance Data unavailable");
+ printed = true;
+ }
+ if (buf[0] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - One or more hypervisor levels below "
+ "this level does not support the STHYI "
+ "instruction");
+ printed = true;
+ }
+ if (buf[0] & 0x20) {
+ if (printed)
+ printf(", ");
+ printf("0x20 - Virtualization stack is incomplete");
+ printed = true;
+ }
+ if (buf[0] & 0x10) {
+ if (printed)
+ printf(", ");
+ printf("0x10 - Execution environment is not within a "
+ "logical partition");
+ printed = true;
+ }
+ if (buf[0] & 0xF) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", buf[0] & 0xF);
+ }
+ printf(" */");
+ }
+
+ print_0x8(", infhflg2", buf, 1, false);
+ print_0x8(", infhval1", buf, 2, false);
+ print_0x8(", infhval2", buf, 3, false);
+
+ /* Reserved */
+ if (buf[4] || buf[5] || buf[6])
+ printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ buf[4], buf[5], buf[6]);
+
+ print_u8(", infhygct", buf, 7, true);
+ print_u16(", infhtotl", buf, 8, true);
+ print_u16(", infhdln", buf, 10, true);
+ print_u16(", infmoff", buf, 12, true);
+ print_u16(", infmlen", buf, 14, true);
+ print_u16(", infpoff", buf, 16, true);
+ print_u16(", infplen", buf, 18, true);
+ print_u16(", infhoff1", buf, 20, true);
+ print_u16(", infhlen1", buf, 22, true);
+ print_u16(", infgoff1", buf, 24, true);
+ print_u16(", infglen1", buf, 26, true);
+ print_u16(", infhoff2", buf, 28, true);
+ print_u16(", infhlen2", buf, 30, true);
+ print_u16(", infgoff2", buf, 32, true);
+ print_u16(", infglen2", buf, 34, true);
+ print_u16(", infhoff3", buf, 36, true);
+ print_u16(", infhlen3", buf, 38, true);
+ print_u16(", infgoff3", buf, 40, true);
+ print_u16(", infglen3", buf, 42, true);
+
+ if (hdr_size > 44 && !is_empty(buf + 44, hdr_size - 44)) {
+ printf(", ");
+ print_quoted_hex((char *) (buf + 44), hdr_size - 44);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+
+ /* Machine header */
+ offs = *(uint16_t *) (buf + 12);
+ if (!offs)
+ goto partition_hdr;
+
+ hdr_size = *(uint16_t *) (buf + 14);
+ if (hdr_size < 60)
+ error_msg_and_fail("sthyi: machine section is too small "
+ "(got %hu, 60 expected)", hdr_size);
+
+ cur = buf + offs;
+
+ printf(", /* machine */ {");
+
+# if VERBOSE
+ print_0x8("infmflg1", cur, 0, false);
+ if (cur[0])
+ printf(", ");
+ print_0x8("infmflg2", cur, 1, false);
+ if (cur[1])
+ printf(", ");
+# endif /* !VERBOSE */
+ print_0x8("infmval1", cur, 2, true);
+
+ bool cnt_valid = cur[2] & 0x80;
+# if VERBOSE
+ bool id_valid = cur[2] & 0x40;
+ bool name_valid = cur[2] & 0x20;
+
+ printf(" /* processor count validity: %d, machine ID validity: %d, "
+ "machine name validity: %d",
+ !!cnt_valid, !!id_valid, !!name_valid);
+ if (cur[2] & 0x1F)
+ printf(", %#hhx - ???", cur[2] & 0x1F);
+ printf(" */");
+ print_0x8(", infmval2", cur, 3, false);
+# endif /* !VERBOSE */
+
+ print_u16(", infmscps", cur, 4, cnt_valid);
+ print_u16(", infmdcps", cur, 6, cnt_valid);
+ print_u16(", infmsifl", cur, 8, cnt_valid);
+ print_u16(", infmdifl", cur, 10, cnt_valid);
+
+# if VERBOSE
+ print_ebcdic(", infmname", cur, 12, 8, name_valid, false);
+
+ print_ebcdic(", infmtype", cur, 20, 4, id_valid, false);
+ print_ebcdic(", infmmanu", cur, 24, 16, id_valid, false);
+ print_ebcdic(", infmseq", cur, 40, 16, id_valid, false);
+ print_ebcdic(", infmpman", cur, 56, 4, id_valid, false);
+
+ if (hdr_size > 60 && !is_empty(cur + 60, hdr_size - 60)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 60), hdr_size - 60);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+
+partition_hdr:
+ /* Partition header */
+ offs = *(uint16_t *) (buf + 16);
+ if (!offs)
+ goto hv_hdr;
+
+ hdr_size = *(uint16_t *) (buf + 18);
+ if (hdr_size < 56)
+ error_msg_and_fail("sthyi: partition section is too small "
+ "(got %hu, 56 expected)", hdr_size);
+
+ cur = buf + offs;
+
+ print_0x8(", /* partition */ {infpflg1", cur, 0, true);
+ mt = !!(cur[0] & 0x80);
+# if VERBOSE
+ if (cur[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[0] & 0x80) {
+ printf("0x80 - multithreading is enabled");
+ printed = true;
+ }
+ if (cur[0] & 0x7F) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[0] & 0x7F);
+ }
+ printf(" */");
+ }
+ print_0x8(", infpflg2", cur, 1, false);
+# endif /* !VERBOSE */
+ print_0x8(", infpval1", cur, 2, true);
+
+ bool pcnt_valid = cur[2] & 0x80;
+ bool pid_valid = cur[2] & 0x10;
+# if VERBOSE
+ bool pwcap_valid = cur[2] & 0x40;
+ bool pacap_valid = cur[2] & 0x20;
+ bool lpar_valid = cur[2] & 0x08;
+# endif /* !VERBOSE */
+
+# if VERBOSE
+ printf(" /* processor count validity: %d, partition weight-based "
+ "capacity validity: %d, partition absolute capacity validity: "
+ "%d, partition ID validity: %d, LPAR group absolute capacity "
+ "capping information validity: %d",
+ !!pcnt_valid, !!pwcap_valid, !!pacap_valid, !!pid_valid,
+ !!lpar_valid);
+ if (cur[2] & 0x7)
+ printf(", %#hhx - ???", cur[2] & 0x7);
+ printf(" */");
+
+ print_0x8(", infpval2", cur, 3, false);
+# endif /* !VERBOSE */
+
+ print_u16(", infppnum", cur, 4, pid_valid);
+
+ print_u16(", infpscps", cur, 6, pcnt_valid);
+ print_u16(", infpdcps", cur, 8, pcnt_valid);
+ print_u16(", infpsifl", cur, 10, pcnt_valid);
+ print_u16(", infpdifl", cur, 12, pcnt_valid);
+
+# if VERBOSE
+ if (cur[14] || cur[15])
+ printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\"",
+ cur[14], cur[15]);
+# endif /* !VERBOSE */
+
+ print_ebcdic(", infppnam", cur, 16, 8, pid_valid, false);
+
+# if VERBOSE
+ print_weight(", infpwbcp", cur, 24, pwcap_valid);
+ print_weight(", infpabcp", cur, 28, pacap_valid);
+ print_weight(", infpwbif", cur, 32, pwcap_valid);
+ print_weight(", infpabif", cur, 36, pacap_valid);
+
+ if (print_ebcdic(", infplgnm", cur, 40, 8, false, false)) {
+
+ print_weight(", infplgcp", cur, 48, false);
+ print_weight(", infplgif", cur, 52, false);
+ } else {
+ if (lpar_valid) {
+ printf(", infplgnm=");
+ print_quoted_hex((char *) (cur + 40), 8);
+ }
+
+ print_x32(", infplgcp", cur, 48, false);
+ print_x32(", infplgif", cur, 52, false);
+ }
+
+ if (hdr_size > 56 && !is_empty(cur + 56, hdr_size - 56)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 56), hdr_size - 56);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+
+hv_hdr:
+ /* Hypervisor/guest headers */
+ print_hypervisor_header(buf, 1, 20, 22, mt);
+ print_guest_header(buf, 1, 24, 26);
+ print_hypervisor_header(buf, 2, 28, 30, mt);
+ print_guest_header(buf, 2, 32, 34);
+ print_hypervisor_header(buf, 3, 36, 38, mt);
+ print_guest_header(buf, 3, 40, 42);
+
+ printf("}");
+}
+
+int
+main(void)
+{
+ static const kernel_ulong_t bogus_func =
+ (kernel_ulong_t) 0xdeafbeefdeadc0deULL;
+ static const kernel_ulong_t bogus_resp_buf =
+ (kernel_ulong_t) 0xfacefeedac0ffeedULL;
+ static const kernel_ulong_t bogus_ret_code =
+ (kernel_ulong_t) 0xf00dfa57decaffedULL;
+ static const kernel_ulong_t bogus_flags =
+ (kernel_ulong_t) 0xfee1deadfa57beefULL;
+
+ unsigned char *buf = tail_alloc(PAGE_SIZE);
+ uint64_t *ret = tail_alloc(sizeof(*ret));
+
+ long rc;
+
+ rc = syscall(__NR_s390_sthyi, 0, 0, 0, 0);
+ printf("s390_sthyi(STHYI_FC_CP_IFL_CAP, NULL, NULL, 0) = %s\n",
+ sprintrc(rc));
+
+ rc = syscall(__NR_s390_sthyi, bogus_func, bogus_resp_buf,
+ bogus_ret_code, bogus_flags);
+ printf("s390_sthyi(%#llx /* STHYI_FC_??? */, %#llx, %#llx, %#llx) = "
+ "%s\n",
+ (unsigned long long) bogus_func,
+ (unsigned long long) bogus_resp_buf,
+ (unsigned long long) bogus_ret_code,
+ (unsigned long long) bogus_flags,
+ sprintrc(rc));
+
+ rc = syscall(__NR_s390_sthyi, bogus_func, buf, ret, 0);
+ printf("s390_sthyi(%#llx /* STHYI_FC_??? */, %p, %p, 0) = %s\n",
+ (unsigned long long) bogus_func, buf, ret, sprintrc(rc));
+
+ rc = syscall(__NR_s390_sthyi, 0, buf, ret, 0);
+ if (rc)
+ error_msg_and_fail("syscall(__NR_s390_sthyi, 0, buf, ret, 0) "
+ "returned unexpected value of %ld", rc);
+
+ printf("s390_sthyi(STHYI_FC_CP_IFL_CAP, ");
+ print_sthyi(buf);
+ printf(", [0], 0) = 0\n");
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("HAVE_ICONV_H && HAVE_ICONV_OPEN && __NR_s390_sthyi")
+
+#endif
--
2.1.4
|
|
From: Eugene S. <es...@re...> - 2018-01-22 12:48:15
|
On Sat, Jan 20, 2018 at 12:23:23PM +0100, Heiko Carstens wrote:
> On Thu, Jan 18, 2018 at 07:16:31AM +0100, Eugene Syromyatnikov wrote:
> > Hello.
> >
> > This patch set introduces compat personality support on s390x along with
> > decoders of s390-specific system calls.
> >
> > Unfortunately, I am no s390 expert by any means, so I likely have missed
> > something. I also have little idea regarding applications where these
> > s390-specific system calls are used, so the feedback regarding quality
> > of the decoders is also welcome.
>
> Looks all good to me. However the s390_sthyi test case fails:
>
> -s390_sthyi(STHYI_FC_CP_IFL_CAP, {/* header */ {infhflg1=00, ...}, /* machine */ {infmval1=0xf0, infmscps=2, infmdcps=0, infmsifl=90, infmdifl=2, ...}, /* partition */ {infpflg1=0x80, infpval1=0xfc, infppnum=63, infpscps=0, infpdcps=0, infpsifl=32, infpdifl=0, infppnam="\xe2\xf8\xf3\xd3\xd7\xf6\xf0\x40" /* "S83LP60 " */, ...}, /* hypervisor 1 */ {infyflg1=0xc0, infycpt=1, infyiflt=2, infysyid="\xc2\xd6\xc5\xe2\xf8\xf3\xf6\xf0" /* "BOES8360" */, infysifl=32, ...}, /* guest 1 */ {infgflg1=0x4, infgusid="\xe2\xf8\xf3\xf6\xf0\xf0\xf1\xf6" /* "S8360016" */, infgsifl=6, infgpflg=00, ...}}, [0], 0) = 0
> +s390_sthyi(STHYI_FC_CP_IFL_CAP, {/* header */ {infhflg1=00, ...}, /* machine */ {infmval1=0xf0, infmscps=2, infmdcps=0, infmsifl=90, infmdifl=2, ...}, /* partition */ {infpflg1=0x80, infpval1=0xfc, infppnum=63, infpscps=0, infpdcps=0, infpsifl=32, infpdifl=0, infppnam="\xe2\xf8\xf3\xd3\xd7\xf6\xf0\x40" /* "S83LP60 " */, ...}, /* hypervisor 1 */ {infyflg1=0xc0, infysyid="\xc2\xd6\xc5\xe2\xf8\xf3\xf6\xf0" /* "BOES8360" */, infysifl=32, ...}, /* guest 1 */ {infgflg1=0x4, infgusid="\xe2\xf8\xf3\xf6\xf0\xf0\xf1\xf6" /* "S8360016" */, infgsifl=6, infgpflg=00, ...}}, [0], 0) = 0
> +++ exited with 0 +++
> s390_sthyi.gen.test: failed test: ../../strace -e trace=s390_sthyi -a47 ../s390_sthyi output mismatch
Thank you for the report! Unfortunately, when I decided that
infycpt/infyiflt aren't that important for abbreviated output, I forgot
to update the test, and the lack of MT-enabled hardware didn't allow me
to catch it early. I'll resend the patch with the fixed test.
|
|
From: Eugene S. <ev...@gm...> - 2018-01-22 12:17:58
|
* tests/riscv_flush_icache.c: New file.
* tests/.gitignore: Add riscv_flush_icache.
* tests/gen_tests.in: Likewise.
* tests/pure_executables.list: Likewise.
---
tests/.gitignore | 1 +
tests/gen_tests.in | 1 +
tests/pure_executables.list | 1 +
tests/riscv_flush_icache.c | 93 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 96 insertions(+)
create mode 100644 tests/riscv_flush_icache.c
diff --git a/tests/.gitignore b/tests/.gitignore
index 4c54589..2a95c6c 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -347,6 +347,7 @@ renameat
renameat2
request_key
restart_syscall
+riscv_flush_icache
rmdir
rt_sigaction
rt_sigpending
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 93b1687..7ede93b 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -295,6 +295,7 @@ rename -a35
renameat
renameat2
request_key -a33 -s12
+riscv_flush_icache -a34
rmdir -a22
rt_sigpending -a20
rt_sigprocmask
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 8f5ff31..710d76e 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -287,6 +287,7 @@ rename
renameat
renameat2
request_key
+riscv_flush_icache
rmdir
rt_sigaction
rt_sigpending
diff --git a/tests/riscv_flush_icache.c b/tests/riscv_flush_icache.c
new file mode 100644
index 0000000..8aaeda5
--- /dev/null
+++ b/tests/riscv_flush_icache.c
@@ -0,0 +1,93 @@
+/*
+ * Check decoding of riscv_flush_icache syscall.
+ *
+ * Copyright (c) 2018 The strace developers.
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#include "scno.h"
+
+#ifdef __NR_riscv_flush_icache
+
+# include <stdint.h>
+# include <stdio.h>
+# include <unistd.h>
+
+int main(void)
+{
+ static struct {
+ kernel_ulong_t addr;
+ const char *str;
+ } addrs[] = {
+ { (kernel_ulong_t) (uintptr_t) ARG_STR(NULL) },
+ { (kernel_ulong_t) 0xbadc0deddeadf157ULL,
+ sizeof(kernel_ulong_t) == 8 ? "0xbadc0deddeadf157" :
+ "0xdeadf157" },
+ };
+ static struct {
+ kernel_ulong_t val;
+ const char *str;
+ } flags[] = {
+ { ARG_STR(0) },
+ { 1, "SYS_RISCV_FLUSH_ICACHE_LOCAL" },
+ { (kernel_ulong_t) 0xfacefeedfffffffeULL,
+ sizeof(kernel_ulong_t) == 8 ?
+ "0xfacefeedfffffffe /* SYS_RISCV_FLUSH_ICACHE_??? */" :
+ "0xfffffffe /* SYS_RISCV_FLUSH_ICACHE_??? */" },
+ { (kernel_ulong_t) 0xfacefeedffffffffULL,
+ sizeof(kernel_ulong_t) == 8 ?
+ "SYS_RISCV_FLUSH_ICACHE_LOCAL|0xfacefeedfffffffe" :
+ "SYS_RISCV_FLUSH_ICACHE_LOCAL|0xfffffffe" },
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(addrs); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(addrs); j++) {
+ for (size_t k = 0; k < ARRAY_SIZE(flags); k++) {
+ long rc = syscall(__NR_riscv_flush_icache,
+ addrs[i].addr,
+ addrs[j].addr,
+ flags[k].val);
+
+ printf("riscv_flush_icache(%s, %s, %s) = %s\n",
+ addrs[i].str, addrs[j].str, flags[k].str,
+ sprintrc(rc));
+ }
+ }
+ }
+
+ puts("+++ exited with 0 +++");
+
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_riscv_flush_icache");
+
+#endif
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-22 12:17:55
|
* linux/riscv/syscallent.h ([259]): Add riscv_flush_icache entry.
* riscv.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* xlat/riscv_flush_icache_flags.in: New file.
* NEWS: Mention it.
---
Makefile.am | 1 +
NEWS | 1 +
linux/riscv/syscallent.h | 3 +++
riscv.c | 53 ++++++++++++++++++++++++++++++++++++++++
xlat/riscv_flush_icache_flags.in | 1 +
5 files changed, 59 insertions(+)
create mode 100644 riscv.c
create mode 100644 xlat/riscv_flush_icache_flags.in
diff --git a/Makefile.am b/Makefile.am
index db822c5..f8061df 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -253,6 +253,7 @@ strace_SOURCES = \
regs.h \
renameat.c \
resource.c \
+ riscv.c \
rt_sigframe.c \
rt_sigreturn.c \
rtc.c \
diff --git a/NEWS b/NEWS
index c1ff7b0..e0f3eb9 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Noteworthy changes in release ?.?? (????-??-??)
* Enhanced decoding of get_thread_area, memfd_create, modify_ldt,
perf_event_open, reboot, set_thread_area, and shmget syscalls.
* Implemented decoding of KVM_* and DM_LIST_DEVICES ioctl commands.
+ * Implemented decoding of riscv_flush_icache syscall.
* Enhanced decoding of getsockopt and setsockopt syscalls for SOL_NETLINK
level.
* Enhanced decoding of BPF_MAP_CREATE command of bpf syscall.
diff --git a/linux/riscv/syscallent.h b/linux/riscv/syscallent.h
index 7c416ef..3dfed89 100644
--- a/linux/riscv/syscallent.h
+++ b/linux/riscv/syscallent.h
@@ -1 +1,4 @@
#include "64/syscallent.h"
+
+/* #define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15) */
+[259] = { 3, TM, SEN(riscv_flush_icache), "riscv_flush_icache" },
diff --git a/riscv.c b/riscv.c
new file mode 100644
index 0000000..aaa3932
--- /dev/null
+++ b/riscv.c
@@ -0,0 +1,53 @@
+/*
+ * RISC-V-specific syscall decoders.
+ *
+ * Copyright (c) 2018 The strace developers.
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "defs.h"
+
+#ifdef RISCV
+
+# include "xlat/riscv_flush_icache_flags.h"
+
+SYS_FUNC(riscv_flush_icache)
+{
+ /* uintptr_t start */
+ printaddr(tcp->u_arg[0]);
+
+ /* uintptr_t end */
+ tprints(", ");
+ printaddr(tcp->u_arg[1]);
+
+ /* uintptr_t flags */
+ tprints(", ");
+ printflags64(riscv_flush_icache_flags, tcp->u_arg[2],
+ "SYS_RISCV_FLUSH_ICACHE_???");
+
+ return RVAL_DECODED;
+}
+
+#endif /* RISCV */
diff --git a/xlat/riscv_flush_icache_flags.in b/xlat/riscv_flush_icache_flags.in
new file mode 100644
index 0000000..173da07
--- /dev/null
+++ b/xlat/riscv_flush_icache_flags.in
@@ -0,0 +1 @@
+SYS_RISCV_FLUSH_ICACHE_LOCAL 1
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-21 21:16:27
|
Some old systems that still make some sense to be supported have only
gawk 3, so let's support them for now.
In order to achieve that, multiple changes have been implemented:
- Multidimensional arrays are replaced with single-dimensional ones.
In most places it's a "][" -> ", " replacement, as awk allows some
kind of emulation of multidimensional arrays that way, but in several
occasions (specifically for storing name and special fields) we have
to iterate over them later, so we store that information in
additional arrays in order to get the keys.
- "switch" statements are replaced with sets of "if ... else if ...
else" statements. This change is trivial, except we've added
a temporary variable in what_is order to store expression value, for
readability purposes.
- No support for array iteration ordering. This one is most ugly of
them all. Luckily, not that ugly, we've just had to process index a
bit in order to make it lexicographically sortable and add two
temporary arrays containing sorted indices in order to sort over them
instead of those two arrays that we've added in order to work around
lack of multidimensional array support.
* mpers.awk (compare_indices): Remove unused function.
(array_get, update_upper_bound, /^DW_AT_data_member_location/,
/^DW_AT_byte_size/, /^DW_AT_encoding/): Replace multidimensional array
access with comma-concatenated index.
(norm_idx): New function.
(array_seq): Replace multidimensional array access with
comma-concatenated index. Use comma-concatenated pair of (array_idx,
"seq") in order to check presence of the item in an array.
(what_is): Add enc and i local variables. Store the value of
array[what_idx, "encoding"] in it. Replace "switch" statements with
sets of "if ... else if ... else" statements. Replace multidimensional
array access with comma-concatenated index. Use for (... ; ...; ...)
iteration over aparents_keys instead of iteration over array.
(/^<[[:xdigit:]]+>/): Store idx as norm_idx(matches[2]). Replace
multidimensional array access with comma-concatenated index. Store an
additional flag in array_names array.
(/^DW_AT_name/): Replace multidimensional array access with
comma-concatenated index. Add a flag to array_names for that idx.
(/^DW_AT_type/): Do not capture "0x" as a part of a group, normalise
the captured group. Replace multidimensional array access with
comma-concatenated index.
(/^Abbrev Number:[^(]+\(DW_TAG_/): Replace multidimensional array access
with comma-concatenated index. Store additional flags in
array_special and array_parents arrays.
(END): Remove PROCINFO["sorted_in"] setup. Sort array_parents. Replace
multidimensional array access with comma-concatenated index. Iterate
over array_special to go over all the items that have "special" field.
Iterate over array_names to go over all items that have "name" field.
---
mpers.awk | 129 +++++++++++++++++++++++++++-----------------------------------
1 file changed, 56 insertions(+), 73 deletions(-)
diff --git a/mpers.awk b/mpers.awk
index 9f8cb64..0d0ffb2 100644
--- a/mpers.awk
+++ b/mpers.awk
@@ -27,19 +27,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-function compare_indices(i1, v1, i2, v2, \
- c1, c2)
-{
- c1 = strtonum(sprintf("%s", i1))
- c2 = strtonum(sprintf("%s", i2))
- if (c1 < c2)
- return -1
- return (c1 != c2)
-}
function array_get(array_idx, array_member, \
array_return)
{
- array_return = array[array_idx][array_member]
+ array_return = array[array_idx, array_member]
if ("" == array_return) {
printf("%s: index [%s] without %s\n",
FILENAME, array_idx, array_member) > "/dev/stderr"
@@ -47,12 +38,16 @@ function array_get(array_idx, array_member, \
}
return array_return
}
+function norm_idx(idx)
+{
+ return sprintf("%016s", idx)
+}
function array_seq(array_idx)
{
- if ("seq" in array[array_idx])
- return array[array_idx]["seq"]
+ if ((array_idx, "seq") in array)
+ return array[array_idx, "seq"]
index_seq++
- array[array_idx]["seq"] = index_seq
+ array[array_idx, "seq"] = index_seq
return index_seq
}
function enter(array_idx,
@@ -75,72 +70,63 @@ function leave(array_idx, to_return)
function update_upper_bound(idx, val, \
count)
{
- count = array[idx]["count"]
+ count = array[idx, "count"]
if (count == "")
count = 1
- array[idx]["count"] = count * val
- array[idx]["upper_bound"] = array[idx]["upper_bound"] "[" val "]"
+ array[idx, "count"] = count * val
+ array[idx, "upper_bound"] = array[idx, "upper_bound"] "[" val "]"
}
function what_is(what_idx, \
item, loc_diff, location, prev_location, prev_returned_size, \
- special, to_return, type_idx)
+ special, to_return, type_idx, enc, i)
{
enter(what_idx)
special = array_get(what_idx, "special")
- switch (special) {
- case "base_type":
- switch (array_get(what_idx, "encoding")) {
- case 5: # signed
+ if (special == "base_type") {
+ enc = array_get(what_idx, "encoding")
+ if (enc == 5) { # signed
printf("int%s_t ",
8 * array_get(what_idx, "byte_size"))
- break
- case 7: # unsigned
+ } else if (enc == 7) { # unsigned
printf("uint%s_t ",
8 * array_get(what_idx, "byte_size"))
- break
- default: # float, signed/unsigned char
+ } else { # float, signed/unsigned char
printf("%s ", array_get(what_idx, "name"))
- break
}
returned_size = array_get(what_idx, "byte_size")
- break
- case "enumeration_type":
+ } else if (special == "enumeration_type") {
returned_size = array_get(what_idx, "byte_size")
printf("uint%s_t ", 8 * returned_size)
- break
- case "pointer_type":
+ } else if (special == "pointer_type") {
printf("mpers_ptr_t ")
returned_size = array_get(what_idx, "byte_size")
- break
- case "array_type":
+ } else if (special == "array_type") {
type_idx = array_get(what_idx, "type")
what_is(type_idx)
- to_return = array[what_idx]["upper_bound"]
+ to_return = array[what_idx, "upper_bound"]
if ("" == to_return)
to_return = "[0]"
- returned_size = array[what_idx]["count"] * returned_size
+ returned_size = array[what_idx, "count"] * returned_size
return leave(what_idx, to_return)
- break
- case "structure_type":
+ } else if (special == "structure_type") {
print "struct {"
prev_location = 0
location = 0
returned_size = 0
prev_returned_size = 0
- for (item in array) {
- if ("parent" in array[item] && \
- array_get(item, "parent") == what_idx) {
- location = array_get(item, "location")
+ for (i = 1; i <= parents_cnt; i += 1) {
+ if (array_parents[aparents_keys[i]] == what_idx) {
+ location = array_get(aparents_keys[i], "location")
loc_diff = location - prev_location - \
prev_returned_size
if (loc_diff != 0) {
printf("unsigned char mpers_%s_%s[%s];\n",
- "filler", array_seq(item), loc_diff)
+ "filler", array_seq(aparents_keys[i]), loc_diff)
}
prev_location = location
- returned = what_is(item)
+ returned = what_is(aparents_keys[i])
prev_returned_size = returned_size
- printf("%s%s;\n", array[item]["name"], returned)
+ printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
}
}
returned_size = array_get(what_idx, "byte_size")
@@ -150,31 +136,25 @@ function what_is(what_idx, \
"end_filler", array_seq(item), loc_diff)
}
printf("} ATTRIBUTE_PACKED ")
- break
- case "union_type":
+ } else if (special == "union_type") {
print "union {"
- for (item in array) {
- if ("parent" in array[item] && \
- array_get(item, "parent") == what_idx) {
- returned = what_is(item)
- printf("%s%s;\n", array[item]["name"], returned)
+ for (i = 1; i <= parents_cnt; i += 1) {
+ if (array_parents[aparents_keys[i]] == what_idx) {
+ returned = what_is(aparents_keys[i])
+ printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
}
}
printf("} ")
returned_size = array_get(what_idx, "byte_size")
- break
- case "typedef":
+ } else if (special == "typedef") {
type_idx = array_get(what_idx, "type")
return leave(what_idx, what_is(type_idx))
- break
- case "member":
+ } else if (special == "member") {
type_idx = array_get(what_idx, "type")
return leave(what_idx, what_is(type_idx))
- break
- default:
+ } else {
type_idx = array_get(what_idx, "type")
what_is(type_idx)
- break
}
return leave(what_idx, "")
}
@@ -186,31 +166,32 @@ BEGIN {
/^<[[:xdigit:]]+>/ {
match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
level = matches[1]
- idx = "0x" matches[2]
- array[idx]["idx"] = idx
+ idx = norm_idx(matches[2])
+ array[idx, "idx"] = idx
parent[level] = idx
}
/^DW_AT_data_member_location/ {
if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
match($0, /([[:digit:]]+)/, temparray)
- array[idx]["location"] = temparray[1]
+ array[idx, "location"] = temparray[1]
}
/^DW_AT_name/ {
match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
temparray)
- array[idx]["name"] = temparray[1]
+ array_names[idx] = 1
+ array[idx, "name"] = temparray[1]
}
/^DW_AT_byte_size/ {
match($0, /[[:digit:]]+/, temparray)
- array[idx]["byte_size"] = temparray[0]
+ array[idx, "byte_size"] = temparray[0]
}
/^DW_AT_encoding/ {
match($0, /[[:digit:]]+/, temparray)
- array[idx]["encoding"] = temparray[0]
+ array[idx, "encoding"] = temparray[0]
}
/^DW_AT_type/ {
- match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
- array[idx]["type"] = temparray[1]
+ match($0, /:[[:space:]]+<0x([[:xdigit:]]*)>$/, temparray)
+ array[idx, "type"] = norm_idx(temparray[1])
}
/^DW_AT_upper_bound/ {
match($0, /[[:digit:]]+/, temparray)
@@ -223,17 +204,19 @@ BEGIN {
/^Abbrev Number:[^(]+\(DW_TAG_/ {
if (match($0, /typedef|union_type|structure_type|pointer_type\
|enumeration_type|array_type|base_type|member/, temparray)) {
- array[idx]["special"] = temparray[0]
+ array_special[idx] = temparray[0]
+ array[idx, "special"] = temparray[0]
if ("pointer_type" == temparray[0])
- array[idx]["byte_size"] = default_pointer_size
+ array[idx, "byte_size"] = default_pointer_size
if (level > 1 && "member" == temparray[0])
- array[idx]["parent"] = parent[level-1]
+ array_parents[idx] = parent[level-1]
}
}
END {
- PROCINFO["sorted_in"] = "compare_indices"
- for (item in array) {
- if (array[item]["special"] == "pointer_type") {
+ parents_cnt = asorti(array_parents, aparents_keys)
+
+ for (item in array_special) {
+ if (array[item, "special"] == "pointer_type") {
mpers_ptr_t = \
"uint" 8 * array_get(item, "byte_size") "_t"
print "#ifndef mpers_ptr_t_is_" mpers_ptr_t
@@ -243,8 +226,8 @@ END {
break
}
}
- for (item in array) {
- if (array[item]["name"] == VAR_NAME) {
+ for (item in array_names) {
+ if (array[item, "name"] == VAR_NAME) {
type = array_get(item, "type")
print "typedef"
what_is(type)
--
2.1.4
|
|
From: Dmitry V. L. <ld...@al...> - 2018-01-20 13:53:37
|
On Thu, Jan 18, 2018 at 10:41:54AM +0100, Eugene Syromyatnikov wrote:
> Some old systems that still make some sense to be supported have only
> gawk 3, so let's support them for now.
>
> In order to achieve that, multiple changes have been implemented:
> - Multidimensional arrays are replaced with single-dimensional ones.
> In most places it's a "][" -> ", " replacement, as awk allows some
> kind of emulation of multidimensional arrays that way, but in several
> occasions (specifically for storing name and special fields) we have
> to iterate over them later, so we store that information in
> additional arrays in order to get the keys.
> - "switch" statements are replaced with sets of "if ... else if ...
> else" statements. This change is trivial, except we've added
> a temporary variable in what_is order to store expression value, for
> readability purposes.
> - No support for array iteration ordering. This one is most ugly of
> them all. Luckily, not that ugly, we've just had to process index a
> bit in order to make it lexicographically sortable and add two
> temporary arrays containing sorted indices in order to sort over them
> instead of those two arrays that we've added in order to work around
> lack of multidimensional array support.
>
> * mpers.awk (compare_indices): Remove unused function.
> (array_get, update_upper_bound, /^DW_AT_data_member_location/,
> /^DW_AT_byte_size/, /^DW_AT_encoding/): Replace multidimensional array
> access with comma-concatenated index.
> (norm_idx): New function.
> (array_seq): Replace multidimensional array access with
> comma-concatenated index. Use comma-concatenated pair of (array_idx,
> "seq") in order to check presence of the item in an array.
> (what_is): Add enc local variable. Store the value of array[what_idx,
> "encoding"] in it. Replace "switch" statements with sets of "if ...
> else if ... else" statements. Replace multidimensional array access
> with comma-concatenated index. Use for (... ; ...; ...) iteration over
> aparents_sorted instead of iteration over array.
> (/^<[[:xdigit:]]+>/): Store idx as norm_idx(matches[2]). Replace
> multidimensional array access with comma-concatenated index. Store an
> additional flag in array_names array.
> (/^DW_AT_name/): Replace multidimensional array access with
> comma-concatenated index. Add a flag to array_names for that idx.
> (/^DW_AT_type/): Do not capture "0x" as a part of a group, normalise
> the captured group. Replace multidimensional array access with
> comma-concatenated index.
> (/^Abbrev Number:[^(]+\(DW_TAG_/): Replace multidimensional array access
> with comma-concatenated index. Store additional flags in
> array_special and array_parents arrays.
> (END): Remove PROCINFO["sorted_in"] setup. Sort array_parents. Replace
> multidimensional array access with comma-concatenated index. Iterate
> over array_special to go over all the items that have "special" field.
> Iterate over array_names to go over all items that have "name" field.
> ---
> mpers.awk | 129 +++++++++++++++++++++++++++-----------------------------------
> 1 file changed, 56 insertions(+), 73 deletions(-)
>
> diff --git a/mpers.awk b/mpers.awk
> index 9f8cb64..9359004 100644
> --- a/mpers.awk
> +++ b/mpers.awk
> @@ -27,19 +27,10 @@
> # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>
> -function compare_indices(i1, v1, i2, v2, \
> - c1, c2)
> -{
> - c1 = strtonum(sprintf("%s", i1))
> - c2 = strtonum(sprintf("%s", i2))
> - if (c1 < c2)
> - return -1
> - return (c1 != c2)
> -}
> function array_get(array_idx, array_member, \
> array_return)
> {
> - array_return = array[array_idx][array_member]
> + array_return = array[array_idx, array_member]
> if ("" == array_return) {
> printf("%s: index [%s] without %s\n",
> FILENAME, array_idx, array_member) > "/dev/stderr"
> @@ -47,12 +38,16 @@ function array_get(array_idx, array_member, \
> }
> return array_return
> }
> +function norm_idx(idx)
> +{
> + return sprintf("%016s", idx)
> +}
> function array_seq(array_idx)
> {
> - if ("seq" in array[array_idx])
> - return array[array_idx]["seq"]
> + if ((array_idx, "seq") in array)
> + return array[array_idx, "seq"]
> index_seq++
> - array[array_idx]["seq"] = index_seq
> + array[array_idx, "seq"] = index_seq
> return index_seq
> }
> function enter(array_idx,
> @@ -75,72 +70,63 @@ function leave(array_idx, to_return)
> function update_upper_bound(idx, val, \
> count)
> {
> - count = array[idx]["count"]
> + count = array[idx, "count"]
> if (count == "")
> count = 1
> - array[idx]["count"] = count * val
> - array[idx]["upper_bound"] = array[idx]["upper_bound"] "[" val "]"
> + array[idx, "count"] = count * val
> + array[idx, "upper_bound"] = array[idx, "upper_bound"] "[" val "]"
> }
> function what_is(what_idx, \
> item, loc_diff, location, prev_location, prev_returned_size, \
> - special, to_return, type_idx)
> + special, to_return, type_idx, enc)
> {
> enter(what_idx)
> special = array_get(what_idx, "special")
> - switch (special) {
> - case "base_type":
> - switch (array_get(what_idx, "encoding")) {
> - case 5: # signed
> + if (special == "base_type") {
> + enc = array_get(what_idx, "encoding")
> + if (enc == 5) { # signed
> printf("int%s_t ",
> 8 * array_get(what_idx, "byte_size"))
> - break
> - case 7: # unsigned
> + } else if (enc == 7) { # unsigned
> printf("uint%s_t ",
> 8 * array_get(what_idx, "byte_size"))
> - break
> - default: # float, signed/unsigned char
> + } else { # float, signed/unsigned char
> printf("%s ", array_get(what_idx, "name"))
> - break
> }
> returned_size = array_get(what_idx, "byte_size")
> - break
> - case "enumeration_type":
> + } else if (special == "enumeration_type") {
> returned_size = array_get(what_idx, "byte_size")
> printf("uint%s_t ", 8 * returned_size)
> - break
> - case "pointer_type":
> + } else if (special == "pointer_type") {
> printf("mpers_ptr_t ")
> returned_size = array_get(what_idx, "byte_size")
> - break
> - case "array_type":
> + } else if (special == "array_type") {
> type_idx = array_get(what_idx, "type")
> what_is(type_idx)
> - to_return = array[what_idx]["upper_bound"]
> + to_return = array[what_idx, "upper_bound"]
> if ("" == to_return)
> to_return = "[0]"
> - returned_size = array[what_idx]["count"] * returned_size
> + returned_size = array[what_idx, "count"] * returned_size
> return leave(what_idx, to_return)
> - break
> - case "structure_type":
> + } else if (special == "structure_type") {
> print "struct {"
> prev_location = 0
> location = 0
> returned_size = 0
> prev_returned_size = 0
> - for (item in array) {
> - if ("parent" in array[item] && \
> - array_get(item, "parent") == what_idx) {
> - location = array_get(item, "location")
> + for (item = 1; item <= parents_cnt; item+=1) {
This is no longer an item, it's an index.
> + if (array_parents[aparents_sorted[item]] == what_idx) {
aparents_sorted is not a sorted array array_parents, it's an array
of sorted keys of array_parents, let's call it aparents_keys or something.
> + location = array_get(aparents_sorted[item], "location")
> loc_diff = location - prev_location - \
> prev_returned_size
> if (loc_diff != 0) {
> printf("unsigned char mpers_%s_%s[%s];\n",
> - "filler", array_seq(item), loc_diff)
> + "filler", array_seq(aparents_sorted[item]), loc_diff)
> }
> prev_location = location
> - returned = what_is(item)
> + returned = what_is(aparents_sorted[item])
> prev_returned_size = returned_size
> - printf("%s%s;\n", array[item]["name"], returned)
> + printf("%s%s;\n", array[aparents_sorted[item], "name"], returned)
> }
> }
> returned_size = array_get(what_idx, "byte_size")
> @@ -150,31 +136,25 @@ function what_is(what_idx, \
> "end_filler", array_seq(item), loc_diff)
> }
> printf("} ATTRIBUTE_PACKED ")
> - break
> - case "union_type":
> + } else if (special == "union_type") {
> print "union {"
> - for (item in array) {
> - if ("parent" in array[item] && \
> - array_get(item, "parent") == what_idx) {
> - returned = what_is(item)
> - printf("%s%s;\n", array[item]["name"], returned)
> + for (item = 1; item <= parents_cnt; item+=1) {
This is no longer an item, it's an index.
> + if (array_parents[aparents_sorted[item]] == what_idx) {
> + returned = what_is(aparents_sorted[item])
> + printf("%s%s;\n", array[aparents_sorted[item], "name"], returned)
> }
> }
> printf("} ")
> returned_size = array_get(what_idx, "byte_size")
> - break
> - case "typedef":
> + } else if (special == "typedef") {
> type_idx = array_get(what_idx, "type")
> return leave(what_idx, what_is(type_idx))
> - break
> - case "member":
> + } else if (special == "member") {
> type_idx = array_get(what_idx, "type")
> return leave(what_idx, what_is(type_idx))
> - break
> - default:
> + } else {
> type_idx = array_get(what_idx, "type")
> what_is(type_idx)
> - break
> }
> return leave(what_idx, "")
> }
> @@ -186,31 +166,32 @@ BEGIN {
> /^<[[:xdigit:]]+>/ {
> match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
> level = matches[1]
> - idx = "0x" matches[2]
> - array[idx]["idx"] = idx
> + idx = norm_idx(matches[2])
> + array[idx, "idx"] = idx
> parent[level] = idx
> }
> /^DW_AT_data_member_location/ {
> if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
> match($0, /([[:digit:]]+)/, temparray)
> - array[idx]["location"] = temparray[1]
> + array[idx, "location"] = temparray[1]
> }
> /^DW_AT_name/ {
> match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
> temparray)
> - array[idx]["name"] = temparray[1]
> + array_names[idx] = 1
> + array[idx, "name"] = temparray[1]
> }
> /^DW_AT_byte_size/ {
> match($0, /[[:digit:]]+/, temparray)
> - array[idx]["byte_size"] = temparray[0]
> + array[idx, "byte_size"] = temparray[0]
> }
> /^DW_AT_encoding/ {
> match($0, /[[:digit:]]+/, temparray)
> - array[idx]["encoding"] = temparray[0]
> + array[idx, "encoding"] = temparray[0]
> }
> /^DW_AT_type/ {
> - match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
> - array[idx]["type"] = temparray[1]
> + match($0, /:[[:space:]]+<0x([[:xdigit:]]*)>$/, temparray)
> + array[idx, "type"] = norm_idx(temparray[1])
> }
> /^DW_AT_upper_bound/ {
> match($0, /[[:digit:]]+/, temparray)
> @@ -223,17 +204,19 @@ BEGIN {
> /^Abbrev Number:[^(]+\(DW_TAG_/ {
> if (match($0, /typedef|union_type|structure_type|pointer_type\
> |enumeration_type|array_type|base_type|member/, temparray)) {
> - array[idx]["special"] = temparray[0]
> + array_special[idx] = temparray[0]
> + array[idx, "special"] = temparray[0]
> if ("pointer_type" == temparray[0])
> - array[idx]["byte_size"] = default_pointer_size
> + array[idx, "byte_size"] = default_pointer_size
> if (level > 1 && "member" == temparray[0])
> - array[idx]["parent"] = parent[level-1]
> + array_parents[idx] = parent[level-1]
> }
> }
> END {
> - PROCINFO["sorted_in"] = "compare_indices"
> - for (item in array) {
> - if (array[item]["special"] == "pointer_type") {
> + parents_cnt = asorti(array_parents, aparents_sorted)
> +
> + for (item in array_special) {
> + if (array[item, "special"] == "pointer_type") {
> mpers_ptr_t = \
> "uint" 8 * array_get(item, "byte_size") "_t"
> print "#ifndef mpers_ptr_t_is_" mpers_ptr_t
> @@ -243,8 +226,8 @@ END {
> break
> }
> }
> - for (item in array) {
> - if (array[item]["name"] == VAR_NAME) {
> + for (item in array_names) {
> + if (array[item, "name"] == VAR_NAME) {
> type = array_get(item, "type")
> print "typedef"
> what_is(type)
Overall looks plausible although less readable than the gawk 4 edition.
--
ldv
|
|
From: Heiko C. <hei...@de...> - 2018-01-20 12:52:43
|
On Thu, Jan 18, 2018 at 07:16:31AM +0100, Eugene Syromyatnikov wrote:
> Hello.
>
> This patch set introduces compat personality support on s390x along with
> decoders of s390-specific system calls.
>
> Unfortunately, I am no s390 expert by any means, so I likely have missed
> something. I also have little idea regarding applications where these
> s390-specific system calls are used, so the feedback regarding quality
> of the decoders is also welcome.
Looks all good to me. However the s390_sthyi test case fails:
-s390_sthyi(STHYI_FC_CP_IFL_CAP, {/* header */ {infhflg1=00, ...}, /* machine */ {infmval1=0xf0, infmscps=2, infmdcps=0, infmsifl=90, infmdifl=2, ...}, /* partition */ {infpflg1=0x80, infpval1=0xfc, infppnum=63, infpscps=0, infpdcps=0, infpsifl=32, infpdifl=0, infppnam="\xe2\xf8\xf3\xd3\xd7\xf6\xf0\x40" /* "S83LP60 " */, ...}, /* hypervisor 1 */ {infyflg1=0xc0, infycpt=1, infyiflt=2, infysyid="\xc2\xd6\xc5\xe2\xf8\xf3\xf6\xf0" /* "BOES8360" */, infysifl=32, ...}, /* guest 1 */ {infgflg1=0x4, infgusid="\xe2\xf8\xf3\xf6\xf0\xf0\xf1\xf6" /* "S8360016" */, infgsifl=6, infgpflg=00, ...}}, [0], 0) = 0
+s390_sthyi(STHYI_FC_CP_IFL_CAP, {/* header */ {infhflg1=00, ...}, /* machine */ {infmval1=0xf0, infmscps=2, infmdcps=0, infmsifl=90, infmdifl=2, ...}, /* partition */ {infpflg1=0x80, infpval1=0xfc, infppnum=63, infpscps=0, infpdcps=0, infpsifl=32, infpdifl=0, infppnam="\xe2\xf8\xf3\xd3\xd7\xf6\xf0\x40" /* "S83LP60 " */, ...}, /* hypervisor 1 */ {infyflg1=0xc0, infysyid="\xc2\xd6\xc5\xe2\xf8\xf3\xf6\xf0" /* "BOES8360" */, infysifl=32, ...}, /* guest 1 */ {infgflg1=0x4, infgusid="\xe2\xf8\xf3\xf6\xf0\xf0\xf1\xf6" /* "S8360016" */, infgsifl=6, infgpflg=00, ...}}, [0], 0) = 0
+++ exited with 0 +++
s390_sthyi.gen.test: failed test: ../../strace -e trace=s390_sthyi -a47 ../s390_sthyi output mismatch
|
|
From: Dmitry V. L. <ld...@al...> - 2018-01-19 01:54:59
|
On Thu, Jan 18, 2018 at 07:16:35AM +0100, Eugene Syromyatnikov wrote: > By very popular demand. > > While we are here, let's refactor the condition for old_mmap_pgoff into > an arch-specific one, as it is used more than in one place. > > * NEWS: Mention this. > * configure.ac (case "$host_cpu" in) <s390x>: Set arch_m32 to s390, set > cc_flags_m32 to -m31. > (st_MPERS([m32])): Add s390x. > * defs.h [S390X]: Define NEED_UID16_PARSERS. > * linux/s390/arch_sigreturn.c [!S390_FRAME_PTR] (S390_FRAME_PTR): New > macro, define to s390_frame_ptr. > [!SIGNAL_FRAMESIZE] (SIGNAL_FRAMESIZE): New macro, define to > __SIGNAL_FRAMESIZE. > [!PTR_TYPE] (PTR_TYPE): New macro, define to unsigned long. > (arch_sigreturn): Use S390_FRAME_PTR, SIGNAL_FRAMESIZE, and PTR_TYPE > instead of s390_frame_ptr, __SIGNAL_FRAMESIZE, and pointer-sized type, > respectively. > * linux/s390/get_error.c [!ARCH_REGSET] (ARCH_REGSET): New macro, define > * to s390_regset. > (get_error): Use it instead of s390_regset. > * linux/s390/get_scno.c (arch_get_scno): Likewise. > * linux/s390/get_syscall_args.c (get_syscall_args): Likewise. > * linux/s390/set_error.c (arch_set_error, arch_set_success): Likewise. > * linux/s390/set_scno.c (arch_set_scno): Likewise. > * linux/s390x/arch_regs.c (psw_compat_t, s390_compat_regs, > s390x_regs_union, s390_frame_ptr, s390x_frame_ptr, s390x_io): New > variable. > (s390_regset, s390x_regset, ARCH_REGS_FOR_GETREGSET, > ARCH_IOVEC_FOR_GETREGSET, ARCH_PC_REG, ARCH_PERSONALITY_0_IOV_SIZE, > ARCH_PERSONALITY_1_IOV_SIZE): New macro. > * linux/s390x/arch_regs.h (s390_frame_ptr, s390x_frame_ptr): New > external definitions. > * linux/s390x/arch_rt_sigframe.c: Behave based on tcp->currpers. > * linux/s390x/arch_sigreturn.c: Likewise. > * linux/s390x/get_error.c: Likewise. > * linux/s390x/get_scno.c: Likewise. > * linux/s390x/get_syscall_args.c: Likewise. > * linux/s390x/set_error.c: Likewise. > * linux/s390x/set_scno.c: Likewise. > * linux/s390x/errnoent1.h: New file. > * linux/s390x/ioctls_arch1.h: Likewise. > * linux/s390x/ioctls_inc1.h: Likewise. > * linux/s390x/signalent1.h: Likewise. > * linux/s390x/syscallent1.h: Likewise. These new files had to be added to Makefile.am as well. > * supported_personalities.h [S390X]: Define SUPPORTED_PERSONALITIES to > 2. > * tests/strace-V.test: Add s390 to the list of architectures that have > m32 personality. > * linux/s390/arch_defs.h (HAVE_ARCH_OLD_MMAP_PGOFF): New definition. > * linux/s390x/arch_defs.h: Likewise. > * mem.c: Replace #ifdef S390 with #ifdef HAVE_ARCH_OLD_MMAP_PGOFF. > * pathtrace.c: Likewise. Looks good, passes tests. Applied, thanks. -- ldv |
|
From: DJ D. <dj...@re...> - 2018-01-18 20:21:03
|
Thanks! |
|
From: Chen J. <che...@gm...> - 2018-01-18 14:03:07
|
* tests/netlink_netfilter.c(test_nfgenmsg): Add check for decoding
of netfilter subsystem.
---
tests/netlink_netfilter.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/tests/netlink_netfilter.c b/tests/netlink_netfilter.c
index e2cecd6..1d20320 100644
--- a/tests/netlink_netfilter.c
+++ b/tests/netlink_netfilter.c
@@ -158,9 +158,26 @@ test_nfgenmsg(const int fd)
printf(", version=%#x /* NFNETLINK_??? */", msg.version);
# endif
printf(", res_id=htons(%d)", NFNL_SUBSYS_NFTABLES));
+# endif /* NFNL_MSG_BATCH_BEGIN */
char str_buf[NLMSG_ALIGN(sizeof(msg)) + 4];
+ msg.res_id = htons(0xefab);
+ memcpy(str_buf, &msg, sizeof(msg));
+ memcpy(str_buf + NLMSG_ALIGN(sizeof(msg)), "1234", 4);
+ TEST_NETLINK_(fd, nlh0,
+ 0xffff, "0xff /* NFNL_SUBSYS_??? */<<8|0xff",
+ NLM_F_REQUEST, "NLM_F_REQUEST",
+ sizeof(str_buf), str_buf, sizeof(str_buf),
+ printf("{nfgen_family=AF_UNIX");
+# ifdef NFNETLINK_V0
+ printf(", version=NFNETLINK_V0");
+# else
+ printf(", version=%#x /* NFNETLINK_??? */", msg.version);
+# endif
+ printf(", res_id=htons(%d)"
+ ", \"\\x31\\x32\\x33\\x34\"", 0xefab));
+# ifdef NFNL_MSG_BATCH_BEGIN
msg.res_id = htons(0xabcd);
memcpy(str_buf, &msg, sizeof(msg));
memcpy(str_buf + NLMSG_ALIGN(sizeof(msg)), "1234", 4);
@@ -177,6 +194,31 @@ test_nfgenmsg(const int fd)
printf(", res_id=htons(%d)"
", \"\\x31\\x32\\x33\\x34\"", 0xabcd));
# endif /* NFNL_MSG_BATCH_BEGIN */
+
+ static const struct nlattr nla = {
+ .nla_len = sizeof(nla),
+ .nla_type = 0x0bcd
+ };
+ char nla_buf[NLMSG_ALIGN(sizeof(msg)) + sizeof(nla)];
+
+ msg.res_id = htons(NFNL_SUBSYS_NFTABLES);
+ memcpy(nla_buf, &msg, sizeof(msg));
+ memcpy(nla_buf + NLMSG_ALIGN(sizeof(msg)), &nla, sizeof(nla));
+
+ TEST_NETLINK_(fd, nlh0,
+ NFNL_SUBSYS_NFTABLES << 8 | 0xff,
+ "NFNL_SUBSYS_NFTABLES<<8|0xff /* NFT_MSG_??? */",
+ NLM_F_REQUEST, "NLM_F_REQUEST",
+ sizeof(nla_buf), nla_buf, sizeof(nla_buf),
+ printf("{nfgen_family=AF_UNIX");
+# ifdef NFNETLINK_V0
+ printf(", version=NFNETLINK_V0");
+# else
+ printf(", version=%#x /* NFNETLINK_??? */", msg.version);
+# endif
+ printf(", res_id=htons(NFNL_SUBSYS_NFTABLES)"
+ ", {nla_len=%d, nla_type=%#x}",
+ nla.nla_len, nla.nla_type));
}
int main(void)
--
2.7.4
|
|
From: Chen J. <che...@gm...> - 2018-01-18 14:02:51
|
* defs.h (nl_netfilter_msg_types): New xlat prototype.
* netlink_netfilter.c: Include "nlattr.h".
(decode_netlink_netfilter): Call decode_nlattr.
---
defs.h | 1 +
netlink_netfilter.c | 11 +++++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 6b51626..cf75802 100644
--- a/defs.h
+++ b/defs.h
@@ -287,6 +287,7 @@ extern const struct xlat inet_protocols[];
extern const struct xlat ip_type_of_services[];
extern const struct xlat msg_flags[];
extern const struct xlat netlink_protocols[];
+extern const struct xlat nl_netfilter_msg_types[];
extern const struct xlat nl_route_types[];
extern const struct xlat open_access_modes[];
extern const struct xlat open_mode_flags[];
diff --git a/netlink_netfilter.c b/netlink_netfilter.c
index a5efeb6..2840301 100644
--- a/netlink_netfilter.c
+++ b/netlink_netfilter.c
@@ -31,6 +31,7 @@
#ifdef HAVE_LINUX_NETFILTER_NFNETLINK_H
# include "print_fields.h"
+# include "nlattr.h"
# include <netinet/in.h>
# include <arpa/inet.h>
@@ -77,8 +78,14 @@ decode_netlink_netfilter(struct tcb *const tcp,
const size_t offset = NLMSG_ALIGN(sizeof(nfmsg));
if (len > offset) {
tprints(", ");
- printstr_ex(tcp, addr + offset,
- len - offset, QUOTE_FORCE_HEX);
+ if (subsys_id >= NFNL_SUBSYS_COUNT
+ || xlookup(nl_netfilter_msg_types,
+ nlmsghdr->nlmsg_type))
+ printstr_ex(tcp, addr + offset,
+ len - offset, QUOTE_FORCE_HEX);
+ else
+ decode_nlattr(tcp, addr + offset, len - offset,
+ NULL, NULL, NULL, 0, NULL);
}
}
--
2.7.4
|
|
From: Chen J. <che...@gm...> - 2018-01-18 14:02:13
|
* tests/netlink_netfilter.c: Include <netinet/in.h>, <arpa/inet.h>
and <linux/netfilter/nf_tables.h>.
Replace "netlink.h" with "test_netlink.h".
(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWTABLE): New macros.
(test_nlmsg_done, test_nfgenmsg): New functions.
(main): Use them.
---
tests/netlink_netfilter.c | 115 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 113 insertions(+), 2 deletions(-)
diff --git a/tests/netlink_netfilter.c b/tests/netlink_netfilter.c
index db2622e..e2cecd6 100644
--- a/tests/netlink_netfilter.c
+++ b/tests/netlink_netfilter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 JingPiao Chen <che...@gm...>
+ * Copyright (c) 2018 Chen Jingpiao <che...@gm...>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,9 +32,21 @@
# include <stdio.h>
# include <string.h>
# include <unistd.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
# include <sys/socket.h>
-# include "netlink.h"
+# include "test_netlink.h"
# include <linux/netfilter/nfnetlink.h>
+# ifdef HAVE_LINUX_NETFILTER_NF_TABLES_H
+# include <linux/netfilter/nf_tables.h>
+# endif
+
+# ifndef NFNL_SUBSYS_NFTABLES
+# define NFNL_SUBSYS_NFTABLES 10
+# endif
+# ifndef NFT_MSG_NEWTABLE
+# define NFT_MSG_NEWTABLE 0
+# endif
static void
test_nlmsg_type(const int fd)
@@ -70,6 +82,103 @@ test_nlmsg_type(const int fd)
fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc));
}
+static void
+test_nlmsg_done(const int fd)
+{
+ void *const nlh0 = tail_alloc(NLMSG_HDRLEN);
+ const int num = 0xabcdefad;
+
+ TEST_NETLINK(fd, nlh0, NLMSG_DONE, NLM_F_REQUEST,
+ sizeof(num), &num, sizeof(num),
+ printf("%d", num));
+}
+
+static void
+test_nfgenmsg(const int fd)
+{
+ void *const nlh0 = tail_alloc(NLMSG_HDRLEN);
+
+ struct nfgenmsg msg = {
+ .nfgen_family = AF_UNIX,
+ .version = 0,
+ .res_id = NFNL_SUBSYS_NFTABLES
+ };
+
+ TEST_NETLINK_OBJECT_EX_(fd, nlh0,
+ NFNL_SUBSYS_NFTABLES << 8 | NFT_MSG_NEWTABLE,
+ "NFNL_SUBSYS_NFTABLES<<8|NFT_MSG_NEWTABLE",
+ NLM_F_REQUEST, "NLM_F_REQUEST",
+ msg, print_quoted_hex,
+ printf("{nfgen_family=AF_UNIX");
+# ifdef NFNETLINK_V0
+ printf(", version=NFNETLINK_V0");
+# else
+ printf(", version=%#x /* NFNETLINK_??? */",
+ msg.version);
+# endif
+ printf(", res_id=NFNL_SUBSYS_NFTABLES"));
+
+ msg.res_id = htons(NFNL_SUBSYS_NFTABLES);
+ TEST_NETLINK_(fd, nlh0,
+ NFNL_SUBSYS_NFTABLES << 8 | NFT_MSG_NEWTABLE,
+ "NFNL_SUBSYS_NFTABLES<<8|NFT_MSG_NEWTABLE",
+ NLM_F_REQUEST, "NLM_F_REQUEST",
+ sizeof(msg), &msg, sizeof(msg),
+ printf("{nfgen_family=AF_UNIX");
+# ifdef NFNETLINK_V0
+ printf(", version=NFNETLINK_V0");
+# else
+ printf(", version=%#x /* NFNETLINK_??? */", msg.version);
+# endif
+ printf(", res_id=htons(NFNL_SUBSYS_NFTABLES)"));
+
+ msg.res_id = htons(0xabcd);
+ TEST_NETLINK_(fd, nlh0,
+ NFNL_SUBSYS_NFTABLES << 8 | NFT_MSG_NEWTABLE,
+ "NFNL_SUBSYS_NFTABLES<<8|NFT_MSG_NEWTABLE",
+ NLM_F_REQUEST, "NLM_F_REQUEST",
+ sizeof(msg), &msg, sizeof(msg),
+ printf("{nfgen_family=AF_UNIX");
+# ifdef NFNETLINK_V0
+ printf(", version=NFNETLINK_V0");
+# else
+ printf(", version=%#x /* NFNETLINK_??? */", msg.version);
+# endif
+ printf(", res_id=htons(%d)", 0xabcd));
+
+# ifdef NFNL_MSG_BATCH_BEGIN
+ msg.res_id = htons(NFNL_SUBSYS_NFTABLES);
+ TEST_NETLINK(fd, nlh0,
+ NFNL_MSG_BATCH_BEGIN, NLM_F_REQUEST,
+ sizeof(msg), &msg, sizeof(msg),
+ printf("{nfgen_family=AF_UNIX");
+# ifdef NFNETLINK_V0
+ printf(", version=NFNETLINK_V0");
+# else
+ printf(", version=%#x /* NFNETLINK_??? */", msg.version);
+# endif
+ printf(", res_id=htons(%d)", NFNL_SUBSYS_NFTABLES));
+
+ char str_buf[NLMSG_ALIGN(sizeof(msg)) + 4];
+
+ msg.res_id = htons(0xabcd);
+ memcpy(str_buf, &msg, sizeof(msg));
+ memcpy(str_buf + NLMSG_ALIGN(sizeof(msg)), "1234", 4);
+
+ TEST_NETLINK(fd, nlh0,
+ NFNL_MSG_BATCH_BEGIN, NLM_F_REQUEST,
+ sizeof(str_buf), str_buf, sizeof(str_buf),
+ printf("{nfgen_family=AF_UNIX");
+# ifdef NFNETLINK_V0
+ printf(", version=NFNETLINK_V0");
+# else
+ printf(", version=%#x /* NFNETLINK_??? */", msg.version);
+# endif
+ printf(", res_id=htons(%d)"
+ ", \"\\x31\\x32\\x33\\x34\"", 0xabcd));
+# endif /* NFNL_MSG_BATCH_BEGIN */
+}
+
int main(void)
{
skip_if_unavailable("/proc/self/fd/");
@@ -77,6 +186,8 @@ int main(void)
int fd = create_nl_socket(NETLINK_NETFILTER);
test_nlmsg_type(fd);
+ test_nlmsg_done(fd);
+ test_nfgenmsg(fd);
printf("+++ exited with 0 +++\n");
--
2.7.4
|
|
From: Chen J. <che...@gm...> - 2018-01-18 13:59:00
|
* netlink_netfilter.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* defs.h (decode_netlink_netfilter): New prototype.
* netlink.c (netlink_decoders): Add NETLINK_NETFILTER.
* xlat/netfilter_versions.in: New file.
---
Makefile.am | 1 +
defs.h | 1 +
netlink.c | 3 ++
netlink_netfilter.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++
xlat/netfilter_versions.in | 2 ++
5 files changed, 95 insertions(+)
create mode 100644 netlink_netfilter.c
create mode 100644 xlat/netfilter_versions.in
diff --git a/Makefile.am b/Makefile.am
index 2515876..358afc1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -196,6 +196,7 @@ strace_SOURCES = \
netlink_crypto.c \
netlink_sock_diag.h \
netlink_inet_diag.c \
+ netlink_netfilter.c \
netlink_netlink_diag.c \
netlink_packet_diag.c \
netlink_route.c \
diff --git a/defs.h b/defs.h
index 3e42908..6b51626 100644
--- a/defs.h
+++ b/defs.h
@@ -699,6 +699,7 @@ decode_netlink_ ## name(struct tcb *, const struct nlmsghdr *, \
/* End of DECL_NETLINK definition. */
DECL_NETLINK(crypto);
+DECL_NETLINK(netfilter);
DECL_NETLINK(route);
DECL_NETLINK(selinux);
DECL_NETLINK(sock_diag);
diff --git a/netlink.c b/netlink.c
index beb6ea4..f5fa1f1 100644
--- a/netlink.c
+++ b/netlink.c
@@ -549,6 +549,9 @@ static const netlink_decoder_t netlink_decoders[] = {
#ifdef HAVE_LINUX_CRYPTOUSER_H
[NETLINK_CRYPTO] = decode_netlink_crypto,
#endif
+#ifdef HAVE_LINUX_NETFILTER_NFNETLINK_H
+ [NETLINK_NETFILTER] = decode_netlink_netfilter,
+#endif
[NETLINK_ROUTE] = decode_netlink_route,
[NETLINK_SELINUX] = decode_netlink_selinux,
[NETLINK_SOCK_DIAG] = decode_netlink_sock_diag
diff --git a/netlink_netfilter.c b/netlink_netfilter.c
new file mode 100644
index 0000000..a5efeb6
--- /dev/null
+++ b/netlink_netfilter.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018 Chen Jingpiao <che...@gm...>
+ * Copyright (c) 2018 The strace developers.
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "defs.h"
+
+#ifdef HAVE_LINUX_NETFILTER_NFNETLINK_H
+
+# include "print_fields.h"
+
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include "netlink.h"
+# include <linux/netfilter/nfnetlink.h>
+
+# include "xlat/netfilter_versions.h"
+# include "xlat/nl_netfilter_subsys_ids.h"
+
+bool
+decode_netlink_netfilter(struct tcb *const tcp,
+ const struct nlmsghdr *const nlmsghdr,
+ const kernel_ulong_t addr,
+ const unsigned int len)
+{
+ if (nlmsghdr->nlmsg_type == NLMSG_DONE)
+ return false;
+
+ struct nfgenmsg nfmsg;
+
+ if (len < sizeof(nfmsg))
+ printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
+ else if (!umove_or_printaddr(tcp, addr, &nfmsg)) {
+ const uint8_t subsys_id = (uint8_t) (nlmsghdr->nlmsg_type >> 8);
+ uint16_t res_id = ntohs(nfmsg.res_id);
+
+ PRINT_FIELD_XVAL("{", nfmsg, nfgen_family, addrfams, "AF_???");
+ PRINT_FIELD_XVAL(", ", nfmsg, version, netfilter_versions,
+ "NFNETLINK_???");
+ tprints(", res_id=");
+ if (subsys_id == NFNL_SUBSYS_NFTABLES
+ && nfmsg.res_id == NFNL_SUBSYS_NFTABLES)
+ tprints("NFNL_SUBSYS_NFTABLES");
+ else {
+ tprints("htons(");
+ if (subsys_id == NFNL_SUBSYS_NFTABLES
+ && res_id == NFNL_SUBSYS_NFTABLES)
+ tprints("NFNL_SUBSYS_NFTABLES");
+ else
+ tprintf("%d", res_id);
+ tprints(")");
+ }
+
+ const size_t offset = NLMSG_ALIGN(sizeof(nfmsg));
+ if (len > offset) {
+ tprints(", ");
+ printstr_ex(tcp, addr + offset,
+ len - offset, QUOTE_FORCE_HEX);
+ }
+ }
+
+ return true;
+}
+
+#endif /* HAVE_LINUX_NETFILTER_NFNETLINK_H */
diff --git a/xlat/netfilter_versions.in b/xlat/netfilter_versions.in
new file mode 100644
index 0000000..da6cd05
--- /dev/null
+++ b/xlat/netfilter_versions.in
@@ -0,0 +1,2 @@
+NFNETLINK_V0
+NFNETLINK_V1
--
2.7.4
|
|
From: Chen J. <che...@gm...> - 2018-01-18 13:58:55
|
xlat/nl_netfilter_subsys_ids.h is included twice because netlink.c and
netlink_netfilter.c are use NFNL_SUBSYS_* constants defined.
we call generic netfilter subsystem decoder ignore msg_type range.
If this design is incorrect, I will drop this patch.
Following kernel commits will help the reviewer:
"res_id" field:
v4.2-rc6-148-ga9de977 ("netfilter: nfnetlink: work around wrong endianess in res_id field")
"version" field:
v2.6.13-158-g080774a ("[NETFILTER]: Add ctnetlink subsystem")
Chen Jingpiao (4):
netlink: introduce NETLINK_NETFILTER parser
tests: add check for NETLINK_NETFILTER parser
nfnetlink: introduce generic netfilter subsystem decoder
tests: add check for decoding of netfilter subsystem
Makefile.am | 1 +
defs.h | 2 +
netlink.c | 3 +
netlink_netfilter.c | 95 +++++++++++++++++++++++++++
tests/netlink_netfilter.c | 157 ++++++++++++++++++++++++++++++++++++++++++++-
xlat/netfilter_versions.in | 2 +
6 files changed, 258 insertions(+), 2 deletions(-)
create mode 100644 netlink_netfilter.c
create mode 100644 xlat/netfilter_versions.in
--
2.7.4
|
|
From: Eugene S. <es...@re...> - 2018-01-18 09:47:53
|
On Fri, Jan 05, 2018 at 04:15:10PM -0500, DJ Delorie wrote: > > "Dmitry V. Levin" <ld...@al...> writes: > > checking whether mpers.sh -m32 works... gawk: ./mpers.awk:42: array_return = array[array_idx][array_member] > > gawk: ./mpers.awk:42: ^ syntax error > > ... > > no > > > > which I wouldn't call "silently ignored". > > Well, ignored then. The build continues but builds an strace without > mpers support. > > >> If not, shouldn't configure check for > >> multi-dimensional array support and fail if it's not found? > > > > Do you suggest failing the build in this case? > > If the target defaults to running mpers, yeah, I think a test for [][] > support in configure would be appropriate (or making the mpers.sh test > fatal), perhaps with an --disable-mpers to work around it. Mpers check is now fatal by default (v4.20-168-g3eb199a). > Building an strace that doesn't do what you expect is worse than not > building an strace until you change your expectations ;-) > > Or if mpers is not built, at least strace should refuse to trace > binaries that would have required the other personalities. At the > moment, it traces them but produces incorrect output. strace now warns in case tracee has unsupported personality (v4.20-166-g88fa069) and the personality support is readily available in strace -V output (v4.20-158-g7dbc378). It is also mentioned in the man page (v4.20-159-gb172dbf). Hope this helps. See also https://sourceforge.net/p/strace/mailman/message/36194990/ |
|
From: Eugene S. <ev...@gm...> - 2018-01-18 09:41:10
|
---
mpers.awk | 132 +++++++++++++++++++++++++++-----------------------------------
1 file changed, 58 insertions(+), 74 deletions(-)
diff --git a/mpers.awk b/mpers.awk
index 6545052..8374b3b 100644
--- a/mpers.awk
+++ b/mpers.awk
@@ -27,19 +27,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-function compare_indices(i1, v1, i2, v2, \
- c1, c2)
-{
- c1 = strtonum(sprintf("%s", i1))
- c2 = strtonum(sprintf("%s", i2))
- if (c1 < c2)
- return -1
- return (c1 != c2)
-}
function array_get(array_idx, array_member, \
array_return)
{
- array_return = array[array_idx][array_member]
+ array_return = array[array_idx, array_member]
if ("" == array_return) {
printf("%s: index [%s] without %s\n",
FILENAME, array_idx, array_member) > "/dev/stderr"
@@ -47,12 +38,16 @@ function array_get(array_idx, array_member, \
}
return array_return
}
+function norm_idx(idx)
+{
+ return sprintf("%016s", idx)
+}
function array_seq(array_idx)
{
- if ("seq" in array[array_idx])
- return array[array_idx]["seq"]
+ if ((array_idx, "seq") in array)
+ return array[array_idx, "seq"]
index_seq++
- array[array_idx]["seq"] = index_seq
+ array[array_idx, "seq"] = index_seq
return index_seq
}
function enter(array_idx,
@@ -75,72 +70,63 @@ function leave(array_idx, to_return)
function update_upper_bound(idx, val, \
count)
{
- count = array[idx]["count"]
+ count = array[idx, "count"]
if (count == "")
count = 1
- array[idx]["count"] = count * val
- array[idx]["upper_bound"] = array[idx]["upper_bound"] "[" val "]"
+ array[idx, "count"] = count * val
+ array[idx, "upper_bound"] = array[idx, "upper_bound"] "[" val "]"
}
function what_is(what_idx, \
item, loc_diff, location, prev_location, prev_returned_size, \
- special, to_return, type_idx)
+ special, to_return, type_idx, enc)
{
enter(what_idx)
special = array_get(what_idx, "special")
- switch (special) {
- case "base_type":
- switch (array_get(what_idx, "encoding")) {
- case 5: # signed
+ if (special == "base_type") {
+ enc = array_get(what_idx, "encoding")
+ if (enc == 5) { # signed
printf("int%s_t ",
8 * array_get(what_idx, "byte_size"))
- break
- case 7: # unsigned
+ } else if (enc == 7) { # unsigned
printf("uint%s_t ",
8 * array_get(what_idx, "byte_size"))
- break
- default: # float, signed/unsigned char
+ } else { # float, signed/unsigned char
printf("%s ", array_get(what_idx, "name"))
- break
}
returned_size = array_get(what_idx, "byte_size")
- break
- case "enumeration_type":
+ } else if (special == "enumeration_type") {
returned_size = array_get(what_idx, "byte_size")
printf("uint%s_t ", 8 * returned_size)
- break
- case "pointer_type":
+ } else if (special == "pointer_type") {
printf("mpers_ptr_t ")
returned_size = array_get(what_idx, "byte_size")
- break
- case "array_type":
+ } else if (special == "array_type") {
type_idx = array_get(what_idx, "type")
what_is(type_idx)
- to_return = array[what_idx]["upper_bound"]
+ to_return = array[what_idx, "upper_bound"]
if ("" == to_return)
to_return = "[0]"
- returned_size = array[what_idx]["count"] * returned_size
+ returned_size = array[what_idx, "count"] * returned_size
return leave(what_idx, to_return)
- break
- case "structure_type":
+ } else if (special == "structure_type") {
print "struct {"
prev_location = 0
location = 0
returned_size = 0
prev_returned_size = 0
- for (item in array) {
- if ("parent" in array[item] && \
- array_get(item, "parent") == what_idx) {
- location = array_get(item, "location")
+ for (item = 1; item <= parents_cnt; item+=1) {
+ if (array_parents[aparents_sorted[item]] == what_idx) {
+ location = array_get(aparents_sorted[item], "location")
loc_diff = location - prev_location - \
prev_returned_size
if (loc_diff != 0) {
printf("unsigned char mpers_%s_%s[%s];\n",
- "filler", array_seq(item), loc_diff)
+ "filler", array_seq(aparents_sorted[item]), loc_diff)
}
prev_location = location
- returned = what_is(item)
+ returned = what_is(aparents_sorted[item])
prev_returned_size = returned_size
- printf("%s%s;\n", array[item]["name"], returned)
+ printf("%s%s;\n", array[aparents_sorted[item], "name"], returned)
}
}
returned_size = array_get(what_idx, "byte_size")
@@ -150,31 +136,25 @@ function what_is(what_idx, \
"end_filler", array_seq(item), loc_diff)
}
printf("} ATTRIBUTE_PACKED ")
- break
- case "union_type":
+ } else if (special == "union_type") {
print "union {"
- for (item in array) {
- if ("parent" in array[item] && \
- array_get(item, "parent") == what_idx) {
- returned = what_is(item)
- printf("%s%s;\n", array[item]["name"], returned)
+ for (item = 1; item <= parents_cnt; item+=1) {
+ if (array_parents[aparents_sorted[item]] == what_idx) {
+ returned = what_is(aparents_sorted[item])
+ printf("%s%s;\n", array[aparents_sorted[item], "name"], returned)
}
}
printf("} ")
returned_size = array_get(what_idx, "byte_size")
- break
- case "typedef":
+ } else if (special == "typedef") {
type_idx = array_get(what_idx, "type")
return leave(what_idx, what_is(type_idx))
- break
- case "member":
+ } else if (special == "member") {
type_idx = array_get(what_idx, "type")
return leave(what_idx, what_is(type_idx))
- break
- default:
+ } else {
type_idx = array_get(what_idx, "type")
what_is(type_idx)
- break
}
return leave(what_idx, "")
}
@@ -186,31 +166,32 @@ BEGIN {
/^<[[:xdigit:]]+>/ {
match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
level = matches[1]
- idx = "0x" matches[2]
- array[idx]["idx"] = idx
+ idx = norm_idx(matches[2])
+ array_names[idx] = 1
+ array[idx, "idx"] = idx
parent[level] = idx
}
/^DW_AT_data_member_location/ {
if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
match($0, /([[:digit:]]+)/, temparray)
- array[idx]["location"] = temparray[1]
+ array[idx, "location"] = temparray[1]
}
/^DW_AT_name/ {
match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
temparray)
- array[idx]["name"] = temparray[1]
+ array[idx, "name"] = temparray[1]
}
/^DW_AT_byte_size/ {
match($0, /[[:digit:]]+/, temparray)
- array[idx]["byte_size"] = temparray[0]
+ array[idx, "byte_size"] = temparray[0]
}
/^DW_AT_encoding/ {
match($0, /[[:digit:]]+/, temparray)
- array[idx]["encoding"] = temparray[0]
+ array[idx, "encoding"] = temparray[0]
}
/^DW_AT_type/ {
- match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
- array[idx]["type"] = temparray[1]
+ match($0, /:[[:space:]]+<0x([[:xdigit:]]*)>$/, temparray)
+ array[idx, "type"] = norm_idx(temparray[1])
}
/^DW_AT_upper_bound/ {
match($0, /[[:digit:]]+/, temparray)
@@ -223,25 +204,28 @@ BEGIN {
/^Abbrev Number:[^(]+\(DW_TAG_/ {
if (match($0, /typedef|union_type|structure_type|pointer_type\
|enumeration_type|array_type|base_type|member/, temparray)) {
- array[idx]["special"] = temparray[0]
+ array_special[idx] = temparray[0]
+ array[idx, "special"] = temparray[0]
if ("pointer_type" == temparray[0])
- array[idx]["byte_size"] = default_pointer_size
+ array[idx, "byte_size"] = default_pointer_size
if (level > 1 && "member" == temparray[0])
- array[idx]["parent"] = parent[level-1]
+ array_parents[idx] = parent[level-1]
}
}
END {
- PROCINFO["sorted_in"] = "compare_indices"
- for (item in array) {
- if (array[item]["special"] == "pointer_type") {
+ names_cnt = asorti(array_names, anames_sorted)
+ parents_cnt = asorti(array_parents, aparents_sorted)
+
+ for (item in array_special) {
+ if (array[item, "special"] == "pointer_type") {
print "typedef uint" \
8 * array_get(item, "byte_size") "_t mpers_ptr_t;"
break
}
}
- for (item in array) {
- if (array[item]["name"] == VAR_NAME) {
- type = array_get(item, "type")
+ for (item = 1; item <= names_cnt; item+=1) {
+ if (array[anames_sorted[item], "name"] == VAR_NAME) {
+ type = array_get(anames_sorted[item], "type")
print "typedef"
what_is(type)
name = array_get(type, "name")
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-18 06:40:46
|
Hello. This patch set introduces compat personality support on s390x along with decoders of s390-specific system calls. Unfortunately, I am no s390 expert by any means, so I likely have missed something. I also have little idea regarding applications where these s390-specific system calls are used, so the feedback regarding quality of the decoders is also welcome. Eugene Syromyatnikov (12): Add compat support for s390x Add print_quoted_string flag to generate comment print_fields.h: add macro to print hexadecimal array field Introduce s390_sthyi system call decoder tests: check s390_sthyi system call decoder Introduce s390_guarded_storage system call decoder tests: check s390_guarded_storage system call decoder Introduce s390_runtime_instr system call decoder tests: check s390_runtime_instr system call decoder Introduce s390_pci_mmio_read, s390_pci_mmio_write system call decoders tests: check s390_pci_mmio_read and s390_pci_mmio_write decoders Update NEWS Makefile.am | 1 + NEWS | 5 +- configure.ac | 7 +- defs.h | 3 +- linux/s390/arch_defs.h | 1 + linux/s390/arch_sigreturn.c | 16 +- linux/s390/get_error.c | 10 +- linux/s390/get_scno.c | 8 +- linux/s390/get_syscall_args.c | 16 +- linux/s390/set_error.c | 8 +- linux/s390/set_scno.c | 6 +- linux/s390/syscallent.h | 9 +- linux/s390x/arch_defs.h | 1 + linux/s390x/arch_regs.c | 37 +- linux/s390x/arch_regs.h | 3 +- linux/s390x/arch_rt_sigframe.c | 5 +- linux/s390x/arch_sigreturn.c | 26 + linux/s390x/errnoent1.h | 1 + linux/s390x/get_error.c | 23 +- linux/s390x/get_scno.c | 21 +- linux/s390x/get_syscall_args.c | 22 +- linux/s390x/ioctls_arch1.h | 1 + linux/s390x/ioctls_inc1.h | 1 + linux/s390x/set_error.c | 34 +- linux/s390x/set_scno.c | 21 +- linux/s390x/signalent1.h | 1 + linux/s390x/syscallent.h | 9 +- linux/s390x/syscallent1.h | 1 + mem.c | 4 +- pathtrace.c | 2 +- print_fields.h | 9 + s390.c | 1277 +++++++++++++++++++++++++++++++++ supported_personalities.h | 1 + tests/.gitignore | 6 + tests/gen_tests.in | 6 + tests/pure_executables.list | 6 + tests/s390_guarded_storage-v.c | 2 + tests/s390_guarded_storage.c | 229 ++++++ tests/s390_pci_mmio_read_write.c | 159 ++++ tests/s390_runtime_instr.c | 99 +++ tests/s390_sthyi-v.c | 2 + tests/s390_sthyi.c | 786 ++++++++++++++++++++ tests/strace-V.test | 2 +- util.c | 9 +- xlat/s390_guarded_storage_commands.in | 5 + xlat/s390_runtime_instr_commands.in | 2 + xlat/s390_sthyi_function_codes.in | 1 + 47 files changed, 2863 insertions(+), 41 deletions(-) create mode 100644 linux/s390x/errnoent1.h create mode 100644 linux/s390x/ioctls_arch1.h create mode 100644 linux/s390x/ioctls_inc1.h create mode 100644 linux/s390x/signalent1.h create mode 100644 linux/s390x/syscallent1.h create mode 100644 s390.c create mode 100644 tests/s390_guarded_storage-v.c create mode 100644 tests/s390_guarded_storage.c create mode 100644 tests/s390_pci_mmio_read_write.c create mode 100644 tests/s390_runtime_instr.c create mode 100644 tests/s390_sthyi-v.c create mode 100644 tests/s390_sthyi.c create mode 100644 xlat/s390_guarded_storage_commands.in create mode 100644 xlat/s390_runtime_instr_commands.in create mode 100644 xlat/s390_sthyi_function_codes.in -- 2.1.4 |
|
From: Eugene S. <ev...@gm...> - 2018-01-18 06:35:38
|
* configure.ac (AC_CHECK_FUNCS): Add iconv_open.
(AC_CHECK_HEADERS): Add iconv.h.
* tests/s390_sthyi-v.c: New file.
* tests/s390_sthyi.c: Likewise.
* tests/.gitignore: Add s390_sthyi, s390_sthyi-v.
* tests/pure_executables.list: Likewise.
* tests/gen_tests.in (s390_sthyi, s390_sthyi): New tests.
---
configure.ac | 2 +
tests/.gitignore | 2 +
tests/gen_tests.in | 2 +
tests/pure_executables.list | 2 +
tests/s390_sthyi-v.c | 2 +
tests/s390_sthyi.c | 786 ++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 796 insertions(+)
create mode 100644 tests/s390_sthyi-v.c
create mode 100644 tests/s390_sthyi.c
diff --git a/configure.ac b/configure.ac
index a1391c7..63595ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -287,6 +287,7 @@ AC_CHECK_FUNCS(m4_normalize([
fstatat
ftruncate
futimens
+ iconv_open
if_indextoname
open64
prctl
@@ -394,6 +395,7 @@ AC_CHECK_HEADERS(m4_normalize([
asm/sysmips.h
bluetooth/bluetooth.h
elf.h
+ iconv.h
inttypes.h
linux/bsg.h
linux/cryptouser.h
diff --git a/tests/.gitignore b/tests/.gitignore
index 4c54589..19aa493 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -357,6 +357,8 @@ rt_sigsuspend
rt_sigtimedwait
rt_tgsigqueueinfo
run_expect_termsig
+s390_sthyi
+s390_sthyi-v
sched_get_priority_mxx
sched_rr_get_interval
sched_xetaffinity
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 93b1687..968f6e4 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -303,6 +303,8 @@ rt_sigreturn -esignal='!USR1'
rt_sigsuspend -a20 -esignal=none
rt_sigtimedwait -a38
rt_tgsigqueueinfo -esignal=none
+s390_sthyi -a47
+s390_sthyi-v -e trace=s390_sthyi -a47
sched test_trace_expr times -e/sched
sched_get_priority_mxx -a33 -e trace=sched_get_priority_min,sched_get_priority_max
sched_rr_get_interval -a31
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 8f5ff31..d8b997d 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -296,6 +296,8 @@ rt_sigreturn
rt_sigsuspend
rt_sigtimedwait
rt_tgsigqueueinfo
+s390_sthyi
+s390_sthyi-v
sched_get_priority_mxx
sched_rr_get_interval
sched_xetaffinity
diff --git a/tests/s390_sthyi-v.c b/tests/s390_sthyi-v.c
new file mode 100644
index 0000000..8605520
--- /dev/null
+++ b/tests/s390_sthyi-v.c
@@ -0,0 +1,2 @@
+#define VERBOSE 1
+#include "s390_sthyi.c"
diff --git a/tests/s390_sthyi.c b/tests/s390_sthyi.c
new file mode 100644
index 0000000..1554daf
--- /dev/null
+++ b/tests/s390_sthyi.c
@@ -0,0 +1,786 @@
+/*
+ * Check decoding of s390_sthyi syscall.
+ *
+ * Copyright (c) 2018 The strace developers.
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "tests.h"
+#include <asm/unistd.h>
+
+#if defined HAVE_ICONV_H && defined HAVE_ICONV_OPEN && defined __NR_s390_sthyi
+
+# include <errno.h>
+# include <iconv.h>
+# include <inttypes.h>
+# include <stdbool.h>
+# include <stdint.h>
+# include <stdio.h>
+# include <unistd.h>
+
+# include <sys/user.h>
+
+# define EBCDIC_MAX_LEN 16
+
+# ifndef VERBOSE
+# define VERBOSE 0
+# endif
+
+static bool
+print_0x8(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ if (!zero && !buf[offs])
+ return false;
+
+ printf("%s=%#02hhx", prefix, buf[offs]);
+
+ return true;
+}
+
+static bool
+print_u8(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ if (!zero && !buf[offs])
+ return false;
+
+ printf("%s=%hhu", prefix, buf[offs]);
+
+ return true;
+}
+
+static bool
+print_u16(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ uint16_t val = *(uint16_t *) (buf + offs);
+
+ if (!zero && !val)
+ return false;
+
+ printf("%s=%" PRIu16, prefix, val);
+
+ return true;
+}
+
+static bool
+print_x32(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
+{
+ uint32_t val = *(uint32_t *) (buf + offs);
+
+ if (!zero && !val)
+ return false;
+
+ printf("%s=%#" PRIx32, prefix, val);
+
+ return true;
+}
+
+static bool
+print_weight(const char *prefix, unsigned char *buf, unsigned int offs,
+ bool zero)
+{
+ uint32_t val = *(uint32_t *) (buf + offs);
+
+ if (print_x32(prefix, buf, offs, zero)) {
+ if (val)
+ printf(" /* %u %u/65536 cores */",
+ val >> 16, val & 0xFFFF);
+ else
+ printf(" /* unlimited */");
+
+ return true;
+ }
+
+ return false;
+}
+
+static char *
+ebcdic2ascii(unsigned char *ebcdic, size_t size)
+{
+ static char ascii_buf[EBCDIC_MAX_LEN];
+
+ char *ebcdic_pos = (char *) ebcdic;
+ char *ascii_pos = ascii_buf;
+ size_t ebcdic_left = size;
+ size_t ascii_left = size;
+ size_t ret;
+
+ iconv_t cd = iconv_open("ASCII", "EBCDICUS");
+
+ if (size > sizeof(ascii_buf))
+ error_msg_and_fail("ebcdic2ascii: EBCDIC string is too big: "
+ "%zu (maximum is %zu)",
+ size, sizeof(ascii_buf));
+ if (cd == (iconv_t) -1)
+ perror_msg_and_fail("ebcdic2ascii: unable to allocate a "
+ "conversion descriptior for converting "
+ "EBCDIC to ASCII");
+
+ while ((ret = iconv(cd, &ebcdic_pos, &ebcdic_left,
+ &ascii_pos, &ascii_left)) == (size_t) -1) {
+ switch (errno) {
+ case EILSEQ:
+ case EINVAL: /* That one is quite unexpected, actually */
+ if (!ebcdic_left || !ascii_left)
+ goto ebcdic2ascii_end;
+
+ *ascii_pos++ = ' ';
+ ebcdic_pos++;
+ ebcdic_left--;
+
+ break;
+
+ case E2BIG:
+ perror_msg_and_fail("ebcdic2ascii: ran out of "
+ "ASCII buffer unexpectedly");
+ default:
+ perror_msg_and_fail("ebcdic2ascii: unexpected error");
+ }
+ }
+
+ebcdic2ascii_end:
+ iconv_close(cd);
+
+ if (ebcdic_left != ascii_left)
+ error_msg_and_fail("ebcdic2ascii: ASCII string differs in size "
+ "from EBCDIC");
+
+ return ascii_buf;
+}
+
+# if VERBOSE
+static bool
+is_empty(unsigned char *ptr, size_t size)
+{
+ size_t i;
+
+ for (i = 0; !*ptr && i < size; ptr++, i++)
+ ;
+
+ return i == size;
+}
+# endif /* !VERBOSE */
+
+static bool
+print_ebcdic(const char *prefix, unsigned char *addr, unsigned int offs,
+ size_t size, bool zero, bool blank)
+{
+ const char *ascii = ebcdic2ascii(addr + offs, size);
+
+ if (!zero) {
+ size_t i;
+
+ for (i = 0; (addr[offs + i] == (blank ? 64 : 0)) && (i < size);
+ i++)
+ ;
+
+ if (i == size)
+ return false;
+ }
+
+ printf("%s=", prefix);
+ print_quoted_hex((char *) (addr + offs), size);
+ printf(" /* ");
+ print_quoted_memory(ascii, size);
+ printf(" */");
+
+ return true;
+}
+
+static void
+print_hypervisor_header(unsigned char *buf, int level, unsigned int offs_pos,
+ unsigned int len_pos, bool mt)
+{
+ uint16_t offs = *(uint16_t *) (buf + offs_pos);
+ uint16_t hdr_size = *(uint16_t *) (buf + len_pos);
+ unsigned char *cur;
+
+ if (!offs)
+ return;
+ if (hdr_size < 32)
+ error_msg_and_fail("sthyi: hypervisor %d section is too small "
+ "(got %hu, 32 expected)", level, hdr_size);
+
+ cur = buf + offs;
+
+ printf(", /* hypervisor %d */ {infyflg1", level);
+ print_0x8("", cur, 0, true);
+# if VERBOSE
+ if (cur[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[0] & 0x80) {
+ printf("0x80 - guest CPU usage had limiting is using "
+ "the consumption method");
+ printed = true;
+ }
+ if (cur[0] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - LIMITHARD caps use prorated core time "
+ "for capping");
+ printed = true;
+ }
+ if (cur[0] & 0x3F) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[0] & 0x3F);
+ }
+ printf(" */");
+ }
+
+ print_0x8(", infyflg2", cur, 1, false);
+ print_0x8(", infyval1", cur, 2, false);
+ print_0x8(", infyval2", cur, 3, false);
+
+ print_u8(", infytype", cur, 4, true);
+ if (cur[4] == 1)
+ printf(" /* z/VM is the hypervisor */");
+ else
+ printf(" /* unknown hypervisor type */");
+
+ if (cur[5])
+ printf(", reserved_1__=\"\\x%#02hhx\"", cur[5]);
+# endif /* !VERBOSE */
+
+ print_u8(", infycpt", cur, 6, VERBOSE && mt);
+ print_u8(", infyiflt", cur, 7, VERBOSE && mt);
+
+ print_ebcdic(", infysyid", cur, 8, 8, VERBOSE, true);
+ print_ebcdic(", infyclnm", cur, 16, 8, VERBOSE, true);
+
+ print_u16(", infyscps", cur, 24, VERBOSE);
+ print_u16(", infydcps", cur, 26, VERBOSE);
+ print_u16(", infysifl", cur, 28, VERBOSE);
+ print_u16(", infydifl", cur, 30, VERBOSE);
+
+# if VERBOSE
+ if (hdr_size > 32 && !is_empty(cur + 32, hdr_size - 32)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 32), hdr_size - 32);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+}
+
+static void
+print_guest_header(unsigned char *buf, int level, unsigned int offs_pos,
+ unsigned int len_pos)
+{
+ uint16_t offs = *(uint16_t *) (buf + offs_pos);
+ uint16_t hdr_size = *(uint16_t *) (buf + len_pos);
+ unsigned char *cur;
+
+ if (!offs)
+ return;
+ if (hdr_size < 56)
+ error_msg_and_fail("sthyi: guest %d section is too small "
+ "(got %hu, 56 expected)", level, hdr_size);
+
+ cur = buf + offs;
+
+ printf(", /* guest %d */ {infgflg1", level);
+ print_0x8("", cur, 0, true);
+# if VERBOSE
+ if (cur[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[0] & 0x80) {
+ printf("0x80 - guest is mobility enabled");
+ printed = true;
+ }
+ if (cur[0] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - guest has multiple virtual CPU types");
+ printed = true;
+ }
+ if (cur[0] & 0x20) {
+ if (printed)
+ printf(", ");
+ printf("0x20 - guest CP dispatch type has LIMITHARD "
+ "cap");
+ printed = true;
+ }
+ if (cur[0] & 0x10) {
+ if (printed)
+ printf(", ");
+ printf("0x10 - guest IFL dispatch type has LIMITHARD "
+ "cap");
+ printed = true;
+ }
+ if (cur[0] & 0x08) {
+ if (printed)
+ printf(", ");
+ printf("0x08 - virtual CPs are thread dispatched");
+ printed = true;
+ }
+ if (cur[0] & 0x04) {
+ if (printed)
+ printf(", ");
+ printf("0x04 - virtual IFLs are thread dispatched");
+ printed = true;
+ }
+ if (cur[0] & 0x3) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[0] & 0x3);
+ }
+ printf(" */");
+ }
+
+ print_0x8(", infgflg2", cur, 1, false);
+ print_0x8(", infgval1", cur, 2, false);
+ print_0x8(", infgval2", cur, 3, false);
+# endif /* !VERBOSE */
+
+ print_ebcdic(", infgusid", cur, 4, 8, true, false);
+
+ print_u16(", infgscps", cur, 12, VERBOSE);
+ print_u16(", infgdcps", cur, 14, VERBOSE);
+
+# if VERBOSE
+ print_u8(", infgcpdt", cur, 16, true);
+ if (cur[16] == 0)
+ printf(" /* General Purpose (CP) */");
+ else
+ printf(" /* unknown */");
+
+ if (cur[17] || cur[18] || cur[19])
+ printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ cur[17], cur[18], cur[19]);
+# endif /* !VERBOSE */
+
+ print_weight(", infgcpcc", cur, 20, VERBOSE);
+
+ print_u16(", infgsifl", cur, 24, VERBOSE);
+ print_u16(", infgdifl", cur, 26, VERBOSE);
+
+# if VERBOSE
+ print_u8(", infgifdt", cur, 28, true);
+ if (cur[28] == 0)
+ printf(" /* General Purpose (CP) */");
+ else if (cur[28] == 3)
+ printf(" /* Integrated Facility for Linux (IFL) */");
+ else
+ printf(" /* unknown */");
+
+ if (cur[29] || cur[30] || cur[31])
+ printf(", reserved_2__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ cur[29], cur[30], cur[31]);
+# endif /* !VERBOSE */
+
+ print_weight(", infgifcc", cur, 32, VERBOSE);
+
+ print_0x8(", infgpflg", cur, 36, true);
+# if VERBOSE
+ if (cur[36]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[36] & 0x80) {
+ printf("0x80 - CPU pool's CP virtual type has "
+ "LIMITHARD cap");
+ printed = true;
+ }
+ if (cur[36] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - CPU pool's CP virtual type has "
+ "CAPACITY cap");
+ printed = true;
+ }
+ if (cur[36] & 0x20) {
+ if (printed)
+ printf(", ");
+ printf("0x20 - CPU pool's IFL virtual type has "
+ "LIMITHARD cap");
+ printed = true;
+ }
+ if (cur[36] & 0x10) {
+ if (printed)
+ printf(", ");
+ printf("0x10 - CPU pool's IFL virtual type has "
+ "CAPACITY cap");
+ printed = true;
+ }
+ if (cur[36] & 0x08) {
+ if (printed)
+ printf(", ");
+ printf("0x08 - CPU pool uses prorated core time");
+ printed = true;
+ }
+ if (cur[36] & 0x7) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[36] & 0x7);
+ }
+ printf(" */");
+ }
+
+ if (cur[37] || cur[38] || cur[39])
+ printf(", reserved_3__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ cur[37], cur[38], cur[39]);
+
+ print_ebcdic(", infgpnam", cur, 40, 8, false, true);
+
+ print_weight(", infgpccc", cur, 48, true);
+ print_weight(", infgpicc", cur, 52, true);
+
+ if (hdr_size > 56 && !is_empty(cur + 56, hdr_size - 56)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 56), hdr_size - 56);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+}
+
+static void
+print_sthyi(unsigned char *buf)
+{
+ unsigned char *cur;
+ uint16_t hdr_size;
+ uint16_t offs;
+ bool mt = false;
+
+ hdr_size = *(uint16_t *) (buf + 10);
+ if (hdr_size < 44)
+ error_msg_and_fail("sthyi: header section is too small "
+ "(got %hu, 44 expected)", hdr_size);
+
+ /* INFHFLG1 */
+ print_0x8("{/* header */ {infhflg1", buf, 0, true);
+# if VERBOSE
+ if (buf[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (buf[0] & 0x80) {
+ printf("0x80 - Global Performance Data unavailable");
+ printed = true;
+ }
+ if (buf[0] & 0x40) {
+ if (printed)
+ printf(", ");
+ printf("0x40 - One or more hypervisor levels below "
+ "this level does not support the STHYI "
+ "instruction");
+ printed = true;
+ }
+ if (buf[0] & 0x20) {
+ if (printed)
+ printf(", ");
+ printf("0x20 - Virtualization stack is incomplete");
+ printed = true;
+ }
+ if (buf[0] & 0x10) {
+ if (printed)
+ printf(", ");
+ printf("0x10 - Execution environment is not within a "
+ "logical partition");
+ printed = true;
+ }
+ if (buf[0] & 0xF) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", buf[0] & 0xF);
+ }
+ printf(" */");
+ }
+
+ print_0x8(", infhflg2", buf, 1, false);
+ print_0x8(", infhval1", buf, 2, false);
+ print_0x8(", infhval2", buf, 3, false);
+
+ /* Reserved */
+ if (buf[4] || buf[5] || buf[6])
+ printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
+ buf[4], buf[5], buf[6]);
+
+ print_u8(", infhygct", buf, 7, true);
+ print_u16(", infhtotl", buf, 8, true);
+ print_u16(", infhdln", buf, 10, true);
+ print_u16(", infmoff", buf, 12, true);
+ print_u16(", infmlen", buf, 14, true);
+ print_u16(", infpoff", buf, 16, true);
+ print_u16(", infplen", buf, 18, true);
+ print_u16(", infhoff1", buf, 20, true);
+ print_u16(", infhlen1", buf, 22, true);
+ print_u16(", infgoff1", buf, 24, true);
+ print_u16(", infglen1", buf, 26, true);
+ print_u16(", infhoff2", buf, 28, true);
+ print_u16(", infhlen2", buf, 30, true);
+ print_u16(", infgoff2", buf, 32, true);
+ print_u16(", infglen2", buf, 34, true);
+ print_u16(", infhoff3", buf, 36, true);
+ print_u16(", infhlen3", buf, 38, true);
+ print_u16(", infgoff3", buf, 40, true);
+ print_u16(", infglen3", buf, 42, true);
+
+ if (hdr_size > 44 && !is_empty(buf + 44, hdr_size - 44)) {
+ printf(", ");
+ print_quoted_hex((char *) (buf + 44), hdr_size - 44);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+
+ /* Machine header */
+ offs = *(uint16_t *) (buf + 12);
+ if (!offs)
+ goto partition_hdr;
+
+ hdr_size = *(uint16_t *) (buf + 14);
+ if (hdr_size < 60)
+ error_msg_and_fail("sthyi: machine section is too small "
+ "(got %hu, 60 expected)", hdr_size);
+
+ cur = buf + offs;
+
+ printf(", /* machine */ {");
+
+# if VERBOSE
+ print_0x8("infmflg1", cur, 0, false);
+ if (cur[0])
+ printf(", ");
+ print_0x8("infmflg2", cur, 1, false);
+ if (cur[1])
+ printf(", ");
+# endif /* !VERBOSE */
+ print_0x8("infmval1", cur, 2, true);
+
+ bool cnt_valid = cur[2] & 0x80;
+# if VERBOSE
+ bool id_valid = cur[2] & 0x40;
+ bool name_valid = cur[2] & 0x20;
+
+ printf(" /* processor count validity: %d, machine ID validity: %d, "
+ "machine name validity: %d",
+ !!cnt_valid, !!id_valid, !!name_valid);
+ if (cur[2] & 0x1F)
+ printf(", %#hhx - ???", cur[2] & 0x1F);
+ printf(" */");
+ print_0x8(", infmval2", cur, 3, false);
+# endif /* !VERBOSE */
+
+ print_u16(", infmscps", cur, 4, cnt_valid);
+ print_u16(", infmdcps", cur, 6, cnt_valid);
+ print_u16(", infmsifl", cur, 8, cnt_valid);
+ print_u16(", infmdifl", cur, 10, cnt_valid);
+
+# if VERBOSE
+ print_ebcdic(", infmname", cur, 12, 8, name_valid, false);
+
+ print_ebcdic(", infmtype", cur, 20, 4, id_valid, false);
+ print_ebcdic(", infmmanu", cur, 24, 16, id_valid, false);
+ print_ebcdic(", infmseq", cur, 40, 16, id_valid, false);
+ print_ebcdic(", infmpman", cur, 56, 4, id_valid, false);
+
+ if (hdr_size > 60 && !is_empty(cur + 60, hdr_size - 60)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 60), hdr_size - 60);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+
+partition_hdr:
+ /* Partition header */
+ offs = *(uint16_t *) (buf + 16);
+ if (!offs)
+ goto hv_hdr;
+
+ hdr_size = *(uint16_t *) (buf + 18);
+ if (hdr_size < 56)
+ error_msg_and_fail("sthyi: partition section is too small "
+ "(got %hu, 56 expected)", hdr_size);
+
+ cur = buf + offs;
+
+ print_0x8(", /* partition */ {infpflg1", cur, 0, true);
+ mt = !!(cur[0] & 0x80);
+# if VERBOSE
+ if (cur[0]) {
+ bool printed = false;
+
+ printf(" /* ");
+ if (cur[0] & 0x80) {
+ printf("0x80 - multithreading is enabled");
+ printed = true;
+ }
+ if (cur[0] & 0x7F) {
+ if (printed)
+ printf(", ");
+ printf("%#hhx - ???", cur[0] & 0x7F);
+ }
+ printf(" */");
+ }
+ print_0x8(", infpflg2", cur, 1, false);
+# endif /* !VERBOSE */
+ print_0x8(", infpval1", cur, 2, true);
+
+ bool pcnt_valid = cur[2] & 0x80;
+ bool pid_valid = cur[2] & 0x10;
+# if VERBOSE
+ bool pwcap_valid = cur[2] & 0x40;
+ bool pacap_valid = cur[2] & 0x20;
+ bool lpar_valid = cur[2] & 0x08;
+# endif /* !VERBOSE */
+
+# if VERBOSE
+ printf(" /* processor count validity: %d, partition weight-based "
+ "capacity validity: %d, partition absolute capacity validity: "
+ "%d, partition ID validity: %d, LPAR group absolute capacity "
+ "capping information validity: %d",
+ !!pcnt_valid, !!pwcap_valid, !!pacap_valid, !!pid_valid,
+ !!lpar_valid);
+ if (cur[2] & 0x7)
+ printf(", %#hhx - ???", cur[2] & 0x7);
+ printf(" */");
+
+ print_0x8(", infpval2", cur, 3, false);
+# endif /* !VERBOSE */
+
+ print_u16(", infppnum", cur, 4, pid_valid);
+
+ print_u16(", infpscps", cur, 6, pcnt_valid);
+ print_u16(", infpdcps", cur, 8, pcnt_valid);
+ print_u16(", infpsifl", cur, 10, pcnt_valid);
+ print_u16(", infpdifl", cur, 12, pcnt_valid);
+
+# if VERBOSE
+ if (cur[14] || cur[15])
+ printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\"",
+ cur[14], cur[15]);
+# endif /* !VERBOSE */
+
+ print_ebcdic(", infppnam", cur, 16, 8, pid_valid, false);
+
+# if VERBOSE
+ print_weight(", infpwbcp", cur, 24, pwcap_valid);
+ print_weight(", infpabcp", cur, 28, pacap_valid);
+ print_weight(", infpwbif", cur, 32, pwcap_valid);
+ print_weight(", infpabif", cur, 36, pacap_valid);
+
+ if (print_ebcdic(", infplgnm", cur, 40, 8, false, false)) {
+
+ print_weight(", infplgcp", cur, 48, false);
+ print_weight(", infplgif", cur, 52, false);
+ } else {
+ if (lpar_valid) {
+ printf(", infplgnm=");
+ print_quoted_hex((char *) (cur + 40), 8);
+ }
+
+ print_x32(", infplgcp", cur, 48, false);
+ print_x32(", infplgif", cur, 52, false);
+ }
+
+ if (hdr_size > 56 && !is_empty(cur + 56, hdr_size - 56)) {
+ printf(", ");
+ print_quoted_hex((char *) (cur + 56), hdr_size - 56);
+ }
+# else /* !VERBOSE */
+ printf(", ...");
+# endif /* !VERBOSE */
+
+ printf("}");
+
+hv_hdr:
+ /* Hypervisor/guest headers */
+ print_hypervisor_header(buf, 1, 20, 22, mt);
+ print_guest_header(buf, 1, 24, 26);
+ print_hypervisor_header(buf, 2, 28, 30, mt);
+ print_guest_header(buf, 2, 32, 34);
+ print_hypervisor_header(buf, 3, 36, 38, mt);
+ print_guest_header(buf, 3, 40, 42);
+
+ printf("}");
+}
+
+int
+main(void)
+{
+ static const kernel_ulong_t bogus_func =
+ (kernel_ulong_t) 0xdeafbeefdeadc0deULL;
+ static const kernel_ulong_t bogus_resp_buf =
+ (kernel_ulong_t) 0xfacefeedac0ffeedULL;
+ static const kernel_ulong_t bogus_ret_code =
+ (kernel_ulong_t) 0xf00dfa57decaffedULL;
+ static const kernel_ulong_t bogus_flags =
+ (kernel_ulong_t) 0xfee1deadfa57beefULL;
+
+ unsigned char *buf = tail_alloc(PAGE_SIZE);
+ uint64_t *ret = tail_alloc(sizeof(*ret));
+
+ long rc;
+
+ rc = syscall(__NR_s390_sthyi, 0, 0, 0, 0);
+ printf("s390_sthyi(STHYI_FC_CP_IFL_CAP, NULL, NULL, 0) = %s\n",
+ sprintrc(rc));
+
+ rc = syscall(__NR_s390_sthyi, bogus_func, bogus_resp_buf,
+ bogus_ret_code, bogus_flags);
+ printf("s390_sthyi(%#llx /* STHYI_FC_??? */, %#llx, %#llx, %#llx) = "
+ "%s\n",
+ (unsigned long long) bogus_func,
+ (unsigned long long) bogus_resp_buf,
+ (unsigned long long) bogus_ret_code,
+ (unsigned long long) bogus_flags,
+ sprintrc(rc));
+
+ rc = syscall(__NR_s390_sthyi, bogus_func, buf, ret, 0);
+ printf("s390_sthyi(%#llx /* STHYI_FC_??? */, %p, %p, 0) = %s\n",
+ (unsigned long long) bogus_func, buf, ret, sprintrc(rc));
+
+ rc = syscall(__NR_s390_sthyi, 0, buf, ret, 0);
+ if (rc)
+ error_msg_and_fail("syscall(__NR_s390_sthyi, 0, buf, ret, 0) "
+ "returned unexpected value of %ld", rc);
+
+ printf("s390_sthyi(STHYI_FC_CP_IFL_CAP, ");
+ print_sthyi(buf);
+ printf(", [0], 0) = 0\n");
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("HAVE_ICONV_H && HAVE_ICONV_OPEN && __NR_s390_sthyi")
+
+#endif
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-18 06:35:38
|
By very popular demand.
While we are here, let's refactor the condition for old_mmap_pgoff into
an arch-specific one, as it is used more than in one place.
* NEWS: Mention this.
* configure.ac (case "$host_cpu" in) <s390x>: Set arch_m32 to s390, set
cc_flags_m32 to -m31.
(st_MPERS([m32])): Add s390x.
* defs.h [S390X]: Define NEED_UID16_PARSERS.
* linux/s390/arch_sigreturn.c [!S390_FRAME_PTR] (S390_FRAME_PTR): New
macro, define to s390_frame_ptr.
[!SIGNAL_FRAMESIZE] (SIGNAL_FRAMESIZE): New macro, define to
__SIGNAL_FRAMESIZE.
[!PTR_TYPE] (PTR_TYPE): New macro, define to unsigned long.
(arch_sigreturn): Use S390_FRAME_PTR, SIGNAL_FRAMESIZE, and PTR_TYPE
instead of s390_frame_ptr, __SIGNAL_FRAMESIZE, and pointer-sized type,
respectively.
* linux/s390/get_error.c [!ARCH_REGSET] (ARCH_REGSET): New macro, define
* to s390_regset.
(get_error): Use it instead of s390_regset.
* linux/s390/get_scno.c (arch_get_scno): Likewise.
* linux/s390/get_syscall_args.c (get_syscall_args): Likewise.
* linux/s390/set_error.c (arch_set_error, arch_set_success): Likewise.
* linux/s390/set_scno.c (arch_set_scno): Likewise.
* linux/s390x/arch_regs.c (psw_compat_t, s390_compat_regs,
s390x_regs_union, s390_frame_ptr, s390x_frame_ptr, s390x_io): New
variable.
(s390_regset, s390x_regset, ARCH_REGS_FOR_GETREGSET,
ARCH_IOVEC_FOR_GETREGSET, ARCH_PC_REG, ARCH_PERSONALITY_0_IOV_SIZE,
ARCH_PERSONALITY_1_IOV_SIZE): New macro.
* linux/s390x/arch_regs.h (s390_frame_ptr, s390x_frame_ptr): New
external definitions.
* linux/s390x/arch_rt_sigframe.c: Behave based on tcp->currpers.
* linux/s390x/arch_sigreturn.c: Likewise.
* linux/s390x/get_error.c: Likewise.
* linux/s390x/get_scno.c: Likewise.
* linux/s390x/get_syscall_args.c: Likewise.
* linux/s390x/set_error.c: Likewise.
* linux/s390x/set_scno.c: Likewise.
* linux/s390x/errnoent1.h: New file.
* linux/s390x/ioctls_arch1.h: Likewise.
* linux/s390x/ioctls_inc1.h: Likewise.
* linux/s390x/signalent1.h: Likewise.
* linux/s390x/syscallent1.h: Likewise.
* supported_personalities.h [S390X]: Define SUPPORTED_PERSONALITIES to
2.
* tests/strace-V.test: Add s390 to the list of architectures that have
m32 personality.
* linux/s390/arch_defs.h (HAVE_ARCH_OLD_MMAP_PGOFF): New definition.
* linux/s390x/arch_defs.h: Likewise.
* mem.c: Replace #ifdef S390 with #ifdef HAVE_ARCH_OLD_MMAP_PGOFF.
* pathtrace.c: Likewise.
---
NEWS | 1 +
configure.ac | 4 +++-
defs.h | 2 +-
linux/s390/arch_defs.h | 1 +
linux/s390/arch_sigreturn.c | 16 +++++++++++++---
linux/s390/get_error.c | 10 +++++++---
linux/s390/get_scno.c | 8 ++++++--
linux/s390/get_syscall_args.c | 16 ++++++++++------
linux/s390/set_error.c | 8 ++++++--
linux/s390/set_scno.c | 6 +++++-
linux/s390x/arch_defs.h | 1 +
linux/s390x/arch_regs.c | 37 ++++++++++++++++++++++++++++++++++++-
linux/s390x/arch_regs.h | 3 ++-
linux/s390x/arch_rt_sigframe.c | 5 ++++-
linux/s390x/arch_sigreturn.c | 26 ++++++++++++++++++++++++++
linux/s390x/errnoent1.h | 1 +
linux/s390x/get_error.c | 23 ++++++++++++++++++++++-
linux/s390x/get_scno.c | 21 ++++++++++++++++++++-
linux/s390x/get_syscall_args.c | 22 +++++++++++++++++++++-
linux/s390x/ioctls_arch1.h | 1 +
linux/s390x/ioctls_inc1.h | 1 +
linux/s390x/set_error.c | 34 +++++++++++++++++++++++++++++++++-
linux/s390x/set_scno.c | 21 ++++++++++++++++++++-
linux/s390x/signalent1.h | 1 +
linux/s390x/syscallent1.h | 1 +
mem.c | 4 ++--
pathtrace.c | 2 +-
supported_personalities.h | 1 +
tests/strace-V.test | 2 +-
29 files changed, 248 insertions(+), 31 deletions(-)
create mode 100644 linux/s390x/errnoent1.h
create mode 100644 linux/s390x/ioctls_arch1.h
create mode 100644 linux/s390x/ioctls_inc1.h
create mode 100644 linux/s390x/signalent1.h
create mode 100644 linux/s390x/syscallent1.h
diff --git a/NEWS b/NEWS
index 0dc23d6..550fc38 100644
--- a/NEWS
+++ b/NEWS
@@ -24,6 +24,7 @@ Noteworthy changes in release ?.?? (????-??-??)
* Updated lists of MSG_*, NT_*, and SHM_* constants.
* Added manual page for the strace-log-merge command.
* Updated lists of ioctl commands from Linux 4.15.
+ * Implemented biarch support for s390x.
* Implemented an optional support for symbol demangling in strace -k output
(activated by --with-libiberty configure option).
* Information about availability of demangling and reliable personality
diff --git a/configure.ac b/configure.ac
index 5af1111..a1391c7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -145,6 +145,8 @@ s390)
;;
s390x)
arch=s390x
+ arch_m32=s390
+ cc_flags_m32=-m31
AC_DEFINE([S390X], 1, [Define for the S390x architecture.])
;;
hppa*|parisc*)
@@ -980,7 +982,7 @@ AC_ARG_ENABLE([mpers],
esac],
[enable_mpers=yes])
-st_MPERS([m32], [aarch64|powerpc64|riscv|sparc64|tile|x32|x86_64])
+st_MPERS([m32], [aarch64|powerpc64|riscv|s390x|sparc64|tile|x32|x86_64])
st_MPERS([mx32], [x86_64])
AX_VALGRIND_DFLT([sgcheck], [off])
diff --git a/defs.h b/defs.h
index 3e42908..2311d86 100644
--- a/defs.h
+++ b/defs.h
@@ -335,7 +335,7 @@ extern const struct xlat whence_codes[];
|| defined(M68K) \
|| defined(MICROBLAZE) \
|| defined(RISCV) \
- || defined(S390) \
+ || defined(S390) || defined(S390X) \
|| defined(SH) || defined(SH64) \
|| defined(SPARC) || defined(SPARC64) \
/**/
diff --git a/linux/s390/arch_defs.h b/linux/s390/arch_defs.h
index 285947f..f49582b 100644
--- a/linux/s390/arch_defs.h
+++ b/linux/s390/arch_defs.h
@@ -1 +1,2 @@
#define HAVE_ARCH_OLD_MMAP 1
+#define HAVE_ARCH_OLD_MMAP_PGOFF 1
diff --git a/linux/s390/arch_sigreturn.c b/linux/s390/arch_sigreturn.c
index d1b8598..9c9e0dd 100644
--- a/linux/s390/arch_sigreturn.c
+++ b/linux/s390/arch_sigreturn.c
@@ -1,11 +1,21 @@
+#ifndef S390_FRAME_PTR
+# define S390_FRAME_PTR s390_frame_ptr
+#endif
+#ifndef SIGNAL_FRAMESIZE
+# define SIGNAL_FRAMESIZE __SIGNAL_FRAMESIZE
+#endif
+#ifndef PTR_TYPE
+# define PTR_TYPE unsigned long
+#endif
+
static void
arch_sigreturn(struct tcb *tcp)
{
- unsigned long mask[NSIG_BYTES / sizeof(long)];
- const unsigned long addr = *s390_frame_ptr + __SIGNAL_FRAMESIZE;
+ PTR_TYPE mask[NSIG_BYTES / sizeof(PTR_TYPE)];
+ const PTR_TYPE addr = *S390_FRAME_PTR + SIGNAL_FRAMESIZE;
if (umove(tcp, addr, &mask) < 0) {
- tprintf("{mask=%#lx}", addr);
+ tprintf("{mask=%#llx}", zero_extend_signed_to_ull(addr));
} else {
tprintsigmask_addr("{mask=", mask);
tprints("}");
diff --git a/linux/s390/get_error.c b/linux/s390/get_error.c
index 6d4d0a5..6f3925b 100644
--- a/linux/s390/get_error.c
+++ b/linux/s390/get_error.c
@@ -1,12 +1,16 @@
#include "negated_errno.h"
+#ifndef ARCH_REGSET
+# define ARCH_REGSET s390_regset
+#endif
+
static void
get_error(struct tcb *tcp, const bool check_errno)
{
- if (check_errno && is_negated_errno(s390_regset.gprs[2])) {
+ if (check_errno && is_negated_errno(ARCH_REGSET.gprs[2])) {
tcp->u_rval = -1;
- tcp->u_error = -s390_regset.gprs[2];
+ tcp->u_error = -ARCH_REGSET.gprs[2];
} else {
- tcp->u_rval = s390_regset.gprs[2];
+ tcp->u_rval = ARCH_REGSET.gprs[2];
}
}
diff --git a/linux/s390/get_scno.c b/linux/s390/get_scno.c
index d323860..2661795 100644
--- a/linux/s390/get_scno.c
+++ b/linux/s390/get_scno.c
@@ -1,8 +1,12 @@
+#ifndef ARCH_REGSET
+# define ARCH_REGSET s390_regset
+#endif
+
/* Return codes: 1 - ok, 0 - ignore, other - error. */
static int
arch_get_scno(struct tcb *tcp)
{
- tcp->scno = s390_regset.gprs[2] ?
- s390_regset.gprs[2] : s390_regset.gprs[1];
+ tcp->scno = ARCH_REGSET.gprs[2] ?
+ ARCH_REGSET.gprs[2] : ARCH_REGSET.gprs[1];
return 1;
}
diff --git a/linux/s390/get_syscall_args.c b/linux/s390/get_syscall_args.c
index ebf6c6c..2c35380 100644
--- a/linux/s390/get_syscall_args.c
+++ b/linux/s390/get_syscall_args.c
@@ -1,12 +1,16 @@
+#ifndef ARCH_REGSET
+# define ARCH_REGSET s390_regset
+#endif
+
/* Return -1 on error or 1 on success (never 0!). */
static int
get_syscall_args(struct tcb *tcp)
{
- tcp->u_arg[0] = s390_regset.orig_gpr2;
- tcp->u_arg[1] = s390_regset.gprs[3];
- tcp->u_arg[2] = s390_regset.gprs[4];
- tcp->u_arg[3] = s390_regset.gprs[5];
- tcp->u_arg[4] = s390_regset.gprs[6];
- tcp->u_arg[5] = s390_regset.gprs[7];
+ tcp->u_arg[0] = ARCH_REGSET.orig_gpr2;
+ tcp->u_arg[1] = ARCH_REGSET.gprs[3];
+ tcp->u_arg[2] = ARCH_REGSET.gprs[4];
+ tcp->u_arg[3] = ARCH_REGSET.gprs[5];
+ tcp->u_arg[4] = ARCH_REGSET.gprs[6];
+ tcp->u_arg[5] = ARCH_REGSET.gprs[7];
return 1;
}
diff --git a/linux/s390/set_error.c b/linux/s390/set_error.c
index 7262e5c..f73e578 100644
--- a/linux/s390/set_error.c
+++ b/linux/s390/set_error.c
@@ -1,13 +1,17 @@
+#ifndef ARCH_REGSET
+# define ARCH_REGSET s390_regset
+#endif
+
static int
arch_set_error(struct tcb *tcp)
{
- s390_regset.gprs[2] = -tcp->u_error;
+ ARCH_REGSET.gprs[2] = -tcp->u_error;
return set_regs(tcp->pid);
}
static int
arch_set_success(struct tcb *tcp)
{
- s390_regset.gprs[2] = tcp->u_rval;
+ ARCH_REGSET.gprs[2] = tcp->u_rval;
return set_regs(tcp->pid);
}
diff --git a/linux/s390/set_scno.c b/linux/s390/set_scno.c
index c7a3110..6bb9999 100644
--- a/linux/s390/set_scno.c
+++ b/linux/s390/set_scno.c
@@ -1,6 +1,10 @@
+#ifndef ARCH_REGSET
+# define ARCH_REGSET s390_regset
+#endif
+
static int
arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
{
- s390_regset.gprs[2] = scno;
+ ARCH_REGSET.gprs[2] = scno;
return set_regs(tcp->pid);
}
diff --git a/linux/s390x/arch_defs.h b/linux/s390x/arch_defs.h
index 285947f..f49582b 100644
--- a/linux/s390x/arch_defs.h
+++ b/linux/s390x/arch_defs.h
@@ -1 +1,2 @@
#define HAVE_ARCH_OLD_MMAP 1
+#define HAVE_ARCH_OLD_MMAP_PGOFF 1
diff --git a/linux/s390x/arch_regs.c b/linux/s390x/arch_regs.c
index 62aece7..b5efde7 100644
--- a/linux/s390x/arch_regs.c
+++ b/linux/s390x/arch_regs.c
@@ -1 +1,36 @@
-#include "s390/arch_regs.c"
+typedef struct {
+ uint32_t mask;
+ uint32_t addr;
+} ATTRIBUTE_ALIGNED(8) psw_compat_t;
+
+typedef struct {
+ psw_compat_t psw;
+ uint32_t gprs[NUM_GPRS];
+ uint32_t acrs[NUM_ACRS];
+ uint32_t orig_gpr2;
+} s390_compat_regs;
+
+static union {
+ s390_compat_regs s390_regs;
+ s390_regs s390x_regs;
+} s390x_regs_union;
+
+#define s390_regset s390x_regs_union.s390_regs
+#define s390x_regset s390x_regs_union.s390x_regs
+
+uint32_t *const s390_frame_ptr = &s390_regset.gprs[15];
+unsigned long *const s390x_frame_ptr = &s390x_regset.gprs[15];
+
+static struct iovec s390x_io = {
+ .iov_base = &s390x_regs_union,
+};
+
+
+#define ARCH_REGS_FOR_GETREGSET s390x_regs_union
+#define ARCH_IOVEC_FOR_GETREGSET s390x_io
+#define ARCH_PC_REG \
+ (s390x_io.iov_len == sizeof(s390_regset) ? \
+ s390_regset.psw.addr : s390x_regset.psw.addr)
+
+#define ARCH_PERSONALITY_0_IOV_SIZE sizeof(s390x_regset)
+#define ARCH_PERSONALITY_1_IOV_SIZE sizeof(s390_regset)
diff --git a/linux/s390x/arch_regs.h b/linux/s390x/arch_regs.h
index 14fced4..1f8b57a 100644
--- a/linux/s390x/arch_regs.h
+++ b/linux/s390x/arch_regs.h
@@ -1 +1,2 @@
-#include "s390/arch_regs.h"
+extern uint32_t *const s390_frame_ptr;
+extern unsigned long *const s390x_frame_ptr;
diff --git a/linux/s390x/arch_rt_sigframe.c b/linux/s390x/arch_rt_sigframe.c
index 9731c0e..9c0255f 100644
--- a/linux/s390x/arch_rt_sigframe.c
+++ b/linux/s390x/arch_rt_sigframe.c
@@ -1 +1,4 @@
-#include "s390/arch_rt_sigframe.c"
+FUNC_GET_RT_SIGFRAME_ADDR
+{
+ return tcp->currpers == 1 ? *s390_frame_ptr : *s390x_frame_ptr;
+}
diff --git a/linux/s390x/arch_sigreturn.c b/linux/s390x/arch_sigreturn.c
index 679a395..edc9edd 100644
--- a/linux/s390x/arch_sigreturn.c
+++ b/linux/s390x/arch_sigreturn.c
@@ -1 +1,27 @@
+#include <stdint.h>
+
+#define S390_SIGNAL_FRAMESIZE 96
+
+#define SIGNAL_FRAMESIZE S390_SIGNAL_FRAMESIZE
+#define PTR_TYPE uint32_t
+#define S390_FRAME_PTR s390_frame_ptr
+#define arch_sigreturn s390_arch_sigreturn
#include "s390/arch_sigreturn.c"
+#undef arch_sigreturn
+#undef S390_FRAME_PTR
+#undef PTR_TYPE
+#undef SIGNAL_FRAMESIZE
+
+#define S390_FRAME_PTR s390x_frame_ptr
+#define arch_sigreturn s390x_arch_sigreturn
+#include "s390/arch_sigreturn.c"
+#undef arch_sigreturn
+
+static void
+arch_sigreturn(struct tcb *tcp)
+{
+ if (tcp->currpers == 1)
+ s390_arch_sigreturn(tcp);
+ else
+ s390x_arch_sigreturn(tcp);
+}
diff --git a/linux/s390x/errnoent1.h b/linux/s390x/errnoent1.h
new file mode 100644
index 0000000..c0f7787
--- /dev/null
+++ b/linux/s390x/errnoent1.h
@@ -0,0 +1 @@
+#include "errnoent.h"
diff --git a/linux/s390x/get_error.c b/linux/s390x/get_error.c
index 8e3944c..f35030b 100644
--- a/linux/s390x/get_error.c
+++ b/linux/s390x/get_error.c
@@ -1 +1,22 @@
-#include "s390/get_error.c"
+#include "negated_errno.h"
+
+#define get_error s390x_get_error
+#define ARCH_REGSET s390x_regset
+#include "../s390/get_error.c"
+#undef ARCH_REGSET
+#undef get_error
+
+#define get_error s390_get_error
+#define ARCH_REGSET s390_regset
+#include "../s390/get_error.c"
+#undef ARCH_REGSET
+#undef get_error
+
+static void
+get_error(struct tcb *tcp, const bool check_errno)
+{
+ if (tcp->currpers == 0)
+ s390x_get_error(tcp, check_errno);
+ else
+ s390_get_error(tcp, check_errno);
+}
diff --git a/linux/s390x/get_scno.c b/linux/s390x/get_scno.c
index 71816fb..620d6bc 100644
--- a/linux/s390x/get_scno.c
+++ b/linux/s390x/get_scno.c
@@ -1 +1,20 @@
-#include "s390/get_scno.c"
+#define arch_get_scno s390x_get_scno
+#define ARCH_REGSET s390x_regset
+#include "../s390/get_scno.c"
+#undef ARCH_REGSET
+#undef arch_get_scno
+
+#define arch_get_scno s390_get_scno
+#define ARCH_REGSET s390_regset
+#include "../s390/get_scno.c"
+#undef ARCH_REGSET
+#undef arch_get_scno
+
+static int
+arch_get_scno(struct tcb *tcp)
+{
+ if (s390x_io.iov_len == sizeof(s390_regset))
+ return s390_get_scno(tcp);
+
+ return s390x_get_scno(tcp);
+}
diff --git a/linux/s390x/get_syscall_args.c b/linux/s390x/get_syscall_args.c
index 4ded41d..91c5786 100644
--- a/linux/s390x/get_syscall_args.c
+++ b/linux/s390x/get_syscall_args.c
@@ -1 +1,21 @@
-#include "s390/get_syscall_args.c"
+#define get_syscall_args s390x_get_syscall_args
+#define ARCH_REGSET s390x_regset
+#include "../s390/get_syscall_args.c"
+#undef ARCH_REGSET
+#undef get_syscall_args
+
+#define get_syscall_args s390_get_syscall_args
+#define ARCH_REGSET s390_regset
+#include "../s390/get_syscall_args.c"
+#undef ARCH_REGSET
+#undef get_syscall_args
+
+/* Return -1 on error or 1 on success (never 0!). */
+static int
+get_syscall_args(struct tcb *tcp)
+{
+ if (tcp->currpers == 1)
+ return s390_get_syscall_args(tcp);
+
+ return s390x_get_syscall_args(tcp);
+}
diff --git a/linux/s390x/ioctls_arch1.h b/linux/s390x/ioctls_arch1.h
new file mode 100644
index 0000000..4a16cb5
--- /dev/null
+++ b/linux/s390x/ioctls_arch1.h
@@ -0,0 +1 @@
+#include "s390/ioctls_arch0.h"
diff --git a/linux/s390x/ioctls_inc1.h b/linux/s390x/ioctls_inc1.h
new file mode 100644
index 0000000..e09b6c6
--- /dev/null
+++ b/linux/s390x/ioctls_inc1.h
@@ -0,0 +1 @@
+#include "s390/ioctls_inc0.h"
diff --git a/linux/s390x/set_error.c b/linux/s390x/set_error.c
index 737ddef..187734f 100644
--- a/linux/s390x/set_error.c
+++ b/linux/s390x/set_error.c
@@ -1 +1,33 @@
-#include "s390/set_error.c"
+#define arch_set_error s390x_set_error
+#define arch_set_success s390x_set_success
+#define ARCH_REGSET s390x_regset
+#include "../s390/set_error.c"
+#undef ARCH_REGSET
+#undef arch_set_success
+#undef arch_set_error
+
+#define arch_set_error s390_set_error
+#define arch_set_success s390_set_success
+#define ARCH_REGSET s390_regset
+#include "../s390/set_error.c"
+#undef ARCH_REGSET
+#undef arch_set_success
+#undef arch_set_error
+
+static int
+arch_set_error(struct tcb *tcp)
+{
+ if (tcp->currpers == 1)
+ return s390_set_error(tcp);
+
+ return s390x_set_error(tcp);
+}
+
+static int
+arch_set_success(struct tcb *tcp)
+{
+ if (tcp->currpers == 1)
+ return s390_set_success(tcp);
+
+ return s390x_set_success(tcp);
+}
diff --git a/linux/s390x/set_scno.c b/linux/s390x/set_scno.c
index 9cea4d1..97c9e2b 100644
--- a/linux/s390x/set_scno.c
+++ b/linux/s390x/set_scno.c
@@ -1 +1,20 @@
-#include "s390/set_scno.c"
+#define arch_set_scno s390x_set_scno
+#define ARCH_REGSET s390x_regset
+#include "../s390/set_scno.c"
+#undef ARCH_REGSET
+#undef arch_set_scno
+
+#define arch_set_scno s390_set_scno
+#define ARCH_REGSET s390_regset
+#include "../s390/set_scno.c"
+#undef ARCH_REGSET
+#undef arch_set_scno
+
+static int
+arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
+{
+ if (tcp->currpers == 1)
+ return s390_set_scno(tcp, scno);
+
+ return s390x_set_scno(tcp, scno);
+}
diff --git a/linux/s390x/signalent1.h b/linux/s390x/signalent1.h
new file mode 100644
index 0000000..093cba7
--- /dev/null
+++ b/linux/s390x/signalent1.h
@@ -0,0 +1 @@
+#include "signalent.h"
diff --git a/linux/s390x/syscallent1.h b/linux/s390x/syscallent1.h
new file mode 100644
index 0000000..b6bdaa5
--- /dev/null
+++ b/linux/s390x/syscallent1.h
@@ -0,0 +1 @@
+#include "../s390/syscallent.h"
diff --git a/mem.c b/mem.c
index 6eb974d..1da607d 100644
--- a/mem.c
+++ b/mem.c
@@ -144,7 +144,7 @@ SYS_FUNC(old_mmap)
return RVAL_DECODED | RVAL_HEX;
}
-# ifdef S390
+#if defined HAVE_ARCH_OLD_MMAP_PGOFF
/* Params are pointed to by u_arg[0], offset is in pages */
SYS_FUNC(old_mmap_pgoff)
{
@@ -163,7 +163,7 @@ SYS_FUNC(old_mmap_pgoff)
return RVAL_DECODED | RVAL_HEX;
}
-# endif /* S390 */
+# endif /* HAVE_ARCH_OLD_MMAP_PGOFF */
#endif /* HAVE_ARCH_OLD_MMAP */
/* Params are passed directly, offset is in bytes */
diff --git a/pathtrace.c b/pathtrace.c
index 9b39fc0..99b8711 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -216,7 +216,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set)
#ifdef HAVE_ARCH_OLD_MMAP
case SEN_old_mmap:
-# if defined(S390)
+# ifdef HAVE_ARCH_OLD_MMAP_PGOFF
case SEN_old_mmap_pgoff:
# endif
{
diff --git a/supported_personalities.h b/supported_personalities.h
index 6f18ed3..58ee027 100644
--- a/supported_personalities.h
+++ b/supported_personalities.h
@@ -33,6 +33,7 @@
#elif defined AARCH64 \
|| defined POWERPC64 \
|| defined RISCV \
+ || defined S390X \
|| defined SPARC64 \
|| defined TILE \
|| defined X32
diff --git a/tests/strace-V.test b/tests/strace-V.test
index 677818f..eb05e86 100755
--- a/tests/strace-V.test
+++ b/tests/strace-V.test
@@ -48,7 +48,7 @@ x86_64)
option_m32=$(getoption HAVE_M32_MPERS ' m32-mpers' ' no-m32-mpers')
option_mx32=$(getoption HAVE_MX32_MPERS ' mx32-mpers' ' no-mx32-mpers')
;;
-aarch64|powerpc64|riscv|sparc64|tile|x32)
+aarch64|powerpc64|riscv|s390x|sparc64|tile|x32)
option_m32=$(getoption HAVE_M32_MPERS ' m32-mpers' ' no-m32-mpers')
;;
esac
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-18 06:35:37
|
Because there are never enough print_quoted_string flags.
* defs.h (QUOTE_EMIT_COMMENT): New quoting flag macro constant.
* util.c (string_quote): Emit " /* " in the beginning and " */" in the
end if QUOTE_EMIT_COMMENT is passed.
(print_quoted_string): Increase alloc_size by 7 if QUOTE_EMIT_COMMENT is
passed.
---
defs.h | 1 +
util.c | 9 ++++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 2311d86..51b1355 100644
--- a/defs.h
+++ b/defs.h
@@ -530,6 +530,7 @@ str_strip_prefix_len(const char *str, const char *prefix, size_t prefix_len)
#define QUOTE_OMIT_LEADING_TRAILING_QUOTES 0x02
#define QUOTE_OMIT_TRAILING_0 0x08
#define QUOTE_FORCE_HEX 0x10
+#define QUOTE_EMIT_COMMENT 0x20
extern int string_quote(const char *, char *, unsigned int, unsigned int);
extern int print_quoted_string(const char *, unsigned int, unsigned int);
diff --git a/util.c b/util.c
index 49cb81b..9a99e1a 100644
--- a/util.c
+++ b/util.c
@@ -497,6 +497,8 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
}
}
+ if (style & QUOTE_EMIT_COMMENT)
+ s = stpcpy(s, " /* ");
if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
*s++ = '\"';
@@ -576,6 +578,8 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
*s++ = '\"';
+ if (style & QUOTE_EMIT_COMMENT)
+ s = stpcpy(s, " */");
*s = '\0';
/* Return zero if we printed entire ASCIZ string (didn't truncate it) */
@@ -591,6 +595,8 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
asciz_ended:
if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
*s++ = '\"';
+ if (style & QUOTE_EMIT_COMMENT)
+ s = stpcpy(s, " */");
*s = '\0';
/* Return zero: we printed entire ASCIZ string (didn't truncate it) */
return 0;
@@ -632,7 +638,8 @@ print_quoted_string(const char *str, unsigned int size,
tprints("???");
return -1;
}
- alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2);
+ alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2) +
+ (style & QUOTE_EMIT_COMMENT ? 7 : 0);
if (use_alloca(alloc_size)) {
outstr = alloca(alloc_size);
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-18 06:35:37
|
---
NEWS | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index 550fc38..8b98a40 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,9 @@ Noteworthy changes in release ?.?? (????-??-??)
BPF_MAP_GET_NEXT_ID, BPF_PROG_GET_FD_BY_ID, BPF_MAP_GET_FD_BY_ID,
and BPF_OBJ_GET_INFO_BY_FD commands of bpf syscall.
* Enhanced decoding of get_thread_area, memfd_create, modify_ldt,
- perf_event_open, reboot, set_thread_area, and shmget syscalls.
+ perf_event_open, reboot, s390_guarded_storage, s390_pcio_mmio_read,
+ s390_pci_mmio_write, s390_runtime_instr, s390_sthyi, set_thread_area,
+ and shmget syscalls.
* Implemented decoding of KVM_* ioctl commands.
* Enhanced decoding of getsockopt and setsockopt syscalls for SOL_NETLINK
level.
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-18 06:34:34
|
* linux/s390/syscallent.h ([378]): Change decoder to s390_guarded_storage.
* linux/s390x/syscallent.h: Likewise.
* s390.c (struct guard_storage_control_block,
struct guard_storage_event_parameter_list): New structure type
definition.
(guard_storage_print_gsepl, guard_storage_print_gscb,
SYS_FUNC(s390_guarded_storage)): New function.
(DIV_ROUND_UP): New macro.
* xlat/s390_guarded_storage_commands.in: New file.
---
linux/s390/syscallent.h | 2 +-
linux/s390x/syscallent.h | 2 +-
s390.c | 180 ++++++++++++++++++++++++++++++++++
xlat/s390_guarded_storage_commands.in | 5 +
4 files changed, 187 insertions(+), 2 deletions(-)
create mode 100644 xlat/s390_guarded_storage_commands.in
diff --git a/linux/s390/syscallent.h b/linux/s390/syscallent.h
index dd1fbb1..522c641 100644
--- a/linux/s390/syscallent.h
+++ b/linux/s390/syscallent.h
@@ -407,7 +407,7 @@
[375] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
[376] = { 6, TD, SEN(preadv2), "preadv2" },
[377] = { 6, TD, SEN(pwritev2), "pwritev2" },
-[378] = { 2, 0, SEN(printargs), "s390_guarded_storage" },
+[378] = { 2, 0, SEN(s390_guarded_storage), "s390_guarded_storage" },
[379] = { 5, TD|TF|TSTA, SEN(statx), "statx" },
[380] = { 4, 0, SEN(s390_sthyi), "s390_sthyi" },
diff --git a/linux/s390x/syscallent.h b/linux/s390x/syscallent.h
index fe5b252..8e068c9 100644
--- a/linux/s390x/syscallent.h
+++ b/linux/s390x/syscallent.h
@@ -391,7 +391,7 @@
[375] = { 6, TD, SEN(copy_file_range), "copy_file_range" },
[376] = { 6, TD, SEN(preadv2), "preadv2" },
[377] = { 6, TD, SEN(pwritev2), "pwritev2" },
-[378] = { 2, 0, SEN(printargs), "s390_guarded_storage" },
+[378] = { 2, 0, SEN(s390_guarded_storage), "s390_guarded_storage" },
[379] = { 5, TD|TF|TSTA, SEN(statx), "statx" },
[380] = { 4, 0, SEN(s390_sthyi), "s390_sthyi" },
diff --git a/s390.c b/s390.c
index daaf6a0..a7efd29 100644
--- a/s390.c
+++ b/s390.c
@@ -35,6 +35,7 @@
#include "print_fields.h"
+#include "xlat/s390_guarded_storage_commands.h"
#include "xlat/s390_sthyi_function_codes.h"
/*
@@ -1030,4 +1031,183 @@ SYS_FUNC(s390_sthyi)
return 0;
}
+
+/*
+ * Structures are written based on
+ * https://www-304.ibm.com/support/docview.wss?uid=isg29c69415c1e82603c852576700058075a&aid=1#page=85
+ */
+
+struct guard_storage_control_block {
+ uint64_t reserved;
+ /**
+ * Guard Storage Designation
+ * - Bits 0..J, J == 64-GSC - Guard Storage Origin (GSO)
+ * - Bits 53..55 - Guard Load Shift (GLS)
+ * - Bits 58..63 - Guard Storage Characteristic (GSC), this is J from
+ * the first item, valud values are 25..56.
+ */
+ uint64_t gsd;
+ uint64_t gssm; /**< Guard Storage Section Mask */
+ uint64_t gs_epl_a; /**< Guard Storage Event Parameter List Address */
+};
+
+struct guard_storage_event_parameter_list {
+ uint8_t pad1;
+ /**
+ * Guard Storage Event Addressing Mode
+ * - 0x40 - Extended addressing mode (E)
+ * - 0x80 - Basic addressing mode (B)
+ */
+ uint8_t gs_eam;
+ /**
+ * Guard Storage Event Cause indication
+ * - 0x01 - CPU was in transaction execution mode (TX)
+ * - 0x02 - CPU was in constrained transaction execution mode (CX)
+ * - 0x80 - Instruction causing the event: 0 - LGG, 1 - LLGFGS
+ */
+ uint8_t gs_eci;
+ /**
+ * Guard Storage Event Access Information
+ * - 0x01 - DAT mode
+ * - Bits 1..2 - Address space indication
+ * - Bits 4..7 - AR number
+ */
+ uint8_t gs_eai;
+ uint32_t pad2;
+ uint64_t gs_eha; /**< Guard Storage Event Handler Address */
+ uint64_t gs_eia; /**< Guard Storage Event Instruction Address */
+ uint64_t gs_eoa; /**< Guard Storage Event Operation Address */
+ uint64_t gs_eir; /**< Guard Storage Event Intermediate Result */
+ uint64_t gs_era; /**< Guard Storage Event Return Address */
+};
+
+static void
+guard_storage_print_gsepl(struct tcb *tcp, uint64_t addr)
+{
+ struct guard_storage_event_parameter_list gsepl;
+
+ /* Since it is 64-bit even on 31-bit s390... */
+ if (sizeof(addr) > current_klongsize &&
+ addr >= (1ULL << (current_klongsize * 8))) {
+ tprintf("%#" PRIx64, addr);
+
+ return;
+ }
+
+ if (umove_or_printaddr(tcp, addr, &gsepl))
+ return;
+
+ tprints("[{");
+
+ if (!abbrev(tcp)) {
+ if (gsepl.pad1) {
+ PRINT_FIELD_0X("", gsepl, pad1);
+ tprints(", ");
+ }
+
+ PRINT_FIELD_0X("", gsepl, gs_eam);
+ tprintf_comment("extended addressing mode: %u, "
+ "basic addressing mode: %u",
+ !!(gsepl.gs_eam & 0x2), !!(gsepl.gs_eam & 0x1));
+
+ PRINT_FIELD_0X(", ", gsepl, gs_eci);
+ tprintf_comment("CPU in TX: %u, CPU in CX: %u, instruction: %s",
+ !!(gsepl.gs_eci & 0x80),
+ !!(gsepl.gs_eci & 0x40),
+ gsepl.gs_eci & 0x01 ? "LLGFGS" : "LGG");
+
+ PRINT_FIELD_0X(", ", gsepl, gs_eai);
+ tprintf_comment("DAT: %u, address space indication: %u, "
+ "AR number: %u",
+ !!(gsepl.gs_eai & 0x40),
+ (gsepl.gs_eai >> 4) & 0x3,
+ gsepl.gs_eai & 0xF);
+
+ if (gsepl.pad2)
+ PRINT_FIELD_0X(", ", gsepl, pad2);
+
+ tprints(", ");
+ }
+
+ PRINT_FIELD_X("", gsepl, gs_eha);
+
+ if (!abbrev(tcp)) {
+ PRINT_FIELD_X(", ", gsepl, gs_eia);
+ PRINT_FIELD_X(", ", gsepl, gs_eoa);
+ PRINT_FIELD_X(", ", gsepl, gs_eir);
+ PRINT_FIELD_X(", ", gsepl, gs_era);
+ } else {
+ tprints(", ...");
+ }
+
+ tprints("}]");
+}
+
+# define DIV_ROUND_UP(x,y) (((x) + ((y) - 1)) / (y))
+
+static void
+guard_storage_print_gscb(struct tcb *tcp, kernel_ulong_t addr)
+{
+ struct guard_storage_control_block gscb;
+
+ if (umove_or_printaddr(tcp, addr, &gscb))
+ return;
+
+ tprints("{");
+
+ if (gscb.reserved) {
+ PRINT_FIELD_0X("", gscb, reserved);
+ tprints(", ");
+ }
+
+ PRINT_FIELD_0X("", gscb, gsd);
+
+ if (!abbrev(tcp)) {
+ unsigned int gsc = gscb.gsd & 0x3F;
+ bool gsc_valid = gsc >= 25 && gsc <= 56;
+ tprintf_comment("GS origin: %#*.*" PRIx64 "%s, "
+ "guard load shift: %" PRIu64 ", "
+ "GS characteristic: %u",
+ gsc_valid ? 2 + DIV_ROUND_UP(64 - gsc, 4) : 0,
+ gsc_valid ? DIV_ROUND_UP(64 - gsc, 4) : 0,
+ gsc_valid ? gscb.gsd >> gsc : 0,
+ gsc_valid ? "" : "[invalid]",
+ (gscb.gsd >> 8) & 0x7, gsc);
+ }
+
+ PRINT_FIELD_0X(", ", gscb, gssm);
+
+ tprints(", gs_epl_a=");
+ guard_storage_print_gsepl(tcp, gscb.gs_epl_a);
+
+ tprints("}");
+}
+
+SYS_FUNC(s390_guarded_storage)
+{
+ int command = (int) tcp->u_arg[0];
+ kernel_ulong_t gs_cb = tcp->u_arg[1];
+
+ printxval(s390_guarded_storage_commands, command, "GS_???");
+
+ switch (command) {
+ case GS_ENABLE:
+ case GS_DISABLE:
+ case GS_CLEAR_BC_CB:
+ case GS_BROADCAST:
+ break;
+
+ case GS_SET_BC_CB:
+ tprints(", ");
+ guard_storage_print_gscb(tcp, gs_cb);
+ break;
+
+ default:
+ tprints(", ");
+ printaddr(gs_cb);
+ }
+
+ return RVAL_DECODED;
+}
+
#endif /* defined S390 || defined S390X */
diff --git a/xlat/s390_guarded_storage_commands.in b/xlat/s390_guarded_storage_commands.in
new file mode 100644
index 0000000..410e33e
--- /dev/null
+++ b/xlat/s390_guarded_storage_commands.in
@@ -0,0 +1,5 @@
+GS_ENABLE 0
+GS_DISABLE 1
+GS_SET_BC_CB 2
+GS_CLEAR_BC_CB 3
+GS_BROADCAST 4
--
2.1.4
|
|
From: Eugene S. <ev...@gm...> - 2018-01-18 06:34:33
|
* linux/s390/syscallent.h ([342]): Change decoder to s390_runtime_instr.
* linux/s390x/syscallent.h: Likewise.
* s390.c (SYS_FUNC(s390_runtime_instr)): New function.
* xlat/s390_runtime_instr_commands.in: New file.
---
linux/s390/syscallent.h | 2 +-
linux/s390x/syscallent.h | 2 +-
s390.c | 31 +++++++++++++++++++++++++++++++
xlat/s390_runtime_instr_commands.in | 2 ++
4 files changed, 35 insertions(+), 2 deletions(-)
create mode 100644 xlat/s390_runtime_instr_commands.in
diff --git a/linux/s390/syscallent.h b/linux/s390/syscallent.h
index 522c641..a807c95 100644
--- a/linux/s390/syscallent.h
+++ b/linux/s390/syscallent.h
@@ -371,7 +371,7 @@
[339] = { 2, TD, SEN(setns), "setns" },
[340] = { 6, 0, SEN(process_vm_readv), "process_vm_readv" },
[341] = { 6, 0, SEN(process_vm_writev), "process_vm_writev" },
-[342] = { 2, 0, SEN(printargs), "s390_runtime_instr" },
+[342] = { 2, 0, SEN(s390_runtime_instr), "s390_runtime_instr" },
[343] = { 5, 0, SEN(kcmp), "kcmp" },
[344] = { 3, TD, SEN(finit_module), "finit_module" },
[345] = { 3, 0, SEN(sched_setattr), "sched_setattr" },
diff --git a/linux/s390x/syscallent.h b/linux/s390x/syscallent.h
index 8e068c9..c4a770d 100644
--- a/linux/s390x/syscallent.h
+++ b/linux/s390x/syscallent.h
@@ -355,7 +355,7 @@
[339] = { 2, TD, SEN(setns), "setns" },
[340] = { 6, 0, SEN(process_vm_readv), "process_vm_readv" },
[341] = { 6, 0, SEN(process_vm_writev), "process_vm_writev" },
-[342] = { 2, 0, SEN(printargs), "s390_runtime_instr" },
+[342] = { 2, 0, SEN(s390_runtime_instr), "s390_runtime_instr" },
[343] = { 5, 0, SEN(kcmp), "kcmp" },
[344] = { 3, TD, SEN(finit_module), "finit_module" },
[345] = { 3, 0, SEN(sched_setattr), "sched_setattr" },
diff --git a/s390.c b/s390.c
index a7efd29..dc7bf36 100644
--- a/s390.c
+++ b/s390.c
@@ -36,6 +36,7 @@
#include "print_fields.h"
#include "xlat/s390_guarded_storage_commands.h"
+#include "xlat/s390_runtime_instr_commands.h"
#include "xlat/s390_sthyi_function_codes.h"
/*
@@ -1210,4 +1211,34 @@ SYS_FUNC(s390_guarded_storage)
return RVAL_DECODED;
}
+SYS_FUNC(s390_runtime_instr)
+{
+ int command = (int) tcp->u_arg[0];
+ int signum = (int) tcp->u_arg[1];
+
+ const char *command_descr =
+ xlookup(s390_runtime_instr_commands, command);
+
+ tprintf("%d", command);
+ tprints_comment(command_descr ? command_descr :
+ "S390_RUNTIME_INSTR_???");
+
+ /*
+ * signum is ignored since Linux 4.4, but let's print it for start
+ * command anyway.
+ */
+ switch (command) {
+ case S390_RUNTIME_INSTR_START:
+ tprints(", ");
+ tprints(signame(signum));
+ break;
+
+ case S390_RUNTIME_INSTR_STOP:
+ default:
+ break;
+ }
+
+ return RVAL_DECODED;
+}
+
#endif /* defined S390 || defined S390X */
diff --git a/xlat/s390_runtime_instr_commands.in b/xlat/s390_runtime_instr_commands.in
new file mode 100644
index 0000000..395afc4
--- /dev/null
+++ b/xlat/s390_runtime_instr_commands.in
@@ -0,0 +1,2 @@
+S390_RUNTIME_INSTR_START 0x1
+S390_RUNTIME_INSTR_STOP 0x2
--
2.1.4
|