xref: /freebsd/tools/tools/kernxref/kernxref.sh (revision 81ad6265)
1:
2#
3# SPDX-License-Identifier: Beerware
4#
5# ----------------------------------------------------------------------------
6# "THE BEER-WARE LICENSE" (Revision 42):
7# <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
8# can do whatever you want with this stuff. If we meet some day, and you think
9# this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
10# ----------------------------------------------------------------------------
11#
12# Sort options by "Matthew Emmerton" <matt@gsicomp.on.ca>
13#
14# $FreeBSD$
15#
16# This shell script will make a cross reference of the symbols of a kernel.
17#
18
19COMPILEDIR=/sys/`uname -m`/compile
20KERNELNAME=LINT
21SORTORDER=-k1
22
23args=`getopt h?k:s: $*`;
24if [ $? != 0 ]
25then
26	args="-h";
27fi
28set -- $args;
29for i
30do
31	case "$i"
32	in
33	-h|-\?)
34		echo "Usage: $0 [ -k <kernelname> ] [ -s [ 'symbol' | 'filename' ] ]";
35		exit 0;
36		;;
37	-k)
38		KERNELNAME=$2
39		if [ -d ${COMPILEDIR}/${KERNELNAME} ];
40		then
41			shift; shift;
42			continue;
43		fi
44		echo "Kernel '$KERNELNAME' does not exist in ${COMPILEDIR}!";
45		exit 1;
46		;;
47	-s)
48		if [ "x$2" = "xsymbol" ]
49		then
50			SORTORDER=-k1
51			shift; shift;
52			continue;
53		fi
54		if [ "x$2" = "xfilename" ]
55		then
56			SORTORDER=-k2
57			shift; shift;
58			continue;
59		fi
60		echo "Invalid selection for -s: $2";
61		exit 1;
62		;;
63	--)
64		shift;
65		break;
66		;;
67	esac
68done
69
70cd ${COMPILEDIR}/${KERNELNAME}
71
72MOD_OBJS=`find modules -name \*.o`
73
74for i in *.o $MOD_OBJS
75do
76	nm -gon $i
77done | sed '
78/aicasm.*:/d
79/genassym.*:/d
80s/.*\///
81s/:/ /
82' |  awk '
83NF > 1	{
84	if ($2 == "t")
85		next
86	if ($2 == "F")
87		next
88	if ($2 == "U") {
89		ref[$3]=ref[$3]" "$1
90		nm[$3]++
91	} else if ($3 == "D" || $3 == "T" || $3 == "B" || $3 == "R" || $3 == "A") {
92		if (def[$4] != "")
93			def[$4]=def[$4]" "$1
94		else
95			def[$4]=$1
96		nm[$4]++
97	} else if ($2 == "?") {
98		if (def[$3] == "S")
99			i++
100		else if (def[$3] != "")
101			def[$3]=def[$3]",S"
102		else
103			def[$3]="S"
104		ref[$3]=ref[$3]" "$1
105		nm[$3]++
106	} else if ($2 == "C") {
107		if (def[$3] == $2)
108			i++
109		else if (def[$3] == "")
110			def[$3]=$1
111		else
112			ref[$3]=ref[$3]" "$1
113		nm[$3]++
114	} else {
115		print ">>>",$0
116	}
117	}
118END	{
119	for (i in nm) {
120		printf "%s {%s} %s\n",i,def[i],ref[i]
121	}
122	}
123' | sort $SORTORDER | awk '
124	{
125	if ($2 == "{S}")
126		$2 = "<Linker set>"
127	if (length($3) == 0) {
128		printf "%-31s %d %s\tUNREF\n",$1,0, $2
129		N1++
130	} else if ($2 == "{}") {
131		printf "%-31s %d {UNDEF}\n",$1, NF-2
132		N2++
133	} else {
134		printf "%-31s %d %s",$1,NF-2,$2
135		p = 80;
136		for (i = 3 ; i <= NF; i++) {
137			if (p+length ($i)+1 > 48) {
138				printf "\n\t\t\t\t\t%s", $i
139				p = 7;
140			} else {
141				printf " %s", $i
142			}
143			p += 1 + length ($i)
144		}
145		printf "\n"
146		N3++
147		if (NF-2 == 1)
148			N4++
149		if (NF-2 == 2)
150			N5++
151	}
152	}
153END	{
154	printf "Total symbols: %5d\n",N1+N2+N3
155	printf "unref symbols: %5d\n",N1
156	printf "undef symbols: %5d\n",N2
157	printf "1 ref symbols: %5d\n",N4
158	printf "2 ref symbols: %5d\n",N5
159	}
160'
161