blob: 9a92ff82a68661f485cde8786b668acc6482df43 [file] [log] [blame]
Kamil Rytarowski5ffda0c2018-02-15 03:36:16 +00001#!/usr/bin/awk -f
2
3#===-- generate_netbsd_ioctls.awk ------------------------------------------===#
4#
5# The LLVM Compiler Infrastructure
6#
7# This file is distributed under the University of Illinois Open Source
8# License. See LICENSE.TXT for details.
9#
10#===------------------------------------------------------------------------===#
11#
12# This file is a generator of:
13# - include/sanitizer/sanitizer_interceptors_ioctl_netbsd.inc
14#
15# This script reads public headers from a NetBSD host.
16#
17#===------------------------------------------------------------------------===#
18
19BEGIN {
20 # harcode the script name
21 script_name = "generate_netbsd_ioctls.awk"
22 outputinc = "../lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc"
23
24 # assert that we are in the directory with scripts
25 in_utils = system("test -f " script_name " && exit 1 || exit 0")
26 if (in_utils == 0) {
27 usage()
28 }
29
30 # assert 0 argument passed
31 if (ARGC != 1) {
32 usage()
33 }
34
35 # accept overloading CLANGFORMAT from environment
36 clangformat = "clang-format"
37 if ("CLANGFORMAT" in ENVIRON) {
38 clangformat = ENVIRON["CLANGFORMAT"]
39 }
40
41 # accept overloading ROOTDIR from environment
42 rootdir = "/usr/include/"
43 if ("ROOTDIR" in ENVIRON) {
44 rootdir = ENVIRON["ROOTDIR"]
45 }
46
47 # hardcode list of headers with ioctl(2) entries
48 # List generated manually with the following script:
49 # for w in `find /usr/include/ -type f -name '*.h' -exec echo {} \;`; \
50 # do awk '/[^a-zA-Z0-9_]_IO[W]*[R]*[ ]*\(/ && $2 ~ /^[A-Z_]+$/ {got=1} END{if(got) {print ARGV[1]}}' $w; \
51 # done|awk '{print " ARGV[ARGC++] = rootdir \"" substr($0, 14) "\""}'
52
53 ARGV[ARGC++] = rootdir "altq/altq_afmap.h"
54 ARGV[ARGC++] = rootdir "altq/altq.h"
55 ARGV[ARGC++] = rootdir "altq/altq_blue.h"
56 ARGV[ARGC++] = rootdir "altq/altq_cbq.h"
57 ARGV[ARGC++] = rootdir "altq/altq_cdnr.h"
58 ARGV[ARGC++] = rootdir "altq/altq_fifoq.h"
59 ARGV[ARGC++] = rootdir "altq/altq_hfsc.h"
60 ARGV[ARGC++] = rootdir "altq/altq_jobs.h"
61 ARGV[ARGC++] = rootdir "altq/altq_priq.h"
62 ARGV[ARGC++] = rootdir "altq/altq_red.h"
63 ARGV[ARGC++] = rootdir "altq/altq_rio.h"
64 ARGV[ARGC++] = rootdir "altq/altq_wfq.h"
65 ARGV[ARGC++] = rootdir "crypto/cryptodev.h"
66 ARGV[ARGC++] = rootdir "dev/apm/apmio.h"
67 ARGV[ARGC++] = rootdir "dev/dm/netbsd-dm.h"
68 ARGV[ARGC++] = rootdir "dev/dmover/dmover_io.h"
69 ARGV[ARGC++] = rootdir "dev/dtv/dtvio_demux.h"
70 ARGV[ARGC++] = rootdir "dev/dtv/dtvio_frontend.h"
71 ARGV[ARGC++] = rootdir "dev/filemon/filemon.h"
72 ARGV[ARGC++] = rootdir "dev/hdaudio/hdaudioio.h"
73 ARGV[ARGC++] = rootdir "dev/hdmicec/hdmicecio.h"
74 ARGV[ARGC++] = rootdir "dev/hpc/hpcfbio.h"
75 ARGV[ARGC++] = rootdir "dev/i2o/iopio.h"
76 ARGV[ARGC++] = rootdir "dev/ic/athioctl.h"
77 ARGV[ARGC++] = rootdir "dev/ic/bt8xx.h"
78 ARGV[ARGC++] = rootdir "dev/ic/hd44780var.h"
79 ARGV[ARGC++] = rootdir "dev/ic/icp_ioctl.h"
80 ARGV[ARGC++] = rootdir "dev/ic/isp_ioctl.h"
81 ARGV[ARGC++] = rootdir "dev/ic/mlxio.h"
82 ARGV[ARGC++] = rootdir "dev/ic/nvmeio.h"
83 ARGV[ARGC++] = rootdir "dev/ir/irdaio.h"
84 ARGV[ARGC++] = rootdir "dev/isa/satlinkio.h"
85 ARGV[ARGC++] = rootdir "dev/isa/isvio.h"
86 ARGV[ARGC++] = rootdir "dev/isa/wtreg.h"
87 ARGV[ARGC++] = rootdir "dev/iscsi/iscsi_ioctl.h"
88 ARGV[ARGC++] = rootdir "dev/ofw/openfirmio.h"
89 ARGV[ARGC++] = rootdir "dev/pci/amrio.h"
90 ARGV[ARGC++] = rootdir "dev/pci/mlyio.h"
91 ARGV[ARGC++] = rootdir "dev/pci/pciio.h"
92 ARGV[ARGC++] = rootdir "dev/pci/tweio.h"
93 ARGV[ARGC++] = rootdir "dev/pcmcia/if_cnwioctl.h"
94 ARGV[ARGC++] = rootdir "dev/pcmcia/if_rayreg.h"
95 ARGV[ARGC++] = rootdir "dev/raidframe/raidframeio.h"
96 ARGV[ARGC++] = rootdir "dev/sbus/mbppio.h"
97 ARGV[ARGC++] = rootdir "dev/scsipi/ses.h"
98 ARGV[ARGC++] = rootdir "dev/sun/disklabel.h"
99 ARGV[ARGC++] = rootdir "dev/sun/fbio.h"
100 ARGV[ARGC++] = rootdir "dev/sun/kbio.h"
101 ARGV[ARGC++] = rootdir "dev/sun/vuid_event.h"
102 ARGV[ARGC++] = rootdir "dev/tc/sticio.h"
103 ARGV[ARGC++] = rootdir "dev/usb/ukyopon.h"
104 ARGV[ARGC++] = rootdir "dev/usb/urio.h"
105 ARGV[ARGC++] = rootdir "dev/usb/usb.h"
106 ARGV[ARGC++] = rootdir "dev/usb/utoppy.h"
107 ARGV[ARGC++] = rootdir "dev/vme/xio.h"
108 ARGV[ARGC++] = rootdir "dev/wscons/wsdisplay_usl_io.h"
109 ARGV[ARGC++] = rootdir "dev/wscons/wsconsio.h"
110 ARGV[ARGC++] = rootdir "dev/biovar.h"
111 ARGV[ARGC++] = rootdir "dev/md.h"
112 ARGV[ARGC++] = rootdir "dev/ccdvar.h"
113 ARGV[ARGC++] = rootdir "dev/cgdvar.h"
114 ARGV[ARGC++] = rootdir "dev/fssvar.h"
115 ARGV[ARGC++] = rootdir "dev/bluetooth/btdev.h"
116 ARGV[ARGC++] = rootdir "dev/bluetooth/btsco.h"
117 ARGV[ARGC++] = rootdir "dev/kttcpio.h"
118 ARGV[ARGC++] = rootdir "dev/lockstat.h"
119 ARGV[ARGC++] = rootdir "dev/vndvar.h"
120 ARGV[ARGC++] = rootdir "dev/spkrio.h"
121 ARGV[ARGC++] = rootdir "net/bpf.h"
122 ARGV[ARGC++] = rootdir "net/if_atm.h"
123 ARGV[ARGC++] = rootdir "net/if_gre.h"
124 ARGV[ARGC++] = rootdir "net/if_ppp.h"
125 ARGV[ARGC++] = rootdir "net/npf.h"
126 ARGV[ARGC++] = rootdir "net/if_pppoe.h"
127 ARGV[ARGC++] = rootdir "net/if_sppp.h"
128 ARGV[ARGC++] = rootdir "net/if_srt.h"
129 ARGV[ARGC++] = rootdir "net/if_tap.h"
130 ARGV[ARGC++] = rootdir "net/if_tun.h"
131 ARGV[ARGC++] = rootdir "net/pfvar.h"
132 ARGV[ARGC++] = rootdir "net/slip.h"
133 ARGV[ARGC++] = rootdir "netbt/hci.h"
134 ARGV[ARGC++] = rootdir "netinet/ip_nat.h"
135 ARGV[ARGC++] = rootdir "netinet/ip_proxy.h"
136 ARGV[ARGC++] = rootdir "netinet6/in6_var.h"
137 ARGV[ARGC++] = rootdir "netnatm/natm.h"
138 ARGV[ARGC++] = rootdir "netsmb/smb_dev.h"
139 ARGV[ARGC++] = rootdir "sys/agpio.h"
140 ARGV[ARGC++] = rootdir "sys/audioio.h"
141 ARGV[ARGC++] = rootdir "sys/ataio.h"
142 ARGV[ARGC++] = rootdir "sys/cdio.h"
143 ARGV[ARGC++] = rootdir "sys/chio.h"
144 ARGV[ARGC++] = rootdir "sys/clockctl.h"
145 ARGV[ARGC++] = rootdir "sys/cpuio.h"
146 ARGV[ARGC++] = rootdir "sys/dkio.h"
147 ARGV[ARGC++] = rootdir "sys/drvctlio.h"
148 ARGV[ARGC++] = rootdir "sys/dvdio.h"
149 ARGV[ARGC++] = rootdir "sys/envsys.h"
150 ARGV[ARGC++] = rootdir "sys/event.h"
151 ARGV[ARGC++] = rootdir "sys/fdio.h"
152 ARGV[ARGC++] = rootdir "sys/filio.h"
153 ARGV[ARGC++] = rootdir "sys/gpio.h"
154 ARGV[ARGC++] = rootdir "sys/ioctl.h"
155 ARGV[ARGC++] = rootdir "sys/ioctl_compat.h"
156 ARGV[ARGC++] = rootdir "sys/joystick.h"
157 ARGV[ARGC++] = rootdir "sys/ksyms.h"
158 ARGV[ARGC++] = rootdir "sys/lua.h"
159 ARGV[ARGC++] = rootdir "sys/midiio.h"
160 ARGV[ARGC++] = rootdir "sys/mtio.h"
161 ARGV[ARGC++] = rootdir "sys/power.h"
162 ARGV[ARGC++] = rootdir "sys/radioio.h"
163 ARGV[ARGC++] = rootdir "sys/rndio.h"
164 ARGV[ARGC++] = rootdir "sys/scanio.h"
165 ARGV[ARGC++] = rootdir "sys/scsiio.h"
166 ARGV[ARGC++] = rootdir "sys/sockio.h"
167 ARGV[ARGC++] = rootdir "sys/timepps.h"
168 ARGV[ARGC++] = rootdir "sys/ttycom.h"
169 ARGV[ARGC++] = rootdir "sys/verified_exec.h"
170 ARGV[ARGC++] = rootdir "sys/videoio.h"
171 ARGV[ARGC++] = rootdir "sys/wdog.h"
172 ARGV[ARGC++] = rootdir "soundcard.h"
173 ARGV[ARGC++] = rootdir "xen/xenio.h"
174
175 ioctl_table_max = 0
176}
177
178# Scan RCS ID
179FNR == 1 {
180 fname[ioctl_table_max] = substr(FILENAME, length(rootdir) + 1)
181}
182
183# _IO
184/[^a-zA-Z0-9_]_IO[W]*[R]*[ ]*\(/ && $2 ~ /^[A-Z_]+$/ {
185 if ($0 ~ /RAIDFRAME_GET_ACCTOTALS/ ||
186 $0 ~ /ALTQATTACH/ ||
187 $0 ~ /ALTQDETACH/ ||
188 $0 ~ /ALTQENABLE/ ||
189 $0 ~ /ALTQDISABLE/ ||
190 $0 ~ /ALTQCLEAR/ ||
191 $0 ~ /ALTQCONFIG/ ||
192 $0 ~ /ALTQADDCLASS/ ||
193 $0 ~ /ALTQMODCLASS/ ||
194 $0 ~ /ALTQDELCLASS/ ||
195 $0 ~ /ALTQADDFILTER/ ||
196 $0 ~ /ALTQDELFILTER/ ||
197 $0 ~ /ALTQGETSTATS/ ||
198 $0 ~ /ALTQGETCNTR/ ||
Kamil Rytarowskib6195b52018-02-26 13:00:40 +0000199 $0 ~ /HFSC_IF_ATTACH/ ||
200 $0 ~ /HFSC_MOD_CLASS/ ||
Kamil Rytarowski5ffda0c2018-02-15 03:36:16 +0000201 $0 ~ /HLCD_DISPCTL/ ||
202 $0 ~ /HLCD_RESET/ ||
203 $0 ~ /HLCD_CLEAR/ ||
204 $0 ~ /HLCD_CURSOR_LEFT/ ||
205 $0 ~ /HLCD_CURSOR_RIGHT/ ||
206 $0 ~ /HLCD_GET_CURSOR_POS/ ||
207 $0 ~ /HLCD_SET_CURSOR_POS/ ||
208 $0 ~ /HLCD_GETC/ ||
209 $0 ~ /HLCD_PUTC/ ||
210 $0 ~ /HLCD_SHIFT_LEFT/ ||
211 $0 ~ /HLCD_SHIFT_RIGHT/ ||
212 $0 ~ /HLCD_HOME/ ||
213 $0 ~ /HLCD_WRITE/ ||
214 $0 ~ /HLCD_READ/ ||
215 $0 ~ /HLCD_REDRAW/ ||
216 $0 ~ /HLCD_WRITE_INST/ ||
217 $0 ~ /HLCD_WRITE_DATA/ ||
218 $0 ~ /HLCD_GET_INFO/ ||
219 $0 ~ /HLCD_GET_CHIPNO/ ||
220 $0 ~ /HLCD_SET_CHIPNO/ ||
221 $0 ~ /RAIDFRAME_TEST_ACC/ ||
222 $0 ~ /FBIOGINFO/ ||
223 $0 ~ /FBIOSATTR/ ||
224 $0 ~ /OBIOCDISK/ ||
225 $0 ~ /OBIOCVOL/ ||
226 $0 ~ /BIOCSORTIMEOUT/ ||
227 $0 ~ /BIOCGORTIMEOUT/ ||
228 $0 ~ /PPPIOCSPASS/ ||
229 $0 ~ /PPPIOCSACTIVE/ ||
230 $0 ~ /PPPIOCSIPASS/ ||
231 $0 ~ /PPPIOCSOPASS/ ||
232 $0 ~ /PPPIOCSIACTIVE/ ||
233 $0 ~ /PPPIOCSOACTIVE/ ||
234 $0 ~ /SIOCPROXY/ ||
235 $0 ~ /SIOCXRAWATM/ ||
236 $0 ~ /AGPIOC_RESERVE/ ||
237 $0 ~ /AGPIOC_PROTECT/ ||
238 $0 ~ /CDIOCREADSUBCHANNEL_BUF/ ||
239 $0 ~ /CDIOREADTOCENTRIES_BUF/ ||
240 $0 ~ /MMCGETDISCINFO/ ||
241 $0 ~ /MMCGETTRACKINFO/ ||
242 $0 ~ /MMCOP/ ||
243 $0 ~ /MMCSETUPWRITEPARAMS/ ||
244 $0 ~ /DIOCGPARTINFO/ ||
245 $0 ~ /ODIOCGDINFO/ ||
246 $0 ~ /ODIOCSDINFO/ ||
247 $0 ~ /ODIOCWDINFO/ ||
248 $0 ~ /ODIOCGDEFLABEL/ ||
249 $0 ~ /GPIOPINREAD/ ||
250 $0 ~ /GPIOPINWRITE/ ||
251 $0 ~ /GPIOPINTOGGLE/ ||
252 $0 ~ /GPIOPINCTL/ ||
253 $0 ~ /GPIODETACH/ ||
254 $0 ~ /SEQUENCER_PERCMODE/ ||
255 $0 ~ /SEQUENCER_TESTMIDI/ ||
256 $0 ~ /SEQUENCER_MIDI_INFO/ ||
257 $0 ~ /SEQUENCER_ID/ ||
258 $0 ~ /SEQUENCER_CONTROL/ ||
259 $0 ~ /SEQUENCER_REMOVESAMPLE/ ||
260 $0 ~ /EVTCHN_RESET/ ||
261 $0 ~ /EVTCHN_BIND/ ||
262 $0 ~ /EVTCHN_UNBIND/) {
263 # broken entry, incomplete definition of the 3rd parameterm etc
264 next
265 }
266
267 if ($0 ~ /APM_IOC_STANDBY/ ||
268 $0 ~ /APM_IOC_SUSPEND/ ||
269 $0 ~ /SCIOC_USE_ADF/ ||
270 $0 ~ /SCBUSIOLLSCAN/ ||
271 $0 ~ /UTOPPYIOCANCEL/ ||
272 $0 ~ /JOY_GET_X_OFFSET/ ||
273 $0 ~ /CHIOGPICKER/ ||
274 $0 ~ /SLIOCGUNIT/ ||
275 $0 ~ /SATIOSBUFSIZE/ ||
276 $0 ~ /TUNSLMODE/ ||
277 $0 ~ /CBQ_IF_ATTACH/ ||
278 $0 ~ /CDNR_IF_ATTACH/ ||
279 $0 ~ /RIO_IF_ATTACH/ ||
280 $0 ~ /CBQ_IF_DETACH/ ||
281 $0 ~ /HFSC_IF_DETACH/ ||
282 $0 ~ /WFQ_IF_DETACH/ ||
283 $0 ~ /RIO_IF_DETACH/ ||
284 $0 ~ /FIFOQ_IF_DETACH/ ||
285 $0 ~ /RED_IF_DETACH/ ||
286 $0 ~ /CDNR_ENABLE/ ||
287 $0 ~ /HFSC_ENABLE/ ||
288 $0 ~ /WFQ_ENABLE/ ||
289 $0 ~ /RIO_ENABLE/ ||
290 $0 ~ /FIFOQ_ENABLE/ ||
291 $0 ~ /RED_ENABLE/ ||
292 $0 ~ /BLUE_ENABLE/ ||
293 $0 ~ /CDNR_DISABLE/ ||
294 $0 ~ /HFSC_DISABLE/ ||
295 $0 ~ /WFQ_DISABLE/ ||
296 $0 ~ /RIO_DISABLE/ ||
297 $0 ~ /FIFOQ_DISABLE/ ||
298 $0 ~ /PRIQ_DISABLE/ ||
299 $0 ~ /CDNR_DEL_FILTER/ ||
300 $0 ~ /JOBS_DEL_CLASS/ ||
301 $0 ~ /JOBS_DEL_FILTER/ ||
302 $0 ~ /JOBS_GETSTATS/ ||
303 $0 ~ /WFQ_GET_STATS/ ||
304 $0 ~ /CBQ_ADD_FILTER/ ||
305 $0 ~ /HFSC_ADD_FILTER/ ||
306 $0 ~ /JOBS_ADD_FILTER/ ||
307 $0 ~ /RED_IF_ATTACH/ ||
308 $0 ~ /FIFOQ_IF_ATTACH/ ||
309 $0 ~ /BLUE_IF_DETACH/ ||
310 $0 ~ /CBQ_DISABLE/ ||
311 $0 ~ /RED_DISABLE/ ||
312 $0 ~ /CBQ_CLEAR_HIERARCHY/ ||
313 $0 ~ /HFSC_DEL_CLASS/ ||
314 $0 ~ /PRIQ_IF_DETACH/ ||
315 $0 ~ /PRIQ_ENABLE/ ||
316 $0 ~ /WFQ_IF_ATTACH/ ||
317 $0 ~ /HFSC_DEL_FILTER/) {
318 # There are entries with duplicate codes.. disable the less used ones
319 next
320 }
321
322 if ($2 in known) {
323 # Avoid duplicates
324 # There are entries compatible with K&R and ANSI preprocessor
325 next
326 }
327
328 known[$2] = 1
329
330 ioctl_name[ioctl_table_max] = $2
331
332 split($3, a, "(")
333 a3 = a[1]
334 if (a3 ~ /_IO[ ]*$/) {
335 ioctl_mode[ioctl_table_max] = "NONE"
336 } else if (a3 ~ /_IOR[ ]*$/) {
337 ioctl_mode[ioctl_table_max] = "WRITE"
338 } else if (a3 ~ /_IOW[ ]*$/) {
339 ioctl_mode[ioctl_table_max] = "READ"
340 } else if (a3 ~ /_IOWR[ ]*$/) {
341 ioctl_mode[ioctl_table_max] = "READWRITE"
342 } else {
343 print "Unknown mode, cannot parse: '" $3 "'"
344 }
345
346 # This !NONE check allows to skip some unparsable entries
347 if (ioctl_mode[ioctl_table_max] != "NONE") {
348 # special cases first
349 if ($0 ~ /POWER_IOC_GET_TYPE_WITH_LOSSAGE/) {
350 ioctl_type[ioctl_table_max] = "sizeof(uptr)"
351 } else {
352 n = split($0, a, ",")
353 if (n == 3) {
354 gsub(/^[ ]+/, "", a[3])
355 match(a[3], /[a-zA-Z0-9_* ]+/)
356 type = get_type(substr(a[3], 0, RLENGTH))
357 ioctl_type[ioctl_table_max] = type
358 }
359 }
360 }
361
362 ioctl_table_max++
363}
364
365END {
366 # empty files?
367 if (NR < 1 && !abnormal_exit) {
368 usage()
369 }
370
371 # Handle abnormal exit
372 if (abnormal_exit) {
373 exit(abnormal_exit)
374 }
375
376 # Generate sanitizer_interceptors_ioctl_netbsd.inc
377
378 # open pipe
379 cmd = clangformat " > " outputinc
380
381 pcmd("//===-- sanitizer_interceptors_ioctl_netbsd.inc -----------------*- C++ -*-===//")
382 pcmd("//")
383 pcmd("// The LLVM Compiler Infrastructure")
384 pcmd("//")
385 pcmd("// This file is distributed under the University of Illinois Open Source")
386 pcmd("// License. See LICENSE.TXT for details.")
387 pcmd("//")
388 pcmd("//===----------------------------------------------------------------------===//")
389 pcmd("//")
390 pcmd("// Ioctl handling in common sanitizer interceptors.")
391 pcmd("//===----------------------------------------------------------------------===//")
392 pcmd("")
393 pcmd("#if SANITIZER_NETBSD")
394 pcmd("")
395 pcmd("#include \"sanitizer_flags.h\"")
396 pcmd("")
397 pcmd("struct ioctl_desc {")
398 pcmd(" unsigned req;")
399 pcmd(" // FIXME: support read+write arguments. Currently READWRITE and WRITE do the")
400 pcmd(" // same thing.")
401 pcmd(" // XXX: The declarations below may use WRITE instead of READWRITE, unless")
402 pcmd(" // explicitly noted.")
403 pcmd(" enum {")
404 pcmd(" NONE,")
405 pcmd(" READ,")
406 pcmd(" WRITE,")
407 pcmd(" READWRITE,")
408 pcmd(" CUSTOM")
409 pcmd(" } type : 3;")
410 pcmd(" unsigned size : 29;")
411 pcmd(" const char* name;")
412 pcmd("};")
413 pcmd("")
414 pcmd("const unsigned ioctl_table_max = " ioctl_table_max ";")
415 pcmd("static ioctl_desc ioctl_table[ioctl_table_max];")
416 pcmd("static unsigned ioctl_table_size = 0;")
417 pcmd("")
418 pcmd("// This can not be declared as a global, because references to struct_*_sz")
419 pcmd("// require a global initializer. And this table must be available before global")
420 pcmd("// initializers are run.")
421 pcmd("static void ioctl_table_fill() {")
422 pcmd("#define _(rq, tp, sz) \\")
423 pcmd(" if (IOCTL_##rq != IOCTL_NOT_PRESENT) { \\")
424 pcmd(" CHECK(ioctl_table_size < ioctl_table_max); \\")
425 pcmd(" ioctl_table[ioctl_table_size].req = IOCTL_##rq; \\")
426 pcmd(" ioctl_table[ioctl_table_size].type = ioctl_desc::tp; \\")
427 pcmd(" ioctl_table[ioctl_table_size].size = sz; \\")
428 pcmd(" ioctl_table[ioctl_table_size].name = #rq; \\")
429 pcmd(" ++ioctl_table_size; \\")
430 pcmd(" }")
431 pcmd("")
432
433 for (i = 0; i < ioctl_table_max; i++) {
434 if (i in fname) {
435 pcmd(" /* Entries from file: " fname[i] " */")
436 }
437
438 if (i in ioctl_type) {
439 type = ioctl_type[i]
440 } else {
441 type = "0"
442 }
443
444 pcmd(" _(" ioctl_name[i] ", " ioctl_mode[i] "," type ");")
445 }
446
447 pcmd("#undef _")
448 pcmd("}")
449 pcmd("")
450 pcmd("static bool ioctl_initialized = false;")
451 pcmd("")
452 pcmd("struct ioctl_desc_compare {")
453 pcmd(" bool operator()(const ioctl_desc& left, const ioctl_desc& right) const {")
454 pcmd(" return left.req < right.req;")
455 pcmd(" }")
456 pcmd("};")
457 pcmd("")
458 pcmd("static void ioctl_init() {")
459 pcmd(" ioctl_table_fill();")
Vitaly Bukad3e55bf72018-05-09 20:42:11 +0000460 pcmd(" Sort(ioctl_table, ioctl_table_size, ioctl_desc_compare());")
Kamil Rytarowski5ffda0c2018-02-15 03:36:16 +0000461 pcmd("")
462 pcmd(" bool bad = false;")
463 pcmd(" for (unsigned i = 0; i < ioctl_table_size - 1; ++i) {")
464 pcmd(" if (ioctl_table[i].req >= ioctl_table[i + 1].req) {")
465 pcmd(" Printf(\"Duplicate or unsorted ioctl request id %x >= %x (%s vs %s)\\n\",")
466 pcmd(" ioctl_table[i].req, ioctl_table[i + 1].req, ioctl_table[i].name,")
467 pcmd(" ioctl_table[i + 1].name);")
468 pcmd(" bad = true;")
469 pcmd(" }")
470 pcmd(" }")
471 pcmd("")
472 pcmd(" if (bad) Die();")
473 pcmd("")
474 pcmd(" ioctl_initialized = true;")
475 pcmd("}")
476 pcmd("")
477 pcmd("static const ioctl_desc *ioctl_table_lookup(unsigned req) {")
478 pcmd(" int left = 0;")
479 pcmd(" int right = ioctl_table_size;")
480 pcmd(" while (left < right) {")
481 pcmd(" int mid = (left + right) / 2;")
482 pcmd(" if (ioctl_table[mid].req < req)")
483 pcmd(" left = mid + 1;")
484 pcmd(" else")
485 pcmd(" right = mid;")
486 pcmd(" }")
487 pcmd(" if (left == right && ioctl_table[left].req == req)")
488 pcmd(" return ioctl_table + left;")
489 pcmd(" else")
490 pcmd(" return nullptr;")
491 pcmd("}")
492 pcmd("")
493 pcmd("static bool ioctl_decode(unsigned req, ioctl_desc *desc) {")
494 pcmd(" CHECK(desc);")
495 pcmd(" desc->req = req;")
496 pcmd(" desc->name = \"<DECODED_IOCTL>\";")
497 pcmd(" desc->size = IOC_SIZE(req);")
498 pcmd(" // Sanity check.")
499 pcmd(" if (desc->size > 0xFFFF) return false;")
500 pcmd(" unsigned dir = IOC_DIR(req);")
501 pcmd(" switch (dir) {")
502 pcmd(" case IOC_NONE:")
503 pcmd(" desc->type = ioctl_desc::NONE;")
504 pcmd(" break;")
505 pcmd(" case IOC_READ | IOC_WRITE:")
506 pcmd(" desc->type = ioctl_desc::READWRITE;")
507 pcmd(" break;")
508 pcmd(" case IOC_READ:")
509 pcmd(" desc->type = ioctl_desc::WRITE;")
510 pcmd(" break;")
511 pcmd(" case IOC_WRITE:")
512 pcmd(" desc->type = ioctl_desc::READ;")
513 pcmd(" break;")
514 pcmd(" default:")
515 pcmd(" return false;")
516 pcmd(" }")
517 pcmd(" // Size can be 0 iff type is NONE.")
518 pcmd(" if ((desc->type == IOC_NONE) != (desc->size == 0)) return false;")
519 pcmd(" // Sanity check.")
520 pcmd(" if (IOC_TYPE(req) == 0) return false;")
521 pcmd(" return true;")
522 pcmd("}")
523 pcmd("")
524 pcmd("static const ioctl_desc *ioctl_lookup(unsigned req) {")
525 pcmd(" const ioctl_desc *desc = ioctl_table_lookup(req);")
526 pcmd(" if (desc) return desc;")
527 pcmd("")
528 pcmd(" // Try stripping access size from the request id.")
529 pcmd(" desc = ioctl_table_lookup(req & ~(IOC_SIZEMASK << IOC_SIZESHIFT));")
530 pcmd(" // Sanity check: requests that encode access size are either read or write and")
531 pcmd(" // have size of 0 in the table.")
532 pcmd(" if (desc && desc->size == 0 &&")
533 pcmd(" (desc->type == ioctl_desc::READWRITE || desc->type == ioctl_desc::WRITE ||")
534 pcmd(" desc->type == ioctl_desc::READ))")
535 pcmd(" return desc;")
536 pcmd(" return nullptr;")
537 pcmd("}")
538 pcmd("")
539 pcmd("static void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d,")
540 pcmd(" unsigned request, void *arg) {")
541 pcmd(" if (desc->type == ioctl_desc::READ || desc->type == ioctl_desc::READWRITE) {")
542 pcmd(" unsigned size = desc->size ? desc->size : IOC_SIZE(request);")
543 pcmd(" COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, size);")
544 pcmd(" }")
545 pcmd(" if (desc->type != ioctl_desc::CUSTOM)")
546 pcmd(" return;")
547 pcmd(" if (request == IOCTL_SIOCGIFCONF) {")
548 pcmd(" struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;")
549 pcmd(" COMMON_INTERCEPTOR_READ_RANGE(ctx, (char*)&ifc->ifc_len,")
550 pcmd(" sizeof(ifc->ifc_len));")
551 pcmd(" }")
552 pcmd("}")
553 pcmd("")
554 pcmd("static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d,")
555 pcmd(" unsigned request, void *arg) {")
556 pcmd(" if (desc->type == ioctl_desc::WRITE || desc->type == ioctl_desc::READWRITE) {")
557 pcmd(" // FIXME: add verbose output")
558 pcmd(" unsigned size = desc->size ? desc->size : IOC_SIZE(request);")
559 pcmd(" COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg, size);")
560 pcmd(" }")
561 pcmd(" if (desc->type != ioctl_desc::CUSTOM)")
562 pcmd(" return;")
563 pcmd(" if (request == IOCTL_SIOCGIFCONF) {")
564 pcmd(" struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;")
565 pcmd(" COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);")
566 pcmd(" }")
567 pcmd("}")
568 pcmd("")
569 pcmd("#endif // SANITIZER_NETBSD")
570
571 close(cmd)
572}
573
574function usage()
575{
576 print "Usage: " script_name
577 abnormal_exit = 1
578 exit 1
579}
580
581function pcmd(string)
582{
583 print string | cmd
584}
585
586function get_type(string)
587{
588 if (string == "int") {
589 return "sizeof(int)"
590 } else if (string == "unsigned int" || string == "u_int" || string == "uint") {
591 return "sizeof(unsigned int)"
592 } else if (string == "long") {
593 return "sizeof(long)"
594 } else if (string == "unsigned long" || string == "u_long") {
595 return "sizeof(unsigned long)"
596 } else if (string == "short") {
597 return "sizeof(short)"
598 } else if (string == "unsigned short") {
599 return "sizeof(unsigned short)"
600 } else if (string == "char") {
601 return "sizeof(char)"
602 } else if (string == "signed char") {
603 return "sizeof(signed char)"
604 } else if (string == "unsigned char") {
605 return "sizeof(unsigned char)"
606 } else if (string == "uint8_t") {
607 return "sizeof(u8)"
608 } else if (string == "uint16_t") {
609 return "sizeof(u16)"
610 } else if (string == "u_int32_t" || string == "uint32_t") {
611 return "sizeof(u32)"
612 } else if (string ~ /\*$/) {
613 return "sizeof(uptr)"
614 } else if (string == "off_t") {
615 return "sizeof(uptr)"
616 } else if (string == "pid_t" || string == "kbd_t") {
617 return "sizeof(int)"
618 } else if (string == "daddr_t" || string == "dev_t") {
619 return "sizeof(u64)"
620 } else if (substr(string, 0, 7) == "struct " ) {
621 gsub(/ /, "", string)
622 return "struct_" substr(string, 7) "_sz"
623 } else if (string == "scsireq_t") {
624 return "struct_scsireq_sz"
625 } else if (string == "tone_t") {
626 return "struct_tone_sz"
627 } else if (string == "union twe_statrequest") {
628 return "union_twe_statrequest_sz"
629 } else if (string == "usb_device_descriptor_t") {
630 return "struct_usb_device_descriptor_sz"
631 } else if (string == "v4l2_std_id") {
632 return "sizeof(u64)"
633 } else if (string == "vtmode_t") {
634 return "struct_vt_mode_sz"
635 } else if (string == "_old_mixer_info") {
636 return "struct__old_mixer_info_sz"
637 } else if (string == "agp_allocate") {
638 return "struct__agp_allocate_sz"
639 } else if (string == "agp_bind") {
640 return "struct__agp_bind_sz"
641 } else if (string == "agp_info") {
642 return "struct__agp_info_sz"
643 } else if (string == "agp_region") {
644 return "struct__agp_region_sz"
645 } else if (string == "agp_setup") {
646 return "struct__agp_setup_sz"
647 } else if (string == "agp_unbind") {
648 return "struct__agp_unbind_sz"
649 } else if (string == "atareq_t") {
650 return "struct_atareq_sz"
651 } else if (string == "cpustate_t") {
652 return "struct_cpustate_sz"
653 } else if (string == "dmx_caps_t") {
654 return "struct_dmx_caps_sz"
655 } else if (string == "dmx_source_t") {
656 return "enum_dmx_source_sz"
657 } else if (string == "dvd_authinfo") {
658 return "union_dvd_authinfo_sz"
659 } else if (string == "dvd_struct") {
660 return "union_dvd_struct_sz"
661 } else if (string == "enum v4l2_priority") {
662 return "enum_v4l2_priority_sz"
663 } else if (string == "envsys_basic_info_t") {
664 return "struct_envsys_basic_info_sz"
665 } else if (string == "envsys_tre_data_t") {
666 return "struct_envsys_tre_data_sz"
667 } else if (string == "ext_accm") {
668 return "(8 * sizeof(u32))"
669 } else if (string == "fe_sec_mini_cmd_t") {
670 return "enum_fe_sec_mini_cmd_sz"
671 } else if (string == "fe_sec_tone_mode_t") {
672 return "enum_fe_sec_tone_mode_sz"
673 } else if (string == "fe_sec_voltage_t") {
674 return "enum_fe_sec_voltage_sz"
675 } else if (string == "fe_status_t") {
676 return "enum_fe_status_sz"
677 } else if (string == "gdt_ctrt_t") {
678 return "struct_gdt_ctrt_sz"
679 } else if (string == "gdt_event_t") {
680 return "struct_gdt_event_sz"
681 } else if (string == "gdt_osv_t") {
682 return "struct_gdt_osv_sz"
683 } else if (string == "gdt_rescan_t") {
684 return "struct_gdt_rescan_sz"
685 } else if (string == "gdt_statist_t") {
686 return "struct_gdt_statist_sz"
687 } else if (string == "gdt_ucmd_t") {
688 return "struct_gdt_ucmd_sz"
689 } else if (string == "iscsi_conn_status_parameters_t") {
690 return "struct_iscsi_conn_status_parameters_sz"
691 } else if (string == "iscsi_get_version_parameters_t") {
692 return "struct_iscsi_get_version_parameters_sz"
693 } else if (string == "iscsi_iocommand_parameters_t") {
694 return "struct_iscsi_iocommand_parameters_sz"
695 } else if (string == "iscsi_login_parameters_t") {
696 return "struct_iscsi_login_parameters_sz"
697 } else if (string == "iscsi_logout_parameters_t") {
698 return "struct_iscsi_logout_parameters_sz"
699 } else if (string == "iscsi_register_event_parameters_t") {
700 return "struct_iscsi_register_event_parameters_sz"
701 } else if (string == "iscsi_remove_parameters_t") {
702 return "struct_iscsi_remove_parameters_sz"
703 } else if (string == "iscsi_send_targets_parameters_t") {
704 return "struct_iscsi_send_targets_parameters_sz"
705 } else if (string == "iscsi_set_node_name_parameters_t") {
706 return "struct_iscsi_set_node_name_parameters_sz"
707 } else if (string == "iscsi_wait_event_parameters_t") {
708 return "struct_iscsi_wait_event_parameters_sz"
709 } else if (string == "isp_stats_t") {
710 return "struct_isp_stats_sz"
711 } else if (string == "lsenable_t") {
712 return "struct_lsenable_sz"
713 } else if (string == "lsdisable_t") {
714 return "struct_lsdisable_sz"
715 } else if (string == "mixer_ctrl_t") {
716 return "struct_mixer_ctrl_sz"
717 } else if (string == "mixer_devinfo_t") {
718 return "struct_mixer_devinfo_sz"
719 } else if (string == "mpu_command_rec") {
720 return "struct_mpu_command_rec_sz"
721 } else if (string == "rndstat_t") {
722 return "struct_rndstat_sz"
723 } else if (string == "rndstat_name_t") {
724 return "struct_rndstat_name_sz"
725 } else if (string == "rndctl_t") {
726 return "struct_rndctl_sz"
727 } else if (string == "rnddata_t") {
728 return "struct_rnddata_sz"
729 } else if (string == "rndpoolstat_t") {
730 return "struct_rndpoolstat_sz"
731 } else if (string == "rndstat_est_t") {
732 return "struct_rndstat_est_sz"
733 } else if (string == "rndstat_est_name_t") {
734 return "struct_rndstat_est_name_sz"
735 } else if (string == "pps_params_t") {
736 return "struct_pps_params_sz"
737 } else if (string == "pps_info_t") {
738 return "struct_pps_info_sz"
739 } else if (string == "linedn_t") {
740 return "(32 * sizeof(char))"
741 } else if (string == "mixer_info") {
742 return "struct_mixer_info_sz"
743 } else if (string == "RF_SparetWait_t") {
744 return "struct_RF_SparetWait_sz"
745 } else if (string == "RF_ComponentLabel_t") {
746 return "struct_RF_ComponentLabel_sz"
747 } else if (string == "RF_SingleComponent_t") {
748 return "struct_RF_SingleComponent_sz"
749 } else if (string == "RF_ProgressInfo_t") {
750 return "struct_RF_ProgressInfo_sz"
751 } else {
752 print "Unrecognized entry: " string
753 print "Aborting"
754 abnormal_exit = 1
755 exit 1
756 }
757
758 return string
759}