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