diff --git a/CMakeLists.txt b/CMakeLists.txt index d8f2801d01..2d802277a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -759,6 +759,7 @@ add_custom_command(OUTPUT include/generated/syscall_dispatch.c ${syscall_list_h} --json-file ${syscalls_json} # Read this file --base-output include/generated/syscalls # Write to this dir --syscall-dispatch include/generated/syscall_dispatch.c # Write this file + --syscall-export-llext include/generated/syscall_export_llext.c --syscall-list ${syscall_list_h} $<$:--gen-mrsh-files> ${SYSCALL_LONG_REGISTERS_ARG} diff --git a/scripts/build/gen_syscalls.py b/scripts/build/gen_syscalls.py index 3741707f80..8755f3c649 100755 --- a/scripts/build/gen_syscalls.py +++ b/scripts/build/gen_syscalls.py @@ -62,8 +62,6 @@ table_template = """/* auto-generated by gen_syscalls.py, don't edit */ const _k_syscall_handler_t _k_syscall_table[K_SYSCALL_LIMIT] = { \t%s }; -/* Export syscalls for extensions */ -%s """ list_template = """/* auto-generated by gen_syscalls.py, don't edit */ @@ -159,6 +157,20 @@ syscall_tracer_void_template = """ #endif """ + +exported_template = """ +/* Export syscalls for extensions */ +static void * const no_handler = NULL; + +/* Weak references, if something is not found by the linker, it will be NULL + * and simply fail during extension load + */ +%s + +/* Exported symbols */ +%s +""" + typename_regex = re.compile(r'(.*?)([A-Za-z0-9_]+)$') @@ -410,6 +422,8 @@ def parse_args(): help="Indicates we are on system with 64-bit registers") parser.add_argument("--gen-mrsh-files", action="store_true", help="Generate marshalling files (*_mrsh.c)") + parser.add_argument("-e", "--syscall-export-llext", + help="output C system call export for extensions") args = parser.parse_args() @@ -431,6 +445,7 @@ def main(): table_entries = [] handlers = [] emit_list = [] + exported = [] for match_group, fn, to_emit in syscalls: handler, inv, mrsh, sys_id, entry = analyze_fn(match_group, fn) @@ -445,6 +460,7 @@ def main(): ids_emit.append(sys_id) table_entries.append(entry) emit_list.append(handler) + exported.append(handler.replace("z_mrsh_", "z_impl_")) else: ids_not_emit.append(sys_id) @@ -464,12 +480,17 @@ def main(): 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);" % s for s in noweak]) - # Export symbols for emitted syscalls - exported_symbols = "\n".join("EXPORT_SYMBOL(%s);" % e for e in emit_list) - fp.write(table_template % (weak_defines, - ",\n\t".join(table_entries), - exported_symbols)) + ",\n\t".join(table_entries))) + + if args.syscall_export_llext: + with open(args.syscall_export_llext, "w") as fp: + # Export symbols for emitted syscalls + weak_refs = "\n".join("extern __weak ALIAS_OF(no_handler) void * const %s;" + % e for e in exported) + exported_symbols = "\n".join("EXPORT_SYMBOL(%s);" + % e for e in exported) + fp.write(exported_template % (weak_refs, exported_symbols)) # Listing header emitted to stdout ids_emit.sort() diff --git a/subsys/llext/llext_export.c b/subsys/llext/llext_export.c index 0ec7fe4ac0..e5b5aa441a 100644 --- a/subsys/llext/llext_export.c +++ b/subsys/llext/llext_export.c @@ -15,3 +15,5 @@ EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); + +#include