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 GENERIC98"
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 | grep -v CVS | 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(
67	cd pc98/conf
68	cp -f GENERIC GENERIC98
69	if $init ; then
70		config -r GENERIC98
71	else
72		config GENERIC98
73	fi
74)
75
76for i in $kernels
77do
78	(
79	echo "Compiling $i"
80	cd compile/$i
81	make > x.0 2>&1
82	tail -4 x.0
83	if [ ! -f kernel ] ; then
84		echo "Error: No $i kernel built"
85		exit 1
86	fi
87	)
88done
89
90(
91echo "Compiling modules"
92cd modules
93make > x.0 2>&1
94)
95
96# Generate the list of object files we want to check
97# you can put a convenient grep right before the sort
98# if you want just some specific subset of files checked
99(
100cd modules
101for i in *
102do
103	if [ -d $i -a $i != CVS ] ; then
104		( cd $i ; ls *.o 2>/dev/null || true)
105	fi
106done
107cd ../compile
108for i in $kernels
109do
110	( cd $i ; ls *.o 2>/dev/null )
111done
112) | sed '
113/aicasm/d
114/genassym/d
115/vers.o/d
116/setdef0.o/d
117/setdef1.o/d
118' | sort -u > _
119
120objlist=`cat _`
121
122
123for o in $objlist
124do
125	l=""
126	src=""
127	for k in $kernels
128	do
129		if [ ! -f compile/$k/$o ] ; then
130			continue;
131		fi
132		l="$l compile/$k"
133		if [ "x$src" = "x" ] ; then
134			cd compile/$k
135			mv $o ${o}_
136			make -n $o > _
137			mv ${o}_ $o
138			src=compile/$k/`awk '$1 == "cc" {print $NF}' _`
139			cd ../..
140			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
141				true
142			else
143				echo NO SRC $o
144				src=""
145			fi
146		fi
147	done
148	for m in modules/*
149	do
150		if [ ! -d $m -o ! -f $m/$o ] ; then
151			continue;
152		fi
153		l="$l $m"
154		if [ "x$src" = "x" ] ; then
155			cd $m
156			mv $o ${o}_
157			make -n $o > _
158			mv ${o}_ $o
159			src=`awk '$1 == "cc" {print $NF}' _`
160			cd ../..
161			if expr "x$src" : 'x.*\.c$' > /dev/null ; then
162				if [ "`dirname $src`" = "." ] ; then
163					src="$m/$src"
164				fi
165				true
166			else
167				echo NO SRC $o
168				src=""
169			fi
170		fi
171	done
172	if [ "x$src" = "x" ] ; then
173		echo "NO SOURCE $o"
174		continue
175	fi
176	echo "OBJ	$o"
177	echo "	SRC	$src"
178
179	grep -n '^[ 	]*#[ 	]*include' $src | sed '
180	s/^\([0-9]*\):[ 	]*#[ 	]*include[ 	]*[<"]/\1 /
181	s/[">].*//
182	/ opt_/d
183	' | sort -rn | while read lin incl
184	do
185		S=""
186		echo "		INCL	$lin	$incl"
187		cp $src ${src}_
188
189		# Check if we can compile without this #include line.
190
191		sed "${lin}s/.*//" ${src}_ > ${src}
192		for t in $l
193		do
194			cd $t
195			mv ${o} ${o}_
196			if make ${o} > _log 2>&1 ; then
197				if cmp -s ${o} ${o}_ ; then
198					echo "			$t	same object"
199				else
200					echo "			$t	changed object"
201					S=TAG
202				fi
203			else
204				echo "			$t	used"
205				S=TAG
206			fi
207			mv ${o}_ ${o}
208			cd ../..
209			if [ "x$S" != "x" ] ; then
210				break
211			fi
212		done
213		if [ "x$S" != "x" ] ; then
214			mv ${src}_ ${src}
215			continue
216		fi
217
218		# Check if this is because it is a nested #include
219		for t in $l
220		do
221			cd $t
222			rm -rf foo
223			mkdir -p foo/${incl}
224			rmdir foo/${incl}
225			touch foo/${incl}
226			mv ${o} ${o}_
227			if make INCLMAGIC=-Ifoo ${o} > _log2 2>&1 ; then
228				if cmp -s ${o} ${o}_ ; then
229					echo "			$t	still same object"
230				else
231					echo "			$t	changed object"
232					S=TAG
233				fi
234			else
235				echo "			$t	nested include"
236				S=TAG
237			fi
238			rm -rf foo
239			mv ${o}_ ${o}
240			cd ../..
241			if [ "x$S" != "x" ] ; then
242				break
243			fi
244		done
245		if [ "x$S" != "x" ] ; then
246			mv ${src}_ ${src}
247			continue
248		fi
249
250		# Check if this is because it is #ifdef'ed out
251
252		sed "${lin}s/.*/#error \"BARF\"/" ${src}_ > ${src}
253		for t in $l
254		do
255			cd $t
256			mv ${o} ${o}_
257			if make ${o} > /dev/null 2>&1 ; then
258				echo "			$t	line not read"
259				S=TAG
260			fi
261			mv ${o}_ ${o}
262			cd ../..
263			if [ "x$S" != "x" ] ; then
264				break
265			fi
266		done
267
268		mv ${src}_ ${src}
269		if [ "x$S" != "x" ] ; then
270			continue
271		fi
272
273		# Check if the warnings changed.
274
275		for t in $l
276		do
277			cd $t
278			mv ${o} ${o}_
279			if make ${o} > _ref 2>&1 ; then
280				if cmp -s _ref _log ; then
281					echo "			$t	same warnings"
282				else
283					echo "			$t	changed warnings"
284					S=TAG
285				fi
286			else
287				echo "ARGHH!!!"
288				exit 9
289			fi
290
291			mv ${o}_ ${o}
292			cd ../..
293			if [ "x$S" != "x" ] ; then
294				break
295			fi
296		done
297		if [ "x$S" != "x" ] ; then
298			continue
299		fi
300		cp $src ${src}_
301		sed "${lin}d" ${src}_ > ${src}
302		rm ${src}_
303		touch _again
304		echo "BINGO $src $lin $incl $obj $l"
305	done
306done
307