diff options
Diffstat (limited to 'scripts')
27 files changed, 1222 insertions, 1062 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 0168d6c37075..59620b1554e0 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include | |||
| @@ -44,6 +44,43 @@ define filechk | |||
| 44 | fi | 44 | fi |
| 45 | endef | 45 | endef |
| 46 | 46 | ||
| 47 | ###### | ||
| 48 | # gcc support functions | ||
| 49 | # See documentation in Documentation/kbuild/makefiles.txt | ||
| 50 | |||
| 51 | # as-option | ||
| 52 | # Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,) | ||
| 53 | |||
| 54 | as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \ | ||
| 55 | -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \ | ||
| 56 | else echo "$(2)"; fi ;) | ||
| 57 | |||
| 58 | # cc-option | ||
| 59 | # Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) | ||
| 60 | |||
| 61 | cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ | ||
| 62 | > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) | ||
| 63 | |||
| 64 | # cc-option-yn | ||
| 65 | # Usage: flag := $(call cc-option-yn, -march=winchip-c6) | ||
| 66 | cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ | ||
| 67 | > /dev/null 2>&1; then echo "y"; else echo "n"; fi;) | ||
| 68 | |||
| 69 | # cc-option-align | ||
| 70 | # Prefix align with either -falign or -malign | ||
| 71 | cc-option-align = $(subst -functions=0,,\ | ||
| 72 | $(call cc-option,-falign-functions=0,-malign-functions=0)) | ||
| 73 | |||
| 74 | # cc-version | ||
| 75 | # Usage gcc-ver := $(call cc-version, $(CC)) | ||
| 76 | cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \ | ||
| 77 | $(if $(1), $(1), $(CC))) | ||
| 78 | |||
| 79 | # cc-ifversion | ||
| 80 | # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) | ||
| 81 | cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \ | ||
| 82 | echo $(3); fi;) | ||
| 83 | |||
| 47 | ### | 84 | ### |
| 48 | # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= | 85 | # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= |
| 49 | # Usage: | 86 | # Usage: |
| @@ -51,8 +88,7 @@ endef | |||
| 51 | build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj | 88 | build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj |
| 52 | 89 | ||
| 53 | # If quiet is set, only print short version of command | 90 | # If quiet is set, only print short version of command |
| 54 | cmd = @$(if $($(quiet)cmd_$(1)),\ | 91 | cmd = @$(echo-cmd) $(cmd_$(1)) |
| 55 | echo ' $(call escsq,$($(quiet)cmd_$(1)))' &&) $(cmd_$(1)) | ||
| 56 | 92 | ||
| 57 | # Add $(obj)/ for paths that is not absolute | 93 | # Add $(obj)/ for paths that is not absolute |
| 58 | objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) | 94 | objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) |
| @@ -75,30 +111,33 @@ endif | |||
| 75 | echo-cmd = $(if $($(quiet)cmd_$(1)), \ | 111 | echo-cmd = $(if $($(quiet)cmd_$(1)), \ |
| 76 | echo ' $(call escsq,$($(quiet)cmd_$(1)))';) | 112 | echo ' $(call escsq,$($(quiet)cmd_$(1)))';) |
| 77 | 113 | ||
| 114 | make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))) | ||
| 115 | |||
| 78 | # function to only execute the passed command if necessary | 116 | # function to only execute the passed command if necessary |
| 79 | # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file | 117 | # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file |
| 80 | # note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars | 118 | # note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars |
| 81 | # | 119 | # |
| 82 | if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | 120 | if_changed = $(if $(strip $(filter-out $(PHONY),$?) \ |
| 121 | $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | ||
| 83 | @set -e; \ | 122 | @set -e; \ |
| 84 | $(echo-cmd) \ | 123 | $(echo-cmd) $(cmd_$(1)); \ |
| 85 | $(cmd_$(1)); \ | 124 | echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd) |
| 86 | echo 'cmd_$@ := $(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).cmd) | ||
| 87 | 125 | ||
| 88 | # execute the command and also postprocess generated .d dependencies | 126 | # execute the command and also postprocess generated .d dependencies |
| 89 | # file | 127 | # file |
| 90 | if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ | 128 | if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?) \ |
| 91 | $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | 129 | $(filter-out FORCE $(wildcard $^),$^) \ |
| 130 | $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | ||
| 92 | @set -e; \ | 131 | @set -e; \ |
| 93 | $(echo-cmd) \ | 132 | $(echo-cmd) $(cmd_$(1)); \ |
| 94 | $(cmd_$(1)); \ | 133 | scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \ |
| 95 | scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \ | ||
| 96 | rm -f $(depfile); \ | 134 | rm -f $(depfile); \ |
| 97 | mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) | 135 | mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) |
| 98 | 136 | ||
| 99 | # Usage: $(call if_changed_rule,foo) | 137 | # Usage: $(call if_changed_rule,foo) |
| 100 | # will check if $(cmd_foo) changed, or any of the prequisites changed, | 138 | # will check if $(cmd_foo) changed, or any of the prequisites changed, |
| 101 | # and if so will execute $(rule_foo) | 139 | # and if so will execute $(rule_foo) |
| 102 | if_changed_rule = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ | 140 | if_changed_rule = $(if $(strip $(filter-out $(PHONY),$?) \ |
| 141 | $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ | ||
| 103 | @set -e; \ | 142 | @set -e; \ |
| 104 | $(rule_$(1))) | 143 | $(rule_$(1))) |
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index c33e62bde6b0..e48e60da3040 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build | |||
| @@ -4,17 +4,18 @@ | |||
| 4 | 4 | ||
| 5 | src := $(obj) | 5 | src := $(obj) |
| 6 | 6 | ||
| 7 | .PHONY: __build | 7 | PHONY := __build |
| 8 | __build: | 8 | __build: |
| 9 | 9 | ||
| 10 | # Read .config if it exist, otherwise ignore | 10 | # Read .config if it exist, otherwise ignore |
| 11 | -include .config | 11 | -include .config |
| 12 | 12 | ||
| 13 | include scripts/Kbuild.include | ||
| 14 | |||
| 13 | # The filename Kbuild has precedence over Makefile | 15 | # The filename Kbuild has precedence over Makefile |
| 14 | kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) | 16 | kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) |
| 15 | include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) | 17 | include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) |
| 16 | 18 | ||
| 17 | include scripts/Kbuild.include | ||
| 18 | include scripts/Makefile.lib | 19 | include scripts/Makefile.lib |
| 19 | 20 | ||
| 20 | ifdef host-progs | 21 | ifdef host-progs |
| @@ -128,7 +129,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi) | |||
| 128 | $(multi-objs-y:.o=.lst) : modname = $(modname-multi) | 129 | $(multi-objs-y:.o=.lst) : modname = $(modname-multi) |
| 129 | 130 | ||
| 130 | quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ | 131 | quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ |
| 131 | cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< | 132 | cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $< |
| 132 | 133 | ||
| 133 | %.s: %.c FORCE | 134 | %.s: %.c FORCE |
| 134 | $(call if_changed_dep,cc_s_c) | 135 | $(call if_changed_dep,cc_s_c) |
| @@ -165,7 +166,7 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< | |||
| 165 | cmd_modversions = \ | 166 | cmd_modversions = \ |
| 166 | if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ | 167 | if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ |
| 167 | $(CPP) -D__GENKSYMS__ $(c_flags) $< \ | 168 | $(CPP) -D__GENKSYMS__ $(c_flags) $< \ |
| 168 | | $(GENKSYMS) \ | 169 | | $(GENKSYMS) -a $(ARCH) \ |
| 169 | > $(@D)/.tmp_$(@F:.o=.ver); \ | 170 | > $(@D)/.tmp_$(@F:.o=.ver); \ |
| 170 | \ | 171 | \ |
| 171 | $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ | 172 | $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ |
| @@ -177,12 +178,10 @@ cmd_modversions = \ | |||
| 177 | endif | 178 | endif |
| 178 | 179 | ||
| 179 | define rule_cc_o_c | 180 | define rule_cc_o_c |
| 180 | $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \ | 181 | $(call echo-cmd,checksrc) $(cmd_checksrc) \ |
| 181 | $(cmd_checksrc) \ | 182 | $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ |
| 182 | $(if $($(quiet)cmd_cc_o_c),echo ' $(call escsq,$($(quiet)cmd_cc_o_c))';) \ | ||
| 183 | $(cmd_cc_o_c); \ | ||
| 184 | $(cmd_modversions) \ | 183 | $(cmd_modversions) \ |
| 185 | scripts/basic/fixdep $(depfile) $@ '$(call escsq,$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp; \ | 184 | scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > $(@D)/.$(@F).tmp; \ |
| 186 | rm -f $(depfile); \ | 185 | rm -f $(depfile); \ |
| 187 | mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd | 186 | mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd |
| 188 | endef | 187 | endef |
| @@ -309,14 +308,14 @@ targets += $(multi-used-y) $(multi-used-m) | |||
| 309 | # Descending | 308 | # Descending |
| 310 | # --------------------------------------------------------------------------- | 309 | # --------------------------------------------------------------------------- |
| 311 | 310 | ||
| 312 | .PHONY: $(subdir-ym) | 311 | PHONY += $(subdir-ym) |
| 313 | $(subdir-ym): | 312 | $(subdir-ym): |
| 314 | $(Q)$(MAKE) $(build)=$@ | 313 | $(Q)$(MAKE) $(build)=$@ |
| 315 | 314 | ||
| 316 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. | 315 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. |
| 317 | # --------------------------------------------------------------------------- | 316 | # --------------------------------------------------------------------------- |
| 318 | 317 | ||
| 319 | .PHONY: FORCE | 318 | PHONY += FORCE |
| 320 | 319 | ||
| 321 | FORCE: | 320 | FORCE: |
| 322 | 321 | ||
| @@ -331,3 +330,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) | |||
| 331 | ifneq ($(cmd_files),) | 330 | ifneq ($(cmd_files),) |
| 332 | include $(cmd_files) | 331 | include $(cmd_files) |
| 333 | endif | 332 | endif |
| 333 | |||
| 334 | |||
| 335 | # Declare the contents of the .PHONY variable as phony. We keep that | ||
| 336 | # information in a variable se we can use it in if_changed and friends. | ||
| 337 | |||
| 338 | .PHONY: $(PHONY) | ||
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 8974ea5fc878..cff33498fa16 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | src := $(obj) | 5 | src := $(obj) |
| 6 | 6 | ||
| 7 | .PHONY: __clean | 7 | PHONY := __clean |
| 8 | __clean: | 8 | __clean: |
| 9 | 9 | ||
| 10 | # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir | 10 | # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir |
| @@ -87,10 +87,16 @@ endif | |||
| 87 | # Descending | 87 | # Descending |
| 88 | # --------------------------------------------------------------------------- | 88 | # --------------------------------------------------------------------------- |
| 89 | 89 | ||
| 90 | .PHONY: $(subdir-ymn) | 90 | PHONY += $(subdir-ymn) |
| 91 | $(subdir-ymn): | 91 | $(subdir-ymn): |
| 92 | $(Q)$(MAKE) $(clean)=$@ | 92 | $(Q)$(MAKE) $(clean)=$@ |
| 93 | 93 | ||
| 94 | # If quiet is set, only print short version of command | 94 | # If quiet is set, only print short version of command |
| 95 | 95 | ||
| 96 | cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1)) | 96 | cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1)) |
| 97 | |||
| 98 | |||
| 99 | # Declare the contents of the .PHONY variable as phony. We keep that | ||
| 100 | # information in a variable se we can use it in if_changed and friends. | ||
| 101 | |||
| 102 | .PHONY: $(PHONY) | ||
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 23fd1bdc25ce..2686dd5dce8c 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Installing modules | 2 | # Installing modules |
| 3 | # ========================================================================== | 3 | # ========================================================================== |
| 4 | 4 | ||
| 5 | .PHONY: __modinst | 5 | PHONY := __modinst |
| 6 | __modinst: | 6 | __modinst: |
| 7 | 7 | ||
| 8 | include scripts/Kbuild.include | 8 | include scripts/Kbuild.include |
| @@ -12,7 +12,7 @@ include scripts/Kbuild.include | |||
| 12 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) | 12 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) |
| 13 | modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) | 13 | modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) |
| 14 | 14 | ||
| 15 | .PHONY: $(modules) | 15 | PHONY += $(modules) |
| 16 | __modinst: $(modules) | 16 | __modinst: $(modules) |
| 17 | @: | 17 | @: |
| 18 | 18 | ||
| @@ -27,3 +27,9 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) | |||
| 27 | 27 | ||
| 28 | $(modules): | 28 | $(modules): |
| 29 | $(call cmd,modules_install,$(MODLIB)/$(modinst_dir)) | 29 | $(call cmd,modules_install,$(MODLIB)/$(modinst_dir)) |
| 30 | |||
| 31 | |||
| 32 | # Declare the contents of the .PHONY variable as phony. We keep that | ||
| 33 | # information in a variable se we can use it in if_changed and friends. | ||
| 34 | |||
| 35 | .PHONY: $(PHONY) | ||
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index bf96a61d4b86..0e056cffffdb 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | # | 4 | # |
| 5 | # Stage one of module building created the following: | 5 | # Stage one of module building created the following: |
| 6 | # a) The individual .o files used for the module | 6 | # a) The individual .o files used for the module |
| 7 | # b) A <module>.o file wich is the .o files above linked together | 7 | # b) A <module>.o file which is the .o files above linked together |
| 8 | # c) A <module>.mod file in $(MODVERDIR)/, listing the name of the | 8 | # c) A <module>.mod file in $(MODVERDIR)/, listing the name of the |
| 9 | # the preliminary <module>.o file, plus all .o files | 9 | # the preliminary <module>.o file, plus all .o files |
| 10 | 10 | ||
| @@ -32,14 +32,15 @@ | |||
| 32 | # Step 4 is solely used to allow module versioning in external modules, | 32 | # Step 4 is solely used to allow module versioning in external modules, |
| 33 | # where the CRC of each module is retrieved from the Module.symers file. | 33 | # where the CRC of each module is retrieved from the Module.symers file. |
| 34 | 34 | ||
| 35 | .PHONY: _modpost | 35 | PHONY := _modpost |
| 36 | _modpost: __modpost | 36 | _modpost: __modpost |
| 37 | 37 | ||
| 38 | include .config | 38 | include .config |
| 39 | include scripts/Kbuild.include | 39 | include scripts/Kbuild.include |
| 40 | include scripts/Makefile.lib | 40 | include scripts/Makefile.lib |
| 41 | 41 | ||
| 42 | symverfile := $(objtree)/Module.symvers | 42 | kernelsymfile := $(objtree)/Module.symvers |
| 43 | modulesymfile := $(KBUILD_EXTMOD)/Modules.symvers | ||
| 43 | 44 | ||
| 44 | # Step 1), find all modules listed in $(MODVERDIR)/ | 45 | # Step 1), find all modules listed in $(MODVERDIR)/ |
| 45 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) | 46 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) |
| @@ -54,10 +55,12 @@ quiet_cmd_modpost = MODPOST | |||
| 54 | cmd_modpost = scripts/mod/modpost \ | 55 | cmd_modpost = scripts/mod/modpost \ |
| 55 | $(if $(CONFIG_MODVERSIONS),-m) \ | 56 | $(if $(CONFIG_MODVERSIONS),-m) \ |
| 56 | $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ | 57 | $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ |
| 57 | $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \ | 58 | $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ |
| 59 | $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ | ||
| 60 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ | ||
| 58 | $(filter-out FORCE,$^) | 61 | $(filter-out FORCE,$^) |
| 59 | 62 | ||
| 60 | .PHONY: __modpost | 63 | PHONY += __modpost |
| 61 | __modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE | 64 | __modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE |
| 62 | $(call cmd,modpost) | 65 | $(call cmd,modpost) |
| 63 | 66 | ||
| @@ -94,7 +97,7 @@ targets += $(modules) | |||
| 94 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. | 97 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. |
| 95 | # --------------------------------------------------------------------------- | 98 | # --------------------------------------------------------------------------- |
| 96 | 99 | ||
| 97 | .PHONY: FORCE | 100 | PHONY += FORCE |
| 98 | 101 | ||
| 99 | FORCE: | 102 | FORCE: |
| 100 | 103 | ||
| @@ -109,3 +112,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) | |||
| 109 | ifneq ($(cmd_files),) | 112 | ifneq ($(cmd_files),) |
| 110 | include $(cmd_files) | 113 | include $(cmd_files) |
| 111 | endif | 114 | endif |
| 115 | |||
| 116 | |||
| 117 | # Declare the contents of the .PHONY variable as phony. We keep that | ||
| 118 | # information in a variable se we can use it in if_changed and friends. | ||
| 119 | |||
| 120 | .PHONY: $(PHONY) | ||
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 679124b11e12..668a11a8b383 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
| @@ -132,20 +132,10 @@ void usage(void) | |||
| 132 | 132 | ||
| 133 | /* | 133 | /* |
| 134 | * Print out the commandline prefixed with cmd_<target filename> := | 134 | * Print out the commandline prefixed with cmd_<target filename> := |
| 135 | * If commandline contains '#' escape with '\' so make to not see | 135 | */ |
| 136 | * the '#' as a start-of-comment symbol | ||
| 137 | **/ | ||
| 138 | void print_cmdline(void) | 136 | void print_cmdline(void) |
| 139 | { | 137 | { |
| 140 | char *p = cmdline; | 138 | printf("cmd_%s := %s\n\n", target, cmdline); |
| 141 | |||
| 142 | printf("cmd_%s := ", target); | ||
| 143 | for (; *p; p++) { | ||
| 144 | if (*p == '#') | ||
| 145 | printf("\\"); | ||
| 146 | printf("%c", *p); | ||
| 147 | } | ||
| 148 | printf("\n\n"); | ||
| 149 | } | 139 | } |
| 150 | 140 | ||
| 151 | char * str_config = NULL; | 141 | char * str_config = NULL; |
diff --git a/scripts/checkconfig.pl b/scripts/checkconfig.pl deleted file mode 100755 index ca1f231b15a6..000000000000 --- a/scripts/checkconfig.pl +++ /dev/null | |||
| @@ -1,65 +0,0 @@ | |||
| 1 | #! /usr/bin/perl | ||
| 2 | # | ||
| 3 | # checkconfig: find uses of CONFIG_* names without matching definitions. | ||
| 4 | # Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>. | ||
| 5 | |||
| 6 | use integer; | ||
| 7 | |||
| 8 | $| = 1; | ||
| 9 | |||
| 10 | foreach $file (@ARGV) | ||
| 11 | { | ||
| 12 | # Open this file. | ||
| 13 | open(FILE, $file) || die "Can't open $file: $!\n"; | ||
| 14 | |||
| 15 | # Initialize variables. | ||
| 16 | my $fInComment = 0; | ||
| 17 | my $fInString = 0; | ||
| 18 | my $fUseConfig = 0; | ||
| 19 | my $iLinuxConfig = 0; | ||
| 20 | my %configList = (); | ||
| 21 | |||
| 22 | LINE: while ( <FILE> ) | ||
| 23 | { | ||
| 24 | # Strip comments. | ||
| 25 | $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); | ||
| 26 | m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); | ||
| 27 | |||
| 28 | # Pick up definitions. | ||
| 29 | if ( m/^\s*#/o ) | ||
| 30 | { | ||
| 31 | $iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o; | ||
| 32 | $configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o; | ||
| 33 | } | ||
| 34 | |||
| 35 | # Strip strings. | ||
| 36 | $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next); | ||
| 37 | m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1))); | ||
| 38 | |||
| 39 | # Pick up definitions. | ||
| 40 | if ( m/^\s*#/o ) | ||
| 41 | { | ||
| 42 | $iLinuxConfig = $. if m/^\s*#\s*include\s*<linux\/config\.h>/o; | ||
| 43 | $configList{uc $1} = 1 if m/^\s*#\s*include\s*<config\/(\S*)\.h>/o; | ||
| 44 | $configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o; | ||
| 45 | $configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o; | ||
| 46 | } | ||
| 47 | |||
| 48 | # Look for usages. | ||
| 49 | next unless m/CONFIG_/o; | ||
| 50 | WORD: while ( m/\bCONFIG_(\w+)/og ) | ||
| 51 | { | ||
| 52 | $fUseConfig = 1; | ||
| 53 | last LINE if $iLinuxConfig; | ||
| 54 | next WORD if exists $configList{$1}; | ||
| 55 | print "$file: $.: need CONFIG_$1.\n"; | ||
| 56 | $configList{$1} = 0; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | # Report superfluous includes. | ||
| 61 | if ( $iLinuxConfig && ! $fUseConfig ) | ||
| 62 | { print "$file: $iLinuxConfig: linux/config.h not needed.\n"; } | ||
| 63 | |||
| 64 | close(FILE); | ||
| 65 | } | ||
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index d9f9f34b22ab..8187e6f0dc2f 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | # $arg1 is [b]zImage filename | 4 | # $arg1 is [b]zImage filename |
| 5 | 5 | ||
| 6 | binoffset="./scripts/binoffset" | 6 | binoffset="./scripts/binoffset" |
| 7 | test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1 | ||
| 7 | 8 | ||
| 8 | IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54" | 9 | IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54" |
| 9 | IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" | 10 | IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" |
| @@ -20,7 +21,7 @@ function dump_config { | |||
| 20 | let start="$start + 8" | 21 | let start="$start + 8" |
| 21 | let size="$end - $start" | 22 | let size="$end - $start" |
| 22 | 23 | ||
| 23 | head --bytes="$end" "$file" | tail --bytes="$size" | zcat | 24 | dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat |
| 24 | 25 | ||
| 25 | clean_up | 26 | clean_up |
| 26 | exit 0 | 27 | exit 0 |
| @@ -45,7 +46,7 @@ then | |||
| 45 | exit 1 | 46 | exit 1 |
| 46 | fi | 47 | fi |
| 47 | 48 | ||
| 48 | TMPFILE="/tmp/ikconfig-$$" | 49 | TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 1 |
| 49 | image="$1" | 50 | image="$1" |
| 50 | 51 | ||
| 51 | # vmlinux: Attempt to dump the configuration from the file directly | 52 | # vmlinux: Attempt to dump the configuration from the file directly |
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 416a694b0998..5b0344e20d61 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c | |||
| @@ -29,481 +29,421 @@ | |||
| 29 | #include <stdarg.h> | 29 | #include <stdarg.h> |
| 30 | #ifdef __GNU_LIBRARY__ | 30 | #ifdef __GNU_LIBRARY__ |
| 31 | #include <getopt.h> | 31 | #include <getopt.h> |
| 32 | #endif /* __GNU_LIBRARY__ */ | 32 | #endif /* __GNU_LIBRARY__ */ |
| 33 | 33 | ||
| 34 | #include "genksyms.h" | 34 | #include "genksyms.h" |
| 35 | |||
| 36 | /*----------------------------------------------------------------------*/ | 35 | /*----------------------------------------------------------------------*/ |
| 37 | 36 | ||
| 38 | #define HASH_BUCKETS 4096 | 37 | #define HASH_BUCKETS 4096 |
| 39 | 38 | ||
| 40 | static struct symbol *symtab[HASH_BUCKETS]; | 39 | static struct symbol *symtab[HASH_BUCKETS]; |
| 41 | FILE *debugfile; | 40 | static FILE *debugfile; |
| 42 | 41 | ||
| 43 | int cur_line = 1; | 42 | int cur_line = 1; |
| 44 | char *cur_filename, *output_directory; | 43 | char *cur_filename; |
| 45 | 44 | ||
| 46 | int flag_debug, flag_dump_defs, flag_warnings; | 45 | static int flag_debug, flag_dump_defs, flag_warnings; |
| 46 | static const char *arch = ""; | ||
| 47 | static const char *mod_prefix = ""; | ||
| 47 | 48 | ||
| 48 | static int errors; | 49 | static int errors; |
| 49 | static int nsyms; | 50 | static int nsyms; |
| 50 | 51 | ||
| 51 | static struct symbol *expansion_trail; | 52 | static struct symbol *expansion_trail; |
| 52 | 53 | ||
| 53 | static const char * const symbol_type_name[] = { | 54 | static const char *const symbol_type_name[] = { |
| 54 | "normal", "typedef", "enum", "struct", "union" | 55 | "normal", "typedef", "enum", "struct", "union" |
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| 58 | static int equal_list(struct string_list *a, struct string_list *b); | ||
| 59 | static void print_list(FILE * f, struct string_list *list); | ||
| 60 | |||
| 57 | /*----------------------------------------------------------------------*/ | 61 | /*----------------------------------------------------------------------*/ |
| 58 | 62 | ||
| 59 | static const unsigned int crctab32[] = | 63 | static const unsigned int crctab32[] = { |
| 60 | { | 64 | 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, |
| 61 | 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, | 65 | 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, |
| 62 | 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, | 66 | 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, |
| 63 | 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, | 67 | 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, |
| 64 | 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, | 68 | 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, |
| 65 | 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, | 69 | 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, |
| 66 | 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, | 70 | 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, |
| 67 | 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, | 71 | 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, |
| 68 | 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, | 72 | 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, |
| 69 | 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, | 73 | 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, |
| 70 | 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, | 74 | 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, |
| 71 | 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, | 75 | 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, |
| 72 | 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, | 76 | 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, |
| 73 | 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, | 77 | 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, |
| 74 | 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, | 78 | 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, |
| 75 | 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, | 79 | 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, |
| 76 | 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, | 80 | 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, |
| 77 | 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, | 81 | 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, |
| 78 | 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, | 82 | 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, |
| 79 | 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, | 83 | 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, |
| 80 | 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, | 84 | 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, |
| 81 | 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, | 85 | 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, |
| 82 | 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, | 86 | 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, |
| 83 | 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, | 87 | 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, |
| 84 | 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, | 88 | 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, |
| 85 | 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, | 89 | 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, |
| 86 | 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, | 90 | 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, |
| 87 | 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, | 91 | 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, |
| 88 | 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, | 92 | 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, |
| 89 | 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, | 93 | 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, |
| 90 | 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, | 94 | 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, |
| 91 | 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, | 95 | 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, |
| 92 | 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, | 96 | 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, |
| 93 | 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, | 97 | 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, |
| 94 | 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, | 98 | 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, |
| 95 | 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, | 99 | 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, |
| 96 | 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, | 100 | 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, |
| 97 | 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, | 101 | 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, |
| 98 | 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, | 102 | 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, |
| 99 | 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, | 103 | 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, |
| 100 | 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, | 104 | 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, |
| 101 | 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, | 105 | 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, |
| 102 | 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, | 106 | 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, |
| 103 | 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, | 107 | 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, |
| 104 | 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, | 108 | 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, |
| 105 | 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, | 109 | 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, |
| 106 | 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, | 110 | 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, |
| 107 | 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, | 111 | 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, |
| 108 | 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, | 112 | 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, |
| 109 | 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, | 113 | 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, |
| 110 | 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, | 114 | 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, |
| 111 | 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, | 115 | 0x2d02ef8dU |
| 112 | 0x2d02ef8dU | ||
| 113 | }; | 116 | }; |
| 114 | 117 | ||
| 115 | static inline unsigned long | 118 | static unsigned long partial_crc32_one(unsigned char c, unsigned long crc) |
| 116 | partial_crc32_one(unsigned char c, unsigned long crc) | ||
| 117 | { | 119 | { |
| 118 | return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); | 120 | return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); |
| 119 | } | 121 | } |
| 120 | 122 | ||
| 121 | static inline unsigned long | 123 | static unsigned long partial_crc32(const char *s, unsigned long crc) |
| 122 | partial_crc32(const char *s, unsigned long crc) | ||
| 123 | { | 124 | { |
| 124 | while (*s) | 125 | while (*s) |
| 125 | crc = partial_crc32_one(*s++, crc); | 126 | crc = partial_crc32_one(*s++, crc); |
| 126 | return crc; | 127 | return crc; |
| 127 | } | 128 | } |
| 128 | 129 | ||
| 129 | static inline unsigned long | 130 | static unsigned long crc32(const char *s) |
| 130 | crc32(const char *s) | ||
| 131 | { | 131 | { |
| 132 | return partial_crc32(s, 0xffffffff) ^ 0xffffffff; | 132 | return partial_crc32(s, 0xffffffff) ^ 0xffffffff; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | |||
| 136 | /*----------------------------------------------------------------------*/ | 135 | /*----------------------------------------------------------------------*/ |
| 137 | 136 | ||
| 138 | static inline enum symbol_type | 137 | static enum symbol_type map_to_ns(enum symbol_type t) |
| 139 | map_to_ns(enum symbol_type t) | ||
| 140 | { | 138 | { |
| 141 | if (t == SYM_TYPEDEF) | 139 | if (t == SYM_TYPEDEF) |
| 142 | t = SYM_NORMAL; | 140 | t = SYM_NORMAL; |
| 143 | else if (t == SYM_UNION) | 141 | else if (t == SYM_UNION) |
| 144 | t = SYM_STRUCT; | 142 | t = SYM_STRUCT; |
| 145 | return t; | 143 | return t; |
| 146 | } | 144 | } |
| 147 | 145 | ||
| 148 | struct symbol * | 146 | struct symbol *find_symbol(const char *name, enum symbol_type ns) |
| 149 | find_symbol(const char *name, enum symbol_type ns) | ||
| 150 | { | 147 | { |
| 151 | unsigned long h = crc32(name) % HASH_BUCKETS; | 148 | unsigned long h = crc32(name) % HASH_BUCKETS; |
| 152 | struct symbol *sym; | 149 | struct symbol *sym; |
| 153 | 150 | ||
| 154 | for (sym = symtab[h]; sym ; sym = sym->hash_next) | 151 | for (sym = symtab[h]; sym; sym = sym->hash_next) |
| 155 | if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0) | 152 | if (map_to_ns(sym->type) == map_to_ns(ns) && |
| 156 | break; | 153 | strcmp(name, sym->name) == 0) |
| 154 | break; | ||
| 157 | 155 | ||
| 158 | return sym; | 156 | return sym; |
| 159 | } | 157 | } |
| 160 | 158 | ||
| 161 | struct symbol * | 159 | struct symbol *add_symbol(const char *name, enum symbol_type type, |
| 162 | add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern) | 160 | struct string_list *defn, int is_extern) |
| 163 | { | 161 | { |
| 164 | unsigned long h = crc32(name) % HASH_BUCKETS; | 162 | unsigned long h = crc32(name) % HASH_BUCKETS; |
| 165 | struct symbol *sym; | 163 | struct symbol *sym; |
| 166 | 164 | ||
| 167 | for (sym = symtab[h]; sym ; sym = sym->hash_next) | 165 | for (sym = symtab[h]; sym; sym = sym->hash_next) { |
| 168 | if (map_to_ns(sym->type) == map_to_ns(type) | 166 | if (map_to_ns(sym->type) == map_to_ns(type) |
| 169 | && strcmp(name, sym->name) == 0) | 167 | && strcmp(name, sym->name) == 0) { |
| 170 | { | 168 | if (!equal_list(sym->defn, defn)) |
| 171 | if (!equal_list(sym->defn, defn)) | 169 | error_with_pos("redefinition of %s", name); |
| 172 | error_with_pos("redefinition of %s", name); | 170 | return sym; |
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | sym = xmalloc(sizeof(*sym)); | ||
| 175 | sym->name = name; | ||
| 176 | sym->type = type; | ||
| 177 | sym->defn = defn; | ||
| 178 | sym->expansion_trail = NULL; | ||
| 179 | sym->is_extern = is_extern; | ||
| 180 | |||
| 181 | sym->hash_next = symtab[h]; | ||
| 182 | symtab[h] = sym; | ||
| 183 | |||
| 184 | if (flag_debug) { | ||
| 185 | fprintf(debugfile, "Defn for %s %s == <", | ||
| 186 | symbol_type_name[type], name); | ||
| 187 | if (is_extern) | ||
| 188 | fputs("extern ", debugfile); | ||
| 189 | print_list(debugfile, defn); | ||
| 190 | fputs(">\n", debugfile); | ||
| 191 | } | ||
| 192 | |||
| 193 | ++nsyms; | ||
| 173 | return sym; | 194 | return sym; |
| 174 | } | ||
| 175 | |||
| 176 | sym = xmalloc(sizeof(*sym)); | ||
| 177 | sym->name = name; | ||
| 178 | sym->type = type; | ||
| 179 | sym->defn = defn; | ||
| 180 | sym->expansion_trail = NULL; | ||
| 181 | sym->is_extern = is_extern; | ||
| 182 | |||
| 183 | sym->hash_next = symtab[h]; | ||
| 184 | symtab[h] = sym; | ||
| 185 | |||
| 186 | if (flag_debug) | ||
| 187 | { | ||
| 188 | fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type], name); | ||
| 189 | if (is_extern) | ||
| 190 | fputs("extern ", debugfile); | ||
| 191 | print_list(debugfile, defn); | ||
| 192 | fputs(">\n", debugfile); | ||
| 193 | } | ||
| 194 | |||
| 195 | ++nsyms; | ||
| 196 | return sym; | ||
| 197 | } | 195 | } |
| 198 | 196 | ||
| 199 | |||
| 200 | /*----------------------------------------------------------------------*/ | 197 | /*----------------------------------------------------------------------*/ |
| 201 | 198 | ||
| 202 | inline void | 199 | void free_node(struct string_list *node) |
| 203 | free_node(struct string_list *node) | ||
| 204 | { | 200 | { |
| 205 | free(node->string); | 201 | free(node->string); |
| 206 | free(node); | 202 | free(node); |
| 207 | } | 203 | } |
| 208 | 204 | ||
| 209 | void | 205 | void free_list(struct string_list *s, struct string_list *e) |
| 210 | free_list(struct string_list *s, struct string_list *e) | ||
| 211 | { | 206 | { |
| 212 | while (s != e) | 207 | while (s != e) { |
| 213 | { | 208 | struct string_list *next = s->next; |
| 214 | struct string_list *next = s->next; | 209 | free_node(s); |
| 215 | free_node(s); | 210 | s = next; |
| 216 | s = next; | 211 | } |
| 217 | } | ||
| 218 | } | 212 | } |
| 219 | 213 | ||
| 220 | inline struct string_list * | 214 | struct string_list *copy_node(struct string_list *node) |
| 221 | copy_node(struct string_list *node) | ||
| 222 | { | 215 | { |
| 223 | struct string_list *newnode; | 216 | struct string_list *newnode; |
| 224 | 217 | ||
| 225 | newnode = xmalloc(sizeof(*newnode)); | 218 | newnode = xmalloc(sizeof(*newnode)); |
| 226 | newnode->string = xstrdup(node->string); | 219 | newnode->string = xstrdup(node->string); |
| 227 | newnode->tag = node->tag; | 220 | newnode->tag = node->tag; |
| 228 | 221 | ||
| 229 | return newnode; | 222 | return newnode; |
| 230 | } | 223 | } |
| 231 | 224 | ||
| 232 | struct string_list * | 225 | static int equal_list(struct string_list *a, struct string_list *b) |
| 233 | copy_list(struct string_list *s, struct string_list *e) | ||
| 234 | { | 226 | { |
| 235 | struct string_list *h, *p; | 227 | while (a && b) { |
| 236 | 228 | if (a->tag != b->tag || strcmp(a->string, b->string)) | |
| 237 | if (s == e) | 229 | return 0; |
| 238 | return NULL; | 230 | a = a->next; |
| 239 | 231 | b = b->next; | |
| 240 | p = h = copy_node(s); | 232 | } |
| 241 | while ((s = s->next) != e) | ||
| 242 | p = p->next = copy_node(s); | ||
| 243 | p->next = NULL; | ||
| 244 | |||
| 245 | return h; | ||
| 246 | } | ||
| 247 | 233 | ||
| 248 | int | 234 | return !a && !b; |
| 249 | equal_list(struct string_list *a, struct string_list *b) | ||
| 250 | { | ||
| 251 | while (a && b) | ||
| 252 | { | ||
| 253 | if (a->tag != b->tag || strcmp(a->string, b->string)) | ||
| 254 | return 0; | ||
| 255 | a = a->next; | ||
| 256 | b = b->next; | ||
| 257 | } | ||
| 258 | |||
| 259 | return !a && !b; | ||
| 260 | } | 235 | } |
| 261 | 236 | ||
| 262 | static inline void | 237 | static void print_node(FILE * f, struct string_list *list) |
| 263 | print_node(FILE *f, struct string_list *list) | ||
| 264 | { | 238 | { |
| 265 | switch (list->tag) | 239 | switch (list->tag) { |
| 266 | { | 240 | case SYM_STRUCT: |
| 267 | case SYM_STRUCT: | 241 | putc('s', f); |
| 268 | putc('s', f); | 242 | goto printit; |
| 269 | goto printit; | 243 | case SYM_UNION: |
| 270 | case SYM_UNION: | 244 | putc('u', f); |
| 271 | putc('u', f); | 245 | goto printit; |
| 272 | goto printit; | 246 | case SYM_ENUM: |
| 273 | case SYM_ENUM: | 247 | putc('e', f); |
| 274 | putc('e', f); | 248 | goto printit; |
| 275 | goto printit; | 249 | case SYM_TYPEDEF: |
| 276 | case SYM_TYPEDEF: | 250 | putc('t', f); |
| 277 | putc('t', f); | 251 | goto printit; |
| 278 | goto printit; | ||
| 279 | |||
| 280 | printit: | ||
| 281 | putc('#', f); | ||
| 282 | case SYM_NORMAL: | ||
| 283 | fputs(list->string, f); | ||
| 284 | break; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | 252 | ||
| 288 | void | 253 | printit: |
| 289 | print_list(FILE *f, struct string_list *list) | 254 | putc('#', f); |
| 290 | { | 255 | case SYM_NORMAL: |
| 291 | struct string_list **e, **b; | 256 | fputs(list->string, f); |
| 292 | struct string_list *tmp, **tmp2; | 257 | break; |
| 293 | int elem = 1; | 258 | } |
| 294 | |||
| 295 | if (list == NULL) | ||
| 296 | { | ||
| 297 | fputs("(nil)", f); | ||
| 298 | return; | ||
| 299 | } | ||
| 300 | |||
| 301 | tmp = list; | ||
| 302 | while((tmp = tmp->next) != NULL) | ||
| 303 | elem++; | ||
| 304 | |||
| 305 | b = alloca(elem * sizeof(*e)); | ||
| 306 | e = b + elem; | ||
| 307 | tmp2 = e - 1; | ||
| 308 | |||
| 309 | (*tmp2--) = list; | ||
| 310 | while((list = list->next) != NULL) | ||
| 311 | *(tmp2--) = list; | ||
| 312 | |||
| 313 | while (b != e) | ||
| 314 | { | ||
| 315 | print_node(f, *b++); | ||
| 316 | putc(' ', f); | ||
| 317 | } | ||
| 318 | } | 259 | } |
| 319 | 260 | ||
| 320 | static unsigned long | 261 | static void print_list(FILE * f, struct string_list *list) |
| 321 | expand_and_crc_list(struct string_list *list, unsigned long crc) | ||
| 322 | { | 262 | { |
| 323 | struct string_list **e, **b; | 263 | struct string_list **e, **b; |
| 324 | struct string_list *tmp, **tmp2; | 264 | struct string_list *tmp, **tmp2; |
| 325 | int elem = 1; | 265 | int elem = 1; |
| 326 | |||
| 327 | if (!list) | ||
| 328 | return crc; | ||
| 329 | 266 | ||
| 330 | tmp = list; | 267 | if (list == NULL) { |
| 331 | while((tmp = tmp->next) != NULL) | 268 | fputs("(nil)", f); |
| 332 | elem++; | 269 | return; |
| 333 | 270 | } | |
| 334 | b = alloca(elem * sizeof(*e)); | ||
| 335 | e = b + elem; | ||
| 336 | tmp2 = e - 1; | ||
| 337 | 271 | ||
| 338 | *(tmp2--) = list; | 272 | tmp = list; |
| 339 | while ((list = list->next) != NULL) | 273 | while ((tmp = tmp->next) != NULL) |
| 340 | *(tmp2--) = list; | 274 | elem++; |
| 341 | 275 | ||
| 342 | while (b != e) | 276 | b = alloca(elem * sizeof(*e)); |
| 343 | { | 277 | e = b + elem; |
| 344 | struct string_list *cur; | 278 | tmp2 = e - 1; |
| 345 | struct symbol *subsym; | ||
| 346 | 279 | ||
| 347 | cur = *(b++); | 280 | (*tmp2--) = list; |
| 348 | switch (cur->tag) | 281 | while ((list = list->next) != NULL) |
| 349 | { | 282 | *(tmp2--) = list; |
| 350 | case SYM_NORMAL: | ||
| 351 | if (flag_dump_defs) | ||
| 352 | fprintf(debugfile, "%s ", cur->string); | ||
| 353 | crc = partial_crc32(cur->string, crc); | ||
| 354 | crc = partial_crc32_one(' ', crc); | ||
| 355 | break; | ||
| 356 | 283 | ||
| 357 | case SYM_TYPEDEF: | 284 | while (b != e) { |
| 358 | subsym = find_symbol(cur->string, cur->tag); | 285 | print_node(f, *b++); |
| 359 | if (subsym->expansion_trail) | 286 | putc(' ', f); |
| 360 | { | 287 | } |
| 361 | if (flag_dump_defs) | 288 | } |
| 362 | fprintf(debugfile, "%s ", cur->string); | ||
| 363 | crc = partial_crc32(cur->string, crc); | ||
| 364 | crc = partial_crc32_one(' ', crc); | ||
| 365 | } | ||
| 366 | else | ||
| 367 | { | ||
| 368 | subsym->expansion_trail = expansion_trail; | ||
| 369 | expansion_trail = subsym; | ||
| 370 | crc = expand_and_crc_list(subsym->defn, crc); | ||
| 371 | } | ||
| 372 | break; | ||
| 373 | 289 | ||
| 374 | case SYM_STRUCT: | 290 | static unsigned long expand_and_crc_list(struct string_list *list, |
| 375 | case SYM_UNION: | 291 | unsigned long crc) |
| 376 | case SYM_ENUM: | 292 | { |
| 377 | subsym = find_symbol(cur->string, cur->tag); | 293 | struct string_list **e, **b; |
| 378 | if (!subsym) | 294 | struct string_list *tmp, **tmp2; |
| 379 | { | 295 | int elem = 1; |
| 380 | struct string_list *n, *t = NULL; | 296 | |
| 381 | 297 | if (!list) | |
| 382 | error_with_pos("expand undefined %s %s", | 298 | return crc; |
| 383 | symbol_type_name[cur->tag], cur->string); | 299 | |
| 384 | 300 | tmp = list; | |
| 385 | n = xmalloc(sizeof(*n)); | 301 | while ((tmp = tmp->next) != NULL) |
| 386 | n->string = xstrdup(symbol_type_name[cur->tag]); | 302 | elem++; |
| 387 | n->tag = SYM_NORMAL; | 303 | |
| 388 | n->next = t; | 304 | b = alloca(elem * sizeof(*e)); |
| 389 | t = n; | 305 | e = b + elem; |
| 390 | 306 | tmp2 = e - 1; | |
| 391 | n = xmalloc(sizeof(*n)); | 307 | |
| 392 | n->string = xstrdup(cur->string); | 308 | *(tmp2--) = list; |
| 393 | n->tag = SYM_NORMAL; | 309 | while ((list = list->next) != NULL) |
| 394 | n->next = t; | 310 | *(tmp2--) = list; |
| 395 | t = n; | 311 | |
| 396 | 312 | while (b != e) { | |
| 397 | n = xmalloc(sizeof(*n)); | 313 | struct string_list *cur; |
| 398 | n->string = xstrdup("{ UNKNOWN }"); | 314 | struct symbol *subsym; |
| 399 | n->tag = SYM_NORMAL; | 315 | |
| 400 | n->next = t; | 316 | cur = *(b++); |
| 401 | 317 | switch (cur->tag) { | |
| 402 | subsym = add_symbol(cur->string, cur->tag, n, 0); | 318 | case SYM_NORMAL: |
| 403 | } | 319 | if (flag_dump_defs) |
| 404 | if (subsym->expansion_trail) | 320 | fprintf(debugfile, "%s ", cur->string); |
| 405 | { | 321 | crc = partial_crc32(cur->string, crc); |
| 406 | if (flag_dump_defs) | 322 | crc = partial_crc32_one(' ', crc); |
| 407 | { | 323 | break; |
| 408 | fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag], | 324 | |
| 409 | cur->string); | 325 | case SYM_TYPEDEF: |
| 326 | subsym = find_symbol(cur->string, cur->tag); | ||
| 327 | if (subsym->expansion_trail) { | ||
| 328 | if (flag_dump_defs) | ||
| 329 | fprintf(debugfile, "%s ", cur->string); | ||
| 330 | crc = partial_crc32(cur->string, crc); | ||
| 331 | crc = partial_crc32_one(' ', crc); | ||
| 332 | } else { | ||
| 333 | subsym->expansion_trail = expansion_trail; | ||
| 334 | expansion_trail = subsym; | ||
| 335 | crc = expand_and_crc_list(subsym->defn, crc); | ||
| 336 | } | ||
| 337 | break; | ||
| 338 | |||
| 339 | case SYM_STRUCT: | ||
| 340 | case SYM_UNION: | ||
| 341 | case SYM_ENUM: | ||
| 342 | subsym = find_symbol(cur->string, cur->tag); | ||
| 343 | if (!subsym) { | ||
| 344 | struct string_list *n, *t = NULL; | ||
| 345 | |||
| 346 | error_with_pos("expand undefined %s %s", | ||
| 347 | symbol_type_name[cur->tag], | ||
| 348 | cur->string); | ||
| 349 | |||
| 350 | n = xmalloc(sizeof(*n)); | ||
| 351 | n->string = xstrdup(symbol_type_name[cur->tag]); | ||
| 352 | n->tag = SYM_NORMAL; | ||
| 353 | n->next = t; | ||
| 354 | t = n; | ||
| 355 | |||
| 356 | n = xmalloc(sizeof(*n)); | ||
| 357 | n->string = xstrdup(cur->string); | ||
| 358 | n->tag = SYM_NORMAL; | ||
| 359 | n->next = t; | ||
| 360 | t = n; | ||
| 361 | |||
| 362 | n = xmalloc(sizeof(*n)); | ||
| 363 | n->string = xstrdup("{ UNKNOWN }"); | ||
| 364 | n->tag = SYM_NORMAL; | ||
| 365 | n->next = t; | ||
| 366 | |||
| 367 | subsym = | ||
| 368 | add_symbol(cur->string, cur->tag, n, 0); | ||
| 369 | } | ||
| 370 | if (subsym->expansion_trail) { | ||
| 371 | if (flag_dump_defs) { | ||
| 372 | fprintf(debugfile, "%s %s ", | ||
| 373 | symbol_type_name[cur->tag], | ||
| 374 | cur->string); | ||
| 375 | } | ||
| 376 | |||
| 377 | crc = partial_crc32(symbol_type_name[cur->tag], | ||
| 378 | crc); | ||
| 379 | crc = partial_crc32_one(' ', crc); | ||
| 380 | crc = partial_crc32(cur->string, crc); | ||
| 381 | crc = partial_crc32_one(' ', crc); | ||
| 382 | } else { | ||
| 383 | subsym->expansion_trail = expansion_trail; | ||
| 384 | expansion_trail = subsym; | ||
| 385 | crc = expand_and_crc_list(subsym->defn, crc); | ||
| 386 | } | ||
| 387 | break; | ||
| 410 | } | 388 | } |
| 411 | |||
| 412 | crc = partial_crc32(symbol_type_name[cur->tag], crc); | ||
| 413 | crc = partial_crc32_one(' ', crc); | ||
| 414 | crc = partial_crc32(cur->string, crc); | ||
| 415 | crc = partial_crc32_one(' ', crc); | ||
| 416 | } | ||
| 417 | else | ||
| 418 | { | ||
| 419 | subsym->expansion_trail = expansion_trail; | ||
| 420 | expansion_trail = subsym; | ||
| 421 | crc = expand_and_crc_list(subsym->defn, crc); | ||
| 422 | } | ||
| 423 | break; | ||
| 424 | } | 389 | } |
| 425 | } | ||
| 426 | 390 | ||
| 427 | return crc; | 391 | return crc; |
| 428 | } | 392 | } |
| 429 | 393 | ||
| 430 | void | 394 | void export_symbol(const char *name) |
| 431 | export_symbol(const char *name) | ||
| 432 | { | 395 | { |
| 433 | struct symbol *sym; | 396 | struct symbol *sym; |
| 434 | 397 | ||
| 435 | sym = find_symbol(name, SYM_NORMAL); | 398 | sym = find_symbol(name, SYM_NORMAL); |
| 436 | if (!sym) | 399 | if (!sym) |
| 437 | error_with_pos("export undefined symbol %s", name); | 400 | error_with_pos("export undefined symbol %s", name); |
| 438 | else | 401 | else { |
| 439 | { | 402 | unsigned long crc; |
| 440 | unsigned long crc; | ||
| 441 | 403 | ||
| 442 | if (flag_dump_defs) | 404 | if (flag_dump_defs) |
| 443 | fprintf(debugfile, "Export %s == <", name); | 405 | fprintf(debugfile, "Export %s == <", name); |
| 444 | 406 | ||
| 445 | expansion_trail = (struct symbol *)-1L; | 407 | expansion_trail = (struct symbol *)-1L; |
| 446 | 408 | ||
| 447 | crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; | 409 | crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; |
| 448 | 410 | ||
| 449 | sym = expansion_trail; | 411 | sym = expansion_trail; |
| 450 | while (sym != (struct symbol *)-1L) | 412 | while (sym != (struct symbol *)-1L) { |
| 451 | { | 413 | struct symbol *n = sym->expansion_trail; |
| 452 | struct symbol *n = sym->expansion_trail; | 414 | sym->expansion_trail = 0; |
| 453 | sym->expansion_trail = 0; | 415 | sym = n; |
| 454 | sym = n; | 416 | } |
| 455 | } | ||
| 456 | 417 | ||
| 457 | if (flag_dump_defs) | 418 | if (flag_dump_defs) |
| 458 | fputs(">\n", debugfile); | 419 | fputs(">\n", debugfile); |
| 459 | 420 | ||
| 460 | /* Used as a linker script. */ | 421 | /* Used as a linker script. */ |
| 461 | printf("__crc_%s = 0x%08lx ;\n", name, crc); | 422 | printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); |
| 462 | } | 423 | } |
| 463 | } | 424 | } |
| 464 | 425 | ||
| 465 | /*----------------------------------------------------------------------*/ | 426 | /*----------------------------------------------------------------------*/ |
| 466 | 427 | void error_with_pos(const char *fmt, ...) | |
| 467 | void | ||
| 468 | error(const char *fmt, ...) | ||
| 469 | { | ||
| 470 | va_list args; | ||
| 471 | |||
| 472 | if (flag_warnings) | ||
| 473 | { | ||
| 474 | va_start(args, fmt); | ||
| 475 | vfprintf(stderr, fmt, args); | ||
| 476 | va_end(args); | ||
| 477 | putc('\n', stderr); | ||
| 478 | |||
| 479 | errors++; | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | void | ||
| 484 | error_with_pos(const char *fmt, ...) | ||
| 485 | { | 428 | { |
| 486 | va_list args; | 429 | va_list args; |
| 487 | 430 | ||
| 488 | if (flag_warnings) | 431 | if (flag_warnings) { |
| 489 | { | 432 | fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", |
| 490 | fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line); | 433 | cur_line); |
| 491 | 434 | ||
| 492 | va_start(args, fmt); | 435 | va_start(args, fmt); |
| 493 | vfprintf(stderr, fmt, args); | 436 | vfprintf(stderr, fmt, args); |
| 494 | va_end(args); | 437 | va_end(args); |
| 495 | putc('\n', stderr); | 438 | putc('\n', stderr); |
| 496 | 439 | ||
| 497 | errors++; | 440 | errors++; |
| 498 | } | 441 | } |
| 499 | } | 442 | } |
| 500 | 443 | ||
| 501 | 444 | static void genksyms_usage(void) | |
| 502 | void genksyms_usage(void) | ||
| 503 | { | 445 | { |
| 504 | fputs("Usage:\n" | 446 | fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n" |
| 505 | "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" | ||
| 506 | "\n" | ||
| 507 | #ifdef __GNU_LIBRARY__ | 447 | #ifdef __GNU_LIBRARY__ |
| 508 | " -d, --debug Increment the debug level (repeatable)\n" | 448 | " -d, --debug Increment the debug level (repeatable)\n" |
| 509 | " -D, --dump Dump expanded symbol defs (for debugging only)\n" | 449 | " -D, --dump Dump expanded symbol defs (for debugging only)\n" |
| @@ -511,81 +451,84 @@ void genksyms_usage(void) | |||
| 511 | " -q, --quiet Disable warnings (default)\n" | 451 | " -q, --quiet Disable warnings (default)\n" |
| 512 | " -h, --help Print this message\n" | 452 | " -h, --help Print this message\n" |
| 513 | " -V, --version Print the release version\n" | 453 | " -V, --version Print the release version\n" |
| 514 | #else /* __GNU_LIBRARY__ */ | 454 | #else /* __GNU_LIBRARY__ */ |
| 515 | " -d Increment the debug level (repeatable)\n" | 455 | " -d Increment the debug level (repeatable)\n" |
| 516 | " -D Dump expanded symbol defs (for debugging only)\n" | 456 | " -D Dump expanded symbol defs (for debugging only)\n" |
| 517 | " -w Enable warnings\n" | 457 | " -w Enable warnings\n" |
| 518 | " -q Disable warnings (default)\n" | 458 | " -q Disable warnings (default)\n" |
| 519 | " -h Print this message\n" | 459 | " -h Print this message\n" |
| 520 | " -V Print the release version\n" | 460 | " -V Print the release version\n" |
| 521 | #endif /* __GNU_LIBRARY__ */ | 461 | #endif /* __GNU_LIBRARY__ */ |
| 522 | , stderr); | 462 | , stderr); |
| 523 | } | 463 | } |
| 524 | 464 | ||
| 525 | int | 465 | int main(int argc, char **argv) |
| 526 | main(int argc, char **argv) | ||
| 527 | { | 466 | { |
| 528 | int o; | 467 | int o; |
| 529 | 468 | ||
| 530 | #ifdef __GNU_LIBRARY__ | 469 | #ifdef __GNU_LIBRARY__ |
| 531 | struct option long_opts[] = { | 470 | struct option long_opts[] = { |
| 532 | {"debug", 0, 0, 'd'}, | 471 | {"arch", 1, 0, 'a'}, |
| 533 | {"warnings", 0, 0, 'w'}, | 472 | {"debug", 0, 0, 'd'}, |
| 534 | {"quiet", 0, 0, 'q'}, | 473 | {"warnings", 0, 0, 'w'}, |
| 535 | {"dump", 0, 0, 'D'}, | 474 | {"quiet", 0, 0, 'q'}, |
| 536 | {"version", 0, 0, 'V'}, | 475 | {"dump", 0, 0, 'D'}, |
| 537 | {"help", 0, 0, 'h'}, | 476 | {"version", 0, 0, 'V'}, |
| 538 | {0, 0, 0, 0} | 477 | {"help", 0, 0, 'h'}, |
| 539 | }; | 478 | {0, 0, 0, 0} |
| 540 | 479 | }; | |
| 541 | while ((o = getopt_long(argc, argv, "dwqVDk:p:", | 480 | |
| 542 | &long_opts[0], NULL)) != EOF) | 481 | while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", |
| 543 | #else /* __GNU_LIBRARY__ */ | 482 | &long_opts[0], NULL)) != EOF) |
| 544 | while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF) | 483 | #else /* __GNU_LIBRARY__ */ |
| 545 | #endif /* __GNU_LIBRARY__ */ | 484 | while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) |
| 546 | switch (o) | 485 | #endif /* __GNU_LIBRARY__ */ |
| 547 | { | 486 | switch (o) { |
| 548 | case 'd': | 487 | case 'a': |
| 549 | flag_debug++; | 488 | arch = optarg; |
| 550 | break; | 489 | break; |
| 551 | case 'w': | 490 | case 'd': |
| 552 | flag_warnings = 1; | 491 | flag_debug++; |
| 553 | break; | 492 | break; |
| 554 | case 'q': | 493 | case 'w': |
| 555 | flag_warnings = 0; | 494 | flag_warnings = 1; |
| 556 | break; | 495 | break; |
| 557 | case 'V': | 496 | case 'q': |
| 558 | fputs("genksyms version 2.5.60\n", stderr); | 497 | flag_warnings = 0; |
| 559 | break; | 498 | break; |
| 560 | case 'D': | 499 | case 'V': |
| 561 | flag_dump_defs = 1; | 500 | fputs("genksyms version 2.5.60\n", stderr); |
| 562 | break; | 501 | break; |
| 563 | case 'h': | 502 | case 'D': |
| 564 | genksyms_usage(); | 503 | flag_dump_defs = 1; |
| 565 | return 0; | 504 | break; |
| 566 | default: | 505 | case 'h': |
| 567 | genksyms_usage(); | 506 | genksyms_usage(); |
| 568 | return 1; | 507 | return 0; |
| 569 | } | 508 | default: |
| 570 | 509 | genksyms_usage(); | |
| 571 | { | 510 | return 1; |
| 572 | extern int yydebug; | 511 | } |
| 573 | extern int yy_flex_debug; | 512 | if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0)) |
| 574 | 513 | mod_prefix = "_"; | |
| 575 | yydebug = (flag_debug > 1); | 514 | { |
| 576 | yy_flex_debug = (flag_debug > 2); | 515 | extern int yydebug; |
| 577 | 516 | extern int yy_flex_debug; | |
| 578 | debugfile = stderr; | 517 | |
| 579 | /* setlinebuf(debugfile); */ | 518 | yydebug = (flag_debug > 1); |
| 580 | } | 519 | yy_flex_debug = (flag_debug > 2); |
| 581 | 520 | ||
| 582 | yyparse(); | 521 | debugfile = stderr; |
| 583 | 522 | /* setlinebuf(debugfile); */ | |
| 584 | if (flag_debug) | 523 | } |
| 585 | { | 524 | |
| 586 | fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", | 525 | yyparse(); |
| 587 | nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS); | 526 | |
| 588 | } | 527 | if (flag_debug) { |
| 589 | 528 | fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", | |
| 590 | return errors != 0; | 529 | nsyms, HASH_BUCKETS, |
| 530 | (double)nsyms / (double)HASH_BUCKETS); | ||
| 531 | } | ||
| 532 | |||
| 533 | return errors != 0; | ||
| 591 | } | 534 | } |
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index f09af47ab281..ab6f34f38735 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h | |||
| @@ -20,74 +20,51 @@ | |||
| 20 | along with this program; if not, write to the Free Software Foundation, | 20 | along with this program; if not, write to the Free Software Foundation, |
| 21 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | 21 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
| 22 | 22 | ||
| 23 | |||
| 24 | #ifndef MODUTILS_GENKSYMS_H | 23 | #ifndef MODUTILS_GENKSYMS_H |
| 25 | #define MODUTILS_GENKSYMS_H 1 | 24 | #define MODUTILS_GENKSYMS_H 1 |
| 26 | 25 | ||
| 27 | #include <stdio.h> | 26 | #include <stdio.h> |
| 28 | 27 | ||
| 29 | 28 | enum symbol_type { | |
| 30 | enum symbol_type | 29 | SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION |
| 31 | { | ||
| 32 | SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION | ||
| 33 | }; | 30 | }; |
| 34 | 31 | ||
| 35 | struct string_list | 32 | struct string_list { |
| 36 | { | 33 | struct string_list *next; |
| 37 | struct string_list *next; | 34 | enum symbol_type tag; |
| 38 | enum symbol_type tag; | 35 | char *string; |
| 39 | char *string; | ||
| 40 | }; | 36 | }; |
| 41 | 37 | ||
| 42 | struct symbol | 38 | struct symbol { |
| 43 | { | 39 | struct symbol *hash_next; |
| 44 | struct symbol *hash_next; | 40 | const char *name; |
| 45 | const char *name; | 41 | enum symbol_type type; |
| 46 | enum symbol_type type; | 42 | struct string_list *defn; |
| 47 | struct string_list *defn; | 43 | struct symbol *expansion_trail; |
| 48 | struct symbol *expansion_trail; | 44 | int is_extern; |
| 49 | int is_extern; | ||
| 50 | }; | 45 | }; |
| 51 | 46 | ||
| 52 | typedef struct string_list **yystype; | 47 | typedef struct string_list **yystype; |
| 53 | #define YYSTYPE yystype | 48 | #define YYSTYPE yystype |
| 54 | 49 | ||
| 55 | extern FILE *outfile, *debugfile; | ||
| 56 | |||
| 57 | extern int cur_line; | 50 | extern int cur_line; |
| 58 | extern char *cur_filename, *output_directory; | 51 | extern char *cur_filename; |
| 59 | |||
| 60 | extern int flag_debug, flag_dump_defs, flag_warnings; | ||
| 61 | extern int checksum_version, kernel_version; | ||
| 62 | |||
| 63 | extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents; | ||
| 64 | extern struct string_list *current_list, *next_list; | ||
| 65 | |||
| 66 | 52 | ||
| 67 | struct symbol *find_symbol(const char *name, enum symbol_type ns); | 53 | struct symbol *find_symbol(const char *name, enum symbol_type ns); |
| 68 | struct symbol *add_symbol(const char *name, enum symbol_type type, | 54 | struct symbol *add_symbol(const char *name, enum symbol_type type, |
| 69 | struct string_list *defn, int is_extern); | 55 | struct string_list *defn, int is_extern); |
| 70 | void export_symbol(const char *); | 56 | void export_symbol(const char *); |
| 71 | 57 | ||
| 72 | struct string_list *reset_list(void); | ||
| 73 | void free_list(struct string_list *s, struct string_list *e); | ||
| 74 | void free_node(struct string_list *list); | 58 | void free_node(struct string_list *list); |
| 59 | void free_list(struct string_list *s, struct string_list *e); | ||
| 75 | struct string_list *copy_node(struct string_list *); | 60 | struct string_list *copy_node(struct string_list *); |
| 76 | struct string_list *copy_list(struct string_list *s, struct string_list *e); | ||
| 77 | int equal_list(struct string_list *a, struct string_list *b); | ||
| 78 | void print_list(FILE *, struct string_list *list); | ||
| 79 | 61 | ||
| 80 | int yylex(void); | 62 | int yylex(void); |
| 81 | int yyparse(void); | 63 | int yyparse(void); |
| 82 | 64 | ||
| 83 | void error_with_pos(const char *, ...); | 65 | void error_with_pos(const char *, ...); |
| 84 | 66 | ||
| 85 | #define version(a,b,c) ((a << 16) | (b << 8) | (c)) | ||
| 86 | |||
| 87 | /*----------------------------------------------------------------------*/ | 67 | /*----------------------------------------------------------------------*/ |
| 88 | |||
| 89 | #define MODUTILS_VERSION "<in-kernel>" | ||
| 90 | |||
| 91 | #define xmalloc(size) ({ void *__ptr = malloc(size); \ | 68 | #define xmalloc(size) ({ void *__ptr = malloc(size); \ |
| 92 | if(!__ptr && size != 0) { \ | 69 | if(!__ptr && size != 0) { \ |
| 93 | fprintf(stderr, "out of memory\n"); \ | 70 | fprintf(stderr, "out of memory\n"); \ |
| @@ -101,4 +78,4 @@ void error_with_pos(const char *, ...); | |||
| 101 | } \ | 78 | } \ |
| 102 | __str; }) | 79 | __str; }) |
| 103 | 80 | ||
| 104 | #endif /* genksyms.h */ | 81 | #endif /* genksyms.h */ |
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index ee4647805c58..d8153f572e40 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped | |||
| @@ -52,9 +52,9 @@ is_reserved_hash (register const char *str, register unsigned int len) | |||
| 52 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, | 52 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, |
| 53 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, | 53 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, |
| 54 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, | 54 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, |
| 55 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 15, | 55 | 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, |
| 56 | 71, 71, 71, 71, 71, 71, 15, 71, 71, 71, | 56 | 71, 71, 71, 71, 71, 71, 35, 71, 71, 71, |
| 57 | 10, 71, 71, 71, 71, 71, 71, 71, 71, 71, | 57 | 5, 71, 71, 71, 71, 71, 71, 71, 71, 71, |
| 58 | 71, 71, 71, 71, 71, 0, 71, 0, 71, 5, | 58 | 71, 71, 71, 71, 71, 0, 71, 0, 71, 5, |
| 59 | 5, 0, 10, 20, 71, 25, 71, 71, 20, 0, | 59 | 5, 0, 10, 20, 71, 25, 71, 71, 20, 0, |
| 60 | 20, 30, 25, 71, 10, 5, 0, 20, 15, 71, | 60 | 20, 30, 25, 71, 10, 5, 0, 20, 15, 71, |
| @@ -84,9 +84,9 @@ is_reserved_word (register const char *str, register unsigned int len) | |||
| 84 | { | 84 | { |
| 85 | enum | 85 | enum |
| 86 | { | 86 | { |
| 87 | TOTAL_KEYWORDS = 41, | 87 | TOTAL_KEYWORDS = 42, |
| 88 | MIN_WORD_LENGTH = 3, | 88 | MIN_WORD_LENGTH = 3, |
| 89 | MAX_WORD_LENGTH = 17, | 89 | MAX_WORD_LENGTH = 24, |
| 90 | MIN_HASH_VALUE = 3, | 90 | MIN_HASH_VALUE = 3, |
| 91 | MAX_HASH_VALUE = 70 | 91 | MAX_HASH_VALUE = 70 |
| 92 | }; | 92 | }; |
| @@ -94,104 +94,105 @@ is_reserved_word (register const char *str, register unsigned int len) | |||
| 94 | static const struct resword wordlist[] = | 94 | static const struct resword wordlist[] = |
| 95 | { | 95 | { |
| 96 | {""}, {""}, {""}, | 96 | {""}, {""}, {""}, |
| 97 | #line 24 "scripts/genksyms/keywords.gperf" | 97 | #line 25 "scripts/genksyms/keywords.gperf" |
| 98 | {"asm", ASM_KEYW}, | 98 | {"asm", ASM_KEYW}, |
| 99 | {""}, | 99 | {""}, |
| 100 | #line 7 "scripts/genksyms/keywords.gperf" | 100 | #line 8 "scripts/genksyms/keywords.gperf" |
| 101 | {"__asm", ASM_KEYW}, | 101 | {"__asm", ASM_KEYW}, |
| 102 | {""}, | 102 | {""}, |
| 103 | #line 8 "scripts/genksyms/keywords.gperf" | 103 | #line 9 "scripts/genksyms/keywords.gperf" |
| 104 | {"__asm__", ASM_KEYW}, | 104 | {"__asm__", ASM_KEYW}, |
| 105 | {""}, | 105 | {""}, |
| 106 | #line 21 "scripts/genksyms/keywords.gperf" | 106 | #line 22 "scripts/genksyms/keywords.gperf" |
| 107 | {"_restrict", RESTRICT_KEYW}, | 107 | {"_restrict", RESTRICT_KEYW}, |
| 108 | #line 50 "scripts/genksyms/keywords.gperf" | 108 | #line 51 "scripts/genksyms/keywords.gperf" |
| 109 | {"__typeof__", TYPEOF_KEYW}, | 109 | {"__typeof__", TYPEOF_KEYW}, |
| 110 | #line 9 "scripts/genksyms/keywords.gperf" | 110 | #line 10 "scripts/genksyms/keywords.gperf" |
| 111 | {"__attribute", ATTRIBUTE_KEYW}, | 111 | {"__attribute", ATTRIBUTE_KEYW}, |
| 112 | #line 11 "scripts/genksyms/keywords.gperf" | 112 | #line 12 "scripts/genksyms/keywords.gperf" |
| 113 | {"__const", CONST_KEYW}, | 113 | {"__const", CONST_KEYW}, |
| 114 | #line 10 "scripts/genksyms/keywords.gperf" | 114 | #line 11 "scripts/genksyms/keywords.gperf" |
| 115 | {"__attribute__", ATTRIBUTE_KEYW}, | 115 | {"__attribute__", ATTRIBUTE_KEYW}, |
| 116 | #line 12 "scripts/genksyms/keywords.gperf" | 116 | #line 13 "scripts/genksyms/keywords.gperf" |
| 117 | {"__const__", CONST_KEYW}, | 117 | {"__const__", CONST_KEYW}, |
| 118 | #line 16 "scripts/genksyms/keywords.gperf" | 118 | #line 17 "scripts/genksyms/keywords.gperf" |
| 119 | {"__signed__", SIGNED_KEYW}, | 119 | {"__signed__", SIGNED_KEYW}, |
| 120 | #line 42 "scripts/genksyms/keywords.gperf" | 120 | #line 43 "scripts/genksyms/keywords.gperf" |
| 121 | {"static", STATIC_KEYW}, | 121 | {"static", STATIC_KEYW}, |
| 122 | {""}, | 122 | {""}, |
| 123 | #line 15 "scripts/genksyms/keywords.gperf" | 123 | #line 16 "scripts/genksyms/keywords.gperf" |
| 124 | {"__signed", SIGNED_KEYW}, | 124 | {"__signed", SIGNED_KEYW}, |
| 125 | #line 30 "scripts/genksyms/keywords.gperf" | 125 | #line 31 "scripts/genksyms/keywords.gperf" |
| 126 | {"char", CHAR_KEYW}, | 126 | {"char", CHAR_KEYW}, |
| 127 | {""}, | 127 | {""}, |
| 128 | #line 43 "scripts/genksyms/keywords.gperf" | 128 | #line 44 "scripts/genksyms/keywords.gperf" |
| 129 | {"struct", STRUCT_KEYW}, | 129 | {"struct", STRUCT_KEYW}, |
| 130 | #line 22 "scripts/genksyms/keywords.gperf" | ||
| 131 | {"__restrict__", RESTRICT_KEYW}, | ||
| 132 | #line 23 "scripts/genksyms/keywords.gperf" | 130 | #line 23 "scripts/genksyms/keywords.gperf" |
| 131 | {"__restrict__", RESTRICT_KEYW}, | ||
| 132 | #line 24 "scripts/genksyms/keywords.gperf" | ||
| 133 | {"restrict", RESTRICT_KEYW}, | 133 | {"restrict", RESTRICT_KEYW}, |
| 134 | #line 33 "scripts/genksyms/keywords.gperf" | 134 | #line 34 "scripts/genksyms/keywords.gperf" |
| 135 | {"enum", ENUM_KEYW}, | 135 | {"enum", ENUM_KEYW}, |
| 136 | #line 17 "scripts/genksyms/keywords.gperf" | 136 | #line 18 "scripts/genksyms/keywords.gperf" |
| 137 | {"__volatile", VOLATILE_KEYW}, | 137 | {"__volatile", VOLATILE_KEYW}, |
| 138 | #line 34 "scripts/genksyms/keywords.gperf" | 138 | #line 35 "scripts/genksyms/keywords.gperf" |
| 139 | {"extern", EXTERN_KEYW}, | 139 | {"extern", EXTERN_KEYW}, |
| 140 | #line 18 "scripts/genksyms/keywords.gperf" | 140 | #line 19 "scripts/genksyms/keywords.gperf" |
| 141 | {"__volatile__", VOLATILE_KEYW}, | 141 | {"__volatile__", VOLATILE_KEYW}, |
| 142 | #line 37 "scripts/genksyms/keywords.gperf" | 142 | #line 38 "scripts/genksyms/keywords.gperf" |
| 143 | {"int", INT_KEYW}, | 143 | {"int", INT_KEYW}, |
| 144 | {""}, | 144 | #line 7 "scripts/genksyms/keywords.gperf" |
| 145 | #line 31 "scripts/genksyms/keywords.gperf" | 145 | {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, |
| 146 | {"const", CONST_KEYW}, | ||
| 147 | #line 32 "scripts/genksyms/keywords.gperf" | 146 | #line 32 "scripts/genksyms/keywords.gperf" |
| 147 | {"const", CONST_KEYW}, | ||
| 148 | #line 33 "scripts/genksyms/keywords.gperf" | ||
| 148 | {"double", DOUBLE_KEYW}, | 149 | {"double", DOUBLE_KEYW}, |
| 149 | {""}, | 150 | {""}, |
| 150 | #line 13 "scripts/genksyms/keywords.gperf" | 151 | #line 14 "scripts/genksyms/keywords.gperf" |
| 151 | {"__inline", INLINE_KEYW}, | 152 | {"__inline", INLINE_KEYW}, |
| 152 | #line 29 "scripts/genksyms/keywords.gperf" | 153 | #line 30 "scripts/genksyms/keywords.gperf" |
| 153 | {"auto", AUTO_KEYW}, | 154 | {"auto", AUTO_KEYW}, |
| 154 | #line 14 "scripts/genksyms/keywords.gperf" | 155 | #line 15 "scripts/genksyms/keywords.gperf" |
| 155 | {"__inline__", INLINE_KEYW}, | 156 | {"__inline__", INLINE_KEYW}, |
| 156 | #line 41 "scripts/genksyms/keywords.gperf" | 157 | #line 42 "scripts/genksyms/keywords.gperf" |
| 157 | {"signed", SIGNED_KEYW}, | 158 | {"signed", SIGNED_KEYW}, |
| 158 | {""}, | 159 | {""}, |
| 159 | #line 46 "scripts/genksyms/keywords.gperf" | 160 | #line 47 "scripts/genksyms/keywords.gperf" |
| 160 | {"unsigned", UNSIGNED_KEYW}, | 161 | {"unsigned", UNSIGNED_KEYW}, |
| 161 | {""}, | 162 | {""}, |
| 162 | #line 40 "scripts/genksyms/keywords.gperf" | 163 | #line 41 "scripts/genksyms/keywords.gperf" |
| 163 | {"short", SHORT_KEYW}, | 164 | {"short", SHORT_KEYW}, |
| 164 | #line 49 "scripts/genksyms/keywords.gperf" | 165 | #line 50 "scripts/genksyms/keywords.gperf" |
| 165 | {"typeof", TYPEOF_KEYW}, | 166 | {"typeof", TYPEOF_KEYW}, |
| 166 | #line 44 "scripts/genksyms/keywords.gperf" | 167 | #line 45 "scripts/genksyms/keywords.gperf" |
| 167 | {"typedef", TYPEDEF_KEYW}, | 168 | {"typedef", TYPEDEF_KEYW}, |
| 168 | #line 48 "scripts/genksyms/keywords.gperf" | 169 | #line 49 "scripts/genksyms/keywords.gperf" |
| 169 | {"volatile", VOLATILE_KEYW}, | 170 | {"volatile", VOLATILE_KEYW}, |
| 170 | {""}, | 171 | {""}, |
| 171 | #line 35 "scripts/genksyms/keywords.gperf" | 172 | #line 36 "scripts/genksyms/keywords.gperf" |
| 172 | {"float", FLOAT_KEYW}, | 173 | {"float", FLOAT_KEYW}, |
| 173 | {""}, {""}, | 174 | {""}, {""}, |
| 174 | #line 39 "scripts/genksyms/keywords.gperf" | 175 | #line 40 "scripts/genksyms/keywords.gperf" |
| 175 | {"register", REGISTER_KEYW}, | 176 | {"register", REGISTER_KEYW}, |
| 176 | #line 47 "scripts/genksyms/keywords.gperf" | 177 | #line 48 "scripts/genksyms/keywords.gperf" |
| 177 | {"void", VOID_KEYW}, | 178 | {"void", VOID_KEYW}, |
| 178 | {""}, | 179 | {""}, |
| 179 | #line 36 "scripts/genksyms/keywords.gperf" | 180 | #line 37 "scripts/genksyms/keywords.gperf" |
| 180 | {"inline", INLINE_KEYW}, | 181 | {"inline", INLINE_KEYW}, |
| 181 | {""}, | 182 | {""}, |
| 182 | #line 5 "scripts/genksyms/keywords.gperf" | 183 | #line 5 "scripts/genksyms/keywords.gperf" |
| 183 | {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, | 184 | {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, |
| 184 | {""}, | 185 | {""}, |
| 185 | #line 20 "scripts/genksyms/keywords.gperf" | 186 | #line 21 "scripts/genksyms/keywords.gperf" |
| 186 | {"_Bool", BOOL_KEYW}, | 187 | {"_Bool", BOOL_KEYW}, |
| 187 | {""}, | 188 | {""}, |
| 188 | #line 6 "scripts/genksyms/keywords.gperf" | 189 | #line 6 "scripts/genksyms/keywords.gperf" |
| 189 | {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, | 190 | {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, |
| 190 | {""}, {""}, {""}, {""}, {""}, {""}, | 191 | {""}, {""}, {""}, {""}, {""}, {""}, |
| 191 | #line 38 "scripts/genksyms/keywords.gperf" | 192 | #line 39 "scripts/genksyms/keywords.gperf" |
| 192 | {"long", LONG_KEYW}, | 193 | {"long", LONG_KEYW}, |
| 193 | {""}, {""}, {""}, {""}, {""}, | 194 | {""}, {""}, {""}, {""}, {""}, |
| 194 | #line 45 "scripts/genksyms/keywords.gperf" | 195 | #line 46 "scripts/genksyms/keywords.gperf" |
| 195 | {"union", UNION_KEYW} | 196 | {"union", UNION_KEYW} |
| 196 | }; | 197 | }; |
| 197 | 198 | ||
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index b6bec765996e..c75e0c8d8f0c 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf | |||
| @@ -4,6 +4,7 @@ struct resword { const char *name; int token; } | |||
| 4 | %% | 4 | %% |
| 5 | EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW | 5 | EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW |
| 6 | EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW | 6 | EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW |
| 7 | EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW | ||
| 7 | __asm, ASM_KEYW | 8 | __asm, ASM_KEYW |
| 8 | __asm__, ASM_KEYW | 9 | __asm__, ASM_KEYW |
| 9 | __attribute, ATTRIBUTE_KEYW | 10 | __attribute, ATTRIBUTE_KEYW |
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index d591578bd3b2..22d281c6ec24 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
| @@ -124,6 +124,11 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
| 124 | * compressed together */ | 124 | * compressed together */ |
| 125 | s->len = strlen(str) + 1; | 125 | s->len = strlen(str) + 1; |
| 126 | s->sym = malloc(s->len + 1); | 126 | s->sym = malloc(s->len + 1); |
| 127 | if (!s->sym) { | ||
| 128 | fprintf(stderr, "kallsyms failure: " | ||
| 129 | "unable to allocate required amount of memory\n"); | ||
| 130 | exit(EXIT_FAILURE); | ||
| 131 | } | ||
| 127 | strcpy((char *)s->sym + 1, str); | 132 | strcpy((char *)s->sym + 1, str); |
| 128 | s->sym[0] = stype; | 133 | s->sym[0] = stype; |
| 129 | 134 | ||
| @@ -272,7 +277,12 @@ static void write_src(void) | |||
| 272 | 277 | ||
| 273 | /* table of offset markers, that give the offset in the compressed stream | 278 | /* table of offset markers, that give the offset in the compressed stream |
| 274 | * every 256 symbols */ | 279 | * every 256 symbols */ |
| 275 | markers = (unsigned int *) malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); | 280 | markers = malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); |
| 281 | if (!markers) { | ||
| 282 | fprintf(stderr, "kallsyms failure: " | ||
| 283 | "unable to allocate required memory\n"); | ||
| 284 | exit(EXIT_FAILURE); | ||
| 285 | } | ||
| 276 | 286 | ||
| 277 | output_label("kallsyms_names"); | 287 | output_label("kallsyms_names"); |
| 278 | off = 0; | 288 | off = 0; |
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 5760e057ecba..e6499db4c8cc 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Kernel configuration targets | 2 | # Kernel configuration targets |
| 3 | # These targets are used from top-level makefile | 3 | # These targets are used from top-level makefile |
| 4 | 4 | ||
| 5 | .PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config | 5 | PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config |
| 6 | 6 | ||
| 7 | xconfig: $(obj)/qconf | 7 | xconfig: $(obj)/qconf |
| 8 | $< arch/$(ARCH)/Kconfig | 8 | $< arch/$(ARCH)/Kconfig |
| @@ -42,7 +42,7 @@ update-po-config: $(obj)/kxgettext | |||
| 42 | $(Q)rm -f arch/um/Kconfig_arch | 42 | $(Q)rm -f arch/um/Kconfig_arch |
| 43 | $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot | 43 | $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot |
| 44 | 44 | ||
| 45 | .PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig | 45 | PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig |
| 46 | 46 | ||
| 47 | randconfig: $(obj)/conf | 47 | randconfig: $(obj)/conf |
| 48 | $< -r arch/$(ARCH)/Kconfig | 48 | $< -r arch/$(ARCH)/Kconfig |
| @@ -78,7 +78,7 @@ help: | |||
| 78 | @echo ' defconfig - New config with default answer to all options' | 78 | @echo ' defconfig - New config with default answer to all options' |
| 79 | @echo ' allmodconfig - New config selecting modules when possible' | 79 | @echo ' allmodconfig - New config selecting modules when possible' |
| 80 | @echo ' allyesconfig - New config where all options are accepted with yes' | 80 | @echo ' allyesconfig - New config where all options are accepted with yes' |
| 81 | @echo ' allnoconfig - New minimal config' | 81 | @echo ' allnoconfig - New config where all options are answered with no' |
| 82 | 82 | ||
| 83 | # =========================================================================== | 83 | # =========================================================================== |
| 84 | # Shared Makefile for the various kconfig executables: | 84 | # Shared Makefile for the various kconfig executables: |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index b0cbbe2e41bb..1b8882ddbc74 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
| @@ -374,6 +374,7 @@ int conf_write(const char *name) | |||
| 374 | out_h = fopen(".tmpconfig.h", "w"); | 374 | out_h = fopen(".tmpconfig.h", "w"); |
| 375 | if (!out_h) | 375 | if (!out_h) |
| 376 | return 1; | 376 | return 1; |
| 377 | file_write_dep(NULL); | ||
| 377 | } | 378 | } |
| 378 | sym = sym_lookup("KERNELVERSION", 0); | 379 | sym = sym_lookup("KERNELVERSION", 0); |
| 379 | sym_calc_value(sym); | 380 | sym_calc_value(sym); |
| @@ -512,7 +513,6 @@ int conf_write(const char *name) | |||
| 512 | if (out_h) { | 513 | if (out_h) { |
| 513 | fclose(out_h); | 514 | fclose(out_h); |
| 514 | rename(".tmpconfig.h", "include/linux/autoconf.h"); | 515 | rename(".tmpconfig.h", "include/linux/autoconf.h"); |
| 515 | file_write_dep(NULL); | ||
| 516 | } | 516 | } |
| 517 | if (!name || basename != conf_def_filename) { | 517 | if (!name || basename != conf_def_filename) { |
| 518 | if (!name) | 518 | if (!name) |
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile index bbf4887cff74..a8b026326247 100644 --- a/scripts/kconfig/lxdialog/Makefile +++ b/scripts/kconfig/lxdialog/Makefile | |||
| @@ -7,10 +7,10 @@ check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh | |||
| 7 | # we really need to do so. (Do not call gcc as part of make mrproper) | 7 | # we really need to do so. (Do not call gcc as part of make mrproper) |
| 8 | HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) | 8 | HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) |
| 9 | HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) | 9 | HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) |
| 10 | |||
| 11 | HOST_EXTRACFLAGS += -DLOCALE | ||
| 12 | 10 | ||
| 13 | .PHONY: dochecklxdialog | 11 | HOST_EXTRACFLAGS += -DLOCALE |
| 12 | |||
| 13 | PHONY += dochecklxdialog | ||
| 14 | $(obj)/dochecklxdialog: | 14 | $(obj)/dochecklxdialog: |
| 15 | $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) | 15 | $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) |
| 16 | 16 | ||
diff --git a/scripts/mkmakefile b/scripts/mkmakefile index c4d621b30d0d..a22cbedd3b3e 100644 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile | |||
| @@ -21,11 +21,13 @@ KERNELOUTPUT := $2 | |||
| 21 | 21 | ||
| 22 | MAKEFLAGS += --no-print-directory | 22 | MAKEFLAGS += --no-print-directory |
| 23 | 23 | ||
| 24 | .PHONY: all \$(MAKECMDGOALS) | ||
| 25 | |||
| 24 | all: | 26 | all: |
| 25 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) | 27 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) |
| 26 | 28 | ||
| 27 | %:: | 29 | Makefile:; |
| 28 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ | ||
| 29 | 30 | ||
| 31 | \$(filter-out all Makefile,\$(MAKECMDGOALS)) %/: | ||
| 32 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ | ||
| 30 | EOF | 33 | EOF |
| 31 | |||
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index c164b230ad6f..84e21201f3c0 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -34,7 +34,7 @@ typedef uint16_t __u16; | |||
| 34 | typedef unsigned char __u8; | 34 | typedef unsigned char __u8; |
| 35 | 35 | ||
| 36 | /* Big exception to the "don't include kernel headers into userspace, which | 36 | /* Big exception to the "don't include kernel headers into userspace, which |
| 37 | * even potentially has different endianness and word sizes, since | 37 | * even potentially has different endianness and word sizes, since |
| 38 | * we handle those differences explicitly below */ | 38 | * we handle those differences explicitly below */ |
| 39 | #include "../../include/linux/mod_devicetable.h" | 39 | #include "../../include/linux/mod_devicetable.h" |
| 40 | #include "../../include/linux/input.h" | 40 | #include "../../include/linux/input.h" |
| @@ -153,8 +153,8 @@ static void do_usb_table(void *symval, unsigned long size, | |||
| 153 | const unsigned long id_size = sizeof(struct usb_device_id); | 153 | const unsigned long id_size = sizeof(struct usb_device_id); |
| 154 | 154 | ||
| 155 | if (size % id_size || size < id_size) { | 155 | if (size % id_size || size < id_size) { |
| 156 | fprintf(stderr, "*** Warning: %s ids %lu bad size " | 156 | warn("%s ids %lu bad size " |
| 157 | "(each on %lu)\n", mod->name, size, id_size); | 157 | "(each on %lu)\n", mod->name, size, id_size); |
| 158 | } | 158 | } |
| 159 | /* Leave last one: it's the terminator. */ | 159 | /* Leave last one: it's the terminator. */ |
| 160 | size -= id_size; | 160 | size -= id_size; |
| @@ -217,9 +217,8 @@ static int do_pci_entry(const char *filename, | |||
| 217 | if ((baseclass_mask != 0 && baseclass_mask != 0xFF) | 217 | if ((baseclass_mask != 0 && baseclass_mask != 0xFF) |
| 218 | || (subclass_mask != 0 && subclass_mask != 0xFF) | 218 | || (subclass_mask != 0 && subclass_mask != 0xFF) |
| 219 | || (interface_mask != 0 && interface_mask != 0xFF)) { | 219 | || (interface_mask != 0 && interface_mask != 0xFF)) { |
| 220 | fprintf(stderr, | 220 | warn("Can't handle masks in %s:%04X\n", |
| 221 | "*** Warning: Can't handle masks in %s:%04X\n", | 221 | filename, id->class_mask); |
| 222 | filename, id->class_mask); | ||
| 223 | return 0; | 222 | return 0; |
| 224 | } | 223 | } |
| 225 | 224 | ||
| @@ -229,7 +228,7 @@ static int do_pci_entry(const char *filename, | |||
| 229 | return 1; | 228 | return 1; |
| 230 | } | 229 | } |
| 231 | 230 | ||
| 232 | /* looks like: "ccw:tNmNdtNdmN" */ | 231 | /* looks like: "ccw:tNmNdtNdmN" */ |
| 233 | static int do_ccw_entry(const char *filename, | 232 | static int do_ccw_entry(const char *filename, |
| 234 | struct ccw_device_id *id, char *alias) | 233 | struct ccw_device_id *id, char *alias) |
| 235 | { | 234 | { |
| @@ -445,8 +444,8 @@ static void do_table(void *symval, unsigned long size, | |||
| 445 | int (*do_entry)(const char *, void *entry, char *alias) = function; | 444 | int (*do_entry)(const char *, void *entry, char *alias) = function; |
| 446 | 445 | ||
| 447 | if (size % id_size || size < id_size) { | 446 | if (size % id_size || size < id_size) { |
| 448 | fprintf(stderr, "*** Warning: %s ids %lu bad size " | 447 | warn("%s ids %lu bad size " |
| 449 | "(each on %lu)\n", mod->name, size, id_size); | 448 | "(each on %lu)\n", mod->name, size, id_size); |
| 450 | } | 449 | } |
| 451 | /* Leave last one: it's the terminator. */ | 450 | /* Leave last one: it's the terminator. */ |
| 452 | size -= id_size; | 451 | size -= id_size; |
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index de2aabf89fb3..3c92c83733f4 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | int | 6 | int |
| 7 | main(int argc, char **argv) | 7 | main(int argc, char **argv) |
| 8 | { | 8 | { |
| 9 | unsigned char ei[EI_NIDENT]; | 9 | unsigned char ei[EI_NIDENT]; |
| 10 | union { short s; char c[2]; } endian_test; | 10 | union { short s; char c[2]; } endian_test; |
| 11 | 11 | ||
| 12 | if (argc != 2) { | 12 | if (argc != 2) { |
| @@ -57,7 +57,7 @@ main(int argc, char **argv) | |||
| 57 | 57 | ||
| 58 | if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) | 58 | if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) |
| 59 | printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); | 59 | printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); |
| 60 | else | 60 | else |
| 61 | printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); | 61 | printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); |
| 62 | 62 | ||
| 63 | return 0; | 63 | return 0; |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b8b2a560b26b..0b92ddff26fd 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * | 2 | * |
| 3 | * Copyright 2003 Kai Germaschewski | 3 | * Copyright 2003 Kai Germaschewski |
| 4 | * Copyright 2002-2004 Rusty Russell, IBM Corporation | 4 | * Copyright 2002-2004 Rusty Russell, IBM Corporation |
| 5 | * | 5 | * Copyright 2006 Sam Ravnborg |
| 6 | * Based in part on module-init-tools/depmod.c,file2alias | 6 | * Based in part on module-init-tools/depmod.c,file2alias |
| 7 | * | 7 | * |
| 8 | * This software may be used and distributed according to the terms | 8 | * This software may be used and distributed according to the terms |
| @@ -20,9 +20,10 @@ int modversions = 0; | |||
| 20 | int have_vmlinux = 0; | 20 | int have_vmlinux = 0; |
| 21 | /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ | 21 | /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ |
| 22 | static int all_versions = 0; | 22 | static int all_versions = 0; |
| 23 | /* If we are modposting external module set to 1 */ | ||
| 24 | static int external_module = 0; | ||
| 23 | 25 | ||
| 24 | void | 26 | void fatal(const char *fmt, ...) |
| 25 | fatal(const char *fmt, ...) | ||
| 26 | { | 27 | { |
| 27 | va_list arglist; | 28 | va_list arglist; |
| 28 | 29 | ||
| @@ -35,8 +36,7 @@ fatal(const char *fmt, ...) | |||
| 35 | exit(1); | 36 | exit(1); |
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | void | 39 | void warn(const char *fmt, ...) |
| 39 | warn(const char *fmt, ...) | ||
| 40 | { | 40 | { |
| 41 | va_list arglist; | 41 | va_list arglist; |
| 42 | 42 | ||
| @@ -47,6 +47,18 @@ warn(const char *fmt, ...) | |||
| 47 | va_end(arglist); | 47 | va_end(arglist); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static int is_vmlinux(const char *modname) | ||
| 51 | { | ||
| 52 | const char *myname; | ||
| 53 | |||
| 54 | if ((myname = strrchr(modname, '/'))) | ||
| 55 | myname++; | ||
| 56 | else | ||
| 57 | myname = modname; | ||
| 58 | |||
| 59 | return strcmp(myname, "vmlinux") == 0; | ||
| 60 | } | ||
| 61 | |||
| 50 | void *do_nofail(void *ptr, const char *expr) | 62 | void *do_nofail(void *ptr, const char *expr) |
| 51 | { | 63 | { |
| 52 | if (!ptr) { | 64 | if (!ptr) { |
| @@ -59,8 +71,7 @@ void *do_nofail(void *ptr, const char *expr) | |||
| 59 | 71 | ||
| 60 | static struct module *modules; | 72 | static struct module *modules; |
| 61 | 73 | ||
| 62 | struct module * | 74 | static struct module *find_module(char *modname) |
| 63 | find_module(char *modname) | ||
| 64 | { | 75 | { |
| 65 | struct module *mod; | 76 | struct module *mod; |
| 66 | 77 | ||
| @@ -70,12 +81,11 @@ find_module(char *modname) | |||
| 70 | return mod; | 81 | return mod; |
| 71 | } | 82 | } |
| 72 | 83 | ||
| 73 | struct module * | 84 | static struct module *new_module(char *modname) |
| 74 | new_module(char *modname) | ||
| 75 | { | 85 | { |
| 76 | struct module *mod; | 86 | struct module *mod; |
| 77 | char *p, *s; | 87 | char *p, *s; |
| 78 | 88 | ||
| 79 | mod = NOFAIL(malloc(sizeof(*mod))); | 89 | mod = NOFAIL(malloc(sizeof(*mod))); |
| 80 | memset(mod, 0, sizeof(*mod)); | 90 | memset(mod, 0, sizeof(*mod)); |
| 81 | p = NOFAIL(strdup(modname)); | 91 | p = NOFAIL(strdup(modname)); |
| @@ -104,6 +114,10 @@ struct symbol { | |||
| 104 | unsigned int crc; | 114 | unsigned int crc; |
| 105 | int crc_valid; | 115 | int crc_valid; |
| 106 | unsigned int weak:1; | 116 | unsigned int weak:1; |
| 117 | unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ | ||
| 118 | unsigned int kernel:1; /* 1 if symbol is from kernel | ||
| 119 | * (only for external modules) **/ | ||
| 120 | unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ | ||
| 107 | char name[0]; | 121 | char name[0]; |
| 108 | }; | 122 | }; |
| 109 | 123 | ||
| @@ -122,11 +136,12 @@ static inline unsigned int tdb_hash(const char *name) | |||
| 122 | return (1103515243 * value + 12345); | 136 | return (1103515243 * value + 12345); |
| 123 | } | 137 | } |
| 124 | 138 | ||
| 125 | /* Allocate a new symbols for use in the hash of exported symbols or | 139 | /** |
| 126 | * the list of unresolved symbols per module */ | 140 | * Allocate a new symbols for use in the hash of exported symbols or |
| 127 | 141 | * the list of unresolved symbols per module | |
| 128 | struct symbol * | 142 | **/ |
| 129 | alloc_symbol(const char *name, unsigned int weak, struct symbol *next) | 143 | static struct symbol *alloc_symbol(const char *name, unsigned int weak, |
| 144 | struct symbol *next) | ||
| 130 | { | 145 | { |
| 131 | struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); | 146 | struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); |
| 132 | 147 | ||
| @@ -138,9 +153,7 @@ alloc_symbol(const char *name, unsigned int weak, struct symbol *next) | |||
| 138 | } | 153 | } |
| 139 | 154 | ||
| 140 | /* For the hash of exported symbols */ | 155 | /* For the hash of exported symbols */ |
| 141 | 156 | static struct symbol *new_symbol(const char *name, struct module *module) | |
| 142 | void | ||
| 143 | new_symbol(const char *name, struct module *module, unsigned int *crc) | ||
| 144 | { | 157 | { |
| 145 | unsigned int hash; | 158 | unsigned int hash; |
| 146 | struct symbol *new; | 159 | struct symbol *new; |
| @@ -148,14 +161,10 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) | |||
| 148 | hash = tdb_hash(name) % SYMBOL_HASH_SIZE; | 161 | hash = tdb_hash(name) % SYMBOL_HASH_SIZE; |
| 149 | new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); | 162 | new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); |
| 150 | new->module = module; | 163 | new->module = module; |
| 151 | if (crc) { | 164 | return new; |
| 152 | new->crc = *crc; | ||
| 153 | new->crc_valid = 1; | ||
| 154 | } | ||
| 155 | } | 165 | } |
| 156 | 166 | ||
| 157 | struct symbol * | 167 | static struct symbol *find_symbol(const char *name) |
| 158 | find_symbol(const char *name) | ||
| 159 | { | 168 | { |
| 160 | struct symbol *s; | 169 | struct symbol *s; |
| 161 | 170 | ||
| @@ -170,25 +179,42 @@ find_symbol(const char *name) | |||
| 170 | return NULL; | 179 | return NULL; |
| 171 | } | 180 | } |
| 172 | 181 | ||
| 173 | /* Add an exported symbol - it may have already been added without a | 182 | /** |
| 174 | * CRC, in this case just update the CRC */ | 183 | * Add an exported symbol - it may have already been added without a |
| 175 | void | 184 | * CRC, in this case just update the CRC |
| 176 | add_exported_symbol(const char *name, struct module *module, unsigned int *crc) | 185 | **/ |
| 186 | static struct symbol *sym_add_exported(const char *name, struct module *mod) | ||
| 177 | { | 187 | { |
| 178 | struct symbol *s = find_symbol(name); | 188 | struct symbol *s = find_symbol(name); |
| 179 | 189 | ||
| 180 | if (!s) { | 190 | if (!s) { |
| 181 | new_symbol(name, module, crc); | 191 | s = new_symbol(name, mod); |
| 182 | return; | 192 | } else { |
| 183 | } | 193 | if (!s->preloaded) { |
| 184 | if (crc) { | 194 | warn("%s: '%s' exported twice. Previous export " |
| 185 | s->crc = *crc; | 195 | "was in %s%s\n", mod->name, name, |
| 186 | s->crc_valid = 1; | 196 | s->module->name, |
| 197 | is_vmlinux(s->module->name) ?"":".ko"); | ||
| 198 | } | ||
| 187 | } | 199 | } |
| 200 | s->preloaded = 0; | ||
| 201 | s->vmlinux = is_vmlinux(mod->name); | ||
| 202 | s->kernel = 0; | ||
| 203 | return s; | ||
| 204 | } | ||
| 205 | |||
| 206 | static void sym_update_crc(const char *name, struct module *mod, | ||
| 207 | unsigned int crc) | ||
| 208 | { | ||
| 209 | struct symbol *s = find_symbol(name); | ||
| 210 | |||
| 211 | if (!s) | ||
| 212 | s = new_symbol(name, mod); | ||
| 213 | s->crc = crc; | ||
| 214 | s->crc_valid = 1; | ||
| 188 | } | 215 | } |
| 189 | 216 | ||
| 190 | void * | 217 | void *grab_file(const char *filename, unsigned long *size) |
| 191 | grab_file(const char *filename, unsigned long *size) | ||
| 192 | { | 218 | { |
| 193 | struct stat st; | 219 | struct stat st; |
| 194 | void *map; | 220 | void *map; |
| @@ -207,13 +233,12 @@ grab_file(const char *filename, unsigned long *size) | |||
| 207 | return map; | 233 | return map; |
| 208 | } | 234 | } |
| 209 | 235 | ||
| 210 | /* | 236 | /** |
| 211 | Return a copy of the next line in a mmap'ed file. | 237 | * Return a copy of the next line in a mmap'ed file. |
| 212 | spaces in the beginning of the line is trimmed away. | 238 | * spaces in the beginning of the line is trimmed away. |
| 213 | Return a pointer to a static buffer. | 239 | * Return a pointer to a static buffer. |
| 214 | */ | 240 | **/ |
| 215 | char* | 241 | char* get_next_line(unsigned long *pos, void *file, unsigned long size) |
| 216 | get_next_line(unsigned long *pos, void *file, unsigned long size) | ||
| 217 | { | 242 | { |
| 218 | static char line[4096]; | 243 | static char line[4096]; |
| 219 | int skip = 1; | 244 | int skip = 1; |
| @@ -243,14 +268,12 @@ get_next_line(unsigned long *pos, void *file, unsigned long size) | |||
| 243 | return NULL; | 268 | return NULL; |
| 244 | } | 269 | } |
| 245 | 270 | ||
| 246 | void | 271 | void release_file(void *file, unsigned long size) |
| 247 | release_file(void *file, unsigned long size) | ||
| 248 | { | 272 | { |
| 249 | munmap(file, size); | 273 | munmap(file, size); |
| 250 | } | 274 | } |
| 251 | 275 | ||
| 252 | void | 276 | static void parse_elf(struct elf_info *info, const char *filename) |
| 253 | parse_elf(struct elf_info *info, const char *filename) | ||
| 254 | { | 277 | { |
| 255 | unsigned int i; | 278 | unsigned int i; |
| 256 | Elf_Ehdr *hdr = info->hdr; | 279 | Elf_Ehdr *hdr = info->hdr; |
| @@ -297,14 +320,13 @@ parse_elf(struct elf_info *info, const char *filename) | |||
| 297 | continue; | 320 | continue; |
| 298 | 321 | ||
| 299 | info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; | 322 | info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; |
| 300 | info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset | 323 | info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset |
| 301 | + sechdrs[i].sh_size; | 324 | + sechdrs[i].sh_size; |
| 302 | info->strtab = (void *)hdr + | 325 | info->strtab = (void *)hdr + |
| 303 | sechdrs[sechdrs[i].sh_link].sh_offset; | 326 | sechdrs[sechdrs[i].sh_link].sh_offset; |
| 304 | } | 327 | } |
| 305 | if (!info->symtab_start) { | 328 | if (!info->symtab_start) { |
| 306 | fprintf(stderr, "modpost: %s no symtab?\n", filename); | 329 | fatal("%s has no symtab?\n", filename); |
| 307 | abort(); | ||
| 308 | } | 330 | } |
| 309 | /* Fix endianness in symbols */ | 331 | /* Fix endianness in symbols */ |
| 310 | for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { | 332 | for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { |
| @@ -316,36 +338,31 @@ parse_elf(struct elf_info *info, const char *filename) | |||
| 316 | return; | 338 | return; |
| 317 | 339 | ||
| 318 | truncated: | 340 | truncated: |
| 319 | fprintf(stderr, "modpost: %s is truncated.\n", filename); | 341 | fatal("%s is truncated.\n", filename); |
| 320 | abort(); | ||
| 321 | } | 342 | } |
| 322 | 343 | ||
| 323 | void | 344 | static void parse_elf_finish(struct elf_info *info) |
| 324 | parse_elf_finish(struct elf_info *info) | ||
| 325 | { | 345 | { |
| 326 | release_file(info->hdr, info->size); | 346 | release_file(info->hdr, info->size); |
| 327 | } | 347 | } |
| 328 | 348 | ||
| 329 | #define CRC_PFX "__crc_" | 349 | #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" |
| 330 | #define KSYMTAB_PFX "__ksymtab_" | 350 | #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" |
| 331 | 351 | ||
| 332 | void | 352 | static void handle_modversions(struct module *mod, struct elf_info *info, |
| 333 | handle_modversions(struct module *mod, struct elf_info *info, | 353 | Elf_Sym *sym, const char *symname) |
| 334 | Elf_Sym *sym, const char *symname) | ||
| 335 | { | 354 | { |
| 336 | unsigned int crc; | 355 | unsigned int crc; |
| 337 | 356 | ||
| 338 | switch (sym->st_shndx) { | 357 | switch (sym->st_shndx) { |
| 339 | case SHN_COMMON: | 358 | case SHN_COMMON: |
| 340 | fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n", | 359 | warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); |
| 341 | symname, mod->name); | ||
| 342 | break; | 360 | break; |
| 343 | case SHN_ABS: | 361 | case SHN_ABS: |
| 344 | /* CRC'd symbol */ | 362 | /* CRC'd symbol */ |
| 345 | if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { | 363 | if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { |
| 346 | crc = (unsigned int) sym->st_value; | 364 | crc = (unsigned int) sym->st_value; |
| 347 | add_exported_symbol(symname + strlen(CRC_PFX), | 365 | sym_update_crc(symname + strlen(CRC_PFX), mod, crc); |
| 348 | mod, &crc); | ||
| 349 | } | 366 | } |
| 350 | break; | 367 | break; |
| 351 | case SHN_UNDEF: | 368 | case SHN_UNDEF: |
| @@ -370,15 +387,15 @@ handle_modversions(struct module *mod, struct elf_info *info, | |||
| 370 | /* Ignore register directives. */ | 387 | /* Ignore register directives. */ |
| 371 | if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) | 388 | if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) |
| 372 | break; | 389 | break; |
| 373 | if (symname[0] == '.') { | 390 | if (symname[0] == '.') { |
| 374 | char *munged = strdup(symname); | 391 | char *munged = strdup(symname); |
| 375 | munged[0] = '_'; | 392 | munged[0] = '_'; |
| 376 | munged[1] = toupper(munged[1]); | 393 | munged[1] = toupper(munged[1]); |
| 377 | symname = munged; | 394 | symname = munged; |
| 378 | } | 395 | } |
| 379 | } | 396 | } |
| 380 | #endif | 397 | #endif |
| 381 | 398 | ||
| 382 | if (memcmp(symname, MODULE_SYMBOL_PREFIX, | 399 | if (memcmp(symname, MODULE_SYMBOL_PREFIX, |
| 383 | strlen(MODULE_SYMBOL_PREFIX)) == 0) | 400 | strlen(MODULE_SYMBOL_PREFIX)) == 0) |
| 384 | mod->unres = alloc_symbol(symname + | 401 | mod->unres = alloc_symbol(symname + |
| @@ -389,8 +406,7 @@ handle_modversions(struct module *mod, struct elf_info *info, | |||
| 389 | default: | 406 | default: |
| 390 | /* All exported symbols */ | 407 | /* All exported symbols */ |
| 391 | if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { | 408 | if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { |
| 392 | add_exported_symbol(symname + strlen(KSYMTAB_PFX), | 409 | sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); |
| 393 | mod, NULL); | ||
| 394 | } | 410 | } |
| 395 | if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) | 411 | if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) |
| 396 | mod->has_init = 1; | 412 | mod->has_init = 1; |
| @@ -400,20 +416,9 @@ handle_modversions(struct module *mod, struct elf_info *info, | |||
| 400 | } | 416 | } |
| 401 | } | 417 | } |
| 402 | 418 | ||
| 403 | int | 419 | /** |
| 404 | is_vmlinux(const char *modname) | 420 | * Parse tag=value strings from .modinfo section |
| 405 | { | 421 | **/ |
| 406 | const char *myname; | ||
| 407 | |||
| 408 | if ((myname = strrchr(modname, '/'))) | ||
| 409 | myname++; | ||
| 410 | else | ||
| 411 | myname = modname; | ||
| 412 | |||
| 413 | return strcmp(myname, "vmlinux") == 0; | ||
| 414 | } | ||
| 415 | |||
| 416 | /* Parse tag=value strings from .modinfo section */ | ||
| 417 | static char *next_string(char *string, unsigned long *secsize) | 422 | static char *next_string(char *string, unsigned long *secsize) |
| 418 | { | 423 | { |
| 419 | /* Skip non-zero chars */ | 424 | /* Skip non-zero chars */ |
| @@ -446,8 +451,418 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, | |||
| 446 | return NULL; | 451 | return NULL; |
| 447 | } | 452 | } |
| 448 | 453 | ||
| 449 | void | 454 | /** |
| 450 | read_symbols(char *modname) | 455 | * Test if string s ends in string sub |
| 456 | * return 0 if match | ||
| 457 | **/ | ||
| 458 | static int strrcmp(const char *s, const char *sub) | ||
| 459 | { | ||
| 460 | int slen, sublen; | ||
| 461 | |||
| 462 | if (!s || !sub) | ||
| 463 | return 1; | ||
| 464 | |||
| 465 | slen = strlen(s); | ||
| 466 | sublen = strlen(sub); | ||
| 467 | |||
| 468 | if ((slen == 0) || (sublen == 0)) | ||
| 469 | return 1; | ||
| 470 | |||
| 471 | if (sublen > slen) | ||
| 472 | return 1; | ||
| 473 | |||
| 474 | return memcmp(s + slen - sublen, sub, sublen); | ||
| 475 | } | ||
| 476 | |||
| 477 | /** | ||
| 478 | * Whitelist to allow certain references to pass with no warning. | ||
| 479 | * Pattern 1: | ||
| 480 | * If a module parameter is declared __initdata and permissions=0 | ||
| 481 | * then this is legal despite the warning generated. | ||
| 482 | * We cannot see value of permissions here, so just ignore | ||
| 483 | * this pattern. | ||
| 484 | * The pattern is identified by: | ||
| 485 | * tosec = .init.data | ||
| 486 | * fromsec = .data* | ||
| 487 | * atsym =__param* | ||
| 488 | * | ||
| 489 | * Pattern 2: | ||
| 490 | * Many drivers utilise a *_driver container with references to | ||
| 491 | * add, remove, probe functions etc. | ||
| 492 | * These functions may often be marked __init and we do not want to | ||
| 493 | * warn here. | ||
| 494 | * the pattern is identified by: | ||
| 495 | * tosec = .init.text | .exit.text | ||
| 496 | * fromsec = .data | ||
| 497 | * atsym = *_driver, *_ops, *_probe, *probe_one | ||
| 498 | **/ | ||
| 499 | static int secref_whitelist(const char *tosec, const char *fromsec, | ||
| 500 | const char *atsym) | ||
| 501 | { | ||
| 502 | int f1 = 1, f2 = 1; | ||
| 503 | const char **s; | ||
| 504 | const char *pat2sym[] = { | ||
| 505 | "_driver", | ||
| 506 | "_ops", | ||
| 507 | "_probe", | ||
| 508 | "_probe_one", | ||
| 509 | NULL | ||
| 510 | }; | ||
| 511 | |||
| 512 | /* Check for pattern 1 */ | ||
| 513 | if (strcmp(tosec, ".init.data") != 0) | ||
| 514 | f1 = 0; | ||
| 515 | if (strncmp(fromsec, ".data", strlen(".data")) != 0) | ||
| 516 | f1 = 0; | ||
| 517 | if (strncmp(atsym, "__param", strlen("__param")) != 0) | ||
| 518 | f1 = 0; | ||
| 519 | |||
| 520 | if (f1) | ||
| 521 | return f1; | ||
| 522 | |||
| 523 | /* Check for pattern 2 */ | ||
| 524 | if ((strcmp(tosec, ".init.text") != 0) && | ||
| 525 | (strcmp(tosec, ".exit.text") != 0)) | ||
| 526 | f2 = 0; | ||
| 527 | if (strcmp(fromsec, ".data") != 0) | ||
| 528 | f2 = 0; | ||
| 529 | |||
| 530 | for (s = pat2sym; *s; s++) | ||
| 531 | if (strrcmp(atsym, *s) == 0) | ||
| 532 | f1 = 1; | ||
| 533 | |||
| 534 | return f1 && f2; | ||
| 535 | } | ||
| 536 | |||
| 537 | /** | ||
| 538 | * Find symbol based on relocation record info. | ||
| 539 | * In some cases the symbol supplied is a valid symbol so | ||
| 540 | * return refsym. If st_name != 0 we assume this is a valid symbol. | ||
| 541 | * In other cases the symbol needs to be looked up in the symbol table | ||
| 542 | * based on section and address. | ||
| 543 | * **/ | ||
| 544 | static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, | ||
| 545 | Elf_Sym *relsym) | ||
| 546 | { | ||
| 547 | Elf_Sym *sym; | ||
| 548 | |||
| 549 | if (relsym->st_name != 0) | ||
| 550 | return relsym; | ||
| 551 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { | ||
| 552 | if (sym->st_shndx != relsym->st_shndx) | ||
| 553 | continue; | ||
| 554 | if (sym->st_value == addr) | ||
| 555 | return sym; | ||
| 556 | } | ||
| 557 | return NULL; | ||
| 558 | } | ||
| 559 | |||
| 560 | /* | ||
| 561 | * Find symbols before or equal addr and after addr - in the section sec. | ||
| 562 | * If we find two symbols with equal offset prefer one with a valid name. | ||
| 563 | * The ELF format may have a better way to detect what type of symbol | ||
| 564 | * it is, but this works for now. | ||
| 565 | **/ | ||
| 566 | static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, | ||
| 567 | const char *sec, | ||
| 568 | Elf_Sym **before, Elf_Sym **after) | ||
| 569 | { | ||
| 570 | Elf_Sym *sym; | ||
| 571 | Elf_Ehdr *hdr = elf->hdr; | ||
| 572 | Elf_Addr beforediff = ~0; | ||
| 573 | Elf_Addr afterdiff = ~0; | ||
| 574 | const char *secstrings = (void *)hdr + | ||
| 575 | elf->sechdrs[hdr->e_shstrndx].sh_offset; | ||
| 576 | |||
| 577 | *before = NULL; | ||
| 578 | *after = NULL; | ||
| 579 | |||
| 580 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { | ||
| 581 | const char *symsec; | ||
| 582 | |||
| 583 | if (sym->st_shndx >= SHN_LORESERVE) | ||
| 584 | continue; | ||
| 585 | symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name; | ||
| 586 | if (strcmp(symsec, sec) != 0) | ||
| 587 | continue; | ||
| 588 | if (sym->st_value <= addr) { | ||
| 589 | if ((addr - sym->st_value) < beforediff) { | ||
| 590 | beforediff = addr - sym->st_value; | ||
| 591 | *before = sym; | ||
| 592 | } | ||
| 593 | else if ((addr - sym->st_value) == beforediff) { | ||
| 594 | /* equal offset, valid name? */ | ||
| 595 | const char *name = elf->strtab + sym->st_name; | ||
| 596 | if (name && strlen(name)) | ||
| 597 | *before = sym; | ||
| 598 | } | ||
| 599 | } | ||
| 600 | else | ||
| 601 | { | ||
| 602 | if ((sym->st_value - addr) < afterdiff) { | ||
| 603 | afterdiff = sym->st_value - addr; | ||
| 604 | *after = sym; | ||
| 605 | } | ||
| 606 | else if ((sym->st_value - addr) == afterdiff) { | ||
| 607 | /* equal offset, valid name? */ | ||
| 608 | const char *name = elf->strtab + sym->st_name; | ||
| 609 | if (name && strlen(name)) | ||
| 610 | *after = sym; | ||
| 611 | } | ||
| 612 | } | ||
| 613 | } | ||
| 614 | } | ||
| 615 | |||
| 616 | /** | ||
| 617 | * Print a warning about a section mismatch. | ||
| 618 | * Try to find symbols near it so user can find it. | ||
| 619 | * Check whitelist before warning - it may be a false positive. | ||
| 620 | **/ | ||
| 621 | static void warn_sec_mismatch(const char *modname, const char *fromsec, | ||
| 622 | struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) | ||
| 623 | { | ||
| 624 | const char *refsymname = ""; | ||
| 625 | Elf_Sym *before, *after; | ||
| 626 | Elf_Sym *refsym; | ||
| 627 | Elf_Ehdr *hdr = elf->hdr; | ||
| 628 | Elf_Shdr *sechdrs = elf->sechdrs; | ||
| 629 | const char *secstrings = (void *)hdr + | ||
| 630 | sechdrs[hdr->e_shstrndx].sh_offset; | ||
| 631 | const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name; | ||
| 632 | |||
| 633 | find_symbols_between(elf, r.r_offset, fromsec, &before, &after); | ||
| 634 | |||
| 635 | refsym = find_elf_symbol(elf, r.r_addend, sym); | ||
| 636 | if (refsym && strlen(elf->strtab + refsym->st_name)) | ||
| 637 | refsymname = elf->strtab + refsym->st_name; | ||
| 638 | |||
| 639 | /* check whitelist - we may ignore it */ | ||
| 640 | if (before && | ||
| 641 | secref_whitelist(secname, fromsec, elf->strtab + before->st_name)) | ||
| 642 | return; | ||
| 643 | |||
| 644 | if (before && after) { | ||
| 645 | warn("%s - Section mismatch: reference to %s:%s from %s " | ||
| 646 | "between '%s' (at offset 0x%llx) and '%s'\n", | ||
| 647 | modname, secname, refsymname, fromsec, | ||
| 648 | elf->strtab + before->st_name, | ||
| 649 | (long long)r.r_offset, | ||
| 650 | elf->strtab + after->st_name); | ||
| 651 | } else if (before) { | ||
| 652 | warn("%s - Section mismatch: reference to %s:%s from %s " | ||
| 653 | "after '%s' (at offset 0x%llx)\n", | ||
| 654 | modname, secname, refsymname, fromsec, | ||
| 655 | elf->strtab + before->st_name, | ||
| 656 | (long long)r.r_offset); | ||
| 657 | } else if (after) { | ||
| 658 | warn("%s - Section mismatch: reference to %s:%s from %s " | ||
| 659 | "before '%s' (at offset -0x%llx)\n", | ||
| 660 | modname, secname, refsymname, fromsec, | ||
| 661 | elf->strtab + before->st_name, | ||
| 662 | (long long)r.r_offset); | ||
| 663 | } else { | ||
| 664 | warn("%s - Section mismatch: reference to %s:%s from %s " | ||
| 665 | "(offset 0x%llx)\n", | ||
| 666 | modname, secname, fromsec, refsymname, | ||
| 667 | (long long)r.r_offset); | ||
| 668 | } | ||
| 669 | } | ||
| 670 | |||
| 671 | /** | ||
| 672 | * A module includes a number of sections that are discarded | ||
| 673 | * either when loaded or when used as built-in. | ||
| 674 | * For loaded modules all functions marked __init and all data | ||
| 675 | * marked __initdata will be discarded when the module has been intialized. | ||
| 676 | * Likewise for modules used built-in the sections marked __exit | ||
| 677 | * are discarded because __exit marked function are supposed to be called | ||
| 678 | * only when a moduel is unloaded which never happes for built-in modules. | ||
| 679 | * The check_sec_ref() function traverses all relocation records | ||
| 680 | * to find all references to a section that reference a section that will | ||
| 681 | * be discarded and warns about it. | ||
| 682 | **/ | ||
| 683 | static void check_sec_ref(struct module *mod, const char *modname, | ||
| 684 | struct elf_info *elf, | ||
| 685 | int section(const char*), | ||
| 686 | int section_ref_ok(const char *)) | ||
| 687 | { | ||
| 688 | int i; | ||
| 689 | Elf_Sym *sym; | ||
| 690 | Elf_Ehdr *hdr = elf->hdr; | ||
| 691 | Elf_Shdr *sechdrs = elf->sechdrs; | ||
| 692 | const char *secstrings = (void *)hdr + | ||
| 693 | sechdrs[hdr->e_shstrndx].sh_offset; | ||
| 694 | |||
| 695 | /* Walk through all sections */ | ||
| 696 | for (i = 0; i < hdr->e_shnum; i++) { | ||
| 697 | Elf_Rela *rela; | ||
| 698 | Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; | ||
| 699 | Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; | ||
| 700 | const char *name = secstrings + sechdrs[i].sh_name + | ||
| 701 | strlen(".rela"); | ||
| 702 | /* We want to process only relocation sections and not .init */ | ||
| 703 | if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA)) | ||
| 704 | continue; | ||
| 705 | |||
| 706 | for (rela = start; rela < stop; rela++) { | ||
| 707 | Elf_Rela r; | ||
| 708 | const char *secname; | ||
| 709 | r.r_offset = TO_NATIVE(rela->r_offset); | ||
| 710 | r.r_info = TO_NATIVE(rela->r_info); | ||
| 711 | r.r_addend = TO_NATIVE(rela->r_addend); | ||
| 712 | sym = elf->symtab_start + ELF_R_SYM(r.r_info); | ||
| 713 | /* Skip special sections */ | ||
| 714 | if (sym->st_shndx >= SHN_LORESERVE) | ||
| 715 | continue; | ||
| 716 | |||
| 717 | secname = secstrings + sechdrs[sym->st_shndx].sh_name; | ||
| 718 | if (section(secname)) | ||
| 719 | warn_sec_mismatch(modname, name, elf, sym, r); | ||
| 720 | } | ||
| 721 | } | ||
| 722 | } | ||
| 723 | |||
| 724 | /** | ||
| 725 | * Functions used only during module init is marked __init and is stored in | ||
| 726 | * a .init.text section. Likewise data is marked __initdata and stored in | ||
| 727 | * a .init.data section. | ||
| 728 | * If this section is one of these sections return 1 | ||
| 729 | * See include/linux/init.h for the details | ||
| 730 | **/ | ||
| 731 | static int init_section(const char *name) | ||
| 732 | { | ||
| 733 | if (strcmp(name, ".init") == 0) | ||
| 734 | return 1; | ||
| 735 | if (strncmp(name, ".init.", strlen(".init.")) == 0) | ||
| 736 | return 1; | ||
| 737 | return 0; | ||
| 738 | } | ||
| 739 | |||
| 740 | /** | ||
| 741 | * Identify sections from which references to a .init section is OK. | ||
| 742 | * | ||
| 743 | * Unfortunately references to read only data that referenced .init | ||
| 744 | * sections had to be excluded. Almost all of these are false | ||
| 745 | * positives, they are created by gcc. The downside of excluding rodata | ||
| 746 | * is that there really are some user references from rodata to | ||
| 747 | * init code, e.g. drivers/video/vgacon.c: | ||
| 748 | * | ||
| 749 | * const struct consw vga_con = { | ||
| 750 | * con_startup: vgacon_startup, | ||
| 751 | * | ||
| 752 | * where vgacon_startup is __init. If you want to wade through the false | ||
| 753 | * positives, take out the check for rodata. | ||
| 754 | **/ | ||
| 755 | static int init_section_ref_ok(const char *name) | ||
| 756 | { | ||
| 757 | const char **s; | ||
| 758 | /* Absolute section names */ | ||
| 759 | const char *namelist1[] = { | ||
| 760 | ".init", | ||
| 761 | ".opd", /* see comment [OPD] at exit_section_ref_ok() */ | ||
| 762 | ".toc1", /* used by ppc64 */ | ||
| 763 | ".stab", | ||
| 764 | ".rodata", | ||
| 765 | ".text.lock", | ||
| 766 | "__bug_table", /* used by powerpc for BUG() */ | ||
| 767 | ".pci_fixup_header", | ||
| 768 | ".pci_fixup_final", | ||
| 769 | ".pdr", | ||
| 770 | "__param", | ||
| 771 | NULL | ||
| 772 | }; | ||
| 773 | /* Start of section names */ | ||
| 774 | const char *namelist2[] = { | ||
| 775 | ".init.", | ||
| 776 | ".altinstructions", | ||
| 777 | ".eh_frame", | ||
| 778 | ".debug", | ||
| 779 | NULL | ||
| 780 | }; | ||
| 781 | /* part of section name */ | ||
| 782 | const char *namelist3 [] = { | ||
| 783 | ".unwind", /* sample: IA_64.unwind.init.text */ | ||
| 784 | NULL | ||
| 785 | }; | ||
| 786 | |||
| 787 | for (s = namelist1; *s; s++) | ||
| 788 | if (strcmp(*s, name) == 0) | ||
| 789 | return 1; | ||
| 790 | for (s = namelist2; *s; s++) | ||
| 791 | if (strncmp(*s, name, strlen(*s)) == 0) | ||
| 792 | return 1; | ||
| 793 | for (s = namelist3; *s; s++) | ||
| 794 | if (strstr(name, *s) != NULL) | ||
| 795 | return 1; | ||
| 796 | return 0; | ||
| 797 | } | ||
| 798 | |||
| 799 | /* | ||
| 800 | * Functions used only during module exit is marked __exit and is stored in | ||
| 801 | * a .exit.text section. Likewise data is marked __exitdata and stored in | ||
| 802 | * a .exit.data section. | ||
| 803 | * If this section is one of these sections return 1 | ||
| 804 | * See include/linux/init.h for the details | ||
| 805 | **/ | ||
| 806 | static int exit_section(const char *name) | ||
| 807 | { | ||
| 808 | if (strcmp(name, ".exit.text") == 0) | ||
| 809 | return 1; | ||
| 810 | if (strcmp(name, ".exit.data") == 0) | ||
| 811 | return 1; | ||
| 812 | return 0; | ||
| 813 | |||
| 814 | } | ||
| 815 | |||
| 816 | /* | ||
| 817 | * Identify sections from which references to a .exit section is OK. | ||
| 818 | * | ||
| 819 | * [OPD] Keith Ownes <kaos@sgi.com> commented: | ||
| 820 | * For our future {in}sanity, add a comment that this is the ppc .opd | ||
| 821 | * section, not the ia64 .opd section. | ||
| 822 | * ia64 .opd should not point to discarded sections. | ||
| 823 | **/ | ||
| 824 | static int exit_section_ref_ok(const char *name) | ||
| 825 | { | ||
| 826 | const char **s; | ||
| 827 | /* Absolute section names */ | ||
| 828 | const char *namelist1[] = { | ||
| 829 | ".exit.text", | ||
| 830 | ".exit.data", | ||
| 831 | ".init.text", | ||
| 832 | ".opd", /* See comment [OPD] */ | ||
| 833 | ".toc1", /* used by ppc64 */ | ||
| 834 | ".altinstructions", | ||
| 835 | ".pdr", | ||
| 836 | "__bug_table", /* used by powerpc for BUG() */ | ||
| 837 | ".exitcall.exit", | ||
| 838 | ".eh_frame", | ||
| 839 | ".stab", | ||
| 840 | NULL | ||
| 841 | }; | ||
| 842 | /* Start of section names */ | ||
| 843 | const char *namelist2[] = { | ||
| 844 | ".debug", | ||
| 845 | NULL | ||
| 846 | }; | ||
| 847 | /* part of section name */ | ||
| 848 | const char *namelist3 [] = { | ||
| 849 | ".unwind", /* Sample: IA_64.unwind.exit.text */ | ||
| 850 | NULL | ||
| 851 | }; | ||
| 852 | |||
| 853 | for (s = namelist1; *s; s++) | ||
| 854 | if (strcmp(*s, name) == 0) | ||
| 855 | return 1; | ||
| 856 | for (s = namelist2; *s; s++) | ||
| 857 | if (strncmp(*s, name, strlen(*s)) == 0) | ||
| 858 | return 1; | ||
| 859 | for (s = namelist3; *s; s++) | ||
| 860 | if (strstr(name, *s) != NULL) | ||
| 861 | return 1; | ||
| 862 | return 0; | ||
| 863 | } | ||
| 864 | |||
| 865 | static void read_symbols(char *modname) | ||
| 451 | { | 866 | { |
| 452 | const char *symname; | 867 | const char *symname; |
| 453 | char *version; | 868 | char *version; |
| @@ -462,9 +877,7 @@ read_symbols(char *modname) | |||
| 462 | /* When there's no vmlinux, don't print warnings about | 877 | /* When there's no vmlinux, don't print warnings about |
| 463 | * unresolved symbols (since there'll be too many ;) */ | 878 | * unresolved symbols (since there'll be too many ;) */ |
| 464 | if (is_vmlinux(modname)) { | 879 | if (is_vmlinux(modname)) { |
| 465 | unsigned int fake_crc = 0; | ||
| 466 | have_vmlinux = 1; | 880 | have_vmlinux = 1; |
| 467 | add_exported_symbol("struct_module", mod, &fake_crc); | ||
| 468 | mod->skip = 1; | 881 | mod->skip = 1; |
| 469 | } | 882 | } |
| 470 | 883 | ||
| @@ -474,6 +887,8 @@ read_symbols(char *modname) | |||
| 474 | handle_modversions(mod, &info, sym, symname); | 887 | handle_modversions(mod, &info, sym, symname); |
| 475 | handle_moddevtable(mod, &info, sym, symname); | 888 | handle_moddevtable(mod, &info, sym, symname); |
| 476 | } | 889 | } |
| 890 | check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); | ||
| 891 | check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); | ||
| 477 | 892 | ||
| 478 | version = get_modinfo(info.modinfo, info.modinfo_len, "version"); | 893 | version = get_modinfo(info.modinfo, info.modinfo_len, "version"); |
| 479 | if (version) | 894 | if (version) |
| @@ -499,21 +914,20 @@ read_symbols(char *modname) | |||
| 499 | * following helper, then compare to the file on disk and | 914 | * following helper, then compare to the file on disk and |
| 500 | * only update the later if anything changed */ | 915 | * only update the later if anything changed */ |
| 501 | 916 | ||
| 502 | void __attribute__((format(printf, 2, 3))) | 917 | void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, |
| 503 | buf_printf(struct buffer *buf, const char *fmt, ...) | 918 | const char *fmt, ...) |
| 504 | { | 919 | { |
| 505 | char tmp[SZ]; | 920 | char tmp[SZ]; |
| 506 | int len; | 921 | int len; |
| 507 | va_list ap; | 922 | va_list ap; |
| 508 | 923 | ||
| 509 | va_start(ap, fmt); | 924 | va_start(ap, fmt); |
| 510 | len = vsnprintf(tmp, SZ, fmt, ap); | 925 | len = vsnprintf(tmp, SZ, fmt, ap); |
| 511 | buf_write(buf, tmp, len); | 926 | buf_write(buf, tmp, len); |
| 512 | va_end(ap); | 927 | va_end(ap); |
| 513 | } | 928 | } |
| 514 | 929 | ||
| 515 | void | 930 | void buf_write(struct buffer *buf, const char *s, int len) |
| 516 | buf_write(struct buffer *buf, const char *s, int len) | ||
| 517 | { | 931 | { |
| 518 | if (buf->size - buf->pos < len) { | 932 | if (buf->size - buf->pos < len) { |
| 519 | buf->size += len + SZ; | 933 | buf->size += len + SZ; |
| @@ -523,10 +937,10 @@ buf_write(struct buffer *buf, const char *s, int len) | |||
| 523 | buf->pos += len; | 937 | buf->pos += len; |
| 524 | } | 938 | } |
| 525 | 939 | ||
| 526 | /* Header for the generated file */ | 940 | /** |
| 527 | 941 | * Header for the generated file | |
| 528 | void | 942 | **/ |
| 529 | add_header(struct buffer *b, struct module *mod) | 943 | static void add_header(struct buffer *b, struct module *mod) |
| 530 | { | 944 | { |
| 531 | buf_printf(b, "#include <linux/module.h>\n"); | 945 | buf_printf(b, "#include <linux/module.h>\n"); |
| 532 | buf_printf(b, "#include <linux/vermagic.h>\n"); | 946 | buf_printf(b, "#include <linux/vermagic.h>\n"); |
| @@ -546,10 +960,10 @@ add_header(struct buffer *b, struct module *mod) | |||
| 546 | buf_printf(b, "};\n"); | 960 | buf_printf(b, "};\n"); |
| 547 | } | 961 | } |
| 548 | 962 | ||
| 549 | /* Record CRCs for unresolved symbols */ | 963 | /** |
| 550 | 964 | * Record CRCs for unresolved symbols | |
| 551 | void | 965 | **/ |
| 552 | add_versions(struct buffer *b, struct module *mod) | 966 | static void add_versions(struct buffer *b, struct module *mod) |
| 553 | { | 967 | { |
| 554 | struct symbol *s, *exp; | 968 | struct symbol *s, *exp; |
| 555 | 969 | ||
| @@ -557,8 +971,8 @@ add_versions(struct buffer *b, struct module *mod) | |||
| 557 | exp = find_symbol(s->name); | 971 | exp = find_symbol(s->name); |
| 558 | if (!exp || exp->module == mod) { | 972 | if (!exp || exp->module == mod) { |
| 559 | if (have_vmlinux && !s->weak) | 973 | if (have_vmlinux && !s->weak) |
| 560 | fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " | 974 | warn("\"%s\" [%s.ko] undefined!\n", |
| 561 | "undefined!\n", s->name, mod->name); | 975 | s->name, mod->name); |
| 562 | continue; | 976 | continue; |
| 563 | } | 977 | } |
| 564 | s->module = exp->module; | 978 | s->module = exp->module; |
| @@ -579,8 +993,7 @@ add_versions(struct buffer *b, struct module *mod) | |||
| 579 | continue; | 993 | continue; |
| 580 | } | 994 | } |
| 581 | if (!s->crc_valid) { | 995 | if (!s->crc_valid) { |
| 582 | fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " | 996 | warn("\"%s\" [%s.ko] has no CRC!\n", |
| 583 | "has no CRC!\n", | ||
| 584 | s->name, mod->name); | 997 | s->name, mod->name); |
| 585 | continue; | 998 | continue; |
| 586 | } | 999 | } |
| @@ -590,8 +1003,8 @@ add_versions(struct buffer *b, struct module *mod) | |||
| 590 | buf_printf(b, "};\n"); | 1003 | buf_printf(b, "};\n"); |
| 591 | } | 1004 | } |
| 592 | 1005 | ||
| 593 | void | 1006 | static void add_depends(struct buffer *b, struct module *mod, |
| 594 | add_depends(struct buffer *b, struct module *mod, struct module *modules) | 1007 | struct module *modules) |
| 595 | { | 1008 | { |
| 596 | struct symbol *s; | 1009 | struct symbol *s; |
| 597 | struct module *m; | 1010 | struct module *m; |
| @@ -621,8 +1034,7 @@ add_depends(struct buffer *b, struct module *mod, struct module *modules) | |||
| 621 | buf_printf(b, "\";\n"); | 1034 | buf_printf(b, "\";\n"); |
| 622 | } | 1035 | } |
| 623 | 1036 | ||
| 624 | void | 1037 | static void add_srcversion(struct buffer *b, struct module *mod) |
| 625 | add_srcversion(struct buffer *b, struct module *mod) | ||
| 626 | { | 1038 | { |
| 627 | if (mod->srcversion[0]) { | 1039 | if (mod->srcversion[0]) { |
| 628 | buf_printf(b, "\n"); | 1040 | buf_printf(b, "\n"); |
| @@ -631,8 +1043,7 @@ add_srcversion(struct buffer *b, struct module *mod) | |||
| 631 | } | 1043 | } |
| 632 | } | 1044 | } |
| 633 | 1045 | ||
| 634 | void | 1046 | static void write_if_changed(struct buffer *b, const char *fname) |
| 635 | write_if_changed(struct buffer *b, const char *fname) | ||
| 636 | { | 1047 | { |
| 637 | char *tmp; | 1048 | char *tmp; |
| 638 | FILE *file; | 1049 | FILE *file; |
| @@ -676,8 +1087,7 @@ write_if_changed(struct buffer *b, const char *fname) | |||
| 676 | fclose(file); | 1087 | fclose(file); |
| 677 | } | 1088 | } |
| 678 | 1089 | ||
| 679 | void | 1090 | static void read_dump(const char *fname, unsigned int kernel) |
| 680 | read_dump(const char *fname) | ||
| 681 | { | 1091 | { |
| 682 | unsigned long size, pos = 0; | 1092 | unsigned long size, pos = 0; |
| 683 | void *file = grab_file(fname, &size); | 1093 | void *file = grab_file(fname, &size); |
| @@ -691,6 +1101,7 @@ read_dump(const char *fname) | |||
| 691 | char *symname, *modname, *d; | 1101 | char *symname, *modname, *d; |
| 692 | unsigned int crc; | 1102 | unsigned int crc; |
| 693 | struct module *mod; | 1103 | struct module *mod; |
| 1104 | struct symbol *s; | ||
| 694 | 1105 | ||
| 695 | if (!(symname = strchr(line, '\t'))) | 1106 | if (!(symname = strchr(line, '\t'))) |
| 696 | goto fail; | 1107 | goto fail; |
| @@ -711,15 +1122,30 @@ read_dump(const char *fname) | |||
| 711 | mod = new_module(NOFAIL(strdup(modname))); | 1122 | mod = new_module(NOFAIL(strdup(modname))); |
| 712 | mod->skip = 1; | 1123 | mod->skip = 1; |
| 713 | } | 1124 | } |
| 714 | add_exported_symbol(symname, mod, &crc); | 1125 | s = sym_add_exported(symname, mod); |
| 1126 | s->kernel = kernel; | ||
| 1127 | s->preloaded = 1; | ||
| 1128 | sym_update_crc(symname, mod, crc); | ||
| 715 | } | 1129 | } |
| 716 | return; | 1130 | return; |
| 717 | fail: | 1131 | fail: |
| 718 | fatal("parse error in symbol dump file\n"); | 1132 | fatal("parse error in symbol dump file\n"); |
| 719 | } | 1133 | } |
| 720 | 1134 | ||
| 721 | void | 1135 | /* For normal builds always dump all symbols. |
| 722 | write_dump(const char *fname) | 1136 | * For external modules only dump symbols |
| 1137 | * that are not read from kernel Module.symvers. | ||
| 1138 | **/ | ||
| 1139 | static int dump_sym(struct symbol *sym) | ||
| 1140 | { | ||
| 1141 | if (!external_module) | ||
| 1142 | return 1; | ||
| 1143 | if (sym->vmlinux || sym->kernel) | ||
| 1144 | return 0; | ||
| 1145 | return 1; | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | static void write_dump(const char *fname) | ||
| 723 | { | 1149 | { |
| 724 | struct buffer buf = { }; | 1150 | struct buffer buf = { }; |
| 725 | struct symbol *symbol; | 1151 | struct symbol *symbol; |
| @@ -728,34 +1154,33 @@ write_dump(const char *fname) | |||
| 728 | for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { | 1154 | for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { |
| 729 | symbol = symbolhash[n]; | 1155 | symbol = symbolhash[n]; |
| 730 | while (symbol) { | 1156 | while (symbol) { |
| 731 | symbol = symbol->next; | 1157 | if (dump_sym(symbol)) |
| 732 | } | 1158 | buf_printf(&buf, "0x%08x\t%s\t%s\n", |
| 733 | } | 1159 | symbol->crc, symbol->name, |
| 734 | 1160 | symbol->module->name); | |
| 735 | for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { | ||
| 736 | symbol = symbolhash[n]; | ||
| 737 | while (symbol) { | ||
| 738 | buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc, | ||
| 739 | symbol->name, symbol->module->name); | ||
| 740 | symbol = symbol->next; | 1161 | symbol = symbol->next; |
| 741 | } | 1162 | } |
| 742 | } | 1163 | } |
| 743 | write_if_changed(&buf, fname); | 1164 | write_if_changed(&buf, fname); |
| 744 | } | 1165 | } |
| 745 | 1166 | ||
| 746 | int | 1167 | int main(int argc, char **argv) |
| 747 | main(int argc, char **argv) | ||
| 748 | { | 1168 | { |
| 749 | struct module *mod; | 1169 | struct module *mod; |
| 750 | struct buffer buf = { }; | 1170 | struct buffer buf = { }; |
| 751 | char fname[SZ]; | 1171 | char fname[SZ]; |
| 752 | char *dump_read = NULL, *dump_write = NULL; | 1172 | char *kernel_read = NULL, *module_read = NULL; |
| 1173 | char *dump_write = NULL; | ||
| 753 | int opt; | 1174 | int opt; |
| 754 | 1175 | ||
| 755 | while ((opt = getopt(argc, argv, "i:mo:a")) != -1) { | 1176 | while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) { |
| 756 | switch(opt) { | 1177 | switch(opt) { |
| 757 | case 'i': | 1178 | case 'i': |
| 758 | dump_read = optarg; | 1179 | kernel_read = optarg; |
| 1180 | break; | ||
| 1181 | case 'I': | ||
| 1182 | module_read = optarg; | ||
| 1183 | external_module = 1; | ||
| 759 | break; | 1184 | break; |
| 760 | case 'm': | 1185 | case 'm': |
| 761 | modversions = 1; | 1186 | modversions = 1; |
| @@ -771,8 +1196,10 @@ main(int argc, char **argv) | |||
| 771 | } | 1196 | } |
| 772 | } | 1197 | } |
| 773 | 1198 | ||
| 774 | if (dump_read) | 1199 | if (kernel_read) |
| 775 | read_dump(dump_read); | 1200 | read_dump(kernel_read, 1); |
| 1201 | if (module_read) | ||
| 1202 | read_dump(module_read, 0); | ||
| 776 | 1203 | ||
| 777 | while (optind < argc) { | 1204 | while (optind < argc) { |
| 778 | read_symbols(argv[optind++]); | 1205 | read_symbols(argv[optind++]); |
| @@ -799,4 +1226,3 @@ main(int argc, char **argv) | |||
| 799 | 1226 | ||
| 800 | return 0; | 1227 | return 0; |
| 801 | } | 1228 | } |
| 802 | |||
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 7334d839145d..b14255c72a37 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h | |||
| @@ -13,20 +13,30 @@ | |||
| 13 | 13 | ||
| 14 | #if KERNEL_ELFCLASS == ELFCLASS32 | 14 | #if KERNEL_ELFCLASS == ELFCLASS32 |
| 15 | 15 | ||
| 16 | #define Elf_Ehdr Elf32_Ehdr | 16 | #define Elf_Ehdr Elf32_Ehdr |
| 17 | #define Elf_Shdr Elf32_Shdr | 17 | #define Elf_Shdr Elf32_Shdr |
| 18 | #define Elf_Sym Elf32_Sym | 18 | #define Elf_Sym Elf32_Sym |
| 19 | #define Elf_Addr Elf32_Addr | ||
| 20 | #define Elf_Section Elf32_Section | ||
| 19 | #define ELF_ST_BIND ELF32_ST_BIND | 21 | #define ELF_ST_BIND ELF32_ST_BIND |
| 20 | #define ELF_ST_TYPE ELF32_ST_TYPE | 22 | #define ELF_ST_TYPE ELF32_ST_TYPE |
| 21 | 23 | ||
| 24 | #define Elf_Rela Elf32_Rela | ||
| 25 | #define ELF_R_SYM ELF32_R_SYM | ||
| 26 | #define ELF_R_TYPE ELF32_R_TYPE | ||
| 22 | #else | 27 | #else |
| 23 | 28 | ||
| 24 | #define Elf_Ehdr Elf64_Ehdr | 29 | #define Elf_Ehdr Elf64_Ehdr |
| 25 | #define Elf_Shdr Elf64_Shdr | 30 | #define Elf_Shdr Elf64_Shdr |
| 26 | #define Elf_Sym Elf64_Sym | 31 | #define Elf_Sym Elf64_Sym |
| 32 | #define Elf_Addr Elf64_Addr | ||
| 33 | #define Elf_Section Elf64_Section | ||
| 27 | #define ELF_ST_BIND ELF64_ST_BIND | 34 | #define ELF_ST_BIND ELF64_ST_BIND |
| 28 | #define ELF_ST_TYPE ELF64_ST_TYPE | 35 | #define ELF_ST_TYPE ELF64_ST_TYPE |
| 29 | 36 | ||
| 37 | #define Elf_Rela Elf64_Rela | ||
| 38 | #define ELF_R_SYM ELF64_R_SYM | ||
| 39 | #define ELF_R_TYPE ELF64_R_TYPE | ||
| 30 | #endif | 40 | #endif |
| 31 | 41 | ||
| 32 | #if KERNEL_ELFDATA != HOST_ELFDATA | 42 | #if KERNEL_ELFDATA != HOST_ELFDATA |
| @@ -91,17 +101,22 @@ struct elf_info { | |||
| 91 | unsigned int modinfo_len; | 101 | unsigned int modinfo_len; |
| 92 | }; | 102 | }; |
| 93 | 103 | ||
| 104 | /* file2alias.c */ | ||
| 94 | void handle_moddevtable(struct module *mod, struct elf_info *info, | 105 | void handle_moddevtable(struct module *mod, struct elf_info *info, |
| 95 | Elf_Sym *sym, const char *symname); | 106 | Elf_Sym *sym, const char *symname); |
| 96 | |||
| 97 | void add_moddevtable(struct buffer *buf, struct module *mod); | 107 | void add_moddevtable(struct buffer *buf, struct module *mod); |
| 98 | 108 | ||
| 109 | /* sumversion.c */ | ||
| 99 | void maybe_frob_rcs_version(const char *modfilename, | 110 | void maybe_frob_rcs_version(const char *modfilename, |
| 100 | char *version, | 111 | char *version, |
| 101 | void *modinfo, | 112 | void *modinfo, |
| 102 | unsigned long modinfo_offset); | 113 | unsigned long modinfo_offset); |
| 103 | void get_src_version(const char *modname, char sum[], unsigned sumlen); | 114 | void get_src_version(const char *modname, char sum[], unsigned sumlen); |
| 104 | 115 | ||
| 116 | /* from modpost.c */ | ||
| 105 | void *grab_file(const char *filename, unsigned long *size); | 117 | void *grab_file(const char *filename, unsigned long *size); |
| 106 | char* get_next_line(unsigned long *pos, void *file, unsigned long size); | 118 | char* get_next_line(unsigned long *pos, void *file, unsigned long size); |
| 107 | void release_file(void *file, unsigned long size); | 119 | void release_file(void *file, unsigned long size); |
| 120 | |||
| 121 | void fatal(const char *fmt, ...); | ||
| 122 | void warn(const char *fmt, ...); | ||
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 43271a1ca01e..8a2875689e4d 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c | |||
| @@ -316,8 +316,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) | |||
| 316 | 316 | ||
| 317 | file = grab_file(cmd, &flen); | 317 | file = grab_file(cmd, &flen); |
| 318 | if (!file) { | 318 | if (!file) { |
| 319 | fprintf(stderr, "Warning: could not find %s for %s\n", | 319 | warn("could not find %s for %s\n", cmd, objfile); |
| 320 | cmd, objfile); | ||
| 321 | goto out; | 320 | goto out; |
| 322 | } | 321 | } |
| 323 | 322 | ||
| @@ -355,9 +354,8 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) | |||
| 355 | /* Check if this file is in same dir as objfile */ | 354 | /* Check if this file is in same dir as objfile */ |
| 356 | if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { | 355 | if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { |
| 357 | if (!parse_file(line, md)) { | 356 | if (!parse_file(line, md)) { |
| 358 | fprintf(stderr, | 357 | warn("could not open %s: %s\n", |
| 359 | "Warning: could not open %s: %s\n", | 358 | line, strerror(errno)); |
| 360 | line, strerror(errno)); | ||
| 361 | goto out_file; | 359 | goto out_file; |
| 362 | } | 360 | } |
| 363 | 361 | ||
| @@ -383,8 +381,11 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) | |||
| 383 | struct md4_ctx md; | 381 | struct md4_ctx md; |
| 384 | char *sources, *end, *fname; | 382 | char *sources, *end, *fname; |
| 385 | const char *basename; | 383 | const char *basename; |
| 386 | char filelist[strlen(getenv("MODVERDIR")) + strlen("/") + | 384 | char filelist[PATH_MAX + 1]; |
| 387 | strlen(modname) - strlen(".o") + strlen(".mod") + 1 ]; | 385 | char *modverdir = getenv("MODVERDIR"); |
| 386 | |||
| 387 | if (!modverdir) | ||
| 388 | modverdir = "."; | ||
| 388 | 389 | ||
| 389 | /* Source files for module are in .tmp_versions/modname.mod, | 390 | /* Source files for module are in .tmp_versions/modname.mod, |
| 390 | after the first line. */ | 391 | after the first line. */ |
| @@ -392,28 +393,25 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) | |||
| 392 | basename = strrchr(modname, '/') + 1; | 393 | basename = strrchr(modname, '/') + 1; |
| 393 | else | 394 | else |
| 394 | basename = modname; | 395 | basename = modname; |
| 395 | sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"), | 396 | sprintf(filelist, "%s/%.*s.mod", modverdir, |
| 396 | (int) strlen(basename) - 2, basename); | 397 | (int) strlen(basename) - 2, basename); |
| 397 | 398 | ||
| 398 | file = grab_file(filelist, &len); | 399 | file = grab_file(filelist, &len); |
| 399 | if (!file) { | 400 | if (!file) { |
| 400 | fprintf(stderr, "Warning: could not find versions for %s\n", | 401 | warn("could not find versions for %s\n", filelist); |
| 401 | filelist); | ||
| 402 | return; | 402 | return; |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | sources = strchr(file, '\n'); | 405 | sources = strchr(file, '\n'); |
| 406 | if (!sources) { | 406 | if (!sources) { |
| 407 | fprintf(stderr, "Warning: malformed versions file for %s\n", | 407 | warn("malformed versions file for %s\n", modname); |
| 408 | modname); | ||
| 409 | goto release; | 408 | goto release; |
| 410 | } | 409 | } |
| 411 | 410 | ||
| 412 | sources++; | 411 | sources++; |
| 413 | end = strchr(sources, '\n'); | 412 | end = strchr(sources, '\n'); |
| 414 | if (!end) { | 413 | if (!end) { |
| 415 | fprintf(stderr, "Warning: bad ending versions file for %s\n", | 414 | warn("bad ending versions file for %s\n", modname); |
| 416 | modname); | ||
| 417 | goto release; | 415 | goto release; |
| 418 | } | 416 | } |
| 419 | *end = '\0'; | 417 | *end = '\0'; |
| @@ -438,19 +436,19 @@ static void write_version(const char *filename, const char *sum, | |||
| 438 | 436 | ||
| 439 | fd = open(filename, O_RDWR); | 437 | fd = open(filename, O_RDWR); |
| 440 | if (fd < 0) { | 438 | if (fd < 0) { |
| 441 | fprintf(stderr, "Warning: changing sum in %s failed: %s\n", | 439 | warn("changing sum in %s failed: %s\n", |
| 442 | filename, strerror(errno)); | 440 | filename, strerror(errno)); |
| 443 | return; | 441 | return; |
| 444 | } | 442 | } |
| 445 | 443 | ||
| 446 | if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { | 444 | if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { |
| 447 | fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n", | 445 | warn("changing sum in %s:%lu failed: %s\n", |
| 448 | filename, offset, strerror(errno)); | 446 | filename, offset, strerror(errno)); |
| 449 | goto out; | 447 | goto out; |
| 450 | } | 448 | } |
| 451 | 449 | ||
| 452 | if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { | 450 | if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { |
| 453 | fprintf(stderr, "Warning: writing sum in %s failed: %s\n", | 451 | warn("writing sum in %s failed: %s\n", |
| 454 | filename, strerror(errno)); | 452 | filename, strerror(errno)); |
| 455 | goto out; | 453 | goto out; |
| 456 | } | 454 | } |
diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 88e30e82f1ca..f34373853ef8 100644 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl | |||
| @@ -66,8 +66,8 @@ require 5; # at least perl 5 | |||
| 66 | use strict; | 66 | use strict; |
| 67 | use File::Find; | 67 | use File::Find; |
| 68 | 68 | ||
| 69 | my $nm = "/usr/bin/nm -p"; | 69 | my $nm = ($ENV{'NM'} || "nm") . " -p"; |
| 70 | my $objdump = "/usr/bin/objdump -s -j .comment"; | 70 | my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment"; |
| 71 | my $srctree = ""; | 71 | my $srctree = ""; |
| 72 | my $objtree = ""; | 72 | my $objtree = ""; |
| 73 | $srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'})); | 73 | $srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'})); |
diff --git a/scripts/package/Makefile b/scripts/package/Makefile index c201ef001f09..7c434e037e7f 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile | |||
| @@ -32,12 +32,11 @@ MKSPEC := $(srctree)/scripts/package/mkspec | |||
| 32 | PREV := set -e; cd ..; | 32 | PREV := set -e; cd ..; |
| 33 | 33 | ||
| 34 | # rpm-pkg | 34 | # rpm-pkg |
| 35 | .PHONY: rpm-pkg rpm | 35 | # --------------------------------------------------------------------------- |
| 36 | |||
| 37 | $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile | 36 | $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile |
| 38 | $(CONFIG_SHELL) $(MKSPEC) > $@ | 37 | $(CONFIG_SHELL) $(MKSPEC) > $@ |
| 39 | 38 | ||
| 40 | rpm-pkg rpm: $(objtree)/kernel.spec | 39 | rpm-pkg rpm: $(objtree)/kernel.spec FORCE |
| 41 | $(MAKE) clean | 40 | $(MAKE) clean |
| 42 | $(PREV) ln -sf $(srctree) $(KERNELPATH) | 41 | $(PREV) ln -sf $(srctree) $(KERNELPATH) |
| 43 | $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. | 42 | $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. |
| @@ -54,11 +53,11 @@ rpm-pkg rpm: $(objtree)/kernel.spec | |||
| 54 | clean-files := $(objtree)/kernel.spec | 53 | clean-files := $(objtree)/kernel.spec |
| 55 | 54 | ||
| 56 | # binrpm-pkg | 55 | # binrpm-pkg |
| 57 | .PHONY: binrpm-pkg | 56 | # --------------------------------------------------------------------------- |
| 58 | $(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile | 57 | $(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile |
| 59 | $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@ | 58 | $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@ |
| 60 | 59 | ||
| 61 | binrpm-pkg: $(objtree)/binkernel.spec | 60 | binrpm-pkg: $(objtree)/binkernel.spec FORCE |
| 62 | $(MAKE) KBUILD_SRC= | 61 | $(MAKE) KBUILD_SRC= |
| 63 | set -e; \ | 62 | set -e; \ |
| 64 | $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version | 63 | $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version |
| @@ -71,9 +70,7 @@ clean-files += $(objtree)/binkernel.spec | |||
| 71 | 70 | ||
| 72 | # Deb target | 71 | # Deb target |
| 73 | # --------------------------------------------------------------------------- | 72 | # --------------------------------------------------------------------------- |
| 74 | # | 73 | deb-pkg: FORCE |
| 75 | .PHONY: deb-pkg | ||
| 76 | deb-pkg: | ||
| 77 | $(MAKE) KBUILD_SRC= | 74 | $(MAKE) KBUILD_SRC= |
| 78 | $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb | 75 | $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb |
| 79 | 76 | ||
| @@ -82,8 +79,7 @@ clean-dirs += $(objtree)/debian/ | |||
| 82 | 79 | ||
| 83 | # tarball targets | 80 | # tarball targets |
| 84 | # --------------------------------------------------------------------------- | 81 | # --------------------------------------------------------------------------- |
| 85 | .PHONY: tar%pkg | 82 | tar%pkg: FORCE |
| 86 | tar%pkg: | ||
| 87 | $(MAKE) KBUILD_SRC= | 83 | $(MAKE) KBUILD_SRC= |
| 88 | $(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ | 84 | $(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ |
| 89 | 85 | ||
| @@ -92,7 +88,7 @@ clean-dirs += $(objtree)/tar-install/ | |||
| 92 | 88 | ||
| 93 | # Help text displayed when executing 'make help' | 89 | # Help text displayed when executing 'make help' |
| 94 | # --------------------------------------------------------------------------- | 90 | # --------------------------------------------------------------------------- |
| 95 | help: | 91 | help: FORCE |
| 96 | @echo ' rpm-pkg - Build the kernel as an RPM package' | 92 | @echo ' rpm-pkg - Build the kernel as an RPM package' |
| 97 | @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel' | 93 | @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel' |
| 98 | @echo ' and modules' | 94 | @echo ' and modules' |
diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl new file mode 100644 index 000000000000..cb4260ebdb91 --- /dev/null +++ b/scripts/profile2linkerlist.pl | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | |||
| 3 | # | ||
| 4 | # Takes a (sorted) output of readprofile and turns it into a list suitable for | ||
| 5 | # linker scripts | ||
| 6 | # | ||
| 7 | # usage: | ||
| 8 | # readprofile | sort -rn | perl profile2linkerlist.pl > functionlist | ||
| 9 | # | ||
| 10 | |||
| 11 | while (<>) { | ||
| 12 | my $line = $_; | ||
| 13 | |||
| 14 | $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/; | ||
| 15 | |||
| 16 | if ( ($line =~ /unknown/) || ($line =~ /total/)) { | ||
| 17 | |||
| 18 | } else { | ||
| 19 | print "*(.text.$1)\n"; | ||
| 20 | } | ||
| 21 | } | ||
diff --git a/scripts/reference_discarded.pl b/scripts/reference_discarded.pl deleted file mode 100644 index 4ee6ab2135b3..000000000000 --- a/scripts/reference_discarded.pl +++ /dev/null | |||
| @@ -1,112 +0,0 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # reference_discarded.pl (C) Keith Owens 2001 <kaos@ocs.com.au> | ||
| 4 | # | ||
| 5 | # Released under GPL V2. | ||
| 6 | # | ||
| 7 | # List dangling references to vmlinux discarded sections. | ||
| 8 | |||
| 9 | use strict; | ||
| 10 | die($0 . " takes no arguments\n") if($#ARGV >= 0); | ||
| 11 | |||
| 12 | my %object; | ||
| 13 | my $object; | ||
| 14 | my $line; | ||
| 15 | my $ignore; | ||
| 16 | my $errorcount; | ||
| 17 | |||
| 18 | $| = 1; | ||
| 19 | |||
| 20 | # printf("Finding objects, "); | ||
| 21 | open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed"; | ||
| 22 | while (defined($line = <OBJDUMP_LIST>)) { | ||
| 23 | chomp($line); | ||
| 24 | if ($line =~ /:\s+file format/) { | ||
| 25 | ($object = $line) =~ s/:.*//; | ||
| 26 | $object{$object}->{'module'} = 0; | ||
| 27 | $object{$object}->{'size'} = 0; | ||
| 28 | $object{$object}->{'off'} = 0; | ||
| 29 | } | ||
| 30 | if ($line =~ /^\s*\d+\s+\.modinfo\s+/) { | ||
| 31 | $object{$object}->{'module'} = 1; | ||
| 32 | } | ||
| 33 | if ($line =~ /^\s*\d+\s+\.comment\s+/) { | ||
| 34 | ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5]; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | close(OBJDUMP_LIST); | ||
| 38 | # printf("%d objects, ", scalar keys(%object)); | ||
| 39 | $ignore = 0; | ||
| 40 | foreach $object (keys(%object)) { | ||
| 41 | if ($object{$object}->{'module'}) { | ||
| 42 | ++$ignore; | ||
| 43 | delete($object{$object}); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | # printf("ignoring %d module(s)\n", $ignore); | ||
| 47 | |||
| 48 | # Ignore conglomerate objects, they have been built from multiple objects and we | ||
| 49 | # only care about the individual objects. If an object has more than one GCC: | ||
| 50 | # string in the comment section then it is conglomerate. This does not filter | ||
| 51 | # out conglomerates that consist of exactly one object, can't be helped. | ||
| 52 | |||
| 53 | # printf("Finding conglomerates, "); | ||
| 54 | $ignore = 0; | ||
| 55 | foreach $object (keys(%object)) { | ||
| 56 | if (exists($object{$object}->{'off'})) { | ||
| 57 | my ($off, $size, $comment, $l); | ||
| 58 | $off = hex($object{$object}->{'off'}); | ||
| 59 | $size = hex($object{$object}->{'size'}); | ||
| 60 | open(OBJECT, "<$object") || die "cannot read $object"; | ||
| 61 | seek(OBJECT, $off, 0) || die "seek to $off in $object failed"; | ||
| 62 | $l = read(OBJECT, $comment, $size); | ||
| 63 | die "read $size bytes from $object .comment failed" if ($l != $size); | ||
| 64 | close(OBJECT); | ||
| 65 | if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) { | ||
| 66 | ++$ignore; | ||
| 67 | delete($object{$object}); | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | ||
| 71 | # printf("ignoring %d conglomerate(s)\n", $ignore); | ||
| 72 | |||
| 73 | # printf("Scanning objects\n"); | ||
| 74 | |||
| 75 | # Keith Ownes <kaos@sgi.com> commented: | ||
| 76 | # For our future {in}sanity, add a comment that this is the ppc .opd | ||
| 77 | # section, not the ia64 .opd section. | ||
| 78 | # ia64 .opd should not point to discarded sections. | ||
| 79 | $errorcount = 0; | ||
| 80 | foreach $object (keys(%object)) { | ||
| 81 | my $from; | ||
| 82 | open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object"; | ||
| 83 | while (defined($line = <OBJDUMP>)) { | ||
| 84 | chomp($line); | ||
| 85 | if ($line =~ /RELOCATION RECORDS FOR /) { | ||
| 86 | ($from = $line) =~ s/.*\[([^]]*).*/$1/; | ||
| 87 | } | ||
| 88 | if (($line =~ /\.text\.exit$/ || | ||
| 89 | $line =~ /\.exit\.text$/ || | ||
| 90 | $line =~ /\.data\.exit$/ || | ||
| 91 | $line =~ /\.exit\.data$/ || | ||
| 92 | $line =~ /\.exitcall\.exit$/) && | ||
| 93 | ($from !~ /\.text\.exit$/ && | ||
| 94 | $from !~ /\.exit\.text$/ && | ||
| 95 | $from !~ /\.data\.exit$/ && | ||
| 96 | $from !~ /\.opd$/ && | ||
| 97 | $from !~ /\.exit\.data$/ && | ||
| 98 | $from !~ /\.altinstructions$/ && | ||
| 99 | $from !~ /\.pdr$/ && | ||
| 100 | $from !~ /\.debug_.*$/ && | ||
| 101 | $from !~ /\.exitcall\.exit$/ && | ||
| 102 | $from !~ /\.eh_frame$/ && | ||
| 103 | $from !~ /\.stab$/)) { | ||
| 104 | printf("Error: %s %s refers to %s\n", $object, $from, $line); | ||
| 105 | $errorcount = $errorcount + 1; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | close(OBJDUMP); | ||
| 109 | } | ||
| 110 | # printf("Done\n"); | ||
| 111 | |||
| 112 | exit(0); | ||
diff --git a/scripts/reference_init.pl b/scripts/reference_init.pl deleted file mode 100644 index 7f6960b175a2..000000000000 --- a/scripts/reference_init.pl +++ /dev/null | |||
| @@ -1,108 +0,0 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # reference_init.pl (C) Keith Owens 2002 <kaos@ocs.com.au> | ||
| 4 | # | ||
| 5 | # List references to vmlinux init sections from non-init sections. | ||
| 6 | |||
| 7 | # Unfortunately I had to exclude references from read only data to .init | ||
| 8 | # sections, almost all of these are false positives, they are created by | ||
| 9 | # gcc. The downside of excluding rodata is that there really are some | ||
| 10 | # user references from rodata to init code, e.g. drivers/video/vgacon.c | ||
| 11 | # | ||
| 12 | # const struct consw vga_con = { | ||
| 13 | # con_startup: vgacon_startup, | ||
| 14 | # | ||
| 15 | # where vgacon_startup is __init. If you want to wade through the false | ||
| 16 | # positives, take out the check for rodata. | ||
| 17 | |||
| 18 | use strict; | ||
| 19 | die($0 . " takes no arguments\n") if($#ARGV >= 0); | ||
| 20 | |||
| 21 | my %object; | ||
| 22 | my $object; | ||
| 23 | my $line; | ||
| 24 | my $ignore; | ||
| 25 | |||
| 26 | $| = 1; | ||
| 27 | |||
| 28 | printf("Finding objects, "); | ||
| 29 | open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed"; | ||
| 30 | while (defined($line = <OBJDUMP_LIST>)) { | ||
| 31 | chomp($line); | ||
| 32 | if ($line =~ /:\s+file format/) { | ||
| 33 | ($object = $line) =~ s/:.*//; | ||
| 34 | $object{$object}->{'module'} = 0; | ||
| 35 | $object{$object}->{'size'} = 0; | ||
| 36 | $object{$object}->{'off'} = 0; | ||
| 37 | } | ||
| 38 | if ($line =~ /^\s*\d+\s+\.modinfo\s+/) { | ||
| 39 | $object{$object}->{'module'} = 1; | ||
| 40 | } | ||
| 41 | if ($line =~ /^\s*\d+\s+\.comment\s+/) { | ||
| 42 | ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5]; | ||
| 43 | } | ||
| 44 | } | ||
| 45 | close(OBJDUMP_LIST); | ||
| 46 | printf("%d objects, ", scalar keys(%object)); | ||
| 47 | $ignore = 0; | ||
| 48 | foreach $object (keys(%object)) { | ||
| 49 | if ($object{$object}->{'module'}) { | ||
| 50 | ++$ignore; | ||
| 51 | delete($object{$object}); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | printf("ignoring %d module(s)\n", $ignore); | ||
| 55 | |||
| 56 | # Ignore conglomerate objects, they have been built from multiple objects and we | ||
| 57 | # only care about the individual objects. If an object has more than one GCC: | ||
| 58 | # string in the comment section then it is conglomerate. This does not filter | ||
| 59 | # out conglomerates that consist of exactly one object, can't be helped. | ||
| 60 | |||
| 61 | printf("Finding conglomerates, "); | ||
| 62 | $ignore = 0; | ||
| 63 | foreach $object (keys(%object)) { | ||
| 64 | if (exists($object{$object}->{'off'})) { | ||
| 65 | my ($off, $size, $comment, $l); | ||
| 66 | $off = hex($object{$object}->{'off'}); | ||
| 67 | $size = hex($object{$object}->{'size'}); | ||
| 68 | open(OBJECT, "<$object") || die "cannot read $object"; | ||
| 69 | seek(OBJECT, $off, 0) || die "seek to $off in $object failed"; | ||
| 70 | $l = read(OBJECT, $comment, $size); | ||
| 71 | die "read $size bytes from $object .comment failed" if ($l != $size); | ||
| 72 | close(OBJECT); | ||
| 73 | if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) { | ||
| 74 | ++$ignore; | ||
| 75 | delete($object{$object}); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | } | ||
| 79 | printf("ignoring %d conglomerate(s)\n", $ignore); | ||
| 80 | |||
| 81 | printf("Scanning objects\n"); | ||
| 82 | foreach $object (sort(keys(%object))) { | ||
| 83 | my $from; | ||
| 84 | open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object"; | ||
| 85 | while (defined($line = <OBJDUMP>)) { | ||
| 86 | chomp($line); | ||
| 87 | if ($line =~ /RELOCATION RECORDS FOR /) { | ||
| 88 | ($from = $line) =~ s/.*\[([^]]*).*/$1/; | ||
| 89 | } | ||
| 90 | if (($line =~ /\.init$/ || $line =~ /\.init\./) && | ||
| 91 | ($from !~ /\.init$/ && | ||
| 92 | $from !~ /\.init\./ && | ||
| 93 | $from !~ /\.stab$/ && | ||
| 94 | $from !~ /\.rodata$/ && | ||
| 95 | $from !~ /\.text\.lock$/ && | ||
| 96 | $from !~ /\.pci_fixup_header$/ && | ||
| 97 | $from !~ /\.pci_fixup_final$/ && | ||
| 98 | $from !~ /\.pdr$/ && | ||
| 99 | $from !~ /\__param$/ && | ||
| 100 | $from !~ /\.altinstructions/ && | ||
| 101 | $from !~ /\.eh_frame/ && | ||
| 102 | $from !~ /\.debug_/)) { | ||
| 103 | printf("Error: %s %s refers to %s\n", $object, $from, $line); | ||
| 104 | } | ||
| 105 | } | ||
| 106 | close(OBJDUMP); | ||
| 107 | } | ||
| 108 | printf("Done\n"); | ||
