blob: b3a4558a57fa0920ff80d42d34f3b8472e73d7c5 [file] [log] [blame]
Andrew Boiefa94ee72017-09-28 16:54:35 -07001#!/usr/bin/env python3
2#
3# Copyright (c) 2017 Intel Corporation
4#
5# SPDX-License-Identifier: Apache-2.0
6
Andrew Boiec78c5e62019-03-11 14:45:43 -07007"""
8Script to generate system call invocation macros
9
10This script parses the system call metadata JSON file emitted by
11parse_syscalls.py to create several files:
12
13- A file containing weak aliases of any potentially unimplemented system calls,
14 as well as the system call dispatch table, which maps system call type IDs
15 to their handler functions.
16
Ruslan Mstoi84822e32020-05-26 16:10:21 +030017- A header file defining the system call type IDs, as well as function
Andrew Boiec78c5e62019-03-11 14:45:43 -070018 prototypes for all system call handler functions.
19
20- A directory containing header files. Each header corresponds to a header
21 that was identified as containing system call declarations. These
22 generated headers contain the inline invocation functions for each system
23 call in that header.
24"""
25
Andrew Boiefa94ee72017-09-28 16:54:35 -070026import sys
27import re
28import argparse
29import os
Sebastian Bøe13a68402017-11-20 13:03:55 +010030import json
Andrew Boiefa94ee72017-09-28 16:54:35 -070031
Kumar Galaa1b77fd2020-05-27 11:26:57 -050032types64 = ["int64_t", "uint64_t"]
Andy Ross65649742019-08-06 13:34:31 -070033
34# The kernel linkage is complicated. These functions from
35# userspace_handlers.c are present in the kernel .a library after
36# userspace.c, which contains the weak fallbacks defined here. So the
37# linker finds the weak one first and stops searching, and thus won't
38# see the real implementation which should override. Yet changing the
39# order runs afoul of a comment in CMakeLists.txt that the order is
40# critical. These are core syscalls that won't ever be unconfigured,
41# just disable the fallback mechanism as a simple workaround.
Marc Herbertf9870292019-09-19 10:30:43 -070042noweak = ["z_mrsh_k_object_release",
43 "z_mrsh_k_object_access_grant",
44 "z_mrsh_k_object_alloc"]
Andy Ross65649742019-08-06 13:34:31 -070045
Andrew Boiefa94ee72017-09-28 16:54:35 -070046table_template = """/* auto-generated by gen_syscalls.py, don't edit */
47
Paul Sokolovsky94620bd2017-10-01 23:47:43 +030048/* Weak handler functions that get replaced by the real ones unless a system
49 * call is not implemented due to kernel configuration.
Andrew Boiefa94ee72017-09-28 16:54:35 -070050 */
51%s
52
53const _k_syscall_handler_t _k_syscall_table[K_SYSCALL_LIMIT] = {
54\t%s
55};
56"""
57
58list_template = """
59/* auto-generated by gen_syscalls.py, don't edit */
Flavio Ceolina7fffa92018-09-13 15:06:35 -070060#ifndef ZEPHYR_SYSCALL_LIST_H
61#define ZEPHYR_SYSCALL_LIST_H
Andrew Boiefa94ee72017-09-28 16:54:35 -070062
Sebastian Bøe1a409902018-08-10 15:23:00 +020063%s
64
Andrew Boiefa94ee72017-09-28 16:54:35 -070065#ifndef _ASMLANGUAGE
66
Andrew Boie800b35f2019-11-05 09:27:18 -080067#include <stdint.h>
Andrew Boiec67eb562018-03-26 13:44:44 -070068
Andrew Boiefa94ee72017-09-28 16:54:35 -070069#endif /* _ASMLANGUAGE */
70
Flavio Ceolina7fffa92018-09-13 15:06:35 -070071#endif /* ZEPHYR_SYSCALL_LIST_H */
Andrew Boiefa94ee72017-09-28 16:54:35 -070072"""
73
74syscall_template = """
75/* auto-generated by gen_syscalls.py, don't edit */
Andy Ross65649742019-08-06 13:34:31 -070076%s
Andrew Boiefa94ee72017-09-28 16:54:35 -070077
78#ifndef _ASMLANGUAGE
79
80#include <syscall_list.h>
Flavio Ceolinf4adf102019-12-03 09:09:07 -080081#include <syscall.h>
Andrew Boiefa94ee72017-09-28 16:54:35 -070082
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +090083#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
Andy Ross65649742019-08-06 13:34:31 -070084#pragma GCC diagnostic push
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +090085#endif
86
87#ifdef __GNUC__
Andy Ross65649742019-08-06 13:34:31 -070088#pragma GCC diagnostic ignored "-Wstrict-aliasing"
Daniel Leung82ec1c02021-06-01 13:19:51 -070089#pragma GCC diagnostic ignored "-Warray-bounds"
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +090090#endif
Andy Ross65649742019-08-06 13:34:31 -070091
Andrew Boiefa94ee72017-09-28 16:54:35 -070092#ifdef __cplusplus
93extern "C" {
94#endif
95
96%s
97
98#ifdef __cplusplus
99}
100#endif
101
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +0900102#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
Andy Ross65649742019-08-06 13:34:31 -0700103#pragma GCC diagnostic pop
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +0900104#endif
Andy Ross65649742019-08-06 13:34:31 -0700105
Andrew Boiefa94ee72017-09-28 16:54:35 -0700106#endif
Andy Ross65649742019-08-06 13:34:31 -0700107#endif /* include guard */
Andrew Boiefa94ee72017-09-28 16:54:35 -0700108"""
109
110handler_template = """
Andrew Boie800b35f2019-11-05 09:27:18 -0800111extern uintptr_t z_hdlr_%s(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
112 uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, void *ssf);
Andrew Boiefa94ee72017-09-28 16:54:35 -0700113"""
114
115weak_template = """
Leandro Pereiraa1ae8452018-03-06 15:08:55 -0800116__weak ALIAS_OF(handler_no_syscall)
Andrew Boie800b35f2019-11-05 09:27:18 -0800117uintptr_t %s(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
118 uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, void *ssf);
Andrew Boiefa94ee72017-09-28 16:54:35 -0700119"""
120
121
Andrew Boiea698e842018-07-23 17:27:57 -0700122typename_regex = re.compile(r'(.*?)([A-Za-z0-9_]+)$')
123
124
125class SyscallParseException(Exception):
126 pass
127
128
129def typename_split(item):
130 if "[" in item:
131 raise SyscallParseException(
132 "Please pass arrays to syscalls as pointers, unable to process '%s'" %
133 item)
134
135 if "(" in item:
136 raise SyscallParseException(
137 "Please use typedefs for function pointers")
138
139 mo = typename_regex.match(item)
140 if not mo:
141 raise SyscallParseException("Malformed system call invocation")
142
143 m = mo.groups()
144 return (m[0].strip(), m[1])
145
Andy Ross65649742019-08-06 13:34:31 -0700146def need_split(argtype):
Andrew Boie9ff64bb2019-11-05 09:39:05 -0800147 return (not args.long_registers) and (argtype in types64)
Andy Ross65649742019-08-06 13:34:31 -0700148
149# Note: "lo" and "hi" are named in little endian conventions,
150# but it doesn't matter as long as they are consistently
151# generated.
152def union_decl(type):
Andrew Boie800b35f2019-11-05 09:27:18 -0800153 return "union { struct { uintptr_t lo, hi; } split; %s val; }" % type
Andy Ross65649742019-08-06 13:34:31 -0700154
155def wrapper_defs(func_name, func_type, args):
Andrew Boie9ff64bb2019-11-05 09:39:05 -0800156 ret64 = need_split(func_type)
Andy Ross65649742019-08-06 13:34:31 -0700157 mrsh_args = [] # List of rvalue expressions for the marshalled invocation
158 split_args = []
159 nsplit = 0
Ulf Magnussona0136b92019-09-13 15:47:16 +0200160 for argtype, argname in args:
Andy Ross65649742019-08-06 13:34:31 -0700161 if need_split(argtype):
162 split_args.append((argtype, argname))
163 mrsh_args.append("parm%d.split.lo" % nsplit)
164 mrsh_args.append("parm%d.split.hi" % nsplit)
165 nsplit += 1
166 else:
Andrew Boie800b35f2019-11-05 09:27:18 -0800167 mrsh_args.append("*(uintptr_t *)&" + argname)
Andy Ross65649742019-08-06 13:34:31 -0700168
169 if ret64:
Andrew Boie800b35f2019-11-05 09:27:18 -0800170 mrsh_args.append("(uintptr_t)&ret64")
Andy Ross65649742019-08-06 13:34:31 -0700171
James Harris074dbb92021-03-04 08:21:14 -0800172 decl_arglist = ", ".join([" ".join(argrec) for argrec in args]) or "void"
Andy Ross65649742019-08-06 13:34:31 -0700173
174 wrap = "extern %s z_impl_%s(%s);\n" % (func_type, func_name, decl_arglist)
175 wrap += "static inline %s %s(%s)\n" % (func_type, func_name, decl_arglist)
176 wrap += "{\n"
177 wrap += "#ifdef CONFIG_USERSPACE\n"
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500178 wrap += ("\t" + "uint64_t ret64;\n") if ret64 else ""
Andy Ross65649742019-08-06 13:34:31 -0700179 wrap += "\t" + "if (z_syscall_trap()) {\n"
180
181 for parmnum, rec in enumerate(split_args):
182 (argtype, argname) = rec
183 wrap += "\t\t%s parm%d;\n" % (union_decl(argtype), parmnum)
184 wrap += "\t\t" + "parm%d.val = %s;\n" % (parmnum, argname)
185
186 if len(mrsh_args) > 6:
Andrew Boie800b35f2019-11-05 09:27:18 -0800187 wrap += "\t\t" + "uintptr_t more[] = {\n"
Andy Ross65649742019-08-06 13:34:31 -0700188 wrap += "\t\t\t" + (",\n\t\t\t".join(mrsh_args[5:])) + "\n"
189 wrap += "\t\t" + "};\n"
Andrew Boie800b35f2019-11-05 09:27:18 -0800190 mrsh_args[5:] = ["(uintptr_t) &more"]
Andy Ross65649742019-08-06 13:34:31 -0700191
192 syscall_id = "K_SYSCALL_" + func_name.upper()
Andrew Boie4f77c2a2019-11-07 12:43:29 -0800193 invoke = ("arch_syscall_invoke%d(%s)"
Andy Ross65649742019-08-06 13:34:31 -0700194 % (len(mrsh_args),
195 ", ".join(mrsh_args + [syscall_id])))
196
Daniel Leung4725db82021-05-26 10:26:51 -0700197 # Coverity does not understand syscall mechanism
198 # and will already complain when any function argument
199 # is not of exact size as uintptr_t. So tell Coverity
200 # to ignore this particular rule here.
201 wrap += "\t\t/* coverity[OVERRUN] */\n"
202
Andy Ross65649742019-08-06 13:34:31 -0700203 if ret64:
204 wrap += "\t\t" + "(void)%s;\n" % invoke
205 wrap += "\t\t" + "return (%s)ret64;\n" % func_type
206 elif func_type == "void":
207 wrap += "\t\t" + "%s;\n" % invoke
Ulf Magnussona0136b92019-09-13 15:47:16 +0200208 wrap += "\t\t" + "return;\n"
Andy Ross65649742019-08-06 13:34:31 -0700209 else:
210 wrap += "\t\t" + "return (%s) %s;\n" % (func_type, invoke)
211
212 wrap += "\t" + "}\n"
213 wrap += "#endif\n"
214
215 # Otherwise fall through to direct invocation of the impl func.
216 # Note the compiler barrier: that is required to prevent code from
217 # the impl call from being hoisted above the check for user
218 # context.
219 impl_arglist = ", ".join([argrec[1] for argrec in args])
220 impl_call = "z_impl_%s(%s)" % (func_name, impl_arglist)
221 wrap += "\t" + "compiler_barrier();\n"
222 wrap += "\t" + "%s%s;\n" % ("return " if func_type != "void" else "",
223 impl_call)
224
225 wrap += "}\n"
226
227 return wrap
228
229# Returns an expression for the specified (zero-indexed!) marshalled
230# parameter to a syscall, with handling for a final "more" parameter.
231def mrsh_rval(mrsh_num, total):
232 if mrsh_num < 5 or total <= 6:
233 return "arg%d" % mrsh_num
234 else:
Andrew Boie800b35f2019-11-05 09:27:18 -0800235 return "(((uintptr_t *)more)[%d])" % (mrsh_num - 5)
Andy Ross65649742019-08-06 13:34:31 -0700236
237def marshall_defs(func_name, func_type, args):
238 mrsh_name = "z_mrsh_" + func_name
239
Andrew Boie800b35f2019-11-05 09:27:18 -0800240 nmrsh = 0 # number of marshalled uintptr_t parameter
Andy Ross65649742019-08-06 13:34:31 -0700241 vrfy_parms = [] # list of (arg_num, mrsh_or_parm_num, bool_is_split)
242 split_parms = [] # list of a (arg_num, mrsh_num) for each split
Ulf Magnussona0136b92019-09-13 15:47:16 +0200243 for i, (argtype, _) in enumerate(args):
Andy Ross65649742019-08-06 13:34:31 -0700244 if need_split(argtype):
245 vrfy_parms.append((i, len(split_parms), True))
246 split_parms.append((i, nmrsh))
247 nmrsh += 2
248 else:
249 vrfy_parms.append((i, nmrsh, False))
250 nmrsh += 1
251
252 # Final argument for a 64 bit return value?
Andrew Boie9ff64bb2019-11-05 09:39:05 -0800253 if need_split(func_type):
Andy Ross65649742019-08-06 13:34:31 -0700254 nmrsh += 1
255
256 decl_arglist = ", ".join([" ".join(argrec) for argrec in args])
257 mrsh = "extern %s z_vrfy_%s(%s);\n" % (func_type, func_name, decl_arglist)
258
Andrew Boie800b35f2019-11-05 09:27:18 -0800259 mrsh += "uintptr_t %s(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2,\n" % mrsh_name
Andy Ross65649742019-08-06 13:34:31 -0700260 if nmrsh <= 6:
Andrew Boie800b35f2019-11-05 09:27:18 -0800261 mrsh += "\t\t" + "uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, void *ssf)\n"
Andy Ross65649742019-08-06 13:34:31 -0700262 else:
Andrew Boie800b35f2019-11-05 09:27:18 -0800263 mrsh += "\t\t" + "uintptr_t arg3, uintptr_t arg4, void *more, void *ssf)\n"
Andy Ross65649742019-08-06 13:34:31 -0700264 mrsh += "{\n"
Andy Ross7353c7f2020-02-06 13:39:03 -0800265 mrsh += "\t" + "_current->syscall_frame = ssf;\n"
Andy Ross65649742019-08-06 13:34:31 -0700266
267 for unused_arg in range(nmrsh, 6):
268 mrsh += "\t(void) arg%d;\t/* unused */\n" % unused_arg
269
270 if nmrsh > 6:
271 mrsh += ("\tZ_OOPS(Z_SYSCALL_MEMORY_READ(more, "
Andrew Boie800b35f2019-11-05 09:27:18 -0800272 + str(nmrsh - 6) + " * sizeof(uintptr_t)));\n")
Andy Ross65649742019-08-06 13:34:31 -0700273
274 for i, split_rec in enumerate(split_parms):
275 arg_num, mrsh_num = split_rec
Ulf Magnussona0136b92019-09-13 15:47:16 +0200276 arg_type = args[arg_num][0]
277 mrsh += "\t%s parm%d;\n" % (union_decl(arg_type), i)
Andy Ross65649742019-08-06 13:34:31 -0700278 mrsh += "\t" + "parm%d.split.lo = %s;\n" % (i, mrsh_rval(mrsh_num,
279 nmrsh))
280 mrsh += "\t" + "parm%d.split.hi = %s;\n" % (i, mrsh_rval(mrsh_num + 1,
281 nmrsh))
282 # Finally, invoke the verify function
283 out_args = []
284 for i, argn, is_split in vrfy_parms:
285 if is_split:
286 out_args.append("parm%d.val" % argn)
287 else:
288 out_args.append("*(%s*)&%s" % (args[i][0], mrsh_rval(argn, nmrsh)))
289
290 vrfy_call = "z_vrfy_%s(%s)\n" % (func_name, ", ".join(out_args))
291
292 if func_type == "void":
293 mrsh += "\t" + "%s;\n" % vrfy_call
Andrew Boie378024c2020-05-28 11:48:54 -0700294 mrsh += "\t" + "_current->syscall_frame = NULL;\n"
Andy Ross65649742019-08-06 13:34:31 -0700295 mrsh += "\t" + "return 0;\n"
296 else:
297 mrsh += "\t" + "%s ret = %s;\n" % (func_type, vrfy_call)
Andrew Boie378024c2020-05-28 11:48:54 -0700298
Andrew Boie9ff64bb2019-11-05 09:39:05 -0800299 if need_split(func_type):
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500300 ptr = "((uint64_t *)%s)" % mrsh_rval(nmrsh - 1, nmrsh)
Andy Ross65649742019-08-06 13:34:31 -0700301 mrsh += "\t" + "Z_OOPS(Z_SYSCALL_MEMORY_WRITE(%s, 8));\n" % ptr
302 mrsh += "\t" + "*%s = ret;\n" % ptr
Andrew Boie378024c2020-05-28 11:48:54 -0700303 mrsh += "\t" + "_current->syscall_frame = NULL;\n"
Andy Ross65649742019-08-06 13:34:31 -0700304 mrsh += "\t" + "return 0;\n"
305 else:
Andrew Boie378024c2020-05-28 11:48:54 -0700306 mrsh += "\t" + "_current->syscall_frame = NULL;\n"
Andrew Boie800b35f2019-11-05 09:27:18 -0800307 mrsh += "\t" + "return (uintptr_t) ret;\n"
Andy Ross65649742019-08-06 13:34:31 -0700308
309 mrsh += "}\n"
310
311 return mrsh, mrsh_name
Andrew Boiea698e842018-07-23 17:27:57 -0700312
313def analyze_fn(match_group):
314 func, args = match_group
315
316 try:
317 if args == "void":
318 args = []
319 else:
320 args = [typename_split(a.strip()) for a in args.split(",")]
321
322 func_type, func_name = typename_split(func)
323 except SyscallParseException:
324 sys.stderr.write("In declaration of %s\n" % func)
325 raise
326
327 sys_id = "K_SYSCALL_" + func_name.upper()
328
Andy Ross65649742019-08-06 13:34:31 -0700329 marshaller = None
330 marshaller, handler = marshall_defs(func_name, func_type, args)
331 invocation = wrapper_defs(func_name, func_type, args)
Andrew Boiea698e842018-07-23 17:27:57 -0700332
333 # Entry in _k_syscall_table
334 table_entry = "[%s] = %s" % (sys_id, handler)
335
Andy Ross65649742019-08-06 13:34:31 -0700336 return (handler, invocation, marshaller, sys_id, table_entry)
Andrew Boiea698e842018-07-23 17:27:57 -0700337
Andrew Boiefa94ee72017-09-28 16:54:35 -0700338def parse_args():
339 global args
Anas Nashif72565532017-12-12 08:19:25 -0500340 parser = argparse.ArgumentParser(
341 description=__doc__,
342 formatter_class=argparse.RawDescriptionHelpFormatter)
Andrew Boiefa94ee72017-09-28 16:54:35 -0700343
Sebastian Bøe13a68402017-11-20 13:03:55 +0100344 parser.add_argument("-i", "--json-file", required=True,
Anas Nashif72565532017-12-12 08:19:25 -0500345 help="Read syscall information from json file")
Andrew Boiefa94ee72017-09-28 16:54:35 -0700346 parser.add_argument("-d", "--syscall-dispatch", required=True,
Anas Nashif72565532017-12-12 08:19:25 -0500347 help="output C system call dispatch table file")
Andrew Boie353acf42018-07-23 18:10:15 -0700348 parser.add_argument("-l", "--syscall-list", required=True,
349 help="output C system call list header")
Andrew Boiefa94ee72017-09-28 16:54:35 -0700350 parser.add_argument("-o", "--base-output", required=True,
Anas Nashif72565532017-12-12 08:19:25 -0500351 help="Base output directory for syscall macro headers")
Andy Ross65649742019-08-06 13:34:31 -0700352 parser.add_argument("-s", "--split-type", action="append",
Andrew Boie9ff64bb2019-11-05 09:39:05 -0800353 help="A long type that must be split/marshalled on 32-bit systems")
354 parser.add_argument("-x", "--long-registers", action="store_true",
355 help="Indicates we are on system with 64-bit registers")
Andrew Boiefa94ee72017-09-28 16:54:35 -0700356 args = parser.parse_args()
357
358
359def main():
360 parse_args()
361
Ulf Magnussona0136b92019-09-13 15:47:16 +0200362 if args.split_type is not None:
Andy Ross65649742019-08-06 13:34:31 -0700363 for t in args.split_type:
364 types64.append(t)
365
Sebastian Bøe13a68402017-11-20 13:03:55 +0100366 with open(args.json_file, 'r') as fd:
367 syscalls = json.load(fd)
368
Andrew Boiefa94ee72017-09-28 16:54:35 -0700369 invocations = {}
Andy Ross65649742019-08-06 13:34:31 -0700370 mrsh_defs = {}
371 mrsh_includes = {}
Andrew Boiefa94ee72017-09-28 16:54:35 -0700372 ids = []
373 table_entries = []
374 handlers = []
375
Andrew Boiea698e842018-07-23 17:27:57 -0700376 for match_group, fn in syscalls:
Andy Ross65649742019-08-06 13:34:31 -0700377 handler, inv, mrsh, sys_id, entry = analyze_fn(match_group)
Andrew Boiea698e842018-07-23 17:27:57 -0700378
Andrew Boiefa94ee72017-09-28 16:54:35 -0700379 if fn not in invocations:
380 invocations[fn] = []
381
382 invocations[fn].append(inv)
383 ids.append(sys_id)
384 table_entries.append(entry)
385 handlers.append(handler)
386
Andy Ross65649742019-08-06 13:34:31 -0700387 if mrsh:
388 syscall = typename_split(match_group[0])[1]
389 mrsh_defs[syscall] = mrsh
390 mrsh_includes[syscall] = "#include <syscalls/%s>" % fn
391
Andrew Boiefa94ee72017-09-28 16:54:35 -0700392 with open(args.syscall_dispatch, "w") as fp:
Leandro Pereiraa1ae8452018-03-06 15:08:55 -0800393 table_entries.append("[K_SYSCALL_BAD] = handler_bad_syscall")
Andrew Boiefa94ee72017-09-28 16:54:35 -0700394
Andy Ross65649742019-08-06 13:34:31 -0700395 weak_defines = "".join([weak_template % name
396 for name in handlers
397 if not name in noweak])
Andrew Boiefa94ee72017-09-28 16:54:35 -0700398
Andy Ross65649742019-08-06 13:34:31 -0700399 # The "noweak" ones just get a regular declaration
Andrew Boie800b35f2019-11-05 09:27:18 -0800400 weak_defines += "\n".join(["extern uintptr_t %s(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, void *ssf);"
Andy Ross65649742019-08-06 13:34:31 -0700401 % s for s in noweak])
402
403 fp.write(table_template % (weak_defines,
404 ",\n\t".join(table_entries)))
Andrew Boiefa94ee72017-09-28 16:54:35 -0700405
406 # Listing header emitted to stdout
407 ids.sort()
408 ids.extend(["K_SYSCALL_BAD", "K_SYSCALL_LIMIT"])
Sebastian Bøe1a409902018-08-10 15:23:00 +0200409
410 ids_as_defines = ""
411 for i, item in enumerate(ids):
412 ids_as_defines += "#define {} {}\n".format(item, i)
413
Andrew Boie353acf42018-07-23 18:10:15 -0700414 with open(args.syscall_list, "w") as fp:
Andy Ross65649742019-08-06 13:34:31 -0700415 fp.write(list_template % ids_as_defines)
Andrew Boiefa94ee72017-09-28 16:54:35 -0700416
417 os.makedirs(args.base_output, exist_ok=True)
418 for fn, invo_list in invocations.items():
419 out_fn = os.path.join(args.base_output, fn)
420
Andy Ross65649742019-08-06 13:34:31 -0700421 ig = re.sub("[^a-zA-Z0-9]", "_", "Z_INCLUDE_SYSCALLS_" + fn).upper()
422 include_guard = "#ifndef %s\n#define %s\n" % (ig, ig)
423 header = syscall_template % (include_guard, "\n\n".join(invo_list))
Andrew Boiefa94ee72017-09-28 16:54:35 -0700424
Andrew Boiefa94ee72017-09-28 16:54:35 -0700425 with open(out_fn, "w") as fp:
426 fp.write(header)
427
Andy Ross65649742019-08-06 13:34:31 -0700428 # Likewise emit _mrsh.c files for syscall inclusion
429 for fn in mrsh_defs:
430 mrsh_fn = os.path.join(args.base_output, fn + "_mrsh.c")
431
432 with open(mrsh_fn, "w") as fp:
433 fp.write("/* auto-generated by gen_syscalls.py, don't edit */\n")
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +0900434 fp.write("#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)\n")
Andy Ross65649742019-08-06 13:34:31 -0700435 fp.write("#pragma GCC diagnostic push\n")
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +0900436 fp.write("#endif\n")
437 fp.write("#ifdef __GNUC__\n")
Andy Ross65649742019-08-06 13:34:31 -0700438 fp.write("#pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n")
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +0900439 fp.write("#endif\n")
Andy Ross65649742019-08-06 13:34:31 -0700440 fp.write(mrsh_includes[fn] + "\n")
441 fp.write("\n")
442 fp.write(mrsh_defs[fn] + "\n")
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +0900443 fp.write("#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)\n")
Andy Ross65649742019-08-06 13:34:31 -0700444 fp.write("#pragma GCC diagnostic pop\n")
Stephanos Ioannidis2a1c6252019-09-26 13:57:59 +0900445 fp.write("#endif\n")
Anas Nashif72565532017-12-12 08:19:25 -0500446
Andrew Boiefa94ee72017-09-28 16:54:35 -0700447if __name__ == "__main__":
448 main()