aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include22
-rw-r--r--scripts/Makefile.build79
-rw-r--r--scripts/Makefile.lib15
-rw-r--r--scripts/Makefile.modinst3
-rw-r--r--scripts/bootgraph.pl16
-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/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
-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.sh159
-rw-r--r--scripts/trace/power.pl108
-rw-r--r--scripts/tracing/draw_functrace.py130
30 files changed, 1350 insertions, 255 deletions
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.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..f0af9aa9b243 100644
--- a/scripts/bootgraph.pl
+++ b/scripts/bootgraph.pl
@@ -78,11 +78,13 @@ while (<>) {
78} 78}
79 79
80if ($count == 0) { 80if ($count == 0) {
81 print "No data found in the dmesg. Make sure that 'printk.time=1' and\n"; 81 print STDERR <<END;
82 print "'initcall_debug' are passed on the kernel command line.\n\n"; 82No data found in the dmesg. Make sure that 'printk.time=1' and
83 print "Usage: \n"; 83'initcall_debug' are passed on the kernel command line.
84 print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n"; 84Usage:
85 exit; 85 dmesg | perl scripts/bootgraph.pl > output.svg
86END
87 exit 1;
86} 88}
87 89
88print "<?xml version=\"1.0\" standalone=\"no\"?> \n"; 90print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
@@ -109,8 +111,8 @@ my $stylecounter = 0;
109my %rows; 111my %rows;
110my $rowscount = 1; 112my $rowscount = 1;
111my @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start); 113my @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start);
112my $key; 114
113foreach $key (@initcalls) { 115foreach my $key (@initcalls) {
114 my $duration = $end{$key} - $start{$key}; 116 my $duration = $end{$key} - $start{$key};
115 117
116 if ($duration >= $threshold) { 118 if ($duration >= $threshold) {
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/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/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..9e3451d2c3a1
--- /dev/null
+++ b/scripts/tags.sh
@@ -0,0 +1,159 @@
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# find sources in arch/$ARCH
28find_arch_sources()
29{
30 find ${tree}arch/$1 $ignore -name "$2" -print;
31}
32
33# find sources in arch/$1/include
34find_arch_include_sources()
35{
36 find ${tree}arch/$1/include $ignore -name "$2" -print;
37}
38
39# find sources in include/
40find_include_sources()
41{
42 find ${tree}include $ignore -name config -prune -o -name "$1" -print;
43}
44
45# find sources in rest of tree
46# we could benefit from a list of dirs to search in here
47find_other_sources()
48{
49 find ${tree}* $ignore \
50 \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
51 -name "$1" -print;
52}
53
54find_sources()
55{
56 find_arch_sources $1 "$2"
57 find_include_sources "$2"
58 find_other_sources "$2"
59}
60
61all_sources()
62{
63 find_sources $SRCARCH '*.[chS]'
64 if [ ! -z "$archinclude" ]; then
65 find_arch_include_sources $archinclude '*.[chS]'
66 fi
67}
68
69all_kconfigs()
70{
71 find_sources $SRCARCH 'Kconfig*'
72}
73
74all_defconfigs()
75{
76 find_sources $SRCARCH "defconfig"
77}
78
79docscope()
80{
81 (echo \-k; echo \-q; all_sources) > cscope.files
82 cscope -b -f cscope.out
83}
84
85exuberant()
86{
87 all_sources | xargs $1 -a \
88 -I __initdata,__exitdata,__acquires,__releases \
89 -I __read_mostly,____cacheline_aligned \
90 -I ____cacheline_aligned_in_smp \
91 -I ____cacheline_internodealigned_in_smp \
92 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
93 --extra=+f --c-kinds=+px \
94 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'
95
96 all_kconfigs | xargs $1 -a \
97 --langdef=kconfig --language-force=kconfig \
98 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/'
99
100 all_kconfigs | xargs $1 -a \
101 --langdef=kconfig --language-force=kconfig \
102 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/'
103
104 all_defconfigs | xargs -r $1 -a \
105 --langdef=dotconfig --language-force=dotconfig \
106 --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'
107
108}
109
110emacs()
111{
112 all_sources | xargs $1 -a
113
114 all_kconfigs | xargs $1 -a \
115 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
116
117 all_kconfigs | xargs $1 -a \
118 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/'
119
120 all_defconfigs | xargs -r $1 -a \
121 --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'
122}
123
124xtags()
125{
126 if $1 --version 2>&1 | grep -iq exuberant; then
127 exuberant $1
128 elif $1 --version 2>&1 | grep -iq emacs; then
129 emacs $1
130 else
131 all_sources | xargs $1 -a
132 fi
133}
134
135
136# Support um (which uses SUBARCH)
137if [ "${ARCH}" = "um" ]; then
138 if [ "$SUBARCH" = "i386" ]; then
139 archinclude=x86
140 elif [ "$SUBARCH" = "x86_64" ]; then
141 archinclude=x86
142 else
143 archinclude=${SUBARCH}
144 fi
145fi
146
147case "$1" in
148 "cscope")
149 docscope
150 ;;
151
152 "tags")
153 xtags ctags
154 ;;
155
156 "TAGS")
157 xtags etags
158 ;;
159esac
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()