blob: 1374ee4899f510b39c57c65a5b90c715b1ed0f37 [file] [log] [blame]
Dmitry V. Levin38a34c92015-12-17 17:56:48 +00001#!/bin/gawk
2#
3# Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
Dmitry V. Levincc902e32016-01-13 02:31:12 +00004# Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
Elliott Hughesb7556142018-02-20 17:03:16 -08005# Copyright (c) 2015-2018 The strace developers.
Dmitry V. Levin38a34c92015-12-17 17:56:48 +00006# All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11# 1. Redistributions of source code must retain the above copyright
12# notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright
14# notice, this list of conditions and the following disclaimer in the
15# documentation and/or other materials provided with the distribution.
16# 3. The name of the author may not be used to endorse or promote products
17# derived from this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
Elliott Hughes77c3ff82017-09-08 17:11:00 -070030function array_get(array_idx, array_member, \
31 array_return)
Dmitry V. Levin59992182015-12-15 00:26:46 +000032{
Elliott Hughesb7556142018-02-20 17:03:16 -080033 array_return = array[array_idx, array_member]
Dmitry V. Levin59992182015-12-15 00:26:46 +000034 if ("" == array_return) {
35 printf("%s: index [%s] without %s\n",
36 FILENAME, array_idx, array_member) > "/dev/stderr"
37 exit 1
38 }
39 return array_return
40}
Elliott Hughesb7556142018-02-20 17:03:16 -080041function norm_idx(idx)
42{
43 return sprintf("%016s", idx)
44}
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000045function array_seq(array_idx)
46{
Elliott Hughesb7556142018-02-20 17:03:16 -080047 if ((array_idx, "seq") in array)
48 return array[array_idx, "seq"]
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000049 index_seq++
Elliott Hughesb7556142018-02-20 17:03:16 -080050 array[array_idx, "seq"] = index_seq
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000051 return index_seq
52}
Elliott Hughes77c3ff82017-09-08 17:11:00 -070053function enter(array_idx,
54 item)
Dmitry V. Levin54d18a22015-12-15 03:35:26 +000055{
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000056 if (array_idx in called) {
Dmitry V. Levin54d18a22015-12-15 03:35:26 +000057 printf("%s: index loop detected:", FILENAME) > "/dev/stderr"
58 for (item in called)
59 printf(" %s", item) > "/dev/stderr"
60 print "" > "/dev/stderr"
61 exit 1
62 }
63 called[array_idx] = 1
64}
65function leave(array_idx, to_return)
66{
67 delete called[array_idx]
68 return to_return
69}
Elliott Hughes77c3ff82017-09-08 17:11:00 -070070function update_upper_bound(idx, val, \
71 count)
Elliott Hughes39bac052017-05-25 16:56:11 -070072{
Elliott Hughesb7556142018-02-20 17:03:16 -080073 count = array[idx, "count"]
Elliott Hughes39bac052017-05-25 16:56:11 -070074 if (count == "")
75 count = 1
Elliott Hughesb7556142018-02-20 17:03:16 -080076 array[idx, "count"] = count * val
77 array[idx, "upper_bound"] = array[idx, "upper_bound"] "[" val "]"
Elliott Hughes39bac052017-05-25 16:56:11 -070078}
Elliott Hughes77c3ff82017-09-08 17:11:00 -070079function what_is(what_idx, \
80 item, loc_diff, location, prev_location, prev_returned_size, \
Elliott Hughesb7556142018-02-20 17:03:16 -080081 special, to_return, type_idx, enc, i)
Elvira Khabirova09294222015-08-04 01:47:02 +030082{
Dmitry V. Levin54d18a22015-12-15 03:35:26 +000083 enter(what_idx)
Dmitry V. Levin59992182015-12-15 00:26:46 +000084 special = array_get(what_idx, "special")
Elliott Hughesb7556142018-02-20 17:03:16 -080085 if (special == "base_type") {
86 enc = array_get(what_idx, "encoding")
87 if (enc == 5) { # signed
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000088 printf("int%s_t ",
89 8 * array_get(what_idx, "byte_size"))
Elliott Hughesb7556142018-02-20 17:03:16 -080090 } else if (enc == 7) { # unsigned
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000091 printf("uint%s_t ",
92 8 * array_get(what_idx, "byte_size"))
Elliott Hughesb7556142018-02-20 17:03:16 -080093 } else { # float, signed/unsigned char
Dmitry V. Levin59992182015-12-15 00:26:46 +000094 printf("%s ", array_get(what_idx, "name"))
Elvira Khabirova09294222015-08-04 01:47:02 +030095 }
Dmitry V. Levin59992182015-12-15 00:26:46 +000096 returned_size = array_get(what_idx, "byte_size")
Elliott Hughesb7556142018-02-20 17:03:16 -080097 } else if (special == "enumeration_type") {
Dmitry V. Levin59992182015-12-15 00:26:46 +000098 returned_size = array_get(what_idx, "byte_size")
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000099 printf("uint%s_t ", 8 * returned_size)
Elliott Hughesb7556142018-02-20 17:03:16 -0800100 } else if (special == "pointer_type") {
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000101 printf("mpers_ptr_t ")
Dmitry V. Levin59992182015-12-15 00:26:46 +0000102 returned_size = array_get(what_idx, "byte_size")
Elliott Hughesb7556142018-02-20 17:03:16 -0800103 } else if (special == "array_type") {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000104 type_idx = array_get(what_idx, "type")
Elvira Khabirova09294222015-08-04 01:47:02 +0300105 what_is(type_idx)
Elliott Hughesb7556142018-02-20 17:03:16 -0800106 to_return = array[what_idx, "upper_bound"]
Dmitry V. Levin59992182015-12-15 00:26:46 +0000107 if ("" == to_return)
Elliott Hughes39bac052017-05-25 16:56:11 -0700108 to_return = "[0]"
Elliott Hughesb7556142018-02-20 17:03:16 -0800109 returned_size = array[what_idx, "count"] * returned_size
Dmitry V. Levin54d18a22015-12-15 03:35:26 +0000110 return leave(what_idx, to_return)
Elliott Hughesb7556142018-02-20 17:03:16 -0800111 } else if (special == "structure_type") {
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300112 print "struct {"
113 prev_location = 0
114 location = 0
115 returned_size = 0
116 prev_returned_size = 0
Elliott Hughesb7556142018-02-20 17:03:16 -0800117 for (i = 1; i <= parents_cnt; i += 1) {
118 if (array_parents[aparents_keys[i]] == what_idx) {
119 location = array_get(aparents_keys[i], "location")
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300120 loc_diff = location - prev_location - \
121 prev_returned_size
122 if (loc_diff != 0) {
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000123 printf("unsigned char mpers_%s_%s[%s];\n",
Elliott Hughesb7556142018-02-20 17:03:16 -0800124 "filler", array_seq(aparents_keys[i]), loc_diff)
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300125 }
126 prev_location = location
Elliott Hughesb7556142018-02-20 17:03:16 -0800127 returned = what_is(aparents_keys[i])
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300128 prev_returned_size = returned_size
Elliott Hughesb7556142018-02-20 17:03:16 -0800129 printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300130 }
131 }
Dmitry V. Levin59992182015-12-15 00:26:46 +0000132 returned_size = array_get(what_idx, "byte_size")
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300133 loc_diff = returned_size - prev_location - prev_returned_size
134 if (loc_diff != 0) {
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000135 printf("unsigned char mpers_%s_%s[%s];\n",
136 "end_filler", array_seq(item), loc_diff)
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300137 }
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000138 printf("} ATTRIBUTE_PACKED ")
Elliott Hughesb7556142018-02-20 17:03:16 -0800139 } else if (special == "union_type") {
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300140 print "union {"
Elliott Hughesb7556142018-02-20 17:03:16 -0800141 for (i = 1; i <= parents_cnt; i += 1) {
142 if (array_parents[aparents_keys[i]] == what_idx) {
143 returned = what_is(aparents_keys[i])
144 printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
Elvira Khabirova09294222015-08-04 01:47:02 +0300145 }
146 }
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000147 printf("} ")
Dmitry V. Levin59992182015-12-15 00:26:46 +0000148 returned_size = array_get(what_idx, "byte_size")
Elliott Hughesb7556142018-02-20 17:03:16 -0800149 } else if (special == "typedef") {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000150 type_idx = array_get(what_idx, "type")
Dmitry V. Levin54d18a22015-12-15 03:35:26 +0000151 return leave(what_idx, what_is(type_idx))
Elliott Hughesb7556142018-02-20 17:03:16 -0800152 } else if (special == "member") {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000153 type_idx = array_get(what_idx, "type")
Dmitry V. Levin54d18a22015-12-15 03:35:26 +0000154 return leave(what_idx, what_is(type_idx))
Elliott Hughesb7556142018-02-20 17:03:16 -0800155 } else {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000156 type_idx = array_get(what_idx, "type")
Elvira Khabirova09294222015-08-04 01:47:02 +0300157 what_is(type_idx)
Elvira Khabirova09294222015-08-04 01:47:02 +0300158 }
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000159 return leave(what_idx, "")
Elvira Khabirova09294222015-08-04 01:47:02 +0300160}
161BEGIN {
Dmitry V. Levincc902e32016-01-13 02:31:12 +0000162 match(ARCH_FLAG, /[[:digit:]]+/, temparray)
163 default_pointer_size = temparray[0] / 8
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700164 print "#include <stdint.h>"
Elvira Khabirova09294222015-08-04 01:47:02 +0300165}
166/^<[[:xdigit:]]+>/ {
167 match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
168 level = matches[1]
Elliott Hughesb7556142018-02-20 17:03:16 -0800169 idx = norm_idx(matches[2])
170 array[idx, "idx"] = idx
Elvira Khabirova09294222015-08-04 01:47:02 +0300171 parent[level] = idx
Elvira Khabirova09294222015-08-04 01:47:02 +0300172}
173/^DW_AT_data_member_location/ {
Dmitry V. Levind2bcb162015-12-16 01:25:10 +0000174 if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
175 match($0, /([[:digit:]]+)/, temparray)
Elliott Hughesb7556142018-02-20 17:03:16 -0800176 array[idx, "location"] = temparray[1]
Elvira Khabirova09294222015-08-04 01:47:02 +0300177}
178/^DW_AT_name/ {
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300179 match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
180 temparray)
Elliott Hughesb7556142018-02-20 17:03:16 -0800181 array_names[idx] = 1
182 array[idx, "name"] = temparray[1]
Elvira Khabirova09294222015-08-04 01:47:02 +0300183}
184/^DW_AT_byte_size/ {
185 match($0, /[[:digit:]]+/, temparray)
Elliott Hughesb7556142018-02-20 17:03:16 -0800186 array[idx, "byte_size"] = temparray[0]
Elvira Khabirova09294222015-08-04 01:47:02 +0300187}
188/^DW_AT_encoding/ {
189 match($0, /[[:digit:]]+/, temparray)
Elliott Hughesb7556142018-02-20 17:03:16 -0800190 array[idx, "encoding"] = temparray[0]
Elvira Khabirova09294222015-08-04 01:47:02 +0300191}
192/^DW_AT_type/ {
Elliott Hughesb7556142018-02-20 17:03:16 -0800193 match($0, /:[[:space:]]+<0x([[:xdigit:]]*)>$/, temparray)
194 array[idx, "type"] = norm_idx(temparray[1])
Elvira Khabirova09294222015-08-04 01:47:02 +0300195}
196/^DW_AT_upper_bound/ {
197 match($0, /[[:digit:]]+/, temparray)
Elliott Hughes39bac052017-05-25 16:56:11 -0700198 update_upper_bound(parent[level - 1], temparray[0] + 1)
Elvira Khabirova09294222015-08-04 01:47:02 +0300199}
Dmitry V. Levincc902e32016-01-13 02:31:12 +0000200/^DW_AT_count/ {
201 match($0, /[[:digit:]]+/, temparray)
Elliott Hughes39bac052017-05-25 16:56:11 -0700202 update_upper_bound(parent[level - 1], temparray[0])
Dmitry V. Levincc902e32016-01-13 02:31:12 +0000203}
Elvira Khabirova09294222015-08-04 01:47:02 +0300204/^Abbrev Number:[^(]+\(DW_TAG_/ {
205 if (match($0, /typedef|union_type|structure_type|pointer_type\
206|enumeration_type|array_type|base_type|member/, temparray)) {
Elliott Hughesb7556142018-02-20 17:03:16 -0800207 array_special[idx] = temparray[0]
208 array[idx, "special"] = temparray[0]
Dmitry V. Levincc902e32016-01-13 02:31:12 +0000209 if ("pointer_type" == temparray[0])
Elliott Hughesb7556142018-02-20 17:03:16 -0800210 array[idx, "byte_size"] = default_pointer_size
Dmitry V. Levincc902e32016-01-13 02:31:12 +0000211 if (level > 1 && "member" == temparray[0])
Elliott Hughesb7556142018-02-20 17:03:16 -0800212 array_parents[idx] = parent[level-1]
Elvira Khabirova09294222015-08-04 01:47:02 +0300213 }
214}
215END {
Elliott Hughesb7556142018-02-20 17:03:16 -0800216 parents_cnt = asorti(array_parents, aparents_keys)
217
218 for (item in array_special) {
219 if (array[item, "special"] == "pointer_type") {
220 mpers_ptr_t = \
221 "uint" 8 * array_get(item, "byte_size") "_t"
222 print "#ifndef mpers_ptr_t_is_" mpers_ptr_t
223 print "typedef " mpers_ptr_t " mpers_ptr_t;"
224 print "#define mpers_ptr_t_is_" mpers_ptr_t
225 print "#endif"
Elvira Khabirova09294222015-08-04 01:47:02 +0300226 break
227 }
228 }
Elliott Hughesb7556142018-02-20 17:03:16 -0800229 for (item in array_names) {
230 if (array[item, "name"] == VAR_NAME) {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000231 type = array_get(item, "type")
Elvira Khabirova09294222015-08-04 01:47:02 +0300232 print "typedef"
Dmitry V. Levin59992182015-12-15 00:26:46 +0000233 what_is(type)
234 name = array_get(type, "name")
235 print ARCH_FLAG "_" name ";"
Elvira Khabirova09294222015-08-04 01:47:02 +0300236 print "#define MPERS_" \
Dmitry V. Levin59992182015-12-15 00:26:46 +0000237 ARCH_FLAG "_" name " " \
238 ARCH_FLAG "_" name
Elvira Khabirova09294222015-08-04 01:47:02 +0300239 break
240 }
241 }
242}