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