* master.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild: (46 commits) kbuild: remove obsoleted scripts/reference_* files kbuild: fix make help & make *pkg kconfig: fix time ordering of writes to .kconfig.d and include/linux/autoconf.h Kconfig: remove the CONFIG_CC_ALIGN_* options kbuild: add -fverbose-asm to i386 Makefile kbuild: clean-up genksyms kbuild: Lindent genksyms.c kbuild: fix genksyms build error kbuild: in makefile.txt note that Makefile is preferred name for kbuild files kbuild: replace PHONY with FORCE kbuild: Fix bug in crc symbol generating of kernel and modules kbuild: change kbuild to not rely on incorrect GNU make behavior kbuild: when warning symbols exported twice now tell user this is the problem kbuild: fix make dir/file.xx when asm symlink is missing kbuild: in the section mismatch check try harder to find symbols kbuild: fix section mismatch check for unwind on IA64 kbuild: kill false positives from section mismatch warnings for powerpc kbuild: kill trailing whitespace in modpost & friends kbuild: small update of allnoconfig description kbuild: make namespace.pl CROSS_COMPILE happy ... Trivial conflict in arch/ppc/boot/Makefile manually fixed up
Showing the changes to scripts (22 of 52 files). Show all
Unified · Split
| @@ -44,6 +44,43 @@ define filechk · 43 unmodified lines | ||
| 44 | 44 | fi |
| 45 | 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 | 85 | # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= |
| 49 | 86 | # Usage: |
| @@ -51,8 +88,7 @@ endef · 1 unmodified line | ||
| 51 | 88 | build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj |
| 52 | 89 | |
| 53 | 90 | # If quiet is set, only print short version of command |
| 54 | −cmd = @$(if $($(quiet)cmd_$(1)),\ | |
| 55 | − echo ' $(call escsq,$($(quiet)cmd_$(1)))' &&) $(cmd_$(1)) | |
| 91 | +cmd = @$(echo-cmd) $(cmd_$(1)) | |
| 56 | 92 | |
| 57 | 93 | # Add $(obj)/ for paths that is not absolute |
| 58 | 94 | objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) |
| @@ -75,30 +111,33 @@ endif · 16 unmodified lines | ||
| 75 | 111 | echo-cmd = $(if $($(quiet)cmd_$(1)), \ |
| 76 | 112 | echo ' $(call escsq,$($(quiet)cmd_$(1)))';) |
| 77 | 113 | |
| 114 | +make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))) | |
| 115 | + | |
| 78 | 116 | # function to only execute the passed command if necessary |
| 79 | 117 | # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file |
| 80 | 118 | # note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars |
| 81 | −# | |
| 82 | −if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | |
| 119 | +# | |
| 120 | +if_changed = $(if $(strip $(filter-out $(PHONY),$?) \ | |
| 121 | + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | |
| 83 | 122 | @set -e; \ |
| 84 | − $(echo-cmd) \ | |
| 85 | − $(cmd_$(1)); \ | |
| 86 | − echo 'cmd_$@ := $(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).cmd) | |
| 123 | + $(echo-cmd) $(cmd_$(1)); \ | |
| 124 | + echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd) | |
| 87 | 125 | |
| 88 | 126 | # execute the command and also postprocess generated .d dependencies |
| 89 | 127 | # file |
| 90 | −if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ | |
| 91 | − $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | |
| 128 | +if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?) \ | |
| 129 | + $(filter-out FORCE $(wildcard $^),$^) \ | |
| 130 | + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ | |
| 92 | 131 | @set -e; \ |
| 93 | − $(echo-cmd) \ | |
| 94 | − $(cmd_$(1)); \ | |
| 95 | − scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \ | |
| 132 | + $(echo-cmd) $(cmd_$(1)); \ | |
| 133 | + scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \ | |
| 96 | 134 | rm -f $(depfile); \ |
| 97 | 135 | mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) |
| 98 | 136 | |
| 99 | 137 | # Usage: $(call if_changed_rule,foo) |
| 100 | 138 | # will check if $(cmd_foo) changed, or any of the prequisites changed, |
| 101 | 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 | 142 | @set -e; \ |
| 104 | 143 | $(rule_$(1))) |
| @@ -4,17 +4,18 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | src := $(obj) |
| 6 | 6 | |
| 7 | −.PHONY: __build | |
| 7 | +PHONY := __build | |
| 8 | 8 | __build: |
| 9 | 9 | |
| 10 | 10 | # Read .config if it exist, otherwise ignore |
| 11 | 11 | -include .config |
| 12 | 12 | |
| 13 | +include scripts/Kbuild.include | |
| 14 | + | |
| 13 | 15 | # The filename Kbuild has precedence over Makefile |
| 14 | 16 | kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) |
| 15 | 17 | include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) |
| 16 | 18 | |
| 17 | −include scripts/Kbuild.include | |
| 18 | 19 | include scripts/Makefile.lib |
| 19 | 20 | |
| 20 | 21 | ifdef host-progs |
| @@ -128,7 +129,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi) · 107 unmodified lines | ||
| 128 | 129 | $(multi-objs-y:.o=.lst) : modname = $(modname-multi) |
| 129 | 130 | |
| 130 | 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 | 134 | %.s: %.c FORCE |
| 134 | 135 | $(call if_changed_dep,cc_s_c) |
| @@ -165,7 +166,7 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< · 30 unmodified lines | ||
| 165 | 166 | cmd_modversions = \ |
| 166 | 167 | if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ |
| 167 | 168 | $(CPP) -D__GENKSYMS__ $(c_flags) $< \ |
| 168 | − | $(GENKSYMS) \ | |
| 169 | + | $(GENKSYMS) -a $(ARCH) \ | |
| 169 | 170 | > $(@D)/.tmp_$(@F:.o=.ver); \ |
| 170 | 171 | \ |
| 171 | 172 | $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ |
| @@ -177,12 +178,10 @@ cmd_modversions = \ · 5 unmodified lines | ||
| 177 | 178 | endif |
| 178 | 179 | |
| 179 | 180 | define rule_cc_o_c |
| 180 | − $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \ | |
| 181 | − $(cmd_checksrc) \ | |
| 182 | − $(if $($(quiet)cmd_cc_o_c),echo ' $(call escsq,$($(quiet)cmd_cc_o_c))';) \ | |
| 183 | − $(cmd_cc_o_c); \ | |
| 181 | + $(call echo-cmd,checksrc) $(cmd_checksrc) \ | |
| 182 | + $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ | |
| 184 | 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 | 185 | rm -f $(depfile); \ |
| 187 | 186 | mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd |
| 188 | 187 | endef |
| @@ -309,14 +308,14 @@ targets += $(multi-used-y) $(multi-used-m) · 120 unmodified lines | ||
| 309 | 308 | # Descending |
| 310 | 309 | # --------------------------------------------------------------------------- |
| 311 | 310 | |
| 312 | −.PHONY: $(subdir-ym) | |
| 311 | +PHONY += $(subdir-ym) | |
| 313 | 312 | $(subdir-ym): |
| 314 | 313 | $(Q)$(MAKE) $(build)=$@ |
| 315 | 314 | |
| 316 | 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 | 320 | FORCE: |
| 322 | 321 | |
| @@ -331,3 +330,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) · 8 unmodified lines | ||
| 331 | 330 | ifneq ($(cmd_files),) |
| 332 | 331 | include $(cmd_files) |
| 333 | 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) | |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | src := $(obj) |
| 6 | 6 | |
| 7 | −.PHONY: __clean | |
| 7 | +PHONY := __clean | |
| 8 | 8 | __clean: |
| 9 | 9 | |
| 10 | 10 | # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir |
| @@ -87,10 +87,16 @@ endif · 76 unmodified lines | ||
| 87 | 87 | # Descending |
| 88 | 88 | # --------------------------------------------------------------------------- |
| 89 | 89 | |
| 90 | −.PHONY: $(subdir-ymn) | |
| 90 | +PHONY += $(subdir-ymn) | |
| 91 | 91 | $(subdir-ymn): |
| 92 | 92 | $(Q)$(MAKE) $(clean)=$@ |
| 93 | 93 | |
| 94 | 94 | # If quiet is set, only print short version of command |
| 95 | 95 | |
| 96 | 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) | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | # Installing modules |
| 3 | 3 | # ========================================================================== |
| 4 | 4 | |
| 5 | −.PHONY: __modinst | |
| 5 | +PHONY := __modinst | |
| 6 | 6 | __modinst: |
| 7 | 7 | |
| 8 | 8 | include scripts/Kbuild.include |
| @@ -12,7 +12,7 @@ include scripts/Kbuild.include · 3 unmodified lines | ||
| 12 | 12 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) |
| 13 | 13 | modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) |
| 14 | 14 | |
| 15 | −.PHONY: $(modules) | |
| 15 | +PHONY += $(modules) | |
| 16 | 16 | __modinst: $(modules) |
| 17 | 17 | @: |
| 18 | 18 | |
| @@ -27,3 +27,9 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) · 8 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | $(modules): |
| 29 | 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) | |
| @@ -32,14 +32,15 @@ · 31 unmodified lines | ||
| 32 | 32 | # Step 4 is solely used to allow module versioning in external modules, |
| 33 | 33 | # where the CRC of each module is retrieved from the Module.symers file. |
| 34 | 34 | |
| 35 | −.PHONY: _modpost | |
| 35 | +PHONY := _modpost | |
| 36 | 36 | _modpost: __modpost |
| 37 | 37 | |
| 38 | 38 | include .config |
| 39 | 39 | include scripts/Kbuild.include |
| 40 | 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 | 45 | # Step 1), find all modules listed in $(MODVERDIR)/ |
| 45 | 46 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) |
| @@ -54,10 +55,12 @@ quiet_cmd_modpost = MODPOST · 8 unmodified lines | ||
| 54 | 55 | cmd_modpost = scripts/mod/modpost \ |
| 55 | 56 | $(if $(CONFIG_MODVERSIONS),-m) \ |
| 56 | 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 | 61 | $(filter-out FORCE,$^) |
| 59 | 62 | |
| 60 | −.PHONY: __modpost | |
| 63 | +PHONY += __modpost | |
| 61 | 64 | __modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE |
| 62 | 65 | $(call cmd,modpost) |
| 63 | 66 | |
| @@ -94,7 +97,7 @@ targets += $(modules) · 30 unmodified lines | ||
| 94 | 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 | 102 | FORCE: |
| 100 | 103 | |
| @@ -109,3 +112,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) · 8 unmodified lines | ||
| 109 | 112 | ifneq ($(cmd_files),) |
| 110 | 113 | include $(cmd_files) |
| 111 | 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) | |
| @@ -132,20 +132,10 @@ void usage(void) · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | /* |
| 134 | 134 | * Print out the commandline prefixed with cmd_<target filename> := |
| 135 | − * If commandline contains '#' escape with '\' so make to not see | |
| 136 | − * the '#' as a start-of-comment symbol | |
| 137 | − **/ | |
| 135 | + */ | |
| 138 | 136 | void print_cmdline(void) |
| 139 | 137 | { |
| 140 | − char *p = 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"); | |
| 138 | + printf("cmd_%s := %s\n\n", target, cmdline); | |
| 149 | 139 | } |
| 150 | 140 | |
| 151 | 141 | char * str_config = 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 | −} | |
| @@ -29,481 +29,421 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <stdarg.h> |
| 30 | 30 | #ifdef __GNU_LIBRARY__ |
| 31 | 31 | #include <getopt.h> |
| 32 | −#endif /* __GNU_LIBRARY__ */ | |
| 32 | +#endif /* __GNU_LIBRARY__ */ | |
| 33 | 33 | |
| 34 | 34 | #include "genksyms.h" |
| 35 | − | |
| 36 | 35 | /*----------------------------------------------------------------------*/ |
| 37 | 36 | |
| 38 | 37 | #define HASH_BUCKETS 4096 |
| 39 | 38 | |
| 40 | 39 | static struct symbol *symtab[HASH_BUCKETS]; |
| 41 | −FILE *debugfile; | |
| 40 | +static FILE *debugfile; | |
| 42 | 41 | |
| 43 | 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 | 49 | static int errors; |
| 49 | 50 | static int nsyms; |
| 50 | 51 | |
| 51 | 52 | static struct symbol *expansion_trail; |
| 52 | 53 | |
| 53 | −static const char * const symbol_type_name[] = { | |
| 54 | − "normal", "typedef", "enum", "struct", "union" | |
| 54 | +static const char *const symbol_type_name[] = { | |
| 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[] = | |
| 60 | −{ | |
| 61 | − 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, | |
| 62 | − 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, | |
| 63 | − 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, | |
| 64 | − 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, | |
| 65 | − 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, | |
| 66 | − 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, | |
| 67 | − 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, | |
| 68 | − 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, | |
| 69 | − 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, | |
| 70 | − 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, | |
| 71 | − 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, | |
| 72 | − 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, | |
| 73 | − 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, | |
| 74 | − 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, | |
| 75 | − 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, | |
| 76 | − 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, | |
| 77 | − 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, | |
| 78 | − 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, | |
| 79 | − 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, | |
| 80 | − 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, | |
| 81 | − 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, | |
| 82 | − 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, | |
| 83 | − 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, | |
| 84 | − 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, | |
| 85 | − 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, | |
| 86 | − 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, | |
| 87 | − 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, | |
| 88 | − 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, | |
| 89 | − 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, | |
| 90 | − 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, | |
| 91 | − 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, | |
| 92 | − 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, | |
| 93 | − 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, | |
| 94 | − 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, | |
| 95 | − 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, | |
| 96 | − 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, | |
| 97 | − 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, | |
| 98 | − 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, | |
| 99 | − 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, | |
| 100 | − 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, | |
| 101 | − 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, | |
| 102 | − 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, | |
| 103 | − 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, | |
| 104 | − 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, | |
| 105 | − 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, | |
| 106 | − 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, | |
| 107 | − 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, | |
| 108 | − 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, | |
| 109 | − 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, | |
| 110 | − 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, | |
| 111 | − 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, | |
| 112 | − 0x2d02ef8dU | |
| 63 | +static const unsigned int crctab32[] = { | |
| 64 | + 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, | |
| 65 | + 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, | |
| 66 | + 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, | |
| 67 | + 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, | |
| 68 | + 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, | |
| 69 | + 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, | |
| 70 | + 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, | |
| 71 | + 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, | |
| 72 | + 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, | |
| 73 | + 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, | |
| 74 | + 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, | |
| 75 | + 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, | |
| 76 | + 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, | |
| 77 | + 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, | |
| 78 | + 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, | |
| 79 | + 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, | |
| 80 | + 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, | |
| 81 | + 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, | |
| 82 | + 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, | |
| 83 | + 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, | |
| 84 | + 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, | |
| 85 | + 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, | |
| 86 | + 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, | |
| 87 | + 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, | |
| 88 | + 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, | |
| 89 | + 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, | |
| 90 | + 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, | |
| 91 | + 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, | |
| 92 | + 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, | |
| 93 | + 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, | |
| 94 | + 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, | |
| 95 | + 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, | |
| 96 | + 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, | |
| 97 | + 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, | |
| 98 | + 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, | |
| 99 | + 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, | |
| 100 | + 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, | |
| 101 | + 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, | |
| 102 | + 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, | |
| 103 | + 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, | |
| 104 | + 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, | |
| 105 | + 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, | |
| 106 | + 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, | |
| 107 | + 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, | |
| 108 | + 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, | |
| 109 | + 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, | |
| 110 | + 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, | |
| 111 | + 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, | |
| 112 | + 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, | |
| 113 | + 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, | |
| 114 | + 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, | |
| 115 | + 0x2d02ef8dU | |
| 113 | 116 | }; |
| 114 | 117 | |
| 115 | −static inline unsigned long | |
| 116 | −partial_crc32_one(unsigned char c, unsigned long crc) | |
| 118 | +static unsigned long 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 | |
| 122 | −partial_crc32(const char *s, unsigned long crc) | |
| 123 | +static unsigned long partial_crc32(const char *s, unsigned long crc) | |
| 123 | 124 | { |
| 124 | − while (*s) | |
| 125 | − crc = partial_crc32_one(*s++, crc); | |
| 126 | − return crc; | |
| 125 | + while (*s) | |
| 126 | + crc = partial_crc32_one(*s++, crc); | |
| 127 | + return crc; | |
| 127 | 128 | } |
| 128 | 129 | |
| 129 | −static inline unsigned long | |
| 130 | −crc32(const char *s) | |
| 130 | +static unsigned long 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 | |
| 139 | −map_to_ns(enum symbol_type t) | |
| 137 | +static enum symbol_type map_to_ns(enum symbol_type t) | |
| 140 | 138 | { |
| 141 | − if (t == SYM_TYPEDEF) | |
| 142 | − t = SYM_NORMAL; | |
| 143 | − else if (t == SYM_UNION) | |
| 144 | − t = SYM_STRUCT; | |
| 145 | − return t; | |
| 139 | + if (t == SYM_TYPEDEF) | |
| 140 | + t = SYM_NORMAL; | |
| 141 | + else if (t == SYM_UNION) | |
| 142 | + t = SYM_STRUCT; | |
| 143 | + return t; | |
| 146 | 144 | } |
| 147 | 145 | |
| 148 | −struct symbol * | |
| 149 | −find_symbol(const char *name, enum symbol_type ns) | |
| 146 | +struct symbol *find_symbol(const char *name, enum symbol_type ns) | |
| 150 | 147 | { |
| 151 | − unsigned long h = crc32(name) % HASH_BUCKETS; | |
| 152 | − struct symbol *sym; | |
| 148 | + unsigned long h = crc32(name) % HASH_BUCKETS; | |
| 149 | + struct symbol *sym; | |
| 153 | 150 | |
| 154 | − 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) | |
| 156 | − break; | |
| 151 | + for (sym = symtab[h]; sym; sym = sym->hash_next) | |
| 152 | + if (map_to_ns(sym->type) == map_to_ns(ns) && | |
| 153 | + strcmp(name, sym->name) == 0) | |
| 154 | + break; | |
| 157 | 155 | |
| 158 | − return sym; | |
| 156 | + return sym; | |
| 159 | 157 | } |
| 160 | 158 | |
| 161 | −struct symbol * | |
| 162 | −add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern) | |
| 159 | +struct symbol *add_symbol(const char *name, enum symbol_type type, | |
| 160 | + struct string_list *defn, int is_extern) | |
| 163 | 161 | { |
| 164 | − unsigned long h = crc32(name) % HASH_BUCKETS; | |
| 165 | − struct symbol *sym; | |
| 166 | − | |
| 167 | − for (sym = symtab[h]; sym ; sym = sym->hash_next) | |
| 168 | − if (map_to_ns(sym->type) == map_to_ns(type) | |
| 169 | − && strcmp(name, sym->name) == 0) | |
| 170 | − { | |
| 171 | − if (!equal_list(sym->defn, defn)) | |
| 172 | − error_with_pos("redefinition of %s", name); | |
| 162 | + unsigned long h = crc32(name) % HASH_BUCKETS; | |
| 163 | + struct symbol *sym; | |
| 164 | + | |
| 165 | + for (sym = symtab[h]; sym; sym = sym->hash_next) { | |
| 166 | + if (map_to_ns(sym->type) == map_to_ns(type) | |
| 167 | + && strcmp(name, sym->name) == 0) { | |
| 168 | + if (!equal_list(sym->defn, defn)) | |
| 169 | + 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 | 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 | |
| 203 | −free_node(struct string_list *node) | |
| 199 | +void free_node(struct string_list *node) | |
| 204 | 200 | { |
| 205 | − free(node->string); | |
| 206 | − free(node); | |
| 201 | + free(node->string); | |
| 202 | + free(node); | |
| 207 | 203 | } |
| 208 | 204 | |
| 209 | −void | |
| 210 | −free_list(struct string_list *s, struct string_list *e) | |
| 205 | +void free_list(struct string_list *s, struct string_list *e) | |
| 211 | 206 | { |
| 212 | − while (s != e) | |
| 213 | − { | |
| 214 | − struct string_list *next = s->next; | |
| 215 | − free_node(s); | |
| 216 | − s = next; | |
| 217 | − } | |
| 207 | + while (s != e) { | |
| 208 | + struct string_list *next = s->next; | |
| 209 | + free_node(s); | |
| 210 | + s = next; | |
| 211 | + } | |
| 218 | 212 | } |
| 219 | 213 | |
| 220 | −inline struct string_list * | |
| 221 | −copy_node(struct string_list *node) | |
| 214 | +struct string_list *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)); | |
| 226 | − newnode->string = xstrdup(node->string); | |
| 227 | − newnode->tag = node->tag; | |
| 218 | + newnode = xmalloc(sizeof(*newnode)); | |
| 219 | + newnode->string = xstrdup(node->string); | |
| 220 | + newnode->tag = node->tag; | |
| 228 | 221 | |
| 229 | − return newnode; | |
| 222 | + return newnode; | |
| 230 | 223 | } |
| 231 | 224 | |
| 232 | −struct string_list * | |
| 233 | −copy_list(struct string_list *s, struct string_list *e) | |
| 225 | +static int equal_list(struct string_list *a, struct string_list *b) | |
| 234 | 226 | { |
| 235 | − struct string_list *h, *p; | |
| 236 | − | |
| 237 | − if (s == e) | |
| 238 | − return NULL; | |
| 239 | − | |
| 240 | − p = h = copy_node(s); | |
| 241 | − while ((s = s->next) != e) | |
| 242 | − p = p->next = copy_node(s); | |
| 243 | − p->next = NULL; | |
| 244 | − | |
| 245 | − return h; | |
| 246 | −} | |
| 227 | + while (a && b) { | |
| 228 | + if (a->tag != b->tag || strcmp(a->string, b->string)) | |
| 229 | + return 0; | |
| 230 | + a = a->next; | |
| 231 | + b = b->next; | |
| 232 | + } | |
| 247 | 233 | |
| 248 | −int | |
| 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; | |
| 234 | + return !a && !b; | |
| 260 | 235 | } |
| 261 | 236 | |
| 262 | −static inline void | |
| 263 | −print_node(FILE *f, struct string_list *list) | |
| 237 | +static void print_node(FILE * f, struct string_list *list) | |
| 264 | 238 | { |
| 265 | − switch (list->tag) | |
| 266 | − { | |
| 267 | − case SYM_STRUCT: | |
| 268 | − putc('s', f); | |
| 269 | − goto printit; | |
| 270 | − case SYM_UNION: | |
| 271 | − putc('u', f); | |
| 272 | − goto printit; | |
| 273 | − case SYM_ENUM: | |
| 274 | − putc('e', f); | |
| 275 | − goto printit; | |
| 276 | − case SYM_TYPEDEF: | |
| 277 | − putc('t', f); | |
| 278 | − goto printit; | |
| 279 | − | |
| 280 | − printit: | |
| 281 | − putc('#', f); | |
| 282 | − case SYM_NORMAL: | |
| 283 | − fputs(list->string, f); | |
| 284 | − break; | |
| 285 | − } | |
| 286 | −} | |
| 239 | + switch (list->tag) { | |
| 240 | + case SYM_STRUCT: | |
| 241 | + putc('s', f); | |
| 242 | + goto printit; | |
| 243 | + case SYM_UNION: | |
| 244 | + putc('u', f); | |
| 245 | + goto printit; | |
| 246 | + case SYM_ENUM: | |
| 247 | + putc('e', f); | |
| 248 | + goto printit; | |
| 249 | + case SYM_TYPEDEF: | |
| 250 | + putc('t', f); | |
| 251 | + goto printit; | |
| 287 | 252 | |
| 288 | −void | |
| 289 | −print_list(FILE *f, struct string_list *list) | |
| 290 | −{ | |
| 291 | − struct string_list **e, **b; | |
| 292 | − struct string_list *tmp, **tmp2; | |
| 293 | − int elem = 1; | |
| 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 | − } | |
| 253 | + printit: | |
| 254 | + putc('#', f); | |
| 255 | + case SYM_NORMAL: | |
| 256 | + fputs(list->string, f); | |
| 257 | + break; | |
| 258 | + } | |
| 318 | 259 | } |
| 319 | 260 | |
| 320 | −static unsigned long | |
| 321 | −expand_and_crc_list(struct string_list *list, unsigned long crc) | |
| 261 | +static void print_list(FILE * f, struct string_list *list) | |
| 322 | 262 | { |
| 323 | − struct string_list **e, **b; | |
| 324 | − struct string_list *tmp, **tmp2; | |
| 325 | − int elem = 1; | |
| 326 | − | |
| 327 | − if (!list) | |
| 328 | − return crc; | |
| 263 | + struct string_list **e, **b; | |
| 264 | + struct string_list *tmp, **tmp2; | |
| 265 | + int elem = 1; | |
| 329 | 266 | |
| 330 | − tmp = list; | |
| 331 | − while((tmp = tmp->next) != NULL) | |
| 332 | − elem++; | |
| 333 | − | |
| 334 | − b = alloca(elem * sizeof(*e)); | |
| 335 | − e = b + elem; | |
| 336 | − tmp2 = e - 1; | |
| 267 | + if (list == NULL) { | |
| 268 | + fputs("(nil)", f); | |
| 269 | + return; | |
| 270 | + } | |
| 337 | 271 | |
| 338 | − *(tmp2--) = list; | |
| 339 | − while ((list = list->next) != NULL) | |
| 340 | − *(tmp2--) = list; | |
| 272 | + tmp = list; | |
| 273 | + while ((tmp = tmp->next) != NULL) | |
| 274 | + elem++; | |
| 341 | 275 | |
| 342 | − while (b != e) | |
| 343 | − { | |
| 344 | − struct string_list *cur; | |
| 345 | − struct symbol *subsym; | |
| 276 | + b = alloca(elem * sizeof(*e)); | |
| 277 | + e = b + elem; | |
| 278 | + tmp2 = e - 1; | |
| 346 | 279 | |
| 347 | − cur = *(b++); | |
| 348 | − switch (cur->tag) | |
| 349 | − { | |
| 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; | |
| 280 | + (*tmp2--) = list; | |
| 281 | + while ((list = list->next) != NULL) | |
| 282 | + *(tmp2--) = list; | |
| 356 | 283 | |
| 357 | − case SYM_TYPEDEF: | |
| 358 | − subsym = find_symbol(cur->string, cur->tag); | |
| 359 | − if (subsym->expansion_trail) | |
| 360 | − { | |
| 361 | − if (flag_dump_defs) | |
| 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; | |
| 284 | + while (b != e) { | |
| 285 | + print_node(f, *b++); | |
| 286 | + putc(' ', f); | |
| 287 | + } | |
| 288 | +} | |
| 373 | 289 | |
| 374 | − case SYM_STRUCT: | |
| 375 | − case SYM_UNION: | |
| 376 | − case SYM_ENUM: | |
| 377 | − subsym = find_symbol(cur->string, cur->tag); | |
| 378 | − if (!subsym) | |
| 379 | − { | |
| 380 | − struct string_list *n, *t = NULL; | |
| 381 | − | |
| 382 | − error_with_pos("expand undefined %s %s", | |
| 383 | − symbol_type_name[cur->tag], cur->string); | |
| 384 | − | |
| 385 | − n = xmalloc(sizeof(*n)); | |
| 386 | − n->string = xstrdup(symbol_type_name[cur->tag]); | |
| 387 | − n->tag = SYM_NORMAL; | |
| 388 | − n->next = t; | |
| 389 | − t = n; | |
| 390 | − | |
| 391 | − n = xmalloc(sizeof(*n)); | |
| 392 | − n->string = xstrdup(cur->string); | |
| 393 | − n->tag = SYM_NORMAL; | |
| 394 | − n->next = t; | |
| 395 | − t = n; | |
| 396 | − | |
| 397 | − n = xmalloc(sizeof(*n)); | |
| 398 | − n->string = xstrdup("{ UNKNOWN }"); | |
| 399 | − n->tag = SYM_NORMAL; | |
| 400 | − n->next = t; | |
| 401 | − | |
| 402 | − subsym = add_symbol(cur->string, cur->tag, n, 0); | |
| 403 | − } | |
| 404 | − if (subsym->expansion_trail) | |
| 405 | − { | |
| 406 | − if (flag_dump_defs) | |
| 407 | − { | |
| 408 | − fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag], | |
| 409 | − cur->string); | |
| 290 | +static unsigned long expand_and_crc_list(struct string_list *list, | |
| 291 | + unsigned long crc) | |
| 292 | +{ | |
| 293 | + struct string_list **e, **b; | |
| 294 | + struct string_list *tmp, **tmp2; | |
| 295 | + int elem = 1; | |
| 296 | + | |
| 297 | + if (!list) | |
| 298 | + return crc; | |
| 299 | + | |
| 300 | + tmp = list; | |
| 301 | + while ((tmp = tmp->next) != NULL) | |
| 302 | + elem++; | |
| 303 | + | |
| 304 | + b = alloca(elem * sizeof(*e)); | |
| 305 | + e = b + elem; | |
| 306 | + tmp2 = e - 1; | |
| 307 | + | |
| 308 | + *(tmp2--) = list; | |
| 309 | + while ((list = list->next) != NULL) | |
| 310 | + *(tmp2--) = list; | |
| 311 | + | |
| 312 | + while (b != e) { | |
| 313 | + struct string_list *cur; | |
| 314 | + struct symbol *subsym; | |
| 315 | + | |
| 316 | + cur = *(b++); | |
| 317 | + switch (cur->tag) { | |
| 318 | + case SYM_NORMAL: | |
| 319 | + if (flag_dump_defs) | |
| 320 | + fprintf(debugfile, "%s ", cur->string); | |
| 321 | + crc = partial_crc32(cur->string, crc); | |
| 322 | + crc = partial_crc32_one(' ', crc); | |
| 323 | + break; | |
| 324 | + | |
| 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 | |
| 431 | −export_symbol(const char *name) | |
| 394 | +void export_symbol(const char *name) | |
| 432 | 395 | { |
| 433 | − struct symbol *sym; | |
| 396 | + struct symbol *sym; | |
| 434 | 397 | |
| 435 | − sym = find_symbol(name, SYM_NORMAL); | |
| 436 | − if (!sym) | |
| 437 | − error_with_pos("export undefined symbol %s", name); | |
| 438 | − else | |
| 439 | − { | |
| 440 | − unsigned long crc; | |
| 398 | + sym = find_symbol(name, SYM_NORMAL); | |
| 399 | + if (!sym) | |
| 400 | + error_with_pos("export undefined symbol %s", name); | |
| 401 | + else { | |
| 402 | + unsigned long crc; | |
| 441 | 403 | |
| 442 | − if (flag_dump_defs) | |
| 443 | − fprintf(debugfile, "Export %s == <", name); | |
| 404 | + if (flag_dump_defs) | |
| 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; | |
| 450 | − while (sym != (struct symbol *)-1L) | |
| 451 | − { | |
| 452 | − struct symbol *n = sym->expansion_trail; | |
| 453 | − sym->expansion_trail = 0; | |
| 454 | − sym = n; | |
| 455 | − } | |
| 411 | + sym = expansion_trail; | |
| 412 | + while (sym != (struct symbol *)-1L) { | |
| 413 | + struct symbol *n = sym->expansion_trail; | |
| 414 | + sym->expansion_trail = 0; | |
| 415 | + sym = n; | |
| 416 | + } | |
| 456 | 417 | |
| 457 | − if (flag_dump_defs) | |
| 458 | − fputs(">\n", debugfile); | |
| 418 | + if (flag_dump_defs) | |
| 419 | + fputs(">\n", debugfile); | |
| 459 | 420 | |
| 460 | − /* Used as a linker script. */ | |
| 461 | − printf("__crc_%s = 0x%08lx ;\n", name, crc); | |
| 462 | − } | |
| 421 | + /* Used as a linker script. */ | |
| 422 | + printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); | |
| 423 | + } | |
| 463 | 424 | } |
| 464 | 425 | |
| 465 | 426 | /*----------------------------------------------------------------------*/ |
| 466 | − | |
| 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, ...) | |
| 427 | +void error_with_pos(const char *fmt, ...) | |
| 485 | 428 | { |
| 486 | − va_list args; | |
| 429 | + va_list args; | |
| 487 | 430 | |
| 488 | − if (flag_warnings) | |
| 489 | − { | |
| 490 | − fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line); | |
| 431 | + if (flag_warnings) { | |
| 432 | + fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", | |
| 433 | + cur_line); | |
| 491 | 434 | |
| 492 | − va_start(args, fmt); | |
| 493 | − vfprintf(stderr, fmt, args); | |
| 494 | − va_end(args); | |
| 495 | − putc('\n', stderr); | |
| 435 | + va_start(args, fmt); | |
| 436 | + vfprintf(stderr, fmt, args); | |
| 437 | + va_end(args); | |
| 438 | + putc('\n', stderr); | |
| 496 | 439 | |
| 497 | − errors++; | |
| 498 | − } | |
| 440 | + errors++; | |
| 441 | + } | |
| 499 | 442 | } |
| 500 | 443 | |
| 501 | − | |
| 502 | −void genksyms_usage(void) | |
| 444 | +static void genksyms_usage(void) | |
| 503 | 445 | { |
| 504 | − fputs("Usage:\n" | |
| 505 | − "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" | |
| 506 | − "\n" | |
| 446 | + fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n" | |
| 507 | 447 | #ifdef __GNU_LIBRARY__ |
| 508 | 448 | " -d, --debug Increment the debug level (repeatable)\n" |
| 509 | 449 | " -D, --dump Dump expanded symbol defs (for debugging only)\n" |
| @@ -511,81 +451,84 @@ void genksyms_usage(void) · 1 unmodified line | ||
| 511 | 451 | " -q, --quiet Disable warnings (default)\n" |
| 512 | 452 | " -h, --help Print this message\n" |
| 513 | 453 | " -V, --version Print the release version\n" |
| 514 | −#else /* __GNU_LIBRARY__ */ | |
| 515 | − " -d Increment the debug level (repeatable)\n" | |
| 516 | − " -D Dump expanded symbol defs (for debugging only)\n" | |
| 517 | − " -w Enable warnings\n" | |
| 518 | − " -q Disable warnings (default)\n" | |
| 519 | − " -h Print this message\n" | |
| 520 | − " -V Print the release version\n" | |
| 521 | −#endif /* __GNU_LIBRARY__ */ | |
| 454 | +#else /* __GNU_LIBRARY__ */ | |
| 455 | + " -d Increment the debug level (repeatable)\n" | |
| 456 | + " -D Dump expanded symbol defs (for debugging only)\n" | |
| 457 | + " -w Enable warnings\n" | |
| 458 | + " -q Disable warnings (default)\n" | |
| 459 | + " -h Print this message\n" | |
| 460 | + " -V Print the release version\n" | |
| 461 | +#endif /* __GNU_LIBRARY__ */ | |
| 522 | 462 | , stderr); |
| 523 | 463 | } |
| 524 | 464 | |
| 525 | −int | |
| 526 | −main(int argc, char **argv) | |
| 465 | +int main(int argc, char **argv) | |
| 527 | 466 | { |
| 528 | − int o; | |
| 467 | + int o; | |
| 529 | 468 | |
| 530 | 469 | #ifdef __GNU_LIBRARY__ |
| 531 | − struct option long_opts[] = { | |
| 532 | − {"debug", 0, 0, 'd'}, | |
| 533 | − {"warnings", 0, 0, 'w'}, | |
| 534 | − {"quiet", 0, 0, 'q'}, | |
| 535 | − {"dump", 0, 0, 'D'}, | |
| 536 | − {"version", 0, 0, 'V'}, | |
| 537 | − {"help", 0, 0, 'h'}, | |
| 538 | − {0, 0, 0, 0} | |
| 539 | − }; | |
| 540 | − | |
| 541 | − while ((o = getopt_long(argc, argv, "dwqVDk:p:", | |
| 542 | − &long_opts[0], NULL)) != EOF) | |
| 543 | −#else /* __GNU_LIBRARY__ */ | |
| 544 | − while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF) | |
| 545 | −#endif /* __GNU_LIBRARY__ */ | |
| 546 | − switch (o) | |
| 547 | − { | |
| 548 | − case 'd': | |
| 549 | − flag_debug++; | |
| 550 | − break; | |
| 551 | − case 'w': | |
| 552 | − flag_warnings = 1; | |
| 553 | − break; | |
| 554 | − case 'q': | |
| 555 | − flag_warnings = 0; | |
| 556 | − break; | |
| 557 | − case 'V': | |
| 558 | − fputs("genksyms version 2.5.60\n", stderr); | |
| 559 | − break; | |
| 560 | − case 'D': | |
| 561 | − flag_dump_defs = 1; | |
| 562 | − break; | |
| 563 | − case 'h': | |
| 564 | − genksyms_usage(); | |
| 565 | − return 0; | |
| 566 | − default: | |
| 567 | − genksyms_usage(); | |
| 568 | − return 1; | |
| 569 | − } | |
| 570 | − | |
| 571 | − { | |
| 572 | − extern int yydebug; | |
| 573 | − extern int yy_flex_debug; | |
| 574 | − | |
| 575 | − yydebug = (flag_debug > 1); | |
| 576 | − yy_flex_debug = (flag_debug > 2); | |
| 577 | − | |
| 578 | − debugfile = stderr; | |
| 579 | − /* setlinebuf(debugfile); */ | |
| 580 | − } | |
| 581 | − | |
| 582 | − yyparse(); | |
| 583 | − | |
| 584 | − if (flag_debug) | |
| 585 | − { | |
| 586 | − fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", | |
| 587 | − nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS); | |
| 588 | − } | |
| 589 | − | |
| 590 | − return errors != 0; | |
| 470 | + struct option long_opts[] = { | |
| 471 | + {"arch", 1, 0, 'a'}, | |
| 472 | + {"debug", 0, 0, 'd'}, | |
| 473 | + {"warnings", 0, 0, 'w'}, | |
| 474 | + {"quiet", 0, 0, 'q'}, | |
| 475 | + {"dump", 0, 0, 'D'}, | |
| 476 | + {"version", 0, 0, 'V'}, | |
| 477 | + {"help", 0, 0, 'h'}, | |
| 478 | + {0, 0, 0, 0} | |
| 479 | + }; | |
| 480 | + | |
| 481 | + while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", | |
| 482 | + &long_opts[0], NULL)) != EOF) | |
| 483 | +#else /* __GNU_LIBRARY__ */ | |
| 484 | + while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) | |
| 485 | +#endif /* __GNU_LIBRARY__ */ | |
| 486 | + switch (o) { | |
| 487 | + case 'a': | |
| 488 | + arch = optarg; | |
| 489 | + break; | |
| 490 | + case 'd': | |
| 491 | + flag_debug++; | |
| 492 | + break; | |
| 493 | + case 'w': | |
| 494 | + flag_warnings = 1; | |
| 495 | + break; | |
| 496 | + case 'q': | |
| 497 | + flag_warnings = 0; | |
| 498 | + break; | |
| 499 | + case 'V': | |
| 500 | + fputs("genksyms version 2.5.60\n", stderr); | |
| 501 | + break; | |
| 502 | + case 'D': | |
| 503 | + flag_dump_defs = 1; | |
| 504 | + break; | |
| 505 | + case 'h': | |
| 506 | + genksyms_usage(); | |
| 507 | + return 0; | |
| 508 | + default: | |
| 509 | + genksyms_usage(); | |
| 510 | + return 1; | |
| 511 | + } | |
| 512 | + if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0)) | |
| 513 | + mod_prefix = "_"; | |
| 514 | + { | |
| 515 | + extern int yydebug; | |
| 516 | + extern int yy_flex_debug; | |
| 517 | + | |
| 518 | + yydebug = (flag_debug > 1); | |
| 519 | + yy_flex_debug = (flag_debug > 2); | |
| 520 | + | |
| 521 | + debugfile = stderr; | |
| 522 | + /* setlinebuf(debugfile); */ | |
| 523 | + } | |
| 524 | + | |
| 525 | + yyparse(); | |
| 526 | + | |
| 527 | + if (flag_debug) { | |
| 528 | + fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", | |
| 529 | + nsyms, HASH_BUCKETS, | |
| 530 | + (double)nsyms / (double)HASH_BUCKETS); | |
| 531 | + } | |
| 532 | + | |
| 533 | + return errors != 0; | |
| 591 | 534 | } |
| @@ -20,74 +20,51 @@ · 19 unmodified lines | ||
| 20 | 20 | along with this program; if not, write to the Free Software Foundation, |
| 21 | 21 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
| 22 | 22 | |
| 23 | − | |
| 24 | 23 | #ifndef MODUTILS_GENKSYMS_H |
| 25 | 24 | #define MODUTILS_GENKSYMS_H 1 |
| 26 | 25 | |
| 27 | 26 | #include <stdio.h> |
| 28 | 27 | |
| 29 | − | |
| 30 | −enum symbol_type | |
| 31 | −{ | |
| 32 | − SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION | |
| 28 | +enum symbol_type { | |
| 29 | + SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION | |
| 33 | 30 | }; |
| 34 | 31 | |
| 35 | −struct string_list | |
| 36 | −{ | |
| 37 | − struct string_list *next; | |
| 38 | − enum symbol_type tag; | |
| 39 | − char *string; | |
| 32 | +struct string_list { | |
| 33 | + struct string_list *next; | |
| 34 | + enum symbol_type tag; | |
| 35 | + char *string; | |
| 40 | 36 | }; |
| 41 | 37 | |
| 42 | −struct symbol | |
| 43 | −{ | |
| 44 | − struct symbol *hash_next; | |
| 45 | − const char *name; | |
| 46 | − enum symbol_type type; | |
| 47 | − struct string_list *defn; | |
| 48 | − struct symbol *expansion_trail; | |
| 49 | − int is_extern; | |
| 38 | +struct symbol { | |
| 39 | + struct symbol *hash_next; | |
| 40 | + const char *name; | |
| 41 | + enum symbol_type type; | |
| 42 | + struct string_list *defn; | |
| 43 | + struct symbol *expansion_trail; | |
| 44 | + int is_extern; | |
| 50 | 45 | }; |
| 51 | 46 | |
| 52 | 47 | typedef struct string_list **yystype; |
| 53 | 48 | #define YYSTYPE yystype |
| 54 | 49 | |
| 55 | −extern FILE *outfile, *debugfile; | |
| 56 | − | |
| 57 | 50 | extern int cur_line; |
| 58 | −extern char *cur_filename, *output_directory; | |
| 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 | − | |
| 51 | +extern char *cur_filename; | |
| 66 | 52 | |
| 67 | 53 | struct symbol *find_symbol(const char *name, enum symbol_type ns); |
| 68 | 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 | 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 | 58 | void free_node(struct string_list *list); |
| 59 | +void free_list(struct string_list *s, struct string_list *e); | |
| 75 | 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 | 62 | int yylex(void); |
| 81 | 63 | int yyparse(void); |
| 82 | 64 | |
| 83 | 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 | 68 | #define xmalloc(size) ({ void *__ptr = malloc(size); \ |
| 92 | 69 | if(!__ptr && size != 0) { \ |
| 93 | 70 | fprintf(stderr, "out of memory\n"); \ |
| @@ -101,4 +78,4 @@ void error_with_pos(const char *, ...); · 7 unmodified lines | ||
| 101 | 78 | } \ |
| 102 | 79 | __str; }) |
| 103 | 80 | |
| 104 | −#endif /* genksyms.h */ | |
| 81 | +#endif /* genksyms.h */ | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | # Kernel configuration targets |
| 3 | 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 | 7 | xconfig: $(obj)/qconf |
| 8 | 8 | $< arch/$(ARCH)/Kconfig |
| @@ -42,7 +42,7 @@ update-po-config: $(obj)/kxgettext · 33 unmodified lines | ||
| 42 | 42 | $(Q)rm -f arch/um/Kconfig_arch |
| 43 | 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 | 47 | randconfig: $(obj)/conf |
| 48 | 48 | $< -r arch/$(ARCH)/Kconfig |
| @@ -78,7 +78,7 @@ help: · 29 unmodified lines | ||
| 78 | 78 | @echo ' defconfig - New config with default answer to all options' |
| 79 | 79 | @echo ' allmodconfig - New config selecting modules when possible' |
| 80 | 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 | 84 | # Shared Makefile for the various kconfig executables: |
| @@ -374,6 +374,7 @@ int conf_write(const char *name) · 373 unmodified lines | ||
| 374 | 374 | out_h = fopen(".tmpconfig.h", "w"); |
| 375 | 375 | if (!out_h) |
| 376 | 376 | return 1; |
| 377 | + file_write_dep(NULL); | |
| 377 | 378 | } |
| 378 | 379 | sym = sym_lookup("KERNELVERSION", 0); |
| 379 | 380 | sym_calc_value(sym); |
| @@ -512,7 +513,6 @@ int conf_write(const char *name) · 132 unmodified lines | ||
| 512 | 513 | if (out_h) { |
| 513 | 514 | fclose(out_h); |
| 514 | 515 | rename(".tmpconfig.h", "include/linux/autoconf.h"); |
| 515 | − file_write_dep(NULL); | |
| 516 | 516 | } |
| 517 | 517 | if (!name || basename != conf_def_filename) { |
| 518 | 518 | if (!name) |
| @@ -7,10 +7,10 @@ check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh · 6 unmodified lines | ||
| 7 | 7 | # we really need to do so. (Do not call gcc as part of make mrproper) |
| 8 | 8 | HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) |
| 9 | 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 | 14 | $(obj)/dochecklxdialog: |
| 15 | 15 | $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) |
| 16 | 16 | |
| @@ -21,11 +21,13 @@ KERNELOUTPUT := $2 · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | MAKEFLAGS += --no-print-directory |
| 23 | 23 | |
| 24 | +.PHONY: all \$(MAKECMDGOALS) | |
| 25 | + | |
| 24 | 26 | all: |
| 25 | 27 | \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) |
| 26 | 28 | |
| 27 | −%:: | |
| 28 | − \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ | |
| 29 | +Makefile:; | |
| 29 | 30 | |
| 31 | +\$(filter-out all Makefile,\$(MAKECMDGOALS)) %/: | |
| 32 | + \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ | |
| 30 | 33 | EOF |
| 31 | − | |
| @@ -34,7 +34,7 @@ typedef uint16_t __u16; · 33 unmodified lines | ||
| 34 | 34 | typedef unsigned char __u8; |
| 35 | 35 | |
| 36 | 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 | 38 | * we handle those differences explicitly below */ |
| 39 | 39 | #include "../../include/linux/mod_devicetable.h" |
| 40 | 40 | #include "../../include/linux/input.h" |
| @@ -153,8 +153,8 @@ static void do_usb_table(void *symval, unsigned long size, · 112 unmodified lines | ||
| 153 | 153 | const unsigned long id_size = sizeof(struct usb_device_id); |
| 154 | 154 | |
| 155 | 155 | if (size % id_size || size < id_size) { |
| 156 | − fprintf(stderr, "*** Warning: %s ids %lu bad size " | |
| 157 | − "(each on %lu)\n", mod->name, size, id_size); | |
| 156 | + warn("%s ids %lu bad size " | |
| 157 | + "(each on %lu)\n", mod->name, size, id_size); | |
| 158 | 158 | } |
| 159 | 159 | /* Leave last one: it's the terminator. */ |
| 160 | 160 | size -= id_size; |
| @@ -217,9 +217,8 @@ static int do_pci_entry(const char *filename, · 56 unmodified lines | ||
| 217 | 217 | if ((baseclass_mask != 0 && baseclass_mask != 0xFF) |
| 218 | 218 | || (subclass_mask != 0 && subclass_mask != 0xFF) |
| 219 | 219 | || (interface_mask != 0 && interface_mask != 0xFF)) { |
| 220 | − fprintf(stderr, | |
| 221 | − "*** Warning: Can't handle masks in %s:%04X\n", | |
| 222 | − filename, id->class_mask); | |
| 220 | + warn("Can't handle masks in %s:%04X\n", | |
| 221 | + filename, id->class_mask); | |
| 223 | 222 | return 0; |
| 224 | 223 | } |
| 225 | 224 | |
| @@ -229,7 +228,7 @@ static int do_pci_entry(const char *filename, · 3 unmodified lines | ||
| 229 | 228 | return 1; |
| 230 | 229 | } |
| 231 | 230 | |
| 232 | −/* looks like: "ccw:tNmNdtNdmN" */ | |
| 231 | +/* looks like: "ccw:tNmNdtNdmN" */ | |
| 233 | 232 | static int do_ccw_entry(const char *filename, |
| 234 | 233 | struct ccw_device_id *id, char *alias) |
| 235 | 234 | { |
| @@ -445,8 +444,8 @@ static void do_table(void *symval, unsigned long size, · 209 unmodified lines | ||
| 445 | 444 | int (*do_entry)(const char *, void *entry, char *alias) = function; |
| 446 | 445 | |
| 447 | 446 | if (size % id_size || size < id_size) { |
| 448 | − fprintf(stderr, "*** Warning: %s ids %lu bad size " | |
| 449 | − "(each on %lu)\n", mod->name, size, id_size); | |
| 447 | + warn("%s ids %lu bad size " | |
| 448 | + "(each on %lu)\n", mod->name, size, id_size); | |
| 450 | 449 | } |
| 451 | 450 | /* Leave last one: it's the terminator. */ |
| 452 | 451 | size -= id_size; |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | int |
| 7 | 7 | main(int argc, char **argv) |
| 8 | 8 | { |
| 9 | − unsigned char ei[EI_NIDENT]; | |
| 9 | + unsigned char ei[EI_NIDENT]; | |
| 10 | 10 | union { short s; char c[2]; } endian_test; |
| 11 | 11 | |
| 12 | 12 | if (argc != 2) { |
| @@ -57,7 +57,7 @@ main(int argc, char **argv) · 44 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) |
| 59 | 59 | printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); |
| 60 | − else | |
| 60 | + else | |
| 61 | 61 | printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); |
| 62 | 62 | |
| 63 | 63 | return 0; |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * |
| 3 | 3 | * Copyright 2003 Kai Germaschewski |
| 4 | 4 | * Copyright 2002-2004 Rusty Russell, IBM Corporation |
| 5 | − * | |
| 5 | + * Copyright 2006 Sam Ravnborg | |
| 6 | 6 | * Based in part on module-init-tools/depmod.c,file2alias |
| 7 | 7 | * |
| 8 | 8 | * This software may be used and distributed according to the terms |
| @@ -20,9 +20,10 @@ int modversions = 0; · 11 unmodified lines | ||
| 20 | 20 | int have_vmlinux = 0; |
| 21 | 21 | /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ |
| 22 | 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 | |
| 25 | −fatal(const char *fmt, ...) | |
| 26 | +void fatal(const char *fmt, ...) | |
| 26 | 27 | { |
| 27 | 28 | va_list arglist; |
| 28 | 29 | |
| @@ -35,8 +36,7 @@ fatal(const char *fmt, ...) · 6 unmodified lines | ||
| 35 | 36 | exit(1); |
| 36 | 37 | } |
| 37 | 38 | |
| 38 | −void | |
| 39 | −warn(const char *fmt, ...) | |
| 39 | +void warn(const char *fmt, ...) | |
| 40 | 40 | { |
| 41 | 41 | va_list arglist; |
| 42 | 42 | |
| @@ -47,6 +47,18 @@ warn(const char *fmt, ...) · 4 unmodified lines | ||
| 47 | 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 | 62 | void *do_nofail(void *ptr, const char *expr) |
| 51 | 63 | { |
| 52 | 64 | if (!ptr) { |
| @@ -59,8 +71,7 @@ void *do_nofail(void *ptr, const char *expr) · 6 unmodified lines | ||
| 59 | 71 | |
| 60 | 72 | static struct module *modules; |
| 61 | 73 | |
| 62 | −struct module * | |
| 63 | −find_module(char *modname) | |
| 74 | +static struct module *find_module(char *modname) | |
| 64 | 75 | { |
| 65 | 76 | struct module *mod; |
| 66 | 77 | |
| @@ -70,12 +81,11 @@ find_module(char *modname) · 3 unmodified lines | ||
| 70 | 81 | return mod; |
| 71 | 82 | } |
| 72 | 83 | |
| 73 | −struct module * | |
| 74 | −new_module(char *modname) | |
| 84 | +static struct module *new_module(char *modname) | |
| 75 | 85 | { |
| 76 | 86 | struct module *mod; |
| 77 | 87 | char *p, *s; |
| 78 | − | |
| 88 | + | |
| 79 | 89 | mod = NOFAIL(malloc(sizeof(*mod))); |
| 80 | 90 | memset(mod, 0, sizeof(*mod)); |
| 81 | 91 | p = NOFAIL(strdup(modname)); |
| @@ -104,6 +114,10 @@ struct symbol { · 22 unmodified lines | ||
| 104 | 114 | unsigned int crc; |
| 105 | 115 | int crc_valid; |
| 106 | 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 | 121 | char name[0]; |
| 108 | 122 | }; |
| 109 | 123 | |
| @@ -122,11 +136,12 @@ static inline unsigned int tdb_hash(const char *name) · 12 unmodified lines | ||
| 122 | 136 | return (1103515243 * value + 12345); |
| 123 | 137 | } |
| 124 | 138 | |
| 125 | −/* Allocate a new symbols for use in the hash of exported symbols or | |
| 126 | − * the list of unresolved symbols per module */ | |
| 127 | − | |
| 128 | −struct symbol * | |
| 129 | −alloc_symbol(const char *name, unsigned int weak, struct symbol *next) | |
| 139 | +/** | |
| 140 | + * Allocate a new symbols for use in the hash of exported symbols or | |
| 141 | + * the list of unresolved symbols per module | |
| 142 | + **/ | |
| 143 | +static struct symbol *alloc_symbol(const char *name, unsigned int weak, | |
| 144 | + struct symbol *next) | |
| 130 | 145 | { |
| 131 | 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) · 5 unmodified lines | ||
| 138 | 153 | } |
| 139 | 154 | |
| 140 | 155 | /* For the hash of exported symbols */ |
| 141 | − | |
| 142 | −void | |
| 143 | −new_symbol(const char *name, struct module *module, unsigned int *crc) | |
| 156 | +static struct symbol *new_symbol(const char *name, struct module *module) | |
| 144 | 157 | { |
| 145 | 158 | unsigned int hash; |
| 146 | 159 | struct symbol *new; |
| @@ -148,14 +161,10 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) · 1 unmodified line | ||
| 148 | 161 | hash = tdb_hash(name) % SYMBOL_HASH_SIZE; |
| 149 | 162 | new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); |
| 150 | 163 | new->module = module; |
| 151 | − if (crc) { | |
| 152 | − new->crc = *crc; | |
| 153 | − new->crc_valid = 1; | |
| 154 | − } | |
| 164 | + return new; | |
| 155 | 165 | } |
| 156 | 166 | |
| 157 | −struct symbol * | |
| 158 | −find_symbol(const char *name) | |
| 167 | +static struct symbol *find_symbol(const char *name) | |
| 159 | 168 | { |
| 160 | 169 | struct symbol *s; |
| 161 | 170 | |
| @@ -170,25 +179,42 @@ find_symbol(const char *name) · 8 unmodified lines | ||
| 170 | 179 | return NULL; |
| 171 | 180 | } |
| 172 | 181 | |
| 173 | −/* Add an exported symbol - it may have already been added without a | |
| 174 | − * CRC, in this case just update the CRC */ | |
| 175 | −void | |
| 176 | −add_exported_symbol(const char *name, struct module *module, unsigned int *crc) | |
| 182 | +/** | |
| 183 | + * Add an exported symbol - it may have already been added without a | |
| 184 | + * CRC, in this case just update the CRC | |
| 185 | + **/ | |
| 186 | +static struct symbol *sym_add_exported(const char *name, struct module *mod) | |
| 177 | 187 | { |
| 178 | 188 | struct symbol *s = find_symbol(name); |
| 179 | 189 | |
| 180 | 190 | if (!s) { |
| 181 | − new_symbol(name, module, crc); | |
| 182 | − return; | |
| 183 | − } | |
| 184 | − if (crc) { | |
| 185 | − s->crc = *crc; | |
| 186 | − s->crc_valid = 1; | |
| 191 | + s = new_symbol(name, mod); | |
| 192 | + } else { | |
| 193 | + if (!s->preloaded) { | |
| 194 | + warn("%s: '%s' exported twice. Previous export " | |
| 195 | + "was in %s%s\n", mod->name, name, | |
| 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 * | |
| 191 | −grab_file(const char *filename, unsigned long *size) | |
| 217 | +void *grab_file(const char *filename, unsigned long *size) | |
| 192 | 218 | { |
| 193 | 219 | struct stat st; |
| 194 | 220 | void *map; |
| @@ -207,13 +233,12 @@ grab_file(const char *filename, unsigned long *size) · 12 unmodified lines | ||
| 207 | 233 | return map; |
| 208 | 234 | } |
| 209 | 235 | |
| 210 | −/* | |
| 211 | − Return a copy of the next line in a mmap'ed file. | |
| 212 | − spaces in the beginning of the line is trimmed away. | |
| 213 | − Return a pointer to a static buffer. | |
| 214 | −*/ | |
| 215 | −char* | |
| 216 | −get_next_line(unsigned long *pos, void *file, unsigned long size) | |
| 236 | +/** | |
| 237 | + * Return a copy of the next line in a mmap'ed file. | |
| 238 | + * spaces in the beginning of the line is trimmed away. | |
| 239 | + * Return a pointer to a static buffer. | |
| 240 | + **/ | |
| 241 | +char* get_next_line(unsigned long *pos, void *file, unsigned long size) | |
| 217 | 242 | { |
| 218 | 243 | static char line[4096]; |
| 219 | 244 | int skip = 1; |
| @@ -243,14 +268,12 @@ get_next_line(unsigned long *pos, void *file, unsigned long size) · 23 unmodified lines | ||
| 243 | 268 | return NULL; |
| 244 | 269 | } |
| 245 | 270 | |
| 246 | −void | |
| 247 | −release_file(void *file, unsigned long size) | |
| 271 | +void release_file(void *file, unsigned long size) | |
| 248 | 272 | { |
| 249 | 273 | munmap(file, size); |
| 250 | 274 | } |
| 251 | 275 | |
| 252 | −void | |
| 253 | −parse_elf(struct elf_info *info, const char *filename) | |
| 276 | +static void parse_elf(struct elf_info *info, const char *filename) | |
| 254 | 277 | { |
| 255 | 278 | unsigned int i; |
| 256 | 279 | Elf_Ehdr *hdr = info->hdr; |
| @@ -297,14 +320,13 @@ parse_elf(struct elf_info *info, const char *filename) · 40 unmodified lines | ||
| 297 | 320 | continue; |
| 298 | 321 | |
| 299 | 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 | 324 | + sechdrs[i].sh_size; |
| 302 | − info->strtab = (void *)hdr + | |
| 325 | + info->strtab = (void *)hdr + | |
| 303 | 326 | sechdrs[sechdrs[i].sh_link].sh_offset; |
| 304 | 327 | } |
| 305 | 328 | if (!info->symtab_start) { |
| 306 | − fprintf(stderr, "modpost: %s no symtab?\n", filename); | |
| 307 | − abort(); | |
| 329 | + fatal("%s has no symtab?\n", filename); | |
| 308 | 330 | } |
| 309 | 331 | /* Fix endianness in symbols */ |
| 310 | 332 | for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { |
| @@ -316,36 +338,31 @@ parse_elf(struct elf_info *info, const char *filename) · 5 unmodified lines | ||
| 316 | 338 | return; |
| 317 | 339 | |
| 318 | 340 | truncated: |
| 319 | − fprintf(stderr, "modpost: %s is truncated.\n", filename); | |
| 320 | − abort(); | |
| 341 | + fatal("%s is truncated.\n", filename); | |
| 321 | 342 | } |
| 322 | 343 | |
| 323 | −void | |
| 324 | −parse_elf_finish(struct elf_info *info) | |
| 344 | +static void parse_elf_finish(struct elf_info *info) | |
| 325 | 345 | { |
| 326 | 346 | release_file(info->hdr, info->size); |
| 327 | 347 | } |
| 328 | 348 | |
| 329 | −#define CRC_PFX "__crc_" | |
| 330 | −#define KSYMTAB_PFX "__ksymtab_" | |
| 349 | +#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" | |
| 350 | +#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" | |
| 331 | 351 | |
| 332 | −void | |
| 333 | −handle_modversions(struct module *mod, struct elf_info *info, | |
| 334 | − Elf_Sym *sym, const char *symname) | |
| 352 | +static void handle_modversions(struct module *mod, struct elf_info *info, | |
| 353 | + Elf_Sym *sym, const char *symname) | |
| 335 | 354 | { |
| 336 | 355 | unsigned int crc; |
| 337 | 356 | |
| 338 | 357 | switch (sym->st_shndx) { |
| 339 | 358 | case SHN_COMMON: |
| 340 | − fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n", | |
| 341 | − symname, mod->name); | |
| 359 | + warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); | |
| 342 | 360 | break; |
| 343 | 361 | case SHN_ABS: |
| 344 | 362 | /* CRC'd symbol */ |
| 345 | 363 | if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { |
| 346 | 364 | crc = (unsigned int) sym->st_value; |
| 347 | − add_exported_symbol(symname + strlen(CRC_PFX), | |
| 348 | − mod, &crc); | |
| 365 | + sym_update_crc(symname + strlen(CRC_PFX), mod, crc); | |
| 349 | 366 | } |
| 350 | 367 | break; |
| 351 | 368 | case SHN_UNDEF: |
| @@ -370,15 +387,15 @@ handle_modversions(struct module *mod, struct elf_info *info, · 18 unmodified lines | ||
| 370 | 387 | /* Ignore register directives. */ |
| 371 | 388 | if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) |
| 372 | 389 | break; |
| 373 | − if (symname[0] == '.') { | |
| 374 | − char *munged = strdup(symname); | |
| 375 | − munged[0] = '_'; | |
| 376 | − munged[1] = toupper(munged[1]); | |
| 377 | − symname = munged; | |
| 378 | − } | |
| 390 | + if (symname[0] == '.') { | |
| 391 | + char *munged = strdup(symname); | |
| 392 | + munged[0] = '_'; | |
| 393 | + munged[1] = toupper(munged[1]); | |
| 394 | + symname = munged; | |
| 395 | + } | |
| 379 | 396 | } |
| 380 | 397 | #endif |
| 381 | − | |
| 398 | + | |
| 382 | 399 | if (memcmp(symname, MODULE_SYMBOL_PREFIX, |
| 383 | 400 | strlen(MODULE_SYMBOL_PREFIX)) == 0) |
| 384 | 401 | mod->unres = alloc_symbol(symname + |
| @@ -389,8 +406,7 @@ handle_modversions(struct module *mod, struct elf_info *info, · 4 unmodified lines | ||
| 389 | 406 | default: |
| 390 | 407 | /* All exported symbols */ |
| 391 | 408 | if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { |
| 392 | − add_exported_symbol(symname + strlen(KSYMTAB_PFX), | |
| 393 | − mod, NULL); | |
| 409 | + sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); | |
| 394 | 410 | } |
| 395 | 411 | if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) |
| 396 | 412 | mod->has_init = 1; |
| @@ -400,20 +416,9 @@ handle_modversions(struct module *mod, struct elf_info *info, · 3 unmodified lines | ||
| 400 | 416 | } |
| 401 | 417 | } |
| 402 | 418 | |
| 403 | −int | |
| 404 | −is_vmlinux(const char *modname) | |
| 405 | −{ | |
| 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 */ | |
| 419 | +/** | |
| 420 | + * Parse tag=value strings from .modinfo section | |
| 421 | + **/ | |
| 417 | 422 | static char *next_string(char *string, unsigned long *secsize) |
| 418 | 423 | { |
| 419 | 424 | /* Skip non-zero chars */ |
| @@ -446,8 +451,418 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, · 26 unmodified lines | ||
| 446 | 451 | return NULL; |
| 447 | 452 | } |
| 448 | 453 | |
| 449 | −void | |
| 450 | −read_symbols(char *modname) | |
| 454 | +/** | |
| 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 | 867 | const char *symname; |
| 453 | 868 | char *version; |
| @@ -462,9 +877,7 @@ read_symbols(char *modname) · 8 unmodified lines | ||
| 462 | 877 | /* When there's no vmlinux, don't print warnings about |
| 463 | 878 | * unresolved symbols (since there'll be too many ;) */ |
| 464 | 879 | if (is_vmlinux(modname)) { |
| 465 | − unsigned int fake_crc = 0; | |
| 466 | 880 | have_vmlinux = 1; |
| 467 | − add_exported_symbol("struct_module", mod, &fake_crc); | |
| 468 | 881 | mod->skip = 1; |
| 469 | 882 | } |
| 470 | 883 | |
| @@ -474,6 +887,8 @@ read_symbols(char *modname) · 3 unmodified lines | ||
| 474 | 887 | handle_modversions(mod, &info, sym, symname); |
| 475 | 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 | 893 | version = get_modinfo(info.modinfo, info.modinfo_len, "version"); |
| 479 | 894 | if (version) |
| @@ -499,21 +914,20 @@ read_symbols(char *modname) · 19 unmodified lines | ||
| 499 | 914 | * following helper, then compare to the file on disk and |
| 500 | 915 | * only update the later if anything changed */ |
| 501 | 916 | |
| 502 | −void __attribute__((format(printf, 2, 3))) | |
| 503 | −buf_printf(struct buffer *buf, const char *fmt, ...) | |
| 917 | +void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, | |
| 918 | + const char *fmt, ...) | |
| 504 | 919 | { |
| 505 | 920 | char tmp[SZ]; |
| 506 | 921 | int len; |
| 507 | 922 | va_list ap; |
| 508 | − | |
| 923 | + | |
| 509 | 924 | va_start(ap, fmt); |
| 510 | 925 | len = vsnprintf(tmp, SZ, fmt, ap); |
| 511 | 926 | buf_write(buf, tmp, len); |
| 512 | 927 | va_end(ap); |
| 513 | 928 | } |
| 514 | 929 | |
| 515 | −void | |
| 516 | −buf_write(struct buffer *buf, const char *s, int len) | |
| 930 | +void buf_write(struct buffer *buf, const char *s, int len) | |
| 517 | 931 | { |
| 518 | 932 | if (buf->size - buf->pos < len) { |
| 519 | 933 | buf->size += len + SZ; |
| @@ -523,10 +937,10 @@ buf_write(struct buffer *buf, const char *s, int len) · 3 unmodified lines | ||
| 523 | 937 | buf->pos += len; |
| 524 | 938 | } |
| 525 | 939 | |
| 526 | −/* Header for the generated file */ | |
| 527 | − | |
| 528 | −void | |
| 529 | −add_header(struct buffer *b, struct module *mod) | |
| 940 | +/** | |
| 941 | + * Header for the generated file | |
| 942 | + **/ | |
| 943 | +static void add_header(struct buffer *b, struct module *mod) | |
| 530 | 944 | { |
| 531 | 945 | buf_printf(b, "#include <linux/module.h>\n"); |
| 532 | 946 | buf_printf(b, "#include <linux/vermagic.h>\n"); |
| @@ -546,10 +960,10 @@ add_header(struct buffer *b, struct module *mod) · 13 unmodified lines | ||
| 546 | 960 | buf_printf(b, "};\n"); |
| 547 | 961 | } |
| 548 | 962 | |
| 549 | −/* Record CRCs for unresolved symbols */ | |
| 550 | − | |
| 551 | −void | |
| 552 | −add_versions(struct buffer *b, struct module *mod) | |
| 963 | +/** | |
| 964 | + * Record CRCs for unresolved symbols | |
| 965 | + **/ | |
| 966 | +static void add_versions(struct buffer *b, struct module *mod) | |
| 553 | 967 | { |
| 554 | 968 | struct symbol *s, *exp; |
| 555 | 969 | |
| @@ -557,8 +971,8 @@ add_versions(struct buffer *b, struct module *mod) · 1 unmodified line | ||
| 557 | 971 | exp = find_symbol(s->name); |
| 558 | 972 | if (!exp || exp->module == mod) { |
| 559 | 973 | if (have_vmlinux && !s->weak) |
| 560 | − fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " | |
| 561 | − "undefined!\n", s->name, mod->name); | |
| 974 | + warn("\"%s\" [%s.ko] undefined!\n", | |
| 975 | + s->name, mod->name); | |
| 562 | 976 | continue; |
| 563 | 977 | } |
| 564 | 978 | s->module = exp->module; |
| @@ -579,8 +993,7 @@ add_versions(struct buffer *b, struct module *mod) · 14 unmodified lines | ||
| 579 | 993 | continue; |
| 580 | 994 | } |
| 581 | 995 | if (!s->crc_valid) { |
| 582 | − fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " | |
| 583 | − "has no CRC!\n", | |
| 996 | + warn("\"%s\" [%s.ko] has no CRC!\n", | |
| 584 | 997 | s->name, mod->name); |
| 585 | 998 | continue; |
| 586 | 999 | } |
| @@ -590,8 +1003,8 @@ add_versions(struct buffer *b, struct module *mod) · 3 unmodified lines | ||
| 590 | 1003 | buf_printf(b, "};\n"); |
| 591 | 1004 | } |
| 592 | 1005 | |
| 593 | −void | |
| 594 | −add_depends(struct buffer *b, struct module *mod, struct module *modules) | |
| 1006 | +static void add_depends(struct buffer *b, struct module *mod, | |
| 1007 | + struct module *modules) | |
| 595 | 1008 | { |
| 596 | 1009 | struct symbol *s; |
| 597 | 1010 | struct module *m; |
| @@ -621,8 +1034,7 @@ add_depends(struct buffer *b, struct module *mod, struct module *modules) · 23 unmodified lines | ||
| 621 | 1034 | buf_printf(b, "\";\n"); |
| 622 | 1035 | } |
| 623 | 1036 | |
| 624 | −void | |
| 625 | −add_srcversion(struct buffer *b, struct module *mod) | |
| 1037 | +static void add_srcversion(struct buffer *b, struct module *mod) | |
| 626 | 1038 | { |
| 627 | 1039 | if (mod->srcversion[0]) { |
| 628 | 1040 | buf_printf(b, "\n"); |
| @@ -631,8 +1043,7 @@ add_srcversion(struct buffer *b, struct module *mod) · 2 unmodified lines | ||
| 631 | 1043 | } |
| 632 | 1044 | } |
| 633 | 1045 | |
| 634 | −void | |
| 635 | −write_if_changed(struct buffer *b, const char *fname) | |
| 1046 | +static void write_if_changed(struct buffer *b, const char *fname) | |
| 636 | 1047 | { |
| 637 | 1048 | char *tmp; |
| 638 | 1049 | FILE *file; |
| @@ -676,8 +1087,7 @@ write_if_changed(struct buffer *b, const char *fname) · 37 unmodified lines | ||
| 676 | 1087 | fclose(file); |
| 677 | 1088 | } |
| 678 | 1089 | |
| 679 | −void | |
| 680 | −read_dump(const char *fname) | |
| 1090 | +static void read_dump(const char *fname, unsigned int kernel) | |
| 681 | 1091 | { |
| 682 | 1092 | unsigned long size, pos = 0; |
| 683 | 1093 | void *file = grab_file(fname, &size); |
| @@ -691,6 +1101,7 @@ read_dump(const char *fname) · 7 unmodified lines | ||
| 691 | 1101 | char *symname, *modname, *d; |
| 692 | 1102 | unsigned int crc; |
| 693 | 1103 | struct module *mod; |
| 1104 | + struct symbol *s; | |
| 694 | 1105 | |
| 695 | 1106 | if (!(symname = strchr(line, '\t'))) |
| 696 | 1107 | goto fail; |
| @@ -711,15 +1122,30 @@ read_dump(const char *fname) · 14 unmodified lines | ||
| 711 | 1122 | mod = new_module(NOFAIL(strdup(modname))); |
| 712 | 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 | 1130 | return; |
| 717 | 1131 | fail: |
| 718 | 1132 | fatal("parse error in symbol dump file\n"); |
| 719 | 1133 | } |
| 720 | 1134 | |
| 721 | −void | |
| 722 | −write_dump(const char *fname) | |
| 1135 | +/* For normal builds always dump all symbols. | |
| 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 | 1150 | struct buffer buf = { }; |
| 725 | 1151 | struct symbol *symbol; |
| @@ -728,34 +1154,33 @@ write_dump(const char *fname) · 2 unmodified lines | ||
| 728 | 1154 | for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { |
| 729 | 1155 | symbol = symbolhash[n]; |
| 730 | 1156 | while (symbol) { |
| 731 | − symbol = symbol->next; | |
| 732 | − } | |
| 733 | − } | |
| 734 | − | |
| 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); | |
| 1157 | + if (dump_sym(symbol)) | |
| 1158 | + buf_printf(&buf, "0x%08x\t%s\t%s\n", | |
| 1159 | + symbol->crc, symbol->name, | |
| 1160 | + symbol->module->name); | |
| 740 | 1161 | symbol = symbol->next; |
| 741 | 1162 | } |
| 742 | 1163 | } |
| 743 | 1164 | write_if_changed(&buf, fname); |
| 744 | 1165 | } |
| 745 | 1166 | |
| 746 | −int | |
| 747 | −main(int argc, char **argv) | |
| 1167 | +int main(int argc, char **argv) | |
| 748 | 1168 | { |
| 749 | 1169 | struct module *mod; |
| 750 | 1170 | struct buffer buf = { }; |
| 751 | 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 | 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 | 1177 | switch(opt) { |
| 757 | 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 | 1184 | break; |
| 760 | 1185 | case 'm': |
| 761 | 1186 | modversions = 1; |
| @@ -771,8 +1196,10 @@ main(int argc, char **argv) · 9 unmodified lines | ||
| 771 | 1196 | } |
| 772 | 1197 | } |
| 773 | 1198 | |
| 774 | − if (dump_read) | |
| 775 | − read_dump(dump_read); | |
| 1199 | + if (kernel_read) | |
| 1200 | + read_dump(kernel_read, 1); | |
| 1201 | + if (module_read) | |
| 1202 | + read_dump(module_read, 0); | |
| 776 | 1203 | |
| 777 | 1204 | while (optind < argc) { |
| 778 | 1205 | read_symbols(argv[optind++]); |
| @@ -799,4 +1226,3 @@ main(int argc, char **argv) · 20 unmodified lines | ||
| 799 | 1226 | |
| 800 | 1227 | return 0; |
| 801 | 1228 | } |
| 802 | − | |
| @@ -13,20 +13,30 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #if KERNEL_ELFCLASS == ELFCLASS32 |
| 15 | 15 | |
| 16 | −#define Elf_Ehdr Elf32_Ehdr | |
| 17 | −#define Elf_Shdr Elf32_Shdr | |
| 16 | +#define Elf_Ehdr Elf32_Ehdr | |
| 17 | +#define Elf_Shdr Elf32_Shdr | |
| 18 | 18 | #define Elf_Sym Elf32_Sym |
| 19 | +#define Elf_Addr Elf32_Addr | |
| 20 | +#define Elf_Section Elf32_Section | |
| 19 | 21 | #define ELF_ST_BIND ELF32_ST_BIND |
| 20 | 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 | 27 | #else |
| 23 | 28 | |
| 24 | −#define Elf_Ehdr Elf64_Ehdr | |
| 25 | −#define Elf_Shdr Elf64_Shdr | |
| 29 | +#define Elf_Ehdr Elf64_Ehdr | |
| 30 | +#define Elf_Shdr Elf64_Shdr | |
| 26 | 31 | #define Elf_Sym Elf64_Sym |
| 32 | +#define Elf_Addr Elf64_Addr | |
| 33 | +#define Elf_Section Elf64_Section | |
| 27 | 34 | #define ELF_ST_BIND ELF64_ST_BIND |
| 28 | 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 | 40 | #endif |
| 31 | 41 | |
| 32 | 42 | #if KERNEL_ELFDATA != HOST_ELFDATA |
| @@ -91,17 +101,22 @@ struct elf_info { · 58 unmodified lines | ||
| 91 | 101 | unsigned int modinfo_len; |
| 92 | 102 | }; |
| 93 | 103 | |
| 104 | +/* file2alias.c */ | |
| 94 | 105 | void handle_moddevtable(struct module *mod, struct elf_info *info, |
| 95 | 106 | Elf_Sym *sym, const char *symname); |
| 96 | − | |
| 97 | 107 | void add_moddevtable(struct buffer *buf, struct module *mod); |
| 98 | 108 | |
| 109 | +/* sumversion.c */ | |
| 99 | 110 | void maybe_frob_rcs_version(const char *modfilename, |
| 100 | 111 | char *version, |
| 101 | 112 | void *modinfo, |
| 102 | 113 | unsigned long modinfo_offset); |
| 103 | 114 | void get_src_version(const char *modname, char sum[], unsigned sumlen); |
| 104 | 115 | |
| 116 | +/* from modpost.c */ | |
| 105 | 117 | void *grab_file(const char *filename, unsigned long *size); |
| 106 | 118 | char* get_next_line(unsigned long *pos, void *file, unsigned long size); |
| 107 | 119 | void release_file(void *file, unsigned long size); |
| 120 | + | |
| 121 | +void fatal(const char *fmt, ...); | |
| 122 | +void warn(const char *fmt, ...); | |
| @@ -316,8 +316,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) · 315 unmodified lines | ||
| 316 | 316 | |
| 317 | 317 | file = grab_file(cmd, &flen); |
| 318 | 318 | if (!file) { |
| 319 | − fprintf(stderr, "Warning: could not find %s for %s\n", | |
| 320 | − cmd, objfile); | |
| 319 | + warn("could not find %s for %s\n", cmd, objfile); | |
| 321 | 320 | goto out; |
| 322 | 321 | } |
| 323 | 322 | |
| @@ -355,9 +354,8 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) · 31 unmodified lines | ||
| 355 | 354 | /* Check if this file is in same dir as objfile */ |
| 356 | 355 | if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { |
| 357 | 356 | if (!parse_file(line, md)) { |
| 358 | − fprintf(stderr, | |
| 359 | − "Warning: could not open %s: %s\n", | |
| 360 | − line, strerror(errno)); | |
| 357 | + warn("could not open %s: %s\n", | |
| 358 | + line, strerror(errno)); | |
| 361 | 359 | goto out_file; |
| 362 | 360 | } |
| 363 | 361 | |
| @@ -383,8 +381,11 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) · 19 unmodified lines | ||
| 383 | 381 | struct md4_ctx md; |
| 384 | 382 | char *sources, *end, *fname; |
| 385 | 383 | const char *basename; |
| 386 | − char filelist[strlen(getenv("MODVERDIR")) + strlen("/") + | |
| 387 | − strlen(modname) - strlen(".o") + strlen(".mod") + 1 ]; | |
| 384 | + char filelist[PATH_MAX + 1]; | |
| 385 | + char *modverdir = getenv("MODVERDIR"); | |
| 386 | + | |
| 387 | + if (!modverdir) | |
| 388 | + modverdir = "."; | |
| 388 | 389 | |
| 389 | 390 | /* Source files for module are in .tmp_versions/modname.mod, |
| 390 | 391 | after the first line. */ |
| @@ -392,28 +393,25 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) · 1 unmodified line | ||
| 392 | 393 | basename = strrchr(modname, '/') + 1; |
| 393 | 394 | else |
| 394 | 395 | basename = modname; |
| 395 | − sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"), | |
| 396 | + sprintf(filelist, "%s/%.*s.mod", modverdir, | |
| 396 | 397 | (int) strlen(basename) - 2, basename); |
| 397 | 398 | |
| 398 | 399 | file = grab_file(filelist, &len); |
| 399 | 400 | if (!file) { |
| 400 | − fprintf(stderr, "Warning: could not find versions for %s\n", | |
| 401 | − filelist); | |
| 401 | + warn("could not find versions for %s\n", filelist); | |
| 402 | 402 | return; |
| 403 | 403 | } |
| 404 | 404 | |
| 405 | 405 | sources = strchr(file, '\n'); |
| 406 | 406 | if (!sources) { |
| 407 | − fprintf(stderr, "Warning: malformed versions file for %s\n", | |
| 408 | − modname); | |
| 407 | + warn("malformed versions file for %s\n", modname); | |
| 409 | 408 | goto release; |
| 410 | 409 | } |
| 411 | 410 | |
| 412 | 411 | sources++; |
| 413 | 412 | end = strchr(sources, '\n'); |
| 414 | 413 | if (!end) { |
| 415 | − fprintf(stderr, "Warning: bad ending versions file for %s\n", | |
| 416 | − modname); | |
| 414 | + warn("bad ending versions file for %s\n", modname); | |
| 417 | 415 | goto release; |
| 418 | 416 | } |
| 419 | 417 | *end = '\0'; |
| @@ -438,19 +436,19 @@ static void write_version(const char *filename, const char *sum, · 18 unmodified lines | ||
| 438 | 436 | |
| 439 | 437 | fd = open(filename, O_RDWR); |
| 440 | 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 | 440 | filename, strerror(errno)); |
| 443 | 441 | return; |
| 444 | 442 | } |
| 445 | 443 | |
| 446 | 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 | 446 | filename, offset, strerror(errno)); |
| 449 | 447 | goto out; |
| 450 | 448 | } |
| 451 | 449 | |
| 452 | 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 | 452 | filename, strerror(errno)); |
| 455 | 453 | goto out; |
| 456 | 454 | } |
| @@ -66,8 +66,8 @@ require 5; # at least perl 5 · 65 unmodified lines | ||
| 66 | 66 | use strict; |
| 67 | 67 | use File::Find; |
| 68 | 68 | |
| 69 | −my $nm = "/usr/bin/nm -p"; | |
| 70 | −my $objdump = "/usr/bin/objdump -s -j .comment"; | |
| 69 | +my $nm = ($ENV{'NM'} || "nm") . " -p"; | |
| 70 | +my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment"; | |
| 71 | 71 | my $srctree = ""; |
| 72 | 72 | my $objtree = ""; |
| 73 | 73 | $srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'})); |
| @@ -32,12 +32,11 @@ MKSPEC := $(srctree)/scripts/package/mkspec · 31 unmodified lines | ||
| 32 | 32 | PREV := set -e; cd ..; |
| 33 | 33 | |
| 34 | 34 | # rpm-pkg |
| 35 | −.PHONY: rpm-pkg rpm | |
| 36 | − | |
| 35 | +# --------------------------------------------------------------------------- | |
| 37 | 36 | $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile |
| 38 | 37 | $(CONFIG_SHELL) $(MKSPEC) > $@ |
| 39 | 38 | |
| 40 | −rpm-pkg rpm: $(objtree)/kernel.spec | |
| 39 | +rpm-pkg rpm: $(objtree)/kernel.spec FORCE | |
| 41 | 40 | $(MAKE) clean |
| 42 | 41 | $(PREV) ln -sf $(srctree) $(KERNELPATH) |
| 43 | 42 | $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. |
| @@ -54,11 +53,11 @@ rpm-pkg rpm: $(objtree)/kernel.spec · 10 unmodified lines | ||
| 54 | 53 | clean-files := $(objtree)/kernel.spec |
| 55 | 54 | |
| 56 | 55 | # binrpm-pkg |
| 57 | −.PHONY: binrpm-pkg | |
| 56 | +# --------------------------------------------------------------------------- | |
| 58 | 57 | $(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile |
| 59 | 58 | $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@ |
| 60 | − | |
| 61 | −binrpm-pkg: $(objtree)/binkernel.spec | |
| 59 | + | |
| 60 | +binrpm-pkg: $(objtree)/binkernel.spec FORCE | |
| 62 | 61 | $(MAKE) KBUILD_SRC= |
| 63 | 62 | set -e; \ |
| 64 | 63 | $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version |
| @@ -71,9 +70,7 @@ clean-files += $(objtree)/binkernel.spec · 6 unmodified lines | ||
| 71 | 70 | |
| 72 | 71 | # Deb target |
| 73 | 72 | # --------------------------------------------------------------------------- |
| 74 | −# | |
| 75 | −.PHONY: deb-pkg | |
| 76 | −deb-pkg: | |
| 73 | +deb-pkg: FORCE | |
| 77 | 74 | $(MAKE) KBUILD_SRC= |
| 78 | 75 | $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb |
| 79 | 76 | |
| @@ -82,8 +79,7 @@ clean-dirs += $(objtree)/debian/ · 2 unmodified lines | ||
| 82 | 79 | |
| 83 | 80 | # tarball targets |
| 84 | 81 | # --------------------------------------------------------------------------- |
| 85 | −.PHONY: tar%pkg | |
| 86 | −tar%pkg: | |
| 82 | +tar%pkg: FORCE | |
| 87 | 83 | $(MAKE) KBUILD_SRC= |
| 88 | 84 | $(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ |
| 89 | 85 | |
| @@ -92,7 +88,7 @@ clean-dirs += $(objtree)/tar-install/ · 2 unmodified lines | ||
| 92 | 88 | |
| 93 | 89 | # Help text displayed when executing 'make help' |
| 94 | 90 | # --------------------------------------------------------------------------- |
| 95 | −help: | |
| 91 | +help: FORCE | |
| 96 | 92 | @echo ' rpm-pkg - Build the kernel as an RPM package' |
| 97 | 93 | @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel' |
| 98 | 94 | @echo ' and modules' |
| @@ -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); | |
| @@ -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"); | |