1956af7daSAkihiko Odaki#!/usr/bin/env python3 2956af7daSAkihiko Odaki# SPDX-License-Identifier: GPL-2.0-or-later 3956af7daSAkihiko Odaki 46c2313e8SAkihiko Odakiimport os, sys, xml.etree.ElementTree 5956af7daSAkihiko Odaki 6956af7daSAkihiko Odakidef writeliteral(indent, bytes): 7956af7daSAkihiko Odaki sys.stdout.write(' ' * indent) 8956af7daSAkihiko Odaki sys.stdout.write('"') 9956af7daSAkihiko Odaki quoted = True 10956af7daSAkihiko Odaki 11956af7daSAkihiko Odaki for c in bytes: 12956af7daSAkihiko Odaki if not quoted: 13956af7daSAkihiko Odaki sys.stdout.write('\n') 14956af7daSAkihiko Odaki sys.stdout.write(' ' * indent) 15956af7daSAkihiko Odaki sys.stdout.write('"') 16956af7daSAkihiko Odaki quoted = True 17956af7daSAkihiko Odaki 18956af7daSAkihiko Odaki if c == b'"'[0]: 19956af7daSAkihiko Odaki sys.stdout.write('\\"') 20956af7daSAkihiko Odaki elif c == b'\\'[0]: 21956af7daSAkihiko Odaki sys.stdout.write('\\\\') 22956af7daSAkihiko Odaki elif c == b'\n'[0]: 23956af7daSAkihiko Odaki sys.stdout.write('\\n"') 24956af7daSAkihiko Odaki quoted = False 25956af7daSAkihiko Odaki elif c >= 32 and c < 127: 26956af7daSAkihiko Odaki sys.stdout.write(c.to_bytes(1, 'big').decode()) 27956af7daSAkihiko Odaki else: 28956af7daSAkihiko Odaki sys.stdout.write(f'\{c:03o}') 29956af7daSAkihiko Odaki 30956af7daSAkihiko Odaki if quoted: 31956af7daSAkihiko Odaki sys.stdout.write('"') 32956af7daSAkihiko Odaki 33956af7daSAkihiko Odakisys.stdout.write('#include "qemu/osdep.h"\n' \ 34956af7daSAkihiko Odaki '#include "exec/gdbstub.h"\n' \ 35956af7daSAkihiko Odaki '\n' 36956af7daSAkihiko Odaki 'const GDBFeature gdb_static_features[] = {\n') 37956af7daSAkihiko Odaki 38956af7daSAkihiko Odakifor input in sys.argv[1:]: 39956af7daSAkihiko Odaki with open(input, 'rb') as file: 40956af7daSAkihiko Odaki read = file.read() 41956af7daSAkihiko Odaki 426c2313e8SAkihiko Odaki parser = xml.etree.ElementTree.XMLPullParser(['start', 'end']) 436c2313e8SAkihiko Odaki parser.feed(read) 446c2313e8SAkihiko Odaki events = parser.read_events() 456c2313e8SAkihiko Odaki event, element = next(events) 466c2313e8SAkihiko Odaki if event != 'start': 476c2313e8SAkihiko Odaki sys.stderr.write(f'unexpected event: {event}\n') 486c2313e8SAkihiko Odaki exit(1) 496c2313e8SAkihiko Odaki if element.tag != 'feature': 506c2313e8SAkihiko Odaki sys.stderr.write(f'unexpected start tag: {element.tag}\n') 516c2313e8SAkihiko Odaki exit(1) 526c2313e8SAkihiko Odaki 53*eb37086fSAkihiko Odaki feature_name = element.attrib['name'] 546c2313e8SAkihiko Odaki regnum = 0 55*eb37086fSAkihiko Odaki regnames = [] 566c2313e8SAkihiko Odaki regnums = [] 576c2313e8SAkihiko Odaki tags = ['feature'] 586c2313e8SAkihiko Odaki for event, element in events: 596c2313e8SAkihiko Odaki if event == 'end': 606c2313e8SAkihiko Odaki if element.tag != tags[len(tags) - 1]: 616c2313e8SAkihiko Odaki sys.stderr.write(f'unexpected end tag: {element.tag}\n') 626c2313e8SAkihiko Odaki exit(1) 636c2313e8SAkihiko Odaki 646c2313e8SAkihiko Odaki tags.pop() 656c2313e8SAkihiko Odaki if element.tag == 'feature': 666c2313e8SAkihiko Odaki break 676c2313e8SAkihiko Odaki elif event == 'start': 686c2313e8SAkihiko Odaki if len(tags) < 2 and element.tag == 'reg': 696c2313e8SAkihiko Odaki if 'regnum' in element.attrib: 706c2313e8SAkihiko Odaki regnum = int(element.attrib['regnum']) 716c2313e8SAkihiko Odaki 72*eb37086fSAkihiko Odaki regnames.append(element.attrib['name']) 736c2313e8SAkihiko Odaki regnums.append(regnum) 746c2313e8SAkihiko Odaki regnum += 1 756c2313e8SAkihiko Odaki 766c2313e8SAkihiko Odaki tags.append(element.tag) 776c2313e8SAkihiko Odaki else: 786c2313e8SAkihiko Odaki raise Exception(f'unexpected event: {event}\n') 796c2313e8SAkihiko Odaki 806c2313e8SAkihiko Odaki if len(tags): 816c2313e8SAkihiko Odaki sys.stderr.write('unterminated feature tag\n') 826c2313e8SAkihiko Odaki exit(1) 836c2313e8SAkihiko Odaki 846c2313e8SAkihiko Odaki base_reg = min(regnums) 856c2313e8SAkihiko Odaki num_regs = max(regnums) - base_reg + 1 if len(regnums) else 0 866c2313e8SAkihiko Odaki 87956af7daSAkihiko Odaki sys.stdout.write(' {\n') 88956af7daSAkihiko Odaki writeliteral(8, bytes(os.path.basename(input), 'utf-8')) 89956af7daSAkihiko Odaki sys.stdout.write(',\n') 90956af7daSAkihiko Odaki writeliteral(8, read) 91*eb37086fSAkihiko Odaki sys.stdout.write(',\n') 92*eb37086fSAkihiko Odaki writeliteral(8, bytes(feature_name, 'utf-8')) 93*eb37086fSAkihiko Odaki sys.stdout.write(',\n (const char * const []) {\n') 94*eb37086fSAkihiko Odaki 95*eb37086fSAkihiko Odaki for index, regname in enumerate(regnames): 96*eb37086fSAkihiko Odaki sys.stdout.write(f' [{regnums[index] - base_reg}] =\n') 97*eb37086fSAkihiko Odaki writeliteral(16, bytes(regname, 'utf-8')) 98*eb37086fSAkihiko Odaki sys.stdout.write(',\n') 99*eb37086fSAkihiko Odaki 100*eb37086fSAkihiko Odaki sys.stdout.write(f' }},\n {num_regs},\n }},\n') 101956af7daSAkihiko Odaki 102956af7daSAkihiko Odakisys.stdout.write(' { NULL }\n};\n') 103