Commit 8a28caf02b7763f3d0b3813805ecd3ede0589c73

Authored by Heinrich Schuchardt
Committed by Tom Rini
1 parent 76df275ce5

Makefile: add coccicheck target

Coccinelle is a program for static code analysis.
For details on Coccinelle see

	http://coccinelle.lip6.fr/

Add scripts/coccicheck copied from Linux kernel v4.14.

The coccicheck script executes the tests *.cocci in
directory scripts/coccinelle by calling spatch.

In Makefile add a coccicheck target. You can use it with

	make coccicheck MODE=<mode>

	where mode in patch, report, context, org.

Add a copy of Linux v4.14 file Documentation/dev-tools/coccinelle.rst
as doc/README.coccinelle.

Cc: Simon Glass <sjg@chromium.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>

Showing 3 changed files with 756 additions and 0 deletions Side-by-side Diff

... ... @@ -1572,6 +1572,7 @@
1572 1572 @echo ''
1573 1573 @echo 'Static analysers'
1574 1574 @echo ' checkstack - Generate a list of stack hogs'
  1575 + @echo ' coccicheck - Execute static code analysis with Coccinelle'
1575 1576 @echo ''
1576 1577 @echo 'Documentation targets:'
1577 1578 @$(MAKE) -f $(srctree)/doc/DocBook/Makefile dochelp
... ... @@ -1663,6 +1664,14 @@
1663 1664 $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
1664 1665 $(build)=$(build-dir) $(@:.ko=.o)
1665 1666 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
  1667 +
  1668 +# Consistency checks
  1669 +# ---------------------------------------------------------------------------
  1670 +
  1671 +PHONY += coccicheck
  1672 +
  1673 +coccicheck:
  1674 + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@
