mirror of
https://github.com/Mbed-TLS/mbedtls-framework.git
synced 2026-06-06 05:25:18 +00:00
code_wrapper: Minor fixes
* imports to mbedtls_framework set to relative package imports. * _C_TYPEDEF_DECLARATION_RE is regex compiled. * `read_typedefs()` set to use `read_logical_lines()` * `_write_prologue/epiloge()` modified to use f-strings * Moved poison_write/poison_mutliwrite logic to psa_wrapper Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This commit is contained in:
@@ -82,7 +82,7 @@ class FunctionInfo:
|
||||
str_text = "{} {} {}({})".format(" ".join(self.qualifiers),
|
||||
self.return_type, self.name,
|
||||
", ".join(str_args)).strip()
|
||||
str_text = FunctionInfo._c_wrap_(str_text)
|
||||
str_text = self._c_wrap_(str_text)
|
||||
return self.doc + "\n" + str_text
|
||||
|
||||
@staticmethod
|
||||
@@ -153,16 +153,16 @@ def read_function_declarations(functions: Dict[str, FunctionInfo],
|
||||
name,
|
||||
arguments)
|
||||
|
||||
_C_TYPEDEF_DECLARATION_RE = r'typedef (?:struct )?(?P<type>\w+) (?P<name>\w+)'
|
||||
_C_TYPEDEF_DECLARATION_RE = re.compile(r'typedef (?:struct )?(?P<type>\w+) (?P<name>\w+)')
|
||||
|
||||
def read_typedefs(filename: str)-> Dict[str, str]:
|
||||
def read_typedefs(filename: str) -> Dict[str, str]:
|
||||
""" Extract type definitions in a {typedef aliased name: original type} dictionary.
|
||||
Multi-line typedef struct are not captured. """
|
||||
|
||||
type_decl = {}
|
||||
with open(filename, encoding='utf-8') as inp:
|
||||
content = inp.read()
|
||||
|
||||
for m in re.finditer(_C_TYPEDEF_DECLARATION_RE, content):
|
||||
type_decl[m.group("name")] = m.group("type")
|
||||
for _, line in read_logical_lines(filename):
|
||||
m = _C_TYPEDEF_DECLARATION_RE.match(line)
|
||||
if m:
|
||||
type_decl[m.group("name")] = m.group("type")
|
||||
return type_decl
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import typing
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
import textwrap
|
||||
from typing import Dict, NamedTuple, List, Optional, Tuple
|
||||
|
||||
from .c_parsing_helper import ArgumentInfo, FunctionInfo
|
||||
from . import typing_util
|
||||
@@ -25,7 +25,7 @@ def c_declare(prefix: str, name: str, suffix: str) -> str:
|
||||
return prefix + name + suffix
|
||||
|
||||
|
||||
WrapperInfo = typing.NamedTuple('WrapperInfo', [
|
||||
WrapperInfo = NamedTuple('WrapperInfo', [
|
||||
('argument_names', List[str]),
|
||||
('guard', Optional[str]),
|
||||
('wrapper_name', str),
|
||||
@@ -67,46 +67,52 @@ class Base:
|
||||
|
||||
This includes a description comment and some include directives.
|
||||
"""
|
||||
prologue = ['/* Automatically generated by {}, do not edit! */'.format(self.program_name),
|
||||
'']
|
||||
prologue += ['/* Copyright The Mbed TLS Contributors',
|
||||
' * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later',
|
||||
' */',
|
||||
'']
|
||||
|
||||
prologue = textwrap.dedent("""
|
||||
/* Automatically generated by generate_psa_wrappers.py, do not edit! */
|
||||
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
""").lstrip()
|
||||
|
||||
if header:
|
||||
prologue += ['#ifndef {}'.format(self.header_guard),
|
||||
'#define {}'.format(self.header_guard),
|
||||
'',
|
||||
'#ifdef __cplusplus',
|
||||
'extern "C" {',
|
||||
'#endif',
|
||||
'']
|
||||
prologue += textwrap.dedent("""
|
||||
#ifndef {guard}
|
||||
#define {guard}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {{
|
||||
#endif
|
||||
|
||||
""".format(guard=self.header_guard)).lstrip()
|
||||
|
||||
for include in self._INCLUDES:
|
||||
prologue.append('#include {}'.format(include))
|
||||
prologue += "#include {}\n".format(include)
|
||||
|
||||
# Make certain there is an empty line at the end of this section.
|
||||
for i in [-1, -2]:
|
||||
if prologue[i] != '':
|
||||
prologue.append('')
|
||||
|
||||
out.write('\n'.join(prologue))
|
||||
if prologue[i] != '\n':
|
||||
prologue += ('\n')
|
||||
out.write(prologue)
|
||||
|
||||
def _write_epilogue(self, out: typing_util.Writable, header: bool) -> None:
|
||||
"""Write the epilogue of a C file.
|
||||
"""
|
||||
epilogue = []
|
||||
epilogue = ""
|
||||
if header:
|
||||
epilogue += ['#ifdef __cplusplus',
|
||||
'}',
|
||||
'#endif',
|
||||
'',
|
||||
'#endif /* {} */'.format(self.header_guard),
|
||||
'']
|
||||
epilogue.append('/* End of automatically generated file. */')
|
||||
epilogue.append('')
|
||||
out.write("\n".join(epilogue))
|
||||
epilogue += textwrap.dedent("""
|
||||
#ifdef __cplusplus
|
||||
}}
|
||||
#endif
|
||||
|
||||
#endif /* {guard} */
|
||||
|
||||
""".format(guard=self.header_guard)).lstrip()
|
||||
|
||||
epilogue += ('/* End of automatically generated file. */\n')
|
||||
out.write(epilogue)
|
||||
|
||||
def _wrapper_function_name(self, original_name: str) -> str:
|
||||
"""The name of the wrapper function.
|
||||
|
||||
Executable → Regular
+1
-28
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
""" PSA Buffer utility data-class.
|
||||
"""
|
||||
|
||||
@@ -6,7 +5,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
from typing import List
|
||||
from mbedtls_framework import typing_util
|
||||
from .. import typing_util
|
||||
|
||||
class BufferParameter:
|
||||
"""Description of an input or output buffer parameter sequence to a PSA function."""
|
||||
@@ -28,29 +27,3 @@ class BufferParameter:
|
||||
self.size_name = size_name
|
||||
self.is_output = is_output
|
||||
|
||||
def poison_write(self,
|
||||
out: typing_util.Writable,
|
||||
poison: bool) -> None:
|
||||
"""Write poisoning or unpoisoning code for a buffer parameter.
|
||||
|
||||
Write poisoning code if poison is true, unpoisoning code otherwise.
|
||||
"""
|
||||
out.write(' MBEDTLS_TEST_MEMORY_{}({}, {});\n'.format(
|
||||
'POISON' if poison else 'UNPOISON',
|
||||
self.buffer_name, self.size_name
|
||||
))
|
||||
|
||||
@staticmethod
|
||||
def poison_multi_write(out: typing_util.Writable,
|
||||
buffer_parameters: List['BufferParameter'],
|
||||
poison: bool) -> None:
|
||||
"""Write poisoning or unpoisoning code for the buffer parameters.
|
||||
|
||||
Write poisoning code if poison is true, unpoisoning code otherwise.
|
||||
"""
|
||||
if not buffer_parameters:
|
||||
return
|
||||
out.write('#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)\n')
|
||||
for param in buffer_parameters:
|
||||
param.poison_write(out, poison)
|
||||
out.write('#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */\n')
|
||||
|
||||
Executable → Regular
+10
-15
@@ -1,26 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate wrapper functions for PSA function calls.
|
||||
"""
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
### WARNING: the code in this file has not been extensively reviewed yet.
|
||||
### We do not think it is harmful, but it may be below our normal standards
|
||||
### for robustness and maintainability.
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import os
|
||||
from typing import Iterator, List, Collection, Optional, Tuple
|
||||
|
||||
from mbedtls_framework import build_tree
|
||||
from mbedtls_framework import c_parsing_helper
|
||||
from mbedtls_framework import c_wrapper_generator
|
||||
from mbedtls_framework import typing_util
|
||||
from .. import build_tree
|
||||
from .. import c_parsing_helper
|
||||
from .. import c_wrapper_generator
|
||||
from .. import typing_util
|
||||
|
||||
from mbedtls_framework.code_wrapper.psa_buffer import BufferParameter
|
||||
from mbedtls_framework.code_wrapper.psa_wrapper import PSAWrapper, PSALoggingWrapper, DEFAULTS
|
||||
from .psa_buffer import BufferParameter
|
||||
from .psa_wrapper import PSAWrapper, PSALoggingWrapper, DEFAULTS
|
||||
|
||||
class PSATestWrapper(PSAWrapper):
|
||||
"""Generate a C source file containing wrapper functions for PSA Crypto API calls."""
|
||||
@@ -31,7 +26,7 @@ class PSATestWrapper(PSAWrapper):
|
||||
_WRAPPER_NAME_PREFIX = 'mbedtls_test_wrap_'
|
||||
_WRAPPER_NAME_SUFFIX = ''
|
||||
|
||||
_PSA_WRAPPER_INCLUDES = ['<psa/crypto.h>\n',
|
||||
_PSA_WRAPPER_INCLUDES = ['<psa/crypto.h>',
|
||||
'<test/memory.h>',
|
||||
'<test/psa_crypto_helpers.h>',
|
||||
'<test/psa_test_wrappers.h>']
|
||||
@@ -39,10 +34,10 @@ class PSATestWrapper(PSAWrapper):
|
||||
class PSALoggingTestWrapper(PSATestWrapper, PSALoggingWrapper):
|
||||
"""Generate a C source file containing wrapper functions that log PSA Crypto API calls."""
|
||||
|
||||
def __init__(self, output_h_f: str,
|
||||
output_c_f: str,
|
||||
def __init__(self, out_h_f: str,
|
||||
out_c_f: str,
|
||||
stream: str,
|
||||
in_headers: Collection[str] = DEFAULTS["input_headers"]) -> None:
|
||||
super().__init__(output_h_f, output_c_f, in_headers)# type: ignore[arg-type]
|
||||
super().__init__(out_h_f, out_c_f, in_headers)# type: ignore[arg-type]
|
||||
self.set_stream(stream)
|
||||
|
||||
|
||||
Executable → Regular
+53
-34
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate wrapper functions for PSA function calls.
|
||||
"""
|
||||
|
||||
@@ -10,13 +9,12 @@ import itertools
|
||||
import os
|
||||
from typing import Any, Iterator, List, Dict, Collection, Optional, Tuple
|
||||
|
||||
from mbedtls_framework import build_tree
|
||||
from mbedtls_framework import c_parsing_helper
|
||||
from mbedtls_framework import c_wrapper_generator
|
||||
from mbedtls_framework import typing_util
|
||||
from .. import build_tree
|
||||
from .. import c_parsing_helper
|
||||
from .. import c_wrapper_generator
|
||||
from .. import typing_util
|
||||
|
||||
from mbedtls_framework.code_wrapper.psa_buffer import BufferParameter
|
||||
from textwrap import dedent
|
||||
from .psa_buffer import BufferParameter
|
||||
|
||||
DEFAULTS = {
|
||||
"input_headers" : ['crypto.h', 'crypto_extra.h'],
|
||||
@@ -54,7 +52,7 @@ DEFAULTS = {
|
||||
'psa_pake_set_peer' : 'defined(PSA_WANT_ALG_SOME_PAKE)',
|
||||
'psa_pake_set_role' : 'defined(PSA_WANT_ALG_SOME_PAKE)',
|
||||
'psa_pake_set_user' : 'defined(PSA_WANT_ALG_SOME_PAKE)',
|
||||
'psa_pake_setup' : 'defined(PSA_WANT_ALG_SOME_PAKE)'
|
||||
'psa_pake_setup' : 'defined(PSA_WANT_ALG_SOME_PAKE)',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,34 +65,32 @@ class PSAWrapper(c_wrapper_generator.Base):
|
||||
_PSA_WRAPPER_INCLUDES = ['<psa/crypto.h>']
|
||||
|
||||
def __init__(self,
|
||||
output_h_f: str,
|
||||
output_c_f: str,
|
||||
out_h_f: str,
|
||||
out_c_f: str,
|
||||
in_headers: Collection[str] = DEFAULTS["input_headers"],
|
||||
config: Dict[str, Any]= DEFAULTS) -> None:
|
||||
config: Dict[str, Any] = DEFAULTS) -> None:
|
||||
|
||||
super().__init__()
|
||||
self._FUNCTION_GUARDS = super()._FUNCTION_GUARDS.copy()
|
||||
self.in_headers = in_headers
|
||||
self.out_c_f = output_c_f
|
||||
self.out_h_f = output_h_f
|
||||
self.out_c_f = out_c_f
|
||||
self.out_h_f = out_h_f
|
||||
|
||||
self.mbedtls_root = build_tree.guess_mbedtls_root()
|
||||
self.read_config(config)
|
||||
|
||||
if in_headers:
|
||||
self.read_headers(in_headers)
|
||||
self.read_headers(in_headers)
|
||||
|
||||
def read_config(self, cfg: Dict[str, Any])-> None:
|
||||
"""Configure instance's parameters based on a module specific default config """
|
||||
|
||||
"""Configure instance's parameters from a user provided config."""
|
||||
if not cfg:
|
||||
return
|
||||
self._CPP_GUARDS = PSAWrapper.parse_def_guards(cfg["define_guards"])
|
||||
self._SKIP_FUNCTIONS = cfg["skip_list"]
|
||||
self._FUNCTION_GUARDS.update(cfg["function_guards"]) # type: ignore[arg-type]
|
||||
self._NOT_IMPLEMENTED = cfg["not_implemented"]
|
||||
self.read_headers(cfg["input_headers"])
|
||||
|
||||
def read_headers(self, headers: Collection[str]) -> None:
|
||||
""" Reads functions from source header files into a Dict[str, FunctionInfo] """
|
||||
|
||||
"""Reads functions to be wrapped from source header files into self.functions."""
|
||||
for header_name in headers:
|
||||
header_path = self.rel_path(header_name)
|
||||
c_parsing_helper.read_function_declarations(self.functions, header_path)
|
||||
@@ -116,16 +112,18 @@ class PSAWrapper(c_wrapper_generator.Base):
|
||||
# Utility Methods
|
||||
@staticmethod
|
||||
def parse_def_guards(def_list: Collection[str])-> str:
|
||||
""" Parse an input list of format ["HASH_DEFINE", "!HASH_DEFINE2" ] and generate a
|
||||
c compatible defined(HASH_DEFINE) && !defined(HASH_DEFINE) syntax string"""
|
||||
""" Parse an input list of format [[[C] preprocessor] macro, ...] and generate a
|
||||
c compatible defined() && !defined() syntax string"""
|
||||
|
||||
output = ""
|
||||
_dl = ["defined({})".format(n) if n[0] != "!" \
|
||||
else "!defined({})".format(n[1:]) for n in def_list]
|
||||
dl = [("defined({})".format(n) if n[0] != "!" else
|
||||
"!defined({})".format(n[1:]))
|
||||
for n in def_list]
|
||||
|
||||
# Split the list in chunks of 2 and add new lines
|
||||
for i in range(0, len(_dl), 2):
|
||||
output += "{} && {} && \\".format(_dl[i], _dl[i+1]) + "\n "\
|
||||
if i+2 <= len(_dl) else _dl[i]
|
||||
for i in range(0, len(dl), 2):
|
||||
output += "{} && {} && \\".format(dl[i], dl[i+1]) + "\n "\
|
||||
if i+2 <= len(dl) else dl[i]
|
||||
return output
|
||||
|
||||
@staticmethod
|
||||
@@ -157,6 +155,27 @@ class PSAWrapper(c_wrapper_generator.Base):
|
||||
|
||||
return True
|
||||
|
||||
def _poison_wrap(self, param : BufferParameter, poison: bool, ident_lv = 1) -> str:
|
||||
"""Returns a custom string based on the values of param and poison."""
|
||||
return "{}MBEDTLS_TEST_MEMORY_{}({}, {});\n".format((ident_lv * 4) * ' ',
|
||||
'POISON' if poison else 'UNPOISON',
|
||||
param.buffer_name, param.size_name)
|
||||
|
||||
def _poison_multi_write(self,
|
||||
out: typing_util.Writable,
|
||||
buffer_parameters: List['BufferParameter'],
|
||||
poison: bool) -> None:
|
||||
"""Write poisoning or unpoisoning code for the buffer parameters.
|
||||
Write poisoning code if poison is true, unpoisoning code otherwise.
|
||||
"""
|
||||
|
||||
if not buffer_parameters:
|
||||
return
|
||||
out.write('#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)\n')
|
||||
for param in buffer_parameters:
|
||||
out.write(self._poison_wrap(param, poison))
|
||||
out.write('#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */\n')
|
||||
|
||||
# Override parent's methods
|
||||
def _write_function_call(self, out: typing_util.Writable,
|
||||
function: c_wrapper_generator.FunctionInfo,
|
||||
@@ -168,9 +187,9 @@ class PSAWrapper(c_wrapper_generator.Base):
|
||||
if self._parameter_should_be_copied(function.name,
|
||||
function.arguments[param.index].name))
|
||||
|
||||
BufferParameter.poison_multi_write(out, buffer_parameters, True)
|
||||
self._poison_multi_write(out, buffer_parameters, True)
|
||||
super()._write_function_call(out, function, argument_names)
|
||||
BufferParameter.poison_multi_write(out, buffer_parameters, False)
|
||||
self._poison_multi_write(out, buffer_parameters, False)
|
||||
|
||||
def _skip_function(self, function: c_wrapper_generator.FunctionInfo) -> bool:
|
||||
if function.return_type != 'psa_status_t':
|
||||
@@ -215,12 +234,12 @@ class PSALoggingWrapper(PSAWrapper, c_wrapper_generator.Logging):
|
||||
|
||||
def __init__(self,
|
||||
stream: str,
|
||||
output_h_f: str,
|
||||
output_c_f: str,
|
||||
out_h_f: str,
|
||||
out_c_f: str,
|
||||
in_headers: Collection[str] = DEFAULTS["input_headers"],
|
||||
config: Dict[str, Any]= DEFAULTS) -> None:
|
||||
|
||||
super().__init__(output_h_f, output_c_f, in_headers, config)
|
||||
super().__init__(out_h_f, out_c_f, in_headers, config)
|
||||
self.set_stream(stream)
|
||||
|
||||
_PRINTF_TYPE_CAST = c_wrapper_generator.Logging._PRINTF_TYPE_CAST.copy()
|
||||
@@ -236,7 +255,7 @@ class PSALoggingWrapper(PSAWrapper, c_wrapper_generator.Logging):
|
||||
'psa_key_usage_flags_t': 'unsigned',
|
||||
'psa_pake_role_t': 'int',
|
||||
'psa_pake_step_t': 'int',
|
||||
'psa_status_t': 'int'
|
||||
'psa_status_t': 'int',
|
||||
})
|
||||
|
||||
def _printf_parameters(self, typ: str, var: str) -> Tuple[str, List[str]]:
|
||||
|
||||
Reference in New Issue
Block a user