Commit 2e1ca21d authored by Linus Torvalds's avatar Linus Torvalds

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

* master.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild: (46 commits)
  kbuild: remove obsoleted scripts/reference_* files
  kbuild: fix make help & make *pkg
  kconfig: fix time ordering of writes to .kconfig.d and include/linux/autoconf.h
  Kconfig: remove the CONFIG_CC_ALIGN_* options
  kbuild: add -fverbose-asm to i386 Makefile
  kbuild: clean-up genksyms
  kbuild: Lindent genksyms.c
  kbuild: fix genksyms build error
  kbuild: in makefile.txt note that Makefile is preferred name for kbuild files
  kbuild: replace PHONY with FORCE
  kbuild: Fix bug in crc symbol generating of kernel and modules
  kbuild: change kbuild to not rely on incorrect GNU make behavior
  kbuild: when warning symbols exported twice now tell user this is the problem
  kbuild: fix make dir/file.xx when asm symlink is missing
  kbuild: in the section mismatch check try harder to find symbols
  kbuild: fix section mismatch check for unwind on IA64
  kbuild: kill false positives from section mismatch warnings for powerpc
  kbuild: kill trailing whitespace in modpost & friends
  kbuild: small update of allnoconfig description
  kbuild: make namespace.pl CROSS_COMPILE happy
  ...

