1#!/usr/bin/awk -f
2
3#===-- generate_netbsd_ioctls.awk ------------------------------------------===#
4#
5# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6# See https://llvm.org/LICENSE.txt for license information.
7# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8#
9#===------------------------------------------------------------------------===#
10#
11# This file is a generator of:
12#  - include/sanitizer/sanitizer_interceptors_ioctl_netbsd.inc
13#
14# This script reads public headers from a NetBSD host.
15#
16# This script shall be executed only on the newest NetBSD version.
17# This script will emit compat code for the older releases.
18#
19# NetBSD minimal version supported 9.0.
20# NetBSD current version supported 9.99.26.
21#
22#===------------------------------------------------------------------------===#
23
24BEGIN {
25  # hardcode the script name
26  script_name = "generate_netbsd_ioctls.awk"
27  outputinc = "../lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc"
28
29  # assert that we are in the directory with scripts
30  in_utils = system("test -f " script_name " && exit 1 || exit 0")
31  if (in_utils == 0) {
32    usage()
33  }
34
35  # assert 0 argument passed
36  if (ARGC != 1) {
37    usage()
38  }
39
40  # accept overloading CLANGFORMAT from environment
41  clangformat = "clang-format"
42  if ("CLANGFORMAT" in ENVIRON) {
43    clangformat = ENVIRON["CLANGFORMAT"]
44  }
45
46  # accept overloading ROOTDIR from environment
47  rootdir = "/usr/include/"
48  if ("ROOTDIR" in ENVIRON) {
49    rootdir = ENVIRON["ROOTDIR"]
50  }
51
52  # detect and register files to detect ioctl() definitions
53  ARGC = 1
54  cmd = "find " rootdir " -type f -name '*.h'"
55  while (cmd | getline) {
56    ARGV[ARGC++] = $0
57  }
58  close(cmd)
59
60  ioctl_table_max = 0
61}
62
63# Scan RCS ID
64FNR == 1 {
65  fname[ioctl_table_max] = substr(FILENAME, length(rootdir) + 1)
66}
67
68# _IO
69/[^a-zA-Z0-9_]_IO[W]*[R]*[ ]*\(/ && $2 ~ /^[A-Z_]+$/ {
70  if ($0 ~ /RAIDFRAME_GET_ACCTOTALS/ ||
71      $0 ~ /ALTQATTACH/ ||
72      $0 ~ /ALTQDETACH/ ||
73      $0 ~ /ALTQENABLE/ ||
74      $0 ~ /ALTQDISABLE/ ||
75      $0 ~ /ALTQCLEAR/ ||
76      $0 ~ /ALTQCONFIG/ ||
77      $0 ~ /ALTQADDCLASS/ ||
78      $0 ~ /ALTQMODCLASS/ ||
79      $0 ~ /ALTQDELCLASS/ ||
80      $0 ~ /ALTQADDFILTER/ ||
81      $0 ~ /ALTQDELFILTER/ ||
82      $0 ~ /ALTQGETSTATS/ ||
83      $0 ~ /ALTQGETCNTR/ ||
84      $0 ~ /HFSC_IF_ATTACH/ ||
85      $0 ~ /HFSC_MOD_CLASS/ ||
86      $0 ~ /HLCD_DISPCTL/ ||
87      $0 ~ /HLCD_RESET/ ||
88      $0 ~ /HLCD_CLEAR/ ||
89      $0 ~ /HLCD_CURSOR_LEFT/ ||
90      $0 ~ /HLCD_CURSOR_RIGHT/ ||
91      $0 ~ /HLCD_GET_CURSOR_POS/ ||
92      $0 ~ /HLCD_SET_CURSOR_POS/ ||
93      $0 ~ /HLCD_GETC/ ||
94      $0 ~ /HLCD_PUTC/ ||
95      $0 ~ /HLCD_SHIFT_LEFT/ ||
96      $0 ~ /HLCD_SHIFT_RIGHT/ ||
97      $0 ~ /HLCD_HOME/ ||
98      $0 ~ /HLCD_WRITE/ ||
99      $0 ~ /HLCD_READ/ ||
100      $0 ~ /HLCD_REDRAW/ ||
101      $0 ~ /HLCD_WRITE_INST/ ||
102      $0 ~ /HLCD_WRITE_DATA/ ||
103      $0 ~ /HLCD_GET_INFO/ ||
104      $0 ~ /HLCD_GET_CHIPNO/ ||
105      $0 ~ /HLCD_SET_CHIPNO/ ||
106      $0 ~ /RAIDFRAME_TEST_ACC/ ||
107      $0 ~ /FBIOGINFO/ ||
108      $0 ~ /FBIOSATTR/ ||
109      $0 ~ /OBIOCDISK/ ||
110      $0 ~ /OBIOCVOL/ ||
111      $0 ~ /BIOCSORTIMEOUT/ ||
112      $0 ~ /BIOCGORTIMEOUT/ ||
113      $0 ~ /PPPIOCSPASS/ ||
114      $0 ~ /PPPIOCSACTIVE/ ||
115      $0 ~ /PPPIOCSIPASS/ ||
116      $0 ~ /PPPIOCSOPASS/ ||
117      $0 ~ /PPPIOCSIACTIVE/ ||
118      $0 ~ /PPPIOCSOACTIVE/ ||
119      $0 ~ /SIOCPROXY/ ||
120      $0 ~ /SIOCXRAWATM/ ||
121      $0 ~ /AGPIOC_RESERVE/ ||
122      $0 ~ /AGPIOC_PROTECT/ ||
123      $0 ~ /CDIOCREADSUBCHANNEL_BUF/ ||
124      $0 ~ /CDIOREADTOCENTRIES_BUF/ ||
125      $0 ~ /MMCGETDISCINFO/ ||
126      $0 ~ /MMCGETTRACKINFO/ ||
127      $0 ~ /MMCOP/ ||
128      $0 ~ /MMCSETUPWRITEPARAMS/ ||
129      $0 ~ /DIOCGPARTINFO/ ||
130      $0 ~ /ODIOCGDINFO/ ||
131      $0 ~ /ODIOCSDINFO/ ||
132      $0 ~ /ODIOCWDINFO/ ||
133      $0 ~ /ODIOCGDEFLABEL/ ||
134      $0 ~ /GPIOPINREAD/ ||
135      $0 ~ /GPIOPINWRITE/ ||
136      $0 ~ /GPIOPINTOGGLE/ ||
137      $0 ~ /GPIOPINCTL/ ||
138      $0 ~ /GPIODETACH/ ||
139      $0 ~ /SEQUENCER_PERCMODE/ ||
140      $0 ~ /SEQUENCER_TESTMIDI/ ||
141      $0 ~ /SEQUENCER_MIDI_INFO/ ||
142      $0 ~ /SEQUENCER_ID/ ||
143      $0 ~ /SEQUENCER_CONTROL/ ||
144      $0 ~ /SEQUENCER_REMOVESAMPLE/ ||
145      $0 ~ /EVTCHN_RESET/ ||
146      $0 ~ /EVTCHN_BIND/ ||
147      $0 ~ /EVTCHN_UNBIND/) {
148    # broken entry, incomplete definition of the 3rd parameterm etc
149    next
150  }
151
152  if ($0 ~ /APM_IOC_STANDBY/ ||
153      $0 ~ /APM_IOC_SUSPEND/ ||
154      $0 ~ /SCIOC_USE_ADF/ ||
155      $0 ~ /SCBUSIOLLSCAN/ ||
156      $0 ~ /UTOPPYIOCANCEL/ ||
157      $0 ~ /JOY_GET_X_OFFSET/ ||
158      $0 ~ /CHIOGPICKER/ ||
159      $0 ~ /SLIOCGUNIT/ ||
160      $0 ~ /TUNSLMODE/ ||
161      $0 ~ /CBQ_IF_ATTACH/ ||
162      $0 ~ /CDNR_IF_ATTACH/ ||
163      $0 ~ /RIO_IF_ATTACH/ ||
164      $0 ~ /CBQ_IF_DETACH/ ||
165      $0 ~ /HFSC_IF_DETACH/ ||
166      $0 ~ /WFQ_IF_DETACH/ ||
167      $0 ~ /RIO_IF_DETACH/ ||
168      $0 ~ /FIFOQ_IF_DETACH/ ||
169      $0 ~ /RED_IF_DETACH/ ||
170      $0 ~ /CDNR_ENABLE/ ||
171      $0 ~ /HFSC_ENABLE/ ||
172      $0 ~ /WFQ_ENABLE/ ||
173      $0 ~ /RIO_ENABLE/ ||
174      $0 ~ /FIFOQ_ENABLE/ ||
175      $0 ~ /RED_ENABLE/ ||
176      $0 ~ /BLUE_ENABLE/ ||
177      $0 ~ /CDNR_DISABLE/ ||
178      $0 ~ /HFSC_DISABLE/ ||
179      $0 ~ /WFQ_DISABLE/ ||
180      $0 ~ /RIO_DISABLE/ ||
181      $0 ~ /FIFOQ_DISABLE/ ||
182      $0 ~ /PRIQ_DISABLE/ ||
183      $0 ~ /CDNR_DEL_FILTER/ ||
184      $0 ~ /JOBS_DEL_CLASS/ ||
185      $0 ~ /JOBS_DEL_FILTER/ ||
186      $0 ~ /JOBS_GETSTATS/ ||
187      $0 ~ /WFQ_GET_STATS/ ||
188      $0 ~ /CBQ_ADD_FILTER/ ||
189      $0 ~ /HFSC_ADD_FILTER/ ||
190      $0 ~ /JOBS_ADD_FILTER/ ||
191      $0 ~ /RED_IF_ATTACH/ ||
192      $0 ~ /FIFOQ_IF_ATTACH/ ||
193      $0 ~ /BLUE_IF_DETACH/ ||
194      $0 ~ /CBQ_DISABLE/ ||
195      $0 ~ /RED_DISABLE/ ||
196      $0 ~ /CBQ_CLEAR_HIERARCHY/ ||
197      $0 ~ /HFSC_DEL_CLASS/ ||
198      $0 ~ /PRIQ_IF_DETACH/ ||
199      $0 ~ /PRIQ_ENABLE/ ||
200      $0 ~ /WFQ_IF_ATTACH/ ||
201      $0 ~ /POWER_IOC_GET_TYPE_WITH_LOSSAGE/ ||
202      $0 ~ /HFSC_DEL_FILTER/) {
203    # There are entries with duplicate codes.. disable the less used ones
204    next
205  }
206
207  if ($2 in known) {
208    # Avoid duplicates
209    # There are entries compatible with K&R and ANSI preprocessor
210    next
211  }
212
213  known[$2] = 1
214
215  ioctl_name[ioctl_table_max] = $2
216
217  split($3, a, "(")
218  a3 = a[1]
219  if (a3 ~ /_IO[ ]*$/) {
220    ioctl_mode[ioctl_table_max] = "NONE"
221  } else if (a3 ~ /_IOR[ ]*$/) {
222    ioctl_mode[ioctl_table_max] = "WRITE"
223  } else if (a3 ~ /_IOW[ ]*$/) {
224    ioctl_mode[ioctl_table_max] = "READ"
225  } else if (a3 ~ /_IOWR[ ]*$/) {
226    ioctl_mode[ioctl_table_max] = "READWRITE"
227  } else {
228    print "Unknown mode, cannot parse: '" $3 "'"
229  }
230
231  # This !NONE check allows to skip some unparsable entries
232  if (ioctl_mode[ioctl_table_max] != "NONE") {
233    n = split($0, a, ",")
234    if (n == 3) {
235      gsub(/^[ ]+/, "", a[3])
236      match(a[3], /[a-zA-Z0-9_* ]+/)
237      type = get_type(substr(a[3], 0, RLENGTH))
238      ioctl_type[ioctl_table_max] = type
239    }
240  }
241
242  ioctl_table_max++
243}
244
245END {
246  # empty files?
247  if (NR < 1 && !abnormal_exit) {
248    usage()
249  }
250
251  # Handle abnormal exit
252  if (abnormal_exit) {
253    exit(abnormal_exit)
254  }
255
256  # Add compat entries
257  add_compat("dev/filemon/filemon.h (compat <= 9.99.26)", "FILEMON_SET_FD", "READWRITE", "sizeof(int)")
258  add_compat("", "FILEMON_SET_PID", "READWRITE", "sizeof(int)")
259  add_compat("dev/usb/urio.h (compat <= 9.99.43)", "URIO_SEND_COMMAND", "READWRITE", "struct_urio_command_sz")
260  add_compat("", "URIO_RECV_COMMAND", "READWRITE", "struct_urio_command_sz")
261
262  # Generate sanitizer_interceptors_ioctl_netbsd.inc
263
264  # open pipe
265  cmd = clangformat " > " outputinc
266
267  pcmd("//===-- sanitizer_interceptors_ioctl_netbsd.inc -----------------*- C++ -*-===//")
268  pcmd("//")
269  pcmd("// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.")
270  pcmd("// See https://llvm.org/LICENSE.txt for license information.")
271  pcmd("// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception")
272  pcmd("//")
273  pcmd("//===----------------------------------------------------------------------===//")
274  pcmd("//")
275  pcmd("// Ioctl handling in common sanitizer interceptors.")
276  pcmd("//===----------------------------------------------------------------------===//")
277  pcmd("")
278  pcmd("#if SANITIZER_NETBSD")
279  pcmd("")
280  pcmd("#include \"sanitizer_flags.h\"")
281  pcmd("")
282  pcmd("struct ioctl_desc {")
283  pcmd("  unsigned req;")
284  pcmd("  // FIXME: support read+write arguments. Currently READWRITE and WRITE do the")
285  pcmd("  // same thing.")
286  pcmd("  // XXX: The declarations below may use WRITE instead of READWRITE, unless")
287  pcmd("  // explicitly noted.")
288  pcmd("  enum {")
289  pcmd("    NONE,")
290  pcmd("    READ,")
291  pcmd("    WRITE,")
292  pcmd("    READWRITE,")
293  pcmd("    CUSTOM")
294  pcmd("  } type : 3;")
295  pcmd("  unsigned size : 29;")
296  pcmd("  const char* name;")
297  pcmd("};")
298  pcmd("")
299  pcmd("const unsigned ioctl_table_max = " ioctl_table_max ";")
300  pcmd("static ioctl_desc ioctl_table[ioctl_table_max];")
301  pcmd("static unsigned ioctl_table_size = 0;")
302  pcmd("")
303  pcmd("// This can not be declared as a global, because references to struct_*_sz")
304  pcmd("// require a global initializer. And this table must be available before global")
305  pcmd("// initializers are run.")
306  pcmd("static void ioctl_table_fill() {")
307  pcmd("#define _(rq, tp, sz)                                    \\")
308  pcmd("  if (IOCTL_##rq != IOCTL_NOT_PRESENT) {                 \\")
309  pcmd("    CHECK(ioctl_table_size < ioctl_table_max);           \\")
310  pcmd("    ioctl_table[ioctl_table_size].req = IOCTL_##rq;      \\")
311  pcmd("    ioctl_table[ioctl_table_size].type = ioctl_desc::tp; \\")
312  pcmd("    ioctl_table[ioctl_table_size].size = sz;             \\")
313  pcmd("    ioctl_table[ioctl_table_size].name = #rq;            \\")
314  pcmd("    ++ioctl_table_size;                                  \\")
315  pcmd("  }")
316  pcmd("")
317
318  for (i = 0; i < ioctl_table_max; i++) {
319    if (i in fname && fname[i] == "dev/nvmm/nvmm_ioctl.h") {
320      pcmd("#if defined(__x86_64__)")
321    }
322    if (i in fname) {
323      pcmd("  /* Entries from file: " fname[i] " */")
324    }
325
326    if (i in ioctl_type) {
327      type = ioctl_type[i]
328    } else {
329      type = "0"
330    }
331
332    pcmd("  _(" ioctl_name[i] ", " ioctl_mode[i] "," type ");")
333
334    if (ioctl_name[i] == "NVMM_IOC_CTL") {
335      pcmd("#endif")
336    }
337  }
338
339  pcmd("#undef _")
340  pcmd("}")
341  pcmd("")
342  pcmd("static bool ioctl_initialized = false;")
343  pcmd("")
344  pcmd("struct ioctl_desc_compare {")
345  pcmd("  bool operator()(const ioctl_desc& left, const ioctl_desc& right) const {")
346  pcmd("    return left.req < right.req;")
347  pcmd("  }")
348  pcmd("};")
349  pcmd("")
350  pcmd("static void ioctl_init() {")
351  pcmd("  ioctl_table_fill();")
352  pcmd("  Sort(ioctl_table, ioctl_table_size, ioctl_desc_compare());")
353  pcmd("")
354  pcmd("  bool bad = false;")
355  pcmd("  for (unsigned i = 0; i < ioctl_table_size - 1; ++i) {")
356  pcmd("    if (ioctl_table[i].req >= ioctl_table[i + 1].req) {")
357  pcmd("      Printf(\"Duplicate or unsorted ioctl request id %x >= %x (%s vs %s)\\n\",")
358  pcmd("             ioctl_table[i].req, ioctl_table[i + 1].req, ioctl_table[i].name,")
359  pcmd("             ioctl_table[i + 1].name);")
360  pcmd("      bad = true;")
361  pcmd("    }")
362  pcmd("  }")
363  pcmd("")
364  pcmd("  if (bad) Die();")
365  pcmd("")
366  pcmd("  ioctl_initialized = true;")
367  pcmd("}")
368  pcmd("")
369  pcmd("static const ioctl_desc *ioctl_table_lookup(unsigned req) {")
370  pcmd("  int left = 0;")
371  pcmd("  int right = ioctl_table_size;")
372  pcmd("  while (left < right) {")
373  pcmd("    int mid = (left + right) / 2;")
374  pcmd("    if (ioctl_table[mid].req < req)")
375  pcmd("      left = mid + 1;")
376  pcmd("    else")
377  pcmd("      right = mid;")
378  pcmd("  }")
379  pcmd("  if (left == right && ioctl_table[left].req == req)")
380  pcmd("    return ioctl_table + left;")
381  pcmd("  else")
382  pcmd("    return nullptr;")
383  pcmd("}")
384  pcmd("")
385  pcmd("static bool ioctl_decode(unsigned req, ioctl_desc *desc) {")
386  pcmd("  CHECK(desc);")
387  pcmd("  desc->req = req;")
388  pcmd("  desc->name = \"<DECODED_IOCTL>\";")
389  pcmd("  desc->size = IOC_SIZE(req);")
390  pcmd("  // Sanity check.")
391  pcmd("  if (desc->size > 0xFFFF) return false;")
392  pcmd("  unsigned dir = IOC_DIR(req);")
393  pcmd("  switch (dir) {")
394  pcmd("    case IOC_NONE:")
395  pcmd("      desc->type = ioctl_desc::NONE;")
396  pcmd("      break;")
397  pcmd("    case IOC_READ | IOC_WRITE:")
398  pcmd("      desc->type = ioctl_desc::READWRITE;")
399  pcmd("      break;")
400  pcmd("    case IOC_READ:")
401  pcmd("      desc->type = ioctl_desc::WRITE;")
402  pcmd("      break;")
403  pcmd("    case IOC_WRITE:")
404  pcmd("      desc->type = ioctl_desc::READ;")
405  pcmd("      break;")
406  pcmd("    default:")
407  pcmd("      return false;")
408  pcmd("  }")
409  pcmd("  // Size can be 0 iff type is NONE.")
410  pcmd("  if ((desc->type == IOC_NONE) != (desc->size == 0)) return false;")
411  pcmd("  // Sanity check.")
412  pcmd("  if (IOC_TYPE(req) == 0) return false;")
413  pcmd("  return true;")
414  pcmd("}")
415  pcmd("")
416  pcmd("static const ioctl_desc *ioctl_lookup(unsigned req) {")
417  pcmd("  const ioctl_desc *desc = ioctl_table_lookup(req);")
418  pcmd("  if (desc) return desc;")
419  pcmd("")
420  pcmd("  // Try stripping access size from the request id.")
421  pcmd("  desc = ioctl_table_lookup(req & ~(IOC_SIZEMASK << IOC_SIZESHIFT));")
422  pcmd("  // Sanity check: requests that encode access size are either read or write and")
423  pcmd("  // have size of 0 in the table.")
424  pcmd("  if (desc && desc->size == 0 &&")
425  pcmd("      (desc->type == ioctl_desc::READWRITE || desc->type == ioctl_desc::WRITE ||")
426  pcmd("       desc->type == ioctl_desc::READ))")
427  pcmd("    return desc;")
428  pcmd("  return nullptr;")
429  pcmd("}")
430  pcmd("")
431  pcmd("static void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d,")
432  pcmd("                             unsigned request, void *arg) {")
433  pcmd("  if (desc->type == ioctl_desc::READ || desc->type == ioctl_desc::READWRITE) {")
434  pcmd("    unsigned size = desc->size ? desc->size : IOC_SIZE(request);")
435  pcmd("    COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, size);")
436  pcmd("  }")
437  pcmd("  if (desc->type != ioctl_desc::CUSTOM)")
438  pcmd("    return;")
439  pcmd("  if (request == IOCTL_SIOCGIFCONF) {")
440  pcmd("    struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;")
441  pcmd("    COMMON_INTERCEPTOR_READ_RANGE(ctx, (char*)&ifc->ifc_len,")
442  pcmd("                                  sizeof(ifc->ifc_len));")
443  pcmd("  }")
444  pcmd("}")
445  pcmd("")
446  pcmd("static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d,")
447  pcmd("                              unsigned request, void *arg) {")
448  pcmd("  if (desc->type == ioctl_desc::WRITE || desc->type == ioctl_desc::READWRITE) {")
449  pcmd("    // FIXME: add verbose output")
450  pcmd("    unsigned size = desc->size ? desc->size : IOC_SIZE(request);")
451  pcmd("    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg, size);")
452  pcmd("  }")
453  pcmd("  if (desc->type != ioctl_desc::CUSTOM)")
454  pcmd("    return;")
455  pcmd("  if (request == IOCTL_SIOCGIFCONF) {")
456  pcmd("    struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;")
457  pcmd("    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);")
458  pcmd("  }")
459  pcmd("}")
460  pcmd("")
461  pcmd("#endif // SANITIZER_NETBSD")
462
463  close(cmd)
464}
465
466function usage()
467{
468  print "Usage: " script_name
469  abnormal_exit = 1
470  exit 1
471}
472
473function pcmd(string)
474{
475  print string | cmd
476}
477
478function get_type(string)
479{
480  if (string == "int") {
481    return "sizeof(int)"
482  } else if (string == "unsigned int" || string == "u_int" || string == "uint") {
483    return "sizeof(unsigned int)"
484  } else if (string == "long") {
485    return "sizeof(long)"
486  } else if (string == "unsigned long" || string == "u_long") {
487    return "sizeof(unsigned long)"
488  } else if (string == "short") {
489    return "sizeof(short)"
490  } else if (string == "unsigned short") {
491    return "sizeof(unsigned short)"
492  } else if (string == "char") {
493    return "sizeof(char)"
494  } else if (string == "signed char") {
495    return "sizeof(signed char)"
496  } else if (string == "unsigned char") {
497    return "sizeof(unsigned char)"
498  } else if (string == "uint8_t") {
499    return "sizeof(u8)"
500  } else if (string == "uint16_t") {
501    return "sizeof(u16)"
502  } else if (string == "u_int32_t" || string == "uint32_t") {
503    return "sizeof(u32)"
504  } else if (string == "u_int64_t" || string == "uint64_t") {
505    return "sizeof(u64)"
506  } else if (string ~ /\*$/) {
507    return "sizeof(uptr)"
508  } else if (string == "off_t") {
509    return "sizeof(uptr)"
510  } else if (string == "pid_t" || string == "kbd_t") {
511    return "sizeof(int)"
512  } else if (string == "daddr_t" || string == "dev_t") {
513    return "sizeof(u64)"
514  } else if (substr(string, 0, 7) == "struct " ) {
515    gsub(/ /, "", string)
516    return "struct_" substr(string, 7) "_sz"
517  } else if (string == "scsireq_t") {
518    return "struct_scsireq_sz"
519  } else if (string == "tone_t") {
520    return "struct_tone_sz"
521  } else if (string == "union twe_statrequest") {
522    return "union_twe_statrequest_sz"
523  } else if (string == "usb_device_descriptor_t") {
524    return "struct_usb_device_descriptor_sz"
525  } else if (string == "v4l2_std_id") {
526    return "sizeof(u64)"
527  } else if (string == "vtmode_t") {
528    return "struct_vt_mode_sz"
529  } else if (string == "_old_mixer_info") {
530    return "struct__old_mixer_info_sz"
531  } else if (string == "agp_allocate") {
532    return "struct__agp_allocate_sz"
533  } else if (string == "agp_bind") {
534    return "struct__agp_bind_sz"
535  } else if (string == "agp_info") {
536    return "struct__agp_info_sz"
537  } else if (string == "agp_region") {
538    return "struct__agp_region_sz"
539  } else if (string == "agp_setup") {
540    return "struct__agp_setup_sz"
541  } else if (string == "agp_unbind") {
542    return "struct__agp_unbind_sz"
543  } else if (string == "atareq_t") {
544    return "struct_atareq_sz"
545  } else if (string == "cpustate_t") {
546    return "struct_cpustate_sz"
547  } else if (string == "dmx_caps_t") {
548    return "struct_dmx_caps_sz"
549  } else if (string == "dmx_source_t") {
550    return "enum_dmx_source_sz"
551  } else if (string == "dvd_authinfo") {
552    return "union_dvd_authinfo_sz"
553  } else if (string == "dvd_struct") {
554    return "union_dvd_struct_sz"
555  } else if (string == "enum v4l2_priority") {
556    return "enum_v4l2_priority_sz"
557  } else if (string == "envsys_basic_info_t") {
558    return "struct_envsys_basic_info_sz"
559  } else if (string == "envsys_tre_data_t") {
560    return "struct_envsys_tre_data_sz"
561  } else if (string == "ext_accm") {
562    return "(8 * sizeof(u32))"
563  } else if (string == "fe_sec_mini_cmd_t") {
564    return "enum_fe_sec_mini_cmd_sz"
565  } else if (string == "fe_sec_tone_mode_t") {
566    return "enum_fe_sec_tone_mode_sz"
567  } else if (string == "fe_sec_voltage_t") {
568    return "enum_fe_sec_voltage_sz"
569  } else if (string == "fe_status_t") {
570    return "enum_fe_status_sz"
571  } else if (string == "gdt_ctrt_t") {
572    return "struct_gdt_ctrt_sz"
573  } else if (string == "gdt_event_t") {
574    return "struct_gdt_event_sz"
575  } else if (string == "gdt_osv_t") {
576    return "struct_gdt_osv_sz"
577  } else if (string == "gdt_rescan_t") {
578    return "struct_gdt_rescan_sz"
579  } else if (string == "gdt_statist_t") {
580    return "struct_gdt_statist_sz"
581  } else if (string == "gdt_ucmd_t") {
582    return "struct_gdt_ucmd_sz"
583  } else if (string == "iscsi_conn_status_parameters_t") {
584    return "struct_iscsi_conn_status_parameters_sz"
585  } else if (string == "iscsi_get_version_parameters_t") {
586    return "struct_iscsi_get_version_parameters_sz"
587  } else if (string == "iscsi_iocommand_parameters_t") {
588    return "struct_iscsi_iocommand_parameters_sz"
589  } else if (string == "iscsi_login_parameters_t") {
590    return "struct_iscsi_login_parameters_sz"
591  } else if (string == "iscsi_logout_parameters_t") {
592    return "struct_iscsi_logout_parameters_sz"
593  } else if (string == "iscsi_register_event_parameters_t") {
594    return "struct_iscsi_register_event_parameters_sz"
595  } else if (string == "iscsi_remove_parameters_t") {
596    return "struct_iscsi_remove_parameters_sz"
597  } else if (string == "iscsi_send_targets_parameters_t") {
598    return "struct_iscsi_send_targets_parameters_sz"
599  } else if (string == "iscsi_set_node_name_parameters_t") {
600    return "struct_iscsi_set_node_name_parameters_sz"
601  } else if (string == "iscsi_wait_event_parameters_t") {
602    return "struct_iscsi_wait_event_parameters_sz"
603  } else if (string == "isp_stats_t") {
604    return "struct_isp_stats_sz"
605  } else if (string == "lsenable_t") {
606    return "struct_lsenable_sz"
607  } else if (string == "lsdisable_t") {
608    return "struct_lsdisable_sz"
609  } else if (string == "mixer_ctrl_t") {
610    return "struct_mixer_ctrl_sz"
611  } else if (string == "mixer_devinfo_t") {
612    return "struct_mixer_devinfo_sz"
613  } else if (string == "mpu_command_rec") {
614    return "struct_mpu_command_rec_sz"
615  } else if (string == "rndstat_t") {
616    return "struct_rndstat_sz"
617  } else if (string == "rndstat_name_t") {
618    return "struct_rndstat_name_sz"
619  } else if (string == "rndctl_t") {
620    return "struct_rndctl_sz"
621  } else if (string == "rnddata_t") {
622    return "struct_rnddata_sz"
623  } else if (string == "rndpoolstat_t") {
624    return "struct_rndpoolstat_sz"
625  } else if (string == "rndstat_est_t") {
626    return "struct_rndstat_est_sz"
627  } else if (string == "rndstat_est_name_t") {
628    return "struct_rndstat_est_name_sz"
629  } else if (string == "pps_params_t") {
630    return "struct_pps_params_sz"
631  } else if (string == "pps_info_t") {
632    return "struct_pps_info_sz"
633  } else if (string == "linedn_t") {
634    return "(32 * sizeof(char))"
635  } else if (string == "mixer_info") {
636    return "struct_mixer_info_sz"
637  } else if (string == "RF_SparetWait_t") {
638    return "struct_RF_SparetWait_sz"
639  } else if (string == "RF_ComponentLabel_t") {
640    return "struct_RF_ComponentLabel_sz"
641  } else if (string == "RF_SingleComponent_t") {
642    return "struct_RF_SingleComponent_sz"
643  } else if (string == "RF_ProgressInfo_t") {
644    return "struct_RF_ProgressInfo_sz"
645  } else if (string == "nvlist_ref_t") {
646    return "struct_nvlist_ref_sz"
647  } else if (string == "spi_ioctl_transfer_t") {
648    return "struct_spi_ioctl_transfer_sz"
649  } else if (string == "spi_ioctl_configure_t") {
650    return "struct_spi_ioctl_configure_sz"
651  } else {
652    print "Unrecognized entry: " string
653    print "Aborting"
654    abnormal_exit = 1
655    exit 1
656  }
657
658  return string
659}
660
661function add_compat(path, name, mode, type)
662{
663  if (path != "") {
664    fname[ioctl_table_max] = path
665  }
666  ioctl_name[ioctl_table_max] = name
667  ioctl_mode[ioctl_table_max] = mode
668  ioctl_type[ioctl_table_max] = type
669  ioctl_table_max++
670}
671