From patchwork Mon Nov 7 10:47:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 13034243 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0176CC4332F for ; Mon, 7 Nov 2022 10:48:03 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.439285.693330 (Exim 4.92) (envelope-from ) id 1orzfV-0002WG-QE; Mon, 07 Nov 2022 10:47:53 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 439285.693330; Mon, 07 Nov 2022 10:47:53 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfV-0002W9-NA; Mon, 07 Nov 2022 10:47:53 +0000 Received: by outflank-mailman (input) for mailman id 439285; Mon, 07 Nov 2022 10:47:52 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfU-0002Pj-Gt for xen-devel@lists.xenproject.org; Mon, 07 Nov 2022 10:47:52 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 9eebd907-5e89-11ed-8fd1-01056ac49cbb; Mon, 07 Nov 2022 11:47:49 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9397823A; Mon, 7 Nov 2022 02:47:55 -0800 (PST) Received: from e125770.cambridge.arm.com (e125770.cambridge.arm.com [10.1.195.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 23ED53F73D; Mon, 7 Nov 2022 02:47:48 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9eebd907-5e89-11ed-8fd1-01056ac49cbb From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: bertrand.marquis@arm.com, wei.chen@arm.com, Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [RFC PATCH 1/4] xen/Makefile: add analysis-coverity and analysis-eclair Date: Mon, 7 Nov 2022 10:47:36 +0000 Message-Id: <20221107104739.10404-2-luca.fancellu@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221107104739.10404-1-luca.fancellu@arm.com> References: <20221107104739.10404-1-luca.fancellu@arm.com> Add new targets to makefile, analysis-{coverity,eclair} that will: - Create a tag database using a new tool called xenfusa-gen-tags.py - Get every file with the FuSa tag SAF- in-code comment, create a copy of it as .safparse and substituting the tags with proprietary tool syntax in-code comments using the database. - build Xen, coverity and eclair are capable of intercepting the compiler invocation on every build file so the only action from them is to run these new targets, the file they will analyse will automatically contain understandable suppression in-code comment for them. - call analysis-clean to restore original files. In case of any error, the user needs to manually run the target analysis-clean to restore the original files, before that step, any following run of analysis-{coverity,eclair} will stop and won't overwrite the original files. Add in docs/misra/ the files safe.json and false-positive-{coverity,eclair}.json that are JSON files containing the data structures for the justifications, they are used by the xenfusa-gen-tags.py to create the substitution list. Add docs/misra/documenting-violations.rst to explain how to add justifications. Add files to .gitignore and update clean rule content in Makefile. Signed-off-by: Luca Fancellu --- .gitignore | 2 + docs/misra/documenting-violations.rst | 172 ++++++++++++++++++++++++ docs/misra/false-positive-coverity.json | 12 ++ docs/misra/false-positive-eclair.json | 12 ++ docs/misra/safe.json | 11 ++ xen/Makefile | 50 ++++++- xen/tools/xenfusa-gen-tags.py | 81 +++++++++++ 7 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 docs/misra/documenting-violations.rst create mode 100644 docs/misra/false-positive-coverity.json create mode 100644 docs/misra/false-positive-eclair.json create mode 100644 docs/misra/safe.json create mode 100755 xen/tools/xenfusa-gen-tags.py diff --git a/.gitignore b/.gitignore index 418bdfaebf36..b48e1e20c4fc 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ *.c.cppcheck *.opic *.a +*.safparse *.so *.so.[0-9]* *.bin @@ -314,6 +315,7 @@ xen/xsm/flask/policy.* xen/xsm/flask/xenpolicy-* tools/flask/policy/policy.conf tools/flask/policy/xenpolicy-* +xen/*.sed xen/xen xen/xen-cppcheck.xml xen/xen-syms diff --git a/docs/misra/documenting-violations.rst b/docs/misra/documenting-violations.rst new file mode 100644 index 000000000000..3430abfaa177 --- /dev/null +++ b/docs/misra/documenting-violations.rst @@ -0,0 +1,172 @@ +.. SPDX-License-Identifier: CC-BY-4.0 + +Documenting violations +====================== + +Static analysers are used on the Xen codebase for both static analysis and MISRA +compliance. +There might be the need to suppress some findings instead of fixing them and +many tools permit the usage of in-code comments that suppress findings so that +they are not shown in the final report. + +Xen includes a tool capable of translating a specific comment used in its +codebase to the right proprietary in-code comment understandable by the selected +analyser that suppress its finding. + +In the Xen codebase, these tags will be used to document and suppress findings: + + - SAF-X-safe: This tag means that the next line of code contains a finding, but + the non compliance to the checker is analysed and demonstrated to be safe. + - SAF-X-false-positive-: This tag means that the next line of code + contains a finding, but the finding is a bug of the tool. + +SAF stands for Static Analyser Finding, the X is a placeholder for a positive +number that starts from zero, the number after SAF- shall be incremental and +unique, base ten notation and without leading zeros. + +Entries in the database shall never be removed, even if they are not used +anymore in the code (if a patch is removing or modifying the faulty line). +This is to make sure that numbers are not reused which could lead to conflicts +with old branches or misleading justifications. + +An entry can be reused in multiple places in the code to suppress a finding if +and only if the justification holds for the same non-compliance to the coding +standard. + +An orphan entry, that is an entry who was justifying a finding in the code, but +later that code was removed and there is no other use of that entry in the code, +can be reused as long as the justification for the finding holds. This is done +to avoid the allocation of a new entry with exactly the same justification, that +would lead to waste of space and maintenance issues of the database. + +The files where to store all the justifications are in xen/docs/misra/ and are +named as safe.json and false-positive-.json, they have JSON format. + +Here is an example to add a new justification in safe.json:: + +|{ +| "version": "1.0", +| "content": [ +| { +| "id": "SAF-0-safe", +| "analyser": { +| "coverity": "misra_c_2012_rule_20_7_violation", +| "eclair": "MC3R1.R20.7" +| }, +| "name": "R20.7 C macro parameters not used as expression", +| "text": "The macro parameters used in this [...]" +| }, +| { +| "id": "SAF-1-safe", +| "analyser": {}, +| "name": "Sentinel", +| "text": "Next ID to be used" +| } +| ] +|} + +Here is an example to add a new justification in false-positive-.json:: + +|{ +| "version": "1.0", +| "content": [ +| { +| "id": "SAF-0-false-positive-", +| "analyser": { +| "": "" +| }, +| "tool-version": "", +| "name": "R20.7 [...]", +| "text": "[...]" +| }, +| { +| "id": "SAF-1-false-positive-", +| "analyser": {}, +| "tool-version": "", +| "name": "Sentinel", +| "text": "Next ID to be used" +| } +| ] +|} + +To document a finding, just add another block {[...]} before the sentinel block, +using the id contained in the sentinel block and increment by one the number +contained in the id of the sentinel block. + +Here an explanation of the field inside an object of the "content" array: + - id: it is a unique string that is used to refer to the finding, many finding + can be tagged with the same id, if the justification holds for any applied + case. + It tells the tool to substitute a Xen in-code comment having this structure: + /* SAF-0-safe [...] \*/ + - analyser: it is an object containing pair of key-value strings, the key is + the analyser, so it can be coverity or eclair, the value is the proprietary + id corresponding on the finding, for example when coverity is used as + analyser, the tool will translate the Xen in-code coment in this way: + /* SAF-0-safe [...] \*/ -> /* coverity[misra_c_2012_rule_20_7_violation] \*/ + if the object doesn't have a key-value, then the corresponding in-code + comment won't be translated. + - name: a simple name for the finding + - text: a proper justification to turn off the finding. + + +Justification example +--------------------- + +Here an example of the usage of the in-code comment tags to suppress a finding +for the Rule 8.6: + +Eclair reports it in its web report, file xen/include/xen/kernel.h, line 68: + +| MC3R1.R8.6 for program 'xen/xen-syms', variable '_start' has no definition + +Also coverity reports it, here is an extract of the finding: + +| xen/include/xen/kernel.h:68: +| 1. misra_c_2012_rule_8_6_violation: Function "_start" is declared but never + defined. + +The analysers are complaining because we have this in xen/include/xen/kernel.h +at line 68:: + +| extern char _start[], _end[], start[]; + +Those are symbols exported by the linker, hence we will need to have a proper +deviation for this finding. + +We will prepare our entry in the safe.json database:: + +|{ +| "version": "1.0", +| "content": [ +| { +| [...] +| }, +| { +| "id": "SAF-1-safe", +| "analyser": { +| "eclair": "MC3R1.R8.6", +| "coverity": "misra_c_2012_rule_8_6_violation" +| }, +| "name": "Rule 8.6: linker script defined symbols", +| "text": "It is safe to declare this symbol because it is defined in the linker script." +| }, +| { +| "id": "SAF-2-safe", +| "analyser": {}, +| "name": "Sentinel", +| "text": "Next ID to be used" +| } +| ] +|} + +And we will use the proper tag above the violation line:: + +| /* SAF-1-safe R8.6 linker defined symbols */ +| extern char _start[], _end[], start[]; + +This entry will fix also the violation on _end and start, because they are on +the same line and the same "violation ID". + +Also, the same tag can be used on other symbols from the linker that are +declared in the codebase, because the justification holds for them too. diff --git a/docs/misra/false-positive-coverity.json b/docs/misra/false-positive-coverity.json new file mode 100644 index 000000000000..f8e6a014acb5 --- /dev/null +++ b/docs/misra/false-positive-coverity.json @@ -0,0 +1,12 @@ +{ + "version": "1.0", + "content": [ + { + "id": "SAF-0-false-positive-coverity", + "analyser": {}, + "tool-version": "", + "name": "Sentinel", + "text": "Next ID to be used" + } + ] +} diff --git a/docs/misra/false-positive-eclair.json b/docs/misra/false-positive-eclair.json new file mode 100644 index 000000000000..63d00e160f9c --- /dev/null +++ b/docs/misra/false-positive-eclair.json @@ -0,0 +1,12 @@ +{ + "version": "1.0", + "content": [ + { + "id": "SAF-0-false-positive-eclair", + "analyser": {}, + "tool-version": "", + "name": "Sentinel", + "text": "Next ID to be used" + } + ] +} diff --git a/docs/misra/safe.json b/docs/misra/safe.json new file mode 100644 index 000000000000..e079d3038120 --- /dev/null +++ b/docs/misra/safe.json @@ -0,0 +1,11 @@ +{ + "version": "1.0", + "content": [ + { + "id": "SAF-0-safe", + "analyser": {}, + "name": "Sentinel", + "text": "Next ID to be used" + } + ] +} diff --git a/xen/Makefile b/xen/Makefile index 9d0df5e2c543..3b8d1acd1697 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -457,7 +457,8 @@ endif # need-config __all: build -main-targets := build install uninstall clean distclean MAP cppcheck cppcheck-html +main-targets := build install uninstall clean distclean MAP cppcheck \ + cppcheck-html analysis-coverity analysis-eclair .PHONY: $(main-targets) ifneq ($(XEN_TARGET_ARCH),x86_32) $(main-targets): %: _% ; @@ -572,7 +573,7 @@ _clean: rm -f $(TARGET).efi $(TARGET).efi.map $(TARGET).efi.stripped rm -f asm-offsets.s arch/*/include/asm/asm-offsets.h rm -f .banner .allconfig.tmp include/xen/compile.h - rm -f cppcheck-misra.* xen-cppcheck.xml + rm -f cppcheck-misra.* xen-cppcheck.xml *.sed .PHONY: _distclean _distclean: clean @@ -757,6 +758,51 @@ cppcheck-version: $(objtree)/include/generated/compiler-def.h: $(Q)$(CC) -dM -E -o $@ - < /dev/null +JUSTIFICATION_FILES := $(XEN_ROOT)/docs/misra/safe.json \ + $(XEN_ROOT)/docs/misra/false-positive-$$*.json + +# The following command is using grep to find all files that contains a comment +# containing "SAF-" on a single line. +# %.safparse will be the original files saved from the build system, these files +# will be restored at the end of the analysis step +PARSE_FILE_LIST := $(addsuffix .safparse,$(filter-out %.safparse,\ +$(shell grep -ERl '^[[:blank:]]*\/\*[[:space:]]+SAF-.*\*\/$$' $(srctree)))) + +.PRECIOUS: $(PARSE_FILE_LIST) $(objtree)/%.sed + +.SECONDEXPANSION: +$(objtree)/%.sed: $(JUSTIFICATION_FILES) $(srctree)/tools/xenfusa-gen-tags.py + $(PYTHON) $(srctree)/tools/xenfusa-gen-tags.py \ + $(foreach file, $(filter %.json, $^), --input $(file)) --output $@ \ + --tool $* + +%.safparse: % +# Create a copy of the original file (-p preserves also timestamp) + $(Q)if [ -f "$@" ]; then \ + echo "Found $@, please check the integrity of $*"; \ + exit 1; \ + fi + $(Q)cp -p "$*" "$@" + +analysis-parse-tags-%: $(PARSE_FILE_LIST) $(objtree)/%.sed + $(Q)for file in $(patsubst %.safparse,%,$(PARSE_FILE_LIST)); do \ + sed -i -f "$(objtree)/$*.sed" "$${file}"; \ + done + +analysis-build-%: analysis-parse-tags-% + $(MAKE) O=$(abs_objtree) -f $(srctree)/Makefile build + +analysis-clean: +# Reverts the original file (-p preserves also timestamp) + $(Q)find $(srctree) -type f -name "*.safparse" -print | \ + while IFS= read file; do \ + cp -p "$${file}" "$${file%.safparse}"; \ + rm -f "$${file}"; \ + done + +_analysis-%: analysis-build-% + $(Q)$(MAKE) O=$(abs_objtree) -f $(srctree)/Makefile analysis-clean + endif #config-build endif # need-sub-make diff --git a/xen/tools/xenfusa-gen-tags.py b/xen/tools/xenfusa-gen-tags.py new file mode 100755 index 000000000000..4ab8c0f07a52 --- /dev/null +++ b/xen/tools/xenfusa-gen-tags.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +import sys, getopt, json + +def help(): + print('Usage: {} [OPTION] ...'.format(sys.argv[0])) + print('') + print('This script converts the justification file to a set of sed rules') + print('that will replace generic tags from Xen codebase in-code comments') + print('to in-code comments having the proprietary syntax for the selected') + print('tool.') + print('') + print('Options:') + print(' -i/--input Json file containing the justifications, can be') + print(' passed multiple times for multiple files') + print(' -o/--output Sed file containing the substitution rules') + print(' -t/--tool Tool that will use the in-code comments') + print('') + +# This is the dictionary for the rules that translates to proprietary comments: +# - cppcheck: /* cppcheck-suppress[id] */ +# - coverity: /* coverity[id] */ +# - eclair: /* -E> hide id 1 "" */ +# Add entries to support more analyzers +tool_syntax = { + "cppcheck":"s,^.*/*[[:space:]]*TAG.*$,/* cppcheck-suppress[VID] */,g", + "coverity":"s,^.*/*[[:space:]]*TAG.*$,/* coverity[VID] */,g", + "eclair":"s,^.*/*[[:space:]]*TAG.*$,/* -E> hide VID 1 \"\" */,g" +} + +def main(argv): + infiles = [] + justifications = [] + outfile = '' + tool = '' + + try: + opts, args = getopt.getopt(argv,"hi:o:t:",["input=","output=","tool="]) + except getopt.GetoptError: + help() + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + help() + sys.exit(0) + elif opt in ("-i", "--input"): + infiles.append(arg) + elif opt in ("-o", "--output"): + outfile = arg + elif opt in ("-t", "--tool"): + tool = arg + + # Open all input files + for file in infiles: + try: + handle = open(file, 'rt') + content = json.load(handle) + justifications = justifications + content['content'] + handle.close() + except json.JSONDecodeError: + print('JSON decoding error in file: ' + file) + except: + print('Error opening ' + file) + sys.exit(1) + + try: + outstr = open(outfile, "w") + except: + print('Error creating ' + outfile) + sys.exit(1) + + for j in justifications: + if tool in j['analyser']: + comment=tool_syntax[tool].replace("TAG",j['id']) + comment=comment.replace("VID",j['analyser'][tool]) + outstr.write('{}\n'.format(comment)) + + outstr.close() + +if __name__ == "__main__": + main(sys.argv[1:]) \ No newline at end of file From patchwork Mon Nov 7 10:47:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 13034245 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0BC22C43219 for ; Mon, 7 Nov 2022 10:48:06 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.439287.693352 (Exim 4.92) (envelope-from ) id 1orzfY-00034T-K6; Mon, 07 Nov 2022 10:47:56 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 439287.693352; Mon, 07 Nov 2022 10:47:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfY-00034I-FG; Mon, 07 Nov 2022 10:47:56 +0000 Received: by outflank-mailman (input) for mailman id 439287; Mon, 07 Nov 2022 10:47:54 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfW-0002Pj-6U for xen-devel@lists.xenproject.org; Mon, 07 Nov 2022 10:47:54 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 9fe5345c-5e89-11ed-8fd1-01056ac49cbb; Mon, 07 Nov 2022 11:47:50 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3E80AED1; Mon, 7 Nov 2022 02:47:57 -0800 (PST) Received: from e125770.cambridge.arm.com (e125770.cambridge.arm.com [10.1.195.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A6EC13F73D; Mon, 7 Nov 2022 02:47:49 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9fe5345c-5e89-11ed-8fd1-01056ac49cbb From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: bertrand.marquis@arm.com, wei.chen@arm.com, Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [RFC PATCH 2/4] xen/Makefile: add analysis-cppcheck and analysis-cppcheck-html Date: Mon, 7 Nov 2022 10:47:37 +0000 Message-Id: <20221107104739.10404-3-luca.fancellu@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221107104739.10404-1-luca.fancellu@arm.com> References: <20221107104739.10404-1-luca.fancellu@arm.com> Change cppcheck invocation method by substituting the Makefile targets cppcheck{-html} with analysis-cppcheck{-html}. Now cppcheck will build Xen while analysing the source files, and it will produce a text output when called with analysis-cppcheck and an additional html output when called with analysis-cppcheck-html. With this patch cppcheck will benefit of platform configuration files that will help it to understand the target of the compilation and improve the analysis. To do so: - modify cppcheck calls in Makefile and add files to clean and distclean. - add platform configuration files for cppcheck. - add scripts to generate text and html output. - add cppcheck-cc.sh script that is a wrapper for cppcheck and it's used as Xen compiler, it will intercept all flags given from the make build system and it will execute cppcheck on the compiled file together with the file compilation. - add a script that generates a suppression list for cppcheck to overcome a problem where cppcheck is not suppressing findings in the headers using in-code comment. The system uses the headers in-code comment to produce the list, so it's transparent to the developer and both c files and header can benefit from in-code comment suppression. - guarded hypercall-defs.c with CPPCHECK define because cppcheck gets confused as the file does not contain c code. - add false-positive-cppcheck.json file - update documentation. - update .gitignore Signed-off-by: Luca Fancellu --- .gitignore | 8 +- docs/misra/cppcheck.txt | 47 +++-- docs/misra/documenting-violations.rst | 7 +- docs/misra/false-positive-cppcheck.json | 12 ++ xen/Makefile | 143 ++++++++----- xen/include/hypercall-defs.c | 9 + xen/tools/cppcheck-build-suppr-list.sh | 81 +++++++ xen/tools/cppcheck-cc.sh | 223 ++++++++++++++++++++ xen/tools/cppcheck-html-prepare.sh | 110 ++++++++++ xen/tools/cppcheck-plat/arm32-wchar_t4.xml | 17 ++ xen/tools/cppcheck-plat/arm64-wchar_t2.xml | 17 ++ xen/tools/cppcheck-plat/arm64-wchar_t4.xml | 17 ++ xen/tools/cppcheck-plat/x86_64-wchar_t2.xml | 17 ++ xen/tools/cppcheck-plat/x86_64-wchar_t4.xml | 17 ++ xen/tools/cppcheck-txt-prepare.sh | 74 +++++++ 15 files changed, 717 insertions(+), 82 deletions(-) create mode 100644 docs/misra/false-positive-cppcheck.json create mode 100755 xen/tools/cppcheck-build-suppr-list.sh create mode 100755 xen/tools/cppcheck-cc.sh create mode 100755 xen/tools/cppcheck-html-prepare.sh create mode 100644 xen/tools/cppcheck-plat/arm32-wchar_t4.xml create mode 100644 xen/tools/cppcheck-plat/arm64-wchar_t2.xml create mode 100644 xen/tools/cppcheck-plat/arm64-wchar_t4.xml create mode 100644 xen/tools/cppcheck-plat/x86_64-wchar_t2.xml create mode 100644 xen/tools/cppcheck-plat/x86_64-wchar_t4.xml create mode 100755 xen/tools/cppcheck-txt-prepare.sh diff --git a/.gitignore b/.gitignore index b48e1e20c4fc..abe47bfda9d2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,11 @@ *.o *.d *.d2 -*.c.cppcheck +*.cppcheck +*.cppcheck.txt *.opic *.a +*.c.json *.safparse *.so *.so.[0-9]* @@ -283,9 +285,11 @@ xen/arch/*/efi/efi.h xen/arch/*/efi/pe.c xen/arch/*/efi/runtime.c xen/arch/*/include/asm/asm-offsets.h +xen/build-dir-cppcheck xen/common/config_data.S xen/common/config.gz xen/cppcheck-htmlreport/ +xen/cppcheck-report/ xen/cppcheck-misra.* xen/include/headers*.chk xen/include/compat/* @@ -317,7 +321,7 @@ tools/flask/policy/policy.conf tools/flask/policy/xenpolicy-* xen/*.sed xen/xen -xen/xen-cppcheck.xml +xen/suppression-list.txt xen/xen-syms xen/xen-syms.map xen/xen.* diff --git a/docs/misra/cppcheck.txt b/docs/misra/cppcheck.txt index 25d8c3050b72..c59ad03dc7e9 100644 --- a/docs/misra/cppcheck.txt +++ b/docs/misra/cppcheck.txt @@ -38,27 +38,32 @@ Dependencies are listed in the readme.md of the project repository. Use cppcheck to analyse Xen =========================== -Using cppcheck integration is very simple, it requires few steps: - - 1) Compile Xen - 2) call the cppcheck make target to generate a report in xml format: - make CPPCHECK_MISRA=y cppcheck - 3) call the cppcheck-html make target to generate a report in xml and html - format: - make CPPCHECK_MISRA=y cppcheck-html - - In case the cppcheck binaries are not in the PATH, CPPCHECK and - CPPCHECK_HTMLREPORT variables can be overridden with the full path to the - binaries: - - make -C xen \ - CPPCHECK=/path/to/cppcheck \ - CPPCHECK_HTMLREPORT=/path/to/cppcheck-htmlreport \ - CPPCHECK_MISRA=y \ - cppcheck-html - -The output is by default in a folder named cppcheck-htmlreport, but the name -can be changed by passing it in the CPPCHECK_HTMLREPORT_OUTDIR variable. +Using cppcheck integration is very simple, it requires one of the following +steps, depending on whether the user wants a text report or also an html report. +The CPPCHECK_MISRA=y variable in the examples instructs cppcheck to analyse for +MISRA compliance, but when not specified, the report will contain just the +static analysis. + + * call the analysis-cppcheck make target to generate a report in text format: + make CPPCHECK_MISRA=y analysis-cppcheck + * call the analysis-cppcheck-html make target to generate a report in text and + html format: + make CPPCHECK_MISRA=y analysis-cppcheck-html + +In case the cppcheck binaries are not in the PATH, CPPCHECK and +CPPCHECK_HTMLREPORT variables can be overridden with the full path to the +binaries: + +make -C xen \ + CPPCHECK=/path/to/cppcheck \ + CPPCHECK_HTMLREPORT=/path/to/cppcheck-htmlreport \ + CPPCHECK_MISRA=y \ + analysis-cppcheck-html + +The text report is by default in a folder named cppcheck-report, but the name +can be changed by passing it in the CPPCHECK_REPORT_OUTDIR variable. +The html report is by default in a folder named cppcheck-htmlreport, but the +name can be changed by passing it in the CPPCHECK_HTMLREPORT_OUTDIR variable. [1] https://sourceforge.net/p/cppcheck/discussion/general/thread/bfc3ab6c41/?limit=25 diff --git a/docs/misra/documenting-violations.rst b/docs/misra/documenting-violations.rst index 3430abfaa177..f4f54a77d2a2 100644 --- a/docs/misra/documenting-violations.rst +++ b/docs/misra/documenting-violations.rst @@ -50,6 +50,7 @@ Here is an example to add a new justification in safe.json:: | { | "id": "SAF-0-safe", | "analyser": { +| "cppcheck": "misra-c2012-20.7", | "coverity": "misra_c_2012_rule_20_7_violation", | "eclair": "MC3R1.R20.7" | }, @@ -100,9 +101,9 @@ Here an explanation of the field inside an object of the "content" array: It tells the tool to substitute a Xen in-code comment having this structure: /* SAF-0-safe [...] \*/ - analyser: it is an object containing pair of key-value strings, the key is - the analyser, so it can be coverity or eclair, the value is the proprietary - id corresponding on the finding, for example when coverity is used as - analyser, the tool will translate the Xen in-code coment in this way: + the analyser, so it can be cppcheck, coverity or eclair, the value is the + proprietary id corresponding on the finding, for example when coverity is + used as analyser, the tool will translate the Xen in-code coment in this way: /* SAF-0-safe [...] \*/ -> /* coverity[misra_c_2012_rule_20_7_violation] \*/ if the object doesn't have a key-value, then the corresponding in-code comment won't be translated. diff --git a/docs/misra/false-positive-cppcheck.json b/docs/misra/false-positive-cppcheck.json new file mode 100644 index 000000000000..0d8a8059d9cd --- /dev/null +++ b/docs/misra/false-positive-cppcheck.json @@ -0,0 +1,12 @@ +{ + "version": "1.0", + "content": [ + { + "id": "SAF-0-false-positive-cppcheck", + "analyser": {}, + "tool-version": "", + "name": "Sentinel", + "text": "Next ID to be used" + } + ] +} diff --git a/xen/Makefile b/xen/Makefile index 3b8d1acd1697..e8a275e6d8a9 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -457,8 +457,8 @@ endif # need-config __all: build -main-targets := build install uninstall clean distclean MAP cppcheck \ - cppcheck-html analysis-coverity analysis-eclair +main-targets := build install uninstall clean distclean MAP analysis-cppcheck \ + analysis-cppcheck-html analysis-coverity analysis-eclair .PHONY: $(main-targets) ifneq ($(XEN_TARGET_ARCH),x86_32) $(main-targets): %: _% ; @@ -567,18 +567,20 @@ _clean: $(Q)$(MAKE) $(clean)=tools/kconfig find . \( -name "*.o" -o -name ".*.d" -o -name ".*.d2" \ -o -name ".*.o.tmp" -o -name "*~" -o -name "core" \ - -o -name '*.lex.c' -o -name '*.tab.[ch]' -o -name '*.c.cppcheck' \ - -o -name "*.gcno" -o -name ".*.cmd" -o -name "lib.a" \) -exec rm -f {} \; + -o -name '*.lex.c' -o -name '*.tab.[ch]' -o -name '*.cppcheck' \ + -o -name '*.cppcheck.txt' -o -name "*.gcno" -o -name ".*.cmd" \ + -o -name "lib.a" -o -name '*.c.json' \) -exec rm -f {} \; rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET)-syms $(TARGET)-syms.map rm -f $(TARGET).efi $(TARGET).efi.map $(TARGET).efi.stripped rm -f asm-offsets.s arch/*/include/asm/asm-offsets.h rm -f .banner .allconfig.tmp include/xen/compile.h - rm -f cppcheck-misra.* xen-cppcheck.xml *.sed + rm -f cppcheck-misra.* xen-cppcheck.xml suppression-list.txt *.sed + rm -rf $(CPPCHECK_BUILD_DIR) .PHONY: _distclean _distclean: clean rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out GTAGS GPATH GRTAGS GSYMS .config source - rm -rf $(CPPCHECK_HTMLREPORT_OUTDIR) + rm -rf $(CPPCHECK_HTMLREPORT_OUTDIR) $(CPPCHECK_REPORT_OUTDIR) $(TARGET).gz: $(TARGET) gzip -n -f -9 < $< > $@.new @@ -663,73 +665,50 @@ CPPCHECK ?= cppcheck # On recent distribution, this is available in the standard path. CPPCHECK_HTMLREPORT ?= cppcheck-htmlreport -# By default we generate the report in cppcheck-htmlreport directory in the +# By default we generate the html report in cppcheck-htmlreport directory in the # build directory. This can be changed by giving a directory in this variable. CPPCHECK_HTMLREPORT_OUTDIR ?= cppcheck-htmlreport +# By default we generate the text report in cppcheck-report directory in the +# build directory. This can be changed by giving a directory in this variable. +CPPCHECK_REPORT_OUTDIR ?= cppcheck-report + # By default we do not check misra rules, to enable pass "CPPCHECK_MISRA=y" to # make command line. CPPCHECK_MISRA ?= n +CPPCHECK_BUILD_DIR := $(objtree)/build-dir-cppcheck + # Compile flags to pass to cppcheck: -# - include directories and defines Xen Makefile is passing (from CFLAGS) # - include config.h as this is passed directly to the compiler. -# - define CPPCHECK as we use to disable or enable some specific part of the +# - define CPPCHECK as we use it to disable or enable some specific part of the # code to solve some cppcheck issues. # - explicitely enable some cppcheck checks as we do not want to use "all" # which includes unusedFunction which gives wrong positives as we check file # per file. +# - Explicitly suppress warnings on compiler-def.h because cppcheck throws an +# unmatchedSuppression due to the rule we put in suppression-list.txt to skip +# every finding in the file. # # Compiler defines are in compiler-def.h which is included in config.h # -CPPCHECKFLAGS := -DCPPCHECK --max-ctu-depth=10 \ - --enable=style,information,missingInclude \ - --include=$(srctree)/include/xen/config.h \ - -I $(srctree)/xsm/flask/include \ - -I $(srctree)/include/xen/libfdt \ - $(filter -D% -I%,$(CFLAGS)) - -# We need to find all C files (as we are not checking assembly files) so -# we find all generated .o files which have a .c corresponding file. -CPPCHECKFILES := $(wildcard $(patsubst $(objtree)/%.o,$(srctree)/%.c, \ - $(filter-out $(objtree)/tools/%, \ - $(shell find $(objtree) -name "*.o")))) - -# Headers and files required to run cppcheck on a file -CPPCHECKDEPS := $(objtree)/include/generated/autoconf.h \ - $(objtree)/include/generated/compiler-def.h +CPPCHECK_FLAGS := --cppcheck-build-dir=$(CPPCHECK_BUILD_DIR) \ + --max-ctu-depth=10 \ + --enable=style,information,missingInclude \ + --template='{file}({line},{column}):{id}:{severity}:{message}' \ + --relative-paths=$(srctree) \ + --inline-suppr \ + --suppressions-list=$(objtree)/suppression-list.txt \ + --suppress='unmatchedSuppression:*generated/compiler-def.h' \ + --include=$(srctree)/include/xen/config.h \ + -DCPPCHECK ifeq ($(CPPCHECK_MISRA),y) - CPPCHECKFLAGS += --addon=cppcheck-misra.json - CPPCHECKDEPS += cppcheck-misra.json -endif - -quiet_cmd_cppcheck_xml = CPPCHECK $(patsubst $(srctree)/%,%,$<) -cmd_cppcheck_xml = $(CPPCHECK) -v -q --xml $(CPPCHECKFLAGS) \ - --output-file=$@ $< - -quiet_cmd_merge_cppcheck_reports = CPPCHECK-MERGE $@ -cmd_merge_cppcheck_reports = $(PYTHON) $(srctree)/tools/merge_cppcheck_reports.py $^ $@ - -quiet_cmd_cppcheck_html = CPPCHECK-HTML $< -cmd_cppcheck_html = $(CPPCHECK_HTMLREPORT) --file=$< --source-dir=$(srctree) \ - --report-dir=$(CPPCHECK_HTMLREPORT_OUTDIR) --title=Xen - -PHONY += _cppcheck _cppcheck-html cppcheck-version - -_cppcheck-html: xen-cppcheck.xml - $(call if_changed,cppcheck_html) - -_cppcheck: xen-cppcheck.xml - -xen-cppcheck.xml: $(patsubst $(srctree)/%.c,$(objtree)/%.c.cppcheck,$(CPPCHECKFILES)) -ifeq ($(CPPCHECKFILES),) - $(error Please build Xen before running cppcheck) +CPPCHECK_FLAGS += --addon=cppcheck-misra.json +CPPCHECK_BUILD_EXTRA_DEPS += cppcheck-misra.json endif - $(call if_changed,merge_cppcheck_reports) -$(objtree)/%.c.cppcheck: $(srctree)/%.c $(CPPCHECKDEPS) | cppcheck-version - $(call if_changed,cppcheck_xml) +PHONY += cppcheck-version cppcheck-version: $(Q)if ! which $(CPPCHECK) > /dev/null 2>&1; then \ @@ -761,6 +740,11 @@ $(objtree)/include/generated/compiler-def.h: JUSTIFICATION_FILES := $(XEN_ROOT)/docs/misra/safe.json \ $(XEN_ROOT)/docs/misra/false-positive-$$*.json +CPPCHECK_CC_FLAGS := --compiler=$(CC) \ + --cppcheck-cmd=$(CPPCHECK) $(CPPCHECK_FLAGS) \ + --cppcheck-plat=$(srctree)/tools/cppcheck-plat \ + --ignore-path=tools/ + # The following command is using grep to find all files that contains a comment # containing "SAF-" on a single line. # %.safparse will be the original files saved from the build system, these files @@ -789,8 +773,49 @@ analysis-parse-tags-%: $(PARSE_FILE_LIST) $(objtree)/%.sed sed -i -f "$(objtree)/$*.sed" "$${file}"; \ done -analysis-build-%: analysis-parse-tags-% - $(MAKE) O=$(abs_objtree) -f $(srctree)/Makefile build +.SECONDEXPANSION: +analysis-build-%: $$(ANALYSIS_BUILD_DEPS) + $(MAKE) O=$(abs_objtree) $(ANALYSIS_EXTRA_MAKE) -f $(srctree)/Makefile build + +$(CPPCHECK_BUILD_DIR) $(CPPCHECK_REPORT_OUTDIR) $(CPPCHECK_HTMLREPORT_OUTDIR): + $(Q)mkdir -p $@ + +$(objtree)/suppression-list.txt: analysis-parse-tags-cppcheck + $(Q)$(srctree)/tools/cppcheck-build-suppr-list.sh --out-list=$@ \ + --source-dir=$(abs_srctree) +# Add this rule to skip every finding in the autogenerated header for cppcheck + $(Q)echo "*:*generated/compiler-def.h" >> $@ + +build-cppcheck: ANALYSIS_EXTRA_MAKE += CC="$(srctree)/tools/cppcheck-cc.sh \ + $(CPPCHECK_CC_FLAGS) $(CPPCHECK_CC_EXTRA_FLAGS) --" +build-cppcheck: ANALYSIS_BUILD_DEPS = $(objtree)/suppression-list.txt \ + $(CPPCHECK_BUILD_EXTRA_DEPS) $(CPPCHECK_BUILD_DIR) \ + $(objtree)/include/generated/compiler-def.h + +build-cppcheck: analysis-build-cppcheck | cppcheck-version + +run-cppcheck: build-cppcheck $(CPPCHECK_REPORT_OUTDIR) + $(Q)$(srctree)/tools/cppcheck-txt-prepare.sh --frag-ext=.cppcheck.txt \ + --rel-path=$(abs_srctree)/ \ + --outfile=$(CPPCHECK_REPORT_OUTDIR)/xen-cppcheck.txt + +run-cppcheck-html: CPPCHECK_CC_EXTRA_FLAGS += --cppcheck-html + +run-cppcheck-html: run-cppcheck $(CPPCHECK_HTMLREPORT_OUTDIR) + $(Q)$(srctree)/tools/cppcheck-html-prepare.sh --frag-ext=.cppcheck \ + --merge-tool=$(abs_srctree)/tools/merge_cppcheck_reports.py \ + --source-dir=$(srctree) \ + --outfile=$(CPPCHECK_HTMLREPORT_OUTDIR)/xen-cppcheck.xml + $(CPPCHECK_HTMLREPORT) \ + --file=$(CPPCHECK_HTMLREPORT_OUTDIR)/xen-cppcheck.xml \ + --source-dir=$(srctree) \ + --report-dir=$(CPPCHECK_HTMLREPORT_OUTDIR)/html --title=Xen +# Strip full build path from html report + $(Q)find $(CPPCHECK_HTMLREPORT_OUTDIR)/html -type f -name '*.html' \ + -exec sed -i -re 's|$(abs_objtree)/||g' {} + +# Strip full source path from html report + $(Q)find $(CPPCHECK_HTMLREPORT_OUTDIR)/html -type f -name '*.html' \ + -exec sed -i -re 's|$(abs_srctree)/||g' {} + analysis-clean: # Reverts the original file (-p preserves also timestamp) @@ -800,7 +825,13 @@ analysis-clean: rm -f "$${file}"; \ done -_analysis-%: analysis-build-% +_analysis-coverity: ANALYSIS_BUILD_DEPS = analysis-parse-tags-coverity +_analysis-eclair: ANALYSIS_BUILD_DEPS = analysis-parse-tags-eclair + +_analysis-coverity _analysis-eclair: _analysis-%: analysis-build-% + $(Q)$(MAKE) O=$(abs_objtree) -f $(srctree)/Makefile analysis-clean + +_analysis-cppcheck _analysis-cppcheck-html: _analysis-cppcheck%: run-cppcheck% $(Q)$(MAKE) O=$(abs_objtree) -f $(srctree)/Makefile analysis-clean endif #config-build diff --git a/xen/include/hypercall-defs.c b/xen/include/hypercall-defs.c index 60cbeb18e4da..d9fbcffa9567 100644 --- a/xen/include/hypercall-defs.c +++ b/xen/include/hypercall-defs.c @@ -60,6 +60,13 @@ * are possible. */ +/* + * Cppcheck thinks this file needs to be analysed because it is preprocessed by + * the compiler, but it gets confused because this file does not contains C + * code. Hence protect the code when CPPCHECK is used. + */ +#ifndef CPPCHECK + #ifdef CONFIG_HVM #define PREFIX_hvm hvm #else @@ -283,3 +290,5 @@ mca do do - - - #ifndef CONFIG_PV_SHIM_EXCLUSIVE paging_domctl_cont do do do do - #endif + +#endif /* !CPPCHECK */ diff --git a/xen/tools/cppcheck-build-suppr-list.sh b/xen/tools/cppcheck-build-suppr-list.sh new file mode 100755 index 000000000000..637ec3ce8d70 --- /dev/null +++ b/xen/tools/cppcheck-build-suppr-list.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +set -e + +function help() { + cat <> "${OUT_LIST}" + +done < <(grep -ERn '^[[:blank:]]*\/\*[[:space:]]+cppcheck-suppress.*\*\/$' \ + "${SOURCE_DIR}" | grep -E '.*\.h') diff --git a/xen/tools/cppcheck-cc.sh b/xen/tools/cppcheck-cc.sh new file mode 100755 index 000000000000..45a9f749f8c7 --- /dev/null +++ b/xen/tools/cppcheck-cc.sh @@ -0,0 +1,223 @@ +#!/usr/bin/env bash + +set -e + +function help() { + cat < + +This script is a wrapper for cppcheck that enables it to analyse the files that +are the target for the build, it is used in place of a selected compiler and the +make process will run it on every file that needs to be built. +All the arguments passed to the original compiler are forwarded to it without +modification, furthermore, they are used to improve the cppcheck analysis. + +Options: + --compiler= Use this compiler for the build + --cppcheck-cmd= Command line for the cppcheck analysis. + --cppcheck-html Prepare for cppcheck HTML output + --cppcheck-plat= Path to the cppcheck platform folder + --ignore-path= This script won't run cppcheck on the files having this + path, the compiler will run anyway on them. This argument + can be specified multiple times. + -h, --help Print this help +EOF +} + +CC_FILE="" +COMPILER="" +CPPCHECK_HTML="n" +CPPCHECK_PLAT_PATH="" +CPPCHECK_TOOL="" +CPPCHECK_TOOL_ARGS="" +FORWARD_FLAGS="" +IGNORE_PATH="n" +IGNORE_PATH_LIST="" +JDB_FILE="" +OBJTREE_PATH="" + +# Variable used for arg parsing +forward_to_cc="n" +sm_tool_args="n" +obj_arg_content="n" + +for OPTION in "$@" +do + if [ "${forward_to_cc}" = "y" ]; then + if [[ ${OPTION} == *.c ]] + then + CC_FILE="${OPTION}" + elif [ "${OPTION}" = "-o" ] + then + # After -o there is the path to the obj file, flag it + obj_arg_content="y" + elif [ "${obj_arg_content}" = "y" ] + then + # This must be the path to the obj file, turn off flag and save path + OBJTREE_PATH="$(dirname "${OPTION}")" + obj_arg_content="n" + fi + # Forward any argument to the compiler + FORWARD_FLAGS="${FORWARD_FLAGS} ${OPTION}" + continue + fi + case ${OPTION} in + -h|--help) + help + exit 0 + ;; + --compiler=*) + COMPILER="$(eval echo "${OPTION#*=}")" + sm_tool_args="n" + ;; + --cppcheck-cmd=*) + CPPCHECK_TOOL="$(eval echo "${OPTION#*=}")" + sm_tool_args="y" + ;; + --cppcheck-html) + CPPCHECK_HTML="y" + sm_tool_args="n" + ;; + --cppcheck-plat=*) + CPPCHECK_PLAT_PATH="$(eval echo "${OPTION#*=}")" + sm_tool_args="n" + ;; + --ignore-path=*) + IGNORE_PATH_LIST="${IGNORE_PATH_LIST} $(eval echo "${OPTION#*=}")" + sm_tool_args="n" + ;; + --) + forward_to_cc="y" + sm_tool_args="n" + ;; + *) + if [ "${sm_tool_args}" = "y" ]; then + CPPCHECK_TOOL_ARGS="${CPPCHECK_TOOL_ARGS} ${OPTION}" + else + echo "Invalid option ${OPTION}" + exit 1 + fi + ;; + esac +done + +if [ "${COMPILER}" = "" ] +then + echo "--compiler arg is mandatory." + exit 1 +fi + +function print_file() { + local text="${1}" + local init_file="${2}" + + if [ "${init_file}" = "y" ] + then + echo -e -n "${text}" > "${JDB_FILE}" + else + echo -e -n "${text}" >> "${JDB_FILE}" + fi +} + +function create_jcd() { + local line="${1}" + local arg_num=0 + local same_line=0 + + print_file "[\n" "y" + print_file " {\n" + print_file " \"arguments\": [\n" + + for arg in ${line}; do + # This code prevents to put comma in the last element of the list or on + # sequential lines that are going to be merged + [ "${arg_num}" -ne 0 ] && [ "${same_line}" -eq 0 ] && print_file ",\n" + if [ "${same_line}" -ne 0 ] + then + print_file "${arg}\"" + same_line=0 + elif [ "${arg}" = "-iquote" ] || [ "${arg}" = "-I" ] + then + # cppcheck doesn't understand -iquote, substitute with -I + print_file " \"-I" + same_line=1 + else + print_file " \"${arg}\"" + fi + arg_num=$(( arg_num + 1 )) + done + print_file "\n" + print_file " ],\n" + print_file " \"directory\": \"$(pwd -P)\",\n" + print_file " \"file\": \"${CC_FILE}\"\n" + print_file " }\n" + print_file "]\n" +} + + +# Execute compiler with forwarded flags +# Shellcheck complains about missing quotes on FORWARD_FLAGS, but they can't be +# used here +# shellcheck disable=SC2086 +${COMPILER} ${FORWARD_FLAGS} + +if [ -n "${CC_FILE}" ]; +then + for path in ${IGNORE_PATH_LIST} + do + if [[ ${CC_FILE} == *${path}* ]] + then + IGNORE_PATH="y" + echo "${0}: ${CC_FILE} ignored by --ignore-path matching *${path}*" + fi + done + if [ "${IGNORE_PATH}" = "n" ] + then + JDB_FILE="${OBJTREE_PATH}/$(basename "${CC_FILE}".json)" + + # Prepare the Json Compilation Database for the file + create_jcd "${COMPILER} ${FORWARD_FLAGS}" + + out_file="${OBJTREE_PATH}/$(basename "${CC_FILE%.c}".cppcheck.txt)" + + # Check wchar size + wchar_plat_suffix="t4" + # sed prints the last occurence of -f(no-)short-wchar which is the one + # applied to the file by the compiler + wchar_option=$(echo "${FORWARD_FLAGS}" | \ + sed -nre 's,.*(-f(no-)?short-wchar).*,\1,p') + if [ "${wchar_option}" = "-fshort-wchar" ] + then + wchar_plat_suffix="t2" + fi + + # Select the right target platform, ARCH is generated from Xen Makefile + platform="${CPPCHECK_PLAT_PATH}/${ARCH}-wchar_${wchar_plat_suffix}.xml" + if [ ! -f "${platform}" ] + then + echo "${platform} not found!" + exit 1 + fi + + # Shellcheck complains about missing quotes on CPPCHECK_TOOL_ARGS, but + # they can't be used here + # shellcheck disable=SC2086 + ${CPPCHECK_TOOL} ${CPPCHECK_TOOL_ARGS} \ + --project="${JDB_FILE}" \ + --output-file="${out_file}" \ + --platform=${platform} + + if [ "${CPPCHECK_HTML}" = "y" ] + then + # Shellcheck complains about missing quotes on CPPCHECK_TOOL_ARGS, + # but they can't be used here + # shellcheck disable=SC2086 + ${CPPCHECK_TOOL} ${CPPCHECK_TOOL_ARGS} \ + --project="${JDB_FILE}" \ + --output-file="${out_file%.txt}" \ + --platform=${platform} \ + -q \ + --xml + fi + fi +fi diff --git a/xen/tools/cppcheck-html-prepare.sh b/xen/tools/cppcheck-html-prepare.sh new file mode 100755 index 000000000000..c889dcc3582c --- /dev/null +++ b/xen/tools/cppcheck-html-prepare.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +set -e + +function help() { + cat < + + 8 + unsigned + + 2 + 4 + 4 + 8 + 4 + 8 + 8 + 4 + 4 + 4 + + diff --git a/xen/tools/cppcheck-plat/arm64-wchar_t2.xml b/xen/tools/cppcheck-plat/arm64-wchar_t2.xml new file mode 100644 index 000000000000..e345b934a986 --- /dev/null +++ b/xen/tools/cppcheck-plat/arm64-wchar_t2.xml @@ -0,0 +1,17 @@ + + + 8 + unsigned + + 2 + 4 + 8 + 8 + 4 + 8 + 16 + 8 + 4 + 2 + + diff --git a/xen/tools/cppcheck-plat/arm64-wchar_t4.xml b/xen/tools/cppcheck-plat/arm64-wchar_t4.xml new file mode 100644 index 000000000000..952b3640c91d --- /dev/null +++ b/xen/tools/cppcheck-plat/arm64-wchar_t4.xml @@ -0,0 +1,17 @@ + + + 8 + unsigned + + 2 + 4 + 8 + 8 + 4 + 8 + 16 + 8 + 4 + 4 + + diff --git a/xen/tools/cppcheck-plat/x86_64-wchar_t2.xml b/xen/tools/cppcheck-plat/x86_64-wchar_t2.xml new file mode 100644 index 000000000000..b2dc2fb2cc50 --- /dev/null +++ b/xen/tools/cppcheck-plat/x86_64-wchar_t2.xml @@ -0,0 +1,17 @@ + + + 8 + unsigned + + 2 + 4 + 8 + 8 + 4 + 8 + 16 + 8 + 8 + 2 + + diff --git a/xen/tools/cppcheck-plat/x86_64-wchar_t4.xml b/xen/tools/cppcheck-plat/x86_64-wchar_t4.xml new file mode 100644 index 000000000000..21d97b611505 --- /dev/null +++ b/xen/tools/cppcheck-plat/x86_64-wchar_t4.xml @@ -0,0 +1,17 @@ + + + 8 + unsigned + + 2 + 4 + 8 + 8 + 4 + 8 + 16 + 8 + 8 + 4 + + diff --git a/xen/tools/cppcheck-txt-prepare.sh b/xen/tools/cppcheck-txt-prepare.sh new file mode 100755 index 000000000000..a3fbaa150111 --- /dev/null +++ b/xen/tools/cppcheck-txt-prepare.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +function help() { + cat <> "${OUTFILE}" +done + +# Remove duplicates, some awk implementation doesn't have inplace change mode +mv "${OUTFILE}" "${OUTFILE}_tmp" +awk '/^\s*?$/||!seen[$0]++' "${OUTFILE}_tmp" > "${OUTFILE}" +rm "${OUTFILE}_tmp" + +if [ -n "${RELPATH}" ] +then + # Strip path + sed -i -re "s|${RELPATH}||g" "${OUTFILE}" +fi From patchwork Mon Nov 7 10:47:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 13034242 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 93907C433FE for ; Mon, 7 Nov 2022 10:48:04 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.439286.693341 (Exim 4.92) (envelope-from ) id 1orzfX-0002nL-8C; Mon, 07 Nov 2022 10:47:55 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 439286.693341; Mon, 07 Nov 2022 10:47:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfX-0002nC-5S; Mon, 07 Nov 2022 10:47:55 +0000 Received: by outflank-mailman (input) for mailman id 439286; Mon, 07 Nov 2022 10:47:54 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfW-0002FR-1m for xen-devel@lists.xenproject.org; Mon, 07 Nov 2022 10:47:54 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id a168385b-5e89-11ed-91b5-6bf2151ebd3b; Mon, 07 Nov 2022 11:47:53 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A62EA113E; Mon, 7 Nov 2022 02:47:58 -0800 (PST) Received: from e125770.cambridge.arm.com (e125770.cambridge.arm.com [10.1.195.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 514C43F73D; Mon, 7 Nov 2022 02:47:51 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a168385b-5e89-11ed-91b5-6bf2151ebd3b From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: bertrand.marquis@arm.com, wei.chen@arm.com, Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [RFC PATCH 3/4] tools/misra: fix skipped rule numbers Date: Mon, 7 Nov 2022 10:47:38 +0000 Message-Id: <20221107104739.10404-4-luca.fancellu@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221107104739.10404-1-luca.fancellu@arm.com> References: <20221107104739.10404-1-luca.fancellu@arm.com> Currently the script convert_misra_doc.py is using a loop through range(1,22) to enumerate rules that needs to be skipped, however range function does not include the stop counter in the enumeration ending up into list rules until 21.21 instead of including rule 22. Fix the issue using a dictionary that list the rules in misra c2012. Fixes: 57caa5375321 ("xen: Add MISRA support to cppcheck make rule") Signed-off-by: Luca Fancellu --- xen/tools/convert_misra_doc.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/xen/tools/convert_misra_doc.py b/xen/tools/convert_misra_doc.py index caa4487f645f..13074d8a2e91 100755 --- a/xen/tools/convert_misra_doc.py +++ b/xen/tools/convert_misra_doc.py @@ -14,6 +14,34 @@ Usage: import sys, getopt, re +# MISRA rule are identified by two numbers, e.g. Rule 1.2, the main rule number +# and a sub-number. This dictionary contains the number of the MISRA rule as key +# and the maximum sub-number for that rule as value. +misra_c2012_rules = { + 1:4, + 2:7, + 3:2, + 4:2, + 5:9, + 6:2, + 7:4, + 8:14, + 9:5, + 10:8, + 11:9, + 12:5, + 13:6, + 14:4, + 15:7, + 16:7, + 17:8, + 18:8, + 19:2, + 20:14, + 21:21, + 22:10 +} + def main(argv): infile = '' outfile = '' @@ -142,8 +170,8 @@ def main(argv): skip_list = [] # Search for missing rules and add a dummy text with the rule number - for i in list(range(1,22)): - for j in list(range(1,22)): + for i in misra_c2012_rules: + for j in list(range(1,misra_c2012_rules[i]+1)): if str(i) + '.' + str(j) not in rule_list: outstr.write('Rule ' + str(i) + '.' + str(j) + '\n') outstr.write('No description for rule ' + str(i) + '.' + str(j) From patchwork Mon Nov 7 10:47:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 13034244 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DDF25C43217 for ; Mon, 7 Nov 2022 10:48:05 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.439288.693358 (Exim 4.92) (envelope-from ) id 1orzfZ-0003DY-3h; Mon, 07 Nov 2022 10:47:57 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 439288.693358; Mon, 07 Nov 2022 10:47:57 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfZ-0003Bx-0N; Mon, 07 Nov 2022 10:47:57 +0000 Received: by outflank-mailman (input) for mailman id 439288; Mon, 07 Nov 2022 10:47:55 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1orzfX-0002Pj-Dc for xen-devel@lists.xenproject.org; Mon, 07 Nov 2022 10:47:55 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id a1a1c49e-5e89-11ed-8fd1-01056ac49cbb; Mon, 07 Nov 2022 11:47:53 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1AAC3139F; Mon, 7 Nov 2022 02:48:00 -0800 (PST) Received: from e125770.cambridge.arm.com (e125770.cambridge.arm.com [10.1.195.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B9C0F3F73D; Mon, 7 Nov 2022 02:47:52 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a1a1c49e-5e89-11ed-8fd1-01056ac49cbb From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: bertrand.marquis@arm.com, wei.chen@arm.com, Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [RFC PATCH 4/4] xen: Justify linker script defined symbols in include/xen/kernel.h Date: Mon, 7 Nov 2022 10:47:39 +0000 Message-Id: <20221107104739.10404-5-luca.fancellu@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221107104739.10404-1-luca.fancellu@arm.com> References: <20221107104739.10404-1-luca.fancellu@arm.com> Eclair and Coverity found violation of the MISRA rule 8.6 for the symbols _start, _end, start, _stext, _etext, _srodata, _erodata, _sinittext, _einittext which are declared in xen/include/xen/kernel.h. All those symbols are defined by the liker script so we can deviate from the rule 8.6 for these cases. Signed-off-by: Luca Fancellu --- docs/misra/safe.json | 9 +++++++++ xen/include/xen/kernel.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/docs/misra/safe.json b/docs/misra/safe.json index e079d3038120..e3c8a1d8eb36 100644 --- a/docs/misra/safe.json +++ b/docs/misra/safe.json @@ -3,6 +3,15 @@ "content": [ { "id": "SAF-0-safe", + "analyser": { + "eclair": "MC3R1.R8.6", + "coverity": "misra_c_2012_rule_8_6_violation" + }, + "name": "Rule 8.6: linker script defined symbols", + "text": "It is safe to declare this symbol because it is defined in the linker script." + }, + { + "id": "SAF-1-safe", "analyser": {}, "name": "Sentinel", "text": "Next ID to be used" diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h index 8cd142032d3b..efcd24b355d6 100644 --- a/xen/include/xen/kernel.h +++ b/xen/include/xen/kernel.h @@ -65,24 +65,28 @@ 1; \ }) +/* SAF-0-safe R8.6 linker script defined symbols */ extern char _start[], _end[], start[]; #define is_kernel(p) ({ \ char *__p = (char *)(unsigned long)(p); \ (__p >= _start) && (__p < _end); \ }) +/* SAF-0-safe R8.6 linker script defined symbols */ extern char _stext[], _etext[]; #define is_kernel_text(p) ({ \ char *__p = (char *)(unsigned long)(p); \ (__p >= _stext) && (__p < _etext); \ }) +/* SAF-0-safe R8.6 linker script defined symbols */ extern const char _srodata[], _erodata[]; #define is_kernel_rodata(p) ({ \ const char *__p = (const char *)(unsigned long)(p); \ (__p >= _srodata) && (__p < _erodata); \ }) +/* SAF-0-safe R8.6 linker script defined symbols */ extern char _sinittext[], _einittext[]; #define is_kernel_inittext(p) ({ \ char *__p = (char *)(unsigned long)(p); \