Trivial conflict in arch/ppc/boot/Makefile manually fixed up
parents 315ab19a eae0f536
...@@ -28,7 +28,7 @@ PS_METHOD = $(prefer-db2x) ...@@ -28,7 +28,7 @@ PS_METHOD = $(prefer-db2x)
### ###
# The targets that may be used. # The targets that may be used.
.PHONY: xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
xmldocs: $(BOOKS) xmldocs: $(BOOKS)
...@@ -211,3 +211,9 @@ clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) ...@@ -211,3 +211,9 @@ clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS))
#man put files in man subdir - traverse down #man put files in man subdir - traverse down
subdir- := man/ subdir- := man/
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
.PHONY: $(PHONY)
...@@ -17,6 +17,7 @@ This document describes the Linux kernel Makefiles. ...@@ -17,6 +17,7 @@ This document describes the Linux kernel Makefiles.
--- 3.8 Command line dependency --- 3.8 Command line dependency
--- 3.9 Dependency tracking --- 3.9 Dependency tracking
--- 3.10 Special Rules --- 3.10 Special Rules
--- 3.11 $(CC) support functions
=== 4 Host Program support === 4 Host Program support
--- 4.1 Simple Host Program --- 4.1 Simple Host Program
...@@ -38,7 +39,6 @@ This document describes the Linux kernel Makefiles. ...@@ -38,7 +39,6 @@ This document describes the Linux kernel Makefiles.
--- 6.6 Commands useful for building a boot image --- 6.6 Commands useful for building a boot image
--- 6.7 Custom kbuild commands --- 6.7 Custom kbuild commands
--- 6.8 Preprocessing linker scripts --- 6.8 Preprocessing linker scripts
--- 6.9 $(CC) support functions
=== 7 Kbuild Variables === 7 Kbuild Variables
=== 8 Makefile language === 8 Makefile language
...@@ -106,9 +106,9 @@ This document is aimed towards normal developers and arch developers. ...@@ -106,9 +106,9 @@ This document is aimed towards normal developers and arch developers.
Most Makefiles within the kernel are kbuild Makefiles that use the Most Makefiles within the kernel are kbuild Makefiles that use the
kbuild infrastructure. This chapter introduce the syntax used in the kbuild infrastructure. This chapter introduce the syntax used in the
kbuild makefiles. kbuild makefiles.
The preferred name for the kbuild files is 'Kbuild' but 'Makefile' will The preferred name for the kbuild files are 'Makefile' but 'Kbuild' can
continue to be supported. All new developmen is expected to use the be used and if both a 'Makefile' and a 'Kbuild' file exists then the 'Kbuild'
Kbuild filename. file will be used.
Section 3.1 "Goal definitions" is a quick intro, further chapters provide Section 3.1 "Goal definitions" is a quick intro, further chapters provide
more details, with real examples. more details, with real examples.
...@@ -385,6 +385,102 @@ more details, with real examples. ...@@ -385,6 +385,102 @@ 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).
--- 3.11 $(CC) support functions
The kernel may be build with several different versions of
$(CC), each supporting a unique set of features and options.
kbuild provide basic support to check for valid options for $(CC).
$(CC) is useally the gcc compiler, but other alternatives are
available.
as-option
as-option is used to check if $(CC) when used to compile
assembler (*.S) files supports the given option. An optional
second option may be specified if first option are not supported.
Example:
#arch/sh/Makefile
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
In the above example cflags-y will be assinged the the option
-Wa$(comma)-isa=$(isa-y) if it is supported by $(CC).
The second argument is optional, and if supplied will be used
if first argument is not supported.
cc-option
cc-option is used to check if $(CC) support a given option, and not
supported to use an optional second option.
Example:
#arch/i386/Makefile
cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
In the above example cflags-y will be assigned the option
-march=pentium-mmx if supported by $(CC), otherwise -march-i586.
The second argument to cc-option is optional, and if omitted
cflags-y will be assigned no value if first option is not supported.
cc-option-yn
cc-option-yn is used to check if gcc supports a given option
and return 'y' if supported, otherwise 'n'.
Example:
#arch/ppc/Makefile
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32
In the above example $(biarch) is set to y if $(CC) supports the -m32
option. When $(biarch) equals to y the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32.
cc-option-align
gcc version >= 3.0 shifted type of options used to speify
alignment of functions, loops etc. $(cc-option-align) whrn used
as prefix to the align options will select the right prefix:
gcc < 3.00
cc-option-align = -malign
gcc >= 3.00
cc-option-align = -falign
Example:
CFLAGS += $(cc-option-align)-functions=4
In the above example the option -falign-functions=4 is used for
gcc >= 3.00. For gcc < 3.00 -malign-functions=4 is used.
cc-version
cc-version return a numerical version of the $(CC) compiler version.
The format is <major><minor> where both are two digits. So for example
gcc 3.41 would return 0341.
cc-version is useful when a specific $(CC) version is faulty in one
area, for example the -mregparm=3 were broken in some gcc version
even though the option was accepted by gcc.
Example:
#arch/i386/Makefile
cflags-y += $(shell \
if [ $(call cc-version) -ge 0300 ] ; then \
echo "-mregparm=3"; fi ;)
In the above example -mregparm=3 is only used for gcc version greater
than or equal to gcc 3.0.
cc-ifversion
cc-ifversion test the version of $(CC) and equals last argument if
version expression is true.
Example:
#fs/reiserfs/Makefile
EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1)
In this example EXTRA_CFLAGS will be assigned the value -O1 if the
$(CC) version is less than 4.2.
cc-ifversion takes all the shell operators:
-eq, -ne, -lt, -le, -gt, and -ge
The third parameter may be a text as in this example, but it may also
be an expanded variable or a macro.
=== 4 Host Program support === 4 Host Program support
...@@ -973,74 +1069,6 @@ When kbuild executes the following steps are followed (roughly): ...@@ -973,74 +1069,6 @@ When kbuild executes the following steps are followed (roughly):
architecture specific files. architecture specific files.
--- 6.9 $(CC) support functions
The kernel may be build with several different versions of
$(CC), each supporting a unique set of features and options.
kbuild provide basic support to check for valid options for $(CC).
$(CC) is useally the gcc compiler, but other alternatives are
available.
cc-option
cc-option is used to check if $(CC) support a given option, and not
supported to use an optional second option.
Example:
#arch/i386/Makefile
cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
In the above example cflags-y will be assigned the option
-march=pentium-mmx if supported by $(CC), otherwise -march-i586.
The second argument to cc-option is optional, and if omitted
cflags-y will be assigned no value if first option is not supported.
cc-option-yn
cc-option-yn is used to check if gcc supports a given option
and return 'y' if supported, otherwise 'n'.
Example:
#arch/ppc/Makefile
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32
In the above example $(biarch) is set to y if $(CC) supports the -m32
option. When $(biarch) equals to y the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32.
cc-option-align
gcc version >= 3.0 shifted type of options used to speify
alignment of functions, loops etc. $(cc-option-align) whrn used
as prefix to the align options will select the right prefix:
gcc < 3.00
cc-option-align = -malign
gcc >= 3.00
cc-option-align = -falign
Example:
CFLAGS += $(cc-option-align)-functions=4
In the above example the option -falign-functions=4 is used for
gcc >= 3.00. For gcc < 3.00 -malign-functions=4 is used.
cc-version
cc-version return a numerical version of the $(CC) compiler version.
The format is <major><minor> where both are two digits. So for example
gcc 3.41 would return 0341.
cc-version is useful when a specific $(CC) version is faulty in one
area, for example the -mregparm=3 were broken in some gcc version
even though the option was accepted by gcc.
Example:
#arch/i386/Makefile
cflags-y += $(shell \
if [ $(call cc-version) -ge 0300 ] ; then \
echo "-mregparm=3"; fi ;)
In the above example -mregparm=3 is only used for gcc version greater
than or equal to gcc 3.0.
=== 7 Kbuild Variables === 7 Kbuild Variables
The top Makefile exports the following variables: The top Makefile exports the following variables:
......
...@@ -13,6 +13,7 @@ In this document you will find information about: ...@@ -13,6 +13,7 @@ In this document you will find information about:
--- 2.2 Available targets --- 2.2 Available targets
--- 2.3 Available options --- 2.3 Available options
--- 2.4 Preparing the kernel tree for module build --- 2.4 Preparing the kernel tree for module build
--- 2.5 Building separate files for a module
=== 3. Example commands === 3. Example commands
=== 4. Creating a kbuild file for an external module === 4. Creating a kbuild file for an external module
=== 5. Include files === 5. Include files
...@@ -22,7 +23,10 @@ In this document you will find information about: ...@@ -22,7 +23,10 @@ In this document you will find information about:
=== 6. Module installation === 6. Module installation
--- 6.1 INSTALL_MOD_PATH --- 6.1 INSTALL_MOD_PATH
--- 6.2 INSTALL_MOD_DIR --- 6.2 INSTALL_MOD_DIR
=== 7. Module versioning === 7. Module versioning & Module.symvers
--- 7.1 Symbols fron the kernel (vmlinux + modules)
--- 7.2 Symbols and external modules
--- 7.3 Symbols from another external module
=== 8. Tips & Tricks === 8. Tips & Tricks
--- 8.1 Testing for CONFIG_FOO_BAR --- 8.1 Testing for CONFIG_FOO_BAR
...@@ -88,7 +92,8 @@ when building an external module. ...@@ -88,7 +92,8 @@ when building an external module.
make -C $KDIR M=$PWD modules_install make -C $KDIR M=$PWD modules_install
Install the external module(s). Install the external module(s).
Installation default is in /lib/modules/<kernel-version>/extra, Installation default is in /lib/modules/<kernel-version>/extra,
but may be prefixed with INSTALL_MOD_PATH - see separate chapter. but may be prefixed with INSTALL_MOD_PATH - see separate
chapter.
make -C $KDIR M=$PWD clean make -C $KDIR M=$PWD clean
Remove all generated files for the module - the kernel Remove all generated files for the module - the kernel
...@@ -131,6 +136,16 @@ when building an external module. ...@@ -131,6 +136,16 @@ when building an external module.
Therefore a full kernel build needs to be executed to make Therefore a full kernel build needs to be executed to make
module versioning work. module versioning work.
--- 2.5 Building separate files for a module
It is possible to build single files which is part of a module.
This works equal for the kernel, a module and even for external
modules.
Examples (module foo.ko, consist of bar.o, baz.o):
make -C $KDIR M=`pwd` bar.lst
make -C $KDIR M=`pwd` bar.o
make -C $KDIR M=`pwd` foo.ko
make -C $KDIR M=`pwd` /
=== 3. Example commands === 3. Example commands
...@@ -422,7 +437,7 @@ External modules are installed in the directory: ...@@ -422,7 +437,7 @@ External modules are installed in the directory:
=> Install dir: /lib/modules/$(KERNELRELEASE)/gandalf => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf
=== 7. Module versioning === 7. Module versioning & Module.symvers
Module versioning is enabled by the CONFIG_MODVERSIONS tag. Module versioning is enabled by the CONFIG_MODVERSIONS tag.
...@@ -432,10 +447,79 @@ when a module is loaded/used then the CRC values contained in the kernel are ...@@ -432,10 +447,79 @@ when a module is loaded/used then the CRC values contained in the kernel are
compared with similar values in the module. If they are not equal then the compared with similar values in the module. If they are not equal then the
kernel refuses to load the module. kernel refuses to load the module.
During a kernel build a file named Module.symvers will be generated. This Module.symvers contains a list of all exported symbols from a kernel build.
file includes the symbol version of all symbols within the kernel. If the
Module.symvers file is saved from the last full kernel compile one does not --- 7.1 Symbols fron the kernel (vmlinux + modules)
have to do a full kernel compile to build a module version's compatible module.
During a kernel build a file named Module.symvers will be generated.
Module.symvers contains all exported symbols from the kernel and
compiled modules. For each symbols the corresponding CRC value
is stored too.
The syntax of the Module.symvers file is:
<CRC> <Symbol> <module>
Sample:
0x2d036834 scsi_remove_host drivers/scsi/scsi_mod
For a kernel build without CONFIG_MODVERSIONING enabled the crc
would read: 0x00000000
Module.symvers serve two purposes.
1) It list all exported symbols both from vmlinux and all modules
2) It list CRC if CONFIG_MODVERSION is enabled
--- 7.2 Symbols and external modules
When building an external module the build system needs access to
the symbols from the kernel to check if all external symbols are
defined. This is done in the MODPOST step and to obtain all
symbols modpost reads Module.symvers from the kernel.
If a Module.symvers file is present in the directory where
the external module is being build this file will be read too.
During the MODPOST step a new Module.symvers file will be written
containing all exported symbols that was not defined in the kernel.
--- 7.3 Symbols from another external module
Sometimes one external module uses exported symbols from another
external module. Kbuild needs to have full knowledge on all symbols
to avoid spitting out warnings about undefined symbols.
Two solutions exist to let kbuild know all symbols of more than
one external module.
The method with a top-level kbuild file is recommended but may be
impractical in certain situations.
Use a top-level Kbuild file
If you have two modules: 'foo', 'bar' and 'foo' needs symbols
from 'bar' then one can use a common top-level kbuild file so
both modules are compiled in same build.
Consider following directory layout:
./foo/ <= contains the foo module
./bar/ <= contains the bar module
The top-level Kbuild file would then look like:
#./Kbuild: (this file may also be named Makefile)
obj-y := foo/ bar/
Executing:
make -C $KDIR M=`pwd`
will then do the expected and compile both modules with full
knowledge on symbols from both modules.
Use an extra Module.symvers file
When an external module is build a Module.symvers file is
generated containing all exported symbols which are not
defined in the kernel.
To get access to symbols from module 'bar' one can copy the
Module.symvers file from the compilation of the 'bar' module
to the directory where the 'foo' module is build.
During the module build kbuild will read the Module.symvers
file in the directory of the external module and when the
build is finished a new Module.symvers file is created
containing the sum of all symbols defined and not part of the
kernel.
=== 8. Tips & Tricks === 8. Tips & Tricks
......
...@@ -56,10 +56,6 @@ Here is the solution: ...@@ -56,10 +56,6 @@ Here is the solution:
writing one file per option. It updates only the files for options writing one file per option. It updates only the files for options
that have changed. that have changed.
mkdep.c no longer generates warning messages for missing or unneeded
<linux/config.h> lines. The new top-level target 'make checkconfig'
checks for these problems.
Flag Dependencies Flag Dependencies
Martin Von Loewis contributed another feature to this patch: Martin Von Loewis contributed another feature to this patch:
......
...@@ -95,7 +95,7 @@ ifdef O ...@@ -95,7 +95,7 @@ ifdef O
endif endif
# That's our default target when none is given on the command line # That's our default target when none is given on the command line
.PHONY: _all PHONY := _all
_all: _all:
ifneq ($(KBUILD_OUTPUT),) ifneq ($(KBUILD_OUTPUT),)
...@@ -106,7 +106,7 @@ KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd) ...@@ -106,7 +106,7 @@ KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
$(if $(KBUILD_OUTPUT),, \ $(if $(KBUILD_OUTPUT),, \
$(error output directory "$(saved-output)" does not exist)) $(error output directory "$(saved-output)" does not exist))
.PHONY: $(MAKECMDGOALS) PHONY += $(MAKECMDGOALS)
$(filter-out _all,$(MAKECMDGOALS)) _all: $(filter-out _all,$(MAKECMDGOALS)) _all:
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \ $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
...@@ -123,7 +123,7 @@ ifeq ($(skip-makefile),) ...@@ -123,7 +123,7 @@ ifeq ($(skip-makefile),)
# If building an external module we do not care about the all: rule # If building an external module we do not care about the all: rule
# but instead _all depend on modules # but instead _all depend on modules
.PHONY: all PHONY += all
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
_all: all _all: all
else else
...@@ -137,7 +137,7 @@ objtree := $(CURDIR) ...@@ -137,7 +137,7 @@ objtree := $(CURDIR)
src := $(srctree) src := $(srctree)
obj := $(objtree) obj := $(objtree)
VPATH := $(srctree) VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
export srctree objtree VPATH TOPDIR export srctree objtree VPATH TOPDIR
...@@ -151,7 +151,7 @@ export srctree objtree VPATH TOPDIR ...@@ -151,7 +151,7 @@ export srctree objtree VPATH TOPDIR
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \ -e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \ -e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ ) -e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
# Cross compiling and selecting different set of gcc/bin-utils # Cross compiling and selecting different set of gcc/bin-utils
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
...@@ -258,38 +258,6 @@ endif ...@@ -258,38 +258,6 @@ endif
export quiet Q KBUILD_VERBOSE export quiet Q KBUILD_VERBOSE
######
# cc support functions to be used (only) in arch/$(ARCH)/Makefile
# See documentation in Documentation/kbuild/makefiles.txt
# as-option
# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,)
as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
-xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
else echo "$(2)"; fi ;)
# cc-option
# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
# cc-option-yn
# Usage: flag := $(call cc-option-yn, -march=winchip-c6)
cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "y"; else echo "n"; fi;)
# cc-option-align
# Prefix align with either -falign or -malign
cc-option-align = $(subst -functions=0,,\
$(call cc-option,-falign-functions=0,-malign-functions=0))
# cc-version
# Usage gcc-ver := $(call cc-version $(CC))
cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \
$(if $(1), $(1), $(CC)))
# Look for make include files relative to root of kernel src # Look for make include files relative to root of kernel src
MAKEFLAGS += --include-dir=$(srctree) MAKEFLAGS += --include-dir=$(srctree)
...@@ -369,14 +337,14 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exc ...@@ -369,14 +337,14 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exc
# Rules shared between *config targets and build targets # Rules shared between *config targets and build targets
# Basic helpers built in scripts/ # Basic helpers built in scripts/
.PHONY: scripts_basic PHONY += scripts_basic
scripts_basic: scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic $(Q)$(MAKE) $(build)=scripts/basic
# To avoid any implicit rule to kick in, define an empty command. # To avoid any implicit rule to kick in, define an empty command.
scripts/basic/%: scripts_basic ; scripts/basic/%: scripts_basic ;
.PHONY: outputmakefile PHONY += outputmakefile
# outputmakefile generate a Makefile to be placed in output directory, if # outputmakefile generate a Makefile to be placed in output directory, if
# using a seperate output directory. This allows convinient use # using a seperate output directory. This allows convinient use
# of make in output directory # of make in output directory
...@@ -452,7 +420,7 @@ ifeq ($(KBUILD_EXTMOD),) ...@@ -452,7 +420,7 @@ ifeq ($(KBUILD_EXTMOD),)
# Additional helpers built in scripts/ # Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice # Carefully list dependencies so we do not try to build scripts twice
# in parrallel # in parrallel
.PHONY: scripts PHONY += scripts
scripts: scripts_basic include/config/MARKER scripts: scripts_basic include/config/MARKER
$(Q)$(MAKE) $(build)=$(@) $(Q)$(MAKE) $(build)=$(@)
...@@ -504,13 +472,6 @@ else ...@@ -504,13 +472,6 @@ else
CFLAGS += -O2 CFLAGS += -O2
endif endif
#Add align options if CONFIG_CC_* is not equal to 0
add-align = $(if $(filter-out 0,$($(1))),$(cc-option-align)$(2)=$($(1)))
CFLAGS += $(call add-align,CONFIG_CC_ALIGN_FUNCTIONS,-functions)
CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LABELS,-labels)
CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LOOPS,-loops)
CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps)
ifdef CONFIG_FRAME_POINTER ifdef CONFIG_FRAME_POINTER
CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
else else
...@@ -756,7 +717,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; ...@@ -756,7 +717,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
# make menuconfig etc. # make menuconfig etc.
# Error messages still appears in the original language # Error messages still appears in the original language
.PHONY: $(vmlinux-dirs) PHONY += $(vmlinux-dirs)
$(vmlinux-dirs): prepare scripts $(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@ $(Q)$(MAKE) $(build)=$@
...@@ -809,10 +770,10 @@ kernelrelease = $(KERNELVERSION)$(localver-full) ...@@ -809,10 +770,10 @@ kernelrelease = $(KERNELVERSION)$(localver-full)
# version.h and scripts_basic is processed / created. # version.h and scripts_basic is processed / created.
# Listed in dependency order # Listed in dependency order
.PHONY: prepare archprepare prepare0 prepare1 prepare2 prepare3 PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
# prepare-all is deprecated, use prepare as valid replacement # prepare-all is deprecated, use prepare as valid replacement
.PHONY: prepare-all PHONY += prepare-all
# prepare3 is used to check if we are building in a separate output directory, # prepare3 is used to check if we are building in a separate output directory,
# and if so do: # and if so do:
...@@ -853,27 +814,6 @@ prepare prepare-all: prepare0 ...@@ -853,27 +814,6 @@ prepare prepare-all: prepare0
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
# Single targets
# ---------------------------------------------------------------------------
%.s: %.c scripts FORCE
$(Q)$(MAKE) $(build)=$(@D) $@
%.i: %.c scripts FORCE
$(Q)$(MAKE) $(build)=$(@D) $@
%.o: %.c scripts FORCE
$(Q)$(MAKE) $(build)=$(@D) $@
%.ko: scripts FORCE
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) $(@:.ko=.o)
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
%/: scripts prepare FORCE
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D)
%.lst: %.c scripts FORCE
$(Q)$(MAKE) $(build)=$(@D) $@
%.s: %.S scripts FORCE
$(Q)$(MAKE) $(build)=$(@D) $@
%.o: %.S scripts FORCE
$(Q)$(MAKE) $(build)=$(@D) $@
# FIXME: The asm symlink changes when $(ARCH) changes. That's # FIXME: The asm symlink changes when $(ARCH) changes. That's
# hard to detect, but I suppose "make mrproper" is a good idea # hard to detect, but I suppose "make mrproper" is a good idea
# before switching between archs anyway. # before switching between archs anyway.
...@@ -914,7 +854,7 @@ include/linux/version.h: $(srctree)/Makefile .config .kernelrelease FORCE ...@@ -914,7 +854,7 @@ include/linux/version.h: $(srctree)/Makefile .config .kernelrelease FORCE
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
.PHONY: depend dep PHONY += depend dep
depend dep: depend dep:
@echo '*** Warning: make $@ is unnecessary now.' @echo '*** Warning: make $@ is unnecessary now.'
...@@ -929,21 +869,21 @@ all: modules ...@@ -929,21 +869,21 @@ all: modules
# Build modules # Build modules
.PHONY: modules PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
@echo ' Building modules, stage 2.'; @echo ' Building modules, stage 2.';
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
# Target to prepare building external modules # Target to prepare building external modules
.PHONY: modules_prepare PHONY += modules_prepare
modules_prepare: prepare scripts modules_prepare: prepare scripts
# Target to install modules # Target to install modules
.PHONY: modules_install PHONY += modules_install
modules_install: _modinst_ _modinst_post modules_install: _modinst_ _modinst_post
.PHONY: _modinst_ PHONY += _modinst_
_modinst_: _modinst_:
@if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \ @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
echo "Warning: you may need to install module-init-tools"; \ echo "Warning: you may need to install module-init-tools"; \
...@@ -970,7 +910,7 @@ depmod_opts := ...@@ -970,7 +910,7 @@ depmod_opts :=
else else
depmod_opts := -b $(INSTALL_MOD_PATH) -r depmod_opts := -b $(INSTALL_MOD_PATH) -r
endif endif
.PHONY: _modinst_post PHONY += _modinst_post
_modinst_post: _modinst_ _modinst_post: _modinst_
if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
...@@ -1013,7 +953,7 @@ clean: rm-dirs := $(CLEAN_DIRS) ...@@ -1013,7 +953,7 @@ clean: rm-dirs := $(CLEAN_DIRS)
clean: rm-files := $(CLEAN_FILES) clean: rm-files := $(CLEAN_FILES)
clean-dirs := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs)) clean-dirs := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs))
.PHONY: $(clean-dirs) clean archclean PHONY += $(clean-dirs) clean archclean
$(clean-dirs): $(clean-dirs):
$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
...@@ -1031,7 +971,7 @@ mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS)) ...@@ -1031,7 +971,7 @@ mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS))
mrproper: rm-files := $(wildcard $(MRPROPER_FILES)) mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
mrproper-dirs := $(addprefix _mrproper_,Documentation/DocBook scripts) mrproper-dirs := $(addprefix _mrproper_,Documentation/DocBook scripts)
.PHONY: $(mrproper-dirs) mrproper archmrproper PHONY += $(mrproper-dirs) mrproper archmrproper
$(mrproper-dirs): $(mrproper-dirs):
$(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@) $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
...@@ -1041,7 +981,7 @@ mrproper: clean archmrproper $(mrproper-dirs) ...@@ -1041,7 +981,7 @@ mrproper: clean archmrproper $(mrproper-dirs)
# distclean # distclean
# #
.PHONY: distclean PHONY += distclean
distclean: mrproper distclean: mrproper
@find $(srctree) $(RCS_FIND_IGNORE) \ @find $(srctree) $(RCS_FIND_IGNORE) \
...@@ -1057,12 +997,10 @@ distclean: mrproper ...@@ -1057,12 +997,10 @@ distclean: mrproper
# rpm target kept for backward compatibility # rpm target kept for backward compatibility
package-dir := $(srctree)/scripts/package package-dir := $(srctree)/scripts/package
.PHONY: %-pkg rpm
%pkg: FORCE %pkg: FORCE
$(Q)$(MAKE) -f $(package-dir)/Makefile $@ $(Q)$(MAKE) $(build)=$(package-dir) $@
rpm: FORCE rpm: FORCE
$(Q)$(MAKE) -f $(package-dir)/Makefile $@ $(Q)$(MAKE) $(build)=$(package-dir) $@
# Brief documentation of the typical targets used # Brief documentation of the typical targets used
...@@ -1094,13 +1032,11 @@ help: ...@@ -1094,13 +1032,11 @@ help:
@echo ' kernelversion - Output the version stored in Makefile' @echo ' kernelversion - Output the version stored in Makefile'
@echo '' @echo ''
@echo 'Static analysers' @echo 'Static analysers'
@echo ' buildcheck - List dangling references to vmlinux discarded sections'
@echo ' and init sections from non-init sections'
@echo ' checkstack - Generate a list of stack hogs' @echo ' checkstack - Generate a list of stack hogs'
@echo ' namespacecheck - Name space analysis on compiled kernel' @echo ' namespacecheck - Name space analysis on compiled kernel'
@echo '' @echo ''
@echo 'Kernel packaging:' @echo 'Kernel packaging:'
@$(MAKE) -f $(package-dir)/Makefile help @$(MAKE) $(build)=$(package-dir) help
@echo '' @echo ''
@echo 'Documentation targets:' @echo 'Documentation targets:'
@$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp
...@@ -1149,11 +1085,12 @@ else # KBUILD_EXTMOD ...@@ -1149,11 +1085,12 @@ else # KBUILD_EXTMOD
# We are always building modules # We are always building modules
KBUILD_MODULES := 1 KBUILD_MODULES := 1
.PHONY: crmodverdir PHONY += crmodverdir
crmodverdir: crmodverdir:
$(Q)rm -rf $(MODVERDIR)
$(Q)mkdir -p $(MODVERDIR) $(Q)mkdir -p $(MODVERDIR)
.PHONY: $(objtree)/Module.symvers PHONY += $(objtree)/Module.symvers
$(objtree)/Module.symvers: $(objtree)/Module.symvers:
@test -e $(objtree)/Module.symvers || ( \ @test -e $(objtree)/Module.symvers || ( \
echo; \ echo; \
...@@ -1162,7 +1099,7 @@ $(objtree)/Module.symvers: ...@@ -1162,7 +1099,7 @@ $(objtree)/Module.symvers:
echo ) echo )
module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD)) module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD))
.PHONY: $(module-dirs) modules PHONY += $(module-dirs) modules
$(module-dirs): crmodverdir $(objtree)/Module.symvers $(module-dirs): crmodverdir $(objtree)/Module.symvers
$(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@) $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
...@@ -1170,13 +1107,32 @@ modules: $(module-dirs) ...@@ -1170,13 +1107,32 @@ modules: $(module-dirs)
@echo ' Building modules, stage 2.'; @echo ' Building modules, stage 2.';
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
.PHONY: modules_install PHONY += modules_install
modules_install: modules_install: _emodinst_ _emodinst_post
install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra)
PHONY += _emodinst_
_emodinst_:
$(Q)rm -rf $(MODLIB)/$(install-dir)
$(Q)mkdir -p $(MODLIB)/$(install-dir)
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst
# Run depmod only is we have System.map and depmod is executable
quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
$(DEPMOD) -ae -F System.map \
$(if $(strip $(INSTALL_MOD_PATH)), \
-b $(INSTALL_MOD_PATH) -r) \
$(KERNELRELEASE); \
fi
PHONY += _emodinst_post
_emodinst_post: _emodinst_
$(call cmd,depmod)
clean-dirs := $(addprefix _clean_,$(KBUILD_EXTMOD)) clean-dirs := $(addprefix _clean_,$(KBUILD_EXTMOD))
.PHONY: $(clean-dirs) clean PHONY += $(clean-dirs) clean
$(clean-dirs): $(clean-dirs):
$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
...@@ -1196,6 +1152,11 @@ help: ...@@ -1196,6 +1152,11 @@ help:
@echo ' modules_install - install the module' @echo ' modules_install - install the module'
@echo ' clean - remove generated files in module directory only' @echo ' clean - remove generated files in module directory only'
@echo '' @echo ''
# Dummies...
PHONY += prepare scripts
prepare: ;
scripts: ;
endif # KBUILD_EXTMOD endif # KBUILD_EXTMOD
# Generate tags for editors # Generate tags for editors
...@@ -1296,17 +1257,13 @@ versioncheck: ...@@ -1296,17 +1257,13 @@ versioncheck:
-name '*.[hcS]' -type f -print | sort \ -name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkversion.pl | xargs $(PERL) -w scripts/checkversion.pl
buildcheck:
$(PERL) $(srctree)/scripts/reference_discarded.pl
$(PERL) $(srctree)/scripts/reference_init.pl
namespacecheck: namespacecheck:
$(PERL) $(srctree)/scripts/namespace.pl $(PERL) $(srctree)/scripts/namespace.pl
endif #ifeq ($(config-targets),1) endif #ifeq ($(config-targets),1)
endif #ifeq ($(mixed-targets),1) endif #ifeq ($(mixed-targets),1)
.PHONY: checkstack PHONY += checkstack
checkstack: checkstack:
$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
$(PERL) $(src)/scripts/checkstack.pl $(ARCH) $(PERL) $(src)/scripts/checkstack.pl $(ARCH)
...@@ -1317,6 +1274,44 @@ kernelrelease: ...@@ -1317,6 +1274,44 @@ kernelrelease:
kernelversion: kernelversion:
@echo $(KERNELVERSION) @echo $(KERNELVERSION)
# Single targets
# ---------------------------------------------------------------------------
# The directory part is taken from first prerequisite, so this
# works even with external modules
%.s: %.c prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@)
%.i: %.c prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@)
%.o: %.c prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@)
%.lst: %.c prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@)
%.s: %.S prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@)
%.o: %.S prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@)
# For external modules we shall include any directory of the target,
# but usual case there is no directory part.
# make M=`pwd` module.o => $(dir $@)=./
# make M=`pwd` foo/module.o => $(dir $@)=foo/
# make M=`pwd` / => $(dir $@)=/
ifeq ($(KBUILD_EXTMOD),)
target-dir = $(@D)
else
zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@)))
target-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash))
endif
/ %/: scripts prepare FORCE
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(target-dir)
%.ko: scripts FORCE
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(target-dir) $(@:.ko=.o)
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
# FIXME Should go into a make.lib or something # FIXME Should go into a make.lib or something
# =========================================================================== # ===========================================================================
...@@ -1351,4 +1346,10 @@ clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj ...@@ -1351,4 +1346,10 @@ clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
endif # skip-makefile endif # skip-makefile
PHONY += FORCE
FORCE: FORCE:
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
.PHONY: $(PHONY)
# #
# arch/arm/Makefile # arch/arm/Makefile
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -177,7 +180,7 @@ endif ...@@ -177,7 +180,7 @@ endif
archprepare: maketools archprepare: maketools
.PHONY: maketools FORCE PHONY += maketools FORCE
maketools: include/linux/version.h include/asm-arm/.arch FORCE maketools: include/linux/version.h include/asm-arm/.arch FORCE
$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
......
# #
# arch/arm/boot/Makefile # arch/arm/boot/Makefile
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -73,7 +76,7 @@ $(obj)/bootpImage: $(obj)/bootp/bootp FORCE ...@@ -73,7 +76,7 @@ $(obj)/bootpImage: $(obj)/bootp/bootp FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
@echo ' Kernel: $@ is ready' @echo ' Kernel: $@ is ready'
.PHONY: initrd FORCE PHONY += initrd FORCE
initrd: initrd:
@test "$(INITRD_PHYS)" != "" || \ @test "$(INITRD_PHYS)" != "" || \
(echo This machine does not support INITRD; exit -1) (echo This machine does not support INITRD; exit -1)
......
# #
# linux/arch/arm/boot/bootp/Makefile # linux/arch/arm/boot/bootp/Makefile
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
LDFLAGS_bootp :=-p --no-undefined -X \ LDFLAGS_bootp :=-p --no-undefined -X \
--defsym initrd_phys=$(INITRD_PHYS) \ --defsym initrd_phys=$(INITRD_PHYS) \
...@@ -21,4 +24,4 @@ $(obj)/kernel.o: arch/arm/boot/zImage FORCE ...@@ -21,4 +24,4 @@ $(obj)/kernel.o: arch/arm/boot/zImage FORCE
$(obj)/initrd.o: $(INITRD) FORCE $(obj)/initrd.o: $(INITRD) FORCE
.PHONY: $(INITRD) FORCE PHONY += $(INITRD) FORCE
# #
# arch/arm26/Makefile # arch/arm26/Makefile
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -49,7 +52,7 @@ all: zImage ...@@ -49,7 +52,7 @@ all: zImage
boot := arch/arm26/boot boot := arch/arm26/boot
.PHONY: maketools FORCE PHONY += maketools FORCE
maketools: FORCE maketools: FORCE
......
# #
# arch/arm26/boot/Makefile # arch/arm26/boot/Makefile
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -60,7 +63,7 @@ $(obj)/xipImage: vmlinux FORCE ...@@ -60,7 +63,7 @@ $(obj)/xipImage: vmlinux FORCE
@echo ' Kernel: $@ is ready' @echo ' Kernel: $@ is ready'
endif endif
.PHONY: initrd PHONY += initrd
initrd: initrd:
@test "$(INITRD_PHYS)" != "" || \ @test "$(INITRD_PHYS)" != "" || \
(echo This machine does not support INITRD; exit -1) (echo This machine does not support INITRD; exit -1)
......
...@@ -99,7 +99,7 @@ AFLAGS += $(mflags-y) ...@@ -99,7 +99,7 @@ AFLAGS += $(mflags-y)
boot := arch/i386/boot boot := arch/i386/boot
.PHONY: zImage bzImage compressed zlilo bzlilo \ PHONY += zImage bzImage compressed zlilo bzlilo \
zdisk bzdisk fdimage fdimage144 fdimage288 install zdisk bzdisk fdimage fdimage144 fdimage288 install
all: bzImage all: bzImage
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <asm-generic/vmlinux.lds.h> #include <asm-generic/vmlinux.lds.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/cache.h>
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386) OUTPUT_ARCH(i386)
...@@ -135,7 +136,7 @@ SECTIONS ...@@ -135,7 +136,7 @@ SECTIONS
__initramfs_start = .; __initramfs_start = .;
.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
__initramfs_end = .; __initramfs_end = .;
. = ALIGN(32); . = ALIGN(L1_CACHE_BYTES);
__per_cpu_start = .; __per_cpu_start = .;
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
__per_cpu_end = .; __per_cpu_end = .;
......
# #
# ia64/Makefile # ia64/Makefile
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -62,7 +65,7 @@ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ ...@@ -62,7 +65,7 @@ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/
boot := arch/ia64/hp/sim/boot boot := arch/ia64/hp/sim/boot
.PHONY: boot compressed check PHONY += boot compressed check
all: compressed unwcheck all: compressed unwcheck
......
# #
# m32r/Makefile # m32r/Makefile
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
LDFLAGS := LDFLAGS :=
OBJCOPYFLAGS := -O binary -R .note -R .comment -S OBJCOPYFLAGS := -O binary -R .note -R .comment -S
...@@ -39,7 +42,7 @@ drivers-$(CONFIG_OPROFILE) += arch/m32r/oprofile/ ...@@ -39,7 +42,7 @@ drivers-$(CONFIG_OPROFILE) += arch/m32r/oprofile/
boot := arch/m32r/boot boot := arch/m32r/boot
.PHONY: zImage PHONY += zImage
all: zImage all: zImage
......
...@@ -150,7 +150,7 @@ CPPFLAGS_vmlinux.lds := -Upowerpc ...@@ -150,7 +150,7 @@ CPPFLAGS_vmlinux.lds := -Upowerpc
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin
.PHONY: $(BOOT_TARGETS) PHONY += $(BOOT_TARGETS)
boot := arch/$(ARCH)/boot boot := arch/$(ARCH)/boot
......
...@@ -82,7 +82,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ ...@@ -82,7 +82,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
.PHONY: $(BOOT_TARGETS) PHONY += $(BOOT_TARGETS)
all: uImage zImage all: uImage zImage
......
#
# arch/ppc/boot/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -22,7 +28,7 @@ subdir- += simple openfirmware ...@@ -22,7 +28,7 @@ subdir- += simple openfirmware
hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree) hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree)
.PHONY: $(BOOT_TARGETS) $(bootdir-y) PHONY += $(BOOT_TARGETS) $(bootdir-y)
$(BOOT_TARGETS): $(bootdir-y) $(BOOT_TARGETS): $(bootdir-y)
......
# Makefile for making bootable images on various OpenFirmware machines. # Makefile for making bootable images on various OpenFirmware machines.
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# Paul Mackerras January 1997 # Paul Mackerras January 1997
# XCOFF bootable images for PowerMacs # XCOFF bootable images for PowerMacs
# Geert Uytterhoeven September 1997 # Geert Uytterhoeven September 1997
...@@ -86,7 +89,7 @@ $(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \ ...@@ -86,7 +89,7 @@ $(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \
# The targets used on the make command-line # The targets used on the make command-line
.PHONY: zImage zImage.initrd PHONY += zImage zImage.initrd
zImage: $(images)/zImage.chrp \ zImage: $(images)/zImage.chrp \
$(images)/zImage.chrp-rs6k $(images)/zImage.chrp-rs6k
@echo ' kernel: $@ is ready ($<)' @echo ' kernel: $@ is ready ($<)'
...@@ -96,7 +99,7 @@ zImage.initrd: $(images)/zImage.initrd.chrp \ ...@@ -96,7 +99,7 @@ zImage.initrd: $(images)/zImage.initrd.chrp \
TFTPIMAGE := /tftpboot/zImage TFTPIMAGE := /tftpboot/zImage
.PHONY: znetboot znetboot.initrd PHONY += znetboot znetboot.initrd
znetboot: $(images)/zImage.chrp znetboot: $(images)/zImage.chrp
cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END) cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END)
@echo ' kernel: $@ is ready ($<)' @echo ' kernel: $@ is ready ($<)'
......
...@@ -172,7 +172,7 @@ include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER ...@@ -172,7 +172,7 @@ include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER
archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach
.PHONY: maketools FORCE PHONY += maketools FORCE
maketools: include/linux/version.h FORCE maketools: include/linux/version.h FORCE
$(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
......
# #
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) # Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
# Licensed under the GPL # Licensed under the GPL
# #
...@@ -88,7 +91,7 @@ CONFIG_KERNEL_HALF_GIGS ?= 0 ...@@ -88,7 +91,7 @@ CONFIG_KERNEL_HALF_GIGS ?= 0
SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
.PHONY: linux PHONY += linux
all: linux all: linux
......
...@@ -67,7 +67,7 @@ drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/ ...@@ -67,7 +67,7 @@ drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/
boot := arch/x86_64/boot boot := arch/x86_64/boot
.PHONY: bzImage bzlilo install archmrproper \ PHONY += bzImage bzlilo install archmrproper \
fdimage fdimage144 fdimage288 archclean fdimage fdimage144 fdimage288 archclean
#Default target when executing "make" #Default target when executing "make"
......
# Ignore generated files
fore200e_mkfirm
fore200e_pca_fw.c
pca200e.bin
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* *
*/ */
/* make checkconfig does not walk through include tree :-( */
#include <linux/config.h> #include <linux/config.h>
#include "matroxfb_DAC1064.h" #include "matroxfb_DAC1064.h"
......
#ifndef __MATROXFB_DAC1064_H__ #ifndef __MATROXFB_DAC1064_H__
#define __MATROXFB_DAC1064_H__ #define __MATROXFB_DAC1064_H__
/* make checkconfig does not walk through include tree */
#include <linux/config.h> #include <linux/config.h>
#include "matroxfb_base.h" #include "matroxfb_base.h"
......
...@@ -78,7 +78,6 @@ ...@@ -78,7 +78,6 @@
* *
*/ */
/* make checkconfig does not verify included files... */
#include <linux/config.h> #include <linux/config.h>
#include "matroxfb_Ti3026.h" #include "matroxfb_Ti3026.h"
......
#ifndef __MATROXFB_TI3026_H__ #ifndef __MATROXFB_TI3026_H__
#define __MATROXFB_TI3026_H__ #define __MATROXFB_TI3026_H__
/* make checkconfig does not walk through whole include tree */
#include <linux/config.h> #include <linux/config.h>
#include "matroxfb_base.h" #include "matroxfb_base.h"
......
...@@ -99,7 +99,6 @@ ...@@ -99,7 +99,6 @@
* *
*/ */
/* make checkconfig does not check included files... */
#include <linux/config.h> #include <linux/config.h>
#include <linux/version.h> #include <linux/version.h>
......
...@@ -84,7 +84,6 @@ ...@@ -84,7 +84,6 @@
* *
*/ */
/* make checkconfig does not check includes for this... */
#include <linux/config.h> #include <linux/config.h>
#include "matroxfb_misc.h" #include "matroxfb_misc.h"
......
...@@ -365,43 +365,6 @@ config SHMEM ...@@ -365,43 +365,6 @@ config SHMEM
option replaces shmem and tmpfs with the much simpler ramfs code, option replaces shmem and tmpfs with the much simpler ramfs code,
which may be appropriate on small systems without swap. which may be appropriate on small systems without swap.
config CC_ALIGN_FUNCTIONS
int "Function alignment" if EMBEDDED
default 0
help
Align the start of functions to the next power-of-two greater than n,
skipping up to n bytes. For instance, 32 aligns functions
to the next 32-byte boundary, but 24 would align to the next
32-byte boundary only if this can be done by skipping 23 bytes or less.
Zero means use compiler's default.
config CC_ALIGN_LABELS
int "Label alignment" if EMBEDDED
default 0
help
Align all branch targets to a power-of-two boundary, skipping
up to n bytes like ALIGN_FUNCTIONS. This option can easily
make code slower, because it must insert dummy operations for
when the branch target is reached in the usual flow of the code.
Zero means use compiler's default.
config CC_ALIGN_LOOPS
int "Loop alignment" if EMBEDDED
default 0
help
Align loops to a power-of-two boundary, skipping up to n bytes.
Zero means use compiler's default.
config CC_ALIGN_JUMPS
int "Jump alignment" if EMBEDDED
default 0
help
Align branch targets to a power-of-two boundary, for branch
targets where the targets can only be reached by jumping,
skipping up to n bytes like ALIGN_FUNCTIONS. In this case,
no dummy operations need be executed.
Zero means use compiler's default.
config SLAB config SLAB
default y default y
bool "Use full SLAB allocator" if EMBEDDED bool "Use full SLAB allocator" if EMBEDDED
......
...@@ -44,6 +44,43 @@ define filechk ...@@ -44,6 +44,43 @@ define filechk
fi fi
endef endef
######
# gcc support functions
# See documentation in Documentation/kbuild/makefiles.txt
# as-option
# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,)
as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
-xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
else echo "$(2)"; fi ;)
# cc-option
# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
# cc-option-yn
# Usage: flag := $(call cc-option-yn, -march=winchip-c6)
cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "y"; else echo "n"; fi;)
# cc-option-align
# Prefix align with either -falign or -malign
cc-option-align = $(subst -functions=0,,\
$(call cc-option,-falign-functions=0,-malign-functions=0))
# cc-version
# Usage gcc-ver := $(call cc-version, $(CC))
cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \
$(if $(1), $(1), $(CC)))
# cc-ifversion
# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \
echo $(3); fi;)
### ###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage: # Usage:
...@@ -51,8 +88,7 @@ endef ...@@ -51,8 +88,7 @@ endef
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
# If quiet is set, only print short version of command # If quiet is set, only print short version of command
cmd = @$(if $($(quiet)cmd_$(1)),\ cmd = @$(echo-cmd) $(cmd_$(1))
echo ' $(call escsq,$($(quiet)cmd_$(1)))' &&) $(cmd_$(1))
# Add $(obj)/ for paths that is not absolute # Add $(obj)/ for paths that is not absolute
objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o)))
...@@ -75,30 +111,33 @@ endif ...@@ -75,30 +111,33 @@ endif
echo-cmd = $(if $($(quiet)cmd_$(1)), \ echo-cmd = $(if $($(quiet)cmd_$(1)), \
echo ' $(call escsq,$($(quiet)cmd_$(1)))';) echo ' $(call escsq,$($(quiet)cmd_$(1)))';)
make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))
# function to only execute the passed command if necessary # function to only execute the passed command if necessary
# >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file
# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars # note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars
# #
if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ if_changed = $(if $(strip $(filter-out $(PHONY),$?) \
$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
@set -e; \ @set -e; \
$(echo-cmd) \ $(echo-cmd) $(cmd_$(1)); \
$(cmd_$(1)); \ echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd)
echo 'cmd_$@ := $(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
# execute the command and also postprocess generated .d dependencies # execute the command and also postprocess generated .d dependencies
# file # file
if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?) \
$(filter-out FORCE $(wildcard $^),$^) \
$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
@set -e; \ @set -e; \
$(echo-cmd) \ $(echo-cmd) $(cmd_$(1)); \
$(cmd_$(1)); \ scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \
scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
rm -f $(depfile); \ rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
# Usage: $(call if_changed_rule,foo) # Usage: $(call if_changed_rule,foo)
# will check if $(cmd_foo) changed, or any of the prequisites changed, # will check if $(cmd_foo) changed, or any of the prequisites changed,
# and if so will execute $(rule_foo) # and if so will execute $(rule_foo)
if_changed_rule = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ if_changed_rule = $(if $(strip $(filter-out $(PHONY),$?) \
$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\
@set -e; \ @set -e; \
$(rule_$(1))) $(rule_$(1)))
...@@ -4,17 +4,18 @@ ...@@ -4,17 +4,18 @@
src := $(obj) src := $(obj)
.PHONY: __build PHONY := __build
__build: __build:
# Read .config if it exist, otherwise ignore # Read .config if it exist, otherwise ignore
-include .config -include .config
include scripts/Kbuild.include
# The filename Kbuild has precedence over Makefile # The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
include scripts/Kbuild.include
include scripts/Makefile.lib include scripts/Makefile.lib
ifdef host-progs ifdef host-progs
...@@ -128,7 +129,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi) ...@@ -128,7 +129,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi)
$(multi-objs-y:.o=.lst) : modname = $(modname-multi) $(multi-objs-y:.o=.lst) : modname = $(modname-multi)
quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $< cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<
%.s: %.c FORCE %.s: %.c FORCE
$(call if_changed_dep,cc_s_c) $(call if_changed_dep,cc_s_c)
...@@ -165,7 +166,7 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< ...@@ -165,7 +166,7 @@ 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 $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \ $(CPP) -D__GENKSYMS__ $(c_flags) $< \
| $(GENKSYMS) \ | $(GENKSYMS) -a $(ARCH) \
> $(@D)/.tmp_$(@F:.o=.ver); \ > $(@D)/.tmp_$(@F:.o=.ver); \
\ \
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
...@@ -177,12 +178,10 @@ cmd_modversions = \ ...@@ -177,12 +178,10 @@ cmd_modversions = \
endif endif
define rule_cc_o_c define rule_cc_o_c
$(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \ $(call echo-cmd,checksrc) $(cmd_checksrc) \
$(cmd_checksrc) \ $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
$(if $($(quiet)cmd_cc_o_c),echo ' $(call escsq,$($(quiet)cmd_cc_o_c))';) \
$(cmd_cc_o_c); \
$(cmd_modversions) \ $(cmd_modversions) \
scripts/basic/fixdep $(depfile) $@ '$(call escsq,$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp; \ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > $(@D)/.$(@F).tmp; \
rm -f $(depfile); \ rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
endef endef
...@@ -309,14 +308,14 @@ targets += $(multi-used-y) $(multi-used-m) ...@@ -309,14 +308,14 @@ targets += $(multi-used-y) $(multi-used-m)
# Descending # Descending
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
.PHONY: $(subdir-ym) PHONY += $(subdir-ym)
$(subdir-ym): $(subdir-ym):
$(Q)$(MAKE) $(build)=$@ $(Q)$(MAKE) $(build)=$@
# Add FORCE to the prequisites of a target to force it to be always rebuilt. # Add FORCE to the prequisites of a target to force it to be always rebuilt.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
.PHONY: FORCE PHONY += FORCE
FORCE: FORCE:
...@@ -331,3 +330,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ...@@ -331,3 +330,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
ifneq ($(cmd_files),) ifneq ($(cmd_files),)
include $(cmd_files) include $(cmd_files)
endif endif
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
.PHONY: $(PHONY)
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
src := $(obj) src := $(obj)
.PHONY: __clean PHONY := __clean
__clean: __clean:
# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir # Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
...@@ -87,10 +87,16 @@ endif ...@@ -87,10 +87,16 @@ endif
# Descending # Descending
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
.PHONY: $(subdir-ymn) PHONY += $(subdir-ymn)
$(subdir-ymn): $(subdir-ymn):
$(Q)$(MAKE) $(clean)=$@ $(Q)$(MAKE) $(clean)=$@
# If quiet is set, only print short version of command # If quiet is set, only print short version of command
cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1)) cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1))
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
.PHONY: $(PHONY)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Installing modules # Installing modules
# ========================================================================== # ==========================================================================
.PHONY: __modinst PHONY := __modinst
__modinst: __modinst:
include scripts/Kbuild.include include scripts/Kbuild.include
...@@ -12,7 +12,7 @@ include scripts/Kbuild.include ...@@ -12,7 +12,7 @@ include scripts/Kbuild.include
__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
.PHONY: $(modules) PHONY += $(modules)
__modinst: $(modules) __modinst: $(modules)
@: @:
...@@ -27,3 +27,9 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) ...@@ -27,3 +27,9 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
$(modules): $(modules):
$(call cmd,modules_install,$(MODLIB)/$(modinst_dir)) $(call cmd,modules_install,$(MODLIB)/$(modinst_dir))
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
.PHONY: $(PHONY)
...@@ -32,14 +32,15 @@ ...@@ -32,14 +32,15 @@
# Step 4 is solely used to allow module versioning in external modules, # Step 4 is solely used to allow module versioning in external modules,
# where the CRC of each module is retrieved from the Module.symers file. # where the CRC of each module is retrieved from the Module.symers file.
.PHONY: _modpost PHONY := _modpost
_modpost: __modpost _modpost: __modpost
include .config include .config
include scripts/Kbuild.include include scripts/Kbuild.include
include scripts/Makefile.lib include scripts/Makefile.lib
symverfile := $(objtree)/Module.symvers kernelsymfile := $(objtree)/Module.symvers
modulesymfile := $(KBUILD_EXTMOD)/Modules.symvers
# Step 1), find all modules listed in $(MODVERDIR)/ # Step 1), find all modules listed in $(MODVERDIR)/
__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
...@@ -54,10 +55,12 @@ quiet_cmd_modpost = MODPOST ...@@ -54,10 +55,12 @@ quiet_cmd_modpost = MODPOST
cmd_modpost = scripts/mod/modpost \ cmd_modpost = scripts/mod/modpost \
$(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODVERSIONS),-m) \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \
$(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
$(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(filter-out FORCE,$^) $(filter-out FORCE,$^)
.PHONY: __modpost PHONY += __modpost
__modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE __modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE
$(call cmd,modpost) $(call cmd,modpost)
...@@ -94,7 +97,7 @@ targets += $(modules) ...@@ -94,7 +97,7 @@ targets += $(modules)
# Add FORCE to the prequisites of a target to force it to be always rebuilt. # Add FORCE to the prequisites of a target to force it to be always rebuilt.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
.PHONY: FORCE PHONY += FORCE
FORCE: FORCE:
...@@ -109,3 +112,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ...@@ -109,3 +112,9 @@ cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
ifneq ($(cmd_files),) ifneq ($(cmd_files),)
include $(cmd_files) include $(cmd_files)
endif endif
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
.PHONY: $(PHONY)
...@@ -132,20 +132,10 @@ void usage(void) ...@@ -132,20 +132,10 @@ void usage(void)
/* /*
* Print out the commandline prefixed with cmd_<target filename> := * Print out the commandline prefixed with cmd_<target filename> :=
* If commandline contains '#' escape with '\' so make to not see */
* the '#' as a start-of-comment symbol
**/
void print_cmdline(void) void print_cmdline(void)
{ {
char *p = cmdline; printf("cmd_%s := %s\n\n", target, cmdline);
printf("cmd_%s := ", target);
for (; *p; p++) {
if (*p == '#')
printf("\\");
printf("%c", *p);
}
printf("\n\n");
} }
char * str_config = NULL; char * str_config = NULL;
......
#! /usr/bin/perl
#
# checkconfig: find uses of CONFIG_* names without matching definitions.
# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>.
use integer;
$| = 1;
foreach $file (@ARGV)
{
# Open this file.
open(FILE, $file) || die "Can't open $file: $!\n";
# Initialize variables.
my $fInComment = 0;
my $fInString = 0;
my $fUseConfig = 0;
my $iLinuxConfig = 0;
my %configList = ();
LINE: while ( <FILE> )
{
# Strip comments.
$fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
# Pick up definitions.
if ( m/^\s*#/o )
{
$iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o;
$configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o;
}
# Strip strings.
$fInString && (s+^.*?"+ +o ? ($fInString = 0) : next);
m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1)));
# Pick up definitions.
if ( m/^\s*#/o )
{
$iLinuxConfig = $. if m/^\s*#\s*include\s*<linux\/config\.h>/o;
$configList{uc $1} = 1 if m/^\s*#\s*include\s*<config\/(\S*)\.h>/o;
$configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o;
$configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o;
}
# Look for usages.
next unless m/CONFIG_/o;
WORD: while ( m/\bCONFIG_(\w+)/og )
{
$fUseConfig = 1;
last LINE if $iLinuxConfig;
next WORD if exists $configList{$1};
print "$file: $.: need CONFIG_$1.\n";
$configList{$1} = 0;
}
}
# Report superfluous includes.
if ( $iLinuxConfig && ! $fUseConfig )
{ print "$file: $iLinuxConfig: linux/config.h not needed.\n"; }
close(FILE);
}
...@@ -32,32 +32,35 @@ ...@@ -32,32 +32,35 @@
#endif /* __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */
#include "genksyms.h" #include "genksyms.h"
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
#define HASH_BUCKETS 4096 #define HASH_BUCKETS 4096
static struct symbol *symtab[HASH_BUCKETS]; static struct symbol *symtab[HASH_BUCKETS];
FILE *debugfile; static FILE *debugfile;
int cur_line = 1; int cur_line = 1;
char *cur_filename, *output_directory; char *cur_filename;
int flag_debug, flag_dump_defs, flag_warnings; static int flag_debug, flag_dump_defs, flag_warnings;
static const char *arch = "";
static const char *mod_prefix = "";
static int errors; static int errors;
static int nsyms; static int nsyms;
static struct symbol *expansion_trail; static struct symbol *expansion_trail;
static const char * const symbol_type_name[] = { static const char *const symbol_type_name[] = {
"normal", "typedef", "enum", "struct", "union" "normal", "typedef", "enum", "struct", "union"
}; };
static int equal_list(struct string_list *a, struct string_list *b);
static void print_list(FILE * f, struct string_list *list);
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static const unsigned int crctab32[] = static const unsigned int crctab32[] = {
{
0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
...@@ -112,31 +115,26 @@ static const unsigned int crctab32[] = ...@@ -112,31 +115,26 @@ static const unsigned int crctab32[] =
0x2d02ef8dU 0x2d02ef8dU
}; };
static inline unsigned long static unsigned long partial_crc32_one(unsigned char c, unsigned long crc)
partial_crc32_one(unsigned char c, unsigned long crc)
{ {
return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
} }
static inline unsigned long static unsigned long partial_crc32(const char *s, unsigned long crc)
partial_crc32(const char *s, unsigned long crc)
{ {
while (*s) while (*s)
crc = partial_crc32_one(*s++, crc); crc = partial_crc32_one(*s++, crc);
return crc; return crc;
} }
static inline unsigned long static unsigned long crc32(const char *s)
crc32(const char *s)
{ {
return partial_crc32(s, 0xffffffff) ^ 0xffffffff; return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
static inline enum symbol_type static enum symbol_type map_to_ns(enum symbol_type t)
map_to_ns(enum symbol_type t)
{ {
if (t == SYM_TYPEDEF) if (t == SYM_TYPEDEF)
t = SYM_NORMAL; t = SYM_NORMAL;
...@@ -145,33 +143,33 @@ map_to_ns(enum symbol_type t) ...@@ -145,33 +143,33 @@ map_to_ns(enum symbol_type t)
return t; return t;
} }
struct symbol * struct symbol *find_symbol(const char *name, enum symbol_type ns)
find_symbol(const char *name, enum symbol_type ns)
{ {
unsigned long h = crc32(name) % HASH_BUCKETS; unsigned long h = crc32(name) % HASH_BUCKETS;
struct symbol *sym; struct symbol *sym;
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) && strcmp(name, sym->name) == 0) if (map_to_ns(sym->type) == map_to_ns(ns) &&
strcmp(name, sym->name) == 0)
break; break;
return sym; return sym;
} }
struct symbol * struct symbol *add_symbol(const char *name, enum symbol_type type,
add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern) struct string_list *defn, int is_extern)
{ {
unsigned long h = crc32(name) % HASH_BUCKETS; unsigned long h = crc32(name) % HASH_BUCKETS;
struct symbol *sym; struct symbol *sym;
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 (!equal_list(sym->defn, defn))
error_with_pos("redefinition of %s", name); error_with_pos("redefinition of %s", name);
return sym; return sym;
} }
}
sym = xmalloc(sizeof(*sym)); sym = xmalloc(sizeof(*sym));
sym->name = name; sym->name = name;
...@@ -183,9 +181,9 @@ add_symbol(const char *name, enum symbol_type type, struct string_list *defn, in ...@@ -183,9 +181,9 @@ add_symbol(const char *name, enum symbol_type type, struct string_list *defn, in
sym->hash_next = symtab[h]; sym->hash_next = symtab[h];
symtab[h] = sym; symtab[h] = sym;
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);
if (is_extern) if (is_extern)
fputs("extern ", debugfile); fputs("extern ", debugfile);
print_list(debugfile, defn); print_list(debugfile, defn);
...@@ -196,29 +194,24 @@ add_symbol(const char *name, enum symbol_type type, struct string_list *defn, in ...@@ -196,29 +194,24 @@ add_symbol(const char *name, enum symbol_type type, struct string_list *defn, in
return sym; return sym;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
inline void void free_node(struct string_list *node)
free_node(struct string_list *node)
{ {
free(node->string); free(node->string);
free(node); free(node);
} }
void void free_list(struct string_list *s, struct string_list *e)
free_list(struct string_list *s, struct string_list *e)
{ {
while (s != e) while (s != e) {
{
struct string_list *next = s->next; struct string_list *next = s->next;
free_node(s); free_node(s);
s = next; s = next;
} }
} }
inline struct string_list * struct string_list *copy_node(struct string_list *node)
copy_node(struct string_list *node)
{ {
struct string_list *newnode; struct string_list *newnode;
...@@ -229,27 +222,9 @@ copy_node(struct string_list *node) ...@@ -229,27 +222,9 @@ copy_node(struct string_list *node)
return newnode; return newnode;
} }
struct string_list * static int equal_list(struct string_list *a, struct string_list *b)
copy_list(struct string_list *s, struct string_list *e)
{ {
struct string_list *h, *p; while (a && b) {
if (s == e)
return NULL;
p = h = copy_node(s);
while ((s = s->next) != e)
p = p->next = copy_node(s);
p->next = NULL;
return h;
}
int
equal_list(struct string_list *a, struct string_list *b)
{
while (a && b)
{
if (a->tag != b->tag || strcmp(a->string, b->string)) if (a->tag != b->tag || strcmp(a->string, b->string))
return 0; return 0;
a = a->next; a = a->next;
...@@ -259,11 +234,9 @@ equal_list(struct string_list *a, struct string_list *b) ...@@ -259,11 +234,9 @@ equal_list(struct string_list *a, struct string_list *b)
return !a && !b; return !a && !b;
} }
static inline void static void print_node(FILE * f, struct string_list *list)
print_node(FILE *f, struct string_list *list)
{ {
switch (list->tag) switch (list->tag) {
{
case SYM_STRUCT: case SYM_STRUCT:
putc('s', f); putc('s', f);
goto printit; goto printit;
...@@ -285,21 +258,19 @@ print_node(FILE *f, struct string_list *list) ...@@ -285,21 +258,19 @@ print_node(FILE *f, struct string_list *list)
} }
} }
void static void print_list(FILE * f, struct string_list *list)
print_list(FILE *f, struct string_list *list)
{ {
struct string_list **e, **b; struct string_list **e, **b;
struct string_list *tmp, **tmp2; struct string_list *tmp, **tmp2;
int elem = 1; int elem = 1;
if (list == NULL) if (list == NULL) {
{
fputs("(nil)", f); fputs("(nil)", f);
return; return;
} }
tmp = list; tmp = list;
while((tmp = tmp->next) != NULL) while ((tmp = tmp->next) != NULL)
elem++; elem++;
b = alloca(elem * sizeof(*e)); b = alloca(elem * sizeof(*e));
...@@ -307,18 +278,17 @@ print_list(FILE *f, struct string_list *list) ...@@ -307,18 +278,17 @@ print_list(FILE *f, struct string_list *list)
tmp2 = e - 1; tmp2 = e - 1;
(*tmp2--) = list; (*tmp2--) = list;
while((list = list->next) != NULL) while ((list = list->next) != NULL)
*(tmp2--) = list; *(tmp2--) = list;
while (b != e) while (b != e) {
{
print_node(f, *b++); print_node(f, *b++);
putc(' ', f); putc(' ', f);
} }
} }
static unsigned long static unsigned long expand_and_crc_list(struct string_list *list,
expand_and_crc_list(struct string_list *list, unsigned long crc) unsigned long crc)
{ {
struct string_list **e, **b; struct string_list **e, **b;
struct string_list *tmp, **tmp2; struct string_list *tmp, **tmp2;
...@@ -328,7 +298,7 @@ expand_and_crc_list(struct string_list *list, unsigned long crc) ...@@ -328,7 +298,7 @@ expand_and_crc_list(struct string_list *list, unsigned long crc)
return crc; return crc;
tmp = list; tmp = list;
while((tmp = tmp->next) != NULL) while ((tmp = tmp->next) != NULL)
elem++; elem++;
b = alloca(elem * sizeof(*e)); b = alloca(elem * sizeof(*e));
...@@ -339,14 +309,12 @@ expand_and_crc_list(struct string_list *list, unsigned long crc) ...@@ -339,14 +309,12 @@ expand_and_crc_list(struct string_list *list, unsigned long crc)
while ((list = list->next) != NULL) while ((list = list->next) != NULL)
*(tmp2--) = list; *(tmp2--) = list;
while (b != e) while (b != e) {
{
struct string_list *cur; struct string_list *cur;
struct symbol *subsym; struct symbol *subsym;
cur = *(b++); cur = *(b++);
switch (cur->tag) switch (cur->tag) {
{
case SYM_NORMAL: case SYM_NORMAL:
if (flag_dump_defs) if (flag_dump_defs)
fprintf(debugfile, "%s ", cur->string); fprintf(debugfile, "%s ", cur->string);
...@@ -356,15 +324,12 @@ expand_and_crc_list(struct string_list *list, unsigned long crc) ...@@ -356,15 +324,12 @@ expand_and_crc_list(struct string_list *list, unsigned long crc)
case SYM_TYPEDEF: case SYM_TYPEDEF:
subsym = find_symbol(cur->string, cur->tag); subsym = find_symbol(cur->string, cur->tag);
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);
crc = partial_crc32(cur->string, crc); crc = partial_crc32(cur->string, crc);
crc = partial_crc32_one(' ', crc); crc = partial_crc32_one(' ', crc);
} } else {
else
{
subsym->expansion_trail = expansion_trail; subsym->expansion_trail = expansion_trail;
expansion_trail = subsym; expansion_trail = subsym;
crc = expand_and_crc_list(subsym->defn, crc); crc = expand_and_crc_list(subsym->defn, crc);
...@@ -375,12 +340,12 @@ expand_and_crc_list(struct string_list *list, unsigned long crc) ...@@ -375,12 +340,12 @@ expand_and_crc_list(struct string_list *list, unsigned long crc)
case SYM_UNION: case SYM_UNION:
case SYM_ENUM: case SYM_ENUM:
subsym = find_symbol(cur->string, cur->tag); subsym = find_symbol(cur->string, cur->tag);
if (!subsym) if (!subsym) {
{
struct string_list *n, *t = NULL; struct string_list *n, *t = NULL;
error_with_pos("expand undefined %s %s", error_with_pos("expand undefined %s %s",
symbol_type_name[cur->tag], cur->string); symbol_type_name[cur->tag],
cur->string);
n = xmalloc(sizeof(*n)); n = xmalloc(sizeof(*n));
n->string = xstrdup(symbol_type_name[cur->tag]); n->string = xstrdup(symbol_type_name[cur->tag]);
...@@ -399,23 +364,22 @@ expand_and_crc_list(struct string_list *list, unsigned long crc) ...@@ -399,23 +364,22 @@ expand_and_crc_list(struct string_list *list, unsigned long crc)
n->tag = SYM_NORMAL; n->tag = SYM_NORMAL;
n->next = t; n->next = t;
subsym = add_symbol(cur->string, cur->tag, n, 0); subsym =
add_symbol(cur->string, cur->tag, n, 0);
} }
if (subsym->expansion_trail) if (subsym->expansion_trail) {
{ if (flag_dump_defs) {
if (flag_dump_defs) fprintf(debugfile, "%s %s ",
{ symbol_type_name[cur->tag],
fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag],
cur->string); cur->string);
} }
crc = partial_crc32(symbol_type_name[cur->tag], crc); crc = partial_crc32(symbol_type_name[cur->tag],
crc);
crc = partial_crc32_one(' ', crc); crc = partial_crc32_one(' ', crc);
crc = partial_crc32(cur->string, crc); crc = partial_crc32(cur->string, crc);
crc = partial_crc32_one(' ', crc); crc = partial_crc32_one(' ', crc);
} } else {
else
{
subsym->expansion_trail = expansion_trail; subsym->expansion_trail = expansion_trail;
expansion_trail = subsym; expansion_trail = subsym;
crc = expand_and_crc_list(subsym->defn, crc); crc = expand_and_crc_list(subsym->defn, crc);
...@@ -427,16 +391,14 @@ expand_and_crc_list(struct string_list *list, unsigned long crc) ...@@ -427,16 +391,14 @@ expand_and_crc_list(struct string_list *list, unsigned long crc)
return crc; return crc;
} }
void void export_symbol(const char *name)
export_symbol(const char *name)
{ {
struct symbol *sym; struct symbol *sym;
sym = find_symbol(name, SYM_NORMAL); sym = find_symbol(name, SYM_NORMAL);
if (!sym) if (!sym)
error_with_pos("export undefined symbol %s", name); error_with_pos("export undefined symbol %s", name);
else else {
{
unsigned long crc; unsigned long crc;
if (flag_dump_defs) if (flag_dump_defs)
...@@ -447,8 +409,7 @@ export_symbol(const char *name) ...@@ -447,8 +409,7 @@ export_symbol(const char *name)
crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; crc = expand_and_crc_list(sym->defn, 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;
sym->expansion_trail = 0; sym->expansion_trail = 0;
sym = n; sym = n;
...@@ -458,36 +419,18 @@ export_symbol(const char *name) ...@@ -458,36 +419,18 @@ export_symbol(const char *name)
fputs(">\n", debugfile); fputs(">\n", debugfile);
/* Used as a linker script. */ /* Used as a linker script. */
printf("__crc_%s = 0x%08lx ;\n", name, crc); printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc);
} }
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
void error_with_pos(const char *fmt, ...)
void
error(const char *fmt, ...)
{ {
va_list args; va_list args;
if (flag_warnings) if (flag_warnings) {
{ fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>",
va_start(args, fmt); cur_line);
vfprintf(stderr, fmt, args);
va_end(args);
putc('\n', stderr);
errors++;
}
}
void
error_with_pos(const char *fmt, ...)
{
va_list args;
if (flag_warnings)
{
fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
va_start(args, fmt); va_start(args, fmt);
vfprintf(stderr, fmt, args); vfprintf(stderr, fmt, args);
...@@ -498,12 +441,9 @@ error_with_pos(const char *fmt, ...) ...@@ -498,12 +441,9 @@ error_with_pos(const char *fmt, ...)
} }
} }
static void genksyms_usage(void)
void genksyms_usage(void)
{ {
fputs("Usage:\n" fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n"
"genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n"
"\n"
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
" -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"
...@@ -522,13 +462,13 @@ void genksyms_usage(void) ...@@ -522,13 +462,13 @@ void genksyms_usage(void)
, stderr); , stderr);
} }
int int main(int argc, char **argv)
main(int argc, char **argv)
{ {
int o; int o;
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
struct option long_opts[] = { struct option long_opts[] = {
{"arch", 1, 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'},
...@@ -538,13 +478,15 @@ main(int argc, char **argv) ...@@ -538,13 +478,15 @@ main(int argc, char **argv)
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
while ((o = getopt_long(argc, argv, "dwqVDk:p:", while ((o = getopt_long(argc, argv, "a:dwqVDk:p:",
&long_opts[0], NULL)) != EOF) &long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF) while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF)
#endif /* __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */
switch (o) switch (o) {
{ case 'a':
arch = optarg;
break;
case 'd': case 'd':
flag_debug++; flag_debug++;
break; break;
...@@ -567,7 +509,8 @@ main(int argc, char **argv) ...@@ -567,7 +509,8 @@ main(int argc, char **argv)
genksyms_usage(); genksyms_usage();
return 1; return 1;
} }
if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0))
mod_prefix = "_";
{ {
extern int yydebug; extern int yydebug;
extern int yy_flex_debug; extern int yy_flex_debug;
...@@ -581,10 +524,10 @@ main(int argc, char **argv) ...@@ -581,10 +524,10 @@ main(int argc, char **argv)
yyparse(); yyparse();
if (flag_debug) if (flag_debug) {
{
fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS); nsyms, HASH_BUCKETS,
(double)nsyms / (double)HASH_BUCKETS);
} }
return errors != 0; return errors != 0;
......
...@@ -20,27 +20,22 @@ ...@@ -20,27 +20,22 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef MODUTILS_GENKSYMS_H #ifndef MODUTILS_GENKSYMS_H
#define MODUTILS_GENKSYMS_H 1 #define MODUTILS_GENKSYMS_H 1
#include <stdio.h> #include <stdio.h>
enum symbol_type {
enum symbol_type
{
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
}; };
struct string_list struct string_list {
{
struct string_list *next; struct string_list *next;
enum symbol_type tag; enum symbol_type tag;
char *string; char *string;
}; };
struct symbol struct symbol {
{
struct symbol *hash_next; struct symbol *hash_next;
const char *name; const char *name;
enum symbol_type type; enum symbol_type type;
...@@ -52,42 +47,24 @@ struct symbol ...@@ -52,42 +47,24 @@ struct symbol
typedef struct string_list **yystype; typedef struct string_list **yystype;
#define YYSTYPE yystype #define YYSTYPE yystype
extern FILE *outfile, *debugfile;
extern int cur_line; extern int cur_line;
extern char *cur_filename, *output_directory; extern char *cur_filename;
extern int flag_debug, flag_dump_defs, flag_warnings;
extern int checksum_version, kernel_version;
extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents;
extern struct string_list *current_list, *next_list;
struct symbol *find_symbol(const char *name, enum symbol_type ns); struct symbol *find_symbol(const char *name, enum symbol_type ns);
struct symbol *add_symbol(const char *name, enum symbol_type type, struct symbol *add_symbol(const char *name, enum symbol_type type,
struct string_list *defn, int is_extern); struct string_list *defn, int is_extern);
void export_symbol(const char *); void export_symbol(const char *);
struct string_list *reset_list(void);
void free_list(struct string_list *s, struct string_list *e);
void free_node(struct string_list *list); void free_node(struct string_list *list);
void free_list(struct string_list *s, struct string_list *e);
struct string_list *copy_node(struct string_list *); struct string_list *copy_node(struct string_list *);
struct string_list *copy_list(struct string_list *s, struct string_list *e);
int equal_list(struct string_list *a, struct string_list *b);
void print_list(FILE *, struct string_list *list);
int yylex(void); int yylex(void);
int yyparse(void); int yyparse(void);
void error_with_pos(const char *, ...); void error_with_pos(const char *, ...);
#define version(a,b,c) ((a << 16) | (b << 8) | (c))
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
#define MODUTILS_VERSION "<in-kernel>"
#define xmalloc(size) ({ void *__ptr = malloc(size); \ #define xmalloc(size) ({ void *__ptr = malloc(size); \
if(!__ptr && size != 0) { \ if(!__ptr && size != 0) { \
fprintf(stderr, "out of memory\n"); \ fprintf(stderr, "out of memory\n"); \
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Kernel configuration targets # Kernel configuration targets
# These targets are used from top-level makefile # These targets are used from top-level makefile
.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
xconfig: $(obj)/qconf xconfig: $(obj)/qconf
$< arch/$(ARCH)/Kconfig $< arch/$(ARCH)/Kconfig
...@@ -42,7 +42,7 @@ update-po-config: $(obj)/kxgettext ...@@ -42,7 +42,7 @@ update-po-config: $(obj)/kxgettext
$(Q)rm -f arch/um/Kconfig_arch $(Q)rm -f arch/um/Kconfig_arch
$(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot
.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
randconfig: $(obj)/conf randconfig: $(obj)/conf
$< -r arch/$(ARCH)/Kconfig $< -r arch/$(ARCH)/Kconfig
...@@ -78,7 +78,7 @@ help: ...@@ -78,7 +78,7 @@ help:
@echo ' defconfig - New config with default answer to all options' @echo ' defconfig - New config with default answer to all options'
@echo ' allmodconfig - New config selecting modules when possible' @echo ' allmodconfig - New config selecting modules when possible'
@echo ' allyesconfig - New config where all options are accepted with yes' @echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New minimal config' @echo ' allnoconfig - New config where all options are answered with no'
# =========================================================================== # ===========================================================================
# Shared Makefile for the various kconfig executables: # Shared Makefile for the various kconfig executables:
......
...@@ -374,6 +374,7 @@ int conf_write(const char *name) ...@@ -374,6 +374,7 @@ int conf_write(const char *name)
out_h = fopen(".tmpconfig.h", "w"); out_h = fopen(".tmpconfig.h", "w");
if (!out_h) if (!out_h)
return 1; return 1;
file_write_dep(NULL);
} }
sym = sym_lookup("KERNELVERSION", 0); sym = sym_lookup("KERNELVERSION", 0);
sym_calc_value(sym); sym_calc_value(sym);
...@@ -512,7 +513,6 @@ int conf_write(const char *name) ...@@ -512,7 +513,6 @@ int conf_write(const char *name)
if (out_h) { if (out_h) {
fclose(out_h); fclose(out_h);
rename(".tmpconfig.h", "include/linux/autoconf.h"); rename(".tmpconfig.h", "include/linux/autoconf.h");
file_write_dep(NULL);
} }
if (!name || basename != conf_def_filename) { if (!name || basename != conf_def_filename) {
if (!name) if (!name)
......
...@@ -10,7 +10,7 @@ HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) ...@@ -10,7 +10,7 @@ HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
HOST_EXTRACFLAGS += -DLOCALE HOST_EXTRACFLAGS += -DLOCALE
.PHONY: dochecklxdialog PHONY += dochecklxdialog
$(obj)/dochecklxdialog: $(obj)/dochecklxdialog:
$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
......
...@@ -21,11 +21,13 @@ KERNELOUTPUT := $2 ...@@ -21,11 +21,13 @@ KERNELOUTPUT := $2
MAKEFLAGS += --no-print-directory MAKEFLAGS += --no-print-directory
.PHONY: all \$(MAKECMDGOALS)
all: all:
\$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT)
%:: Makefile:;
\$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@
\$(filter-out all Makefile,\$(MAKECMDGOALS)) %/:
\$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@
EOF EOF
...@@ -153,7 +153,7 @@ static void do_usb_table(void *symval, unsigned long size, ...@@ -153,7 +153,7 @@ static void do_usb_table(void *symval, unsigned long size,
const unsigned long id_size = sizeof(struct usb_device_id); const unsigned long id_size = sizeof(struct usb_device_id);
if (size % id_size || size < id_size) { if (size % id_size || size < id_size) {
fprintf(stderr, "*** Warning: %s ids %lu bad size " warn("%s ids %lu bad size "
"(each on %lu)\n", mod->name, size, id_size); "(each on %lu)\n", mod->name, size, id_size);
} }
/* Leave last one: it's the terminator. */ /* Leave last one: it's the terminator. */
...@@ -217,8 +217,7 @@ static int do_pci_entry(const char *filename, ...@@ -217,8 +217,7 @@ static int do_pci_entry(const char *filename,
if ((baseclass_mask != 0 && baseclass_mask != 0xFF) if ((baseclass_mask != 0 && baseclass_mask != 0xFF)
|| (subclass_mask != 0 && subclass_mask != 0xFF) || (subclass_mask != 0 && subclass_mask != 0xFF)
|| (interface_mask != 0 && interface_mask != 0xFF)) { || (interface_mask != 0 && interface_mask != 0xFF)) {
fprintf(stderr, warn("Can't handle masks in %s:%04X\n",
"*** Warning: Can't handle masks in %s:%04X\n",
filename, id->class_mask); filename, id->class_mask);
return 0; return 0;
} }
...@@ -445,7 +444,7 @@ static void do_table(void *symval, unsigned long size, ...@@ -445,7 +444,7 @@ static void do_table(void *symval, unsigned long size,
int (*do_entry)(const char *, void *entry, char *alias) = function; int (*do_entry)(const char *, void *entry, char *alias) = function;
if (size % id_size || size < id_size) { if (size % id_size || size < id_size) {
fprintf(stderr, "*** Warning: %s ids %lu bad size " warn("%s ids %lu bad size "
"(each on %lu)\n", mod->name, size, id_size); "(each on %lu)\n", mod->name, size, id_size);
} }
/* Leave last one: it's the terminator. */ /* Leave last one: it's the terminator. */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* *
* Copyright 2003 Kai Germaschewski * Copyright 2003 Kai Germaschewski
* Copyright 2002-2004 Rusty Russell, IBM Corporation * Copyright 2002-2004 Rusty Russell, IBM Corporation
* * Copyright 2006 Sam Ravnborg
* Based in part on module-init-tools/depmod.c,file2alias * Based in part on module-init-tools/depmod.c,file2alias
* *
* This software may be used and distributed according to the terms * This software may be used and distributed according to the terms
...@@ -20,9 +20,10 @@ int modversions = 0; ...@@ -20,9 +20,10 @@ int modversions = 0;
int have_vmlinux = 0; int have_vmlinux = 0;
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */ /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
static int all_versions = 0; static int all_versions = 0;
/* If we are modposting external module set to 1 */
static int external_module = 0;
void void fatal(const char *fmt, ...)
fatal(const char *fmt, ...)
{ {
va_list arglist; va_list arglist;
...@@ -35,8 +36,7 @@ fatal(const char *fmt, ...) ...@@ -35,8 +36,7 @@ fatal(const char *fmt, ...)
exit(1); exit(1);
} }
void void warn(const char *fmt, ...)
warn(const char *fmt, ...)
{ {
va_list arglist; va_list arglist;
...@@ -47,6 +47,18 @@ warn(const char *fmt, ...) ...@@ -47,6 +47,18 @@ warn(const char *fmt, ...)
va_end(arglist); va_end(arglist);
} }
static int is_vmlinux(const char *modname)
{
const char *myname;
if ((myname = strrchr(modname, '/')))
myname++;
else
myname = modname;
return strcmp(myname, "vmlinux") == 0;
}
void *do_nofail(void *ptr, const char *expr) void *do_nofail(void *ptr, const char *expr)
{ {
if (!ptr) { if (!ptr) {
...@@ -59,8 +71,7 @@ void *do_nofail(void *ptr, const char *expr) ...@@ -59,8 +71,7 @@ void *do_nofail(void *ptr, const char *expr)
static struct module *modules; static struct module *modules;
struct module * static struct module *find_module(char *modname)
find_module(char *modname)
{ {
struct module *mod; struct module *mod;
...@@ -70,8 +81,7 @@ find_module(char *modname) ...@@ -70,8 +81,7 @@ find_module(char *modname)
return mod; return mod;
} }
struct module * static struct module *new_module(char *modname)
new_module(char *modname)
{ {
struct module *mod; struct module *mod;
char *p, *s; char *p, *s;
...@@ -104,6 +114,10 @@ struct symbol { ...@@ -104,6 +114,10 @@ struct symbol {
unsigned int crc; unsigned int crc;
int crc_valid; int crc_valid;
unsigned int weak:1; unsigned int weak:1;
unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
unsigned int kernel:1; /* 1 if symbol is from kernel
* (only for external modules) **/
unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
char name[0]; char name[0];
}; };
...@@ -122,11 +136,12 @@ static inline unsigned int tdb_hash(const char *name) ...@@ -122,11 +136,12 @@ static inline unsigned int tdb_hash(const char *name)
return (1103515243 * value + 12345); return (1103515243 * value + 12345);
} }
/* Allocate a new symbols for use in the hash of exported symbols or /**
* the list of unresolved symbols per module */ * Allocate a new symbols for use in the hash of exported symbols or
* the list of unresolved symbols per module
struct symbol * **/
alloc_symbol(const char *name, unsigned int weak, struct symbol *next) static struct symbol *alloc_symbol(const char *name, unsigned int weak,
struct symbol *next)
{ {
struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
...@@ -138,9 +153,7 @@ alloc_symbol(const char *name, unsigned int weak, struct symbol *next) ...@@ -138,9 +153,7 @@ alloc_symbol(const char *name, unsigned int weak, struct symbol *next)
} }
/* For the hash of exported symbols */ /* For the hash of exported symbols */
static struct symbol *new_symbol(const char *name, struct module *module)
void
new_symbol(const char *name, struct module *module, unsigned int *crc)
{ {
unsigned int hash; unsigned int hash;
struct symbol *new; struct symbol *new;
...@@ -148,14 +161,10 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) ...@@ -148,14 +161,10 @@ new_symbol(const char *name, struct module *module, unsigned int *crc)
hash = tdb_hash(name) % SYMBOL_HASH_SIZE; hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
new->module = module; new->module = module;
if (crc) { return new;
new->crc = *crc;
new->crc_valid = 1;
}
} }
struct symbol * static struct symbol *find_symbol(const char *name)
find_symbol(const char *name)
{ {
struct symbol *s; struct symbol *s;
...@@ -170,25 +179,42 @@ find_symbol(const char *name) ...@@ -170,25 +179,42 @@ find_symbol(const char *name)
return NULL; return NULL;
} }
/* Add an exported symbol - it may have already been added without a /**
* CRC, in this case just update the CRC */ * Add an exported symbol - it may have already been added without a
void * CRC, in this case just update the CRC
add_exported_symbol(const char *name, struct module *module, unsigned int *crc) **/
static struct symbol *sym_add_exported(const char *name, struct module *mod)
{ {
struct symbol *s = find_symbol(name); struct symbol *s = find_symbol(name);
if (!s) { if (!s) {
new_symbol(name, module, crc); s = new_symbol(name, mod);
return; } else {
if (!s->preloaded) {
warn("%s: '%s' exported twice. Previous export "
"was in %s%s\n", mod->name, name,
s->module->name,
is_vmlinux(s->module->name) ?"":".ko");
} }
if (crc) {
s->crc = *crc;
s->crc_valid = 1;
} }
s->preloaded = 0;
s->vmlinux = is_vmlinux(mod->name);
s->kernel = 0;
return s;
} }
void * static void sym_update_crc(const char *name, struct module *mod,
grab_file(const char *filename, unsigned long *size) unsigned int crc)
{
struct symbol *s = find_symbol(name);
if (!s)
s = new_symbol(name, mod);
s->crc = crc;
s->crc_valid = 1;
}
void *grab_file(const char *filename, unsigned long *size)
{ {
struct stat st; struct stat st;
void *map; void *map;
...@@ -207,13 +233,12 @@ grab_file(const char *filename, unsigned long *size) ...@@ -207,13 +233,12 @@ grab_file(const char *filename, unsigned long *size)
return map; return map;
} }
/* /**
Return a copy of the next line in a mmap'ed file. * Return a copy of the next line in a mmap'ed file.
spaces in the beginning of the line is trimmed away. * spaces in the beginning of the line is trimmed away.
Return a pointer to a static buffer. * Return a pointer to a static buffer.
*/ **/
char* char* get_next_line(unsigned long *pos, void *file, unsigned long size)
get_next_line(unsigned long *pos, void *file, unsigned long size)
{ {
static char line[4096]; static char line[4096];
int skip = 1; int skip = 1;
...@@ -243,14 +268,12 @@ get_next_line(unsigned long *pos, void *file, unsigned long size) ...@@ -243,14 +268,12 @@ get_next_line(unsigned long *pos, void *file, unsigned long size)
return NULL; return NULL;
} }
void void release_file(void *file, unsigned long size)
release_file(void *file, unsigned long size)
{ {
munmap(file, size); munmap(file, size);
} }
void static void parse_elf(struct elf_info *info, const char *filename)
parse_elf(struct elf_info *info, const char *filename)
{ {
unsigned int i; unsigned int i;
Elf_Ehdr *hdr = info->hdr; Elf_Ehdr *hdr = info->hdr;
...@@ -303,8 +326,7 @@ parse_elf(struct elf_info *info, const char *filename) ...@@ -303,8 +326,7 @@ parse_elf(struct elf_info *info, const char *filename)
sechdrs[sechdrs[i].sh_link].sh_offset; sechdrs[sechdrs[i].sh_link].sh_offset;
} }
if (!info->symtab_start) { if (!info->symtab_start) {
fprintf(stderr, "modpost: %s no symtab?\n", filename); fatal("%s has no symtab?\n", filename);
abort();
} }
/* Fix endianness in symbols */ /* Fix endianness in symbols */
for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
...@@ -316,36 +338,31 @@ parse_elf(struct elf_info *info, const char *filename) ...@@ -316,36 +338,31 @@ parse_elf(struct elf_info *info, const char *filename)
return; return;
truncated: truncated:
fprintf(stderr, "modpost: %s is truncated.\n", filename); fatal("%s is truncated.\n", filename);
abort();
} }
void static void parse_elf_finish(struct elf_info *info)
parse_elf_finish(struct elf_info *info)
{ {
release_file(info->hdr, info->size); release_file(info->hdr, info->size);
} }
#define CRC_PFX "__crc_" #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
#define KSYMTAB_PFX "__ksymtab_" #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
void static void handle_modversions(struct module *mod, struct elf_info *info,
handle_modversions(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname) Elf_Sym *sym, const char *symname)
{ {
unsigned int crc; unsigned int crc;
switch (sym->st_shndx) { switch (sym->st_shndx) {
case SHN_COMMON: case SHN_COMMON:
fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n", warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
symname, mod->name);
break; break;
case SHN_ABS: case SHN_ABS:
/* CRC'd symbol */ /* CRC'd symbol */
if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
crc = (unsigned int) sym->st_value; crc = (unsigned int) sym->st_value;
add_exported_symbol(symname + strlen(CRC_PFX), sym_update_crc(symname + strlen(CRC_PFX), mod, crc);
mod, &crc);
} }
break; break;
case SHN_UNDEF: case SHN_UNDEF:
...@@ -389,8 +406,7 @@ handle_modversions(struct module *mod, struct elf_info *info, ...@@ -389,8 +406,7 @@ handle_modversions(struct module *mod, struct elf_info *info,
default: default:
/* All exported symbols */ /* All exported symbols */
if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
add_exported_symbol(symname + strlen(KSYMTAB_PFX), sym_add_exported(symname + strlen(KSYMTAB_PFX), mod);
mod, NULL);
} }
if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
mod->has_init = 1; mod->has_init = 1;
...@@ -400,20 +416,9 @@ handle_modversions(struct module *mod, struct elf_info *info, ...@@ -400,20 +416,9 @@ handle_modversions(struct module *mod, struct elf_info *info,
} }
} }
int /**
is_vmlinux(const char *modname) * Parse tag=value strings from .modinfo section
{ **/
const char *myname;
if ((myname = strrchr(modname, '/')))
myname++;
else
myname = modname;
return strcmp(myname, "vmlinux") == 0;
}
/* Parse tag=value strings from .modinfo section */
static char *next_string(char *string, unsigned long *secsize) static char *next_string(char *string, unsigned long *secsize)
{ {
/* Skip non-zero chars */ /* Skip non-zero chars */
...@@ -446,8 +451,418 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, ...@@ -446,8 +451,418 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
return NULL; return NULL;
} }
void /**
read_symbols(char *modname) * Test if string s ends in string sub
* return 0 if match
**/
static int strrcmp(const char *s, const char *sub)
{
int slen, sublen;
if (!s || !sub)
return 1;
slen = strlen(s);
sublen = strlen(sub);
if ((slen == 0) || (sublen == 0))
return 1;
if (sublen > slen)
return 1;
return memcmp(s + slen - sublen, sub, sublen);
}
/**
* Whitelist to allow certain references to pass with no warning.
* Pattern 1:
* If a module parameter is declared __initdata and permissions=0
* then this is legal despite the warning generated.
* We cannot see value of permissions here, so just ignore
* this pattern.
* The pattern is identified by:
* tosec = .init.data
* fromsec = .data*
* atsym =__param*
*
* Pattern 2:
* Many drivers utilise a *_driver container with references to
* add, remove, probe functions etc.
* These functions may often be marked __init and we do not want to
* warn here.
* the pattern is identified by:
* tosec = .init.text | .exit.text
* fromsec = .data
* atsym = *_driver, *_ops, *_probe, *probe_one
**/
static int secref_whitelist(const char *tosec, const char *fromsec,
const char *atsym)
{
int f1 = 1, f2 = 1;
const char **s;
const char *pat2sym[] = {
"_driver",
"_ops",
"_probe",
"_probe_one",
NULL
};
/* Check for pattern 1 */
if (strcmp(tosec, ".init.data") != 0)
f1 = 0;
if (strncmp(fromsec, ".data", strlen(".data")) != 0)
f1 = 0;
if (strncmp(atsym, "__param", strlen("__param")) != 0)
f1 = 0;
if (f1)
return f1;
/* Check for pattern 2 */
if ((strcmp(tosec, ".init.text") != 0) &&
(strcmp(tosec, ".exit.text") != 0))
f2 = 0;
if (strcmp(fromsec, ".data") != 0)
f2 = 0;
for (s = pat2sym; *s; s++)
if (strrcmp(atsym, *s) == 0)
f1 = 1;
return f1 && f2;
}
/**
* Find symbol based on relocation record info.
* In some cases the symbol supplied is a valid symbol so
* return refsym. If st_name != 0 we assume this is a valid symbol.
* In other cases the symbol needs to be looked up in the symbol table
* based on section and address.
* **/
static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr,
Elf_Sym *relsym)
{
Elf_Sym *sym;
if (relsym->st_name != 0)
return relsym;
for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
if (sym->st_shndx != relsym->st_shndx)
continue;
if (sym->st_value == addr)
return sym;
}
return NULL;
}
/*
* Find symbols before or equal addr and after addr - in the section sec.
* If we find two symbols with equal offset prefer one with a valid name.
* The ELF format may have a better way to detect what type of symbol
* it is, but this works for now.
**/
static void find_symbols_between(struct elf_info *elf, Elf_Addr addr,
const char *sec,
Elf_Sym **before, Elf_Sym **after)
{
Elf_Sym *sym;
Elf_Ehdr *hdr = elf->hdr;
Elf_Addr beforediff = ~0;
Elf_Addr afterdiff = ~0;
const char *secstrings = (void *)hdr +
elf->sechdrs[hdr->e_shstrndx].sh_offset;
*before = NULL;
*after = NULL;
for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
const char *symsec;
if (sym->st_shndx >= SHN_LORESERVE)
continue;
symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name;
if (strcmp(symsec, sec) != 0)
continue;
if (sym->st_value <= addr) {
if ((addr - sym->st_value) < beforediff) {
beforediff = addr - sym->st_value;
*before = sym;
}
else if ((addr - sym->st_value) == beforediff) {
/* equal offset, valid name? */
const char *name = elf->strtab + sym->st_name;
if (name && strlen(name))
*before = sym;
}
}
else
{
if ((sym->st_value - addr) < afterdiff) {
afterdiff = sym->st_value - addr;
*after = sym;
}
else if ((sym->st_value - addr) == afterdiff) {
/* equal offset, valid name? */
const char *name = elf->strtab + sym->st_name;
if (name && strlen(name))
*after = sym;
}
}
}
}
/**
* Print a warning about a section mismatch.
* Try to find symbols near it so user can find it.
* Check whitelist before warning - it may be a false positive.
**/
static void warn_sec_mismatch(const char *modname, const char *fromsec,
struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
{
const char *refsymname = "";
Elf_Sym *before, *after;
Elf_Sym *refsym;
Elf_Ehdr *hdr = elf->hdr;
Elf_Shdr *sechdrs = elf->sechdrs;
const char *secstrings = (void *)hdr +
sechdrs[hdr->e_shstrndx].sh_offset;
const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
find_symbols_between(elf, r.r_offset, fromsec, &before, &after);
refsym = find_elf_symbol(elf, r.r_addend, sym);
if (refsym && strlen(elf->strtab + refsym->st_name))
refsymname = elf->strtab + refsym->st_name;
/* check whitelist - we may ignore it */
if (before &&
secref_whitelist(secname, fromsec, elf->strtab + before->st_name))
return;
if (before && after) {
warn("%s - Section mismatch: reference to %s:%s from %s "
"between '%s' (at offset 0x%llx) and '%s'\n",
modname, secname, refsymname, fromsec,
elf->strtab + before->st_name,
(long long)r.r_offset,
elf->strtab + after->st_name);
} else if (before) {
warn("%s - Section mismatch: reference to %s:%s from %s "
"after '%s' (at offset 0x%llx)\n",
modname, secname, refsymname, fromsec,
elf->strtab + before->st_name,
(long long)r.r_offset);
} else if (after) {
warn("%s - Section mismatch: reference to %s:%s from %s "
"before '%s' (at offset -0x%llx)\n",
modname, secname, refsymname, fromsec,
elf->strtab + before->st_name,
(long long)r.r_offset);
} else {
warn("%s - Section mismatch: reference to %s:%s from %s "
"(offset 0x%llx)\n",
modname, secname, fromsec, refsymname,
(long long)r.r_offset);
}
}
/**
* A module includes a number of sections that are discarded
* either when loaded or when used as built-in.
* For loaded modules all functions marked __init and all data
* marked __initdata will be discarded when the module has been intialized.
* Likewise for modules used built-in the sections marked __exit
* are discarded because __exit marked function are supposed to be called
* only when a moduel is unloaded which never happes for built-in modules.
* The check_sec_ref() function traverses all relocation records
* to find all references to a section that reference a section that will
* be discarded and warns about it.
**/
static void check_sec_ref(struct module *mod, const char *modname,
struct elf_info *elf,
int section(const char*),
int section_ref_ok(const char *))
{
int i;
Elf_Sym *sym;
Elf_Ehdr *hdr = elf->hdr;
Elf_Shdr *sechdrs = elf->sechdrs;
const char *secstrings = (void *)hdr +
sechdrs[hdr->e_shstrndx].sh_offset;
/* Walk through all sections */
for (i = 0; i < hdr->e_shnum; i++) {
Elf_Rela *rela;
Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
Elf_Rela *stop = (void*)start + sechdrs[i].sh_size;
const char *name = secstrings + sechdrs[i].sh_name +
strlen(".rela");
/* We want to process only relocation sections and not .init */
if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA))
continue;
for (rela = start; rela < stop; rela++) {
Elf_Rela r;
const char *secname;
r.r_offset = TO_NATIVE(rela->r_offset);
r.r_info = TO_NATIVE(rela->r_info);
r.r_addend = TO_NATIVE(rela->r_addend);
sym = elf->symtab_start + ELF_R_SYM(r.r_info);
/* Skip special sections */
if (sym->st_shndx >= SHN_LORESERVE)
continue;
secname = secstrings + sechdrs[sym->st_shndx].sh_name;
if (section(secname))
warn_sec_mismatch(modname, name, elf, sym, r);
}
}
}
/**
* Functions used only during module init is marked __init and is stored in
* a .init.text section. Likewise data is marked __initdata and stored in
* a .init.data section.
* If this section is one of these sections return 1
* See include/linux/init.h for the details
**/
static int init_section(const char *name)
{
if (strcmp(name, ".init") == 0)
return 1;
if (strncmp(name, ".init.", strlen(".init.")) == 0)
return 1;
return 0;
}
/**
* Identify sections from which references to a .init section is OK.
*
* Unfortunately references to read only data that referenced .init
* sections had to be excluded. Almost all of these are false
* positives, they are created by gcc. The downside of excluding rodata
* is that there really are some user references from rodata to
* init code, e.g. drivers/video/vgacon.c:
*
* const struct consw vga_con = {
* con_startup: vgacon_startup,
*
* where vgacon_startup is __init. If you want to wade through the false
* positives, take out the check for rodata.
**/
static int init_section_ref_ok(const char *name)
{
const char **s;
/* Absolute section names */
const char *namelist1[] = {
".init",
".opd", /* see comment [OPD] at exit_section_ref_ok() */
".toc1", /* used by ppc64 */
".stab",
".rodata",
".text.lock",
"__bug_table", /* used by powerpc for BUG() */
".pci_fixup_header",
".pci_fixup_final",
".pdr",
"__param",
NULL
};
/* Start of section names */
const char *namelist2[] = {
".init.",
".altinstructions",
".eh_frame",
".debug",
NULL
};
/* part of section name */
const char *namelist3 [] = {
".unwind", /* sample: IA_64.unwind.init.text */
NULL
};
for (s = namelist1; *s; s++)
if (strcmp(*s, name) == 0)
return 1;
for (s = namelist2; *s; s++)
if (strncmp(*s, name, strlen(*s)) == 0)
return 1;
for (s = namelist3; *s; s++)
if (strstr(name, *s) != NULL)
return 1;
return 0;
}
/*
* Functions used only during module exit is marked __exit and is stored in
* a .exit.text section. Likewise data is marked __exitdata and stored in
* a .exit.data section.
* If this section is one of these sections return 1
* See include/linux/init.h for the details
**/
static int exit_section(const char *name)
{
if (strcmp(name, ".exit.text") == 0)
return 1;
if (strcmp(name, ".exit.data") == 0)
return 1;
return 0;
}
/*
* Identify sections from which references to a .exit section is OK.
*
* [OPD] Keith Ownes <kaos@sgi.com> commented:
* For our future {in}sanity, add a comment that this is the ppc .opd
* section, not the ia64 .opd section.
* ia64 .opd should not point to discarded sections.
**/
static int exit_section_ref_ok(const char *name)
{
const char **s;
/* Absolute section names */
const char *namelist1[] = {
".exit.text",
".exit.data",
".init.text",
".opd", /* See comment [OPD] */
".toc1", /* used by ppc64 */
".altinstructions",
".pdr",
"__bug_table", /* used by powerpc for BUG() */
".exitcall.exit",
".eh_frame",
".stab",
NULL
};
/* Start of section names */
const char *namelist2[] = {
".debug",
NULL
};
/* part of section name */
const char *namelist3 [] = {
".unwind", /* Sample: IA_64.unwind.exit.text */
NULL
};
for (s = namelist1; *s; s++)
if (strcmp(*s, name) == 0)
return 1;
for (s = namelist2; *s; s++)
if (strncmp(*s, name, strlen(*s)) == 0)
return 1;
for (s = namelist3; *s; s++)
if (strstr(name, *s) != NULL)
return 1;
return 0;
}
static void read_symbols(char *modname)
{ {
const char *symname; const char *symname;
char *version; char *version;
...@@ -462,9 +877,7 @@ read_symbols(char *modname) ...@@ -462,9 +877,7 @@ read_symbols(char *modname)
/* When there's no vmlinux, don't print warnings about /* When there's no vmlinux, don't print warnings about
* unresolved symbols (since there'll be too many ;) */ * unresolved symbols (since there'll be too many ;) */
if (is_vmlinux(modname)) { if (is_vmlinux(modname)) {
unsigned int fake_crc = 0;
have_vmlinux = 1; have_vmlinux = 1;
add_exported_symbol("struct_module", mod, &fake_crc);
mod->skip = 1; mod->skip = 1;
} }
...@@ -474,6 +887,8 @@ read_symbols(char *modname) ...@@ -474,6 +887,8 @@ read_symbols(char *modname)
handle_modversions(mod, &info, sym, symname); handle_modversions(mod, &info, sym, symname);
handle_moddevtable(mod, &info, sym, symname); handle_moddevtable(mod, &info, sym, symname);
} }
check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok);
check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok);
version = get_modinfo(info.modinfo, info.modinfo_len, "version"); version = get_modinfo(info.modinfo, info.modinfo_len, "version");
if (version) if (version)
...@@ -499,8 +914,8 @@ read_symbols(char *modname) ...@@ -499,8 +914,8 @@ read_symbols(char *modname)
* following helper, then compare to the file on disk and * following helper, then compare to the file on disk and
* only update the later if anything changed */ * only update the later if anything changed */
void __attribute__((format(printf, 2, 3))) void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
buf_printf(struct buffer *buf, const char *fmt, ...) const char *fmt, ...)
{ {
char tmp[SZ]; char tmp[SZ];
int len; int len;
...@@ -512,8 +927,7 @@ buf_printf(struct buffer *buf, const char *fmt, ...) ...@@ -512,8 +927,7 @@ buf_printf(struct buffer *buf, const char *fmt, ...)
va_end(ap); va_end(ap);
} }
void void buf_write(struct buffer *buf, const char *s, int len)
buf_write(struct buffer *buf, const char *s, int len)
{ {
if (buf->size - buf->pos < len) { if (buf->size - buf->pos < len) {
buf->size += len + SZ; buf->size += len + SZ;
...@@ -523,10 +937,10 @@ buf_write(struct buffer *buf, const char *s, int len) ...@@ -523,10 +937,10 @@ buf_write(struct buffer *buf, const char *s, int len)
buf->pos += len; buf->pos += len;
} }
/* Header for the generated file */ /**
* Header for the generated file
void **/
add_header(struct buffer *b, struct module *mod) static void add_header(struct buffer *b, struct module *mod)
{ {
buf_printf(b, "#include <linux/module.h>\n"); buf_printf(b, "#include <linux/module.h>\n");
buf_printf(b, "#include <linux/vermagic.h>\n"); buf_printf(b, "#include <linux/vermagic.h>\n");
...@@ -546,10 +960,10 @@ add_header(struct buffer *b, struct module *mod) ...@@ -546,10 +960,10 @@ add_header(struct buffer *b, struct module *mod)
buf_printf(b, "};\n"); buf_printf(b, "};\n");
} }
/* Record CRCs for unresolved symbols */ /**
* Record CRCs for unresolved symbols
void **/
add_versions(struct buffer *b, struct module *mod) static void add_versions(struct buffer *b, struct module *mod)
{ {
struct symbol *s, *exp; struct symbol *s, *exp;
...@@ -557,8 +971,8 @@ add_versions(struct buffer *b, struct module *mod) ...@@ -557,8 +971,8 @@ add_versions(struct buffer *b, struct module *mod)
exp = find_symbol(s->name); exp = find_symbol(s->name);
if (!exp || exp->module == mod) { if (!exp || exp->module == mod) {
if (have_vmlinux && !s->weak) if (have_vmlinux && !s->weak)
fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " warn("\"%s\" [%s.ko] undefined!\n",
"undefined!\n", s->name, mod->name); s->name, mod->name);
continue; continue;
} }
s->module = exp->module; s->module = exp->module;
...@@ -579,8 +993,7 @@ add_versions(struct buffer *b, struct module *mod) ...@@ -579,8 +993,7 @@ add_versions(struct buffer *b, struct module *mod)
continue; continue;
} }
if (!s->crc_valid) { if (!s->crc_valid) {
fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " warn("\"%s\" [%s.ko] has no CRC!\n",
"has no CRC!\n",
s->name, mod->name); s->name, mod->name);
continue; continue;
} }
...@@ -590,8 +1003,8 @@ add_versions(struct buffer *b, struct module *mod) ...@@ -590,8 +1003,8 @@ add_versions(struct buffer *b, struct module *mod)
buf_printf(b, "};\n"); buf_printf(b, "};\n");
} }
void static void add_depends(struct buffer *b, struct module *mod,
add_depends(struct buffer *b, struct module *mod, struct module *modules) struct module *modules)
{ {
struct symbol *s; struct symbol *s;
struct module *m; struct module *m;
...@@ -621,8 +1034,7 @@ add_depends(struct buffer *b, struct module *mod, struct module *modules) ...@@ -621,8 +1034,7 @@ add_depends(struct buffer *b, struct module *mod, struct module *modules)
buf_printf(b, "\";\n"); buf_printf(b, "\";\n");
} }
void static void add_srcversion(struct buffer *b, struct module *mod)
add_srcversion(struct buffer *b, struct module *mod)
{ {
if (mod->srcversion[0]) { if (mod->srcversion[0]) {
buf_printf(b, "\n"); buf_printf(b, "\n");
...@@ -631,8 +1043,7 @@ add_srcversion(struct buffer *b, struct module *mod) ...@@ -631,8 +1043,7 @@ add_srcversion(struct buffer *b, struct module *mod)
} }
} }
void static void write_if_changed(struct buffer *b, const char *fname)
write_if_changed(struct buffer *b, const char *fname)
{ {
char *tmp; char *tmp;
FILE *file; FILE *file;
...@@ -676,8 +1087,7 @@ write_if_changed(struct buffer *b, const char *fname) ...@@ -676,8 +1087,7 @@ write_if_changed(struct buffer *b, const char *fname)
fclose(file); fclose(file);
} }
void static void read_dump(const char *fname, unsigned int kernel)
read_dump(const char *fname)
{ {
unsigned long size, pos = 0; unsigned long size, pos = 0;
void *file = grab_file(fname, &size); void *file = grab_file(fname, &size);
...@@ -691,6 +1101,7 @@ read_dump(const char *fname) ...@@ -691,6 +1101,7 @@ read_dump(const char *fname)
char *symname, *modname, *d; char *symname, *modname, *d;
unsigned int crc; unsigned int crc;
struct module *mod; struct module *mod;
struct symbol *s;
if (!(symname = strchr(line, '\t'))) if (!(symname = strchr(line, '\t')))
goto fail; goto fail;
...@@ -711,15 +1122,30 @@ read_dump(const char *fname) ...@@ -711,15 +1122,30 @@ read_dump(const char *fname)
mod = new_module(NOFAIL(strdup(modname))); mod = new_module(NOFAIL(strdup(modname)));
mod->skip = 1; mod->skip = 1;
} }
add_exported_symbol(symname, mod, &crc); s = sym_add_exported(symname, mod);
s->kernel = kernel;
s->preloaded = 1;
sym_update_crc(symname, mod, crc);
} }
return; return;
fail: fail:
fatal("parse error in symbol dump file\n"); fatal("parse error in symbol dump file\n");
} }
void /* For normal builds always dump all symbols.
write_dump(const char *fname) * For external modules only dump symbols
* that are not read from kernel Module.symvers.
**/
static int dump_sym(struct symbol *sym)
{
if (!external_module)
return 1;
if (sym->vmlinux || sym->kernel)
return 0;
return 1;
}
static void write_dump(const char *fname)
{ {
struct buffer buf = { }; struct buffer buf = { };
struct symbol *symbol; struct symbol *symbol;
...@@ -728,34 +1154,33 @@ write_dump(const char *fname) ...@@ -728,34 +1154,33 @@ write_dump(const char *fname)
for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
symbol = symbolhash[n]; symbol = symbolhash[n];
while (symbol) { while (symbol) {
symbol = symbol->next; if (dump_sym(symbol))
} buf_printf(&buf, "0x%08x\t%s\t%s\n",
} symbol->crc, symbol->name,
symbol->module->name);
for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
symbol = symbolhash[n];
while (symbol) {
buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,
symbol->name, symbol->module->name);
symbol = symbol->next; symbol = symbol->next;
} }
} }
write_if_changed(&buf, fname); write_if_changed(&buf, fname);
} }
int int main(int argc, char **argv)
main(int argc, char **argv)
{ {
struct module *mod; struct module *mod;
struct buffer buf = { }; struct buffer buf = { };
char fname[SZ]; char fname[SZ];
char *dump_read = NULL, *dump_write = NULL; char *kernel_read = NULL, *module_read = NULL;
char *dump_write = NULL;
int opt; int opt;
while ((opt = getopt(argc, argv, "i:mo:a")) != -1) { while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) {
switch(opt) { switch(opt) {
case 'i': case 'i':
dump_read = optarg; kernel_read = optarg;
break;
case 'I':
module_read = optarg;
external_module = 1;
break; break;
case 'm': case 'm':
modversions = 1; modversions = 1;
...@@ -771,8 +1196,10 @@ main(int argc, char **argv) ...@@ -771,8 +1196,10 @@ main(int argc, char **argv)
} }
} }
if (dump_read) if (kernel_read)
read_dump(dump_read); read_dump(kernel_read, 1);
if (module_read)
read_dump(module_read, 0);
while (optind < argc) { while (optind < argc) {
read_symbols(argv[optind++]); read_symbols(argv[optind++]);
...@@ -799,4 +1226,3 @@ main(int argc, char **argv) ...@@ -799,4 +1226,3 @@ main(int argc, char **argv)
return 0; return 0;
} }
...@@ -16,17 +16,27 @@ ...@@ -16,17 +16,27 @@
#define Elf_Ehdr Elf32_Ehdr #define Elf_Ehdr Elf32_Ehdr
#define Elf_Shdr Elf32_Shdr #define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym #define Elf_Sym Elf32_Sym
#define Elf_Addr Elf32_Addr
#define Elf_Section Elf32_Section
#define ELF_ST_BIND ELF32_ST_BIND #define ELF_ST_BIND ELF32_ST_BIND
#define ELF_ST_TYPE ELF32_ST_TYPE #define ELF_ST_TYPE ELF32_ST_TYPE
#define Elf_Rela Elf32_Rela
#define ELF_R_SYM ELF32_R_SYM
#define ELF_R_TYPE ELF32_R_TYPE
#else #else
#define Elf_Ehdr Elf64_Ehdr #define Elf_Ehdr Elf64_Ehdr
#define Elf_Shdr Elf64_Shdr #define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym #define Elf_Sym Elf64_Sym
#define Elf_Addr Elf64_Addr
#define Elf_Section Elf64_Section
#define ELF_ST_BIND ELF64_ST_BIND #define ELF_ST_BIND ELF64_ST_BIND
#define ELF_ST_TYPE ELF64_ST_TYPE #define ELF_ST_TYPE ELF64_ST_TYPE
#define Elf_Rela Elf64_Rela
#define ELF_R_SYM ELF64_R_SYM
#define ELF_R_TYPE ELF64_R_TYPE
#endif #endif
#if KERNEL_ELFDATA != HOST_ELFDATA #if KERNEL_ELFDATA != HOST_ELFDATA
...@@ -91,17 +101,22 @@ struct elf_info { ...@@ -91,17 +101,22 @@ struct elf_info {
unsigned int modinfo_len; unsigned int modinfo_len;
}; };
/* file2alias.c */
void handle_moddevtable(struct module *mod, struct elf_info *info, void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname); Elf_Sym *sym, const char *symname);
void add_moddevtable(struct buffer *buf, struct module *mod); void add_moddevtable(struct buffer *buf, struct module *mod);
/* sumversion.c */
void maybe_frob_rcs_version(const char *modfilename, void maybe_frob_rcs_version(const char *modfilename,
char *version, char *version,
void *modinfo, void *modinfo,
unsigned long modinfo_offset); unsigned long modinfo_offset);
void get_src_version(const char *modname, char sum[], unsigned sumlen); void get_src_version(const char *modname, char sum[], unsigned sumlen);
/* from modpost.c */
void *grab_file(const char *filename, unsigned long *size); void *grab_file(const char *filename, unsigned long *size);
char* get_next_line(unsigned long *pos, void *file, unsigned long size); char* get_next_line(unsigned long *pos, void *file, unsigned long size);
void release_file(void *file, unsigned long size); void release_file(void *file, unsigned long size);
void fatal(const char *fmt, ...);
void warn(const char *fmt, ...);
...@@ -316,8 +316,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) ...@@ -316,8 +316,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
file = grab_file(cmd, &flen); file = grab_file(cmd, &flen);
if (!file) { if (!file) {
fprintf(stderr, "Warning: could not find %s for %s\n", warn("could not find %s for %s\n", cmd, objfile);
cmd, objfile);
goto out; goto out;
} }
...@@ -355,8 +354,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) ...@@ -355,8 +354,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
/* Check if this file is in same dir as objfile */ /* Check if this file is in same dir as objfile */
if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {
if (!parse_file(line, md)) { if (!parse_file(line, md)) {
fprintf(stderr, warn("could not open %s: %s\n",
"Warning: could not open %s: %s\n",
line, strerror(errno)); line, strerror(errno));
goto out_file; goto out_file;
} }
...@@ -383,8 +381,11 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) ...@@ -383,8 +381,11 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen)
struct md4_ctx md; struct md4_ctx md;
char *sources, *end, *fname; char *sources, *end, *fname;
const char *basename; const char *basename;
char filelist[strlen(getenv("MODVERDIR")) + strlen("/") + char filelist[PATH_MAX + 1];
strlen(modname) - strlen(".o") + strlen(".mod") + 1 ]; char *modverdir = getenv("MODVERDIR");
if (!modverdir)
modverdir = ".";
/* Source files for module are in .tmp_versions/modname.mod, /* Source files for module are in .tmp_versions/modname.mod,
after the first line. */ after the first line. */
...@@ -392,28 +393,25 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) ...@@ -392,28 +393,25 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen)
basename = strrchr(modname, '/') + 1; basename = strrchr(modname, '/') + 1;
else else
basename = modname; basename = modname;
sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"), sprintf(filelist, "%s/%.*s.mod", modverdir,
(int) strlen(basename) - 2, basename); (int) strlen(basename) - 2, basename);
file = grab_file(filelist, &len); file = grab_file(filelist, &len);
if (!file) { if (!file) {
fprintf(stderr, "Warning: could not find versions for %s\n", warn("could not find versions for %s\n", filelist);
filelist);
return; return;
} }
sources = strchr(file, '\n'); sources = strchr(file, '\n');
if (!sources) { if (!sources) {
fprintf(stderr, "Warning: malformed versions file for %s\n", warn("malformed versions file for %s\n", modname);
modname);
goto release; goto release;
} }
sources++; sources++;
end = strchr(sources, '\n'); end = strchr(sources, '\n');
if (!end) { if (!end) {
fprintf(stderr, "Warning: bad ending versions file for %s\n", warn("bad ending versions file for %s\n", modname);
modname);
goto release; goto release;
} }
*end = '\0'; *end = '\0';
...@@ -438,19 +436,19 @@ static void write_version(const char *filename, const char *sum, ...@@ -438,19 +436,19 @@ static void write_version(const char *filename, const char *sum,
fd = open(filename, O_RDWR); fd = open(filename, O_RDWR);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "Warning: changing sum in %s failed: %s\n", warn("changing sum in %s failed: %s\n",
filename, strerror(errno)); filename, strerror(errno));
return; return;
} }
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n", warn("changing sum in %s:%lu failed: %s\n",
filename, offset, strerror(errno)); filename, offset, strerror(errno));
goto out; goto out;
} }
if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
fprintf(stderr, "Warning: writing sum in %s failed: %s\n", warn("writing sum in %s failed: %s\n",
filename, strerror(errno)); filename, strerror(errno));
goto out; goto out;
} }
......
...@@ -66,8 +66,8 @@ require 5; # at least perl 5 ...@@ -66,8 +66,8 @@ require 5; # at least perl 5
use strict; use strict;
use File::Find; use File::Find;
my $nm = "/usr/bin/nm -p"; my $nm = ($ENV{'NM'} || "nm") . " -p";
my $objdump = "/usr/bin/objdump -s -j .comment"; my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment";
my $srctree = ""; my $srctree = "";
my $objtree = ""; my $objtree = "";
$srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'})); $srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'}));
......
...@@ -32,12 +32,11 @@ MKSPEC := $(srctree)/scripts/package/mkspec ...@@ -32,12 +32,11 @@ MKSPEC := $(srctree)/scripts/package/mkspec
PREV := set -e; cd ..; PREV := set -e; cd ..;
# rpm-pkg # rpm-pkg
.PHONY: rpm-pkg rpm # ---------------------------------------------------------------------------
$(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile
$(CONFIG_SHELL) $(MKSPEC) > $@ $(CONFIG_SHELL) $(MKSPEC) > $@
rpm-pkg rpm: $(objtree)/kernel.spec rpm-pkg rpm: $(objtree)/kernel.spec FORCE
$(MAKE) clean $(MAKE) clean
$(PREV) ln -sf $(srctree) $(KERNELPATH) $(PREV) ln -sf $(srctree) $(KERNELPATH)
$(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
...@@ -54,11 +53,11 @@ rpm-pkg rpm: $(objtree)/kernel.spec ...@@ -54,11 +53,11 @@ rpm-pkg rpm: $(objtree)/kernel.spec
clean-files := $(objtree)/kernel.spec clean-files := $(objtree)/kernel.spec
# binrpm-pkg # binrpm-pkg
.PHONY: binrpm-pkg # ---------------------------------------------------------------------------
$(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile $(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile
$(CONFIG_SHELL) $(MKSPEC) prebuilt > $@ $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@
binrpm-pkg: $(objtree)/binkernel.spec binrpm-pkg: $(objtree)/binkernel.spec FORCE
$(MAKE) KBUILD_SRC= $(MAKE) KBUILD_SRC=
set -e; \ set -e; \
$(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
...@@ -71,9 +70,7 @@ clean-files += $(objtree)/binkernel.spec ...@@ -71,9 +70,7 @@ clean-files += $(objtree)/binkernel.spec
# Deb target # Deb target
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# deb-pkg: FORCE
.PHONY: deb-pkg
deb-pkg:
$(MAKE) KBUILD_SRC= $(MAKE) KBUILD_SRC=
$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb
...@@ -82,8 +79,7 @@ clean-dirs += $(objtree)/debian/ ...@@ -82,8 +79,7 @@ clean-dirs += $(objtree)/debian/
# tarball targets # tarball targets
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
.PHONY: tar%pkg tar%pkg: FORCE
tar%pkg:
$(MAKE) KBUILD_SRC= $(MAKE) KBUILD_SRC=
$(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ $(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@
...@@ -92,7 +88,7 @@ clean-dirs += $(objtree)/tar-install/ ...@@ -92,7 +88,7 @@ clean-dirs += $(objtree)/tar-install/
# Help text displayed when executing 'make help' # Help text displayed when executing 'make help'
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
help: help: FORCE
@echo ' rpm-pkg - Build the kernel as an RPM package' @echo ' rpm-pkg - Build the kernel as an RPM package'
@echo ' binrpm-pkg - Build an rpm package containing the compiled kernel' @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel'
@echo ' and modules' @echo ' and modules'
......
#!/usr/bin/perl -w
#
# reference_discarded.pl (C) Keith Owens 2001 <kaos@ocs.com.au>
#
# Released under GPL V2.
#
# List dangling references to vmlinux discarded sections.
use strict;
die($0 . " takes no arguments\n") if($#ARGV >= 0);
my %object;
my $object;
my $line;
my $ignore;
my $errorcount;
$| = 1;
# printf("Finding objects, ");
open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed";
while (defined($line = <OBJDUMP_LIST>)) {
chomp($line);
if ($line =~ /:\s+file format/) {
($object = $line) =~ s/:.*//;
$object{$object}->{'module'} = 0;
$object{$object}->{'size'} = 0;
$object{$object}->{'off'} = 0;
}
if ($line =~ /^\s*\d+\s+\.modinfo\s+/) {
$object{$object}->{'module'} = 1;
}
if ($line =~ /^\s*\d+\s+\.comment\s+/) {
($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5];
}
}
close(OBJDUMP_LIST);
# printf("%d objects, ", scalar keys(%object));
$ignore = 0;
foreach $object (keys(%object)) {
if ($object{$object}->{'module'}) {
++$ignore;
delete($object{$object});
}
}
# printf("ignoring %d module(s)\n", $ignore);
# Ignore conglomerate objects, they have been built from multiple objects and we
# only care about the individual objects. If an object has more than one GCC:
# string in the comment section then it is conglomerate. This does not filter
# out conglomerates that consist of exactly one object, can't be helped.
# printf("Finding conglomerates, ");
$ignore = 0;
foreach $object (keys(%object)) {
if (exists($object{$object}->{'off'})) {
my ($off, $size, $comment, $l);
$off = hex($object{$object}->{'off'});
$size = hex($object{$object}->{'size'});
open(OBJECT, "<$object") || die "cannot read $object";
seek(OBJECT, $off, 0) || die "seek to $off in $object failed";
$l = read(OBJECT, $comment, $size);
die "read $size bytes from $object .comment failed" if ($l != $size);
close(OBJECT);
if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
++$ignore;
delete($object{$object});
}
}
}
# printf("ignoring %d conglomerate(s)\n", $ignore);
# printf("Scanning objects\n");
# Keith Ownes <kaos@sgi.com> commented:
# For our future {in}sanity, add a comment that this is the ppc .opd
# section, not the ia64 .opd section.
# ia64 .opd should not point to discarded sections.
$errorcount = 0;
foreach $object (keys(%object)) {
my $from;
open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object";
while (defined($line = <OBJDUMP>)) {
chomp($line);
if ($line =~ /RELOCATION RECORDS FOR /) {
($from = $line) =~ s/.*\[([^]]*).*/$1/;
}
if (($line =~ /\.text\.exit$/ ||
$line =~ /\.exit\.text$/ ||
$line =~ /\.data\.exit$/ ||
$line =~ /\.exit\.data$/ ||
$line =~ /\.exitcall\.exit$/) &&
($from !~ /\.text\.exit$/ &&
$from !~ /\.exit\.text$/ &&
$from !~ /\.data\.exit$/ &&
$from !~ /\.opd$/ &&
$from !~ /\.exit\.data$/ &&
$from !~ /\.altinstructions$/ &&
$from !~ /\.pdr$/ &&
$from !~ /\.debug_.*$/ &&
$from !~ /\.exitcall\.exit$/ &&
$from !~ /\.eh_frame$/ &&
$from !~ /\.stab$/)) {
printf("Error: %s %s refers to %s\n", $object, $from, $line);
$errorcount = $errorcount + 1;
}
}
close(OBJDUMP);
}
# printf("Done\n");
exit(0);
#!/usr/bin/perl -w
#
# reference_init.pl (C) Keith Owens 2002 <kaos@ocs.com.au>
#
# List references to vmlinux init sections from non-init sections.
# Unfortunately I had to exclude references from read only data to .init
# sections, almost all of these are false positives, they are created by
# gcc. The downside of excluding rodata is that there really are some
# user references from rodata to init code, e.g. drivers/video/vgacon.c
#
# const struct consw vga_con = {
# con_startup: vgacon_startup,
#
# where vgacon_startup is __init. If you want to wade through the false
# positives, take out the check for rodata.
use strict;
die($0 . " takes no arguments\n") if($#ARGV >= 0);
my %object;
my $object;
my $line;
my $ignore;
$| = 1;
printf("Finding objects, ");
open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed";
while (defined($line = <OBJDUMP_LIST>)) {
chomp($line);
if ($line =~ /:\s+file format/) {
($object = $line) =~ s/:.*//;
$object{$object}->{'module'} = 0;
$object{$object}->{'size'} = 0;
$object{$object}->{'off'} = 0;
}
if ($line =~ /^\s*\d+\s+\.modinfo\s+/) {
$object{$object}->{'module'} = 1;
}
if ($line =~ /^\s*\d+\s+\.comment\s+/) {
($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5];
}
}
close(OBJDUMP_LIST);
printf("%d objects, ", scalar keys(%object));
$ignore = 0;
foreach $object (keys(%object)) {
if ($object{$object}->{'module'}) {
++$ignore;
delete($object{$object});
}
}
printf("ignoring %d module(s)\n", $ignore);
# Ignore conglomerate objects, they have been built from multiple objects and we
# only care about the individual objects. If an object has more than one GCC:
# string in the comment section then it is conglomerate. This does not filter
# out conglomerates that consist of exactly one object, can't be helped.
printf("Finding conglomerates, ");
$ignore = 0;
foreach $object (keys(%object)) {
if (exists($object{$object}->{'off'})) {
my ($off, $size, $comment, $l);
$off = hex($object{$object}->{'off'});
$size = hex($object{$object}->{'size'});
open(OBJECT, "<$object") || die "cannot read $object";
seek(OBJECT, $off, 0) || die "seek to $off in $object failed";
$l = read(OBJECT, $comment, $size);
die "read $size bytes from $object .comment failed" if ($l != $size);
close(OBJECT);
if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
++$ignore;
delete($object{$object});
}
}
}
printf("ignoring %d conglomerate(s)\n", $ignore);
printf("Scanning objects\n");
foreach $object (sort(keys(%object))) {
my $from;
open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object";
while (defined($line = <OBJDUMP>)) {
chomp($line);
if ($line =~ /RELOCATION RECORDS FOR /) {
($from = $line) =~ s/.*\[([^]]*).*/$1/;
}
if (($line =~ /\.init$/ || $line =~ /\.init\./) &&
($from !~ /\.init$/ &&
$from !~ /\.init\./ &&
$from !~ /\.stab$/ &&
$from !~ /\.rodata$/ &&
$from !~ /\.text\.lock$/ &&
$from !~ /\.pci_fixup_header$/ &&
$from !~ /\.pci_fixup_final$/ &&
$from !~ /\.pdr$/ &&
$from !~ /\__param$/ &&
$from !~ /\.altinstructions/ &&
$from !~ /\.eh_frame/ &&
$from !~ /\.debug_/)) {
printf("Error: %s %s refers to %s\n", $object, $from, $line);
}
}
close(OBJDUMP);
}
printf("Done\n");
#Ignore generated files
maui_boot.h
pss_boot.h
trix_boot.h
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