1 #!/usr/bin/env bash !! 1 #!/bin/bash 2 # SPDX-License-Identifier: GPL-2.0 !! 2 3 # Linux kernel coccicheck << 4 # << 5 # Read Documentation/dev-tools/coccinelle.rst << 6 # 3 # 7 # This script requires at least spatch 4 # This script requires at least spatch 8 # version 1.0.0-rc11. 5 # version 1.0.0-rc11. >> 6 # 9 7 10 DIR="$(dirname $(readlink -f $0))/.." << 11 SPATCH="`which ${SPATCH:=spatch}`" 8 SPATCH="`which ${SPATCH:=spatch}`" 12 9 13 if [ ! -x "$SPATCH" ]; then !! 10 trap kill_running SIGTERM SIGINT 14 echo 'spatch is part of the Coccinelle pro !! 11 declare -a SPATCH_PID 15 exit 1 << 16 fi << 17 << 18 SPATCH_VERSION=$($SPATCH --version | head -1 | << 19 << 20 USE_JOBS="no" << 21 $SPATCH --help | grep -e "--jobs" > /dev/null << 22 12 23 # The verbosity may be set by the environmenta 13 # The verbosity may be set by the environmental parameter V= 24 # as for example with 'make V=1 coccicheck' 14 # as for example with 'make V=1 coccicheck' 25 15 26 if [ -n "$V" -a "$V" != "0" ]; then 16 if [ -n "$V" -a "$V" != "0" ]; then 27 VERBOSE="$V" 17 VERBOSE="$V" 28 else 18 else 29 VERBOSE=0 19 VERBOSE=0 30 fi 20 fi 31 21 32 FLAGS="--very-quiet" !! 22 if [ -z "$J" ]; then 33 !! 23 NPROC=$(getconf _NPROCESSORS_ONLN) 34 # You can use SPFLAGS to append extra argument !! 24 else 35 # heuristics done in this file as Coccinelle a !! 25 NPROC="$J" 36 # options conflict. << 37 # << 38 # A good example for use of SPFLAGS is if you << 39 # you can for instance use the following: << 40 # << 41 # $ export COCCI=scripts/coccinelle/misc/irqf_ << 42 # $ make coccicheck MODE=report DEBUG_FILE="al << 43 # << 44 # "--show-trying" should show you what rule is << 45 # stdout, you do not need a debug file for tha << 46 # be sent to stdout, if you provide a DEBUG_FI << 47 # inspected there. << 48 # << 49 # --profile will not output if --very-quiet is << 50 echo $SPFLAGS | grep -E -e "--profile|--show-t << 51 if [ $? -eq 0 ]; then << 52 FLAGS="--quiet" << 53 fi 26 fi 54 27 >> 28 FLAGS="$SPFLAGS --very-quiet" >> 29 55 # spatch only allows include directories with 30 # spatch only allows include directories with the syntax "-I include" 56 # while gcc also allows "-Iinclude" and "-incl 31 # while gcc also allows "-Iinclude" and "-include include" 57 COCCIINCLUDE=${LINUXINCLUDE//-I/-I } 32 COCCIINCLUDE=${LINUXINCLUDE//-I/-I } 58 COCCIINCLUDE=${COCCIINCLUDE// -include/ --incl 33 COCCIINCLUDE=${COCCIINCLUDE// -include/ --include} 59 34 60 if [ "$C" = "1" -o "$C" = "2" ]; then 35 if [ "$C" = "1" -o "$C" = "2" ]; then 61 ONLINE=1 36 ONLINE=1 62 37 63 if [[ $# -le 0 ]]; then << 64 echo '' << 65 echo 'Specifying both the variable << 66 command results in a shift count error.' << 67 echo '' << 68 echo 'Try specifying "scripts/cocc << 69 echo '' << 70 echo 'Example: make C=2 CHECK << 71 echo '' << 72 exit 1 << 73 fi << 74 << 75 # Take only the last argument, which is th 38 # Take only the last argument, which is the C file to test 76 shift $(( $# - 1 )) 39 shift $(( $# - 1 )) 77 OPTIONS="$COCCIINCLUDE $1" 40 OPTIONS="$COCCIINCLUDE $1" 78 << 79 # No need to parallelize Coccinelle since << 80 NPROC=1 << 81 else 41 else 82 ONLINE=0 42 ONLINE=0 83 if [ "$KBUILD_EXTMOD" = "" ] ; then 43 if [ "$KBUILD_EXTMOD" = "" ] ; then 84 OPTIONS="--dir $srctree $COCCIINCLUDE" 44 OPTIONS="--dir $srctree $COCCIINCLUDE" 85 else 45 else 86 OPTIONS="--dir $KBUILD_EXTMOD $COCCIIN 46 OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" 87 fi 47 fi 88 << 89 # Use only one thread per core by default << 90 THREADS_PER_CORE=$(LANG=C lscpu | grep "Th << 91 if [ -z "$J" ]; then << 92 NPROC=$(getconf _NPROCESSORS_ONLN) << 93 if [ $THREADS_PER_CORE -gt 1 -a $NPROC << 94 NPROC=$((NPROC/2)) << 95 fi << 96 else << 97 NPROC="$J" << 98 fi << 99 fi 48 fi 100 49 101 if [ "$KBUILD_EXTMOD" != "" ] ; then 50 if [ "$KBUILD_EXTMOD" != "" ] ; then 102 OPTIONS="--patch $srctree $OPTIONS" 51 OPTIONS="--patch $srctree $OPTIONS" 103 fi 52 fi 104 53 105 # You can override by using SPFLAGS !! 54 if [ ! -x "$SPATCH" ]; then 106 if [ "$USE_JOBS" = "no" ]; then !! 55 echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/' 107 trap kill_running SIGTERM SIGINT !! 56 exit 1 108 declare -a SPATCH_PID << 109 elif [ "$NPROC" != "1" ]; then << 110 # Using 0 should work as well, refer t << 111 # https://github.com/rdicosmo/parmap/b << 112 OPTIONS="$OPTIONS --jobs $NPROC --chun << 113 fi 57 fi 114 58 115 if [ "$MODE" = "" ] ; then 59 if [ "$MODE" = "" ] ; then 116 if [ "$ONLINE" = "0" ] ; then 60 if [ "$ONLINE" = "0" ] ; then 117 echo 'You have not explicitly specifie 61 echo 'You have not explicitly specified the mode to use. Using default "report" mode.' 118 echo 'Available modes are the followin !! 62 echo 'Available modes are the following: patch, report, context, org' 119 echo 'You can specify the mode with "m 63 echo 'You can specify the mode with "make coccicheck MODE=<mode>"' 120 echo 'Note however that some modes are 64 echo 'Note however that some modes are not implemented by some semantic patches.' 121 fi 65 fi 122 MODE="report" 66 MODE="report" 123 fi 67 fi 124 68 125 if [ "$MODE" = "chain" ] ; then 69 if [ "$MODE" = "chain" ] ; then 126 if [ "$ONLINE" = "0" ] ; then 70 if [ "$ONLINE" = "0" ] ; then 127 echo 'You have selected the "chain" mo 71 echo 'You have selected the "chain" mode.' 128 echo 'All available modes will be trie 72 echo 'All available modes will be tried (in that order): patch, report, context, org' 129 fi 73 fi 130 elif [ "$MODE" = "report" -o "$MODE" = "org" ] 74 elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then 131 FLAGS="--no-show-diff $FLAGS" !! 75 FLAGS="$FLAGS --no-show-diff" 132 fi 76 fi 133 77 134 if [ "$ONLINE" = "0" ] ; then 78 if [ "$ONLINE" = "0" ] ; then 135 echo '' 79 echo '' 136 echo 'Please check for false positives in 80 echo 'Please check for false positives in the output before submitting a patch.' 137 echo 'When using "patch" mode, carefully r 81 echo 'When using "patch" mode, carefully review the patch before submitting it.' 138 echo '' 82 echo '' 139 fi 83 fi 140 84 141 run_cmd_parmap() { !! 85 run_cmd() { 142 if [ $VERBOSE -ne 0 ] ; then << 143 echo "Running ($NPROC in paral << 144 fi << 145 if [ "$DEBUG_FILE" != "/dev/null" -a " << 146 echo $@>>$DEBUG_FILE << 147 $@ 2>>$DEBUG_FILE << 148 else << 149 echo $@ << 150 $@ 2>&1 << 151 fi << 152 << 153 err=$? << 154 if [[ $err -ne 0 ]]; then << 155 echo "coccicheck failed" << 156 exit $err << 157 fi << 158 } << 159 << 160 run_cmd_old() { << 161 local i 86 local i 162 if [ $VERBOSE -ne 0 ] ; then 87 if [ $VERBOSE -ne 0 ] ; then 163 echo "Running ($NPROC in paral 88 echo "Running ($NPROC in parallel): $@" 164 fi 89 fi 165 for i in $(seq 0 $(( NPROC - 1)) ); do 90 for i in $(seq 0 $(( NPROC - 1)) ); do 166 eval "$@ --max $NPROC --index 91 eval "$@ --max $NPROC --index $i &" 167 SPATCH_PID[$i]=$! 92 SPATCH_PID[$i]=$! 168 if [ $VERBOSE -eq 2 ] ; then 93 if [ $VERBOSE -eq 2 ] ; then 169 echo "${SPATCH_PID[$i] 94 echo "${SPATCH_PID[$i]} running" 170 fi 95 fi 171 done 96 done 172 wait 97 wait 173 } 98 } 174 99 175 run_cmd() { << 176 if [ "$USE_JOBS" = "yes" ]; then << 177 run_cmd_parmap $@ << 178 else << 179 run_cmd_old $@ << 180 fi << 181 } << 182 << 183 kill_running() { 100 kill_running() { 184 for i in $(seq 0 $(( NPROC - 1 )) ); d !! 101 for i in $(seq $(( NPROC - 1 )) ); do 185 if [ $VERBOSE -eq 2 ] ; then 102 if [ $VERBOSE -eq 2 ] ; then 186 echo "Killing ${SPATCH 103 echo "Killing ${SPATCH_PID[$i]}" 187 fi 104 fi 188 kill ${SPATCH_PID[$i]} 2>/dev/ 105 kill ${SPATCH_PID[$i]} 2>/dev/null 189 done 106 done 190 } 107 } 191 108 192 # You can override heuristics with SPFLAGS, th << 193 OPTIONS="$OPTIONS $SPFLAGS" << 194 << 195 coccinelle () { 109 coccinelle () { 196 COCCI="$1" 110 COCCI="$1" 197 111 198 OPT=`grep "Options:" $COCCI | cut -d':' -f !! 112 OPT=`grep "Option" $COCCI | cut -d':' -f2` 199 REQ=`grep "Requires:" $COCCI | cut -d':' - << 200 if [ -n "$REQ" ] && ! { echo "$REQ"; echo << 201 echo "Skipping coccinelle SmPL pat << 202 echo "You have coccinelle: << 203 echo "This SmPL patch requires: << 204 return << 205 fi << 206 113 207 # The option '--parse-cocci' can be used to 114 # The option '--parse-cocci' can be used to syntactically check the SmPL files. 208 # 115 # 209 # $SPATCH -D $MODE $FLAGS -parse_cocci $COC 116 # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null 210 117 211 if [ $VERBOSE -ne 0 -a $ONLINE -eq 0 ] ; t 118 if [ $VERBOSE -ne 0 -a $ONLINE -eq 0 ] ; then 212 119 213 FILE=${COCCI#$srctree/} !! 120 FILE=`echo $COCCI | sed "s|$srctree/||"` 214 121 215 echo "Processing `basename $COCCI`" 122 echo "Processing `basename $COCCI`" 216 echo "with option(s) \"$OPT\"" 123 echo "with option(s) \"$OPT\"" 217 echo '' 124 echo '' 218 echo 'Message example to submit a patc 125 echo 'Message example to submit a patch:' 219 126 220 sed -ne 's|^///||p' $COCCI 127 sed -ne 's|^///||p' $COCCI 221 128 222 if [ "$MODE" = "patch" ] ; then 129 if [ "$MODE" = "patch" ] ; then 223 echo ' The semantic patch that mak 130 echo ' The semantic patch that makes this change is available' 224 elif [ "$MODE" = "report" ] ; then 131 elif [ "$MODE" = "report" ] ; then 225 echo ' The semantic patch that mak 132 echo ' The semantic patch that makes this report is available' 226 elif [ "$MODE" = "context" ] ; then 133 elif [ "$MODE" = "context" ] ; then 227 echo ' The semantic patch that spo 134 echo ' The semantic patch that spots this code is available' 228 elif [ "$MODE" = "org" ] ; then 135 elif [ "$MODE" = "org" ] ; then 229 echo ' The semantic patch that mak 136 echo ' The semantic patch that makes this Org report is available' 230 else 137 else 231 echo ' The semantic patch that mak 138 echo ' The semantic patch that makes this output is available' 232 fi 139 fi 233 echo " in $FILE." 140 echo " in $FILE." 234 echo '' 141 echo '' 235 echo ' More information about semantic 142 echo ' More information about semantic patching is available at' 236 echo ' http://coccinelle.lip6.fr/' 143 echo ' http://coccinelle.lip6.fr/' 237 echo '' 144 echo '' 238 145 239 if [ "`sed -ne 's|^//#||p' $COCCI`" ] 146 if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then 240 echo 'Semantic patch information:' 147 echo 'Semantic patch information:' 241 sed -ne 's|^//#||p' $COCCI 148 sed -ne 's|^//#||p' $COCCI 242 echo '' 149 echo '' 243 fi 150 fi 244 fi 151 fi 245 152 246 if [ "$MODE" = "chain" ] ; then 153 if [ "$MODE" = "chain" ] ; then 247 run_cmd $SPATCH -D patch \ 154 run_cmd $SPATCH -D patch \ 248 $FLAGS --cocci-file $COCCI $OP 155 $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \ 249 run_cmd $SPATCH -D report \ 156 run_cmd $SPATCH -D report \ 250 $FLAGS --cocci-file $COCCI $OP 157 $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || \ 251 run_cmd $SPATCH -D context \ 158 run_cmd $SPATCH -D context \ 252 $FLAGS --cocci-file $COCCI $OP 159 $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \ 253 run_cmd $SPATCH -D org \ 160 run_cmd $SPATCH -D org \ 254 $FLAGS --cocci-file $COCCI $OP 161 $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || exit 1 255 elif [ "$MODE" = "rep+ctxt" ] ; then 162 elif [ "$MODE" = "rep+ctxt" ] ; then 256 run_cmd $SPATCH -D report \ 163 run_cmd $SPATCH -D report \ 257 $FLAGS --cocci-file $COCCI $OP 164 $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff && \ 258 run_cmd $SPATCH -D context \ 165 run_cmd $SPATCH -D context \ 259 $FLAGS --cocci-file $COCCI $OP 166 $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1 260 else 167 else 261 run_cmd $SPATCH -D $MODE $FLAGS --co 168 run_cmd $SPATCH -D $MODE $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1 262 fi 169 fi 263 170 264 } 171 } 265 << 266 if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_F << 267 if [ -f $DEBUG_FILE ]; then << 268 echo "Debug file $DEBUG_FILE e << 269 exit << 270 fi << 271 else << 272 DEBUG_FILE="/dev/null" << 273 fi << 274 172 275 if [ "$COCCI" = "" ] ; then 173 if [ "$COCCI" = "" ] ; then 276 for f in `find $srctree/scripts/coccinelle 174 for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do 277 coccinelle $f 175 coccinelle $f 278 done 176 done 279 else 177 else 280 coccinelle $COCCI 178 coccinelle $COCCI 281 fi 179 fi
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.