11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#!/usr/bin/perl -w
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	namespace.pl.  Mon Aug 30 2004
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	Perform a name space analysis on the linux kernel.
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	Copyright Keith Owens <kaos@ocs.com.au>.  GPL.
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	Invoke by changing directory to the top of the kernel object
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	tree then namespace.pl, no parameters.
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	Tuned for 2.1.x kernels with the new module handling, it will
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	work with 2.0 kernels as well.
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	Last change 2.6.9-rc1, adding support for separate source and object
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	trees.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	The source must be compiled/assembled first, the object files
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	are the primary input to this script.  Incomplete or missing
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	objects will result in a flawed analysis.  Compile both vmlinux
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	and modules.
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	Even with complete objects, treat the result of the analysis
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	with caution.  Some external references are only used by
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	certain architectures, others with certain combinations of
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	configuration parameters.  Ideally the source should include
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	something like
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	#ifndef CONFIG_...
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	static
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	#endif
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	symbol_definition;
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	so the symbols are defined as static unless a particular
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	CONFIG_... requires it to be external.
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	A symbol that is suffixed with '(export only)' has these properties
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* It is global.
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* It is marked EXPORT_SYMBOL or EXPORT_SYMBOL_GPL, either in the same
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  source file or a different source file.
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* Given the current .config, nothing uses the symbol.
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	The symbol is a candidate for conversion to static, plus removal of the
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	export.  But be careful that a different .config might use the symbol.
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	Name space analysis and cleanup is an iterative process.  You cannot
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	expect to find all the problems in a single pass.
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* Identify possibly unnecessary global declarations, verify that they
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  really are unnecessary and change them to static.
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* Compile and fix up gcc warnings about static, removing dead symbols
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  as necessary.
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* make clean and rebuild with different configs (especially
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  CONFIG_MODULES=n) to see which symbols are being defined when the
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  config does not require them.  These symbols bloat the kernel object
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  for no good reason, which is frustrating for embedded systems.
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* Wrap config sensitive symbols in #ifdef CONFIG_foo, as long as the
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  code does not get too ugly.
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	* Repeat the name space analysis until you can live with with the
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#	  result.
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrequire 5;	# at least perl 5
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsuse strict;
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsuse File::Find;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
693a25f0b19f2eefd158955ab809c8947ed8feadf1Aaron Brooksmy $nm = ($ENV{'NM'} || "nm") . " -p";
703a25f0b19f2eefd158955ab809c8947ed8feadf1Aaron Brooksmy $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment";
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmy $srctree = "";
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmy $objtree = "";
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds$srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'}));
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds$objtree = "$ENV{'objtree'}/" if (exists($ENV{'objtree'}));
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsif ($#ARGV != -1) {
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	print STDERR "usage: $0 takes no parameters\n";
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	die("giving up\n");
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmy %nmdata = ();	# nm data for each object
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmy %def = ();		# all definitions for each name
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmy %ksymtab = ();	# names that appear in __ksymtab_
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmy %ref = ();		# $ref{$name} exists if there is a true external reference to $name
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmy %export = ();	# $export{$name} exists if there is an EXPORT_... of $name
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8743f683c9e465a64259c6058a7c313facc697b203Stephen Hemmingermy %nmexception = (
8843f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'fs/ext3/bitmap'			=> 1,
8943f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'fs/ext4/bitmap'			=> 1,
9043f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'arch/x86/lib/thunk_32'		=> 1,
9143f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'arch/x86/lib/cmpxchg'		=> 1,
9243f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'arch/x86/vdso/vdso32/note'		=> 1,
9343f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'lib/irq_regs'			=> 1,
9443f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'usr/initramfs_data'		=> 1,
9543f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'drivers/scsi/aic94xx/aic94xx_dump'	=> 1,
9643f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'drivers/scsi/libsas/sas_dump'	=> 1,
9743f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'lib/dec_and_lock'			=> 1,
9843f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'drivers/ide/ide-probe-mini'	=> 1,
9943f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'usr/initramfs_data'		=> 1,
10043f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'drivers/acpi/acpia/exdump'		=> 1,
10143f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'drivers/acpi/acpia/rsdump'		=> 1,
10243f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'drivers/acpi/acpia/nsdumpdv'	=> 1,
10343f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'drivers/acpi/acpia/nsdump'		=> 1,
10443f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'arch/ia64/sn/kernel/sn2/io'	=> 1,
10543f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'arch/ia64/kernel/gate-data'	=> 1,
10643f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'security/capability'		=> 1,
10743f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'fs/ntfs/sysctl'			=> 1,
10843f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'fs/jfs/jfs_debug'			=> 1,
10943f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger);
11043f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger
11143f683c9e465a64259c6058a7c313facc697b203Stephen Hemmingermy %nameexception = (
11243f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'mod_use_count_'	 => 1,
11343f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__initramfs_end'	=> 1,
11443f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__initramfs_start'	=> 1,
11543f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '_einittext'	=> 1,
11643f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '_sinittext'	=> 1,
11743f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'kallsyms_names'	=> 1,
11843f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'kallsyms_num_syms'	=> 1,
11943f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'kallsyms_addresses'=> 1,
12043f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__this_module'	=> 1,
12143f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '_etext'		=> 1,
12243f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '_edata'		=> 1,
12343f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '_end'		=> 1,
12443f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__bss_start'	=> 1,
12543f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '_text'		=> 1,
12643f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '_stext'		=> 1,
12743f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__gp'		=> 1,
12843f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'ia64_unw_start'	=> 1,
12943f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'ia64_unw_end'	=> 1,
13043f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__init_begin'	=> 1,
13143f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__init_end'	=> 1,
13243f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__bss_stop'	=> 1,
13343f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__nosave_begin'	=> 1,
13443f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    '__nosave_end'	=> 1,
13543f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger    'pg0'		=> 1,
136abb438526201c6a79949ad45375c051b6681c253Amerigo Wang    'vdso_enabled'	=> 1,
137abb438526201c6a79949ad45375c051b6681c253Amerigo Wang    '__stack_chk_fail'  => 1,
138abb438526201c6a79949ad45375c051b6681c253Amerigo Wang    'VDSO32_PRELINK'	=> 1,
139abb438526201c6a79949ad45375c051b6681c253Amerigo Wang    'VDSO32_vsyscall'	=> 1,
140abb438526201c6a79949ad45375c051b6681c253Amerigo Wang    'VDSO32_rt_sigreturn'=>1,
141abb438526201c6a79949ad45375c051b6681c253Amerigo Wang    'VDSO32_sigreturn'	=> 1,
14243f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger);
14343f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger
14443f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds&find(\&linux_objects, '.');	# find the objects and do_nm on them
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds&list_multiply_defined();
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds&resolve_external_references();
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds&list_extra_externals();
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit(0);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssub linux_objects
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	# Select objects, ignoring objects which are only created by
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	# merging other objects.  Also ignore all of modules, scripts
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	# and compressed.  Most conglomerate objects are handled by do_nm,
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	# this list only contains the special cases.  These include objects
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	# that are linked from just one other object and objects for which
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	# there is really no permanent source file.
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my $basename = $_;
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	$_ = $File::Find::name;
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	s:^\./::;
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (/.*\.o$/ &&
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		! (
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		m:/built-in.o$:
166abb438526201c6a79949ad45375c051b6681c253Amerigo Wang		|| m:arch/x86/vdso/:
167abb438526201c6a79949ad45375c051b6681c253Amerigo Wang		|| m:arch/x86/boot/:
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/ia32/ia32.o$:
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/kernel/gate-syms.o$:
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__divdi3.o$:
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__divsi3.o$:
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__moddi3.o$:
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__modsi3.o$:
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__udivdi3.o$:
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__udivsi3.o$:
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__umoddi3.o$:
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/lib/__umodsi3.o$:
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/scripts/check_gas_for_hint.o$:
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:arch/ia64/sn/kernel/xp.o$:
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:boot/bbootsect.o$:
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:boot/bsetup.o$:
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:/bootsect.o$:
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:/boot/setup.o$:
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:/compressed/:
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:drivers/cdrom/driver.o$:
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:drivers/char/drm/tdfx_drv.o$:
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:drivers/ide/ide-detect.o$:
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:drivers/ide/pci/idedriver-pci.o$:
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:drivers/media/media.o$:
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:drivers/scsi/sd_mod.o$:
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:drivers/video/video.o$:
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/devpts/devpts.o$:
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/exportfs/exportfs.o$:
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/hugetlbfs/hugetlbfs.o$:
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/msdos/msdos.o$:
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/nls/nls.o$:
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/ramfs/ramfs.o$:
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/romfs/romfs.o$:
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:fs/vfat/vfat.o$:
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:init/mounts.o$:
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:^modules/:
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:net/netlink/netlink.o$:
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:net/sched/sched.o$:
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:/piggy.o$:
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:^scripts/:
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:sound/.*/snd-:
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:^.*/\.tmp_:
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:^\.tmp_:
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		|| m:/vmlinux-obj.o$:
210abb438526201c6a79949ad45375c051b6681c253Amerigo Wang		|| m:^tools/:
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		)
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	) {
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		do_nm($basename, $_);
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	$_ = $basename;		# File::Find expects $_ untouched (undocumented)
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssub do_nm
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my ($basename, $fullname) = @_;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my ($source, $type, $name);
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (! -e $basename) {
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf STDERR "$basename does not exist\n";
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ($fullname !~ /\.o$/) {
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf STDERR "$fullname is not an object file\n";
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
230c25f415751c0c5507561d997fe5f7f05f4342912Amerigo Wang	($source = $basename) =~ s/\.o$//;
231c25f415751c0c5507561d997fe5f7f05f4342912Amerigo Wang	if (-e "$source.c" || -e "$source.S") {
232c25f415751c0c5507561d997fe5f7f05f4342912Amerigo Wang		$source = "$objtree$File::Find::dir/$source";
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
234c25f415751c0c5507561d997fe5f7f05f4342912Amerigo Wang		$source = "$srctree$File::Find::dir/$source";
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (! -e "$source.c" && ! -e "$source.S") {
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# No obvious source, exclude the object if it is conglomerate
23886d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	        open(my $objdumpdata, "$objdump $basename|")
23986d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger		    or die "$objdump $fullname failed $!\n";
24086d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		my $comment;
24286d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger		while (<$objdumpdata>) {
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			chomp();
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (/^In archive/) {
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				# Archives are always conglomerate
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$comment = "GCC:GCC:";
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				last;
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			next if (! /^[ 0-9a-f]{5,} /);
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			$comment .= substr($_, 43);
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
25286d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger		close($objdumpdata);
25386d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf STDERR "No source file found for $fullname\n";
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
25986d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	open (my $nmdata, "$nm $basename|")
26086d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	    or die "$nm $fullname failed $!\n";
26186d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my @nmdata;
26386d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	while (<$nmdata>) {
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		chop;
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		($type, $name) = (split(/ +/, $_, 3))[1..2];
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# Expected types
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# A absolute symbol
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# B weak external reference to data that has been resolved
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# C global variable, uninitialised
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# D global variable, initialised
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# G global variable, initialised, small data section
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# R global array, initialised
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# S global variable, uninitialised, small bss
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# T global label/procedure
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# U external reference
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# W weak external reference to text that has been resolved
277e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang		# V similar to W, but the value of the weak symbol becomes zero with no error.
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# a assembler equate
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# b static variable, uninitialised
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# d static variable, initialised
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# g static variable, initialised, small data section
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# r static array, initialised
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# s static variable, uninitialised, small bss
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# t static label/procedures
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# w weak external reference to text that has not been resolved
286e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang		# v similar to w
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		# ? undefined type, used a lot by modules
288e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang		if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) {
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf STDERR "nm output for $fullname contains unknown type '$_'\n";
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		elsif ($name =~ /\./) {
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			# name with '.' is local static
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else {
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			$type = 'R' if ($type eq '?');	# binutils replaced ? with R at one point
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			# binutils keeps changing the type for exported symbols, force it to R
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			$type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			$name =~ s/_R[a-f0-9]{8}$//;	# module versions adds this
299e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang			if ($type =~ /[ABCDGRSTWV]/ &&
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name ne 'init_module' &&
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name ne 'cleanup_module' &&
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name ne 'Using_Versions' &&
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^Version_[0-9]+$/ &&
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__parm_/ &&
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__kstrtab/ &&
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__ksymtab/ &&
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__kcrctab_/ &&
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__exitcall_/ &&
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__initcall_/ &&
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__kdb_initcall_/ &&
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__kdb_exitcall_/ &&
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__module_/ &&
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__mod_/ &&
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name !~ /^__crc_/ &&
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name ne '__this_module' &&
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name ne 'kernel_version') {
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!exists($def{$name})) {
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					$def{$name} = [];
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				push(@{$def{$name}}, $fullname);
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			push(@nmdata, "$type $name");
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ($name =~ /^__ksymtab_/) {
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				$name = substr($name, 10);
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!exists($ksymtab{$name})) {
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					$ksymtab{$name} = [];
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				push(@{$ksymtab{$name}}, $fullname);
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
33286d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	close($nmdata);
33386d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ($#nmdata < 0) {
33543f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger	    printf "No nm data for $fullname\n"
33643f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger		unless $nmexception{$fullname};
33743f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger	    return;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	$nmdata{$fullname} = \@nmdata;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssub drop_def
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my ($object, $name) = @_;
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my $nmdata = $nmdata{$object};
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my ($i, $j);
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for ($i = 0; $i <= $#{$nmdata}; ++$i) {
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ($name eq (split(' ', $nmdata->[$i], 2))[1]) {
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			splice(@{$nmdata{$object}}, $i, 1);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			my $def = $def{$name};
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for ($j = 0; $j < $#{$def{$name}}; ++$j) {
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if ($def{$name}[$j] eq $object) {
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					splice(@{$def{$name}}, $j, 1);
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			last;
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssub list_multiply_defined
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
36386d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	foreach my $name (keys(%def)) {
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ($#{$def{$name}} > 0) {
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			# Special case for cond_syscall
366abb438526201c6a79949ad45375c051b6681c253Amerigo Wang			if ($#{$def{$name}} == 1 &&
367abb438526201c6a79949ad45375c051b6681c253Amerigo Wang			   ($name =~ /^sys_/ || $name =~ /^compat_sys_/ ||
368abb438526201c6a79949ad45375c051b6681c253Amerigo Wang			    $name =~ /^sys32_/)) {
369e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang				if($def{$name}[0] eq "kernel/sys_ni.o" ||
370e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang				   $def{$name}[1] eq "kernel/sys_ni.o") {
371e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang					&drop_def("kernel/sys_ni.o", $name);
372e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang					next;
373e8cf981346b78ee50c2bfce83be9ee55704b3d4fAmerigo Wang				}
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
37586d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf "$name is multiply defined in :-\n";
37786d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			foreach my $module (@{$def{$name}}) {
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf "\t$module\n";
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssub resolve_external_references
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
38686d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	my ($kstrtab, $ksymtab, $export);
38786d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf "\n";
38986d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	foreach my $object (keys(%nmdata)) {
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		my $nmdata = $nmdata{$object};
39186d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger		for (my $i = 0; $i <= $#{$nmdata}; ++$i) {
39286d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			my ($type, $name) = split(' ', $nmdata->[$i], 2);
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ($type eq "U" || $type eq "w") {
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (exists($def{$name}) || exists($ksymtab{$name})) {
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					# add the owning object to the nmdata
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					$nmdata->[$i] = "$type $name $object";
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					# only count as a reference if it is not EXPORT_...
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					$kstrtab = "R __kstrtab_$name";
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					$ksymtab = "R __ksymtab_$name";
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					$export = 0;
40186d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger					for (my $j = 0; $j <= $#{$nmdata}; ++$j) {
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						if ($nmdata->[$j] eq $kstrtab ||
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						    $nmdata->[$j] eq $ksymtab) {
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							$export = 1;
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							last;
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						}
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if ($export) {
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						$export{$name} = "";
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					else {
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						$ref{$name} = ""
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
41543f683c9e465a64259c6058a7c313facc697b203Stephen Hemminger				elsif ( ! $nameexception{$name}
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__sched_text_/
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__start_/
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__end_/
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__stop_/
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__scheduling_functions_.*_here/
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__.*initcall_/
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__.*per_cpu_start/
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__.*per_cpu_end/
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__alt_instructions/
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__setup_/
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__mod_timer/
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^__mod_page_state/
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^init_module/
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					&& $name !~ /^cleanup_module/
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				) {
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printf "Cannot resolve ";
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printf "weak " if ($type eq "w");
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printf "reference to $name from $object\n";
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssub list_extra_externals
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	my %noref = ();
44386d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger
44486d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger	foreach my $name (keys(%def)) {
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (! exists($ref{$name})) {
44686d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			my @module = @{$def{$name}};
44786d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			foreach my $module (@module) {
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (! exists($noref{$module})) {
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					$noref{$module} = [];
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				push(@{$noref{$module}}, $name);
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (%noref) {
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf "\nExternally defined symbols with no external references\n";
45786d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger		foreach my $module (sort(keys(%noref))) {
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf "  $module\n";
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			foreach (sort(@{$noref{$module}})) {
46086d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			    my $export;
46186d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			    if (exists($export{$_})) {
46286d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger				$export = " (export only)";
46386d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			    } else {
46486d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger				$export = "";
46586d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			    }
46686d08e569f63a71a2d259507e335beea32b4d2aaStephen Hemminger			    printf "    $_$export\n";
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
471