1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0-or-later 3 4import os, sys, xml.etree.ElementTree 5 6def 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 33sys.stdout.write('#include "qemu/osdep.h"\n' \ 34 '#include "exec/gdbstub.h"\n' \ 35 '\n' 36 'const GDBFeature gdb_static_features[] = {\n') 37 38for 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 writeliteral(8, bytes(os.path.basename(input), 'utf-8')) 89 sys.stdout.write(',\n') 90 writeliteral(8, read) 91 sys.stdout.write(',\n') 92 writeliteral(8, bytes(feature_name, 'utf-8')) 93 sys.stdout.write(',\n (const char * const []) {\n') 94 95 for index, regname in enumerate(regnames): 96 sys.stdout.write(f' [{regnums[index] - base_reg}] =\n') 97 writeliteral(16, bytes(regname, 'utf-8')) 98 sys.stdout.write(',\n') 99 100 sys.stdout.write(f' }},\n {num_regs},\n }},\n') 101 102sys.stdout.write(' { NULL }\n};\n') 103