Commit 96faec94 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next

* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next: (25 commits)
  allow stripping of generated symbols under CONFIG_KALLSYMS_ALL
  kbuild: strip generated symbols from *.ko
  kbuild: simplify use of genksyms
  kernel-doc: check for extra kernel-doc notations
  kbuild: add headerdep used to detect inclusion cycles in header files
  kbuild: fix string equality testing in tags.sh
  kbuild: fix make tags/cscope
  kbuild: fix make incompatibility
  kbuild: remove TAR_IGNORE
  setlocalversion: add git-svn support
  setlocalversion: print correct subversion revision
  scripts: improve the decodecode script
  scripts/package: allow custom options to rpm
  genksyms: allow to ignore symbol checksum changes
  genksyms: track symbol checksum changes
  tags and cscope support really belongs in a shell script
  kconfig: fix options to check-lxdialog.sh
  kbuild: gen_init_cpio expands shell variables in file names
  remove bashisms from scripts/extract-ikconfig
  kbuild: teach mkmakfile to be silent
  ...
parents 29263285 9bb48247
...@@ -383,6 +383,20 @@ more details, with real examples. ...@@ -383,6 +383,20 @@ more details, with real examples.
to prerequisites are referenced with $(src) (because they are not to prerequisites are referenced with $(src) (because they are not
generated files). 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 --- 3.11 $(CC) support functions
The kernel may be built with several different versions of The kernel may be built with several different versions of
......
...@@ -336,7 +336,7 @@ LINUXINCLUDE := -Iinclude \ ...@@ -336,7 +336,7 @@ LINUXINCLUDE := -Iinclude \
-I$(srctree)/arch/$(hdr-arch)/include \ -I$(srctree)/arch/$(hdr-arch)/include \
-include include/linux/autoconf.h -include include/linux/autoconf.h
KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) KBUILD_CPPFLAGS := -D__KERNEL__
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \ -fno-strict-aliasing -fno-common \
...@@ -439,7 +439,11 @@ ifeq ($(config-targets),1) ...@@ -439,7 +439,11 @@ ifeq ($(config-targets),1)
include $(srctree)/arch/$(SRCARCH)/Makefile include $(srctree)/arch/$(SRCARCH)/Makefile
export KBUILD_DEFCONFIG KBUILD_KCONFIG 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)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig $@ $(Q)$(MAKE) $(build)=scripts/kconfig $@
...@@ -600,20 +604,25 @@ export INSTALL_PATH ?= /boot ...@@ -600,20 +604,25 @@ export INSTALL_PATH ?= /boot
MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
export MODLIB export MODLIB
# strip-symbols := $(srctree)/scripts/strip-symbols \
# INSTALL_MOD_STRIP, if defined, will cause modules to be $(wildcard $(srctree)/arch/$(ARCH)/scripts/strip-symbols)
# 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.
#
# 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 ifdef INSTALL_MOD_STRIP
ifeq ($(INSTALL_MOD_STRIP),1) 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 else
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) mod_strip_cmd = $(OBJCOPY) $(INSTALL_MOD_STRIP)
endif # INSTALL_MOD_STRIP=1 endif # INSTALL_MOD_STRIP=1
else else
mod_strip_cmd = true mod_strip_cmd = false
endif # INSTALL_MOD_STRIP endif # INSTALL_MOD_STRIP
export mod_strip_cmd export mod_strip_cmd
...@@ -743,6 +752,7 @@ last_kallsyms := 2 ...@@ -743,6 +752,7 @@ last_kallsyms := 2
endif endif
kallsyms.o := .tmp_kallsyms$(last_kallsyms).o kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
kallsyms.h := $(wildcard include/config/kallsyms/*.h) $(wildcard include/config/kallsyms/*/*.h)
define verify_kallsyms define verify_kallsyms
$(Q)$(if $($(quiet)cmd_sysmap), \ $(Q)$(if $($(quiet)cmd_sysmap), \
...@@ -767,24 +777,41 @@ endef ...@@ -767,24 +777,41 @@ endef
# Generate .S file with all kernel symbols # Generate .S file with all kernel symbols
quiet_cmd_kallsyms = KSYM $@ quiet_cmd_kallsyms = KSYM $@
cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \ cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } \
$(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@ | $(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) $(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) $(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 must be complete except kallsyms, so update vmlinux version
.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE .tmp_vmlinux%: $(vmlinux-lds) $(vmlinux-all) FORCE
$(call if_changed_rule,ksym_ld) $(if $(filter 1,$*),$(call if_changed_rule,ksym_ld),$(call if_changed,vmlinux__))
.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE .tmp_vmlinux0$(strip-ext):
$(call if_changed,vmlinux__) $(Q)echo "placeholder" >$@
.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE .tmp_vmlinux1: .tmp_kallsyms0.o
$(call if_changed,vmlinux__) .tmp_vmlinux2: .tmp_kallsyms1.o
.tmp_vmlinux3: .tmp_kallsyms2.o
# Needs to visit scripts/ before $(KALLSYMS) can be used. # Needs to visit scripts/ before $(KALLSYMS) can be used.
$(KALLSYMS): scripts ; $(KALLSYMS): scripts ;
...@@ -926,7 +953,7 @@ PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 ...@@ -926,7 +953,7 @@ PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
# 2) Create the include2 directory, used for the second asm symlink # 2) Create the include2 directory, used for the second asm symlink
prepare3: include/config/kernel.release prepare3: include/config/kernel.release
ifneq ($(KBUILD_SRC),) 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 \ $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \
echo " $(srctree) is not clean, please run 'make mrproper'";\ echo " $(srctree) is not clean, please run 'make mrproper'";\
echo " in the '$(srctree)' directory.";\ echo " in the '$(srctree)' directory.";\
...@@ -983,7 +1010,7 @@ endef ...@@ -983,7 +1010,7 @@ endef
# directory for generated filesas used by some architectures. # directory for generated filesas used by some architectures.
define create-symlink define create-symlink
if [ ! -L include/asm ]; then \ if [ ! -L include/asm ]; then \
echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ $(kecho) ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \
if [ ! -d include/asm-$(SRCARCH) ]; then \ if [ ! -d include/asm-$(SRCARCH) ]; then \
mkdir -p include/asm-$(SRCARCH); \ mkdir -p include/asm-$(SRCARCH); \
fi; \ fi; \
...@@ -1022,6 +1049,10 @@ include/linux/version.h: $(srctree)/Makefile FORCE ...@@ -1022,6 +1049,10 @@ include/linux/version.h: $(srctree)/Makefile FORCE
include/linux/utsrelease.h: include/config/kernel.release FORCE include/linux/utsrelease.h: include/config/kernel.release FORCE
$(call filechk,utsrelease.h) $(call filechk,utsrelease.h)
PHONY += headerdep
headerdep:
$(Q)find include/ -name '*.h' | xargs --max-args 1 scripts/headerdep.pl
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
PHONY += depend dep PHONY += depend dep
...@@ -1096,7 +1127,7 @@ all: modules ...@@ -1096,7 +1127,7 @@ all: modules
PHONY += modules PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order $(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.modpost
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild
...@@ -1270,7 +1301,8 @@ help: ...@@ -1270,7 +1301,8 @@ help:
@echo ' versioncheck - Sanity check on version.h usage' @echo ' versioncheck - Sanity check on version.h usage'
@echo ' includecheck - Check for duplicate included header files' @echo ' includecheck - Check for duplicate included header files'
@echo ' export_report - List the usages of all exported symbols' @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 ''
@echo 'Kernel packaging:' @echo 'Kernel packaging:'
@$(MAKE) $(build)=$(package-dir) help @$(MAKE) $(build)=$(package-dir) help
...@@ -1360,7 +1392,7 @@ $(module-dirs): crmodverdir $(objtree)/Module.symvers ...@@ -1360,7 +1392,7 @@ $(module-dirs): crmodverdir $(objtree)/Module.symvers
$(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@) $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
modules: $(module-dirs) modules: $(module-dirs)
@echo ' Building modules, stage 2.'; @$(kecho) ' Building modules, stage 2.';
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
PHONY += modules_install PHONY += modules_install
...@@ -1409,123 +1441,12 @@ endif # KBUILD_EXTMOD ...@@ -1409,123 +1441,12 @@ endif # KBUILD_EXTMOD
# Generate tags for editors # 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 tags TAGS cscope: FORCE
#(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
$(call cmd,tags) $(call cmd,tags)
# Scripts to check various things for consistency # Scripts to check various things for consistency
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
...@@ -1604,7 +1525,11 @@ endif ...@@ -1604,7 +1525,11 @@ endif
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
# Modules # 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) $(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(build)=$(build-dir)
...@@ -1638,7 +1563,7 @@ cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \ ...@@ -1638,7 +1563,7 @@ cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
$(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*) $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \ 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) $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
quiet_cmd_as_o_S = AS $@ quiet_cmd_as_o_S = AS $@
......
...@@ -25,7 +25,7 @@ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE ...@@ -25,7 +25,7 @@ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
$(obj)/vmImage: $(obj)/vmlinux.gz $(obj)/vmImage: $(obj)/vmlinux.gz
$(call if_changed,uimage) $(call if_changed,uimage)
@echo 'Kernel: $@ is ready' @$(kecho) 'Kernel: $@ is ready'
install: install:
sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
__cpu_vendor_dev_X86_VENDOR_*
...@@ -588,6 +588,13 @@ config KALLSYMS_ALL ...@@ -588,6 +588,13 @@ config KALLSYMS_ALL
Say N. 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 config KALLSYMS_EXTRA_PASS
bool "Do an extra kallsyms pass" bool "Do an extra kallsyms pass"
depends on KALLSYMS depends on KALLSYMS
......
...@@ -30,20 +30,19 @@ ...@@ -30,20 +30,19 @@
#define all_var 0 #define all_var 0
#endif #endif
/* These will be re-linked against their real values during the second link stage */ extern const unsigned long kallsyms_addresses[];
extern const unsigned long kallsyms_addresses[] __attribute__((weak)); extern const u8 kallsyms_names[];
extern const u8 kallsyms_names[] __attribute__((weak));
/* tell the compiler that the count isn't in the small data section if the arch /* tell the compiler that the count isn't in the small data section if the arch
* has one (eg: FRV) * has one (eg: FRV)
*/ */
extern const unsigned long kallsyms_num_syms extern const unsigned long kallsyms_num_syms
__attribute__((weak, section(".rodata"))); __attribute__((__section__(".rodata")));
extern const u8 kallsyms_token_table[] __attribute__((weak)); extern const u8 kallsyms_token_table[];
extern const u16 kallsyms_token_index[] __attribute__((weak)); 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) static inline int is_kernel_inittext(unsigned long addr)
{ {
...@@ -168,9 +167,6 @@ static unsigned long get_symbol_pos(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 symbol_start = 0, symbol_end = 0;
unsigned long i, low, high, mid; 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 */ /* do a binary search on the sorted kallsyms_addresses array */
low = 0; low = 0;
high = kallsyms_num_syms; high = kallsyms_num_syms;
......
...@@ -24,6 +24,13 @@ basetarget = $(basename $(notdir $@)) ...@@ -24,6 +24,13 @@ basetarget = $(basename $(notdir $@))
# Escape single quote for use in echo statements # Escape single quote for use in echo statements
escsq = $(subst $(squote),'\$(squote)',$1) 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. # filechk is used to check if the content of a generated file is updated.
# Sample usage: # Sample usage:
...@@ -39,22 +46,15 @@ escsq = $(subst $(squote),'\$(squote)',$1) ...@@ -39,22 +46,15 @@ escsq = $(subst $(squote),'\$(squote)',$1)
# - If they are equal no change, and no timestamp update # - If they are equal no change, and no timestamp update
# - stdin is piped in from the first prerequisite ($<) so one has # - stdin is piped in from the first prerequisite ($<) so one has
# to specify a valid file as first prerequisite (often the kbuild file) # 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 define filechk
$(Q)set -e; \ $(Q)set -e; \
$($(quiet)chk_filechk); \ $(kecho) ' CHK $@'; \
mkdir -p $(dir $@); \ mkdir -p $(dir $@); \
$(filechk_$(1)) < $< > $@.tmp; \ $(filechk_$(1)) < $< > $@.tmp; \
if [ -r $@ ] && cmp -s $@ $@.tmp; then \ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
rm -f $@.tmp; \ rm -f $@.tmp; \
else \ else \
$($(quiet)upd_filechk); \ $(kecho) ' UPD $@'; \
mv -f $@.tmp $@; \ mv -f $@.tmp $@; \
fi fi
endef endef
...@@ -144,7 +144,9 @@ ld-option = $(call try-run,\ ...@@ -144,7 +144,9 @@ ld-option = $(call try-run,\
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
# Prefix -I with $(srctree) if it is not an absolute path. # 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 # Find all -I options and call addtree
flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
......
...@@ -151,14 +151,20 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< ...@@ -151,14 +151,20 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
$(obj)/%.i: $(src)/%.c FORCE $(obj)/%.i: $(src)/%.c FORCE
$(call if_changed_dep,cc_i_c) $(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) $@ quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
cmd_cc_symtypes_c = \ cmd_cc_symtypes_c = \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \ set -e; \
| $(GENKSYMS) -T $@ >/dev/null; \ $(call cmd_genksyms, true) >/dev/null; \
test -s $@ || rm -f $@ test -s $@ || rm -f $@
$(obj)/%.symtypes : $(src)/%.c FORCE $(obj)/%.symtypes : $(src)/%.c FORCE
$(call if_changed_dep,cc_symtypes_c) $(call cmd,cc_symtypes_c)
# C (.c) files # C (.c) files
# The C file is compiled and updated dependency information is generated. # The C file is compiled and updated dependency information is generated.
...@@ -171,30 +177,38 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< ...@@ -171,30 +177,38 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
else else
# When module versioning is enabled the following steps are executed: # When module versioning is enabled the following steps are executed:
# o compile a .tmp_<file>.o from <file>.c # o compile a .tmp_<file>.s from <file>.c
# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does # o if .tmp_<file>.s doesn't contain a __ksymtab version, i.e. does
# not export symbols, we just rename .tmp_<file>.o to <file>.o and # not export symbols, we just assemble .tmp_<file>.s to <file>.o and
# are done. # are done.
# o otherwise, we calculate symbol versions using the good old # o otherwise, we calculate symbol versions using the good old
# genksyms on the preprocessed source and postprocess them in a way # genksyms on the preprocessed source and postprocess them in a way
# that they are usable as a linker script # that they are usable as assembly source
# o generate <file>.o from .tmp_<file>.o using the linker to # o assemble <file>.o from .tmp_<file>.s forcing inclusion of directives
# replace the unresolved symbols __crc_exported_symbol with # defining the actual values of __crc_*, followed by objcopy-ing them
# the actual value of the checksum generated by genksyms # 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 = \ cmd_modversions = \
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ if grep -q __ksymtab $(s_file); then \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \ if $(call cmd_genksyms, $(KBUILD_SYMTYPES)) > $(v_file) \
| $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \ && $(CC) $(no_g_c_flags) -c -Wa,$(v_file) \
-T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \ -o $(tmp_o_file) $(s_file) \
> $(@D)/.tmp_$(@F:.o=.ver); \ && $(OBJCOPY) -L '__crc_*' -L '___crc_*' -w \
\ $(tmp_o_file) $@; \
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ then \
-T $(@D)/.tmp_$(@F:.o=.ver); \ : ; \
rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ else \
rm -f $@; exit 1; \
fi; \
else \ else \
mv -f $(@D)/.tmp_$(@F) $@; \ rm -f $(v_file); \
$(CC) $(no_g_c_flags) -c -o $@ $(s_file); \
fi; fi;
endif endif
...@@ -211,7 +225,12 @@ define rule_cc_o_c ...@@ -211,7 +225,12 @@ define rule_cc_o_c
$(cmd_record_mcount) \ $(cmd_record_mcount) \
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
$(dot-target).tmp; \ $(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 mv -f $(dot-target).tmp $(dot-target).cmd
endef endef
......
...@@ -104,9 +104,11 @@ else ...@@ -104,9 +104,11 @@ else
debug_flags = debug_flags =
endif 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)) _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)) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
# If building the kernel in a separate objtree expand all occurrences # If building the kernel in a separate objtree expand all occurrences
...@@ -127,15 +129,16 @@ __a_flags = $(call flags,_a_flags) ...@@ -127,15 +129,16 @@ __a_flags = $(call flags,_a_flags)
__cpp_flags = $(call flags,_cpp_flags) __cpp_flags = $(call flags,_cpp_flags)
endif endif
c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(__c_flags) $(modkern_cflags) \ $(__c_flags) $(modkern_cflags) \
-D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
$(debug_flags) $(debug_flags)
a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(__a_flags) $(modkern_aflags) $(__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) ld_flags = $(LDFLAGS) $(ldflags-y)
......
...@@ -17,7 +17,8 @@ __modinst: $(modules) ...@@ -17,7 +17,8 @@ __modinst: $(modules)
@: @:
quiet_cmd_modules_install = INSTALL $@ 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 # Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra INSTALL_MOD_DIR ?= extra
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# AFLAGS=--32 decodecode < 386.oops # AFLAGS=--32 decodecode < 386.oops
cleanup() { cleanup() {
rm -f $T $T.s $T.o rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa
exit 1 exit 1
} }
...@@ -44,21 +44,33 @@ if [ $marker -eq 0 ]; then ...@@ -44,21 +44,33 @@ if [ $marker -eq 0 ]; then
marker=`expr index "$code" "\("` marker=`expr index "$code" "\("`
fi fi
touch $T.oo
if [ $marker -ne 0 ]; then 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 -n " .byte 0x" > $T.s
echo $beforemark | sed -e 's/ /,0x/g' >> $T.s echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s
as $AFLAGS -o $T.o $T.s as $AFLAGS -o $T.o $T.s &> /dev/null
objdump -S $T.o objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo
rm $T.o $T.s cat $T.ooo >> $T.oo
rm -f $T.o $T.s $T.ooo
# and fix code at-and-after marker # and fix code at-and-after marker
code=`echo "$code" | cut -c$((${marker} + 1))-` code=`echo "$code" | cut -c$((${marker} + 1))-`
fi fi
echo Code starting with the faulting instruction > $T.aa
echo =========================================== >> $T.aa
code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'` code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'`
echo -n " .byte 0x" > $T.s echo -n " .byte 0x" > $T.s
echo $code >> $T.s echo $code >> $T.s
as $AFLAGS -o $T.o $T.s as $AFLAGS -o $T.o $T.s &> /dev/null
objdump -S $T.o objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa
rm $T $T.s $T.o 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
...@@ -8,8 +8,8 @@ test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1 ...@@ -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_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"
IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"
function dump_config { dump_config() {
typeset file="$1" file="$1"
start=`$binoffset $file $IKCFG_ST 2>/dev/null` start=`$binoffset $file $IKCFG_ST 2>/dev/null`
[ "$?" != "0" ] && start="-1" [ "$?" != "0" ] && start="-1"
...@@ -18,8 +18,8 @@ function dump_config { ...@@ -18,8 +18,8 @@ function dump_config {
fi fi
end=`$binoffset $file $IKCFG_ED 2>/dev/null` end=`$binoffset $file $IKCFG_ED 2>/dev/null`
let start="$start + 8" start=`expr $start + 8`
let size="$end - $start" size=`expr $end - $start`
dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat
......
...@@ -42,7 +42,8 @@ static FILE *debugfile; ...@@ -42,7 +42,8 @@ static FILE *debugfile;
int cur_line = 1; int cur_line = 1;
char *cur_filename; 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 *arch = "";
static const char *mod_prefix = ""; static const char *mod_prefix = "";
...@@ -58,6 +59,8 @@ static const char *const symbol_type_name[] = { ...@@ -58,6 +59,8 @@ static const char *const symbol_type_name[] = {
static int equal_list(struct string_list *a, struct string_list *b); 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_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) ...@@ -151,27 +154,83 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns)
for (sym = symtab[h]; sym; sym = sym->hash_next) for (sym = symtab[h]; sym; sym = sym->hash_next)
if (map_to_ns(sym->type) == map_to_ns(ns) && if (map_to_ns(sym->type) == map_to_ns(ns) &&
strcmp(name, sym->name) == 0) strcmp(name, sym->name) == 0 &&
sym->is_declared)
break; break;
return sym; return sym;
} }
struct symbol *add_symbol(const char *name, enum symbol_type type, static int is_unknown_symbol(struct symbol *sym)
struct string_list *defn, int is_extern) {
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; unsigned long h = crc32(name) % HASH_BUCKETS;
struct symbol *sym; struct symbol *sym;
enum symbol_status status = STATUS_UNCHANGED;
for (sym = symtab[h]; sym; sym = sym->hash_next) { for (sym = symtab[h]; sym; sym = sym->hash_next) {
if (map_to_ns(sym->type) == map_to_ns(type) if (map_to_ns(sym->type) == map_to_ns(type) &&
&& strcmp(name, sym->name) == 0) { strcmp(name, sym->name) == 0) {
if (!equal_list(sym->defn, defn)) 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); 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 = xmalloc(sizeof(*sym));
sym->name = name; sym->name = name;
sym->type = type; sym->type = type;
...@@ -183,6 +242,10 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, ...@@ -183,6 +242,10 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
sym->hash_next = symtab[h]; sym->hash_next = symtab[h];
symtab[h] = sym; symtab[h] = sym;
sym->is_declared = !is_reference;
sym->status = status;
sym->is_override = 0;
if (flag_debug) { if (flag_debug) {
fprintf(debugfile, "Defn for %s %s == <", fprintf(debugfile, "Defn for %s %s == <",
symbol_type_name[type], name); symbol_type_name[type], name);
...@@ -196,6 +259,18 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, ...@@ -196,6 +259,18 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
return sym; 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) void free_node(struct string_list *node)
...@@ -236,6 +311,90 @@ static int equal_list(struct string_list *a, struct string_list *b) ...@@ -236,6 +311,90 @@ static int equal_list(struct string_list *a, struct string_list *b)
return !a && !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) static void print_node(FILE * f, struct string_list *list)
{ {
if (list->tag != SYM_NORMAL) { if (list->tag != SYM_NORMAL) {
...@@ -311,6 +470,7 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) ...@@ -311,6 +470,7 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
case SYM_TYPEDEF: case SYM_TYPEDEF:
subsym = find_symbol(cur->string, cur->tag); subsym = find_symbol(cur->string, cur->tag);
/* FIXME: Bad reference files can segfault here. */
if (subsym->expansion_trail) { if (subsym->expansion_trail) {
if (flag_dump_defs) if (flag_dump_defs)
fprintf(debugfile, "%s ", cur->string); fprintf(debugfile, "%s ", cur->string);
...@@ -347,9 +507,22 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) ...@@ -347,9 +507,22 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
t = n; t = n;
n = xmalloc(sizeof(*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->tag = SYM_NORMAL;
n->next = t; n->next = t;
t = n;
subsym = subsym =
add_symbol(cur->string, cur->tag, n, 0); add_symbol(cur->string, cur->tag, n, 0);
...@@ -397,37 +570,75 @@ void export_symbol(const char *name) ...@@ -397,37 +570,75 @@ void export_symbol(const char *name)
error_with_pos("export undefined symbol %s", name); error_with_pos("export undefined symbol %s", name);
else { else {
unsigned long crc; unsigned long crc;
int has_changed = 0;
if (flag_dump_defs) if (flag_dump_defs)
fprintf(debugfile, "Export %s == <", name); fprintf(debugfile, "Export %s == <", name);
expansion_trail = (struct symbol *)-1L; expansion_trail = (struct symbol *)-1L;
sym->expansion_trail = expansion_trail;
expansion_trail = sym;
crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
sym = expansion_trail; sym = expansion_trail;
while (sym != (struct symbol *)-1L) { while (sym != (struct symbol *)-1L) {
struct symbol *n = sym->expansion_trail; 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->expansion_trail = 0;
sym = n; sym = n;
} }
if (has_changed)
fprintf(stderr, "\n");
if (flag_dump_defs) if (flag_dump_defs)
fputs(">\n", debugfile); fputs(">\n", debugfile);
/* Used as a linker script. */ /* Used as assembly source or a linker script. */
printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); 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 ? : "<stdin>", 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, ...) void error_with_pos(const char *fmt, ...)
{ {
va_list args; va_list args;
if (flag_warnings) { if (flag_warnings) {
fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", print_location();
cur_line);
va_start(args, fmt); va_start(args, fmt);
vfprintf(stderr, fmt, args); vfprintf(stderr, fmt, args);
...@@ -440,21 +651,27 @@ void error_with_pos(const char *fmt, ...) ...@@ -440,21 +651,27 @@ void error_with_pos(const char *fmt, ...)
static void genksyms_usage(void) 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__ #ifdef __GNU_LIBRARY__
" -a, --arch Select architecture\n" " -a, --arch Select architecture\n"
" -A, --asm Generate assembly rather than linker script\n"
" -d, --debug Increment the debug level (repeatable)\n" " -d, --debug Increment the debug level (repeatable)\n"
" -D, --dump Dump expanded symbol defs (for debugging only)\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" " -w, --warnings Enable warnings\n"
" -q, --quiet Disable warnings (default)\n" " -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n" " -h, --help Print this message\n"
" -V, --version Print the release version\n" " -V, --version Print the release version\n"
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
" -a Select architecture\n" " -a Select architecture\n"
" -A Generate assembly rather than linker script\n"
" -d Increment the debug level (repeatable)\n" " -d Increment the debug level (repeatable)\n"
" -D Dump expanded symbol defs (for debugging only)\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" " -w Enable warnings\n"
" -q Disable warnings (default)\n" " -q Disable warnings (default)\n"
" -h Print this message\n" " -h Print this message\n"
...@@ -465,26 +682,29 @@ static void genksyms_usage(void) ...@@ -465,26 +682,29 @@ static void genksyms_usage(void)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *dumpfile = NULL; FILE *dumpfile = NULL, *ref_file = NULL;
int o; int o;
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
struct option long_opts[] = { struct option long_opts[] = {
{"arch", 1, 0, 'a'}, {"arch", 1, 0, 'a'},
{"asm", 0, 0, 'A'},
{"debug", 0, 0, 'd'}, {"debug", 0, 0, 'd'},
{"warnings", 0, 0, 'w'}, {"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'}, {"quiet", 0, 0, 'q'},
{"dump", 0, 0, 'D'}, {"dump", 0, 0, 'D'},
{"reference", 1, 0, 'r'},
{"dump-types", 1, 0, 'T'}, {"dump-types", 1, 0, 'T'},
{"preserve", 0, 0, 'p'},
{"version", 0, 0, 'V'}, {"version", 0, 0, 'V'},
{"help", 0, 0, 'h'}, {"help", 0, 0, 'h'},
{0, 0, 0, 0} {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) &long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */ #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__ */ #endif /* __GNU_LIBRARY__ */
switch (o) { switch (o) {
case 'a': case 'a':
...@@ -502,9 +722,20 @@ int main(int argc, char **argv) ...@@ -502,9 +722,20 @@ int main(int argc, char **argv)
case 'V': case 'V':
fputs("genksyms version 2.5.60\n", stderr); fputs("genksyms version 2.5.60\n", stderr);
break; break;
case 'A':
flag_asm = 1;
break;
case 'D': case 'D':
flag_dump_defs = 1; flag_dump_defs = 1;
break; break;
case 'r':
flag_reference = 1;
ref_file = fopen(optarg, "r");
if (!ref_file) {
perror(optarg);
return 1;
}
break;
case 'T': case 'T':
flag_dump_types = 1; flag_dump_types = 1;
dumpfile = fopen(optarg, "w"); dumpfile = fopen(optarg, "w");
...@@ -513,6 +744,9 @@ int main(int argc, char **argv) ...@@ -513,6 +744,9 @@ int main(int argc, char **argv)
return 1; return 1;
} }
break; break;
case 'p':
flag_preserve = 1;
break;
case 'h': case 'h':
genksyms_usage(); genksyms_usage();
return 0; return 0;
...@@ -533,12 +767,17 @@ int main(int argc, char **argv) ...@@ -533,12 +767,17 @@ int main(int argc, char **argv)
/* setlinebuf(debugfile); */ /* setlinebuf(debugfile); */
} }
if (flag_reference)
read_reference(ref_file);
yyparse(); yyparse();
if (flag_dump_types && visited_symbols) { if (flag_dump_types && visited_symbols) {
while (visited_symbols != (struct symbol *)-1L) { while (visited_symbols != (struct symbol *)-1L) {
struct symbol *sym = visited_symbols; struct symbol *sym = visited_symbols;
if (sym->is_override)
fputs("override ", dumpfile);
if (sym->type != SYM_NORMAL) { if (sym->type != SYM_NORMAL) {
putc(symbol_type_name[sym->type][0], dumpfile); putc(symbol_type_name[sym->type][0], dumpfile);
putc('#', dumpfile); putc('#', dumpfile);
......
...@@ -29,6 +29,10 @@ enum symbol_type { ...@@ -29,6 +29,10 @@ enum symbol_type {
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION 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 {
struct string_list *next; struct string_list *next;
enum symbol_type tag; enum symbol_type tag;
...@@ -43,6 +47,9 @@ struct symbol { ...@@ -43,6 +47,9 @@ struct symbol {
struct symbol *expansion_trail; struct symbol *expansion_trail;
struct symbol *visited; struct symbol *visited;
int is_extern; int is_extern;
int is_declared;
enum symbol_status status;
int is_override;
}; };
typedef struct string_list **yystype; typedef struct string_list **yystype;
......
/* 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 */ /* 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) \ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#line 3 "scripts/genksyms/keywords.gperf" #line 3 "scripts/genksyms/keywords.gperf"
struct resword { const char *name; int token; }; struct resword { const char *name; int token; };
/* maximum key range = 62, duplicates = 0 */ /* maximum key range = 64, duplicates = 0 */
#ifdef __GNUC__ #ifdef __GNUC__
__inline __inline
...@@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len) ...@@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len)
{ {
static const unsigned char asso_values[] = static const unsigned char asso_values[] =
{ {
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 5, 67, 67, 67, 67, 67, 67, 67, 67, 67, 0,
65, 65, 65, 65, 65, 65, 35, 65, 65, 65, 67, 67, 67, 67, 67, 67, 15, 67, 67, 67,
0, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 0, 65, 0, 65, 5, 67, 67, 67, 67, 67, 0, 67, 0, 67, 5,
20, 15, 10, 30, 65, 15, 65, 65, 20, 0, 25, 20, 15, 30, 67, 15, 67, 67, 10, 0,
10, 35, 20, 65, 10, 5, 0, 10, 5, 65, 10, 40, 20, 67, 10, 5, 0, 10, 15, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65, 65, 65, 65, 65, 65 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]]; 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) ...@@ -84,116 +84,119 @@ is_reserved_word (register const char *str, register unsigned int len)
{ {
enum enum
{ {
TOTAL_KEYWORDS = 43, TOTAL_KEYWORDS = 45,
MIN_WORD_LENGTH = 3, MIN_WORD_LENGTH = 3,
MAX_WORD_LENGTH = 24, MAX_WORD_LENGTH = 24,
MIN_HASH_VALUE = 3, MIN_HASH_VALUE = 3,
MAX_HASH_VALUE = 64 MAX_HASH_VALUE = 66
}; };
static const struct resword wordlist[] = static const struct resword wordlist[] =
{ {
{""}, {""}, {""}, {""}, {""}, {""},
#line 26 "scripts/genksyms/keywords.gperf" #line 28 "scripts/genksyms/keywords.gperf"
{"asm", ASM_KEYW}, {"asm", ASM_KEYW},
{""}, {""},
#line 8 "scripts/genksyms/keywords.gperf" #line 10 "scripts/genksyms/keywords.gperf"
{"__asm", ASM_KEYW}, {"__asm", ASM_KEYW},
{""}, {""},
#line 9 "scripts/genksyms/keywords.gperf" #line 11 "scripts/genksyms/keywords.gperf"
{"__asm__", ASM_KEYW}, {"__asm__", ASM_KEYW},
{""}, {""}, {""}, {""},
#line 52 "scripts/genksyms/keywords.gperf" #line 54 "scripts/genksyms/keywords.gperf"
{"__typeof__", TYPEOF_KEYW}, {"__typeof__", TYPEOF_KEYW},
{""}, {""},
#line 12 "scripts/genksyms/keywords.gperf" #line 14 "scripts/genksyms/keywords.gperf"
{"__const", CONST_KEYW}, {"__const", CONST_KEYW},
#line 11 "scripts/genksyms/keywords.gperf"
{"__attribute__", ATTRIBUTE_KEYW},
#line 13 "scripts/genksyms/keywords.gperf" #line 13 "scripts/genksyms/keywords.gperf"
{"__attribute__", ATTRIBUTE_KEYW},
#line 15 "scripts/genksyms/keywords.gperf"
{"__const__", CONST_KEYW}, {"__const__", CONST_KEYW},
#line 18 "scripts/genksyms/keywords.gperf" #line 20 "scripts/genksyms/keywords.gperf"
{"__signed__", SIGNED_KEYW}, {"__signed__", SIGNED_KEYW},
#line 44 "scripts/genksyms/keywords.gperf" #line 46 "scripts/genksyms/keywords.gperf"
{"static", STATIC_KEYW}, {"static", STATIC_KEYW},
#line 20 "scripts/genksyms/keywords.gperf" {""},
{"__volatile__", VOLATILE_KEYW}, #line 41 "scripts/genksyms/keywords.gperf"
#line 39 "scripts/genksyms/keywords.gperf"
{"int", INT_KEYW}, {"int", INT_KEYW},
#line 32 "scripts/genksyms/keywords.gperf" #line 34 "scripts/genksyms/keywords.gperf"
{"char", CHAR_KEYW}, {"char", CHAR_KEYW},
#line 33 "scripts/genksyms/keywords.gperf" #line 35 "scripts/genksyms/keywords.gperf"
{"const", CONST_KEYW}, {"const", CONST_KEYW},
#line 45 "scripts/genksyms/keywords.gperf" #line 47 "scripts/genksyms/keywords.gperf"
{"struct", STRUCT_KEYW}, {"struct", STRUCT_KEYW},
#line 24 "scripts/genksyms/keywords.gperf" #line 26 "scripts/genksyms/keywords.gperf"
{"__restrict__", RESTRICT_KEYW}, {"__restrict__", RESTRICT_KEYW},
#line 25 "scripts/genksyms/keywords.gperf" #line 27 "scripts/genksyms/keywords.gperf"
{"restrict", RESTRICT_KEYW}, {"restrict", RESTRICT_KEYW},
#line 23 "scripts/genksyms/keywords.gperf" #line 7 "scripts/genksyms/keywords.gperf"
{"_restrict", RESTRICT_KEYW}, {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
#line 16 "scripts/genksyms/keywords.gperf" #line 18 "scripts/genksyms/keywords.gperf"
{"__inline__", INLINE_KEYW}, {"__inline__", INLINE_KEYW},
#line 10 "scripts/genksyms/keywords.gperf"
{"__attribute", ATTRIBUTE_KEYW},
{""}, {""},
#line 14 "scripts/genksyms/keywords.gperf" #line 22 "scripts/genksyms/keywords.gperf"
{"__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}, {"__extension__", EXTENSION_KEYW},
#line 35 "scripts/genksyms/keywords.gperf" #line 37 "scripts/genksyms/keywords.gperf"
{"enum", ENUM_KEYW}, {"enum", ENUM_KEYW},
#line 19 "scripts/genksyms/keywords.gperf" #line 8 "scripts/genksyms/keywords.gperf"
{"__volatile", VOLATILE_KEYW}, {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW},
#line 36 "scripts/genksyms/keywords.gperf" #line 38 "scripts/genksyms/keywords.gperf"
{"extern", EXTERN_KEYW}, {"extern", EXTERN_KEYW},
{""}, {""},
#line 17 "scripts/genksyms/keywords.gperf" #line 19 "scripts/genksyms/keywords.gperf"
{"__signed", SIGNED_KEYW}, {"__signed", SIGNED_KEYW},
#line 7 "scripts/genksyms/keywords.gperf" #line 9 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
{""}, #line 49 "scripts/genksyms/keywords.gperf"
#line 51 "scripts/genksyms/keywords.gperf" {"union", UNION_KEYW},
#line 53 "scripts/genksyms/keywords.gperf"
{"typeof", TYPEOF_KEYW}, {"typeof", TYPEOF_KEYW},
#line 46 "scripts/genksyms/keywords.gperf" #line 48 "scripts/genksyms/keywords.gperf"
{"typedef", TYPEDEF_KEYW}, {"typedef", TYPEDEF_KEYW},
#line 15 "scripts/genksyms/keywords.gperf" #line 17 "scripts/genksyms/keywords.gperf"
{"__inline", INLINE_KEYW}, {"__inline", INLINE_KEYW},
#line 31 "scripts/genksyms/keywords.gperf" #line 33 "scripts/genksyms/keywords.gperf"
{"auto", AUTO_KEYW}, {"auto", AUTO_KEYW},
#line 47 "scripts/genksyms/keywords.gperf" #line 21 "scripts/genksyms/keywords.gperf"
{"union", UNION_KEYW}, {"__volatile", VOLATILE_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" #line 50 "scripts/genksyms/keywords.gperf"
{"volatile", VOLATILE_KEYW}, {"unsigned", UNSIGNED_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" #line 44 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, {"short", SHORT_KEYW},
{""}, {""}, #line 40 "scripts/genksyms/keywords.gperf"
#line 38 "scripts/genksyms/keywords.gperf"
{"inline", INLINE_KEYW}, {"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 22 "scripts/genksyms/keywords.gperf" #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}, {"_Bool", BOOL_KEYW},
#line 43 "scripts/genksyms/keywords.gperf"
{"signed", SIGNED_KEYW},
{""}, {""}, {""}, {""},
#line 40 "scripts/genksyms/keywords.gperf" #line 43 "scripts/genksyms/keywords.gperf"
{"long", LONG_KEYW} {"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) if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
......
...@@ -5,6 +5,8 @@ struct resword { const char *name; int token; } ...@@ -5,6 +5,8 @@ struct resword { const char *name; int token; }
EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
EXPORT_SYMBOL_GPL_FUTURE, 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
__asm__, ASM_KEYW __asm__, ASM_KEYW
__attribute, ATTRIBUTE_KEYW __attribute, ATTRIBUTE_KEYW
......
#! /usr/bin/perl
#
# Detect cycles in the header file dependency graph
# Vegard Nossum <vegardno@ifi.uio.no>
#
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";
}
...@@ -130,18 +130,9 @@ static int read_symbol(FILE *in, struct sym_entry *s) ...@@ -130,18 +130,9 @@ static int read_symbol(FILE *in, struct sym_entry *s)
static int symbol_valid(struct sym_entry *s) static int symbol_valid(struct sym_entry *s)
{ {
/* Symbols which vary between passes. Passes 1 and 2 must have /* Symbols which vary between passes. Passes 1 and 2 must have
* identical symbol lists. The kallsyms_* symbols below are only added * identical symbol lists.
* after pass 1, they would be included in pass 2 when --all-symbols is
* specified so exclude them to get a stable symbol list.
*/ */
static char *special_symbols[] = { 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 */ /* Exclude linker generated symbols which vary between passes */
"_SDA_BASE_", /* ppc */ "_SDA_BASE_", /* ppc */
"_SDA2_BASE_", /* ppc */ "_SDA2_BASE_", /* ppc */
...@@ -173,7 +164,9 @@ static int symbol_valid(struct sym_entry *s) ...@@ -173,7 +164,9 @@ static int symbol_valid(struct sym_entry *s)
} }
/* Exclude symbols which vary between passes. */ /* 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; return 0;
for (i = 0; special_symbols[i]; i++) for (i = 0; special_symbols[i]; i++)
...@@ -550,8 +543,10 @@ int main(int argc, char **argv) ...@@ -550,8 +543,10 @@ int main(int argc, char **argv)
usage(); usage();
read_map(stdin); read_map(stdin);
sort_symbols(); if (table_cnt) {
optimize_token_table(); sort_symbols();
optimize_token_table();
}
write_src(); write_src();
return 0; return 0;
......
...@@ -52,7 +52,7 @@ EOF ...@@ -52,7 +52,7 @@ EOF
} }
usage() { 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 if [ $# -eq 0 ]; then
......
...@@ -289,6 +289,8 @@ my %parameterdescs; ...@@ -289,6 +289,8 @@ my %parameterdescs;
my @parameterlist; my @parameterlist;
my %sections; my %sections;
my @sectionlist; my @sectionlist;
my $sectcheck;
my $struct_actual;
my $contents = ""; my $contents = "";
my $section_default = "Description"; # default section my $section_default = "Description"; # default section
...@@ -378,10 +380,12 @@ sub dump_section { ...@@ -378,10 +380,12 @@ sub dump_section {
# print STDERR "parameter def '$1' = '$contents'\n"; # print STDERR "parameter def '$1' = '$contents'\n";
$name = $1; $name = $1;
$parameterdescs{$name} = $contents; $parameterdescs{$name} = $contents;
$sectcheck = $sectcheck . $name . " ";
} elsif ($name eq "@\.\.\.") { } elsif ($name eq "@\.\.\.") {
# print STDERR "parameter def '...' = '$contents'\n"; # print STDERR "parameter def '...' = '$contents'\n";
$name = "..."; $name = "...";
$parameterdescs{$name} = $contents; $parameterdescs{$name} = $contents;
$sectcheck = $sectcheck . $name . " ";
} else { } else {
# print STDERR "other section '$name' = '$contents'\n"; # print STDERR "other section '$name' = '$contents'\n";
if (defined($sections{$name}) && ($sections{$name} ne "")) { if (defined($sections{$name}) && ($sections{$name} ne "")) {
...@@ -1405,21 +1409,25 @@ sub dump_union($$) { ...@@ -1405,21 +1409,25 @@ sub dump_union($$) {
sub dump_struct($$) { sub dump_struct($$) {
my $x = shift; my $x = shift;
my $file = shift; my $file = shift;
my $nested;
if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
$declaration_name = $2; $declaration_name = $2;
my $members = $3; my $members = $3;
# ignore embedded structs or unions # ignore embedded structs or unions
$members =~ s/{.*}//g; $members =~ s/({.*})//g;
$nested = $1;
# ignore members marked private: # ignore members marked private:
$members =~ s/\/\*.*?private:.*?public:.*?\*\///gos; $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
$members =~ s/\/\*.*?private:.*//gos; $members =~ s/\/\*.*?private:.*//gos;
# strip comments: # strip comments:
$members =~ s/\/\*.*?\*\///gos; $members =~ s/\/\*.*?\*\///gos;
$nested =~ s/\/\*.*?\*\///gos;
create_parameterlist($members, ';', $file); create_parameterlist($members, ';', $file);
check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
output_declaration($declaration_name, output_declaration($declaration_name,
'struct', 'struct',
...@@ -1505,6 +1513,14 @@ sub dump_typedef($$) { ...@@ -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($$$) { sub create_parameterlist($$$) {
my $args = shift; my $args = shift;
my $splitter = shift; my $splitter = shift;
...@@ -1537,6 +1553,7 @@ sub create_parameterlist($$$) { ...@@ -1537,6 +1553,7 @@ sub create_parameterlist($$$) {
$param = $1; $param = $1;
$type = $arg; $type = $arg;
$type =~ s/([^\(]+\(\*?)\s*$param/$1/; $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
save_struct_actual($param);
push_parameter($param, $type, $file); push_parameter($param, $type, $file);
} elsif ($arg) { } elsif ($arg) {
$arg =~ s/\s*:\s*/:/g; $arg =~ s/\s*:\s*/:/g;
...@@ -1561,14 +1578,17 @@ sub create_parameterlist($$$) { ...@@ -1561,14 +1578,17 @@ sub create_parameterlist($$$) {
foreach $param (@args) { foreach $param (@args) {
if ($param =~ m/^(\*+)\s*(.*)/) { if ($param =~ m/^(\*+)\s*(.*)/) {
save_struct_actual($2);
push_parameter($2, "$type $1", $file); push_parameter($2, "$type $1", $file);
} }
elsif ($param =~ m/(.*?):(\d+)/) { elsif ($param =~ m/(.*?):(\d+)/) {
if ($type ne "") { # skip unnamed bit-fields if ($type ne "") { # skip unnamed bit-fields
save_struct_actual($1);
push_parameter($1, "$type:$2", $file) push_parameter($1, "$type:$2", $file)
} }
} }
else { else {
save_struct_actual($param);
push_parameter($param, $type, $file); push_parameter($param, $type, $file);
} }
} }
...@@ -1634,6 +1654,46 @@ sub push_parameter($$$) { ...@@ -1634,6 +1654,46 @@ sub push_parameter($$$) {
$parametertypes{$param} = $type; $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 # takes a function prototype and the name of the current file being
# processed and spits out all the details stored in the global # processed and spits out all the details stored in the global
...@@ -1699,6 +1759,9 @@ sub dump_function($$) { ...@@ -1699,6 +1759,9 @@ sub dump_function($$) {
return; return;
} }
my $prms = join " ", @parameterlist;
check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");
output_declaration($declaration_name, output_declaration($declaration_name,
'function', 'function',
{'function' => $declaration_name, {'function' => $declaration_name,
...@@ -1757,6 +1820,8 @@ sub reset_state { ...@@ -1757,6 +1820,8 @@ sub reset_state {
@parameterlist = (); @parameterlist = ();
%sections = (); %sections = ();
@sectionlist = (); @sectionlist = ();
$sectcheck = "";
$struct_actual = "";
$prototype = ""; $prototype = "";
$state = 0; $state = 0;
......
...@@ -4,6 +4,8 @@ SMP=$3 ...@@ -4,6 +4,8 @@ SMP=$3
PREEMPT=$4 PREEMPT=$4
CC=$5 CC=$5
vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; }
# If compile.h exists already and we don't own autoconf.h # 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 # (i.e. we're not the same user who did make *config), don't
# modify compile.h # modify compile.h
...@@ -11,7 +13,7 @@ CC=$5 ...@@ -11,7 +13,7 @@ CC=$5
# do "compiled by root" # do "compiled by root"
if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then
echo " SKIPPED $TARGET" vecho " SKIPPED $TARGET"
exit 0 exit 0
fi fi
...@@ -89,7 +91,7 @@ if [ -r $TARGET ] && \ ...@@ -89,7 +91,7 @@ if [ -r $TARGET ] && \
cmp -s .tmpver.1 .tmpver.2; then cmp -s .tmpver.1 .tmpver.2; then
rm -f .tmpcompile rm -f .tmpcompile
else else
echo " UPD $TARGET" vecho " UPD $TARGET"
mv -f .tmpcompile $TARGET mv -f .tmpcompile $TARGET
fi fi
rm -f .tmpver.1 .tmpver.2 rm -f .tmpver.1 .tmpver.2
...@@ -17,7 +17,9 @@ if test -e $2/Makefile && ! grep -q Automatically $2/Makefile ...@@ -17,7 +17,9 @@ if test -e $2/Makefile && ! grep -q Automatically $2/Makefile
then then
exit 0 exit 0
fi fi
echo " GEN $2/Makefile" if [ "${quiet}" != "silent_" ]; then
echo " GEN $2/Makefile"
fi
cat << EOF > $2/Makefile cat << EOF > $2/Makefile
# Automatically generated by $0: don't edit # Automatically generated by $0: don't edit
......
...@@ -37,9 +37,6 @@ ...@@ -37,9 +37,6 @@
# readprofile starts reading symbols when _stext is found, and # readprofile starts reading symbols when _stext is found, and
# continue until it finds a symbol which is not either of 'T', 't', # continue until it finds a symbol which is not either of 'T', 't',
# 'W' or 'w'. __crc_ are 'A' and placed in the middle # 'W' or 'w'.
# 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
$NM -n $1 | grep -v '\( [aNUw] \)\|\( \$[adt]\)' > $2
# Makefile for the different targets used to generate full packages of a kernel # Makefile for the different targets used to generate full packages of a kernel
# It uses the generic clean infrastructure of kbuild # 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 # RPM target
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# The rpm target generates two rpm files: # The rpm target generates two rpm files:
...@@ -47,7 +43,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE ...@@ -47,7 +43,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE
set -e; \ set -e; \
mv -f $(objtree)/.tmp_version $(objtree)/.version 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 rm ../$(KERNELPATH).tar.gz
clean-files := $(objtree)/kernel.spec clean-files := $(objtree)/kernel.spec
...@@ -64,7 +60,8 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE ...@@ -64,7 +60,8 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE
set -e; \ set -e; \
mv -f $(objtree)/.tmp_version $(objtree)/.version 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 clean-files += $(objtree)/binkernel.spec
......
...@@ -19,6 +19,11 @@ if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then ...@@ -19,6 +19,11 @@ if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
fi fi
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? # Are there uncommitted changes?
git update-index --refresh --unmerged > /dev/null git update-index --refresh --unmerged > /dev/null
if git diff-index --name-only HEAD | grep -v "^scripts/package" \ if git diff-index --name-only HEAD | grep -v "^scripts/package" \
...@@ -51,7 +56,7 @@ if hgid=`hg id 2>/dev/null`; then ...@@ -51,7 +56,7 @@ if hgid=`hg id 2>/dev/null`; then
fi fi
# Check for svn and a svn repo. # 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}'` rev=`echo $rev | awk '{print $NF}'`
changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l` changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l`
......
<*>
*.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
#!/bin/sh
# Generate tags or cscope files
# Usage tags.sh <mode>
#
# 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
...@@ -370,6 +370,30 @@ error: ...@@ -370,6 +370,30 @@ error:
return rc; 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) static int cpio_mkfile_line(const char *line)
{ {
char name[PATH_MAX + 1]; char name[PATH_MAX + 1];
...@@ -415,7 +439,8 @@ static int cpio_mkfile_line(const char *line) ...@@ -415,7 +439,8 @@ static int cpio_mkfile_line(const char *line)
} else { } else {
dname = name; dname = name;
} }
rc = cpio_mkfile(dname, location, mode, uid, gid, nlinks); rc = cpio_mkfile(dname, cpio_replace_env(location),
mode, uid, gid, nlinks);
fail: fail:
if (dname_len) free(dname); if (dname_len) free(dname);
return rc; return rc;
...@@ -439,6 +464,7 @@ void usage(const char *prog) ...@@ -439,6 +464,7 @@ void usage(const char *prog)
"\n" "\n"
"<name> name of the file/dir/nod/etc in the archive\n" "<name> name of the file/dir/nod/etc in the archive\n"
"<location> location of the file in the current filesystem\n" "<location> location of the file in the current filesystem\n"
" expands shell variables quoted with ${}\n"
"<target> link target\n" "<target> link target\n"
"<mode> mode/permissions of the file\n" "<mode> mode/permissions of the file\n"
"<uid> user id (0=root)\n" "<uid> user id (0=root)\n"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment