xref: /aosp_15_r20/external/strace/mpers.awk (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker#!/bin/gawk
2*cf84ac9aSAndroid Build Coastguard Worker#
3*cf84ac9aSAndroid Build Coastguard Worker# Copyright (c) 2015 Elvira Khabirova <[email protected]>
4*cf84ac9aSAndroid Build Coastguard Worker# Copyright (c) 2015-2016 Dmitry V. Levin <[email protected]>
5*cf84ac9aSAndroid Build Coastguard Worker# Copyright (c) 2015-2018 The strace developers.
6*cf84ac9aSAndroid Build Coastguard Worker# All rights reserved.
7*cf84ac9aSAndroid Build Coastguard Worker#
8*cf84ac9aSAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without
9*cf84ac9aSAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions
10*cf84ac9aSAndroid Build Coastguard Worker# are met:
11*cf84ac9aSAndroid Build Coastguard Worker# 1. Redistributions of source code must retain the above copyright
12*cf84ac9aSAndroid Build Coastguard Worker#    notice, this list of conditions and the following disclaimer.
13*cf84ac9aSAndroid Build Coastguard Worker# 2. Redistributions in binary form must reproduce the above copyright
14*cf84ac9aSAndroid Build Coastguard Worker#    notice, this list of conditions and the following disclaimer in the
15*cf84ac9aSAndroid Build Coastguard Worker#    documentation and/or other materials provided with the distribution.
16*cf84ac9aSAndroid Build Coastguard Worker# 3. The name of the author may not be used to endorse or promote products
17*cf84ac9aSAndroid Build Coastguard Worker#    derived from this software without specific prior written permission.
18*cf84ac9aSAndroid Build Coastguard Worker#
19*cf84ac9aSAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20*cf84ac9aSAndroid Build Coastguard Worker# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*cf84ac9aSAndroid Build Coastguard Worker# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*cf84ac9aSAndroid Build Coastguard Worker# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23*cf84ac9aSAndroid Build Coastguard Worker# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24*cf84ac9aSAndroid Build Coastguard Worker# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25*cf84ac9aSAndroid Build Coastguard Worker# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26*cf84ac9aSAndroid Build Coastguard Worker# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*cf84ac9aSAndroid Build Coastguard Worker# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28*cf84ac9aSAndroid Build Coastguard Worker# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*cf84ac9aSAndroid Build Coastguard Worker
30*cf84ac9aSAndroid Build Coastguard Workerfunction array_get(array_idx, array_member, \
31*cf84ac9aSAndroid Build Coastguard Worker		   array_return)
32*cf84ac9aSAndroid Build Coastguard Worker{
33*cf84ac9aSAndroid Build Coastguard Worker	array_return = array[array_idx, array_member]
34*cf84ac9aSAndroid Build Coastguard Worker	if ("" == array_return) {
35*cf84ac9aSAndroid Build Coastguard Worker		printf("%s: index [%s] without %s\n",
36*cf84ac9aSAndroid Build Coastguard Worker		       FILENAME, array_idx, array_member) > "/dev/stderr"
37*cf84ac9aSAndroid Build Coastguard Worker		exit 1
38*cf84ac9aSAndroid Build Coastguard Worker	}
39*cf84ac9aSAndroid Build Coastguard Worker	return array_return
40*cf84ac9aSAndroid Build Coastguard Worker}
41*cf84ac9aSAndroid Build Coastguard Workerfunction norm_idx(idx)
42*cf84ac9aSAndroid Build Coastguard Worker{
43*cf84ac9aSAndroid Build Coastguard Worker	return sprintf("%016s", idx)
44*cf84ac9aSAndroid Build Coastguard Worker}
45*cf84ac9aSAndroid Build Coastguard Workerfunction array_seq(array_idx)
46*cf84ac9aSAndroid Build Coastguard Worker{
47*cf84ac9aSAndroid Build Coastguard Worker	if ((array_idx, "seq") in array)
48*cf84ac9aSAndroid Build Coastguard Worker		return array[array_idx, "seq"]
49*cf84ac9aSAndroid Build Coastguard Worker	index_seq++
50*cf84ac9aSAndroid Build Coastguard Worker	array[array_idx, "seq"] = index_seq
51*cf84ac9aSAndroid Build Coastguard Worker	return index_seq
52*cf84ac9aSAndroid Build Coastguard Worker}
53*cf84ac9aSAndroid Build Coastguard Workerfunction enter(array_idx,
54*cf84ac9aSAndroid Build Coastguard Worker	       item)
55*cf84ac9aSAndroid Build Coastguard Worker{
56*cf84ac9aSAndroid Build Coastguard Worker	if (array_idx in called) {
57*cf84ac9aSAndroid Build Coastguard Worker		printf("%s: index loop detected:", FILENAME) > "/dev/stderr"
58*cf84ac9aSAndroid Build Coastguard Worker		for (item in called)
59*cf84ac9aSAndroid Build Coastguard Worker			printf(" %s", item) > "/dev/stderr"
60*cf84ac9aSAndroid Build Coastguard Worker		print "" > "/dev/stderr"
61*cf84ac9aSAndroid Build Coastguard Worker		exit 1
62*cf84ac9aSAndroid Build Coastguard Worker	}
63*cf84ac9aSAndroid Build Coastguard Worker	called[array_idx] = 1
64*cf84ac9aSAndroid Build Coastguard Worker}
65*cf84ac9aSAndroid Build Coastguard Workerfunction leave(array_idx, to_return)
66*cf84ac9aSAndroid Build Coastguard Worker{
67*cf84ac9aSAndroid Build Coastguard Worker	delete called[array_idx]
68*cf84ac9aSAndroid Build Coastguard Worker	return to_return
69*cf84ac9aSAndroid Build Coastguard Worker}
70*cf84ac9aSAndroid Build Coastguard Workerfunction update_upper_bound(idx, val, \
71*cf84ac9aSAndroid Build Coastguard Worker			    count)
72*cf84ac9aSAndroid Build Coastguard Worker{
73*cf84ac9aSAndroid Build Coastguard Worker	count = array[idx, "count"]
74*cf84ac9aSAndroid Build Coastguard Worker	if (count == "")
75*cf84ac9aSAndroid Build Coastguard Worker		count = 1
76*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "count"] = count * val
77*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "upper_bound"] = array[idx, "upper_bound"] "[" val "]"
78*cf84ac9aSAndroid Build Coastguard Worker}
79*cf84ac9aSAndroid Build Coastguard Workerfunction what_is(what_idx, \
80*cf84ac9aSAndroid Build Coastguard Worker		 item, loc_diff, location, prev_location, prev_returned_size, \
81*cf84ac9aSAndroid Build Coastguard Worker		 special, to_return, type_idx, enc, i)
82*cf84ac9aSAndroid Build Coastguard Worker{
83*cf84ac9aSAndroid Build Coastguard Worker	enter(what_idx)
84*cf84ac9aSAndroid Build Coastguard Worker	special = array_get(what_idx, "special")
85*cf84ac9aSAndroid Build Coastguard Worker	if (special == "base_type") {
86*cf84ac9aSAndroid Build Coastguard Worker		enc = array_get(what_idx, "encoding")
87*cf84ac9aSAndroid Build Coastguard Worker		if (enc == 5) { # signed
88*cf84ac9aSAndroid Build Coastguard Worker			printf("int%s_t ",
89*cf84ac9aSAndroid Build Coastguard Worker			       8 * array_get(what_idx, "byte_size"))
90*cf84ac9aSAndroid Build Coastguard Worker		} else if (enc == 7) { # unsigned
91*cf84ac9aSAndroid Build Coastguard Worker			printf("uint%s_t ",
92*cf84ac9aSAndroid Build Coastguard Worker			       8 * array_get(what_idx, "byte_size"))
93*cf84ac9aSAndroid Build Coastguard Worker		} else { # float, signed/unsigned char
94*cf84ac9aSAndroid Build Coastguard Worker			printf("%s ", array_get(what_idx, "name"))
95*cf84ac9aSAndroid Build Coastguard Worker		}
96*cf84ac9aSAndroid Build Coastguard Worker		returned_size = array_get(what_idx, "byte_size")
97*cf84ac9aSAndroid Build Coastguard Worker	} else if (special == "enumeration_type") {
98*cf84ac9aSAndroid Build Coastguard Worker		returned_size = array_get(what_idx, "byte_size")
99*cf84ac9aSAndroid Build Coastguard Worker		printf("uint%s_t ", 8 * returned_size)
100*cf84ac9aSAndroid Build Coastguard Worker	} else if (special == "pointer_type") {
101*cf84ac9aSAndroid Build Coastguard Worker		printf("mpers_ptr_t ")
102*cf84ac9aSAndroid Build Coastguard Worker		returned_size = array_get(what_idx, "byte_size")
103*cf84ac9aSAndroid Build Coastguard Worker	} else if (special == "array_type") {
104*cf84ac9aSAndroid Build Coastguard Worker		type_idx = array_get(what_idx, "type")
105*cf84ac9aSAndroid Build Coastguard Worker		what_is(type_idx)
106*cf84ac9aSAndroid Build Coastguard Worker		to_return = array[what_idx, "upper_bound"]
107*cf84ac9aSAndroid Build Coastguard Worker		if ("" == to_return)
108*cf84ac9aSAndroid Build Coastguard Worker			to_return = "[0]"
109*cf84ac9aSAndroid Build Coastguard Worker		returned_size = array[what_idx, "count"] * returned_size
110*cf84ac9aSAndroid Build Coastguard Worker		return leave(what_idx, to_return)
111*cf84ac9aSAndroid Build Coastguard Worker	} else if (special == "structure_type") {
112*cf84ac9aSAndroid Build Coastguard Worker		print "struct {"
113*cf84ac9aSAndroid Build Coastguard Worker		prev_location = 0
114*cf84ac9aSAndroid Build Coastguard Worker		location = 0
115*cf84ac9aSAndroid Build Coastguard Worker		returned_size = 0
116*cf84ac9aSAndroid Build Coastguard Worker		prev_returned_size = 0
117*cf84ac9aSAndroid Build Coastguard Worker		for (i = 1; i <= parents_cnt; i += 1) {
118*cf84ac9aSAndroid Build Coastguard Worker			if (array_parents[aparents_keys[i]] == what_idx) {
119*cf84ac9aSAndroid Build Coastguard Worker				location = array_get(aparents_keys[i], "location")
120*cf84ac9aSAndroid Build Coastguard Worker				loc_diff = location - prev_location - \
121*cf84ac9aSAndroid Build Coastguard Worker					prev_returned_size
122*cf84ac9aSAndroid Build Coastguard Worker				if (loc_diff != 0) {
123*cf84ac9aSAndroid Build Coastguard Worker					printf("unsigned char mpers_%s_%s[%s];\n",
124*cf84ac9aSAndroid Build Coastguard Worker					       "filler", array_seq(aparents_keys[i]), loc_diff)
125*cf84ac9aSAndroid Build Coastguard Worker				}
126*cf84ac9aSAndroid Build Coastguard Worker				prev_location = location
127*cf84ac9aSAndroid Build Coastguard Worker				returned = what_is(aparents_keys[i])
128*cf84ac9aSAndroid Build Coastguard Worker				prev_returned_size = returned_size
129*cf84ac9aSAndroid Build Coastguard Worker				printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
130*cf84ac9aSAndroid Build Coastguard Worker			}
131*cf84ac9aSAndroid Build Coastguard Worker		}
132*cf84ac9aSAndroid Build Coastguard Worker		returned_size = array_get(what_idx, "byte_size")
133*cf84ac9aSAndroid Build Coastguard Worker		loc_diff = returned_size - prev_location - prev_returned_size
134*cf84ac9aSAndroid Build Coastguard Worker		if (loc_diff != 0) {
135*cf84ac9aSAndroid Build Coastguard Worker			printf("unsigned char mpers_%s_%s[%s];\n",
136*cf84ac9aSAndroid Build Coastguard Worker			       "end_filler", array_seq(item), loc_diff)
137*cf84ac9aSAndroid Build Coastguard Worker		}
138*cf84ac9aSAndroid Build Coastguard Worker		printf("} ATTRIBUTE_PACKED ")
139*cf84ac9aSAndroid Build Coastguard Worker	} else if (special == "union_type") {
140*cf84ac9aSAndroid Build Coastguard Worker		print "union {"
141*cf84ac9aSAndroid Build Coastguard Worker		for (i = 1; i <= parents_cnt; i += 1) {
142*cf84ac9aSAndroid Build Coastguard Worker			if (array_parents[aparents_keys[i]] == what_idx) {
143*cf84ac9aSAndroid Build Coastguard Worker				returned = what_is(aparents_keys[i])
144*cf84ac9aSAndroid Build Coastguard Worker				printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
145*cf84ac9aSAndroid Build Coastguard Worker			}
146*cf84ac9aSAndroid Build Coastguard Worker		}
147*cf84ac9aSAndroid Build Coastguard Worker		printf("} ")
148*cf84ac9aSAndroid Build Coastguard Worker		returned_size = array_get(what_idx, "byte_size")
149*cf84ac9aSAndroid Build Coastguard Worker	} else if (special == "typedef") {
150*cf84ac9aSAndroid Build Coastguard Worker		type_idx = array_get(what_idx, "type")
151*cf84ac9aSAndroid Build Coastguard Worker		return leave(what_idx, what_is(type_idx))
152*cf84ac9aSAndroid Build Coastguard Worker	} else if (special == "member") {
153*cf84ac9aSAndroid Build Coastguard Worker		type_idx = array_get(what_idx, "type")
154*cf84ac9aSAndroid Build Coastguard Worker		return leave(what_idx, what_is(type_idx))
155*cf84ac9aSAndroid Build Coastguard Worker	} else {
156*cf84ac9aSAndroid Build Coastguard Worker		type_idx = array_get(what_idx, "type")
157*cf84ac9aSAndroid Build Coastguard Worker		what_is(type_idx)
158*cf84ac9aSAndroid Build Coastguard Worker	}
159*cf84ac9aSAndroid Build Coastguard Worker	return leave(what_idx, "")
160*cf84ac9aSAndroid Build Coastguard Worker}
161*cf84ac9aSAndroid Build Coastguard WorkerBEGIN {
162*cf84ac9aSAndroid Build Coastguard Worker	match(ARCH_FLAG, /[[:digit:]]+/, temparray)
163*cf84ac9aSAndroid Build Coastguard Worker	default_pointer_size = temparray[0] / 8
164*cf84ac9aSAndroid Build Coastguard Worker	print "#include <stdint.h>"
165*cf84ac9aSAndroid Build Coastguard Worker}
166*cf84ac9aSAndroid Build Coastguard Worker/^<[[:xdigit:]]+>/ {
167*cf84ac9aSAndroid Build Coastguard Worker	match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
168*cf84ac9aSAndroid Build Coastguard Worker	level = matches[1]
169*cf84ac9aSAndroid Build Coastguard Worker	idx = norm_idx(matches[2])
170*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "idx"] = idx
171*cf84ac9aSAndroid Build Coastguard Worker	parent[level] = idx
172*cf84ac9aSAndroid Build Coastguard Worker}
173*cf84ac9aSAndroid Build Coastguard Worker/^DW_AT_data_member_location/ {
174*cf84ac9aSAndroid Build Coastguard Worker	if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
175*cf84ac9aSAndroid Build Coastguard Worker		match($0, /([[:digit:]]+)/, temparray)
176*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "location"] = temparray[1]
177*cf84ac9aSAndroid Build Coastguard Worker}
178*cf84ac9aSAndroid Build Coastguard Worker/^DW_AT_name/ {
179*cf84ac9aSAndroid Build Coastguard Worker	match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
180*cf84ac9aSAndroid Build Coastguard Worker		temparray)
181*cf84ac9aSAndroid Build Coastguard Worker	array_names[idx] = 1
182*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "name"] = temparray[1]
183*cf84ac9aSAndroid Build Coastguard Worker}
184*cf84ac9aSAndroid Build Coastguard Worker/^DW_AT_byte_size/ {
185*cf84ac9aSAndroid Build Coastguard Worker	match($0, /[[:digit:]]+/, temparray)
186*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "byte_size"] = temparray[0]
187*cf84ac9aSAndroid Build Coastguard Worker}
188*cf84ac9aSAndroid Build Coastguard Worker/^DW_AT_encoding/ {
189*cf84ac9aSAndroid Build Coastguard Worker	match($0, /[[:digit:]]+/, temparray)
190*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "encoding"] = temparray[0]
191*cf84ac9aSAndroid Build Coastguard Worker}
192*cf84ac9aSAndroid Build Coastguard Worker/^DW_AT_type/ {
193*cf84ac9aSAndroid Build Coastguard Worker	match($0, /:[[:space:]]+<0x([[:xdigit:]]*)>$/, temparray)
194*cf84ac9aSAndroid Build Coastguard Worker	array[idx, "type"] = norm_idx(temparray[1])
195*cf84ac9aSAndroid Build Coastguard Worker}
196*cf84ac9aSAndroid Build Coastguard Worker/^DW_AT_upper_bound/ {
197*cf84ac9aSAndroid Build Coastguard Worker	match($0, /[[:digit:]]+/, temparray)
198*cf84ac9aSAndroid Build Coastguard Worker	update_upper_bound(parent[level - 1], temparray[0] + 1)
199*cf84ac9aSAndroid Build Coastguard Worker}
200*cf84ac9aSAndroid Build Coastguard Worker/^DW_AT_count/ {
201*cf84ac9aSAndroid Build Coastguard Worker	match($0, /[[:digit:]]+/, temparray)
202*cf84ac9aSAndroid Build Coastguard Worker	update_upper_bound(parent[level - 1], temparray[0])
203*cf84ac9aSAndroid Build Coastguard Worker}
204*cf84ac9aSAndroid Build Coastguard Worker/^Abbrev Number:[^(]+\(DW_TAG_/ {
205*cf84ac9aSAndroid Build Coastguard Worker	if (match($0, /typedef|union_type|structure_type|pointer_type\
206*cf84ac9aSAndroid Build Coastguard Worker|enumeration_type|array_type|base_type|member/, temparray)) {
207*cf84ac9aSAndroid Build Coastguard Worker		array_special[idx] = temparray[0]
208*cf84ac9aSAndroid Build Coastguard Worker		array[idx, "special"] = temparray[0]
209*cf84ac9aSAndroid Build Coastguard Worker		if ("pointer_type" == temparray[0])
210*cf84ac9aSAndroid Build Coastguard Worker			array[idx, "byte_size"] = default_pointer_size
211*cf84ac9aSAndroid Build Coastguard Worker		if (level > 1 && "member" == temparray[0])
212*cf84ac9aSAndroid Build Coastguard Worker			array_parents[idx] = parent[level-1]
213*cf84ac9aSAndroid Build Coastguard Worker	}
214*cf84ac9aSAndroid Build Coastguard Worker}
215*cf84ac9aSAndroid Build Coastguard WorkerEND {
216*cf84ac9aSAndroid Build Coastguard Worker	parents_cnt = asorti(array_parents, aparents_keys)
217*cf84ac9aSAndroid Build Coastguard Worker
218*cf84ac9aSAndroid Build Coastguard Worker	for (item in array_special) {
219*cf84ac9aSAndroid Build Coastguard Worker		if (array[item, "special"] == "pointer_type") {
220*cf84ac9aSAndroid Build Coastguard Worker			mpers_ptr_t = \
221*cf84ac9aSAndroid Build Coastguard Worker				"uint" 8 * array_get(item, "byte_size") "_t"
222*cf84ac9aSAndroid Build Coastguard Worker			print "#ifndef mpers_ptr_t_is_" mpers_ptr_t
223*cf84ac9aSAndroid Build Coastguard Worker			print "typedef " mpers_ptr_t " mpers_ptr_t;"
224*cf84ac9aSAndroid Build Coastguard Worker			print "#define mpers_ptr_t_is_" mpers_ptr_t
225*cf84ac9aSAndroid Build Coastguard Worker			print "#endif"
226*cf84ac9aSAndroid Build Coastguard Worker			break
227*cf84ac9aSAndroid Build Coastguard Worker		}
228*cf84ac9aSAndroid Build Coastguard Worker	}
229*cf84ac9aSAndroid Build Coastguard Worker	for (item in array_names) {
230*cf84ac9aSAndroid Build Coastguard Worker		if (array[item, "name"] == VAR_NAME) {
231*cf84ac9aSAndroid Build Coastguard Worker			type = array_get(item, "type")
232*cf84ac9aSAndroid Build Coastguard Worker			print "typedef"
233*cf84ac9aSAndroid Build Coastguard Worker			what_is(type)
234*cf84ac9aSAndroid Build Coastguard Worker			name = array_get(type, "name")
235*cf84ac9aSAndroid Build Coastguard Worker			print ARCH_FLAG "_" name ";"
236*cf84ac9aSAndroid Build Coastguard Worker			print "#define MPERS_" \
237*cf84ac9aSAndroid Build Coastguard Worker				ARCH_FLAG "_" name " " \
238*cf84ac9aSAndroid Build Coastguard Worker				ARCH_FLAG "_" name
239*cf84ac9aSAndroid Build Coastguard Worker			break
240*cf84ac9aSAndroid Build Coastguard Worker		}
241*cf84ac9aSAndroid Build Coastguard Worker	}
242*cf84ac9aSAndroid Build Coastguard Worker}
243