The latest & greatest unused #include spotter. Faster, one-pass and
more precise than ever. 1230 hits on the current kernel.
This commit is contained in:
parent
ae7c8a2bb8
commit
a1b75a424f
@ -11,135 +11,21 @@
|
||||
# This script tries to find #include statements which are not needed in
|
||||
# the FreeBSD kernel tree.
|
||||
#
|
||||
# For each include file on the tasklist (set in $includes right below)
|
||||
# For each object file (see around line 170 for how these are selected)
|
||||
# For each kernel (set in $kernels right below) and all modules
|
||||
# if the object exists
|
||||
# figure out the sourcefile
|
||||
# if the sourcefile doesn't contain "#include $include"
|
||||
# continue
|
||||
# if object can be compile without $include existing
|
||||
# continue /* probably protected by #ifdef something */
|
||||
# if object can't be compile with empty file for $include
|
||||
# continue /* needed something/
|
||||
# if the compiler warnings/errors were different than normal
|
||||
# continue /* needed something/
|
||||
# if the resulting object were different than normal
|
||||
# continue /* needed something */
|
||||
# /* didn't need this include */
|
||||
# remove $include from source file
|
||||
#
|
||||
# Takes about 12h to run on a PII/400
|
||||
#
|
||||
# NOTE: /usr/include is mucked about with!!
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Base of the kernel sources you want to work on
|
||||
cd /some/sourcetree/sys
|
||||
cd /sys
|
||||
|
||||
# Set to true to start from scratch, false to resume
|
||||
init=true
|
||||
init=false
|
||||
|
||||
# Which kernels you want to check
|
||||
kernels="LINT GENERIC GENERIC98"
|
||||
|
||||
# Which includes you want to check
|
||||
(
|
||||
find */include -name '*.h' -ls | sed 's;.*include;machine;'
|
||||
find * -name '*.h' -print
|
||||
) | sed '
|
||||
/compile/d
|
||||
/modules/d
|
||||
/boot/d
|
||||
' | sort -u > _includes
|
||||
|
||||
# Insert some filtering here if you want to...
|
||||
includes=`cat _includes`
|
||||
|
||||
NO_MODULES=yes
|
||||
export NO_MODULES
|
||||
|
||||
check_it ()
|
||||
{
|
||||
if [ -f ::$2 ] ; then
|
||||
if grep "#[ ]*include[ ].$1." ::$2 > /dev/null; then
|
||||
src=`ls -l ::$2 | awk '{print $11}'`
|
||||
else
|
||||
echo " -"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
rm -f $2
|
||||
make -n $2 > _0 2>&1 || true
|
||||
src=`awk '$1 == "cc" {print $NF}' _0`
|
||||
if expr "x$src" : 'x.*\.c$' > /dev/null ; then
|
||||
ln -s $src ::$2
|
||||
else
|
||||
echo " not C source"
|
||||
# don't create $2, we don't care about it.
|
||||
exit 0
|
||||
fi
|
||||
if grep "#[ ]*include[ ].$1." $src > /dev/null; then
|
||||
true
|
||||
else
|
||||
echo " -"
|
||||
touch $2
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
rm ../../$3
|
||||
rm -f $2
|
||||
if [ -f /usr/include/$1 ] ; then
|
||||
mv /usr/include/$1 /usr/include/${1}_
|
||||
make $2 > _0 2>&1 || true
|
||||
mv /usr/include/${1}_ /usr/include/$1
|
||||
else
|
||||
make $2 > _0 2>&1 || true
|
||||
fi
|
||||
echo > ../../$3
|
||||
if [ -f $2 ] ; then
|
||||
echo " no read"
|
||||
cp ../../${3}_ ../../$3
|
||||
exit 0
|
||||
fi
|
||||
|
||||
make $2 > _1 2>&1 || true
|
||||
|
||||
cp ../../${3}_ ../../$3
|
||||
|
||||
if [ ! -f $2 ] ; then
|
||||
echo " compile error"
|
||||
touch $2
|
||||
exit 0
|
||||
fi
|
||||
m2=`md5 < $2`
|
||||
|
||||
rm $2
|
||||
make $2 > _0 2>&1 || true
|
||||
if [ ! -f $2 ] ; then
|
||||
echo "$2 reference compile failed"
|
||||
touch $2
|
||||
cat _0
|
||||
exit 0
|
||||
fi
|
||||
m1=`md5 < $2`
|
||||
|
||||
if cmp _0 _1 > /dev/null 2>&1 ; then
|
||||
true
|
||||
else
|
||||
echo " warnings changed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ $m1 != $m2 ] ; then
|
||||
echo " MD5 changed"
|
||||
#exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if $init ; then
|
||||
(
|
||||
echo "Cleaning modules"
|
||||
@ -156,18 +42,35 @@ if $init ; then
|
||||
cd compile
|
||||
ls | grep -v CVS | xargs rm -rf
|
||||
)
|
||||
fi
|
||||
|
||||
(
|
||||
echo "Cleaning temp files"
|
||||
find . -name '*.h_' -print | xargs rm -f
|
||||
find . -name '::*' -print | xargs rm -f
|
||||
find . -name '*.o' -size 0 -print | xargs rm -f
|
||||
)
|
||||
|
||||
echo "Configuring kernels"
|
||||
(
|
||||
cd i386/conf
|
||||
make LINT
|
||||
config -r -p LINT
|
||||
if $init ; then
|
||||
config -r LINT
|
||||
config -r GENERIC
|
||||
else
|
||||
config LINT
|
||||
config GENERIC
|
||||
fi
|
||||
)
|
||||
(
|
||||
cd pc98/conf
|
||||
cp -f GENERIC GENERIC98
|
||||
if $init ; then
|
||||
config -r GENERIC98
|
||||
else
|
||||
config GENERIC98
|
||||
fi
|
||||
)
|
||||
|
||||
for i in $kernels
|
||||
@ -175,8 +78,7 @@ if $init ; then
|
||||
(
|
||||
echo "Compiling $i"
|
||||
cd compile/$i
|
||||
rm -f ::*
|
||||
make -k > x.0 2>&1
|
||||
make > x.0 2>&1
|
||||
tail -4 x.0
|
||||
if [ ! -f kernel ] ; then
|
||||
echo "Error: No $i kernel built"
|
||||
@ -188,10 +90,8 @@ if $init ; then
|
||||
(
|
||||
echo "Compiling modules"
|
||||
cd modules
|
||||
rm -f */::*
|
||||
make -k > x.0 2>&1 || true
|
||||
make > x.0 2>&1
|
||||
)
|
||||
fi
|
||||
|
||||
# Generate the list of object files we want to check
|
||||
# you can put a convenient grep right before the sort
|
||||
@ -215,72 +115,192 @@ done
|
||||
/vers.o/d
|
||||
/setdef0.o/d
|
||||
/setdef1.o/d
|
||||
/::/d
|
||||
' | sort -u > _
|
||||
|
||||
objlist=`cat _`
|
||||
|
||||
find . -name '*.h_' -print | xargs rm -f
|
||||
|
||||
for incl in $includes
|
||||
for o in $objlist
|
||||
do
|
||||
inclf=`echo $incl | sed 's/machine/i386\/include/'`
|
||||
if [ ! -f ${inclf} ] ; then
|
||||
continue
|
||||
fi
|
||||
if [ ! -f ${inclf}_ ] ; then
|
||||
cp $inclf ${inclf}_
|
||||
fi
|
||||
for obj in $objlist
|
||||
do
|
||||
(
|
||||
echo -n "$incl $obj:"
|
||||
l=""
|
||||
src=""
|
||||
|
||||
cd compile
|
||||
for i in $kernels
|
||||
for k in $kernels
|
||||
do
|
||||
cd $i
|
||||
|
||||
if [ ! -f $obj ] ; then
|
||||
cd ..
|
||||
continue
|
||||
if [ ! -f compile/$k/$o ] ; then
|
||||
continue;
|
||||
fi
|
||||
echo -n " [$i]"
|
||||
check_it $incl $obj $inclf
|
||||
cd ..
|
||||
done
|
||||
cd ..
|
||||
cd modules
|
||||
for d in */$obj
|
||||
do
|
||||
if [ ! -f $d ] ; then
|
||||
continue
|
||||
fi
|
||||
b=`dirname $d`
|
||||
echo -n " [$b]"
|
||||
cd $b
|
||||
check_it $incl $obj $inclf
|
||||
cd ..
|
||||
done
|
||||
cd ..
|
||||
l="$l compile/$k"
|
||||
if [ "x$src" = "x" ] ; then
|
||||
echo " -"
|
||||
exit 0
|
||||
fi
|
||||
echo -n " ($src)"
|
||||
echo "$incl $src" >> _incl
|
||||
(
|
||||
cd compile/LINT
|
||||
if [ -f $src ] ; then
|
||||
grep -v "#[ ]*include[ ]*.$incl." $src > ${src}_
|
||||
mv ${src}_ $src
|
||||
echo " BINGO!"
|
||||
cd compile/$k
|
||||
mv $o ${o}_
|
||||
make -n $o > _
|
||||
mv ${o}_ $o
|
||||
src=compile/$k/`awk '$1 == "cc" {print $NF}' _`
|
||||
cd ../..
|
||||
if expr "x$src" : 'x.*\.c$' > /dev/null ; then
|
||||
true
|
||||
else
|
||||
echo " BINGO!, but not in LINT"
|
||||
echo NO SRC $o
|
||||
src=""
|
||||
fi
|
||||
fi
|
||||
)
|
||||
)
|
||||
done
|
||||
for m in modules/*
|
||||
do
|
||||
if [ ! -d $m -o ! -f $m/$o ] ; then
|
||||
continue;
|
||||
fi
|
||||
l="$l $m"
|
||||
if [ "x$src" = "x" ] ; then
|
||||
cd $m
|
||||
mv $o ${o}_
|
||||
make -n $o > _
|
||||
mv ${o}_ $o
|
||||
src=`awk '$1 == "cc" {print $NF}' _`
|
||||
cd ../..
|
||||
if expr "x$src" : 'x.*\.c$' > /dev/null ; then
|
||||
if [ "`dirname $src`" = "." ] ; then
|
||||
src="$m/$src"
|
||||
fi
|
||||
true
|
||||
else
|
||||
echo NO SRC $o
|
||||
src=""
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ "x$src" = "x" ] ; then
|
||||
echo "NO SOURCE $o"
|
||||
continue
|
||||
fi
|
||||
echo "OBJ $o"
|
||||
echo " SRC $src"
|
||||
|
||||
grep -n '^[ ]*#[ ]*include' $src | sed '
|
||||
s/^\([0-9]*\):[ ]*#[ ]*include[ ]*[<"]/\1 /
|
||||
s/[">].*//
|
||||
/ opt_/d
|
||||
' | sort -rn | while read lin incl
|
||||
do
|
||||
S=""
|
||||
echo " INCL $lin $incl"
|
||||
cp $src ${src}_
|
||||
|
||||
# Check if we can compile without this #include line.
|
||||
|
||||
sed "${lin}s/.*//" ${src}_ > ${src}
|
||||
for t in $l
|
||||
do
|
||||
cd $t
|
||||
mv ${o} ${o}_
|
||||
if make ${o} > _log 2>&1 ; then
|
||||
if cmp -s ${o} ${o}_ ; then
|
||||
echo " $t same object"
|
||||
else
|
||||
echo " $t changed object"
|
||||
S=TAG
|
||||
fi
|
||||
else
|
||||
echo " $t used"
|
||||
S=TAG
|
||||
fi
|
||||
mv ${o}_ ${o}
|
||||
cd ../..
|
||||
if [ "x$S" != "x" ] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "x$S" != "x" ] ; then
|
||||
mv ${src}_ ${src}
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if this is because it is a nested #include
|
||||
for t in $l
|
||||
do
|
||||
cd $t
|
||||
rm -rf foo
|
||||
mkdir -p foo/${incl}
|
||||
rmdir foo/${incl}
|
||||
touch foo/${incl}
|
||||
mv ${o} ${o}_
|
||||
if make INCLMAGIC=-Ifoo ${o} > _log2 2>&1 ; then
|
||||
if cmp -s ${o} ${o}_ ; then
|
||||
echo " $t still same object"
|
||||
else
|
||||
echo " $t changed object"
|
||||
S=TAG
|
||||
fi
|
||||
else
|
||||
echo " $t nested include"
|
||||
S=TAG
|
||||
fi
|
||||
rm -rf foo
|
||||
mv ${o}_ ${o}
|
||||
cd ../..
|
||||
if [ "x$S" != "x" ] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "x$S" != "x" ] ; then
|
||||
mv ${src}_ ${src}
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if this is because it is #ifdef'ed out
|
||||
|
||||
sed "${lin}s/.*/#error \"BARF\"/" ${src}_ > ${src}
|
||||
for t in $l
|
||||
do
|
||||
cd $t
|
||||
mv ${o} ${o}_
|
||||
if make ${o} > /dev/null 2>&1 ; then
|
||||
echo " $t line not read"
|
||||
S=TAG
|
||||
fi
|
||||
mv ${o}_ ${o}
|
||||
cd ../..
|
||||
if [ "x$S" != "x" ] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
mv ${src}_ ${src}
|
||||
if [ "x$S" != "x" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if the warnings changed.
|
||||
|
||||
for t in $l
|
||||
do
|
||||
cd $t
|
||||
mv ${o} ${o}_
|
||||
if make ${o} > _ref 2>&1 ; then
|
||||
if cmp -s _ref _log ; then
|
||||
echo " $t same warnings"
|
||||
else
|
||||
echo " $t changed warnings"
|
||||
S=TAG
|
||||
fi
|
||||
else
|
||||
echo "ARGHH!!!"
|
||||
exit 9
|
||||
fi
|
||||
|
||||
mv ${o}_ ${o}
|
||||
cd ../..
|
||||
if [ "x$S" != "x" ] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "x$S" != "x" ] ; then
|
||||
continue
|
||||
fi
|
||||
cp $src ${src}_
|
||||
sed "${lin}d" ${src}_ > ${src}
|
||||
rm ${src}_
|
||||
touch _again
|
||||
echo "BINGO $src $lin $incl $obj $l"
|
||||
done
|
||||
done
|
||||
|
Loading…
x
Reference in New Issue
Block a user