From d86fca3affca04b6c2cedd7060206c3e7091ecc8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 29 Sep 2024 20:50:11 -0400 Subject: xdrgen: Exit status should be zero on success To use xdrgen in Makefiles, it needs to exit with a zero status if the compilation worked. Otherwise the make command fails with an error. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdrgen | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdrgen b/tools/net/sunrpc/xdrgen/xdrgen index 95f303b2861b..43762be39252 100755 --- a/tools/net/sunrpc/xdrgen/xdrgen +++ b/tools/net/sunrpc/xdrgen/xdrgen @@ -128,5 +128,7 @@ There is NO WARRANTY, to the extent permitted by law.""", try: if __name__ == "__main__": sys.exit(main()) -except (SystemExit, KeyboardInterrupt, BrokenPipeError): +except SystemExit: + sys.exit(0) +except (KeyboardInterrupt, BrokenPipeError): sys.exit(1) -- cgit v1.2.3 From 5383ccd0cc23530b69a0822fba54605615b71946 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 29 Sep 2024 20:50:12 -0400 Subject: xdrgen: Clean up type_specifier Clean up: Make both arms of the type_specifier AST transformer match. No behavior change is expected. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index dbd3fcf9c957..5d96c544a07b 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -303,9 +303,9 @@ class ParseToAst(Transformer): c_classifier=c_classifier, ) - token = children[0].data + name = children[0].data.value return _XdrBuiltInType( - type_name=token.value, + type_name=name, c_classifier=c_classifier, ) -- cgit v1.2.3 From 041962d5c6a965f1a6c338be49acfe7ab51d2056 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 29 Sep 2024 20:50:13 -0400 Subject: xdrgen: Rename "variable-length strings" I misread RFC 4506. The built-in data type is called simply "string", as there is no fixed-length variety. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/generators/pointer.py | 8 ++++---- tools/net/sunrpc/xdrgen/generators/struct.py | 8 ++++---- tools/net/sunrpc/xdrgen/generators/typedef.py | 10 +++++----- tools/net/sunrpc/xdrgen/grammars/xdr.lark | 2 +- .../sunrpc/xdrgen/templates/C/pointer/decoder/string.j2 | 6 ++++++ .../C/pointer/decoder/variable_length_string.j2 | 6 ------ .../xdrgen/templates/C/pointer/definition/string.j2 | 5 +++++ .../C/pointer/definition/variable_length_string.j2 | 5 ----- .../sunrpc/xdrgen/templates/C/pointer/encoder/string.j2 | 8 ++++++++ .../C/pointer/encoder/variable_length_string.j2 | 8 -------- .../sunrpc/xdrgen/templates/C/struct/decoder/string.j2 | 6 ++++++ .../C/struct/decoder/variable_length_string.j2 | 6 ------ .../xdrgen/templates/C/struct/definition/string.j2 | 5 +++++ .../C/struct/definition/variable_length_string.j2 | 5 ----- .../sunrpc/xdrgen/templates/C/struct/encoder/string.j2 | 8 ++++++++ .../C/struct/encoder/variable_length_string.j2 | 8 -------- .../xdrgen/templates/C/typedef/declaration/string.j2 | 4 ++++ .../C/typedef/declaration/variable_length_string.j2 | 4 ---- .../sunrpc/xdrgen/templates/C/typedef/decoder/string.j2 | 17 +++++++++++++++++ .../C/typedef/decoder/variable_length_string.j2 | 17 ----------------- .../xdrgen/templates/C/typedef/definition/string.j2 | 6 ++++++ .../C/typedef/definition/variable_length_string.j2 | 6 ------ .../sunrpc/xdrgen/templates/C/typedef/encoder/string.j2 | 17 +++++++++++++++++ .../C/typedef/encoder/variable_length_string.j2 | 17 ----------------- .../sunrpc/xdrgen/templates/C/union/decoder/string.j2 | 6 ++++++ .../templates/C/union/decoder/variable_length_string.j2 | 6 ------ tools/net/sunrpc/xdrgen/xdr_ast.py | 10 +++++----- 27 files changed, 107 insertions(+), 107 deletions(-) create mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/definition/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/definition/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/decoder/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/decoder/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/definition/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/definition/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/encoder/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/encoder/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/definition/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/definition/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/variable_length_string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/union/decoder/string.j2 delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/union/decoder/variable_length_string.j2 (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/generators/pointer.py b/tools/net/sunrpc/xdrgen/generators/pointer.py index b0b27f1819c8..0aa3d35203f5 100644 --- a/tools/net/sunrpc/xdrgen/generators/pointer.py +++ b/tools/net/sunrpc/xdrgen/generators/pointer.py @@ -8,7 +8,7 @@ from jinja2 import Environment from generators import SourceGenerator, kernel_c_type from generators import create_jinja2_environment, get_jinja2_template -from xdr_ast import _XdrBasic, _XdrVariableLengthString +from xdr_ast import _XdrBasic, _XdrString from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray from xdr_ast import _XdrOptionalData, _XdrPointer, _XdrDeclaration @@ -46,7 +46,7 @@ def emit_pointer_member_definition( elif isinstance(field, _XdrVariableLengthOpaque): template = get_jinja2_template(environment, "definition", field.template) print(template.render(name=field.name)) - elif isinstance(field, _XdrVariableLengthString): + elif isinstance(field, _XdrString): template = get_jinja2_template(environment, "definition", field.template) print(template.render(name=field.name)) elif isinstance(field, _XdrFixedLengthArray): @@ -119,7 +119,7 @@ def emit_pointer_member_decoder( maxsize=field.maxsize, ) ) - elif isinstance(field, _XdrVariableLengthString): + elif isinstance(field, _XdrString): template = get_jinja2_template(environment, "decoder", field.template) print( template.render( @@ -198,7 +198,7 @@ def emit_pointer_member_encoder( maxsize=field.maxsize, ) ) - elif isinstance(field, _XdrVariableLengthString): + elif isinstance(field, _XdrString): template = get_jinja2_template(environment, "encoder", field.template) print( template.render( diff --git a/tools/net/sunrpc/xdrgen/generators/struct.py b/tools/net/sunrpc/xdrgen/generators/struct.py index b694cd470829..6dd7f4d7cd53 100644 --- a/tools/net/sunrpc/xdrgen/generators/struct.py +++ b/tools/net/sunrpc/xdrgen/generators/struct.py @@ -8,7 +8,7 @@ from jinja2 import Environment from generators import SourceGenerator, kernel_c_type from generators import create_jinja2_environment, get_jinja2_template -from xdr_ast import _XdrBasic, _XdrVariableLengthString +from xdr_ast import _XdrBasic, _XdrString from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray from xdr_ast import _XdrOptionalData, _XdrStruct, _XdrDeclaration @@ -46,7 +46,7 @@ def emit_struct_member_definition( elif isinstance(field, _XdrVariableLengthOpaque): template = get_jinja2_template(environment, "definition", field.template) print(template.render(name=field.name)) - elif isinstance(field, _XdrVariableLengthString): + elif isinstance(field, _XdrString): template = get_jinja2_template(environment, "definition", field.template) print(template.render(name=field.name)) elif isinstance(field, _XdrFixedLengthArray): @@ -119,7 +119,7 @@ def emit_struct_member_decoder( maxsize=field.maxsize, ) ) - elif isinstance(field, _XdrVariableLengthString): + elif isinstance(field, _XdrString): template = get_jinja2_template(environment, "decoder", field.template) print( template.render( @@ -198,7 +198,7 @@ def emit_struct_member_encoder( maxsize=field.maxsize, ) ) - elif isinstance(field, _XdrVariableLengthString): + elif isinstance(field, _XdrString): template = get_jinja2_template(environment, "encoder", field.template) print( template.render( diff --git a/tools/net/sunrpc/xdrgen/generators/typedef.py b/tools/net/sunrpc/xdrgen/generators/typedef.py index 85a1b2303333..6ea98445f5c8 100644 --- a/tools/net/sunrpc/xdrgen/generators/typedef.py +++ b/tools/net/sunrpc/xdrgen/generators/typedef.py @@ -8,7 +8,7 @@ from jinja2 import Environment from generators import SourceGenerator, kernel_c_type from generators import create_jinja2_environment, get_jinja2_template -from xdr_ast import _XdrBasic, _XdrTypedef, _XdrVariableLengthString +from xdr_ast import _XdrBasic, _XdrTypedef, _XdrString from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray from xdr_ast import _XdrOptionalData, _XdrVoid, _XdrDeclaration @@ -28,7 +28,7 @@ def emit_typedef_declaration(environment: Environment, node: _XdrDeclaration) -> classifier=node.spec.c_classifier, ) ) - elif isinstance(node, _XdrVariableLengthString): + elif isinstance(node, _XdrString): template = get_jinja2_template(environment, "declaration", node.template) print(template.render(name=node.name)) elif isinstance(node, _XdrFixedLengthOpaque): @@ -74,7 +74,7 @@ def emit_type_definition(environment: Environment, node: _XdrDeclaration) -> Non classifier=node.spec.c_classifier, ) ) - elif isinstance(node, _XdrVariableLengthString): + elif isinstance(node, _XdrString): template = get_jinja2_template(environment, "definition", node.template) print(template.render(name=node.name)) elif isinstance(node, _XdrFixedLengthOpaque): @@ -119,7 +119,7 @@ def emit_typedef_decoder(environment: Environment, node: _XdrDeclaration) -> Non type=node.spec.type_name, ) ) - elif isinstance(node, _XdrVariableLengthString): + elif isinstance(node, _XdrString): template = get_jinja2_template(environment, "decoder", node.template) print( template.render( @@ -180,7 +180,7 @@ def emit_typedef_encoder(environment: Environment, node: _XdrDeclaration) -> Non type=node.spec.type_name, ) ) - elif isinstance(node, _XdrVariableLengthString): + elif isinstance(node, _XdrString): template = get_jinja2_template(environment, "encoder", node.template) print( template.render( diff --git a/tools/net/sunrpc/xdrgen/grammars/xdr.lark b/tools/net/sunrpc/xdrgen/grammars/xdr.lark index f3c4552e548d..0e1aeb02d667 100644 --- a/tools/net/sunrpc/xdrgen/grammars/xdr.lark +++ b/tools/net/sunrpc/xdrgen/grammars/xdr.lark @@ -3,7 +3,7 @@ declaration : "opaque" identifier "[" value "]" -> fixed_length_opaque | "opaque" identifier "<" [ value ] ">" -> variable_length_opaque - | "string" identifier "<" [ value ] ">" -> variable_length_string + | "string" identifier "<" [ value ] ">" -> string | type_specifier identifier "[" value "]" -> fixed_length_array | type_specifier identifier "<" [ value ] ">" -> variable_length_array | type_specifier "*" identifier -> optional_data diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/string.j2 new file mode 100644 index 000000000000..12d20b143b43 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/string.j2 @@ -0,0 +1,6 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +{% if annotate %} + /* member {{ name }} (variable-length string) */ +{% endif %} + if (!xdrgen_decode_string(xdr, (string *)ptr, {{ maxsize }})) + return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/variable_length_string.j2 deleted file mode 100644 index 12d20b143b43..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/pointer/decoder/variable_length_string.j2 +++ /dev/null @@ -1,6 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} -{% if annotate %} - /* member {{ name }} (variable-length string) */ -{% endif %} - if (!xdrgen_decode_string(xdr, (string *)ptr, {{ maxsize }})) - return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/definition/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/definition/string.j2 new file mode 100644 index 000000000000..2de2feec77db --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/pointer/definition/string.j2 @@ -0,0 +1,5 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +{% if annotate %} + /* (variable-length string) */ +{% endif %} + string {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/definition/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/definition/variable_length_string.j2 deleted file mode 100644 index 2de2feec77db..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/pointer/definition/variable_length_string.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} -{% if annotate %} - /* (variable-length string) */ -{% endif %} - string {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/string.j2 new file mode 100644 index 000000000000..cf65b71eaef3 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/string.j2 @@ -0,0 +1,8 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +{% if annotate %} + /* member {{ name }} (variable-length string) */ +{% endif %} + if (value->{{ name }}.len > {{ maxsize }}) + return false; + if (xdr_stream_encode_opaque(xdr, value->{{ name }}.data, value->{{ name }}.len) < 0) + return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/variable_length_string.j2 deleted file mode 100644 index cf65b71eaef3..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/pointer/encoder/variable_length_string.j2 +++ /dev/null @@ -1,8 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} -{% if annotate %} - /* member {{ name }} (variable-length string) */ -{% endif %} - if (value->{{ name }}.len > {{ maxsize }}) - return false; - if (xdr_stream_encode_opaque(xdr, value->{{ name }}.data, value->{{ name }}.len) < 0) - return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/decoder/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/decoder/string.j2 new file mode 100644 index 000000000000..12d20b143b43 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/struct/decoder/string.j2 @@ -0,0 +1,6 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +{% if annotate %} + /* member {{ name }} (variable-length string) */ +{% endif %} + if (!xdrgen_decode_string(xdr, (string *)ptr, {{ maxsize }})) + return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/decoder/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/decoder/variable_length_string.j2 deleted file mode 100644 index 12d20b143b43..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/struct/decoder/variable_length_string.j2 +++ /dev/null @@ -1,6 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} -{% if annotate %} - /* member {{ name }} (variable-length string) */ -{% endif %} - if (!xdrgen_decode_string(xdr, (string *)ptr, {{ maxsize }})) - return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/definition/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/definition/string.j2 new file mode 100644 index 000000000000..2de2feec77db --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/struct/definition/string.j2 @@ -0,0 +1,5 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +{% if annotate %} + /* (variable-length string) */ +{% endif %} + string {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/definition/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/definition/variable_length_string.j2 deleted file mode 100644 index 2de2feec77db..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/struct/definition/variable_length_string.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} -{% if annotate %} - /* (variable-length string) */ -{% endif %} - string {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/encoder/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/encoder/string.j2 new file mode 100644 index 000000000000..cf65b71eaef3 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/struct/encoder/string.j2 @@ -0,0 +1,8 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +{% if annotate %} + /* member {{ name }} (variable-length string) */ +{% endif %} + if (value->{{ name }}.len > {{ maxsize }}) + return false; + if (xdr_stream_encode_opaque(xdr, value->{{ name }}.data, value->{{ name }}.len) < 0) + return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/encoder/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/encoder/variable_length_string.j2 deleted file mode 100644 index cf65b71eaef3..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/struct/encoder/variable_length_string.j2 +++ /dev/null @@ -1,8 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} -{% if annotate %} - /* member {{ name }} (variable-length string) */ -{% endif %} - if (value->{{ name }}.len > {{ maxsize }}) - return false; - if (xdr_stream_encode_opaque(xdr, value->{{ name }}.data, value->{{ name }}.len) < 0) - return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/string.j2 new file mode 100644 index 000000000000..3fe3ddd9f359 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/string.j2 @@ -0,0 +1,4 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + +bool xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ classifier }}{{ name }} *ptr); +bool xdrgen_encode_{{ name }}(struct xdr_stream *xdr, const {{ classifier }}{{ name }} value); diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/variable_length_string.j2 deleted file mode 100644 index 3fe3ddd9f359..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/typedef/declaration/variable_length_string.j2 +++ /dev/null @@ -1,4 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} - -bool xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ classifier }}{{ name }} *ptr); -bool xdrgen_encode_{{ name }}(struct xdr_stream *xdr, const {{ classifier }}{{ name }} value); diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/string.j2 new file mode 100644 index 000000000000..56c5a17d6a70 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/string.j2 @@ -0,0 +1,17 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + +{% if annotate %} +/* typedef {{ name }} */ +{% endif %} +{% if name in public_apis %} +bool +{% else %} +static bool __maybe_unused +{% endif %} +xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ classifier }}{{ name }} *ptr) +{ +{% if annotate %} + /* (variable-length string) */ +{% endif %} + return xdrgen_decode_string(xdr, ptr, {{ maxsize }}); +}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/variable_length_string.j2 deleted file mode 100644 index 56c5a17d6a70..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/typedef/decoder/variable_length_string.j2 +++ /dev/null @@ -1,17 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} - -{% if annotate %} -/* typedef {{ name }} */ -{% endif %} -{% if name in public_apis %} -bool -{% else %} -static bool __maybe_unused -{% endif %} -xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ classifier }}{{ name }} *ptr) -{ -{% if annotate %} - /* (variable-length string) */ -{% endif %} - return xdrgen_decode_string(xdr, ptr, {{ maxsize }}); -}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/definition/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/definition/string.j2 new file mode 100644 index 000000000000..c03c2df8e625 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/definition/string.j2 @@ -0,0 +1,6 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + +{% if annotate %} +/* typedef {{ name }} (variable-length string) */ +{% endif %} +typedef string {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/definition/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/definition/variable_length_string.j2 deleted file mode 100644 index c03c2df8e625..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/typedef/definition/variable_length_string.j2 +++ /dev/null @@ -1,6 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} - -{% if annotate %} -/* typedef {{ name }} (variable-length string) */ -{% endif %} -typedef string {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/string.j2 new file mode 100644 index 000000000000..3d490ff180d0 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/string.j2 @@ -0,0 +1,17 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + +{% if annotate %} +/* typedef {{ name }} */ +{% endif %} +{% if name in public_apis %} +bool +{% else %} +static bool __maybe_unused +{% endif %} +xdrgen_encode_{{ name }}(struct xdr_stream *xdr, const {{ classifier }}{{ name }} value) +{ +{% if annotate %} + /* (variable-length string) */ +{% endif %} + return xdr_stream_encode_opaque(xdr, value.data, value.len) >= 0; +}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/variable_length_string.j2 deleted file mode 100644 index 3d490ff180d0..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/typedef/encoder/variable_length_string.j2 +++ /dev/null @@ -1,17 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} - -{% if annotate %} -/* typedef {{ name }} */ -{% endif %} -{% if name in public_apis %} -bool -{% else %} -static bool __maybe_unused -{% endif %} -xdrgen_encode_{{ name }}(struct xdr_stream *xdr, const {{ classifier }}{{ name }} value) -{ -{% if annotate %} - /* (variable-length string) */ -{% endif %} - return xdr_stream_encode_opaque(xdr, value.data, value.len) >= 0; -}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/union/decoder/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/union/decoder/string.j2 new file mode 100644 index 000000000000..83b6e5a14e7f --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/union/decoder/string.j2 @@ -0,0 +1,6 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +{% if annotate %} + /* member {{ name }} (variable-length string) */ +{% endif %} + if (!xdrgen_decode_string(xdr, (struct string *)ptr->u.{{ name }}, {{ maxsize }})) + return false; diff --git a/tools/net/sunrpc/xdrgen/templates/C/union/decoder/variable_length_string.j2 b/tools/net/sunrpc/xdrgen/templates/C/union/decoder/variable_length_string.j2 deleted file mode 100644 index 83b6e5a14e7f..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/union/decoder/variable_length_string.j2 +++ /dev/null @@ -1,6 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} -{% if annotate %} - /* member {{ name }} (variable-length string) */ -{% endif %} - if (!xdrgen_decode_string(xdr, (struct string *)ptr->u.{{ name }}, {{ maxsize }})) - return false; diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 5d96c544a07b..17d1689b5858 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -88,12 +88,12 @@ class _XdrVariableLengthOpaque(_XdrDeclaration): @dataclass -class _XdrVariableLengthString(_XdrDeclaration): +class _XdrString(_XdrDeclaration): """A (NUL-terminated) variable-length string declaration""" name: str maxsize: str - template: str = "variable_length_string" + template: str = "string" @dataclass @@ -350,15 +350,15 @@ class ParseToAst(Transformer): return _XdrVariableLengthOpaque(name, maxsize) - def variable_length_string(self, children): - """Instantiate one _XdrVariableLengthString declaration object""" + def string(self, children): + """Instantiate one _XdrString declaration object""" name = children[0].symbol if children[1] is not None: maxsize = children[1].value else: maxsize = "0" - return _XdrVariableLengthString(name, maxsize) + return _XdrString(name, maxsize) def fixed_length_array(self, children): """Instantiate one _XdrFixedLengthArray declaration object""" -- cgit v1.2.3 From c060f8168bdf22aa986970955af99702d142dfbe Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 29 Sep 2024 20:50:14 -0400 Subject: xdrgen: Rename enum's declaration Jinja2 template "close.j2" is a confusing name. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/generators/enum.py | 2 +- tools/net/sunrpc/xdrgen/templates/C/enum/declaration/close.j2 | 4 ---- tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 | 4 ++++ 3 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 tools/net/sunrpc/xdrgen/templates/C/enum/declaration/close.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/generators/enum.py b/tools/net/sunrpc/xdrgen/generators/enum.py index 855e43f4ae38..e37b5c297821 100644 --- a/tools/net/sunrpc/xdrgen/generators/enum.py +++ b/tools/net/sunrpc/xdrgen/generators/enum.py @@ -18,7 +18,7 @@ class XdrEnumGenerator(SourceGenerator): def emit_declaration(self, node: _XdrEnum) -> None: """Emit one declaration pair for an XDR enum type""" if node.name in public_apis: - template = self.environment.get_template("declaration/close.j2") + template = self.environment.get_template("declaration/enum.j2") print(template.render(name=node.name)) def emit_definition(self, node: _XdrEnum) -> None: diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/close.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/close.j2 deleted file mode 100644 index ab1e576c9531..000000000000 --- a/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/close.j2 +++ /dev/null @@ -1,4 +0,0 @@ -{# SPDX-License-Identifier: GPL-2.0 #} - -bool xdrgen_decode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} *ptr); -bool xdrgen_encode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} value); diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 new file mode 100644 index 000000000000..ab1e576c9531 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 @@ -0,0 +1,4 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + +bool xdrgen_decode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} *ptr); +bool xdrgen_encode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} value); -- cgit v1.2.3 From 6e853dcd2d3d6f796597c1042340a2de0ce2469f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 29 Sep 2024 20:50:15 -0400 Subject: xdrgen: Rename "enum yada" types as just "yada" This simplifies the generated C code and makes way for supporting big-endian XDR enums. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 | 4 ++-- tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2 | 2 +- tools/net/sunrpc/xdrgen/templates/C/enum/definition/close.j2 | 1 + tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum.j2 | 2 +- tools/net/sunrpc/xdrgen/xdr_ast.py | 4 ---- 5 files changed, 5 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 index ab1e576c9531..d1405c7c5354 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/declaration/enum.j2 @@ -1,4 +1,4 @@ {# SPDX-License-Identifier: GPL-2.0 #} -bool xdrgen_decode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} *ptr); -bool xdrgen_encode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} value); +bool xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ name }} *ptr); +bool xdrgen_encode_{{ name }}(struct xdr_stream *xdr, {{ name }} value); diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2 index 341d829afeda..6482984f1cb7 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum.j2 @@ -8,7 +8,7 @@ bool {% else %} static bool __maybe_unused {% endif %} -xdrgen_decode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} *ptr) +xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ name }} *ptr) { u32 val; diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/definition/close.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/definition/close.j2 index 9e62344a976a..a07586cbee17 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/enum/definition/close.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/definition/close.j2 @@ -1,2 +1,3 @@ {# SPDX-License-Identifier: GPL-2.0 #} }; +typedef enum {{ name }} {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum.j2 index bd0a770e50f2..67245b9a914d 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum.j2 @@ -8,7 +8,7 @@ bool {% else %} static bool __maybe_unused {% endif %} -xdrgen_encode_{{ name }}(struct xdr_stream *xdr, enum {{ name }} value) +xdrgen_encode_{{ name }}(struct xdr_stream *xdr, {{ name }} value) { return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; } diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 17d1689b5858..576e1ecfe1d7 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -15,7 +15,6 @@ this_module = sys.modules[__name__] excluded_apis = [] header_name = "none" public_apis = [] -enums = set() structs = set() pass_by_reference = set() @@ -294,8 +293,6 @@ class ParseToAst(Transformer): c_classifier = "" if isinstance(children[0], _XdrIdentifier): name = children[0].symbol - if name in enums: - c_classifier = "enum " if name in structs: c_classifier = "struct " return _XdrDefinedType( @@ -320,7 +317,6 @@ class ParseToAst(Transformer): def enum(self, children): """Instantiate one _XdrEnum object""" enum_name = children[0].symbol - enums.add(enum_name) i = 0 enumerators = [] -- cgit v1.2.3 From b376d519bd142c65ba9bba35db12b6be95b46893 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 29 Sep 2024 20:50:16 -0400 Subject: xdrgen: Implement big-endian enums Signed-off-by: Chuck Lever --- include/linux/sunrpc/xdr.h | 21 +++++++++++++ tools/net/sunrpc/xdrgen/README | 17 +++++++++++ tools/net/sunrpc/xdrgen/generators/enum.py | 17 ++++++++--- tools/net/sunrpc/xdrgen/generators/union.py | 34 ++++++++++++++++------ tools/net/sunrpc/xdrgen/grammars/xdr.lark | 4 ++- .../xdrgen/templates/C/enum/decoder/enum_be.j2 | 14 +++++++++ .../xdrgen/templates/C/enum/definition/close_be.j2 | 3 ++ .../xdrgen/templates/C/enum/encoder/enum_be.j2 | 14 +++++++++ .../templates/C/union/decoder/case_spec_be.j2 | 2 ++ .../templates/C/union/encoder/case_spec_be.j2 | 2 ++ tools/net/sunrpc/xdrgen/xdr_ast.py | 3 ++ 11 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/enum/definition/close_be.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum_be.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/union/decoder/case_spec_be.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/union/encoder/case_spec_be.j2 (limited to 'tools') diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 5f775e104f9a..a2ab813a9800 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -680,6 +680,27 @@ xdr_stream_decode_u32(struct xdr_stream *xdr, __u32 *ptr) return 0; } +/** + * xdr_stream_decode_be32 - Decode a big-endian 32-bit integer + * @xdr: pointer to xdr_stream + * @ptr: location to store integer + * + * Return values: + * %0 on success + * %-EBADMSG on XDR buffer overflow + */ +static inline ssize_t +xdr_stream_decode_be32(struct xdr_stream *xdr, __be32 *ptr) +{ + const size_t count = sizeof(*ptr); + __be32 *p = xdr_inline_decode(xdr, count); + + if (unlikely(!p)) + return -EBADMSG; + *ptr = *p; + return 0; +} + /** * xdr_stream_decode_u64 - Decode a 64-bit integer * @xdr: pointer to xdr_stream diff --git a/tools/net/sunrpc/xdrgen/README b/tools/net/sunrpc/xdrgen/README index 92f7738ad50c..27218a78ab40 100644 --- a/tools/net/sunrpc/xdrgen/README +++ b/tools/net/sunrpc/xdrgen/README @@ -150,6 +150,23 @@ Pragma directives specify exceptions to the normal generation of encoding and decoding functions. Currently one directive is implemented: "public". +Pragma big_endian +------ ---------- + + pragma big_endian ; + +For variables that might contain only a small number values, it +is more efficient to avoid the byte-swap when encoding or decoding +on little-endian machines. Such is often the case with error status +codes. For example: + + pragma big_endian nfsstat3; + +In this case, when generating an XDR struct or union containing a +field of type "nfsstat3", xdrgen will make the type of that field +"__be32" instead of "enum nfsstat3". XDR unions then switch on the +non-byte-swapped value of that field. + Pragma exclude ------ ------- diff --git a/tools/net/sunrpc/xdrgen/generators/enum.py b/tools/net/sunrpc/xdrgen/generators/enum.py index e37b5c297821..e63f45b8eb74 100644 --- a/tools/net/sunrpc/xdrgen/generators/enum.py +++ b/tools/net/sunrpc/xdrgen/generators/enum.py @@ -4,7 +4,7 @@ """Generate code to handle XDR enum types""" from generators import SourceGenerator, create_jinja2_environment -from xdr_ast import _XdrEnum, public_apis +from xdr_ast import _XdrEnum, public_apis, big_endian class XdrEnumGenerator(SourceGenerator): @@ -30,15 +30,24 @@ class XdrEnumGenerator(SourceGenerator): for enumerator in node.enumerators: print(template.render(name=enumerator.name, value=enumerator.value)) - template = self.environment.get_template("definition/close.j2") + if node.name in big_endian: + template = self.environment.get_template("definition/close_be.j2") + else: + template = self.environment.get_template("definition/close.j2") print(template.render(name=node.name)) def emit_decoder(self, node: _XdrEnum) -> None: """Emit one decoder function for an XDR enum type""" - template = self.environment.get_template("decoder/enum.j2") + if node.name in big_endian: + template = self.environment.get_template("decoder/enum_be.j2") + else: + template = self.environment.get_template("decoder/enum.j2") print(template.render(name=node.name)) def emit_encoder(self, node: _XdrEnum) -> None: """Emit one encoder function for an XDR enum type""" - template = self.environment.get_template("encoder/enum.j2") + if node.name in big_endian: + template = self.environment.get_template("encoder/enum_be.j2") + else: + template = self.environment.get_template("encoder/enum.j2") print(template.render(name=node.name)) diff --git a/tools/net/sunrpc/xdrgen/generators/union.py b/tools/net/sunrpc/xdrgen/generators/union.py index 7974967bbb9f..4522a5b7a943 100644 --- a/tools/net/sunrpc/xdrgen/generators/union.py +++ b/tools/net/sunrpc/xdrgen/generators/union.py @@ -8,7 +8,7 @@ from jinja2 import Environment from generators import SourceGenerator from generators import create_jinja2_environment, get_jinja2_template -from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid +from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid, big_endian from xdr_ast import _XdrDeclaration, _XdrCaseSpec, public_apis @@ -77,13 +77,18 @@ def emit_union_switch_spec_decoder( print(template.render(name=node.name, type=node.spec.type_name)) -def emit_union_case_spec_decoder(environment: Environment, node: _XdrCaseSpec) -> None: +def emit_union_case_spec_decoder( + environment: Environment, node: _XdrCaseSpec, big_endian_discriminant: bool +) -> None: """Emit decoder functions for an XDR union's case arm""" if isinstance(node.arm, _XdrVoid): return - template = get_jinja2_template(environment, "decoder", "case_spec") + if big_endian_discriminant: + template = get_jinja2_template(environment, "decoder", "case_spec_be") + else: + template = get_jinja2_template(environment, "decoder", "case_spec") for case in node.values: print(template.render(case=case)) @@ -136,7 +141,11 @@ def emit_union_decoder(environment: Environment, node: _XdrUnion) -> None: emit_union_switch_spec_decoder(environment, node.discriminant) for case in node.cases: - emit_union_case_spec_decoder(environment, case) + emit_union_case_spec_decoder( + environment, + case, + node.discriminant.spec.type_name in big_endian, + ) emit_union_default_spec_decoder(environment, node) @@ -153,17 +162,21 @@ def emit_union_switch_spec_encoder( print(template.render(name=node.name, type=node.spec.type_name)) -def emit_union_case_spec_encoder(environment: Environment, node: _XdrCaseSpec) -> None: +def emit_union_case_spec_encoder( + environment: Environment, node: _XdrCaseSpec, big_endian_discriminant: bool +) -> None: """Emit encoder functions for an XDR union's case arm""" if isinstance(node.arm, _XdrVoid): return - template = get_jinja2_template(environment, "encoder", "case_spec") + if big_endian_discriminant: + template = get_jinja2_template(environment, "encoder", "case_spec_be") + else: + template = get_jinja2_template(environment, "encoder", "case_spec") for case in node.values: print(template.render(case=case)) - assert isinstance(node.arm, _XdrBasic) template = get_jinja2_template(environment, "encoder", node.arm.template) print( template.render( @@ -192,7 +205,6 @@ def emit_union_default_spec_encoder(environment: Environment, node: _XdrUnion) - print(template.render()) return - assert isinstance(default_case.arm, _XdrBasic) template = get_jinja2_template(environment, "encoder", default_case.arm.template) print( template.render( @@ -210,7 +222,11 @@ def emit_union_encoder(environment, node: _XdrUnion) -> None: emit_union_switch_spec_encoder(environment, node.discriminant) for case in node.cases: - emit_union_case_spec_encoder(environment, case) + emit_union_case_spec_encoder( + environment, + case, + node.discriminant.spec.type_name in big_endian, + ) emit_union_default_spec_encoder(environment, node) diff --git a/tools/net/sunrpc/xdrgen/grammars/xdr.lark b/tools/net/sunrpc/xdrgen/grammars/xdr.lark index 0e1aeb02d667..7c2c1b8c86d1 100644 --- a/tools/net/sunrpc/xdrgen/grammars/xdr.lark +++ b/tools/net/sunrpc/xdrgen/grammars/xdr.lark @@ -87,12 +87,14 @@ procedure_def : type_specifier identifier "(" type_specifier ")" "=" c pragma_def : "pragma" directive identifier [ identifier ] ";" -directive : exclude_directive +directive : big_endian_directive + | exclude_directive | header_directive | pages_directive | public_directive | skip_directive +big_endian_directive : "big_endian" exclude_directive : "exclude" header_directive : "header" pages_directive : "pages" diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2 new file mode 100644 index 000000000000..44c391c10b42 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/decoder/enum_be.j2 @@ -0,0 +1,14 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + +{% if annotate %} +/* enum {{ name }} (big-endian) */ +{% endif %} +{% if name in public_apis %} +bool +{% else %} +static bool __maybe_unused +{% endif %} +xdrgen_decode_{{ name }}(struct xdr_stream *xdr, {{ name }} *ptr) +{ + return xdr_stream_decode_be32(xdr, ptr) == 0; +} diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/definition/close_be.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/definition/close_be.j2 new file mode 100644 index 000000000000..2c18948bddf7 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/definition/close_be.j2 @@ -0,0 +1,3 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +}; +typedef __be32 {{ name }}; diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum_be.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum_be.j2 new file mode 100644 index 000000000000..fbbcc45948d6 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/encoder/enum_be.j2 @@ -0,0 +1,14 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + +{% if annotate %} +/* enum {{ name }} (big-endian) */ +{% endif %} +{% if name in public_apis %} +bool +{% else %} +static bool __maybe_unused +{% endif %} +xdrgen_encode_{{ name }}(struct xdr_stream *xdr, {{ name }} value) +{ + return xdr_stream_encode_be32(xdr, value) == XDR_UNIT; +} diff --git a/tools/net/sunrpc/xdrgen/templates/C/union/decoder/case_spec_be.j2 b/tools/net/sunrpc/xdrgen/templates/C/union/decoder/case_spec_be.j2 new file mode 100644 index 000000000000..917f3a1c4588 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/union/decoder/case_spec_be.j2 @@ -0,0 +1,2 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + case __constant_cpu_to_be32({{ case }}): diff --git a/tools/net/sunrpc/xdrgen/templates/C/union/encoder/case_spec_be.j2 b/tools/net/sunrpc/xdrgen/templates/C/union/encoder/case_spec_be.j2 new file mode 100644 index 000000000000..917f3a1c4588 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/union/encoder/case_spec_be.j2 @@ -0,0 +1,2 @@ +{# SPDX-License-Identifier: GPL-2.0 #} + case __constant_cpu_to_be32({{ case }}): diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 576e1ecfe1d7..d5f0535ec84c 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -12,6 +12,7 @@ from lark.tree import Meta this_module = sys.modules[__name__] +big_endian = [] excluded_apis = [] header_name = "none" public_apis = [] @@ -480,6 +481,8 @@ class ParseToAst(Transformer): """Instantiate one _Pragma object""" directive = children[0].children[0].data match directive: + case "big_endian_directive": + big_endian.append(children[1].symbol) case "exclude_directive": excluded_apis.append(children[1].symbol) case "header_directive": -- cgit v1.2.3 From 1acd13cbc7c9c69a09e5d8325cf6c3e3f0a75049 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:31 -0400 Subject: xdrgen: Refactor transformer arms Clean up: Add a __post_init__ function to the data classes that need to update the "structs" and "pass_by_reference" sets. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 57 ++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index d5f0535ec84c..68f09945f2c4 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -51,13 +51,17 @@ class _XdrTypeSpecifier(_XdrAst): """Corresponds to 'type_specifier' in the XDR language grammar""" type_name: str - c_classifier: str + c_classifier: str = "" @dataclass class _XdrDefinedType(_XdrTypeSpecifier): """Corresponds to a type defined by the input specification""" + def __post_init__(self): + if self.type_name in structs: + self.c_classifier = "struct " + @dataclass class _XdrBuiltInType(_XdrTypeSpecifier): @@ -124,6 +128,10 @@ class _XdrOptionalData(_XdrDeclaration): spec: _XdrTypeSpecifier template: str = "optional_data" + def __post_init__(self): + structs.add(self.name) + pass_by_reference.add(self.name) + @dataclass class _XdrBasic(_XdrDeclaration): @@ -174,6 +182,10 @@ class _XdrStruct(_XdrAst): name: str fields: List[_XdrDeclaration] + def __post_init__(self): + structs.add(self.name) + pass_by_reference.add(self.name) + @dataclass class _XdrPointer(_XdrAst): @@ -182,6 +194,10 @@ class _XdrPointer(_XdrAst): name: str fields: List[_XdrDeclaration] + def __post_init__(self): + structs.add(self.name) + pass_by_reference.add(self.name) + @dataclass class _XdrTypedef(_XdrAst): @@ -189,6 +205,15 @@ class _XdrTypedef(_XdrAst): declaration: _XdrDeclaration + def __post_init__(self): + if not isinstance(self.declaration, _XdrBasic): + return + + new_type = self.declaration + if isinstance(new_type.spec, _XdrDefinedType): + if new_type.spec.type_name in pass_by_reference: + pass_by_reference.add(new_type.name) + @dataclass class _XdrCaseSpec(_XdrAst): @@ -216,6 +241,10 @@ class _XdrUnion(_XdrAst): cases: List[_XdrCaseSpec] default: _XdrDeclaration + def __post_init__(self): + structs.add(self.name) + pass_by_reference.add(self.name) + @dataclass class _RpcProcedure(_XdrAst): @@ -290,22 +319,13 @@ class ParseToAst(Transformer): return _XdrConstantValue(value) def type_specifier(self, children): - """Instantiate one type_specifier object""" - c_classifier = "" + """Instantiate one _XdrTypeSpecifier object""" if isinstance(children[0], _XdrIdentifier): name = children[0].symbol - if name in structs: - c_classifier = "struct " - return _XdrDefinedType( - type_name=name, - c_classifier=c_classifier, - ) + return _XdrDefinedType(type_name=name) name = children[0].data.value - return _XdrBuiltInType( - type_name=name, - c_classifier=c_classifier, - ) + return _XdrBuiltInType(type_name=name) def constant_def(self, children): """Instantiate one _XdrConstant object""" @@ -380,8 +400,6 @@ class ParseToAst(Transformer): """Instantiate one _XdrOptionalData declaration object""" spec = children[0] name = children[1].symbol - structs.add(name) - pass_by_reference.add(name) return _XdrOptionalData(name, spec) @@ -400,8 +418,6 @@ class ParseToAst(Transformer): def struct(self, children): """Instantiate one _XdrStruct object""" name = children[0].symbol - structs.add(name) - pass_by_reference.add(name) fields = children[1].children last_field = fields[-1] @@ -416,11 +432,6 @@ class ParseToAst(Transformer): def typedef(self, children): """Instantiate one _XdrTypedef object""" new_type = children[0] - if isinstance(new_type, _XdrBasic) and isinstance( - new_type.spec, _XdrDefinedType - ): - if new_type.spec.type_name in pass_by_reference: - pass_by_reference.add(new_type.name) return _XdrTypedef(new_type) @@ -442,8 +453,6 @@ class ParseToAst(Transformer): def union(self, children): """Instantiate one _XdrUnion object""" name = children[0].symbol - structs.add(name) - pass_by_reference.add(name) body = children[1] discriminant = body.children[0].children[0] -- cgit v1.2.3 From 189f55d93d3eb76d733c28f0c70fd2d162a9ffc5 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:32 -0400 Subject: xdrgen: Track constant values In order to compute the numeric on-the-wire width of XDR types, xdrgen needs to keep track of the numeric value of constants that are defined in the input specification so it can perform calculations with those values. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 68f09945f2c4..b7df45f47707 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -19,6 +19,8 @@ public_apis = [] structs = set() pass_by_reference = set() +constants = {} + @dataclass class _XdrAst(ast_utils.Ast): @@ -156,6 +158,10 @@ class _XdrConstant(_XdrAst): name: str value: str + def __post_init__(self): + if self.value not in constants: + constants[self.name] = int(self.value, 0) + @dataclass class _XdrEnumerator(_XdrAst): @@ -164,6 +170,10 @@ class _XdrEnumerator(_XdrAst): name: str value: str + def __post_init__(self): + if self.value not in constants: + constants[self.name] = int(self.value, 0) + @dataclass class _XdrEnum(_XdrAst): -- cgit v1.2.3 From 631c2925bae41c11dcf3915a2ab5f3be9af54277 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:33 -0400 Subject: xdrgen: Keep track of on-the-wire data type widths The generic parts of the RPC layer need to know the widths (in XDR_UNIT increments) of the XDR data types defined for each protocol. As a first step, add dictionaries to keep track of the symbolic and actual maximum XDR width of XDR types. This makes it straightforward to look up the width of a type by its name. The built-in dictionaries are pre-loaded with the widths of the built-in XDR types as defined in RFC 4506. Signed-off-by: Chuck Lever --- include/linux/sunrpc/xdrgen/_defs.h | 9 ++++++++ tools/net/sunrpc/xdrgen/xdr_ast.py | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) (limited to 'tools') diff --git a/include/linux/sunrpc/xdrgen/_defs.h b/include/linux/sunrpc/xdrgen/_defs.h index be9e62371758..20c7270aa64d 100644 --- a/include/linux/sunrpc/xdrgen/_defs.h +++ b/include/linux/sunrpc/xdrgen/_defs.h @@ -23,4 +23,13 @@ typedef struct { u8 *data; } opaque; +#define XDR_void (0) +#define XDR_bool (1) +#define XDR_int (1) +#define XDR_unsigned_int (1) +#define XDR_long (1) +#define XDR_unsigned_long (1) +#define XDR_hyper (2) +#define XDR_unsigned_hyper (2) + #endif /* _SUNRPC_XDRGEN__DEFS_H_ */ diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index b7df45f47707..f1d93a1d0ed8 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -21,6 +21,31 @@ pass_by_reference = set() constants = {} +symbolic_widths = { + "void": ["XDR_void"], + "bool": ["XDR_bool"], + "int": ["XDR_int"], + "unsigned_int": ["XDR_unsigned_int"], + "long": ["XDR_long"], + "unsigned_long": ["XDR_unsigned_long"], + "hyper": ["XDR_hyper"], + "unsigned_hyper": ["XDR_unsigned_hyper"], +} + +# Numeric XDR widths are tracked in a dictionary that is keyed +# by type_name because sometimes a caller has nothing more than +# the type_name to use to figure out the numeric width. +max_widths = { + "void": 0, + "bool": 1, + "int": 1, + "unsigned_int": 1, + "long": 1, + "unsigned_long": 1, + "hyper": 2, + "unsigned_hyper": 2, +} + @dataclass class _XdrAst(ast_utils.Ast): @@ -60,15 +85,24 @@ class _XdrTypeSpecifier(_XdrAst): class _XdrDefinedType(_XdrTypeSpecifier): """Corresponds to a type defined by the input specification""" + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return [get_header_name().upper() + "_" + self.type_name + "_sz"] + def __post_init__(self): if self.type_name in structs: self.c_classifier = "struct " + symbolic_widths[self.type_name] = self.symbolic_width() @dataclass class _XdrBuiltInType(_XdrTypeSpecifier): """Corresponds to a built-in XDR type""" + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return symbolic_widths[self.type_name] + @dataclass class _XdrDeclaration(_XdrAst): @@ -148,8 +182,17 @@ class _XdrBasic(_XdrDeclaration): class _XdrVoid(_XdrDeclaration): """A void declaration""" + name: str = "void" template: str = "void" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return 0 + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return [] + @dataclass class _XdrConstant(_XdrAst): -- cgit v1.2.3 From 3f890755c8f5958ef537a6d8f14de5ec4bfdc3fe Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:34 -0400 Subject: xdrgen: XDR widths for enum types RFC 4506 says that an XDR enum is represented as a signed integer on the wire; thus its width is 1 XDR_UNIT. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index f1d93a1d0ed8..fbee954c7f70 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -227,6 +227,18 @@ class _XdrEnum(_XdrAst): maximum: int enumerators: List[_XdrEnumerator] + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return 1 + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return ["XDR_int"] + + def __post_init__(self): + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() + @dataclass class _XdrStruct(_XdrAst): -- cgit v1.2.3 From 16c98ce04a6929019f66dab40367fb14d0afc678 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:35 -0400 Subject: xdrgen: XDR width for fixed-length opaque The XDR width for a fixed-length opaque is the byte size of the opaque rounded up to the next XDR_UNIT, divided by XDR_UNIT. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index fbee954c7f70..9fe7fa688caa 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -21,6 +21,16 @@ pass_by_reference = set() constants = {} + +def xdr_quadlen(val: str) -> int: + """Return integer XDR width of an XDR type""" + if val in constants: + octets = constants[val] + else: + octets = int(val) + return int((octets + 3) / 4) + + symbolic_widths = { "void": ["XDR_void"], "bool": ["XDR_bool"], @@ -117,6 +127,18 @@ class _XdrFixedLengthOpaque(_XdrDeclaration): size: str template: str = "fixed_length_opaque" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return xdr_quadlen(self.size) + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return ["XDR_QUADLEN(" + self.size + ")"] + + def __post_init__(self): + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() + @dataclass class _XdrVariableLengthOpaque(_XdrDeclaration): -- cgit v1.2.3 From b0b85ef754740102cd659aea10aa516fe27f6b36 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:36 -0400 Subject: xdrgen: XDR width for variable-length opaque The byte size of a variable-length opaque is conveyed in an unsigned integer. If there is a specified maximum size, that is included in the type's widths list. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 9fe7fa688caa..94cdcfb36e77 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -148,6 +148,21 @@ class _XdrVariableLengthOpaque(_XdrDeclaration): maxsize: str template: str = "variable_length_opaque" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return 1 + xdr_quadlen(self.maxsize) + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + widths = ["XDR_unsigned_int"] + if self.maxsize != "0": + widths.append("XDR_QUADLEN(" + self.maxsize + ")") + return widths + + def __post_init__(self): + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() + @dataclass class _XdrString(_XdrDeclaration): -- cgit v1.2.3 From da298d01136e2f80a1a3a47f81d8bb3ade2d306c Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:37 -0400 Subject: xdrgen: XDR width for a string A string works like a variable-length opaque. See Section 4.11 of RFC 4506. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 94cdcfb36e77..d5f48c094729 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -172,6 +172,21 @@ class _XdrString(_XdrDeclaration): maxsize: str template: str = "string" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return 1 + xdr_quadlen(self.maxsize) + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + widths = ["XDR_unsigned_int"] + if self.maxsize != "0": + widths.append("XDR_QUADLEN(" + self.maxsize + ")") + return widths + + def __post_init__(self): + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() + @dataclass class _XdrFixedLengthArray(_XdrDeclaration): -- cgit v1.2.3 From 59b01b9636646bbf2eee59e19cc7da5b584f24c7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:38 -0400 Subject: xdrgen: XDR width for fixed-length array Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index d5f48c094729..e9bc81e83b48 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -197,6 +197,19 @@ class _XdrFixedLengthArray(_XdrDeclaration): size: str template: str = "fixed_length_array" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return xdr_quadlen(self.size) * max_widths[self.spec.type_name] + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + item_width = " + ".join(symbolic_widths[self.spec.type_name]) + return ["(" + self.size + " * (" + item_width + "))"] + + def __post_init__(self): + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() + @dataclass class _XdrVariableLengthArray(_XdrDeclaration): -- cgit v1.2.3 From 2db8940e6ceda6aeb566429e8d58c34ab093d3c7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:39 -0400 Subject: xdrgen: XDR width for variable-length array Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index e9bc81e83b48..cb89d5d9987c 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -220,6 +220,22 @@ class _XdrVariableLengthArray(_XdrDeclaration): maxsize: str template: str = "variable_length_array" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return 1 + (xdr_quadlen(self.maxsize) * max_widths[self.spec.type_name]) + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + widths = ["XDR_unsigned_int"] + if self.maxsize != "0": + item_width = " + ".join(symbolic_widths[self.spec.type_name]) + widths.append("(" + self.maxsize + " * (" + item_width + "))") + return widths + + def __post_init__(self): + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() + @dataclass class _XdrOptionalData(_XdrDeclaration): -- cgit v1.2.3 From dc6fa83b6aff5c50277045f53a448afce9616b07 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:40 -0400 Subject: xdrgen: XDR width for optional_data type Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index cb89d5d9987c..f2ef78654e36 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -245,9 +245,19 @@ class _XdrOptionalData(_XdrDeclaration): spec: _XdrTypeSpecifier template: str = "optional_data" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return 1 + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return ["XDR_bool"] + def __post_init__(self): structs.add(self.name) pass_by_reference.add(self.name) + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() @dataclass -- cgit v1.2.3 From 2852c92ba1305fd2d85fd69f73bb4b43a3c58146 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:41 -0400 Subject: xdrgen: XDR width for typedef The XDR width of a typedef is the same as the width of the base type. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index f2ef78654e36..8996f26cbd55 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -268,6 +268,18 @@ class _XdrBasic(_XdrDeclaration): spec: _XdrTypeSpecifier template: str = "basic" + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return max_widths[self.spec.type_name] + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return symbolic_widths[self.spec.type_name] + + def __post_init__(self): + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() + @dataclass class _XdrVoid(_XdrDeclaration): @@ -361,14 +373,22 @@ class _XdrTypedef(_XdrAst): declaration: _XdrDeclaration - def __post_init__(self): - if not isinstance(self.declaration, _XdrBasic): - return + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + return self.declaration.max_width() - new_type = self.declaration - if isinstance(new_type.spec, _XdrDefinedType): - if new_type.spec.type_name in pass_by_reference: - pass_by_reference.add(new_type.name) + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + return self.declaration.symbolic_width() + + def __post_init__(self): + if isinstance(self.declaration, _XdrBasic): + new_type = self.declaration + if isinstance(new_type.spec, _XdrDefinedType): + if new_type.spec.type_name in pass_by_reference: + pass_by_reference.add(new_type.name) + max_widths[new_type.name] = self.max_width() + symbolic_widths[new_type.name] = self.symbolic_width() @dataclass -- cgit v1.2.3 From f4bc1e996a34a47f6c8334edcd8ddcd7dc0634b1 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:42 -0400 Subject: xdrgen: XDR width for struct types The XDR width of a struct type is the sum of the widths of each of the struct's fields. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 8996f26cbd55..f34b147c8dfd 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -350,9 +350,25 @@ class _XdrStruct(_XdrAst): name: str fields: List[_XdrDeclaration] + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + width = 0 + for field in self.fields: + width += field.max_width() + return width + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + widths = [] + for field in self.fields: + widths += field.symbolic_width() + return widths + def __post_init__(self): structs.add(self.name) pass_by_reference.add(self.name) + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() @dataclass -- cgit v1.2.3 From 447dc1efebac1484d5903ba34655289e7725df6d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:43 -0400 Subject: xdrgen: XDR width for pointer types The XDR width of a pointer type is the sum of the widths of each of the struct's fields, except for the last field. The width of the implicit boolean "value follows" field is added as well. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index f34b147c8dfd..8d53c889eee8 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -378,9 +378,26 @@ class _XdrPointer(_XdrAst): name: str fields: List[_XdrDeclaration] + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + width = 1 + for field in self.fields[0:-1]: + width += field.max_width() + return width + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + widths = [] + widths += ["XDR_bool"] + for field in self.fields[0:-1]: + widths += field.symbolic_width() + return widths + def __post_init__(self): structs.add(self.name) pass_by_reference.add(self.name) + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() @dataclass -- cgit v1.2.3 From ce5a75d9939fab904d27b403011eddd2b173b495 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:44 -0400 Subject: xdrgen: XDR width for union types Not yet complete. The tool doesn't do any math yet. Thus, even though the maximum XDR width of a union is the width of the union enumerator plus the width of its largest arm, we're using the sum of all the elements of the union for the moment. This means that buffer size requirements are overestimated, and that the generated maxsize macro cannot yet be used for determining data element alignment in the XDR buffer. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/xdr_ast.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py index 8d53c889eee8..5233e73c7046 100644 --- a/tools/net/sunrpc/xdrgen/xdr_ast.py +++ b/tools/net/sunrpc/xdrgen/xdr_ast.py @@ -450,9 +450,35 @@ class _XdrUnion(_XdrAst): cases: List[_XdrCaseSpec] default: _XdrDeclaration + def max_width(self) -> int: + """Return width of type in XDR_UNITS""" + max_width = 0 + for case in self.cases: + if case.arm.max_width() > max_width: + max_width = case.arm.max_width() + if self.default: + if self.default.arm.max_width() > max_width: + max_width = self.default.arm.max_width() + return 1 + max_width + + def symbolic_width(self) -> List: + """Return list containing XDR width of type's components""" + max_width = 0 + for case in self.cases: + if case.arm.max_width() > max_width: + max_width = case.arm.max_width() + width = case.arm.symbolic_width() + if self.default: + if self.default.arm.max_width() > max_width: + max_width = self.default.arm.max_width() + width = self.default.arm.symbolic_width() + return symbolic_widths[self.discriminant.name] + width + def __post_init__(self): structs.add(self.name) pass_by_reference.add(self.name) + max_widths[self.name] = self.max_width() + symbolic_widths[self.name] = self.symbolic_width() @dataclass -- cgit v1.2.3 From e9e1e7e75acd737cf41c6ee64d62da6ea0c10036 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:45 -0400 Subject: xdrgen: Add generator code for XDR width macros Introduce logic in the code generators to emit maxsize (XDR width) definitions. In C, these are pre-processor macros. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/generators/__init__.py | 4 ++++ tools/net/sunrpc/xdrgen/generators/enum.py | 13 ++++++++++++- tools/net/sunrpc/xdrgen/generators/pointer.py | 18 +++++++++++++++++- tools/net/sunrpc/xdrgen/generators/struct.py | 18 +++++++++++++++++- tools/net/sunrpc/xdrgen/generators/typedef.py | 18 +++++++++++++++++- tools/net/sunrpc/xdrgen/generators/union.py | 20 ++++++++++++++++++-- .../sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2 | 2 ++ .../xdrgen/templates/C/pointer/maxsize/pointer.j2 | 3 +++ .../xdrgen/templates/C/struct/maxsize/struct.j2 | 3 +++ .../xdrgen/templates/C/typedef/maxsize/basic.j2 | 3 +++ .../C/typedef/maxsize/fixed_length_opaque.j2 | 2 ++ .../xdrgen/templates/C/typedef/maxsize/string.j2 | 2 ++ .../C/typedef/maxsize/variable_length_array.j2 | 2 ++ .../C/typedef/maxsize/variable_length_opaque.j2 | 2 ++ .../sunrpc/xdrgen/templates/C/union/maxsize/union.j2 | 3 +++ 15 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2 create mode 100644 tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2 (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/generators/__init__.py b/tools/net/sunrpc/xdrgen/generators/__init__.py index fd2457461274..b98574a36a4a 100644 --- a/tools/net/sunrpc/xdrgen/generators/__init__.py +++ b/tools/net/sunrpc/xdrgen/generators/__init__.py @@ -111,3 +111,7 @@ class SourceGenerator: def emit_encoder(self, node: _XdrAst) -> None: """Emit one encoder function for this XDR type""" raise NotImplementedError("Encoder generation not supported") + + def emit_maxsize(self, node: _XdrAst) -> None: + """Emit one maxsize macro for this XDR type""" + raise NotImplementedError("Maxsize macro generation not supported") diff --git a/tools/net/sunrpc/xdrgen/generators/enum.py b/tools/net/sunrpc/xdrgen/generators/enum.py index e63f45b8eb74..e62f715d3996 100644 --- a/tools/net/sunrpc/xdrgen/generators/enum.py +++ b/tools/net/sunrpc/xdrgen/generators/enum.py @@ -4,7 +4,7 @@ """Generate code to handle XDR enum types""" from generators import SourceGenerator, create_jinja2_environment -from xdr_ast import _XdrEnum, public_apis, big_endian +from xdr_ast import _XdrEnum, public_apis, big_endian, get_header_name class XdrEnumGenerator(SourceGenerator): @@ -51,3 +51,14 @@ class XdrEnumGenerator(SourceGenerator): else: template = self.environment.get_template("encoder/enum.j2") print(template.render(name=node.name)) + + def emit_maxsize(self, node: _XdrEnum) -> None: + """Emit one maxsize macro for an XDR enum type""" + macro_name = get_header_name().upper() + "_" + node.name + "_sz" + template = self.environment.get_template("maxsize/enum.j2") + print( + template.render( + macro=macro_name, + width=" + ".join(node.symbolic_width()), + ) + ) diff --git a/tools/net/sunrpc/xdrgen/generators/pointer.py b/tools/net/sunrpc/xdrgen/generators/pointer.py index 0aa3d35203f5..6dbda60ad2db 100644 --- a/tools/net/sunrpc/xdrgen/generators/pointer.py +++ b/tools/net/sunrpc/xdrgen/generators/pointer.py @@ -12,7 +12,7 @@ from xdr_ast import _XdrBasic, _XdrString from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray from xdr_ast import _XdrOptionalData, _XdrPointer, _XdrDeclaration -from xdr_ast import public_apis +from xdr_ast import public_apis, get_header_name def emit_pointer_declaration(environment: Environment, node: _XdrPointer) -> None: @@ -247,6 +247,18 @@ def emit_pointer_encoder(environment: Environment, node: _XdrPointer) -> None: print(template.render()) +def emit_pointer_maxsize(environment: Environment, node: _XdrPointer) -> None: + """Emit one maxsize macro for an XDR pointer type""" + macro_name = get_header_name().upper() + "_" + node.name + "_sz" + template = get_jinja2_template(environment, "maxsize", "pointer") + print( + template.render( + macro=macro_name, + width=" + ".join(node.symbolic_width()), + ) + ) + + class XdrPointerGenerator(SourceGenerator): """Generate source code for XDR pointer""" @@ -270,3 +282,7 @@ class XdrPointerGenerator(SourceGenerator): def emit_encoder(self, node: _XdrPointer) -> None: """Emit one encoder function for an XDR pointer type""" emit_pointer_encoder(self.environment, node) + + def emit_maxsize(self, node: _XdrPointer) -> None: + """Emit one maxsize macro for an XDR pointer type""" + emit_pointer_maxsize(self.environment, node) diff --git a/tools/net/sunrpc/xdrgen/generators/struct.py b/tools/net/sunrpc/xdrgen/generators/struct.py index 6dd7f4d7cd53..64911de46f62 100644 --- a/tools/net/sunrpc/xdrgen/generators/struct.py +++ b/tools/net/sunrpc/xdrgen/generators/struct.py @@ -12,7 +12,7 @@ from xdr_ast import _XdrBasic, _XdrString from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray from xdr_ast import _XdrOptionalData, _XdrStruct, _XdrDeclaration -from xdr_ast import public_apis +from xdr_ast import public_apis, get_header_name def emit_struct_declaration(environment: Environment, node: _XdrStruct) -> None: @@ -247,6 +247,18 @@ def emit_struct_encoder(environment: Environment, node: _XdrStruct) -> None: print(template.render()) +def emit_struct_maxsize(environment: Environment, node: _XdrStruct) -> None: + """Emit one maxsize macro for an XDR struct type""" + macro_name = get_header_name().upper() + "_" + node.name + "_sz" + template = get_jinja2_template(environment, "maxsize", "struct") + print( + template.render( + macro=macro_name, + width=" + ".join(node.symbolic_width()), + ) + ) + + class XdrStructGenerator(SourceGenerator): """Generate source code for XDR structs""" @@ -270,3 +282,7 @@ class XdrStructGenerator(SourceGenerator): def emit_encoder(self, node: _XdrStruct) -> None: """Emit one encoder function for an XDR struct type""" emit_struct_encoder(self.environment, node) + + def emit_maxsize(self, node: _XdrStruct) -> None: + """Emit one maxsize macro for an XDR struct type""" + emit_struct_maxsize(self.environment, node) diff --git a/tools/net/sunrpc/xdrgen/generators/typedef.py b/tools/net/sunrpc/xdrgen/generators/typedef.py index 6ea98445f5c8..fab72e9d6915 100644 --- a/tools/net/sunrpc/xdrgen/generators/typedef.py +++ b/tools/net/sunrpc/xdrgen/generators/typedef.py @@ -12,7 +12,7 @@ from xdr_ast import _XdrBasic, _XdrTypedef, _XdrString from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray from xdr_ast import _XdrOptionalData, _XdrVoid, _XdrDeclaration -from xdr_ast import public_apis +from xdr_ast import public_apis, get_header_name def emit_typedef_declaration(environment: Environment, node: _XdrDeclaration) -> None: @@ -230,6 +230,18 @@ def emit_typedef_encoder(environment: Environment, node: _XdrDeclaration) -> Non raise NotImplementedError("typedef: type not recognized") +def emit_typedef_maxsize(environment: Environment, node: _XdrDeclaration) -> None: + """Emit a maxsize macro for an XDR typedef""" + macro_name = get_header_name().upper() + "_" + node.name + "_sz" + template = get_jinja2_template(environment, "maxsize", node.template) + print( + template.render( + macro=macro_name, + width=" + ".join(node.symbolic_width()), + ) + ) + + class XdrTypedefGenerator(SourceGenerator): """Generate source code for XDR typedefs""" @@ -253,3 +265,7 @@ class XdrTypedefGenerator(SourceGenerator): def emit_encoder(self, node: _XdrTypedef) -> None: """Emit one encoder function for an XDR typedef""" emit_typedef_encoder(self.environment, node.declaration) + + def emit_maxsize(self, node: _XdrTypedef) -> None: + """Emit one maxsize macro for an XDR typedef""" + emit_typedef_maxsize(self.environment, node.declaration) diff --git a/tools/net/sunrpc/xdrgen/generators/union.py b/tools/net/sunrpc/xdrgen/generators/union.py index 4522a5b7a943..2cca00e279cd 100644 --- a/tools/net/sunrpc/xdrgen/generators/union.py +++ b/tools/net/sunrpc/xdrgen/generators/union.py @@ -8,8 +8,8 @@ from jinja2 import Environment from generators import SourceGenerator from generators import create_jinja2_environment, get_jinja2_template -from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid, big_endian -from xdr_ast import _XdrDeclaration, _XdrCaseSpec, public_apis +from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid, get_header_name +from xdr_ast import _XdrDeclaration, _XdrCaseSpec, public_apis, big_endian def emit_union_declaration(environment: Environment, node: _XdrUnion) -> None: @@ -234,6 +234,18 @@ def emit_union_encoder(environment, node: _XdrUnion) -> None: print(template.render()) +def emit_union_maxsize(environment: Environment, node: _XdrUnion) -> None: + """Emit one maxsize macro for an XDR union type""" + macro_name = get_header_name().upper() + "_" + node.name + "_sz" + template = get_jinja2_template(environment, "maxsize", "union") + print( + template.render( + macro=macro_name, + width=" + ".join(node.symbolic_width()), + ) + ) + + class XdrUnionGenerator(SourceGenerator): """Generate source code for XDR unions""" @@ -257,3 +269,7 @@ class XdrUnionGenerator(SourceGenerator): def emit_encoder(self, node: _XdrUnion) -> None: """Emit one encoder function for an XDR union""" emit_union_encoder(self.environment, node) + + def emit_maxsize(self, node: _XdrUnion) -> None: + """Emit one maxsize macro for an XDR union""" + emit_union_maxsize(self.environment, node) diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2 new file mode 100644 index 000000000000..45c1d4c21b22 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2 @@ -0,0 +1,2 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2 new file mode 100644 index 000000000000..9f3bfb47d2f4 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2 @@ -0,0 +1,3 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} \ + ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2 new file mode 100644 index 000000000000..9f3bfb47d2f4 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2 @@ -0,0 +1,3 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} \ + ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2 new file mode 100644 index 000000000000..9f3bfb47d2f4 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2 @@ -0,0 +1,3 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} \ + ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2 new file mode 100644 index 000000000000..45c1d4c21b22 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2 @@ -0,0 +1,2 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2 new file mode 100644 index 000000000000..45c1d4c21b22 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2 @@ -0,0 +1,2 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2 new file mode 100644 index 000000000000..45c1d4c21b22 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2 @@ -0,0 +1,2 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2 new file mode 100644 index 000000000000..45c1d4c21b22 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2 @@ -0,0 +1,2 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} ({{ width }}) diff --git a/tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2 b/tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2 new file mode 100644 index 000000000000..9f3bfb47d2f4 --- /dev/null +++ b/tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2 @@ -0,0 +1,3 @@ +{# SPDX-License-Identifier: GPL-2.0 #} +#define {{ '{:<31}'.format(macro) }} \ + ({{ width }}) -- cgit v1.2.3 From ac159338d53b8846b020be8260884e8234572a70 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 3 Oct 2024 14:54:46 -0400 Subject: xdrgen: emit maxsize macros Add "definitions" subcommand logic to emit maxsize macros in generated code. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/subcmds/definitions.py | 24 +++++++++++++++++++++--- tools/net/sunrpc/xdrgen/subcmds/source.py | 3 +-- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/subcmds/definitions.py b/tools/net/sunrpc/xdrgen/subcmds/definitions.py index 5cd13d53221f..c956e27f37c0 100644 --- a/tools/net/sunrpc/xdrgen/subcmds/definitions.py +++ b/tools/net/sunrpc/xdrgen/subcmds/definitions.py @@ -28,9 +28,7 @@ from xdr_parse import xdr_parser, set_xdr_annotate logger.setLevel(logging.INFO) -def emit_header_definitions( - root: Specification, language: str, peer: str -) -> None: +def emit_header_definitions(root: Specification, language: str, peer: str) -> None: """Emit header definitions""" for definition in root.definitions: if isinstance(definition.value, _XdrConstant): @@ -52,6 +50,25 @@ def emit_header_definitions( gen.emit_definition(definition.value) +def emit_header_maxsize(root: Specification, language: str, peer: str) -> None: + """Emit header maxsize macros""" + print("") + for definition in root.definitions: + if isinstance(definition.value, _XdrEnum): + gen = XdrEnumGenerator(language, peer) + elif isinstance(definition.value, _XdrPointer): + gen = XdrPointerGenerator(language, peer) + elif isinstance(definition.value, _XdrTypedef): + gen = XdrTypedefGenerator(language, peer) + elif isinstance(definition.value, _XdrStruct): + gen = XdrStructGenerator(language, peer) + elif isinstance(definition.value, _XdrUnion): + gen = XdrUnionGenerator(language, peer) + else: + continue + gen.emit_maxsize(definition.value) + + def handle_parse_error(e: UnexpectedInput) -> bool: """Simple parse error reporting, no recovery attempted""" print(e) @@ -71,6 +88,7 @@ def subcmd(args: Namespace) -> int: gen.emit_definition(args.filename, ast) emit_header_definitions(ast, args.language, args.peer) + emit_header_maxsize(ast, args.language, args.peer) gen = XdrHeaderBottomGenerator(args.language, args.peer) gen.emit_definition(args.filename, ast) diff --git a/tools/net/sunrpc/xdrgen/subcmds/source.py b/tools/net/sunrpc/xdrgen/subcmds/source.py index 00c04ad15b89..2024954748f0 100644 --- a/tools/net/sunrpc/xdrgen/subcmds/source.py +++ b/tools/net/sunrpc/xdrgen/subcmds/source.py @@ -83,8 +83,7 @@ def generate_client_source(filename: str, root: Specification, language: str) -> gen = XdrSourceTopGenerator(language, "client") gen.emit_source(filename, root) - # cel: todo: client needs XDR size macros - + print("") for definition in root.definitions: emit_source_encoder(definition.value, language, "client") for definition in root.definitions: -- cgit v1.2.3 From a32442f6ca32cf402a76856d5e713bd742481ba2 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 7 Oct 2024 14:07:54 -0400 Subject: xdrgen: Add a utility for extracting XDR from RFCs For convenience, copy the XDR extraction script from RFC Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- MAINTAINERS | 1 + tools/net/sunrpc/extract.sh | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100755 tools/net/sunrpc/extract.sh (limited to 'tools') diff --git a/MAINTAINERS b/MAINTAINERS index 21fdaa19229a..f711449753b3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12367,6 +12367,7 @@ F: include/trace/misc/sunrpc.h F: include/uapi/linux/nfsd/ F: include/uapi/linux/sunrpc/ F: net/sunrpc/ +F: tools/net/sunrpc/ KERNEL PACMAN PACKAGING (in addition to generic KERNEL BUILD) M: Thomas Weißschuh diff --git a/tools/net/sunrpc/extract.sh b/tools/net/sunrpc/extract.sh new file mode 100755 index 000000000000..f944066f25bc --- /dev/null +++ b/tools/net/sunrpc/extract.sh @@ -0,0 +1,11 @@ +#! /bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Extract an RPC protocol specification from an RFC document. +# The version of this script comes from RFC 8166. +# +# Usage: +# $ extract.sh < rfcNNNN.txt > protocol.x +# + +grep '^ *///' | sed 's?^ */// ??' | sed 's?^ *///$??' -- cgit v1.2.3 From 07decac0ac6282672af182521ef0b4b61605c4b9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 22 Oct 2024 13:43:54 -0400 Subject: xdrgen: Remove tracepoint call site This tracepoint was a "note to self" and is not operational. It is added only to client-side code, which so far we haven't needed. It will cause immediate breakage once we start generating client code, though, so remove it now. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 b/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 index d304eccb5c40..38c31b3f0589 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 @@ -13,10 +13,8 @@ static int {{ program }}_xdr_dec_{{ result }}(struct rpc_rqst *req, if (!xdrgen_decode_{{ result }}(xdr, result)) return -EIO; - if (result->stat != nfs_ok) { - trace_nfs_xdr_status(xdr, (int)result->stat); + if (result->stat != nfs_ok) return {{ program }}_stat_to_errno(result->stat); - } {% endif %} return 0; } -- cgit v1.2.3 From 82c2a36179d9bd00b792f4215cc4f71ca2d4c3a8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 22 Oct 2024 13:44:01 -0400 Subject: xdrgen: Remove check for "nfs_ok" in C templates Obviously, "nfs_ok" is defined only for NFS protocols. Other XDR protocols won't know "nfs_ok" from Adam. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 b/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 index 38c31b3f0589..4ce4cc9fab79 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 @@ -13,7 +13,7 @@ static int {{ program }}_xdr_dec_{{ result }}(struct rpc_rqst *req, if (!xdrgen_decode_{{ result }}(xdr, result)) return -EIO; - if (result->stat != nfs_ok) + if (result->stat) return {{ program }}_stat_to_errno(result->stat); {% endif %} return 0; -- cgit v1.2.3 From 903a7d37d9ea03cfed21040467d3d345d1e6fc76 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 22 Oct 2024 13:44:08 -0400 Subject: xdrgen: Update the files included in client-side source code In particular, client-side source code needs the definition of "struct rpc_procinfo" and does not want header files that pull in "struct svc_rqst". Otherwise, the source does not compile. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/templates/C/source_top/client.j2 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/templates/C/source_top/client.j2 b/tools/net/sunrpc/xdrgen/templates/C/source_top/client.j2 index e3a802cbc4d7..c5518c519854 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/source_top/client.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/source_top/client.j2 @@ -3,6 +3,11 @@ // XDR specification file: {{ filename }} // XDR specification modification time: {{ mtime }} -#include +#include -#include "{{ program }}xdr_gen.h" +#include +#include +#include +#include + +#include -- cgit v1.2.3 From 573954a996c0056b25eda4638edfee8c010e27f7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 22 Oct 2024 13:44:15 -0400 Subject: xdrgen: Remove program_stat_to_errno() call sites Refactor: Translating an on-the-wire value to a local host errno is architecturally a job for the proc function, not the XDR decoder. Signed-off-by: Chuck Lever --- tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools') diff --git a/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 b/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 index 4ce4cc9fab79..aa9940e322db 100644 --- a/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 +++ b/tools/net/sunrpc/xdrgen/templates/C/program/decoder/result.j2 @@ -13,8 +13,6 @@ static int {{ program }}_xdr_dec_{{ result }}(struct rpc_rqst *req, if (!xdrgen_decode_{{ result }}(xdr, result)) return -EIO; - if (result->stat) - return {{ program }}_stat_to_errno(result->stat); {% endif %} return 0; } -- cgit v1.2.3