diff --git a/meta/Makefile b/meta/Makefile index b4711dd9c..0b437d020 100644 --- a/meta/Makefile +++ b/meta/Makefile @@ -119,13 +119,16 @@ xml: $(DEPS) Doxyfile Doxyfile.compat $(CONSTHEADERS) EXTRA = acronyms.txt aspell.en.pws *.pm *.cap +saimetadatasize.h: $(DEPS) + ./size.sh + saimetadatatest.c saimetadata.c saimetadata.h: xml $(XMLDEPS) parse.pl $(CONSTHEADERS) $(EXTRA) perl -I. parse.pl rpc sai.thrift sai_rpc_server.cpp sai_adapter.py: xml $(XMLDEPS) gensairpc.pl perl -Irpc gensairpc.pl $(GEN_SAIRPC_OPTS) -HEADERS = saimetadata.h $(CONSTHEADERS) +HEADERS = saimetadata.h saimetadatasize.h $(CONSTHEADERS) %.o: %.c $(HEADERS) $(CC) -c -o $@ $< $(CFLAGS) @@ -158,7 +161,7 @@ saidepgraph.svg: saidepgraph.gv clean: rm -f *.o *~ .*~ *.tmp .*.swp .*.swo *.bak sai*.gv sai*.svg *.o.symbols doxygen*.db - rm -f saimetadata.h saimetadata.c saimetadatatest.c + rm -f saimetadata.h saimetadatasize.h saimetadata.c saimetadatatest.c rm -f saisanitycheck saimetadatatest saiserializetest saidepgraphgen rm -f sai.thrift sai_rpc_server.cpp sai_adapter.py rm -rf xml html dist temp generated diff --git a/meta/size.pl b/meta/size.pl new file mode 100755 index 000000000..1b636a648 --- /dev/null +++ b/meta/size.pl @@ -0,0 +1,140 @@ +#!/usr/bin/perl +# +# Copyright (c) 2023 Microsoft Open Technologies, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# +# Microsoft would like to thank the following companies for their review and +# assistance with these files: Intel Corporation, Mellanox Technologies Ltd, +# Dell Products, L.P., Facebook, Inc., Marvell International Ltd. +# +# @file size.pl +# +# @brief This module defines SAI struct/union size generator +# + +BEGIN { push @INC,'.'; } + +use strict; +use warnings; +use diagnostics; +use sort 'stable'; + +use utils; +use File::Temp qw/ tempfile /; + +our $SIZE_CONTENT = ""; + +sub WriteSize +{ + my $content = shift; + + $SIZE_CONTENT .= $content . "\n"; +} + +our %STRUCTS=(); +our $TEMP_DIR = ".."; + +sub CheckArguments +{ + if (scalar @ARGV != 1) + { + print "expected 1 argument which is temporary SAI directory\n"; + exit 1; + } + + $TEMP_DIR = shift @ARGV; +} + +sub ExtractStructsAndUnions +{ + my @headers = GetHeaderFiles("$TEMP_DIR/inc/"); # we ignore experimental headers + + for my $header (@headers) + { + my $data = ReadHeaderFile("$TEMP_DIR/inc/".$header); + + my @lines = split/\n/,$data; + + for my $line (@lines) + { + next if not $line =~ /typedef\s+(?:struct|union)\s+_(sai_\w+_t)/; + + $STRUCTS{$1}=$1; + } + } +} + +sub ConstructSource +{ + my $source = "#include \n"; + + $source .= "#include \n"; + $source .= "#include \n"; + $source .= "int main() {\n"; + + for my $struct (sort keys %STRUCTS) + { + my $upname = uc($struct); + + $source .= "printf(\"#define ${upname}_SIZE (%zu)\\n\", sizeof($struct));\n"; + } + + $source .= "return 0; }"; + + return $source; +} + +sub GetValues +{ + my $dir = $TEMP_DIR; + + my $source = ConstructSource(); + + my ($fhs, $src) = tempfile( SUFFIX => '.c', UNLINK => 1 ); + + WriteFile($src, $source); + + my ($fhb, $bin) = tempfile( SUFFIX => '.bin', UNLINK => 1 ); + + LogDebug("gcc $src -I$dir/inc/ -I$dir/experimental/ -o $bin"); + + system("gcc $src -I$dir/inc/ -I$dir/experimental/ -o $bin") == 0 or die "gcc failed! $!"; + + close $fhs; + close $fhb; + + my %hash = (); + + my @lines = `$bin`; + + for my $line(@lines) + { + chomp $line; + + WriteSize($line); + } +} + +CheckArguments(); + +WriteSize("#ifndef __SAI_METADATASIZE_H__"); +WriteSize("#define __SAI_METADATASIZE_H__"); + +ExtractStructsAndUnions(); + +GetValues(); + +WriteSize("#endif /* __SAI_METADATASIZE_H__ */"); + +WriteFile("saimetadatasize.h", $SIZE_CONTENT); diff --git a/meta/size.sh b/meta/size.sh new file mode 100755 index 000000000..ee2bce8a6 --- /dev/null +++ b/meta/size.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Copyright (c) 2023 Microsoft Open Technologies, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# +# Microsoft would like to thank the following companies for their review and +# assistance with these files: Intel Corporation, Mellanox Technologies Ltd, +# Dell Products, L.P., Facebook, Inc., Marvell International Ltd. +# +# @file size.sh +# +# @brief This module generates saimetadatasize.h with struct/union sizes +# + +set -e + +TEMP_DIR="tmp" + +COMMIT=origin/master # should be corresponding branch HEAD + +rm -rf $TEMP_DIR + +mkdir $TEMP_DIR + +echo "git checkout dir inc and experimental on commit: $COMMIT" + +git --work-tree=$TEMP_DIR/ checkout $COMMIT inc experimental 2>/dev/null + +perl size.pl $TEMP_DIR + +rm -rf $TEMP_DIR diff --git a/meta/style.pm b/meta/style.pm index db39d61e7..4d12a87c9 100644 --- a/meta/style.pm +++ b/meta/style.pm @@ -682,6 +682,7 @@ sub CheckMetadataSourceFiles next if $file eq "saimetadata.h"; next if $file eq "saimetadata.c"; next if $file eq "saimetadatatest.c"; + next if $file eq "saimetadatasize.h"; next if $file =~ /swig|wrap/; @@ -901,6 +902,7 @@ sub CheckHeadersStyle for my $header (@headers) { next if $header eq "saimetadata.h"; # skip auto generated header + next if $header eq "saimetadatasize.h"; # skip auto generated header my $data = ReadHeaderFile($header); diff --git a/meta/test.pm b/meta/test.pm index a577891f3..464d322c3 100644 --- a/meta/test.pm +++ b/meta/test.pm @@ -555,6 +555,50 @@ sub CreateApiImplementedTest WriteTest "}"; } +sub CreateStructUnionSizeCheckTest +{ + my @headers = GetHeaderFiles(); # we ignore experimental headers + + my %STRUCTS = (); + + WriteTest "#pragma GCC diagnostic push"; + WriteTest "#pragma GCC diagnostic ignored \"-Wsuggest-attribute=noreturn\""; + + DefineTestName "struct_union_size"; + + WriteTest "{"; + + for my $header (@headers) + { + my $data = ReadHeaderFile($header); + + my @lines = split/\n/,$data; + + for my $line (@lines) + { + next if not $line =~ /typedef\s+(?:struct|union)\s+_(sai_\w+_t)/; + + my $name = $1; + + $STRUCTS{$name} = $name; + + next if $name =~ /^sai_\w+_api_t$/; # skip api structs + + my $upname = uc($name); + + WriteTest "#ifdef ${upname}_SIZE"; + WriteTest " TEST_ASSERT_TRUE_EXT(sizeof($name) == (${upname}_SIZE), \"wrong size of $name, expected %d, got %zu\", ${upname}_SIZE, sizeof($name));"; + WriteTest " TEST_ASSERT_TRUE_EXT(sizeof($name [3]) == (3*${upname}_SIZE), \"wrong size of $name [3], expected %d, got %zu\", 3*${upname}_SIZE, 3*sizeof($name));"; + WriteTest "#else"; + WriteTest " fprintf(stderr, \"struct/union $name not defined in base branch, skipping size check\\n\");"; + WriteTest "#endif"; + } + } + + WriteTest "}"; + WriteTest "#pragma GCC diagnostic pop"; +} + sub WriteTestHeader { # @@ -565,8 +609,10 @@ sub WriteTestHeader WriteTest "#include "; WriteTest "#include "; WriteTest "#include \"saimetadata.h\""; + WriteTest "#include \"saimetadatasize.h\""; WriteTest "#define PP(x) printf(\"%p\\n\", (x));"; WriteTest "#define TEST_ASSERT_TRUE(x,msg) if (!(x)){ fprintf(stderr, \"ASSERT TRUE FAILED(%d): %s: %s\\n\", __LINE__, #x, msg); exit(1);}"; + WriteTest "#define TEST_ASSERT_TRUE_EXT(x,format,...) if (!(x)){ fprintf(stderr, \"ASSERT TRUE FAILED(%d): %s: \" format \"\\n\", __LINE__, #x, ##__VA_ARGS__); exit(1);}"; } sub WriteTestMain @@ -645,6 +691,8 @@ sub CreateTests CreateApiImplementedTest(); + CreateStructUnionSizeCheckTest(); + CreatePragmaPop(); WriteTestMain(); diff --git a/meta/utils.pm b/meta/utils.pm index 5a7b581c6..898772bfb 100644 --- a/meta/utils.pm +++ b/meta/utils.pm @@ -390,7 +390,7 @@ sub ExitOnErrors { return if $errors == 0; - LogError "please corret all $errors error(s) before continue"; + LogError "please correct all $errors error(s) before continue"; exit 1; } @@ -399,7 +399,7 @@ sub ExitOnErrorsOrWarnings { return if $errors == 0 and $warnings == 0; - LogError "please corret all $errors error(s) and all $warnings warnings before continue"; + LogError "please correct all $errors error(s) and all $warnings warnings before continue"; exit 1; }