ia64/xen-unstable

changeset 13291:4a164bf1edfc

Handle the creation of startup info for compatibility mode guests. This
includes a script to auto-generate checking or translation code between
native and compatibility mode hypercall argument structures.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Emmanuel Ackaouy <ack@xensource.com>
date Fri Jan 05 17:34:28 2007 +0000 (2007-01-05)
parents e98b092c2057
children 4c8f157a3a47
files Config.mk xen/arch/x86/domain_build.c xen/arch/x86/setup.c xen/common/compat/Makefile xen/common/compat/xlat.c xen/include/Makefile xen/include/xlat.lst xen/tools/get-fields.sh
line diff
     1.1 --- a/Config.mk	Fri Jan 05 17:34:28 2007 +0000
     1.2 +++ b/Config.mk	Fri Jan 05 17:34:28 2007 +0000
     1.3 @@ -11,6 +11,8 @@ XEN_OS              ?= $(shell uname -s)
     1.4  
     1.5  CONFIG_$(XEN_OS) := y
     1.6  
     1.7 +SHELL     ?= /bin/sh
     1.8 +
     1.9  # Tools to run on system hosting the build
    1.10  HOSTCC     = gcc
    1.11  HOSTCFLAGS = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
     2.1 --- a/xen/arch/x86/domain_build.c	Fri Jan 05 17:34:28 2007 +0000
     2.2 +++ b/xen/arch/x86/domain_build.c	Fri Jan 05 17:34:28 2007 +0000
     2.3 @@ -19,6 +19,7 @@
     2.4  #include <xen/version.h>
     2.5  #include <xen/iocap.h>
     2.6  #include <xen/bitops.h>
     2.7 +#include <xen/compat.h>
     2.8  #include <asm/regs.h>
     2.9  #include <asm/system.h>
    2.10  #include <asm/io.h>
    2.11 @@ -848,6 +849,11 @@ int construct_dom0(struct domain *d,
    2.12          si->console.dom0.info_size = sizeof(struct dom0_vga_console_info);
    2.13      }
    2.14  
    2.15 +#ifdef CONFIG_COMPAT
    2.16 +    if ( IS_COMPAT(d) )
    2.17 +        xlat_start_info(si, XLAT_start_info_console_dom0);
    2.18 +#endif
    2.19 +
    2.20      /* Reinstate the caller's page tables. */
    2.21      write_ptbase(current);
    2.22      local_irq_enable();
     3.1 --- a/xen/arch/x86/setup.c	Fri Jan 05 17:34:28 2007 +0000
     3.2 +++ b/xen/arch/x86/setup.c	Fri Jan 05 17:34:28 2007 +0000
     3.3 @@ -18,6 +18,10 @@
     3.4  #include <xen/keyhandler.h>
     3.5  #include <xen/numa.h>
     3.6  #include <public/version.h>
     3.7 +#ifdef CONFIG_COMPAT
     3.8 +#include <compat/platform.h>
     3.9 +#include <compat/xen.h>
    3.10 +#endif
    3.11  #include <asm/bitops.h>
    3.12  #include <asm/smp.h>
    3.13  #include <asm/processor.h>
    3.14 @@ -546,6 +550,14 @@ void __init __start_xen(multiboot_info_t
    3.15      BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
    3.16      BUILD_BUG_ON(sizeof(vcpu_info_t) != 64);
    3.17  
    3.18 +#ifdef CONFIG_COMPAT
    3.19 +    BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) !=
    3.20 +                 sizeof(((struct compat_platform_op *)0)->u.pad));
    3.21 +    BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE);
    3.22 +    BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE);
    3.23 +    BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64);
    3.24 +#endif
    3.25 +
    3.26      /* Check definitions in public headers match internal defs. */
    3.27      BUILD_BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START);
    3.28  #ifdef HYPERVISOR_VIRT_END
     4.1 --- a/xen/common/compat/Makefile	Fri Jan 05 17:34:28 2007 +0000
     4.2 +++ b/xen/common/compat/Makefile	Fri Jan 05 17:34:28 2007 +0000
     4.3 @@ -1,4 +1,5 @@
     4.4  obj-y += kernel.o
     4.5 +obj-y += xlat.o
     4.6  
     4.7  # extra dependencies
     4.8  kernel.o:	../kernel.c
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/common/compat/xlat.c	Fri Jan 05 17:34:28 2007 +0000
     5.3 @@ -0,0 +1,32 @@
     5.4 +/******************************************************************************
     5.5 + * xlat.c
     5.6 + */
     5.7 +
     5.8 +#include <xen/compat.h>
     5.9 +#include <xen/lib.h>
    5.10 +#include <public/xen.h>
    5.11 +#include <compat/xen.h>
    5.12 +
    5.13 +/* In-place translation functons: */
    5.14 +void xlat_start_info(struct start_info *native,
    5.15 +                     enum XLAT_start_info_console console)
    5.16 +{
    5.17 +    struct compat_start_info *compat = (void *)native;
    5.18 +
    5.19 +    BUILD_BUG_ON(sizeof(*native) < sizeof(*compat));
    5.20 +    XLAT_start_info(compat, native);
    5.21 +}
    5.22 +
    5.23 +#define xen_dom0_vga_console_info dom0_vga_console_info
    5.24 +CHECK_dom0_vga_console_info;
    5.25 +#undef dom0_vga_console_info
    5.26 +
    5.27 +/*
    5.28 + * Local variables:
    5.29 + * mode: C
    5.30 + * c-set-style: "BSD"
    5.31 + * c-basic-offset: 4
    5.32 + * tab-width: 4
    5.33 + * indent-tabs-mode: nil
    5.34 + * End:
    5.35 + */
     6.1 --- a/xen/include/Makefile	Fri Jan 05 17:34:28 2007 +0000
     6.2 +++ b/xen/include/Makefile	Fri Jan 05 17:34:28 2007 +0000
     6.3 @@ -4,7 +4,7 @@ compat-arch-$(CONFIG_X86) := x86_32
     6.4  
     6.5  headers-y                 := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g')
     6.6  headers-y                 := $(filter-out %/dom0_ops.h,$(headers-y))
     6.7 -headers-y                 += compat/arch-$(compat-arch-y).h
     6.8 +headers-y                 += compat/arch-$(compat-arch-y).h compat/xlat.h
     6.9  
    6.10  cppflags-y                := -include public/xen-compat.h
    6.11  cppflags-$(CONFIG_X86)    += -m32
    6.12 @@ -53,5 +53,12 @@ compat/%.c: public/%.h Makefile
    6.13  	    >$@.new
    6.14  	mv -f $@.new $@
    6.15  
    6.16 +compat/xlat.h: xlat.lst $(filter-out compat/xlat.h,$(headers-y)) $(BASEDIR)/tools/get-fields.sh Makefile
    6.17 +	grep -v '^[[:space:]]*#' xlat.lst | \
    6.18 +	while read what name hdr; do \
    6.19 +		$(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $$(echo compat/$$hdr | sed 's,@arch@,$(compat-arch-y),g') || exit $$?; \
    6.20 +	done >$@.new
    6.21 +	mv -f $@.new $@
    6.22 +
    6.23  clean::
    6.24  	rm -rf compat
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xen/include/xlat.lst	Fri Jan 05 17:34:28 2007 +0000
     7.3 @@ -0,0 +1,5 @@
     7.4 +# First column indicator:
     7.5 +# ! - needs translation
     7.6 +# ? - needs checking
     7.7 +?	dom0_vga_console_info		xen.h
     7.8 +!	start_info			xen.h
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/tools/get-fields.sh	Fri Jan 05 17:34:28 2007 +0000
     8.3 @@ -0,0 +1,425 @@
     8.4 +#!/bin/sh
     8.5 +test -n "$1" -a -n "$2" -a -n "$3"
     8.6 +set -ef
     8.7 +
     8.8 +get_fields() {
     8.9 +	local level=1 aggr=0 name= fields=
    8.10 +	for token in $2
    8.11 +	do
    8.12 +		case "$token" in
    8.13 +		struct|union)
    8.14 +			test $level != 1 || aggr=1 fields= name=
    8.15 +			;;
    8.16 +		"{")
    8.17 +			level=$(expr $level + 1)
    8.18 +			;;
    8.19 +		"}")
    8.20 +			level=$(expr $level - 1)
    8.21 +			if [ $level = 1 -a $name = $1 ]
    8.22 +			then
    8.23 +				echo "$fields }"
    8.24 +				return 0
    8.25 +			fi
    8.26 +			;;
    8.27 +		[[:alpha:]_]*)
    8.28 +			test $aggr = 0 -o -n "$name" || name="$token"
    8.29 +			;;
    8.30 +		esac
    8.31 +		test $aggr = 0 || fields="$fields $token"
    8.32 +	done
    8.33 +}
    8.34 +
    8.35 +build_enums() {
    8.36 +	local level=1 kind= fields= members= named= id= token
    8.37 +	for token in $2
    8.38 +	do
    8.39 +		case "$token" in
    8.40 +		struct|union)
    8.41 +			test $level != 2 || fields=" "
    8.42 +			kind="$token;$kind"
    8.43 +			;;
    8.44 +		"{")
    8.45 +			level=$(expr $level + 1)
    8.46 +			;;
    8.47 +		"}")
    8.48 +			level=$(expr $level - 1)
    8.49 +			if [ $level = 1 ]
    8.50 +			then
    8.51 +				if [ "${kind%%;*}" = union ]
    8.52 +				then
    8.53 +					echo
    8.54 +					echo "enum XLAT_$1 {"
    8.55 +					for m in $members
    8.56 +					do
    8.57 +						echo "    XLAT_${1}_$m,"
    8.58 +					done
    8.59 +					echo "};"
    8.60 +				fi
    8.61 +				return 0
    8.62 +			elif [ $level = 2 ]
    8.63 +			then
    8.64 +				named='?'
    8.65 +			fi
    8.66 +			;;
    8.67 +		[[:alpha:]]*)
    8.68 +			id=$token
    8.69 +			if [ -n "$named" -a -n "${kind#*;}" ]
    8.70 +			then
    8.71 +				build_enums ${1}_$token "$fields"
    8.72 +				named='!'
    8.73 +			fi
    8.74 +			;;
    8.75 +		",")
    8.76 +			test $level != 2 || members="$members $id"
    8.77 +			;;
    8.78 +		";")
    8.79 +			test $level != 2 || members="$members $id"
    8.80 +			test -z "$named" || kind=${kind#*;}
    8.81 +			named=
    8.82 +			;;
    8.83 +		esac
    8.84 +		test -z "$fields" || fields="$fields $token"
    8.85 +	done
    8.86 +}
    8.87 +
    8.88 +handle_field() {
    8.89 +	if [ -z "$5" ]
    8.90 +	then
    8.91 +		echo " \\"
    8.92 +		if [ -z "$4" ]
    8.93 +		then
    8.94 +			echo -n "$1(_d_)->$3 = (_s_)->$3;"
    8.95 +		else
    8.96 +			echo -n "$1XLAT_${2}_HNDL_$(echo $3 | sed 's,\.,_,g')(_d_, _s_);"
    8.97 +		fi
    8.98 +	elif [ -z "$(echo "$5" | sed 's,[^{}],,g')" ]
    8.99 +	then
   8.100 +		local tag=$(echo "$5" | sed 's,[[:space:]]*\(struct\|union\)[[:space:]]\+\(compat_\)\?\([[:alnum:]_]\+\)[[:space:]].*,\3,')
   8.101 +		echo " \\"
   8.102 +		echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);"
   8.103 +	else
   8.104 +		local level=1 kind= fields= id= array= arrlvl=1 array_type= type= token
   8.105 +		for token in $5
   8.106 +		do
   8.107 +			case "$token" in
   8.108 +			struct|union)
   8.109 +				test $level != 2 || fields=" "
   8.110 +				if [ $level == 1 ]
   8.111 +				then
   8.112 +					kind=$token
   8.113 +					if [ $kind = union ]
   8.114 +					then
   8.115 +						echo " \\"
   8.116 +						echo -n "${1}switch ($(echo $3 | sed 's,\.,_,g')) {"
   8.117 +					fi
   8.118 +				fi
   8.119 +				;;
   8.120 +			"{")
   8.121 +				level=$(expr $level + 1) id=
   8.122 +				;;
   8.123 +			"}")
   8.124 +				level=$(expr $level - 1) id=
   8.125 +				if [ $level == 1 -a $kind = union ]
   8.126 +				then
   8.127 +					echo " \\"
   8.128 +					echo -n "$1}"
   8.129 +				fi
   8.130 +				;;
   8.131 +			"[")
   8.132 +				if [ $level != 2 -o $arrlvl != 1 ]
   8.133 +				then
   8.134 +					:
   8.135 +				elif [ -z "$array" ]
   8.136 +				then
   8.137 +					array=" "
   8.138 +				else
   8.139 +					array="$array;"
   8.140 +				fi
   8.141 +				arrlvl=$(expr $arrlvl + 1)
   8.142 +				;;
   8.143 +			"]")
   8.144 +				arrlvl=$(expr $arrlvl - 1)
   8.145 +				;;
   8.146 +			COMPAT_HANDLE\(*\))
   8.147 +				if [ $level == 2 -a -z "$id" ]
   8.148 +				then
   8.149 +					type=${token#COMPAT_HANDLE?}
   8.150 +					type=${type%?}
   8.151 +					type=${type#compat_}
   8.152 +				fi
   8.153 +				;;
   8.154 +			compat_domain_handle_t)
   8.155 +				if [ $level == 2 -a -z "$id" ]
   8.156 +				then
   8.157 +					array_type=$token
   8.158 +				fi
   8.159 +				;;
   8.160 +			[[:alpha:]]*)
   8.161 +				id=$token
   8.162 +				;;
   8.163 +			[\,\;])
   8.164 +				if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
   8.165 +				then
   8.166 +					if [ $kind = union ]
   8.167 +					then
   8.168 +						echo " \\"
   8.169 +						echo -n "${1}case XLAT_${2}_$(echo $3.$id | sed 's,\.,_,g'):"
   8.170 +						handle_field "$1    " $2 $3.$id "$type" "$fields"
   8.171 +					elif [ -z "$array" -a -z "$array_type" ]
   8.172 +					then
   8.173 +						handle_field "$1" $2 $3.$id "$type" "$fields"
   8.174 +					elif [ -z "$array" ]
   8.175 +					then
   8.176 +						copy_array "    " $3.$id
   8.177 +					else
   8.178 +						handle_array "$1" $2 $3.$id "${array#*;}" "$type" "$fields"
   8.179 +					fi
   8.180 +					test "$token" != ";" || fields= id= type=
   8.181 +					array=
   8.182 +					if [ $kind = union ]
   8.183 +					then
   8.184 +						echo " \\"
   8.185 +						echo -n "$1    break;"
   8.186 +					fi
   8.187 +				fi
   8.188 +				;;
   8.189 +			*)
   8.190 +				if [ -n "$array" ]
   8.191 +				then
   8.192 +					array="$array $token"
   8.193 +				fi
   8.194 +				;;
   8.195 +			esac
   8.196 +			test -z "$fields" || fields="$fields $token"
   8.197 +		done
   8.198 +	fi
   8.199 +}
   8.200 +
   8.201 +copy_array() {
   8.202 +	echo " \\"
   8.203 +	echo "${1}if ((_d_)->$2 != (_s_)->$2) \\"
   8.204 +	echo -n "$1    memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));"
   8.205 +}
   8.206 +
   8.207 +handle_array() {
   8.208 +	local i="i$(echo $4 | sed 's,[^;], ,g' | wc -w)"
   8.209 +	echo " \\"
   8.210 +	echo "$1{ \\"
   8.211 +	echo "$1    unsigned int $i; \\"
   8.212 +	echo -n "$1    for ($i = 0; $i < "${4%%;*}"; ++$i) {"
   8.213 +	if [ "$4" = "${4#*;}" ]
   8.214 +	then
   8.215 +		handle_field "$1        " $2 $3[$i] "$5" "$6"
   8.216 +	else
   8.217 +		handle_array "$1        " $2 $3[$i] "${4#*;}" "$5" "$6"
   8.218 +	fi
   8.219 +	echo " \\"
   8.220 +	echo "$1    } \\"
   8.221 +	echo -n "$1}"
   8.222 +}
   8.223 +
   8.224 +build_body() {
   8.225 +	echo
   8.226 +	echo -n "#define XLAT_$1(_d_, _s_)"
   8.227 +	local level=1 fields= id= array= arrlvl=1 array_type= type= token
   8.228 +	for token in $2
   8.229 +	do
   8.230 +		case "$token" in
   8.231 +		struct|union)
   8.232 +			test $level != 2 || fields=" "
   8.233 +			;;
   8.234 +		"{")
   8.235 +			level=$(expr $level + 1) id=
   8.236 +			;;
   8.237 +		"}")
   8.238 +			level=$(expr $level - 1) id=
   8.239 +			;;
   8.240 +		"[")
   8.241 +			if [ $level != 2 -o $arrlvl != 1 ]
   8.242 +			then
   8.243 +				:
   8.244 +			elif [ -z "$array" ]
   8.245 +			then
   8.246 +				array=" "
   8.247 +			else
   8.248 +				array="$array;"
   8.249 +			fi
   8.250 +			arrlvl=$(expr $arrlvl + 1)
   8.251 +			;;
   8.252 +		"]")
   8.253 +			arrlvl=$(expr $arrlvl - 1)
   8.254 +			;;
   8.255 +		COMPAT_HANDLE\(*\))
   8.256 +			if [ $level == 2 -a -z "$id" ]
   8.257 +			then
   8.258 +				type=${token#COMPAT_HANDLE?}
   8.259 +				type=${type%?}
   8.260 +				type=${type#compat_}
   8.261 +			fi
   8.262 +			;;
   8.263 +		compat_domain_handle_t)
   8.264 +			if [ $level == 2 -a -z "$id" ]
   8.265 +			then
   8.266 +				array_type=$token
   8.267 +			fi
   8.268 +			;;
   8.269 +		[[:alpha:]_]*)
   8.270 +			if [ -n "$array" ]
   8.271 +			then
   8.272 +				array="$array $token"
   8.273 +			else
   8.274 +				id=$token
   8.275 +			fi
   8.276 +			;;
   8.277 +		[\,\;])
   8.278 +			if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
   8.279 +			then
   8.280 +				if [ -z "$array" -a -z "$array_type" ]
   8.281 +				then
   8.282 +					handle_field "    " $1 $id "$type" "$fields"
   8.283 +				elif [ -z "$array" ]
   8.284 +				then
   8.285 +					copy_array "    " $id
   8.286 +				else
   8.287 +					handle_array "    " $1 $id "${array#*;}" "$type" "$fields"
   8.288 +				fi
   8.289 +				test "$token" != ";" || fields= id= type=
   8.290 +				array=
   8.291 +			fi
   8.292 +			;;
   8.293 +		*)
   8.294 +			if [ -n "$array" ]
   8.295 +			then
   8.296 +				array="$array $token"
   8.297 +			fi
   8.298 +			;;
   8.299 +		esac
   8.300 +		test -z "$fields" || fields="$fields $token"
   8.301 +	done
   8.302 +	echo ""
   8.303 +}
   8.304 +
   8.305 +check_field() {
   8.306 +	if [ -z "$(echo "$4" | sed 's,[^{}],,g')" ]
   8.307 +	then
   8.308 +		echo "; \\"
   8.309 +		local n=$(echo $3 | sed 's,[^.], ,g' | wc -w)
   8.310 +		if [ -n "$4" ]
   8.311 +		then
   8.312 +			for n in $4
   8.313 +			do
   8.314 +				case $n in
   8.315 +				struct|union)
   8.316 +					;;
   8.317 +				[[:alpha:]_]*)
   8.318 +					echo -n "    CHECK_$n"
   8.319 +					break
   8.320 +					;;
   8.321 +				*)
   8.322 +					echo "Malformed compound declaration: '$n'" >&2
   8.323 +					exit 1
   8.324 +					;;
   8.325 +				esac
   8.326 +			done
   8.327 +		elif [ $n = 0 ]
   8.328 +		then
   8.329 +			echo -n "    CHECK_FIELD_($1, $2, $3)"
   8.330 +		else
   8.331 +			echo -n "    CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | sed 's!\.!, !g'))"
   8.332 +		fi
   8.333 +	else
   8.334 +		local level=1 fields= id= token
   8.335 +		for token in $4
   8.336 +		do
   8.337 +			case "$token" in
   8.338 +			struct|union)
   8.339 +				test $level != 2 || fields=" "
   8.340 +				;;
   8.341 +			"{")
   8.342 +				level=$(expr $level + 1) id=
   8.343 +				;;
   8.344 +			"}")
   8.345 +				level=$(expr $level - 1) id=
   8.346 +				;;
   8.347 +			[[:alpha:]]*)
   8.348 +				id=$token
   8.349 +				;;
   8.350 +			[\,\;])
   8.351 +				if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
   8.352 +				then
   8.353 +					check_field $1 $2 $3.$id "$fields"
   8.354 +					test "$token" != ";" || fields= id=
   8.355 +				fi
   8.356 +				;;
   8.357 +			esac
   8.358 +			test -z "$fields" || fields="$fields $token"
   8.359 +		done
   8.360 +	fi
   8.361 +}
   8.362 +
   8.363 +build_check() {
   8.364 +	echo
   8.365 +	echo "#define CHECK_$1 \\"
   8.366 +	local level=1 fields= kind= id= arrlvl=1 token
   8.367 +	for token in $2
   8.368 +	do
   8.369 +		case "$token" in
   8.370 +		struct|union)
   8.371 +			if [ $level == 1 ]
   8.372 +			then
   8.373 +				kind=$token
   8.374 +				echo -n "    CHECK_SIZE_($kind, $1)"
   8.375 +			elif [ $level == 2 ]
   8.376 +			then
   8.377 +				fields=" "
   8.378 +			fi
   8.379 +			;;
   8.380 +		"{")
   8.381 +			level=$(expr $level + 1) id=
   8.382 +			;;
   8.383 +		"}")
   8.384 +			level=$(expr $level - 1) id=
   8.385 +			;;
   8.386 +		"[")
   8.387 +			arrlvl=$(expr $arrlvl + 1)
   8.388 +			;;
   8.389 +		"]")
   8.390 +			arrlvl=$(expr $arrlvl - 1)
   8.391 +			;;
   8.392 +		[[:alpha:]_]*)
   8.393 +			test $level != 2 -o $arrlvl != 1 || id=$token
   8.394 +			;;
   8.395 +		[\,\;])
   8.396 +			if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
   8.397 +			then
   8.398 +				check_field $kind $1 $id "$fields"
   8.399 +				test "$token" != ";" || fields= id=
   8.400 +			fi
   8.401 +			;;
   8.402 +		esac
   8.403 +		test -z "$fields" || fields="$fields $token"
   8.404 +	done
   8.405 +	echo ""
   8.406 +}
   8.407 +
   8.408 +fields="$(get_fields $(echo $2 | sed 's,^compat_xen,compat_,') "$(sed -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")"
   8.409 +if [ -z "$fields" ]
   8.410 +then
   8.411 +	echo "Fields of '$2' not found in '$3'" >&2
   8.412 +	exit 1
   8.413 +fi
   8.414 +name=${2#compat_}
   8.415 +name=${name#xen}
   8.416 +case "$1" in
   8.417 +"!")
   8.418 +	build_enums $name "$fields"
   8.419 +	build_body $name "$fields"
   8.420 +	;;
   8.421 +"?")
   8.422 +	build_check $name "$fields"
   8.423 +	;;
   8.424 +*)
   8.425 +	echo "Invalid translation indicator: '$1'" >&2
   8.426 +	exit 1
   8.427 +	;;
   8.428 +esac