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="LINT64 X86_64_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 LINT64
58	if $init ; then
59		config -r LINT64
60		config -r X86_64_GENERIC
61	else
62		config LINT64
63		config X86_64_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/genassym/d
105/vers.o/d
106/setdef0.o/d
107/setdef1.o/d
108' | sort -u > _
109
110objlist=`cat _`
111
112
113for o in $objlist
114do
115	l=""
116	src=""
117	for k in $kernels
118	do
119		if [ ! -f compile/$k/$o ] ; then
120			continue;
121		fi
122		l="$l compile/$k"
123		if [ "x$src" = "x" ] ; then
124			cd compile/$k
125			mv $o ${o}_
126			make -n $o > _
127			mv ${o}_ $o
128			src=compile/$k/`awk '$1 == "cc" {print $NF}' _`
129			cd ../..
130			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
131				true
132			else
133				echo NO SRC $o
134				src=""
135			fi
136		fi
137	done
138	for m in modules/*
139	do
140		if [ ! -d $m -o ! -f $m/$o ] ; then
141			continue;
142		fi
143		l="$l $m"
144		if [ "x$src" = "x" ] ; then
145			cd $m
146			mv $o ${o}_
147			make -n $o > _
148			mv ${o}_ $o
149			src=`awk '$1 == "cc" {print $NF}' _`
150			cd ../..
151			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
152				if [ "`dirname $src`" = "." ] ; then
153					src="$m/$src"
154				fi
155				true
156			else
157				echo NO SRC $o
158				src=""
159			fi
160		fi
161	done
162	if [ "x$src" = "x" ] ; then
163		echo "NO SOURCE $o"
164		continue
165	fi
166	echo "OBJ	$o"
167	echo "	SRC	$src"
168
169	grep -n '^[ 	]*#[ 	]*include' $src | sed '
170	s/^\([0-9]*\):[ 	]*#[ 	]*include[ 	]*[<"]/\1 /
171	s/[">].*//
172	/ opt_/d
173	' | sort -rn | while read lin incl
174	do
175		S=""
176		echo "		INCL	$lin	$incl"
177		cp $src ${src}_
178
179		# Check if we can compile without this #include line.
180
181		sed "${lin}s/.*//" ${src}_ > ${src}
182		for t in $l
183		do
184			cd $t
185			mv ${o} ${o}_
186			if make ${o} > _log 2>&1 ; then
187				if cmp -s ${o} ${o}_ ; then
188					echo "			$t	same object"
189				else
190					echo "			$t	changed object"
191					S=TAG
192				fi
193			else
194				echo "			$t	used"
195				S=TAG
196			fi
197			mv ${o}_ ${o}
198			cd ../..
199			if [ "x$S" != "x" ] ; then
200				break
201			fi
202		done
203		if [ "x$S" != "x" ] ; then
204			mv ${src}_ ${src}
205			continue
206		fi
207
208		# Check if this is because it is a nested #include
209		for t in $l
210		do
211			cd $t
212			rm -rf foo
213			mkdir -p foo/${incl}
214			rmdir foo/${incl}
215			touch foo/${incl}
216			mv ${o} ${o}_
217			if make INCLMAGIC=-Ifoo ${o} > _log2 2>&1 ; then
218				if cmp -s ${o} ${o}_ ; then
219					echo "			$t	still same object"
220				else
221					echo "			$t	changed object"
222					S=TAG
223				fi
224			else
225				echo "			$t	nested include"
226				S=TAG
227			fi
228			rm -rf foo
229			mv ${o}_ ${o}
230			cd ../..
231			if [ "x$S" != "x" ] ; then
232				break
233			fi
234		done
235		if [ "x$S" != "x" ] ; then
236			mv ${src}_ ${src}
237			continue
238		fi
239
240		# Check if this is because it is #ifdef'ed out
241
242		sed "${lin}s/.*/#error \"BARF\"/" ${src}_ > ${src}
243		for t in $l
244		do
245			cd $t
246			mv ${o} ${o}_
247			if make ${o} > /dev/null 2>&1 ; then
248				echo "			$t	line not read"
249				S=TAG
250			fi
251			mv ${o}_ ${o}
252			cd ../..
253			if [ "x$S" != "x" ] ; then
254				break
255			fi
256		done
257
258		mv ${src}_ ${src}
259		if [ "x$S" != "x" ] ; then
260			continue
261		fi
262
263		# Check if the warnings changed.
264
265		for t in $l
266		do
267			cd $t
268			mv ${o} ${o}_
269			if make ${o} > _ref 2>&1 ; then
270				if cmp -s _ref _log ; then
271					echo "			$t	same warnings"
272				else
273					echo "			$t	changed warnings"
274					S=TAG
275				fi
276			else
277				echo "ARGHH!!!"
278				exit 9
279			fi
280
281			mv ${o}_ ${o}
282			cd ../..
283			if [ "x$S" != "x" ] ; then
284				break
285			fi
286		done
287		if [ "x$S" != "x" ] ; then
288			continue
289		fi
290		cp $src ${src}_
291		sed "${lin}d" ${src}_ > ${src}
292		rm ${src}_
293		touch _again
294		echo "BINGO $src $lin $incl $obj $l"
295	done
296done
297