From b8685d5ccdf93495341a77adb9ccf1dbeba3274a Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Sat, 12 Aug 2023 10:59:22 +0900 Subject: [PATCH] virtual: Factor out code generation templates This makes the code generation script more generic by factoring out templates into separate files. Signed-off-by: Daiki Ueno --- .gitignore | 2 + configure.ac | 2 +- p11-kit/Makefile.am | 52 ++-- p11-kit/gen-fixed-closures.py | 46 +++ p11-kit/gen-virtual.py | 363 ------------------------ p11-kit/gen-wrappers.py | 145 ++++++++++ p11-kit/meson.build | 56 ++-- p11-kit/templates/base-wrappers.py | 40 +++ p11-kit/templates/binding-wrappers.py | 29 ++ p11-kit/templates/fixed-wrappers.py | 117 ++++++++ p11-kit/templates/stack-wrappers.py | 29 ++ p11-kit/templates/virtual-excludes.list | 5 + p11-kit/virtual.c | 3 +- 13 files changed, 489 insertions(+), 400 deletions(-) create mode 100755 p11-kit/gen-fixed-closures.py delete mode 100755 p11-kit/gen-virtual.py create mode 100755 p11-kit/gen-wrappers.py create mode 100644 p11-kit/templates/base-wrappers.py create mode 100644 p11-kit/templates/binding-wrappers.py create mode 100644 p11-kit/templates/fixed-wrappers.py create mode 100644 p11-kit/templates/stack-wrappers.py create mode 100644 p11-kit/templates/virtual-excludes.list diff --git a/.gitignore b/.gitignore index 56b0dda26..bf1f51bb4 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,8 @@ frob-* /p11-kit/pkcs11.conf.example /p11-kit/p11-kit-server.service /p11-kit/virtual-*-generated.h +/p11-kit/virtual-fixed-wrappers.h +/p11-kit/virtual-fixed-closures.h /p11-kit/*.gnu.c /p11-kit/p11-kit-testable diff --git a/configure.ac b/configure.ac index 86d4f5fce..251a5486e 100644 --- a/configure.ac +++ b/configure.ac @@ -63,7 +63,7 @@ AC_PROG_CC AC_PROG_CPP AM_PROG_CC_C_O PKG_PROG_PKG_CONFIG -AM_MISSING_PROG([PYTHON], [python]) +AM_PATH_PYTHON([3.6],, [:]) AM_MISSING_PROG([CASTXML], [castxml]) LINGUAS="" diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am index 09dfe908a..167397aa7 100644 --- a/p11-kit/Makefile.am +++ b/p11-kit/Makefile.am @@ -29,7 +29,8 @@ COMMON_SRCS = \ VIRTUAL_GENERATED = \ p11-kit/virtual-ffi-generated.h \ - p11-kit/virtual-fixed-generated.h \ + p11-kit/virtual-fixed-wrappers.h \ + p11-kit/virtual-fixed-closures.h \ p11-kit/virtual-stack-generated.h \ p11-kit/virtual-base-generated.h \ $(NULL) @@ -43,21 +44,36 @@ CLEANFILES += \ $(VIRTUAL_GENERATED) \ $(NULL) -p11-kit/virtual-ffi-generated.h: Makefile p11-kit/gen-virtual.py pkcs11-json/pkcs11.json - $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-virtual.py --ffi \ - $(srcdir)/pkcs11-json/pkcs11.json $@ - -p11-kit/virtual-fixed-generated.h: Makefile p11-kit/gen-virtual.py pkcs11-json/pkcs11.json - $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-virtual.py --fixed $(closures) \ - $(srcdir)/pkcs11-json/pkcs11.json $@ - -p11-kit/virtual-stack-generated.h: Makefile p11-kit/gen-virtual.py pkcs11-json/pkcs11.json - $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-virtual.py --stack \ - $(srcdir)/pkcs11-json/pkcs11.json $@ - -p11-kit/virtual-base-generated.h: Makefile p11-kit/gen-virtual.py pkcs11-json/pkcs11.json - $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-virtual.py --base \ - $(srcdir)/pkcs11-json/pkcs11.json $@ +p11-kit/virtual-ffi-generated.h: Makefile p11-kit/gen-wrappers.py pkcs11-json/pkcs11.json + $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-wrappers.py \ + --template $(srcdir)/p11-kit/templates/binding-wrappers.py \ + --excludes $(srcdir)/p11-kit/templates/virtual-excludes.list \ + --infile $(srcdir)/pkcs11-json/pkcs11.json --outfile $@ + +p11-kit/virtual-fixed-wrappers.h: Makefile p11-kit/gen-wrappers.py pkcs11-json/pkcs11.json + $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-wrappers.py \ + --template $(srcdir)/p11-kit/templates/fixed-wrappers.py \ + --excludes $(srcdir)/p11-kit/templates/virtual-excludes.list \ + --renames C_GetFunctionStatus:short C_CancelFunction:short \ + --concat-lines \ + --infile $(srcdir)/pkcs11-json/pkcs11.json --outfile $@ + +p11-kit/virtual-fixed-closures.h: Makefile p11-kit/gen-fixed-closures.py pkcs11-json/pkcs11.json + $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-fixed-closures.py \ + --closures $(closures) \ + --infile $(srcdir)/pkcs11-json/pkcs11.json --outfile $@ + +p11-kit/virtual-stack-generated.h: Makefile p11-kit/gen-wrappers.py pkcs11-json/pkcs11.json + $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-wrappers.py \ + --template $(srcdir)/p11-kit/templates/stack-wrappers.py \ + --excludes $(srcdir)/p11-kit/templates/virtual-excludes.list \ + --infile $(srcdir)/pkcs11-json/pkcs11.json --outfile $@ + +p11-kit/virtual-base-generated.h: Makefile p11-kit/gen-wrappers.py pkcs11-json/pkcs11.json + $(AM_V_GEN)$(PYTHON) $(srcdir)/p11-kit/gen-wrappers.py \ + --template $(srcdir)/p11-kit/templates/base-wrappers.py \ + --excludes $(srcdir)/p11-kit/templates/virtual-excludes.list \ + --infile $(srcdir)/pkcs11-json/pkcs11.json --outfile $@ lib_LTLIBRARIES += \ libp11-kit.la @@ -220,7 +236,8 @@ example_DATA = p11-kit/pkcs11.conf.example EXTRA_DIST += \ p11-kit/docs.h \ p11-kit/gen-pkcs11-gnu.sh \ - p11-kit/gen-virtual.py \ + p11-kit/gen-wrappers.py \ + p11-kit/gen-fixed-closures.py \ p11-kit/meson.build \ p11-kit/meson_post_install.sh \ p11-kit/libp11-kit.map \ @@ -553,6 +570,7 @@ mock_eleven_la_LIBADD = $(mock_one_la_LIBADD) EXTRA_DIST += \ p11-kit/fixtures \ + p11-kit/templates \ p11-kit/test-mock.c \ p11-kit/test-transport-base.c \ p11-kit/test-profiles.sh \ diff --git a/p11-kit/gen-fixed-closures.py b/p11-kit/gen-fixed-closures.py new file mode 100755 index 000000000..daa73438f --- /dev/null +++ b/p11-kit/gen-fixed-closures.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +""" +SPDX-License-Identifier: BSD-3-Clause +""" + +import io +import sys + +INDENT = " " + + +def fixed_instantiate(closures): + output = io.StringIO() + for i in range(closures): + output.write(f"P11_VIRTUAL_FIXED_FUNCTIONS({i})\n") + + initializers_concatenated = ",\n".join([ + f"{INDENT}P11_VIRTUAL_FIXED_INITIALIZER({i})" + for i in range(closures) + ]) + output.write(f''' +CK_FUNCTION_LIST_3_0 p11_virtual_fixed[P11_VIRTUAL_MAX_FIXED] = {{ +{initializers_concatenated} +}}; + +''') + for i in range(closures): + output.write(f"""\ +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST({i}) +P11_VIRTUAL_FIXED_GET_INTERFACE_LIST({i}) +P11_VIRTUAL_FIXED_GET_INTERFACE({i}) +""") + return output.getvalue() + + +if __name__ == "__main__": + import argparse + parser = argparse.ArgumentParser() + parser.add_argument("--closures", type=int, + default=64) + parser.add_argument("--outfile", type=argparse.FileType("w"), + default=sys.stdout) + args = parser.parse_args() + + args.outfile.write(fixed_instantiate(args.closures)) diff --git a/p11-kit/gen-virtual.py b/p11-kit/gen-virtual.py deleted file mode 100755 index 757bf1ff5..000000000 --- a/p11-kit/gen-virtual.py +++ /dev/null @@ -1,363 +0,0 @@ -#!/usr/bin/python - -""" -SPDX-License-Identifier: BSD-3-Clause -""" - -import io -import json - -INDENT = " " - -# These functions should not appear in CK_X_FUNCTION_LIST -EXCLUDE_IN_X = [ - "C_GetFunctionList", - "C_GetFunctionStatus", - "C_CancelFunction", - "C_GetInterfaceList", - "C_GetInterface", -] - -# Short-circuited functions in fixed closures -SHORT_FUNCTIONS = [ - "C_GetFunctionStatus", - "C_CancelFunction", -] - - -def binding_function(function): - name = f"binding_{function['name']}" - name_indent = " " * len(name + " (") - call = f"funcs->{function['name']}" - call_indent = " " * len("*ret = " + call + " (") - call_args_concatenated = ",\n".join([ - f"{INDENT}{call_indent}*({arg['type']} *)args[{i}]" - for i, arg in enumerate(function["arguments"]) - ]) - return f'''\ -static void -{name} (ffi_cif *cif, -{name_indent}CK_RV *ret, -{name_indent}void* args[], -{name_indent}CK_X_FUNCTION_LIST *funcs) -{{ -{INDENT}*ret = {call} (funcs, -{call_args_concatenated}); -}} - -''' - - -def function_binding_info(function): - args_concatenated = ", ".join([ - f"&ffi_type_{arg['ffi-type']}" for arg in function["arguments"] - ]) - return (f"{INDENT}{{ binding_{function['name']}, " - f"{{ {args_concatenated}, NULL }} }}") - - -def binding_info(functions): - function_binding_info_concatenated = ",\n".join([ - function_binding_info(function) for function in functions - if function["name"] not in EXCLUDE_IN_X - ]) - return f'''\ -static const BindingInfo binding_info[] = {{ -{function_binding_info_concatenated}, -{INDENT}{{ 0, }} -}}; -''' - - -def stack_function(function): - name = f"stack_{function['name']}" - arg_indent = " " * len(name + " (") - args = ",\n".join([ - f"{arg_indent}{arg['type']} {arg['name']}" - for arg in function["arguments"] - ]) - call = f"funcs->{function['name']}" - call_indent = " " * len("return " + call + " (") - call_args_concatenated = ",\n".join([ - f"{INDENT}{call_indent}{arg['name']}" - for arg in function["arguments"] - ]) - return f'''\ -static CK_RV -{name} (CK_X_FUNCTION_LIST *self, -{args}) -{{ -{INDENT}p11_virtual *virt = (p11_virtual *)self; -{INDENT}CK_X_FUNCTION_LIST *funcs = virt->lower_module; -{INDENT}return {call} (funcs, -{call_args_concatenated}); -}} - -''' - - -def stack_function_list(functions): - stack_functions_concatenated = ",\n".join([ - f"{INDENT}stack_{function['name']}" for function in functions - if function["name"] not in EXCLUDE_IN_X - ]) - return f'''\ -CK_X_FUNCTION_LIST p11_virtual_stack = {{ -{INDENT}{{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }}, /* version */ -{stack_functions_concatenated} -}}; -''' - - -def base_function(function): - name = f"base_{function['name']}" - arg_indent = " " * len(name + " (") - args = ",\n".join([ - f"{arg_indent}{arg['type']} {arg['name']}" - for arg in function["arguments"] - ]) - call = f"funcs->{function['name']}" - call_indent = " " * len("return " + call + " (") - call_args_concatenated = f",\n{INDENT}{call_indent}".join([ - arg["name"] for arg in function["arguments"] - ]) - - if function["version"] > 2: - function_list = "CK_FUNCTION_LIST_3_0" - v3_guard = f''' -{INDENT}if (funcs->version.major < 3) -{INDENT}{INDENT}return CKR_FUNCTION_NOT_SUPPORTED; -''' - else: - function_list = "CK_FUNCTION_LIST" - v3_guard = "" - - return f'''\ -static CK_RV -{name} (CK_X_FUNCTION_LIST *self, -{args}) -{{ -{INDENT}p11_virtual *virt = (p11_virtual *)self; -{INDENT}{function_list} *funcs = virt->lower_module; -{v3_guard} -{INDENT}return {call} ({call_args_concatenated}); -}} - -''' - - -def base_function_list(functions): - base_functions_concatenated = ",\n".join([ - f"{INDENT}base_{function['name']}" for function in functions - if function["name"] not in EXCLUDE_IN_X - ]) - return f'''\ -CK_X_FUNCTION_LIST p11_virtual_base = {{ -{INDENT}{{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }}, /* version */ -{base_functions_concatenated} -}}; -''' - - -def format_fixed_function_name(name): - if name in SHORT_FUNCTIONS: - return f"short_{name}" - else: - return f"fixed ## fixed_index ## _{name}" - - -def fixed_function(function): - name = format_fixed_function_name(function["name"]) - arg_indent = " " * len(name + " (") - args = f", \\\n{arg_indent}".join([ - f"{arg['type']} {arg['name']}" - for arg in function["arguments"] - ]) - call = f"funcs->{function['name']}" - call_indent = " " * len("return " + call + " (") - call_args_concatenated = f", \\\n{INDENT}{call_indent}".join([ - arg["name"] for arg in function["arguments"] - ]) - - return f'''\ -static CK_RV \\ -{name} ({args}) \\ -{{ \\ -{INDENT}CK_FUNCTION_LIST_3_0 *bound; \\ -{INDENT}Wrapper *wrapper; \\ -{INDENT}CK_X_FUNCTION_LIST *funcs; \\ -{INDENT}bound = fixed_closures[fixed_index]; \\ -{INDENT}return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \\ -{INDENT}wrapper = (Wrapper *) bound; \\ -{INDENT}funcs = &wrapper->virt->funcs; \\ -{INDENT}return {call} (funcs, \\ -{INDENT}{call_indent}{call_args_concatenated}); \\ -}} \\ -\\ -''' - - -def fixed(functions, closures): - output = io.StringIO() - fixed_functions_concatenated = "".join([ - fixed_function(function) for function in functions - if function["name"] not in EXCLUDE_IN_X - ]) - output.write(f'''\ -#define P11_VIRTUAL_FIXED_FUNCTIONS(fixed_index) \\ -{fixed_functions_concatenated}\ -static CK_RV \\ -fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list); \\ -\\ -static CK_RV \\ -fixed ## fixed_index ## _C_GetInterfaceList (CK_INTERFACE_PTR pInterfacesList, \\ - CK_ULONG_PTR pulCount); \\ -\\ -static CK_RV \\ -fixed ## fixed_index ## _C_GetInterface (CK_UTF8CHAR_PTR pInterfaceName, \\ - CK_VERSION_PTR pVersion, \\ - CK_INTERFACE_PTR_PTR ppInterface, \\ - CK_FLAGS flags); - -#define P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(fixed_index) \\ -static CK_RV \\ -fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) \\ -{{ \\ - if (!list) \\ - return CKR_ARGUMENTS_BAD; \\ - *list = (CK_FUNCTION_LIST *)fixed_closures[fixed_index]; \\ - return CKR_OK; \\ -}} - -#define P11_VIRTUAL_FIXED_GET_INTERFACE_LIST(fixed_index) \\ -static CK_RV \\ -fixed ## fixed_index ## _C_GetInterfaceList (CK_INTERFACE_PTR pInterfacesList, \\ - CK_ULONG_PTR pulCount) \\ -{{ \\ - CK_RV rv = CKR_OK; \\ -\\ - if (pulCount == NULL_PTR) \\ - return CKR_ARGUMENTS_BAD; \\ -\\ - if (pInterfacesList == NULL_PTR) {{ \\ - *pulCount = 1; \\ - return CKR_OK; \\ - }} \\ -\\ - if (*pulCount < 1) {{ \\ - *pulCount = 1; \\ - return CKR_BUFFER_TOO_SMALL; \\ - }} \\ -\\ - if (rv == CKR_OK) {{ \\ - memcpy (pInterfacesList, \\ - fixed_interfaces[fixed_index], \\ - sizeof(CK_INTERFACE)); \\ - *pulCount = 1; \\ - }} \\ -\\ - return rv; \\ -}} - -#define P11_VIRTUAL_FIXED_GET_INTERFACE(fixed_index) \\ -static CK_RV \\ -fixed ## fixed_index ## _C_GetInterface (CK_UTF8CHAR_PTR pInterfaceName, \\ - CK_VERSION_PTR pVersion, \\ - CK_INTERFACE_PTR_PTR ppInterface, \\ - CK_FLAGS flags) \\ -{{ \\ - CK_INTERFACE_PTR interface = fixed_interfaces[fixed_index]; \\ - CK_VERSION_PTR cmp_version = &fixed_closures[fixed_index]->version; \\ -\\ - if (ppInterface == NULL_PTR) {{ \\ - return CKR_ARGUMENTS_BAD; \\ - }} \\ -\\ - if (pInterfaceName == NULL) {{ \\ - *ppInterface = interface; \\ - return CKR_OK; \\ - }} \\ -\\ - if (strcmp ((char *)pInterfaceName, interface->pInterfaceName) != 0 || \\ - (pVersion != NULL && (pVersion->major != cmp_version->major || \\ - pVersion->minor != cmp_version->minor)) || \\ - ((flags & interface->flags) != flags)) {{ \\ - return CKR_ARGUMENTS_BAD; \\ - }} \\ - *ppInterface = interface; \\ - return CKR_OK; \\ -}} -''') - functions_concatenated = f", \\\n{INDENT}".join([ - format_fixed_function_name(function["name"]) for function in functions - ]) - output.write(f'''\ -#define P11_VIRTUAL_FIXED_INITIALIZER(fixed_index) \\ -{{ \\ - {{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }}, /* version */ \\ -{functions_concatenated} \\ -}} - -''') - for i in range(closures): - output.write(f"P11_VIRTUAL_FIXED_FUNCTIONS({i})\n") - - initializers_concatenated = ",\n".join([ - f"{INDENT}P11_VIRTUAL_FIXED_INITIALIZER({i})" - for i in range(closures) - ]) - output.write(f''' -CK_FUNCTION_LIST_3_0 p11_virtual_fixed[P11_VIRTUAL_MAX_FIXED] = {{ -{initializers_concatenated} -}}; - -''') - for i in range(closures): - output.write(f"""\ -P11_VIRTUAL_FIXED_GET_FUNCTION_LIST({i}) -P11_VIRTUAL_FIXED_GET_INTERFACE_LIST({i}) -P11_VIRTUAL_FIXED_GET_INTERFACE({i}) -""") - return output.getvalue() - - -if __name__ == "__main__": - import argparse - parser = argparse.ArgumentParser() - parser.add_argument("--ffi", - action="store_true", help="Generate FFI bindings") - parser.add_argument("--stack", - action="store_true", help="Generate stacked closures") - parser.add_argument("--base", - action="store_true", help="Generate base closures") - parser.add_argument("--fixed", type=int, - help="Generate fixed closures") - parser.add_argument("infile", type=argparse.FileType("r")) - parser.add_argument("outfile", type=argparse.FileType("w")) - args = parser.parse_args() - - functions = json.load(args.infile)["functions"] - - if args.ffi: - for function in functions: - if function["name"] in EXCLUDE_IN_X: - continue - args.outfile.write(binding_function(function)) - args.outfile.write(binding_info(functions)) - - if args.stack: - for function in functions: - if function["name"] in EXCLUDE_IN_X: - continue - args.outfile.write(stack_function(function)) - args.outfile.write(stack_function_list(functions)) - - if args.base: - for function in functions: - if function["name"] in EXCLUDE_IN_X: - continue - args.outfile.write(base_function(function)) - args.outfile.write(base_function_list(functions)) - - if args.fixed is not None: - args.outfile.write(fixed(functions, args.fixed)) diff --git a/p11-kit/gen-wrappers.py b/p11-kit/gen-wrappers.py new file mode 100755 index 000000000..23943668c --- /dev/null +++ b/p11-kit/gen-wrappers.py @@ -0,0 +1,145 @@ +#!/usr/bin/python + +""" +SPDX-License-Identifier: BSD-3-Clause +""" + +import ast +import json +import sys + +INDENT = " " + + +def emit_wrapper_function(function, templates, concat_lines=False): + arglist_separator = ", \\\n" if concat_lines else ",\n" + + function_name = templates["function_name"].format( + function=function["name"], + ) + arglist_indent = " " * len(f"{function_name} (") + arglist = f"{arglist_separator}{arglist_indent}".join([ + templates["function_argument"].format( + argument_index=index, + argument_name=argument["name"], + argument_type=argument["type"], + ) + for index, argument in enumerate(function["arguments"]) + ]) + + call_lower_template = templates["call_lower"] + if function["version"] >= 3: + call_lower_template = templates.get("call_lower_v3", + call_lower_template) + + call_lower = call_lower_template.format( + function=function["name"], + ) + call_lower_arglist_indent = " " * len(f"{INDENT}{call_lower} (") + call_lower_arglist = f"{arglist_separator}{call_lower_arglist_indent}".join([ + templates["call_lower_argument"].format( + argument_index=index, + argument_name=argument["name"], + argument_type=argument["type"], + ) + for index, argument in enumerate(function["arguments"]) + ]) + + function_body_template = templates["function_body"] + if function["version"] >= 3: + function_body_template = templates.get("function_body_v3", + function_body_template) + + return function_body_template.format( + indent=INDENT, + function_name=function_name, + arglist=arglist, + arglist_indent=arglist_indent, + call_lower=call_lower, + call_lower_arglist=call_lower_arglist, + call_lower_arglist_indent=call_lower_arglist_indent, + ) + + +def emit_wrapper_entry(function, templates, suffix=None): + if suffix is not None: + template_name = f"function_name_{suffix}" + else: + template_name = "function_name" + + function_name = templates[template_name].format( + function=function["name"], + ) + + entry_arglist = ", ".join([ + templates["entry_argument"].format( + argument_ffi_type=argument["ffi-type"], + ) + for argument in function["arguments"] + ]) + + return templates["entry"].format( + function_name=function_name, + entry_arglist=entry_arglist, + ) + + +if __name__ == "__main__": + import argparse + parser = argparse.ArgumentParser() + parser.add_argument("--template", required=True, + type=argparse.FileType("r")) + parser.add_argument("--concat-lines", action="store_true") + parser.add_argument("--excludes", type=argparse.FileType("r")) + parser.add_argument("--renames", nargs="*") + parser.add_argument("--infile", required=True, + type=argparse.FileType("r")) + parser.add_argument("--outfile", type=argparse.FileType("w"), + default=sys.stdout) + args = parser.parse_args() + + functions = json.load(args.infile)["functions"] + templates = ast.literal_eval(args.template.read()) + + excludes = [] + if args.excludes: + excludes.extend(args.excludes.read().split()) + + renames = {} + if args.renames: + renames.update({k: v for k, v in [r.split(":") for r in args.renames]}) + + separator = "\\\n" if args.concat_lines else "\n" + wrappers = separator.join([ + emit_wrapper_function( + function, + templates, + args.concat_lines, + ) + for function in functions if function["name"] not in excludes + ]) + + separator = ", \\\n" if args.concat_lines else ",\n" + xentries = separator.join([ + INDENT + emit_wrapper_entry( + function, + templates, + renames.get(function["name"]), + ) + for function in functions if function["name"] not in excludes + ]) + entries = separator.join([ + INDENT + emit_wrapper_entry( + function, + templates, + renames.get(function["name"]), + ) + for function in functions + ]) + + args.outfile.write(templates["outer"].format( + indent=INDENT, + wrappers=wrappers, + xentries=xentries, + entries=entries, + )) diff --git a/p11-kit/meson.build b/p11-kit/meson.build index a93edc97b..a238b580b 100644 --- a/p11-kit/meson.build +++ b/p11-kit/meson.build @@ -20,40 +20,60 @@ libp11_kit_internal_sources += custom_target('generate virtual-ffi-generated.h', output: 'virtual-ffi-generated.h', command: [ python, - meson.current_source_dir() / 'gen-virtual.py', - '--ffi', - '@INPUT@', - '@OUTPUT@', + meson.current_source_dir() / 'gen-wrappers.py', + '--template', meson.current_source_dir() / 'templates' / 'binding-wrappers.py', + '--excludes', meson.current_source_dir() / 'templates' / 'virtual-excludes.list', + '--infile', '@INPUT@', + '--outfile', '@OUTPUT@', ]) -libp11_kit_internal_sources += custom_target('generate virtual-fixed-generated.h', +libp11_kit_internal_sources += custom_target('generate virtual-fixed-wrappers.h', input: pkcs11_json, - output: 'virtual-fixed-generated.h', + output: 'virtual-fixed-wrappers.h', command: [ python, - meson.current_source_dir() / 'gen-virtual.py', - '--fixed', '@0@'.format(closures), - '@INPUT@', - '@OUTPUT@', + meson.current_source_dir() / 'gen-wrappers.py', + '--template', meson.current_source_dir() / 'templates' / 'fixed-wrappers.py', + '--excludes', meson.current_source_dir() / 'templates' / 'virtual-excludes.list', + '--renames', + 'C_GetFunctionStatus:short', + 'C_CancelFunction:short', + '--concat-lines', + '--infile', '@INPUT@', + '--outfile', '@OUTPUT@', ]) + +libp11_kit_internal_sources += custom_target('generate virtual-fixed-closures.h', + input: pkcs11_json, + output: 'virtual-fixed-closures.h', + command: [ + python, + meson.current_source_dir() / 'gen-fixed-closures.py', + '--closures', '@0@'.format(closures), + '--infile', '@INPUT@', + '--outfile', '@OUTPUT@', + ]) + libp11_kit_internal_sources += custom_target('generate virtual-stack-generated.h', input: pkcs11_json, output: 'virtual-stack-generated.h', command: [ python, - meson.current_source_dir() / 'gen-virtual.py', - '--stack', - '@INPUT@', - '@OUTPUT@', + meson.current_source_dir() / 'gen-wrappers.py', + '--template', meson.current_source_dir() / 'templates' / 'stack-wrappers.py', + '--excludes', meson.current_source_dir() / 'templates' / 'virtual-excludes.list', + '--infile', '@INPUT@', + '--outfile', '@OUTPUT@', ]) libp11_kit_internal_sources += custom_target('generate virtual-base-generated.h', input: pkcs11_json, output: 'virtual-base-generated.h', command: [ python, - meson.current_source_dir() / 'gen-virtual.py', - '--base', - '@INPUT@', - '@OUTPUT@', + meson.current_source_dir() / 'gen-wrappers.py', + '--template', meson.current_source_dir() / 'templates' / 'base-wrappers.py', + '--excludes', meson.current_source_dir() / 'templates' / 'virtual-excludes.list', + '--infile', '@INPUT@', + '--outfile', '@OUTPUT@', ]) libp11_kit_internal_sources += 'virtual.c' diff --git a/p11-kit/templates/base-wrappers.py b/p11-kit/templates/base-wrappers.py new file mode 100644 index 000000000..e765810c4 --- /dev/null +++ b/p11-kit/templates/base-wrappers.py @@ -0,0 +1,40 @@ +{ + "function_name": "base_{function}", + "function_argument": "{argument_type} {argument_name}", + "call_lower": "return funcs->{function}", + "call_lower_argument": "{argument_name}", + "function_body": """\ +static CK_RV +{function_name} (CK_X_FUNCTION_LIST *self, +{arglist_indent}{arglist}) +{{ +{indent}p11_virtual *virt = (p11_virtual *)self; +{indent}CK_FUNCTION_LIST *funcs = virt->lower_module; +{indent}{call_lower} ({call_lower_arglist}); +}} + """, + "function_body_v3": """\ +static CK_RV +{function_name} (CK_X_FUNCTION_LIST *self, +{arglist_indent}{arglist}) +{{ +{indent}p11_virtual *virt = (p11_virtual *)self; +{indent}CK_FUNCTION_LIST_3_0 *funcs = virt->lower_module; +{indent}if (funcs->version.major < 3) +{indent}{indent}return CKR_FUNCTION_NOT_SUPPORTED; +{indent}{call_lower} ({call_lower_arglist}); +}} + """, + "entry_argument": "", # unused + "entry": "{function_name}", + "outer": """ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ + +{wrappers} + +CK_X_FUNCTION_LIST p11_virtual_base = {{ +{indent}{{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }}, /* version */ +{xentries} +}}; +""" +} diff --git a/p11-kit/templates/binding-wrappers.py b/p11-kit/templates/binding-wrappers.py new file mode 100644 index 000000000..819d5ffd7 --- /dev/null +++ b/p11-kit/templates/binding-wrappers.py @@ -0,0 +1,29 @@ +{ + "function_name": "binding_{function}", + "function_argument": "", # unused + "call_lower": "*ret = funcs->{function}", + "call_lower_argument": "*({argument_type} *)args[{argument_index}]", + "function_body": """\ +static void +{function_name} (ffi_cif *cif, +{arglist_indent}CK_RV *ret, +{arglist_indent}void* args[], +{arglist_indent}CK_X_FUNCTION_LIST *funcs) +{{ +{indent}{call_lower} (funcs, +{call_lower_arglist_indent}{call_lower_arglist}); +}} + """, + "entry_argument": "&ffi_type_{argument_ffi_type}", + "entry": "{{ {function_name}, {{ {entry_arglist}, NULL }} }}", + "outer": """ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ + +{wrappers} + +static const BindingInfo binding_info[] = {{ +{xentries}, +{indent}{{ 0, }} +}}; +""" +} diff --git a/p11-kit/templates/fixed-wrappers.py b/p11-kit/templates/fixed-wrappers.py new file mode 100644 index 000000000..298821c06 --- /dev/null +++ b/p11-kit/templates/fixed-wrappers.py @@ -0,0 +1,117 @@ +{ + "function_name": "fixed ## fixed_index ## _{function}", + "function_name_short": "short_{function}", + "function_argument": "{argument_type} {argument_name}", + "call_lower": "return funcs->{function}", + "call_lower_argument": "{argument_name}", + "function_body": """\ +static CK_RV \\ +{function_name} ({arglist}) \\ +{{ \\ +{indent}CK_FUNCTION_LIST_3_0 *bound; \\ +{indent}Wrapper *wrapper; \\ +{indent}CK_X_FUNCTION_LIST *funcs; \\ +{indent}bound = fixed_closures[fixed_index]; \\ +{indent}return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \\ +{indent}wrapper = (Wrapper *) bound; \\ +{indent}funcs = &wrapper->virt->funcs; \\ +{indent}{call_lower} (funcs, \\ +{call_lower_arglist_indent}{call_lower_arglist}); \\ +}} \\ +""", + "entry_argument": "", + "entry": "{function_name}", + "outer": """ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ + +#define P11_VIRTUAL_FIXED_FUNCTIONS(fixed_index) \\ +{wrappers}\ +static CK_RV \\ +fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list); \\ +\\ +static CK_RV \\ +fixed ## fixed_index ## _C_GetInterfaceList (CK_INTERFACE_PTR pInterfacesList, \\ + CK_ULONG_PTR pulCount); \\ +\\ +static CK_RV \\ +fixed ## fixed_index ## _C_GetInterface (CK_UTF8CHAR_PTR pInterfaceName, \\ + CK_VERSION_PTR pVersion, \\ + CK_INTERFACE_PTR_PTR ppInterface, \\ + CK_FLAGS flags); + +#define P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(fixed_index) \\ +static CK_RV \\ +fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) \\ +{{ \\ + if (!list) \\ + return CKR_ARGUMENTS_BAD; \\ + *list = (CK_FUNCTION_LIST *)fixed_closures[fixed_index]; \\ + return CKR_OK; \\ +}} + +#define P11_VIRTUAL_FIXED_GET_INTERFACE_LIST(fixed_index) \\ +static CK_RV \\ +fixed ## fixed_index ## _C_GetInterfaceList (CK_INTERFACE_PTR pInterfacesList, \\ + CK_ULONG_PTR pulCount) \\ +{{ \\ + CK_RV rv = CKR_OK; \\ +\\ + if (pulCount == NULL_PTR) \\ + return CKR_ARGUMENTS_BAD; \\ +\\ + if (pInterfacesList == NULL_PTR) {{ \\ + *pulCount = 1; \\ + return CKR_OK; \\ + }} \\ +\\ + if (*pulCount < 1) {{ \\ + *pulCount = 1; \\ + return CKR_BUFFER_TOO_SMALL; \\ + }} \\ +\\ + if (rv == CKR_OK) {{ \\ + memcpy (pInterfacesList, \\ + fixed_interfaces[fixed_index], \\ + sizeof(CK_INTERFACE)); \\ + *pulCount = 1; \\ + }} \\ +\\ + return rv; \\ +}} + +#define P11_VIRTUAL_FIXED_GET_INTERFACE(fixed_index) \\ +static CK_RV \\ +fixed ## fixed_index ## _C_GetInterface (CK_UTF8CHAR_PTR pInterfaceName, \\ + CK_VERSION_PTR pVersion, \\ + CK_INTERFACE_PTR_PTR ppInterface, \\ + CK_FLAGS flags) \\ +{{ \\ + CK_INTERFACE_PTR interface = fixed_interfaces[fixed_index]; \\ + CK_VERSION_PTR cmp_version = &fixed_closures[fixed_index]->version; \\ +\\ + if (ppInterface == NULL_PTR) {{ \\ + return CKR_ARGUMENTS_BAD; \\ + }} \\ +\\ + if (pInterfaceName == NULL) {{ \\ + *ppInterface = interface; \\ + return CKR_OK; \\ + }} \\ +\\ + if (strcmp ((char *)pInterfaceName, interface->pInterfaceName) != 0 || \\ + (pVersion != NULL && (pVersion->major != cmp_version->major || \\ + pVersion->minor != cmp_version->minor)) || \\ + ((flags & interface->flags) != flags)) {{ \\ + return CKR_ARGUMENTS_BAD; \\ + }} \\ + *ppInterface = interface; \\ + return CKR_OK; \\ +}} + +#define P11_VIRTUAL_FIXED_INITIALIZER(fixed_index) \\ +{{ \\ +{indent}{{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }}, /* version */ \\ +{entries} \\ +}} +""" +} diff --git a/p11-kit/templates/stack-wrappers.py b/p11-kit/templates/stack-wrappers.py new file mode 100644 index 000000000..a7170b92a --- /dev/null +++ b/p11-kit/templates/stack-wrappers.py @@ -0,0 +1,29 @@ +{ + "function_name": "stack_{function}", + "function_argument": "{argument_type} {argument_name}", + "call_lower": "return funcs->{function}", + "call_lower_argument": "{argument_name}", + "function_body": """\ +static CK_RV +{function_name} (CK_X_FUNCTION_LIST *self, +{arglist_indent}{arglist}) +{{ +{indent}p11_virtual *virt = (p11_virtual *)self; +{indent}CK_X_FUNCTION_LIST *funcs = virt->lower_module; +{indent}{call_lower} (funcs, +{call_lower_arglist_indent}{call_lower_arglist}); +}} + """, + "entry_argument": "", # unused + "entry": "{function_name}", + "outer": """ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ + +{wrappers} + +CK_X_FUNCTION_LIST p11_virtual_stack = {{ +{indent}{{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }}, /* version */ +{xentries} +}}; +""" +} diff --git a/p11-kit/templates/virtual-excludes.list b/p11-kit/templates/virtual-excludes.list new file mode 100644 index 000000000..788ac6418 --- /dev/null +++ b/p11-kit/templates/virtual-excludes.list @@ -0,0 +1,5 @@ +C_GetFunctionList +C_GetFunctionStatus +C_CancelFunction +C_GetInterfaceList +C_GetInterface diff --git a/p11-kit/virtual.c b/p11-kit/virtual.c index f7da19ad6..3ad6b6630 100644 --- a/p11-kit/virtual.c +++ b/p11-kit/virtual.c @@ -623,7 +623,8 @@ p11_virtual_unwrap (CK_FUNCTION_LIST_PTR module) free (wrapper); } -#include "p11-kit/virtual-fixed-generated.h" +#include "p11-kit/virtual-fixed-wrappers.h" +#include "p11-kit/virtual-fixed-closures.h" static CK_FUNCTION_LIST_3_0 * p11_virtual_wrap_fixed (p11_virtual *virt,