]> granicus.if.org Git - strace/blob - maint/ioctls_sym.awk
print_array: enhance printing of unfetchable object addresses
[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 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions
11 # are met:
12 # 1. Redistributions of source code must retain the above copyright
13 #    notice, this list of conditions and the following disclaimer.
14 # 2. Redistributions in binary form must reproduce the above copyright
15 #    notice, this list of conditions and the following disclaimer in the
16 #    documentation and/or other materials provided with the distribution.
17 # 3. The name of the author may not be used to endorse or promote products
18 #    derived from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 BEGIN {
32         dirmap[2^8] = "_IOC_NONE"
33         dirmap[2^9] = "_IOC_READ"
34         dirmap[2^10] = "_IOC_WRITE"
35         dirmap[2^10 + 2^9] = "_IOC_READ|_IOC_WRITE"
36 }
37 function array_get(array_idx, array_member, \
38                    array_return)
39 {
40         array_return = array[array_idx][array_member]
41         if ("" == array_return) {
42                 printf("%s: index [%s] without %s\n",
43                        FILENAME, array_idx, array_member) > "/dev/stderr"
44                 exit 1
45         }
46         return array_return
47 }
48 function dir2str(dir, \
49                  r) {
50         r = dirmap[dir]
51         if (r == "") {
52                 printf("%s: ioctl direction %d is not known\n",
53                        FILENAME, dir) > "/dev/stderr"
54                 exit 1
55         }
56         return r
57 }
58 /^<[[:xdigit:]]+>/ {
59         match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
60         level = matches[1]
61         idx = "0x" matches[2]
62         parent[level] = idx
63 }
64 /^DW_AT_name/ {
65         match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/,
66                 temparray)
67         array[idx]["name"] = temparray[1]
68 }
69 /^DW_AT_type/ {
70         match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
71         array[idx]["type"] = temparray[1]
72 }
73 /^DW_AT_upper_bound/ {
74         match($0, /[[:digit:]]+/, temparray)
75         array[array[idx]["parent"]]["size"] = temparray[0]
76 }
77 /^DW_AT_count/ {
78         match($0, /[[:digit:]]+/, temparray)
79         array[array[idx]["parent"]]["size"] = temparray[0] - 1
80 }
81 /^Abbrev Number:[^(]+\(DW_TAG_/ {
82         if (match($0, /member|subrange_type|variable/, temparray)) {
83                 array[idx]["special"] = temparray[0]
84                 if (level > 1 && ("member" == temparray[0] ||
85                     "subrange_type" == temparray[0]))
86                         array[idx]["parent"] = parent[level-1]
87         }
88 }
89 END {
90         for (i in array) {
91                 if (array[i]["special"] == "variable" &&
92                     index(array_get(i, "name"), "ioc_") == 1) {
93                         ioc_name = substr(array_get(i, "name"),
94                                           length("ioc_") + 1)
95                         type = array_get(i, "type")
96                         delete sizemap
97                         for (j in array) {
98                                 if ("parent" in array[j] &&
99                                     type == array_get(j, "parent")) {
100                                         t = array_get(j, "type")
101
102                                         field_name = array_get(j, "name")
103                                         sizemap[field_name] = \
104                                                 array_get(t, "size")
105                                 }
106                         }
107                         if (sizemap["d"] == "" ||
108                             sizemap["n"] == "" ||
109                             sizemap["s"] == "") {
110                                 printf("%s: failed to parse %s ioctl info\n",
111                                        FILENAME, ioc_name) > "/dev/stderr"
112                                 exit 1
113                         }
114                         printf("{ \"%s\", \"%s\", %s, 0x%04x, 0x%02x },\n",
115                                   HEADER_NAME, ioc_name, dir2str(sizemap["d"]),
116                                   sizemap["n"], sizemap["s"])
117                 }
118         }
119 }