master
py 109 lines 3.31 KB
Raw
1 #!/usr/bin/env python3
2 # SPDX-License-Identifier: GPL-2.0-or-later
3
4 import os, sys, xml.etree.ElementTree
5
6 def writeliteral(indent, bytes):
7 sys.stdout.write(' ' * indent)
8 sys.stdout.write('"')
9 quoted = True
10
11 for c in bytes:
12 if not quoted:
13 sys.stdout.write('\n')
14 sys.stdout.write(' ' * indent)
15 sys.stdout.write('"')
16 quoted = True
17
18 if c == b'"'[0]:
19 sys.stdout.write('\\"')
20 elif c == b'\\'[0]:
21 sys.stdout.write('\\\\')
22 elif c == b'\n'[0]:
23 sys.stdout.write('\\n"')
24 quoted = False
25 elif c >= 32 and c < 127:
26 sys.stdout.write(c.to_bytes(1, 'big').decode())
27 else:
28 sys.stdout.write(f'\\{c:03o}')
29
30 if quoted:
31 sys.stdout.write('"')
32
33 sys.stdout.write('#include "qemu/osdep.h"\n' \
34 '#include "exec/gdbstub.h"\n' \
35 '\n'
36 'const GDBFeature gdb_static_features[] = {\n')
37
38 for input in sys.argv[1:]:
39 with open(input, 'rb') as file:
40 read = file.read()
41
42 parser = xml.etree.ElementTree.XMLPullParser(['start', 'end'])
43 parser.feed(read)
44 events = parser.read_events()
45 event, element = next(events)
46 if event != 'start':
47 sys.stderr.write(f'unexpected event: {event}\n')
48 exit(1)
49 if element.tag != 'feature':
50 sys.stderr.write(f'unexpected start tag: {element.tag}\n')
51 exit(1)
52
53 feature_name = element.attrib['name']
54 regnum = 0
55 regnames = []
56 regnums = []
57 tags = ['feature']
58 for event, element in events:
59 if event == 'end':
60 if element.tag != tags[len(tags) - 1]:
61 sys.stderr.write(f'unexpected end tag: {element.tag}\n')
62 exit(1)
63
64 tags.pop()
65 if element.tag == 'feature':
66 break
67 elif event == 'start':
68 if len(tags) < 2 and element.tag == 'reg':
69 if 'regnum' in element.attrib:
70 regnum = int(element.attrib['regnum'])
71
72 regnames.append(element.attrib['name'])
73 regnums.append(regnum)
74 regnum += 1
75
76 tags.append(element.tag)
77 else:
78 raise Exception(f'unexpected event: {event}\n')
79
80 if len(tags):
81 sys.stderr.write('unterminated feature tag\n')
82 exit(1)
83
84 base_reg = min(regnums)
85 num_regs = max(regnums) - base_reg + 1 if len(regnums) else 0
86
87 sys.stdout.write(' {\n')
88 sys.stdout.write(' .xmlname = ')
89 writeliteral(0, bytes(os.path.basename(input), 'utf-8'))
90 sys.stdout.write(',\n')
91 sys.stdout.write(' .xml = \n')
92 writeliteral(12, read)
93 sys.stdout.write(',\n')
94 sys.stdout.write(' .name = ')
95 writeliteral(0, bytes(feature_name, 'utf-8'))
96 sys.stdout.write(',\n')
97 sys.stdout.write(f' .regs = (const char * const [{num_regs}]) {{\n')
98
99 for index, regname in enumerate(regnames):
100 sys.stdout.write(f' [{regnums[index] - base_reg}] =\n')
101 writeliteral(16, bytes(regname, 'utf-8'))
102 sys.stdout.write(',\n')
103
104 sys.stdout.write( ' },\n')
105 sys.stdout.write(f' .base_reg = {base_reg},\n')
106 sys.stdout.write(f' .num_regs = {num_regs},\n')
107 sys.stdout.write( ' },\n')
108
109 sys.stdout.write(' { NULL }\n};\n')