(root)/
strace-6.5/
tests-m32/
ioctl_kd.c
       1  /*
       2   * This file is part of ioctl_kd strace test.
       3   *
       4   * Copyright (c) 2019-2021 Eugene Syromyatnikov <evgsyr@gmail.com>
       5   * Copyright (c) 2019-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  
      13  #include <errno.h>
      14  #include <inttypes.h>
      15  #include <limits.h>
      16  #include <signal.h>
      17  #include <stddef.h>
      18  #include <stdio.h>
      19  #include <stdlib.h>
      20  #include <string.h>
      21  #include <unistd.h>
      22  #include "scno.h"
      23  
      24  #include <linux/ioctl.h>
      25  #include <linux/kd.h>
      26  #include <linux/keyboard.h>
      27  
      28  #ifndef RETVAL_INJECTED
      29  # define RETVAL_INJECTED 0
      30  #endif
      31  
      32  #if RETVAL_INJECTED
      33  # define RETVAL "42 (INJECTED)\n"
      34  #else
      35  # define RETVAL "-1 EBADF (%m)\n"
      36  #endif
      37  
      38  #ifndef HAVE_STRUCT_KBDIACRUC
      39  struct kbdiacruc {
      40  	unsigned int diacr, base, result;
      41  };
      42  #endif
      43  
      44  #ifndef HAVE_STRUCT_KBDIACRSUC
      45  struct kbdiacrsuc {
      46  	struct kbdiacruc kbdiacruc[256];
      47  }
      48  #endif
      49  
      50  struct arg_val {
      51  	kernel_ulong_t val;
      52  	const char *str;
      53  };
      54  
      55  static long
      56  sys_ioctl(kernel_long_t fd, kernel_ulong_t cmd, kernel_ulong_t arg)
      57  {
      58  	return syscall(__NR_ioctl, fd, cmd, arg);
      59  }
      60  
      61  static void
      62  check_null_invalid(unsigned int c, const char *s)
      63  {
      64  	static char *p;
      65  
      66  	if (!p)
      67  		p = tail_alloc(1);
      68  
      69  	sys_ioctl(-1, c, 0);
      70  	printf("ioctl(-1, " XLAT_FMT ", NULL) = " RETVAL, XLAT_SEL(c, s));
      71  
      72  	if (F8ILL_KULONG_SUPPORTED) {
      73  		sys_ioctl(-1, c, F8ILL_KULONG_MASK);
      74  		printf("ioctl(-1, " XLAT_FMT ", NULL) = " RETVAL,
      75  		       XLAT_SEL(c, s));
      76  	}
      77  
      78  	sys_ioctl(-1, c, (uintptr_t) p + 1);
      79  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL, XLAT_SEL(c, s), p + 1);
      80  }
      81  
      82  /* GIO_SCRNMAP, PIO_SCRNMAP */
      83  static void
      84  check_scrnmap(unsigned int c, const char *s)
      85  {
      86  	char *scrnmap = tail_alloc(E_TABSZ);
      87  
      88  	int saved_errno;
      89  	long rc;
      90  
      91  	fill_memory_ex(scrnmap, E_TABSZ, 0, 0xff);
      92  
      93  	check_null_invalid(c, s);
      94  
      95  	sys_ioctl(-1, c, (uintptr_t) scrnmap + E_TABSZ - 31);
      96  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
      97  	       XLAT_SEL(c, s), scrnmap + E_TABSZ - 31);
      98  
      99  	sys_ioctl(-1, c, (uintptr_t) scrnmap + E_TABSZ - 32);
     100  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
     101  	       XLAT_SEL(c, s), scrnmap + E_TABSZ - 32);
     102  
     103  	rc = sys_ioctl(-1, c, (uintptr_t) scrnmap + E_TABSZ - 33);
     104  	saved_errno = errno;
     105  	printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     106  	if ((rc >= 0 || c == PIO_SCRNMAP) && (DEFAULT_STRLEN <= 32)) {
     107  		print_quoted_hex(scrnmap + E_TABSZ - 33, 32);
     108  		printf("...");
     109  	} else {
     110  		printf("%p", scrnmap + E_TABSZ - 33);
     111  	}
     112  	errno = saved_errno;
     113  	printf(") = " RETVAL);
     114  
     115  	rc = sys_ioctl(-1, c, (uintptr_t) scrnmap);
     116  	saved_errno = errno;
     117  	printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     118  	if (rc >= 0 || c == PIO_SCRNMAP) {
     119  		print_quoted_hex(scrnmap, MIN(E_TABSZ, DEFAULT_STRLEN));
     120  		if (DEFAULT_STRLEN < E_TABSZ)
     121  			printf("...");
     122  	} else {
     123  		printf("%p", scrnmap);
     124  	}
     125  	errno = saved_errno;
     126  	printf(") = " RETVAL);
     127  }
     128  
     129  /* KDGKBENT, KDSKBENT */
     130  static void
     131  check_kbdent(unsigned int c, const char *s)
     132  {
     133  	static const struct arg_val kbtbl_vecs[] = {
     134  		{ ARG_XLAT_KNOWN(0, "K_NORMTAB") },
     135  		{ ARG_XLAT_KNOWN(0x1, "K_SHIFTTAB") },
     136  		{ ARG_XLAT_KNOWN(0x3, "K_ALTSHIFTTAB") },
     137  		{ ARG_XLAT_KNOWN(0x4, "1<<KG_CTRL") },
     138  		{ ARG_XLAT_KNOWN(0xff,
     139  				 "1<<KG_SHIFT|1<<KG_ALTGR|1<<KG_CTRL"
     140  				 "|1<<KG_ALT|1<<KG_SHIFTL|1<<KG_SHIFTR"
     141  				 "|1<<KG_CTRLL|1<<KG_CTRLR") },
     142  	};
     143  
     144  	static const struct arg_val kbval_vecs[] = {
     145  		{ ARG_STR(0) NRAW(" /* K(KT_LATIN, '\\x00') */") },
     146  		{ ARG_STR(0x10) NRAW(" /* K(KT_LATIN, '\\x10') */") },
     147  		{ ARG_STR(0x20) NRAW(" /* K(KT_LATIN, ' ') */") },
     148  		{ ARG_STR(0x7e) NRAW(" /* K(KT_LATIN, '~') */") },
     149  		{ ARG_STR(0x7f) NRAW(" /* K(KT_LATIN, '\\x7f') */") },
     150  
     151  		{ ARG_STR(0x100) NRAW(" /* K_F1 */") },
     152  		{ ARG_STR(0x11d) NRAW(" /* K_PAUSE */") },
     153  		{ ARG_STR(0x1ff) NRAW(" /* K_UNDO */") },
     154  
     155  		{ ARG_STR(0x200) NRAW(" /* K_HOLE */") },
     156  		{ ARG_STR(0x213) NRAW(" /* K_BARENUMLOCK */") },
     157  		{ ARG_STR(0x214) NRAW(" /* K(KT_SPEC, 0x14) */") },
     158  		{ ARG_STR(0x27d) NRAW(" /* K(KT_SPEC, 0x7d) */") },
     159  		{ ARG_STR(0x27e) NRAW(" /* K_ALLOCATED */") },
     160  		{ ARG_STR(0x27f) NRAW(" /* K_NOSUCHMAP */") },
     161  		{ ARG_STR(0x280) NRAW(" /* K(KT_SPEC, 0x80) */") },
     162  		{ ARG_STR(0x2ff) NRAW(" /* K(KT_SPEC, 0xff) */") },
     163  
     164  		{ ARG_STR(0x300) NRAW(" /* K_P0 */") },
     165  		{ ARG_STR(0x313) NRAW(" /* K_PPARENR */") },
     166  		{ ARG_STR(0x314) NRAW(" /* K(KT_PAD, 0x14) */") },
     167  		{ ARG_STR(0x37f) NRAW(" /* K(KT_PAD, 0x7f) */") },
     168  		{ ARG_STR(0x3ff) NRAW(" /* K(KT_PAD, 0xff) */") },
     169  
     170  		{ ARG_STR(0x400) NRAW(" /* K_DGRAVE */") },
     171  		{ ARG_STR(0x41a) NRAW(" /* K_DGREEK */") },
     172  		{ ARG_STR(0x41b) NRAW(" /* K(KT_DEAD, 0x1b) */") },
     173  		{ ARG_STR(0x47f) NRAW(" /* K(KT_DEAD, 0x7f) */") },
     174  		{ ARG_STR(0x4ff) NRAW(" /* K(KT_DEAD, 0xff) */") },
     175  
     176  		{ ARG_STR(0x500) NRAW(" /* K(KT_CONS, 0) */") },
     177  		{ ARG_STR(0x540) NRAW(" /* K(KT_CONS, 0x40) */") },
     178  		{ ARG_STR(0x5ff) NRAW(" /* K(KT_CONS, 0xff) */") },
     179  
     180  		{ ARG_STR(0x600) NRAW(" /* K_DOWN */") },
     181  		{ ARG_STR(0x603) NRAW(" /* K_UP */") },
     182  		{ ARG_STR(0x604) NRAW(" /* K(KT_CUR, 0x4) */") },
     183  		{ ARG_STR(0x680) NRAW(" /* K(KT_CUR, 0x80) */") },
     184  		{ ARG_STR(0x6ff) NRAW(" /* K(KT_CUR, 0xff) */") },
     185  
     186  		{ ARG_STR(0x700) NRAW(" /* K_SHIFT */") },
     187  		{ ARG_STR(0x708) NRAW(" /* K_CAPSSHIFT */") },
     188  		{ ARG_STR(0x709) NRAW(" /* K(KT_SHIFT, 0x9) */") },
     189  		{ ARG_STR(0x7ff) NRAW(" /* K(KT_SHIFT, 0xff) */") },
     190  
     191  		{ ARG_STR(0x800) NRAW(" /* K(KT_META, '\\x00') */") },
     192  		{ ARG_STR(0x841) NRAW(" /* K(KT_META, 'A') */") },
     193  		{ ARG_STR(0x8ff) NRAW(" /* K(KT_META, '\\xff') */") },
     194  
     195  		{ ARG_STR(0x900) NRAW(" /* K_ASC0 */") },
     196  		{ ARG_STR(0x909) NRAW(" /* K_ASC9 */") },
     197  		{ ARG_STR(0x90a) NRAW(" /* K_HEX0 */") },
     198  		{ ARG_STR(0x919) NRAW(" /* K_HEXf */") },
     199  		{ ARG_STR(0x91a) NRAW(" /* K(KT_ASCII, 0x1a) */") },
     200  		{ ARG_STR(0x9ff) NRAW(" /* K(KT_ASCII, 0xff) */") },
     201  
     202  		{ ARG_STR(0xa00) NRAW(" /* K_SHIFTLOCK */") },
     203  		{ ARG_STR(0xa08) NRAW(" /* K_CAPSSHIFTLOCK */") },
     204  		{ ARG_STR(0xa09) NRAW(" /* K(KT_LOCK, 0x9) */") },
     205  		{ ARG_STR(0xaff) NRAW(" /* K(KT_LOCK, 0xff) */") },
     206  
     207  		{ ARG_STR(0xb00) NRAW(" /* K(KT_LETTER, '\\x00') */") },
     208  		{ ARG_STR(0xb40) NRAW(" /* K(KT_LETTER, '@') */") },
     209  		{ ARG_STR(0xb7f) NRAW(" /* K(KT_LETTER, '\\x7f') */") },
     210  		{ ARG_STR(0xbff) NRAW(" /* K(KT_LETTER, '\\xff') */") },
     211  
     212  		{ ARG_STR(0xc00) NRAW(" /* K_SHIFT_SLOCK */") },
     213  		{ ARG_STR(0xc08) NRAW(" /* K_CAPSSHIFT_SLOCK */") },
     214  		{ ARG_STR(0xc09) NRAW(" /* K(KT_SLOCK, 0x9) */") },
     215  		{ ARG_STR(0xcff) NRAW(" /* K(KT_SLOCK, 0xff) */") },
     216  
     217  		{ ARG_STR(0xd00) NRAW(" /* K(KT_DEAD2, '\\x00') */") },
     218  		{ ARG_STR(0xd13) NRAW(" /* K(KT_DEAD2, '\\x13') */") },
     219  		{ ARG_STR(0xd5c) NRAW(" /* K(KT_DEAD2, '\\\\') */") },
     220  		{ ARG_STR(0xdff) NRAW(" /* K(KT_DEAD2, '\\xff') */") },
     221  
     222  		{ ARG_STR(0xe00) NRAW(" /* K_BRL_BLANK */") },
     223  		{ ARG_STR(0xe0a) NRAW(" /* K_BRL_DOT10 */") },
     224  		{ ARG_STR(0xe0b) NRAW(" /* K(KT_BRL, 0xb) */") },
     225  		{ ARG_STR(0xeff) NRAW(" /* K(KT_BRL, 0xff) */") },
     226  
     227  		{ ARG_STR(0xf00) NRAW(" /* K(0xf, 0) */") },
     228  		{ ARG_STR(0xfed) NRAW(" /* K(0xf, 0xed) */") },
     229  		{ ARG_STR(0xf00d) NRAW(" /* K(0xf0, 0xd) */") },
     230  	};
     231  
     232  	struct kbentry *kbe = tail_alloc(sizeof(*kbe));
     233  
     234  	int saved_errno;
     235  	long rc;
     236  
     237  	check_null_invalid(c, s);
     238  
     239  	kbe->kb_value = 0xa8a8;
     240  	sys_ioctl(-1, c, (uintptr_t) kbe + 2);
     241  	printf("ioctl(-1, " XLAT_FMT ", {kb_table=%s, kb_index=168%s}"
     242  	       ") = " RETVAL,
     243  	       XLAT_SEL(c, s), XLAT_STR(1<<KG_ALT|1<<KG_SHIFTR|1<<KG_CTRLR),
     244  	       RETVAL_INJECTED || c == KDSKBENT ? ", kb_value=???" : ""
     245  	       );
     246  
     247  	for (size_t i = 0;
     248  	     i < MAX(ARRAY_SIZE(kbtbl_vecs), ARRAY_SIZE(kbval_vecs)); i++) {
     249  		kbe->kb_table = kbtbl_vecs[i % ARRAY_SIZE(kbtbl_vecs)].val;
     250  		kbe->kb_index = i * 3141;
     251  		kbe->kb_value = kbval_vecs[i % ARRAY_SIZE(kbval_vecs)].val;
     252  
     253  		rc = sys_ioctl(-1, c, (uintptr_t) kbe);
     254  		saved_errno = errno;
     255  		printf("ioctl(-1, " XLAT_FMT ", {kb_table=%s, kb_index=%u",
     256  		       XLAT_SEL(c, s),
     257  		       kbtbl_vecs[i % ARRAY_SIZE(kbtbl_vecs)].str,
     258  		       kbe->kb_index);
     259  		if (rc >= 0 || c == KDSKBENT) {
     260  			printf(", kb_value=%s",
     261  			       kbval_vecs[i % ARRAY_SIZE(kbval_vecs)].str);
     262  		}
     263  		errno = saved_errno;
     264  		printf("}) = " RETVAL);
     265  	}
     266  }
     267  
     268  /* KDGKBSENT, KDSKBSENT */
     269  static void
     270  check_kbdsent(unsigned int c, const char *s)
     271  {
     272  	static struct arg_val kbse_offsets[] = {
     273  		{ sizeof(struct kbsentry) - 1, "KVAL(K_F2)" },
     274  		{ sizeof(struct kbsentry) - 2, "KVAL(K_F1)" },
     275  		{ sizeof(struct kbsentry) - 34, "KVAL(K_F214)" },
     276  		{ sizeof(struct kbsentry) - 35, "KVAL(K_F213)" },
     277  		{ 1, "KVAL(K_F1)" },
     278  		{ 0, "KVAL(K_F245)" },
     279  	};
     280  
     281  	static const struct arg_val kbfn_vecs[] = {
     282  		{ ARG_XLAT_KNOWN(0, "KVAL(K_F1)") },
     283  		{ ARG_XLAT_KNOWN(0x10, "KVAL(K_F17)") },
     284  		{ ARG_XLAT_KNOWN(0x7f, "KVAL(K_F118)") },
     285  		{ ARG_XLAT_KNOWN(0xff, "KVAL(K_UNDO)") },
     286  	};
     287  
     288  	struct kbsentry *kbse = tail_alloc(sizeof(*kbse));
     289  
     290  	int saved_errno;
     291  
     292  	fill_memory_ex(kbse->kb_string, sizeof(kbse->kb_string), 0, 0xff);
     293  	kbse->kb_func = 0xfe;
     294  
     295  	check_null_invalid(c, s);
     296  
     297  	for (size_t i = 0; i < ARRAY_SIZE(kbse_offsets); i++) {
     298  		sys_ioctl(-1, c,
     299  			  (uintptr_t) kbse + kbse_offsets[i].val);
     300  		saved_errno = errno;
     301  		printf("ioctl(-1, " XLAT_FMT ", {kb_func=%s",
     302  	               XLAT_SEL(c, s),
     303  		       sprintxlat(kbse_offsets[i].str,
     304  				  (kbse_offsets[i].val + 254) % 0xff, NULL));
     305  
     306  		if (RETVAL_INJECTED || c == KDSKBSENT) {
     307  			printf(", kb_string=");
     308  			if (kbse_offsets[i].val < 255 * 2) {
     309  				print_quoted_stringn(
     310  					(char *) kbse->kb_string +
     311  					kbse_offsets[i].val,
     312  					MIN(DEFAULT_STRLEN,
     313  					    sizeof(kbse->kb_string)));
     314  			} else {
     315  				printf("???");
     316  			}
     317  		}
     318  
     319  		errno = saved_errno;
     320  		printf("}) = " RETVAL);
     321  	}
     322  
     323  	fill_memory_ex(kbse->kb_string, sizeof(kbse->kb_string), 0x80, 0x7f);
     324  	kbse->kb_func = KVAL(K_PGDN);
     325  
     326  	sys_ioctl(-1, c, (uintptr_t) kbse);
     327  	saved_errno = errno;
     328  	printf("ioctl(-1, " XLAT_FMT ", {kb_func="
     329  	       XLAT_KNOWN(0x19, "KVAL(K_PGDN)"),
     330                 XLAT_SEL(c, s));
     331  
     332  	if (RETVAL_INJECTED || c == KDSKBSENT) {
     333  		printf(", kb_string=");
     334  		print_quoted_stringn((char *) kbse->kb_string,
     335  				     MIN(DEFAULT_STRLEN,
     336  					 sizeof(kbse->kb_string)));
     337  	}
     338  
     339  	errno = saved_errno;
     340  	printf("}) = " RETVAL);
     341  
     342  	for (size_t i = 0; i < ARRAY_SIZE(kbfn_vecs); i++) {
     343  		kbse->kb_func = kbfn_vecs[i].val;
     344  		fill_memory_ex(kbse->kb_string, sizeof(kbse->kb_string),
     345  			       i * 357 + 42, i * 257 + 13);
     346  
     347  		sys_ioctl(-1, c, (uintptr_t) kbse);
     348  		saved_errno = errno;
     349  		printf("ioctl(-1, " XLAT_FMT ", {kb_func=%s",
     350  		       XLAT_SEL(c, s),
     351  		       kbfn_vecs[i].str);
     352  
     353  		if (RETVAL_INJECTED || c == KDSKBSENT) {
     354  			printf(", kb_string=");
     355  			print_quoted_stringn((char *) kbse->kb_string,
     356  					     MIN(DEFAULT_STRLEN,
     357  						 sizeof(kbse->kb_string)));
     358  		}
     359  
     360  		errno = saved_errno;
     361  		printf("}) = " RETVAL);
     362  	}
     363  
     364  	if (DEFAULT_STRLEN < sizeof(kbse->kb_string) &&
     365  	    (RETVAL_INJECTED || c == KDSKBSENT)) {
     366  		/*
     367  		 * Check how struct kbsentry.kb_string is printed when it
     368  		 * starts DEFAULT_STRLEN / 2 bytes before the page boundary.
     369  		 */
     370  		struct kbsentry *const k =
     371  			tail_alloc(get_page_size() +
     372  				   DEFAULT_STRLEN / 2 + sizeof(k->kb_func));
     373  		fill_memory_ex(k->kb_string, DEFAULT_STRLEN - 1, '0', 10);
     374  		k->kb_string[DEFAULT_STRLEN - 1] = '\0';
     375  
     376  		sys_ioctl(-1, c, (uintptr_t) k);
     377  		printf("ioctl(-1, " XLAT_FMT ", {kb_func="
     378  		       XLAT_KNOWN(0xff, "KVAL(K_UNDO)")
     379  		       ", kb_string=\"%s\"}) = " RETVAL,
     380  		       XLAT_SEL(c, s), k->kb_string);
     381  	}
     382  }
     383  
     384  /* KDGKBDIACR, KDSKBDIACR */
     385  static void
     386  check_diacr(unsigned int c, const char *s)
     387  {
     388  	static struct arg_val diac_vecs[] = {
     389  		{ 0,    "\\x00" },
     390  		{ '\n', "\\n" },
     391  		{ ' ',  " " },
     392  		{ 'a',  "a" },
     393  		{ '~',  "~" },
     394  		{ '\'',  "\\'" },
     395  		{ '\\',  "\\\\" },
     396  		{ '"',  "\"" },
     397  		{ '`',  "`" },
     398  		{ 0x7f, "\\x7f" },
     399  		{ 0xff, "\\xff" },
     400  	};
     401  
     402  	struct kbdiacrs *diacrs0 = tail_alloc(sizeof(diacrs0->kb_cnt));
     403  	struct kbdiacrs *diacrs1 = tail_alloc(sizeof(diacrs1->kb_cnt) +
     404  					      4 * sizeof(struct kbdiacr));
     405  	struct kbdiacrs *diacrs2 = tail_alloc(sizeof(*diacrs2));
     406  
     407  	int saved_errno;
     408  
     409  	check_null_invalid(c, s);
     410  
     411  	for (size_t i = 0; i < 2; i++) {
     412  		diacrs0->kb_cnt = i;
     413  		sys_ioctl(-1, c, (uintptr_t) diacrs0);
     414  		saved_errno = errno;
     415  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     416  		if (RETVAL_INJECTED || c == KDSKBDIACR) {
     417  			printf("{kb_cnt=%zu, kbdiacr=", i);
     418  			if (i)
     419  				printf("%p}", diacrs0->kbdiacr);
     420  			else
     421  				printf("[]}");
     422  		} else {
     423  			printf("%p", diacrs0);
     424  		}
     425  		errno = saved_errno;
     426  		printf(") = " RETVAL);
     427  	}
     428  
     429  	fill_memory_ex(diacrs1->kbdiacr, 4 * sizeof(struct kbdiacr), 40, 44);
     430  	for (size_t i = 0; i < 7; i++) {
     431  		diacrs1->kb_cnt = i;
     432  		sys_ioctl(-1, c, (uintptr_t) diacrs1);
     433  		saved_errno = errno;
     434  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     435  		if (RETVAL_INJECTED || c == KDSKBDIACR) {
     436  			printf("{kb_cnt=%zu, kbdiacr=[", i);
     437  			for (size_t j = 0; j < MIN(i, 4); j++)
     438  				printf("%s{diacr='%c', base='%c', result='%c'}",
     439  				       j ? ", " : "", (int) (40 + j * 3),
     440  				       (int) (41 + j * 3), (int) (42 + j * 3));
     441  
     442  			if (i > 4)
     443  				printf(", ... /* %p */", diacrs1->kbdiacr + 4);
     444  			printf("]}");
     445  		} else {
     446  			printf("%p", diacrs1);
     447  		}
     448  		errno = saved_errno;
     449  		printf(") = " RETVAL);
     450  	}
     451  
     452  	fill_memory_ex(diacrs2->kbdiacr, sizeof(diacrs2->kbdiacr), 40, 52);
     453  
     454  	for (size_t i = ARRAY_SIZE(diacrs2->kbdiacr) - 1;
     455  	     i < ARRAY_SIZE(diacrs2->kbdiacr) + 3; i++) {
     456  		diacrs2->kb_cnt = i;
     457  		sys_ioctl(-1, c, (uintptr_t) diacrs2);
     458  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     459  		saved_errno = errno;
     460  		if (RETVAL_INJECTED || c == KDSKBDIACR) {
     461  			printf("{kb_cnt=%zu, kbdiacr=[", i);
     462  			for (size_t j = 0;
     463  			     j < MIN(i, MIN(DEFAULT_STRLEN,
     464  					    ARRAY_SIZE(diacrs2->kbdiacr))); j++)
     465  				printf("%s{diacr='%c', base='%c', result='%c'}",
     466  				       j ? ", " : "",
     467  				       (int) (40 + (j * 3 + 0) % 52),
     468  				       (int) (40 + (j * 3 + 1) % 52),
     469  				       (int) (40 + (j * 3 + 2) % 52));
     470  
     471  			if (i > MIN(DEFAULT_STRLEN,
     472  				    ARRAY_SIZE(diacrs2->kbdiacr)))
     473  				printf(", ...");
     474  			printf("]}");
     475  		} else {
     476  			printf("%p", diacrs2);
     477  		}
     478  		errno = saved_errno;
     479  		printf(") = " RETVAL);
     480  	}
     481  
     482  	for (size_t i = 0; i< ARRAY_SIZE(diac_vecs); i++) {
     483  		diacrs2->kbdiacr[i].diacr  = diac_vecs[i].val;
     484  		diacrs2->kbdiacr[i].base   = diac_vecs[i].val;
     485  		diacrs2->kbdiacr[i].result = diac_vecs[i].val;
     486  	}
     487  	diacrs2->kb_cnt = ARRAY_SIZE(diac_vecs);
     488  
     489  	sys_ioctl(-1, c, (uintptr_t) diacrs2);
     490  	printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     491  	saved_errno = errno;
     492  	if (RETVAL_INJECTED || c == KDSKBDIACR) {
     493  		printf("{kb_cnt=%zu, kbdiacr=[", ARRAY_SIZE(diac_vecs));
     494  		for (size_t i = 0; i < ARRAY_SIZE(diac_vecs); i++)
     495  			printf("%1$s{diacr='%2$s', base='%2$s', result='%2$s'}",
     496  			       i ? ", " : "", diac_vecs[i].str);
     497  		printf("]}");
     498  	} else {
     499  		printf("%p", diacrs2);
     500  	}
     501  	errno = saved_errno;
     502  	printf(") = " RETVAL);
     503  }
     504  
     505  /* KDGETKEYCODE, KDSETKEYCODE */
     506  static void
     507  check_xetkeycode(unsigned int c, const char *s)
     508  {
     509  	static const struct kbkeycode args[] = {
     510  		{ 0, 0 },
     511  		{ 0, 0xdeadface },
     512  		{ 0xfacefeed, 0 },
     513  		{ 0xdecaffed, 0xdadfaced },
     514  	};
     515  	struct kbkeycode *tail_arg = tail_alloc(sizeof(args[0]));
     516  
     517  	check_null_invalid(c, s);
     518  
     519  	sys_ioctl(-1, c, (uintptr_t) tail_arg + 4);
     520  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
     521  	       XLAT_SEL(c, s), (char *) tail_arg + 4);
     522  
     523  	for (size_t i = 0; i < ARRAY_SIZE(args); i++) {
     524  		memcpy(tail_arg, args + i, sizeof(args[i]));
     525  
     526  		sys_ioctl(-1, c, (uintptr_t) tail_arg);
     527  		printf("ioctl(-1, " XLAT_FMT ", {scancode=%#x, keycode=%#x",
     528  		       XLAT_SEL(c, s), args[i].scancode, args[i].keycode);
     529  		if ((c == KDGETKEYCODE) && RETVAL_INJECTED)
     530  			printf(" => %#x", args[i].keycode);
     531  		printf("}) = " RETVAL);
     532  	}
     533  }
     534  
     535  /* KDKBDREP */
     536  static void
     537  check_kbdrep(unsigned int c, const char *s)
     538  {
     539  	static const struct kbd_repeat args[] = {
     540  		{ -1, -1 },
     541  		{ -1234567890,  0 },
     542  		{  0, -2134567890 },
     543  		{ 314159265, 271828182 },
     544  	};
     545  	struct kbd_repeat *tail_arg = tail_alloc(sizeof(args[0]));
     546  
     547  	check_null_invalid(c, s);
     548  
     549  	sys_ioctl(-1, c, (uintptr_t) tail_arg + 4);
     550  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
     551  	       XLAT_SEL(c, s), (char *) tail_arg + 4);
     552  
     553  	for (size_t i = 0; i < ARRAY_SIZE(args); i++) {
     554  		memcpy(tail_arg, args + i, sizeof(args[i]));
     555  
     556  		sys_ioctl(-1, c, (uintptr_t) tail_arg);
     557  		printf("ioctl(-1, " XLAT_FMT, XLAT_SEL(c, s));
     558  		for (size_t j = 0; j < 1 + RETVAL_INJECTED; j++) {
     559  			printf("%s {delay=%d, period=%d}",
     560  			       j ? " =>" : ",", args[i].delay, args[i].period);
     561  		}
     562  		printf(") = " RETVAL);
     563  	}
     564  }
     565  
     566  /* GIO_FONT, PIO_FONT */
     567  static void
     568  check_font(unsigned int c, const char *s)
     569  {
     570  	char *data = tail_alloc(8192);
     571  	char *data_end = data + 8192;
     572  
     573  	fill_memory(data, 8192);
     574  
     575  	check_null_invalid(c, s);
     576  
     577  	sys_ioctl(-1, c, (uintptr_t) data_end - 31);
     578  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
     579  	       XLAT_SEL(c, s), data_end - 31);
     580  
     581  	sys_ioctl(-1, c, (uintptr_t) data_end - 32);
     582  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
     583  	       XLAT_SEL(c, s), data_end - 32);
     584  
     585  	bool ok = (DEFAULT_STRLEN == 32)
     586  		   && ((c != GIO_FONT) || RETVAL_INJECTED);
     587  	sys_ioctl(-1, c, (uintptr_t) data_end - 33);
     588  	printf("ioctl(-1, " XLAT_FMT ", %s", XLAT_SEL(c, s), ok ? "\"" : "");
     589  	if (ok) {
     590  		for (size_t i = 8192 - 33; i < 8192 - 1; i++)
     591  			printf("\\x%hhx", (unsigned char) ( 0x80 + i % 0x80));
     592  	} else {
     593  		printf("%p", data_end - 33);
     594  	}
     595  	printf("%s) = " RETVAL, ok ? "\"..." : "");
     596  
     597  	ok = (c != GIO_FONT) || RETVAL_INJECTED;
     598  	sys_ioctl(-1, c, (uintptr_t) data_end - 1025);
     599  	printf("ioctl(-1, " XLAT_FMT ", %s", XLAT_SEL(c, s), ok ? "\"" : "");
     600  	if (ok) {
     601  		for (size_t i = 8192 - 1025; i < 8192 - 1025 + DEFAULT_STRLEN;
     602  		     i++)
     603  			printf("\\x%hhx", (unsigned char) (0x80 + i % 0x80));
     604  	} else {
     605  		printf("%p", data_end - 1025);
     606  	}
     607  	printf("%s) = " RETVAL, ok ? "\"..." : "");
     608  
     609  	sys_ioctl(-1, c, (uintptr_t) data);
     610  	printf("ioctl(-1, " XLAT_FMT ", %s", XLAT_SEL(c, s), ok ? "\"" : "");
     611  	if (ok) {
     612  		for (size_t i = 0; i < DEFAULT_STRLEN; i++)
     613  			printf("\\x%hhx", (unsigned char) (0x80 + i % 0x80));
     614  	} else {
     615  		printf("%p", data);
     616  	}
     617  	printf("%s) = " RETVAL, ok ? "\"..." : "");
     618  }
     619  
     620  /* GIO_UNIMAP, PIO_UNIMAP */
     621  static void
     622  check_unimap(unsigned int c, const char *s)
     623  {
     624  	struct unimapdesc *umd = tail_alloc(sizeof(*umd));
     625  	struct unipair *ups = tail_alloc(33 * sizeof(*ups));
     626  
     627  	fill_memory16(ups, 33 * sizeof(*ups));
     628  	ups[0].unicode = 0;
     629  	ups[0].fontpos = 0;
     630  
     631  	check_null_invalid(c, s);
     632  
     633  	umd->entry_ct = 0xdead;
     634  	umd->entries = NULL;
     635  	sys_ioctl(-1, c, (uintptr_t) umd);
     636  	printf("ioctl(-1, " XLAT_FMT ", {entry_ct=57005%s, entries=NULL}) = "
     637  	       RETVAL, XLAT_SEL(c, s), c == GIO_UNIMAP ? " => 57005" : "");
     638  
     639  	umd->entry_ct = 0;
     640  	umd->entries = ups + 33;
     641  	sys_ioctl(-1, c, (uintptr_t) umd);
     642  	printf("ioctl(-1, " XLAT_FMT ", {entry_ct=0%s, entries=",
     643  	       XLAT_SEL(c, s), c == GIO_UNIMAP ? " => 0" : "");
     644  	if (c == GIO_UNIMAP && !RETVAL_INJECTED)
     645  		printf("%p", ups + 33);
     646  	else
     647  		printf("[]");
     648  	printf("}) = " RETVAL);
     649  
     650  	umd->entry_ct = 1;
     651  	sys_ioctl(-1, c, (uintptr_t) umd);
     652  	printf("ioctl(-1, " XLAT_FMT ", {entry_ct=1%s, entries=%p}) = " RETVAL,
     653  	       XLAT_SEL(c, s), c == GIO_UNIMAP ? " => 1" : "", ups + 33);
     654  
     655  	for (unsigned int i = 0; i < 6; i++) {
     656  		umd->entry_ct = 31 + (i + 1) / 2;
     657  		umd->entries = ups + 2 - i / 2;
     658  		sys_ioctl(-1, c, (uintptr_t) umd);
     659  		printf("ioctl(-1, " XLAT_FMT ", {entry_ct=%u",
     660  		       XLAT_SEL(c, s), 31 + (i + 1) / 2);
     661  
     662  		if (c == GIO_UNIMAP) {
     663  			printf(" => %u", 31 + (i + 1) / 2);
     664  #if !RETVAL_INJECTED
     665  			printf(", entries=%p}) = " RETVAL, ups + 2 - i / 2);
     666  			continue;
     667  #endif
     668  		}
     669  
     670  		printf(", entries=[%s", i > 3 ? "{unicode=0, fontpos=0}" : "");
     671  
     672  		for (unsigned int j = 0; j < 31
     673  #if DEFAULT_STRLEN > 32
     674  						+ MIN(i / 2, 1)
     675  #else
     676  						+ ((i / 2) == 1)
     677  #endif
     678  		     ; j++) {
     679  			printf("%s{unicode=%#x, fontpos=%#x}",
     680  			       j == 0 && i < 4 ? "" : ", ",
     681  			       0x80c4 + 2 * (j - MIN(i / 2, 1)),
     682  			       0x80c5 + 2 * (j - MIN(i / 2, 1)));
     683  		}
     684  		if (i == 1 || i == 3 || ((DEFAULT_STRLEN > 32) && (i == 5)))
     685  			printf(", ... /* %p */", ups + 33);
     686  #if DEFAULT_STRLEN == 32
     687  		if (i > 3)
     688  			printf(", ...");
     689  #endif
     690  		printf("]}) = " RETVAL);
     691  	}
     692  }
     693  
     694  /* GIO_UNISCRNMAP, PIO_UNISCRNMAP */
     695  static void
     696  check_uniscrnmap(unsigned int c, const char *s)
     697  {
     698  	uint16_t *map = tail_alloc(256 * sizeof(*map));
     699  	for (unsigned int i = 0; i < 256; i++)
     700  		map[i] = 0xeff1 + 32 * (i % 112) - i / 8;
     701  
     702  	check_null_invalid(c, s);
     703  
     704  	for (unsigned int i = 0; i < 3; i++) {
     705  		sys_ioctl(-1, c, (uintptr_t) (map + 224 - 112 * i));
     706  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     707  
     708  		if (c == GIO_UNISCRNMAP && !RETVAL_INJECTED) {
     709  			printf("%p) = " RETVAL, map + 224 - 112 * i);
     710  			continue;
     711  		}
     712  
     713  		for (size_t j = 0;
     714  		     j < MIN(32 + 112 * i, DEFAULT_STRLEN); j++) {
     715  			uint16_t v = 0xefd5 + 32 * (j % 112) - j / 8 + i * 14;
     716  			if ((j % 112) < (2 - (i + 1 - j / 112) / 2)
     717  			    || (j % 112) > (17 - (i + 1 - j / 112) / 2)) {
     718  				printf("%s%#hx", j ? ", " : "[", v);
     719  			} else {
     720  				printf(", "
     721  				       XLAT_KNOWN_FMT("%#hx",
     722  						      "UNI_DIRECT_BASE+%#hx"),
     723  				       XLAT_SEL(v, (uint16_t) (v - 0xf000)));
     724  			}
     725  		}
     726  
     727  		if (DEFAULT_STRLEN == 32 || i < 2) {
     728  			printf(", ...");
     729  			if (DEFAULT_STRLEN >= 32 + 112 * i)
     730  				printf(" /* %p */", map + 256);
     731  		}
     732  
     733  		printf("]) = " RETVAL);
     734  	}
     735  }
     736  
     737  /* GIO_FONTX, PIO_FONTX */
     738  static void
     739  check_fontx(unsigned int c, const char *s)
     740  {
     741  	static const short cnts[] = { 1, 32, 256 };
     742  	struct consolefontdesc *cfd = tail_alloc(sizeof(*cfd));
     743  	char *data = tail_alloc(2048);
     744  	char *data_end = data + 2048;
     745  
     746  	fill_memory_ex(data, 2048, 0xf0, 255);
     747  
     748  	check_null_invalid(c, s);
     749  
     750  	cfd->charcount = 0;
     751  	cfd->charheight = 0xdead;
     752  	cfd->chardata = NULL;
     753  	sys_ioctl(-1, c, (uintptr_t) cfd);
     754  	printf("ioctl(-1, " XLAT_FMT
     755  	       ", {charcount=0, charheight=57005, chardata=NULL}%s) = " RETVAL,
     756  	       XLAT_SEL(c, s), RETVAL_INJECTED && (c == GIO_FONTX)
     757  		? " => {charcount=0, charheight=57005, chardata=NULL}" : "");
     758  
     759  	cfd->chardata = data_end;
     760  	sys_ioctl(-1, c, (uintptr_t) cfd);
     761  	printf("ioctl(-1, " XLAT_FMT
     762  	       ", {charcount=0, charheight=57005, chardata=%p}",
     763  	       XLAT_SEL(c, s), data_end);
     764  #if RETVAL_INJECTED
     765  	if (c == GIO_FONTX)
     766  		printf(" => {charcount=0, charheight=57005, chardata=\"\"}");
     767  #endif
     768  	printf(") = " RETVAL);
     769  
     770  	cfd->chardata = data;
     771  	sys_ioctl(-1, c, (uintptr_t) cfd);
     772  	printf("ioctl(-1, " XLAT_FMT
     773  	       ", {charcount=0, charheight=57005, chardata=%p}",
     774  	       XLAT_SEL(c, s), data);
     775  #if RETVAL_INJECTED
     776  	if (c == GIO_FONTX)
     777  		printf(" => {charcount=0, charheight=57005, chardata=\"\"}");
     778  #endif
     779  	printf(") = " RETVAL);
     780  
     781  	for (size_t i = 0; i < ARRAY_SIZE(cnts); i++) {
     782  		char *p = data_end - MIN(2048, cnts[i] * 32);
     783  		cfd->charcount = cnts[i];
     784  
     785  		cfd->chardata = p + 1;
     786  		sys_ioctl(-1, c, (uintptr_t) cfd);
     787  		printf("ioctl(-1, " XLAT_FMT
     788  		       ", {charcount=%u, charheight=57005, chardata=",
     789  		       XLAT_SEL(c, s), cnts[i]);
     790  		if (c == PIO_FONTX && cnts[i] * 32 > DEFAULT_STRLEN) {
     791  			print_quoted_hex(p + 1, DEFAULT_STRLEN);
     792  			printf("...}");
     793  		} else {
     794  			printf("%p}", p + 1);
     795  		}
     796  #if RETVAL_INJECTED
     797  		if (c == GIO_FONTX) {
     798  			printf(" => {charcount=%u, charheight=57005, chardata=",
     799  			       cnts[i]);
     800  			if (cnts[i] * 32 > DEFAULT_STRLEN) {
     801  				print_quoted_hex(p + 1, DEFAULT_STRLEN);
     802  				printf("...}");
     803  			} else {
     804  				printf("%p}", p + 1);
     805  			}
     806  		}
     807  #endif
     808  		printf(") = " RETVAL);
     809  
     810  		cfd->chardata = p;
     811  		sys_ioctl(-1, c, (uintptr_t) cfd);
     812  		printf("ioctl(-1, " XLAT_FMT
     813  		       ", {charcount=%u, charheight=57005, chardata=",
     814  		       XLAT_SEL(c, s), cnts[i]);
     815  		if (c == PIO_FONTX) {
     816  			print_quoted_hex(p, MIN(DEFAULT_STRLEN, cnts[i] * 32));
     817  			if (cnts[i] * 32 > DEFAULT_STRLEN)
     818  				printf("...");
     819  		} else {
     820  			printf("%p", p);
     821  		}
     822  		printf("}");
     823  #if RETVAL_INJECTED
     824  		if (c == GIO_FONTX) {
     825  			printf(" => {charcount=%u, charheight=57005, chardata=",
     826  			       cnts[i]);
     827  			print_quoted_hex(p, MIN(DEFAULT_STRLEN, cnts[i] * 32));
     828  			if (cnts[i] * 32 > DEFAULT_STRLEN)
     829  				printf("...");
     830  			printf("}");
     831  		}
     832  #endif
     833  		printf(") = " RETVAL);
     834  	}
     835  }
     836  
     837  /* GIO_CMAP, PIO_CMAP */
     838  static void
     839  check_cmap(unsigned int c, const char *s)
     840  {
     841  	char *cmap = tail_alloc(48);
     842  
     843  	fill_memory(cmap, 48);
     844  
     845  	check_null_invalid(c, s);
     846  
     847  	sys_ioctl(-1, c, (uintptr_t) (cmap + 1));
     848  	printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     849  	if ((c == PIO_CMAP || RETVAL_INJECTED) && (DEFAULT_STRLEN == 32)) {
     850  		printf("\"");
     851  		for (unsigned int i = 0; i < MIN(DEFAULT_STRLEN, 48); i++)
     852  			printf("\\x%x", 0x81 + i);
     853  		printf("\"...");
     854  	} else {
     855  		printf("%p", cmap + 1);
     856  	}
     857  	printf(") = " RETVAL);
     858  
     859  	sys_ioctl(-1, c, (uintptr_t) cmap);
     860  	printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     861  	if (c == PIO_CMAP || RETVAL_INJECTED) {
     862  		printf("\"");
     863  		for (unsigned int i = 0; i < MIN(DEFAULT_STRLEN, 48); i++)
     864  			printf("\\x%x", 0x80 + i);
     865  #if DEFAULT_STRLEN == 32
     866  		printf("\"...");
     867  #else
     868  		printf("\"");
     869  #endif
     870  	} else {
     871  		printf("%p", cmap);
     872  	}
     873  	printf(") = " RETVAL);
     874  }
     875  
     876  /* KDGKBDIACRUC, KDSKBDIACRUC */
     877  static void
     878  check_diacruc(unsigned int c, const char *s)
     879  {
     880  	struct kbdiacrsuc *diacrs0 = tail_alloc(sizeof(diacrs0->kb_cnt));
     881  	struct kbdiacrsuc *diacrs1 = tail_alloc(sizeof(diacrs1->kb_cnt) +
     882  						4 * sizeof(struct kbdiacruc));
     883  	struct kbdiacrsuc *diacrs2 = tail_alloc(sizeof(*diacrs2));
     884  
     885  	int saved_errno;
     886  
     887  	check_null_invalid(c, s);
     888  
     889  	for (size_t i = 0; i < 2; i++) {
     890  		diacrs0->kb_cnt = i;
     891  		sys_ioctl(-1, c, (uintptr_t) diacrs0);
     892  		saved_errno = errno;
     893  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     894  		if (RETVAL_INJECTED || c == KDSKBDIACRUC) {
     895  			printf("{kb_cnt=%zu, kbdiacruc=", i);
     896  			if (i)
     897  				printf("%p}", diacrs0->kbdiacruc);
     898  			else
     899  				printf("[]}");
     900  		} else {
     901  			printf("%p", diacrs0);
     902  		}
     903  		errno = saved_errno;
     904  		printf(") = " RETVAL);
     905  	}
     906  
     907  	fill_memory32(diacrs1->kbdiacruc, 4 * sizeof(struct kbdiacruc));
     908  	for (size_t i = 0; i < 7; i++) {
     909  		diacrs1->kb_cnt = i;
     910  		sys_ioctl(-1, c, (uintptr_t) diacrs1);
     911  		saved_errno = errno;
     912  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     913  		if (RETVAL_INJECTED || c == KDSKBDIACRUC) {
     914  			printf("{kb_cnt=%zu, kbdiacruc=[", i);
     915  			for (size_t j = 0; j < MIN(i, 4); j++)
     916  				printf("%s{diacr=%#x, base=%#x, result=%#x}",
     917  				       j ? ", " : "",
     918  				       (unsigned int) (0x80a0c0e0 + j * 3),
     919  				       (unsigned int) (0x80a0c0e1 + j * 3),
     920  				       (unsigned int) (0x80a0c0e2 + j * 3));
     921  
     922  			if (i > 4) {
     923  				printf(", ... /* %p */",
     924  				       diacrs1->kbdiacruc + 4);
     925  			}
     926  			printf("]}");
     927  		} else {
     928  			printf("%p", diacrs1);
     929  		}
     930  		errno = saved_errno;
     931  		printf(") = " RETVAL);
     932  	}
     933  
     934  	fill_memory32(diacrs2->kbdiacruc, sizeof(diacrs2->kbdiacruc));
     935  
     936  	for (size_t i = ARRAY_SIZE(diacrs2->kbdiacruc) - 1;
     937  	     i < ARRAY_SIZE(diacrs2->kbdiacruc) + 3; i++) {
     938  		diacrs2->kb_cnt = i;
     939  		sys_ioctl(-1, c, (uintptr_t) diacrs2);
     940  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(c, s));
     941  		saved_errno = errno;
     942  		if (RETVAL_INJECTED || c == KDSKBDIACRUC) {
     943  			printf("{kb_cnt=%zu, kbdiacruc=[", i);
     944  			for (size_t j = 0;
     945  			     j < MIN(i, MIN(ARRAY_SIZE(diacrs2->kbdiacruc),
     946  					    DEFAULT_STRLEN)); j++)
     947  				printf("%s{diacr=%#x, base=%#x, result=%#x}",
     948  				       j ? ", " : "",
     949  				       (unsigned int) (0x80a0c0e0 + j * 3),
     950  				       (unsigned int) (0x80a0c0e1 + j * 3),
     951  				       (unsigned int) (0x80a0c0e2 + j * 3));
     952  
     953  			if (i > MIN(DEFAULT_STRLEN,
     954  				    ARRAY_SIZE(diacrs2->kbdiacruc)))
     955  				printf(", ...");
     956  			printf("]}");
     957  		} else {
     958  			printf("%p", diacrs2);
     959  		}
     960  		errno = saved_errno;
     961  		printf(") = " RETVAL);
     962  	}
     963  }
     964  
     965  int
     966  main(int argc, char *argv[])
     967  {
     968  	static const kernel_ulong_t magic =
     969  		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
     970  
     971  	static const uint32_t unknown_ioctls[] = {
     972  		0xfffffff1, 0xc0007fff, 0xfffb800c, 0xfff8c000,
     973  		0xffffffff, 0xffffffff, 0xffffffff, 0xf3ffffff,
     974  	};
     975  
     976  	enum { MAP_ELEM_BIT = sizeof(unknown_ioctls[0]) * CHAR_BIT };
     977  
     978  	long rc;
     979  
     980  #if RETVAL_INJECTED
     981  	unsigned long num_skip;
     982  	bool locked = false;
     983  
     984  	if (argc < 2)
     985  		error_msg_and_fail("Usage: %s NUM_SKIP", argv[0]);
     986  
     987  	num_skip = strtoul(argv[1], NULL, 0);
     988  
     989  	for (unsigned int i = 0; i < num_skip; i++) {
     990  		long rc = sys_ioctl(-1, KDGETLED, 0);
     991  		printf("ioctl(-1, " XLAT_FMT ", NULL) = %s%s\n",
     992  		       XLAT_ARGS(KDGETLED), sprintrc(rc),
     993  		       rc == 42 ? " (INJECTED)" : "");
     994  
     995  		if (rc != 42)
     996  			continue;
     997  
     998  		locked = true;
     999  		break;
    1000  	}
    1001  
    1002  	if (!locked)
    1003  		error_msg_and_fail("Have not locked on ioctl(-1"
    1004  				   ", KDGETLED, NULL) returning 42");
    1005  #endif
    1006  
    1007  	for (size_t i = 0; i < ARRAY_SIZE(unknown_ioctls); i++) {
    1008  		for (size_t j = 0; j < MAP_ELEM_BIT; j++) {
    1009  			if (!((unknown_ioctls[i] >> j) & 1))
    1010  				continue;
    1011  
    1012  			const unsigned int id = i * MAP_ELEM_BIT + j;
    1013  
    1014  			sys_ioctl(-1, 'K' << 8 | id, magic);
    1015  			printf("ioctl(-1, "
    1016  			       NABBR("%#x") VERB(" /* ")
    1017  			       NRAW("_IOC(%s, 0x4b, %#x, 0)") VERB(" */")
    1018  			       ", %#lx) = " RETVAL,
    1019  #if XLAT_RAW || XLAT_VERBOSE
    1020  			       'K' << 8 | id,
    1021  #endif
    1022  #if !XLAT_RAW
    1023  			       _IOC_NONE ? "0" : "_IOC_NONE", id,
    1024  #endif
    1025  			       (unsigned long) magic);
    1026  		}
    1027  	}
    1028  
    1029  
    1030  	/* KIOCSOUND */
    1031  	sys_ioctl(-1, KIOCSOUND, 0);
    1032  	printf("ioctl(-1, " XLAT_FMT ", 0" NRAW(" /* off */") ") = " RETVAL,
    1033  	       XLAT_ARGS(KIOCSOUND));
    1034  
    1035  	sys_ioctl(-1, KIOCSOUND, 1);
    1036  	printf("ioctl(-1, " XLAT_FMT ", 1" NRAW(" /* 1193182 Hz */")
    1037  	       ") = " RETVAL, XLAT_ARGS(KIOCSOUND));
    1038  
    1039  	sys_ioctl(-1, KIOCSOUND, 440);
    1040  	printf("ioctl(-1, " XLAT_FMT ", 440" NRAW(" /* 2711 Hz */")
    1041  	       ") = " RETVAL, XLAT_ARGS(KIOCSOUND));
    1042  
    1043  	sys_ioctl(-1, KIOCSOUND, 1193182);
    1044  	printf("ioctl(-1, " XLAT_FMT ", 1193182" NRAW(" /* 1 Hz */")
    1045  	       ") = " RETVAL, XLAT_ARGS(KIOCSOUND));
    1046  
    1047  	sys_ioctl(-1, KIOCSOUND, 1193183);
    1048  	printf("ioctl(-1, " XLAT_FMT ", 1193183" NRAW(" /* off */")
    1049  	       ") = " RETVAL, XLAT_ARGS(KIOCSOUND));
    1050  
    1051  	sys_ioctl(-1, KIOCSOUND,
    1052  		  (kernel_ulong_t) (0xbadc0ded00000000ULL | 2710));
    1053  	printf("ioctl(-1, " XLAT_FMT
    1054  #if SIZEOF_LONG == 4
    1055  	       ", 2710" NRAW(" /* 440 Hz */")
    1056  #else
    1057  	       ", 13464652297489353366" NRAW(" /* off */")
    1058  #endif
    1059  	       ") = " RETVAL, XLAT_ARGS(KIOCSOUND));
    1060  
    1061  	sys_ioctl(-1, KIOCSOUND, (kernel_ulong_t) 0xbadc0deddeadfaceULL);
    1062  	printf("ioctl(-1, " XLAT_FMT
    1063  #if SIZEOF_LONG == 8
    1064  	       ", 13464652301225294542"
    1065  #else
    1066  	       ", 3735943886"
    1067  #endif
    1068  	       NRAW(" /* off */") ") = " RETVAL, XLAT_ARGS(KIOCSOUND));
    1069  
    1070  	/* KDMKTONE */
    1071  	sys_ioctl(-1, KDMKTONE, 0);
    1072  	printf("ioctl(-1, " XLAT_FMT ", 0" NRAW(" /* off */") ") = " RETVAL,
    1073  	       XLAT_ARGS(KDMKTONE));
    1074  
    1075  	sys_ioctl(-1, KDMKTONE, 440);
    1076  	printf("ioctl(-1, " XLAT_FMT ", 440" NRAW(" /* off */") ") = " RETVAL,
    1077  	       XLAT_ARGS(KDMKTONE));
    1078  
    1079  	sys_ioctl(-1, KDMKTONE, 0xffff);
    1080  	printf("ioctl(-1, " XLAT_FMT ", 65535" NRAW(" /* off */") ") = " RETVAL,
    1081  	       XLAT_ARGS(KDMKTONE));
    1082  
    1083  	sys_ioctl(-1, KDMKTONE, 0x10000);
    1084  	printf("ioctl(-1, " XLAT_FMT ", 1<<16|0" NRAW(" /* off */")
    1085  	       ") = " RETVAL, XLAT_ARGS(KDMKTONE));
    1086  
    1087  	sys_ioctl(-1, KDMKTONE,
    1088  		  (kernel_ulong_t) (0xbadc0ded00000000ULL | 0x10001));
    1089  	printf("ioctl(-1, " XLAT_FMT ", 1<<16|1" NRAW(" /* 1193182 Hz, 1 ms */")
    1090  	       ") = " RETVAL, XLAT_ARGS(KDMKTONE));
    1091  
    1092  	sys_ioctl(-1, KDMKTONE, 0x1ffff);
    1093  	printf("ioctl(-1, " XLAT_FMT ", 1<<16|65535" NRAW(" /* 18 Hz, 1 ms */")
    1094  	       ") = " RETVAL, XLAT_ARGS(KDMKTONE));
    1095  
    1096  	sys_ioctl(-1, KDMKTONE, (kernel_ulong_t) 0xbadc0deddeadfaceULL);
    1097  	printf("ioctl(-1, " XLAT_FMT ", 57005<<16|64206"
    1098  	       NRAW(" /* 18 Hz, 57005 ms */") ") = " RETVAL,
    1099  	       XLAT_ARGS(KDMKTONE));
    1100  
    1101  
    1102  	/* KDGETLED */
    1103  	static const struct arg_val led_vecs[] = {
    1104  		{ ARG_STR(0) },
    1105  		{ ARG_XLAT_KNOWN(0x1, "LED_SCR") },
    1106  		{ ARG_XLAT_KNOWN(0x7, "LED_SCR|LED_NUM|LED_CAP") },
    1107  		{ ARG_XLAT_KNOWN(0xfe, "LED_NUM|LED_CAP|0xf8") },
    1108  		{ (kernel_ulong_t) 0xbadc0dedfeedfaf0ULL,
    1109  		  XLAT_UNKNOWN(0xf0, "LED_???") },
    1110  	};
    1111  
    1112  	unsigned char *leds = tail_alloc(sizeof(*leds));
    1113  
    1114  	check_null_invalid(ARG_STR(KDGETLED));
    1115  
    1116  	for (size_t i = 0; i < ARRAY_SIZE(led_vecs); i++) {
    1117  		*leds = led_vecs[i].val;
    1118  		rc = sys_ioctl(-1, KDGETLED, (uintptr_t) leds);
    1119  		if (rc >= 0) {
    1120  			printf("ioctl(-1, " XLAT_FMT ", [%s]) = " RETVAL,
    1121  			       XLAT_ARGS(KDGETLED), led_vecs[i].str);
    1122  		} else {
    1123  			printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
    1124  			       XLAT_ARGS(KDGETLED), leds);
    1125  		}
    1126  	}
    1127  
    1128  
    1129  	/* KDSETLED */
    1130  	for (size_t i = 0; i < ARRAY_SIZE(led_vecs); i++) {
    1131  		sys_ioctl(-1, KDSETLED, led_vecs[i].val);
    1132  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1133  		       XLAT_ARGS(KDSETLED), led_vecs[i].str);
    1134  	}
    1135  
    1136  	sys_ioctl(-1, KDSETLED, (kernel_ulong_t) 0xdeadc0defeedfaceULL);
    1137  	printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1138  	       XLAT_ARGS(KDSETLED), XLAT_STR(LED_NUM|LED_CAP|0xc8));
    1139  
    1140  
    1141  	/* KDGKBTYPE */
    1142  	static const struct arg_val kbt_vecs[] = {
    1143  		{ ARG_XLAT_UNKNOWN(0, "KB_???") },
    1144  		{ ARG_XLAT_KNOWN(0x1, "KB_84") },
    1145  		{ ARG_XLAT_KNOWN(0x2, "KB_101") },
    1146  		{ ARG_XLAT_KNOWN(0x3, "KB_OTHER") },
    1147  		{ ARG_XLAT_UNKNOWN(0x4, "KB_???") },
    1148  		{ (kernel_ulong_t) 0xbadc0dedcacafefeULL,
    1149  		  XLAT_UNKNOWN(0xfe, "KB_???") },
    1150  	};
    1151  
    1152  	unsigned char *kbt = tail_alloc(sizeof(*kbt));
    1153  
    1154  	check_null_invalid(ARG_STR(KDGKBTYPE));
    1155  
    1156  	for (size_t i = 0; i < ARRAY_SIZE(kbt_vecs); i++) {
    1157  		*kbt = kbt_vecs[i].val;
    1158  		rc = sys_ioctl(-1, KDGKBTYPE, (uintptr_t) kbt);
    1159  		if (rc >= 0) {
    1160  			printf("ioctl(-1, " XLAT_FMT ", [%s]) = " RETVAL,
    1161  			       XLAT_ARGS(KDGKBTYPE), kbt_vecs[i].str);
    1162  		} else {
    1163  			printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
    1164  			       XLAT_ARGS(KDGKBTYPE), kbt);
    1165  		}
    1166  	}
    1167  
    1168  
    1169  	/* KDADDIO */
    1170  	static const struct arg_val iop_vecs[] = {
    1171  		{ ARG_STR(0) },
    1172  		{ ARG_STR(0x3b3) },
    1173  		{ ARG_STR(0x3b4) NRAW(" /* GPFIRST + 0 */") },
    1174  		{ ARG_STR(0x3c0) NRAW(" /* GPFIRST + 12 */") },
    1175  		{ ARG_STR(0x3df) NRAW(" /* GPFIRST + 43 */") },
    1176  		{ ARG_STR(0x3e0) },
    1177  		{ ARG_STR(0xdeadc0de) },
    1178  		{ (kernel_ulong_t) 0xbadc0dedfacefeedULL,
    1179  #if SIZEOF_LONG > 4
    1180  		  "0xbadc0dedfacefeed"
    1181  #else
    1182  		  "0xfacefeed"
    1183  #endif
    1184  		},
    1185  	};
    1186  
    1187  	for (size_t i = 0; i < ARRAY_SIZE(iop_vecs); i++) {
    1188  		sys_ioctl(-1, KDADDIO, iop_vecs[i].val);
    1189  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1190  		       XLAT_ARGS(KDADDIO), iop_vecs[i].str);
    1191  	}
    1192  
    1193  
    1194  	/* KDDELIO */
    1195  	for (size_t i = 0; i < ARRAY_SIZE(iop_vecs); i++) {
    1196  		sys_ioctl(-1, KDDELIO, iop_vecs[i].val);
    1197  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1198  		       XLAT_ARGS(KDDELIO), iop_vecs[i].str);
    1199  	}
    1200  
    1201  
    1202  	/* KDENABIO */
    1203  	sys_ioctl(-1, KDENABIO, (kernel_ulong_t) 0xbadc0deddeadface);
    1204  	printf("ioctl(-1, " XLAT_FMT ") = " RETVAL, XLAT_ARGS(KDENABIO));
    1205  
    1206  
    1207  	/* KDDISABIO */
    1208  	sys_ioctl(-1, KDDISABIO, (kernel_ulong_t) 0xbadc0deddeadface);
    1209  	printf("ioctl(-1, " XLAT_FMT ") = " RETVAL, XLAT_ARGS(KDDISABIO));
    1210  
    1211  
    1212  	/* KDSETMODE */
    1213  	static const struct arg_val mode_vecs[] = {
    1214  		{ ARG_XLAT_KNOWN(0, "KD_TEXT") },
    1215  		{ ARG_XLAT_KNOWN(0x1, "KD_GRAPHICS") },
    1216  		{ ARG_XLAT_KNOWN(0x3, "KD_TEXT1") },
    1217  		{ ARG_XLAT_UNKNOWN(0x4, "KD_???") },
    1218  		{ (kernel_ulong_t) 0xbadc0dedcacafefeULL,
    1219  		  "0xcacafefe" NRAW(" /* KD_??? */") },
    1220  	};
    1221  
    1222  	for (size_t i = 0; i < ARRAY_SIZE(mode_vecs); i++) {
    1223  		sys_ioctl(-1, KDSETMODE, mode_vecs[i].val);
    1224  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1225  		       XLAT_ARGS(KDSETMODE), mode_vecs[i].str);
    1226  	}
    1227  
    1228  
    1229  	/* KDGETMODE */
    1230  	unsigned int *mode = tail_alloc(sizeof(*mode));
    1231  
    1232  	check_null_invalid(ARG_STR(KDGETMODE));
    1233  
    1234  	for (size_t i = 0; i < ARRAY_SIZE(mode_vecs); i++) {
    1235  		*mode = mode_vecs[i].val;
    1236  		rc = sys_ioctl(-1, KDGETMODE, (uintptr_t) mode);
    1237  		if (rc >= 0) {
    1238  			printf("ioctl(-1, " XLAT_FMT ", [%s]) = " RETVAL,
    1239  			       XLAT_ARGS(KDGETMODE), mode_vecs[i].str);
    1240  		} else {
    1241  			printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
    1242  			       XLAT_ARGS(KDGETMODE), mode);
    1243  		}
    1244  	}
    1245  
    1246  
    1247  	/* KDMAPDISP */
    1248  	sys_ioctl(-1, KDMAPDISP, (kernel_ulong_t) 0xbadc0deddeadface);
    1249  	printf("ioctl(-1, " XLAT_FMT ") = " RETVAL, XLAT_ARGS(KDMAPDISP));
    1250  
    1251  
    1252  	/* KDUNMAPDISP */
    1253  	sys_ioctl(-1, KDUNMAPDISP, (kernel_ulong_t) 0xbadc0deddeadface);
    1254  	printf("ioctl(-1, " XLAT_FMT ") = " RETVAL, XLAT_ARGS(KDUNMAPDISP));
    1255  
    1256  
    1257  	/* GIO_SCRNMAP */
    1258  	check_scrnmap(ARG_STR(GIO_SCRNMAP));
    1259  
    1260  
    1261  	/* PIO_SCRNMAP */
    1262  	check_scrnmap(ARG_STR(PIO_SCRNMAP));
    1263  
    1264  
    1265  	/* KDGKBMODE */
    1266  	static const struct arg_val kbmode_vecs[] = {
    1267  		{ ARG_XLAT_UNKNOWN(-1, "K_???") },
    1268  		{ ARG_XLAT_KNOWN(0, "K_RAW") },
    1269  		{ ARG_XLAT_KNOWN(1, "K_XLATE") },
    1270  		{ ARG_XLAT_KNOWN(4, "K_OFF") },
    1271  		{ ARG_XLAT_UNKNOWN(5, "K_???") },
    1272  		{ (kernel_ulong_t) 0xbadc0dedfeeddeadULL,
    1273  		  XLAT_UNKNOWN(-17965395, "K_???") },
    1274  	};
    1275  
    1276  	check_null_invalid(ARG_STR(KDGKBMODE));
    1277  
    1278  	for (size_t i = 0; i < ARRAY_SIZE(kbmode_vecs); i++) {
    1279  		*mode = kbmode_vecs[i].val;
    1280  		rc = sys_ioctl(-1, KDGKBMODE, (uintptr_t) mode);
    1281  		if (rc >= 0) {
    1282  			printf("ioctl(-1, " XLAT_FMT ", [%s]) = " RETVAL,
    1283  			       XLAT_ARGS(KDGKBMODE), kbmode_vecs[i].str);
    1284  		} else {
    1285  			printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
    1286  			       XLAT_ARGS(KDGKBMODE), mode);
    1287  		}
    1288  	}
    1289  
    1290  
    1291  	/* KDSKBMODE */
    1292  	for (size_t i = 0; i < ARRAY_SIZE(kbmode_vecs); i++) {
    1293  		sys_ioctl(-1, KDSKBMODE, kbmode_vecs[i].val);
    1294  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1295  		       XLAT_ARGS(KDSKBMODE), kbmode_vecs[i].str);
    1296  	}
    1297  
    1298  
    1299  	/* KDGKBENT */
    1300  	check_kbdent(ARG_STR(KDGKBENT));
    1301  
    1302  
    1303  	/* KDSKBENT */
    1304  	check_kbdent(ARG_STR(KDSKBENT));
    1305  
    1306  
    1307  	/* KDGKBSENT */
    1308  	check_kbdsent(ARG_STR(KDGKBSENT));
    1309  
    1310  
    1311  	/* KDSKBSENT */
    1312  	check_kbdsent(ARG_STR(KDSKBSENT));
    1313  
    1314  
    1315  	/* KDGKBDIACR */
    1316  	check_diacr(ARG_STR(KDGKBDIACR));
    1317  
    1318  
    1319  	/* KDSKBDIACR */
    1320  	check_diacr(ARG_STR(KDSKBDIACR));
    1321  
    1322  
    1323  	/* KDGETKEYCODE */
    1324  	check_xetkeycode(ARG_STR(KDGETKEYCODE));
    1325  
    1326  
    1327  	/* KDSETKEYCODE */
    1328  	check_xetkeycode(ARG_STR(KDSETKEYCODE));
    1329  
    1330  
    1331  	/* KDSIGACCEPT */
    1332  	static const struct {
    1333  		kernel_ulong_t val;
    1334  		const char *str;
    1335  	} sigaccept_vecs[] = {
    1336  		{ (kernel_ulong_t) -1ULL,
    1337  		  SIZEOF_LONG == 8 ? "18446744073709551615" : "4294967295" },
    1338  		{ 0, "0" },
    1339  		{ ARG_XLAT_KNOWN(SIGHUP, "SIGHUP") },
    1340  		{ ARG_XLAT_KNOWN(SIGUSR1, "SIGUSR1") },
    1341  		{ ARG_XLAT_KNOWN(32, "SIGRTMIN") },
    1342  		{ ARG_XLAT_KNOWN(33, "SIGRT_1") },
    1343  		{ ARG_STR(128) },
    1344  	};
    1345  
    1346  	for (size_t i = 0; i < ARRAY_SIZE(sigaccept_vecs); i++) {
    1347  		sys_ioctl(-1, KDSIGACCEPT, sigaccept_vecs[i].val);
    1348  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1349  		       XLAT_ARGS(KDSIGACCEPT), sigaccept_vecs[i].str);
    1350  	}
    1351  
    1352  
    1353  	/* KDKBDREP */
    1354  	check_kbdrep(ARG_STR(KDKBDREP));
    1355  
    1356  
    1357  	/* GIO_FONT */
    1358  	check_font(ARG_STR(GIO_FONT));
    1359  
    1360  
    1361  	/* PIO_FONT */
    1362  	check_font(ARG_STR(PIO_FONT));
    1363  
    1364  
    1365  	/* KDGKBMETA */
    1366  	static const struct {
    1367  		kernel_ulong_t arg;
    1368  		const char *str;
    1369  	} meta_vecs[] = {
    1370  		{ ARG_XLAT_UNKNOWN(0, "K_???") },
    1371  		{ ARG_XLAT_UNKNOWN(0x1, "K_???") },
    1372  		{ ARG_XLAT_UNKNOWN(0x2, "K_???") },
    1373  		{ ARG_XLAT_KNOWN(0x3, "K_METABIT") },
    1374  		{ ARG_XLAT_KNOWN(0x4, "K_ESCPREFIX") },
    1375  		{ ARG_XLAT_UNKNOWN(0x5, "K_???") },
    1376  		{ (kernel_ulong_t) 0xdeadfacebeeffeedULL,
    1377  		  "0xbeeffeed" NRAW(" /* K_??? */") },
    1378  	};
    1379  	int *meta = tail_alloc(sizeof(*meta));
    1380  
    1381  	check_null_invalid(ARG_STR(KDGKBMETA));
    1382  
    1383  	for (size_t i = 0; i < ARRAY_SIZE(meta_vecs); i++) {
    1384  		*meta = meta_vecs[i].arg;
    1385  		sys_ioctl(-1, KDGKBMETA, (uintptr_t) meta);
    1386  		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_ARGS(KDGKBMETA));
    1387  #if RETVAL_INJECTED
    1388  		printf("[%s]", meta_vecs[i].str);
    1389  #else
    1390  		printf("%p", meta);
    1391  #endif
    1392  		printf(") = " RETVAL);
    1393  	}
    1394  
    1395  
    1396  	/* KDSKBMETA */
    1397  	for (size_t i = 0; i < ARRAY_SIZE(meta_vecs); i++) {
    1398  		sys_ioctl(-1, KDSKBMETA, meta_vecs[i].arg);
    1399  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1400  		       XLAT_ARGS(KDSKBMETA), meta_vecs[i].str);
    1401  	}
    1402  
    1403  
    1404  	/* KDGKBLED */
    1405  	static const struct arg_val kbled_vecs[] = {
    1406  		{ ARG_STR(0) },
    1407  		{ ARG_XLAT_KNOWN(0x1, "LED_SCR") },
    1408  		{ ARG_XLAT_KNOWN(0x7, "LED_SCR|LED_NUM|LED_CAP") },
    1409  		{ ARG_XLAT_KNOWN(0x10, "LED_SCR<<4") },
    1410  		{ ARG_XLAT_KNOWN(0x70, "LED_SCR<<4|LED_NUM<<4|LED_CAP<<4") },
    1411  		{ ARG_XLAT_KNOWN(0xfe, "LED_NUM|LED_CAP|LED_SCR<<4|LED_NUM<<4"
    1412  				       "|LED_CAP<<4|0x88") },
    1413  		{ (kernel_ulong_t) 0xbadc0dedfeedfa88ULL,
    1414  		  XLAT_UNKNOWN(0x88, "LED_???") },
    1415  	};
    1416  
    1417  	unsigned char *kbleds = tail_alloc(sizeof(*kbleds));
    1418  
    1419  	check_null_invalid(ARG_STR(KDGKBLED));
    1420  
    1421  	for (size_t i = 0; i < ARRAY_SIZE(kbled_vecs); i++) {
    1422  		*kbleds = kbled_vecs[i].val;
    1423  		rc = sys_ioctl(-1, KDGKBLED, (uintptr_t) kbleds);
    1424  		if (rc >= 0) {
    1425  			printf("ioctl(-1, " XLAT_FMT ", [%s]) = " RETVAL,
    1426  			       XLAT_ARGS(KDGKBLED), kbled_vecs[i].str);
    1427  		} else {
    1428  			printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
    1429  			       XLAT_ARGS(KDGKBLED), kbleds);
    1430  		}
    1431  	}
    1432  
    1433  
    1434  	/* KDSKBLED */
    1435  	for (size_t i = 0; i < ARRAY_SIZE(kbled_vecs); i++) {
    1436  		sys_ioctl(-1, KDSKBLED, kbled_vecs[i].val);
    1437  		printf("ioctl(-1, " XLAT_FMT ", %s) = " RETVAL,
    1438  		       XLAT_ARGS(KDSKBLED), kbled_vecs[i].str);
    1439  	}
    1440  
    1441  
    1442  	/* GIO_UNIMAP */
    1443  	check_unimap(ARG_STR(GIO_UNIMAP));
    1444  
    1445  
    1446  	/* PIO_UNIMAP */
    1447  	check_unimap(ARG_STR(PIO_UNIMAP));
    1448  
    1449  
    1450  	/* PIO_UNIMAPCLR */
    1451  	struct unimapinit *umi = tail_alloc(sizeof(*umi));
    1452  
    1453  	check_null_invalid(ARG_STR(PIO_UNIMAPCLR));
    1454  
    1455  	sys_ioctl(-1, PIO_UNIMAPCLR, (uintptr_t) umi + 2);
    1456  	printf("ioctl(-1, " XLAT_FMT ", %p) = " RETVAL,
    1457  	       XLAT_ARGS(PIO_UNIMAPCLR), (char *) umi + 2);
    1458  
    1459  	memset(umi, 0, sizeof(*umi));
    1460  	sys_ioctl(-1, PIO_UNIMAPCLR, (uintptr_t) umi);
    1461  	printf("ioctl(-1, " XLAT_FMT ", {advised_hashsize=0"
    1462  	       ", advised_hashstep=0, advised_hashlevel=0}) = " RETVAL,
    1463  	       XLAT_ARGS(PIO_UNIMAPCLR));
    1464  
    1465  	fill_memory16(umi, sizeof(*umi));
    1466  	sys_ioctl(-1, PIO_UNIMAPCLR, (uintptr_t) umi);
    1467  	printf("ioctl(-1, " XLAT_FMT ", {advised_hashsize=32960"
    1468  	       ", advised_hashstep=32961, advised_hashlevel=32962}) = " RETVAL,
    1469  	       XLAT_ARGS(PIO_UNIMAPCLR));
    1470  
    1471  
    1472  	/* GIO_UNISCRNMAP */
    1473  	check_uniscrnmap(ARG_STR(GIO_UNISCRNMAP));
    1474  
    1475  
    1476  	/* PIO_UNISCRNMAP */
    1477  	check_uniscrnmap(ARG_STR(PIO_UNISCRNMAP));
    1478  
    1479  
    1480  	/* GIO_FONTX */
    1481  	check_fontx(ARG_STR(GIO_FONTX));
    1482  
    1483  
    1484  	/* PIO_FONTX */
    1485  	check_fontx(ARG_STR(GIO_FONTX));
    1486  
    1487  
    1488  	/* PIO_FONTRESET */
    1489  	sys_ioctl(-1, PIO_FONTRESET, (kernel_ulong_t) 0xbadc0deddeadface);
    1490  	printf("ioctl(-1, " XLAT_FMT ") = " RETVAL, XLAT_ARGS(PIO_FONTRESET));
    1491  
    1492  
    1493  	/* GIO_CMAP */
    1494  	check_cmap(ARG_STR(GIO_CMAP));
    1495  
    1496  
    1497  	/* PIO_CMAP */
    1498  	check_cmap(ARG_STR(PIO_CMAP));
    1499  
    1500  
    1501  	/* KDFONTOP */
    1502  	struct console_font_op *cfo = tail_alloc(sizeof(*cfo));
    1503  	unsigned char *cfo_data = tail_alloc(2048);
    1504  	unsigned char *cfo_data_end = cfo_data + 2048;
    1505  
    1506  	fill_memory(cfo_data, 2048);
    1507  
    1508  	check_null_invalid(ARG_STR(KDFONTOP));
    1509  
    1510  	cfo->op = 4;
    1511  	cfo->flags = 0xdeadbeef;
    1512  	cfo->width = 0xbadc0ded;
    1513  	cfo->height = 0xfacecafe;
    1514  	cfo->charcount = 0xdadfaded;
    1515  	cfo->data = NULL;
    1516  	sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1517  	printf("ioctl(-1, " XLAT_FMT ", {op=0x4" NRAW(" /* KD_FONT_OP_??? */")
    1518  	       ", flags=" XLAT_KNOWN(0xdeadbeef, "KD_FONT_FLAG_DONT_RECALC"
    1519  						 "|KD_FONT_FLAG_OLD|0x5eadbeee")
    1520  	       ", width=3134983661, height=4207856382, charcount=3672092141"
    1521  	       ", data=NULL}"
    1522  #if RETVAL_INJECTED
    1523  	       " => {width=3134983661, height=4207856382, charcount=3672092141"
    1524  	       ", data=NULL}"
    1525  #endif
    1526  	       ") = " RETVAL, XLAT_ARGS(KDFONTOP));
    1527  
    1528  	cfo->op = 0xbeefface;
    1529  	cfo->flags = 0x5a1ecafe;;
    1530  	cfo->data = (unsigned char *) cfo;
    1531  	sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1532  	printf("ioctl(-1, " XLAT_FMT ", {op=0xbeefface"
    1533  	       NRAW(" /* KD_FONT_OP_??? */")
    1534  	       ", flags=0x5a1ecafe" NRAW(" /* KD_FONT_FLAG_??? */")
    1535  	       ", width=3134983661, height=4207856382, charcount=3672092141"
    1536  	       ", data=%p}"
    1537  #if RETVAL_INJECTED
    1538  	       " => {width=3134983661, height=4207856382, charcount=3672092141"
    1539  	       ", data=%p}"
    1540  #endif
    1541  	       ") = " RETVAL, XLAT_ARGS(KDFONTOP), cfo
    1542  #if RETVAL_INJECTED
    1543  	       , cfo
    1544  #endif
    1545  	       );
    1546  
    1547  	static const struct strval32 kdfont_ops[] = {
    1548  		{ ARG_XLAT_KNOWN(0, "KD_FONT_OP_SET") },
    1549  		{ ARG_XLAT_KNOWN(0x1, "KD_FONT_OP_GET") },
    1550  	};
    1551  
    1552  	for (size_t i = 0; i < ARRAY_SIZE(kdfont_ops); i++) {
    1553  		cfo->op = kdfont_ops[i].val;
    1554  		cfo->flags = 1;
    1555  		cfo->width = 0;
    1556  		cfo->height = 0;
    1557  		cfo->charcount = 0;
    1558  		cfo->data = NULL;
    1559  		sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1560  		printf("ioctl(-1, " XLAT_FMT ", {op=%s, flags="
    1561  		       XLAT_FMT ", width=0, height=0, charcount=0, data=NULL}",
    1562  		       XLAT_ARGS(KDFONTOP), kdfont_ops[i].str,
    1563  		       XLAT_ARGS(KD_FONT_FLAG_DONT_RECALC));
    1564  		if (kdfont_ops[i].val == KD_FONT_OP_GET && RETVAL_INJECTED) {
    1565  			printf(" => {width=0, height=0, charcount=0"
    1566  			       ", data=NULL}");
    1567  		}
    1568  		printf(") = " RETVAL);
    1569  
    1570  		cfo->data = cfo_data_end;
    1571  		for (size_t j = 0; j < 2; j++) {
    1572  			cfo->charcount = j;
    1573  			sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1574  			printf("ioctl(-1, " XLAT_FMT ", {op=%s, flags="
    1575  			       XLAT_FMT ", width=0, height=0, charcount=%zu"
    1576  			       ", data=",
    1577  			       XLAT_ARGS(KDFONTOP), kdfont_ops[i].str,
    1578  			       XLAT_ARGS(KD_FONT_FLAG_DONT_RECALC), j);
    1579  			if (kdfont_ops[i].val == KD_FONT_OP_SET)
    1580  				printf("\"\"");
    1581  			else
    1582  				printf("%p", cfo_data_end);
    1583  #if RETVAL_INJECTED
    1584  			if (kdfont_ops[i].val == KD_FONT_OP_GET) {
    1585  				printf("} => {width=0, height=0, charcount=%zu"
    1586  				       ", data=\"\"", j);
    1587  			}
    1588  #endif
    1589  			printf("}) = " RETVAL);
    1590  
    1591  		}
    1592  
    1593  		cfo->flags = 0;
    1594  		cfo->width = 1;
    1595  		cfo->data = cfo_data_end - 31;
    1596  		sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1597  		printf("ioctl(-1, " XLAT_FMT ", {op=%s, flags=0, width=1"
    1598  		       ", height=0, charcount=1, data=%p}",
    1599  		       XLAT_ARGS(KDFONTOP), kdfont_ops[i].str,
    1600  		       cfo_data_end - 31);
    1601  		if (kdfont_ops[i].val == KD_FONT_OP_GET && RETVAL_INJECTED) {
    1602  			printf(" => {width=1, height=0, charcount=1, data=%p}",
    1603  			       cfo_data_end - 31);
    1604  		}
    1605  		printf(") = " RETVAL);
    1606  
    1607  		cfo->data = cfo_data_end - 32;
    1608  		sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1609  		printf("ioctl(-1, " XLAT_FMT ", {op=%s, flags=0, width=1"
    1610  		       ", height=0, charcount=1, data=",
    1611  		       XLAT_ARGS(KDFONTOP), kdfont_ops[i].str);
    1612  		if (kdfont_ops[i].val == KD_FONT_OP_SET)
    1613  			print_quoted_hex(cfo_data_end - 32, 32);
    1614  		else
    1615  			printf("%p", cfo_data_end - 32);
    1616  		if (kdfont_ops[i].val == KD_FONT_OP_GET && RETVAL_INJECTED) {
    1617  			printf("} => {width=1, height=0, charcount=1, data=");
    1618  			print_quoted_hex(cfo_data_end - 32, 32);
    1619  
    1620  		}
    1621  		printf("}) = " RETVAL);
    1622  
    1623  		cfo->charcount = 32;
    1624  		cfo->data = cfo_data_end - 1023;
    1625  		sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1626  		printf("ioctl(-1, " XLAT_FMT ", {op=%s, flags=0, width=1"
    1627  		       ", height=0, charcount=32, data=",
    1628  		       XLAT_ARGS(KDFONTOP), kdfont_ops[i].str);
    1629  		if (kdfont_ops[i].val == KD_FONT_OP_SET && DEFAULT_STRLEN == 32)
    1630  		{
    1631  			print_quoted_hex(cfo_data_end - 1023, 32);
    1632  			printf("...");
    1633  		} else {
    1634  			printf("%p", cfo_data_end - 1023);
    1635  		}
    1636  		if (kdfont_ops[i].val == KD_FONT_OP_GET && RETVAL_INJECTED) {
    1637  			printf("} => {width=1, height=0, charcount=32, data=");
    1638  #if DEFAULT_STRLEN == 32
    1639  			print_quoted_hex(cfo_data_end - 1023, 32);
    1640  			printf("...");
    1641  #else
    1642  			printf("%p", cfo_data_end - 1023);
    1643  #endif
    1644  
    1645  		}
    1646  		printf("}) = " RETVAL);
    1647  
    1648  		cfo->data = cfo_data_end - 1024;
    1649  		sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1650  		printf("ioctl(-1, " XLAT_FMT ", {op=%s, flags=0, width=1"
    1651  		       ", height=0, charcount=32, data=",
    1652  		       XLAT_ARGS(KDFONTOP), kdfont_ops[i].str);
    1653  		if (kdfont_ops[i].val == KD_FONT_OP_SET) {
    1654  			print_quoted_hex(cfo_data_end - 1024, DEFAULT_STRLEN);
    1655  #if DEFAULT_STRLEN == 32
    1656  			printf("...");
    1657  #endif
    1658  		} else {
    1659  			printf("%p", cfo_data_end - 1024);
    1660  		}
    1661  		if (kdfont_ops[i].val == KD_FONT_OP_GET && RETVAL_INJECTED) {
    1662  			printf("} => {width=1, height=0, charcount=32, data=");
    1663  			print_quoted_hex(cfo_data_end - 1024, DEFAULT_STRLEN);
    1664  #if DEFAULT_STRLEN == 32
    1665  			printf("...");
    1666  #endif
    1667  		}
    1668  		printf("}) = " RETVAL);
    1669  
    1670  		cfo->charcount = 256;
    1671  		cfo->data = cfo_data_end - 1025;
    1672  		sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1673  		printf("ioctl(-1, " XLAT_FMT ", {op=%s, flags=0, width=1"
    1674  		       ", height=0, charcount=256, data=",
    1675  		       XLAT_ARGS(KDFONTOP), kdfont_ops[i].str);
    1676  		if (kdfont_ops[i].val == KD_FONT_OP_SET) {
    1677  			print_quoted_hex(cfo_data_end - 1025, DEFAULT_STRLEN);
    1678  			printf("...");
    1679  		} else {
    1680  			printf("%p", cfo_data_end - 1025);
    1681  		}
    1682  		if (kdfont_ops[i].val == KD_FONT_OP_GET && RETVAL_INJECTED) {
    1683  			printf("} => {width=1, height=0, charcount=256, data=");
    1684  			print_quoted_hex(cfo_data_end - 1025, DEFAULT_STRLEN);
    1685  			printf("...");
    1686  
    1687  		}
    1688  		printf("}) = " RETVAL);
    1689  	}
    1690  
    1691  	cfo->op = 2;
    1692  	cfo->data = NULL;
    1693  	sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1694  	printf("ioctl(-1, " XLAT_FMT ", {op=" XLAT_FMT ", width=1, height=0"
    1695  	       ", data=NULL}"
    1696  #if RETVAL_INJECTED
    1697  	       " => {width=1, height=0}"
    1698  #endif
    1699  	       ") = " RETVAL,
    1700  	       XLAT_ARGS(KDFONTOP), XLAT_ARGS(KD_FONT_OP_SET_DEFAULT));
    1701  
    1702  	cfo->data = cfo_data_end - 1;
    1703  	cfo->data[0] = '\0';
    1704  	sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1705  	printf("ioctl(-1, " XLAT_FMT ", {op=" XLAT_FMT ", width=1, height=0"
    1706  	       ", data=\"\"}"
    1707  #if RETVAL_INJECTED
    1708  	       " => {width=1, height=0}"
    1709  #endif
    1710  	       ") = " RETVAL,
    1711  	       XLAT_ARGS(KDFONTOP), XLAT_ARGS(KD_FONT_OP_SET_DEFAULT));
    1712  
    1713  	cfo->data[0] = 'x';
    1714  	sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1715  	printf("ioctl(-1, " XLAT_FMT ", {op=" XLAT_FMT ", width=1, height=0"
    1716  	       ", data=%p}"
    1717  #if RETVAL_INJECTED
    1718  	       " => {width=1, height=0}"
    1719  #endif
    1720  	       ") = " RETVAL,
    1721  	       XLAT_ARGS(KDFONTOP), XLAT_ARGS(KD_FONT_OP_SET_DEFAULT),
    1722  	       cfo_data_end - 1);
    1723  
    1724  	cfo->width = 0xcafebeef;
    1725  	cfo->height = 0xbea7bee5;
    1726  	cfo->data = cfo_data_end - 32;
    1727  	strcpy((char *) cfo->data,
    1728  	       "\1\2\3\r\n\t\v\f\\\"OH\377HAI\7\10\02101234567890x");
    1729  	for (size_t j = 0; j < 2; j++) {
    1730  		sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1731  		printf("ioctl(-1, " XLAT_FMT ", {op=" XLAT_FMT
    1732  		       ", width=3405692655, height=3198664421, data=\"\\1\\2\\3"
    1733  		       "\\r\\n\\t\\v\\f\\\\\\\"OH\\377HAI\\7\\10\\0210123456789"
    1734  		       "0x\"%s}"
    1735  #if RETVAL_INJECTED
    1736  		       " => {width=3405692655, height=3198664421}"
    1737  #endif
    1738  		       ") = " RETVAL,
    1739  		       XLAT_ARGS(KDFONTOP), XLAT_ARGS(KD_FONT_OP_SET_DEFAULT),
    1740  		       j ? "..." : "");
    1741  
    1742  		cfo->data[31] = 'y';
    1743  	}
    1744  
    1745  	cfo->op = 3;
    1746  	cfo->height = 0;
    1747  	sys_ioctl(-1, KDFONTOP, (uintptr_t) cfo);
    1748  	printf("ioctl(-1, " XLAT_FMT ", {op=" XLAT_FMT ", height=0}) = " RETVAL,
    1749  	       XLAT_ARGS(KDFONTOP), XLAT_ARGS(KD_FONT_OP_COPY));
    1750  
    1751  
    1752  	/* KDGKBDIACRUC */
    1753  	check_diacruc(ARG_STR(KDGKBDIACRUC));
    1754  
    1755  
    1756  	/* KDSKBDIACRUC */
    1757  	check_diacruc(ARG_STR(KDSKBDIACRUC));
    1758  
    1759  
    1760  	puts("+++ exited with 0 +++");
    1761  	return 0;
    1762  }