diff --git a/.gitignore b/.gitignore
index 18ef56a780..c9951063c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -297,7 +297,6 @@ xen/.banner
xen/.config
xen/.config.old
xen/.xen.elf32
-xen/xen-cppcheck.xml
xen/System.map
xen/arch/x86/boot/mkelf32
xen/arch/x86/boot/cmdline.S
@@ -318,7 +317,8 @@ xen/arch/*/efi/runtime.c
xen/arch/*/include/asm/asm-offsets.h
xen/common/config_data.S
xen/common/config.gz
-xen/cppcheck-htmlreport
+xen/cppcheck-htmlreport/
+xen/cppcheck-misra.*
xen/include/headers*.chk
xen/include/compat/*
xen/include/config/
@@ -347,6 +347,7 @@ xen/xsm/flask/xenpolicy-*
tools/flask/policy/policy.conf
tools/flask/policy/xenpolicy-*
xen/xen
+xen/xen-cppcheck.xml
xen/xen-syms
xen/xen-syms.map
xen/xen.*
diff --git a/xen/Makefile b/xen/Makefile
index ede4f15b18..4d770fef84 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -547,7 +547,7 @@ _clean:
rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET).efi $(TARGET).efi.map $(TARGET)-syms $(TARGET)-syms.map
rm -f asm-offsets.s arch/*/include/asm/asm-offsets.h
rm -f .banner .allconfig.tmp include/xen/compile.h
- rm -f xen-cppcheck.xml
+ rm -f cppcheck-misra.* xen-cppcheck.xml
.PHONY: _distclean
_distclean: clean
@@ -641,6 +641,10 @@ CPPCHECK_HTMLREPORT ?= cppcheck-htmlreport
# build directory. This can be changed by giving a directory in this variable.
CPPCHECK_HTMLREPORT_OUTDIR ?= cppcheck-htmlreport
+# By default we do not check misra rules, to enable pass "CPPCHECK_MISRA=y" to
+# make command line.
+CPPCHECK_MISRA ?= n
+
# 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.
@@ -665,6 +669,15 @@ 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
+
+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=$@ $<
@@ -689,7 +702,7 @@ ifeq ($(CPPCHECKFILES),)
endif
$(call if_changed,merge_cppcheck_reports)
-$(objtree)/%.c.cppcheck: $(srctree)/%.c $(objtree)/include/generated/autoconf.h $(objtree)/include/generated/compiler-def.h | cppcheck-version
+$(objtree)/%.c.cppcheck: $(srctree)/%.c $(CPPCHECKDEPS) | cppcheck-version
$(call if_changed,cppcheck_xml)
cppcheck-version:
@@ -702,6 +715,18 @@ cppcheck-version:
exit 1; \
fi
+# List of Misra rules to respect is written inside a doc.
+# In order to have some helpful text in the cppcheck output, generate a text
+# file containing the rules identifier, classification and text from the Xen
+# documentation file. Also generate a json file with the right arguments for
+# cppcheck in json format including the list of rules to ignore.
+#
+cppcheck-misra.txt: $(XEN_ROOT)/docs/misra/rules.rst $(srctree)/tools/convert_misra_doc.py
+ $(Q)$(srctree)/tools/convert_misra_doc.py -i $< -o $@ -j $(@:.txt=.json)
+
+# convert_misra_doc is generating both files.
+cppcheck-misra.json: cppcheck-misra.txt
+
# Put this in generated headers this way it is cleaned by include/Makefile
$(objtree)/include/generated/compiler-def.h:
$(Q)$(CC) -dM -E -o $@ - < /dev/null
diff --git a/xen/tools/convert_misra_doc.py b/xen/tools/convert_misra_doc.py
new file mode 100644
index 0000000000..caa4487f64
--- /dev/null
+++ b/xen/tools/convert_misra_doc.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+
+"""
+This script is converting the misra documentation RST file into a text file
+that can be used as text-rules for cppcheck.
+Usage:
+ convert_misr_doc.py -i INPUT [-o OUTPUT] [-j JSON]
+
+ INPUT - RST file containing the list of misra rules.
+ OUTPUT - file to store the text output to be used by cppcheck.
+ If not specified, the result will be printed to stdout.
+ JSON - cppcheck json file to be created (optional).
+"""
+
+import sys, getopt, re
+
+def main(argv):
+ infile = ''
+ outfile = ''
+ outstr = sys.stdout
+ jsonfile = ''
+
+ try:
+ opts, args = getopt.getopt(argv,"hi:o:j:",["input=","output=","json="])
+ except getopt.GetoptError:
+ print('convert-misra.py -i [-o