]> granicus.if.org Git - strace/blob - tests/s390_sthyi.c
tests: do not include <stdbool.h> in files that include "tests.h"
[strace] / tests / s390_sthyi.c
1 /*
2  * Check decoding of s390_sthyi syscall.
3  *
4  * Copyright (c) 2018 The strace developers.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "tests.h"
31 #include <asm/unistd.h>
32
33 #if defined HAVE_ICONV_H && defined HAVE_ICONV_OPEN && defined __NR_s390_sthyi
34
35 # include <errno.h>
36 # include <iconv.h>
37 # include <inttypes.h>
38 # include <stdint.h>
39 # include <stdio.h>
40 # include <unistd.h>
41
42 # include <sys/user.h>
43
44 # define EBCDIC_MAX_LEN 16
45
46 # ifndef VERBOSE
47 #  define VERBOSE 0
48 # endif
49
50 static bool
51 print_0x8(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
52 {
53         if (!zero && !buf[offs])
54                 return false;
55
56         printf("%s=%#02hhx", prefix, buf[offs]);
57
58         return true;
59 }
60
61 static bool
62 print_u8(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
63 {
64         if (!zero && !buf[offs])
65                 return false;
66
67         printf("%s=%hhu", prefix, buf[offs]);
68
69         return true;
70 }
71
72 static bool
73 print_u16(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
74 {
75         uint16_t val = *(uint16_t *) (buf + offs);
76
77         if (!zero && !val)
78                 return false;
79
80         printf("%s=%" PRIu16, prefix, val);
81
82         return true;
83 }
84
85 static bool
86 print_x32(const char *prefix, unsigned char *buf, unsigned int offs, bool zero)
87 {
88         uint32_t val = *(uint32_t *) (buf + offs);
89
90         if (!zero && !val)
91                 return false;
92
93         printf("%s=%#" PRIx32, prefix, val);
94
95         return true;
96 }
97
98 static bool
99 print_weight(const char *prefix, unsigned char *buf, unsigned int offs,
100              bool zero)
101 {
102         uint32_t val = *(uint32_t *) (buf + offs);
103
104         if (print_x32(prefix, buf, offs, zero)) {
105                 if (val)
106                         printf(" /* %u %u/65536 cores */",
107                                val >> 16, val & 0xFFFF);
108                 else
109                         printf(" /* unlimited */");
110
111                 return true;
112         }
113
114         return false;
115 }
116
117 static char *
118 ebcdic2ascii(unsigned char *ebcdic, size_t size)
119 {
120         static char ascii_buf[EBCDIC_MAX_LEN];
121
122         char *ebcdic_pos = (char *) ebcdic;
123         char *ascii_pos = ascii_buf;
124         size_t ebcdic_left = size;
125         size_t ascii_left = size;
126         size_t ret;
127
128         iconv_t cd = iconv_open("ASCII", "EBCDICUS");
129
130         if (size > sizeof(ascii_buf))
131                 error_msg_and_fail("ebcdic2ascii: EBCDIC string is too big: "
132                                    "%zu (maximum is %zu)",
133                                    size, sizeof(ascii_buf));
134         if (cd == (iconv_t) -1)
135                 perror_msg_and_fail("ebcdic2ascii: unable to allocate a "
136                                     "conversion descriptior for converting "
137                                     "EBCDIC to ASCII");
138
139         while ((ret = iconv(cd, &ebcdic_pos, &ebcdic_left,
140             &ascii_pos, &ascii_left)) == (size_t) -1) {
141                 switch (errno) {
142                 case EILSEQ:
143                 case EINVAL: /* That one is quite unexpected, actually */
144                         if (!ebcdic_left || !ascii_left)
145                                 goto ebcdic2ascii_end;
146
147                         *ascii_pos++ = ' ';
148                         ebcdic_pos++;
149                         ebcdic_left--;
150
151                         break;
152
153                 case E2BIG:
154                         perror_msg_and_fail("ebcdic2ascii: ran out of "
155                                             "ASCII buffer unexpectedly");
156                 default:
157                         perror_msg_and_fail("ebcdic2ascii: unexpected error");
158                 }
159         }
160
161 ebcdic2ascii_end:
162         iconv_close(cd);
163
164         if (ebcdic_left != ascii_left)
165                 error_msg_and_fail("ebcdic2ascii: ASCII string differs in size "
166                                    "from EBCDIC");
167
168         return ascii_buf;
169 }
170
171 # if VERBOSE
172 static bool
173 is_empty(unsigned char *ptr, size_t size)
174 {
175         size_t i;
176
177         for (i = 0; !*ptr && i < size; ptr++, i++)
178                 ;
179
180         return i == size;
181 }
182 # endif /* !VERBOSE */
183
184 static bool
185 print_ebcdic(const char *prefix, unsigned char *addr, unsigned int offs,
186              size_t size, bool zero, bool blank)
187 {
188         const char *ascii = ebcdic2ascii(addr + offs, size);
189
190         if (!zero) {
191                 size_t i;
192
193                 for (i = 0; (addr[offs + i] == (blank ? 64 : 0)) && (i < size);
194                     i++)
195                         ;
196
197                 if (i == size)
198                         return false;
199         }
200
201         printf("%s=", prefix);
202         print_quoted_hex((char *) (addr + offs), size);
203         printf(" /* ");
204         print_quoted_memory(ascii, size);
205         printf(" */");
206
207         return true;
208 }
209
210 static void
211 print_hypervisor_header(unsigned char *buf, int level, unsigned int offs_pos,
212                         unsigned int len_pos, bool mt)
213 {
214         uint16_t offs = *(uint16_t *) (buf + offs_pos);
215         uint16_t hdr_size = *(uint16_t *) (buf + len_pos);
216         unsigned char *cur;
217
218         if (!offs)
219                 return;
220         if (hdr_size < 32)
221                 error_msg_and_fail("sthyi: hypervisor %d section is too small "
222                                    "(got %hu, 32 expected)", level, hdr_size);
223
224         cur = buf + offs;
225
226         printf(", /* hypervisor %d */ {infyflg1", level);
227         print_0x8("", cur, 0, true);
228 # if VERBOSE
229         if (cur[0]) {
230                 bool printed = false;
231
232                 printf(" /* ");
233                 if (cur[0] & 0x80) {
234                         printf("0x80 - guest CPU usage had limiting is using "
235                                "the consumption method");
236                         printed = true;
237                 }
238                 if (cur[0] & 0x40) {
239                         if (printed)
240                                 printf(", ");
241                         printf("0x40 - LIMITHARD caps use prorated core time "
242                                "for capping");
243                         printed = true;
244                 }
245                 if (cur[0] & 0x3F) {
246                         if (printed)
247                                 printf(", ");
248                         printf("%#hhx - ???", cur[0] & 0x3F);
249                 }
250                 printf(" */");
251         }
252
253         print_0x8(", infyflg2", cur, 1, false);
254         print_0x8(", infyval1", cur, 2, false);
255         print_0x8(", infyval2", cur, 3, false);
256
257         print_u8(", infytype", cur, 4, true);
258         if (cur[4] == 1)
259                 printf(" /* z/VM is the hypervisor */");
260         else
261                 printf(" /* unknown hypervisor type */");
262
263         if (cur[5])
264                 printf(", reserved_1__=\"\\x%#02hhx\"", cur[5]);
265
266         print_u8(", infycpt",  cur, 6, mt);
267         print_u8(", infyiflt", cur, 7, mt);
268 # endif /* !VERBOSE */
269
270         print_ebcdic(", infysyid", cur, 8,  8, VERBOSE, true);
271         print_ebcdic(", infyclnm", cur, 16, 8, VERBOSE, true);
272
273         print_u16(", infyscps", cur, 24, VERBOSE);
274         print_u16(", infydcps", cur, 26, VERBOSE);
275         print_u16(", infysifl", cur, 28, VERBOSE);
276         print_u16(", infydifl", cur, 30, VERBOSE);
277
278 # if VERBOSE
279         if (hdr_size > 32 && !is_empty(cur + 32, hdr_size - 32)) {
280                 printf(", ");
281                 print_quoted_hex((char *) (cur + 32), hdr_size - 32);
282         }
283 # else /* !VERBOSE */
284         printf(", ...");
285 # endif /* !VERBOSE */
286
287         printf("}");
288 }
289
290 static void
291 print_guest_header(unsigned char *buf, int level, unsigned int offs_pos,
292                    unsigned int len_pos)
293 {
294         uint16_t offs = *(uint16_t *) (buf + offs_pos);
295         uint16_t hdr_size = *(uint16_t *) (buf + len_pos);
296         unsigned char *cur;
297
298         if (!offs)
299                 return;
300         if (hdr_size < 56)
301                 error_msg_and_fail("sthyi: guest %d section is too small "
302                                    "(got %hu, 56 expected)", level, hdr_size);
303
304         cur = buf + offs;
305
306         printf(", /* guest %d */ {infgflg1", level);
307         print_0x8("", cur, 0, true);
308 # if VERBOSE
309         if (cur[0]) {
310                 bool printed = false;
311
312                 printf(" /* ");
313                 if (cur[0] & 0x80) {
314                         printf("0x80 - guest is mobility enabled");
315                         printed = true;
316                 }
317                 if (cur[0] & 0x40) {
318                         if (printed)
319                                 printf(", ");
320                         printf("0x40 - guest has multiple virtual CPU types");
321                         printed = true;
322                 }
323                 if (cur[0] & 0x20) {
324                         if (printed)
325                                 printf(", ");
326                         printf("0x20 - guest CP dispatch type has LIMITHARD "
327                                "cap");
328                         printed = true;
329                 }
330                 if (cur[0] & 0x10) {
331                         if (printed)
332                                 printf(", ");
333                         printf("0x10 - guest IFL dispatch type has LIMITHARD "
334                                "cap");
335                         printed = true;
336                 }
337                 if (cur[0] & 0x08) {
338                         if (printed)
339                                 printf(", ");
340                         printf("0x08 - virtual CPs are thread dispatched");
341                         printed = true;
342                 }
343                 if (cur[0] & 0x04) {
344                         if (printed)
345                                 printf(", ");
346                         printf("0x04 - virtual IFLs are thread dispatched");
347                         printed = true;
348                 }
349                 if (cur[0] & 0x3) {
350                         if (printed)
351                                 printf(", ");
352                         printf("%#hhx - ???", cur[0] & 0x3);
353                 }
354                 printf(" */");
355         }
356
357         print_0x8(", infgflg2", cur, 1, false);
358         print_0x8(", infgval1", cur, 2, false);
359         print_0x8(", infgval2", cur, 3, false);
360 # endif /* !VERBOSE */
361
362         print_ebcdic(", infgusid", cur, 4, 8, true, false);
363
364         print_u16(", infgscps", cur, 12, VERBOSE);
365         print_u16(", infgdcps", cur, 14, VERBOSE);
366
367 # if VERBOSE
368         print_u8(", infgcpdt", cur, 16, true);
369         if (cur[16] == 0)
370                 printf(" /* General Purpose (CP) */");
371         else
372                 printf(" /* unknown */");
373
374         if (cur[17] || cur[18] || cur[19])
375                 printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
376                        cur[17], cur[18], cur[19]);
377 # endif /* !VERBOSE */
378
379         print_weight(", infgcpcc", cur, 20, VERBOSE);
380
381         print_u16(", infgsifl", cur, 24, VERBOSE);
382         print_u16(", infgdifl", cur, 26, VERBOSE);
383
384 # if VERBOSE
385         print_u8(", infgifdt", cur, 28, true);
386         if (cur[28] == 0)
387                 printf(" /* General Purpose (CP) */");
388         else if (cur[28] == 3)
389                 printf(" /* Integrated Facility for Linux (IFL) */");
390         else
391                 printf(" /* unknown */");
392
393         if (cur[29] || cur[30] || cur[31])
394                 printf(", reserved_2__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
395                        cur[29], cur[30], cur[31]);
396 # endif /* !VERBOSE */
397
398         print_weight(", infgifcc", cur, 32, VERBOSE);
399
400         print_0x8(", infgpflg", cur, 36, true);
401 # if VERBOSE
402         if (cur[36]) {
403                 bool printed = false;
404
405                 printf(" /* ");
406                 if (cur[36] & 0x80) {
407                         printf("0x80 - CPU pool's CP virtual type has "
408                                "LIMITHARD cap");
409                         printed = true;
410                 }
411                 if (cur[36] & 0x40) {
412                         if (printed)
413                                 printf(", ");
414                         printf("0x40 - CPU pool's CP virtual type has "
415                                "CAPACITY cap");
416                         printed = true;
417                 }
418                 if (cur[36] & 0x20) {
419                         if (printed)
420                                 printf(", ");
421                         printf("0x20 - CPU pool's IFL virtual type has "
422                                "LIMITHARD cap");
423                         printed = true;
424                 }
425                 if (cur[36] & 0x10) {
426                         if (printed)
427                                 printf(", ");
428                         printf("0x10 - CPU pool's IFL virtual type has "
429                                "CAPACITY cap");
430                         printed = true;
431                 }
432                 if (cur[36] & 0x08) {
433                         if (printed)
434                                 printf(", ");
435                         printf("0x08 - CPU pool uses prorated core time");
436                         printed = true;
437                 }
438                 if (cur[36] & 0x7) {
439                         if (printed)
440                                 printf(", ");
441                         printf("%#hhx - ???", cur[36] & 0x7);
442                 }
443                 printf(" */");
444         }
445
446         if (cur[37] || cur[38] || cur[39])
447                 printf(", reserved_3__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
448                        cur[37], cur[38], cur[39]);
449
450         print_ebcdic(", infgpnam", cur, 40, 8, false, true);
451
452         print_weight(", infgpccc", cur, 48, true);
453         print_weight(", infgpicc", cur, 52, true);
454
455         if (hdr_size > 56 && !is_empty(cur + 56, hdr_size - 56)) {
456                 printf(", ");
457                 print_quoted_hex((char *) (cur + 56), hdr_size - 56);
458         }
459 # else /* !VERBOSE */
460         printf(", ...");
461 # endif /* !VERBOSE */
462
463         printf("}");
464 }
465
466 static void
467 print_sthyi(unsigned char *buf)
468 {
469         unsigned char *cur;
470         uint16_t hdr_size;
471         uint16_t offs;
472         bool mt = false;
473
474         hdr_size = *(uint16_t *) (buf + 10);
475         if (hdr_size < 44)
476                 error_msg_and_fail("sthyi: header section is too small "
477                                    "(got %hu, 44 expected)", hdr_size);
478
479         /* INFHFLG1 */
480         print_0x8("{/* header */ {infhflg1", buf, 0, true);
481 # if VERBOSE
482         if (buf[0]) {
483                 bool printed = false;
484
485                 printf(" /* ");
486                 if (buf[0] & 0x80) {
487                         printf("0x80 - Global Performance Data unavailable");
488                         printed = true;
489                 }
490                 if (buf[0] & 0x40) {
491                         if (printed)
492                                 printf(", ");
493                         printf("0x40 - One or more hypervisor levels below "
494                                "this level does not support the STHYI "
495                                "instruction");
496                         printed = true;
497                 }
498                 if (buf[0] & 0x20) {
499                         if (printed)
500                                 printf(", ");
501                         printf("0x20 - Virtualization stack is incomplete");
502                         printed = true;
503                 }
504                 if (buf[0] & 0x10) {
505                         if (printed)
506                                 printf(", ");
507                         printf("0x10 - Execution environment is not within a "
508                                "logical partition");
509                         printed = true;
510                 }
511                 if (buf[0] & 0xF) {
512                         if (printed)
513                                 printf(", ");
514                         printf("%#hhx - ???", buf[0] & 0xF);
515                 }
516                 printf(" */");
517         }
518
519         print_0x8(", infhflg2", buf, 1, false);
520         print_0x8(", infhval1", buf, 2, false);
521         print_0x8(", infhval2", buf, 3, false);
522
523         /* Reserved */
524         if (buf[4] || buf[5] || buf[6])
525                 printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\\x%#02hhx\"",
526                        buf[4], buf[5], buf[6]);
527
528         print_u8(", infhygct", buf, 7, true);
529         print_u16(", infhtotl", buf, 8, true);
530         print_u16(", infhdln", buf, 10, true);
531         print_u16(", infmoff", buf, 12, true);
532         print_u16(", infmlen", buf, 14, true);
533         print_u16(", infpoff", buf, 16, true);
534         print_u16(", infplen", buf, 18, true);
535         print_u16(", infhoff1", buf, 20, true);
536         print_u16(", infhlen1", buf, 22, true);
537         print_u16(", infgoff1", buf, 24, true);
538         print_u16(", infglen1", buf, 26, true);
539         print_u16(", infhoff2", buf, 28, true);
540         print_u16(", infhlen2", buf, 30, true);
541         print_u16(", infgoff2", buf, 32, true);
542         print_u16(", infglen2", buf, 34, true);
543         print_u16(", infhoff3", buf, 36, true);
544         print_u16(", infhlen3", buf, 38, true);
545         print_u16(", infgoff3", buf, 40, true);
546         print_u16(", infglen3", buf, 42, true);
547
548         if (hdr_size > 44 && !is_empty(buf + 44, hdr_size - 44)) {
549                 printf(", ");
550                 print_quoted_hex((char *) (buf + 44), hdr_size - 44);
551         }
552 # else /* !VERBOSE */
553         printf(", ...");
554 # endif /* !VERBOSE */
555
556         printf("}");
557
558         /* Machine header */
559         offs = *(uint16_t *) (buf + 12);
560         if (!offs)
561                 goto partition_hdr;
562
563         hdr_size = *(uint16_t *) (buf + 14);
564         if (hdr_size < 60)
565                 error_msg_and_fail("sthyi: machine section is too small "
566                                    "(got %hu, 60 expected)", hdr_size);
567
568         cur = buf + offs;
569
570         printf(", /* machine */ {");
571
572 # if VERBOSE
573         print_0x8("infmflg1", cur, 0, false);
574         if (cur[0])
575                 printf(", ");
576         print_0x8("infmflg2", cur, 1, false);
577         if (cur[1])
578                 printf(", ");
579 # endif /* !VERBOSE */
580         print_0x8("infmval1", cur, 2, true);
581
582         bool cnt_valid = cur[2] & 0x80;
583 # if VERBOSE
584         bool id_valid = cur[2] & 0x40;
585         bool name_valid = cur[2] & 0x20;
586
587         printf(" /* processor count validity: %d, machine ID validity: %d, "
588                "machine name validity: %d",
589                !!cnt_valid, !!id_valid, !!name_valid);
590         if (cur[2] & 0x1F)
591                 printf(", %#hhx - ???", cur[2] & 0x1F);
592         printf(" */");
593         print_0x8(", infmval2", cur, 3, false);
594 # endif /* !VERBOSE */
595
596         print_u16(", infmscps", cur, 4,  cnt_valid);
597         print_u16(", infmdcps", cur, 6,  cnt_valid);
598         print_u16(", infmsifl", cur, 8,  cnt_valid);
599         print_u16(", infmdifl", cur, 10, cnt_valid);
600
601 # if VERBOSE
602         print_ebcdic(", infmname", cur, 12, 8, name_valid, false);
603
604         print_ebcdic(", infmtype", cur, 20, 4,  id_valid, false);
605         print_ebcdic(", infmmanu", cur, 24, 16, id_valid, false);
606         print_ebcdic(", infmseq",  cur, 40, 16, id_valid, false);
607         print_ebcdic(", infmpman", cur, 56, 4,  id_valid, false);
608
609         if (hdr_size > 60 && !is_empty(cur + 60, hdr_size - 60)) {
610                 printf(", ");
611                 print_quoted_hex((char *) (cur + 60), hdr_size - 60);
612         }
613 # else /* !VERBOSE */
614         printf(", ...");
615 # endif /* !VERBOSE */
616
617         printf("}");
618
619 partition_hdr:
620         /* Partition header */
621         offs = *(uint16_t *) (buf + 16);
622         if (!offs)
623                 goto hv_hdr;
624
625         hdr_size = *(uint16_t *) (buf + 18);
626         if (hdr_size < 56)
627                 error_msg_and_fail("sthyi: partition section is too small "
628                                    "(got %hu, 56 expected)", hdr_size);
629
630         cur = buf + offs;
631
632         print_0x8(", /* partition */ {infpflg1", cur, 0, true);
633         mt = !!(cur[0] & 0x80);
634 # if VERBOSE
635         if (cur[0]) {
636                 bool printed = false;
637
638                 printf(" /* ");
639                 if (cur[0] & 0x80) {
640                         printf("0x80 - multithreading is enabled");
641                         printed = true;
642                 }
643                 if (cur[0] & 0x7F) {
644                         if (printed)
645                                 printf(", ");
646                         printf("%#hhx - ???", cur[0] & 0x7F);
647                 }
648                 printf(" */");
649         }
650         print_0x8(", infpflg2", cur, 1, false);
651 # endif /* !VERBOSE */
652         print_0x8(", infpval1", cur, 2, true);
653
654         bool pcnt_valid  = cur[2] & 0x80;
655         bool pid_valid   = cur[2] & 0x10;
656 # if VERBOSE
657         bool pwcap_valid = cur[2] & 0x40;
658         bool pacap_valid = cur[2] & 0x20;
659         bool lpar_valid  = cur[2] & 0x08;
660 # endif /* !VERBOSE */
661
662 # if VERBOSE
663         printf(" /* processor count validity: %d, partition weight-based "
664                "capacity validity: %d, partition absolute capacity validity: "
665                "%d, partition ID validity: %d, LPAR group absolute capacity "
666                "capping information validity: %d",
667                !!pcnt_valid, !!pwcap_valid, !!pacap_valid, !!pid_valid,
668                !!lpar_valid);
669         if (cur[2] & 0x7)
670                 printf(", %#hhx - ???", cur[2] & 0x7);
671         printf(" */");
672
673         print_0x8(", infpval2", cur, 3, false);
674 # endif /* !VERBOSE */
675
676         print_u16(", infppnum", cur, 4, pid_valid);
677
678         print_u16(", infpscps", cur, 6,  pcnt_valid);
679         print_u16(", infpdcps", cur, 8,  pcnt_valid);
680         print_u16(", infpsifl", cur, 10, pcnt_valid);
681         print_u16(", infpdifl", cur, 12, pcnt_valid);
682
683 # if VERBOSE
684         if (cur[14] || cur[15])
685                 printf(", reserved_1__=\"\\x%#02hhx\\x%#02hhx\"",
686                        cur[14], cur[15]);
687 # endif /* !VERBOSE */
688
689         print_ebcdic(", infppnam", cur, 16, 8, pid_valid, false);
690
691 # if VERBOSE
692         print_weight(", infpwbcp", cur, 24, pwcap_valid);
693         print_weight(", infpabcp", cur, 28, pacap_valid);
694         print_weight(", infpwbif", cur, 32, pwcap_valid);
695         print_weight(", infpabif", cur, 36, pacap_valid);
696
697         if (print_ebcdic(", infplgnm", cur, 40, 8, false, false)) {
698
699                 print_weight(", infplgcp", cur, 48, false);
700                 print_weight(", infplgif", cur, 52, false);
701         } else {
702                 if (lpar_valid) {
703                         printf(", infplgnm=");
704                         print_quoted_hex((char *) (cur + 40), 8);
705                 }
706
707                 print_x32(", infplgcp", cur, 48, false);
708                 print_x32(", infplgif", cur, 52, false);
709         }
710
711         if (hdr_size > 56 && !is_empty(cur + 56, hdr_size - 56)) {
712                 printf(", ");
713                 print_quoted_hex((char *) (cur + 56), hdr_size - 56);
714         }
715 # else /* !VERBOSE */
716         printf(", ...");
717 # endif /* !VERBOSE */
718
719         printf("}");
720
721 hv_hdr:
722         /* Hypervisor/guest headers */
723         print_hypervisor_header(buf, 1, 20, 22, mt);
724         print_guest_header(buf, 1, 24, 26);
725         print_hypervisor_header(buf, 2, 28, 30, mt);
726         print_guest_header(buf, 2, 32, 34);
727         print_hypervisor_header(buf, 3, 36, 38, mt);
728         print_guest_header(buf, 3, 40, 42);
729
730         printf("}");
731 }
732
733 int
734 main(void)
735 {
736         static const kernel_ulong_t bogus_func =
737                 (kernel_ulong_t) 0xdeafbeefdeadc0deULL;
738         static const kernel_ulong_t bogus_resp_buf =
739                 (kernel_ulong_t) 0xfacefeedac0ffeedULL;
740         static const kernel_ulong_t bogus_ret_code =
741                 (kernel_ulong_t) 0xf00dfa57decaffedULL;
742         static const kernel_ulong_t bogus_flags =
743                 (kernel_ulong_t) 0xfee1deadfa57beefULL;
744
745         unsigned char *buf = tail_alloc(PAGE_SIZE);
746         uint64_t *ret = tail_alloc(sizeof(*ret));
747
748         long rc;
749
750         rc = syscall(__NR_s390_sthyi, 0, 0, 0, 0);
751         printf("s390_sthyi(STHYI_FC_CP_IFL_CAP, NULL, NULL, 0) = %s\n",
752                sprintrc(rc));
753
754         rc = syscall(__NR_s390_sthyi, bogus_func, bogus_resp_buf,
755                      bogus_ret_code, bogus_flags);
756         printf("s390_sthyi(%#llx /* STHYI_FC_??? */, %#llx, %#llx, %#llx) = "
757                "%s\n",
758                (unsigned long long) bogus_func,
759                (unsigned long long) bogus_resp_buf,
760                (unsigned long long) bogus_ret_code,
761                (unsigned long long) bogus_flags,
762                sprintrc(rc));
763
764         rc = syscall(__NR_s390_sthyi, bogus_func, buf, ret, 0);
765         printf("s390_sthyi(%#llx /* STHYI_FC_??? */, %p, %p, 0) = %s\n",
766                (unsigned long long) bogus_func, buf, ret, sprintrc(rc));
767
768         rc = syscall(__NR_s390_sthyi, 0, buf, ret, 0);
769         if (rc)
770                 error_msg_and_skip("syscall(__NR_s390_sthyi, 0, buf, ret, 0) "
771                                    "returned unexpected value of %ld", rc);
772
773         printf("s390_sthyi(STHYI_FC_CP_IFL_CAP, ");
774         print_sthyi(buf);
775         printf(", [0], 0) = 0\n");
776
777         puts("+++ exited with 0 +++");
778         return 0;
779 }
780
781 #else
782
783 SKIP_MAIN_UNDEFINED("HAVE_ICONV_H && HAVE_ICONV_OPEN && __NR_s390_sthyi")
784
785 #endif