1666 1675  
1667 1676 # FIXME Should go into a make.lib or something
1668 1677 # ===========================================================================
doc/README.coccinelle
  1 +.. Copyright 2010 Nicolas Palix <npalix@diku.dk>
  2 +.. Copyright 2010 Julia Lawall <julia@diku.dk>
  3 +.. Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
  4 +
  5 +.. highlight:: none
  6 +
  7 +Coccinelle
  8 +==========
  9 +
  10 +Coccinelle is a tool for pattern matching and text transformation that has
  11 +many uses in kernel development, including the application of complex,
  12 +tree-wide patches and detection of problematic programming patterns.
  13 +
  14 +Getting Coccinelle
  15 +-------------------
  16 +
  17 +The semantic patches included in the kernel use features and options
  18 +which are provided by Coccinelle version 1.0.0-rc11 and above.
  19 +Using earlier versions will fail as the option names used by
  20 +the Coccinelle files and coccicheck have been updated.
  21 +
  22 +Coccinelle is available through the package manager
  23 +of many distributions, e.g. :
  24 +
  25 + - Debian
  26 + - Fedora
  27 + - Ubuntu
  28 + - OpenSUSE
  29 + - Arch Linux
  30 + - NetBSD
  31 + - FreeBSD
  32 +
  33 +You can get the latest version released from the Coccinelle homepage at
  34 +http://coccinelle.lip6.fr/
  35 +
  36 +Information and tips about Coccinelle are also provided on the wiki
  37 +pages at http://cocci.ekstranet.diku.dk/wiki/doku.php
  38 +
  39 +Once you have it, run the following command::
  40 +
  41 + ./configure
  42 + make
  43 +
  44 +as a regular user, and install it with::
  45 +
  46 + sudo make install
  47 +
  48 +Supplemental documentation
  49 +---------------------------
  50 +
  51 +For supplemental documentation refer to the wiki:
  52 +
  53 +https://bottest.wiki.kernel.org/coccicheck
  54 +
  55 +The wiki documentation always refers to the linux-next version of the script.
  56 +
  57 +Using Coccinelle on the Linux kernel
  58 +------------------------------------
  59 +
  60 +A Coccinelle-specific target is defined in the top level
  61 +Makefile. This target is named ``coccicheck`` and calls the ``coccicheck``
  62 +front-end in the ``scripts`` directory.
  63 +
  64 +Four basic modes are defined: ``patch``, ``report``, ``context``, and
  65 +``org``. The mode to use is specified by setting the MODE variable with
  66 +``MODE=<mode>``.
  67 +
  68 +- ``patch`` proposes a fix, when possible.
  69 +
  70 +- ``report`` generates a list in the following format:
  71 + file:line:column-column: message
  72 +
  73 +- ``context`` highlights lines of interest and their context in a
  74 + diff-like style.Lines of interest are indicated with ``-``.
  75 +
  76 +- ``org`` generates a report in the Org mode format of Emacs.
  77 +
  78 +Note that not all semantic patches implement all modes. For easy use
  79 +of Coccinelle, the default mode is "report".
  80 +
  81 +Two other modes provide some common combinations of these modes.
  82 +
  83 +- ``chain`` tries the previous modes in the order above until one succeeds.
  84 +
  85 +- ``rep+ctxt`` runs successively the report mode and the context mode.
  86 + It should be used with the C option (described later)
  87 + which checks the code on a file basis.
  88 +
  89 +Examples
  90 +~~~~~~~~
  91 +
  92 +To make a report for every semantic patch, run the following command::
  93 +
  94 + make coccicheck MODE=report
  95 +
  96 +To produce patches, run::
  97 +
  98 + make coccicheck MODE=patch
  99 +
  100 +
  101 +The coccicheck target applies every semantic patch available in the
  102 +sub-directories of ``scripts/coccinelle`` to the entire Linux kernel.
  103 +
  104 +For each semantic patch, a commit message is proposed. It gives a
  105 +description of the problem being checked by the semantic patch, and
  106 +includes a reference to Coccinelle.
  107 +
  108 +As any static code analyzer, Coccinelle produces false
  109 +positives. Thus, reports must be carefully checked, and patches
  110 +reviewed.
  111 +
  112 +To enable verbose messages set the V= variable, for example::
  113 +
  114 + make coccicheck MODE=report V=1
  115 +
  116 +Coccinelle parallelization
  117 +---------------------------
  118 +
  119 +By default, coccicheck tries to run as parallel as possible. To change
  120 +the parallelism, set the J= variable. For example, to run across 4 CPUs::
  121 +
  122 + make coccicheck MODE=report J=4
  123 +
  124 +As of Coccinelle 1.0.2 Coccinelle uses Ocaml parmap for parallelization,
  125 +if support for this is detected you will benefit from parmap parallelization.
  126 +
  127 +When parmap is enabled coccicheck will enable dynamic load balancing by using
  128 +``--chunksize 1`` argument, this ensures we keep feeding threads with work
  129 +one by one, so that we avoid the situation where most work gets done by only
  130 +a few threads. With dynamic load balancing, if a thread finishes early we keep
  131 +feeding it more work.
  132 +
  133 +When parmap is enabled, if an error occurs in Coccinelle, this error
  134 +value is propagated back, the return value of the ``make coccicheck``
  135 +captures this return value.
  136 +
  137 +Using Coccinelle with a single semantic patch
  138 +---------------------------------------------
  139 +
  140 +The optional make variable COCCI can be used to check a single
  141 +semantic patch. In that case, the variable must be initialized with
  142 +the name of the semantic patch to apply.
  143 +
  144 +For instance::
  145 +
  146 + make coccicheck COCCI=<my_SP.cocci> MODE=patch
  147 +
  148 +or::
  149 +
  150 + make coccicheck COCCI=<my_SP.cocci> MODE=report
  151 +
  152 +
  153 +Controlling Which Files are Processed by Coccinelle
  154 +---------------------------------------------------
  155 +
  156 +By default the entire kernel source tree is checked.
  157 +
  158 +To apply Coccinelle to a specific directory, ``M=`` can be used.
  159 +For example, to check drivers/net/wireless/ one may write::
  160 +
  161 + make coccicheck M=drivers/net/wireless/
  162 +
  163 +To apply Coccinelle on a file basis, instead of a directory basis, the
  164 +following command may be used::
  165 +
  166 + make C=1 CHECK="scripts/coccicheck"
  167 +
  168 +To check only newly edited code, use the value 2 for the C flag, i.e.::
  169 +
  170 + make C=2 CHECK="scripts/coccicheck"
  171 +
  172 +In these modes, which works on a file basis, there is no information
  173 +about semantic patches displayed, and no commit message proposed.
  174 +
  175 +This runs every semantic patch in scripts/coccinelle by default. The
  176 +COCCI variable may additionally be used to only apply a single
  177 +semantic patch as shown in the previous section.
  178 +
  179 +The "report" mode is the default. You can select another one with the
  180 +MODE variable explained above.
  181 +
  182 +Debugging Coccinelle SmPL patches
  183 +---------------------------------
  184 +
  185 +Using coccicheck is best as it provides in the spatch command line
  186 +include options matching the options used when we compile the kernel.
  187 +You can learn what these options are by using V=1, you could then
  188 +manually run Coccinelle with debug options added.
  189 +
  190 +Alternatively you can debug running Coccinelle against SmPL patches
  191 +by asking for stderr to be redirected to stderr, by default stderr
  192 +is redirected to /dev/null, if you'd like to capture stderr you
  193 +can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For
  194 +instance::
  195 +
  196 + rm -f cocci.err
  197 + make coccicheck COCCI=scripts/coccinelle/free/kfree.cocci MODE=report DEBUG_FILE=cocci.err
  198 + cat cocci.err
  199 +
  200 +You can use SPFLAGS to add debugging flags, for instance you may want to
  201 +add both --profile --show-trying to SPFLAGS when debugging. For instance
  202 +you may want to use::
  203 +
  204 + rm -f err.log
  205 + export COCCI=scripts/coccinelle/misc/irqf_oneshot.cocci
  206 + make coccicheck DEBUG_FILE="err.log" MODE=report SPFLAGS="--profile --show-trying" M=./drivers/mfd/arizona-irq.c
  207 +
  208 +err.log will now have the profiling information, while stdout will
  209 +provide some progress information as Coccinelle moves forward with
  210 +work.
  211 +
  212 +DEBUG_FILE support is only supported when using coccinelle >= 1.2.
  213 +
  214 +.cocciconfig support
  215 +--------------------
  216 +
  217 +Coccinelle supports reading .cocciconfig for default Coccinelle options that
  218 +should be used every time spatch is spawned, the order of precedence for
  219 +variables for .cocciconfig is as follows:
  220 +
  221 +- Your current user's home directory is processed first
  222 +- Your directory from which spatch is called is processed next
  223 +- The directory provided with the --dir option is processed last, if used
  224 +
  225 +Since coccicheck runs through make, it naturally runs from the kernel
  226 +proper dir, as such the second rule above would be implied for picking up a
  227 +.cocciconfig when using ``make coccicheck``.
  228 +
  229 +``make coccicheck`` also supports using M= targets.If you do not supply
  230 +any M= target, it is assumed you want to target the entire kernel.
  231 +The kernel coccicheck script has::
  232 +
  233 + if [ "$KBUILD_EXTMOD" = "" ] ; then
  234 + OPTIONS="--dir $srctree $COCCIINCLUDE"
  235 + else
  236 + OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
  237 + fi
  238 +
  239 +KBUILD_EXTMOD is set when an explicit target with M= is used. For both cases
  240 +the spatch --dir argument is used, as such third rule applies when whether M=
  241 +is used or not, and when M= is used the target directory can have its own
  242 +.cocciconfig file. When M= is not passed as an argument to coccicheck the
  243 +target directory is the same as the directory from where spatch was called.
  244 +
  245 +If not using the kernel's coccicheck target, keep the above precedence
  246 +order logic of .cocciconfig reading. If using the kernel's coccicheck target,
  247 +override any of the kernel's .coccicheck's settings using SPFLAGS.
  248 +
  249 +We help Coccinelle when used against Linux with a set of sensible defaults
  250 +options for Linux with our own Linux .cocciconfig. This hints to coccinelle
  251 +git can be used for ``git grep`` queries over coccigrep. A timeout of 200
  252 +seconds should suffice for now.
  253 +
  254 +The options picked up by coccinelle when reading a .cocciconfig do not appear
  255 +as arguments to spatch processes running on your system, to confirm what
  256 +options will be used by Coccinelle run::
  257 +
  258 + spatch --print-options-only
  259 +
  260 +You can override with your own preferred index option by using SPFLAGS. Take
  261 +note that when there are conflicting options Coccinelle takes precedence for
  262 +the last options passed. Using .cocciconfig is possible to use idutils, however
  263 +given the order of precedence followed by Coccinelle, since the kernel now
  264 +carries its own .cocciconfig, you will need to use SPFLAGS to use idutils if
  265 +desired. See below section "Additional flags" for more details on how to use
  266 +idutils.
  267 +
  268 +Additional flags
  269 +----------------
  270 +
  271 +Additional flags can be passed to spatch through the SPFLAGS
  272 +variable. This works as Coccinelle respects the last flags
  273 +given to it when options are in conflict. ::
  274 +
  275 + make SPFLAGS=--use-glimpse coccicheck
  276 +
  277 +Coccinelle supports idutils as well but requires coccinelle >= 1.0.6.
  278 +When no ID file is specified coccinelle assumes your ID database file
  279 +is in the file .id-utils.index on the top level of the kernel, coccinelle
  280 +carries a script scripts/idutils_index.sh which creates the database with::
  281 +
  282 + mkid -i C --output .id-utils.index
  283 +
  284 +If you have another database filename you can also just symlink with this
  285 +name. ::
  286 +
  287 + make SPFLAGS=--use-idutils coccicheck
  288 +
  289 +Alternatively you can specify the database filename explicitly, for
  290 +instance::
  291 +
  292 + make SPFLAGS="--use-idutils /full-path/to/ID" coccicheck
  293 +
  294 +See ``spatch --help`` to learn more about spatch options.
  295 +
  296 +Note that the ``--use-glimpse`` and ``--use-idutils`` options
  297 +require external tools for indexing the code. None of them is
  298 +thus active by default. However, by indexing the code with
  299 +one of these tools, and according to the cocci file used,
  300 +spatch could proceed the entire code base more quickly.
  301 +
  302 +SmPL patch specific options
  303 +---------------------------
  304 +
  305 +SmPL patches can have their own requirements for options passed
  306 +to Coccinelle. SmPL patch specific options can be provided by
  307 +providing them at the top of the SmPL patch, for instance::
  308 +
  309 + // Options: --no-includes --include-headers
  310 +
  311 +SmPL patch Coccinelle requirements
  312 +----------------------------------
  313 +
  314 +As Coccinelle features get added some more advanced SmPL patches
  315 +may require newer versions of Coccinelle. If an SmPL patch requires
  316 +at least a version of Coccinelle, this can be specified as follows,
  317 +as an example if requiring at least Coccinelle >= 1.0.5::
  318 +
  319 + // Requires: 1.0.5
  320 +
  321 +Proposing new semantic patches
  322 +-------------------------------
  323 +
  324 +New semantic patches can be proposed and submitted by kernel
  325 +developers. For sake of clarity, they should be organized in the
  326 +sub-directories of ``scripts/coccinelle/``.
  327 +
  328 +
  329 +Detailed description of the ``report`` mode
  330 +-------------------------------------------
  331 +
  332 +``report`` generates a list in the following format::
  333 +
  334 + file:line:column-column: message
  335 +
  336 +Example
  337 +~~~~~~~
  338 +
  339 +Running::
  340 +
  341 + make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci
  342 +
  343 +will execute the following part of the SmPL script::
  344 +
  345 + <smpl>
  346 + @r depends on !context && !patch && (org || report)@
  347 + expression x;
  348 + position p;
  349 + @@
  350 +
  351 + ERR_PTR@p(PTR_ERR(x))
  352 +
  353 + @script:python depends on report@
  354 + p << r.p;
  355 + x << r.x;
  356 + @@
  357 +
  358 + msg="ERR_CAST can be used with %s" % (x)
  359 + coccilib.report.print_report(p[0], msg)
  360 + </smpl>
  361 +
  362 +This SmPL excerpt generates entries on the standard output, as
  363 +illustrated below::
  364 +
  365 + /home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
  366 + /home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
  367 + /home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
  368 +
  369 +
  370 +Detailed description of the ``patch`` mode
  371 +------------------------------------------
  372 +
  373 +When the ``patch`` mode is available, it proposes a fix for each problem
  374 +identified.
  375 +
  376 +Example
  377 +~~~~~~~
  378 +
  379 +Running::
  380 +
  381 + make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci
  382 +
  383 +will execute the following part of the SmPL script::
  384 +
  385 + <smpl>
  386 + @ depends on !context && patch && !org && !report @
  387 + expression x;
  388 + @@
  389 +
  390 + - ERR_PTR(PTR_ERR(x))
  391 + + ERR_CAST(x)
  392 + </smpl>
  393 +
  394 +This SmPL excerpt generates patch hunks on the standard output, as
  395 +illustrated below::
  396 +
  397 + diff -u -p a/crypto/ctr.c b/crypto/ctr.c
  398 + --- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
  399 + +++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
  400 + @@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
  401 + alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
  402 + CRYPTO_ALG_TYPE_MASK);
  403 + if (IS_ERR(alg))
  404 + - return ERR_PTR(PTR_ERR(alg));
  405 + + return ERR_CAST(alg);
  406 +
  407 + /* Block size must be >= 4 bytes. */
  408 + err = -EINVAL;
  409 +
  410 +Detailed description of the ``context`` mode
  411 +--------------------------------------------
  412 +
  413 +``context`` highlights lines of interest and their context
  414 +in a diff-like style.
  415 +
  416 + **NOTE**: The diff-like output generated is NOT an applicable patch. The
  417 + intent of the ``context`` mode is to highlight the important lines
  418 + (annotated with minus, ``-``) and gives some surrounding context
  419 + lines around. This output can be used with the diff mode of
  420 + Emacs to review the code.
  421 +
  422 +Example
  423 +~~~~~~~
  424 +
  425 +Running::
  426 +
  427 + make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci
  428 +
  429 +will execute the following part of the SmPL script::
  430 +
  431 + <smpl>
  432 + @ depends on context && !patch && !org && !report@
  433 + expression x;
  434 + @@
  435 +
  436 + * ERR_PTR(PTR_ERR(x))
  437 + </smpl>
  438 +
  439 +This SmPL excerpt generates diff hunks on the standard output, as
  440 +illustrated below::
  441 +
  442 + diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
  443 + --- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
  444 + +++ /tmp/nothing
  445 + @@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
  446 + alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
  447 + CRYPTO_ALG_TYPE_MASK);
  448 + if (IS_ERR(alg))
  449 + - return ERR_PTR(PTR_ERR(alg));
  450 +
  451 + /* Block size must be >= 4 bytes. */
  452 + err = -EINVAL;
  453 +
  454 +Detailed description of the ``org`` mode
  455 +----------------------------------------
  456 +
  457 +``org`` generates a report in the Org mode format of Emacs.
  458 +
  459 +Example
  460 +~~~~~~~
  461 +
  462 +Running::
  463 +
  464 + make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci
  465 +
  466 +will execute the following part of the SmPL script::
  467 +
  468 + <smpl>
  469 + @r depends on !context && !patch && (org || report)@
  470 + expression x;
  471 + position p;
  472 + @@
  473 +
  474 + ERR_PTR@p(PTR_ERR(x))
  475 +
  476 + @script:python depends on org@
  477 + p << r.p;
  478 + x << r.x;
  479 + @@
  480 +
  481 + msg="ERR_CAST can be used with %s" % (x)
  482 + msg_safe=msg.replace("[","@(").replace("]",")")
  483 + coccilib.org.print_todo(p[0], msg_safe)
  484 + </smpl>
  485 +
  486 +This SmPL excerpt generates Org entries on the standard output, as
  487 +illustrated below::
  488 +
  489 + * TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
  490 + * TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
  491 + * TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
  1 +#!/bin/bash
  2 +# SPDX-License-Identifier: GPL-2.0
  3 +# Linux kernel coccicheck
  4 +#
  5 +# Read doc/README.coccinelle
  6 +#
  7 +# This script requires at least spatch
  8 +# version 1.0.0-rc11.
  9 +
  10 +DIR="$(dirname $(readlink -f $0))/.."
  11 +SPATCH="`which ${SPATCH:=spatch}`"
  12 +
  13 +if [ ! -x "$SPATCH" ]; then
  14 + echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
  15 + exit 1
  16 +fi
  17 +
  18 +SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}')
  19 +SPATCH_VERSION_NUM=$(echo $SPATCH_VERSION | ${DIR}/scripts/ld-version.sh)
  20 +
  21 +USE_JOBS="no"
  22 +$SPATCH --help | grep "\-\-jobs" > /dev/null && USE_JOBS="yes"
  23 +
  24 +# The verbosity may be set by the environmental parameter V=
  25 +# as for example with 'make V=1 coccicheck'
  26 +
  27 +if [ -n "$V" -a "$V" != "0" ]; then
  28 + VERBOSE="$V"
  29 +else
  30 + VERBOSE=0
  31 +fi
  32 +
  33 +if [ -z "$J" ]; then
  34 + NPROC=$(getconf _NPROCESSORS_ONLN)
  35 +else
  36 + NPROC="$J"
  37 +fi
  38 +
  39 +FLAGS="--very-quiet"
  40 +
  41 +# You can use SPFLAGS to append extra arguments to coccicheck or override any
  42 +# heuristics done in this file as Coccinelle accepts the last options when
  43 +# options conflict.
  44 +#
  45 +# A good example for use of SPFLAGS is if you want to debug your cocci script,
  46 +# you can for instance use the following:
  47 +#
  48 +# $ export COCCI=scripts/coccinelle/misc/irqf_oneshot.cocci
  49 +# $ make coccicheck MODE=report DEBUG_FILE="all.err" SPFLAGS="--profile --show-trying" M=./drivers/mfd/arizona-irq.c
  50 +#
  51 +# "--show-trying" should show you what rule is being processed as it goes to
  52 +# stdout, you do not need a debug file for that. The profile output will be
  53 +# be sent to stdout, if you provide a DEBUG_FILE the profiling data can be
  54 +# inspected there.
  55 +#
  56 +# --profile will not output if --very-quiet is used, so avoid it.
  57 +echo $SPFLAGS | egrep -e "--profile|--show-trying" 2>&1 > /dev/null
  58 +if [ $? -eq 0 ]; then
  59 + FLAGS="--quiet"
  60 +fi
  61 +
  62 +# spatch only allows include directories with the syntax "-I include"
  63 +# while gcc also allows "-Iinclude" and "-include include"
  64 +COCCIINCLUDE=${LINUXINCLUDE//-I/-I }
  65 +COCCIINCLUDE=${COCCIINCLUDE// -include/ --include}
  66 +
  67 +if [ "$C" = "1" -o "$C" = "2" ]; then
  68 + ONLINE=1
  69 +
  70 + # Take only the last argument, which is the C file to test
  71 + shift $(( $# - 1 ))
  72 + OPTIONS="$COCCIINCLUDE $1"
  73 +else
  74 + ONLINE=0
  75 + if [ "$KBUILD_EXTMOD" = "" ] ; then
  76 + OPTIONS="--dir $srctree $COCCIINCLUDE"
  77 + else
  78 + OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
  79 + fi
  80 +fi
  81 +
  82 +if [ "$KBUILD_EXTMOD" != "" ] ; then
  83 + OPTIONS="--patch $srctree $OPTIONS"
  84 +fi
  85 +
  86 +# You can override by using SPFLAGS
  87 +if [ "$USE_JOBS" = "no" ]; then
  88 + trap kill_running SIGTERM SIGINT
  89 + declare -a SPATCH_PID
  90 +elif [ "$NPROC" != "1" ]; then
  91 + # Using 0 should work as well, refer to _SC_NPROCESSORS_ONLN use on
  92 + # https://github.com/rdicosmo/parmap/blob/master/setcore_stubs.c
  93 + OPTIONS="$OPTIONS --jobs $NPROC --chunksize 1"
  94 +fi
  95 +
  96 +if [ "$MODE" = "" ] ; then
  97 + if [ "$ONLINE" = "0" ] ; then
  98 + echo 'You have not explicitly specified the mode to use. Using default "report" mode.'
  99 + echo 'Available modes are the following: patch, report, context, org'
  100 + echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
  101 + echo 'Note however that some modes are not implemented by some semantic patches.'
  102 + fi
  103 + MODE="report"
  104 +fi
  105 +
  106 +if [ "$MODE" = "chain" ] ; then
  107 + if [ "$ONLINE" = "0" ] ; then
  108 + echo 'You have selected the "chain" mode.'
  109 + echo 'All available modes will be tried (in that order): patch, report, context, org'
  110 + fi
  111 +elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
  112 + FLAGS="--no-show-diff $FLAGS"
  113 +fi
  114 +
  115 +if [ "$ONLINE" = "0" ] ; then
  116 + echo ''
  117 + echo 'Please check for false positives in the output before submitting a patch.'
  118 + echo 'When using "patch" mode, carefully review the patch before submitting it.'
  119 + echo ''
  120 +fi
  121 +
  122 +run_cmd_parmap() {
  123 + if [ $VERBOSE -ne 0 ] ; then
  124 + echo "Running ($NPROC in parallel): $@"
  125 + fi
  126 + if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
  127 + if [ -f $DEBUG_FILE ]; then
  128 + echo "Debug file $DEBUG_FILE exists, bailing"
  129 + exit
  130 + fi
  131 + else
  132 + DEBUG_FILE="/dev/null"
  133 + fi
  134 + $@ 2>$DEBUG_FILE
  135 + if [[ $? -ne 0 ]]; then
  136 + echo "coccicheck failed"
  137 + exit $?
  138 + fi
  139 +}
  140 +
  141 +run_cmd_old() {
  142 + local i
  143 + if [ $VERBOSE -ne 0 ] ; then
  144 + echo "Running ($NPROC in parallel): $@"
  145 + fi
  146 + for i in $(seq 0 $(( NPROC - 1)) ); do
  147 + eval "$@ --max $NPROC --index $i &"
  148 + SPATCH_PID[$i]=$!
  149 + if [ $VERBOSE -eq 2 ] ; then
  150 + echo "${SPATCH_PID[$i]} running"
  151 + fi
  152 + done
  153 + wait
  154 +}
  155 +
  156 +run_cmd() {
  157 + if [ "$USE_JOBS" = "yes" ]; then
  158 + run_cmd_parmap $@
  159 + else
  160 + run_cmd_old $@
  161 + fi
  162 +}
  163 +
  164 +kill_running() {
  165 + for i in $(seq 0 $(( NPROC - 1 )) ); do
  166 + if [ $VERBOSE -eq 2 ] ; then
  167 + echo "Killing ${SPATCH_PID[$i]}"
  168 + fi
  169 + kill ${SPATCH_PID[$i]} 2>/dev/null
  170 + done
  171 +}
  172 +
  173 +# You can override heuristics with SPFLAGS, these must always go last
  174 +OPTIONS="$OPTIONS $SPFLAGS"
  175 +
  176 +coccinelle () {
  177 + COCCI="$1"
  178 +
  179 + OPT=`grep "Option" $COCCI | cut -d':' -f2`
  180 + REQ=`grep "Requires" $COCCI | cut -d':' -f2 | sed "s| ||"`
  181 + REQ_NUM=$(echo $REQ | ${DIR}/scripts/ld-version.sh)
  182 + if [ "$REQ_NUM" != "0" ] ; then
  183 + if [ "$SPATCH_VERSION_NUM" -lt "$REQ_NUM" ] ; then
  184 + echo "Skipping coccinele SmPL patch: $COCCI"
  185 + echo "You have coccinelle: $SPATCH_VERSION"
  186 + echo "This SmPL patch requires: $REQ"
  187 + return
  188 + fi
  189 + fi
  190 +
  191 +# The option '--parse-cocci' can be used to syntactically check the SmPL files.
  192 +#
  193 +# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
  194 +
  195 + if [ $VERBOSE -ne 0 -a $ONLINE -eq 0 ] ; then
  196 +
  197 + FILE=`echo $COCCI | sed "s|$srctree/||"`
  198 +
  199 + echo "Processing `basename $COCCI`"
  200 + echo "with option(s) \"$OPT\""
  201 + echo ''
  202 + echo 'Message example to submit a patch:'
  203 +
  204 + sed -ne 's|^///||p' $COCCI
  205 +
  206 + if [ "$MODE" = "patch" ] ; then
  207 + echo ' The semantic patch that makes this change is available'
  208 + elif [ "$MODE" = "report" ] ; then
  209 + echo ' The semantic patch that makes this report is available'
  210 + elif [ "$MODE" = "context" ] ; then
  211 + echo ' The semantic patch that spots this code is available'
  212 + elif [ "$MODE" = "org" ] ; then
  213 + echo ' The semantic patch that makes this Org report is available'
  214 + else
  215 + echo ' The semantic patch that makes this output is available'
  216 + fi
  217 + echo " in $FILE."
  218 + echo ''
  219 + echo ' More information about semantic patching is available at'
  220 + echo ' http://coccinelle.lip6.fr/'
  221 + echo ''
  222 +
  223 + if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
  224 + echo 'Semantic patch information:'
  225 + sed -ne 's|^//#||p' $COCCI
  226 + echo ''
  227 + fi
  228 + fi
  229 +
  230 + if [ "$MODE" = "chain" ] ; then
  231 + run_cmd $SPATCH -D patch \
  232 + $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
  233 + run_cmd $SPATCH -D report \
  234 + $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || \
  235 + run_cmd $SPATCH -D context \
  236 + $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
  237 + run_cmd $SPATCH -D org \
  238 + $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || exit 1
  239 + elif [ "$MODE" = "rep+ctxt" ] ; then
  240 + run_cmd $SPATCH -D report \
  241 + $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff && \
  242 + run_cmd $SPATCH -D context \
  243 + $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
  244 + else
  245 + run_cmd $SPATCH -D $MODE $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
  246 + fi
  247 +
  248 +}
  249 +
  250 +if [ "$COCCI" = "" ] ; then
  251 + for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
  252 + coccinelle $f
  253 + done
  254 +else
  255 + coccinelle $COCCI
  256 +fi