aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include4
-rw-r--r--scripts/Makefile.build16
-rw-r--r--scripts/Makefile.host14
-rw-r--r--scripts/Makefile.lib6
-rw-r--r--scripts/Makefile.modinst2
-rw-r--r--scripts/Makefile.modpost4
-rw-r--r--scripts/basic/Makefile6
-rw-r--r--scripts/basic/split-include.c226
-rwxr-xr-xscripts/bloat-o-meter3
-rwxr-xr-xscripts/checkstack.pl14
-rwxr-xr-xscripts/checkversion.pl7
-rw-r--r--scripts/export_report.pl169
-rw-r--r--scripts/genksyms/genksyms.c77
-rw-r--r--scripts/genksyms/genksyms.h1
-rw-r--r--scripts/genksyms/lex.c_shipped2
-rw-r--r--scripts/genksyms/lex.l2
-rw-r--r--scripts/kconfig/conf.c23
-rw-r--r--scripts/kconfig/confdata.c491
-rw-r--r--scripts/kconfig/expr.c53
-rw-r--r--scripts/kconfig/expr.h20
-rw-r--r--scripts/kconfig/gconf.c12
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped91
-rw-r--r--scripts/kconfig/lkc.h10
-rw-r--r--scripts/kconfig/lkc_proto.h5
-rw-r--r--scripts/kconfig/lxdialog/checklist.c7
-rw-r--r--scripts/kconfig/menu.c34
-rw-r--r--scripts/kconfig/qconf.cc1048
-rw-r--r--scripts/kconfig/qconf.h158
-rw-r--r--scripts/kconfig/symbol.c50
-rw-r--r--scripts/kconfig/util.c4
-rw-r--r--scripts/kconfig/zconf.gperf3
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped181
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped930
-rw-r--r--scripts/kconfig/zconf.y33
-rwxr-xr-xscripts/kernel-doc32
-rw-r--r--scripts/mod/mk_elfconfig.c6
-rw-r--r--scripts/mod/modpost.c219
-rw-r--r--scripts/mod/modpost.h6
-rwxr-xr-xscripts/package/mkspec5
-rw-r--r--scripts/rt-tester/check-all.sh22
-rw-r--r--scripts/rt-tester/rt-tester.py222
-rw-r--r--scripts/rt-tester/t2-l1-2rt-sameprio.tst99
-rw-r--r--scripts/rt-tester/t2-l1-pi.tst82
-rw-r--r--scripts/rt-tester/t2-l1-signal.tst77
-rw-r--r--scripts/rt-tester/t2-l2-2rt-deadlock.tst89
-rw-r--r--scripts/rt-tester/t3-l1-pi-1rt.tst92
-rw-r--r--scripts/rt-tester/t3-l1-pi-2rt.tst93
-rw-r--r--scripts/rt-tester/t3-l1-pi-3rt.tst92
-rw-r--r--scripts/rt-tester/t3-l1-pi-signal.tst98
-rw-r--r--scripts/rt-tester/t3-l1-pi-steal.tst96
-rw-r--r--scripts/rt-tester/t3-l2-pi.tst92
-rw-r--r--scripts/rt-tester/t4-l2-pi-deboost.tst123
-rw-r--r--scripts/rt-tester/t5-l4-pi-boost-deboost-setsched.tst183
-rw-r--r--scripts/rt-tester/t5-l4-pi-boost-deboost.tst143
-rw-r--r--scripts/setlocalversion4
55 files changed, 4145 insertions, 1436 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index b0d067be739..2180c88cfe8 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -13,6 +13,10 @@ space := $(empty) $(empty)
depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
###
+# filename of target with directory and extension stripped
+basetarget = $(basename $(notdir $@))
+
+###
# Escape single quote for use in echo statements
escsq = $(subst $(squote),'\$(squote)',$1)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index e48e60da304..3cb445cc743 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -8,7 +8,7 @@ PHONY := __build
__build:
# Read .config if it exist, otherwise ignore
--include .config
+-include include/config/auto.conf
include scripts/Kbuild.include
@@ -117,7 +117,7 @@ $(real-objs-m:.o=.lst): quiet_modtag := [M]
$(obj-m) : quiet_modtag := [M]
# Default for not multi-part modules
-modname = $(*F)
+modname = $(basetarget)
$(multi-objs-m) : modname = $(modname-multi)
$(multi-objs-m:.o=.i) : modname = $(modname-multi)
@@ -140,6 +140,15 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
%.i: %.c FORCE
$(call if_changed_dep,cc_i_c)
+quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
+cmd_cc_symtypes_c = \
+ $(CPP) -D__GENKSYMS__ $(c_flags) $< \
+ | $(GENKSYMS) -T $@ >/dev/null; \
+ test -s $@ || rm -f $@
+
+%.symtypes : %.c FORCE
+ $(call if_changed_dep,cc_symtypes_c)
+
# C (.c) files
# The C file is compiled and updated dependency information is generated.
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
@@ -166,7 +175,8 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
cmd_modversions = \
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \
- | $(GENKSYMS) -a $(ARCH) \
+ | $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \
+ -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \
> $(@D)/.tmp_$(@F:.o=.ver); \
\
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 2d519704b8f..18ecd4d5df7 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -33,8 +33,8 @@
__hostprogs := $(sort $(hostprogs-y)$(hostprogs-m))
# hostprogs-y := tools/build may have been specified. Retreive directory
-obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
-obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs))))
+host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
+host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs))))
# C code
@@ -73,13 +73,17 @@ host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
host-cshlib := $(addprefix $(obj)/,$(host-cshlib))
host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs))
-obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
+host-objdirs := $(addprefix $(obj)/,$(host-objdirs))
+
+obj-dirs += $(host-objdirs)
#####
# Handle options to gcc. Support building with separate output directory
-_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o)
-_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o)
+_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
+ $(HOSTCFLAGS_$(basetarget).o)
+_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
+ $(HOSTCXXFLAGS_$(basetarget).o)
ifeq ($(KBUILD_SRC),)
__hostc_flags = $(_hostc_flags)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 2cb4935e85d..fc498fee68e 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -82,12 +82,12 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
# than one module. In that case KBUILD_MODNAME will be set to foo_bar,
# where foo and bar are the name of the modules.
name-fix = $(subst $(comma),_,$(subst -,_,$1))
-basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(*F)))"
+basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
-_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
-_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(basetarget).o)
+_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
_cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F))
# If building the kernel in a separate objtree expand all occurrences
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index 2686dd5dce8..f0ff248f5e6 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -17,7 +17,7 @@ __modinst: $(modules)
@:
quiet_cmd_modules_install = INSTALL $@
- cmd_modules_install = mkdir -p $(2); cp $@ $(2)
+ cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@)
# Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 0e056cffffd..a49550205dc 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -35,7 +35,7 @@
PHONY := _modpost
_modpost: __modpost
-include .config
+include include/config/auto.conf
include scripts/Kbuild.include
include scripts/Makefile.lib
@@ -72,7 +72,7 @@ $(modules:.ko=.mod.c): __modpost ;
# Step 5), compile all *.mod.c files
# modname is set to make c_flags define KBUILD_MODNAME
-modname = $(*F)
+modname = $(notdir $(@:.mod.o=))
quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index f22e94c3a2d..2f60070f973 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -1,17 +1,15 @@
###
# Makefile.basic list the most basic programs used during the build process.
# The programs listed herein is what is needed to do the basic stuff,
-# such as splitting .config and fix dependency file.
+# such as fix dependency file.
# This initial step is needed to avoid files to be recompiled
# when kernel configuration changes (which is what happens when
# .config is included by main Makefile.
# ---------------------------------------------------------------------------
# fixdep: Used to generate dependency information during build process
-# split-include: Divide all config symbols up in a number of files in
-# include/config/...
# docproc: Used in Documentation/docbook
-hostprogs-y := fixdep split-include docproc
+hostprogs-y := fixdep docproc
always := $(hostprogs-y)
# fixdep is needed to compile other host programs
diff --git a/scripts/basic/split-include.c b/scripts/basic/split-include.c
deleted file mode 100644
index 459c45276cb..00000000000
--- a/scripts/basic/split-include.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * split-include.c
- *
- * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
- * This is a C version of syncdep.pl by Werner Almesberger.
- *
- * This program takes autoconf.h as input and outputs a directory full
- * of one-line include files, merging onto the old values.
- *
- * Think of the configuration options as key-value pairs. Then there
- * are five cases:
- *
- * key old value new value action
- *
- * KEY-1 VALUE-1 VALUE-1 leave file alone
- * KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file
- * KEY-3 - VALUE-3 write VALUE-3 into file
- * KEY-4 VALUE-4 - write an empty file
- * KEY-5 (empty) - leave old empty file alone
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define ERROR_EXIT(strExit) \
- { \
- const int errnoSave = errno; \
- fprintf(stderr, "%s: ", str_my_name); \
- errno = errnoSave; \
- perror((strExit)); \
- exit(1); \
- }
-
-
-
-int main(int argc, const char * argv [])
-{
- const char * str_my_name;
- const char * str_file_autoconf;
- const char * str_dir_config;
-
- FILE * fp_config;
- FILE * fp_target;
- FILE * fp_find;
-
- int buffer_size;
-
- char * line;
- char * old_line;
- char * list_target;
- char * ptarget;
-
- struct stat stat_buf;
-
- /* Check arg count. */
- if (argc != 3)
- {
- fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]);
- exit(1);
- }
-
- str_my_name = argv[0];
- str_file_autoconf = argv[1];
- str_dir_config = argv[2];
-
- /* Find a buffer size. */
- if (stat(str_file_autoconf, &stat_buf) != 0)
- ERROR_EXIT(str_file_autoconf);
- buffer_size = 2 * stat_buf.st_size + 4096;
-
- /* Allocate buffers. */
- if ( (line = malloc(buffer_size)) == NULL
- || (old_line = malloc(buffer_size)) == NULL
- || (list_target = malloc(buffer_size)) == NULL )
- ERROR_EXIT(str_file_autoconf);
-
- /* Open autoconfig file. */
- if ((fp_config = fopen(str_file_autoconf, "r")) == NULL)
- ERROR_EXIT(str_file_autoconf);
-
- /* Make output directory if needed. */
- if (stat(str_dir_config, &stat_buf) != 0)
- {
- if (mkdir(str_dir_config, 0755) != 0)
- ERROR_EXIT(str_dir_config);
- }
-
- /* Change to output directory. */
- if (chdir(str_dir_config) != 0)
- ERROR_EXIT(str_dir_config);
-
- /* Put initial separator into target list. */
- ptarget = list_target;
- *ptarget++ = '\n';
-
- /* Read config lines. */
- while (fgets(line, buffer_size, fp_config))
- {
- const char * str_config;
- int is_same;
- int itarget;
-
- if (line[0] != '#')
- continue;
- if ((str_config = strstr(line, "CONFIG_")) == NULL)
- continue;
-
- /* Make the output file name. */
- str_config += sizeof("CONFIG_") - 1;
- for (itarget = 0; !isspace(str_config[itarget]); itarget++)
- {
- int c = (unsigned char) str_config[itarget];
- if (isupper(c)) c = tolower(c);
- if (c == '_') c = '/';
- ptarget[itarget] = c;
- }
- ptarget[itarget++] = '.';
- ptarget[itarget++] = 'h';
- ptarget[itarget++] = '\0';
-
- /* Check for existing file. */
- is_same = 0;
- if ((fp_target = fopen(ptarget, "r")) != NULL)
- {
- fgets(old_line, buffer_size, fp_target);
- if (fclose(fp_target) != 0)
- ERROR_EXIT(ptarget);
- if (!strcmp(line, old_line))
- is_same = 1;
- }
-
- if (!is_same)
- {
- /* Auto-create directories. */
- int islash;
- for (islash = 0; islash < itarget; islash++)
- {
- if (ptarget[islash] == '/')
- {
- ptarget[islash] = '\0';
- if (stat(ptarget, &stat_buf) != 0
- && mkdir(ptarget, 0755) != 0)
- ERROR_EXIT( ptarget );
- ptarget[islash] = '/';
- }
- }
-
- /* Write the file. */
- if ((fp_target = fopen(ptarget, "w" )) == NULL)
- ERROR_EXIT(ptarget);
- fputs(line, fp_target);
- if (ferror(fp_target) || fclose(fp_target) != 0)
- ERROR_EXIT(ptarget);
- }
-
- /* Update target list */
- ptarget += itarget;
- *(ptarget-1) = '\n';
- }
-
- /*
- * Close autoconfig file.
- * Terminate the target list.
- */
- if (fclose(fp_config) != 0)
- ERROR_EXIT(str_file_autoconf);
- *ptarget = '\0';
-
- /*
- * Fix up existing files which have no new value.
- * This is Case 4 and Case 5.
- *
- * I re-read the tree and filter it against list_target.
- * This is crude. But it avoids data copies. Also, list_target
- * is compact and contiguous, so it easily fits into cache.
- *
- * Notice that list_target contains strings separated by \n,
- * with a \n before the first string and after the last.
- * fgets gives the incoming names a terminating \n.
- * So by having an initial \n, strstr will find exact matches.
- */
-
- fp_find = popen("find * -type f -name \"*.h\" -print", "r");
- if (fp_find == 0)
- ERROR_EXIT( "find" );
-
- line[0] = '\n';
- while (fgets(line+1, buffer_size, fp_find))
- {
- if (strstr(list_target, line) == NULL)
- {
- /*
- * This is an old file with no CONFIG_* flag in autoconf.h.
- */
-
- /* First strip the \n. */
- line[strlen(line)-1] = '\0';
-
- /* Grab size. */
- if (stat(line+1, &stat_buf) != 0)
- ERROR_EXIT(line);
-
- /* If file is not empty, make it empty and give it a fresh date. */
- if (stat_buf.st_size != 0)
- {
- if ((fp_target = fopen(line+1, "w")) == NULL)
- ERROR_EXIT(line);
- if (fclose(fp_target) != 0)
- ERROR_EXIT(line);
- }
- }
- }
-
- if (pclose(fp_find) != 0)
- ERROR_EXIT("find");
-
- return 0;
-}
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index 75f21d843c1..ce59fc2d8de 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -18,7 +18,8 @@ def getsizes(file):
for l in os.popen("nm --size-sort " + file).readlines():
size, type, name = l[:-1].split()
if type in "tTdDbB":
- sym[name] = int(size, 16)
+ if "." in name: name = "static." + name.split(".")[0]
+ sym[name] = sym.get(name, 0) + int(size, 16)
return sym
old = getsizes(sys.argv[1])
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index dadfa20ffec..b34924663ac 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -89,11 +89,21 @@ sub bysize($) {
#
my $funcre = qr/^$x* <(.*)>:$/;
my $func;
+my $file, $lastslash;
+
while (my $line = <STDIN>) {
if ($line =~ m/$funcre/) {
$func = $1;
}
- if ($line =~ m/$re/) {
+ elsif ($line =~ m/(.*):\s*file format/) {
+ $file = $1;
+ $file =~ s/\.ko//;
+ $lastslash = rindex($file, "/");
+ if ($lastslash != -1) {
+ $file = substr($file, $lastslash + 1);
+ }
+ }
+ elsif ($line =~ m/$re/) {
my $size = $1;
$size = hex($size) if ($size =~ /^0x/);
@@ -109,7 +119,7 @@ while (my $line = <STDIN>) {
$addr =~ s/ /0/g;
$addr = "0x$addr";
- my $intro = "$addr $func:";
+ my $intro = "$addr $func [$file]:";
my $padlen = 56 - length($intro);
while ($padlen > 0) {
$intro .= ' ';
diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl
index 9f84e562318..ec7d21161bd 100755
--- a/scripts/checkversion.pl
+++ b/scripts/checkversion.pl
@@ -1,7 +1,7 @@
#! /usr/bin/perl
#
-# checkversion find uses of LINUX_VERSION_CODE, KERNEL_VERSION, or
-# UTS_RELEASE without including <linux/version.h>, or cases of
+# checkversion find uses of LINUX_VERSION_CODE or KERNEL_VERSION
+# without including <linux/version.h>, or cases of
# including <linux/version.h> that don't need it.
# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
@@ -41,8 +41,7 @@ foreach $file (@ARGV)
}
# Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
- if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/) ||
- ($_ =~ /UTS_RELEASE/)) {
+ if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) {
$fUseVersion = 1;
last LINE if $iLinuxVersion;
}
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
new file mode 100644
index 00000000000..9ed00d9bb0a
--- /dev/null
+++ b/scripts/export_report.pl
@@ -0,0 +1,169 @@
+#!/usr/bin/perl -w
+#
+# (C) Copyright IBM Corporation 2006.
+# Released under GPL v2.
+# Author : Ram Pai (linuxram@us.ibm.com)
+#
+# Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c
+#
+
+use Getopt::Std;
+use strict;
+
+sub numerically {
+ my $no1 = (split /\s+/, $a)[1];
+ my $no2 = (split /\s+/, $b)[1];
+ return $no1 <=> $no2;
+}
+
+sub alphabetically {
+ my ($module1, $value1) = @{$a};
+ my ($module2, $value2) = @{$b};
+ return $value1 <=> $value2 || $module2 cmp $module1;
+}
+
+sub print_depends_on {
+ my ($href) = @_;
+ print "\n";
+ while (my ($mod, $list) = each %$href) {
+ print "\t$mod:\n";
+ foreach my $sym (sort numerically @{$list}) {
+ my ($symbol, $no) = split /\s+/, $sym;
+ printf("\t\t%-25s\t%-25d\n", $symbol, $no);
+ }
+ print "\n";
+ }
+ print "\n";
+ print "~"x80 , "\n";
+}
+
+sub usage {
+ print "Usage: @_ -h -k Module.symvers [ -o outputfile ] \n",
+ "\t-f: treat all the non-option argument as .mod.c files. ",
+ "Recommend using this as the last option\n",
+ "\t-h: print detailed help\n",
+ "\t-k: the path to Module.symvers file. By default uses ",
+ "the file from the current directory\n",
+ "\t-o outputfile: output the report to outputfile\n";
+ exit 0;
+}
+
+sub collectcfiles {
+ my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`;
+ @file = grep {s/\.ko/.mod.c/} @file;
+ chomp @file;
+ return @file;
+}
+
+my (%SYMBOL, %MODULE, %opt, @allcfiles);
+
+if (not getopts('hk:o:f',\%opt) or defined $opt{'h'}) {
+ usage($0);
+}
+
+if (defined $opt{'f'}) {
+ @allcfiles = @ARGV;
+} else {
+ @allcfiles = collectcfiles();
+}
+
+if (not defined $opt{'k'}) {
+ $opt{'k'} = "Module.symvers";
+}
+
+unless (open(MODULE_SYMVERS, $opt{'k'})) {
+ die "Sorry, cannot open $opt{'k'}: $!\n";
+}
+
+if (defined $opt{'o'}) {
+ unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) {
+ die "Sorry, cannot open $opt{'o'} $!\n";
+ }
+ select OUTPUT_HANDLE;
+}
+#
+# collect all the symbols and their attributes from the
+# Module.symvers file
+#
+while ( <MODULE_SYMVERS> ) {
+ chomp;
+ my (undef, $symbol, $module, $gpl) = split;
+ $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
+}
+close(MODULE_SYMVERS);
+
+#
+# collect the usage count of each symbol.
+#
+foreach my $thismod (@allcfiles) {
+ unless (open(MODULE_MODULE, $thismod)) {
+ print "Sorry, cannot open $thismod: $!\n";
+ next;
+ }
+ my $state=0;
+ while ( <MODULE_MODULE> ) {
+ chomp;
+ if ($state eq 0) {
+ $state = 1 if ($_ =~ /static const struct modversion_info/);
+ next;
+ }
+ if ($state eq 1) {
+ $state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/);
+ next;
+ }
+ if ($state eq 2) {
+ if ( $_ !~ /0x[0-9a-f]{7,8},/ ) {
+ next;
+ }
+ my $sym = (split /([,"])/,)[4];
+ my ($module, $value, $symbol, $gpl) = @{$SYMBOL{$sym}};
+ $SYMBOL{ $sym } = [ $module, $value+1, $symbol, $gpl];
+ push(@{$MODULE{$thismod}} , $sym);
+ }
+ }
+ if ($state ne 2) {
+ print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
+ }
+ close(MODULE_MODULE);
+}
+
+print "\tThis file reports the exported symbols usage patterns by in-tree\n",
+ "\t\t\t\tmodules\n";
+printf("%s\n\n\n","x"x80);
+printf("\t\t\t\tINDEX\n\n\n");
+printf("SECTION 1: Usage counts of all exported symbols\n");
+printf("SECTION 2: List of modules and the exported symbols they use\n");
<