diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Kbuild.include | 65 | ||||
-rw-r--r-- | scripts/Makefile.build | 27 | ||||
-rw-r--r-- | scripts/Makefile.clean | 10 | ||||
-rw-r--r-- | scripts/Makefile.modinst | 10 | ||||
-rw-r--r-- | scripts/Makefile.modpost | 21 | ||||
-rw-r--r-- | scripts/basic/fixdep.c | 14 | ||||
-rwxr-xr-x | scripts/checkconfig.pl | 65 | ||||
-rwxr-xr-x | scripts/extract-ikconfig | 5 | ||||
-rw-r--r-- | scripts/genksyms/genksyms.c | 843 | ||||
-rw-r--r-- | scripts/genksyms/genksyms.h | 57 | ||||
-rw-r--r-- | scripts/kallsyms.c | 12 | ||||
-rw-r--r-- | scripts/kconfig/Makefile | 6 | ||||
-rw-r--r-- | scripts/kconfig/confdata.c | 2 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/Makefile | 6 | ||||
-rw-r--r-- | scripts/mkmakefile | 8 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 17 | ||||
-rw-r--r-- | scripts/mod/mk_elfconfig.c | 4 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 698 | ||||
-rw-r--r-- | scripts/mod/modpost.h | 25 | ||||
-rw-r--r-- | scripts/mod/sumversion.c | 32 | ||||
-rw-r--r-- | scripts/namespace.pl | 4 | ||||
-rw-r--r-- | scripts/package/Makefile | 20 | ||||
-rw-r--r-- | scripts/profile2linkerlist.pl | 21 | ||||
-rw-r--r-- | scripts/reference_discarded.pl | 112 | ||||
-rw-r--r-- | scripts/reference_init.pl | 108 |
25 files changed, 1175 insertions, 1017 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 0168d6c37075..59620b1554e0 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -44,6 +44,43 @@ define filechk fi endef +###### +# gcc support functions +# See documentation in Documentation/kbuild/makefiles.txt + +# as-option +# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,) + +as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \ + -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \ + else echo "$(2)"; fi ;) + +# cc-option +# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) + +cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ + > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) + +# cc-option-yn +# Usage: flag := $(call cc-option-yn, -march=winchip-c6) +cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ + > /dev/null 2>&1; then echo "y"; else echo "n"; fi;) + +# cc-option-align +# Prefix align with either -falign or -malign +cc-option-align = $(subst -functions=0,,\ + $(call cc-option,-falign-functions=0,-malign-functions=0)) + +# cc-version +# Usage gcc-ver := $(call cc-version, $(CC)) +cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \ + $(if $(1), $(1), $(CC))) + +# cc-ifversion +# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) +cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \ + echo $(3); fi;) + ### # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= # Usage: @@ -51,8 +88,7 @@ endef build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj # If quiet is set, only print short version of command -cmd = @$(if $($(quiet)cmd_$(1)),\ - echo ' $(call escsq,$($(quiet)cmd_$(1)))' &&) $(cmd_$(1)) +cmd = @$(echo-cmd) $(cmd_$(1)) # Add $(obj)/ for paths that is not absolute objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) @@ -75,30 +111,33 @@ endif echo-cmd = $(if $($(quiet)cmd_$(1)), \ echo ' $(call escsq,$($(quiet)cmd_$(1)))';) +make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))) + # function to only execute the passed command if necessary # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file # note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars -# -if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ +# +if_changed = $(if $(strip $(filter-out $(PHONY),$?) \ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ @set -e; \ - $(echo-cmd) \ - $(cmd_$(1)); \ - echo 'cmd_$@ := $(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).cmd) + $(echo-cmd) $(cmd_$(1)); \ + echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd) # execute the command and also postprocess generated .d dependencies # file -if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ - $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ +if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?) \ + $(filter-out FORCE $(wildcard $^),$^) \ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ @set -e; \ - $(echo-cmd) \ - $(cmd_$(1)); \ - scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \ + $(echo-cmd) $(cmd_$(1)); \ + scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \ rm -f $(depfile); \ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) # Usage: $(call if_changed_rule,foo) # will check if $(cmd_foo) changed, or any of the prequisites changed, # and if so will execute $(rule_foo) -if_changed_rule = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ +if_changed_rule = $(if $(strip $(filter-out $(PHONY),$?) \ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ @set -e; \ $(rule_$(1))) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index c33e62bde6b0..e48e60da3040 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -4,17 +4,18 @@ src := $(obj) -.PHONY: __build +PHONY := __build __build: # Read .config if it exist, otherwise ignore -include .config +include scripts/Kbuild.include + # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) -include scripts/Kbuild.include include scripts/Makefile.lib ifdef host-progs @@ -128,7 +129,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi) $(multi-objs-y:.o=.lst) : modname = $(modname-multi) quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ -cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< +cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $< %.s: %.c FORCE $(call if_changed_dep,cc_s_c) @@ -165,7 +166,7 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< cmd_modversions = \ if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ $(CPP) -D__GENKSYMS__ $(c_flags) $< \ - | $(GENKSYMS) \ + | $(GENKSYMS) -a $(ARCH) \ > $(@D)/.tmp_$(@F:.o=.ver); \ \ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ @@ -177,12 +178,10 @@ cmd_modversions = \ endif define rule_cc_o_c - $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \ - $(cmd_checksrc) \ - $(if $($(quiet)cmd_cc_o_c),echo ' $(call escsq,$($(quiet)cmd_cc_o_c))';) \ - $(cmd_cc_o_c); \ + $(call echo-cmd,checksrc) $(cmd_checksrc) \ + $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ $(cmd_modversions) \ - scripts/basic/fixdep $(depfile) $@ '$(call escsq,$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp; \ + scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > $(@D)/.$(@F).tmp; \ rm -f $(depfile); \ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd endef @@ -309,14 +308,14 @@ targets += $(multi-used-y) $(multi-used-m) # Descending # --------------------------------------------------------------------------- -.PHONY: $(subdir-ym) +PHONY += $(subdir-ym) $(subdir-ym): $(Q)$(MAKE) $(build)=$@ # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- -.PHONY: FORCE +PHONY += FORCE FORCE: @@ -331,3 +330,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) endif + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 8974ea5fc878..cff33498fa16 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -4,7 +4,7 @@ src := $(obj) -.PHONY: __clean +PHONY := __clean __clean: # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir @@ -87,10 +87,16 @@ endif # Descending # --------------------------------------------------------------------------- -.PHONY: $(subdir-ymn) +PHONY += $(subdir-ymn) $(subdir-ymn): $(Q)$(MAKE) $(clean)=$@ # If quiet is set, only print short version of command cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1)) + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 23fd1bdc25ce..2686dd5dce8c 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -2,7 +2,7 @@ # Installing modules # ========================================================================== -.PHONY: __modinst +PHONY := __modinst __modinst: include scripts/Kbuild.include @@ -12,7 +12,7 @@ include scripts/Kbuild.include __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) -.PHONY: $(modules) +PHONY += $(modules) __modinst: $(modules) @: @@ -27,3 +27,9 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) $(modules): $(call cmd,modules_install,$(MODLIB)/$(modinst_dir)) + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index bf96a61d4b86..0e056cffffdb 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -4,7 +4,7 @@ # # Stage one of module building created the following: # a) The individual .o files used for the module -# b) A <module>.o file wich is the .o files above linked together +# b) A <module>.o file which is the .o files above linked together # c) A <module>.mod file in $(MODVERDIR)/, listing the name of the # the preliminary <module>.o file, plus all .o files @@ -32,14 +32,15 @@ # Step 4 is solely used to allow module versioning in external modules, # where the CRC of each module is retrieved from the Module.symers file. -.PHONY: _modpost +PHONY := _modpost _modpost: __modpost include .config include scripts/Kbuild.include include scripts/Makefile.lib -symverfile := $(objtree)/Module.symvers +kernelsymfile := $(objtree)/Module.symvers +modulesymfile := $(KBUILD_EXTMOD)/Modules.symvers # Step 1), find all modules listed in $(MODVERDIR)/ __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) @@ -54,10 +55,12 @@ quiet_cmd_modpost = MODPOST cmd_modpost = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ - $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \ + $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ + $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ + $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(filter-out FORCE,$^) -.PHONY: __modpost +PHONY += __modpost __modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE $(call cmd,modpost) @@ -94,7 +97,7 @@ targets += $(modules) # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- -.PHONY: FORCE +PHONY += FORCE FORCE: @@ -109,3 +112,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) endif + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 679124b11e12..668a11a8b383 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -132,20 +132,10 @@ void usage(void) /* * Print out the commandline prefixed with cmd_<target filename> := - * If commandline contains '#' escape with '\' so make to not see - * the '#' as a start-of-comment symbol - **/ + */ void print_cmdline(void) { - char *p = cmdline; - - printf("cmd_%s := ", target); - for (; *p; p++) { - if (*p == '#') - printf("\\"); - printf("%c", *p); - } - printf("\n\n"); + printf("cmd_%s := %s\n\n", target, cmdline); } char * str_config = NULL; diff --git a/scripts/checkconfig.pl b/scripts/checkconfig.pl deleted file mode 100755 index ca1f231b15a6..000000000000 --- a/scripts/checkconfig.pl +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/perl -# -# checkconfig: find uses of CONFIG_* names without matching definitions. -# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>. - -use integer; - -$| = 1; - -foreach $file (@ARGV) -{ - # Open this file. - open(FILE, $file) || die "Can't open $file: $!\n"; - - # Initialize variables. - my $fInComment = 0; - my $fInString = 0; - my $fUseConfig = 0; - my $iLinuxConfig = 0; - my %configList = (); - - LINE: while ( <FILE> ) - { - # Strip comments. - $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); - m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); - - # Pick up definitions. - if ( m/^\s*#/o ) - { - $iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o; - $configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o; - } - - # Strip strings. - $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next); - m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1))); - - # Pick up definitions. - if ( m/^\s*#/o ) - { - $iLinuxConfig = $. if m/^\s*#\s*include\s*<linux\/config\.h>/o; - $configList{uc $1} = 1 if m/^\s*#\s*include\s*<config\/(\S*)\.h>/o; - $configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o; - $configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o; - } - - # Look for usages. - next unless m/CONFIG_/o; - WORD: while ( m/\bCONFIG_(\w+)/og ) - { - $fUseConfig = 1; - last LINE if $iLinuxConfig; - next WORD if exists $configList{$1}; - print "$file: $.: need CONFIG_$1.\n"; - $configList{$1} = 0; - } - } - - # Report superfluous includes. - if ( $iLinuxConfig && ! $fUseConfig ) - { print "$file: $iLinuxConfig: linux/config.h not needed.\n"; } - - close(FILE); -} diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index d9f9f34b22ab..8187e6f0dc2f 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig @@ -4,6 +4,7 @@ # $arg1 is [b]zImage filename binoffset="./scripts/binoffset" +test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1 IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54" IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" @@ -20,7 +21,7 @@ function dump_config { let start="$start + 8" let size="$end - $start" - head --bytes="$end" "$file" | tail --bytes="$size" | zcat + dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat clean_up exit 0 @@ -45,7 +46,7 @@ then exit 1 fi -TMPFILE="/tmp/ikconfig-$$" +TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 1 image="$1" # vmlinux: Attempt to dump the configuration from the file directly diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 416a694b0998..5b0344e20d61 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -29,481 +29,421 @@ #include <stdarg.h> #ifdef __GNU_LIBRARY__ #include <getopt.h> -#endif /* __GNU_LIBRARY__ */ +#endif /* __GNU_LIBRARY__ */ #include "genksyms.h" - /*----------------------------------------------------------------------*/ #define HASH_BUCKETS 4096 static struct symbol *symtab[HASH_BUCKETS]; -FILE *debugfile; +static FILE *debugfile; int cur_line = 1; -char *cur_filename, *output_directory; +char *cur_filename; -int flag_debug, flag_dump_defs, flag_warnings; +static int flag_debug, flag_dump_defs, flag_warnings; +static const char *arch = ""; +static const char *mod_prefix = ""; static int errors; static int nsyms; static struct symbol *expansion_trail; -static const char * const symbol_type_name[] = { - "normal", "typedef", "enum", "struct", "union" +static const char *const symbol_type_name[] = { + "normal", "typedef", "enum", "struct", "union" }; +static int equal_list(struct string_list *a, struct string_list *b); +static void print_list(FILE * f, struct string_list *list); + /*----------------------------------------------------------------------*/ -static const unsigned int crctab32[] = -{ - 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, - 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, - 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, - 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, - 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, - 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, - 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, - 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, - 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, - 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, - 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, - 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, - 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, - 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, - 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, - 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, - 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, - 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, - 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, - 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, - 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, - 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, - 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, - 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, - 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, - 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, - 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, - 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, - 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, - 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, - 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, - 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, - 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, - 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, - 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, - 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, - 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, - 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, - 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, - 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, - 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, - 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, - 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, - 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, - 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, - 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, - 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, - 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, - 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, - 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, - 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, - 0x2d02ef8dU +static const unsigned int crctab32[] = { + 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, + 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, + 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, + 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, + 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, + 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, + 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, + 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, + 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, + 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, + 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, + 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, + 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, + 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, + 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, + 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, + 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, + 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, + 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, + 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, + 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, + 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, + 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, + 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, + 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, + 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, + 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, + 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, + 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, + 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, + 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, + 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, + 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, + 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, + 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, + 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, + 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, + 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, + 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, + 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, + 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, + 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, + 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, + 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, + 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, + 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, + 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, + 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, + 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, + 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, + 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, + 0x2d02ef8dU }; -static inline unsigned long -partial_crc32_one(unsigned char c, unsigned long crc) +static unsigned long partial_crc32_one(unsigned char c, unsigned long crc) { - return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); + return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); } -static inline unsigned long -partial_crc32(const char *s, unsigned long crc) +static unsigned long partial_crc32(const char *s, unsigned long crc) { - while (*s) - crc = partial_crc32_one(*s++, crc); - return crc; + while (*s) + crc = partial_crc32_one(*s++, crc); + return crc; } -static inline unsigned long -crc32(const char *s) +static unsigned long crc32(const char *s) { - return partial_crc32(s, 0xffffffff) ^ 0xffffffff; + return partial_crc32(s, 0xffffffff) ^ 0xffffffff; } - /*----------------------------------------------------------------------*/ -static inline enum symbol_type -map_to_ns(enum symbol_type t) +static enum symbol_type map_to_ns(enum symbol_type t) { - if (t == SYM_TYPEDEF) - t = SYM_NORMAL; - else if (t == SYM_UNION) - t = SYM_STRUCT; - return t; + if (t == SYM_TYPEDEF) + t = SYM_NORMAL; + else if (t == SYM_UNION) + t = SYM_STRUCT; + return t; } -struct symbol * -find_symbol(const char *name, enum symbol_type ns) +struct symbol *find_symbol(const char *name, enum symbol_type ns) { - unsigned long h = crc32(name) % HASH_BUCKETS; - struct symbol *sym; + unsigned long h = crc32(name) % HASH_BUCKETS; + struct symbol *sym; - for (sym = symtab[h]; sym ; sym = sym->hash_next) - if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0) - break; + for (sym = symtab[h]; sym; sym = sym->hash_next) + if (map_to_ns(sym->type) == map_to_ns(ns) && + strcmp(name, sym->name) == 0) + break; - return sym; + return sym; } -struct symbol * -add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern) +struct symbol *add_symbol(const char *name, enum symbol_type type, + struct string_list *defn, int is_extern) { - unsigned long h = crc32(name) % HASH_BUCKETS; - struct symbol *sym; - - for (sym = symtab[h]; sym ; sym = sym->hash_next) - if (map_to_ns(sym->type) == map_to_ns(type) - && strcmp(name, sym->name) == 0) - { - if (!equal_list(sym->defn, defn)) - error_with_pos("redefinition of %s", name); + unsigned long h = crc32(name) % HASH_BUCKETS; + struct symbol *sym; + + for (sym = symtab[h]; sym; sym = sym->hash_next) { + if (map_to_ns(sym->type) == map_to_ns(type) + && strcmp(name, sym->name) == 0) { + if (!equal_list(sym->defn, defn)) + error_with_pos("redefinition of %s", name); + return sym; + } + } + + sym = xmalloc(sizeof(*sym)); + sym->name = name; + sym->type = type; + sym->defn = defn; + sym->expansion_trail = NULL; + sym->is_extern = is_extern; + + sym->hash_next = symtab[h]; + symtab[h] = sym; + + if (flag_debug) { + fprintf(debugfile, "Defn for %s %s == <", + symbol_type_name[type], name); + if (is_extern) + fputs("extern ", debugfile); + print_list(debugfile, defn); + fputs(">\n", debugfile); + } + + ++nsyms; return sym; - } - - sym = xmalloc(sizeof(*sym)); - sym->name = name; - sym->type = type; - sym->defn = defn; - sym->expansion_trail = NULL; - sym->is_extern = is_extern; - - sym->hash_next = symtab[h]; - symtab[h] = sym; - - if (flag_debug) - { - fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type], name); - if (is_extern) - fputs("extern ", debugfile); - print_list(debugfile, defn); - fputs(">\n", debugfile); - } - - ++nsyms; - return sym; } - /*----------------------------------------------------------------------*/ -inline void -free_node(struct string_list *node) +void free_node(struct string_list *node) { - free(node->string); - free(node); + free(node->string); + free(node); } -void -free_list(struct string_list *s, struct string_list *e) +void free_list(struct string_list *s, struct string_list *e) { - while (s != e) - { - struct string_list *next = s->next; - free_node(s); - s = next; - } + while (s != e) { + struct string_list *next = s->next; + free_node(s); + s = next; + } } -inline struct string_list * -copy_node(struct string_list *node) +struct string_list *copy_node(struct string_list *node) { - struct string_list *newnode; + struct string_list *newnode; - newnode = xmalloc(sizeof(*newnode)); - newnode->string = xstrdup(node->string); - newnode->tag = node->tag; + newnode = xmalloc(sizeof(*newnode)); + newnode->string = xstrdup(node->string); + newnode->tag = node->tag; - return newnode; + return newnode; } -struct string_list * -copy_list(struct string_list *s, struct string_list *e) +static int equal_list(struct string_list *a, struct string_list *b) { - struct string_list *h, *p; - - if (s == e) - return NULL; - - p = h = copy_node(s); - while ((s = s->next) != e) - p = p->next = copy_node(s); - p->next = NULL; - - return h; -} + while (a && b) { + if (a->tag != b->tag || strcmp(a->string, b->string)) + return 0; + a = a->next; + b = b->next; + } -int -equal_list(struct string_list *a, struct string_list *b) -{ - while (a && b) - { - if (a->tag != b->tag || strcmp(a->string, b->string)) - return 0; - a = a->next; - b = b->next; - } - - return !a && !b; + return !a && !b; } -static inline void -print_node(FILE *f, struct string_list *list) +static void print_node(FILE * f, struct string_list *list) { - switch (list->tag) - { - case SYM_STRUCT: - putc('s', f); - goto printit; - case SYM_UNION: - putc('u', f); - goto printit; - case SYM_ENUM: - putc('e', f); - goto printit; - case SYM_TYPEDEF: - putc('t', f); - goto printit; - - printit: - putc('#', f); - case SYM_NORMAL: - fputs(list->string, f); - break; - } -} + switch (list->tag) { + case SYM_STRUCT: + putc('s', f); + goto printit; + case SYM_UNION: + putc('u', f); + goto printit; + case SYM_ENUM: + putc('e', f); + goto printit; + case SYM_TYPEDEF: + putc('t', f); + goto printit; -void -print_list(FILE *f, struct string_list *list) -{ - struct string_list **e, **b; - struct string_list *tmp, **tmp2; - int elem = 1; - - if (list == NULL) - { - fputs("(nil)", f); - return; - } - - tmp = list; - while((tmp = tmp->next) != NULL) - elem++; - - b = alloca(elem * sizeof(*e)); - e = b + elem; - tmp2 = e - 1; - - (*tmp2--) = list; - while((list = list->next) != NULL) - *(tmp2--) = list; - - while (b != e) - { - print_node(f, *b++); - putc(' ', f); - } + printit: + putc('#', f); + case SYM_NORMAL: + fputs(list->string, f); + break; + } } -static unsigned long -expand_and_crc_list(struct string_list *list, unsigned long crc) +static void print_list(FILE * f, struct string_list *list) { - struct string_list **e, **b; - struct string_list *tmp, **tmp2; - int elem = 1; - - if (!list) - return crc; + struct string_list **e, **b; + struct string_list *tmp, **tmp2; + int elem = 1; - tmp = list; - while((tmp = tmp->next) != NULL) - elem++; - - b = alloca(elem * sizeof(*e)); - e = b + elem; - tmp2 = e - 1; + if (list == NULL) { + fputs("(nil)", f); + return; + } - *(tmp2--) = list; - while ((list = list->next) != NULL) - *(tmp2--) = list; + tmp = list; + while ((tmp = tmp->next) != NULL) + elem++; - while (b != e) - { - struct string_list *cur; - struct symbol *subsym; + b = alloca(elem * sizeof(*e)); + e = b + elem; + tmp2 = e - 1; - cur = *(b++); - switch (cur->tag) - { - case SYM_NORMAL: - if (flag_dump_defs) - fprintf(debugfile, "%s ", cur->string); - crc = partial_crc32(cur->string, crc); - crc = partial_crc32_one(' ', crc); - break; + (*tmp2--) = list; + while ((list = list->next) != NULL) + *(tmp2--) = list; - case SYM_TYPEDEF: - subsym = find_symbol(cur->string, cur->tag); - if (subsym->expansion_trail) - { - if (flag_dump_defs) - fprintf(debugfile, "%s ", cur->string); - crc = partial_crc32(cur->string, crc); - crc = partial_crc32_one(' ', crc); - } - else - { - subsym->expansion_trail = expansion_trail; - expansion_trail = subsym; - crc = expand_and_crc_list(subsym->defn, crc); - } - break; + while (b != e) { + print_node(f, *b++); + putc(' ', f); + } +} - case SYM_STRUCT: - case SYM_UNION: - case SYM_ENUM: - subsym = find_symbol(cur->string, cur->tag); - if (!subsym) - { - struct string_list *n, *t = NULL; - - error_with_pos("expand undefined %s %s", - symbol_type_name[cur->tag], cur->string); - - n = xmalloc(sizeof(*n)); - n->string = xstrdup(symbol_type_name[cur->tag]); - n->tag = SYM_NORMAL; - n->next = t; - t = n; - - n = xmalloc(sizeof(*n)); - n->string = xstrdup(cur->string); - n->tag = SYM_NORMAL; - n->next = t; - t = n; - - n = xmalloc(sizeof(*n)); - n->string = xstrdup("{ UNKNOWN }"); - n->tag = SYM_NORMAL; - n->next = t; - - subsym = add_symbol(cur->string, cur->tag, n, 0); - } - if (subsym->expansion_trail) - { - if (flag_dump_defs) - { - fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag], - cur->string); +static unsigned long expand_and_crc_list(struct string_list *list, + unsigned long crc) +{ + struct string_list **e, **b; + struct string_list *tmp, **tmp2; + int elem = 1; + + if (!list) + return crc; + + tmp = list; + while ((tmp = tmp->next) != NULL) + elem++; + + b = alloca(elem * sizeof(*e)); + e = b + elem; + tmp2 = e - 1; + + *(tmp2--) = list; + while ((list = list->next) != NULL) + *(tmp2--) = list; + + while (b != e) { + struct string_list *cur; + struct symbol *subsym; + + cur = *(b++); + switch (cur->tag) { + case SYM_NORMAL: + if (flag_dump_defs) + fprintf(debugfile, "%s ", cur->string); + crc = partial_crc32(cur->string, crc); + crc = partial_crc32_one(' ', crc); + break; + + case SYM_TYPEDEF: + subsym = find_symbol(cur->string, cur->tag); + if (subsym->expansion_trail) { + if (flag_dump_defs) + fprintf(debugfile, "%s ", cur->string); + crc = partial_crc32(cur->string, crc); + crc = partial_crc32_one(' ', crc); + } else { + subsym->expansion_trail = expansion_trail; + expansion_trail = subsym; + crc = expand_and_crc_list(subsym->defn, crc); + } + break; + + case SYM_STRUCT: + case SYM_UNION: + case SYM_ENUM: + subsym = find_symbol(cur->string, cur->tag); + if (!subsym) { + struct string_list *n, *t = NULL; + + error_with_pos("expand undefined %s %s", + symbol_type_name[cur->tag], + cur->string); + + n = xmalloc(sizeof(*n)); + n->string = xstrdup(symbol_type_name[cur->tag]); + n->tag = SYM_NORMAL; + n->next = t; + t = n; + + n = xmalloc(sizeof(*n)); + n->string = xstrdup(cur->string); + n->tag = SYM_NORMAL; + n->next = t; + t = n; + + n = xmalloc(sizeof(*n)); + n->string = xstrdup("{ UNKNOWN }"); + n->tag = SYM_NORMAL; + n->next = t; + + subsym = + add_symbol(cur->string, cur->tag, n, 0); + } + if (subsym->expansion_trail) { + if (flag_dump_defs) { + fprintf(debugfile, "%s %s ", + symbol_type_name[cur->tag], + cur->string); + } + + crc = partial_crc32(symbol_type_name[cur->tag], + crc); + crc = partial_crc32_one(' ', crc); + crc = partial_crc32(cur->string, crc); + crc = partial_crc32_one(' ', crc); + } else { + subsym->expansion_trail = expansion_trail; + expansion_trail = subsym; + crc = expand_and_crc_list(subsym->defn, crc); + } + break; } - - crc = partial_crc32(symbol_type_name[cur->tag], crc); - crc = partial_crc32_one(' ', crc); - crc = partial_crc32(cur->string, crc); - crc = partial_crc32_one(' ', crc); - } - else - { - subsym->expansion_trail = expansion_trail; - expansion_trail = subsym; - crc = expand_and_crc_list(subsym->defn, crc); - } - break; } - } - return crc; + return crc; } -void -export_symbol(const char *name) +void export_symbol(const char *name) { - struct symbol *sym; + struct symbol *sym; - sym = find_symbol(name, SYM_NORMAL); - if (!sym) - error_with_pos("export undefined symbol %s", name); - else - { - unsigned long crc; + sym = find_symbol(name, SYM_NORMAL); + if (!sym) + error_with_pos("export undefined symbol %s", name); + else { + unsigned long crc; - if (flag_dump_defs) - fprintf(debugfile, "Export %s == <", name); + if (flag_dump_defs) + fprintf(debugfile, "Export %s == <", name); - expansion_trail = (struct symbol *)-1L; + expansion_trail = (struct symbol *)-1L; - crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; + crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; - sym = expansion_trail; - while (sym != (struct symbol *)-1L) - { - struct symbol *n = sym->expansion_trail; - sym->expansion_trail = 0; - sym = n; - } + sym = expansion_trail; + while (sym != (struct symbol *)-1L) { + struct symbol *n = sym->expansion_trail; + sym->expansion_trail = 0; + sym = n; + } - if (flag_dump_defs) - fputs(">\n", debugfile); + if (flag_dump_defs) + fputs(">\n", debugfile); - /* Used as a linker script. */ - printf("__crc_%s = 0x%08lx ;\n", name, crc); - } + /* Used as a linker script. */ + printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); + } } /*----------------------------------------------------------------------*/ - -void -error(const char *fmt, ...) -{ - va_list args; - - if (flag_warnings) - { - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - putc('\n', stderr); - - errors++; - } -} - -void -error_with_pos(const char *fmt, ...) +void error_with_pos(const char *fmt, ...) { - va_list args; + va_list args; - if (flag_warnings) - { - fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line); + if (flag_warnings) { + fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", + cur_line); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - putc('\n', stderr); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + putc('\n', stderr); - errors++; - } + errors++; + } } - -void genksyms_usage(void) +static void genksyms_usage(void) { - fputs("Usage:\n" - "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" - "\n" + fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n" #ifdef __GNU_LIBRARY__ " -d, --debug Increment the debug level (repeatable)\n" " -D, --dump Dump expanded symbol defs (for debugging only)\n" @@ -511,81 +451,84 @@ void genksyms_usage(void) " -q, --quiet Disable warnings (default)\n" " -h, --help Print this message\n" " -V, --version Print the release version\n" -#else /* __GNU_LIBRARY__ */ - " -d Increment the debug level (repeatable)\n" - " -D Dump expanded symbol defs (for debugging only)\n" - " -w Enable warnings\n" - " -q Disable warnings (default)\n" - " -h Print this message\n" - " -V Print the release version\n" -#endif /* __GNU_LIBRARY__ */ +#else /* __GNU_LIBRARY__ */ + " -d Increment the debug level (repeatable)\n" + " -D Dump expanded symbol defs (for debugging only)\n" + " -w Enable warnings\n" + " -q Disable warnings (default)\n" + " -h Print this message\n" + " -V Print the release version\n" +#endif /* __GNU_LIBRARY__ */ , stderr); } -int -main(int argc, char **argv) +int main(int argc, char **argv) { - int o; + int o; #ifdef __GNU_LIBRARY__ - struct option long_opts[] = { - {"debug", 0, 0, 'd'}, - {"warnings", 0, 0, 'w'}, - {"quiet", 0, 0, 'q'}, - {"dump", 0, 0, 'D'}, - {"version", 0, 0, 'V'}, - {"help", 0, 0, 'h'}, - {0, 0, 0, 0} - }; - - while ((o = getopt_long(argc, argv, "dwqVDk:p:", - &long_opts[0], NULL)) != EOF) -#else /* __GNU_LIBRARY__ */ - while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF) -#endif /* __GNU_LIBRARY__ */ - switch (o) - { - case 'd': - flag_debug++; - break; - case 'w': - flag_warnings = 1; - break; - case 'q': - flag_warnings = 0; - break; - case 'V': - fputs("genksyms version 2.5.60\n", stderr); - break; - case 'D': - flag_dump_defs = 1; - break; - case 'h': - genksyms_usage(); - return 0; - default: - genksyms_usage(); - return 1; - } - - { - extern int yydebug; - extern int yy_flex_debug; - - yydebug = (flag_debug > 1); - yy_flex_debug = (flag_debug > 2); - - debugfile = stderr; - /* setlinebuf(debugfile); */ - } - - yyparse(); - - if (flag_debug) - { - fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", - nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS); - } - - return errors != 0; + struct option long_opts[] = { + {"arch", 1, 0, 'a'}, + {"debug", 0, 0, 'd'}, + {"warnings", 0, 0, 'w'}, + {"quiet", 0, 0, 'q'}, + {"dump", 0, 0, 'D'}, + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} + }; + + while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", + &long_opts[0], NULL)) != EOF) +#else /* __GNU_LIBRARY__ */ + while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) +#endif /* __GNU_LIBRARY__ */ + switch (o) { + case 'a': + arch = optarg; + break; + case 'd': + flag_debug++; + break; + case 'w': + flag_warnings = 1; + break; + case 'q': + flag_warnings = 0; + break; + case 'V': + fputs("genksyms version 2.5.60\n", stderr); + break; + case 'D': + flag_dump_defs = 1; + break; + case 'h': + genksyms_usage(); + return 0; + default: + genksyms_usage(); + return 1; + } + if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0)) + mod_prefix = "_"; + { + extern int yydebug; + extern int yy_flex_debug; + + yydebug = (flag_debug > 1); + yy_flex_debug = (flag_debug > 2); + + debugfile = stderr; + /* setlinebuf(debugfile); */ + } + + yyparse(); + + if (flag_debug) { + fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", + nsyms, HASH_BUCKETS, + (double)nsyms / (double)HASH_BUCKETS); + } + + return errors != 0; } diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index f09af47ab281..ab6f34f38735 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h @@ -20,74 +20,51 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #ifndef MODUTILS_GENKSYMS_H #define MODUTILS_GENKSYMS_H 1 #include <stdio.h> - -enum symbol_type -{ - SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION +enum symbol_type { + SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION }; -struct string_list -{ - struct string_list *next; - enum symbol_type tag; - char *string; +struct string_list { + struct string_list *next; + enum symbol_type tag; + char *string; }; -struct symbol -{ - struct symbol *hash_next; - const char *name; - enum symbol_type type; - struct string_list *defn; - struct symbol *expansion_trail; - int is_extern; +struct symbol { + struct symbol *hash_next; + const char *name; + enum symbol_type type; + struct string_list *defn; + struct symbol *expansion_trail; + int is_extern; }; typedef struct string_list **yystype; #define YYSTYPE yystype -extern FILE *outfile, *debugfile; - extern int cur_line; -extern char *cur_filename, *output_directory; - -extern int flag_debug, flag_dump_defs, flag_warnings; -extern int checksum_version, kernel_version; - -extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents; -extern struct string_list *current_list, *next_list; - +extern char *cur_filename; struct symbol *find_symbol(const char *name, enum symbol_type ns); struct symbol *add_symbol(const char *name, enum symbol_type type, - struct string_list *defn, int is_extern); + struct string_list *defn, int is_extern); void export_symbol(const char *); -struct string_list *reset_list(void); -void free_list(struct string_list *s, struct string_list *e); void free_node(struct string_list *list); +void free_list(struct string_list *s, struct string_list *e); struct string_list *copy_node(struct string_list *); -struct string_list *copy_list(struct string_list *s, struct string_list *e); -int equal_list(struct string_list *a, struct string_list *b); -void print_list(FILE *, struct string_list *list); int yylex(void); int yyparse(void); void error_with_pos(const char *, ...); -#define version(a,b,c) ((a << 16) | (b << 8) | (c)) - /*----------------------------------------------------------------------*/ - -#define MODUTILS_VERSION "<in-kernel>" - #define xmalloc(size) ({ void *__ptr = malloc(size); \ if(!__ptr && size != 0) { \ fprintf(stderr, "out of memory\n"); \ @@ -101,4 +78,4 @@ void error_with_pos(const char *, ...); } \ __str; }) -#endif /* genksyms.h */ +#endif /* genksyms.h */ diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index d591578bd3b2..22d281c6ec24 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -124,6 +124,11 @@ static int read_symbol(FILE *in, struct sym_entry *s) * compressed together */ s->len = strlen(str) + 1; s->sym = malloc(s->len + 1); + if (!s->sym) { + fprintf(stderr, "kallsyms failure: " + "unable to allocate required amount of memory\n"); + exit(EXIT_FAILURE); + } strcpy((char *)s->sym + 1, str); s->sym[0] = stype; @@ -272,7 +277,12 @@ static void write_src(void) /* table of offset markers, that give the offset in the compressed stream * every 256 symbols */ - markers = (unsigned int *) malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); + markers = malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); + if (!markers) { + fprintf(stderr, "kallsyms failure: " + "unable to allocate required memory\n"); + exit(EXIT_FAILURE); + } output_label("kallsyms_names"); off = 0; diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 5760e057ecba..e6499db4c8cc 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -2,7 +2,7 @@ # Kernel configuration targets # These targets are used from top-level makefile -.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config +PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config xconfig: $(obj)/qconf $< arch/$(ARCH)/Kconfig @@ -42,7 +42,7 @@ update-po-config: $(obj)/kxgettext $(Q)rm -f arch/um/Kconfig_arch $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot -.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig +PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig randconfig: $(obj)/conf $< -r arch/$(ARCH)/Kconfig @@ -78,7 +78,7 @@ help: @echo ' defconfig - New config with default answer to all options' @echo ' allmodconfig - New config selecting modules when possible' @echo ' allyesconfig - New config where all options are accepted with yes' - @echo ' allnoconfig - New minimal config' + @echo ' allnoconfig - New config where all options are answered with no' # =========================================================================== # Shared Makefile for the various kconfig executables: diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index b0cbbe2e41bb..1b8882ddbc74 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -374,6 +374,7 @@ int conf_write(const char *name) out_h = fopen(".tmpconfig.h", "w"); if (!out_h) return 1; + file_write_dep(NULL); } sym = sym_lookup("KERNELVERSION", 0); sym_calc_value(sym); @@ -512,7 +513,6 @@ int conf_write(const char *name) if (out_h) { fclose(out_h); rename(".tmpconfig.h", "include/linux/autoconf.h"); - file_write_dep(NULL); } if (!name || basename != conf_def_filename) { if (!name) diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile index bbf4887cff74..a8b026326247 100644 --- a/scripts/kconfig/lxdialog/Makefile +++ b/scripts/kconfig/lxdialog/Makefile @@ -7,10 +7,10 @@ check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh # we really need to do so. (Do not call gcc as part of make mrproper) HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) - -HOST_EXTRACFLAGS += -DLOCALE -.PHONY: dochecklxdialog +HOST_EXTRACFLAGS += -DLOCALE + +PHONY += dochecklxdialog $(obj)/dochecklxdialog: $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) diff --git a/scripts/mkmakefile b/scripts/mkmakefile index c4d621b30d0d..a22cbedd3b3e 100644 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile @@ -21,11 +21,13 @@ KERNELOUTPUT := $2 MAKEFLAGS += --no-print-directory +.PHONY: all \$(MAKECMDGOALS) + all: \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) -%:: - \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ +Makefile:; +\$(filter-out all Makefile,\$(MAKECMDGOALS)) %/: + \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ EOF - diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index c164b230ad6f..84e21201f3c0 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -34,7 +34,7 @@ typedef uint16_t __u16; typedef unsigned char __u8; /* Big exception to the "don't include kernel headers into userspace, which - * even potentially has different endianness and word sizes, since + * even potentially has different endianness and word sizes, since * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" #include "../../include/linux/input.h" @@ -153,8 +153,8 @@ static void do_usb_table(void *symval, unsigned long size, const unsigned long id_size = sizeof(struct usb_device_id); if (size % id_size || size < id_size) { - fprintf(stderr, "*** Warning: %s ids %lu bad size " - "(each on %lu)\n", mod->name, size, id_size); + warn("%s ids %lu bad size " + "(each on %lu)\n", mod->name, size, id_size); } /* Leave last one: it's the terminator. */ size -= id_size; @@ -217,9 +217,8 @@ static int do_pci_entry(const char *filename, if ((baseclass_mask != 0 && baseclass_mask != 0xFF) || (subclass_mask != 0 && subclass_mask != 0xFF) || (interface_mask != 0 && interface_mask != 0xFF)) { - fprintf(stderr, - "*** Warning: Can't handle masks in %s:%04X\n", - filename, id->class_mask); + warn("Can't handle masks in %s:%04X\n", + filename, id->class_mask); return 0; } @@ -229,7 +228,7 @@ static int do_pci_entry(const char *filename, return 1; } -/* looks like: "ccw:tNmNdtNdmN" */ +/* looks like: "ccw:tNmNdtNdmN" */ static int do_ccw_entry(const char *filename, struct ccw_device_id *id, char *alias) { @@ -445,8 +444,8 @@ static void do_table(void *symval, unsigned long size, int (*do_entry)(const char *, void *entry, char *alias) = function; if (size % id_size || size < id_size) { - fprintf(stderr, "*** Warning: %s ids %lu bad size " - "(each on %lu)\n", mod->name, size, id_size); + warn("%s ids %lu bad size " + "(each on %lu)\n", mod->name, size, id_size); } /* Leave last one: it's the terminator. */ size -= id_size; diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index de2aabf89fb3..3c92c83733f4 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -6,7 +6,7 @@ int main(int argc, char **argv) { - unsigned char ei[EI_NIDENT]; + unsigned char ei[EI_NIDENT]; union { short s; char c[2]; } endian_test; if (argc != 2) { @@ -57,7 +57,7 @@ main(int argc, char **argv) if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); - else + else printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); return 0; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b8b2a560b26b..0b92ddff26fd 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2,7 +2,7 @@ * * Copyright 2003 Kai Germaschewski * Copyright 2002-2004 Rusty Russell, IBM Corporation - * + * Copyright 2006 Sam Ravnborg * Based in part on module-init-tools/depmod.c,file2alias * * This software may be used and distributed according to the terms @@ -20,9 +20,10 @@ int modversions = 0; int have_vmlinux = 0; /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ static int all_versions = 0; +/* If we are modposting external module set to 1 */ +static int external_module = 0; -void -fatal(const char *fmt, ...) +void fatal(const char *fmt, ...) { va_list arglist; @@ -35,8 +36,7 @@ fatal(const char *fmt, ...) exit(1); } -void -warn(const char *fmt, ...) +void warn(const char *fmt, ...) { va_list arglist; @@ -47,6 +47,18 @@ warn(const char *fmt, ...) va_end(arglist); } +static int is_vmlinux(const char *modname) +{ + const char *myname; + + if ((myname = strrchr(modname, '/'))) + myname++; + else + myname = modname; + + return strcmp(myname, "vmlinux") == 0; +} + void *do_nofail(void *ptr, const char *expr) { if (!ptr) { @@ -59,8 +71,7 @@ void *do_nofail(void *ptr, const char *expr) static struct module *modules; -struct module * -find_module(char *modname) +static struct module *find_module(char *modname) { struct module *mod; @@ -70,12 +81,11 @@ find_module(char *modname) return mod; } -struct module * -new_module(char *modname) +static struct module *new_module(char *modname) { struct module *mod; char *p, *s; - + mod = NOFAIL(malloc(sizeof(*mod))); memset(mod, 0, sizeof(*mod)); p = NOFAIL(strdup(modname)); @@ -104,6 +114,10 @@ struct symbol { unsigned int crc; int crc_valid; unsigned int weak:1; + unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ + unsigned int kernel:1; /* 1 if symbol is from kernel + * (only for external modules) **/ + unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ char name[0]; }; @@ -122,11 +136,12 @@ static inline unsigned int tdb_hash(const char *name) return (1103515243 * value + 12345); } -/* Allocate a new symbols for use in the hash of exported symbols or - * the list of unresolved symbols per module */ - -struct symbol * -alloc_symbol(const char *name, unsigned int weak, struct symbol *next) +/** + * Allocate a new symbols for use in the hash of exported symbols or + * the list of unresolved symbols per module + **/ +static struct symbol *alloc_symbol(const char *name, unsigned int weak, + struct symbol *next) { struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); @@ -138,9 +153,7 @@ alloc_symbol(const char *name, unsigned int weak, struct symbol *next) } /* For the hash of exported symbols */ - -void -new_symbol(const char *name, struct module *module, unsigned int *crc) +static struct symbol *new_symbol(const char *name, struct module *module) { unsigned int hash; struct symbol *new; @@ -148,14 +161,10 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) hash = tdb_hash(name) % SYMBOL_HASH_SIZE; new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); new->module = module; - if (crc) { - new->crc = *crc; - new->crc_valid = 1; - } + return new; } -struct symbol * -find_symbol(const char *name) +static struct symbol *find_symbol(const char *name) { struct symbol *s; @@ -170,25 +179,42 @@ find_symbol(const char *name) return NULL; } -/* Add an exported symbol - it may have already been added without a - * CRC, in this case just update the CRC */ -void -add_exported_symbol(const char *name, struct module *module, unsigned int *crc) +/** + * Add an exported symbol - it may have already been added without a + * CRC, in this case just update the CRC + **/ +static struct symbol *sym_add_exported(const char *name, struct module *mod) { struct symbol *s = find_symbol(name); if (!s) { - new_symbol(name, module, crc); - return; - } - if (crc) { - s->crc = *crc; - s->crc_valid = 1; + s = new_symbol(name, mod); + } else { + if (!s->preloaded) { + warn("%s: '%s' exported twice. Previous export " + "was in %s%s\n", mod->name, name, + s->module->name, + is_vmlinux(s->module->name) ?"":".ko"); + } } + s->preloaded = 0; + s->vmlinux = is_vmlinux(mod->name); + s->kernel = 0; + return s; +} + +static void sym_update_crc(const char *name, struct module *mod, + unsigned int crc) +{ + struct symbol *s = find_symbol(name); + + if (!s) + s = new_symbol(name, mod); + s->crc = crc; + s->crc_valid = 1; } -void * -grab_file(const char *filename, unsigned long *size) +void *grab_file(const char *filename, unsigned long *size) { struct stat st; void *map; @@ -207,13 +233,12 @@ grab_file(const char *filename, unsigned long *size) return map; } -/* - Return a copy of the next line in a mmap'ed file. - spaces in the beginning of the line is trimmed away. - Return a pointer to a static buffer. -*/ -char* -get_next_line(unsigned long *pos, void *file, unsigned long size) +/** + * Return a copy of the next line in a mmap'ed file. + * spaces in the beginning of the line is trimmed away. + * Return a pointer to a static buffer. + **/ +char* get_next_line(unsigned long *pos, void *file, unsigned long size) { static char line[4096]; int skip = 1; @@ -243,14 +268,12 @@ get_next_line(unsigned long *pos, void *file, unsigned long size) return NULL; } -void -release_file(void *file, unsigned long size) +void release_file(void *file, unsigned long size) { munmap(file, size); } -void -parse_elf(struct elf_info *info, const char *filename) +static void parse_elf(struct elf_info *info, const char *filename) { unsigned int i; Elf_Ehdr *hdr = info->hdr; @@ -297,14 +320,13 @@ parse_elf(struct elf_info *info, const char *filename) continue; info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; - info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset + info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset + sechdrs[i].sh_size; - info->strtab = (void *)hdr + + info->strtab = (void *)hdr + sechdrs[sechdrs[i].sh_link].sh_offset; } if (!info->symtab_start) { - fprintf(stderr, "modpost: %s no symtab?\n", filename); - abort(); + fatal("%s has no symtab?\n", filename); } /* Fix endianness in symbols */ for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { @@ -316,36 +338,31 @@ parse_elf(struct elf_info *info, const char *filename) return; truncated: - fprintf(stderr, "modpost: %s is truncated.\n", filename); - abort(); + fatal("%s is truncated.\n", filename); } -void -parse_elf_finish(struct elf_info *info) +static void parse_elf_finish(struct elf_info *info) { release_file(info->hdr, info->size); } -#define CRC_PFX "__crc_" -#define KSYMTAB_PFX "__ksymtab_" +#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" +#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" -void -handle_modversions(struct module *mod, struct elf_info *info, - Elf_Sym *sym, const char *symname) +static void handle_modversions(struct module *mod, struct elf_info *info, + Elf_Sym *sym, const char *symname) { unsigned int crc; switch (sym->st_shndx) { case SHN_COMMON: - fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n", - symname, mod->name); + warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); break; case SHN_ABS: /* CRC'd symbol */ if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { crc = (unsigned int) sym->st_value; - add_exported_symbol(symname + strlen(CRC_PFX), - mod, &crc); + sym_update_crc(symname + strlen(CRC_PFX), mod, crc); } break; case SHN_UNDEF: @@ -370,15 +387,15 @@ handle_modversions(struct module *mod, struct elf_info *info, /* Ignore register directives. */ if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) break; - if (symname[0] == '.') { - char *munged = strdup(symname); - munged[0] = '_'; - munged[1] = toupper(munged[1]); - symname = munged; - } + if (symname[0] == '.') { + char *munged = strdup(symname); + munged[0] = '_'; + munged[1] = toupper(munged[1]); + symname = munged; + } } #endif - + if (memcmp(symname, MODULE_SYMBOL_PREFIX, strlen(MODULE_SYMBOL_PREFIX)) == 0) mod->unres = alloc_symbol(symname + @@ -389,8 +406,7 @@ handle_modversions(struct module *mod, struct elf_info *info, default: /* All exported symbols */ if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { - add_exported_symbol(symname + strlen(KSYMTAB_PFX), - mod, NULL); + sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); } if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) mod->has_init = 1; @@ -400,20 +416,9 @@ handle_modversions(struct module *mod, struct elf_info *info, } } -int -is_vmlinux(const char *modname) -{ - const char *myname; - - if ((myname = strrchr(modname, '/'))) - myname++; - else - myname = modname; - - return strcmp(myname, "vmlinux") == 0; -} - -/* Parse tag=value strings from .modinfo section */ +/** + * Parse tag=value strings from .modinfo section + **/ static char *next_string(char *string, unsigned long *secsize) { /* Skip non-zero chars */ @@ -446,8 +451,418 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, return NULL; } -void -read_symbols(char *modname) +/** + * Test if string s ends in string sub + * return 0 if match + **/ +static int strrcmp(const char *s, const char *sub) +{ + int slen, sublen; + + if (!s || !sub) + return 1; + + slen = strlen(s); + sublen = strlen(sub); + + if ((slen == 0) || (sublen == 0)) + return 1; + + if (sublen > slen) + return 1; + + return memcmp(s + slen - sublen, sub, sublen); +} + +/** + * Whitelist to allow certain references to pass with no warning. + * Pattern 1: + * If a module parameter is declared __initdata and permissions=0 + * then this is legal despite the warning generated. + * We cannot see value of permissions here, so just ignore + * this pattern. + * The pattern is identified by: + * tosec = .init.data + * fromsec = .data* + * atsym =__param* + * + * Pattern 2: + * Many drivers utilise a *_driver container with references to + * add, remove, probe functions etc. + * These functions may often be marked __init and we do not want to + * warn here. + * the pattern is identified by: + * tosec = .init.text | .exit.text + * fromsec = .data + * atsym = *_driver, *_ops, *_probe, *probe_one + **/ +static int secref_whitelist(const char *tosec, const char *fromsec, + const char *atsym) +{ + int f1 = 1, f2 = 1; + const char **s; + const char *pat2sym[] = { + "_driver", + "_ops", + "_probe", + "_probe_one", + NULL + }; + + /* Check for pattern 1 */ + if (strcmp(tosec, ".init.data") != 0) + f1 = 0; + if (strncmp(fromsec, ".data", strlen(".data")) != 0) + f1 = 0; + if (strncmp(atsym, "__param", strlen("__param")) != 0) + f1 = 0; + + if (f1) + return f1; + + /* Check for pattern 2 */ + if ((strcmp(tosec, ".init.text") != 0) && + (strcmp(tosec, ".exit.text") != 0)) + f2 = 0; + if (strcmp(fromsec, ".data") != 0) + f2 = 0; + + for (s = pat2sym; *s; s++) + if (strrcmp(atsym, *s) == 0) + f1 = 1; + + return f1 && f2; +} + +/** + * Find symbol based on relocation record info. + * In some cases the symbol supplied is a valid symbol so + * return refsym. If st_name != 0 we assume this is a valid symbol. + * In other cases the symbol needs to be looked up in the symbol table + * based on section and address. + * **/ +static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, + Elf_Sym *relsym) +{ + Elf_Sym *sym; + + if (relsym->st_name != 0) + return relsym; + for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { + if (sym->st_shndx != relsym->st_shndx) + continue; + if (sym->st_value == addr) + return sym; + } + return NULL; +} + +/* + * Find symbols before or equal addr and after addr - in the section sec. + * If we find two symbols with equal offset prefer one with a valid name. + * The ELF format may have a better way to detect what type of symbol + * it is, but this works for now. + **/ +static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, + const char *sec, + Elf_Sym **before, Elf_Sym **after) +{ + Elf_Sym *sym; + Elf_Ehdr *hdr = elf->hdr; + Elf_Addr beforediff = ~0; + Elf_Addr afterdiff = ~0; + const char *secstrings = (void *)hdr + + elf->sechdrs[hdr->e_shstrndx].sh_offset; + + *before = NULL; + *after = NULL; + + for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { + const char *symsec; + + if (sym->st_shndx >= SHN_LORESERVE) + continue; + symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name; + if (strcmp(symsec, sec) != 0) + continue; + if (sym->st_value <= addr) { + if ((addr - sym->st_value) < beforediff) { + beforediff = addr - sym->st_value; + *before = sym; + } + else if ((addr - sym->st_value) == beforediff) { + /* equal offset, valid name? */ + const char *name = elf->strtab + sym->st_name; + if (name && strlen(name)) + *before = sym; + } + } + else + { + if ((sym->st_value - addr) < afterdiff) { + afterdiff = sym->st_value - addr; + *after = sym; + } + else if ((sym->st_value - addr) == afterdiff) { + /* equal offset, valid name? */ + const char *name = elf->strtab + sym->st_name; + if (name && strlen(name)) + *after = sym; + } + } + } +} + +/** + * Print a warning about a section mismatch. + * Try to find symbols near it so user can find it. + * Check whitelist before warning - it may be a false positive. + **/ +static void warn_sec_mismatch(const char *modname, const char *fromsec, + struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) +{ + const char *refsymname = ""; + Elf_Sym *before, *after; + Elf_Sym *refsym; + Elf_Ehdr *hdr = elf->hdr; + Elf_Shdr *sechdrs = elf->sechdrs; + const char *secstrings = (void *)hdr + + sechdrs[hdr->e_shstrndx].sh_offset; + const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name; + + find_symbols_between(elf, r.r_offset, fromsec, &before, &after); + + refsym = find_elf_symbol(elf, r.r_addend, sym); + if (refsym && strlen(elf->strtab + refsym->st_name)) + refsymname = elf->strtab + refsym->st_name; + + /* check whitelist - we may ignore it */ + if (before && + secref_whitelist(secname, fromsec, elf->strtab + before->st_name)) + return; + + if (before && after) { + warn("%s - Section mismatch: reference to %s:%s from %s " + "between '%s' (at offset 0x%llx) and '%s'\n", + modname, secname, refsymname, fromsec, + elf->strtab + before->st_name, + (long long)r.r_offset, + elf->strtab + after->st_name); + } else if (before) { + warn("%s - Section mismatch: reference to %s:%s from %s " + "after '%s' (at offset 0x%llx)\n", + modname, secname, refsymname, fromsec, + elf->strtab + before->st_name, + (long long)r.r_offset); + } else if (after) { + warn("%s - Section mismatch: reference to %s:%s from %s " + "before '%s' (at offset -0x%llx)\n", + modname, secname, refsymname, fromsec, + elf->strtab + before->st_name, + (long long)r.r_offset); + } else { + warn("%s - Section mismatch: reference to %s:%s from %s " + "(offset 0x%llx)\n", + modname, secname, fromsec, refsymname, + (long long)r.r_offset); + } +} + +/** + * A module includes a number of sections that are discarded + * either when loaded or when used as built-in. + * For loaded modules all functions marked __init and all data + * marked __initdata will be discarded when the module has been intialized. + * Likewise for modules used built-in the sections marked __exit + * are discarded because __exit marked function are supposed to be called + * only when a moduel is unloaded which never happes for built-in modules. + * The check_sec_ref() function traverses all relocation records + * to find all references to a section that reference a section that will + * be discarded and warns about it. + **/ +static void check_sec_ref(struct module *mod, const char *modname, + struct elf_info *elf, + int section(const char*), + int section_ref_ok(const char *)) +{ + int i; + Elf_Sym *sym; + Elf_Ehdr *hdr = elf->hdr; + Elf_Shdr *sechdrs = elf->sechdrs; + const char *secstrings = (void *)hdr + + sechdrs[hdr->e_shstrndx].sh_offset; + + /* Walk through all sections */ + for (i = 0; i < hdr->e_shnum; i++) { + Elf_Rela *rela; + Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; + Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; + const char *name = secstrings + sechdrs[i].sh_name + + strlen(".rela"); + /* We want to process only relocation sections and not .init */ + if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA)) + continue; + + for (rela = start; rela < stop; rela++) { + Elf_Rela r; + const char *secname; + r.r_offset = TO_NATIVE(rela->r_offset); + r.r_info = TO_NATIVE(rela->r_info); + r.r_addend = TO_NATIVE(rela->r_addend); + sym = elf->symtab_start + ELF_R_SYM(r.r_info); + /* Skip special sections */ + if (sym->st_shndx >= SHN_LORESERVE) + continue; + + secname = secstrings + sechdrs[sym->st_shndx].sh_name; + if (section(secname)) + warn_sec_mismatch(modname, name, elf, sym, r); + } + } +} + +/** + * Functions used only during module init is marked __init and is stored in + * a .init.text section. Likewise data is marked __initdata and stored in + * a .init.data section. + * If this section is one of these sections return 1 + * See include/linux/init.h for the details + **/ +static int init_section(const char *name) +{ + if (strcmp(name, ".init") == 0) + return 1; + if (strncmp(name, ".init.", strlen(".init.")) == 0) + return 1; + return 0; +} + +/** + * Identify sections from which references to a .init section is OK. + * + * Unfortunately references to read only data that referenced .init + * sections had to be excluded. Almost all of these are false + * positives, they are created by gcc. The downside of excluding rodata + * is that there really are some user references from rodata to + * init code, e.g. drivers/video/vgacon.c: + * + * const struct consw vga_con = { + * con_startup: vgacon_startup, + * + * where vgacon_startup is __init. If you want to wade through the false + * positives, take out the check for rodata. + **/ +static int init_section_ref_ok(const char *name) +{ + const char **s; + /* Absolute section names */ + const char *namelist1[] = { + ".init", + ".opd", /* see comment [OPD] at exit_section_ref_ok() */ + ".toc1", /* used by ppc64 */ + ".stab", + ".rodata", + ".text.lock", + "__bug_table", /* used by powerpc for BUG() */ + ".pci_fixup_header", + ".pci_fixup_final", + ".pdr", + "__param", + NULL + }; + /* Start of section names */ + const char *namelist2[] = { + ".init.", + ".altinstructions", + ".eh_frame", + ".debug", + NULL + }; + /* part of section name */ + const char *namelist3 [] = { + ".unwind", /* sample: IA_64.unwind.init.text */ + NULL + }; + + for (s = namelist1; *s; s++) + if (strcmp(*s, name) == 0) + return 1; + for (s = namelist2; *s; s++) + if (strncmp(*s, name, strlen(*s)) == 0) + return 1; + for (s = namelist3; *s; s++) + if (strstr(name, *s) != NULL) + return 1; + return 0; +} + +/* + * Functions used only during module exit is marked __exit and is stored in + * a .exit.text section. Likewise data is marked __exitdata and stored in + * a .exit.data section. + * If this section is one of these sections return 1 + * See include/linux/init.h for the details + **/ +static int exit_section(const char *name) +{ + if (strcmp(name, ".exit.text") == 0) + return 1; + if (strcmp(name, ".exit.data") == 0) + return 1; + return 0; + +} + +/* + * Identify sections from which references to a .exit section is OK. + * + * [OPD] Keith Ownes <kaos@sgi.com> commented: + * For our future {in}sanity, add a comment that this is the ppc .opd + * section, not the ia64 .opd section. + * ia64 .opd should not point to discarded sections. + **/ +static int exit_section_ref_ok(const char *name) +{ + const char **s; + /* Absolute section names */ + const char *namelist1[] = { + ".exit.text", + ".exit.data", + ".init.text", + ".opd", /* See comment [OPD] */ + ".toc1", /* used by ppc64 */ + ".altinstructions", + ".pdr", + "__bug_table", /* used by powerpc for BUG() */ + ".exitcall.exit", + ".eh_frame", + ".stab", + NULL + }; + /* Start of section names */ + const char *namelist2[] = { + ".debug", + NULL + }; + /* part of section name */ + const char *namelist3 [] = { + ".unwind", /* Sample: IA_64.unwind.exit.text */ + NULL + }; + + for (s = namelist1; *s; s++) + if (strcmp(*s, name) == 0) + return 1; + for (s = namelist2; *s; s++) + if (strncmp(*s, name, strlen(*s)) == 0) + return 1; + for (s = namelist3; *s; s++) + if (strstr(name, *s) != NULL) + return 1; + return 0; +} + +static void read_symbols(char *modname) { const char *symname; char *version; @@ -462,9 +877,7 @@ read_symbols(char *modname) /* When there's no vmlinux, don't print warnings about * unresolved symbols (since there'll be too many ;) */ if (is_vmlinux(modname)) { - unsigned int fake_crc = 0; have_vmlinux = 1; - add_exported_symbol("struct_module", mod, &fake_crc); mod->skip = 1; } @@ -474,6 +887,8 @@ read_symbols(char *modname) handle_modversions(mod, &info, sym, symname); handle_moddevtable(mod, &info, sym, symname); } + check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); + check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); version = get_modinfo(info.modinfo, info.modinfo_len, "version"); if (version) @@ -499,21 +914,20 @@ read_symbols(char *modname) * following helper, then compare to the file on disk and * only update the later if anything changed */ -void __attribute__((format(printf, 2, 3))) -buf_printf(struct buffer *buf, const char *fmt, ...) +void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, + const char *fmt, ...) { char tmp[SZ]; int len; va_list ap; - + va_start(ap, fmt); len = vsnprintf(tmp, SZ, fmt, ap); buf_write(buf, tmp, len); va_end(ap); } -void -buf_write(struct buffer *buf, const char *s, int len) +void buf_write(struct buffer *buf, const char *s, int len) { if (buf->size - buf->pos < len) { buf->size += len + SZ; @@ -523,10 +937,10 @@ buf_write(struct buffer *buf, const char *s, int len) buf->pos += len; } -/* Header for the generated file */ - -void -add_header(struct buffer *b, struct module *mod) +/** + * Header for the generated file + **/ +static void add_header(struct buffer *b, struct module *mod) { buf_printf(b, "#include <linux/module.h>\n"); buf_printf(b, "#include <linux/vermagic.h>\n"); @@ -546,10 +960,10 @@ add_header(struct buffer *b, struct module *mod) buf_printf(b, "};\n"); } -/* Record CRCs for unresolved symbols */ - -void -add_versions(struct buffer *b, struct module *mod) +/** + * Record CRCs for unresolved symbols + **/ +static void add_versions(struct buffer *b, struct module *mod) { struct symbol *s, *exp; @@ -557,8 +971,8 @@ add_versions(struct buffer *b, struct module *mod) exp = find_symbol(s->name); if (!exp || exp->module == mod) { if (have_vmlinux && !s->weak) - fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " - "undefined!\n", s->name, mod->name); + warn("\"%s\" [%s.ko] undefined!\n", + s->name, mod->name); continue; } s->module = exp->module; @@ -579,8 +993,7 @@ add_versions(struct buffer *b, struct module *mod) continue; } if (!s->crc_valid) { - fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " - "has no CRC!\n", + warn("\"%s\" [%s.ko] has no CRC!\n", s->name, mod->name); continue; } @@ -590,8 +1003,8 @@ add_versions(struct buffer *b, struct module *mod) buf_printf(b, "};\n"); } -void -add_depends(struct buffer *b, struct module *mod, struct module *modules) +static void add_depends(struct buffer *b, struct module *mod, + struct module *modules) { struct symbol *s; struct module *m; @@ -621,8 +1034,7 @@ add_depends(struct buffer *b, struct module *mod, struct module *modules) buf_printf(b, "\";\n"); } -void -add_srcversion(struct buffer *b, struct module *mod) +static void add_srcversion(struct buffer *b, struct module *mod) { if (mod->srcversion[0]) { buf_printf(b, "\n"); @@ -631,8 +1043,7 @@ add_srcversion(struct buffer *b, struct module *mod) } } -void -write_if_changed(struct buffer *b, const char *fname) +static void write_if_changed(struct buffer *b, const char *fname) { char *tmp; FILE *file; @@ -676,8 +1087,7 @@ write_if_changed(struct buffer *b, const char *fname) fclose(file); } -void -read_dump(const char *fname) +static void read_dump(const char *fname, unsigned int kernel) { unsigned long size, pos = 0; void *file = grab_file(fname, &size); @@ -691,6 +1101,7 @@ read_dump(const char *fname) char *symname, *modname, *d; unsigned int crc; struct module *mod; + struct symbol *s; if (!(symname = strchr(line, '\t'))) goto fail; @@ -711,15 +1122,30 @@ read_dump(const char *fname) mod = new_module(NOFAIL(strdup(modname))); mod->skip = 1; } - add_exported_symbol(symname, mod, &crc); + s = sym_add_exported(symname, mod); + s->kernel = kernel; + s->preloaded = 1; + sym_update_crc(symname, mod, crc); } return; fail: fatal("parse error in symbol dump file\n"); } -void -write_dump(const char *fname) +/* For normal builds always dump all symbols. + * For external modules only dump symbols + * that are not read from kernel Module.symvers. + **/ +static int dump_sym(struct symbol *sym) +{ + if (!external_module) + return 1; + if (sym->vmlinux || sym->kernel) + return 0; + return 1; +} + +static void write_dump(const char *fname) { struct buffer buf = { }; struct symbol *symbol; @@ -728,34 +1154,33 @@ write_dump(const char *fname) for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { symbol = symbolhash[n]; while (symbol) { - symbol = symbol->next; - } - } - - for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { - symbol = symbolhash[n]; - while (symbol) { - buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc, - symbol->name, symbol->module->name); + if (dump_sym(symbol)) + buf_printf(&buf, "0x%08x\t%s\t%s\n", + symbol->crc, symbol->name, + symbol->module->name); symbol = symbol->next; } } write_if_changed(&buf, fname); } -int -main(int argc, char **argv) +int main(int argc, char **argv) { struct module *mod; struct buffer buf = { }; char fname[SZ]; - char *dump_read = NULL, *dump_write = NULL; + char *kernel_read = NULL, *module_read = NULL; + char *dump_write = NULL; int opt; - while ((opt = getopt(argc, argv, "i:mo:a")) != -1) { + while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) { switch(opt) { case 'i': - dump_read = optarg; + kernel_read = optarg; + break; + case 'I': + module_read = optarg; + external_module = 1; break; case 'm': modversions = 1; @@ -771,8 +1196,10 @@ main(int argc, char **argv) } } - if (dump_read) - read_dump(dump_read); + if (kernel_read) + read_dump(kernel_read, 1); + if (module_read) + read_dump(module_read, 0); while (optind < argc) { read_symbols(argv[optind++]); @@ -799,4 +1226,3 @@ main(int argc, char **argv) return 0; } - diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 7334d839145d..b14255c72a37 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -13,20 +13,30 @@ #if KERNEL_ELFCLASS == ELFCLASS32 -#define Elf_Ehdr Elf32_Ehdr -#define Elf_Shdr Elf32_Shdr +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym +#define Elf_Addr Elf32_Addr +#define Elf_Section Elf32_Section #define ELF_ST_BIND ELF32_ST_BIND #define ELF_ST_TYPE ELF32_ST_TYPE +#define Elf_Rela Elf32_Rela +#define ELF_R_SYM ELF32_R_SYM +#define ELF_R_TYPE ELF32_R_TYPE #else -#define Elf_Ehdr Elf64_Ehdr -#define Elf_Shdr Elf64_Shdr +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym +#define Elf_Addr Elf64_Addr +#define Elf_Section Elf64_Section #define ELF_ST_BIND ELF64_ST_BIND #define ELF_ST_TYPE ELF64_ST_TYPE +#define Elf_Rela Elf64_Rela +#define ELF_R_SYM ELF64_R_SYM +#define ELF_R_TYPE ELF64_R_TYPE #endif #if KERNEL_ELFDATA != HOST_ELFDATA @@ -91,17 +101,22 @@ struct elf_info { unsigned int modinfo_len; }; +/* file2alias.c */ void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); - void add_moddevtable(struct buffer *buf, struct module *mod); +/* sumversion.c */ void maybe_frob_rcs_version(const char *modfilename, char *version, void *modinfo, unsigned long modinfo_offset); void get_src_version(const char *modname, char sum[], unsigned sumlen); +/* from modpost.c */ void *grab_file(const char *filename, unsigned long *size); char* get_next_line(unsigned long *pos, void *file, unsigned long size); void release_file(void *file, unsigned long size); + +void fatal(const char *fmt, ...); +void warn(const char *fmt, ...); diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 43271a1ca01e..8a2875689e4d 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -316,8 +316,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) file = grab_file(cmd, &flen); if (!file) { - fprintf(stderr, "Warning: could not find %s for %s\n", - cmd, objfile); + warn("could not find %s for %s\n", cmd, objfile); goto out; } @@ -355,9 +354,8 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) /* Check if this file is in same dir as objfile */ if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { if (!parse_file(line, md)) { - fprintf(stderr, - "Warning: could not open %s: %s\n", - line, strerror(errno)); + warn("could not open %s: %s\n", + line, strerror(errno)); goto out_file; } @@ -383,8 +381,11 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) struct md4_ctx md; char *sources, *end, *fname; const char *basename; - char filelist[strlen(getenv("MODVERDIR")) + strlen("/") + - strlen(modname) - strlen(".o") + strlen(".mod") + 1 ]; + char filelist[PATH_MAX + 1]; + char *modverdir = getenv("MODVERDIR"); + + if (!modverdir) + modverdir = "."; /* Source files for module are in .tmp_versions/modname.mod, after the first line. */ @@ -392,28 +393,25 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) basename = strrchr(modname, '/') + 1; else basename = modname; - sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"), + sprintf(filelist, "%s/%.*s.mod", modverdir, (int) strlen(basename) - 2, basename); file = grab_file(filelist, &len); if (!file) { - fprintf(stderr, "Warning: could not find versions for %s\n", - filelist); + warn("could not find versions for %s\n", filelist); return; } sources = strchr(file, '\n'); if (!sources) { - fprintf(stderr, "Warning: malformed versions file for %s\n", - modname); + warn("malformed versions file for %s\n", modname); goto release; } sources++; end = strchr(sources, '\n'); if (!end) { - fprintf(stderr, "Warning: bad ending versions file for %s\n", - modname); + warn("bad ending versions file for %s\n", modname); goto release; } *end = '\0'; @@ -438,19 +436,19 @@ static void write_version(const char *filename, const char *sum, fd = open(filename, O_RDWR); if (fd < 0) { - fprintf(stderr, "Warning: changing sum in %s failed: %s\n", + warn("changing sum in %s failed: %s\n", filename, strerror(errno)); return; } if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { - fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n", + warn("changing sum in %s:%lu failed: %s\n", filename, offset, strerror(errno)); goto out; } if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { - fprintf(stderr, "Warning: writing sum in %s failed: %s\n", + warn("writing sum in %s failed: %s\n", filename, strerror(errno)); goto out; } diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 88e30e82f1ca..f34373853ef8 100644 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -66,8 +66,8 @@ require 5; # at least perl 5 use strict; use File::Find; -my $nm = "/usr/bin/nm -p"; -my $objdump = "/usr/bin/objdump -s -j .comment"; +my $nm = ($ENV{'NM'} || "nm") . " -p"; +my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment"; my $srctree = ""; my $objtree = ""; $srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'})); diff --git a/scripts/package/Makefile b/scripts/package/Makefile index c201ef001f09..7c434e037e7f 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -32,12 +32,11 @@ MKSPEC := $(srctree)/scripts/package/mkspec PREV := set -e; cd ..; # rpm-pkg -.PHONY: rpm-pkg rpm - +# --------------------------------------------------------------------------- $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile $(CONFIG_SHELL) $(MKSPEC) > $@ -rpm-pkg rpm: $(objtree)/kernel.spec +rpm-pkg rpm: $(objtree)/kernel.spec FORCE $(MAKE) clean $(PREV) ln -sf $(srctree) $(KERNELPATH) $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. @@ -54,11 +53,11 @@ rpm-pkg rpm: $(objtree)/kernel.spec clean-files := $(objtree)/kernel.spec # binrpm-pkg -.PHONY: binrpm-pkg +# --------------------------------------------------------------------------- $(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@ - -binrpm-pkg: $(objtree)/binkernel.spec + +binrpm-pkg: $(objtree)/binkernel.spec FORCE $(MAKE) KBUILD_SRC= set -e; \ $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version @@ -71,9 +70,7 @@ clean-files += $(objtree)/binkernel.spec # Deb target # --------------------------------------------------------------------------- -# -.PHONY: deb-pkg -deb-pkg: +deb-pkg: FORCE $(MAKE) KBUILD_SRC= $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb @@ -82,8 +79,7 @@ clean-dirs += $(objtree)/debian/ # tarball targets # --------------------------------------------------------------------------- -.PHONY: tar%pkg -tar%pkg: +tar%pkg: FORCE $(MAKE) KBUILD_SRC= $(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ @@ -92,7 +88,7 @@ clean-dirs += $(objtree)/tar-install/ # Help text displayed when executing 'make help' # --------------------------------------------------------------------------- -help: +help: FORCE @echo ' rpm-pkg - Build the kernel as an RPM package' @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel' @echo ' and modules' diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl new file mode 100644 index 000000000000..cb4260ebdb91 --- /dev/null +++ b/scripts/profile2linkerlist.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +# +# Takes a (sorted) output of readprofile and turns it into a list suitable for +# linker scripts +# +# usage: +# readprofile | sort -rn | perl profile2linkerlist.pl > functionlist +# + +while (<>) { + my $line = $_; + + $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/; + + if ( ($line =~ /unknown/) || ($line =~ /total/)) { + + } else { + print "*(.text.$1)\n"; + } +} diff --git a/scripts/reference_discarded.pl b/scripts/reference_discarded.pl deleted file mode 100644 index 4ee6ab2135b3..000000000000 --- a/scripts/reference_discarded.pl +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/perl -w -# -# reference_discarded.pl (C) Keith Owens 2001 <kaos@ocs.com.au> -# -# Released under GPL V2. -# -# List dangling references to vmlinux discarded sections. - -use strict; -die($0 . " takes no arguments\n") if($#ARGV >= 0); - -my %object; -my $object; -my $line; -my $ignore; -my $errorcount; - -$| = 1; - -# printf("Finding objects, "); -open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed"; -while (defined($line = <OBJDUMP_LIST>)) { - chomp($line); - if ($line =~ /:\s+file format/) { - ($object = $line) =~ s/:.*//; - $object{$object}->{'module'} = 0; - $object{$object}->{'size'} = 0; - $object{$object}->{'off'} = 0; - } - if ($line =~ /^\s*\d+\s+\.modinfo\s+/) { - $object{$object}->{'module'} = 1; - } - if ($line =~ /^\s*\d+\s+\.comment\s+/) { - ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5]; - } -} -close(OBJDUMP_LIST); -# printf("%d objects, ", scalar keys(%object)); -$ignore = 0; -foreach $object (keys(%object)) { - if ($object{$object}->{'module'}) { - ++$ignore; - delete($object{$object}); - } -} -# printf("ignoring %d module(s)\n", $ignore); - -# Ignore conglomerate objects, they have been built from multiple objects and we -# only care about the individual objects. If an object has more than one GCC: -# string in the comment section then it is conglomerate. This does not filter -# out conglomerates that consist of exactly one object, can't be helped. - -# printf("Finding conglomerates, "); -$ignore = 0; -foreach $object (keys(%object)) { - if (exists($object{$object}->{'off'})) { - my ($off, $size, $comment, $l); - $off = hex($object{$object}->{'off'}); - $size = hex($object{$object}->{'size'}); - open(OBJECT, "<$object") || die "cannot read $object"; - seek(OBJECT, $off, 0) || die "seek to $off in $object failed"; - $l = read(OBJECT, $comment, $size); - die "read $size bytes from $object .comment failed" if ($l != $size); - close(OBJECT); - if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) { - ++$ignore; - delete($object{$object}); - } - } -} -# printf("ignoring %d conglomerate(s)\n", $ignore); - -# printf("Scanning objects\n"); - -# Keith Ownes <kaos@sgi.com> commented: -# For our future {in}sanity, add a comment that this is the ppc .opd -# section, not the ia64 .opd section. -# ia64 .opd should not point to discarded sections. -$errorcount = 0; -foreach $object (keys(%object)) { - my $from; - open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object"; - while (defined($line = <OBJDUMP>)) { - chomp($line); - if ($line =~ /RELOCATION RECORDS FOR /) { - ($from = $line) =~ s/.*\[([^]]*).*/$1/; - } - if (($line =~ /\.text\.exit$/ || - $line =~ /\.exit\.text$/ || - $line =~ /\.data\.exit$/ || - $line =~ /\.exit\.data$/ || - $line =~ /\.exitcall\.exit$/) && - ($from !~ /\.text\.exit$/ && - $from !~ /\.exit\.text$/ && - $from !~ /\.data\.exit$/ && - $from !~ /\.opd$/ && - $from !~ /\.exit\.data$/ && - $from !~ /\.altinstructions$/ && - $from !~ /\.pdr$/ && - $from !~ /\.debug_.*$/ && - $from !~ /\.exitcall\.exit$/ && - $from !~ /\.eh_frame$/ && - $from !~ /\.stab$/)) { - printf("Error: %s %s refers to %s\n", $object, $from, $line); - $errorcount = $errorcount + 1; - } - } - close(OBJDUMP); -} -# printf("Done\n"); - -exit(0); diff --git a/scripts/reference_init.pl b/scripts/reference_init.pl deleted file mode 100644 index 7f6960b175a2..000000000000 --- a/scripts/reference_init.pl +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/perl -w -# -# reference_init.pl (C) Keith Owens 2002 <kaos@ocs.com.au> -# -# List references to vmlinux init sections from non-init sections. - -# Unfortunately I had to exclude references from read only data to .init -# sections, almost all of these are false positives, they are created by -# gcc. The downside of excluding rodata is that there really are some -# user references from rodata to init code, e.g. drivers/video/vgacon.c -# -# const struct consw vga_con = { -# con_startup: vgacon_startup, -# -# where vgacon_startup is __init. If you want to wade through the false -# positives, take out the check for rodata. - -use strict; -die($0 . " takes no arguments\n") if($#ARGV >= 0); - -my %object; -my $object; -my $line; -my $ignore; - -$| = 1; - -printf("Finding objects, "); -open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed"; -while (defined($line = <OBJDUMP_LIST>)) { - chomp($line); - if ($line =~ /:\s+file format/) { - ($object = $line) =~ s/:.*//; - $object{$object}->{'module'} = 0; - $object{$object}->{'size'} = 0; - $object{$object}->{'off'} = 0; - } - if ($line =~ /^\s*\d+\s+\.modinfo\s+/) { - $object{$object}->{'module'} = 1; - } - if ($line =~ /^\s*\d+\s+\.comment\s+/) { - ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5]; - } -} -close(OBJDUMP_LIST); -printf("%d objects, ", scalar keys(%object)); -$ignore = 0; -foreach $object (keys(%object)) { - if ($object{$object}->{'module'}) { - ++$ignore; - delete($object{$object}); - } -} -printf("ignoring %d module(s)\n", $ignore); - -# Ignore conglomerate objects, they have been built from multiple objects and we -# only care about the individual objects. If an object has more than one GCC: -# string in the comment section then it is conglomerate. This does not filter -# out conglomerates that consist of exactly one object, can't be helped. - -printf("Finding conglomerates, "); -$ignore = 0; -foreach $object (keys(%object)) { - if (exists($object{$object}->{'off'})) { - my ($off, $size, $comment, $l); - $off = hex($object{$object}->{'off'}); - $size = hex($object{$object}->{'size'}); - open(OBJECT, "<$object") || die "cannot read $object"; - seek(OBJECT, $off, 0) || die "seek to $off in $object failed"; - $l = read(OBJECT, $comment, $size); - die "read $size bytes from $object .comment failed" if ($l != $size); - close(OBJECT); - if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) { - ++$ignore; - delete($object{$object}); - } - } -} -printf("ignoring %d conglomerate(s)\n", $ignore); - -printf("Scanning objects\n"); -foreach $object (sort(keys(%object))) { - my $from; - open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object"; - while (defined($line = <OBJDUMP>)) { - chomp($line); - if ($line =~ /RELOCATION RECORDS FOR /) { - ($from = $line) =~ s/.*\[([^]]*).*/$1/; - } - if (($line =~ /\.init$/ || $line =~ /\.init\./) && - ($from !~ /\.init$/ && - $from !~ /\.init\./ && - $from !~ /\.stab$/ && - $from !~ /\.rodata$/ && - $from !~ /\.text\.lock$/ && - $from !~ /\.pci_fixup_header$/ && - $from !~ /\.pci_fixup_final$/ && - $from !~ /\.pdr$/ && - $from !~ /\__param$/ && - $from !~ /\.altinstructions/ && - $from !~ /\.eh_frame/ && - $from !~ /\.debug_/)) { - printf("Error: %s %s refers to %s\n", $object, $from, $line); - } - } - close(OBJDUMP); -} -printf("Done\n"); |