xref: /aosp_15_r20/trusty/kernel/lib/syscall/stubgen/stubgen.py (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker#!/bin/sh
2*344aa361SAndroid Build Coastguard Worker"." "`dirname $0`/../../../../../trusty/vendor/google/aosp/scripts/envsetup.sh"
3*344aa361SAndroid Build Coastguard Worker"exec" "$PY3" "$0" "$@"
4*344aa361SAndroid Build Coastguard Worker
5*344aa361SAndroid Build Coastguard Worker# Copyright 2013-2017 Google Inc. +All rights reserved.
6*344aa361SAndroid Build Coastguard Worker#
7*344aa361SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining
8*344aa361SAndroid Build Coastguard Worker# a copy of this software and associated documentation files
9*344aa361SAndroid Build Coastguard Worker# (the "Software"), to deal in the Software without restriction,
10*344aa361SAndroid Build Coastguard Worker# including without limitation the rights to use, copy, modify, merge,
11*344aa361SAndroid Build Coastguard Worker# publish, distribute, sublicense, and/or sell copies of the Software,
12*344aa361SAndroid Build Coastguard Worker# and to permit persons to whom the Software is furnished to do so,
13*344aa361SAndroid Build Coastguard Worker# subject to the following conditions:
14*344aa361SAndroid Build Coastguard Worker#
15*344aa361SAndroid Build Coastguard Worker# The above copyright notice and this permission notice shall be
16*344aa361SAndroid Build Coastguard Worker# included in all copies or substantial portions of the Software.
17*344aa361SAndroid Build Coastguard Worker#
18*344aa361SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19*344aa361SAndroid Build Coastguard Worker# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*344aa361SAndroid Build Coastguard Worker# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21*344aa361SAndroid Build Coastguard Worker# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22*344aa361SAndroid Build Coastguard Worker# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23*344aa361SAndroid Build Coastguard Worker# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24*344aa361SAndroid Build Coastguard Worker# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*344aa361SAndroid Build Coastguard Worker
26*344aa361SAndroid Build Coastguard Workerimport re
27*344aa361SAndroid Build Coastguard Workerimport sys
28*344aa361SAndroid Build Coastguard Workerfrom optparse import OptionParser
29*344aa361SAndroid Build Coastguard Worker
30*344aa361SAndroid Build Coastguard Worker"""
31*344aa361SAndroid Build Coastguard WorkerScript to generate syscall stubs from a syscall table file
32*344aa361SAndroid Build Coastguard Workerwith definitions like this:
33*344aa361SAndroid Build Coastguard Worker
34*344aa361SAndroid Build Coastguard WorkerDEF_SYSCALL(nr_syscall, syscall_name, return_type, nr_args, arg_list...)
35*344aa361SAndroid Build Coastguard Worker
36*344aa361SAndroid Build Coastguard WorkerFor e.g.,
37*344aa361SAndroid Build Coastguard WorkerDEF_SYSCALL(0x3, read, 3, int fd, void *buf, int size)
38*344aa361SAndroid Build Coastguard WorkerDEF_SYSCALL(0x4, write, 4, int fd, void *buf, int size)
39*344aa361SAndroid Build Coastguard Worker
40*344aa361SAndroid Build Coastguard WorkerFUNCTION(read)
41*344aa361SAndroid Build Coastguard Worker    ldr     r12, =__NR_read
42*344aa361SAndroid Build Coastguard Worker    swi     #0
43*344aa361SAndroid Build Coastguard Worker    bx      lr
44*344aa361SAndroid Build Coastguard Worker
45*344aa361SAndroid Build Coastguard WorkerFUNCTION(write)
46*344aa361SAndroid Build Coastguard Worker    ldr     r12, =__NR_write
47*344aa361SAndroid Build Coastguard Worker    swi     #0
48*344aa361SAndroid Build Coastguard Worker    bx      lr
49*344aa361SAndroid Build Coastguard Worker
50*344aa361SAndroid Build Coastguard WorkerAnother file with a enumeration of all syscalls is also generated:
51*344aa361SAndroid Build Coastguard Worker
52*344aa361SAndroid Build Coastguard Worker#define __NR_read  0x3
53*344aa361SAndroid Build Coastguard Worker#define __NR_write 0x4
54*344aa361SAndroid Build Coastguard Worker...
55*344aa361SAndroid Build Coastguard Worker
56*344aa361SAndroid Build Coastguard Worker
57*344aa361SAndroid Build Coastguard WorkerOnly syscalls with 4 or less arguments are supported.
58*344aa361SAndroid Build Coastguard Worker"""
59*344aa361SAndroid Build Coastguard Worker
60*344aa361SAndroid Build Coastguard Workercopyright_header = """/*
61*344aa361SAndroid Build Coastguard Worker * Copyright (c) 2012-2018 LK Trusty Authors. All Rights Reserved.
62*344aa361SAndroid Build Coastguard Worker *
63*344aa361SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining
64*344aa361SAndroid Build Coastguard Worker * a copy of this software and associated documentation files
65*344aa361SAndroid Build Coastguard Worker * (the "Software"), to deal in the Software without restriction,
66*344aa361SAndroid Build Coastguard Worker * including without limitation the rights to use, copy, modify, merge,
67*344aa361SAndroid Build Coastguard Worker * publish, distribute, sublicense, and/or sell copies of the Software,
68*344aa361SAndroid Build Coastguard Worker * and to permit persons to whom the Software is furnished to do so,
69*344aa361SAndroid Build Coastguard Worker * subject to the following conditions:
70*344aa361SAndroid Build Coastguard Worker *
71*344aa361SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be
72*344aa361SAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software.
73*344aa361SAndroid Build Coastguard Worker *
74*344aa361SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
75*344aa361SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
76*344aa361SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
77*344aa361SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
78*344aa361SAndroid Build Coastguard Worker * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
79*344aa361SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
80*344aa361SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
81*344aa361SAndroid Build Coastguard Worker */
82*344aa361SAndroid Build Coastguard Worker"""
83*344aa361SAndroid Build Coastguard Worker
84*344aa361SAndroid Build Coastguard Workerautogen_header = """
85*344aa361SAndroid Build Coastguard Worker/* This file is auto-generated. !!! DO NOT EDIT !!! */
86*344aa361SAndroid Build Coastguard Worker
87*344aa361SAndroid Build Coastguard Worker"""
88*344aa361SAndroid Build Coastguard Workerclang_format_off = "/* clang-format off */\n\n"
89*344aa361SAndroid Build Coastguard Worker
90*344aa361SAndroid Build Coastguard Worker
91*344aa361SAndroid Build Coastguard Workerincludes_header = "#include <%s>\n"
92*344aa361SAndroid Build Coastguard Worker
93*344aa361SAndroid Build Coastguard Worker
94*344aa361SAndroid Build Coastguard Workerclass Architecture:
95*344aa361SAndroid Build Coastguard Worker    def __init__(self, syscall_stub, footer=""):
96*344aa361SAndroid Build Coastguard Worker        self.syscall_stub = syscall_stub
97*344aa361SAndroid Build Coastguard Worker        self.footer = footer
98*344aa361SAndroid Build Coastguard Worker
99*344aa361SAndroid Build Coastguard Workerarch_dict = {
100*344aa361SAndroid Build Coastguard Worker    "arm" : Architecture (
101*344aa361SAndroid Build Coastguard Worker        syscall_stub = """
102*344aa361SAndroid Build Coastguard Worker.section .text._trusty_%(sys_fn)s
103*344aa361SAndroid Build Coastguard Worker.arm
104*344aa361SAndroid Build Coastguard Worker.balign 4
105*344aa361SAndroid Build Coastguard WorkerFUNCTION(_trusty_%(sys_fn)s)
106*344aa361SAndroid Build Coastguard Worker    ldr     r12, =__NR_%(sys_fn)s
107*344aa361SAndroid Build Coastguard Worker    svc     #0
108*344aa361SAndroid Build Coastguard Worker    bx      lr
109*344aa361SAndroid Build Coastguard Worker.size _trusty_%(sys_fn)s,.-_trusty_%(sys_fn)s
110*344aa361SAndroid Build Coastguard Worker"""),
111*344aa361SAndroid Build Coastguard Worker    "arm64" : Architecture (
112*344aa361SAndroid Build Coastguard Worker        # Note: for arm64 we're using "mov" to set the syscall number instead of
113*344aa361SAndroid Build Coastguard Worker        # "ldr" because of an assembler bug. The ldr instruction would always
114*344aa361SAndroid Build Coastguard Worker        # load from a constant pool instead of encoding the constant in the
115*344aa361SAndroid Build Coastguard Worker        # instruction. For arm64, "mov" should work for the range of constants
116*344aa361SAndroid Build Coastguard Worker        # we care about.
117*344aa361SAndroid Build Coastguard Worker        syscall_stub = """
118*344aa361SAndroid Build Coastguard Worker.section .text._trusty_%(sys_fn)s
119*344aa361SAndroid Build Coastguard Worker.balign 4
120*344aa361SAndroid Build Coastguard WorkerFUNCTION(_trusty_%(sys_fn)s)
121*344aa361SAndroid Build Coastguard Worker    mov     x12, #__NR_%(sys_fn)s
122*344aa361SAndroid Build Coastguard Worker    svc     #0
123*344aa361SAndroid Build Coastguard Worker    ret
124*344aa361SAndroid Build Coastguard Worker.size _trusty_%(sys_fn)s,.-_trusty_%(sys_fn)s
125*344aa361SAndroid Build Coastguard Worker""",
126*344aa361SAndroid Build Coastguard Worker        footer = """
127*344aa361SAndroid Build Coastguard WorkerSECTION_GNU_NOTE_PROPERTY_AARCH64_FEATURES(GNU_NOTE_FEATURE_AARCH64_BTI)
128*344aa361SAndroid Build Coastguard Worker"""),
129*344aa361SAndroid Build Coastguard Worker    "x86" : Architecture (
130*344aa361SAndroid Build Coastguard Worker        syscall_stub = """
131*344aa361SAndroid Build Coastguard Worker.global _trusty_%(sys_fn)s
132*344aa361SAndroid Build Coastguard Worker.type _trusty_%(sys_fn)s,STT_FUNC
133*344aa361SAndroid Build Coastguard Worker_trusty_%(sys_fn)s:
134*344aa361SAndroid Build Coastguard Worker    pushq %%r15
135*344aa361SAndroid Build Coastguard Worker    movq $__NR_%(sys_fn)s, %%rax
136*344aa361SAndroid Build Coastguard Worker    movq %%rcx, %%r10
137*344aa361SAndroid Build Coastguard Worker    movq %%rsp, %%r15
138*344aa361SAndroid Build Coastguard Worker    syscall
139*344aa361SAndroid Build Coastguard Worker    movq %%r15, %%rsp
140*344aa361SAndroid Build Coastguard Worker    popq %%r15
141*344aa361SAndroid Build Coastguard Worker    ret
142*344aa361SAndroid Build Coastguard Worker.size _trusty_%(sys_fn)s,.-_trusty_%(sys_fn)s
143*344aa361SAndroid Build Coastguard Worker"""),
144*344aa361SAndroid Build Coastguard Worker}
145*344aa361SAndroid Build Coastguard Worker
146*344aa361SAndroid Build Coastguard Workersyscall_define = "#define __NR_%(sys_fn)s\t\t%(sys_nr)s\n"
147*344aa361SAndroid Build Coastguard Worker
148*344aa361SAndroid Build Coastguard Workersyscall_proto = "%(sys_rt)s _trusty_%(sys_fn)s(%(sys_args)s);\n"
149*344aa361SAndroid Build Coastguard Worker
150*344aa361SAndroid Build Coastguard Workerasm_ifdef = "\n#ifndef ASSEMBLY\n"
151*344aa361SAndroid Build Coastguard Workerasm_endif = "\n#endif\n"
152*344aa361SAndroid Build Coastguard Worker
153*344aa361SAndroid Build Coastguard Workerbeg_cdecls = "\n__BEGIN_CDECLS\n"
154*344aa361SAndroid Build Coastguard Workerend_cdecls = "\n__END_CDECLS\n"
155*344aa361SAndroid Build Coastguard Worker
156*344aa361SAndroid Build Coastguard Workersyscall_def = "DEF_SYSCALL"
157*344aa361SAndroid Build Coastguard Worker
158*344aa361SAndroid Build Coastguard Workersyscall_pat = (
159*344aa361SAndroid Build Coastguard Worker    r'DEF_SYSCALL\s*\('
160*344aa361SAndroid Build Coastguard Worker    r'\s*(?P<sys_nr>\d+|0x[\da-fA-F]+)\s*,'      # syscall nr
161*344aa361SAndroid Build Coastguard Worker    r'\s*(?P<sys_fn>\w+)\s*,'                    # syscall name
162*344aa361SAndroid Build Coastguard Worker    r'\s*(?P<sys_rt>[\w*\s]+)\s*,'               # return type
163*344aa361SAndroid Build Coastguard Worker    r'\s*(?P<sys_nr_args>\d+)\s*'                # nr ags
164*344aa361SAndroid Build Coastguard Worker    r'('
165*344aa361SAndroid Build Coastguard Worker    r'\)\s*$|'                                   # empty arg list or
166*344aa361SAndroid Build Coastguard Worker    r',\s*(?P<sys_args>[\w,*\s]+)'               # arg list
167*344aa361SAndroid Build Coastguard Worker    r'\)\s*$'
168*344aa361SAndroid Build Coastguard Worker    r')')
169*344aa361SAndroid Build Coastguard Worker
170*344aa361SAndroid Build Coastguard Workersyscall_re = re.compile(syscall_pat)
171*344aa361SAndroid Build Coastguard Worker
172*344aa361SAndroid Build Coastguard Workersyscall_rust_proto = '    pub fn _trusty_%(sys_fn)s(%(rust_args)s) -> %(rust_rt)s;\n'
173*344aa361SAndroid Build Coastguard Workerbeg_rust = 'extern "C" {\n'
174*344aa361SAndroid Build Coastguard Workerend_rust = '}\n'
175*344aa361SAndroid Build Coastguard Worker
176*344aa361SAndroid Build Coastguard Workerdef fatal_parse_error(line, err_str):
177*344aa361SAndroid Build Coastguard Worker    sys.stderr.write("Error processing line %r:\n%s\n" % (line, err_str))
178*344aa361SAndroid Build Coastguard Worker    sys.exit(2)
179*344aa361SAndroid Build Coastguard Worker
180*344aa361SAndroid Build Coastguard Worker
181*344aa361SAndroid Build Coastguard WorkerBUILTIN_TYPES = set(['char', 'int', 'long', 'void'])
182*344aa361SAndroid Build Coastguard Workerfor i in [8, 16, 32, 64]:
183*344aa361SAndroid Build Coastguard Worker    BUILTIN_TYPES.add('int%d_t' % i)
184*344aa361SAndroid Build Coastguard Worker    BUILTIN_TYPES.add('uint%d_t' % i)
185*344aa361SAndroid Build Coastguard Worker
186*344aa361SAndroid Build Coastguard Workerdef reformat_c_to_rust(arg):
187*344aa361SAndroid Build Coastguard Worker    """Reformat a C-style argument into corresponding Rust argument
188*344aa361SAndroid Build Coastguard Worker
189*344aa361SAndroid Build Coastguard Worker    Raises:
190*344aa361SAndroid Build Coastguard Worker        NotImplementedError: If argument type was too complex to reformat.
191*344aa361SAndroid Build Coastguard Worker    """
192*344aa361SAndroid Build Coastguard Worker    m = re.match(r"(const )?(struct )?(.*?)\s*( ?\* ?)?$", arg)
193*344aa361SAndroid Build Coastguard Worker    is_const = m.group(1) is not None
194*344aa361SAndroid Build Coastguard Worker    ty = m.group(3)
195*344aa361SAndroid Build Coastguard Worker    is_ptr = m.group(4) is not None
196*344aa361SAndroid Build Coastguard Worker    rust_arg = ''
197*344aa361SAndroid Build Coastguard Worker    if '*' in ty:
198*344aa361SAndroid Build Coastguard Worker        raise NotImplementedError("Rust arg reformatting needs to be extended "
199*344aa361SAndroid Build Coastguard Worker                                  f"to handle double indirection in arg: {arg}")
200*344aa361SAndroid Build Coastguard Worker    if is_ptr:
201*344aa361SAndroid Build Coastguard Worker        rust_arg += '*%s ' % ('const' if is_const else 'mut')
202*344aa361SAndroid Build Coastguard Worker    rust_arg += ty
203*344aa361SAndroid Build Coastguard Worker    return rust_arg
204*344aa361SAndroid Build Coastguard Worker
205*344aa361SAndroid Build Coastguard Workerdef parse_check_def(line, struct_types):
206*344aa361SAndroid Build Coastguard Worker    """
207*344aa361SAndroid Build Coastguard Worker    Parse a DEF_SYSCALL line and check for errors
208*344aa361SAndroid Build Coastguard Worker    Returns various components from the line.
209*344aa361SAndroid Build Coastguard Worker    """
210*344aa361SAndroid Build Coastguard Worker
211*344aa361SAndroid Build Coastguard Worker    m = syscall_re.match(line)
212*344aa361SAndroid Build Coastguard Worker    if m is None:
213*344aa361SAndroid Build Coastguard Worker        fatal_parse_error(line, "Line did not match expected pattern.")
214*344aa361SAndroid Build Coastguard Worker    gd = m.groupdict()
215*344aa361SAndroid Build Coastguard Worker
216*344aa361SAndroid Build Coastguard Worker    sys_nr_args = int(gd['sys_nr_args'])
217*344aa361SAndroid Build Coastguard Worker    sys_args = gd['sys_args']
218*344aa361SAndroid Build Coastguard Worker    sys_args_list = re.split(r'\s*,\s*', sys_args) if sys_args else []
219*344aa361SAndroid Build Coastguard Worker
220*344aa361SAndroid Build Coastguard Worker    if sys_nr_args > 4:
221*344aa361SAndroid Build Coastguard Worker        fatal_parse_error(line, "Only syscalls with up to 4 arguments are "
222*344aa361SAndroid Build Coastguard Worker                          "supported.")
223*344aa361SAndroid Build Coastguard Worker
224*344aa361SAndroid Build Coastguard Worker    if sys_nr_args != len(sys_args_list):
225*344aa361SAndroid Build Coastguard Worker        fatal_parse_error(line, "Expected %d syscall arguments, got %d." %
226*344aa361SAndroid Build Coastguard Worker                          (sys_nr_args, len(sys_args_list)))
227*344aa361SAndroid Build Coastguard Worker
228*344aa361SAndroid Build Coastguard Worker    # Find struct types in the arguments.
229*344aa361SAndroid Build Coastguard Worker    for arg in sys_args_list:
230*344aa361SAndroid Build Coastguard Worker        # Remove arg name.
231*344aa361SAndroid Build Coastguard Worker        arg = re.sub(r"\s*\w+$", "", arg)
232*344aa361SAndroid Build Coastguard Worker        # Remove trailing pointer.
233*344aa361SAndroid Build Coastguard Worker        arg = re.sub(r"\s*\*$", "", arg)
234*344aa361SAndroid Build Coastguard Worker        # Remove initial const.
235*344aa361SAndroid Build Coastguard Worker        arg = re.sub(r"^const\s+", "", arg)
236*344aa361SAndroid Build Coastguard Worker        # Ignore the type if it's obviously not a struct.
237*344aa361SAndroid Build Coastguard Worker        if arg in BUILTIN_TYPES:
238*344aa361SAndroid Build Coastguard Worker            continue
239*344aa361SAndroid Build Coastguard Worker        # Require explicit struct declarations, because forward declaring
240*344aa361SAndroid Build Coastguard Worker        # typedefs is tricky.
241*344aa361SAndroid Build Coastguard Worker        if not arg.startswith("struct "):
242*344aa361SAndroid Build Coastguard Worker            fatal_parse_error(line, "Not an integer type or explicit struct "
243*344aa361SAndroid Build Coastguard Worker                              "type: %r. Don't use typedefs." % arg)
244*344aa361SAndroid Build Coastguard Worker        struct_types.add(arg)
245*344aa361SAndroid Build Coastguard Worker
246*344aa361SAndroid Build Coastguard Worker    # Reformat arguments into Rust syntax
247*344aa361SAndroid Build Coastguard Worker    rust_args = []
248*344aa361SAndroid Build Coastguard Worker    try:
249*344aa361SAndroid Build Coastguard Worker        for arg in sys_args_list:
250*344aa361SAndroid Build Coastguard Worker            m = re.match(r"(.*?)(\w+)$", arg)
251*344aa361SAndroid Build Coastguard Worker            ty = m.group(1)
252*344aa361SAndroid Build Coastguard Worker            name = m.group(2)
253*344aa361SAndroid Build Coastguard Worker            rust_args.append('%s: %s' % (name, reformat_c_to_rust(ty)))
254*344aa361SAndroid Build Coastguard Worker        gd['rust_args'] = ', '.join(rust_args)
255*344aa361SAndroid Build Coastguard Worker        gd['rust_rt'] = reformat_c_to_rust(gd['sys_rt'])
256*344aa361SAndroid Build Coastguard Worker    except NotImplementedError as err:
257*344aa361SAndroid Build Coastguard Worker        # reformat_c_to_rust failed to convert argument or return type
258*344aa361SAndroid Build Coastguard Worker        fatal_parse_error(line, err)
259*344aa361SAndroid Build Coastguard Worker
260*344aa361SAndroid Build Coastguard Worker    # In C, a forward declaration with an empty list of arguments has an
261*344aa361SAndroid Build Coastguard Worker    # unknown number of arguments. Set it to 'void' to declare there are
262*344aa361SAndroid Build Coastguard Worker    # zero arguments.
263*344aa361SAndroid Build Coastguard Worker    if sys_nr_args == 0:
264*344aa361SAndroid Build Coastguard Worker        gd['sys_args'] = 'void'
265*344aa361SAndroid Build Coastguard Worker
266*344aa361SAndroid Build Coastguard Worker    return gd
267*344aa361SAndroid Build Coastguard Worker
268*344aa361SAndroid Build Coastguard Worker
269*344aa361SAndroid Build Coastguard Workerdef process_table(table_file, std_file, stubs_file, rust_file, verify, arch):
270*344aa361SAndroid Build Coastguard Worker    """
271*344aa361SAndroid Build Coastguard Worker    Process a syscall table and generate:
272*344aa361SAndroid Build Coastguard Worker    1. A sycall stubs file
273*344aa361SAndroid Build Coastguard Worker    2. A trusty_std.h header file with syscall definitions
274*344aa361SAndroid Build Coastguard Worker       and function prototypes
275*344aa361SAndroid Build Coastguard Worker    """
276*344aa361SAndroid Build Coastguard Worker    define_lines = ""
277*344aa361SAndroid Build Coastguard Worker    proto_lines = "\n"
278*344aa361SAndroid Build Coastguard Worker    stub_lines = ""
279*344aa361SAndroid Build Coastguard Worker    rust_lines = ""
280*344aa361SAndroid Build Coastguard Worker
281*344aa361SAndroid Build Coastguard Worker    struct_types = set()
282*344aa361SAndroid Build Coastguard Worker
283*344aa361SAndroid Build Coastguard Worker    tbl = open(table_file, "r")
284*344aa361SAndroid Build Coastguard Worker    for line in tbl:
285*344aa361SAndroid Build Coastguard Worker        line = line.strip()
286*344aa361SAndroid Build Coastguard Worker
287*344aa361SAndroid Build Coastguard Worker        # skip all lines that don't start with a syscall definition
288*344aa361SAndroid Build Coastguard Worker        # multi-line defintions are not supported.
289*344aa361SAndroid Build Coastguard Worker        if not line.startswith(syscall_def):
290*344aa361SAndroid Build Coastguard Worker            continue
291*344aa361SAndroid Build Coastguard Worker
292*344aa361SAndroid Build Coastguard Worker        params = parse_check_def(line, struct_types)
293*344aa361SAndroid Build Coastguard Worker
294*344aa361SAndroid Build Coastguard Worker        if not verify:
295*344aa361SAndroid Build Coastguard Worker            define_lines += syscall_define % params
296*344aa361SAndroid Build Coastguard Worker            proto_lines += syscall_proto % params
297*344aa361SAndroid Build Coastguard Worker            stub_lines += arch.syscall_stub % params
298*344aa361SAndroid Build Coastguard Worker            rust_lines += syscall_rust_proto % params
299*344aa361SAndroid Build Coastguard Worker
300*344aa361SAndroid Build Coastguard Worker
301*344aa361SAndroid Build Coastguard Worker    tbl.close()
302*344aa361SAndroid Build Coastguard Worker
303*344aa361SAndroid Build Coastguard Worker    if verify:
304*344aa361SAndroid Build Coastguard Worker        return
305*344aa361SAndroid Build Coastguard Worker
306*344aa361SAndroid Build Coastguard Worker    if std_file is not None:
307*344aa361SAndroid Build Coastguard Worker        with open(std_file, "w") as std:
308*344aa361SAndroid Build Coastguard Worker            std.writelines(copyright_header + autogen_header)
309*344aa361SAndroid Build Coastguard Worker            std.writelines(clang_format_off)
310*344aa361SAndroid Build Coastguard Worker            std.writelines(define_lines + asm_ifdef)
311*344aa361SAndroid Build Coastguard Worker            std.writelines("\n")
312*344aa361SAndroid Build Coastguard Worker            std.writelines(includes_header % "lk/compiler.h")
313*344aa361SAndroid Build Coastguard Worker            std.writelines(includes_header % "stdint.h")
314*344aa361SAndroid Build Coastguard Worker            std.writelines(beg_cdecls)
315*344aa361SAndroid Build Coastguard Worker            # Forward declare the struct types.
316*344aa361SAndroid Build Coastguard Worker            std.writelines("\n")
317*344aa361SAndroid Build Coastguard Worker            std.writelines([t + ";\n" for t in sorted(struct_types)])
318*344aa361SAndroid Build Coastguard Worker            std.writelines(proto_lines + end_cdecls + asm_endif)
319*344aa361SAndroid Build Coastguard Worker
320*344aa361SAndroid Build Coastguard Worker    if stubs_file is not None:
321*344aa361SAndroid Build Coastguard Worker        with open(stubs_file, "w") as stubs:
322*344aa361SAndroid Build Coastguard Worker            stubs.writelines(copyright_header + autogen_header)
323*344aa361SAndroid Build Coastguard Worker            stubs.writelines(includes_header % "lk/asm.h")
324*344aa361SAndroid Build Coastguard Worker            stubs.writelines(includes_header % "trusty_syscalls.h")
325*344aa361SAndroid Build Coastguard Worker            stubs.writelines(stub_lines)
326*344aa361SAndroid Build Coastguard Worker            stubs.writelines(arch.footer)
327*344aa361SAndroid Build Coastguard Worker
328*344aa361SAndroid Build Coastguard Worker    if rust_file is not None:
329*344aa361SAndroid Build Coastguard Worker        with open(rust_file, "w") as rust:
330*344aa361SAndroid Build Coastguard Worker            rust.writelines(copyright_header + autogen_header)
331*344aa361SAndroid Build Coastguard Worker            rust.writelines(beg_rust)
332*344aa361SAndroid Build Coastguard Worker            rust.writelines(rust_lines)
333*344aa361SAndroid Build Coastguard Worker            rust.writelines(end_rust)
334*344aa361SAndroid Build Coastguard Worker
335*344aa361SAndroid Build Coastguard Worker
336*344aa361SAndroid Build Coastguard Workerdef main():
337*344aa361SAndroid Build Coastguard Worker
338*344aa361SAndroid Build Coastguard Worker    usage = "usage:  %prog [options] <syscall-table>"
339*344aa361SAndroid Build Coastguard Worker
340*344aa361SAndroid Build Coastguard Worker    op = OptionParser(usage=usage)
341*344aa361SAndroid Build Coastguard Worker    op.add_option("-v", "--verify", action="store_true",
342*344aa361SAndroid Build Coastguard Worker            dest="verify", default=False,
343*344aa361SAndroid Build Coastguard Worker            help="Check syscall table. Do not generate any files.")
344*344aa361SAndroid Build Coastguard Worker    op.add_option("-d", "--std-header", type="string",
345*344aa361SAndroid Build Coastguard Worker            dest="std_file", default=None,
346*344aa361SAndroid Build Coastguard Worker            help="path to syscall defintions header file.")
347*344aa361SAndroid Build Coastguard Worker    op.add_option("-s", "--stubs-file", type="string",
348*344aa361SAndroid Build Coastguard Worker            dest="stub_file", default=None,
349*344aa361SAndroid Build Coastguard Worker            help="path to syscall assembly stubs file.")
350*344aa361SAndroid Build Coastguard Worker    op.add_option("-r", "--rust-file", type="string",
351*344aa361SAndroid Build Coastguard Worker            dest="rust_file", default=None,
352*344aa361SAndroid Build Coastguard Worker            help="path to rust declarations file")
353*344aa361SAndroid Build Coastguard Worker    op.add_option("-a", "--arch", type="string",
354*344aa361SAndroid Build Coastguard Worker            dest="arch", default="arm",
355*344aa361SAndroid Build Coastguard Worker            help="arch of stub assembly files: " + str(arch_dict.keys()))
356*344aa361SAndroid Build Coastguard Worker
357*344aa361SAndroid Build Coastguard Worker    (opts, args) = op.parse_args()
358*344aa361SAndroid Build Coastguard Worker
359*344aa361SAndroid Build Coastguard Worker    if len(args) == 0:
360*344aa361SAndroid Build Coastguard Worker        op.print_help()
361*344aa361SAndroid Build Coastguard Worker        sys.exit(1)
362*344aa361SAndroid Build Coastguard Worker
363*344aa361SAndroid Build Coastguard Worker    if not opts.verify:
364*344aa361SAndroid Build Coastguard Worker        if opts.std_file is None and opts.stub_file is None:
365*344aa361SAndroid Build Coastguard Worker            op.print_help()
366*344aa361SAndroid Build Coastguard Worker            sys.exit(1)
367*344aa361SAndroid Build Coastguard Worker
368*344aa361SAndroid Build Coastguard Worker    process_table(args[0], opts.std_file, opts.stub_file, opts.rust_file,
369*344aa361SAndroid Build Coastguard Worker                  opts.verify, arch_dict[opts.arch])
370*344aa361SAndroid Build Coastguard Worker
371*344aa361SAndroid Build Coastguard Worker
372*344aa361SAndroid Build Coastguard Workerif __name__ == '__main__':
373*344aa361SAndroid Build Coastguard Worker    main()
374