blob: ca8f6fd74eb9c7893f3c8533591a19dc43874939 [file] [log] [blame]
Elvira Khabirova09294222015-08-04 01:47:02 +03001function compare_indices(i1, v1, i2, v2) {
2 c1 = strtonum(sprintf("%s", i1))
3 c2 = strtonum(sprintf("%s", i2))
4 if (c1 < c2)
5 return -1
6 return (c1 != c2)
7}
Dmitry V. Levin59992182015-12-15 00:26:46 +00008function array_get(array_idx, array_member, array_return)
9{
10 array_return = array[array_idx][array_member]
11 if ("" == array_return) {
12 printf("%s: index [%s] without %s\n",
13 FILENAME, array_idx, array_member) > "/dev/stderr"
14 exit 1
15 }
16 return array_return
17}
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000018function array_seq(array_idx)
19{
20 if ("seq" in array[array_idx])
21 return array[array_idx]["seq"]
22 index_seq++
23 array[array_idx]["seq"] = index_seq
24 return index_seq
25}
Dmitry V. Levin54d18a22015-12-15 03:35:26 +000026function enter(array_idx)
27{
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000028 if (array_idx in called) {
Dmitry V. Levin54d18a22015-12-15 03:35:26 +000029 printf("%s: index loop detected:", FILENAME) > "/dev/stderr"
30 for (item in called)
31 printf(" %s", item) > "/dev/stderr"
32 print "" > "/dev/stderr"
33 exit 1
34 }
35 called[array_idx] = 1
36}
37function leave(array_idx, to_return)
38{
39 delete called[array_idx]
40 return to_return
41}
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +030042function what_is(what_idx, type_idx, special, item, \
43 location, prev_location, prev_returned_size)
Elvira Khabirova09294222015-08-04 01:47:02 +030044{
Dmitry V. Levin54d18a22015-12-15 03:35:26 +000045 enter(what_idx)
Dmitry V. Levin59992182015-12-15 00:26:46 +000046 special = array_get(what_idx, "special")
Elvira Khabirova09294222015-08-04 01:47:02 +030047 switch (special) {
48 case "base_type":
Dmitry V. Levin59992182015-12-15 00:26:46 +000049 switch (array_get(what_idx, "encoding")) {
Elvira Khabirova09294222015-08-04 01:47:02 +030050 case 5: # signed
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000051 printf("int%s_t ",
52 8 * array_get(what_idx, "byte_size"))
Elvira Khabirova09294222015-08-04 01:47:02 +030053 break
54 case 7: # unsigned
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000055 printf("uint%s_t ",
56 8 * array_get(what_idx, "byte_size"))
Elvira Khabirova09294222015-08-04 01:47:02 +030057 break
58 default: # float, signed/unsigned char
Dmitry V. Levin59992182015-12-15 00:26:46 +000059 printf("%s ", array_get(what_idx, "name"))
Elvira Khabirova09294222015-08-04 01:47:02 +030060 break
61 }
Dmitry V. Levin59992182015-12-15 00:26:46 +000062 returned_size = array_get(what_idx, "byte_size")
Elvira Khabirova09294222015-08-04 01:47:02 +030063 break
64 case "enumeration_type":
Dmitry V. Levin59992182015-12-15 00:26:46 +000065 type_idx = array_get(what_idx, "type")
66 returned_size = array_get(what_idx, "byte_size")
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000067 printf("uint%s_t ", 8 * returned_size)
Elvira Khabirova09294222015-08-04 01:47:02 +030068 break
69 case "pointer_type":
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000070 printf("mpers_ptr_t ")
Dmitry V. Levin59992182015-12-15 00:26:46 +000071 returned_size = array_get(what_idx, "byte_size")
Elvira Khabirova09294222015-08-04 01:47:02 +030072 break
73 case "array_type":
Dmitry V. Levin59992182015-12-15 00:26:46 +000074 type_idx = array_get(what_idx, "type")
Elvira Khabirova09294222015-08-04 01:47:02 +030075 what_is(type_idx)
76 to_return = array[what_idx]["upper_bound"]
Dmitry V. Levin59992182015-12-15 00:26:46 +000077 if ("" == to_return)
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000078 to_return = 0
79 returned_size = to_return * returned_size
Dmitry V. Levin54d18a22015-12-15 03:35:26 +000080 return leave(what_idx, to_return)
Elvira Khabirova09294222015-08-04 01:47:02 +030081 break
82 case "structure_type":
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +030083 print "struct {"
84 prev_location = 0
85 location = 0
86 returned_size = 0
87 prev_returned_size = 0
Elvira Khabirova09294222015-08-04 01:47:02 +030088 for (item in array) {
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +030089 if ("parent" in array[item] && \
Dmitry V. Levin59992182015-12-15 00:26:46 +000090 array_get(item, "parent") == what_idx) {
91 location = array_get(item, "location")
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +030092 loc_diff = location - prev_location - \
93 prev_returned_size
94 if (loc_diff != 0) {
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +000095 printf("unsigned char mpers_%s_%s[%s];\n",
96 "filler", array_seq(item), loc_diff)
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +030097 }
98 prev_location = location
99 returned = what_is(item)
100 prev_returned_size = returned_size
101 printf("%s", array[item]["name"])
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000102 if ("" != returned) {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000103 printf("[%s]", returned)
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300104 }
105 print ";"
106 }
107 }
Dmitry V. Levin59992182015-12-15 00:26:46 +0000108 returned_size = array_get(what_idx, "byte_size")
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300109 loc_diff = returned_size - prev_location - prev_returned_size
110 if (loc_diff != 0) {
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000111 printf("unsigned char mpers_%s_%s[%s];\n",
112 "end_filler", array_seq(item), loc_diff)
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300113 }
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000114 printf("} ATTRIBUTE_PACKED ")
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300115 break
116 case "union_type":
117 print "union {"
118 for (item in array) {
119 if ("parent" in array[item] && \
Dmitry V. Levin59992182015-12-15 00:26:46 +0000120 array_get(item, "parent") == what_idx) {
Elvira Khabirova09294222015-08-04 01:47:02 +0300121 returned = what_is(item)
Dmitry V. Levin59992182015-12-15 00:26:46 +0000122 printf("%s", array_get(item, "name"))
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000123 if ("" != returned) {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000124 printf("[%s]", returned)
Elvira Khabirova09294222015-08-04 01:47:02 +0300125 }
126 print ";"
127 }
128 }
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000129 printf("} ")
Dmitry V. Levin59992182015-12-15 00:26:46 +0000130 returned_size = array_get(what_idx, "byte_size")
Elvira Khabirova09294222015-08-04 01:47:02 +0300131 break
132 case "typedef":
Dmitry V. Levin59992182015-12-15 00:26:46 +0000133 type_idx = array_get(what_idx, "type")
Dmitry V. Levin54d18a22015-12-15 03:35:26 +0000134 return leave(what_idx, what_is(type_idx))
Elvira Khabirova09294222015-08-04 01:47:02 +0300135 break
136 case "member":
Dmitry V. Levin59992182015-12-15 00:26:46 +0000137 type_idx = array_get(what_idx, "type")
Dmitry V. Levin54d18a22015-12-15 03:35:26 +0000138 return leave(what_idx, what_is(type_idx))
Elvira Khabirova09294222015-08-04 01:47:02 +0300139 break
140 default:
Dmitry V. Levin59992182015-12-15 00:26:46 +0000141 type_idx = array_get(what_idx, "type")
Elvira Khabirova09294222015-08-04 01:47:02 +0300142 what_is(type_idx)
143 break
144 }
Dmitry V. Levinc4afd6d2015-12-15 12:58:42 +0000145 return leave(what_idx, "")
Elvira Khabirova09294222015-08-04 01:47:02 +0300146}
147BEGIN {
148 print "#include <inttypes.h>"
149}
150/^<[[:xdigit:]]+>/ {
151 match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
152 level = matches[1]
153 idx = "0x" matches[2]
154 array[idx]["idx"] = idx
155 parent[level] = idx
156 if (level > 1) {
157 array[idx]["parent"] = parent[level-1]
158 }
159}
160/^DW_AT_data_member_location/ {
161 match($0, /[[:digit:]]+/, temparray)
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300162 array[idx]["location"] = temparray[0]
Elvira Khabirova09294222015-08-04 01:47:02 +0300163}
164/^DW_AT_name/ {
Elvira Khabirovaa5ffa182015-11-26 03:03:24 +0300165 match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
166 temparray)
Elvira Khabirova09294222015-08-04 01:47:02 +0300167 array[idx]["name"] = temparray[1]
168}
169/^DW_AT_byte_size/ {
170 match($0, /[[:digit:]]+/, temparray)
171 array[idx]["byte_size"] = temparray[0]
172}
173/^DW_AT_encoding/ {
174 match($0, /[[:digit:]]+/, temparray)
175 array[idx]["encoding"] = temparray[0]
176}
177/^DW_AT_type/ {
178 match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
179 array[idx]["type"] = temparray[1]
180}
181/^DW_AT_upper_bound/ {
182 match($0, /[[:digit:]]+/, temparray)
183 array[parent[level-1]]["upper_bound"] = temparray[0] + 1
184}
185/^Abbrev Number:[^(]+\(DW_TAG_/ {
186 if (match($0, /typedef|union_type|structure_type|pointer_type\
187|enumeration_type|array_type|base_type|member/, temparray)) {
188 array[idx]["special"] = temparray[0]
189 }
190}
191END {
192 PROCINFO["sorted_in"] = "compare_indices"
193 for (item in array) {
194 if (array[item]["special"] == "pointer_type") {
195 print "typedef uint" \
Dmitry V. Levin59992182015-12-15 00:26:46 +0000196 8 * array_get(item, "byte_size") "_t mpers_ptr_t;"
Elvira Khabirova09294222015-08-04 01:47:02 +0300197 break
198 }
199 }
200 for (item in array) {
201 if (array[item]["name"] == VAR_NAME) {
Dmitry V. Levin59992182015-12-15 00:26:46 +0000202 type = array_get(item, "type")
Elvira Khabirova09294222015-08-04 01:47:02 +0300203 print "typedef"
Dmitry V. Levin59992182015-12-15 00:26:46 +0000204 what_is(type)
205 name = array_get(type, "name")
206 print ARCH_FLAG "_" name ";"
Elvira Khabirova09294222015-08-04 01:47:02 +0300207 print "#define MPERS_" \
Dmitry V. Levin59992182015-12-15 00:26:46 +0000208 ARCH_FLAG "_" name " " \
209 ARCH_FLAG "_" name
Elvira Khabirova09294222015-08-04 01:47:02 +0300210 break
211 }
212 }
213}