debuggers.hg

view xen/tools/get-fields.sh @ 22855:1d1eec7e1fb4

xl: Perform minimal validation of virtual disk file while parsing config file

This patch performs some very basic validation on the virtual disk
file passed through the config file. This validation ensures that we
don't go too far with the initialization like spawn qemu and more
while there could be some potentially fundamental issues.

[ Patch fixed up to work with PHYSTYPE_EMPTY 22808:6ec61438713a -iwj ]

Signed-off-by: Kamala Narasimhan <kamala.narasimhan@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Kamala Narasimhan <kamala.narasimhan@gmail.com>
date Tue Jan 25 18:09:49 2011 +0000 (2011-01-25)
parents f964ec304363
children
line source
1 test -n "$1" -a -n "$2" -a -n "$3"
2 set -ef
4 SED=sed
5 if test -x /usr/xpg4/bin/sed; then
6 SED=/usr/xpg4/bin/sed
7 fi
8 if test -z ${PYTHON}; then
9 PYTHON=`/usr/bin/env python`
10 fi
11 if test -z ${PYTHON}; then
12 echo "Python not found"
13 exit 1
14 fi
16 get_fields ()
17 {
18 local level=1 aggr=0 name= fields=
19 for token in $2
20 do
21 case "$token" in
22 struct|union)
23 test $level != 1 || aggr=1 fields= name=
24 ;;
25 "{")
26 level=$(expr $level + 1)
27 ;;
28 "}")
29 level=$(expr $level - 1)
30 if [ $level = 1 -a $name = $1 ]
31 then
32 echo "$fields }"
33 return 0
34 fi
35 ;;
36 [a-zA-Z_]*)
37 test $aggr = 0 -o -n "$name" || name="$token"
38 ;;
39 esac
40 test $aggr = 0 || fields="$fields $token"
41 done
42 }
44 get_typedefs ()
45 {
46 local level=1 state=
47 for token in $1
48 do
49 case "$token" in
50 typedef)
51 test $level != 1 || state=1
52 ;;
53 COMPAT_HANDLE\(*\))
54 test $level != 1 -o "$state" != 1 || state=2
55 ;;
56 [\{\[])
57 level=$(expr $level + 1)
58 ;;
59 [\}\]])
60 level=$(expr $level - 1)
61 ;;
62 ";")
63 test $level != 1 || state=
64 ;;
65 [a-zA-Z_]*)
66 test $level != 1 -o "$state" != 2 || echo "$token"
67 ;;
68 esac
69 done
70 }
72 build_enums ()
73 {
74 local level=1 kind= fields= members= named= id= token
75 for token in $2
76 do
77 case "$token" in
78 struct|union)
79 test $level != 2 || fields=" "
80 kind="$token;$kind"
81 ;;
82 "{")
83 level=$(expr $level + 1)
84 ;;
85 "}")
86 level=$(expr $level - 1)
87 if [ $level = 1 ]
88 then
89 if [ "${kind%%;*}" = union ]
90 then
91 echo
92 echo "enum XLAT_$1 {"
93 for m in $members
94 do
95 echo " XLAT_${1}_$m,"
96 done
97 echo "};"
98 fi
99 return 0
100 elif [ $level = 2 ]
101 then
102 named='?'
103 fi
104 ;;
105 [a-zA-Z]*)
106 id=$token
107 if [ -n "$named" -a -n "${kind#*;}" ]
108 then
109 build_enums ${1}_$token "$fields"
110 named='!'
111 fi
112 ;;
113 ",")
114 test $level != 2 || members="$members $id"
115 ;;
116 ";")
117 test $level != 2 || members="$members $id"
118 test -z "$named" || kind=${kind#*;}
119 named=
120 ;;
121 esac
122 test -z "$fields" || fields="$fields $token"
123 done
124 }
126 handle_field ()
127 {
128 if [ -z "$5" ]
129 then
130 echo " \\"
131 if [ -z "$4" ]
132 then
133 echo -n "$1(_d_)->$3 = (_s_)->$3;"
134 else
135 echo -n "$1XLAT_${2}_HNDL_$(echo $3 | $SED 's,\.,_,g')(_d_, _s_);"
136 fi
137 elif [ -z "$(echo "$5" | $SED 's,[^{}],,g')" ]
138 then
139 local tag=$(echo "$5" | ${PYTHON} -c '
140 import re,sys
141 for line in sys.stdin.readlines():
142 print re.subn(r"\s*(struct|union)\s+(compat_)?(\w+)\s.*", r"\3", line)[0].rstrip()
143 ')
144 echo " \\"
145 echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);"
146 else
147 local level=1 kind= fields= id= array= arrlvl=1 array_type= type= token
148 for token in $5
149 do
150 case "$token" in
151 struct|union)
152 test $level != 2 || fields=" "
153 if [ $level = 1 ]
154 then
155 kind=$token
156 if [ $kind = union ]
157 then
158 echo " \\"
159 echo -n "${1}switch ($(echo $3 | $SED 's,\.,_,g')) {"
160 fi
161 fi
162 ;;
163 "{")
164 level=$(expr $level + 1) id=
165 ;;
166 "}")
167 level=$(expr $level - 1) id=
168 if [ $level = 1 -a $kind = union ]
169 then
170 echo " \\"
171 echo -n "$1}"
172 fi
173 ;;
174 "[")
175 if [ $level != 2 -o $arrlvl != 1 ]
176 then
177 :
178 elif [ -z "$array" ]
179 then
180 array=" "
181 else
182 array="$array;"
183 fi
184 arrlvl=$(expr $arrlvl + 1)
185 ;;
186 "]")
187 arrlvl=$(expr $arrlvl - 1)
188 ;;
189 COMPAT_HANDLE\(*\))
190 if [ $level = 2 -a -z "$id" ]
191 then
192 type=${token#COMPAT_HANDLE?}
193 type=${type%?}
194 type=${type#compat_}
195 fi
196 ;;
197 compat_domain_handle_t)
198 if [ $level = 2 -a -z "$id" ]
199 then
200 array_type=$token
201 fi
202 ;;
203 [a-zA-Z]*)
204 if [ -z "$id" -a -z "$type" -a -z "$array_type" ]
205 then
206 for id in $typedefs
207 do
208 test $id != "$token" || type=$id
209 done
210 if [ -z "$type" ]
211 then
212 id=$token
213 else
214 id=
215 fi
216 else
217 id=$token
218 fi
219 ;;
220 [\,\;])
221 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
222 then
223 if [ $kind = union ]
224 then
225 echo " \\"
226 echo -n "${1}case XLAT_${2}_$(echo $3.$id | $SED 's,\.,_,g'):"
227 handle_field "$1 " $2 $3.$id "$type" "$fields"
228 elif [ -z "$array" -a -z "$array_type" ]
229 then
230 handle_field "$1" $2 $3.$id "$type" "$fields"
231 elif [ -z "$array" ]
232 then
233 copy_array " " $3.$id
234 else
235 handle_array "$1" $2 $3.$id "${array#*;}" "$type" "$fields"
236 fi
237 test "$token" != ";" || fields= id= type=
238 array=
239 if [ $kind = union ]
240 then
241 echo " \\"
242 echo -n "$1 break;"
243 fi
244 fi
245 ;;
246 *)
247 if [ -n "$array" ]
248 then
249 array="$array $token"
250 fi
251 ;;
252 esac
253 test -z "$fields" || fields="$fields $token"
254 done
255 fi
256 }
258 copy_array ()
259 {
260 echo " \\"
261 echo "${1}if ((_d_)->$2 != (_s_)->$2) \\"
262 echo -n "$1 memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));"
263 }
265 handle_array ()
266 {
267 local i="i$(echo $4 | $SED 's,[^;], ,g' | wc -w | $SED 's,[[:space:]]*,,g')"
268 echo " \\"
269 echo "$1{ \\"
270 echo "$1 unsigned int $i; \\"
271 echo -n "$1 for ($i = 0; $i < "${4%%;*}"; ++$i) {"
272 if [ "$4" = "${4#*;}" ]
273 then
274 handle_field "$1 " $2 $3[$i] "$5" "$6"
275 else
276 handle_array "$1 " $2 $3[$i] "${4#*;}" "$5" "$6"
277 fi
278 echo " \\"
279 echo "$1 } \\"
280 echo -n "$1}"
281 }
283 build_body ()
284 {
285 echo
286 echo -n "#define XLAT_$1(_d_, _s_) do {"
287 local level=1 fields= id= array= arrlvl=1 array_type= type= token
288 for token in $2
289 do
290 case "$token" in
291 struct|union)
292 test $level != 2 || fields=" "
293 ;;
294 "{")
295 level=$(expr $level + 1) id=
296 ;;
297 "}")
298 level=$(expr $level - 1) id=
299 ;;
300 "[")
301 if [ $level != 2 -o $arrlvl != 1 ]
302 then
303 :
304 elif [ -z "$array" ]
305 then
306 array=" "
307 else
308 array="$array;"
309 fi
310 arrlvl=$(expr $arrlvl + 1)
311 ;;
312 "]")
313 arrlvl=$(expr $arrlvl - 1)
314 ;;
315 COMPAT_HANDLE\(*\))
316 if [ $level = 2 -a -z "$id" ]
317 then
318 type=${token#COMPAT_HANDLE?}
319 type=${type%?}
320 type=${type#compat_}
321 fi
322 ;;
323 compat_domain_handle_t)
324 if [ $level = 2 -a -z "$id" ]
325 then
326 array_type=$token
327 fi
328 ;;
329 [a-zA-Z_]*)
330 if [ -n "$array" ]
331 then
332 array="$array $token"
333 elif [ -z "$id" -a -z "$type" -a -z "$array_type" ]
334 then
335 for id in $typedefs
336 do
337 test $id != "$token" || type=$id
338 done
339 if [ -z "$type" ]
340 then
341 id=$token
342 else
343 id=
344 fi
345 else
346 id=$token
347 fi
348 ;;
349 [\,\;])
350 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
351 then
352 if [ -z "$array" -a -z "$array_type" ]
353 then
354 handle_field " " $1 $id "$type" "$fields"
355 elif [ -z "$array" ]
356 then
357 copy_array " " $id
358 else
359 handle_array " " $1 $id "${array#*;}" "$type" "$fields"
360 fi
361 test "$token" != ";" || fields= id= type=
362 array=
363 fi
364 ;;
365 *)
366 if [ -n "$array" ]
367 then
368 array="$array $token"
369 fi
370 ;;
371 esac
372 test -z "$fields" || fields="$fields $token"
373 done
374 echo " \\"
375 echo "} while (0)"
376 }
378 check_field ()
379 {
380 if [ -z "$(echo "$4" | $SED 's,[^{}],,g')" ]
381 then
382 echo "; \\"
383 local n=$(echo $3 | $SED 's,[^.], ,g' | wc -w | $SED 's,[[:space:]]*,,g')
384 if [ -n "$4" ]
385 then
386 for n in $4
387 do
388 case $n in
389 struct|union)
390 ;;
391 [a-zA-Z_]*)
392 echo -n " CHECK_${n#xen_}"
393 break
394 ;;
395 *)
396 echo "Malformed compound declaration: '$n'" >&2
397 exit 1
398 ;;
399 esac
400 done
401 elif [ $n = 0 ]
402 then
403 echo -n " CHECK_FIELD_($1, $2, $3)"
404 else
405 echo -n " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | $SED 's!\.!, !g'))"
406 fi
407 else
408 local level=1 fields= id= token
409 for token in $4
410 do
411 case "$token" in
412 struct|union)
413 test $level != 2 || fields=" "
414 ;;
415 "{")
416 level=$(expr $level + 1) id=
417 ;;
418 "}")
419 level=$(expr $level - 1) id=
420 ;;
421 [a-zA-Z]*)
422 id=$token
423 ;;
424 [\,\;])
425 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
426 then
427 check_field $1 $2 $3.$id "$fields"
428 test "$token" != ";" || fields= id=
429 fi
430 ;;
431 esac
432 test -z "$fields" || fields="$fields $token"
433 done
434 fi
435 }
437 build_check ()
438 {
439 echo
440 echo "#define CHECK_$1 \\"
441 local level=1 fields= kind= id= arrlvl=1 token
442 for token in $2
443 do
444 case "$token" in
445 struct|union)
446 if [ $level = 1 ]
447 then
448 kind=$token
449 echo -n " CHECK_SIZE_($kind, $1)"
450 elif [ $level = 2 ]
451 then
452 fields=" "
453 fi
454 ;;
455 "{")
456 level=$(expr $level + 1) id=
457 ;;
458 "}")
459 level=$(expr $level - 1) id=
460 ;;
461 "[")
462 arrlvl=$(expr $arrlvl + 1)
463 ;;
464 "]")
465 arrlvl=$(expr $arrlvl - 1)
466 ;;
467 [a-zA-Z_]*)
468 test $level != 2 -o $arrlvl != 1 || id=$token
469 ;;
470 [\,\;])
471 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
472 then
473 check_field $kind $1 $id "$fields"
474 test "$token" != ";" || fields= id=
475 fi
476 ;;
477 esac
478 test -z "$fields" || fields="$fields $token"
479 done
480 echo ""
481 }
483 list="$($SED -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)"
484 fields="$(get_fields $(echo $2 | $SED 's,^compat_xen,compat_,') "$list")"
485 if [ -z "$fields" ]
486 then
487 echo "Fields of '$2' not found in '$3'" >&2
488 exit 1
489 fi
490 name=${2#compat_}
491 name=${name#xen}
492 case "$1" in
493 "!")
494 typedefs="$(get_typedefs "$list")"
495 build_enums $name "$fields"
496 build_body $name "$fields"
497 ;;
498 "?")
499 build_check $name "$fields"
500 ;;
501 *)
502 echo "Invalid translation indicator: '$1'" >&2
503 exit 1
504 ;;
505 esac