152139Sphk#!/bin/sh
252139Sphk# ----------------------------------------------------------------------------
352139Sphk# "THE BEER-WARE LICENSE" (Revision 42):
452139Sphk# <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
552139Sphk# can do whatever you want with this stuff. If we meet some day, and you think
652139Sphk# this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
752139Sphk# ----------------------------------------------------------------------------
852139Sphk#
952139Sphk# $FreeBSD$
1052139Sphk#
1152139Sphk# This script tries to find #include statements which are not needed in
1252139Sphk# the FreeBSD kernel tree.
1352139Sphk#
1452139Sphk
1552139Sphkset -e
1652139Sphk
1752139Sphk# Base of the kernel sources you want to work on
1867812Sphkcd /sys
1952139Sphk
2052139Sphk# Set to true to start from scratch, false to resume
2167812Sphkinit=false
2252139Sphk
2352139Sphk# Which kernels you want to check
2452139Sphkkernels="LINT GENERIC GENERIC98"
2552139Sphk
2664894SphkNO_MODULES=yes
2764894Sphkexport NO_MODULES
2864894Sphk
2952139Sphkif $init ; then
3052139Sphk	(
3159706Sphk	echo "Cleaning modules"
3252139Sphk	cd modules
3352139Sphk	make clean > /dev/null 2>&1
3452139Sphk	make cleandir > /dev/null 2>&1
3552139Sphk	make cleandir > /dev/null 2>&1
3652139Sphk	make clean > /dev/null 2>&1
3752139Sphk	make clean > /dev/null 2>&1
3852139Sphk	)
3952139Sphk
4052139Sphk	(
4159706Sphk	echo "Cleaning compile"
4252139Sphk	cd compile
4352139Sphk	ls | grep -v CVS | xargs rm -rf
4452139Sphk	)
4567812Sphkfi
4652139Sphk
4767812Sphk(
4867812Sphkecho "Cleaning temp files"
4967812Sphkfind . -name '*.h_' -print | xargs rm -f
5067812Sphkfind . -name '::*' -print | xargs rm -f
5167812Sphkfind . -name '*.o' -size 0 -print | xargs rm -f
5267812Sphk)
5367812Sphk
5467812Sphkecho "Configuring kernels"
5567812Sphk(
5667812Sphk	cd i386/conf
5767812Sphk	make LINT
5867812Sphk	if $init ; then
5975872Sphk		rm -rf ../../compile/LINT ../../compile/GENERIC
6067812Sphk	fi
6175872Sphk	config LINT
6275872Sphk	config GENERIC
6367812Sphk)
6467812Sphk(
6567812Sphk	cd pc98/conf
6667812Sphk	cp -f GENERIC GENERIC98
6767812Sphk	if $init ; then
6875872Sphk		rm -rf ../../compile/GENERIC98
6967812Sphk	fi
7075872Sphk	config GENERIC98
7167812Sphk)
7252139Sphk
7367812Sphkfor i in $kernels
7467812Sphkdo
7552139Sphk	(
7667812Sphk	echo "Compiling $i"
7767812Sphk	cd compile/$i
7867812Sphk	make > x.0 2>&1
7967812Sphk	tail -4 x.0
8067812Sphk	if [ ! -f kernel ] ; then
8167812Sphk		echo "Error: No $i kernel built"
8267812Sphk		exit 1
8367812Sphk	fi
8452139Sphk	)
8567812Sphkdone
8652139Sphk
8767812Sphk(
8867812Sphkecho "Compiling modules"
8967812Sphkcd modules
9067812Sphkmake > x.0 2>&1 
9167812Sphk)
9267812Sphk
9352139Sphk# Generate the list of object files we want to check
9452139Sphk# you can put a convenient grep right before the sort
9552139Sphk# if you want just some specific subset of files checked
9652139Sphk(
9752139Sphkcd modules
9852139Sphkfor i in *
9952139Sphkdo
10052139Sphk	if [ -d $i -a $i != CVS ] ; then
10152139Sphk		( cd $i ; ls *.o 2>/dev/null || true)
10252139Sphk	fi
10352139Sphkdone
10452139Sphkcd ../compile
10552139Sphkfor i in $kernels
10652139Sphkdo
10752139Sphk	( cd $i ; ls *.o 2>/dev/null )
10852139Sphkdone
10952139Sphk) | sed '
11052139Sphk/aicasm/d	
11152139Sphk/genassym/d
11252139Sphk/vers.o/d
11352139Sphk/setdef0.o/d
11452139Sphk/setdef1.o/d
11552139Sphk' | sort -u > _
11652139Sphk
11752139Sphkobjlist=`cat _`
11852139Sphk
11952139Sphk
12067812Sphkfor o in $objlist
12152139Sphkdo
12267812Sphk	l=""
12367812Sphk	src=""
12467812Sphk	for k in $kernels
12567812Sphk	do
12667812Sphk		if [ ! -f compile/$k/$o ] ; then
12767812Sphk			continue;
12867812Sphk		fi
12967812Sphk		l="$l compile/$k"
13067812Sphk		if [ "x$src" = "x" ] ; then
13167812Sphk			cd compile/$k
13267812Sphk			mv $o ${o}_
13367812Sphk			make -n $o > _
13467812Sphk			mv ${o}_ $o
13567812Sphk			src=compile/$k/`awk '$1 == "cc" {print $NF}' _`
13667812Sphk			cd ../..
13767812Sphk			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
13867812Sphk				true
13967812Sphk			else
14067812Sphk				echo NO SRC $o
14167812Sphk				src=""
14267812Sphk			fi
14367812Sphk		fi
14467812Sphk	done
14567812Sphk	for m in modules/*
14667812Sphk	do
14767812Sphk		if [ ! -d $m -o ! -f $m/$o ] ; then
14867812Sphk			continue;
14967812Sphk		fi
15067812Sphk		l="$l $m"
15167812Sphk		if [ "x$src" = "x" ] ; then
15267812Sphk			cd $m
15367812Sphk			mv $o ${o}_
15467812Sphk			make -n $o > _
15567812Sphk			mv ${o}_ $o
15667812Sphk			src=`awk '$1 == "cc" {print $NF}' _`
15767812Sphk			cd ../..
15867812Sphk			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
15967812Sphk				if [ "`dirname $src`" = "." ] ; then
16067812Sphk					src="$m/$src"
16167812Sphk				fi
16267812Sphk				true
16367812Sphk			else
16467812Sphk				echo NO SRC $o
16567812Sphk				src=""
16667812Sphk			fi
16767812Sphk		fi
16867812Sphk	done
16967812Sphk	if [ "x$src" = "x" ] ; then
17067812Sphk		echo "NO SOURCE $o"
17152139Sphk		continue
17252139Sphk	fi
17367812Sphk	echo "OBJ	$o"
17467812Sphk	echo "	SRC	$src"
17567812Sphk
17667812Sphk	grep -n '^[ 	]*#[ 	]*include' $src | sed '
17767812Sphk	s/^\([0-9]*\):[ 	]*#[ 	]*include[ 	]*[<"]/\1 /
17867812Sphk	s/[">].*//
17967812Sphk	/ opt_/d
18067812Sphk	' | sort -rn | while read lin incl
18152139Sphk	do
18267812Sphk		S=""
18367812Sphk		echo "		INCL	$lin	$incl"
18467812Sphk		cp $src ${src}_
18552139Sphk
18667812Sphk		# Check if we can compile without this #include line.
18767812Sphk
18867812Sphk		sed "${lin}s/.*//" ${src}_ > ${src}
18967812Sphk		for t in $l
19052139Sphk		do
19167812Sphk			cd $t
19267812Sphk			mv ${o} ${o}_
19367812Sphk			if make ${o} > _log 2>&1 ; then
19467812Sphk				if cmp -s ${o} ${o}_ ; then
19567812Sphk					echo "			$t	same object"
19667812Sphk				else
19767812Sphk					echo "			$t	changed object"
19867812Sphk					S=TAG
19967812Sphk				fi
20067812Sphk			else
20167812Sphk				echo "			$t	used"
20267812Sphk				S=TAG
20367812Sphk			fi
20467812Sphk			mv ${o}_ ${o}
20567812Sphk			cd ../..
20667812Sphk			if [ "x$S" != "x" ] ; then
20767812Sphk				break
20867812Sphk			fi
20967812Sphk		done
21067812Sphk		if [ "x$S" != "x" ] ; then
21167812Sphk			mv ${src}_ ${src}
21267812Sphk			continue
21367812Sphk		fi
21452139Sphk
21567812Sphk		# Check if this is because it is a nested #include
21667812Sphk		for t in $l
21767812Sphk		do
21867812Sphk			cd $t
21967812Sphk			rm -rf foo
22067812Sphk			mkdir -p foo/${incl}
22167812Sphk			rmdir foo/${incl}
22267812Sphk			touch foo/${incl}
22367812Sphk			mv ${o} ${o}_
22467812Sphk			if make INCLMAGIC=-Ifoo ${o} > _log2 2>&1 ; then
22567812Sphk				if cmp -s ${o} ${o}_ ; then
22667812Sphk					echo "			$t	still same object"
22767812Sphk				else
22867812Sphk					echo "			$t	changed object"
22967812Sphk					S=TAG
23067812Sphk				fi
23167812Sphk			else
23267812Sphk				echo "			$t	nested include"
23367812Sphk				S=TAG
23452139Sphk			fi
23567812Sphk			rm -rf foo
23667812Sphk			mv ${o}_ ${o}
23767812Sphk			cd ../..
23867812Sphk			if [ "x$S" != "x" ] ; then
23967812Sphk				break
24067812Sphk			fi
24152139Sphk		done
24267812Sphk		if [ "x$S" != "x" ] ; then
24367812Sphk			mv ${src}_ ${src}
24467812Sphk			continue
24567812Sphk		fi
24667812Sphk
24767812Sphk		# Check if this is because it is #ifdef'ed out
24867812Sphk
24967812Sphk		sed "${lin}s/.*/#error \"BARF\"/" ${src}_ > ${src}
25067812Sphk		for t in $l
25152139Sphk		do
25267812Sphk			cd $t
25367812Sphk			mv ${o} ${o}_
25467812Sphk			if make ${o} > /dev/null 2>&1 ; then
25567812Sphk				echo "			$t	line not read"
25667812Sphk				S=TAG
25752139Sphk			fi
25867812Sphk			mv ${o}_ ${o}
25967812Sphk			cd ../..
26067812Sphk			if [ "x$S" != "x" ] ; then
26167812Sphk				break
26267812Sphk			fi
26352139Sphk		done
26467812Sphk
26567812Sphk		mv ${src}_ ${src}
26667812Sphk		if [ "x$S" != "x" ] ; then
26767812Sphk			continue
26852139Sphk		fi
26967812Sphk
27067812Sphk		# Check if the warnings changed.
27167812Sphk
27267812Sphk		for t in $l
27367812Sphk		do
27467812Sphk			cd $t
27567812Sphk			mv ${o} ${o}_
27667812Sphk			if make ${o} > _ref 2>&1 ; then
27767812Sphk				if cmp -s _ref _log ; then
27867812Sphk					echo "			$t	same warnings"
27967812Sphk				else
28067812Sphk					echo "			$t	changed warnings"
28167812Sphk					S=TAG
28267812Sphk				fi
28367812Sphk			else
28467812Sphk				echo "ARGHH!!!"
28567812Sphk				exit 9
28667812Sphk			fi
28767812Sphk					
28867812Sphk			mv ${o}_ ${o}
28967812Sphk			cd ../..
29067812Sphk			if [ "x$S" != "x" ] ; then
29167812Sphk				break
29267812Sphk			fi
29367812Sphk		done
29467812Sphk		if [ "x$S" != "x" ] ; then
29567812Sphk			continue
29664894Sphk		fi
29767812Sphk		cp $src ${src}_
29867812Sphk		sed "${lin}d" ${src}_ > ${src}
29967812Sphk		rm ${src}_
30067812Sphk		touch _again
30167812Sphk		echo "BINGO $src $lin $incl $obj $l"
30252139Sphk	done
30352139Sphkdone
304