aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-16 11:46:22 -0500
committerIngo Molnar <mingo@elte.hu>2009-01-16 11:46:22 -0500
commit5a2dd72abdae75ea2960145e0549635ce4e0be96 (patch)
tree44dba0119c75679a17215200f92ab23bdde9efc2 /scripts
parentefdc64f0c792ea744bcc9203f35b908e66d42f41 (diff)
parent7cb36b6ccdca03bd87e8faca7fd920643dd1aec7 (diff)
Merge branch 'linus' into irq/genirq
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Kbuild.include22
-rw-r--r--scripts/Makefile3
-rw-r--r--scripts/Makefile.build79
-rw-r--r--scripts/Makefile.lib15
-rw-r--r--scripts/Makefile.modinst3
-rw-r--r--scripts/bootgraph.pl72
-rwxr-xr-xscripts/checkpatch.pl184
-rwxr-xr-xscripts/config150
-rwxr-xr-xscripts/decodecode32
-rwxr-xr-xscripts/extract-ikconfig8
-rw-r--r--scripts/genksyms/genksyms.c277
-rw-r--r--scripts/genksyms/genksyms.h7
-rw-r--r--scripts/genksyms/keywords.c_shipped189
-rw-r--r--scripts/genksyms/keywords.gperf2
-rwxr-xr-xscripts/headerdep.pl193
-rw-r--r--scripts/headers_check.pl70
-rw-r--r--scripts/headers_install.pl3
-rw-r--r--scripts/ihex2fw.c268
-rw-r--r--scripts/kallsyms.c21
-rw-r--r--scripts/kconfig/expr.h82
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped7
-rw-r--r--scripts/kconfig/lxdialog/check-lxdialog.sh2
-rw-r--r--scripts/kconfig/zconf.l7
-rwxr-xr-xscripts/kernel-doc67
-rw-r--r--scripts/markup_oops.pl203
-rwxr-xr-xscripts/mkcompile_h6
-rw-r--r--scripts/mkmakefile4
-rw-r--r--scripts/mksysmap7
-rw-r--r--scripts/package/Makefile9
-rwxr-xr-xscripts/recordmcount.pl51
-rwxr-xr-xscripts/setlocalversion7
-rw-r--r--scripts/strip-symbols22
-rwxr-xr-xscripts/tags.sh167
-rw-r--r--scripts/trace/power.pl108
-rw-r--r--scripts/tracing/draw_functrace.py130
36 files changed, 2173 insertions, 305 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index b939fbd01195..09e2406f3b78 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,6 +1,7 @@
1# 1#
2# Generated files 2# Generated files
3# 3#
4ihex2fw
4conmakehash 5conmakehash
5kallsyms 6kallsyms
6pnmtologo 7pnmtologo
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 982dcae7bbe2..c29be8f90248 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -25,6 +25,13 @@ basetarget = $(basename $(notdir $@))
25escsq = $(subst $(squote),'\$(squote)',$1) 25escsq = $(subst $(squote),'\$(squote)',$1)
26 26
27### 27###
28# Easy method for doing a status message
29 kecho := :
30 quiet_kecho := echo
31silent_kecho := :
32kecho := $($(quiet)kecho)
33
34###
28# filechk is used to check if the content of a generated file is updated. 35# filechk is used to check if the content of a generated file is updated.
29# Sample usage: 36# Sample usage:
30# define filechk_sample 37# define filechk_sample
@@ -39,22 +46,15 @@ escsq = $(subst $(squote),'\$(squote)',$1)
39# - If they are equal no change, and no timestamp update 46# - If they are equal no change, and no timestamp update
40# - stdin is piped in from the first prerequisite ($<) so one has 47# - stdin is piped in from the first prerequisite ($<) so one has
41# to specify a valid file as first prerequisite (often the kbuild file) 48# to specify a valid file as first prerequisite (often the kbuild file)
42 chk_filechk = :
43 quiet_chk_filechk = echo ' CHK $@'
44silent_chk_filechk = :
45 upd_filechk = :
46 quiet_upd_filechk = echo ' UPD $@'
47silent_upd_filechk = :
48
49define filechk 49define filechk
50 $(Q)set -e; \ 50 $(Q)set -e; \
51 $($(quiet)chk_filechk); \ 51 $(kecho) ' CHK $@'; \
52 mkdir -p $(dir $@); \ 52 mkdir -p $(dir $@); \
53 $(filechk_$(1)) < $< > $@.tmp; \ 53 $(filechk_$(1)) < $< > $@.tmp; \
54 if [ -r $@ ] && cmp -s $@ $@.tmp; then \ 54 if [ -r $@ ] && cmp -s $@ $@.tmp; then \
55 rm -f $@.tmp; \ 55 rm -f $@.tmp; \
56 else \ 56 else \
57 $($(quiet)upd_filechk); \ 57 $(kecho) ' UPD $@'; \
58 mv -f $@.tmp $@; \ 58 mv -f $@.tmp $@; \
59 fi 59 fi
60endef 60endef
@@ -144,7 +144,9 @@ ld-option = $(call try-run,\
144build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj 144build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
145 145
146# Prefix -I with $(srctree) if it is not an absolute path. 146# Prefix -I with $(srctree) if it is not an absolute path.
147addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) 147# skip if -I has no parameter
148addtree = $(if $(patsubst -I%,%,$(1)), \
149$(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1))
148 150
149# Find all -I options and call addtree 151# Find all -I options and call addtree
150flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) 152flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
diff --git a/scripts/Makefile b/scripts/Makefile
index aafdf064feef..035182e16afb 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -2,11 +2,12 @@
2# scripts contains sources for various helper programs used throughout 2# scripts contains sources for various helper programs used throughout
3# the kernel for the build process. 3# the kernel for the build process.
4# --------------------------------------------------------------------------- 4# ---------------------------------------------------------------------------
5# ihex2fw: Parser/loader for IHEX formatted data
5# kallsyms: Find all symbols in vmlinux 6# kallsyms: Find all symbols in vmlinux
6# pnmttologo: Convert pnm files to logo files 7# pnmttologo: Convert pnm files to logo files
7# conmakehash: Create chartable
8# conmakehash: Create arrays for initializing the kernel console tables 8# conmakehash: Create arrays for initializing the kernel console tables
9 9
10hostprogs-y := ihex2fw
10hostprogs-$(CONFIG_KALLSYMS) += kallsyms 11hostprogs-$(CONFIG_KALLSYMS) += kallsyms
11hostprogs-$(CONFIG_LOGO) += pnmtologo 12hostprogs-$(CONFIG_LOGO) += pnmtologo
12hostprogs-$(CONFIG_VT) += conmakehash 13hostprogs-$(CONFIG_VT) += conmakehash
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 468fbc9016c7..5d900307de3e 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -151,14 +151,20 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
151$(obj)/%.i: $(src)/%.c FORCE 151$(obj)/%.i: $(src)/%.c FORCE
152 $(call if_changed_dep,cc_i_c) 152 $(call if_changed_dep,cc_i_c)
153 153
154cmd_genksyms = \
155 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \
156 $(GENKSYMS) -T $@ -A -a $(ARCH) \
157 $(if $(KBUILD_PRESERVE),-p) \
158 $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null)))
159
154quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ 160quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
155cmd_cc_symtypes_c = \ 161cmd_cc_symtypes_c = \
156 $(CPP) -D__GENKSYMS__ $(c_flags) $< \ 162 set -e; \
157 | $(GENKSYMS) -T $@ >/dev/null; \ 163 $(call cmd_genksyms, true) >/dev/null; \
158 test -s $@ || rm -f $@ 164 test -s $@ || rm -f $@
159 165
160$(obj)/%.symtypes : $(src)/%.c FORCE 166$(obj)/%.symtypes : $(src)/%.c FORCE
161 $(call if_changed_dep,cc_symtypes_c) 167 $(call cmd,cc_symtypes_c)
162 168
163# C (.c) files 169# C (.c) files
164# The C file is compiled and updated dependency information is generated. 170# The C file is compiled and updated dependency information is generated.
@@ -171,43 +177,45 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
171 177
172else 178else
173# When module versioning is enabled the following steps are executed: 179# When module versioning is enabled the following steps are executed:
174# o compile a .tmp_<file>.o from <file>.c 180# o compile a .tmp_<file>.s from <file>.c
175# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does 181# o if .tmp_<file>.s doesn't contain a __ksymtab version, i.e. does
176# not export symbols, we just rename .tmp_<file>.o to <file>.o and 182# not export symbols, we just assemble .tmp_<file>.s to <file>.o and
177# are done. 183# are done.
178# o otherwise, we calculate symbol versions using the good old 184# o otherwise, we calculate symbol versions using the good old
179# genksyms on the preprocessed source and postprocess them in a way 185# genksyms on the preprocessed source and postprocess them in a way
180# that they are usable as a linker script 186# that they are usable as assembly source
181# o generate <file>.o from .tmp_<file>.o using the linker to 187# o assemble <file>.o from .tmp_<file>.s forcing inclusion of directives
182# replace the unresolved symbols __crc_exported_symbol with 188# defining the actual values of __crc_*, followed by objcopy-ing them
183# the actual value of the checksum generated by genksyms 189# to force these symbols to be local to permit stripping them later.
190s_file = $(@D)/.tmp_$(@F:.o=.s)
191v_file = $(@D)/.tmp_$(@F:.o=.v)
192tmp_o_file = $(@D)/.tmp_$(@F)
193no_g_c_flags = $(filter-out -g%,$(c_flags))
194
195cmd_cc_o_c = $(CC) $(c_flags) -S -o $(s_file) $<
184 196
185cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
186cmd_modversions = \ 197cmd_modversions = \
187 if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ 198 if grep -q __ksymtab $(s_file); then \
188 $(CPP) -D__GENKSYMS__ $(c_flags) $< \ 199 if $(call cmd_genksyms, $(KBUILD_SYMTYPES)) > $(v_file) \
189 | $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \ 200 && $(CC) $(no_g_c_flags) -c -Wa,$(v_file) \
190 -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \ 201 -o $(tmp_o_file) $(s_file) \
191 > $(@D)/.tmp_$(@F:.o=.ver); \ 202 && $(OBJCOPY) -L '__crc_*' -L '___crc_*' -w \
192 \ 203 $(tmp_o_file) $@; \
193 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ 204 then \
194 -T $(@D)/.tmp_$(@F:.o=.ver); \ 205 : ; \
195 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ 206 else \
207 rm -f $@; exit 1; \
208 fi; \
196 else \ 209 else \
197 mv -f $(@D)/.tmp_$(@F) $@; \ 210 rm -f $(v_file); \
211 $(CC) $(no_g_c_flags) -c -o $@ $(s_file); \
198 fi; 212 fi;
199endif 213endif
200 214
201ifdef CONFIG_64BIT
202arch_bits = 64
203else
204arch_bits = 32
205endif
206
207ifdef CONFIG_FTRACE_MCOUNT_RECORD 215ifdef CONFIG_FTRACE_MCOUNT_RECORD
208cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \ 216cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
209 "$(ARCH)" "$(arch_bits)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" \ 217 "$(if $(CONFIG_64BIT),64,32)" \
210 "$(NM)" "$(RM)" "$(MV)" "$(@)"; 218 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)";
211endif 219endif
212 220
213define rule_cc_o_c 221define rule_cc_o_c
@@ -217,7 +225,12 @@ define rule_cc_o_c
217 $(cmd_record_mcount) \ 225 $(cmd_record_mcount) \
218 scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ 226 scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
219 $(dot-target).tmp; \ 227 $(dot-target).tmp; \
220 rm -f $(depfile); \ 228 if [ -r $(@D)/.tmp_$(@F:.o=.v) ]; then \
229 echo >> $(dot-target).tmp; \
230 echo '$@: $(GENKSYMS)' >> $(dot-target).tmp; \
231 echo '$(GENKSYMS):: ;' >> $(dot-target).tmp; \
232 fi; \
233 rm -f $(depfile) $(@D)/.tmp_$(@F:.o=.?); \
221 mv -f $(dot-target).tmp $(dot-target).cmd 234 mv -f $(dot-target).tmp $(dot-target).cmd
222endef 235endef
223 236
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index b4ca38a21158..e06365775bdf 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -104,9 +104,11 @@ else
104debug_flags = 104debug_flags =
105endif 105endif
106 106
107orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) 107orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \
108 $(ccflags-y) $(CFLAGS_$(basetarget).o)
108_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) 109_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
109_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) 110_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \
111 $(asflags-y) $(AFLAGS_$(basetarget).o)
110_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) 112_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
111 113
112# If building the kernel in a separate objtree expand all occurrences 114# If building the kernel in a separate objtree expand all occurrences
@@ -127,15 +129,16 @@ __a_flags = $(call flags,_a_flags)
127__cpp_flags = $(call flags,_cpp_flags) 129__cpp_flags = $(call flags,_cpp_flags)
128endif 130endif
129 131
130c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ 132c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
131 $(__c_flags) $(modkern_cflags) \ 133 $(__c_flags) $(modkern_cflags) \
132 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ 134 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
133 $(debug_flags) 135 $(debug_flags)
134 136
135a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ 137a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
136 $(__a_flags) $(modkern_aflags) 138 $(__a_flags) $(modkern_aflags)
137 139
138cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags) 140cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
141 $(__cpp_flags)
139 142
140ld_flags = $(LDFLAGS) $(ldflags-y) 143ld_flags = $(LDFLAGS) $(ldflags-y)
141 144
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index efa5d940e632..a5122dce1264 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -17,7 +17,8 @@ __modinst: $(modules)
17 @: 17 @:
18 18
19quiet_cmd_modules_install = INSTALL $@ 19quiet_cmd_modules_install = INSTALL $@
20 cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) 20 cmd_modules_install = mkdir -p $(2); \
21 $(mod_strip_cmd) $@ $(2)/$(notdir $@) || cp $@ $(2)
21 22
22# Modules built outside the kernel source tree go into extra by default 23# Modules built outside the kernel source tree go into extra by default
23INSTALL_MOD_DIR ?= extra 24INSTALL_MOD_DIR ?= extra
diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
index d2c61efc216f..b0246307aac4 100644
--- a/scripts/bootgraph.pl
+++ b/scripts/bootgraph.pl
@@ -41,11 +41,13 @@ use strict;
41 41
42my %start; 42my %start;
43my %end; 43my %end;
44my %type;
44my $done = 0; 45my $done = 0;
45my $maxtime = 0; 46my $maxtime = 0;
46my $firsttime = 100; 47my $firsttime = 100;
47my $count = 0; 48my $count = 0;
48my %pids; 49my %pids;
50my %pidctr;
49 51
50while (<>) { 52while (<>) {
51 my $line = $_; 53 my $line = $_;
@@ -53,6 +55,7 @@ while (<>) {
53 my $func = $2; 55 my $func = $2;
54 if ($done == 0) { 56 if ($done == 0) {
55 $start{$func} = $1; 57 $start{$func} = $1;
58 $type{$func} = 0;
56 if ($1 < $firsttime) { 59 if ($1 < $firsttime) {
57 $firsttime = $1; 60 $firsttime = $1;
58 } 61 }
@@ -63,12 +66,40 @@ while (<>) {
63 $count = $count + 1; 66 $count = $count + 1;
64 } 67 }
65 68
69 if ($line =~ /([0-9\.]+)\] async_waiting @ ([0-9]+)/) {
70 my $pid = $2;
71 my $func;
72 if (!defined($pidctr{$pid})) {
73 $func = "wait_" . $pid . "_1";
74 $pidctr{$pid} = 1;
75 } else {
76 $pidctr{$pid} = $pidctr{$pid} + 1;
77 $func = "wait_" . $pid . "_" . $pidctr{$pid};
78 }
79 if ($done == 0) {
80 $start{$func} = $1;
81 $type{$func} = 1;
82 if ($1 < $firsttime) {
83 $firsttime = $1;
84 }
85 }
86 $pids{$func} = $pid;
87 $count = $count + 1;
88 }
89
66 if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) { 90 if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) {
67 if ($done == 0) { 91 if ($done == 0) {
68 $end{$2} = $1; 92 $end{$2} = $1;
69 $maxtime = $1; 93 $maxtime = $1;
70 } 94 }
71 } 95 }
96
97 if ($line =~ /([0-9\.]+)\] async_continuing @ ([0-9]+)/) {
98 my $pid = $2;
99 my $func = "wait_" . $pid . "_" . $pidctr{$pid};
100 $end{$func} = $1;
101 $maxtime = $1;
102 }
72 if ($line =~ /Write protecting the/) { 103 if ($line =~ /Write protecting the/) {
73 $done = 1; 104 $done = 1;
74 } 105 }
@@ -78,15 +109,17 @@ while (<>) {
78} 109}
79 110
80if ($count == 0) { 111if ($count == 0) {
81 print "No data found in the dmesg. Make sure that 'printk.time=1' and\n"; 112 print STDERR <<END;
82 print "'initcall_debug' are passed on the kernel command line.\n\n"; 113No data found in the dmesg. Make sure that 'printk.time=1' and
83 print "Usage: \n"; 114'initcall_debug' are passed on the kernel command line.
84 print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n"; 115Usage:
85 exit; 116 dmesg | perl scripts/bootgraph.pl > output.svg
117END
118 exit 1;
86} 119}
87 120
88print "<?xml version=\"1.0\" standalone=\"no\"?> \n"; 121print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
89print "<svg width=\"1000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"; 122print "<svg width=\"2000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
90 123
91my @styles; 124my @styles;
92 125
@@ -103,18 +136,21 @@ $styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0
103$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 136$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
104$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)"; 137$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
105 138
106my $mult = 950.0 / ($maxtime - $firsttime); 139my $style_wait = "fill:rgb(128,128,128);fill-opacity:0.5;stroke-width:0;stroke:rgb(0,0,0)";
107my $threshold = ($maxtime - $firsttime) / 60.0; 140
141my $mult = 1950.0 / ($maxtime - $firsttime);
142my $threshold2 = ($maxtime - $firsttime) / 120.0;
143my $threshold = $threshold2/10;
108my $stylecounter = 0; 144my $stylecounter = 0;
109my %rows; 145my %rows;
110my $rowscount = 1; 146my $rowscount = 1;
111my @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start); 147my @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start);
112my $key; 148
113foreach $key (@initcalls) { 149foreach my $key (@initcalls) {
114 my $duration = $end{$key} - $start{$key}; 150 my $duration = $end{$key} - $start{$key};
115 151
116 if ($duration >= $threshold) { 152 if ($duration >= $threshold) {
117 my ($s, $s2, $e, $w, $y, $y2, $style); 153 my ($s, $s2, $s3, $e, $w, $y, $y2, $style);
118 my $pid = $pids{$key}; 154 my $pid = $pids{$key};
119 155
120 if (!defined($rows{$pid})) { 156 if (!defined($rows{$pid})) {
@@ -123,6 +159,7 @@ foreach $key (@initcalls) {
123 } 159 }
124 $s = ($start{$key} - $firsttime) * $mult; 160 $s = ($start{$key} - $firsttime) * $mult;
125 $s2 = $s + 6; 161 $s2 = $s + 6;
162 $s3 = $s + 1;
126 $e = ($end{$key} - $firsttime) * $mult; 163 $e = ($end{$key} - $firsttime) * $mult;
127 $w = $e - $s; 164 $w = $e - $s;
128 165
@@ -135,8 +172,17 @@ foreach $key (@initcalls) {
135 $stylecounter = 0; 172 $stylecounter = 0;
136 }; 173 };
137 174
138 print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n"; 175 if ($type{$key} == 1) {
139 print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n"; 176 $y = $y + 15;
177 print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"115\" style=\"$style_wait\"/>\n";
178 } else {
179 print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n";
180 if ($duration >= $threshold2) {
181 print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
182 } else {
183 print "<text transform=\"translate($s3,$y2) rotate(90)\" font-size=\"3pt\">$key</text>\n";
184 }
185 }
140 } 186 }
141} 187}
142 188
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index f88bb3e21cda..45eb0ae98eba 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,7 +1,8 @@
1#!/usr/bin/perl -w 1#!/usr/bin/perl -w
2# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit) 2# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc) 4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5# (c) 2008, Andy Whitcroft <apw@canonical.com>
5# Licensed under the terms of the GNU GPL License version 2 6# Licensed under the terms of the GNU GPL License version 2
6 7
7use strict; 8use strict;
@@ -9,7 +10,7 @@ use strict;
9my $P = $0; 10my $P = $0;
10$P =~ s@.*/@@g; 11$P =~ s@.*/@@g;
11 12
12my $V = '0.24'; 13my $V = '0.27';
13 14
14use Getopt::Long qw(:config no_auto_abbrev); 15use Getopt::Long qw(:config no_auto_abbrev);
15 16
@@ -68,7 +69,9 @@ my $dbg_possible = 0;
68my $dbg_type = 0; 69my $dbg_type = 0;
69my $dbg_attr = 0; 70my $dbg_attr = 0;
70for my $key (keys %debug) { 71for my $key (keys %debug) {
71 eval "\${dbg_$key} = '$debug{$key}';" 72 ## no critic
73 eval "\${dbg_$key} = '$debug{$key}';";
74 die "$@" if ($@);
72} 75}
73 76
74if ($terse) { 77if ($terse) {
@@ -116,7 +119,8 @@ our $Attribute = qr{
116 __(?:mem|cpu|dev|)(?:initdata|init)| 119 __(?:mem|cpu|dev|)(?:initdata|init)|
117 ____cacheline_aligned| 120 ____cacheline_aligned|
118 ____cacheline_aligned_in_smp| 121 ____cacheline_aligned_in_smp|
119 ____cacheline_internodealigned_in_smp 122 ____cacheline_internodealigned_in_smp|
123 __weak
120 }x; 124 }x;
121our $Modifier; 125our $Modifier;
122our $Inline = qr{inline|__always_inline|noinline}; 126our $Inline = qr{inline|__always_inline|noinline};
@@ -125,6 +129,7 @@ our $Lval = qr{$Ident(?:$Member)*};
125 129
126our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; 130our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
127our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; 131our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
132our $Compare = qr{<=|>=|==|!=|<|>};
128our $Operators = qr{ 133our $Operators = qr{
129 <=|>=|==|!=| 134 <=|>=|==|!=|
130 =>|->|<<|>>|<|>|!|~| 135 =>|->|<<|>>|<|>|!|~|
@@ -190,7 +195,7 @@ sub build_types {
190 }x; 195 }x;
191 $Type = qr{ 196 $Type = qr{
192 $NonptrType 197 $NonptrType
193 (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? 198 (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)?
194 (?:\s+$Inline|\s+$Modifier)* 199 (?:\s+$Inline|\s+$Modifier)*
195 }x; 200 }x;
196 $Declare = qr{(?:$Storage\s+)?$Type}; 201 $Declare = qr{(?:$Storage\s+)?$Type};
@@ -203,9 +208,9 @@ my @dep_includes = ();
203my @dep_functions = (); 208my @dep_functions = ();
204my $removal = "Documentation/feature-removal-schedule.txt"; 209my $removal = "Documentation/feature-removal-schedule.txt";
205if ($tree && -f "$root/$removal") { 210if ($tree && -f "$root/$removal") {
206 open(REMOVE, "<$root/$removal") || 211 open(my $REMOVE, '<', "$root/$removal") ||
207 die "$P: $removal: open failed - $!\n"; 212 die "$P: $removal: open failed - $!\n";
208 while (<REMOVE>) { 213 while (<$REMOVE>) {
209 if (/^Check:\s+(.*\S)/) { 214 if (/^Check:\s+(.*\S)/) {
210 for my $entry (split(/[, ]+/, $1)) { 215 for my $entry (split(/[, ]+/, $1)) {
211 if ($entry =~ m@include/(.*)@) { 216 if ($entry =~ m@include/(.*)@) {
@@ -217,17 +222,21 @@ if ($tree && -f "$root/$removal") {
217 } 222 }
218 } 223 }
219 } 224 }
225 close($REMOVE);
220} 226}
221 227
222my @rawlines = (); 228my @rawlines = ();
223my @lines = (); 229my @lines = ();
224my $vname; 230my $vname;
225for my $filename (@ARGV) { 231for my $filename (@ARGV) {
232 my $FILE;
226 if ($file) { 233 if ($file) {
227 open(FILE, "diff -u /dev/null $filename|") || 234 open($FILE, '-|', "diff -u /dev/null $filename") ||
228 die "$P: $filename: diff failed - $!\n"; 235 die "$P: $filename: diff failed - $!\n";
236 } elsif ($filename eq '-') {
237 open($FILE, '<&STDIN');
229 } else { 238 } else {
230 open(FILE, "<$filename") || 239 open($FILE, '<', "$filename") ||
231 die "$P: $filename: open failed - $!\n"; 240 die "$P: $filename: open failed - $!\n";
232 } 241 }
233 if ($filename eq '-') { 242 if ($filename eq '-') {
@@ -235,11 +244,11 @@ for my $filename (@ARGV) {
235 } else { 244 } else {
236 $vname = $filename; 245 $vname = $filename;
237 } 246 }
238 while (<FILE>) { 247 while (<$FILE>) {
239 chomp; 248 chomp;
240 push(@rawlines, $_); 249 push(@rawlines, $_);
241 } 250 }
242 close(FILE); 251 close($FILE);
243 if (!process($filename)) { 252 if (!process($filename)) {
244 $exit = 1; 253 $exit = 1;
245 } 254 }
@@ -366,7 +375,7 @@ sub sanitise_line {
366 } 375 }
367 } 376 }
368 377
369 #print "SQ:$sanitise_quote\n"; 378 #print "c<$c> SQ<$sanitise_quote>\n";
370 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 379 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
371 substr($res, $off, 1, $;); 380 substr($res, $off, 1, $;);
372 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 381 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
@@ -402,12 +411,15 @@ sub ctx_statement_block {
402 411
403 my $type = ''; 412 my $type = '';
404 my $level = 0; 413 my $level = 0;
414 my @stack = ();
405 my $p; 415 my $p;
406 my $c; 416 my $c;
407 my $len = 0; 417 my $len = 0;
408 418
409 my $remainder; 419 my $remainder;
410 while (1) { 420 while (1) {
421 @stack = (['', 0]) if ($#stack == -1);
422
411 #warn "CSB: blk<$blk> remain<$remain>\n"; 423 #warn "CSB: blk<$blk> remain<$remain>\n";
412 # If we are about to drop off the end, pull in more 424 # If we are about to drop off the end, pull in more
413 # context. 425 # context.
@@ -433,6 +445,16 @@ sub ctx_statement_block {
433 $remainder = substr($blk, $off); 445 $remainder = substr($blk, $off);
434 446
435 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 447 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
448
449 # Handle nested #if/#else.
450 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
451 push(@stack, [ $type, $level ]);
452 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
453 ($type, $level) = @{$stack[$#stack - 1]};
454 } elsif ($remainder =~ /^#\s*endif\b/) {
455 ($type, $level) = @{pop(@stack)};
456 }
457
436 # Statement ends at the ';' or a close '}' at the 458 # Statement ends at the ';' or a close '}' at the
437 # outermost level. 459 # outermost level.
438 if ($level == 0 && $c eq ';') { 460 if ($level == 0 && $c eq ';') {
@@ -579,11 +601,22 @@ sub ctx_block_get {
579 my @res = (); 601 my @res = ();
580 602
581 my $level = 0; 603 my $level = 0;
604 my @stack = ($level);
582 for ($line = $start; $remain > 0; $line++) { 605 for ($line = $start; $remain > 0; $line++) {
583 next if ($rawlines[$line] =~ /^-/); 606 next if ($rawlines[$line] =~ /^-/);
584 $remain--; 607 $remain--;
585 608
586 $blk .= $rawlines[$line]; 609 $blk .= $rawlines[$line];
610
611 # Handle nested #if/#else.
612 if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
613 push(@stack, $level);
614 } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
615 $level = $stack[$#stack - 1];
616 } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) {
617 $level = pop(@stack);
618 }
619
587 foreach my $c (split(//, $rawlines[$line])) { 620 foreach my $c (split(//, $rawlines[$line])) {
588 ##print "C<$c>L<$level><$open$close>O<$off>\n"; 621 ##print "C<$c>L<$level><$open$close>O<$off>\n";
589 if ($off > 0) { 622 if ($off > 0) {
@@ -843,11 +876,11 @@ sub annotate_values {
843 $type = 'V'; 876 $type = 'V';
844 $av_pending = 'V'; 877 $av_pending = 'V';
845 878
846 } elsif ($cur =~ /^($Ident\s*):/) { 879 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
847 if ($type eq 'E') { 880 if (defined $2 && $type eq 'C' || $type eq 'T') {
848 $av_pend_colon = 'L';
849 } elsif ($type eq 'T') {
850 $av_pend_colon = 'B'; 881 $av_pend_colon = 'B';
882 } elsif ($type eq 'E') {
883 $av_pend_colon = 'L';
851 } 884 }
852 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 885 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
853 $type = 'V'; 886 $type = 'V';
@@ -865,6 +898,10 @@ sub annotate_values {
865 $type = 'E'; 898 $type = 'E';
866 $av_pend_colon = 'O'; 899 $av_pend_colon = 'O';
867 900
901 } elsif ($cur =~/^(,)/) {
902 print "COMMA($1)\n" if ($dbg_values > 1);
903 $type = 'C';
904
868 } elsif ($cur =~ /^(\?)/o) { 905 } elsif ($cur =~ /^(\?)/o) {
869 print "QUESTION($1)\n" if ($dbg_values > 1); 906 print "QUESTION($1)\n" if ($dbg_values > 1);
870 $type = 'N'; 907 $type = 'N';
@@ -880,7 +917,7 @@ sub annotate_values {
880 } 917 }
881 $av_pend_colon = 'O'; 918 $av_pend_colon = 'O';
882 919
883 } elsif ($cur =~ /^(;|\[)/o) { 920 } elsif ($cur =~ /^(\[)/o) {
884 print "CLOSE($1)\n" if ($dbg_values > 1); 921 print "CLOSE($1)\n" if ($dbg_values > 1);
885 $type = 'N'; 922 $type = 'N';
886 923
@@ -1051,6 +1088,7 @@ sub process {
1051 my $in_comment = 0; 1088 my $in_comment = 0;
1052 my $comment_edge = 0; 1089 my $comment_edge = 0;
1053 my $first_line = 0; 1090 my $first_line = 0;
1091 my $p1_prefix = '';
1054 1092
1055 my $prev_values = 'E'; 1093 my $prev_values = 'E';
1056 1094
@@ -1097,9 +1135,12 @@ sub process {
1097 $rawlines[$ln - 1] =~ /^-/); 1135 $rawlines[$ln - 1] =~ /^-/);
1098 $cnt--; 1136 $cnt--;
1099 #print "RAW<$rawlines[$ln - 1]>\n"; 1137 #print "RAW<$rawlines[$ln - 1]>\n";
1100 ($edge) = (defined $rawlines[$ln - 1] && 1138 last if (!defined $rawlines[$ln - 1]);
1101 $rawlines[$ln - 1] =~ m@(/\*|\*/)@); 1139 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1102 last if (defined $edge); 1140 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1141 ($edge) = $1;
1142 last;
1143 }
1103 } 1144 }
1104 if (defined $edge && $edge eq '*/') { 1145 if (defined $edge && $edge eq '*/') {
1105 $in_comment = 1; 1146 $in_comment = 1;
@@ -1109,7 +1150,7 @@ sub process {
1109 # is the start of a diff block and this line starts 1150 # is the start of a diff block and this line starts
1110 # ' *' then it is very likely a comment. 1151 # ' *' then it is very likely a comment.
1111 if (!defined $edge && 1152 if (!defined $edge &&
1112 $rawlines[$linenr] =~ m@^.\s* \*(?:\s|$)@) 1153 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1113 { 1154 {
1114 $in_comment = 1; 1155 $in_comment = 1;
1115 } 1156 }
@@ -1196,7 +1237,12 @@ sub process {
1196 # extract the filename as it passes 1237 # extract the filename as it passes
1197 if ($line=~/^\+\+\+\s+(\S+)/) { 1238 if ($line=~/^\+\+\+\s+(\S+)/) {
1198 $realfile = $1; 1239 $realfile = $1;
1199 $realfile =~ s@^[^/]*/@@; 1240 $realfile =~ s@^([^/]*)/@@;
1241
1242 $p1_prefix = $1;
1243 if ($tree && $p1_prefix ne '' && -e "$root/$p1_prefix") {
1244 WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
1245 }
1200 1246
1201 if ($realfile =~ m@^include/asm/@) { 1247 if ($realfile =~ m@^include/asm/@) {
1202 ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 1248 ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
@@ -1336,7 +1382,7 @@ sub process {
1336 } 1382 }
1337 1383
1338 # any (foo ... *) is a pointer cast, and foo is a type 1384 # any (foo ... *) is a pointer cast, and foo is a type
1339 while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/sg) { 1385 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
1340 possible($1, "C:" . $s); 1386 possible($1, "C:" . $s);
1341 } 1387 }
1342 1388
@@ -1594,7 +1640,7 @@ sub process {
1594 $herecurr); 1640 $herecurr);
1595 } 1641 }
1596# check for static initialisers. 1642# check for static initialisers.
1597 if ($line =~ /\s*static\s.*=\s*(0|NULL|false)\s*;/) { 1643 if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
1598 ERROR("do not initialise statics to 0 or NULL\n" . 1644 ERROR("do not initialise statics to 0 or NULL\n" .
1599 $herecurr); 1645 $herecurr);
1600 } 1646 }
@@ -1602,7 +1648,7 @@ sub process {
1602# check for new typedefs, only function parameters and sparse annotations 1648# check for new typedefs, only function parameters and sparse annotations
1603# make sense. 1649# make sense.
1604 if ($line =~ /\btypedef\s/ && 1650 if ($line =~ /\btypedef\s/ &&
1605 $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && 1651 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
1606 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 1652 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
1607 $line !~ /\b$typeTypedefs\b/ && 1653 $line !~ /\b$typeTypedefs\b/ &&
1608 $line !~ /\b__bitwise(?:__|)\b/) { 1654 $line !~ /\b__bitwise(?:__|)\b/) {
@@ -1610,21 +1656,39 @@ sub process {
1610 } 1656 }
1611 1657
1612# * goes on variable not on type 1658# * goes on variable not on type
1613 if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) { 1659 # (char*[ const])
1614 ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" . 1660 if ($line =~ m{\($NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)*)\)}) {
1615 $herecurr); 1661 my ($from, $to) = ($1, $1);
1616 1662
1617 } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) { 1663 # Should start with a space.
1618 ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" . 1664 $to =~ s/^(\S)/ $1/;
1619 $herecurr); 1665 # Should not end with a space.
1666 $to =~ s/\s+$//;
1667 # '*'s should not have spaces between.
1668 while ($to =~ s/\*\s+\*/\*\*/) {
1669 }
1620 1670
1621 } elsif ($line =~ m{\b$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) { 1671 #print "from<$from> to<$to>\n";
1622 ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" . 1672 if ($from ne $to) {
1623 $herecurr); 1673 ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr);
1674 }
1675 } elsif ($line =~ m{\b$NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)?)($Ident)}) {
1676 my ($from, $to, $ident) = ($1, $1, $2);
1624 1677
1625 } elsif ($line =~ m{\b$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) { 1678 # Should start with a space.
1626 ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" . 1679 $to =~ s/^(\S)/ $1/;
1627 $herecurr); 1680 # Should not end with a space.
1681 $to =~ s/\s+$//;
1682 # '*'s should not have spaces between.
1683 while ($to =~ s/\*\s+\*/\*\*/) {
1684 }
1685 # Modifiers should have spaces.
1686 $to =~ s/(\b$Modifier$)/$1 /;
1687
1688 #print "from<$from> to<$to>\n";
1689 if ($from ne $to) {
1690 ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr);
1691 }
1628 } 1692 }
1629 1693
1630# # no BUG() or BUG_ON() 1694# # no BUG() or BUG_ON()
@@ -1759,7 +1823,7 @@ sub process {
1759 $c = 'C' if ($elements[$n + 2] =~ /^$;/); 1823 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
1760 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 1824 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
1761 $c = 'O' if ($elements[$n + 2] eq ''); 1825 $c = 'O' if ($elements[$n + 2] eq '');
1762 $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); 1826 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
1763 } else { 1827 } else {
1764 $c = 'E'; 1828 $c = 'E';
1765 } 1829 }
@@ -1950,9 +2014,13 @@ sub process {
1950 my $spacing = $1; 2014 my $spacing = $1;
1951 my $value = $2; 2015 my $value = $2;
1952 2016
1953 # Flatten any parentheses and braces 2017 # Flatten any parentheses
1954 $value =~ s/\)\(/\) \(/g; 2018 $value =~ s/\)\(/\) \(/g;
1955 while ($value =~ s/\([^\(\)]*\)/1/) { 2019 while ($value =~ s/\[[^\{\}]*\]/1/ ||
2020 $value !~ /(?:$Ident|-?$Constant)\s*
2021 $Compare\s*
2022 (?:$Ident|-?$Constant)/x &&
2023 $value =~ s/\([^\(\)]*\)/1/) {
1956 } 2024 }
1957 2025
1958 if ($value =~ /^(?:$Ident|-?$Constant)$/) { 2026 if ($value =~ /^(?:$Ident|-?$Constant)$/) {
@@ -1992,7 +2060,7 @@ sub process {
1992 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 2060 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
1993 my ($s, $c) = ($stat, $cond); 2061 my ($s, $c) = ($stat, $cond);
1994 2062
1995 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) { 2063 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
1996 ERROR("do not use assignment in if condition\n" . $herecurr); 2064 ERROR("do not use assignment in if condition\n" . $herecurr);
1997 } 2065 }
1998 2066
@@ -2040,6 +2108,11 @@ sub process {
2040 ERROR("trailing statements should be on next line\n" . $herecurr); 2108 ERROR("trailing statements should be on next line\n" . $herecurr);
2041 } 2109 }
2042 } 2110 }
2111# if should not continue a brace
2112 if ($line =~ /}\s*if\b/) {
2113 ERROR("trailing statements should be on next line\n" .
2114 $herecurr);
2115 }
2043# case and default should not have general statements after them 2116# case and default should not have general statements after them
2044 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 2117 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
2045 $line !~ /\G(?: 2118 $line !~ /\G(?:
@@ -2167,9 +2240,10 @@ sub process {
2167 MODULE_PARAM_DESC| 2240 MODULE_PARAM_DESC|
2168 DECLARE_PER_CPU| 2241 DECLARE_PER_CPU|
2169 DEFINE_PER_CPU| 2242 DEFINE_PER_CPU|
2170 __typeof__\( 2243 __typeof__\(|
2244 \.$Ident\s*=\s*
2171 }x; 2245 }x;
2172 #print "REST<$rest>\n"; 2246 #print "REST<$rest> dstat<$dstat>\n";
2173 if ($rest ne '') { 2247 if ($rest ne '') {
2174 if ($rest !~ /while\s*\(/ && 2248 if ($rest !~ /while\s*\(/ &&
2175 $dstat !~ /$exceptions/) 2249 $dstat !~ /$exceptions/)
@@ -2189,6 +2263,15 @@ sub process {
2189 } 2263 }
2190 } 2264 }
2191 2265
2266# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
2267# all assignments may have only one of the following with an assignment:
2268# .
2269# ALIGN(...)
2270# VMLINUX_SYMBOL(...)
2271 if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
2272 WARN("vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
2273 }
2274
2192# check for redundant bracing round if etc 2275# check for redundant bracing round if etc
2193 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 2276 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
2194 my ($level, $endln, @chunks) = 2277 my ($level, $endln, @chunks) =
@@ -2443,6 +2526,12 @@ sub process {
2443 if ($line =~ /^.\s*__initcall\s*\(/) { 2526 if ($line =~ /^.\s*__initcall\s*\(/) {
2444 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr); 2527 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
2445 } 2528 }
2529# check for struct file_operations, ensure they are const.
2530 if ($line !~ /\bconst\b/ &&
2531 $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) {
2532 WARN("struct $1 should normally be const\n" .
2533 $herecurr);
2534 }
2446 2535
2447# use of NR_CPUS is usually wrong 2536# use of NR_CPUS is usually wrong
2448# ignore definitions of NR_CPUS and usage to define arrays as likely right 2537# ignore definitions of NR_CPUS and usage to define arrays as likely right
@@ -2466,6 +2555,15 @@ sub process {
2466 last; 2555 last;
2467 } 2556 }
2468 } 2557 }
2558
2559# whine mightly about in_atomic
2560 if ($line =~ /\bin_atomic\s*\(/) {
2561 if ($realfile =~ m@^drivers/@) {
2562 ERROR("do not use in_atomic in drivers\n" . $herecurr);
2563 } else {
2564 WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
2565 }
2566 }
2469 } 2567 }
2470 2568
2471 # If we have no input at all, then there is nothing to report on 2569 # If we have no input at all, then there is nothing to report on
diff --git a/scripts/config b/scripts/config
new file mode 100755
index 000000000000..68b9761cdc38
--- /dev/null
+++ b/scripts/config
@@ -0,0 +1,150 @@
1#!/bin/bash
2# Manipulate options in a .config file from the command line
3
4usage() {
5 cat >&2 <<EOL
6Manipulate options in a .config file from the command line.
7Usage:
8config options command ...
9commands:
10 --enable|-e option Enable option
11 --disable|-d option Disable option
12 --module|-m option Turn option into a module
13 --state|-s option Print state of option (n,y,m,undef)
14
15 --enable-after|-E beforeopt option
16 Enable option directly after other option
17 --disable-after|-D beforeopt option
18 Disable option directly after other option
19 --module-after|-M beforeopt option
20 Turn option into module directly after other option
21
22 commands can be repeated multiple times
23
24options:
25 --file .config file to change (default .config)
26
27config doesn't check the validity of the .config file. This is done at next
28 make time.
29The options need to be already in the file before they can be changed,
30but sometimes you can cheat with the --*-after options.
31EOL
32 exit 1
33}
34
35checkarg() {
36 ARG="$1"
37 if [ "$ARG" = "" ] ; then
38 usage
39 fi
40 case "$ARG" in
41 CONFIG_*)
42 ARG="${ARG/CONFIG_/}"
43 ;;
44 esac
45 ARG="`echo $ARG | tr a-z A-Z`"
46}
47
48replace() {
49 sed -i -e "$@" $FN
50}
51
52if [ "$1" = "--file" ]; then
53 FN="$2"
54 if [ "$FN" = "" ] ; then
55 usage
56 fi
57 shift
58 shift
59else
60 FN=.config
61fi
62
63while [ "$1" != "" ] ; do
64 CMD="$1"
65 shift
66 case "$CMD" in
67 --enable|-e)
68 checkarg "$1"
69 replace "s/# CONFIG_$ARG is not set/CONFIG_$ARG=y/"
70 shift
71 ;;
72
73 --disable|-d)
74 checkarg "$1"
75 replace "s/CONFIG_$ARG=[my]/# CONFIG_$ARG is not set/"
76 shift
77 ;;
78
79 --module|-m)
80 checkarg "$1"
81 replace "s/CONFIG_$ARG=y/CONFIG_$ARG=m/" \
82 -e "s/# CONFIG_$ARG is not set/CONFIG_$ARG=m/"
83 shift
84 ;;
85
86 --state|-s)
87 checkarg "$1"
88 if grep -q "# CONFIG_$ARG is not set" $FN ; then
89 echo n
90 else
91 V="$(grep "^CONFIG_$ARG=" $FN)"
92 if [ $? != 0 ] ; then
93 echo undef
94 else
95 V="${V/CONFIG_$ARG=/}"
96 V="${V/\"/}"
97 echo "$V"
98 fi
99 fi
100 shift
101 ;;
102
103 --enable-after|-E)
104 checkarg "$1"
105 A=$ARG
106 checkarg "$2"
107 B=$ARG
108 replace "/CONFIG_$A=[my]/aCONFIG_$B=y" \
109 -e "/# CONFIG_$ARG is not set/a/CONFIG_$ARG=y" \
110 -e "s/# CONFIG_$ARG is not set/CONFIG_$ARG=y/"
111 shift
112 shift
113 ;;
114
115 --disable-after|-D)
116 checkarg "$1"
117 A=$ARG
118 checkarg "$2"
119 B=$ARG
120 replace "/CONFIG_$A=[my]/a# CONFIG_$B is not set" \
121 -e "/# CONFIG_$ARG is not set/a/# CONFIG_$ARG is not set" \
122 -e "s/CONFIG_$ARG=[my]/# CONFIG_$ARG is not set/"
123 shift
124 shift
125 ;;
126
127 --module-after|-M)
128 checkarg "$1"
129 A=$ARG
130 checkarg "$2"
131 B=$ARG
132 replace "/CONFIG_$A=[my]/aCONFIG_$B=m" \
133 -e "/# CONFIG_$ARG is not set/a/CONFIG_$ARG=m" \
134 -e "s/CONFIG_$ARG=y/CONFIG_$ARG=m/" \
135 -e "s/# CONFIG_$ARG is not set/CONFIG_$ARG=m/"
136 shift
137 shift
138 ;;
139
140 # undocumented because it ignores --file (fixme)
141 --refresh)
142 yes "" | make oldconfig
143 ;;
144
145 *)
146 usage
147 ;;
148 esac
149done
150
diff --git a/scripts/decodecode b/scripts/decodecode
index 235d3938529d..4b00647814bc 100755
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -7,7 +7,7 @@
7# AFLAGS=--32 decodecode < 386.oops 7# AFLAGS=--32 decodecode < 386.oops
8 8
9cleanup() { 9cleanup() {
10 rm -f $T $T.s $T.o 10 rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa
11 exit 1 11 exit 1
12} 12}
13 13
@@ -44,21 +44,33 @@ if [ $marker -eq 0 ]; then
44 marker=`expr index "$code" "\("` 44 marker=`expr index "$code" "\("`
45fi 45fi
46 46
47touch $T.oo
47if [ $marker -ne 0 ]; then 48if [ $marker -ne 0 ]; then
48 beforemark=`echo "$code" | cut -c-$((${marker} - 1))` 49 echo All code >> $T.oo
50 echo ======== >> $T.oo
51 beforemark=`echo "$code"`
49 echo -n " .byte 0x" > $T.s 52 echo -n " .byte 0x" > $T.s
50 echo $beforemark | sed -e 's/ /,0x/g' >> $T.s 53 echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s
51 as $AFLAGS -o $T.o $T.s 54 as $AFLAGS -o $T.o $T.s &> /dev/null
52 objdump -S $T.o 55 objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo
53 rm $T.o $T.s 56 cat $T.ooo >> $T.oo
57 rm -f $T.o $T.s $T.ooo
54 58
55# and fix code at-and-after marker 59# and fix code at-and-after marker
56 code=`echo "$code" | cut -c$((${marker} + 1))-` 60 code=`echo "$code" | cut -c$((${marker} + 1))-`
57fi 61fi
58 62echo Code starting with the faulting instruction > $T.aa
63echo =========================================== >> $T.aa
59code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'` 64code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'`
60echo -n " .byte 0x" > $T.s 65echo -n " .byte 0x" > $T.s
61echo $code >> $T.s 66echo $code >> $T.s
62as $AFLAGS -o $T.o $T.s 67as $AFLAGS -o $T.o $T.s &> /dev/null
63objdump -S $T.o 68objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa
64rm $T $T.s $T.o 69cat $T.aaa >> $T.aa
70
71faultline=`cat $T.aaa | head -1 | cut -d":" -f2`
72
73cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g"
74echo
75cat $T.aa
76cleanup
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig
index 8187e6f0dc2f..72997c353cb3 100755
--- a/scripts/extract-ikconfig
+++ b/scripts/extract-ikconfig
@@ -8,8 +8,8 @@ test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1
8 8
9IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54" 9IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"
10IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" 10IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"
11function dump_config { 11dump_config() {
12 typeset file="$1" 12 file="$1"
13 13
14 start=`$binoffset $file $IKCFG_ST 2>/dev/null` 14 start=`$binoffset $file $IKCFG_ST 2>/dev/null`
15 [ "$?" != "0" ] && start="-1" 15 [ "$?" != "0" ] && start="-1"
@@ -18,8 +18,8 @@ function dump_config {
18 fi 18 fi
19 end=`$binoffset $file $IKCFG_ED 2>/dev/null` 19 end=`$binoffset $file $IKCFG_ED 2>/dev/null`
20 20
21 let start="$start + 8" 21 start=`expr $start + 8`
22 let size="$end - $start" 22 size=`expr $end - $start`
23 23
24 dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat 24 dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat
25 25
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index c249274e005a..f8bb4cabd62d 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -42,7 +42,8 @@ static FILE *debugfile;
42int cur_line = 1; 42int cur_line = 1;
43char *cur_filename; 43char *cur_filename;
44 44
45static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings; 45static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
46 flag_preserve, flag_warnings, flag_asm;
46static const char *arch = ""; 47static const char *arch = "";
47static const char *mod_prefix = ""; 48static const char *mod_prefix = "";
48 49
@@ -58,6 +59,8 @@ static const char *const symbol_type_name[] = {
58 59
59static int equal_list(struct string_list *a, struct string_list *b); 60static int equal_list(struct string_list *a, struct string_list *b);
60static void print_list(FILE * f, struct string_list *list); 61static void print_list(FILE * f, struct string_list *list);
62static void print_location(void);
63static void print_type_name(enum symbol_type type, const char *name);
61 64
62/*----------------------------------------------------------------------*/ 65/*----------------------------------------------------------------------*/
63 66
@@ -151,27 +154,83 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns)
151 154
152 for (sym = symtab[h]; sym; sym = sym->hash_next) 155 for (sym = symtab[h]; sym; sym = sym->hash_next)
153 if (map_to_ns(sym->type) == map_to_ns(ns) && 156 if (map_to_ns(sym->type) == map_to_ns(ns) &&
154 strcmp(name, sym->name) == 0) 157 strcmp(name, sym->name) == 0 &&
158 sym->is_declared)
155 break; 159 break;
156 160
157 return sym; 161 return sym;
158} 162}
159 163
160struct symbol *add_symbol(const char *name, enum symbol_type type, 164static int is_unknown_symbol(struct symbol *sym)
161 struct string_list *defn, int is_extern) 165{
166 struct string_list *defn;
167
168 return ((sym->type == SYM_STRUCT ||
169 sym->type == SYM_UNION ||
170 sym->type == SYM_ENUM) &&
171 (defn = sym->defn) && defn->tag == SYM_NORMAL &&
172 strcmp(defn->string, "}") == 0 &&
173 (defn = defn->next) && defn->tag == SYM_NORMAL &&
174 strcmp(defn->string, "UNKNOWN") == 0 &&
175 (defn = defn->next) && defn->tag == SYM_NORMAL &&
176 strcmp(defn->string, "{") == 0);
177}
178
179struct symbol *__add_symbol(const char *name, enum symbol_type type,
180 struct string_list *defn, int is_extern,
181 int is_reference)
162{ 182{
163 unsigned long h = crc32(name) % HASH_BUCKETS; 183 unsigned long h = crc32(name) % HASH_BUCKETS;
164 struct symbol *sym; 184 struct symbol *sym;
185 enum symbol_status status = STATUS_UNCHANGED;
165 186
166 for (sym = symtab[h]; sym; sym = sym->hash_next) { 187 for (sym = symtab[h]; sym; sym = sym->hash_next) {
167 if (map_to_ns(sym->type) == map_to_ns(type) 188 if (map_to_ns(sym->type) == map_to_ns(type) &&
168 && strcmp(name, sym->name) == 0) { 189 strcmp(name, sym->name) == 0) {
169 if (!equal_list(sym->defn, defn)) 190 if (is_reference)
191 /* fall through */ ;
192 else if (sym->type == type &&
193 equal_list(sym->defn, defn)) {
194 if (!sym->is_declared && sym->is_override) {
195 print_location();
196 print_type_name(type, name);
197 fprintf(stderr, " modversion is "
198 "unchanged\n");
199 }
200 sym->is_declared = 1;
201 return sym;
202 } else if (!sym->is_declared) {
203 if (sym->is_override && flag_preserve) {
204 print_location();
205 fprintf(stderr, "ignoring ");
206 print_type_name(type, name);
207 fprintf(stderr, " modversion change\n");
208 sym->is_declared = 1;
209 return sym;
210 } else {
211 status = is_unknown_symbol(sym) ?
212 STATUS_DEFINED : STATUS_MODIFIED;
213 }
214 } else {
170 error_with_pos("redefinition of %s", name); 215 error_with_pos("redefinition of %s", name);
171 return sym; 216 return sym;
217 }
218 break;
172 } 219 }
173 } 220 }
174 221
222 if (sym) {
223 struct symbol **psym;
224
225 for (psym = &symtab[h]; *psym; psym = &(*psym)->hash_next) {
226 if (*psym == sym) {
227 *psym = sym->hash_next;
228 break;
229 }
230 }
231 --nsyms;
232 }
233
175 sym = xmalloc(sizeof(*sym)); 234 sym = xmalloc(sizeof(*sym));
176 sym->name = name; 235 sym->name = name;
177 sym->type = type; 236 sym->type = type;
@@ -183,6 +242,10 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
183 sym->hash_next = symtab[h]; 242 sym->hash_next = symtab[h];
184 symtab[h] = sym; 243 symtab[h] = sym;
185 244
245 sym->is_declared = !is_reference;
246 sym->status = status;
247 sym->is_override = 0;
248
186 if (flag_debug) { 249 if (flag_debug) {
187 fprintf(debugfile, "Defn for %s %s == <", 250 fprintf(debugfile, "Defn for %s %s == <",
188 symbol_type_name[type], name); 251 symbol_type_name[type], name);
@@ -196,6 +259,18 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
196 return sym; 259 return sym;
197} 260}
198 261
262struct symbol *add_symbol(const char *name, enum symbol_type type,
263 struct string_list *defn, int is_extern)
264{
265 return __add_symbol(name, type, defn, is_extern, 0);
266}
267
268struct symbol *add_reference_symbol(const char *name, enum symbol_type type,
269 struct string_list *defn, int is_extern)
270{
271 return __add_symbol(name, type, defn, is_extern, 1);
272}
273
199/*----------------------------------------------------------------------*/ 274/*----------------------------------------------------------------------*/
200 275
201void free_node(struct string_list *node) 276void free_node(struct string_list *node)
@@ -236,6 +311,90 @@ static int equal_list(struct string_list *a, struct string_list *b)
236 return !a && !b; 311 return !a && !b;
237} 312}
238 313
314#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
315
316struct string_list *read_node(FILE *f)
317{
318 char buffer[256];
319 struct string_list node = {
320 .string = buffer,
321 .tag = SYM_NORMAL };
322 int c;
323
324 while ((c = fgetc(f)) != EOF) {
325 if (c == ' ') {
326 if (node.string == buffer)
327 continue;
328 break;
329 } else if (c == '\n') {
330 if (node.string == buffer)
331 return NULL;
332 ungetc(c, f);
333 break;
334 }
335 if (node.string >= buffer + sizeof(buffer) - 1) {
336 fprintf(stderr, "Token too long\n");
337 exit(1);
338 }
339 *node.string++ = c;
340 }
341 if (node.string == buffer)
342 return NULL;
343 *node.string = 0;
344 node.string = buffer;
345
346 if (node.string[1] == '#') {
347 int n;
348
349 for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) {
350 if (node.string[0] == symbol_type_name[n][0]) {
351 node.tag = n;
352 node.string += 2;
353 return copy_node(&node);
354 }
355 }
356 fprintf(stderr, "Unknown type %c\n", node.string[0]);
357 exit(1);
358 }
359 return copy_node(&node);
360}
361
362static void read_reference(FILE *f)
363{
364 while (!feof(f)) {
365 struct string_list *defn = NULL;
366 struct string_list *sym, *def;
367 int is_extern = 0, is_override = 0;
368 struct symbol *subsym;
369
370 sym = read_node(f);
371 if (sym && sym->tag == SYM_NORMAL &&
372 !strcmp(sym->string, "override")) {
373 is_override = 1;
374 free_node(sym);
375 sym = read_node(f);
376 }
377 if (!sym)
378 continue;
379 def = read_node(f);
380 if (def && def->tag == SYM_NORMAL &&
381 !strcmp(def->string, "extern")) {
382 is_extern = 1;
383 free_node(def);
384 def = read_node(f);
385 }
386 while (def) {
387 def->next = defn;
388 defn = def;
389 def = read_node(f);
390 }
391 subsym = add_reference_symbol(xstrdup(sym->string), sym->tag,
392 defn, is_extern);
393 subsym->is_override = is_override;
394 free_node(sym);
395 }
396}
397
239static void print_node(FILE * f, struct string_list *list) 398static void print_node(FILE * f, struct string_list *list)
240{ 399{
241 if (list->tag != SYM_NORMAL) { 400 if (list->tag != SYM_NORMAL) {
@@ -311,6 +470,7 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
311 470
312 case SYM_TYPEDEF: 471 case SYM_TYPEDEF:
313 subsym = find_symbol(cur->string, cur->tag); 472 subsym = find_symbol(cur->string, cur->tag);
473 /* FIXME: Bad reference files can segfault here. */
314 if (subsym->expansion_trail) { 474 if (subsym->expansion_trail) {
315 if (flag_dump_defs) 475 if (flag_dump_defs)
316 fprintf(debugfile, "%s ", cur->string); 476 fprintf(debugfile, "%s ", cur->string);
@@ -347,9 +507,22 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
347 t = n; 507 t = n;
348 508
349 n = xmalloc(sizeof(*n)); 509 n = xmalloc(sizeof(*n));
350 n->string = xstrdup("{ UNKNOWN }"); 510 n->string = xstrdup("{");
511 n->tag = SYM_NORMAL;
512 n->next = t;
513 t = n;
514
515 n = xmalloc(sizeof(*n));
516 n->string = xstrdup("UNKNOWN");
517 n->tag = SYM_NORMAL;
518 n->next = t;
519 t = n;
520
521 n = xmalloc(sizeof(*n));
522 n->string = xstrdup("}");
351 n->tag = SYM_NORMAL; 523 n->tag = SYM_NORMAL;
352 n->next = t; 524 n->next = t;
525 t = n;
353 526
354 subsym = 527 subsym =
355 add_symbol(cur->string, cur->tag, n, 0); 528 add_symbol(cur->string, cur->tag, n, 0);
@@ -397,37 +570,75 @@ void export_symbol(const char *name)
397 error_with_pos("export undefined symbol %s", name); 570 error_with_pos("export undefined symbol %s", name);
398 else { 571 else {
399 unsigned long crc; 572 unsigned long crc;
573 int has_changed = 0;
400 574
401 if (flag_dump_defs) 575 if (flag_dump_defs)
402 fprintf(debugfile, "Export %s == <", name); 576 fprintf(debugfile, "Export %s == <", name);
403 577
404 expansion_trail = (struct symbol *)-1L; 578 expansion_trail = (struct symbol *)-1L;
405 579
580 sym->expansion_trail = expansion_trail;
581 expansion_trail = sym;
406 crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; 582 crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
407 583
408 sym = expansion_trail; 584 sym = expansion_trail;
409 while (sym != (struct symbol *)-1L) { 585 while (sym != (struct symbol *)-1L) {
410 struct symbol *n = sym->expansion_trail; 586 struct symbol *n = sym->expansion_trail;
587
588 if (sym->status != STATUS_UNCHANGED) {
589 if (!has_changed) {
590 print_location();
591 fprintf(stderr, "%s: %s: modversion "
592 "changed because of changes "
593 "in ", flag_preserve ? "error" :
594 "warning", name);
595 } else
596 fprintf(stderr, ", ");
597 print_type_name(sym->type, sym->name);
598 if (sym->status == STATUS_DEFINED)
599 fprintf(stderr, " (became defined)");
600 has_changed = 1;
601 if (flag_preserve)
602 errors++;
603 }
411 sym->expansion_trail = 0; 604 sym->expansion_trail = 0;
412 sym = n; 605 sym = n;
413 } 606 }
607 if (has_changed)
608 fprintf(stderr, "\n");
414 609
415 if (flag_dump_defs) 610 if (flag_dump_defs)
416 fputs(">\n", debugfile); 611 fputs(">\n", debugfile);
417 612
418 /* Used as a linker script. */ 613 /* Used as assembly source or a linker script. */
419 printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); 614 printf(flag_asm
615 ? ".equiv %s__crc_%s, %#08lx\n"
616 : "%s__crc_%s = %#08lx ;\n",
617 mod_prefix, name, crc);
420 } 618 }
421} 619}
422 620
423/*----------------------------------------------------------------------*/ 621/*----------------------------------------------------------------------*/
622
623static void print_location(void)
624{
625 fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
626}
627
628static void print_type_name(enum symbol_type type, const char *name)
629{
630 if (type != SYM_NORMAL)
631 fprintf(stderr, "%s %s", symbol_type_name[type], name);
632 else
633 fprintf(stderr, "%s", name);
634}
635
424void error_with_pos(const char *fmt, ...) 636void error_with_pos(const char *fmt, ...)
425{ 637{
426 va_list args; 638 va_list args;
427 639
428 if (flag_warnings) { 640 if (flag_warnings) {
429 fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", 641 print_location();
430 cur_line);
431 642
432 va_start(args, fmt); 643 va_start(args, fmt);
433 vfprintf(stderr, fmt, args); 644 vfprintf(stderr, fmt, args);
@@ -440,21 +651,27 @@ void error_with_pos(const char *fmt, ...)
440 651
441static void genksyms_usage(void) 652static void genksyms_usage(void)
442{ 653{
443 fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" 654 fputs("Usage:\n" "genksyms [-aAdDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
444#ifdef __GNU_LIBRARY__ 655#ifdef __GNU_LIBRARY__
445 " -a, --arch Select architecture\n" 656 " -a, --arch Select architecture\n"
657 " -A, --asm Generate assembly rather than linker script\n"
446 " -d, --debug Increment the debug level (repeatable)\n" 658 " -d, --debug Increment the debug level (repeatable)\n"
447 " -D, --dump Dump expanded symbol defs (for debugging only)\n" 659 " -D, --dump Dump expanded symbol defs (for debugging only)\n"
448 " -T, --dump-types file Dump expanded types into file (for debugging only)\n" 660 " -r, --reference file Read reference symbols from a file\n"
661 " -T, --dump-types file Dump expanded types into file\n"
662 " -p, --preserve Preserve reference modversions or fail\n"
449 " -w, --warnings Enable warnings\n" 663 " -w, --warnings Enable warnings\n"
450 " -q, --quiet Disable warnings (default)\n" 664 " -q, --quiet Disable warnings (default)\n"
451 " -h, --help Print this message\n" 665 " -h, --help Print this message\n"
452 " -V, --version Print the release version\n" 666 " -V, --version Print the release version\n"
453#else /* __GNU_LIBRARY__ */ 667#else /* __GNU_LIBRARY__ */
454 " -a Select architecture\n" 668 " -a Select architecture\n"
669 " -A Generate assembly rather than linker script\n"
455 " -d Increment the debug level (repeatable)\n" 670 " -d Increment the debug level (repeatable)\n"
456 " -D Dump expanded symbol defs (for debugging only)\n" 671 " -D Dump expanded symbol defs (for debugging only)\n"
457 " -T file Dump expanded types into file (for debugging only)\n" 672 " -r file Read reference symbols from a file\n"
673 " -T file Dump expanded types into file\n"
674 " -p Preserve reference modversions or fail\n"
458 " -w Enable warnings\n" 675 " -w Enable warnings\n"
459 " -q Disable warnings (default)\n" 676 " -q Disable warnings (default)\n"
460 " -h Print this message\n" 677 " -h Print this message\n"
@@ -465,26 +682,29 @@ static void genksyms_usage(void)
465 682
466int main(int argc, char **argv) 683int main(int argc, char **argv)
467{ 684{
468 FILE *dumpfile = NULL; 685 FILE *dumpfile = NULL, *ref_file = NULL;
469 int o; 686 int o;
470 687
471#ifdef __GNU_LIBRARY__ 688#ifdef __GNU_LIBRARY__
472 struct option long_opts[] = { 689 struct option long_opts[] = {
473 {"arch", 1, 0, 'a'}, 690 {"arch", 1, 0, 'a'},
691 {"asm", 0, 0, 'A'},
474 {"debug", 0, 0, 'd'}, 692 {"debug", 0, 0, 'd'},
475 {"warnings", 0, 0, 'w'}, 693 {"warnings", 0, 0, 'w'},
476 {"quiet", 0, 0, 'q'}, 694 {"quiet", 0, 0, 'q'},
477 {"dump", 0, 0, 'D'}, 695 {"dump", 0, 0, 'D'},
696 {"reference", 1, 0, 'r'},
478 {"dump-types", 1, 0, 'T'}, 697 {"dump-types", 1, 0, 'T'},
698 {"preserve", 0, 0, 'p'},
479 {"version", 0, 0, 'V'}, 699 {"version", 0, 0, 'V'},
480 {"help", 0, 0, 'h'}, 700 {"help", 0, 0, 'h'},
481 {0, 0, 0, 0} 701 {0, 0, 0, 0}
482 }; 702 };
483 703
484 while ((o = getopt_long(argc, argv, "a:dwqVDT:h", 704 while ((o = getopt_long(argc, argv, "a:dwqVADr:T:ph",
485 &long_opts[0], NULL)) != EOF) 705 &long_opts[0], NULL)) != EOF)
486#else /* __GNU_LIBRARY__ */ 706#else /* __GNU_LIBRARY__ */
487 while ((o = getopt(argc, argv, "a:dwqVDT:h")) != EOF) 707 while ((o = getopt(argc, argv, "a:dwqVADr:T:ph")) != EOF)
488#endif /* __GNU_LIBRARY__ */ 708#endif /* __GNU_LIBRARY__ */
489 switch (o) { 709 switch (o) {
490 case 'a': 710 case 'a':
@@ -502,9 +722,20 @@ int main(int argc, char **argv)
502 case 'V': 722 case 'V':
503 fputs("genksyms version 2.5.60\n", stderr); 723 fputs("genksyms version 2.5.60\n", stderr);
504 break; 724 break;
725 case 'A':
726 flag_asm = 1;
727 break;
505 case 'D': 728 case 'D':
506 flag_dump_defs = 1; 729 flag_dump_defs = 1;
507 break; 730 break;
731 case 'r':
732 flag_reference = 1;
733 ref_file = fopen(optarg, "r");
734 if (!ref_file) {
735 perror(optarg);
736 return 1;
737 }
738 break;
508 case 'T': 739 case 'T':
509 flag_dump_types = 1; 740 flag_dump_types = 1;
510 dumpfile = fopen(optarg, "w"); 741 dumpfile = fopen(optarg, "w");
@@ -513,6 +744,9 @@ int main(int argc, char **argv)
513 return 1; 744 return 1;
514 } 745 }
515 break; 746 break;
747 case 'p':
748 flag_preserve = 1;
749 break;
516 case 'h': 750 case 'h':
517 genksyms_usage(); 751 genksyms_usage();
518 return 0; 752 return 0;
@@ -533,12 +767,17 @@ int main(int argc, char **argv)
533 /* setlinebuf(debugfile); */ 767 /* setlinebuf(debugfile); */
534 } 768 }
535 769
770 if (flag_reference)
771 read_reference(ref_file);
772
536 yyparse(); 773 yyparse();
537 774
538 if (flag_dump_types && visited_symbols) { 775 if (flag_dump_types && visited_symbols) {
539 while (visited_symbols != (struct symbol *)-1L) { 776 while (visited_symbols != (struct symbol *)-1L) {
540 struct symbol *sym = visited_symbols; 777 struct symbol *sym = visited_symbols;
541 778
779 if (sym->is_override)
780 fputs("override ", dumpfile);
542 if (sym->type != SYM_NORMAL) { 781 if (sym->type != SYM_NORMAL) {
543 putc(symbol_type_name[sym->type][0], dumpfile); 782 putc(symbol_type_name[sym->type][0], dumpfile);
544 putc('#', dumpfile); 783 putc('#', dumpfile);
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h
index 2668287aa498..25c4d40cefc1 100644
--- a/scripts/genksyms/genksyms.h
+++ b/scripts/genksyms/genksyms.h
@@ -29,6 +29,10 @@ enum symbol_type {
29 SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION 29 SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
30}; 30};
31 31
32enum symbol_status {
33 STATUS_UNCHANGED, STATUS_DEFINED, STATUS_MODIFIED
34};
35
32struct string_list { 36struct string_list {
33 struct string_list *next; 37 struct string_list *next;
34 enum symbol_type tag; 38 enum symbol_type tag;
@@ -43,6 +47,9 @@ struct symbol {
43 struct symbol *expansion_trail; 47 struct symbol *expansion_trail;
44 struct symbol *visited; 48 struct symbol *visited;
45 int is_extern; 49 int is_extern;
50 int is_declared;
51 enum symbol_status status;
52 int is_override;
46}; 53};
47 54
48typedef struct string_list **yystype; 55typedef struct string_list **yystype;
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index 971e0113ae7a..83484fe93ede 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -1,4 +1,4 @@
1/* ANSI-C code produced by gperf version 3.0.2 */ 1/* ANSI-C code produced by gperf version 3.0.1 */
2/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ 2/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */
3 3
4#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 4#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -32,7 +32,7 @@
32 32
33#line 3 "scripts/genksyms/keywords.gperf" 33#line 3 "scripts/genksyms/keywords.gperf"
34struct resword { const char *name; int token; }; 34struct resword { const char *name; int token; };
35/* maximum key range = 62, duplicates = 0 */ 35/* maximum key range = 64, duplicates = 0 */
36 36
37#ifdef __GNUC__ 37#ifdef __GNUC__
38__inline 38__inline
@@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len)
46{ 46{
47 static const unsigned char asso_values[] = 47 static const unsigned char asso_values[] =
48 { 48 {
49 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 49 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
50 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 50 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
51 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 51 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
52 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 52 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
53 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 53 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
54 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 54 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
55 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, 55 67, 67, 67, 67, 67, 67, 67, 67, 67, 0,
56 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, 56 67, 67, 67, 67, 67, 67, 15, 67, 67, 67,
57 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, 57 0, 67, 67, 67, 67, 67, 67, 67, 67, 67,
58 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, 58 67, 67, 67, 67, 67, 0, 67, 0, 67, 5,
59 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, 59 25, 20, 15, 30, 67, 15, 67, 67, 10, 0,
60 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, 60 10, 40, 20, 67, 10, 5, 0, 10, 15, 67,
61 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
62 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 62 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
63 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 63 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
64 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 64 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
66 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
67 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
68 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 68 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
69 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 69 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
70 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
71 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 71 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
72 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 72 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
73 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 73 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
74 65, 65, 65, 65, 65, 65 74 67, 67, 67, 67, 67, 67
75 }; 75 };
76 return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; 76 return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
77} 77}
@@ -84,116 +84,119 @@ is_reserved_word (register const char *str, register unsigned int len)
84{ 84{
85 enum 85 enum
86 { 86 {
87 TOTAL_KEYWORDS = 43, 87 TOTAL_KEYWORDS = 45,
88 MIN_WORD_LENGTH = 3, 88 MIN_WORD_LENGTH = 3,
89 MAX_WORD_LENGTH = 24, 89 MAX_WORD_LENGTH = 24,
90 MIN_HASH_VALUE = 3, 90 MIN_HASH_VALUE = 3,
91 MAX_HASH_VALUE = 64 91 MAX_HASH_VALUE = 66
92 }; 92 };
93 93
94 static const struct resword wordlist[] = 94 static const struct resword wordlist[] =
95 { 95 {
96 {""}, {""}, {""}, 96 {""}, {""}, {""},
97#line 26 "scripts/genksyms/keywords.gperf" 97#line 28 "scripts/genksyms/keywords.gperf"
98 {"asm", ASM_KEYW}, 98 {"asm", ASM_KEYW},
99 {""}, 99 {""},
100#line 8 "scripts/genksyms/keywords.gperf" 100#line 10 "scripts/genksyms/keywords.gperf"
101 {"__asm", ASM_KEYW}, 101 {"__asm", ASM_KEYW},
102 {""}, 102 {""},
103#line 9 "scripts/genksyms/keywords.gperf" 103#line 11 "scripts/genksyms/keywords.gperf"
104 {"__asm__", ASM_KEYW}, 104 {"__asm__", ASM_KEYW},
105 {""}, {""}, 105 {""}, {""},
106#line 52 "scripts/genksyms/keywords.gperf" 106#line 54 "scripts/genksyms/keywords.gperf"
107 {"__typeof__", TYPEOF_KEYW}, 107 {"__typeof__", TYPEOF_KEYW},
108 {""}, 108 {""},
109#line 12 "scripts/genksyms/keywords.gperf" 109#line 14 "scripts/genksyms/keywords.gperf"
110 {"__const", CONST_KEYW}, 110 {"__const", CONST_KEYW},
111#line 11 "scripts/genksyms/keywords.gperf"
112 {"__attribute__", ATTRIBUTE_KEYW},
113#line 13 "scripts/genksyms/keywords.gperf" 111#line 13 "scripts/genksyms/keywords.gperf"
112 {"__attribute__", ATTRIBUTE_KEYW},
113#line 15 "scripts/genksyms/keywords.gperf"
114 {"__const__", CONST_KEYW}, 114 {"__const__", CONST_KEYW},
115#line 18 "scripts/genksyms/keywords.gperf" 115#line 20 "scripts/genksyms/keywords.gperf"
116 {"__signed__", SIGNED_KEYW}, 116 {"__signed__", SIGNED_KEYW},
117#line 44 "scripts/genksyms/keywords.gperf" 117#line 46 "scripts/genksyms/keywords.gperf"
118 {"static", STATIC_KEYW}, 118 {"static", STATIC_KEYW},
119#line 20 "scripts/genksyms/keywords.gperf" 119 {""},
120 {"__volatile__", VOLATILE_KEYW}, 120#line 41 "scripts/genksyms/keywords.gperf"
121#line 39 "scripts/genksyms/keywords.gperf"
122 {"int", INT_KEYW}, 121 {"int", INT_KEYW},
123#line 32 "scripts/genksyms/keywords.gperf" 122#line 34 "scripts/genksyms/keywords.gperf"
124 {"char", CHAR_KEYW}, 123 {"char", CHAR_KEYW},
125#line 33 "scripts/genksyms/keywords.gperf" 124#line 35 "scripts/genksyms/keywords.gperf"
126 {"const", CONST_KEYW}, 125 {"const", CONST_KEYW},
127#line 45 "scripts/genksyms/keywords.gperf" 126#line 47 "scripts/genksyms/keywords.gperf"
128 {"struct", STRUCT_KEYW}, 127 {"struct", STRUCT_KEYW},
129#line 24 "scripts/genksyms/keywords.gperf" 128#line 26 "scripts/genksyms/keywords.gperf"
130 {"__restrict__", RESTRICT_KEYW}, 129 {"__restrict__", RESTRICT_KEYW},
131#line 25 "scripts/genksyms/keywords.gperf" 130#line 27 "scripts/genksyms/keywords.gperf"
132 {"restrict", RESTRICT_KEYW}, 131 {"restrict", RESTRICT_KEYW},
133#line 23 "scripts/genksyms/keywords.gperf" 132#line 7 "scripts/genksyms/keywords.gperf"
134 {"_restrict", RESTRICT_KEYW}, 133 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
135#line 16 "scripts/genksyms/keywords.gperf" 134#line 18 "scripts/genksyms/keywords.gperf"
136 {"__inline__", INLINE_KEYW}, 135 {"__inline__", INLINE_KEYW},
137#line 10 "scripts/genksyms/keywords.gperf"
138 {"__attribute", ATTRIBUTE_KEYW},
139 {""}, 136 {""},
140#line 14 "scripts/genksyms/keywords.gperf" 137#line 22 "scripts/genksyms/keywords.gperf"
138 {"__volatile__", VOLATILE_KEYW},
139#line 5 "scripts/genksyms/keywords.gperf"
140 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
141#line 25 "scripts/genksyms/keywords.gperf"
142 {"_restrict", RESTRICT_KEYW},
143 {""},
144#line 12 "scripts/genksyms/keywords.gperf"
145 {"__attribute", ATTRIBUTE_KEYW},
146#line 6 "scripts/genksyms/keywords.gperf"
147 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
148#line 16 "scripts/genksyms/keywords.gperf"
141 {"__extension__", EXTENSION_KEYW}, 149 {"__extension__", EXTENSION_KEYW},
142#line 35 "scripts/genksyms/keywords.gperf" 150#line 37 "scripts/genksyms/keywords.gperf"
143 {"enum", ENUM_KEYW}, 151 {"enum", ENUM_KEYW},
144#line 19 "scripts/genksyms/keywords.gperf" 152#line 8 "scripts/genksyms/keywords.gperf"
145 {"__volatile", VOLATILE_KEYW}, 153 {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW},
146#line 36 "scripts/genksyms/keywords.gperf" 154#line 38 "scripts/genksyms/keywords.gperf"
147 {"extern", EXTERN_KEYW}, 155 {"extern", EXTERN_KEYW},
148 {""}, 156 {""},
149#line 17 "scripts/genksyms/keywords.gperf" 157#line 19 "scripts/genksyms/keywords.gperf"
150 {"__signed", SIGNED_KEYW}, 158 {"__signed", SIGNED_KEYW},
151#line 7 "scripts/genksyms/keywords.gperf" 159#line 9 "scripts/genksyms/keywords.gperf"
152 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, 160 {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
153 {""}, 161#line 49 "scripts/genksyms/keywords.gperf"
154#line 51 "scripts/genksyms/keywords.gperf" 162 {"union", UNION_KEYW},
163#line 53 "scripts/genksyms/keywords.gperf"
155 {"typeof", TYPEOF_KEYW}, 164 {"typeof", TYPEOF_KEYW},
156#line 46 "scripts/genksyms/keywords.gperf" 165#line 48 "scripts/genksyms/keywords.gperf"
157 {"typedef", TYPEDEF_KEYW}, 166 {"typedef", TYPEDEF_KEYW},
158#line 15 "scripts/genksyms/keywords.gperf" 167#line 17 "scripts/genksyms/keywords.gperf"
159 {"__inline", INLINE_KEYW}, 168 {"__inline", INLINE_KEYW},
160#line 31 "scripts/genksyms/keywords.gperf" 169#line 33 "scripts/genksyms/keywords.gperf"
161 {"auto", AUTO_KEYW}, 170 {"auto", AUTO_KEYW},
162#line 47 "scripts/genksyms/keywords.gperf" 171#line 21 "scripts/genksyms/keywords.gperf"
163 {"union", UNION_KEYW}, 172 {"__volatile", VOLATILE_KEYW},
164 {""}, {""},
165#line 48 "scripts/genksyms/keywords.gperf"
166 {"unsigned", UNSIGNED_KEYW},
167#line 49 "scripts/genksyms/keywords.gperf"
168 {"void", VOID_KEYW},
169#line 42 "scripts/genksyms/keywords.gperf"
170 {"short", SHORT_KEYW},
171 {""}, {""}, 173 {""}, {""},
172#line 50 "scripts/genksyms/keywords.gperf" 174#line 50 "scripts/genksyms/keywords.gperf"
173 {"volatile", VOLATILE_KEYW}, 175 {"unsigned", UNSIGNED_KEYW},
174 {""},
175#line 37 "scripts/genksyms/keywords.gperf"
176 {"float", FLOAT_KEYW},
177#line 34 "scripts/genksyms/keywords.gperf"
178 {"double", DOUBLE_KEYW},
179 {""}, 176 {""},
180#line 5 "scripts/genksyms/keywords.gperf" 177#line 44 "scripts/genksyms/keywords.gperf"
181 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, 178 {"short", SHORT_KEYW},
182 {""}, {""}, 179#line 40 "scripts/genksyms/keywords.gperf"
183#line 38 "scripts/genksyms/keywords.gperf"
184 {"inline", INLINE_KEYW}, 180 {"inline", INLINE_KEYW},
185#line 6 "scripts/genksyms/keywords.gperf"
186 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
187#line 41 "scripts/genksyms/keywords.gperf"
188 {"register", REGISTER_KEYW},
189 {""}, 181 {""},
190#line 22 "scripts/genksyms/keywords.gperf" 182#line 52 "scripts/genksyms/keywords.gperf"
183 {"volatile", VOLATILE_KEYW},
184#line 42 "scripts/genksyms/keywords.gperf"
185 {"long", LONG_KEYW},
186#line 24 "scripts/genksyms/keywords.gperf"
191 {"_Bool", BOOL_KEYW}, 187 {"_Bool", BOOL_KEYW},
192#line 43 "scripts/genksyms/keywords.gperf"
193 {"signed", SIGNED_KEYW},
194 {""}, {""}, 188 {""}, {""},
195#line 40 "scripts/genksyms/keywords.gperf" 189#line 43 "scripts/genksyms/keywords.gperf"
196 {"long", LONG_KEYW} 190 {"register", REGISTER_KEYW},
191#line 51 "scripts/genksyms/keywords.gperf"
192 {"void", VOID_KEYW},
193#line 39 "scripts/genksyms/keywords.gperf"
194 {"float", FLOAT_KEYW},
195#line 36 "scripts/genksyms/keywords.gperf"
196 {"double", DOUBLE_KEYW},
197 {""}, {""}, {""}, {""},
198#line 45 "scripts/genksyms/keywords.gperf"
199 {"signed", SIGNED_KEYW}
197 }; 200 };
198 201
199 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 202 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
index 5ef3733225fb..8abe7ab8d88f 100644
--- a/scripts/genksyms/keywords.gperf
+++ b/scripts/genksyms/keywords.gperf
@@ -5,6 +5,8 @@ struct resword { const char *name; int token; }
5EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW 5EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
6EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW 6EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
7EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW 7EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
8EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW
9EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
8__asm, ASM_KEYW 10__asm, ASM_KEYW
9__asm__, ASM_KEYW 11__asm__, ASM_KEYW
10__attribute, ATTRIBUTE_KEYW 12__attribute, ATTRIBUTE_KEYW
diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl
new file mode 100755
index 000000000000..97399da89ef2
--- /dev/null
+++ b/scripts/headerdep.pl
@@ -0,0 +1,193 @@
1#! /usr/bin/perl
2#
3# Detect cycles in the header file dependency graph
4# Vegard Nossum <vegardno@ifi.uio.no>
5#
6
7use strict;
8use warnings;
9
10use Getopt::Long;
11
12my $opt_all;
13my @opt_include;
14my $opt_graph;
15
16&Getopt::Long::Configure(qw(bundling pass_through));
17&GetOptions(
18 help => \&help,
19 version => \&version,
20
21 all => \$opt_all,
22 I => \@opt_include,
23 graph => \$opt_graph,
24);
25
26push @opt_include, 'include';
27my %deps = ();
28my %linenos = ();
29
30my @headers = grep { strip($_) } @ARGV;
31
32parse_all(@headers);
33
34if($opt_graph) {
35 graph();
36} else {
37 detect_cycles(@headers);
38}
39
40
41sub help {
42 print "Usage: $0 [options] file...\n";
43 print "\n";
44 print "Options:\n";
45 print " --all\n";
46 print " --graph\n";
47 print "\n";
48 print " -I includedir\n";
49 print "\n";
50 print "To make nice graphs, try:\n";
51 print " $0 --graph include/linux/kernel.h | dot -Tpng -o graph.png\n";
52 exit;
53}
54
55sub version {
56 print "headerdep version 2\n";
57 exit;
58}
59
60# Get a file name that is relative to our include paths
61sub strip {
62 my $filename = shift;
63
64 for my $i (@opt_include) {
65 my $stripped = $filename;
66 $stripped =~ s/^$i\///;
67
68 return $stripped if $stripped ne $filename;
69 }
70
71 return $filename;
72}
73
74# Search for the file name in the list of include paths
75sub search {
76 my $filename = shift;
77 return $filename if -f $filename;
78
79 for my $i (@opt_include) {
80 my $path = "$i/$filename";
81 return $path if -f $path;
82 }
83
84 return undef;
85}
86
87sub parse_all {
88 # Parse all the headers.
89 my @queue = @_;
90 while(@queue) {
91 my $header = pop @queue;
92 next if exists $deps{$header};
93
94 $deps{$header} = [] unless exists $deps{$header};
95
96 my $path = search($header);
97 next unless $path;
98
99 open(my $file, '<', $path) or die($!);
100 chomp(my @lines = <$file>);
101 close($file);
102
103 for my $i (0 .. $#lines) {
104 my $line = $lines[$i];
105 if(my($dep) = ($line =~ m/^#\s*include\s*<(.*?)>/)) {
106 push @queue, $dep;
107 push @{$deps{$header}}, [$i + 1, $dep];
108 }
109 }
110 }
111}
112
113sub print_cycle {
114 # $cycle[n] includes $cycle[n + 1];
115 # $cycle[-1] will be the culprit
116 my $cycle = shift;
117
118 # Adjust the line numbers
119 for my $i (0 .. $#$cycle - 1) {
120 $cycle->[$i]->[0] = $cycle->[$i + 1]->[0];
121 }
122 $cycle->[-1]->[0] = 0;
123
124 my $first = shift @$cycle;
125 my $last = pop @$cycle;
126
127 my $msg = "In file included";
128 printf "%s from %s,\n", $msg, $last->[1] if defined $last;
129
130 for my $header (reverse @$cycle) {
131 printf "%s from %s:%d%s\n",
132 " " x length $msg,
133 $header->[1], $header->[0],
134 $header->[1] eq $last->[1] ? ' <-- here' : '';
135 }
136
137 printf "%s:%d: warning: recursive header inclusion\n",
138 $first->[1], $first->[0];
139}
140
141# Find and print the smallest cycle starting in the specified node.
142sub detect_cycles {
143 my @queue = map { [[0, $_]] } @_;
144 while(@queue) {
145 my $top = pop @queue;
146 my $name = $top->[-1]->[1];
147
148 for my $dep (@{$deps{$name}}) {
149 my $chain = [@$top, [$dep->[0], $dep->[1]]];
150
151 # If the dep already exists in the chain, we have a
152 # cycle...
153 if(grep { $_->[1] eq $dep->[1] } @$top) {
154 print_cycle($chain);
155 next if $opt_all;
156 return;
157 }
158
159 push @queue, $chain;
160 }
161 }
162}
163
164sub mangle {
165 $_ = shift;
166 s/\//__/g;
167 s/\./_/g;
168 s/-/_/g;
169 $_;
170}
171
172# Output dependency graph in GraphViz language.
173sub graph {
174 print "digraph {\n";
175
176 print "\t/* vertices */\n";
177 for my $header (keys %deps) {
178 printf "\t%s [label=\"%s\"];\n",
179 mangle($header), $header;
180 }
181
182 print "\n";
183
184 print "\t/* edges */\n";
185 for my $header (keys %deps) {
186 for my $dep (@{$deps{$header}}) {
187 printf "\t%s -> %s;\n",
188 mangle($header), mangle($dep->[1]);
189 }
190 }
191
192 print "}\n";
193}
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl
index 488a3b1f760f..db30fac3083e 100644
--- a/scripts/headers_check.pl
+++ b/scripts/headers_check.pl
@@ -14,7 +14,9 @@
14# Only include files located in asm* and linux* are checked. 14# Only include files located in asm* and linux* are checked.
15# The rest are assumed to be system include files. 15# The rest are assumed to be system include files.
16# 16#
17# 2) TODO: check for leaked CONFIG_ symbols 17# 2) It is checked that prototypes does not use "extern"
18#
19# 3) Check for leaked CONFIG_ symbols
18 20
19use strict; 21use strict;
20 22
@@ -32,7 +34,11 @@ foreach my $file (@files) {
32 $lineno = 0; 34 $lineno = 0;
33 while ($line = <FH>) { 35 while ($line = <FH>) {
34 $lineno++; 36 $lineno++;
35 check_include(); 37 &check_include();
38 &check_asm_types();
39 &check_sizetypes();
40 &check_prototypes();
41 &check_config();
36 } 42 }
37 close FH; 43 close FH;
38} 44}
@@ -54,3 +60,63 @@ sub check_include
54 } 60 }
55 } 61 }
56} 62}
63
64sub check_prototypes
65{
66 if ($line =~ m/^\s*extern\b/) {
67 printf STDERR "$filename:$lineno: extern's make no sense in userspace\n";
68 }
69}
70
71sub check_config
72{
73 if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9]+)[^a-zA-Z0-9]/) {
74 printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n";
75 }
76}
77
78my $linux_asm_types;
79sub check_asm_types()
80{
81 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
82 return;
83 }
84 if ($lineno == 1) {
85 $linux_asm_types = 0;
86 } elsif ($linux_asm_types >= 1) {
87 return;
88 }
89 if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) {
90 $linux_asm_types = 1;
91 printf STDERR "$filename:$lineno: " .
92 "include of <linux/types.h> is preferred over <asm/types.h>\n"
93 # Warn until headers are all fixed
94 #$ret = 1;
95 }
96}
97
98my $linux_types;
99sub check_sizetypes
100{
101 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
102 return;
103 }
104 if ($lineno == 1) {
105 $linux_types = 0;
106 } elsif ($linux_types >= 1) {
107 return;
108 }
109 if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
110 $linux_types = 1;
111 return;
112 }
113 if ($line =~ m/__[us](8|16|32|64)\b/) {
114 printf STDERR "$filename:$lineno: " .
115 "found __[us]{8,16,32,64} type " .
116 "without #include <linux/types.h>\n";
117 $linux_types = 2;
118 # Warn until headers are all fixed
119 #$ret = 1;
120 }
121}
122
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl
index 7d2b4146e02f..c6ae4052ab43 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -36,6 +36,9 @@ foreach my $file (@files) {
36 $line =~ s/\s__attribute_const__\s/ /g; 36 $line =~ s/\s__attribute_const__\s/ /g;
37 $line =~ s/\s__attribute_const__$//g; 37 $line =~ s/\s__attribute_const__$//g;
38 $line =~ s/^#include <linux\/compiler.h>//; 38 $line =~ s/^#include <linux\/compiler.h>//;
39 $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
40 $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
41 $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
39 printf OUTFILE "%s", $line; 42 printf OUTFILE "%s", $line;
40 } 43 }
41 close OUTFILE; 44 close OUTFILE;
diff --git a/scripts/ihex2fw.c b/scripts/ihex2fw.c
new file mode 100644
index 000000000000..8f7fdaa9e010
--- /dev/null
+++ b/scripts/ihex2fw.c
@@ -0,0 +1,268 @@
1/*
2 * Parser/loader for IHEX formatted data.
3 *
4 * Copyright © 2008 David Woodhouse <dwmw2@infradead.org>
5 * Copyright © 2005 Jan Harkes <jaharkes@cs.cmu.edu>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <stdint.h>
13#include <arpa/inet.h>
14#include <stdio.h>
15#include <errno.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <sys/mman.h>
19#include <fcntl.h>
20#include <string.h>
21#include <unistd.h>
22#include <stdlib.h>
23#define _GNU_SOURCE
24#include <getopt.h>
25
26
27struct ihex_binrec {
28 struct ihex_binrec *next; /* not part of the real data structure */
29 uint32_t addr;
30 uint16_t len;
31 uint8_t data[];
32};
33
34/**
35 * nybble/hex are little helpers to parse hexadecimal numbers to a byte value
36 **/
37static uint8_t nybble(const uint8_t n)
38{
39 if (n >= '0' && n <= '9') return n - '0';
40 else if (n >= 'A' && n <= 'F') return n - ('A' - 10);
41 else if (n >= 'a' && n <= 'f') return n - ('a' - 10);
42 return 0;
43}
44
45static uint8_t hex(const uint8_t *data, uint8_t *crc)
46{
47 uint8_t val = (nybble(data[0]) << 4) | nybble(data[1]);
48 *crc += val;
49 return val;
50}
51
52static int process_ihex(uint8_t *data, ssize_t size);
53static void file_record(struct ihex_binrec *record);
54static int output_records(int outfd);
55
56static int sort_records = 0;
57static int wide_records = 0;
58
59int usage(void)
60{
61 fprintf(stderr, "ihex2fw: Convert ihex files into binary "
62 "representation for use by Linux kernel\n");
63 fprintf(stderr, "usage: ihex2fw [<options>] <src.HEX> <dst.fw>\n");
64 fprintf(stderr, " -w: wide records (16-bit length)\n");
65 fprintf(stderr, " -s: sort records by address\n");
66 return 1;
67}
68
69int main(int argc, char **argv)
70{
71 int infd, outfd;
72 struct stat st;
73 uint8_t *data;
74 int opt;
75
76 while ((opt = getopt(argc, argv, "ws")) != -1) {
77 switch (opt) {
78 case 'w':
79 wide_records = 1;
80 break;
81 case 's':
82 sort_records = 1;
83 break;
84 default:
85 return usage();
86 }
87 }
88
89 if (optind + 2 != argc)
90 return usage();
91
92 if (!strcmp(argv[optind], "-"))
93 infd = 0;
94 else
95 infd = open(argv[optind], O_RDONLY);
96 if (infd == -1) {
97 fprintf(stderr, "Failed to open source file: %s",
98 strerror(errno));
99 return usage();
100 }
101 if (fstat(infd, &st)) {
102 perror("stat");
103 return 1;
104 }
105 data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, infd, 0);
106 if (data == MAP_FAILED) {
107 perror("mmap");
108 return 1;
109 }
110
111 if (!strcmp(argv[optind+1], "-"))
112 outfd = 1;
113 else
114 outfd = open(argv[optind+1], O_TRUNC|O_CREAT|O_WRONLY, 0644);
115 if (outfd == -1) {
116 fprintf(stderr, "Failed to open destination file: %s",
117 strerror(errno));
118 return usage();
119 }
120 if (process_ihex(data, st.st_size))
121 return 1;
122
123 output_records(outfd);
124 return 0;
125}
126
127static int process_ihex(uint8_t *data, ssize_t size)
128{
129 struct ihex_binrec *record;
130 uint32_t offset = 0;
131 uint8_t type, crc = 0, crcbyte = 0;
132 int i, j;
133 int line = 1;
134 int len;
135
136 i = 0;
137next_record:
138 /* search for the start of record character */
139 while (i < size) {
140 if (data[i] == '\n') line++;
141 if (data[i++] == ':') break;
142 }
143
144 /* Minimum record length would be about 10 characters */
145 if (i + 10 > size) {
146 fprintf(stderr, "Can't find valid record at line %d\n", line);
147 return -EINVAL;
148 }
149
150 len = hex(data + i, &crc); i += 2;
151 if (wide_records) {
152 len <<= 8;
153 len += hex(data + i, &crc); i += 2;
154 }
155 record = malloc((sizeof (*record) + len + 3) & ~3);
156 if (!record) {
157 fprintf(stderr, "out of memory for records\n");
158 return -ENOMEM;
159 }
160 memset(record, 0, (sizeof(*record) + len + 3) & ~3);
161 record->len = len;
162
163 /* now check if we have enough data to read everything */
164 if (i + 8 + (record->len * 2) > size) {
165 fprintf(stderr, "Not enough data to read complete record at line %d\n",
166 line);
167 return -EINVAL;
168 }
169
170 record->addr = hex(data + i, &crc) << 8; i += 2;
171 record->addr |= hex(data + i, &crc); i += 2;
172 type = hex(data + i, &crc); i += 2;
173
174 for (j = 0; j < record->len; j++, i += 2)
175 record->data[j] = hex(data + i, &crc);
176
177 /* check CRC */
178 crcbyte = hex(data + i, &crc); i += 2;
179 if (crc != 0) {
180 fprintf(stderr, "CRC failure at line %d: got 0x%X, expected 0x%X\n",
181 line, crcbyte, (unsigned char)(crcbyte-crc));
182 return -EINVAL;
183 }
184
185 /* Done reading the record */
186 switch (type) {
187 case 0:
188 /* old style EOF record? */
189 if (!record->len)
190 break;
191
192 record->addr += offset;
193 file_record(record);
194 goto next_record;
195
196 case 1: /* End-Of-File Record */
197 if (record->addr || record->len) {
198 fprintf(stderr, "Bad EOF record (type 01) format at line %d",
199 line);
200 return -EINVAL;
201 }
202 break;
203
204 case 2: /* Extended Segment Address Record (HEX86) */
205 case 4: /* Extended Linear Address Record (HEX386) */
206 if (record->addr || record->len != 2) {
207 fprintf(stderr, "Bad HEX86/HEX386 record (type %02X) at line %d\n",
208 type, line);
209 return -EINVAL;
210 }
211
212 /* We shouldn't really be using the offset for HEX86 because
213 * the wraparound case is specified quite differently. */
214 offset = record->data[0] << 8 | record->data[1];
215 offset <<= (type == 2 ? 4 : 16);
216 goto next_record;
217
218 case 3: /* Start Segment Address Record */
219 case 5: /* Start Linear Address Record */
220 if (record->addr || record->len != 4) {
221 fprintf(stderr, "Bad Start Address record (type %02X) at line %d\n",
222 type, line);
223 return -EINVAL;
224 }
225
226 /* These records contain the CS/IP or EIP where execution
227 * starts. Don't really know what to do with them. */
228 goto next_record;
229
230 default:
231 fprintf(stderr, "Unknown record (type %02X)\n", type);
232 return -EINVAL;
233 }
234
235 return 0;
236}
237
238static struct ihex_binrec *records;
239
240static void file_record(struct ihex_binrec *record)
241{
242 struct ihex_binrec **p = &records;
243
244 while ((*p) && (!sort_records || (*p)->addr < record->addr))
245 p = &((*p)->next);
246
247 record->next = *p;
248 *p = record;
249}
250
251static int output_records(int outfd)
252{
253 unsigned char zeroes[6] = {0, 0, 0, 0, 0, 0};
254 struct ihex_binrec *p = records;
255
256 while (p) {
257 uint16_t writelen = (p->len + 9) & ~3;
258
259 p->addr = htonl(p->addr);
260 p->len = htons(p->len);
261 write(outfd, &p->addr, writelen);
262 p = p->next;
263 }
264 /* EOF record is zero length, since we don't bother to represent
265 the type field in the binary version */
266 write(outfd, zeroes, 6);
267 return 0;
268}
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index ad2434b26970..92758120a767 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -130,18 +130,9 @@ static int read_symbol(FILE *in, struct sym_entry *s)
130static int symbol_valid(struct sym_entry *s) 130static int symbol_valid(struct sym_entry *s)
131{ 131{
132 /* Symbols which vary between passes. Passes 1 and 2 must have 132 /* Symbols which vary between passes. Passes 1 and 2 must have
133 * identical symbol lists. The kallsyms_* symbols below are only added 133 * identical symbol lists.
134 * after pass 1, they would be included in pass 2 when --all-symbols is
135 * specified so exclude them to get a stable symbol list.
136 */ 134 */
137 static char *special_symbols[] = { 135 static char *special_symbols[] = {
138 "kallsyms_addresses",
139 "kallsyms_num_syms",
140 "kallsyms_names",
141 "kallsyms_markers",
142 "kallsyms_token_table",
143 "kallsyms_token_index",
144
145 /* Exclude linker generated symbols which vary between passes */ 136 /* Exclude linker generated symbols which vary between passes */
146 "_SDA_BASE_", /* ppc */ 137 "_SDA_BASE_", /* ppc */
147 "_SDA2_BASE_", /* ppc */ 138 "_SDA2_BASE_", /* ppc */
@@ -173,7 +164,9 @@ static int symbol_valid(struct sym_entry *s)
173 } 164 }
174 165
175 /* Exclude symbols which vary between passes. */ 166 /* Exclude symbols which vary between passes. */
176 if (strstr((char *)s->sym + offset, "_compiled.")) 167 if (strstr((char *)s->sym + offset, "_compiled.") ||
168 strncmp((char*)s->sym + offset, "__compound_literal.", 19) == 0 ||
169 strncmp((char*)s->sym + offset, "__compound_literal$", 19) == 0)
177 return 0; 170 return 0;
178 171
179 for (i = 0; special_symbols[i]; i++) 172 for (i = 0; special_symbols[i]; i++)
@@ -550,8 +543,10 @@ int main(int argc, char **argv)
550 usage(); 543 usage();
551 544
552 read_map(stdin); 545 read_map(stdin);
553 sort_symbols(); 546 if (table_cnt) {
554 optimize_token_table(); 547 sort_symbols();
548 optimize_token_table();
549 }
555 write_src(); 550 write_src();
556 551
557 return 0; 552 return 0;
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 9d4cba1c001d..6408fefae083 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -65,9 +65,13 @@ enum symbol_type {
65 S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER 65 S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
66}; 66};
67 67
68/* enum values are used as index to symbol.def[] */
68enum { 69enum {
69 S_DEF_USER, /* main user value */ 70 S_DEF_USER, /* main user value */
70 S_DEF_AUTO, 71 S_DEF_AUTO, /* values read from auto.conf */
72 S_DEF_DEF3, /* Reserved for UI usage */
73 S_DEF_DEF4, /* Reserved for UI usage */
74 S_DEF_COUNT
71}; 75};
72 76
73struct symbol { 77struct symbol {
@@ -75,7 +79,7 @@ struct symbol {
75 char *name; 79 char *name;
76 enum symbol_type type; 80 enum symbol_type type;
77 struct symbol_value curr; 81 struct symbol_value curr;
78 struct symbol_value def[4]; 82 struct symbol_value def[S_DEF_COUNT];
79 tristate visible; 83 tristate visible;
80 int flags; 84 int flags;
81 struct property *prop; 85 struct property *prop;
@@ -84,42 +88,64 @@ struct symbol {
84 88
85#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) 89#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
86 90
87#define SYMBOL_CONST 0x0001 91#define SYMBOL_CONST 0x0001 /* symbol is const */
88#define SYMBOL_CHECK 0x0008 92#define SYMBOL_CHECK 0x0008 /* used during dependency checking */
89#define SYMBOL_CHOICE 0x0010 93#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */
90#define SYMBOL_CHOICEVAL 0x0020 94#define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */
91#define SYMBOL_VALID 0x0080 95#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */
92#define SYMBOL_OPTIONAL 0x0100 96#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
93#define SYMBOL_WRITE 0x0200 97#define SYMBOL_WRITE 0x0200 /* ? */
94#define SYMBOL_CHANGED 0x0400 98#define SYMBOL_CHANGED 0x0400 /* ? */
95#define SYMBOL_AUTO 0x1000 99#define SYMBOL_AUTO 0x1000 /* value from environment variable */
96#define SYMBOL_CHECKED 0x2000 100#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
97#define SYMBOL_WARNED 0x8000 101#define SYMBOL_WARNED 0x8000 /* warning has been issued */
98#define SYMBOL_DEF 0x10000 102
99#define SYMBOL_DEF_USER 0x10000 103/* Set when symbol.def[] is used */
100#define SYMBOL_DEF_AUTO 0x20000 104#define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */
101#define SYMBOL_DEF3 0x40000 105#define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */
102#define SYMBOL_DEF4 0x80000 106#define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */
107#define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */
108#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
103 109
104#define SYMBOL_MAXLENGTH 256 110#define SYMBOL_MAXLENGTH 256
105#define SYMBOL_HASHSIZE 257 111#define SYMBOL_HASHSIZE 257
106#define SYMBOL_HASHMASK 0xff 112#define SYMBOL_HASHMASK 0xff
107 113
114/* A property represent the config options that can be associated
115 * with a config "symbol".
116 * Sample:
117 * config FOO
118 * default y
119 * prompt "foo prompt"
120 * select BAR
121 * config BAZ
122 * int "BAZ Value"
123 * range 1..255
124 */
108enum prop_type { 125enum prop_type {
109 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, 126 P_UNKNOWN,
110 P_SELECT, P_RANGE, P_ENV 127 P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */
128 P_COMMENT, /* text associated with a comment */
129 P_MENU, /* prompt associated with a menuconfig option */
130 P_DEFAULT, /* default y */
131 P_CHOICE, /* choice value */
132 P_SELECT, /* select BAR */
133 P_RANGE, /* range 7..100 (for a symbol) */
134 P_ENV, /* value from environment variable */
111}; 135};
112 136
113struct property { 137struct property {
114 struct property *next; 138 struct property *next; /* next property - null if last */
115 struct symbol *sym; 139 struct symbol *sym; /* the symbol for which the property is associated */
116 enum prop_type type; 140 enum prop_type type; /* type of property */
117 const char *text; 141 const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */
118 struct expr_value visible; 142 struct expr_value visible;
119 struct expr *expr; 143 struct expr *expr; /* the optional conditional part of the property */
120 struct menu *menu; 144 struct menu *menu; /* the menu the property are associated with
121 struct file *file; 145 * valid for: P_SELECT, P_RANGE, P_CHOICE,
122 int lineno; 146 * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */
147 struct file *file; /* what file was this property defined */
148 int lineno; /* what lineno was this property defined */
123}; 149};
124 150
125#define for_all_properties(sym, st, tok) \ 151#define for_all_properties(sym, st, tok) \
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index 7342ce0a7780..dc3e81807d13 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -2370,11 +2370,14 @@ void zconf_nextfile(const char *name)
2370 current_buf = buf; 2370 current_buf = buf;
2371 2371
2372 if (file->flags & FILE_BUSY) { 2372 if (file->flags & FILE_BUSY) {
2373 printf("recursive scan (%s)?\n", name); 2373 printf("%s:%d: do not source '%s' from itself\n",
2374 zconf_curname(), zconf_lineno(), name);
2374 exit(1); 2375 exit(1);
2375 } 2376 }
2376 if (file->flags & FILE_SCANNED) { 2377 if (file->flags & FILE_SCANNED) {
2377 printf("file %s already scanned?\n", name); 2378 printf("%s:%d: file '%s' is already sourced from '%s'\n",
2379 zconf_curname(), zconf_lineno(), name,
2380 file->parent->name);
2378 exit(1); 2381 exit(1);
2379 } 2382 }
2380 file->flags |= FILE_BUSY; 2383 file->flags |= FILE_BUSY;
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index 5552154cbedb..fcef0f59d553 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -52,7 +52,7 @@ EOF
52} 52}
53 53
54usage() { 54usage() {
55 printf "Usage: $0 [-check compiler options|-header|-library]\n" 55 printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n"
56} 56}
57 57
58if [ $# -eq 0 ]; then 58if [ $# -eq 0 ]; then
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 5164ef7ce499..21ff69c9ad4e 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -314,11 +314,14 @@ void zconf_nextfile(const char *name)
314 current_buf = buf; 314 current_buf = buf;
315 315
316 if (file->flags & FILE_BUSY) { 316 if (file->flags & FILE_BUSY) {
317 printf("recursive scan (%s)?\n", name); 317 printf("%s:%d: do not source '%s' from itself\n",
318 zconf_curname(), zconf_lineno(), name);
318 exit(1); 319 exit(1);
319 } 320 }
320 if (file->flags & FILE_SCANNED) { 321 if (file->flags & FILE_SCANNED) {
321 printf("file %s already scanned?\n", name); 322 printf("%s:%d: file '%s' is already sourced from '%s'\n",
323 zconf_curname(), zconf_lineno(), name,
324 file->parent->name);
322 exit(1); 325 exit(1);
323 } 326 }
324 file->flags |= FILE_BUSY; 327 file->flags |= FILE_BUSY;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index d27aad78e1d8..8bb83a100edb 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -289,6 +289,8 @@ my %parameterdescs;
289my @parameterlist; 289my @parameterlist;
290my %sections; 290my %sections;
291my @sectionlist; 291my @sectionlist;
292my $sectcheck;
293my $struct_actual;
292 294
293my $contents = ""; 295my $contents = "";
294my $section_default = "Description"; # default section 296my $section_default = "Description"; # default section
@@ -378,10 +380,12 @@ sub dump_section {
378# print STDERR "parameter def '$1' = '$contents'\n"; 380# print STDERR "parameter def '$1' = '$contents'\n";
379 $name = $1; 381 $name = $1;
380 $parameterdescs{$name} = $contents; 382 $parameterdescs{$name} = $contents;
383 $sectcheck = $sectcheck . $name . " ";
381 } elsif ($name eq "@\.\.\.") { 384 } elsif ($name eq "@\.\.\.") {
382# print STDERR "parameter def '...' = '$contents'\n"; 385# print STDERR "parameter def '...' = '$contents'\n";
383 $name = "..."; 386 $name = "...";
384 $parameterdescs{$name} = $contents; 387 $parameterdescs{$name} = $contents;
388 $sectcheck = $sectcheck . $name . " ";
385 } else { 389 } else {
386# print STDERR "other section '$name' = '$contents'\n"; 390# print STDERR "other section '$name' = '$contents'\n";
387 if (defined($sections{$name}) && ($sections{$name} ne "")) { 391 if (defined($sections{$name}) && ($sections{$name} ne "")) {
@@ -1405,21 +1409,25 @@ sub dump_union($$) {
1405sub dump_struct($$) { 1409sub dump_struct($$) {
1406 my $x = shift; 1410 my $x = shift;
1407 my $file = shift; 1411 my $file = shift;
1412 my $nested;
1408 1413
1409 if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { 1414 if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
1410 $declaration_name = $2; 1415 $declaration_name = $2;
1411 my $members = $3; 1416 my $members = $3;
1412 1417
1413 # ignore embedded structs or unions 1418 # ignore embedded structs or unions
1414 $members =~ s/{.*}//g; 1419 $members =~ s/({.*})//g;
1420 $nested = $1;
1415 1421
1416 # ignore members marked private: 1422 # ignore members marked private:
1417 $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos; 1423 $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
1418 $members =~ s/\/\*.*?private:.*//gos; 1424 $members =~ s/\/\*.*?private:.*//gos;
1419 # strip comments: 1425 # strip comments:
1420 $members =~ s/\/\*.*?\*\///gos; 1426 $members =~ s/\/\*.*?\*\///gos;
1427 $nested =~ s/\/\*.*?\*\///gos;
1421 1428
1422 create_parameterlist($members, ';', $file); 1429 create_parameterlist($members, ';', $file);
1430 check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
1423 1431
1424 output_declaration($declaration_name, 1432 output_declaration($declaration_name,
1425 'struct', 1433 'struct',
@@ -1505,6 +1513,14 @@ sub dump_typedef($$) {
1505 } 1513 }
1506} 1514}
1507 1515
1516sub save_struct_actual($) {
1517 my $actual = shift;
1518
1519 # strip all spaces from the actual param so that it looks like one string item
1520 $actual =~ s/\s*//g;
1521 $struct_actual = $struct_actual . $actual . " ";
1522}
1523
1508sub create_parameterlist($$$) { 1524sub create_parameterlist($$$) {
1509 my $args = shift; 1525 my $args = shift;
1510 my $splitter = shift; 1526 my $splitter = shift;
@@ -1537,6 +1553,7 @@ sub create_parameterlist($$$) {
1537 $param = $1; 1553 $param = $1;
1538 $type = $arg; 1554 $type = $arg;
1539 $type =~ s/([^\(]+\(\*?)\s*$param/$1/; 1555 $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
1556 save_struct_actual($param);
1540 push_parameter($param, $type, $file); 1557 push_parameter($param, $type, $file);
1541 } elsif ($arg) { 1558 } elsif ($arg) {
1542 $arg =~ s/\s*:\s*/:/g; 1559 $arg =~ s/\s*:\s*/:/g;
@@ -1561,14 +1578,17 @@ sub create_parameterlist($$$) {
1561 1578
1562 foreach $param (@args) { 1579 foreach $param (@args) {
1563 if ($param =~ m/^(\*+)\s*(.*)/) { 1580 if ($param =~ m/^(\*+)\s*(.*)/) {
1581 save_struct_actual($2);
1564 push_parameter($2, "$type $1", $file); 1582 push_parameter($2, "$type $1", $file);
1565 } 1583 }
1566 elsif ($param =~ m/(.*?):(\d+)/) { 1584 elsif ($param =~ m/(.*?):(\d+)/) {
1567 if ($type ne "") { # skip unnamed bit-fields 1585 if ($type ne "") { # skip unnamed bit-fields
1586 save_struct_actual($1);
1568 push_parameter($1, "$type:$2", $file) 1587 push_parameter($1, "$type:$2", $file)
1569 } 1588 }
1570 } 1589 }
1571 else { 1590 else {
1591 save_struct_actual($param);
1572 push_parameter($param, $type, $file); 1592 push_parameter($param, $type, $file);
1573 } 1593 }
1574 } 1594 }
@@ -1634,6 +1654,46 @@ sub push_parameter($$$) {
1634 $parametertypes{$param} = $type; 1654 $parametertypes{$param} = $type;
1635} 1655}
1636 1656
1657sub check_sections($$$$$$) {
1658 my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_;
1659 my @sects = split ' ', $sectcheck;
1660 my @prms = split ' ', $prmscheck;
1661 my $err;
1662 my ($px, $sx);
1663 my $prm_clean; # strip trailing "[array size]" and/or beginning "*"
1664
1665 foreach $sx (0 .. $#sects) {
1666 $err = 1;
1667 foreach $px (0 .. $#prms) {
1668 $prm_clean = $prms[$px];
1669 $prm_clean =~ s/\[.*\]//;
1670 $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//;
1671 ##$prm_clean =~ s/^\**//;
1672 if ($prm_clean eq $sects[$sx]) {
1673 $err = 0;
1674 last;
1675 }
1676 }
1677 if ($err) {
1678 if ($decl_type eq "function") {
1679 print STDERR "Warning(${file}:$.): " .
1680 "Excess function parameter " .
1681 "'$sects[$sx]' " .
1682 "description in '$decl_name'\n";
1683 ++$warnings;
1684 } else {
1685 if ($nested !~ m/\Q$sects[$sx]\E/) {
1686 print STDERR "Warning(${file}:$.): " .
1687 "Excess struct/union/enum/typedef member " .
1688 "'$sects[$sx]' " .
1689 "description in '$decl_name'\n";
1690 ++$warnings;
1691 }
1692 }
1693 }
1694 }
1695}
1696
1637## 1697##
1638# takes a function prototype and the name of the current file being 1698# takes a function prototype and the name of the current file being
1639# processed and spits out all the details stored in the global 1699# processed and spits out all the details stored in the global
@@ -1699,6 +1759,9 @@ sub dump_function($$) {
1699 return; 1759 return;
1700 } 1760 }
1701 1761
1762 my $prms = join " ", @parameterlist;
1763 check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");
1764
1702 output_declaration($declaration_name, 1765 output_declaration($declaration_name,
1703 'function', 1766 'function',
1704 {'function' => $declaration_name, 1767 {'function' => $declaration_name,
@@ -1757,6 +1820,8 @@ sub reset_state {
1757 @parameterlist = (); 1820 @parameterlist = ();
1758 %sections = (); 1821 %sections = ();
1759 @sectionlist = (); 1822 @sectionlist = ();
1823 $sectcheck = "";
1824 $struct_actual = "";
1760 $prototype = ""; 1825 $prototype = "";
1761 1826
1762 $state = 0; 1827 $state = 0;
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
new file mode 100644
index 000000000000..d40449cafa84
--- /dev/null
+++ b/scripts/markup_oops.pl
@@ -0,0 +1,203 @@
1#!/usr/bin/perl -w
2
3use File::Basename;
4
5# Copyright 2008, Intel Corporation
6#
7# This file is part of the Linux kernel
8#
9# This program file is free software; you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by the
11# Free Software Foundation; version 2 of the License.
12#
13# Authors:
14# Arjan van de Ven <arjan@linux.intel.com>
15
16
17my $vmlinux_name = $ARGV[0];
18if (!defined($vmlinux_name)) {
19 my $kerver = `uname -r`;
20 chomp($kerver);
21 $vmlinux_name = "/lib/modules/$kerver/build/vmlinux";
22 print "No vmlinux specified, assuming $vmlinux_name\n";
23}
24my $filename = $vmlinux_name;
25#
26# Step 1: Parse the oops to find the EIP value
27#
28
29my $target = "0";
30my $function;
31my $module = "";
32my $func_offset;
33my $vmaoffset = 0;
34
35while (<STDIN>) {
36 my $line = $_;
37 if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
38 $target = $1;
39 }
40 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) {
41 $function = $1;
42 $func_offset = $2;
43 }
44
45 # check if it's a module
46 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) {
47 $module = $3;
48 }
49}
50
51my $decodestart = hex($target) - hex($func_offset);
52my $decodestop = $decodestart + 8192;
53if ($target eq "0") {
54 print "No oops found!\n";
55 print "Usage: \n";
56 print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
57 exit;
58}
59
60# if it's a module, we need to find the .ko file and calculate a load offset
61if ($module ne "") {
62 my $dir = dirname($filename);
63 $dir = $dir . "/";
64 my $mod = $module . ".ko";
65 my $modulefile = `find $dir -name $mod | head -1`;
66 chomp($modulefile);
67 $filename = $modulefile;
68 if ($filename eq "") {
69 print "Module .ko file for $module not found. Aborting\n";
70 exit;
71 }
72 # ok so we found the module, now we need to calculate the vma offset
73 open(FILE, "objdump -dS $filename |") || die "Cannot start objdump";
74 while (<FILE>) {
75 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
76 my $fu = $1;
77 $vmaoffset = hex($target) - hex($fu) - hex($func_offset);
78 }
79 }
80 close(FILE);
81}
82
83my $counter = 0;
84my $state = 0;
85my $center = 0;
86my @lines;
87
88sub InRange {
89 my ($address, $target) = @_;
90 my $ad = "0x".$address;
91 my $ta = "0x".$target;
92 my $delta = hex($ad) - hex($ta);
93
94 if (($delta > -4096) && ($delta < 4096)) {
95 return 1;
96 }
97 return 0;
98}
99
100
101
102# first, parse the input into the lines array, but to keep size down,
103# we only do this for 4Kb around the sweet spot
104
105open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
106
107while (<FILE>) {
108 my $line = $_;
109 chomp($line);
110 if ($state == 0) {
111 if ($line =~ /^([a-f0-9]+)\:/) {
112 if (InRange($1, $target)) {
113 $state = 1;
114 }
115 }
116 } else {
117 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
118 my $val = $1;
119 if (!InRange($val, $target)) {
120 last;
121 }
122 if ($val eq $target) {
123 $center = $counter;
124 }
125 }
126 $lines[$counter] = $line;
127
128 $counter = $counter + 1;
129 }
130}
131
132close(FILE);
133
134if ($counter == 0) {
135 print "No matching code found \n";
136 exit;
137}
138
139if ($center == 0) {
140 print "No matching code found \n";
141 exit;
142}
143
144my $start;
145my $finish;
146my $codelines = 0;
147my $binarylines = 0;
148# now we go up and down in the array to find how much we want to print
149
150$start = $center;
151
152while ($start > 1) {
153 $start = $start - 1;
154 my $line = $lines[$start];
155 if ($line =~ /^([a-f0-9]+)\:/) {
156 $binarylines = $binarylines + 1;
157 } else {
158 $codelines = $codelines + 1;
159 }
160 if ($codelines > 10) {
161 last;
162 }
163 if ($binarylines > 20) {
164 last;
165 }
166}
167
168
169$finish = $center;
170$codelines = 0;
171$binarylines = 0;
172while ($finish < $counter) {
173 $finish = $finish + 1;
174 my $line = $lines[$finish];
175 if ($line =~ /^([a-f0-9]+)\:/) {
176 $binarylines = $binarylines + 1;
177 } else {
178 $codelines = $codelines + 1;
179 }
180 if ($codelines > 10) {
181 last;
182 }
183 if ($binarylines > 20) {
184 last;
185 }
186}
187
188
189my $i;
190
191my $fulltext = "";
192$i = $start;
193while ($i < $finish) {
194 if ($i == $center) {
195 $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n";
196 } else {
197 $fulltext = $fulltext . " $lines[$i]\n";
198 }
199 $i = $i +1;
200}
201
202print $fulltext;
203
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index a8740df07b09..6a12dd9f1181 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -4,6 +4,8 @@ SMP=$3
4PREEMPT=$4 4PREEMPT=$4
5CC=$5 5CC=$5
6 6
7vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; }
8
7# If compile.h exists already and we don't own autoconf.h 9# If compile.h exists already and we don't own autoconf.h
8# (i.e. we're not the same user who did make *config), don't 10# (i.e. we're not the same user who did make *config), don't
9# modify compile.h 11# modify compile.h
@@ -11,7 +13,7 @@ CC=$5
11# do "compiled by root" 13# do "compiled by root"
12 14
13if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then 15if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then
14 echo " SKIPPED $TARGET" 16 vecho " SKIPPED $TARGET"
15 exit 0 17 exit 0
16fi 18fi
17 19
@@ -89,7 +91,7 @@ if [ -r $TARGET ] && \
89 cmp -s .tmpver.1 .tmpver.2; then 91 cmp -s .tmpver.1 .tmpver.2; then
90 rm -f .tmpcompile 92 rm -f .tmpcompile
91else 93else
92 echo " UPD $TARGET" 94 vecho " UPD $TARGET"
93 mv -f .tmpcompile $TARGET 95 mv -f .tmpcompile $TARGET
94fi 96fi
95rm -f .tmpver.1 .tmpver.2 97rm -f .tmpver.1 .tmpver.2
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
index e65d8b33faa4..67d59c7a18dc 100644
--- a/scripts/mkmakefile
+++ b/scripts/mkmakefile
@@ -17,7 +17,9 @@ if test -e $2/Makefile && ! grep -q Automatically $2/Makefile
17then 17then
18 exit 0 18 exit 0
19fi 19fi
20echo " GEN $2/Makefile" 20if [ "${quiet}" != "silent_" ]; then
21 echo " GEN $2/Makefile"
22fi
21 23
22cat << EOF > $2/Makefile 24cat << EOF > $2/Makefile
23# Automatically generated by $0: don't edit 25# Automatically generated by $0: don't edit
diff --git a/scripts/mksysmap b/scripts/mksysmap
index 6e133a0bae7a..1db316a3712b 100644
--- a/scripts/mksysmap
+++ b/scripts/mksysmap
@@ -37,9 +37,6 @@
37 37
38# readprofile starts reading symbols when _stext is found, and 38# readprofile starts reading symbols when _stext is found, and
39# continue until it finds a symbol which is not either of 'T', 't', 39# continue until it finds a symbol which is not either of 'T', 't',
40# 'W' or 'w'. __crc_ are 'A' and placed in the middle 40# 'W' or 'w'.
41# so we just ignore them to let readprofile continue to work.
42# (At least sparc64 has __crc_ in the middle).
43
44$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2
45 41
42$NM -n $1 | grep -v '\( [aNUw] \)\|\( \$[adt]\)' > $2
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index 5e326078a4a2..8c6b7b09606a 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -1,10 +1,6 @@
1# Makefile for the different targets used to generate full packages of a kernel 1# Makefile for the different targets used to generate full packages of a kernel
2# It uses the generic clean infrastructure of kbuild 2# It uses the generic clean infrastructure of kbuild
3 3
4# Ignore the following files/directories during tar operation
5TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS
6
7
8# RPM target 4# RPM target
9# --------------------------------------------------------------------------- 5# ---------------------------------------------------------------------------
10# The rpm target generates two rpm files: 6# The rpm target generates two rpm files:
@@ -47,7 +43,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE
47 set -e; \ 43 set -e; \
48 mv -f $(objtree)/.tmp_version $(objtree)/.version 44 mv -f $(objtree)/.tmp_version $(objtree)/.version
49 45
50 $(RPM) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz 46 $(RPM) $(RPMOPTS) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz
51 rm ../$(KERNELPATH).tar.gz 47 rm ../$(KERNELPATH).tar.gz
52 48
53clean-files := $(objtree)/kernel.spec 49clean-files := $(objtree)/kernel.spec
@@ -64,7 +60,8 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE
64 set -e; \ 60 set -e; \
65 mv -f $(objtree)/.tmp_version $(objtree)/.version 61 mv -f $(objtree)/.tmp_version $(objtree)/.version
66 62
67 $(RPM) --define "_builddir $(srctree)" --target $(UTS_MACHINE) -bb $< 63 $(RPM) $(RPMOPTS) --define "_builddir $(srctree)" --target \
64 $(UTS_MACHINE) -bb $<
68 65
69clean-files += $(objtree)/binkernel.spec 66clean-files += $(objtree)/binkernel.spec
70 67
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 6b9fe3eb8360..fe831412bea9 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -112,6 +112,9 @@ my ($arch, $bits, $objdump, $objcopy, $cc,
112# Acceptable sections to record. 112# Acceptable sections to record.
113my %text_sections = ( 113my %text_sections = (
114 ".text" => 1, 114 ".text" => 1,
115 ".sched.text" => 1,
116 ".spinlock.text" => 1,
117 ".irqentry.text" => 1,
115); 118);
116 119
117$objdump = "objdump" if ((length $objdump) == 0); 120$objdump = "objdump" if ((length $objdump) == 0);
@@ -130,10 +133,13 @@ my %weak; # List of weak functions
130my %convert; # List of local functions used that needs conversion 133my %convert; # List of local functions used that needs conversion
131 134
132my $type; 135my $type;
136my $nm_regex; # Find the local functions (return function)
133my $section_regex; # Find the start of a section 137my $section_regex; # Find the start of a section
134my $function_regex; # Find the name of a function 138my $function_regex; # Find the name of a function
135 # (return offset and func name) 139 # (return offset and func name)
136my $mcount_regex; # Find the call site to mcount (return offset) 140my $mcount_regex; # Find the call site to mcount (return offset)
141my $alignment; # The .align value to use for $mcount_section
142my $section_type; # Section header plus possible alignment command
137 143
138if ($arch eq "x86") { 144if ($arch eq "x86") {
139 if ($bits == 64) { 145 if ($bits == 64) {
@@ -143,11 +149,21 @@ if ($arch eq "x86") {
143 } 149 }
144} 150}
145 151
152#
153# We base the defaults off of i386, the other archs may
154# feel free to change them in the below if statements.
155#
156$nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
157$section_regex = "Disassembly of section\\s+(\\S+):";
158$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
159$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
160$section_type = '@progbits';
161$type = ".long";
162
146if ($arch eq "x86_64") { 163if ($arch eq "x86_64") {
147 $section_regex = "Disassembly of section\\s+(\\S+):";
148 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
149 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; 164 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$";
150 $type = ".quad"; 165 $type = ".quad";
166 $alignment = 8;
151 167
152 # force flags for this arch 168 # force flags for this arch
153 $ld .= " -m elf_x86_64"; 169 $ld .= " -m elf_x86_64";
@@ -156,10 +172,7 @@ if ($arch eq "x86_64") {
156 $cc .= " -m64"; 172 $cc .= " -m64";
157 173
158} elsif ($arch eq "i386") { 174} elsif ($arch eq "i386") {
159 $section_regex = "Disassembly of section\\s+(\\S+):"; 175 $alignment = 4;
160 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
161 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
162 $type = ".long";
163 176
164 # force flags for this arch 177 # force flags for this arch
165 $ld .= " -m elf_i386"; 178 $ld .= " -m elf_i386";
@@ -167,6 +180,27 @@ if ($arch eq "x86_64") {
167 $objcopy .= " -O elf32-i386"; 180 $objcopy .= " -O elf32-i386";
168 $cc .= " -m32"; 181 $cc .= " -m32";
169 182
183} elsif ($arch eq "sh") {
184 $alignment = 2;
185
186 # force flags for this arch
187 $ld .= " -m shlelf_linux";
188 $objcopy .= " -O elf32-sh-linux";
189 $cc .= " -m32";
190
191} elsif ($arch eq "powerpc") {
192 $nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
193 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
194 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
195
196 if ($bits == 64) {
197 $type = ".quad";
198 }
199
200} elsif ($arch eq "arm") {
201 $alignment = 2;
202 $section_type = '%progbits';
203
170} else { 204} else {
171 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 205 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
172} 206}
@@ -236,7 +270,7 @@ if (!$found_version) {
236# 270#
237open (IN, "$nm $inputfile|") || die "error running $nm"; 271open (IN, "$nm $inputfile|") || die "error running $nm";
238while (<IN>) { 272while (<IN>) {
239 if (/^[0-9a-fA-F]+\s+t\s+(\S+)/) { 273 if (/$nm_regex/) {
240 $locals{$1} = 1; 274 $locals{$1} = 1;
241 } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) { 275 } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) {
242 $weak{$2} = $1; 276 $weak{$2} = $1;
@@ -287,7 +321,8 @@ sub update_funcs
287 if (!$opened) { 321 if (!$opened) {
288 open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; 322 open(FILE, ">$mcount_s") || die "can't create $mcount_s\n";
289 $opened = 1; 323 $opened = 1;
290 print FILE "\t.section $mcount_section,\"a\",\@progbits\n"; 324 print FILE "\t.section $mcount_section,\"a\",$section_type\n";
325 print FILE "\t.align $alignment\n" if (defined($alignment));
291 } 326 }
292 printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset; 327 printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset;
293 } 328 }
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 72d233528ade..f6946cf99ce1 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -19,6 +19,11 @@ if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
19 fi 19 fi
20 fi 20 fi
21 21
22 # Is this git on svn?
23 if git config --get svn-remote.svn.url >/dev/null; then
24 printf -- '-svn%s' "`git-svn find-rev $head`"
25 fi
26
22 # Are there uncommitted changes? 27 # Are there uncommitted changes?
23 git update-index --refresh --unmerged > /dev/null 28 git update-index --refresh --unmerged > /dev/null
24 if git diff-index --name-only HEAD | grep -v "^scripts/package" \ 29 if git diff-index --name-only HEAD | grep -v "^scripts/package" \
@@ -51,7 +56,7 @@ if hgid=`hg id 2>/dev/null`; then
51fi 56fi
52 57
53# Check for svn and a svn repo. 58# Check for svn and a svn repo.
54if rev=`svn info 2>/dev/null | grep '^Revision'`; then 59if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
55 rev=`echo $rev | awk '{print $NF}'` 60 rev=`echo $rev | awk '{print $NF}'`
56 changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l` 61 changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l`
57 62
diff --git a/scripts/strip-symbols b/scripts/strip-symbols
new file mode 100644
index 000000000000..29ee8c1a014b
--- /dev/null
+++ b/scripts/strip-symbols
@@ -0,0 +1,22 @@
1<*>
2*.h
3__compound_literal[$.][0-9]*
4__crc_[a-zA-Z_]*
5__exitcall_[a-zA-Z_]*
6__func__[$.][0-9]*
7__FUNCTION__[$.][0-9]*
8gcc[0-9]_compiled[$.]
9__initcall_[a-zA-Z_]*
10__kcrctab_[a-zA-Z_]*
11__kstrtab_[a-zA-Z_]*
12__ksymtab_[a-zA-Z_]*
13__mod_[a-zA-Z_]*[0-9]
14__module_depends
15__param_[a-zA-Z_]*
16__pci_fixup_*PCI_ANY_IDPCI_ANY_ID*
17__pci_fixup_*PCI_ANY_IDPCI_DEVICE_ID_*
18__pci_fixup_*PCI_VENDOR_ID_*PCI_ANY_ID*
19__pci_fixup_*PCI_VENDOR_ID_*PCI_DEVICE_ID_*
20__PRETTY_FUNCTION__[$.][0-9]*
21__setup_[a-zA-Z_]*
22____versions
diff --git a/scripts/tags.sh b/scripts/tags.sh
new file mode 100755
index 000000000000..fdbe78bb5e2b
--- /dev/null
+++ b/scripts/tags.sh
@@ -0,0 +1,167 @@
1#!/bin/sh
2# Generate tags or cscope files
3# Usage tags.sh <mode>
4#
5# mode may be any of: tags, TAGS, cscope
6#
7# Uses the following environment variables:
8# ARCH, SUBARCH, srctree, src, obj
9
10if [ "$KBUILD_VERBOSE" = "1" ]; then
11 set -x
12fi
13
14# This is a duplicate of RCS_FIND_IGNORE without escaped '()'
15ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \
16 -name CVS -o -name .pc -o -name .hg -o \
17 -name .git ) \
18 -prune -o"
19
20# Do not use full path is we do not use O=.. builds
21if [ "${KBUILD_SRC}" = "" ]; then
22 tree=
23else
24 tree=${srctree}/
25fi
26
27# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
28if [ "${ALLSOURCE_ARCHS}" = "" ]; then
29 ALLSOURCE_ARCHS=${SRCARCH}
30fi
31
32# find sources in arch/$ARCH
33find_arch_sources()
34{
35 find ${tree}arch/$1 $ignore -name "$2" -print;
36}
37
38# find sources in arch/$1/include
39find_arch_include_sources()
40{
41 find ${tree}arch/$1/include $ignore -name "$2" -print;
42}
43
44# find sources in include/
45find_include_sources()
46{
47 find ${tree}include $ignore -name config -prune -o -name "$1" -print;
48}
49
50# find sources in rest of tree
51# we could benefit from a list of dirs to search in here
52find_other_sources()
53{
54 find ${tree}* $ignore \
55 \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
56 -name "$1" -print;
57}
58
59find_sources()
60{
61 find_arch_sources $1 "$2"
62}
63
64all_sources()
65{
66 for arch in $ALLSOURCE_ARCHS
67 do
68 find_sources $arch '*.[chS]'
69 done
70 if [ ! -z "$archinclude" ]; then
71 find_arch_include_sources $archinclude '*.[chS]'
72 fi
73 find_include_sources '*.[chS]'
74 find_other_sources '*.[chS]'
75}
76
77all_kconfigs()
78{
79 find_sources $ALLSOURCE_ARCHS 'Kconfig*'
80}
81
82all_defconfigs()
83{
84 find_sources $ALLSOURCE_ARCHS "defconfig"
85}
86
87docscope()
88{
89 (echo \-k; echo \-q; all_sources) > cscope.files
90 cscope -b -f cscope.out
91}
92
93exuberant()
94{
95 all_sources | xargs $1 -a \
96 -I __initdata,__exitdata,__acquires,__releases \
97 -I __read_mostly,____cacheline_aligned \
98 -I ____cacheline_aligned_in_smp \
99 -I ____cacheline_internodealigned_in_smp \
100 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
101 --extra=+f --c-kinds=+px \
102 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'
103
104 all_kconfigs | xargs $1 -a \
105 --langdef=kconfig --language-force=kconfig \
106 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/'
107
108 all_kconfigs | xargs $1 -a \
109 --langdef=kconfig --language-force=kconfig \
110 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/'
111
112 all_defconfigs | xargs -r $1 -a \
113 --langdef=dotconfig --language-force=dotconfig \
114 --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'
115
116}
117
118emacs()
119{
120 all_sources | xargs $1 -a
121
122 all_kconfigs | xargs $1 -a \
123 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
124
125 all_kconfigs | xargs $1 -a \
126 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/'
127
128 all_defconfigs | xargs -r $1 -a \
129 --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'
130}
131
132xtags()
133{
134 if $1 --version 2>&1 | grep -iq exuberant; then
135 exuberant $1
136 elif $1 --version 2>&1 | grep -iq emacs; then
137 emacs $1
138 else
139 all_sources | xargs $1 -a
140 fi
141}
142
143
144# Support um (which uses SUBARCH)
145if [ "${ARCH}" = "um" ]; then
146 if [ "$SUBARCH" = "i386" ]; then
147 archinclude=x86
148 elif [ "$SUBARCH" = "x86_64" ]; then
149 archinclude=x86
150 else
151 archinclude=${SUBARCH}
152 fi
153fi
154
155case "$1" in
156 "cscope")
157 docscope
158 ;;
159
160 "tags")
161 xtags ctags
162 ;;
163
164 "TAGS")
165 xtags etags
166 ;;
167esac
diff --git a/scripts/trace/power.pl b/scripts/trace/power.pl
new file mode 100644
index 000000000000..4f729b3501e0
--- /dev/null
+++ b/scripts/trace/power.pl
@@ -0,0 +1,108 @@
1#!/usr/bin/perl
2
3# Copyright 2008, Intel Corporation
4#
5# This file is part of the Linux kernel
6#
7# This program file is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the
9# Free Software Foundation; version 2 of the License.
10#
11# This program is distributed in the hope that it will be useful, but WITHOUT
12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14# for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program in a file named COPYING; if not, write to the
18# Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor,
20# Boston, MA 02110-1301 USA
21#
22# Authors:
23# Arjan van de Ven <arjan@linux.intel.com>
24
25
26#
27# This script turns a cstate ftrace output into a SVG graphic that shows
28# historic C-state information
29#
30#
31# cat /sys/kernel/debug/tracing/trace | perl power.pl > out.svg
32#
33
34my @styles;
35my $base = 0;
36
37my @pstate_last;
38my @pstate_level;
39
40$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
41$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
42$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
43$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
44$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
45$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
46$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
47$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
48$styles[8] = "fill:rgb(0,25,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
49
50
51print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
52print "<svg width=\"10000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
53
54my $scale = 30000.0;
55while (<>) {
56 my $line = $_;
57 if ($line =~ /([0-9\.]+)\] CSTATE: Going to C([0-9]) on cpu ([0-9]+) for ([0-9\.]+)/) {
58 if ($base == 0) {
59 $base = $1;
60 }
61 my $time = $1 - $base;
62 $time = $time * $scale;
63 my $C = $2;
64 my $cpu = $3;
65 my $y = 400 * $cpu;
66 my $duration = $4 * $scale;
67 my $msec = int($4 * 100000)/100.0;
68 my $height = $C * 20;
69 $style = $styles[$C];
70
71 $y = $y + 140 - $height;
72
73 $x2 = $time + 4;
74 $y2 = $y + 4;
75
76
77 print "<rect x=\"$time\" width=\"$duration\" y=\"$y\" height=\"$height\" style=\"$style\"/>\n";
78 print "<text transform=\"translate($x2,$y2) rotate(90)\">C$C $msec</text>\n";
79 }
80 if ($line =~ /([0-9\.]+)\] PSTATE: Going to P([0-9]) on cpu ([0-9]+)/) {
81 my $time = $1 - $base;
82 my $state = $2;
83 my $cpu = $3;
84
85 if (defined($pstate_last[$cpu])) {
86 my $from = $pstate_last[$cpu];
87 my $oldstate = $pstate_state[$cpu];
88 my $duration = ($time-$from) * $scale;
89
90 $from = $from * $scale;
91 my $to = $from + $duration;
92 my $height = 140 - ($oldstate * (140/8));
93
94 my $y = 400 * $cpu + 200 + $height;
95 my $y2 = $y+4;
96 my $style = $styles[8];
97
98 print "<rect x=\"$from\" y=\"$y\" width=\"$duration\" height=\"5\" style=\"$style\"/>\n";
99 print "<text transform=\"translate($from,$y2)\">P$oldstate (cpu $cpu)</text>\n";
100 };
101
102 $pstate_last[$cpu] = $time;
103 $pstate_state[$cpu] = $state;
104 }
105}
106
107
108print "</svg>\n";
diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py
new file mode 100644
index 000000000000..902f9a992620
--- /dev/null
+++ b/scripts/tracing/draw_functrace.py
@@ -0,0 +1,130 @@
1#!/usr/bin/python
2
3"""
4Copyright 2008 (c) Frederic Weisbecker <fweisbec@gmail.com>
5Licensed under the terms of the GNU GPL License version 2
6
7This script parses a trace provided by the function tracer in
8kernel/trace/trace_functions.c
9The resulted trace is processed into a tree to produce a more human
10view of the call stack by drawing textual but hierarchical tree of
11calls. Only the functions's names and the the call time are provided.
12
13Usage:
14 Be sure that you have CONFIG_FUNCTION_TRACER
15 # mkdir /debugfs
16 # mount -t debug debug /debug
17 # echo function > /debug/tracing/current_tracer
18 $ cat /debug/tracing/trace_pipe > ~/raw_trace_func
19 Wait some times but not too much, the script is a bit slow.
20 Break the pipe (Ctrl + Z)
21 $ scripts/draw_functrace.py < raw_trace_func > draw_functrace
22 Then you have your drawn trace in draw_functrace
23"""
24
25
26import sys, re
27
28class CallTree:
29 """ This class provides a tree representation of the functions
30 call stack. If a function has no parent in the kernel (interrupt,
31 syscall, kernel thread...) then it is attached to a virtual parent
32 called ROOT.
33 """
34 ROOT = None
35
36 def __init__(self, func, time = None, parent = None):
37 self._func = func
38 self._time = time
39 if parent is None:
40 self._parent = CallTree.ROOT
41 else:
42 self._parent = parent
43 self._children = []
44
45 def calls(self, func, calltime):
46 """ If a function calls another one, call this method to insert it
47 into the tree at the appropriate place.
48 @return: A reference to the newly created child node.
49 """
50 child = CallTree(func, calltime, self)
51 self._children.append(child)
52 return child
53
54 def getParent(self, func):
55 """ Retrieve the last parent of the current node that
56 has the name given by func. If this function is not
57 on a parent, then create it as new child of root
58 @return: A reference to the parent.
59 """
60 tree = self
61 while tree != CallTree.ROOT and tree._func != func:
62 tree = tree._parent
63 if tree == CallTree.ROOT:
64 child = CallTree.ROOT.calls(func, None)
65 return child
66 return tree
67
68 def __repr__(self):
69 return self.__toString("", True)
70
71 def __toString(self, branch, lastChild):
72 if self._time is not None:
73 s = "%s----%s (%s)\n" % (branch, self._func, self._time)
74 else:
75 s = "%s----%s\n" % (branch, self._func)
76
77 i = 0
78 if lastChild:
79 branch = branch[:-1] + " "
80 while i < len(self._children):
81 if i != len(self._children) - 1:
82 s += "%s" % self._children[i].__toString(branch +\
83 " |", False)
84 else:
85 s += "%s" % self._children[i].__toString(branch +\
86 " |", True)
87 i += 1
88 return s
89
90class BrokenLineException(Exception):
91 """If the last line is not complete because of the pipe breakage,
92 we want to stop the processing and ignore this line.
93 """
94 pass
95
96class CommentLineException(Exception):
97 """ If the line is a comment (as in the beginning of the trace file),
98 just ignore it.
99 """
100 pass
101
102
103def parseLine(line):
104 line = line.strip()
105 if line.startswith("#"):
106 raise CommentLineException
107 m = re.match("[^]]+?\\] +([0-9.]+): (\\w+) <-(\\w+)", line)
108 if m is None:
109 raise BrokenLineException
110 return (m.group(1), m.group(2), m.group(3))
111
112
113def main():
114 CallTree.ROOT = CallTree("Root (Nowhere)", None, None)
115 tree = CallTree.ROOT
116
117 for line in sys.stdin:
118 try:
119 calltime, callee, caller = parseLine(line)
120 except BrokenLineException:
121 break
122 except CommentLineException:
123 continue
124 tree = tree.getParent(caller)
125 tree = tree.calls(callee, calltime)
126
127 print CallTree.ROOT
128
129if __name__ == "__main__":
130 main()