1#!/bin/sh
2# ----------------------------------------------------------------------------
3# "THE BEER-WARE LICENSE" (Revision 42):
4# <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
5# can do whatever you want with this stuff. If we meet some day, and you think
6# this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7# ----------------------------------------------------------------------------
8#
9# $FreeBSD: src/tools/tools/kerninclude/kerninclude.sh,v 1.1.2.1 2001/03/05 12:18:27 kris Exp $
10#
11# This script tries to find #include statements which are not needed in
12# the FreeBSD kernel tree.
13#
14
15set -e
16
17# Base of the kernel sources you want to work on
18cd /sys
19
20# Set to true to start from scratch, false to resume
21init=false
22
23# Which kernels you want to check
24kernels="LINT GENERIC"
25
26NO_MODULES=yes
27export NO_MODULES
28
29if $init ; then
30	(
31	echo "Cleaning modules"
32	cd modules
33	make clean > /dev/null 2>&1
34	make cleandir > /dev/null 2>&1
35	make cleandir > /dev/null 2>&1
36	make clean > /dev/null 2>&1
37	make clean > /dev/null 2>&1
38	)
39
40	(
41	echo "Cleaning compile"
42	cd compile
43	ls | xargs rm -rf
44	)
45fi
46
47(
48echo "Cleaning temp files"
49find . -name '*.h_' -print | xargs rm -f
50find . -name '::*' -print | xargs rm -f
51find . -name '*.o' -size 0 -print | xargs rm -f
52)
53
54echo "Configuring kernels"
55(
56	cd i386/conf
57	make LINT
58	if $init ; then
59		config -r LINT
60		config -r GENERIC
61	else
62		config LINT
63		config GENERIC
64	fi
65)
66
67for i in $kernels
68do
69	(
70	echo "Compiling $i"
71	cd compile/$i
72	make > x.0 2>&1
73	tail -4 x.0
74	if [ ! -f kernel ] ; then
75		echo "Error: No $i kernel built"
76		exit 1
77	fi
78	)
79done
80
81(
82echo "Compiling modules"
83cd modules
84make > x.0 2>&1
85)
86
87# Generate the list of object files we want to check
88# you can put a convenient grep right before the sort
89# if you want just some specific subset of files checked
90(
91cd modules
92for i in *
93do
94	if [ -d $i ] ; then
95		( cd $i ; ls *.o 2>/dev/null || true)
96	fi
97done
98cd ../compile
99for i in $kernels
100do
101	( cd $i ; ls *.o 2>/dev/null )
102done
103) | sed '
104/aicasm/d
105/genassym/d
106/vers.o/d
107/setdef0.o/d
108/setdef1.o/d
109' | sort -u > _
110
111objlist=`cat _`
112
113
114for o in $objlist
115do
116	l=""
117	src=""
118	for k in $kernels
119	do
120		if [ ! -f compile/$k/$o ] ; then
121			continue;
122		fi
123		l="$l compile/$k"
124		if [ "x$src" = "x" ] ; then
125			cd compile/$k
126			mv $o ${o}_
127			make -n $o > _
128			mv ${o}_ $o
129			src=compile/$k/`awk '$1 == "cc" {print $NF}' _`
130			cd ../..
131			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
132				true
133			else
134				echo NO SRC $o
135				src=""
136			fi
137		fi
138	done
139	for m in modules/*
140	do
141		if [ ! -d $m -o ! -f $m/$o ] ; then
142			continue;
143		fi
144		l="$l $m"
145		if [ "x$src" = "x" ] ; then
146			cd $m
147			mv $o ${o}_
148			make -n $o > _
149			mv ${o}_ $o
150			src=`awk '$1 == "cc" {print $NF}' _`
151			cd ../..
152			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
153				if [ "`dirname $src`" = "." ] ; then
154					src="$m/$src"
155				fi
156				true
157			else
158				echo NO SRC $o
159				src=""
160			fi
161		fi
162	done
163	if [ "x$src" = "x" ] ; then
164		echo "NO SOURCE $o"
165		continue
166	fi
167	echo "OBJ	$o"
168	echo "	SRC	$src"
169
170	grep -n '^[ 	]*#[ 	]*include' $src | sed '
171	s/^\([0-9]*\):[ 	]*#[ 	]*include[ 	]*[<"]/\1 /
172	s/[">].*//
173	/ opt_/d
174	' | sort -rn | while read lin incl
175	do
176		S=""
177		echo "		INCL	$lin	$incl"
178		cp $src ${src}_
179
180		# Check if we can compile without this #include line.
181
182		sed "${lin}s/.*//" ${src}_ > ${src}
183		for t in $l
184		do
185			cd $t
186			mv ${o} ${o}_
187			if make ${o} > _log 2>&1 ; then
188				if cmp -s ${o} ${o}_ ; then
189					echo "			$t	same object"
190				else
191					echo "			$t	changed object"
192					S=TAG
193				fi
194			else
195				echo "			$t	used"
196				S=TAG
197			fi
198			mv ${o}_ ${o}
199			cd ../..
200			if [ "x$S" != "x" ] ; then
201				break
202			fi
203		done
204		if [ "x$S" != "x" ] ; then
205			mv ${src}_ ${src}
206			continue
207		fi
208
209		# Check if this is because it is a nested #include
210		for t in $l
211		do
212			cd $t
213			rm -rf foo
214			mkdir -p foo/${incl}
215			rmdir foo/${incl}
216			touch foo/${incl}
217			mv ${o} ${o}_
218			if make INCLMAGIC=-Ifoo ${o} > _log2 2>&1 ; then
219				if cmp -s ${o} ${o}_ ; then
220					echo "			$t	still same object"
221				else
222					echo "			$t	changed object"
223					S=TAG
224				fi
225			else
226				echo "			$t	nested include"
227				S=TAG
228			fi
229			rm -rf foo
230			mv ${o}_ ${o}
231			cd ../..
232			if [ "x$S" != "x" ] ; then
233				break
234			fi
235		done
236		if [ "x$S" != "x" ] ; then
237			mv ${src}_ ${src}
238			continue
239		fi
240
241		# Check if this is because it is #ifdef'ed out
242
243		sed "${lin}s/.*/#error \"BARF\"/" ${src}_ > ${src}
244		for t in $l
245		do
246			cd $t
247			mv ${o} ${o}_
248			if make ${o} > /dev/null 2>&1 ; then
249				echo "			$t	line not read"
250				S=TAG
251			fi
252			mv ${o}_ ${o}
253			cd ../..
254			if [ "x$S" != "x" ] ; then
255				break
256			fi
257		done
258
259		mv ${src}_ ${src}
260		if [ "x$S" != "x" ] ; then
261			continue
262		fi
263
264		# Check if the warnings changed.
265
266		for t in $l
267		do
268			cd $t
269			mv ${o} ${o}_
270			if make ${o} > _ref 2>&1 ; then
271				if cmp -s _ref _log ; then
272					echo "			$t	same warnings"
273				else
274					echo "			$t	changed warnings"
275					S=TAG
276				fi
277			else
278				echo "ARGHH!!!"
279				exit 9
280			fi
281
282			mv ${o}_ ${o}
283			cd ../..
284			if [ "x$S" != "x" ] ; then
285				break
286			fi
287		done
288		if [ "x$S" != "x" ] ; then
289			continue
290		fi
291		cp $src ${src}_
292		sed "${lin}d" ${src}_ > ${src}
293		rm ${src}_
294		touch _again
295		echo "BINGO $src $lin $incl $obj $l"
296	done
297done
298