#!/bin/gawk
#
# Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
# Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
# Copyright (c) 2015-2018 The strace developers.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

function array_get(array_idx, array_member, \
		   array_return)
{
	array_return = array[array_idx, array_member]
	if ("" == array_return) {
		printf("%s: index [%s] without %s\n",
		       FILENAME, array_idx, array_member) > "/dev/stderr"
		exit 1
	}
	return array_return
}
function norm_idx(idx)
{
	return sprintf("%016s", idx)
}
function array_seq(array_idx)
{
	if ((array_idx, "seq") in array)
		return array[array_idx, "seq"]
	index_seq++
	array[array_idx, "seq"] = index_seq
	return index_seq
}
function enter(array_idx,
	       item)
{
	if (array_idx in called) {
		printf("%s: index loop detected:", FILENAME) > "/dev/stderr"
		for (item in called)
			printf(" %s", item) > "/dev/stderr"
		print "" > "/dev/stderr"
		exit 1
	}
	called[array_idx] = 1
}
function leave(array_idx, to_return)
{
	delete called[array_idx]
	return to_return
}
function update_upper_bound(idx, val, \
			    count)
{
	count = array[idx, "count"]
	if (count == "")
		count = 1
	array[idx, "count"] = count * val
	array[idx, "upper_bound"] = array[idx, "upper_bound"] "[" val "]"
}
function what_is(what_idx, \
		 item, loc_diff, location, prev_location, prev_returned_size, \
		 special, to_return, type_idx, enc, i)
{
	enter(what_idx)
	special = array_get(what_idx, "special")
	if (special == "base_type") {
		enc = array_get(what_idx, "encoding")
		if (enc == 5) { # signed
			printf("int%s_t ",
			       8 * array_get(what_idx, "byte_size"))
		} else if (enc == 7) { # unsigned
			printf("uint%s_t ",
			       8 * array_get(what_idx, "byte_size"))
		} else { # float, signed/unsigned char
			printf("%s ", array_get(what_idx, "name"))
		}
		returned_size = array_get(what_idx, "byte_size")
	} else if (special == "enumeration_type") {
		returned_size = array_get(what_idx, "byte_size")
		printf("uint%s_t ", 8 * returned_size)
	} else if (special == "pointer_type") {
		printf("mpers_ptr_t ")
		returned_size = array_get(what_idx, "byte_size")
	} else if (special == "array_type") {
		type_idx = array_get(what_idx, "type")
		what_is(type_idx)
		to_return = array[what_idx, "upper_bound"]
		if ("" == to_return)
			to_return = "[0]"
		returned_size = array[what_idx, "count"] * returned_size
		return leave(what_idx, to_return)
	} else if (special == "structure_type") {
		print "struct {"
		prev_location = 0
		location = 0
		returned_size = 0
		prev_returned_size = 0
		for (i = 1; i <= parents_cnt; i += 1) {
			if (array_parents[aparents_keys[i]] == what_idx) {
				location = array_get(aparents_keys[i], "location")
				loc_diff = location - prev_location - \
					prev_returned_size
				if (loc_diff != 0) {
					printf("unsigned char mpers_%s_%s[%s];\n",
					       "filler", array_seq(aparents_keys[i]), loc_diff)
				}
				prev_location = location
				returned = what_is(aparents_keys[i])
				prev_returned_size = returned_size
				printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
			}
		}
		returned_size = array_get(what_idx, "byte_size")
		loc_diff = returned_size - prev_location - prev_returned_size
		if (loc_diff != 0) {
			printf("unsigned char mpers_%s_%s[%s];\n",
			       "end_filler", array_seq(item), loc_diff)
		}
		printf("} ATTRIBUTE_PACKED ")
	} else if (special == "union_type") {
		print "union {"
		for (i = 1; i <= parents_cnt; i += 1) {
			if (array_parents[aparents_keys[i]] == what_idx) {
				returned = what_is(aparents_keys[i])
				printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
			}
		}
		printf("} ")
		returned_size = array_get(what_idx, "byte_size")
	} else if (special == "typedef") {
		type_idx = array_get(what_idx, "type")
		return leave(what_idx, what_is(type_idx))
	} else if (special == "member") {
		type_idx = array_get(what_idx, "type")
		return leave(what_idx, what_is(type_idx))
	} else {
		type_idx = array_get(what_idx, "type")
		what_is(type_idx)
	}
	return leave(what_idx, "")
}
BEGIN {
	match(ARCH_FLAG, /[[:digit:]]+/, temparray)
	default_pointer_size = temparray[0] / 8
	print "#include <inttypes.h>"
}
/^<[[:xdigit:]]+>/ {
	match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
	level = matches[1]
	idx = norm_idx(matches[2])
	array[idx, "idx"] = idx
	parent[level] = idx
}
/^DW_AT_data_member_location/ {
	if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
		match($0, /([[:digit:]]+)/, temparray)
	array[idx, "location"] = temparray[1]
}
/^DW_AT_name/ {
	match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
		temparray)
	array_names[idx] = 1
	array[idx, "name"] = temparray[1]
}
/^DW_AT_byte_size/ {
	match($0, /[[:digit:]]+/, temparray)
	array[idx, "byte_size"] = temparray[0]
}
/^DW_AT_encoding/ {
	match($0, /[[:digit:]]+/, temparray)
	array[idx, "encoding"] = temparray[0]
}
/^DW_AT_type/ {
	match($0, /:[[:space:]]+<0x([[:xdigit:]]*)>$/, temparray)
	array[idx, "type"] = norm_idx(temparray[1])
}
/^DW_AT_upper_bound/ {
	match($0, /[[:digit:]]+/, temparray)
	update_upper_bound(parent[level - 1], temparray[0] + 1)
}
/^DW_AT_count/ {
	match($0, /[[:digit:]]+/, temparray)
	update_upper_bound(parent[level - 1], temparray[0])
}
/^Abbrev Number:[^(]+\(DW_TAG_/ {
	if (match($0, /typedef|union_type|structure_type|pointer_type\
|enumeration_type|array_type|base_type|member/, temparray)) {
		array_special[idx] = temparray[0]
		array[idx, "special"] = temparray[0]
		if ("pointer_type" == temparray[0])
			array[idx, "byte_size"] = default_pointer_size
		if (level > 1 && "member" == temparray[0])
			array_parents[idx] = parent[level-1]
	}
}
END {
	parents_cnt = asorti(array_parents, aparents_keys)

	for (item in array_special) {
		if (array[item, "special"] == "pointer_type") {
			mpers_ptr_t = \
				"uint" 8 * array_get(item, "byte_size") "_t"
			print "#ifndef mpers_ptr_t_is_" mpers_ptr_t
			print "typedef " mpers_ptr_t " mpers_ptr_t;"
			print "#define mpers_ptr_t_is_" mpers_ptr_t
			print "#endif"
			break
		}
	}
	for (item in array_names) {
		if (array[item, "name"] == VAR_NAME) {
			type = array_get(item, "type")
			print "typedef"
			what_is(type)
			name = array_get(type, "name")
			print ARCH_FLAG "_" name ";"
			print "#define MPERS_" \
				ARCH_FLAG "_" name " " \
				ARCH_FLAG "_" name
			break
		}
	}
}
