diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index 7a7753321a2..51104f9194a 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -383,6 +383,20 @@ more details, with real examples. to prerequisites are referenced with $(src) (because they are not generated files). + $(kecho) + echoing information to user in a rule is often a good practice + but when execution "make -s" one does not expect to see any output + except for warnings/errors. + To support this kbuild define $(kecho) which will echo out the + text following $(kecho) to stdout except if "make -s" is used. + + Example: + #arch/blackfin/boot/Makefile + $(obj)/vmImage: $(obj)/vmlinux.gz + $(call if_changed,uimage) + @$(kecho) 'Kernel: $@ is ready' + + --- 3.11 $(CC) support functions The kernel may be built with several different versions of diff --git a/Makefile b/Makefile index 71e98e9e6ac..09ff7d81809 100644 --- a/Makefile +++ b/Makefile @@ -336,7 +336,7 @@ LINUXINCLUDE := -Iinclude \ -I$(srctree)/arch/$(hdr-arch)/include \ -include include/linux/autoconf.h -KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) +KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ @@ -439,7 +439,11 @@ ifeq ($(config-targets),1) include $(srctree)/arch/$(SRCARCH)/Makefile export KBUILD_DEFCONFIG KBUILD_KCONFIG -config %config: scripts_basic outputmakefile FORCE +config: scripts_basic outputmakefile FORCE + $(Q)mkdir -p include/linux include/config + $(Q)$(MAKE) $(build)=scripts/kconfig $@ + +%config: scripts_basic outputmakefile FORCE $(Q)mkdir -p include/linux include/config $(Q)$(MAKE) $(build)=scripts/kconfig $@ @@ -600,20 +604,25 @@ export INSTALL_PATH ?= /boot MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB -# -# INSTALL_MOD_STRIP, if defined, will cause modules to be -# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then -# the default option --strip-debug will be used. Otherwise, -# INSTALL_MOD_STRIP will used as the options to the strip command. +strip-symbols := $(srctree)/scripts/strip-symbols \ + $(wildcard $(srctree)/arch/$(ARCH)/scripts/strip-symbols) +# +# INSTALL_MOD_STRIP, if defined, will cause modules to be stripped while +# they get installed. If INSTALL_MOD_STRIP is '1', then the default +# options (see below) will be used. Otherwise, INSTALL_MOD_STRIP will +# be used as the option(s) to the objcopy command. ifdef INSTALL_MOD_STRIP ifeq ($(INSTALL_MOD_STRIP),1) -mod_strip_cmd = $(STRIP) --strip-debug +mod_strip_cmd = $(OBJCOPY) --strip-debug +ifeq ($(CONFIG_KALLSYMS_ALL),$(CONFIG_KALLSYMS_STRIP_GENERATED)) +mod_strip_cmd += --wildcard $(addprefix --strip-symbols ,$(strip-symbols)) +endif else -mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) +mod_strip_cmd = $(OBJCOPY) $(INSTALL_MOD_STRIP) endif # INSTALL_MOD_STRIP=1 else -mod_strip_cmd = true +mod_strip_cmd = false endif # INSTALL_MOD_STRIP export mod_strip_cmd @@ -743,6 +752,7 @@ last_kallsyms := 2 endif kallsyms.o := .tmp_kallsyms$(last_kallsyms).o +kallsyms.h := $(wildcard include/config/kallsyms/*.h) $(wildcard include/config/kallsyms/*/*.h) define verify_kallsyms $(Q)$(if $($(quiet)cmd_sysmap), \ @@ -767,24 +777,41 @@ endef # Generate .S file with all kernel symbols quiet_cmd_kallsyms = KSYM $@ - cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \ - $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@ + cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } \ + | $(KALLSYMS) $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) >$@ -.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE +quiet_cmd_kstrip = STRIP $@ + cmd_kstrip = $(OBJCOPY) --wildcard $(addprefix --strip$(if $(CONFIG_RELOCATABLE),-unneeded)-symbols ,$(filter %/scripts/strip-symbols,$^)) $< $@ + +$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): KBUILD_AFLAGS += -Wa,--strip-local-absolute +$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): %.o: %.S scripts FORCE $(call if_changed_dep,as_o_S) -.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS) +ifeq ($(CONFIG_KALLSYMS_STRIP_GENERATED),y) +strip-ext := .stripped +endif + +.tmp_kallsyms%.S: .tmp_vmlinux%$(strip-ext) $(KALLSYMS) $(kallsyms.h) $(call cmd,kallsyms) +# make -jN seems to have problems with intermediate files, see bug #3330. +.SECONDARY: $(foreach n,1 2 3,.tmp_vmlinux$(n).stripped) +.tmp_vmlinux%.stripped: .tmp_vmlinux% $(strip-symbols) $(kallsyms.h) + $(call cmd,kstrip) + +ifneq ($(CONFIG_DEBUG_INFO),y) +.tmp_vmlinux%: LDFLAGS_vmlinux += -S +endif # .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version -.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE - $(call if_changed_rule,ksym_ld) +.tmp_vmlinux%: $(vmlinux-lds) $(vmlinux-all) FORCE + $(if $(filter 1,$*),$(call if_changed_rule,ksym_ld),$(call if_changed,vmlinux__)) -.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE - $(call if_changed,vmlinux__) +.tmp_vmlinux0$(strip-ext): + $(Q)echo "placeholder" >$@ -.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE - $(call if_changed,vmlinux__) +.tmp_vmlinux1: .tmp_kallsyms0.o +.tmp_vmlinux2: .tmp_kallsyms1.o +.tmp_vmlinux3: .tmp_kallsyms2.o # Needs to visit scripts/ before $(KALLSYMS) can be used. $(KALLSYMS): scripts ; @@ -926,7 +953,7 @@ PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 # 2) Create the include2 directory, used for the second asm symlink prepare3: include/config/kernel.release ifneq ($(KBUILD_SRC),) - @echo ' Using $(srctree) as source for kernel' + @$(kecho) ' Using $(srctree) as source for kernel' $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \ echo " $(srctree) is not clean, please run 'make mrproper'";\ echo " in the '$(srctree)' directory.";\ @@ -983,7 +1010,7 @@ endef # directory for generated filesas used by some architectures. define create-symlink if [ ! -L include/asm ]; then \ - echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ + $(kecho) ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ if [ ! -d include/asm-$(SRCARCH) ]; then \ mkdir -p include/asm-$(SRCARCH); \ fi; \ @@ -1022,6 +1049,10 @@ include/linux/version.h: $(srctree)/Makefile FORCE include/linux/utsrelease.h: include/config/kernel.release FORCE $(call filechk,utsrelease.h) +PHONY += headerdep +headerdep: + $(Q)find include/ -name '*.h' | xargs --max-args 1 scripts/headerdep.pl + # --------------------------------------------------------------------------- PHONY += depend dep @@ -1096,7 +1127,7 @@ all: modules PHONY += modules modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order - @echo ' Building modules, stage 2.'; + @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild @@ -1270,7 +1301,8 @@ help: @echo ' versioncheck - Sanity check on version.h usage' @echo ' includecheck - Check for duplicate included header files' @echo ' export_report - List the usages of all exported symbols' - @echo ' headers_check - Sanity check on exported headers'; \ + @echo ' headers_check - Sanity check on exported headers' + @echo ' headerdep - Detect inclusion cycles in headers'; \ echo '' @echo 'Kernel packaging:' @$(MAKE) $(build)=$(package-dir) help @@ -1360,7 +1392,7 @@ $(module-dirs): crmodverdir $(objtree)/Module.symvers $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@) modules: $(module-dirs) - @echo ' Building modules, stage 2.'; + @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost PHONY += modules_install @@ -1409,123 +1441,12 @@ endif # KBUILD_EXTMOD # Generate tags for editors # --------------------------------------------------------------------------- +quiet_cmd_tags = GEN $@ + cmd_tags = $(CONFIG_SHELL) $(srctree)/scripts/tags.sh $@ -#We want __srctree to totally vanish out when KBUILD_OUTPUT is not set -#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file. -#Adding $(srctree) adds about 20M on i386 to the size of the output file! - -ifeq ($(src),$(obj)) -__srctree = -else -__srctree = $(srctree)/ -endif - -ifeq ($(ALLSOURCE_ARCHS),) -ifeq ($(ARCH),um) -ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH) -else -ALLINCLUDE_ARCHS := $(SRCARCH) -endif -else -#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour. -ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS) -endif - -ALLSOURCE_ARCHS := $(SRCARCH) - -define find-sources - ( for arch in $(ALLSOURCE_ARCHS) ; do \ - find $(__srctree)arch/$${arch} $(RCS_FIND_IGNORE) \ - -wholename $(__srctree)arch/$${arch}/include/asm -type d -prune \ - -o -name $1 -print; \ - done ; \ - find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \ - -name $1 -print; \ - find $(__srctree)include $(RCS_FIND_IGNORE) \ - \( -name config -o -name 'asm-*' \) -prune \ - -o -name $1 -print; \ - for arch in $(ALLINCLUDE_ARCHS) ; do \ - test -e $(__srctree)include/asm-$${arch} && \ - find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \ - -name $1 -print; \ - test -e $(__srctree)arch/$${arch}/include/asm && \ - find $(__srctree)arch/$${arch}/include/asm $(RCS_FIND_IGNORE) \ - -name $1 -print; \ - done ; \ - find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ - -name $1 -print; \ - find $(__srctree) $(RCS_FIND_IGNORE) \ - \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \ - -name $1 -print; \ - ) -endef - -define all-sources - $(call find-sources,'*.[chS]') -endef -define all-kconfigs - $(call find-sources,'Kconfig*') -endef -define all-defconfigs - $(call find-sources,'defconfig') -endef - -define xtags - if $1 --version 2>&1 | grep -iq exuberant; then \ - $(all-sources) | xargs $1 -a \ - -I __initdata,__exitdata,__acquires,__releases \ - -I __read_mostly,____cacheline_aligned,____cacheline_aligned_in_smp,____cacheline_internodealigned_in_smp \ - -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ - --extra=+f --c-kinds=+px \ - --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'; \ - $(all-kconfigs) | xargs $1 -a \ - --langdef=kconfig \ - --language-force=kconfig \ - --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/'; \ - $(all-defconfigs) | xargs -r $1 -a \ - --langdef=dotconfig \ - --language-force=dotconfig \ - --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'; \ - elif $1 --version 2>&1 | grep -iq emacs; then \ - $(all-sources) | xargs $1 -a; \ - $(all-kconfigs) | xargs $1 -a \ - --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'; \ - $(all-defconfigs) | xargs -r $1 -a \ - --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \ - else \ - $(all-sources) | xargs $1 -a; \ - fi -endef - -quiet_cmd_cscope-file = FILELST cscope.files - cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files - -quiet_cmd_cscope = MAKE cscope.out - cmd_cscope = cscope -b -f cscope.out - -cscope: FORCE - $(call cmd,cscope-file) - $(call cmd,cscope) - -quiet_cmd_TAGS = MAKE $@ -define cmd_TAGS - rm -f $@; \ - $(call xtags,etags) -endef - -TAGS: FORCE - $(call cmd,TAGS) - -quiet_cmd_tags = MAKE $@ -define cmd_tags - rm -f $@; \ - $(call xtags,ctags) -endef - -tags: FORCE +tags TAGS cscope: FORCE $(call cmd,tags) - # Scripts to check various things for consistency # --------------------------------------------------------------------------- @@ -1604,7 +1525,11 @@ endif $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) # Modules -/ %/: prepare scripts FORCE +/: prepare scripts FORCE + $(cmd_crmodverdir) + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) +%/: prepare scripts FORCE $(cmd_crmodverdir) $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ $(build)=$(build-dir) @@ -1638,7 +1563,7 @@ cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \ $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*) a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \ - $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ + $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CPPFLAGS) \ $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o) quiet_cmd_as_o_S = AS $@ diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile index 522f3c12406..e028d13481a 100644 --- a/arch/blackfin/boot/Makefile +++ b/arch/blackfin/boot/Makefile @@ -25,7 +25,7 @@ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE $(obj)/vmImage: $(obj)/vmlinux.gz $(call if_changed,uimage) - @echo 'Kernel: $@ is ready' + @$(kecho) 'Kernel: $@ is ready' install: sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" diff --git a/arch/x86/scripts/strip-symbols b/arch/x86/scripts/strip-symbols new file mode 100644 index 00000000000..a2f1ccb827c --- /dev/null +++ b/arch/x86/scripts/strip-symbols @@ -0,0 +1 @@ +__cpu_vendor_dev_X86_VENDOR_* diff --git a/init/Kconfig b/init/Kconfig index f291f086caa..8a63c404ef4 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -588,6 +588,13 @@ config KALLSYMS_ALL Say N. +config KALLSYMS_STRIP_GENERATED + bool "Strip machine generated symbols from kallsyms" + depends on KALLSYMS_ALL + default y + help + Say N if you want kallsyms to retain even machine generated symbols. + config KALLSYMS_EXTRA_PASS bool "Do an extra kallsyms pass" depends on KALLSYMS diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 7b8b0f21a5b..e694afa0eb8 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -30,20 +30,19 @@ #define all_var 0 #endif -/* These will be re-linked against their real values during the second link stage */ -extern const unsigned long kallsyms_addresses[] __attribute__((weak)); -extern const u8 kallsyms_names[] __attribute__((weak)); +extern const unsigned long kallsyms_addresses[]; +extern const u8 kallsyms_names[]; /* tell the compiler that the count isn't in the small data section if the arch * has one (eg: FRV) */ extern const unsigned long kallsyms_num_syms -__attribute__((weak, section(".rodata"))); + __attribute__((__section__(".rodata"))); -extern const u8 kallsyms_token_table[] __attribute__((weak)); -extern const u16 kallsyms_token_index[] __attribute__((weak)); +extern const u8 kallsyms_token_table[]; +extern const u16 kallsyms_token_index[]; -extern const unsigned long kallsyms_markers[] __attribute__((weak)); +extern const unsigned long kallsyms_markers[]; static inline int is_kernel_inittext(unsigned long addr) { @@ -168,9 +167,6 @@ static unsigned long get_symbol_pos(unsigned long addr, unsigned long symbol_start = 0, symbol_end = 0; unsigned long i, low, high, mid; - /* This kernel should never had been booted. */ - BUG_ON(!kallsyms_addresses); - /* do a binary search on the sorted kallsyms_addresses array */ low = 0; high = kallsyms_num_syms; diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 982dcae7bbe..c29be8f9024 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -24,6 +24,13 @@ basetarget = $(basename $(notdir $@)) # Escape single quote for use in echo statements escsq = $(subst $(squote),'\$(squote)',$1) +### +# Easy method for doing a status message + kecho := : + quiet_kecho := echo +silent_kecho := : +kecho := $($(quiet)kecho) + ### # filechk is used to check if the content of a generated file is updated. # Sample usage: @@ -39,22 +46,15 @@ escsq = $(subst $(squote),'\$(squote)',$1) # - If they are equal no change, and no timestamp update # - stdin is piped in from the first prerequisite ($<) so one has # to specify a valid file as first prerequisite (often the kbuild file) - chk_filechk = : - quiet_chk_filechk = echo ' CHK $@' -silent_chk_filechk = : - upd_filechk = : - quiet_upd_filechk = echo ' UPD $@' -silent_upd_filechk = : - define filechk $(Q)set -e; \ - $($(quiet)chk_filechk); \ + $(kecho) ' CHK $@'; \ mkdir -p $(dir $@); \ $(filechk_$(1)) < $< > $@.tmp; \ if [ -r $@ ] && cmp -s $@ $@.tmp; then \ rm -f $@.tmp; \ else \ - $($(quiet)upd_filechk); \ + $(kecho) ' UPD $@'; \ mv -f $@.tmp $@; \ fi endef @@ -144,7 +144,9 @@ ld-option = $(call try-run,\ build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj # Prefix -I with $(srctree) if it is not an absolute path. -addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) +# skip if -I has no parameter +addtree = $(if $(patsubst -I%,%,$(1)), \ +$(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)) # Find all -I options and call addtree flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 7a176773af8..5d900307de3 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -151,14 +151,20 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(src)/%.c FORCE $(call if_changed_dep,cc_i_c) +cmd_genksyms = \ + $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ + $(GENKSYMS) -T $@ -A -a $(ARCH) \ + $(if $(KBUILD_PRESERVE),-p) \ + $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null))) + quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ -cmd_cc_symtypes_c = \ - $(CPP) -D__GENKSYMS__ $(c_flags) $< \ - | $(GENKSYMS) -T $@ >/dev/null; \ - test -s $@ || rm -f $@ +cmd_cc_symtypes_c = \ + set -e; \ + $(call cmd_genksyms, true) >/dev/null; \ + test -s $@ || rm -f $@ $(obj)/%.symtypes : $(src)/%.c FORCE - $(call if_changed_dep,cc_symtypes_c) + $(call cmd,cc_symtypes_c) # C (.c) files # The C file is compiled and updated dependency information is generated. @@ -171,30 +177,38 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< else # When module versioning is enabled the following steps are executed: -# o compile a .tmp_.o from .c -# o if .tmp_.o doesn't contain a __ksymtab version, i.e. does -# not export symbols, we just rename .tmp_.o to .o and +# o compile a .tmp_.s from .c +# o if .tmp_.s doesn't contain a __ksymtab version, i.e. does +# not export symbols, we just assemble .tmp_.s to .o and # are done. # o otherwise, we calculate symbol versions using the good old # genksyms on the preprocessed source and postprocess them in a way -# that they are usable as a linker script -# o generate .o from .tmp_.o using the linker to -# replace the unresolved symbols __crc_exported_symbol with -# the actual value of the checksum generated by genksyms +# that they are usable as assembly source +# o assemble .o from .tmp_.s forcing inclusion of directives +# defining the actual values of __crc_*, followed by objcopy-ing them +# to force these symbols to be local to permit stripping them later. +s_file = $(@D)/.tmp_$(@F:.o=.s) +v_file = $(@D)/.tmp_$(@F:.o=.v) +tmp_o_file = $(@D)/.tmp_$(@F) +no_g_c_flags = $(filter-out -g%,$(c_flags)) + +cmd_cc_o_c = $(CC) $(c_flags) -S -o $(s_file) $< -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) $(if $(KBUILD_SYMTYPES), \ - -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \ - > $(@D)/.tmp_$(@F:.o=.ver); \ - \ - $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ - -T $(@D)/.tmp_$(@F:.o=.ver); \ - rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ + if grep -q __ksymtab $(s_file); then \ + if $(call cmd_genksyms, $(KBUILD_SYMTYPES)) > $(v_file) \ + && $(CC) $(no_g_c_flags) -c -Wa,$(v_file) \ + -o $(tmp_o_file) $(s_file) \ + && $(OBJCOPY) -L '__crc_*' -L '___crc_*' -w \ + $(tmp_o_file) $@; \ + then \ + : ; \ + else \ + rm -f $@; exit 1; \ + fi; \ else \ - mv -f $(@D)/.tmp_$(@F) $@; \ + rm -f $(v_file); \ + $(CC) $(no_g_c_flags) -c -o $@ $(s_file); \ fi; endif @@ -211,7 +225,12 @@ define rule_cc_o_c $(cmd_record_mcount) \ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ $(dot-target).tmp; \ - rm -f $(depfile); \ + if [ -r $(@D)/.tmp_$(@F:.o=.v) ]; then \ + echo >> $(dot-target).tmp; \ + echo '$@: $(GENKSYMS)' >> $(dot-target).tmp; \ + echo '$(GENKSYMS):: ;' >> $(dot-target).tmp; \ + fi; \ + rm -f $(depfile) $(@D)/.tmp_$(@F:.o=.?); \ mv -f $(dot-target).tmp $(dot-target).cmd endef diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index b4ca38a2115..e06365775bd 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -104,9 +104,11 @@ else debug_flags = endif -orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) +orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ + $(ccflags-y) $(CFLAGS_$(basetarget).o) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) -_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) +_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \ + $(asflags-y) $(AFLAGS_$(basetarget).o) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) # If building the kernel in a separate objtree expand all occurrences @@ -127,15 +129,16 @@ __a_flags = $(call flags,_a_flags) __cpp_flags = $(call flags,_cpp_flags) endif -c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ - $(__c_flags) $(modkern_cflags) \ +c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ + $(__c_flags) $(modkern_cflags) \ -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ $(debug_flags) -a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ +a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(__a_flags) $(modkern_aflags) -cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags) +cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ + $(__cpp_flags) ld_flags = $(LDFLAGS) $(ldflags-y) diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index efa5d940e63..a5122dce126 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -17,7 +17,8 @@ __modinst: $(modules) @: quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) + cmd_modules_install = mkdir -p $(2); \ + $(mod_strip_cmd) $@ $(2)/$(notdir $@) || cp $@ $(2) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra diff --git a/scripts/decodecode b/scripts/decodecode index 235d3938529..4b00647814b 100755 --- a/scripts/decodecode +++ b/scripts/decodecode @@ -7,7 +7,7 @@ # AFLAGS=--32 decodecode < 386.oops cleanup() { - rm -f $T $T.s $T.o + rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa exit 1 } @@ -44,21 +44,33 @@ if [ $marker -eq 0 ]; then marker=`expr index "$code" "\("` fi +touch $T.oo if [ $marker -ne 0 ]; then - beforemark=`echo "$code" | cut -c-$((${marker} - 1))` + echo All code >> $T.oo + echo ======== >> $T.oo + beforemark=`echo "$code"` echo -n " .byte 0x" > $T.s - echo $beforemark | sed -e 's/ /,0x/g' >> $T.s - as $AFLAGS -o $T.o $T.s - objdump -S $T.o - rm $T.o $T.s + echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's///g' >> $T.s + as $AFLAGS -o $T.o $T.s &> /dev/null + objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo + cat $T.ooo >> $T.oo + rm -f $T.o $T.s $T.ooo # and fix code at-and-after marker code=`echo "$code" | cut -c$((${marker} + 1))-` fi - +echo Code starting with the faulting instruction > $T.aa +echo =========================================== >> $T.aa code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'` echo -n " .byte 0x" > $T.s echo $code >> $T.s -as $AFLAGS -o $T.o $T.s -objdump -S $T.o -rm $T $T.s $T.o +as $AFLAGS -o $T.o $T.s &> /dev/null +objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa +cat $T.aaa >> $T.aa + +faultline=`cat $T.aaa | head -1 | cut -d":" -f2` + +cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g" +echo +cat $T.aa +cleanup diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index 8187e6f0dc2..72997c353cb 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig @@ -8,8 +8,8 @@ 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" -function dump_config { - typeset file="$1" +dump_config() { + file="$1" start=`$binoffset $file $IKCFG_ST 2>/dev/null` [ "$?" != "0" ] && start="-1" @@ -18,8 +18,8 @@ function dump_config { fi end=`$binoffset $file $IKCFG_ED 2>/dev/null` - let start="$start + 8" - let size="$end - $start" + start=`expr $start + 8` + size=`expr $end - $start` dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index c249274e005..f8bb4cabd62 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -42,7 +42,8 @@ static FILE *debugfile; int cur_line = 1; char *cur_filename; -static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings; +static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, + flag_preserve, flag_warnings, flag_asm; static const char *arch = ""; static const char *mod_prefix = ""; @@ -58,6 +59,8 @@ static const char *const symbol_type_name[] = { static int equal_list(struct string_list *a, struct string_list *b); static void print_list(FILE * f, struct string_list *list); +static void print_location(void); +static void print_type_name(enum symbol_type type, const char *name); /*----------------------------------------------------------------------*/ @@ -151,27 +154,83 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns) for (sym = symtab[h]; sym; sym = sym->hash_next) if (map_to_ns(sym->type) == map_to_ns(ns) && - strcmp(name, sym->name) == 0) + strcmp(name, sym->name) == 0 && + sym->is_declared) break; return sym; } -struct symbol *add_symbol(const char *name, enum symbol_type type, - struct string_list *defn, int is_extern) +static int is_unknown_symbol(struct symbol *sym) +{ + struct string_list *defn; + + return ((sym->type == SYM_STRUCT || + sym->type == SYM_UNION || + sym->type == SYM_ENUM) && + (defn = sym->defn) && defn->tag == SYM_NORMAL && + strcmp(defn->string, "}") == 0 && + (defn = defn->next) && defn->tag == SYM_NORMAL && + strcmp(defn->string, "UNKNOWN") == 0 && + (defn = defn->next) && defn->tag == SYM_NORMAL && + strcmp(defn->string, "{") == 0); +} + +struct symbol *__add_symbol(const char *name, enum symbol_type type, + struct string_list *defn, int is_extern, + int is_reference) { unsigned long h = crc32(name) % HASH_BUCKETS; struct symbol *sym; + enum symbol_status status = STATUS_UNCHANGED; 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)) + if (map_to_ns(sym->type) == map_to_ns(type) && + strcmp(name, sym->name) == 0) { + if (is_reference) + /* fall through */ ; + else if (sym->type == type && + equal_list(sym->defn, defn)) { + if (!sym->is_declared && sym->is_override) { + print_location(); + print_type_name(type, name); + fprintf(stderr, " modversion is " + "unchanged\n"); + } + sym->is_declared = 1; + return sym; + } else if (!sym->is_declared) { + if (sym->is_override && flag_preserve) { + print_location(); + fprintf(stderr, "ignoring "); + print_type_name(type, name); + fprintf(stderr, " modversion change\n"); + sym->is_declared = 1; + return sym; + } else { + status = is_unknown_symbol(sym) ? + STATUS_DEFINED : STATUS_MODIFIED; + } + } else { error_with_pos("redefinition of %s", name); - return sym; + return sym; + } + break; } } + if (sym) { + struct symbol **psym; + + for (psym = &symtab[h]; *psym; psym = &(*psym)->hash_next) { + if (*psym == sym) { + *psym = sym->hash_next; + break; + } + } + --nsyms; + } + sym = xmalloc(sizeof(*sym)); sym->name = name; sym->type = type; @@ -183,6 +242,10 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, sym->hash_next = symtab[h]; symtab[h] = sym; + sym->is_declared = !is_reference; + sym->status = status; + sym->is_override = 0; + if (flag_debug) { fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type], name); @@ -196,6 +259,18 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, return sym; } +struct symbol *add_symbol(const char *name, enum symbol_type type, + struct string_list *defn, int is_extern) +{ + return __add_symbol(name, type, defn, is_extern, 0); +} + +struct symbol *add_reference_symbol(const char *name, enum symbol_type type, + struct string_list *defn, int is_extern) +{ + return __add_symbol(name, type, defn, is_extern, 1); +} + /*----------------------------------------------------------------------*/ void free_node(struct string_list *node) @@ -236,6 +311,90 @@ static int equal_list(struct string_list *a, struct string_list *b) return !a && !b; } +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +struct string_list *read_node(FILE *f) +{ + char buffer[256]; + struct string_list node = { + .string = buffer, + .tag = SYM_NORMAL }; + int c; + + while ((c = fgetc(f)) != EOF) { + if (c == ' ') { + if (node.string == buffer) + continue; + break; + } else if (c == '\n') { + if (node.string == buffer) + return NULL; + ungetc(c, f); + break; + } + if (node.string >= buffer + sizeof(buffer) - 1) { + fprintf(stderr, "Token too long\n"); + exit(1); + } + *node.string++ = c; + } + if (node.string == buffer) + return NULL; + *node.string = 0; + node.string = buffer; + + if (node.string[1] == '#') { + int n; + + for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) { + if (node.string[0] == symbol_type_name[n][0]) { + node.tag = n; + node.string += 2; + return copy_node(&node); + } + } + fprintf(stderr, "Unknown type %c\n", node.string[0]); + exit(1); + } + return copy_node(&node); +} + +static void read_reference(FILE *f) +{ + while (!feof(f)) { + struct string_list *defn = NULL; + struct string_list *sym, *def; + int is_extern = 0, is_override = 0; + struct symbol *subsym; + + sym = read_node(f); + if (sym && sym->tag == SYM_NORMAL && + !strcmp(sym->string, "override")) { + is_override = 1; + free_node(sym); + sym = read_node(f); + } + if (!sym) + continue; + def = read_node(f); + if (def && def->tag == SYM_NORMAL && + !strcmp(def->string, "extern")) { + is_extern = 1; + free_node(def); + def = read_node(f); + } + while (def) { + def->next = defn; + defn = def; + def = read_node(f); + } + subsym = add_reference_symbol(xstrdup(sym->string), sym->tag, + defn, is_extern); + subsym->is_override = is_override; + free_node(sym); + } +} + static void print_node(FILE * f, struct string_list *list) { if (list->tag != SYM_NORMAL) { @@ -311,6 +470,7 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) case SYM_TYPEDEF: subsym = find_symbol(cur->string, cur->tag); + /* FIXME: Bad reference files can segfault here. */ if (subsym->expansion_trail) { if (flag_dump_defs) fprintf(debugfile, "%s ", cur->string); @@ -347,9 +507,22 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) t = n; n = xmalloc(sizeof(*n)); - n->string = xstrdup("{ UNKNOWN }"); + n->string = xstrdup("{"); n->tag = SYM_NORMAL; n->next = t; + t = n; + + n = xmalloc(sizeof(*n)); + n->string = xstrdup("UNKNOWN"); + n->tag = SYM_NORMAL; + n->next = t; + t = n; + + n = xmalloc(sizeof(*n)); + n->string = xstrdup("}"); + n->tag = SYM_NORMAL; + n->next = t; + t = n; subsym = add_symbol(cur->string, cur->tag, n, 0); @@ -397,37 +570,75 @@ void export_symbol(const char *name) error_with_pos("export undefined symbol %s", name); else { unsigned long crc; + int has_changed = 0; if (flag_dump_defs) fprintf(debugfile, "Export %s == <", name); expansion_trail = (struct symbol *)-1L; + sym->expansion_trail = expansion_trail; + expansion_trail = sym; crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; sym = expansion_trail; while (sym != (struct symbol *)-1L) { struct symbol *n = sym->expansion_trail; + + if (sym->status != STATUS_UNCHANGED) { + if (!has_changed) { + print_location(); + fprintf(stderr, "%s: %s: modversion " + "changed because of changes " + "in ", flag_preserve ? "error" : + "warning", name); + } else + fprintf(stderr, ", "); + print_type_name(sym->type, sym->name); + if (sym->status == STATUS_DEFINED) + fprintf(stderr, " (became defined)"); + has_changed = 1; + if (flag_preserve) + errors++; + } sym->expansion_trail = 0; sym = n; } + if (has_changed) + fprintf(stderr, "\n"); if (flag_dump_defs) fputs(">\n", debugfile); - /* Used as a linker script. */ - printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); + /* Used as assembly source or a linker script. */ + printf(flag_asm + ? ".equiv %s__crc_%s, %#08lx\n" + : "%s__crc_%s = %#08lx ;\n", + mod_prefix, name, crc); } } /*----------------------------------------------------------------------*/ + +static void print_location(void) +{ + fprintf(stderr, "%s:%d: ", cur_filename ? : "", cur_line); +} + +static void print_type_name(enum symbol_type type, const char *name) +{ + if (type != SYM_NORMAL) + fprintf(stderr, "%s %s", symbol_type_name[type], name); + else + fprintf(stderr, "%s", name); +} + void error_with_pos(const char *fmt, ...) { va_list args; if (flag_warnings) { - fprintf(stderr, "%s:%d: ", cur_filename ? : "", - cur_line); + print_location(); va_start(args, fmt); vfprintf(stderr, fmt, args); @@ -440,21 +651,27 @@ void error_with_pos(const char *fmt, ...) static void genksyms_usage(void) { - fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" + fputs("Usage:\n" "genksyms [-aAdDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" #ifdef __GNU_LIBRARY__ " -a, --arch Select architecture\n" + " -A, --asm Generate assembly rather than linker script\n" " -d, --debug Increment the debug level (repeatable)\n" " -D, --dump Dump expanded symbol defs (for debugging only)\n" - " -T, --dump-types file Dump expanded types into file (for debugging only)\n" + " -r, --reference file Read reference symbols from a file\n" + " -T, --dump-types file Dump expanded types into file\n" + " -p, --preserve Preserve reference modversions or fail\n" " -w, --warnings Enable warnings\n" " -q, --quiet Disable warnings (default)\n" " -h, --help Print this message\n" " -V, --version Print the release version\n" #else /* __GNU_LIBRARY__ */ " -a Select architecture\n" + " -A Generate assembly rather than linker script\n" " -d Increment the debug level (repeatable)\n" " -D Dump expanded symbol defs (for debugging only)\n" - " -T file Dump expanded types into file (for debugging only)\n" + " -r file Read reference symbols from a file\n" + " -T file Dump expanded types into file\n" + " -p Preserve reference modversions or fail\n" " -w Enable warnings\n" " -q Disable warnings (default)\n" " -h Print this message\n" @@ -465,26 +682,29 @@ static void genksyms_usage(void) int main(int argc, char **argv) { - FILE *dumpfile = NULL; + FILE *dumpfile = NULL, *ref_file = NULL; int o; #ifdef __GNU_LIBRARY__ struct option long_opts[] = { {"arch", 1, 0, 'a'}, + {"asm", 0, 0, 'A'}, {"debug", 0, 0, 'd'}, {"warnings", 0, 0, 'w'}, {"quiet", 0, 0, 'q'}, {"dump", 0, 0, 'D'}, + {"reference", 1, 0, 'r'}, {"dump-types", 1, 0, 'T'}, + {"preserve", 0, 0, 'p'}, {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; - while ((o = getopt_long(argc, argv, "a:dwqVDT:h", + while ((o = getopt_long(argc, argv, "a:dwqVADr:T:ph", &long_opts[0], NULL)) != EOF) #else /* __GNU_LIBRARY__ */ - while ((o = getopt(argc, argv, "a:dwqVDT:h")) != EOF) + while ((o = getopt(argc, argv, "a:dwqVADr:T:ph")) != EOF) #endif /* __GNU_LIBRARY__ */ switch (o) { case 'a': @@ -502,9 +722,20 @@ int main(int argc, char **argv) case 'V': fputs("genksyms version 2.5.60\n", stderr); break; + case 'A': + flag_asm = 1; + break; case 'D': flag_dump_defs = 1; break; + case 'r': + flag_reference = 1; + ref_file = fopen(optarg, "r"); + if (!ref_file) { + perror(optarg); + return 1; + } + break; case 'T': flag_dump_types = 1; dumpfile = fopen(optarg, "w"); @@ -513,6 +744,9 @@ int main(int argc, char **argv) return 1; } break; + case 'p': + flag_preserve = 1; + break; case 'h': genksyms_usage(); return 0; @@ -533,12 +767,17 @@ int main(int argc, char **argv) /* setlinebuf(debugfile); */ } + if (flag_reference) + read_reference(ref_file); + yyparse(); if (flag_dump_types && visited_symbols) { while (visited_symbols != (struct symbol *)-1L) { struct symbol *sym = visited_symbols; + if (sym->is_override) + fputs("override ", dumpfile); if (sym->type != SYM_NORMAL) { putc(symbol_type_name[sym->type][0], dumpfile); putc('#', dumpfile); diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index 2668287aa49..25c4d40cefc 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h @@ -29,6 +29,10 @@ enum symbol_type { SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION }; +enum symbol_status { + STATUS_UNCHANGED, STATUS_DEFINED, STATUS_MODIFIED +}; + struct string_list { struct string_list *next; enum symbol_type tag; @@ -43,6 +47,9 @@ struct symbol { struct symbol *expansion_trail; struct symbol *visited; int is_extern; + int is_declared; + enum symbol_status status; + int is_override; }; typedef struct string_list **yystype; diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index 971e0113ae7..83484fe93ed 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.1 */ /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -32,7 +32,7 @@ #line 3 "scripts/genksyms/keywords.gperf" struct resword { const char *name; int token; }; -/* maximum key range = 62, duplicates = 0 */ +/* maximum key range = 64, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, - 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, - 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, - 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, - 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65 + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 0, + 67, 67, 67, 67, 67, 67, 15, 67, 67, 67, + 0, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 0, 67, 0, 67, 5, + 25, 20, 15, 30, 67, 15, 67, 67, 10, 0, + 10, 40, 20, 67, 10, 5, 0, 10, 15, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; } @@ -84,116 +84,119 @@ is_reserved_word (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 43, + TOTAL_KEYWORDS = 45, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 24, MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 64 + MAX_HASH_VALUE = 66 }; static const struct resword wordlist[] = { {""}, {""}, {""}, -#line 26 "scripts/genksyms/keywords.gperf" +#line 28 "scripts/genksyms/keywords.gperf" {"asm", ASM_KEYW}, {""}, -#line 8 "scripts/genksyms/keywords.gperf" +#line 10 "scripts/genksyms/keywords.gperf" {"__asm", ASM_KEYW}, {""}, -#line 9 "scripts/genksyms/keywords.gperf" +#line 11 "scripts/genksyms/keywords.gperf" {"__asm__", ASM_KEYW}, {""}, {""}, -#line 52 "scripts/genksyms/keywords.gperf" +#line 54 "scripts/genksyms/keywords.gperf" {"__typeof__", TYPEOF_KEYW}, {""}, -#line 12 "scripts/genksyms/keywords.gperf" - {"__const", CONST_KEYW}, -#line 11 "scripts/genksyms/keywords.gperf" - {"__attribute__", ATTRIBUTE_KEYW}, -#line 13 "scripts/genksyms/keywords.gperf" - {"__const__", CONST_KEYW}, -#line 18 "scripts/genksyms/keywords.gperf" - {"__signed__", SIGNED_KEYW}, -#line 44 "scripts/genksyms/keywords.gperf" - {"static", STATIC_KEYW}, -#line 20 "scripts/genksyms/keywords.gperf" - {"__volatile__", VOLATILE_KEYW}, -#line 39 "scripts/genksyms/keywords.gperf" - {"int", INT_KEYW}, -#line 32 "scripts/genksyms/keywords.gperf" - {"char", CHAR_KEYW}, -#line 33 "scripts/genksyms/keywords.gperf" - {"const", CONST_KEYW}, -#line 45 "scripts/genksyms/keywords.gperf" - {"struct", STRUCT_KEYW}, -#line 24 "scripts/genksyms/keywords.gperf" - {"__restrict__", RESTRICT_KEYW}, -#line 25 "scripts/genksyms/keywords.gperf" - {"restrict", RESTRICT_KEYW}, -#line 23 "scripts/genksyms/keywords.gperf" - {"_restrict", RESTRICT_KEYW}, -#line 16 "scripts/genksyms/keywords.gperf" - {"__inline__", INLINE_KEYW}, -#line 10 "scripts/genksyms/keywords.gperf" - {"__attribute", ATTRIBUTE_KEYW}, - {""}, #line 14 "scripts/genksyms/keywords.gperf" - {"__extension__", EXTENSION_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" - {"enum", ENUM_KEYW}, -#line 19 "scripts/genksyms/keywords.gperf" - {"__volatile", VOLATILE_KEYW}, -#line 36 "scripts/genksyms/keywords.gperf" - {"extern", EXTERN_KEYW}, + {"__const", CONST_KEYW}, +#line 13 "scripts/genksyms/keywords.gperf" + {"__attribute__", ATTRIBUTE_KEYW}, +#line 15 "scripts/genksyms/keywords.gperf" + {"__const__", CONST_KEYW}, +#line 20 "scripts/genksyms/keywords.gperf" + {"__signed__", SIGNED_KEYW}, +#line 46 "scripts/genksyms/keywords.gperf" + {"static", STATIC_KEYW}, {""}, -#line 17 "scripts/genksyms/keywords.gperf" - {"__signed", SIGNED_KEYW}, +#line 41 "scripts/genksyms/keywords.gperf" + {"int", INT_KEYW}, +#line 34 "scripts/genksyms/keywords.gperf" + {"char", CHAR_KEYW}, +#line 35 "scripts/genksyms/keywords.gperf" + {"const", CONST_KEYW}, +#line 47 "scripts/genksyms/keywords.gperf" + {"struct", STRUCT_KEYW}, +#line 26 "scripts/genksyms/keywords.gperf" + {"__restrict__", RESTRICT_KEYW}, +#line 27 "scripts/genksyms/keywords.gperf" + {"restrict", RESTRICT_KEYW}, #line 7 "scripts/genksyms/keywords.gperf" {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, - {""}, -#line 51 "scripts/genksyms/keywords.gperf" - {"typeof", TYPEOF_KEYW}, -#line 46 "scripts/genksyms/keywords.gperf" - {"typedef", TYPEDEF_KEYW}, -#line 15 "scripts/genksyms/keywords.gperf" - {"__inline", INLINE_KEYW}, -#line 31 "scripts/genksyms/keywords.gperf" - {"auto", AUTO_KEYW}, -#line 47 "scripts/genksyms/keywords.gperf" - {"union", UNION_KEYW}, - {""}, {""}, -#line 48 "scripts/genksyms/keywords.gperf" - {"unsigned", UNSIGNED_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" - {"void", VOID_KEYW}, -#line 42 "scripts/genksyms/keywords.gperf" - {"short", SHORT_KEYW}, - {""}, {""}, -#line 50 "scripts/genksyms/keywords.gperf" - {"volatile", VOLATILE_KEYW}, - {""}, -#line 37 "scripts/genksyms/keywords.gperf" - {"float", FLOAT_KEYW}, -#line 34 "scripts/genksyms/keywords.gperf" - {"double", DOUBLE_KEYW}, - {""}, -#line 5 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, - {""}, {""}, -#line 38 "scripts/genksyms/keywords.gperf" - {"inline", INLINE_KEYW}, -#line 6 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 41 "scripts/genksyms/keywords.gperf" - {"register", REGISTER_KEYW}, +#line 18 "scripts/genksyms/keywords.gperf" + {"__inline__", INLINE_KEYW}, {""}, #line 22 "scripts/genksyms/keywords.gperf" - {"_Bool", BOOL_KEYW}, -#line 43 "scripts/genksyms/keywords.gperf" - {"signed", SIGNED_KEYW}, + {"__volatile__", VOLATILE_KEYW}, +#line 5 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 25 "scripts/genksyms/keywords.gperf" + {"_restrict", RESTRICT_KEYW}, + {""}, +#line 12 "scripts/genksyms/keywords.gperf" + {"__attribute", ATTRIBUTE_KEYW}, +#line 6 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 16 "scripts/genksyms/keywords.gperf" + {"__extension__", EXTENSION_KEYW}, +#line 37 "scripts/genksyms/keywords.gperf" + {"enum", ENUM_KEYW}, +#line 8 "scripts/genksyms/keywords.gperf" + {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 38 "scripts/genksyms/keywords.gperf" + {"extern", EXTERN_KEYW}, + {""}, +#line 19 "scripts/genksyms/keywords.gperf" + {"__signed", SIGNED_KEYW}, +#line 9 "scripts/genksyms/keywords.gperf" + {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 49 "scripts/genksyms/keywords.gperf" + {"union", UNION_KEYW}, +#line 53 "scripts/genksyms/keywords.gperf" + {"typeof", TYPEOF_KEYW}, +#line 48 "scripts/genksyms/keywords.gperf" + {"typedef", TYPEDEF_KEYW}, +#line 17 "scripts/genksyms/keywords.gperf" + {"__inline", INLINE_KEYW}, +#line 33 "scripts/genksyms/keywords.gperf" + {"auto", AUTO_KEYW}, +#line 21 "scripts/genksyms/keywords.gperf" + {"__volatile", VOLATILE_KEYW}, {""}, {""}, +#line 50 "scripts/genksyms/keywords.gperf" + {"unsigned", UNSIGNED_KEYW}, + {""}, +#line 44 "scripts/genksyms/keywords.gperf" + {"short", SHORT_KEYW}, #line 40 "scripts/genksyms/keywords.gperf" - {"long", LONG_KEYW} + {"inline", INLINE_KEYW}, + {""}, +#line 52 "scripts/genksyms/keywords.gperf" + {"volatile", VOLATILE_KEYW}, +#line 42 "scripts/genksyms/keywords.gperf" + {"long", LONG_KEYW}, +#line 24 "scripts/genksyms/keywords.gperf" + {"_Bool", BOOL_KEYW}, + {""}, {""}, +#line 43 "scripts/genksyms/keywords.gperf" + {"register", REGISTER_KEYW}, +#line 51 "scripts/genksyms/keywords.gperf" + {"void", VOID_KEYW}, +#line 39 "scripts/genksyms/keywords.gperf" + {"float", FLOAT_KEYW}, +#line 36 "scripts/genksyms/keywords.gperf" + {"double", DOUBLE_KEYW}, + {""}, {""}, {""}, {""}, +#line 45 "scripts/genksyms/keywords.gperf" + {"signed", SIGNED_KEYW} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index 5ef3733225f..8abe7ab8d88 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf @@ -5,6 +5,8 @@ struct resword { const char *name; int token; } EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW __asm, ASM_KEYW __asm__, ASM_KEYW __attribute, ATTRIBUTE_KEYW diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl new file mode 100755 index 00000000000..97399da89ef --- /dev/null +++ b/scripts/headerdep.pl @@ -0,0 +1,193 @@ +#! /usr/bin/perl +# +# Detect cycles in the header file dependency graph +# Vegard Nossum +# + +use strict; +use warnings; + +use Getopt::Long; + +my $opt_all; +my @opt_include; +my $opt_graph; + +&Getopt::Long::Configure(qw(bundling pass_through)); +&GetOptions( + help => \&help, + version => \&version, + + all => \$opt_all, + I => \@opt_include, + graph => \$opt_graph, +); + +push @opt_include, 'include'; +my %deps = (); +my %linenos = (); + +my @headers = grep { strip($_) } @ARGV; + +parse_all(@headers); + +if($opt_graph) { + graph(); +} else { + detect_cycles(@headers); +} + + +sub help { + print "Usage: $0 [options] file...\n"; + print "\n"; + print "Options:\n"; + print " --all\n"; + print " --graph\n"; + print "\n"; + print " -I includedir\n"; + print "\n"; + print "To make nice graphs, try:\n"; + print " $0 --graph include/linux/kernel.h | dot -Tpng -o graph.png\n"; + exit; +} + +sub version { + print "headerdep version 2\n"; + exit; +} + +# Get a file name that is relative to our include paths +sub strip { + my $filename = shift; + + for my $i (@opt_include) { + my $stripped = $filename; + $stripped =~ s/^$i\///; + + return $stripped if $stripped ne $filename; + } + + return $filename; +} + +# Search for the file name in the list of include paths +sub search { + my $filename = shift; + return $filename if -f $filename; + + for my $i (@opt_include) { + my $path = "$i/$filename"; + return $path if -f $path; + } + + return undef; +} + +sub parse_all { + # Parse all the headers. + my @queue = @_; + while(@queue) { + my $header = pop @queue; + next if exists $deps{$header}; + + $deps{$header} = [] unless exists $deps{$header}; + + my $path = search($header); + next unless $path; + + open(my $file, '<', $path) or die($!); + chomp(my @lines = <$file>); + close($file); + + for my $i (0 .. $#lines) { + my $line = $lines[$i]; + if(my($dep) = ($line =~ m/^#\s*include\s*<(.*?)>/)) { + push @queue, $dep; + push @{$deps{$header}}, [$i + 1, $dep]; + } + } + } +} + +sub print_cycle { + # $cycle[n] includes $cycle[n + 1]; + # $cycle[-1] will be the culprit + my $cycle = shift; + + # Adjust the line numbers + for my $i (0 .. $#$cycle - 1) { + $cycle->[$i]->[0] = $cycle->[$i + 1]->[0]; + } + $cycle->[-1]->[0] = 0; + + my $first = shift @$cycle; + my $last = pop @$cycle; + + my $msg = "In file included"; + printf "%s from %s,\n", $msg, $last->[1] if defined $last; + + for my $header (reverse @$cycle) { + printf "%s from %s:%d%s\n", + " " x length $msg, + $header->[1], $header->[0], + $header->[1] eq $last->[1] ? ' <-- here' : ''; + } + + printf "%s:%d: warning: recursive header inclusion\n", + $first->[1], $first->[0]; +} + +# Find and print the smallest cycle starting in the specified node. +sub detect_cycles { + my @queue = map { [[0, $_]] } @_; + while(@queue) { + my $top = pop @queue; + my $name = $top->[-1]->[1]; + + for my $dep (@{$deps{$name}}) { + my $chain = [@$top, [$dep->[0], $dep->[1]]]; + + # If the dep already exists in the chain, we have a + # cycle... + if(grep { $_->[1] eq $dep->[1] } @$top) { + print_cycle($chain); + next if $opt_all; + return; + } + + push @queue, $chain; + } + } +} + +sub mangle { + $_ = shift; + s/\//__/g; + s/\./_/g; + s/-/_/g; + $_; +} + +# Output dependency graph in GraphViz language. +sub graph { + print "digraph {\n"; + + print "\t/* vertices */\n"; + for my $header (keys %deps) { + printf "\t%s [label=\"%s\"];\n", + mangle($header), $header; + } + + print "\n"; + + print "\t/* edges */\n"; + for my $header (keys %deps) { + for my $dep (@{$deps{$header}}) { + printf "\t%s -> %s;\n", + mangle($header), mangle($dep->[1]); + } + } + + print "}\n"; +} diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index ad2434b2697..92758120a76 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -130,18 +130,9 @@ static int read_symbol(FILE *in, struct sym_entry *s) static int symbol_valid(struct sym_entry *s) { /* Symbols which vary between passes. Passes 1 and 2 must have - * identical symbol lists. The kallsyms_* symbols below are only added - * after pass 1, they would be included in pass 2 when --all-symbols is - * specified so exclude them to get a stable symbol list. + * identical symbol lists. */ static char *special_symbols[] = { - "kallsyms_addresses", - "kallsyms_num_syms", - "kallsyms_names", - "kallsyms_markers", - "kallsyms_token_table", - "kallsyms_token_index", - /* Exclude linker generated symbols which vary between passes */ "_SDA_BASE_", /* ppc */ "_SDA2_BASE_", /* ppc */ @@ -173,7 +164,9 @@ static int symbol_valid(struct sym_entry *s) } /* Exclude symbols which vary between passes. */ - if (strstr((char *)s->sym + offset, "_compiled.")) + if (strstr((char *)s->sym + offset, "_compiled.") || + strncmp((char*)s->sym + offset, "__compound_literal.", 19) == 0 || + strncmp((char*)s->sym + offset, "__compound_literal$", 19) == 0) return 0; for (i = 0; special_symbols[i]; i++) @@ -550,8 +543,10 @@ int main(int argc, char **argv) usage(); read_map(stdin); - sort_symbols(); - optimize_token_table(); + if (table_cnt) { + sort_symbols(); + optimize_token_table(); + } write_src(); return 0; diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 5552154cbed..fcef0f59d55 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -52,7 +52,7 @@ EOF } usage() { - printf "Usage: $0 [-check compiler options|-header|-library]\n" + printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n" } if [ $# -eq 0 ]; then diff --git a/scripts/kernel-doc b/scripts/kernel-doc index d27aad78e1d..8bb83a100ed 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -289,6 +289,8 @@ my %parameterdescs; my @parameterlist; my %sections; my @sectionlist; +my $sectcheck; +my $struct_actual; my $contents = ""; my $section_default = "Description"; # default section @@ -378,10 +380,12 @@ sub dump_section { # print STDERR "parameter def '$1' = '$contents'\n"; $name = $1; $parameterdescs{$name} = $contents; + $sectcheck = $sectcheck . $name . " "; } elsif ($name eq "@\.\.\.") { # print STDERR "parameter def '...' = '$contents'\n"; $name = "..."; $parameterdescs{$name} = $contents; + $sectcheck = $sectcheck . $name . " "; } else { # print STDERR "other section '$name' = '$contents'\n"; if (defined($sections{$name}) && ($sections{$name} ne "")) { @@ -1405,21 +1409,25 @@ sub dump_union($$) { sub dump_struct($$) { my $x = shift; my $file = shift; + my $nested; if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { $declaration_name = $2; my $members = $3; # ignore embedded structs or unions - $members =~ s/{.*}//g; + $members =~ s/({.*})//g; + $nested = $1; # ignore members marked private: $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos; $members =~ s/\/\*.*?private:.*//gos; # strip comments: $members =~ s/\/\*.*?\*\///gos; + $nested =~ s/\/\*.*?\*\///gos; create_parameterlist($members, ';', $file); + check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested); output_declaration($declaration_name, 'struct', @@ -1505,6 +1513,14 @@ sub dump_typedef($$) { } } +sub save_struct_actual($) { + my $actual = shift; + + # strip all spaces from the actual param so that it looks like one string item + $actual =~ s/\s*//g; + $struct_actual = $struct_actual . $actual . " "; +} + sub create_parameterlist($$$) { my $args = shift; my $splitter = shift; @@ -1537,6 +1553,7 @@ sub create_parameterlist($$$) { $param = $1; $type = $arg; $type =~ s/([^\(]+\(\*?)\s*$param/$1/; + save_struct_actual($param); push_parameter($param, $type, $file); } elsif ($arg) { $arg =~ s/\s*:\s*/:/g; @@ -1561,14 +1578,17 @@ sub create_parameterlist($$$) { foreach $param (@args) { if ($param =~ m/^(\*+)\s*(.*)/) { + save_struct_actual($2); push_parameter($2, "$type $1", $file); } elsif ($param =~ m/(.*?):(\d+)/) { if ($type ne "") { # skip unnamed bit-fields + save_struct_actual($1); push_parameter($1, "$type:$2", $file) } } else { + save_struct_actual($param); push_parameter($param, $type, $file); } } @@ -1634,6 +1654,46 @@ sub push_parameter($$$) { $parametertypes{$param} = $type; } +sub check_sections($$$$$$) { + my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_; + my @sects = split ' ', $sectcheck; + my @prms = split ' ', $prmscheck; + my $err; + my ($px, $sx); + my $prm_clean; # strip trailing "[array size]" and/or beginning "*" + + foreach $sx (0 .. $#sects) { + $err = 1; + foreach $px (0 .. $#prms) { + $prm_clean = $prms[$px]; + $prm_clean =~ s/\[.*\]//; + $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//; + ##$prm_clean =~ s/^\**//; + if ($prm_clean eq $sects[$sx]) { + $err = 0; + last; + } + } + if ($err) { + if ($decl_type eq "function") { + print STDERR "Warning(${file}:$.): " . + "Excess function parameter " . + "'$sects[$sx]' " . + "description in '$decl_name'\n"; + ++$warnings; + } else { + if ($nested !~ m/\Q$sects[$sx]\E/) { + print STDERR "Warning(${file}:$.): " . + "Excess struct/union/enum/typedef member " . + "'$sects[$sx]' " . + "description in '$decl_name'\n"; + ++$warnings; + } + } + } + } +} + ## # takes a function prototype and the name of the current file being # processed and spits out all the details stored in the global @@ -1699,6 +1759,9 @@ sub dump_function($$) { return; } + my $prms = join " ", @parameterlist; + check_sections($file, $declaration_name, "function", $sectcheck, $prms, ""); + output_declaration($declaration_name, 'function', {'function' => $declaration_name, @@ -1757,6 +1820,8 @@ sub reset_state { @parameterlist = (); %sections = (); @sectionlist = (); + $sectcheck = ""; + $struct_actual = ""; $prototype = ""; $state = 0; diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index a8740df07b0..6a12dd9f118 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -4,6 +4,8 @@ SMP=$3 PREEMPT=$4 CC=$5 +vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } + # If compile.h exists already and we don't own autoconf.h # (i.e. we're not the same user who did make *config), don't # modify compile.h @@ -11,7 +13,7 @@ CC=$5 # do "compiled by root" if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then - echo " SKIPPED $TARGET" + vecho " SKIPPED $TARGET" exit 0 fi @@ -89,7 +91,7 @@ if [ -r $TARGET ] && \ cmp -s .tmpver.1 .tmpver.2; then rm -f .tmpcompile else - echo " UPD $TARGET" + vecho " UPD $TARGET" mv -f .tmpcompile $TARGET fi rm -f .tmpver.1 .tmpver.2 diff --git a/scripts/mkmakefile b/scripts/mkmakefile index e65d8b33faa..67d59c7a18d 100644 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile @@ -17,7 +17,9 @@ if test -e $2/Makefile && ! grep -q Automatically $2/Makefile then exit 0 fi -echo " GEN $2/Makefile" +if [ "${quiet}" != "silent_" ]; then + echo " GEN $2/Makefile" +fi cat << EOF > $2/Makefile # Automatically generated by $0: don't edit diff --git a/scripts/mksysmap b/scripts/mksysmap index 6e133a0bae7..1db316a3712 100644 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -37,9 +37,6 @@ # readprofile starts reading symbols when _stext is found, and # continue until it finds a symbol which is not either of 'T', 't', -# 'W' or 'w'. __crc_ are 'A' and placed in the middle -# so we just ignore them to let readprofile continue to work. -# (At least sparc64 has __crc_ in the middle). - -$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2 +# 'W' or 'w'. +$NM -n $1 | grep -v '\( [aNUw] \)\|\( \$[adt]\)' > $2 diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 5e326078a4a..8c6b7b09606 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -1,10 +1,6 @@ # Makefile for the different targets used to generate full packages of a kernel # It uses the generic clean infrastructure of kbuild -# Ignore the following files/directories during tar operation -TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS - - # RPM target # --------------------------------------------------------------------------- # The rpm target generates two rpm files: @@ -47,7 +43,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE set -e; \ mv -f $(objtree)/.tmp_version $(objtree)/.version - $(RPM) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz + $(RPM) $(RPMOPTS) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz rm ../$(KERNELPATH).tar.gz clean-files := $(objtree)/kernel.spec @@ -64,7 +60,8 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE set -e; \ mv -f $(objtree)/.tmp_version $(objtree)/.version - $(RPM) --define "_builddir $(srctree)" --target $(UTS_MACHINE) -bb $< + $(RPM) $(RPMOPTS) --define "_builddir $(srctree)" --target \ + $(UTS_MACHINE) -bb $< clean-files += $(objtree)/binkernel.spec diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 72d233528ad..f6946cf99ce 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -19,6 +19,11 @@ if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then fi fi + # Is this git on svn? + if git config --get svn-remote.svn.url >/dev/null; then + printf -- '-svn%s' "`git-svn find-rev $head`" + fi + # Are there uncommitted changes? git update-index --refresh --unmerged > /dev/null if git diff-index --name-only HEAD | grep -v "^scripts/package" \ @@ -51,7 +56,7 @@ if hgid=`hg id 2>/dev/null`; then fi # Check for svn and a svn repo. -if rev=`svn info 2>/dev/null | grep '^Revision'`; then +if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then rev=`echo $rev | awk '{print $NF}'` changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l` diff --git a/scripts/strip-symbols b/scripts/strip-symbols new file mode 100644 index 00000000000..29ee8c1a014 --- /dev/null +++ b/scripts/strip-symbols @@ -0,0 +1,22 @@ +<*> +*.h +__compound_literal[$.][0-9]* +__crc_[a-zA-Z_]* +__exitcall_[a-zA-Z_]* +__func__[$.][0-9]* +__FUNCTION__[$.][0-9]* +gcc[0-9]_compiled[$.] +__initcall_[a-zA-Z_]* +__kcrctab_[a-zA-Z_]* +__kstrtab_[a-zA-Z_]* +__ksymtab_[a-zA-Z_]* +__mod_[a-zA-Z_]*[0-9] +__module_depends +__param_[a-zA-Z_]* +__pci_fixup_*PCI_ANY_IDPCI_ANY_ID* +__pci_fixup_*PCI_ANY_IDPCI_DEVICE_ID_* +__pci_fixup_*PCI_VENDOR_ID_*PCI_ANY_ID* +__pci_fixup_*PCI_VENDOR_ID_*PCI_DEVICE_ID_* +__PRETTY_FUNCTION__[$.][0-9]* +__setup_[a-zA-Z_]* +____versions diff --git a/scripts/tags.sh b/scripts/tags.sh new file mode 100755 index 00000000000..4e754720985 --- /dev/null +++ b/scripts/tags.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# Generate tags or cscope files +# Usage tags.sh +# +# mode may be any of: tags, TAGS, cscope +# +# Uses the following environment variables: +# ARCH, SUBARCH, srctree, src, obj + +if [ "$KBUILD_VERBOSE" = "1" ]; then + set -x +fi + +# This is a duplicate of RCS_FIND_IGNORE without escaped '()' +ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \ + -name CVS -o -name .pc -o -name .hg -o \ + -name .git ) \ + -prune -o" + +# Do not use full path is we do not use O=.. builds +if [ "${KBUILD_SRC}" = "" ]; then + tree= +else + tree=${srctree}/ +fi + +# find sources in arch/$ARCH +find_arch_sources() +{ + find ${tree}arch/$1 $ignore -name "$2" -print; +} + +# find sources in arch/$1/include +find_arch_include_sources() +{ + find ${tree}arch/$1/include $ignore -name "$2" -print; +} + +# find sources in include/ +find_include_sources() +{ + find ${tree}include $ignore -name config -prune -o -name "$1" -print; +} + +# find sources in rest of tree +# we could benefit from a list of dirs to search in here +find_other_sources() +{ + find ${tree}* $ignore \ + \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \ + -name "$1" -print; +} + +find_sources() +{ + find_arch_sources $1 "$2" + find_include_sources "$2" + find_other_sources "$2" +} + +all_sources() +{ + find_sources $SRCARCH '*.[chS]' + if [ ! -z "$archinclude" ]; then + find_arch_include_sources $archinclude '*.[chS]' + fi +} + +all_kconfigs() +{ + find_sources $SRCARCH 'Kconfig*' +} + +all_defconfigs() +{ + find_sources $SRCARCH "defconfig" +} + +docscope() +{ + (echo \-k; echo \-q; all_sources) > cscope.files + cscope -b -f cscope.out +} + +exuberant() +{ + all_sources > all + all_sources | xargs $1 -a \ + -I __initdata,__exitdata,__acquires,__releases \ + -I __read_mostly,____cacheline_aligned \ + -I ____cacheline_aligned_in_smp \ + -I ____cacheline_internodealigned_in_smp \ + -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ + --extra=+f --c-kinds=+px \ + --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' + + all_kconfigs | xargs $1 -a \ + --langdef=kconfig --language-force=kconfig \ + --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/' + + all_kconfigs | xargs $1 -a \ + --langdef=kconfig --language-force=kconfig \ + --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/' + + all_defconfigs | xargs -r $1 -a \ + --langdef=dotconfig --language-force=dotconfig \ + --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' + +} + +emacs() +{ + all_sources | xargs $1 -a + + all_kconfigs | xargs $1 -a \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' + + all_kconfigs | xargs $1 -a \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/' + + all_defconfigs | xargs -r $1 -a \ + --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/' +} + +xtags() +{ + if $1 --version 2>&1 | grep -iq exuberant; then + exuberant $1 + elif $1 --version 2>&1 | grep -iq emacs; then + emacs $1 + else + all_sources | xargs $1 -a + fi +} + + +# Support um (which uses SUBARCH) +if [ "${ARCH}" = "um" ]; then + if [ "$SUBARCH" = "i386" ]; then + archinclude=x86 + elif [ "$SUBARCH" = "x86_64" ]; then + archinclude=x86 + else + archinclude=${SUBARCH} + fi +fi + +case "$1" in + "cscope") + docscope + ;; + + "tags") + xtags ctags + ;; + + "TAGS") + xtags etags + ;; +esac diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 7abc07f0fcd..f1d3fe34176 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -370,6 +370,30 @@ error: return rc; } +static char *cpio_replace_env(char *new_location) +{ + char expanded[PATH_MAX + 1]; + char env_var[PATH_MAX + 1]; + char *start; + char *end; + + for (start = NULL; (start = strstr(new_location, "${")); ) { + end = strchr(start, '}'); + if (start < end) { + *env_var = *expanded = '\0'; + strncat(env_var, start + 2, end - start - 2); + strncat(expanded, new_location, start - new_location); + strncat(expanded, getenv(env_var), PATH_MAX); + strncat(expanded, end + 1, PATH_MAX); + strncpy(new_location, expanded, PATH_MAX); + } else + break; + } + + return new_location; +} + + static int cpio_mkfile_line(const char *line) { char name[PATH_MAX + 1]; @@ -415,7 +439,8 @@ static int cpio_mkfile_line(const char *line) } else { dname = name; } - rc = cpio_mkfile(dname, location, mode, uid, gid, nlinks); + rc = cpio_mkfile(dname, cpio_replace_env(location), + mode, uid, gid, nlinks); fail: if (dname_len) free(dname); return rc; @@ -439,6 +464,7 @@ void usage(const char *prog) "\n" " name of the file/dir/nod/etc in the archive\n" " location of the file in the current filesystem\n" + " expands shell variables quoted with ${}\n" " link target\n" " mode/permissions of the file\n" " user id (0=root)\n"