]> granicus.if.org Git - strace/blob - maint/ioctls_sym.awk
44819daea4d997eb758e4581262fdca81beb2086
[strace] / maint / ioctls_sym.awk
1 #!/bin/gawk -f
2 #
3 # Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
4 # Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
5 # Copyright (c) 2017 Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
6 # Copyright (c) 2015-2017 The strace developers.
7 # All rights reserved.
8 #
9 # SPDX-License-Identifier: LGPL-2.1-or-later
10
11 BEGIN {
12         dirmap[2^8] = "_IOC_NONE"
13         dirmap[2^9] = "_IOC_READ"
14         dirmap[2^10] = "_IOC_WRITE"
15         dirmap[2^10 + 2^9] = "_IOC_READ|_IOC_WRITE"
16 }
17 function array_get(array_idx, array_member, \
18                    array_return)
19 {
20         array_return = array[array_idx][array_member]
21         if ("" == array_return) {
22                 printf("%s: index [%s] without %s\n",
23                        FILENAME, array_idx, array_member) > "/dev/stderr"
24                 exit 1
25         }
26         return array_return
27 }
28 function dir2str(dir, \
29                  r) {
30         r = dirmap[dir]
31         if (r == "") {
32                 printf("%s: ioctl direction %d is not known\n",
33                        FILENAME, dir) > "/dev/stderr"
34                 exit 1
35         }
36         return r
37 }
38 /^<[[:xdigit:]]+>/ {
39         match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
40         level = matches[1]
41         idx = "0x" matches[2]
42         parent[level] = idx
43 }
44 /^DW_AT_name/ {
45         match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/,
46                 temparray)
47         array[idx]["name"] = temparray[1]
48 }
49 /^DW_AT_type/ {
50         match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
51         array[idx]["type"] = temparray[1]
52 }
53 /^DW_AT_upper_bound/ {
54         match($0, /[[:digit:]]+/, temparray)
55         array[array[idx]["parent"]]["size"] = temparray[0]
56 }
57 /^DW_AT_count/ {
58         match($0, /[[:digit:]]+/, temparray)
59         array[array[idx]["parent"]]["size"] = temparray[0] - 1
60 }
61 /^Abbrev Number:[^(]+\(DW_TAG_/ {
62         if (match($0, /member|subrange_type|variable/, temparray)) {
63                 array[idx]["special"] = temparray[0]
64                 if (level > 1 && ("member" == temparray[0] ||
65                     "subrange_type" == temparray[0]))
66                         array[idx]["parent"] = parent[level-1]
67         }
68 }
69 END {
70         for (i in array) {
71                 if (array[i]["special"] == "variable" &&
72                     index(array_get(i, "name"), "ioc_") == 1) {
73                         ioc_name = substr(array_get(i, "name"),
74                                           length("ioc_") + 1)
75                         type = array_get(i, "type")
76                         delete sizemap
77                         for (j in array) {
78                                 if ("parent" in array[j] &&
79                                     type == array_get(j, "parent")) {
80                                         t = array_get(j, "type")
81
82                                         field_name = array_get(j, "name")
83                                         sizemap[field_name] = \
84                                                 array_get(t, "size")
85                                 }
86                         }
87                         if (sizemap["d"] == "" ||
88                             sizemap["n"] == "" ||
89                             sizemap["s"] == "") {
90                                 printf("%s: failed to parse %s ioctl info\n",
91                                        FILENAME, ioc_name) > "/dev/stderr"
92                                 exit 1
93                         }
94                         printf("{ \"%s\", \"%s\", %s, 0x%04x, 0x%02x },\n",
95                                   HEADER_NAME, ioc_name, dir2str(sizemap["d"]),
96                                   sizemap["n"], sizemap["s"])
97                 }
98         }
99 }