Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Jan 2008 11:46:14 +0000 (22:46 +1100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Jan 2008 11:46:14 +0000 (22:46 +1100)
* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild: (79 commits)
  Remove references to "make dep"
  kconfig: document use of HAVE_*
  Introduce new section reference annotations tags: __ref, __refdata, __refconst
  kbuild: warn about ld added unique sections
  kbuild: add verbose option to Section mismatch reporting in modpost
  kconfig: tristate choices with mixed tristate and boolean values
  asm-generic/vmlix.lds.h: simplify __mem{init,exit}* dependencies
  remove __attribute_used__
  kbuild: support ARCH=x86 in buildtar
  kconfig: remove "enable"
  kbuild: simplified warning report in modpost
  kbuild: introduce a few helpers in modpost
  kbuild: use simpler section mismatch warnings in modpost
  kbuild: link vmlinux.o before kallsyms passes
  kbuild: introduce new option to enhance section mismatch analysis
  Use separate sections for __dev/__cpu/__mem code/data
  compiler.h: introduce __section()
  all archs: consolidate init and exit sections in vmlinux.lds.h
  kbuild: check section names consistently in modpost
  kbuild: introduce blacklisting in modpost
  ...

110 files changed:
.gitignore
Documentation/kbuild/kconfig-language.txt
Makefile
arch/alpha/kernel/vmlinux.lds.S
arch/alpha/lib/dec_and_lock.c
arch/arm/kernel/vmlinux.lds.S
arch/arm/mach-imx/Makefile
arch/arm/mach-netx/Makefile
arch/avr32/kernel/vmlinux.lds.S
arch/blackfin/kernel/vmlinux.lds.S
arch/cris/arch-v10/vmlinux.lds.S
arch/cris/arch-v32/boot/compressed/Makefile
arch/cris/arch-v32/vmlinux.lds.S
arch/frv/boot/Makefile
arch/frv/kernel/gdb-stub.c
arch/frv/kernel/vmlinux.lds.S
arch/h8300/kernel/vmlinux.lds.S
arch/ia64/kernel/vmlinux.lds.S
arch/m32r/kernel/vmlinux.lds.S
arch/m68k/kernel/vmlinux-std.lds
arch/m68k/kernel/vmlinux-sun3.lds
arch/m68knommu/kernel/vmlinux.lds.S
arch/mips/kernel/vmlinux.lds.S
arch/mips/tx4927/common/Makefile
arch/mips/tx4938/common/Makefile
arch/mips/tx4938/toshiba_rbtx4938/Makefile
arch/parisc/kernel/vmlinux.lds.S
arch/powerpc/boot/Makefile
arch/powerpc/kernel/sysfs.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/oprofile/op_model_power4.c
arch/ppc/kernel/vmlinux.lds.S
arch/s390/kernel/vmlinux.lds.S
arch/sh/kernel/vmlinux_32.lds.S
arch/sh/kernel/vmlinux_64.lds.S
arch/sparc/kernel/vmlinux.lds.S
arch/sparc64/kernel/unaligned.c
arch/sparc64/kernel/vmlinux.lds.S
arch/um/include/init.h
arch/um/kernel/dyn.lds.S
arch/um/kernel/uml.lds.S
arch/v850/kernel/vmlinux.lds.S
arch/x86/kernel/vmlinux_32.lds.S
arch/x86/kernel/vmlinux_64.lds.S
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/mm/Makefile
arch/xtensa/platform-iss/Makefile
drivers/base/power/Makefile
drivers/infiniband/hw/cxgb3/Makefile
drivers/rapidio/rio.h
fs/compat_ioctl.c
fs/smbfs/Makefile
include/asm-avr32/setup.h
include/asm-generic/vmlinux.lds.h
include/asm-ia64/gcc_intrin.h
include/asm-sh/machvec.h
include/asm-sh/thread_info.h
include/asm-x86/thread_info_32.h
include/linux/Kbuild
include/linux/compiler-gcc3.h
include/linux/compiler-gcc4.h
include/linux/compiler.h
include/linux/elfnote.h
include/linux/init.h
include/linux/module.h
include/linux/moduleparam.h
include/linux/pci.h
init/Kconfig
lib/Kconfig.debug
scripts/Makefile.build
scripts/Makefile.lib
scripts/Makefile.modinst
scripts/Makefile.modpost
scripts/basic/docproc.c
scripts/decodecode
scripts/gcc-version.sh
scripts/genksyms/genksyms.c
scripts/kconfig/Makefile
scripts/kconfig/POTFILES.in
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kconfig/expr.c
scripts/kconfig/expr.h
scripts/kconfig/gconf.c
scripts/kconfig/lex.zconf.c_shipped
scripts/kconfig/lkc.h
scripts/kconfig/lxdialog/check-lxdialog.sh
scripts/kconfig/lxdialog/checklist.c
scripts/kconfig/lxdialog/dialog.h
scripts/kconfig/lxdialog/inputbox.c
scripts/kconfig/lxdialog/menubox.c
scripts/kconfig/lxdialog/textbox.c
scripts/kconfig/lxdialog/util.c
scripts/kconfig/lxdialog/yesno.c
scripts/kconfig/mconf.c
scripts/kconfig/menu.c
scripts/kconfig/qconf.cc
scripts/kconfig/symbol.c
scripts/kconfig/util.c
scripts/kconfig/zconf.gperf
scripts/kconfig/zconf.hash.c_shipped
scripts/kconfig/zconf.l
scripts/kernel-doc
scripts/mkmakefile
scripts/mod/modpost.c
scripts/mod/modpost.h
scripts/package/Makefile
scripts/package/buildtar
scripts/patch-kernel
scripts/setlocalversion

index 8d14531846b95bfa3564b58ccfb7913a034323b8..8363e48cdcdc67bad8834a08ec8dd57b8cb41635 100644 (file)
@@ -17,6 +17,7 @@
 *.i
 *.lst
 *.symtypes
+*.order
 
 #
 # Top-level generic files
index 616043a6da99a0afd945e3cb5acb93b26bbb3f17..649cb87998900e235afe6b83c5e9f10077be2085 100644 (file)
@@ -24,7 +24,7 @@ visible if its parent entry is also visible.
 Menu entries
 ------------
 
-Most entries define a config option, all other entries help to organize
+Most entries define a config option; all other entries help to organize
 them. A single configuration option is defined like this:
 
 config MODVERSIONS
@@ -50,7 +50,7 @@ applicable everywhere (see syntax).
 
 - type definition: "bool"/"tristate"/"string"/"hex"/"int"
   Every config option must have a type. There are only two basic types:
-  tristate and string, the other types are based on these two. The type
+  tristate and string; the other types are based on these two. The type
   definition optionally accepts an input prompt, so these two examples
   are equivalent:
 
@@ -108,7 +108,7 @@ applicable everywhere (see syntax).
        equal to 'y' without visiting the dependencies. So abusing
        select you are able to select a symbol FOO even if FOO depends
        on BAR that is not set. In general use select only for
-       non-visible symbols (no promts anywhere) and for symbols with
+       non-visible symbols (no prompts anywhere) and for symbols with
        no dependencies. That will limit the usefulness but on the
        other hand avoid the illegal configurations all over. kconfig
        should one day warn about such things.
@@ -127,6 +127,27 @@ applicable everywhere (see syntax).
   used to help visually separate configuration logic from help within
   the file as an aid to developers.
 
+- misc options: "option" <symbol>[=<value>]
+  Various less common options can be defined via this option syntax,
+  which can modify the behaviour of the menu entry and its config
+  symbol. These options are currently possible:
+
+  - "defconfig_list"
+    This declares a list of default entries which can be used when
+    looking for the default configuration (which is used when the main
+    .config doesn't exists yet.)
+
+  - "modules"
+    This declares the symbol to be used as the MODULES symbol, which
+    enables the third modular state for all config symbols.
+
+  - "env"=<value>
+    This imports the environment variable into Kconfig. It behaves like
+    a default, except that the value comes from the environment, this
+    also means that the behaviour when mixing it with normal defaults is
+    undefined at this point. The symbol is currently not exported back
+    to the build environment (if this is desired, it can be done via
+    another symbol).
 
 Menu dependencies
 -----------------
@@ -162,9 +183,9 @@ An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
 respectively for calculations). A menu entry becomes visible when it's
 expression evaluates to 'm' or 'y'.
 
-There are two types of symbols: constant and nonconstant symbols.
-Nonconstant symbols are the most common ones and are defined with the
-'config' statement. Nonconstant symbols consist entirely of alphanumeric
+There are two types of symbols: constant and non-constant symbols.
+Non-constant symbols are the most common ones and are defined with the
+'config' statement. Non-constant symbols consist entirely of alphanumeric
 characters or underscores.
 Constant symbols are only part of expressions. Constant symbols are
 always surrounded by single or double quotes. Within the quote, any
@@ -301,3 +322,81 @@ mainmenu:
 
 This sets the config program's title bar if the config program chooses
 to use it.
+
+
+Kconfig hints
+-------------
+This is a collection of Kconfig tips, most of which aren't obvious at
+first glance and most of which have become idioms in several Kconfig
+files.
+
+Adding common features and make the usage configurable
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It is a common idiom to implement a feature/functionality that are
+relevant for some architectures but not all.
+The recommended way to do so is to use a config variable named HAVE_*
+that is defined in a common Kconfig file and selected by the relevant
+architectures.
+An example is the generic IOMAP functionality.
+
+We would in lib/Kconfig see:
+
+# Generic IOMAP is used to ...
+config HAVE_GENERIC_IOMAP
+
+config GENERIC_IOMAP
+       depends on HAVE_GENERIC_IOMAP && FOO
+
+And in lib/Makefile we would see:
+obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
+
+For each architecture using the generic IOMAP functionality we would see:
+
+config X86
+       select ...
+       select HAVE_GENERIC_IOMAP
+       select ...
+
+Note: we use the existing config option and avoid creating a new
+config variable to select HAVE_GENERIC_IOMAP.
+
+Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is
+introduced to overcome the limitation of select which will force a
+config option to 'y' no matter the dependencies.
+The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the
+situation where select forces a symbol equals to 'y'.
+
+Build as module only
+~~~~~~~~~~~~~~~~~~~~
+To restrict a component build to module-only, qualify its config symbol
+with "depends on m".  E.g.:
+
+config FOO
+       depends on BAR && m
+
+limits FOO to module (=m) or disabled (=n).
+
+
+Build limited by a third config symbol which may be =y or =m
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A common idiom that we see (and sometimes have problems with) is this:
+
+When option C in B (module or subsystem) uses interfaces from A (module
+or subsystem), and both A and B are tristate (could be =y or =m if they
+were independent of each other, but they aren't), then we need to limit
+C such that it cannot be built statically if A is built as a loadable
+module.  (C already depends on B, so there is no dependency issue to
+take care of here.)
+
+If A is linked statically into the kernel image, C can be built
+statically or as loadable module(s).  However, if A is built as loadable
+module(s), then C must be restricted to loadable module(s) also.  This
+can be expressed in kconfig language as:
+
+config C
+       depends on A = y || A = B
+
+or for real examples, use this command in a kernel tree:
+
+$ find . -name Kconfig\* | xargs grep -ns "depends on.*=.*||.*=" | grep -v orig
+
index 6d419f67939c29f28a2b003272ce70d9881bc769..0f84c742ed0e1c8363d27121fb2ce563fb582bc7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -520,6 +520,11 @@ KBUILD_CFLAGS      += -g
 KBUILD_AFLAGS  += -gdwarf-2
 endif
 
+# We trigger additional mismatches with less inlining
+ifdef CONFIG_DEBUG_SECTION_MISMATCH
+KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
+endif
+
 # Force gcc to behave correct even for buggy distributions
 KBUILD_CFLAGS         += $(call cc-option, -fno-stack-protector)
 
@@ -793,7 +798,7 @@ define rule_vmlinux-modpost
 endef
 
 # vmlinux image - including updated kernel symbols
-vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o FORCE
+vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
 ifdef CONFIG_HEADERS_CHECK
        $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
 endif
@@ -804,7 +809,9 @@ endif
        $(call if_changed_rule,vmlinux__)
        $(Q)rm -f .old_version
 
-vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
+# build vmlinux.o first to catch section mismatch errors early
+$(kallsyms.o): vmlinux.o
+vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE
        $(call if_changed_rule,vmlinux-modpost)
 
 # The actual objects are generated when descending, 
@@ -1021,9 +1028,14 @@ ifdef CONFIG_MODULES
 all: modules
 
 #      Build modules
+#
+#      A module can be listed more than once in obj-m resulting in
+#      duplicate lines in modules.order files.  Those are removed
+#      using awk while concatenating to the final file.
 
 PHONY += modules
 modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
+       $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
        @echo '  Building modules, stage 2.';
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
 
@@ -1051,6 +1063,7 @@ _modinst_:
                rm -f $(MODLIB)/build ; \
                ln -s $(objtree) $(MODLIB)/build ; \
        fi
+       @cp -f $(objtree)/modules.order $(MODLIB)/
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
 # This depmod is only for convenience to give the initial
@@ -1110,7 +1123,7 @@ clean: archclean $(clean-dirs)
        @find . $(RCS_FIND_IGNORE) \
                \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
                -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-               -o -name '*.symtypes' \) \
+               -o -name '*.symtypes' -o -name 'modules.order' \) \
                -type f -print | xargs rm -f
 
 # mrproper - Delete all generated files, including .config
@@ -1175,7 +1188,7 @@ help:
        @echo  '  dir/            - Build all files in dir and below'
        @echo  '  dir/file.[ois]  - Build specified target only'
        @echo  '  dir/file.ko     - Build module including final link'
-       @echo  '  rpm             - Build a kernel as an RPM package'
+       @echo  '  prepare         - Set up for building external modules'
        @echo  '  tags/TAGS       - Generate tags file for editors'
        @echo  '  cscope          - Generate cscope index'
        @echo  '  kernelrelease   - Output the release version string'
@@ -1188,6 +1201,8 @@ help:
        @echo  'Static analysers'
        @echo  '  checkstack      - Generate a list of stack hogs'
        @echo  '  namespacecheck  - Name space analysis on compiled kernel'
+       @echo  '  versioncheck    - Sanity check on version.h usage'
+       @echo  '  includecheck    - Check for duplicate included header files'
        @echo  '  export_report   - List the usages of all exported symbols'
        @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
         echo  '  headers_check   - Sanity check on exported headers'; \
@@ -1371,6 +1386,7 @@ define xtags
        if $1 --version 2>&1 | grep -iq exuberant; then \
            $(all-sources) | xargs $1 -a \
                -I __initdata,__exitdata,__acquires,__releases \
+               -I __read_mostly,____cacheline_aligned,____cacheline_aligned_in_smp,____cacheline_internodealigned_in_smp \
                -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
                --extra=+f --c-kinds=+px \
                --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'; \
@@ -1428,12 +1444,12 @@ tags: FORCE
 includecheck:
        find * $(RCS_FIND_IGNORE) \
                -name '*.[hcS]' -type f -print | sort \
-               | xargs $(PERL) -w scripts/checkincludes.pl
+               | xargs $(PERL) -w $(srctree)/scripts/checkincludes.pl
 
 versioncheck:
        find * $(RCS_FIND_IGNORE) \
                -name '*.[hcS]' -type f -print | sort \
-               | xargs $(PERL) -w scripts/checkversion.pl
+               | xargs $(PERL) -w $(srctree)/scripts/checkversion.pl
 
 namespacecheck:
        $(PERL) $(srctree)/scripts/namespace.pl
index 55c05b511f4c060d5a8cab8f7140d6f07563bd0f..f13249be17c50736e23686158854799164582aeb 100644 (file)
@@ -46,11 +46,11 @@ SECTIONS
        __init_begin = .;
        .init.text : {
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
        .init.data : {
-               *(.init.data)
+               INIT_DATA
        }
 
        . = ALIGN(16);
@@ -136,8 +136,8 @@ SECTIONS
 
        /* Sections to be discarded */
        /DISCARD/ : {
-               *(.exit.text)
-               *(.exit.data)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
        }
 
index 6ae2500a9d9e8dec21fd4fb05302ef1c6dae11ca..0f5520d2f45fc41d72d2d333fb291c50517bfa3c 100644 (file)
@@ -30,8 +30,7 @@ _atomic_dec_and_lock:                         \n\
        .previous                               \n\
        .end _atomic_dec_and_lock");
 
-static int __attribute_used__
-atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
+static int __used atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
 {
        /* Slow path */
        spin_lock(lock);
index 30f732c7fdb505b9762b6d12f4fbc6ebf5ebb5ae..4898bdcfe7dd638b5c4d9962f3932244a1249a38 100644 (file)
@@ -30,7 +30,7 @@ SECTIONS
        }
 
        .init : {                       /* Init code and data           */
-                       *(.init.text)
+                       INIT_TEXT
                _einittext = .;
                __proc_info_begin = .;
                        *(.proc.info.init)
@@ -70,15 +70,15 @@ SECTIONS
                __per_cpu_end = .;
 #ifndef CONFIG_XIP_KERNEL
                __init_begin = _stext;
-               *(.init.data)
+               INIT_DATA
                . = ALIGN(4096);
                __init_end = .;
 #endif
        }
 
        /DISCARD/ : {                   /* Exit code and data           */
-               *(.exit.text)
-               *(.exit.data)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
 #ifndef CONFIG_MMU
                *(.fixup)
@@ -130,7 +130,7 @@ SECTIONS
 #ifdef CONFIG_XIP_KERNEL
                . = ALIGN(4096);
                __init_begin = .;
-               *(.init.data)
+               INIT_DATA
                . = ALIGN(4096);
                __init_end = .;
 #endif
index 02272aa36e90c69e433b465ab799f08574478a5d..88d5e61a2e13d6f85a90d77d8219c0f11474392d 100644 (file)
@@ -1,9 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
 
 # Object file lists.
 
index 18785ff37657f71a272d33e2b5057ec371ae1e3d..7ce4ba9eb242b1ec13855d918d625368d5d7220b 100644 (file)
@@ -1,9 +1,6 @@
 #
 # Makefile for the linux kernel.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
 
 # Object file lists.
 
index 11f08e35a2eb36df6ee235549a0f9779f3120f91..481cfd40c0539e85297ed33366ec579041d95680 100644 (file)
@@ -27,19 +27,19 @@ SECTIONS
                __init_begin = .;
                        _sinittext = .;
                        *(.text.reset)
-                       *(.init.text)
+                       INIT_TEXT
                        /*
                         * .exit.text is discarded at runtime, not
                         * link time, to deal with references from
                         * __bug_table
                         */
-                       *(.exit.text)
+                       EXIT_TEXT
                        _einittext = .;
                . = ALIGN(4);
                __tagtable_begin = .;
                        *(.taglist.init)
                __tagtable_end = .;
-                       *(.init.data)
+                       INIT_DATA
                . = ALIGN(16);
                __setup_start = .;
                        *(.init.setup)
@@ -135,7 +135,7 @@ SECTIONS
         * thrown away, as cleanup code is never called unless it's a module.
         */
        /DISCARD/               : {
-               *(.exit.data)
+               EXIT_DATA
                *(.exitcall.exit)
        }
 
index 9b75bc83c71fac9847cd8e0f578183dbfb87115c..858722421b40db4f693dcdc33122e60b47b8801f 100644 (file)
@@ -91,13 +91,13 @@ SECTIONS
        {
                . = ALIGN(PAGE_SIZE);
                __sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                __einittext = .;
        }
        .init.data :
        {
                . = ALIGN(16);
-               *(.init.data)
+               INIT_DATA
        }
        .init.setup :
        {
@@ -198,8 +198,8 @@ SECTIONS
 
        /DISCARD/ :
        {
-               *(.exit.text)
-               *(.exit.data)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
        }
 }
index 97a7876ed6819061fec0a9be042f60be1d260d77..93c9f0ea286b8f23d5445f154f7e783a298b86c2 100644 (file)
@@ -57,10 +57,10 @@ SECTIONS
        __init_begin = .;
        .init.text : { 
                   _sinittext = .;
-                  *(.init.text)
+                  INIT_TEXT
                   _einittext = .;
        }
-       .init.data : { *(.init.data) }
+       .init.data : { INIT_DATA }
        . = ALIGN(16);
        __setup_start = .;
        .init.setup : { *(.init.setup) }
@@ -109,8 +109,8 @@ SECTIONS
 
        /* Sections to be discarded */
        /DISCARD/ : {
-               *(.text.exit)
-               *(.data.exit)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
         }
 
index 9f77eda914ba7448a9f38d515876566d0f338f29..609692f9d5eb424bd906abdb9248701938b188be 100644 (file)
@@ -7,7 +7,7 @@
 target = $(target_compressed_dir)
 src    = $(src_compressed_dir)
 
-CC = gcc-cris -mlinux -march=v32 -I $(TOPDIR)/include
+CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
 CFLAGS = -O2
 LD = gcc-cris -mlinux -march=v32 -nostdlib
 OBJCOPY = objcopy-cris
index b076c134c0bbd797d9c28940a651523abadf3a63..fead8c59ea63bfcf727091a774982b55b91d131a 100644 (file)
@@ -61,10 +61,10 @@ SECTIONS
        __init_begin = .;
        .init.text : {
                   _sinittext = .;
-                  *(.init.text)
+                  INIT_TEXT
                   _einittext = .;
        }
-       .init.data : { *(.init.data) }
+       .init.data : { INIT_DATA }
        . = ALIGN(16);
        __setup_start = .;
        .init.setup : { *(.init.setup) }
@@ -124,8 +124,8 @@ SECTIONS
 
        /* Sections to be discarded */
        /DISCARD/ : {
-               *(.text.exit)
-               *(.data.exit)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
         }
 
index dc6f03824423c76f378c1cc384671e70e2b1503b..6ae3254da01976b6fdaa374f588c3c58a081058c 100644 (file)
@@ -10,7 +10,7 @@
 
 targets := Image zImage bootpImage
 
-SYSTEM =$(TOPDIR)/$(LINUX)
+SYSTEM =$(LINUX)
 
 ZTEXTADDR       = 0x02080000
 PARAMS_PHYS     = 0x0207c000
@@ -45,7 +45,7 @@ zImage:       $(CONFIGURE) compressed/$(LINUX)
 bootpImage: bootp/bootp
        $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
 
-compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep
+compressed/$(LINUX): $(LINUX) dep
        @$(MAKE) -C compressed $(LINUX)
 
 bootp/bootp: zImage initrd
@@ -59,10 +59,10 @@ initrd:
 # installation
 #
 install: $(CONFIGURE) Image
-       sh ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+       sh ./install.sh $(KERNELRELEASE) Image System.map "$(INSTALL_PATH)"
 
 zinstall: $(CONFIGURE) zImage
-       sh ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+       sh ./install.sh $(KERNELRELEASE) zImage System.map "$(INSTALL_PATH)"
 
 #
 # miscellany
index e89cad1192a99e5949e12f01020f76a7053671dd..48a0393e7cee1cd0e14fb15a7c20bbee9008fde3 100644 (file)
@@ -87,7 +87,7 @@
  *  Example:
  *    $ cd ~/linux
  *    $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
- *    $ make dep; make vmlinux
+ *    $ make vmlinux
  *
  *  Step 3:
  *  Download the kernel to the remote target and start
index a17a81d58bf69386638f89b66a01548e22a4b61e..f42b328b1dd0475e1af868308cdc000c89d40942 100644 (file)
@@ -28,14 +28,14 @@ SECTIONS
   .init.text : {
        *(.text.head)
 #ifndef CONFIG_DEBUG_INFO
-       *(.init.text)
-       *(.exit.text)
-       *(.exit.data)
+       INIT_TEXT
+       EXIT_TEXT
+       EXIT_DATA
        *(.exitcall.exit)
 #endif
   }
   _einittext = .;
-  .init.data : { *(.init.data) }
+  .init.data : { INIT_DATA }
 
   . = ALIGN(8);
   __setup_start = .;
@@ -106,8 +106,8 @@ SECTIONS
        LOCK_TEXT
 #ifdef CONFIG_DEBUG_INFO
        *(
-       .init.text
-       .exit.text
+       INIT_TEXT
+       EXIT_TEXT
        .exitcall.exit
        )
 #endif
@@ -138,7 +138,7 @@ SECTIONS
   .data : {                    /* Data */
        DATA_DATA
        *(.data.*)
-       *(.exit.data)
+       EXIT_DATA
        CONSTRUCTORS
        }
 
index a2e72d495551cd370454556898a9bf687fa869aa..43a87b9085b6b449cb7fbfb64bfb5d715551185c 100644 (file)
@@ -110,9 +110,9 @@ SECTIONS
        . = ALIGN(0x4) ;
        ___init_begin = .;
        __sinittext = .; 
-               *(.init.text)
+               INIT_TEXT
        __einittext = .; 
-               *(.init.data)
+               INIT_DATA
        . = ALIGN(0x4) ;
        ___setup_start = .;
                *(.init.setup)
@@ -124,8 +124,8 @@ SECTIONS
        ___con_initcall_start = .;
                *(.con_initcall.init)
        ___con_initcall_end = .;
-               *(.exit.text)
-               *(.exit.data)
+               EXIT_TEXT
+               EXIT_DATA
 #if defined(CONFIG_BLK_DEV_INITRD)
                . = ALIGN(4);
        ___initramfs_start = .;
index 757e419ebcf81f0ea1da02916e82d7302dc8395f..80622acc95deea98c83f5e2ce97cc11cc4bc883a 100644 (file)
@@ -27,8 +27,8 @@ SECTIONS
 {
   /* Sections to be discarded */
   /DISCARD/ : {
-       *(.exit.text)
-       *(.exit.data)
+       EXIT_TEXT
+       EXIT_DATA
        *(.exitcall.exit)
        *(.IA_64.unwind.exit.text)
        *(.IA_64.unwind_info.exit.text)
@@ -119,12 +119,12 @@ SECTIONS
   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
        {
          _sinittext = .;
-         *(.init.text)
+         INIT_TEXT
          _einittext = .;
        }
 
   .init.data : AT(ADDR(.init.data) - LOAD_OFFSET)
-       { *(.init.data) }
+       { INIT_DATA }
 
 #ifdef CONFIG_BLK_DEV_INITRD
   .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET)
index 942a8c7a44174b0c010d88c10694523ec93c248f..41b07854fcc609c5d12c2254e1e09a807f1e9417 100644 (file)
@@ -76,10 +76,10 @@ SECTIONS
   __init_begin = .;
   .init.text : {
        _sinittext = .;
-       *(.init.text)
+       INIT_TEXT
        _einittext = .;
   }
-  .init.data : { *(.init.data) }
+  .init.data : { INIT_DATA }
   . = ALIGN(16);
   __setup_start = .;
   .init.setup : { *(.init.setup) }
@@ -100,8 +100,8 @@ SECTIONS
   .altinstr_replacement : { *(.altinstr_replacement) }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }
+  .exit.text : { EXIT_TEXT }
+  .exit.data : { EXIT_DATA }
 
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(4096);
@@ -124,8 +124,8 @@ SECTIONS
 
   /* Sections to be discarded */
   /DISCARD/ : {
-       *(.exit.text)
-       *(.exit.data)
+       EXIT_TEXT
+       EXIT_DATA
        *(.exitcall.exit)
        }
 
index 59fe285865ec050b958545a94007568d94c7f707..7537cc5e61592ac87c0af127850b214d6d56f977 100644 (file)
@@ -45,10 +45,10 @@ SECTIONS
   __init_begin = .;
   .init.text : {
        _sinittext = .;
-       *(.init.text)
+       INIT_TEXT
        _einittext = .;
   }
-  .init.data : { *(.init.data) }
+  .init.data : { INIT_DATA }
   . = ALIGN(16);
   __setup_start = .;
   .init.setup : { *(.init.setup) }
@@ -82,8 +82,8 @@ SECTIONS
 
   /* Sections to be discarded */
   /DISCARD/ : {
-       *(.exit.text)
-       *(.exit.data)
+       EXIT_TEXT
+       EXIT_DATA
        *(.exitcall.exit)
        }
 
index 4adffefb5c48c673b5f349a6c0142b4a10a26ada..cdc313e7c299a66c2d7700526f00bcd0463142cf 100644 (file)
@@ -38,10 +38,10 @@ SECTIONS
 __init_begin = .;
        .init.text : {
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
-       .init.data : { *(.init.data) }
+       .init.data : { INIT_DATA }
        . = ALIGN(16);
        __setup_start = .;
        .init.setup : { *(.init.setup) }
@@ -77,8 +77,8 @@ __init_begin = .;
 
   /* Sections to be discarded */
   /DISCARD/ : {
-       *(.exit.text)
-       *(.exit.data)
+       EXIT_TEXT
+       EXIT_DATA
        *(.exitcall.exit)
        }
 
index 07a0055602f447b4466442c7bedb125d3a149e7f..b44edb08e21276f3dce89e8b938c4e6a5252596c 100644 (file)
@@ -143,9 +143,9 @@ SECTIONS {
                . = ALIGN(4096);
                __init_begin = .;
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
-               *(.init.data)
+               INIT_DATA
                . = ALIGN(16);
                __setup_start = .;
                *(.init.setup)
@@ -170,8 +170,8 @@ SECTIONS {
        } > INIT
 
        /DISCARD/ : {
-               *(.exit.text)
-               *(.exit.data)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
        }
 
index 5fc2398bdb76673ac8ebf92cbd21db0a5d34b7b9..b5470ceb418b301847f385d72e306eff0b1bf6dc 100644 (file)
@@ -114,11 +114,11 @@ SECTIONS
        __init_begin = .;
        .init.text : {
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
        .init.data : {
-               *(.init.data)
+               INIT_DATA
        }
        . = ALIGN(16);
        .init.setup : {
@@ -144,10 +144,10 @@ SECTIONS
         * references from .rodata
         */
        .exit.text : {
-               *(.exit.text)
+               EXIT_TEXT
        }
        .exit.data : {
-               *(.exit.data)
+               EXIT_DATA
        }
 #if defined(CONFIG_BLK_DEV_INITRD)
        . = ALIGN(_PAGE_SIZE);
index 18375787e094380a152d0d2634f74d7eb377817e..e8629617f25db3ddb2dbe927638f19afff77dcf2 100644 (file)
@@ -1,10 +1,6 @@
 #
 # Makefile for common code for Toshiba TX4927 based systems
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
 
 obj-y  += tx4927_prom.o tx4927_setup.o tx4927_irq.o
 
index 8352eca679066c34f7d85667ad1cb7dc0b3e3119..eff3d1d47f88651ad1eb0ca46d2e3b167e9cbf81 100644 (file)
@@ -1,10 +1,6 @@
 #
 # Makefile for common code for Toshiba TX4927 based systems
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
 
 obj-y  += prom.o setup.o irq.o
 obj-$(CONFIG_KGDB) += dbgio.o
index 675bb1c3e40c72cc4776b906c05dd2abb8840904..2316dd7dd1bdf91ba62e0034a4a3b322ef54698c 100644 (file)
@@ -1,10 +1,6 @@
 #
 # Makefile for common code for Toshiba TX4927 based systems
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
 
 obj-y  += prom.o setup.o irq.o spi_eeprom.o
 
index 40d0ff9b81ab685acfd88dd5ca1a04158a25b1dd..50b4a3a25d0af70dbfb59134aae12940cbd03f12 100644 (file)
@@ -172,11 +172,11 @@ SECTIONS
        __init_begin = .;
        .init.text : { 
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
        .init.data : {
-               *(.init.data)
+               INIT_DATA
        }
        . = ALIGN(16);
        .init.setup : {
@@ -215,10 +215,10 @@ SECTIONS
         *  from .altinstructions and .eh_frame
         */
        .exit.text : {
-               *(.exit.text)
+               EXIT_TEXT
        }
        .exit.data : {
-               *(.exit.data)
+               EXIT_DATA
        }
 #ifdef CONFIG_BLK_DEV_INITRD
        . = ALIGN(PAGE_SIZE);
index 18e32719d0ed4544202bae47cc9c1361e6116649..4b1d98b8135ef5db6da95654bf4f430e4704e4f3 100644 (file)
@@ -65,7 +65,7 @@ obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
 obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
 
 quiet_cmd_copy_zlib = COPY    $@
-      cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
+      cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
 
 quiet_cmd_copy_zlibheader = COPY    $@
       cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
index 25d9a96484ddeb914ff0d7fe63aa1b0c3baf7e8e..c8127f832df0f6d28d8efb0ee3a2097f8933dcce 100644 (file)
@@ -158,7 +158,7 @@ static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
        unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
        return sprintf(buf, "%lx\n", val); \
 } \
-static ssize_t __attribute_used__ \
+static ssize_t __used \
        store_##NAME(struct sys_device *dev, const char *buf, size_t count) \
 { \
        struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
index f66fa5d966b0d75ebecf99d53ac4723e8f2622ce..0afb9e31d2a008a79f1b5a4d2ff70d8dc798a458 100644 (file)
@@ -23,7 +23,7 @@ SECTIONS
        /* Sections to be discarded. */
        /DISCARD/ : {
        *(.exitcall.exit)
-       *(.exit.data)
+       EXIT_DATA
        }
 
        . = KERNELBASE;
@@ -76,17 +76,19 @@ SECTIONS
 
        .init.text : {
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
 
        /* .exit.text is discarded at runtime, not link time,
         * to deal with references from __bug_table
         */
-       .exit.text : { *(.exit.text) }
+       .exit.text : {
+               EXIT_TEXT
+       }
 
        .init.data : {
-               *(.init.data);
+               INIT_DATA
                __vtop_table_begin = .;
                *(.vtop_fixup);
                __vtop_table_end = .;
index cddc250a6a5cf13325556175cbbed3473c61ec02..446a8bbb847b0f2dcd679ac74eaece531cee4476 100644 (file)
@@ -172,15 +172,15 @@ static void power4_stop(void)
 }
 
 /* Fake functions used by canonicalize_pc */
-static void __attribute_used__ hypervisor_bucket(void)
+static void __used hypervisor_bucket(void)
 {
 }
 
-static void __attribute_used__ rtas_bucket(void)
+static void __used rtas_bucket(void)
 {
 }
 
-static void __attribute_used__ kernel_unknown_bucket(void)
+static void __used kernel_unknown_bucket(void)
 {
 }
 
index 98c1212674f6e76c2953c5a9a8a5344bb6b94ca1..52b64fcbdfc50d493a76bef799400e2365cdd15e 100644 (file)
@@ -97,14 +97,14 @@ SECTIONS
   __init_begin = .;
   .init.text : {
        _sinittext = .;
-       *(.init.text)
+       INIT_TEXT
        _einittext = .;
   }
   /* .exit.text is discarded at runtime, not link time,
      to deal with references from __bug_table */
-  .exit.text : { *(.exit.text) }
+  .exit.text : { EXIT_TEXT }
   .init.data : {
-    *(.init.data);
+    INIT_DATA
     __vtop_table_begin = .;
     *(.vtop_fixup);
     __vtop_table_end = .;
@@ -164,6 +164,6 @@ SECTIONS
   /* Sections to be discarded. */
   /DISCARD/ : {
     *(.exitcall.exit)
-    *(.exit.data)
+    EXIT_DATA
   }
 }
index 936159199346520387f895c7fec5f6ffcba33345..7d43c3cd3ef35880b5b0fd5a5fbb08b33a51e605 100644 (file)
@@ -97,7 +97,7 @@ SECTIONS
        __init_begin = .;
        .init.text : {
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
        /*
@@ -105,11 +105,11 @@ SECTIONS
         * to deal with references from __bug_table
        */
        .exit.text : {
-               *(.exit.text)
+               EXIT_TEXT
        }
 
        .init.data : {
-               *(.init.data)
+               INIT_DATA
        }
        . = ALIGN(0x100);
        .init.setup : {
@@ -156,7 +156,7 @@ SECTIONS
 
        /* Sections to be discarded */
        /DISCARD/ : {
-               *(.exit.data)
+               EXIT_DATA
                *(.exitcall.exit)
        }
 
index d549fac6d3e7dc5cb1692122ad890d670c1a4b9a..c7113786ecd4c1158c461128880cfef650a31857 100644 (file)
@@ -84,9 +84,9 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);           /* Init code and data */
        __init_begin = .;
        _sinittext = .;
-       .init.text : { *(.init.text) }
+       .init.text : { INIT_TEXT }
        _einittext = .;
-       .init.data : { *(.init.data) }
+       .init.data : { INIT_DATA }
 
        . = ALIGN(16);
        __setup_start = .;
@@ -122,8 +122,8 @@ SECTIONS
         * .exit.text is discarded at runtime, not link time, to deal with
         * references from __bug_table
         */
-       .exit.text : { *(.exit.text) }
-       .exit.data : { *(.exit.data) }
+       .exit.text : { EXIT_TEXT }
+       .exit.data : { EXIT_DATA }
 
        . = ALIGN(PAGE_SIZE);
        .bss : {
index 2fd0f74014846ac5c920ea58fcbc3c124a6ae66a..3f1bd6392bb343c8699c309c5d98da640ec839d3 100644 (file)
@@ -96,9 +96,9 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);           /* Init code and data */
        __init_begin = .;
        _sinittext = .;
-       .init.text : C_PHYS(.init.text) { *(.init.text) }
+       .init.text : C_PHYS(.init.text) { INIT_TEXT }
        _einittext = .;
-       .init.data : C_PHYS(.init.data) { *(.init.data) }
+       .init.data : C_PHYS(.init.data) { INIT_DATA }
        . = ALIGN(L1_CACHE_BYTES);      /* Better if Cache Line aligned */
        __setup_start = .;
        .init.setup : C_PHYS(.init.setup) { *(.init.setup) }
@@ -134,8 +134,8 @@ SECTIONS
         * .exit.text is discarded at runtime, not link time, to deal with
         * references from __bug_table
         */
-       .exit.text : C_PHYS(.exit.text) { *(.exit.text) }
-       .exit.data : C_PHYS(.exit.data) { *(.exit.data) }
+       .exit.text : C_PHYS(.exit.text) { EXIT_TEXT }
+       .exit.data : C_PHYS(.exit.data) { EXIT_DATA }
 
        . = ALIGN(PAGE_SIZE);
        .bss : C_PHYS(.bss) {
index a8b4200f9cc379e0bc6319e6f2c786ae3df2f4b6..216147d6e61f6882d8050c161d356c4bd6f15bec 100644 (file)
@@ -48,12 +48,12 @@ SECTIONS
        __init_begin = .;
        .init.text : {
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
        __init_text_end = .;
        .init.data : {
-               *(.init.data)
+               INIT_DATA
        }
        . = ALIGN(16);
        .init.setup : {
@@ -102,8 +102,8 @@ SECTIONS
        _end = . ;
        PROVIDE (end = .);
        /DISCARD/ : {
-               *(.exit.text)
-               *(.exit.data)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
        }
 
index 953be816fa2564b6692a7f3a25d884337958f017..dc7bf1b6321ceb89fbe658cce07f08f7df513808 100644 (file)
@@ -175,7 +175,7 @@ unsigned long compute_effective_address(struct pt_regs *regs,
 }
 
 /* This is just to make gcc think die_if_kernel does return... */
-static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs)
+static void __used unaligned_panic(char *str, struct pt_regs *regs)
 {
        die_if_kernel(str, regs);
 }
index 9fcd503bc04ad5574488379dc43787cf4cabfec3..01f809617e5e708df97764794de91b3a6bad8c81 100644 (file)
@@ -56,11 +56,11 @@ SECTIONS
        .init.text : {
                __init_begin = .;
                _sinittext = .;
-               *(.init.text)
+               INIT_TEXT
                _einittext = .;
        }
        .init.data : {
-               *(.init.data)
+               INIT_DATA
        }
        . = ALIGN(16);
        .init.setup : {
@@ -137,8 +137,8 @@ SECTIONS
        PROVIDE (end = .);
 
        /DISCARD/ : {
-               *(.exit.text)
-               *(.exit.data)
+               EXIT_TEXT
+               EXIT_DATA
                *(.exitcall.exit)
        }
 
index d4de7c0120ced888209122f47424d9754c1ed50f..cebc6cae91903442235e8f4b4e782b71a5feb5c9 100644 (file)
@@ -42,15 +42,15 @@ typedef void (*exitcall_t)(void);
 
 /* These are for everybody (although not all archs will actually
    discard it in modules) */
-#define __init         __attribute__ ((__section__ (".init.text")))
-#define __initdata     __attribute__ ((__section__ (".init.data")))
-#define __exitdata     __attribute__ ((__section__(".exit.data")))
-#define __exit_call    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
+#define __init         __section(.init.text)
+#define __initdata     __section(.init.data)
+#define __exitdata     __section(.exit.data)
+#define __exit_call    __used __section(.exitcall.exit)
 
 #ifdef MODULE
-#define __exit         __attribute__ ((__section__(".exit.text")))
+#define __exit         __section(.exit.text)
 #else
-#define __exit         __attribute_used__ __attribute__ ((__section__(".exit.text")))
+#define __exit         __used __section(.exit.text)
 #endif
 
 #endif
@@ -103,16 +103,16 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
  * Mark functions and data as being only used at initialization
  * or exit time.
  */
-#define __uml_init_setup       __attribute_used__ __attribute__ ((__section__ (".uml.setup.init")))
-#define __uml_setup_help       __attribute_used__ __attribute__ ((__section__ (".uml.help.init")))
-#define __uml_init_call                __attribute_used__ __attribute__ ((__section__ (".uml.initcall.init")))
-#define __uml_postsetup_call   __attribute_used__ __attribute__ ((__section__ (".uml.postsetup.init")))
-#define __uml_exit_call                __attribute_used__ __attribute__ ((__section__ (".uml.exitcall.exit")))
+#define __uml_init_setup       __used __section(.uml.setup.init)
+#define __uml_setup_help       __used __section(.uml.help.init)
+#define __uml_init_call                __used __section(.uml.initcall.init)
+#define __uml_postsetup_call   __used __section(.uml.postsetup.init)
+#define __uml_exit_call                __used __section(.uml.exitcall.exit)
 
 #ifndef __KERNEL__
 
 #define __define_initcall(level,fn) \
-       static initcall_t __initcall_##fn __attribute_used__ \
+       static initcall_t __initcall_##fn __used \
        __attribute__((__section__(".initcall" level ".init"))) = fn
 
 /* Userspace initcalls shouldn't depend on anything in the kernel, so we'll
@@ -122,7 +122,7 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
 
 #define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
 
-#define __init_call    __attribute_used__ __attribute__ ((__section__ (".initcall.init")))
+#define __init_call    __used __section(.initcall.init)
 
 #endif
 
index 3866f4960f04519de02a1ab4c6cdff3452d29ffc..26090b7f323ecf3806f0a86668250ebad253bc6f 100644 (file)
@@ -17,7 +17,7 @@ SECTIONS
   __init_begin = .;
   .init.text : {
        _sinittext = .;
-       *(.init.text)
+       INIT_TEXT
        _einittext = .;
   }
 
@@ -84,7 +84,7 @@ SECTIONS
 
   #include "asm/common.lds.S"
 
-  init.data : { *(.init.data) }
+  init.data : { INIT_DATA }
 
   /* Ensure the __preinit_array_start label is properly aligned.  We
      could instead move the label definition inside the section, but
index 13df191e2b41e6b66fe6c3668b5daa689dada71a..5828c1d54505f7fa0603c86a1b819fd52e528e7a 100644 (file)
@@ -23,7 +23,7 @@ SECTIONS
   __init_begin = .;
   .init.text : {
        _sinittext = .;
-       *(.init.text)
+       INIT_TEXT
        _einittext = .;
   }
   . = ALIGN(4096);
@@ -48,7 +48,7 @@ SECTIONS
 
   #include "asm/common.lds.S"
 
-  init.data : { *(init.data) }
+  init.data : { INIT_DATA }
   .data    :
   {
     . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
index 6172599b4ce2aab5e3fe3551cb351b44ecd5ff0c..d08cd1d27f27a77cfdf5375bd14d54534acf27ea 100644 (file)
 #define DATA_CONTENTS                                                        \
                __sdata = . ;                                                 \
                DATA_DATA                                                     \
-                       *(.exit.data)   /* 2.5 convention */                  \
+                       EXIT_DATA       /* 2.5 convention */                  \
                        *(.data.exit)   /* 2.4 convention */                  \
                . = ALIGN (16) ;                                              \
                *(.data.cacheline_aligned)                                    \
                . = ALIGN (4096) ;                                            \
                __init_start = . ;                                            \
                        __sinittext = .;                                      \
-                       *(.init.text)   /* 2.5 convention */                  \
+                       INIT_TEXT       /* 2.5 convention */                  \
                        __einittext = .;                                      \
-                       *(.init.data)                                         \
+                       INIT_DATA                                             \
                        *(.text.init)   /* 2.4 convention */                  \
                        *(.data.init)                                         \
                INITCALL_CONTENTS                                             \
 #define ROMK_INIT_RAM_CONTENTS                                               \
                . = ALIGN (4096) ;                                            \
                __init_start = . ;                                            \
-                       *(.init.data)   /* 2.5 convention */                  \
+                       INIT_DATA       /* 2.5 convention */                  \
                        *(.data.init)   /* 2.4 convention */                  \
                __init_end = . ;                                              \
                . = ALIGN (4096) ;
    should go into ROM.  */     
 #define ROMK_INIT_ROM_CONTENTS                                               \
                        _sinittext = .;                                       \
-                       *(.init.text)   /* 2.5 convention */                  \
+                       INIT_TEXT       /* 2.5 convention */                  \
                        _einittext = .;                                       \
                        *(.text.init)   /* 2.4 convention */                  \
                INITCALL_CONTENTS                                             \
index 7d72cce0052946c93446eaa279c0d476da80af51..84c913f38f980b621e6549ccca86f3a01a8666af 100644 (file)
@@ -131,10 +131,12 @@ SECTIONS
   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
        __init_begin = .;
        _sinittext = .;
-       *(.init.text)
+       INIT_TEXT
        _einittext = .;
   }
-  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
+       INIT_DATA
+  }
   . = ALIGN(16);
   .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
        __setup_start = .;
@@ -169,8 +171,12 @@ SECTIONS
   }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
-  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
+       EXIT_TEXT
+  }
+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
+       EXIT_DATA
+  }
 #if defined(CONFIG_BLK_DEV_INITRD)
   . = ALIGN(4096);
   .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
index ba8ea97abd219359d6e7c68541e375dbe97f5c7a..ea5386944e67e75da4e88712272ed251cad93761 100644 (file)
@@ -155,12 +155,15 @@ SECTIONS
   __init_begin = .;
   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
        _sinittext = .;
-       *(.init.text)
+       INIT_TEXT
        _einittext = .;
   }
-  __initdata_begin = .;
-  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
-  __initdata_end = .;
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
+       __initdata_begin = .;
+       INIT_DATA
+       __initdata_end = .;
+   }
+
   . = ALIGN(16);
   __setup_start = .;
   .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
@@ -187,8 +190,12 @@ SECTIONS
   }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
-  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
+       EXIT_TEXT
+  }
+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
+       EXIT_DATA
+  }
 
 /* vdso blob that is mapped into user space */
   vdso_start = . ;
index ac4ed52034dbfb44c00564e9af7020750f0a75aa..7d0f55a4982d41ba997e4ec557807d4a768fde23 100644 (file)
@@ -136,13 +136,13 @@ SECTIONS
   __init_begin = .;
   .init.text : {
        _sinittext = .;
-       *(.init.literal) *(.init.text)
+       *(.init.literal) INIT_TEXT
        _einittext = .;
   }
 
   .init.data :
   {
-    *(.init.data)
+    INIT_DATA
     . = ALIGN(0x4);
     __tagtable_begin = .;
     *(.taglist)
@@ -278,8 +278,9 @@ SECTIONS
   /* Sections to be discarded */
   /DISCARD/ :
   {
-       *(.exit.literal .exit.text)
-       *(.exit.data)
+       *(.exit.literal)
+       EXIT_TEXT
+       EXIT_DATA
         *(.exitcall.exit)
   }
 
index 10aec22a8f98b2478fcc7c8d01b8b55bce88c035..64e304a2f884e4395fdff94d46da28d717a6c79b 100644 (file)
@@ -1,9 +1,5 @@
 #
 # Makefile for the Linux/Xtensa-specific parts of the memory manager.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
 
 obj-y   := init.o fault.o tlb.o misc.o cache.o
index 5b394e9620e5c70a6b104bbc818c23b039711eca..af96e314d71fa7a228abcb371ff862246410f9c9 100644 (file)
@@ -3,11 +3,6 @@
 # Makefile for the Xtensa Instruction Set Simulator (ISS)
 # "prom monitor" library routines under Linux.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are in the main makefile...
 
 obj-y                  = io.o console.o setup.o network.o
 
index 06a86fe6a78d77a1c2d0a3b7e84003456c430933..de28dfd3b96c6ff4db97ed85320f017a8542e799 100644 (file)
@@ -2,9 +2,5 @@ obj-$(CONFIG_PM)        += sysfs.o
 obj-$(CONFIG_PM_SLEEP) += main.o
 obj-$(CONFIG_PM_TRACE) += trace.o
 
-ifeq ($(CONFIG_DEBUG_DRIVER),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
-ifeq ($(CONFIG_PM_VERBOSE),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
+ccflags-$(CONFIG_PM_VERBOSE)   += -DDEBUG
index 36b98989b15ecaf79274a547a0733a42859fb0d5..7e7b5a66f042ad096b9960cdb6e6ebf66e759d6a 100644 (file)
@@ -1,5 +1,4 @@
-EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3 \
-               -I$(TOPDIR)/drivers/infiniband/hw/cxgb3/core
+EXTRA_CFLAGS += -Idrivers/net/cxgb3
 
 obj-$(CONFIG_INFINIBAND_CXGB3) += iw_cxgb3.o
 
index b242cee656e77e5bf1a57069e15db0517b389ee2..80e3f03b5041e0348f766b14caca2fa601efa82f 100644 (file)
@@ -31,8 +31,8 @@ extern struct rio_route_ops __end_rio_route_ops[];
 
 /* Helpers internal to the RIO core code */
 #define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook)  \
-        static struct rio_route_ops __rio_route_ops __attribute_used__   \
-               __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook };
+       static struct rio_route_ops __rio_route_ops __used   \
+       __section(section)= { vid, did, add_hook, get_hook };
 
 /**
  * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
index da8cb3b3592c96ade1614ab8e553b5e16597b42a..ffdc022cae64adb62b5108d259f08fa3057b1423 100644 (file)
@@ -1376,7 +1376,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
         return -EINVAL;
 }
 
-static __attribute_used__ int 
+static __used int
 ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        return -EINVAL;
index 6673ee82cb4c09667ed06805a1505870c156220e..4faf8c4722c35804fcbbae88f06e2f3137584876 100644 (file)
@@ -16,23 +16,3 @@ EXTRA_CFLAGS += -DSMBFS_PARANOIA
 #EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP
 #EXTRA_CFLAGS += -Werror
 
-#
-# Maintainer rules
-#
-
-# getopt.c not included. It is intentionally separate
-SRC = proc.c dir.c cache.c sock.c inode.c file.c ioctl.c smbiod.c request.c \
-       symlink.c
-
-proto:
-       -rm -f proto.h
-       @echo >  proto2.h "/*"
-       @echo >> proto2.h " *  Autogenerated with cproto on: " `date`
-       @echo >> proto2.h " */"
-       @echo >> proto2.h ""
-       @echo >> proto2.h "struct smb_request;"
-       @echo >> proto2.h "struct sock;"
-       @echo >> proto2.h "struct statfs;"
-       @echo >> proto2.h ""
-       cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
-       mv proto2.h proto.h
index b0828d43e110c93f27b65adf593fc0c40e58a676..ea3070ff13a528872b55915195c707ae1079f764 100644 (file)
@@ -110,7 +110,7 @@ struct tagtable {
        int     (*parse)(struct tag *);
 };
 
-#define __tag __attribute_used__ __attribute__((__section__(".taglist.init")))
+#define __tag __used __attribute__((__section__(".taglist.init")))
 #define __tagtable(tag, fn)                                            \
        static struct tagtable __tagtable_##fn __tag = { tag, fn }
 
index 9f584cc5c5fb48f9491b1cdbe8ceca5e01d844ca..76df771be58566171cd5b74ab16489ae1c5f2cea 100644 (file)
@@ -9,10 +9,46 @@
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
+/* The actual configuration determine if the init/exit sections
+ * are handled as text/data or they can be discarded (which
+ * often happens at runtime)
+ */
+#ifdef CONFIG_HOTPLUG
+#define DEV_KEEP(sec)    *(.dev##sec)
+#define DEV_DISCARD(sec)
+#else
+#define DEV_KEEP(sec)
+#define DEV_DISCARD(sec) *(.dev##sec)
+#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define CPU_KEEP(sec)    *(.cpu##sec)
+#define CPU_DISCARD(sec)
+#else
+#define CPU_KEEP(sec)
+#define CPU_DISCARD(sec) *(.cpu##sec)
+#endif
+
+#if defined(CONFIG_MEMORY_HOTPLUG)
+#define MEM_KEEP(sec)    *(.mem##sec)
+#define MEM_DISCARD(sec)
+#else
+#define MEM_KEEP(sec)
+#define MEM_DISCARD(sec) *(.mem##sec)
+#endif
+
+
 /* .data section */
 #define DATA_DATA                                                      \
        *(.data)                                                        \
        *(.data.init.refok)                                             \
+       *(.ref.data)                                                    \
+       DEV_KEEP(init.data)                                             \
+       DEV_KEEP(exit.data)                                             \
+       CPU_KEEP(init.data)                                             \
+       CPU_KEEP(exit.data)                                             \
+       MEM_KEEP(init.data)                                             \
+       MEM_KEEP(exit.data)                                             \
        . = ALIGN(8);                                                   \
        VMLINUX_SYMBOL(__start___markers) = .;                          \
        *(__markers)                                                    \
                *(__ksymtab_strings)                                    \
        }                                                               \
                                                                        \
+       /* __*init sections */                                          \
+       __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) {         \
+               *(.ref.rodata)                                          \
+               DEV_KEEP(init.rodata)                                   \
+               DEV_KEEP(exit.rodata)                                   \
+               CPU_KEEP(init.rodata)                                   \
+               CPU_KEEP(exit.rodata)                                   \
+               MEM_KEEP(init.rodata)                                   \
+               MEM_KEEP(exit.rodata)                                   \
+       }                                                               \
+                                                                       \
        /* Built-in module parameters. */                               \
        __param : AT(ADDR(__param) - LOAD_OFFSET) {                     \
                VMLINUX_SYMBOL(__start___param) = .;                    \
                VMLINUX_SYMBOL(__stop___param) = .;                     \
                VMLINUX_SYMBOL(__end_rodata) = .;                       \
        }                                                               \
-                                                                       \
        . = ALIGN((align));
 
 /* RODATA provided for backward compatibility.
 #define TEXT_TEXT                                                      \
                ALIGN_FUNCTION();                                       \
                *(.text)                                                \
+               *(.ref.text)                                            \
                *(.text.init.refok)                                     \
-               *(.exit.text.refok)
+               *(.exit.text.refok)                                     \
+       DEV_KEEP(init.text)                                             \
+       DEV_KEEP(exit.text)                                             \
+       CPU_KEEP(init.text)                                             \
+       CPU_KEEP(exit.text)                                             \
+       MEM_KEEP(init.text)                                             \
+       MEM_KEEP(exit.text)
+
 
 /* sched.text is aling to function alignment to secure we have same
  * address even at second ld pass when generating System.map */
                *(.kprobes.text)                                        \
                VMLINUX_SYMBOL(__kprobes_text_end) = .;
 
+/* init and exit section handling */
+#define INIT_DATA                                                      \
+       *(.init.data)                                                   \
+       DEV_DISCARD(init.data)                                          \
+       DEV_DISCARD(init.rodata)                                        \
+       CPU_DISCARD(init.data)                                          \
+       CPU_DISCARD(init.rodata)                                        \
+       MEM_DISCARD(init.data)                                          \
+       MEM_DISCARD(init.rodata)
+
+#define INIT_TEXT                                                      \
+       *(.init.text)                                                   \
+       DEV_DISCARD(init.text)                                          \
+       CPU_DISCARD(init.text)                                          \
+       MEM_DISCARD(init.text)
+
+#define EXIT_DATA                                                      \
+       *(.exit.data)                                                   \
+       DEV_DISCARD(exit.data)                                          \
+       DEV_DISCARD(exit.rodata)                                        \
+       CPU_DISCARD(exit.data)                                          \
+       CPU_DISCARD(exit.rodata)                                        \
+       MEM_DISCARD(exit.data)                                          \
+       MEM_DISCARD(exit.rodata)
+
+#define EXIT_TEXT                                                      \
+       *(.exit.text)                                                   \
+       DEV_DISCARD(exit.text)                                          \
+       CPU_DISCARD(exit.text)                                          \
+       MEM_DISCARD(exit.text)
+
                /* DWARF debug sections.
                Symbols in the DWARF debugging sections are relative to
                the beginning of the section so we begin them at 0.  */
index e58d3298fa109eb4ba733d580e39d3b06580dbcc..5b6665c754c914213f4e6fa8fb76bc497e5bbf1c 100644 (file)
@@ -24,7 +24,7 @@
 extern void ia64_bad_param_for_setreg (void);
 extern void ia64_bad_param_for_getreg (void);
 
-register unsigned long ia64_r13 asm ("r13") __attribute_used__;
+register unsigned long ia64_r13 asm ("r13") __used;
 
 #define ia64_setreg(regnum, val)                                               \
 ({                                                                             \
index ddb18ad23303ae8a4f26dafdf38da0e3dd83c8fc..b2e4124070aef289a724a90049bba93adfcffa64 100644 (file)
@@ -65,6 +65,6 @@ extern struct sh_machine_vector sh_mv;
 #define get_system_type()      sh_mv.mv_name
 
 #define __initmv \
-       __attribute_used__ __attribute__((__section__ (".machvec.init")))
+       __used __section(.machvec.init)
 
 #endif /* _ASM_SH_MACHVEC_H */
index c6577d3dc46d594e33bc4a572f71d44bb02a88f2..c50e5d35fe84fefe26978011966a5d39f3d2ac7b 100644 (file)
@@ -68,7 +68,7 @@ struct thread_info {
 #define init_stack             (init_thread_union.stack)
 
 /* how to get the current stack pointer from C */
-register unsigned long current_stack_pointer asm("r15") __attribute_used__;
+register unsigned long current_stack_pointer asm("r15") __used;
 
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
index ef58fd2a6eb089f49086f1dfec56d451af127f8b..a516e9192f1135a2a6b310caf5aaf0525df43220 100644 (file)
@@ -85,7 +85,7 @@ struct thread_info {
 
 
 /* how to get the current stack pointer from C */
-register unsigned long current_stack_pointer asm("esp") __attribute_used__;
+register unsigned long current_stack_pointer asm("esp") __used;
 
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
index bd694f779346687e787a61b6547f15a9af28f0c7..ad99ce9f916960063e521d05017dace2f551f79f 100644 (file)
@@ -34,7 +34,6 @@ header-y += atmsap.h
 header-y += atmsvc.h
 header-y += atm_zatm.h
 header-y += auto_fs4.h
-header-y += auxvec.h
 header-y += ax25.h
 header-y += b1lli.h
 header-y += baycom.h
@@ -73,7 +72,7 @@ header-y += gen_stats.h
 header-y += gigaset_dev.h
 header-y += hdsmart.h
 header-y += hysdn_if.h
-header-y += i2c-dev.h
+header-y += i2o-dev.h
 header-y += i8k.h
 header-y += if_arcnet.h
 header-y += if_bonding.h
@@ -158,7 +157,6 @@ header-y += veth.h
 header-y += video_decoder.h
 header-y += video_encoder.h
 header-y += videotext.h
-header-y += vt.h
 header-y += x25.h
 
 unifdef-y += acct.h
@@ -173,6 +171,7 @@ unifdef-y += atm.h
 unifdef-y += atm_tcp.h
 unifdef-y += audit.h
 unifdef-y += auto_fs.h
+unifdef-y += auxvec.h
 unifdef-y += binfmts.h
 unifdef-y += capability.h
 unifdef-y += capi.h
@@ -214,7 +213,7 @@ unifdef-y += hdreg.h
 unifdef-y += hiddev.h
 unifdef-y += hpet.h
 unifdef-y += i2c.h
-unifdef-y += i2o-dev.h
+unifdef-y += i2c-dev.h
 unifdef-y += icmp.h
 unifdef-y += icmpv6.h
 unifdef-y += if_addr.h
@@ -349,6 +348,7 @@ unifdef-y += videodev.h
 unifdef-y += virtio_config.h
 unifdef-y += virtio_blk.h
 unifdef-y += virtio_net.h
+unifdef-y += vt.h
 unifdef-y += wait.h
 unifdef-y += wanrouter.h
 unifdef-y += watchdog.h
index 2d8c0f48f55e6236a4c25b8510feafb48670ff10..e5eb795f78a1c9b22f2c9c474b80c32a0cfff810 100644 (file)
@@ -7,10 +7,8 @@
 
 #if __GNUC_MINOR__ >= 3
 # define __used                        __attribute__((__used__))
-# define __attribute_used__    __used                          /* deprecated */
 #else
 # define __used                        __attribute__((__unused__))
-# define __attribute_used__    __used                          /* deprecated */
 #endif
 
 #if __GNUC_MINOR__ >= 4
index ee7ca5de970cb6cfadd4c04f5df4444ed07645a8..0ab3a32323307d1445392ea571550698c0cd70d1 100644 (file)
@@ -15,7 +15,6 @@
 #endif
 
 #define __used                 __attribute__((__used__))
-#define __attribute_used__     __used                  /* deprecated */
 #define __must_check           __attribute__((warn_unused_result))
 #define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
 #define __always_inline                inline __attribute__((always_inline))
index c68b67b86ef1d5cccbed6f7f76f5a94c5a692c80..d0e17e1657dca11b86f151084a10bc87204c80a1 100644 (file)
@@ -126,10 +126,6 @@ extern void __chk_io_ptr(const volatile void __iomem *);
  * Mark functions that are referenced only in inline assembly as __used so
  * the code is emitted even though it appears to be unreferenced.
  */
-#ifndef __attribute_used__
-# define __attribute_used__    /* deprecated */
-#endif
-
 #ifndef __used
 # define __used                        /* unimplemented */
 #endif
@@ -175,4 +171,9 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 #define __cold
 #endif
 
+/* Simple shorthand for a section definition */
+#ifndef __section
+# define __section(S) __attribute__ ((__section__(#S)))
+#endif
+
 #endif /* __LINUX_COMPILER_H */
index e831759b2fb5f971cfabdb94dfa9863b4f57cc4b..278e3ef0533699f2e9a3845bdc12715ce6be30cb 100644 (file)
@@ -76,7 +76,7 @@
                typeof(desc) _desc                                      \
                             __attribute__((aligned(sizeof(Elf##size##_Word)))); \
        } _ELFNOTE_PASTE(_note_, unique)                                \
-               __attribute_used__                                      \
+               __used                                                  \
                __attribute__((section(".note." name),                  \
                               aligned(sizeof(Elf##size##_Word)),       \
                               unused)) = {                             \
index 5141381a75279bbb0a6b15c729e93d015302088b..2efbda01674186d166671dbf2455063970c52bfa 100644 (file)
 
 /* These are for everybody (although not all archs will actually
    discard it in modules) */
-#define __init         __attribute__ ((__section__ (".init.text"))) __cold
-#define __initdata     __attribute__ ((__section__ (".init.data")))
-#define __exitdata     __attribute__ ((__section__(".exit.data")))
-#define __exit_call    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
+#define __init         __section(.init.text) __cold
+#define __initdata     __section(.init.data)
+#define __exitdata     __section(.exit.data)
+#define __exit_call    __used __section(.exitcall.exit)
 
 /* modpost check for section mismatches during the kernel build.
  * A section mismatch happens when there are references from a
  * when early init has completed so all such references are potential bugs.
  * For exit sections the same issue exists.
  * The following markers are used for the cases where the reference to
- * the init/exit section (code or data) is valid and will teach modpost
- * not to issue a warning.
+ * the *init / *exit section (code or data) is valid and will teach
+ * modpost not to issue a warning.
  * The markers follow same syntax rules as __init / __initdata. */
-#define __init_refok     noinline __attribute__ ((__section__ (".text.init.refok")))
-#define __initdata_refok          __attribute__ ((__section__ (".data.init.refok")))
-#define __exit_refok     noinline __attribute__ ((__section__ (".exit.text.refok")))
+#define __ref            __section(.ref.text) noinline
+#define __refdata        __section(.ref.data)
+#define __refconst       __section(.ref.rodata)
+
+/* backward compatibility note
+ *  A few places hardcode the old section names:
+ *  .text.init.refok
+ *  .data.init.refok
+ *  .exit.text.refok
+ *  They should be converted to use the defines from this file
+ */
+
+/* compatibility defines */
+#define __init_refok     __ref
+#define __initdata_refok __refdata
+#define __exit_refok     __ref
+
 
 #ifdef MODULE
-#define __exit         __attribute__ ((__section__(".exit.text"))) __cold
+#define __exitused
 #else
-#define __exit         __attribute_used__ __attribute__ ((__section__(".exit.text"))) __cold
+#define __exitused  __used
 #endif
 
+#define __exit          __section(.exit.text) __exitused __cold
+
+/* Used for HOTPLUG */
+#define __devinit        __section(.devinit.text) __cold
+#define __devinitdata    __section(.devinit.data)
+#define __devinitconst   __section(.devinit.rodata)
+#define __devexit        __section(.devexit.text) __exitused __cold
+#define __devexitdata    __section(.devexit.data)
+#define __devexitconst   __section(.devexit.rodata)
+
+/* Used for HOTPLUG_CPU */
+#define __cpuinit        __section(.cpuinit.text) __cold
+#define __cpuinitdata    __section(.cpuinit.data)
+#define __cpuinitconst   __section(.cpuinit.rodata)
+#define __cpuexit        __section(.cpuexit.text) __exitused __cold
+#define __cpuexitdata    __section(.cpuexit.data)
+#define __cpuexitconst   __section(.cpuexit.rodata)
+
+/* Used for MEMORY_HOTPLUG */
+#define __meminit        __section(.meminit.text) __cold
+#define __meminitdata    __section(.meminit.data)
+#define __meminitconst   __section(.meminit.rodata)
+#define __memexit        __section(.memexit.text) __exitused __cold
+#define __memexitdata    __section(.memexit.data)
+#define __memexitconst   __section(.memexit.rodata)
+
 /* For assembly routines */
 #define __INIT         .section        ".init.text","ax"
-#define __INIT_REFOK   .section        ".text.init.refok","ax"
 #define __FINIT                .previous
+
 #define __INITDATA     .section        ".init.data","aw"
-#define __INITDATA_REFOK .section      ".data.init.refok","aw"
+
+#define __DEVINIT        .section      ".devinit.text", "ax"
+#define __DEVINITDATA    .section      ".devinit.data", "aw"
+
+#define __CPUINIT        .section      ".cpuinit.text", "ax"
+#define __CPUINITDATA    .section      ".cpuinit.data", "aw"
+
+#define __MEMINIT        .section      ".meminit.text", "ax"
+#define __MEMINITDATA    .section      ".meminit.data", "aw"
+
+/* silence warnings when references are OK */
+#define __REF            .section       ".ref.text", "ax"
+#define __REFDATA        .section       ".ref.data", "aw"
+#define __REFCONST       .section       ".ref.rodata", "aw"
+/* backward compatibility */
+#define __INIT_REFOK     .section      __REF
+#define __INITDATA_REFOK .section      __REFDATA
 
 #ifndef __ASSEMBLY__
 /*
@@ -108,7 +164,7 @@ void prepare_namespace(void);
  */
 
 #define __define_initcall(level,fn,id) \
-       static initcall_t __initcall_##fn##id __attribute_used__ \
+       static initcall_t __initcall_##fn##id __used \
        __attribute__((__section__(".initcall" level ".init"))) = fn
 
 /*
@@ -142,11 +198,11 @@ void prepare_namespace(void);
 
 #define console_initcall(fn) \
        static initcall_t __initcall_##fn \
-       __attribute_used__ __attribute__((__section__(".con_initcall.init")))=fn
+       __used __section(.con_initcall.init) = fn
 
 #define security_initcall(fn) \
        static initcall_t __initcall_##fn \
-       __attribute_used__ __attribute__((__section__(".security_initcall.init"))) = fn
+       __used __section(.security_initcall.init) = fn
 
 struct obs_kernel_param {
        const char *str;
@@ -163,8 +219,7 @@ struct obs_kernel_param {
 #define __setup_param(str, unique_id, fn, early)                       \
        static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
        static struct obs_kernel_param __setup_##unique_id      \
-               __attribute_used__                              \
-               __attribute__((__section__(".init.setup")))     \
+               __used __section(.init.setup)                   \
                __attribute__((aligned((sizeof(long)))))        \
                = { __setup_str_##unique_id, fn, early }
 
@@ -242,7 +297,7 @@ void __init parse_early_param(void);
 #endif
 
 /* Data marked not to be saved by software suspend */
-#define __nosavedata __attribute__ ((__section__ (".data.nosave")))
+#define __nosavedata __section(.data.nosave)
 
 /* This means "can be init if no module support, otherwise module load
    may call it." */
@@ -254,43 +309,6 @@ void __init parse_early_param(void);
 #define __initdata_or_module __initdata
 #endif /*CONFIG_MODULES*/
 
-#ifdef CONFIG_HOTPLUG
-#define __devinit
-#define __devinitdata
-#define __devexit
-#define __devexitdata
-#else
-#define __devinit __init
-#define __devinitdata __initdata
-#define __devexit __exit
-#define __devexitdata __exitdata
-#endif
-
-#ifdef CONFIG_HOTPLUG_CPU
-#define __cpuinit
-#define __cpuinitdata
-#define __cpuexit
-#define __cpuexitdata
-#else
-#define __cpuinit      __init
-#define __cpuinitdata __initdata
-#define __cpuexit __exit
-#define __cpuexitdata  __exitdata
-#endif
-
-#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \
-       || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
-#define __meminit
-#define __meminitdata
-#define __memexit
-#define __memexitdata
-#else
-#define __meminit      __init
-#define __meminitdata __initdata
-#define __memexit __exit
-#define __memexitdata  __exitdata
-#endif
-
 /* Functions marked as __devexit may be discarded at kernel link time, depending
    on config options.  Newer versions of binutils detect references from
    retained sections to discarded sections and flag an error.  Pointers to
index aedc06be1de846d4b9b8b3bb73dd2912fcd2c3a2..ac481e2094fd01b79e12279a0b631092b7b6f8e4 100644 (file)
@@ -178,7 +178,7 @@ void *__symbol_get_gpl(const char *symbol);
 #define __CRC_SYMBOL(sym, sec)                                 \
        extern void *__crc_##sym __attribute__((weak));         \
        static const unsigned long __kcrctab_##sym              \
-       __attribute_used__                                      \
+       __used                                                  \
        __attribute__((section("__kcrctab" sec), unused))       \
        = (unsigned long) &__crc_##sym;
 #else
@@ -193,7 +193,7 @@ void *__symbol_get_gpl(const char *symbol);
        __attribute__((section("__ksymtab_strings")))           \
        = MODULE_SYMBOL_PREFIX #sym;                            \
        static const struct kernel_symbol __ksymtab_##sym       \
-       __attribute_used__                                      \
+       __used                                                  \
        __attribute__((section("__ksymtab" sec), unused))       \
        = { (unsigned long)&sym, __kstrtab_##sym }
 
index 13410b20600f4a33284da6252cc7beeb99c9f105..8126e55c5bdcbd3c68d4c6ffc4c83797e3b1ca7c 100644 (file)
@@ -18,7 +18,7 @@
 #define __module_cat(a,b) ___module_cat(a,b)
 #define __MODULE_INFO(tag, name, info)                                   \
 static const char __module_cat(name,__LINE__)[]                                  \
-  __attribute_used__                                                     \
+  __used                                                                 \
   __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
 #else  /* !MODULE */
 #define __MODULE_INFO(tag, name, info)
@@ -72,7 +72,7 @@ struct kparam_array
        BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \
        static const char __param_str_##name[] = prefix #name;          \
        static struct kernel_param const __param_##name                 \
-       __attribute_used__                                              \
+       __used                                                          \
     __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
        = { __param_str_##name, perm, set, get, { arg } }
 
index 0dd93bb62fbe9f4af33c458f24db96ca79d8c0c2..ae1006322f808d90b233188108efac1f59f23359 100644 (file)
@@ -867,7 +867,7 @@ enum pci_fixup_pass {
 
 /* Anonymous variables would be nice... */
 #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \
-       static const struct pci_fixup __pci_fixup_##name __attribute_used__ \
+       static const struct pci_fixup __pci_fixup_##name __used         \
        __attribute__((__section__(#section))) = { vendor, device, hook };
 #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook)                  \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,                     \
index 288444b4cd8ae8a7e1b74614b9fd4745c635de7a..0d0bbf218f1f363d2c4732fe7cde4d9ac0909529 100644 (file)
@@ -1,3 +1,11 @@
+config ARCH
+       string
+       option env="ARCH"
+
+config KERNELVERSION
+       string
+       option env="KERNELVERSION"
+
 config DEFCONFIG_LIST
        string
        depends on !UML
index 14fb355e3caacc1311adfcaf52435e974c715dce..c4ecb2994ba3855110cdb596b6500a99b2404b24 100644 (file)
@@ -79,6 +79,38 @@ config HEADERS_CHECK
          exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in
          your build tree), to make sure they're suitable.
 
+config DEBUG_SECTION_MISMATCH
+       bool "Enable full Section mismatch analysis"
+       default n
+       help
+         The section mismatch analysis checks if there are illegal
+         references from one section to another section.
+         Linux will during link or during runtime drop some sections
+         and any use of code/data previously in these sections will
+         most likely result in an oops.
+         In the code functions and variables are annotated with
+         __init, __devinit etc. (see full list in include/linux/init.h)
+         which result in the code/data being placed in specific sections.
+         The section mismatch anaylsis are always done after a full
+         kernel build but enabling this options will in addition
+         do the following:
+         - Add the option -fno-inline-functions-called-once to gcc
+           When inlining a function annotated __init in a non-init
+           function we would loose the section information and thus
+           the analysis would not catch the illegal reference.
+           This options tell gcc to inline less but will also
+           result in a larger kernel.
+         - Run the section mismatch analysis for each module/built-in.o
+           When we run the section mismatch analysis on vmlinux.o we
+           looses valueable information about where the mismatch was
+           introduced.
+           Running the analysis for each module/built-in.o file
+           will tell where the mismatch happens much closer to the
+           source. The drawback is that we will report the same
+           mismatch at least twice.
+         - Enable verbose reporting from modpost to help solving
+           the section mismatches reported.
+
 config DEBUG_KERNEL
        bool "Kernel debugging"
        help
index de9836eee8bbba866312ce4e5c22f05caef98486..67fb4530a6ff88afb7e3a86945dc2837c87c72f5 100644 (file)
@@ -83,10 +83,12 @@ ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
 builtin-target := $(obj)/built-in.o
 endif
 
+modorder-target := $(obj)/modules.order
+
 # We keep a list of all modules in $(MODVERDIR)
 
 __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
-        $(if $(KBUILD_MODULES),$(obj-m)) \
+        $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
         $(subdir-ym) $(always)
        @:
 
@@ -101,6 +103,10 @@ ifneq ($(KBUILD_CHECKSRC),0)
   endif
 endif
 
+# Do section mismatch analysis for each module/built-in.o
+ifdef CONFIG_DEBUG_SECTION_MISMATCH
+  cmd_secanalysis = ; scripts/mod/modpost $@
+endif
 
 # Compile C sources (.c)
 # ---------------------------------------------------------------------------
@@ -266,7 +272,8 @@ ifdef builtin-target
 quiet_cmd_link_o_target = LD      $@
 # If the list of objects to link is empty, just create an empty built-in.o
 cmd_link_o_target = $(if $(strip $(obj-y)),\
-                     $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
+                     $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
+                     $(cmd_secanalysis),\
                      rm -f $@; $(AR) rcs $@)
 
 $(builtin-target): $(obj-y) FORCE
@@ -275,6 +282,19 @@ $(builtin-target): $(obj-y) FORCE
 targets += $(builtin-target)
 endif # builtin-target
 
+#
+# Rule to create modules.order file
+#
+# Create commands to either record .ko file or cat modules.order from
+# a subdirectory
+modorder-cmds =                                                \
+       $(foreach m, $(modorder),                       \
+               $(if $(filter %/modules.order, $m),     \
+                       cat $m;, echo kernel/$m;))
+
+$(modorder-target): $(subdir-ym) FORCE
+       $(Q)(cat /dev/null; $(modorder-cmds)) > $@
+
 #
 # Rule to compile a set of .o files into one .a file
 #
@@ -301,7 +321,7 @@ $($(subst $(obj)/,,$(@:.o=-objs)))    \
 $($(subst $(obj)/,,$(@:.o=-y)))), $^)
  
 quiet_cmd_link_multi-y = LD      $@
-cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)
+cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis)
 
 quiet_cmd_link_multi-m = LD [M]  $@
 cmd_link_multi-m = $(cmd_link_multi-y)
index 3c5e88bfecf1bc3d00e2de16fc4c31720406a8fe..8e440233c27dacf8e3083417047d1f8024f25131 100644 (file)
@@ -25,6 +25,11 @@ lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
 # o if we encounter foo/ in $(obj-m), remove it from $(obj-m) 
 #   and add the directory to the list of dirs to descend into: $(subdir-m)
 
+# Determine modorder.
+# Unfortunately, we don't have information about ordering between -y
+# and -m subdirs.  Just put -y's first.
+modorder       := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko))
+
 __subdir-y     := $(patsubst %/,%,$(filter %/, $(obj-y)))
 subdir-y       += $(__subdir-y)
 __subdir-m     := $(patsubst %/,%,$(filter %/, $(obj-m)))
@@ -64,6 +69,7 @@ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)
 extra-y                := $(addprefix $(obj)/,$(extra-y))
 always         := $(addprefix $(obj)/,$(always))
 targets                := $(addprefix $(obj)/,$(targets))
+modorder       := $(addprefix $(obj)/,$(modorder))
 obj-y          := $(addprefix $(obj)/,$(obj-y))
 obj-m          := $(addprefix $(obj)/,$(obj-m))
 lib-y          := $(addprefix $(obj)/,$(lib-y))
index f0ff248f5e6f55e07d71b66104cb794e7310d959..efa5d940e6324caa0aa120343043b89475502e74 100644 (file)
@@ -21,7 +21,7 @@ quiet_cmd_modules_install = INSTALL $@
 
 # Modules built outside the kernel source tree go into extra by default
 INSTALL_MOD_DIR ?= extra
-ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(KBUILD_EXTMOD),,$(@D))
+ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D))
 
 modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
 
index d988f5d21e3df12b50e31b9eac86bc21e82b867c..65e707e1ffc3a564e1ed1924cab806ff88e09286 100644 (file)
@@ -62,6 +62,7 @@ modpost = scripts/mod/modpost                    \
  $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile)   \
  $(if $(KBUILD_EXTMOD),-I $(modulesymfile))      \
  $(if $(KBUILD_EXTMOD),-o $(modulesymfile))      \
+ $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S)      \
  $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
 
 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
index 0e4bd5459df4e08e90770516e942ba9236da3a22..35bdc68b6e66604fc31f184fff4ad1c0e6c5398e 100644 (file)
@@ -30,6 +30,7 @@
  *             !Ifilename
  *             !Dfilename
  *             !Ffilename
+ *             !Pfilename
  *
  */
 
@@ -57,6 +58,7 @@ FILEONLY *symbolsonly;
 typedef void FILELINE(char * file, char * line);
 FILELINE * singlefunctions;
 FILELINE * entity_system;
+FILELINE * docsection;
 
 #define MAXLINESZ     2048
 #define MAXFILES      250
@@ -65,6 +67,7 @@ FILELINE * entity_system;
 #define DOCBOOK       "-docbook"
 #define FUNCTION      "-function"
 #define NOFUNCTION    "-nofunction"
+#define NODOCSECTIONS "-no-doc-sections"
 
 char *srctree;
 
@@ -231,13 +234,14 @@ void docfunctions(char * filename, char * type)
 
        for (i=0; i <= symfilecnt; i++)
                symcnt += symfilelist[i].symbolcnt;
-       vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*));
+       vec = malloc((2 + 2 * symcnt + 3) * sizeof(char *));
        if (vec == NULL) {
                perror("docproc: ");
                exit(1);
        }
        vec[idx++] = KERNELDOC;
        vec[idx++] = DOCBOOK;
+       vec[idx++] = NODOCSECTIONS;
        for (i=0; i < symfilecnt; i++) {
                struct symfile * sym = &symfilelist[i];
                for (j=0; j < sym->symbolcnt; j++) {
@@ -286,13 +290,37 @@ void singfunc(char * filename, char * line)
        exec_kernel_doc(vec);
 }
 
+/*
+ * Insert specific documentation section from a file.
+ * Call kernel-doc with the following parameters:
+ * kernel-doc -docbook -function "doc section" filename
+ */
+void docsect(char *filename, char *line)
+{
+       char *vec[6]; /* kerneldoc -docbook -function "section" file NULL */
+       char *s;
+
+       for (s = line; *s; s++)
+               if (*s == '\n')
+                       *s = '\0';
+
+       vec[0] = KERNELDOC;
+       vec[1] = DOCBOOK;
+       vec[2] = FUNCTION;
+       vec[3] = line;
+       vec[4] = filename;
+       vec[5] = NULL;
+       exec_kernel_doc(vec);
+}
+
 /*
  * Parse file, calling action specific functions for:
  * 1) Lines containing !E
  * 2) Lines containing !I
  * 3) Lines containing !D
  * 4) Lines containing !F
- * 5) Default lines - lines not matching the above
+ * 5) Lines containing !P
+ * 6) Default lines - lines not matching the above
  */
 void parse_file(FILE *infile)
 {
@@ -326,6 +354,15 @@ void parse_file(FILE *infile)
                                                s++;
                                        singlefunctions(line +2, s);
                                        break;
+                               case 'P':
+                                       /* filename */
+                                       while (*s && !isspace(*s)) s++;
+                                       *s++ = '\0';
+                                       /* DOC: section name */
+                                       while (isspace(*s))
+                                               s++;
+                                       docsection(line + 2, s);
+                                       break;
                                default:
                                        defaultline(line);
                        }
@@ -372,6 +409,7 @@ int main(int argc, char *argv[])
                externalfunctions = find_export_symbols;
                symbolsonly       = find_export_symbols;
                singlefunctions   = noaction2;
+               docsection        = noaction2;
                parse_file(infile);
 
                /* Rewind to start from beginning of file again */
@@ -381,6 +419,7 @@ int main(int argc, char *argv[])
                externalfunctions = extfunc;
                symbolsonly       = printline;
                singlefunctions   = singfunc;
+               docsection        = docsect;
 
                parse_file(infile);
        }
@@ -394,6 +433,7 @@ int main(int argc, char *argv[])
                externalfunctions = adddep;
                symbolsonly       = adddep;
                singlefunctions   = adddep2;
+               docsection        = adddep2;
                parse_file(infile);
                printf("\n");
        }
index 1e1a8f620c473708d3477048105c24e05de83428..235d3938529db23f34c53996ec65bca70172d34a 100644 (file)
@@ -6,7 +6,19 @@
 # e.g., to decode an i386 oops on an x86_64 system, use:
 # AFLAGS=--32 decodecode < 386.oops
 
-T=`mktemp`
+cleanup() {
+       rm -f $T $T.s $T.o
+       exit 1
+}
+
+die() {
+       echo "$@"
+       exit 1
+}
+
+trap cleanup EXIT
+
+T=`mktemp` || die "cannot create temp file"
 code=
 
 while read i ; do
@@ -20,6 +32,7 @@ esac
 done
 
 if [ -z "$code" ]; then
+       rm $T
        exit
 fi
 
@@ -48,4 +61,4 @@ echo -n "     .byte 0x" > $T.s
 echo $code >> $T.s
 as $AFLAGS -o $T.o $T.s
 objdump -S $T.o
-rm $T.o $T.s
+rm $T $T.s $T.o
index a5121a6d8949eb6bce96cca1904801f75a8bbe57..cc767b388baf7b30ef04b61650911069818d7ba0 100644 (file)
@@ -9,7 +9,10 @@
 # gcc-2.95.3, `030301' for gcc-3.3.1, etc.
 #
 
-if [[ $1 = "-p" ]] ; then with_patchlevel=1; shift; fi
+if [ "$1" = "-p" ] ; then
+       with_patchlevel=1;
+       shift;
+fi
 
 compiler="$*"
 
index 511023b430a8fc8cb688de2614e73d3dba7c47f4..dca5e0dd09bf1fdc57b525f23befeba074e41c10 100644 (file)
@@ -440,17 +440,21 @@ void error_with_pos(const char *fmt, ...)
 
 static void genksyms_usage(void)
 {
-       fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n"
+       fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
 #ifdef __GNU_LIBRARY__
+             "  -a, --arch            Select architecture\n"
              "  -d, --debug           Increment the debug level (repeatable)\n"
              "  -D, --dump            Dump expanded symbol defs (for debugging only)\n"
+             "  -T, --dump-types file Dump expanded types into file (for debugging only)\n"
              "  -w, --warnings        Enable warnings\n"
              "  -q, --quiet           Disable warnings (default)\n"
              "  -h, --help            Print this message\n"
              "  -V, --version         Print the release version\n"
 #else                          /* __GNU_LIBRARY__ */
+             "  -a                    Select architecture\n"
              "  -d                    Increment the debug level (repeatable)\n"
              "  -D                    Dump expanded symbol defs (for debugging only)\n"
+             "  -T file               Dump expanded types into file (for debugging only)\n"
              "  -w                    Enable warnings\n"
              "  -q                    Disable warnings (default)\n"
              "  -h                    Print this message\n"
@@ -477,10 +481,10 @@ int main(int argc, char **argv)
                {0, 0, 0, 0}
        };
 
-       while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:",
+       while ((o = getopt_long(argc, argv, "a:dwqVDT:h",
                                &long_opts[0], NULL)) != EOF)
 #else                          /* __GNU_LIBRARY__ */
-       while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF)
+       while ((o = getopt(argc, argv, "a:dwqVDT:h")) != EOF)
 #endif                         /* __GNU_LIBRARY__ */
                switch (o) {
                case 'a':
index 1ad6f7fc490a1233b46bcb20fd8ea7e0562f02ba..32e8c5a227c3a28bab34514da98e1491d057bef4 100644 (file)
@@ -24,22 +24,25 @@ oldconfig: $(obj)/conf
 silentoldconfig: $(obj)/conf
        $< -s $(Kconfig)
 
-# Create new linux.po file
+# Create new linux.pot file
 # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
 # The symlink is used to repair a deficiency in arch/um
-update-po-config: $(obj)/kxgettext
-       xgettext --default-domain=linux                  \
+update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
+       $(Q)echo "  GEN config"
+       $(Q)xgettext --default-domain=linux              \
            --add-comments --keyword=_ --keyword=N_      \
            --from-code=UTF-8                            \
            --files-from=scripts/kconfig/POTFILES.in     \
            --output $(obj)/config.pot
        $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
        $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch
-       (for i in `ls arch/`;                            \
-       do                                               \
-           $(obj)/kxgettext arch/$$i/Kconfig;           \
-       done ) >> $(obj)/config.pot
-       msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
+       $(Q)(for i in `ls arch/`;                        \
+           do                                           \
+               echo "  GEN $$i";                        \
+               $(obj)/kxgettext arch/$$i/Kconfig        \
+                    >> $(obj)/config.pot;               \
+           done )
+       $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
            --output $(obj)/linux.pot
        $(Q)rm -f arch/um/Kconfig.arch
        $(Q)rm -f $(obj)/config.pot
@@ -93,12 +96,6 @@ HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
 
 HOST_EXTRACFLAGS += -DLOCALE
 
-PHONY += $(obj)/dochecklxdialog
-$(obj)/dochecklxdialog:
-       $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
-
-always := dochecklxdialog
-
 
 # ===========================================================================
 # Shared Makefile for the various kconfig executables:
@@ -142,8 +139,17 @@ gconf-objs := gconf.o kconfig_load.o zconf.tab.o
 endif
 
 clean-files    := lkc_defs.h qconf.moc .tmp_qtcheck \
-                  .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
+                  .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
 clean-files     += mconf qconf gconf
+clean-files     += config.pot linux.pot
+
+# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
+PHONY += $(obj)/dochecklxdialog
+$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
+$(obj)/dochecklxdialog:
+       $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES)
+
+always := dochecklxdialog
 
 # Add environment specific flags
 HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
@@ -248,6 +254,9 @@ $(obj)/%.moc: $(src)/%.h
 $(obj)/lkc_defs.h: $(src)/lkc_proto.h
        sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
 
+# Extract gconf menu items for I18N support
+$(obj)/gconf.glade.h: $(obj)/gconf.glade
+       intltool-extract --type=gettext/glade $(obj)/gconf.glade
 
 ###
 # The following requires flex/bison/gperf
index cc94e46a79e8cf37cc5c074e74c11bf23989ea8f..9674573969902fab7bc90a3875f653d5bae6ba20 100644 (file)
@@ -1,5 +1,12 @@
+scripts/kconfig/lxdialog/checklist.c
+scripts/kconfig/lxdialog/inputbox.c
+scripts/kconfig/lxdialog/menubox.c
+scripts/kconfig/lxdialog/textbox.c
+scripts/kconfig/lxdialog/util.c
+scripts/kconfig/lxdialog/yesno.c
 scripts/kconfig/mconf.c
 scripts/kconfig/conf.c
 scripts/kconfig/confdata.c
 scripts/kconfig/gconf.c
+scripts/kconfig/gconf.glade.h
 scripts/kconfig/qconf.cc
index 8d6f17490c5efe753e34b28e38158997f6226567..fda63136ae6809512c6d84ab5c11d1497eee3bc5 100644 (file)
@@ -3,12 +3,13 @@
  * Released under the terms of the GNU GPL v2.0.
  */
 
+#include <locale.h>
 #include <ctype.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 #include <time.h>
+#include <unistd.h>
 #include <sys/stat.h>
 
 #define LKC_DIRECT_LINK
@@ -40,7 +41,7 @@ static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"
 static const char *get_help(struct menu *menu)
 {
        if (menu_has_help(menu))
-               return menu_get_help(menu);
+               return _(menu_get_help(menu));
        else
                return nohelp_text;
 }
@@ -78,7 +79,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
        tristate val;
 
        if (!sym_has_value(sym))
-               printf("(NEW) ");
+               printf(_("(NEW) "));
 
        line[0] = '\n';
        line[1] = 0;
@@ -160,7 +161,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
                }
        case set_random:
                do {
-                       val = (tristate)(random() % 3);
+                       val = (tristate)(rand() % 3);
                } while (!sym_tristate_within_range(sym, val));
                switch (val) {
                case no: line[0] = 'n'; break;
@@ -183,7 +184,7 @@ int conf_string(struct menu *menu)
        const char *def;
 
        while (1) {
-               printf("%*s%s ", indent - 1, "", menu->prompt->text);
+               printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
                printf("(%s) ", sym->name);
                def = sym_get_string_value(sym);
                if (sym_get_string_value(sym))
@@ -216,7 +217,7 @@ static int conf_sym(struct menu *menu)
        tristate oldval, newval;
 
        while (1) {
-               printf("%*s%s ", indent - 1, "", menu->prompt->text);
+               printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
                if (sym->name)
                        printf("(%s) ", sym->name);
                type = sym_get_type(sym);
@@ -306,7 +307,7 @@ static int conf_choice(struct menu *menu)
                case no:
                        return 1;
                case mod:
-                       printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+                       printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
                        return 0;
                case yes:
                        break;
@@ -316,7 +317,7 @@ static int conf_choice(struct menu *menu)
        while (1) {
                int cnt, def;
 
-               printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+               printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
                def_sym = sym_get_choice_value(sym);
                cnt = def = 0;
                line[0] = 0;
@@ -324,7 +325,7 @@ static int conf_choice(struct menu *menu)
                        if (!menu_is_visible(child))
                                continue;
                        if (!child->sym) {
-                               printf("%*c %s\n", indent, '*', menu_get_prompt(child));
+                               printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
                                continue;
                        }
                        cnt++;
@@ -333,14 +334,14 @@ static int conf_choice(struct menu *menu)
                                printf("%*c", indent, '>');
                        } else
                                printf("%*c", indent, ' ');
-                       printf(" %d. %s", cnt, menu_get_prompt(child));
+                       printf(" %d. %s", cnt, _(menu_get_prompt(child)));
                        if (child->sym->name)
                                printf(" (%s)", child->sym->name);
                        if (!sym_has_value(child->sym))
-                               printf(" (NEW)");
+                               printf(_(" (NEW)"));
                        printf("\n");
                }
-               printf("%*schoice", indent - 1, "");
+               printf(_("%*schoice"), indent - 1, "");
                if (cnt == 1) {
                        printf("[1]: 1\n");
                        goto conf_childs;
@@ -375,7 +376,7 @@ static int conf_choice(struct menu *menu)
                        break;
                case set_random:
                        if (is_new)
-                               def = (random() % cnt) + 1;
+                               def = (rand() % cnt) + 1;
                case set_default:
                case set_yes:
                case set_mod:
@@ -399,9 +400,9 @@ static int conf_choice(struct menu *menu)
                        continue;
                }
                sym_set_choice_value(sym, child->sym);
-               if (child->list) {
+               for (child = child->list; child; child = child->next) {
                        indent += 2;
-                       conf(child->list);
+                       conf(child);
                        indent -= 2;
                }
                return 1;
@@ -433,7 +434,7 @@ static void conf(struct menu *menu)
                        if (prompt)
                                printf("%*c\n%*c %s\n%*c\n",
                                        indent, '*',
-                                       indent, '*', prompt,
+                                       indent, '*', _(prompt),
                                        indent, '*');
                default:
                        ;
@@ -495,12 +496,16 @@ static void check_conf(struct menu *menu)
 
 int main(int ac, char **av)
 {
-       int i = 1;
+       int opt;
        const char *name;
        struct stat tmpstat;
 
-       if (ac > i && av[i][0] == '-') {
-               switch (av[i++][1]) {
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+
+       while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
+               switch (opt) {
                case 'o':
                        input_mode = ask_new;
                        break;
@@ -513,12 +518,7 @@ int main(int ac, char **av)
                        break;
                case 'D':
                        input_mode = set_default;
-                       defconfig_file = av[i++];
-                       if (!defconfig_file) {
-                               printf(_("%s: No default config file specified\n"),
-                                       av[0]);
-                               exit(1);
-                       }
+                       defconfig_file = optarg;
                        break;
                case 'n':
                        input_mode = set_no;
@@ -531,19 +531,22 @@ int main(int ac, char **av)
                        break;
                case 'r':
                        input_mode = set_random;
-                       srandom(time(NULL));
+                       srand(time(NULL));
                        break;
                case 'h':
-               case '?':
-                       fprintf(stderr, "See README for usage info\n");
+                       printf(_("See README for usage info\n"));
                        exit(0);
+                       break;
+               default:
+                       fprintf(stderr, _("See README for usage info\n"));
+                       exit(1);
                }
        }
-       name = av[i];
-       if (!name) {
+       if (ac == optind) {
                printf(_("%s: Kconfig file missing\n"), av[0]);
                exit(1);
        }
+       name = av[optind];
        conf_parse(name);
        //zconfdump(stdout);
        switch (input_mode) {
@@ -551,9 +554,9 @@ int main(int ac, char **av)
                if (!defconfig_file)
                        defconfig_file = conf_get_default_confname();
                if (conf_read(defconfig_file)) {
-                       printf("***\n"
+                       printf(_("***\n"
                                "*** Can't find default configuration \"%s\"!\n"
-                               "***\n", defconfig_file);
+                               "***\n"), defconfig_file);
                        exit(1);
                }
                break;
index e0f402f3b75d94d765875a6299f1f154e23a1c32..ee5fe943d58db0eda374b91a8181e5991d8cf23b 100644 (file)
@@ -232,8 +232,7 @@ load:
                                        sym->type = S_BOOLEAN;
                        }
                        if (sym->flags & def_flags) {
-                               conf_warning("trying to reassign symbol %s", sym->name);
-                               break;
+                               conf_warning("override: reassigning to symbol %s", sym->name);
                        }
                        switch (sym->type) {
                        case S_BOOLEAN:
@@ -272,8 +271,7 @@ load:
                                        sym->type = S_OTHER;
                        }
                        if (sym->flags & def_flags) {
-                               conf_warning("trying to reassign symbol %s", sym->name);
-                               break;
+                               conf_warning("override: reassigning to symbol %s", sym->name);
                        }
                        if (conf_set_sym_val(sym, def, def_flags, p))
                                continue;
@@ -297,14 +295,12 @@ load:
                                }
                                break;
                        case yes:
-                               if (cs->def[def].tri != no) {
-                                       conf_warning("%s creates inconsistent choice state", sym->name);
-                                       cs->flags &= ~def_flags;
-                               } else
-                                       cs->def[def].val = sym;
+                               if (cs->def[def].tri != no)
+                                       conf_warning("override: %s changes choice state", sym->name);
+                               cs->def[def].val = sym;
                                break;
                        }
-                       cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
+                       cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
                }
        }
        fclose(in);
@@ -316,7 +312,7 @@ load:
 
 int conf_read(const char *name)
 {
-       struct symbol *sym;
+       struct symbol *sym, *choice_sym;
        struct property *prop;
        struct expr *e;
        int i, flags;
@@ -357,9 +353,9 @@ int conf_read(const char *name)
                 */
                prop = sym_get_choice_prop(sym);
                flags = sym->flags;
-               for (e = prop->expr; e; e = e->left.expr)
-                       if (e->right.sym->visible != no)
-                               flags &= e->right.sym->flags;
+               expr_list_for_each_sym(prop->expr, e, choice_sym)
+                       if (choice_sym->visible != no)
+                               flags &= choice_sym->flags;
                sym->flags &= flags | ~SYMBOL_DEF_USER;
        }
 
index 6f98dbfe70cf4df2e57432e838465c33e4f4888e..579ece4fa584506a882e9e2bdd3e7fbb28d3b0c1 100644 (file)
@@ -87,7 +87,7 @@ struct expr *expr_copy(struct expr *org)
                break;
        case E_AND:
        case E_OR:
-       case E_CHOICE:
+       case E_LIST:
                e->left.expr = expr_copy(org->left.expr);
                e->right.expr = expr_copy(org->right.expr);
                break;
@@ -217,7 +217,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
                expr_free(e2);
                trans_count = old_count;
                return res;
-       case E_CHOICE:
+       case E_LIST:
        case E_RANGE:
        case E_NONE:
                /* panic */;
@@ -648,7 +648,7 @@ struct expr *expr_transform(struct expr *e)
        case E_EQUAL:
        case E_UNEQUAL:
        case E_SYMBOL:
-       case E_CHOICE:
+       case E_LIST:
                break;
        default:
                e->left.expr = expr_transform(e->left.expr);
@@ -932,7 +932,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
                break;
        case E_SYMBOL:
                return expr_alloc_comp(type, e->left.sym, sym);
-       case E_CHOICE:
+       case E_LIST:
        case E_RANGE:
        case E_NONE:
                /* panic */;
@@ -955,14 +955,14 @@ tristate expr_calc_value(struct expr *e)
        case E_AND:
                val1 = expr_calc_value(e->left.expr);
                val2 = expr_calc_value(e->right.expr);
-               return E_AND(val1, val2);
+               return EXPR_AND(val1, val2);
        case E_OR:
                val1 = expr_calc_value(e->left.expr);
                val2 = expr_calc_value(e->right.expr);
-               return E_OR(val1, val2);
+               return EXPR_OR(val1, val2);
        case E_NOT:
                val1 = expr_calc_value(e->left.expr);
-               return E_NOT(val1);
+               return EXPR_NOT(val1);
        case E_EQUAL:
                sym_calc_value(e->left.sym);
                sym_calc_value(e->right.sym);
@@ -1000,9 +1000,9 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
                if (t2 == E_OR)
                        return 1;
        case E_OR:
-               if (t2 == E_CHOICE)
+               if (t2 == E_LIST)
                        return 1;
-       case E_CHOICE:
+       case E_LIST:
                if (t2 == 0)
                        return 1;
        default:
@@ -1034,12 +1034,18 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
                expr_print(e->left.expr, fn, data, E_NOT);
                break;
        case E_EQUAL:
-               fn(data, e->left.sym, e->left.sym->name);
+               if (e->left.sym->name)
+                       fn(data, e->left.sym, e->left.sym->name);
+               else
+                       fn(data, NULL, "<choice>");
                fn(data, NULL, "=");
                fn(data, e->right.sym, e->right.sym->name);
                break;
        case E_UNEQUAL:
-               fn(data, e->left.sym, e->left.sym->name);
+               if (e->left.sym->name)
+                       fn(data, e->left.sym, e->left.sym->name);
+               else
+                       fn(data, NULL, "<choice>");
                fn(data, NULL, "!=");
                fn(data, e->right.sym, e->right.sym->name);
                break;
@@ -1053,11 +1059,11 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
                fn(data, NULL, " && ");
                expr_print(e->right.expr, fn, data, E_AND);
                break;
-       case E_CHOICE:
+       case E_LIST:
                fn(data, e->right.sym, e->right.sym->name);
                if (e->left.expr) {
                        fn(data, NULL, " ^ ");
-                       expr_print(e->left.expr, fn, data, E_CHOICE);
+                       expr_print(e->left.expr, fn, data, E_LIST);
                }
                break;
        case E_RANGE:
index a195986eec6f83f0d7b76627782815855fc845fe..9d4cba1c001d9ec5f48a365a2d864e1b2f3f467a 100644 (file)
@@ -25,14 +25,13 @@ struct file {
 
 #define FILE_BUSY              0x0001
 #define FILE_SCANNED           0x0002
-#define FILE_PRINTED           0x0004
 
 typedef enum tristate {
        no, mod, yes
 } tristate;
 
 enum expr_type {
-       E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
+       E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
 };
 
 union expr_data {
@@ -45,9 +44,12 @@ struct expr {
        union expr_data left, right;
 };
 
-#define E_OR(dep1, dep2)       (((dep1)>(dep2))?(dep1):(dep2))
-#define E_AND(dep1, dep2)      (((dep1)<(dep2))?(dep1):(dep2))
-#define E_NOT(dep)             (2-(dep))
+#define EXPR_OR(dep1, dep2)    (((dep1)>(dep2))?(dep1):(dep2))
+#define EXPR_AND(dep1, dep2)   (((dep1)<(dep2))?(dep1):(dep2))
+#define EXPR_NOT(dep)          (2-(dep))
+
+#define expr_list_for_each_sym(l, e, s) \
+       for (e = (l); e && (s = e->right.sym); e = e->left.expr)
 
 struct expr_value {
        struct expr *expr;
@@ -86,7 +88,6 @@ struct symbol {
 #define SYMBOL_CHECK           0x0008
 #define SYMBOL_CHOICE          0x0010
 #define SYMBOL_CHOICEVAL       0x0020
-#define SYMBOL_PRINTED         0x0040
 #define SYMBOL_VALID           0x0080
 #define SYMBOL_OPTIONAL                0x0100
 #define SYMBOL_WRITE           0x0200
@@ -105,7 +106,8 @@ struct symbol {
 #define SYMBOL_HASHMASK                0xff
 
 enum prop_type {
-       P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+       P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE,
+       P_SELECT, P_RANGE, P_ENV
 };
 
 struct property {
index 262908cfc2ac66a057eb18d4a7c1853f96f34f95..199b22bb49e2a7940bae8f84e38348e6aca30480 100644 (file)
@@ -119,8 +119,6 @@ const char *dbg_print_flags(int val)
                strcat(buf, "choice/");
        if (val & SYMBOL_CHOICEVAL)
                strcat(buf, "choiceval/");
-       if (val & SYMBOL_PRINTED)
-               strcat(buf, "printed/");
        if (val & SYMBOL_VALID)
                strcat(buf, "valid/");
        if (val & SYMBOL_OPTIONAL)
@@ -457,14 +455,18 @@ static void text_insert_help(struct menu *menu)
 {
        GtkTextBuffer *buffer;
        GtkTextIter start, end;
-       const char *prompt = menu_get_prompt(menu);
+       const char *prompt = _(menu_get_prompt(menu));
        gchar *name;
        const char *help;
 
-       help = _(menu_get_help(menu));
+       help = menu_get_help(menu);
+
+       /* Gettextize if the help text not empty */
+       if ((help != 0) && (help[0] != 0))
+               help = _(help);
 
        if (menu->sym && menu->sym->name)
-               name = g_strdup_printf(_(menu->sym->name));
+               name = g_strdup_printf(menu->sym->name);
        else
                name = g_strdup("");
 
@@ -1171,7 +1173,7 @@ static gchar **fill_row(struct menu *menu)
        bzero(row, sizeof(row));
 
        row[COL_OPTION] =
-           g_strdup_printf("%s %s", menu_get_prompt(menu),
+           g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
                            sym && sym_has_value(sym) ? "(NEW)" : "");
 
        if (show_all && !menu_is_visible(menu))
@@ -1221,7 +1223,7 @@ static gchar **fill_row(struct menu *menu)
 
                if (def_menu)
                        row[COL_VALUE] =
-                           g_strdup(menu_get_prompt(def_menu));
+                           g_strdup(_(menu_get_prompt(def_menu)));
        }
        if (sym->flags & SYMBOL_CHOICEVAL)
                row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
index a065d5a57c01c131694d6da73ce5591063b34e9b..bed0f4e2d2f7e6632518c8577d39afd74462afdc 100644 (file)
@@ -1275,6 +1275,11 @@ YY_RULE_SETUP
 case 32:
 YY_RULE_SETUP
 {
+               while (zconfleng) {
+                       if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t'))
+                               break;
+                       zconfleng--;
+               }
                append_string(zconftext, zconfleng);
                if (!first_ts)
                        first_ts = last_ts;
index 8a07ee4f6bd486a8cb18fec1297ef1f21dc08e82..4bc68f20a73c4ab8ac9364133ee57e5cd5655375 100644 (file)
@@ -44,6 +44,7 @@ extern "C" {
 
 #define T_OPT_MODULES          1
 #define T_OPT_DEFCONFIG_LIST   2
+#define T_OPT_ENV              3
 
 struct kconf_id {
        int name;
@@ -74,6 +75,7 @@ void kconfig_load(void);
 
 /* menu.c */
 void menu_init(void);
+void menu_warn(struct menu *menu, const char *fmt, ...);
 struct menu *menu_add_menu(void);
 void menu_end_menu(void);
 void menu_add_entry(struct symbol *sym);
@@ -103,6 +105,8 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
 const char *str_get(struct gstr *gs);
 
 /* symbol.c */
+extern struct expr *sym_env_list;
+
 void sym_init(void);
 void sym_clear_all_valid(void);
 void sym_set_all_changed(void);
@@ -110,6 +114,7 @@ void sym_set_changed(struct symbol *sym);
 struct symbol *sym_check_deps(struct symbol *sym);
 struct property *prop_alloc(enum prop_type type, struct symbol *sym);
 struct symbol *prop_get_symbol(struct property *prop);
+struct property *sym_get_env_prop(struct symbol *sym);
 
 static inline tristate sym_get_tristate_value(struct symbol *sym)
 {
index 9681476b96e7fcf371840d78e17aa85657d327a1..62e1e02126e61d5cde4945c9d7f922153ea6f90e 100644 (file)
@@ -36,14 +36,16 @@ trap "rm -f $tmp" 0 1 2 3 15
 
 # Check if we can link to ncurses
 check() {
-       echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null
+       echo -e " #include CURSES_LOC \n main() {}" |
+           $cc -xc - -o $tmp 2> /dev/null
        if [ $? != 0 ]; then
-               echo " *** Unable to find the ncurses libraries."          1>&2
-               echo " *** make menuconfig require the ncurses libraries"  1>&2
-               echo " *** "                                               1>&2
-               echo " *** Install ncurses (ncurses-devel) and try again"  1>&2
-               echo " *** "                                               1>&2
-               exit 1
+           echo " *** Unable to find the ncurses libraries or the"       1>&2
+           echo " *** required header files."                            1>&2
+           echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
+           echo " *** "                                                  1>&2
+           echo " *** Install ncurses (ncurses-devel) and try again."    1>&2
+           echo " *** "                                                  1>&2
+           exit 1
        fi
 }
 
index cf697080ddddd4bf47df0057f860ef681255ea29..b2a878c936d63c793bca031b9b5d52f62b9e2e19 100644 (file)
@@ -97,8 +97,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
        int x = width / 2 - 11;
        int y = height - 2;
 
-       print_button(dialog, "Select", y, x, selected == 0);
-       print_button(dialog, " Help ", y, x + 14, selected == 1);
+       print_button(dialog, gettext("Select"), y, x, selected == 0);
+       print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
 
        wmove(dialog, y, x + 1 + 14 * selected);
        wrefresh(dialog);
index 7e17eba75ae8d8e7b23cef47fe19096fa33870db..b5211fce0d946ab90eaf1ba239f3b20b40039b11 100644 (file)
 #include <string.h>
 #include <stdbool.h>
 
+#ifndef KBUILD_NO_NLS
+# include <libintl.h>
+#else
+# define gettext(Msgid) ((const char *) (Msgid))
+#endif
+
 #ifdef __sun__
 #define CURS_MACROS
 #endif
@@ -187,10 +193,9 @@ int item_is_tag(char tag);
 int on_key_esc(WINDOW *win);
 int on_key_resize(void);
 
-void init_dialog(const char *backtitle);
+int init_dialog(const char *backtitle);
 void set_dialog_backtitle(const char *backtitle);
-void reset_dialog(void);
-void end_dialog(void);
+void end_dialog(int x, int y);
 void attr_clear(WINDOW * win, int height, int width, chtype attr);
 void dialog_clear(void);
 void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
index 05e72066b35987dfe7037f6abd2fe29a03cb016a..4946bd02b46d4324939b8ba7e03db1174359d645 100644 (file)
@@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
        int x = width / 2 - 11;
        int y = height - 2;
 
-       print_button(dialog, "  Ok  ", y, x, selected == 0);
-       print_button(dialog, " Help ", y, x + 14, selected == 1);
+       print_button(dialog, gettext("  Ok  "), y, x, selected == 0);
+       print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
 
        wmove(dialog, y, x + 1 + 14 * selected);
        wrefresh(dialog);
index 0d83159d90127a1dad38be99edff1a0973353a33..fa9d633f293c7c3a107b956e15774afd27560b12 100644 (file)
@@ -157,9 +157,9 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)
        int x = width / 2 - 16;
        int y = height - 2;
 
-       print_button(win, "Select", y, x, selected == 0);
-       print_button(win, " Exit ", y, x + 12, selected == 1);
-       print_button(win, " Help ", y, x + 24, selected == 2);
+       print_button(win, gettext("Select"), y, x, selected == 0);
+       print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
+       print_button(win, gettext(" Help "), y, x + 24, selected == 2);
 
        wmove(win, y, x + 1 + 12 * selected);
        wrefresh(win);
index fabfc1ad789d674f5f91637cba70cbfc335431d0..c704712d02271431fa9c42d0cd95be9c2ab9d988 100644 (file)
@@ -114,7 +114,7 @@ do_resize:
 
        print_title(dialog, title, width);
 
-       print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+       print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
        wnoutrefresh(dialog);
        getyx(dialog, cur_y, cur_x);    /* Save cursor position */
 
index a1bddefe73d07485ab008b382a71905ede31ee71..86d95cca46a7cfc57922e50d8fd91b74fc8da745 100644 (file)
@@ -266,31 +266,41 @@ void dialog_clear(void)
 /*
  * Do some initialization for dialog
  */
-void init_dialog(const char *backtitle)
+int init_dialog(const char *backtitle)
 {
-       dlg.backtitle = backtitle;
-       color_setup(getenv("MENUCONFIG_COLOR"));
-}
+       int height, width;
+
+       initscr();              /* Init curses */
+       getmaxyx(stdscr, height, width);
+       if (height < 19 || width < 80) {
+               endwin();
+               return -ERRDISPLAYTOOSMALL;
+       }
 
-void set_dialog_backtitle(const char *backtitle)
-{
        dlg.backtitle = backtitle;
-}
+       color_setup(getenv("MENUCONFIG_COLOR"));
 
-void reset_dialog(void)
-{
-       initscr();              /* Init curses */
        keypad(stdscr, TRUE);
        cbreak();
        noecho();
        dialog_clear();
+
+       return 0;
+}
+
+void set_dialog_backtitle(const char *backtitle)
+{
+       dlg.backtitle = backtitle;
 }
 
 /*
  * End using dialog functions.
  */
-void end_dialog(void)
+void end_dialog(int x, int y)
 {
+       /* move cursor back to original position */
+       move(y, x);
+       refresh();
        endwin();
 }
 
index ee0a04e3e012ecd4ba119cd153d96a08ded7b2a2..4e6e8090c20b573868e3cfe15015a6b6f54b2f69 100644 (file)
@@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
        int x = width / 2 - 10;
        int y = height - 2;
 
-       print_button(dialog, " Yes ", y, x, selected == 0);
-       print_button(dialog, "  No  ", y, x + 13, selected == 1);
+       print_button(dialog, gettext(" Yes "), y, x, selected == 0);
+       print_button(dialog, gettext("  No  "), y, x + 13, selected == 1);
 
        wmove(dialog, y, x + 1 + 13 * selected);
        wrefresh(dialog);
index 47e226fdedd7c8564447c76ab2481dd0ee608a44..50e61c411bc0f89d8f9c5ec9d7c7ea6992a43371 100644 (file)
@@ -8,17 +8,13 @@
  * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  */
 
-#include <sys/ioctl.h>
-#include <sys/wait.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <signal.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
-#include <termios.h>
 #include <unistd.h>
 #include <locale.h>
 
@@ -275,8 +271,6 @@ search_help[] = N_(
        "\n");
 
 static int indent;
-static struct termios ios_org;
-static int rows = 0, cols = 0;
 static struct menu *current_menu;
 static int child_count;
 static int single_menu_mode;
@@ -290,51 +284,16 @@ static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
 
-static void init_wsize(void)
-{
-       struct winsize ws;
-       char *env;
-
-       if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
-               rows = ws.ws_row;
-               cols = ws.ws_col;
-       }
-
-       if (!rows) {
-               env = getenv("LINES");
-               if (env)
-                       rows = atoi(env);
-               if (!rows)
-                       rows = 24;
-       }
-       if (!cols) {
-               env = getenv("COLUMNS");
-               if (env)
-                       cols = atoi(env);
-               if (!cols)
-                       cols = 80;
-       }
-
-       if (rows < 19 || cols < 80) {
-               fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
-               fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
-               exit(1);
-       }
-
-       rows -= 4;
-       cols -= 5;
-}
-
 static void get_prompt_str(struct gstr *r, struct property *prop)
 {
        int i, j;
        struct menu *submenu[8], *menu;
 
-       str_printf(r, "Prompt: %s\n", prop->text);
-       str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
+       str_printf(r, _("Prompt: %s\n"), _(prop->text));
+       str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name,
                prop->menu->lineno);
        if (!expr_is_yes(prop->visible.expr)) {
-               str_append(r, "  Depends on: ");
+               str_append(r, _("  Depends on: "));
                expr_gstr_print(prop->visible.expr, r);
                str_append(r, "\n");
        }
@@ -342,13 +301,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
        for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
                submenu[i++] = menu;
        if (i > 0) {
-               str_printf(r, "  Location:\n");
+               str_printf(r, _("  Location:\n"));
                for (j = 4; --i >= 0; j += 2) {
                        menu = submenu[i];
-                       str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+                       str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
                        if (menu->sym) {
                                str_printf(r, " (%s [=%s])", menu->sym->name ?
-                                       menu->sym->name : "<choice>",
+                                       menu->sym->name : _("<choice>"),
                                        sym_get_string_value(menu->sym));
                        }
                        str_append(r, "\n");
@@ -378,7 +337,7 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym)
        if (hit)
                str_append(r, "\n");
        if (sym->rev_dep.expr) {
-               str_append(r, "  Selected by: ");
+               str_append(r, _("  Selected by: "));
                expr_gstr_print(sym->rev_dep.expr, r);
                str_append(r, "\n");
        }
@@ -394,7 +353,7 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
        for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
                get_symbol_str(&res, sym);
        if (!i)
-               str_append(&res, "No matches found.\n");
+               str_append(&res, _("No matches found.\n"));
        return res;
 }
 
@@ -474,6 +433,7 @@ static void build_conf(struct menu *menu)
                        switch (prop->type) {
                        case P_MENU:
                                child_count++;
+                               prompt = _(prompt);
                                if (single_menu_mode) {
                                        item_make("%s%*c%s",
                                                  menu->data ? "-->" : "++>",
@@ -489,7 +449,7 @@ static void build_conf(struct menu *menu)
                        case P_COMMENT:
                                if (prompt) {
                                        child_count++;
-                                       item_make("   %*c*** %s ***", indent + 1, ' ', prompt);
+                                       item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt));
                                        item_set_tag(':');
                                        item_set_data(menu);
                                }
@@ -497,7 +457,7 @@ static void build_conf(struct menu *menu)
                        default:
                                if (prompt) {
                                        child_count++;
-                                       item_make("---%*c%s", indent + 1, ' ', prompt);
+                                       item_make("---%*c%s", indent + 1, ' ', _(prompt));
                                        item_set_tag(':');
                                        item_set_data(menu);
                                }
@@ -541,10 +501,10 @@ static void build_conf(struct menu *menu)
                        item_set_data(menu);
                }
 
-               item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+               item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
                if (val == yes) {
                        if (def_menu) {
-                               item_add_str(" (%s)", menu_get_prompt(def_menu));
+                               item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
                                item_add_str("  --->");
                                if (def_menu->list) {
                                        indent += 2;
@@ -556,7 +516,7 @@ static void build_conf(struct menu *menu)
                }
        } else {
                if (menu == current_menu) {
-                       item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+                       item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
                        item_set_tag(':');
                        item_set_data(menu);
                        goto conf_childs;
@@ -599,17 +559,17 @@ static void build_conf(struct menu *menu)
                                tmp = indent - tmp + 4;
                                if (tmp < 0)
                                        tmp = 0;
-                               item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
+                               item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
                                             (sym_has_value(sym) || !sym_is_changable(sym)) ?
-                                            "" : " (NEW)");
+                                            "" : _(" (NEW)"));
                                item_set_tag('s');
                                item_set_data(menu);
                                goto conf_childs;
                        }
                }
-               item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
+               item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
                          (sym_has_value(sym) || !sym_is_changable(sym)) ?
-                         "" : " (NEW)");
+                         "" : _(" (NEW)"));
                if (menu->prompt->type == P_MENU) {
                        item_add_str("  --->");
                        return;
@@ -647,7 +607,7 @@ static void conf(struct menu *menu)
                        item_set_tag('S');
                }
                dialog_clear();
-               res = dialog_menu(prompt ? prompt : _("Main Menu"),
+               res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
                                  _(menu_instructions),
                                  active_menu, &s_scroll);
                if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
@@ -694,7 +654,7 @@ static void conf(struct menu *menu)
                        if (sym)
                                show_help(submenu);
                        else
-                               show_helptext("README", _(mconf_readme));
+                               show_helptext(_("README"), _(mconf_readme));
                        break;
                case 3:
                        if (item_is_tag('t')) {
@@ -752,13 +712,13 @@ static void show_help(struct menu *menu)
                str_append(&help, nohelp_text);
        }
        get_symbol_str(&help, sym);
-       show_helptext(menu_get_prompt(menu), str_get(&help));
+       show_helptext(_(menu_get_prompt(menu)), str_get(&help));
        str_free(&help);
 }
 
 static void conf_choice(struct menu *menu)
 {
-       const char *prompt = menu_get_prompt(menu);
+       const char *prompt = _(menu_get_prompt(menu));
        struct menu *child;
        struct symbol *active;
 
@@ -772,7 +732,7 @@ static void conf_choice(struct menu *menu)
                for (child = menu->list; child; child = child->next) {
                        if (!menu_is_visible(child))
                                continue;
-                       item_make("%s", menu_get_prompt(child));
+                       item_make("%s", _(menu_get_prompt(child)));
                        item_set_data(child);
                        if (child->sym == active)
                                item_set_selected(1);
@@ -780,7 +740,7 @@ static void conf_choice(struct menu *menu)
                                item_set_tag('X');
                }
                dialog_clear();
-               res = dialog_checklist(prompt ? prompt : _("Main Menu"),
+               res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
                                        _(radiolist_instructions),
                                         15, 70, 6);
                selected = item_activate_selected();
@@ -826,10 +786,10 @@ static void conf_string(struct menu *menu)
                        heading = _(inputbox_instructions_string);
                        break;
                default:
-                       heading = "Internal mconf error!";
+                       heading = _("Internal mconf error!");
                }
                dialog_clear();
-               res = dialog_inputbox(prompt ? prompt : _("Main Menu"),
+               res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
                                      heading, 10, 75,
                                      sym_get_string_value(menu->sym));
                switch (res) {
@@ -900,13 +860,9 @@ static void conf_save(void)
        }
 }
 
-static void conf_cleanup(void)
-{
-       tcsetattr(1, TCSAFLUSH, &ios_org);
-}
-
 int main(int ac, char **av)
 {
+       int saved_x, saved_y;
        char *mode;
        int res;
 
@@ -923,11 +879,13 @@ int main(int ac, char **av)
                        single_menu_mode = 1;
        }
 
-       tcgetattr(1, &ios_org);
-       atexit(conf_cleanup);
-       init_wsize();
-       reset_dialog();
-       init_dialog(NULL);
+       getyx(stdscr, saved_y, saved_x);
+       if (init_dialog(NULL)) {
+               fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
+               fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
+               return 1;
+       }
+
        set_config_filename(conf_get_configname());
        do {
                conf(&rootmenu);
@@ -941,7 +899,7 @@ int main(int ac, char **av)
                else
                        res = -1;
        } while (res == KEY_ESC);
-       end_dialog();
+       end_dialog(saved_x, saved_y);
 
        switch (res) {
        case 0:
index f9d0d91a3fe44e2407761a60bb5a31dc22926b41..fdad17367f612428d61ab78e8ebb0df864672454 100644 (file)
@@ -15,7 +15,7 @@ static struct menu **last_entry_ptr;
 struct file *file_list;
 struct file *current_file;
 
-static void menu_warn(struct menu *menu, const char *fmt, ...)
+void menu_warn(struct menu *menu, const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
@@ -172,6 +172,9 @@ void menu_add_option(int token, char *arg)
                else if (sym_defconfig_list != current_entry->sym)
                        zconf_error("trying to redefine defconfig symbol");
                break;
+       case T_OPT_ENV:
+               prop_add_env(arg);
+               break;
        }
 }
 
@@ -239,9 +242,11 @@ void menu_finalize(struct menu *parent)
                        for (menu = parent->list; menu; menu = menu->next) {
                                if (menu->sym) {
                                        current_entry = parent;
-                                       menu_set_type(menu->sym->type);
+                                       if (sym->type == S_UNKNOWN)
+                                               menu_set_type(menu->sym->type);
                                        current_entry = menu;
-                                       menu_set_type(sym->type);
+                                       if (menu->sym->type == S_UNKNOWN)
+                                               menu_set_type(sym->type);
                                        break;
                                }
                        }
@@ -326,12 +331,42 @@ void menu_finalize(struct menu *parent)
                                            "values not supported");
                        }
                        current_entry = menu;
-                       menu_set_type(sym->type);
+                       if (menu->sym->type == S_UNKNOWN)
+                               menu_set_type(sym->type);
+                       /* Non-tristate choice values of tristate choices must
+                        * depend on the choice being set to Y. The choice
+                        * values' dependencies were propagated to their
+                        * properties above, so the change here must be re-
+                        * propagated. */
+                       if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
+                               basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
+                               basedep = expr_alloc_and(basedep, menu->dep);
+                               basedep = expr_eliminate_dups(basedep);
+                               menu->dep = basedep;
+                               for (prop = menu->sym->prop; prop; prop = prop->next) {
+                                       if (prop->menu != menu)
+                                               continue;
+                                       dep = expr_alloc_and(expr_copy(basedep),
+                                                            prop->visible.expr);
+                                       dep = expr_eliminate_dups(dep);
+                                       dep = expr_trans_bool(dep);
+                                       prop->visible.expr = dep;
+                                       if (prop->type == P_SELECT) {
+                                               struct symbol *es = prop_get_symbol(prop);
+                                               dep2 = expr_alloc_symbol(menu->sym);
+                                               dep = expr_alloc_and(dep2,
+                                                                    expr_copy(dep));
+                                               dep = expr_alloc_or(es->rev_dep.expr, dep);
+                                               dep = expr_eliminate_dups(dep);
+                                               es->rev_dep.expr = dep;
+                                       }
+                               }
+                       }
                        menu_add_symbol(P_CHOICE, sym, NULL);
                        prop = sym_get_choice_prop(sym);
                        for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
                                ;
-                       *ep = expr_alloc_one(E_CHOICE, NULL);
+                       *ep = expr_alloc_one(E_LIST, NULL);
                        (*ep)->right.sym = menu->sym;
                }
                if (menu->list && (!menu->prompt || !menu->prompt->text)) {
@@ -394,9 +429,9 @@ bool menu_is_visible(struct menu *menu)
 const char *menu_get_prompt(struct menu *menu)
 {
        if (menu->prompt)
-               return _(menu->prompt->text);
+               return menu->prompt->text;
        else if (menu->sym)
-               return _(menu->sym->name);
+               return menu->sym->name;
        return NULL;
 }
 
index b9bb32dfd62866527a8a414164e82c92721eea83..5d0fd38b089b937614dee19073ec9a2657b26d22 100644 (file)
@@ -114,7 +114,7 @@ void ConfigItem::updateMenu(void)
 
        sym = menu->sym;
        prop = menu->prompt;
-       prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
+       prompt = _(menu_get_prompt(menu));
 
        if (prop) switch (prop->type) {
        case P_MENU:
@@ -208,7 +208,7 @@ void ConfigItem::updateMenu(void)
                break;
        }
        if (!sym_has_value(sym) && visible)
-               prompt += " (NEW)";
+               prompt += _(" (NEW)");
 set_prompt:
        setText(promptColIdx, prompt);
 }
@@ -346,7 +346,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
 
        for (i = 0; i < colNr; i++)
                colMap[i] = colRevMap[i] = -1;
-       addColumn(promptColIdx, "Option");
+       addColumn(promptColIdx, _("Option"));
 
        reinit();
 }
@@ -360,14 +360,14 @@ void ConfigList::reinit(void)
        removeColumn(nameColIdx);
 
        if (showName)
-               addColumn(nameColIdx, "Name");
+               addColumn(nameColIdx, _("Name"));
        if (showRange) {
                addColumn(noColIdx, "N");
                addColumn(modColIdx, "M");
                addColumn(yesColIdx, "Y");
        }
        if (showData)
-               addColumn(dataColIdx, "Value");
+               addColumn(dataColIdx, _("Value"));
 
        updateListAll();
 }
@@ -803,7 +803,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
                        QAction *action;
 
                        headerPopup = new QPopupMenu(this);
-                       action = new QAction(NULL, "Show Name", 0, this);
+                       action = new QAction(NULL, _("Show Name"), 0, this);
                          action->setToggleAction(TRUE);
                          connect(action, SIGNAL(toggled(bool)),
                                  parent(), SLOT(setShowName(bool)));
@@ -811,7 +811,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
                                  action, SLOT(setOn(bool)));
                          action->setOn(showName);
                          action->addTo(headerPopup);
-                       action = new QAction(NULL, "Show Range", 0, this);
+                       action = new QAction(NULL, _("Show Range"), 0, this);
                          action->setToggleAction(TRUE);
                          connect(action, SIGNAL(toggled(bool)),
                                  parent(), SLOT(setShowRange(bool)));
@@ -819,7 +819,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
                                  action, SLOT(setOn(bool)));
                          action->setOn(showRange);
                          action->addTo(headerPopup);
-                       action = new QAction(NULL, "Show Data", 0, this);
+                       action = new QAction(NULL, _("Show Data"), 0, this);
                          action->setToggleAction(TRUE);
                          connect(action, SIGNAL(toggled(bool)),
                                  parent(), SLOT(setShowData(bool)));
@@ -1041,7 +1041,12 @@ void ConfigInfoView::menuInfo(void)
                if (showDebug())
                        debug = debug_info(sym);
 
-               help = print_filter(_(menu_get_help(menu)));
+               help = menu_get_help(menu);
+               /* Gettextize if the help text not empty */
+               if (help.isEmpty())
+                       help = print_filter(menu_get_help(menu));
+               else
+                       help = print_filter(_(menu_get_help(menu)));
        } else if (menu->prompt) {
                head += "<big><b>";
                head += print_filter(_(menu->prompt->text));
@@ -1083,7 +1088,11 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
                        debug += "</a><br>";
                        break;
                case P_DEFAULT:
-                       debug += "default: ";
+               case P_SELECT:
+               case P_RANGE:
+               case P_ENV:
+                       debug += prop_get_type_name(prop->type);
+                       debug += ": ";
                        expr_print(prop->expr, expr_print_help, &debug, E_NONE);
                        debug += "<br>";
                        break;
@@ -1094,16 +1103,6 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
                                debug += "<br>";
                        }
                        break;
-               case P_SELECT:
-                       debug += "select: ";
-                       expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-                       debug += "<br>";
-                       break;
-               case P_RANGE:
-                       debug += "range: ";
-                       expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-                       debug += "<br>";
-                       break;
                default:
                        debug += "unknown property: ";
                        debug += prop_get_type_name(prop->type);
@@ -1167,7 +1166,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
 {
        QPopupMenu* popup = Parent::createPopupMenu(pos);
-       QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
+       QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
          action->setToggleAction(TRUE);
          connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
          connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1189,11 +1188,11 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
 
        QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
        QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
-       layout2->addWidget(new QLabel("Find:", this));
+       layout2->addWidget(new QLabel(_("Find:"), this));
        editField = new QLineEdit(this);
        connect(editField, SIGNAL(returnPressed()), SLOT(search()));
        layout2->addWidget(editField);
-       searchButton = new QPushButton("Search", this);
+       searchButton = new QPushButton(_("Search"), this);
        searchButton->setAutoDefault(FALSE);
        connect(searchButton, SIGNAL(clicked()), SLOT(search()));
        layout2->addWidget(searchButton);
@@ -1313,58 +1312,58 @@ ConfigMainWindow::ConfigMainWindow(void)
        menu = menuBar();
        toolBar = new QToolBar("Tools", this);
 
-       backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
+       backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
          connect(backAction, SIGNAL(activated()), SLOT(goBack()));
          backAction->setEnabled(FALSE);
-       QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
+       QAction *quitAction = new QAction("Quit", _("&Quit"), CTRL+Key_Q, this);
          connect(quitAction, SIGNAL(activated()), SLOT(close()));
-       QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
+       QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), CTRL+Key_L, this);
          connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
-       saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
+       saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), CTRL+Key_S, this);
          connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
        conf_set_changed_callback(conf_changed);
        // Set saveAction's initial state
        conf_changed();
-       QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
+       QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
          connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
-       QAction *searchAction = new QAction("Find", "&Find", CTRL+Key_F, this);
+       QAction *searchAction = new QAction("Find", _("&Find"), CTRL+Key_F, this);
          connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
-       QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
+       QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
          connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
-       QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
+       QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
          connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
-       QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
+       QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
          connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
 
-       QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
+       QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
          showNameAction->setToggleAction(TRUE);
          connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
          connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
          showNameAction->setOn(configView->showName());
-       QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
+       QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
          showRangeAction->setToggleAction(TRUE);
          connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
          connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
          showRangeAction->setOn(configList->showRange);
-       QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
+       QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
          showDataAction->setToggleAction(TRUE);
          connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
          connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
          showDataAction->setOn(configList->showData);
-       QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
+       QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
          showAllAction->setToggleAction(TRUE);
          connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
          connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
          showAllAction->setOn(configList->showAll);
-       QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
+       QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
          showDebugAction->setToggleAction(TRUE);
          connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
          connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
          showDebugAction->setOn(helpText->showDebug());
 
-       QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
+       QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
          connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
-       QAction *showAboutAction = new QAction(NULL, "About", 0, this);
+       QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
          connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
 
        // init tool bar
@@ -1379,7 +1378,7 @@ ConfigMainWindow::ConfigMainWindow(void)
 
        // create config menu
        QPopupMenu* config = new QPopupMenu(this);
-       menu->insertItem("&File", config);
+       menu->insertItem(_("&File"), config);
        loadAction->addTo(config);
        saveAction->addTo(config);
        saveAsAction->addTo(config);
@@ -1388,12 +1387,12 @@ ConfigMainWindow::ConfigMainWindow(void)
 
        // create edit menu
        QPopupMenu* editMenu = new QPopupMenu(this);
-       menu->insertItem("&Edit", editMenu);
+       menu->insertItem(_("&Edit"), editMenu);
        searchAction->addTo(editMenu);
 
        // create options menu
        QPopupMenu* optionMenu = new QPopupMenu(this);
-       menu->insertItem("&Option", optionMenu);
+       menu->insertItem(_("&Option"), optionMenu);
        showNameAction->addTo(optionMenu);
        showRangeAction->addTo(optionMenu);
        showDataAction->addTo(optionMenu);
@@ -1404,7 +1403,7 @@ ConfigMainWindow::ConfigMainWindow(void)
        // create help menu
        QPopupMenu* helpMenu = new QPopupMenu(this);
        menu->insertSeparator();
-       menu->insertItem("&Help", helpMenu);
+       menu->insertItem(_("&Help"), helpMenu);
        showIntroAction->addTo(helpMenu);
        showAboutAction->addTo(helpMenu);
 
@@ -1452,14 +1451,14 @@ void ConfigMainWindow::loadConfig(void)
        if (s.isNull())
                return;
        if (conf_read(QFile::encodeName(s)))
-               QMessageBox::information(this, "qconf", "Unable to load configuration!");
+               QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
        ConfigView::updateListAll();
 }
 
 void ConfigMainWindow::saveConfig(void)
 {
        if (conf_write(NULL))
-               QMessageBox::information(this, "qconf", "Unable to save configuration!");
+               QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
 }
 
 void ConfigMainWindow::saveConfigAs(void)
@@ -1468,7 +1467,7 @@ void ConfigMainWindow::saveConfigAs(void)
        if (s.isNull())
                return;
        if (conf_write(QFile::encodeName(s)))
-               QMessageBox::information(this, "qconf", "Unable to save configuration!");
+               QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
 }
 
 void ConfigMainWindow::searchConfig(void)
@@ -1612,11 +1611,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
                e->accept();
                return;
        }
-       QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
+       QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
                        QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
-       mb.setButtonText(QMessageBox::Yes, "&Save Changes");
-       mb.setButtonText(QMessageBox::No, "&Discard Changes");
-       mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
+       mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
+       mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
+       mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
        switch (mb.exec()) {
        case QMessageBox::Yes:
                conf_write(NULL);
@@ -1631,7 +1630,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
 
 void ConfigMainWindow::showIntro(void)
 {
-       static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
+       static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
                "For each option, a blank box indicates the feature is disabled, a check\n"
                "indicates it is enabled, and a dot indicates that it is to be compiled\n"
                "as a module.  Clicking on the box will cycle through the three states.\n\n"
@@ -1641,15 +1640,15 @@ void ConfigMainWindow::showIntro(void)
                "options must be enabled to support the option you are interested in, you can\n"
                "still view the help of a grayed-out option.\n\n"
                "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
-               "which you can then match by examining other options.\n\n";
+               "which you can then match by examining other options.\n\n");
 
        QMessageBox::information(this, "qconf", str);
 }
 
 void ConfigMainWindow::showAbout(void)
 {
-       static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
-               "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
+       static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
+               "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
 
        QMessageBox::information(this, "qconf", str);
 }
@@ -1707,7 +1706,7 @@ static const char *progname;
 
 static void usage(void)
 {
-       printf("%s <config>\n", progname);
+       printf(_("%s <config>\n"), progname);
        exit(0);
 }
 
index c35dcc5d61894ba51d7e265484a5dc9296ae57a4..3929e5b35e79db7dc0d03083aabaa988e10e1992 100644 (file)
@@ -34,6 +34,8 @@ struct symbol *sym_defconfig_list;
 struct symbol *modules_sym;
 tristate modules_val;
 
+struct expr *sym_env_list;
+
 void sym_add_default(struct symbol *sym, const char *def)
 {
        struct property *prop = prop_alloc(P_DEFAULT, sym);
@@ -45,7 +47,6 @@ void sym_init(void)
 {
        struct symbol *sym;
        struct utsname uts;
-       char *p;
        static bool inited = false;
 
        if (inited)
@@ -54,20 +55,6 @@ void sym_init(void)
 
        uname(&uts);
 
-       sym = sym_lookup("ARCH", 0);
-       sym->type = S_STRING;
-       sym->flags |= SYMBOL_AUTO;
-       p = getenv("ARCH");
-       if (p)
-               sym_add_default(sym, p);
-
-       sym = sym_lookup("KERNELVERSION", 0);
-       sym->type = S_STRING;
-       sym->flags |= SYMBOL_AUTO;
-       p = getenv("KERNELVERSION");
-       if (p)
-               sym_add_default(sym, p);
-
        sym = sym_lookup("UNAME_RELEASE", 0);
        sym->type = S_STRING;
        sym->flags |= SYMBOL_AUTO;
@@ -117,6 +104,15 @@ struct property *sym_get_choice_prop(struct symbol *sym)
        return NULL;
 }
 
+struct property *sym_get_env_prop(struct symbol *sym)
+{
+       struct property *prop;
+
+       for_all_properties(sym, prop, P_ENV)
+               return prop;
+       return NULL;
+}
+
 struct property *sym_get_default_prop(struct symbol *sym)
 {
        struct property *prop;
@@ -199,7 +195,7 @@ static void sym_calc_visibility(struct symbol *sym)
        tri = no;
        for_all_prompts(sym, prop) {
                prop->visible.tri = expr_calc_value(prop->visible.expr);
-               tri = E_OR(tri, prop->visible.tri);
+               tri = EXPR_OR(tri, prop->visible.tri);
        }
        if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
                tri = yes;
@@ -247,8 +243,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
 
        /* just get the first visible value */
        prop = sym_get_choice_prop(sym);
-       for (e = prop->expr; e; e = e->left.expr) {
-               def_sym = e->right.sym;
+       expr_list_for_each_sym(prop->expr, e, def_sym) {
                sym_calc_visibility(def_sym);
                if (def_sym->visible != no)
                        return def_sym;
@@ -303,7 +298,7 @@ void sym_calc_value(struct symbol *sym)
                if (sym_is_choice_value(sym) && sym->visible == yes) {
                        prop = sym_get_choice_prop(sym);
                        newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
-               } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
+               } else if (EXPR_OR(sym->visible, sym->rev_dep.tri) != no) {
                        sym->flags |= SYMBOL_WRITE;
                        if (sym_has_value(sym))
                                newval.tri = sym->def[S_DEF_USER].tri;
@@ -312,7 +307,7 @@ void sym_calc_value(struct symbol *sym)
                                if (prop)
                                        newval.tri = expr_calc_value(prop->expr);
                        }
-                       newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
+                       newval.tri = EXPR_OR(EXPR_AND(newval.tri, sym->visible), sym->rev_dep.tri);
                } else if (!sym_is_choice(sym)) {
                        prop = sym_get_default_prop(sym);
                        if (prop) {
@@ -347,6 +342,9 @@ void sym_calc_value(struct symbol *sym)
                ;
        }
 
+       if (sym->flags & SYMBOL_AUTO)
+               sym->flags &= ~SYMBOL_WRITE;
+
        sym->curr = newval;
        if (sym_is_choice(sym) && newval.tri == yes)
                sym->curr.val = sym_calc_choice(sym);
@@ -361,12 +359,14 @@ void sym_calc_value(struct symbol *sym)
        }
 
        if (sym_is_choice(sym)) {
+               struct symbol *choice_sym;
                int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
+
                prop = sym_get_choice_prop(sym);
-               for (e = prop->expr; e; e = e->left.expr) {
-                       e->right.sym->flags |= flags;
+               expr_list_for_each_sym(prop->expr, e, choice_sym) {
+                       choice_sym->flags |= flags;
                        if (flags & SYMBOL_CHANGED)
-                               sym_set_changed(e->right.sym);
+                               sym_set_changed(choice_sym);
                }
        }
 }
@@ -849,7 +849,7 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym)
 struct symbol *prop_get_symbol(struct property *prop)
 {
        if (prop->expr && (prop->expr->type == E_SYMBOL ||
-                          prop->expr->type == E_CHOICE))
+                          prop->expr->type == E_LIST))
                return prop->expr->left.sym;
        return NULL;
 }
@@ -859,6 +859,8 @@ const char *prop_get_type_name(enum prop_type type)
        switch (type) {
        case P_PROMPT:
                return "prompt";
+       case P_ENV:
+               return "env";
        case P_COMMENT:
                return "comment";
        case P_MENU:
@@ -876,3 +878,32 @@ const char *prop_get_type_name(enum prop_type type)
        }
        return "unknown";
 }
+
+void prop_add_env(const char *env)
+{
+       struct symbol *sym, *sym2;
+       struct property *prop;
+       char *p;
+
+       sym = current_entry->sym;
+       sym->flags |= SYMBOL_AUTO;
+       for_all_properties(sym, prop, P_ENV) {
+               sym2 = prop_get_symbol(prop);
+               if (strcmp(sym2->name, env))
+                       menu_warn(current_entry, "redefining environment symbol from %s",
+                                 sym2->name);
+               return;
+       }
+
+       prop = prop_alloc(P_ENV, sym);
+       prop->expr = expr_alloc_symbol(sym_lookup(env, 1));
+
+       sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
+       sym_env_list->right.sym = sym;
+
+       p = getenv(env);
+       if (p)
+               sym_add_default(sym, p);
+       else
+               menu_warn(current_entry, "environment variable %s undefined", env);
+}
index e1cad924c0a41ab6fa1e8f917c0c01198419b549..f8e73c039dc880984f96aa8cadd4e43edaa6baba 100644 (file)
@@ -29,6 +29,8 @@ struct file *file_lookup(const char *name)
 /* write a dependency file as used by kbuild to track dependencies */
 int file_write_dep(const char *name)
 {
+       struct symbol *sym, *env_sym;
+       struct expr *e;
        struct file *file;
        FILE *out;
 
@@ -45,8 +47,25 @@ int file_write_dep(const char *name)
                        fprintf(out, "\t%s\n", file->name);
        }
        fprintf(out, "\ninclude/config/auto.conf: \\\n"
-                    "\t$(deps_config)\n\n"
-                    "$(deps_config): ;\n");
+                    "\t$(deps_config)\n\n");
+
+       expr_list_for_each_sym(sym_env_list, e, sym) {
+               struct property *prop;
+               const char *value;
+
+               prop = sym_get_env_prop(sym);
+               env_sym = prop_get_symbol(prop);
+               if (!env_sym)
+                       continue;
+               value = getenv(env_sym->name);
+               if (!value)
+                       value = "";
+               fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
+               fprintf(out, "include/config/auto.conf: FORCE\n");
+               fprintf(out, "endif\n");
+       }
+
+       fprintf(out, "\n$(deps_config): ;\n");
        fclose(out);
        rename("..config.tmp", name);
        return 0;
index 93538e567bda8e31943b857a3b50e567fa5c691a..25ef5d01c0afa961a4b5c57c0154d11b83f69e7f 100644 (file)
@@ -35,10 +35,10 @@ int,                T_TYPE,         TF_COMMAND, S_INT
 hex,           T_TYPE,         TF_COMMAND, S_HEX
 string,                T_TYPE,         TF_COMMAND, S_STRING
 select,                T_SELECT,       TF_COMMAND
-enable,                T_SELECT,       TF_COMMAND
 range,         T_RANGE,        TF_COMMAND
 option,                T_OPTION,       TF_COMMAND
 on,            T_ON,           TF_PARAM
 modules,       T_OPT_MODULES,  TF_OPTION
 defconfig_list,        T_OPT_DEFCONFIG_LIST,TF_OPTION
+env,           T_OPT_ENV,      TF_OPTION
 %%
index ab28b18153a7a6bb4fcb7d7b0c24b919610c94d3..5c73d51339d81b30e88cdd1010d65f273f2e62e1 100644 (file)
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.2 */
+/* ANSI-C code produced by gperf version 3.0.3 */
 /* Command-line: gperf  */
 /* Computed positions: -k'1,3' */
 
@@ -53,9 +53,9 @@ kconf_id_hash (register const char *str, register unsigned int len)
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 18, 11,  5,
+      49, 49, 49, 49, 49, 49, 49, 49, 11,  5,
        0,  0,  5, 49,  5, 20, 49, 49,  5, 20,
-       5,  0, 30, 49,  0, 15,  0, 10, 49, 49,
+       5,  0, 30, 49,  0, 15,  0, 10,  0, 49,
       25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
       49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
@@ -89,6 +89,7 @@ kconf_id_hash (register const char *str, register unsigned int len)
 struct kconf_id_strings_t
   {
     char kconf_id_strings_str2[sizeof("on")];
+    char kconf_id_strings_str3[sizeof("env")];
     char kconf_id_strings_str5[sizeof("endif")];
     char kconf_id_strings_str6[sizeof("option")];
     char kconf_id_strings_str7[sizeof("endmenu")];
@@ -107,7 +108,6 @@ struct kconf_id_strings_t
     char kconf_id_strings_str21[sizeof("string")];
     char kconf_id_strings_str22[sizeof("if")];
     char kconf_id_strings_str23[sizeof("int")];
-    char kconf_id_strings_str24[sizeof("enable")];
     char kconf_id_strings_str26[sizeof("select")];
     char kconf_id_strings_str27[sizeof("modules")];
     char kconf_id_strings_str28[sizeof("tristate")];
@@ -123,6 +123,7 @@ struct kconf_id_strings_t
 static struct kconf_id_strings_t kconf_id_strings_contents =
   {
     "on",
+    "env",
     "endif",
     "option",
     "endmenu",
@@ -141,7 +142,6 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
     "string",
     "if",
     "int",
-    "enable",
     "select",
     "modules",
     "tristate",
@@ -157,6 +157,9 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
 #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
 #ifdef __GNUC__
 __inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
 #endif
 struct kconf_id *
 kconf_id_lookup (register const char *str, register unsigned int len)
@@ -174,7 +177,8 @@ kconf_id_lookup (register const char *str, register unsigned int len)
     {
       {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,            T_ON,           TF_PARAM},
-      {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3,            T_OPT_ENV,      TF_OPTION},
+      {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5,            T_ENDIF,        TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6,            T_OPTION,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7,    T_ENDMENU,      TF_COMMAND},
@@ -194,8 +198,7 @@ kconf_id_lookup (register const char *str, register unsigned int len)
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,           T_TYPE,         TF_COMMAND, S_STRING},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,           T_IF,           TF_COMMAND|TF_PARAM},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,           T_TYPE,         TF_COMMAND, S_INT},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24,           T_SELECT,       TF_COMMAND},
-      {-1},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,           T_SELECT,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,   T_OPT_MODULES,  TF_OPTION},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,   T_TYPE,         TF_COMMAND, S_TRISTATE},
index 187d38ccadd57f489b89cbbf16798cdf5f08ef49..4cea5c85cd0a9297f029d58cf97c4771825f4641 100644 (file)
@@ -217,6 +217,11 @@ n  [A-Za-z0-9_]
                append_string("\n", 1);
        }
        [^ \t\n].* {
+               while (yyleng) {
+                       if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
+                               break;
+                       yyleng--;
+               }
                append_string(yytext, yyleng);
                if (!first_ts)
                        first_ts = last_ts;
index 1d1401807e95809a43e2b72c84ee17d4be2854e8..ec54f12f57b04c10b6f24f7aa561afccb3fba0b7 100755 (executable)
@@ -46,21 +46,24 @@ use strict;
 # Note: This only supports 'c'.
 
 # usage:
-# kernel-doc [ -docbook | -html | -text | -man ]
+# kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ]
 #           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
 # or
 #           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
 #
 #  Set output format using one of -docbook -html -text or -man.  Default is man.
 #
+#  -no-doc-sections
+#      Do not output DOC: sections
+#
 #  -function funcname
-#      If set, then only generate documentation for the given function(s).  All
-#      other functions are ignored.
+#      If set, then only generate documentation for the given function(s) or
+#      DOC: section titles.  All other functions and DOC: sections are ignored.
 #
 #  -nofunction funcname
-#      If set, then only generate documentation for the other function(s).
-#      Cannot be used together with -function
-#      (yes, that's a bug -- perl hackers can fix it 8))
+#      If set, then only generate documentation for the other function(s)/DOC:
+#      sections. Cannot be used together with -function (yes, that's a bug --
+#      perl hackers can fix it 8))
 #
 #  c files - list of 'c' files to process
 #
@@ -182,10 +185,10 @@ my $blankline_html = $local_lt . "p" . $local_gt; # was "<p>"
 my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
                        $type_constant, "<constant>\$1</constant>",
                        $type_func, "<function>\$1</function>",
-                       $type_struct, "<structname>\$1</structname>",
+                       $type_struct_xml, "<structname>\$1</structname>",
                        $type_env, "<envar>\$1</envar>",
                        $type_param, "<parameter>\$1</parameter>" );
-my $blankline_xml = "</para><para>\n";
+my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n";
 
 # gnome, docbook format
 my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
@@ -211,7 +214,7 @@ my $blankline_text = "";
 
 
 sub usage {
-    print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
+    print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ] [ -no-doc-sections ]\n";
     print "         [ -function funcname [ -function funcname ...] ]\n";
     print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
     print "         c source file(s) > outputfile\n";
@@ -225,6 +228,7 @@ if ($#ARGV==-1) {
 
 my $verbose = 0;
 my $output_mode = "man";
+my $no_doc_sections = 0;
 my %highlights = %highlights_man;
 my $blankline = $blankline_man;
 my $modulename = "Kernel API";
@@ -329,12 +333,14 @@ while ($ARGV[0] =~ m/^-(.*)/) {
        usage();
     } elsif ($cmd eq '-filelist') {
            $filelist = shift @ARGV;
+    } elsif ($cmd eq '-no-doc-sections') {
+           $no_doc_sections = 1;
     }
 }
 
 # get kernel version from env
 sub get_kernel_version() {
-    my $version;
+    my $version = 'unknown kernel version';
 
     if (defined($ENV{'KERNELVERSION'})) {
        $version = $ENV{'KERNELVERSION'};
@@ -373,6 +379,29 @@ sub dump_section {
     }
 }
 
+##
+# dump DOC: section after checking that it should go out
+#
+sub dump_doc_section {
+    my $name = shift;
+    my $contents = join "\n", @_;
+
+    if ($no_doc_sections) {
+        return;
+    }
+
+    if (($function_only == 0) ||
+       ( $function_only == 1 && defined($function_table{$name})) ||
+       ( $function_only == 2 && !defined($function_table{$name})))
+    {
+       dump_section $name, $contents;
+       output_blockhead({'sectionlist' => \@sectionlist,
+                         'sections' => \%sections,
+                         'module' => $modulename,
+                         'content-only' => ($function_only != 0), });
+    }
+}
+
 ##
 # output function
 #
@@ -394,7 +423,7 @@ sub output_highlight {
 #      confess "output_highlight got called with no args?\n";
 #   }
 
-    if ($output_mode eq "html") {
+    if ($output_mode eq "html" || $output_mode eq "xml") {
        $contents = local_unescape($contents);
        # convert data read & converted thru xml_escape() into &xyz; format:
        $contents =~ s/\\\\\\/&/g;
@@ -564,8 +593,8 @@ sub output_function_html(%) {
     print "<hr>\n";
 }
 
-# output intro in html
-sub output_intro_html(%) {
+# output DOC: block header in html
+sub output_blockhead_html(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
@@ -871,7 +900,7 @@ sub output_typedef_xml(%) {
 }
 
 # output in XML DocBook
-sub output_intro_xml(%) {
+sub output_blockhead_xml(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
@@ -882,15 +911,23 @@ sub output_intro_xml(%) {
     # print out each section
     $lineprefix="   ";
     foreach $section (@{$args{'sectionlist'}}) {
-       print "<refsect1>\n <title>$section</title>\n <para>\n";
+       if (!$args{'content-only'}) {
+               print "<refsect1>\n <title>$section</title>\n";
+       }
        if ($section =~ m/EXAMPLE/i) {
            print "<example><para>\n";
+       } else {
+           print "<para>\n";
        }
        output_highlight($args{'sections'}{$section});
        if ($section =~ m/EXAMPLE/i) {
            print "</para></example>\n";
+       } else {
+           print "</para>";
+       }
+       if (!$args{'content-only'}) {
+               print "\n</refsect1>\n";
        }
-       print " </para>\n</refsect1>\n";
     }
 
     print "\n\n";
@@ -1137,7 +1174,7 @@ sub output_typedef_man(%) {
     }
 }
 
-sub output_intro_man(%) {
+sub output_blockhead_man(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
@@ -1294,7 +1331,7 @@ sub output_struct_text(%) {
     output_section_text(@_);
 }
 
-sub output_intro_text(%) {
+sub output_blockhead_text(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
 
@@ -1325,9 +1362,9 @@ sub output_declaration {
 
 ##
 # generic output function - calls the right one based on current output mode.
-sub output_intro {
+sub output_blockhead {
     no strict 'refs';
-    my $func = "output_intro_".$output_mode;
+    my $func = "output_blockhead_".$output_mode;
     &$func(@_);
     $section_counter++;
 }
@@ -1926,9 +1963,7 @@ sub process_file($) {
        } elsif ($state == 4) {
                # Documentation block
                if (/$doc_block/) {
-                       dump_section($section, xml_escape($contents));
-                       output_intro({'sectionlist' => \@sectionlist,
-                                     'sections' => \%sections });
+                       dump_doc_section($section, xml_escape($contents));
                        $contents = "";
                        $function = "";
                        %constants = ();
@@ -1946,9 +1981,7 @@ sub process_file($) {
                }
                elsif (/$doc_end/)
                {
-                       dump_section($section, xml_escape($contents));
-                       output_intro({'sectionlist' => \@sectionlist,
-                                     'sections' => \%sections });
+                       dump_doc_section($section, xml_escape($contents));
                        $contents = "";
                        $function = "";
                        %constants = ();
index e0f54b9d8feca95bf693ec7cc9ad294bd70ab1df..e65d8b33faa4cae649044fb48d8fc87fa012d574 100644 (file)
@@ -25,8 +25,11 @@ cat << EOF > $2/Makefile
 VERSION = $3
 PATCHLEVEL = $4
 
-KERNELSRC    := $1
-KERNELOUTPUT := $2
+lastword = \$(word \$(words \$(1)),\$(1))
+makedir := \$(dir \$(call lastword,\$(MAKEFILE_LIST)))
+
+MAKEARGS := -C $1
+MAKEARGS += O=\$(if \$(patsubst /%,,\$(makedir)),\$(CURDIR)/)\$(patsubst %/,%,\$(makedir))
 
 MAKEFLAGS += --no-print-directory
 
@@ -35,10 +38,11 @@ MAKEFLAGS += --no-print-directory
 all    := \$(filter-out all Makefile,\$(MAKECMDGOALS))
 
 all:
-       \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$(all)
+       \$(MAKE) \$(MAKEARGS) \$(all)
 
 Makefile:;
 
 \$(all) %/: all
        @:
+
 EOF
index 93ac52adb4980b3d23a0b40acd6800e48f75b349..f8efc93eb7004c9ee0004c979acd617ca7d2e8f8 100644 (file)
@@ -2,7 +2,7 @@
  *
  * Copyright 2003       Kai Germaschewski
  * Copyright 2002-2004  Rusty Russell, IBM Corporation
- * Copyright 2006       Sam Ravnborg
+ * Copyright 2006-2008  Sam Ravnborg
  * Based in part on module-init-tools/depmod.c,file2alias
  *
  * This software may be used and distributed according to the terms
@@ -28,12 +28,17 @@ static int vmlinux_section_warnings = 1;
 /* Only warn about unresolved symbols */
 static int warn_unresolved = 0;
 /* How a symbol is exported */
+static int sec_mismatch_count = 0;
+static int sec_mismatch_verbose = 1;
+
 enum export {
        export_plain,      export_unused,     export_gpl,
        export_unused_gpl, export_gpl_future, export_unknown
 };
 
-void fatal(const char *fmt, ...)
+#define PRINTF __attribute__ ((format (printf, 1, 2)))
+
+PRINTF void fatal(const char *fmt, ...)
 {
        va_list arglist;
 
@@ -46,7 +51,7 @@ void fatal(const char *fmt, ...)
        exit(1);
 }
 
-void warn(const char *fmt, ...)
+PRINTF void warn(const char *fmt, ...)
 {
        va_list arglist;
 
@@ -57,7 +62,7 @@ void warn(const char *fmt, ...)
        va_end(arglist);
 }
 
-void merror(const char *fmt, ...)
+PRINTF void merror(const char *fmt, ...)
 {
        va_list arglist;
 
@@ -72,7 +77,8 @@ static int is_vmlinux(const char *modname)
 {
        const char *myname;
 
-       if ((myname = strrchr(modname, '/')))
+       myname = strrchr(modname, '/');
+       if (myname)
                myname++;
        else
                myname = modname;
@@ -83,14 +89,13 @@ static int is_vmlinux(const char *modname)
 
 void *do_nofail(void *ptr, const char *expr)
 {
-       if (!ptr) {
+       if (!ptr)
                fatal("modpost: Memory allocation failure: %s.\n", expr);
-       }
+
        return ptr;
 }
 
 /* A list of all modules we processed */
-
 static struct module *modules;
 
 static struct module *find_module(char *modname)
@@ -113,7 +118,8 @@ static struct module *new_module(char *modname)
        p = NOFAIL(strdup(modname));
 
        /* strip trailing .o */
-       if ((s = strrchr(p, '.')) != NULL)
+       s = strrchr(p, '.');
+       if (s != NULL)
                if (strcmp(s, ".o") == 0)
                        *s = '\0';
 
@@ -154,7 +160,7 @@ static inline unsigned int tdb_hash(const char *name)
        unsigned   i;   /* Used to cycle through random values. */
 
        /* Set the initial value from the key size. */
-       for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
+       for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
                value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
 
        return (1103515243 * value + 12345);
@@ -198,7 +204,7 @@ static struct symbol *find_symbol(const char *name)
        if (name[0] == '.')
                name++;
 
-       for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
+       for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
                if (strcmp(s->name, name) == 0)
                        return s;
        }
@@ -223,9 +229,10 @@ static const char *export_str(enum export ex)
        return export_list[ex].str;
 }
 
-static enum export export_no(const char * s)
+static enum export export_no(const char *s)
 {
        int i;
+
        if (!s)
                return export_unknown;
        for (i = 0; export_list[i].export != export_unknown; i++) {
@@ -315,7 +322,7 @@ void *grab_file(const char *filename, unsigned long *size)
   * spaces in the beginning of the line is trimmed away.
   * Return a pointer to a static buffer.
   **/
-charget_next_line(unsigned long *pos, void *file, unsigned long size)
+char *get_next_line(unsigned long *pos, void *file, unsigned long size)
 {
        static char line[4096];
        int skip = 1;
@@ -323,8 +330,7 @@ char* get_next_line(unsigned long *pos, void *file, unsigned long size)
        signed char *p = (signed char *)file + *pos;
        char *s = line;
 
-       for (; *pos < size ; (*pos)++)
-       {
+       for (; *pos < size ; (*pos)++) {
                if (skip && isspace(*p)) {
                        p++;
                        continue;
@@ -386,7 +392,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
 
        /* Check if file offset is correct */
        if (hdr->e_shoff > info->size) {
-               fatal("section header offset=%u in file '%s' is bigger then filesize=%lu\n", hdr->e_shoff, filename, info->size);
+               fatal("section header offset=%lu in file '%s' is bigger than "
+                     "filesize=%lu\n", (unsigned long)hdr->e_shoff,
+                     filename, info->size);
                return 0;
        }
 
@@ -407,7 +415,10 @@ static int parse_elf(struct elf_info *info, const char *filename)
                const char *secname;
 
                if (sechdrs[i].sh_offset > info->size) {
-                       fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr));
+                       fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
+                             "sizeof(*hrd)=%zu\n", filename,
+                             (unsigned long)sechdrs[i].sh_offset,
+                             sizeof(*hdr));
                        return 0;
                }
                secname = secstrings + sechdrs[i].sh_name;
@@ -434,9 +445,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
                info->strtab       = (void *)hdr +
                                     sechdrs[sechdrs[i].sh_link].sh_offset;
        }
-       if (!info->symtab_start) {
+       if (!info->symtab_start)
                fatal("%s has no symtab?\n", filename);
-       }
+
        /* Fix endianness in symbols */
        for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
                sym->st_shndx = TO_NATIVE(sym->st_shndx);
@@ -505,11 +516,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
 #endif
 
                if (memcmp(symname, MODULE_SYMBOL_PREFIX,
-                          strlen(MODULE_SYMBOL_PREFIX)) == 0)
-                       mod->unres = alloc_symbol(symname +
-                                                 strlen(MODULE_SYMBOL_PREFIX),
-                                                 ELF_ST_BIND(sym->st_info) == STB_WEAK,
-                                                 mod->unres);
+                          strlen(MODULE_SYMBOL_PREFIX)) == 0) {
+                       mod->unres =
+                         alloc_symbol(symname +
+                                      strlen(MODULE_SYMBOL_PREFIX),
+                                      ELF_ST_BIND(sym->st_info) == STB_WEAK,
+                                      mod->unres);
+               }
                break;
        default:
                /* All exported symbols */
@@ -578,69 +591,303 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
  **/
 static int strrcmp(const char *s, const char *sub)
 {
-        int slen, sublen;
+       int slen, sublen;
 
        if (!s || !sub)
                return 1;
 
        slen = strlen(s);
-        sublen = strlen(sub);
+       sublen = strlen(sub);
 
        if ((slen == 0) || (sublen == 0))
                return 1;
 
-        if (sublen > slen)
-                return 1;
+       if (sublen > slen)
+               return 1;
 
-        return memcmp(s + slen - sublen, sub, sublen);
+       return memcmp(s + slen - sublen, sub, sublen);
 }
 
-/*
- * 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 const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
+{
+       if (sym)
+               return elf->strtab + sym->st_name;
+       else
+               return "";
+}
+
+static const char *sec_name(struct elf_info *elf, int shndx)
+{
+       Elf_Shdr *sechdrs = elf->sechdrs;
+       return (void *)elf->hdr +
+               elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
+               sechdrs[shndx].sh_name;
+}
+
+static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
+{
+       return (void *)elf->hdr +
+               elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
+               sechdr->sh_name;
+}
+
+/* if sym is empty or point to a string
+ * like ".[0-9]+" then return 1.
+ * This is the optional prefix added by ld to some sections
  */
-static int init_section(const char *name)
+static int number_prefix(const char *sym)
 {
-       if (strcmp(name, ".init") == 0)
-               return 1;
-       if (strncmp(name, ".init.", strlen(".init.")) == 0)
+       if (*sym++ == '\0')
                return 1;
+       if (*sym != '.')
+               return 0;
+       do {
+               char c = *sym++;
+               if (c < '0' || c > '9')
+                       return 0;
+       } while (*sym);
+       return 1;
+}
+
+/* The pattern is an array of simple patterns.
+ * "foo" will match an exact string equal to "foo"
+ * "*foo" will match a string that ends with "foo"
+ * "foo*" will match a string that begins with "foo"
+ * "foo$" will match a string equal to "foo" or "foo.1"
+ *   where the '1' can be any number including several digits.
+ *   The $ syntax is for sections where ld append a dot number
+ *   to make section name unique.
+ */
+int match(const char *sym, const char * const pat[])
+{
+       const char *p;
+       while (*pat) {
+               p = *pat++;
+               const char *endp = p + strlen(p) - 1;
+
+               /* "*foo" */
+               if (*p == '*') {
+                       if (strrcmp(sym, p + 1) == 0)
+                               return 1;
+               }
+               /* "foo*" */
+               else if (*endp == '*') {
+                       if (strncmp(sym, p, strlen(p) - 1) == 0)
+                               return 1;
+               }
+               /* "foo$" */
+               else if (*endp == '$') {
+                       if (strncmp(sym, p, strlen(p) - 1) == 0) {
+                               if (number_prefix(sym + strlen(p) - 1))
+                                       return 1;
+                       }
+               }
+               /* no wildcards */
+               else {
+                       if (strcmp(p, sym) == 0)
+                               return 1;
+               }
+       }
+       /* no match */
        return 0;
 }
 
+/* sections that we do not want to do full section mismatch check on */
+static const char *section_white_list[] =
+       { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL };
+
 /*
- * 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)
+ * Is this section one we do not want to check?
+ * This is often debug sections.
+ * If we are going to check this section then
+ * test if section name ends with a dot and a number.
+ * This is used to find sections where the linker have
+ * appended a dot-number to make the name unique.
+ * The cause of this is often a section specified in assembler
+ * without "ax" / "aw" and the same section used in .c
+ * code where gcc add these.
+ */
+static int check_section(const char *modname, const char *sec)
 {
-       if (strcmp(name, ".exit.text") == 0)
-               return 1;
-       if (strcmp(name, ".exit.data") == 0)
+       const char *e = sec + strlen(sec) - 1;
+       if (match(sec, section_white_list))
                return 1;
-       return 0;
 
+       if (*e && isdigit(*e)) {
+               /* consume all digits */
+               while (*e && e != sec && isdigit(*e))
+                       e--;
+               if (*e == '.') {
+                       warn("%s (%s): unexpected section name.\n"
+                            "The (.[number]+) following section name are "
+                            "ld generated and not expected.\n"
+                            "Did you forget to use \"ax\"/\"aw\" "
+                            "in a .S file?\n"
+                            "Note that for example <linux/init.h> contains\n"
+                            "section definitions for use in .S files.\n\n",
+                            modname, sec);
+               }
+       }
+       return 0;
 }
 
-/*
- * Data sections are named like this:
- * .data | .data.rel | .data.rel.*
- * Return 1 if the specified section is a data section
+
+
+#define ALL_INIT_DATA_SECTIONS \
+       ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
+#define ALL_EXIT_DATA_SECTIONS \
+       ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$"
+
+#define ALL_INIT_TEXT_SECTIONS \
+       ".init.text$", ".devinit.text$", ".cpuinit.text$", ".meminit.text$"
+#define ALL_EXIT_TEXT_SECTIONS \
+       ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
+
+#define ALL_INIT_SECTIONS ALL_INIT_DATA_SECTIONS, ALL_INIT_TEXT_SECTIONS
+#define ALL_EXIT_SECTIONS ALL_EXIT_DATA_SECTIONS, ALL_EXIT_TEXT_SECTIONS
+
+#define DATA_SECTIONS ".data$", ".data.rel$"
+#define TEXT_SECTIONS ".text$"
+
+#define INIT_SECTIONS      ".init.data$", ".init.text$"
+#define DEV_INIT_SECTIONS  ".devinit.data$", ".devinit.text$"
+#define CPU_INIT_SECTIONS  ".cpuinit.data$", ".cpuinit.text$"
+#define MEM_INIT_SECTIONS  ".meminit.data$", ".meminit.text$"
+
+#define EXIT_SECTIONS      ".exit.data$", ".exit.text$"
+#define DEV_EXIT_SECTIONS  ".devexit.data$", ".devexit.text$"
+#define CPU_EXIT_SECTIONS  ".cpuexit.data$", ".cpuexit.text$"
+#define MEM_EXIT_SECTIONS  ".memexit.data$", ".memexit.text$"
+
+/* init data sections */
+static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL };
+
+/* all init sections */
+static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
+
+/* All init and exit sections (code + data) */
+static const char *init_exit_sections[] =
+       {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
+
+/* data section */
+static const char *data_sections[] = { DATA_SECTIONS, NULL };
+
+/* sections that may refer to an init/exit section with no warning */
+static const char *initref_sections[] =
+{
+       ".text.init.refok*",
+       ".exit.text.refok*",
+       ".data.init.refok*",
+       NULL
+};
+
+
+/* symbols in .data that may refer to init/exit sections */
+static const char *symbol_white_list[] =
+{
+       "*driver",
+       "*_template", /* scsi uses *_template a lot */
+       "*_timer",    /* arm uses ops structures named _timer a lot */
+       "*_sht",      /* scsi also used *_sht to some extent */
+       "*_ops",
+       "*_probe",
+       "*_probe_one",
+       "*_console",
+       NULL
+};
+
+static const char *head_sections[] = { ".head.text*", NULL };
+static const char *linker_symbols[] =
+       { "__init_begin", "_sinittext", "_einittext", NULL };
+
+enum mismatch {
+       NO_MISMATCH,
+       TEXT_TO_INIT,
+       DATA_TO_INIT,
+       TEXT_TO_EXIT,
+       DATA_TO_EXIT,
+       XXXINIT_TO_INIT,
+       XXXEXIT_TO_EXIT,
+       INIT_TO_EXIT,
+       EXIT_TO_INIT,
+       EXPORT_TO_INIT_EXIT,
+};
+
+struct sectioncheck {
+       const char *fromsec[20];
+       const char *tosec[20];
+       enum mismatch mismatch;
+};
+
+const struct sectioncheck sectioncheck[] = {
+/* Do not reference init/exit code/data from
+ * normal code and data
  */
-static int data_section(const char *name)
 {
-       if ((strcmp(name, ".data") == 0) ||
-           (strcmp(name, ".data.rel") == 0) ||
-           (strncmp(name, ".data.rel.", strlen(".data.rel.")) == 0))
-               return 1;
-       else
-               return 0;
+       .fromsec = { TEXT_SECTIONS, NULL },
+       .tosec   = { ALL_INIT_SECTIONS, NULL },
+       .mismatch = TEXT_TO_INIT,
+},
+{
+       .fromsec = { DATA_SECTIONS, NULL },
+       .tosec   = { ALL_INIT_SECTIONS, NULL },
+       .mismatch = DATA_TO_INIT,
+},
+{
+       .fromsec = { TEXT_SECTIONS, NULL },
+       .tosec   = { ALL_EXIT_SECTIONS, NULL },
+       .mismatch = TEXT_TO_EXIT,
+},
+{
+       .fromsec = { DATA_SECTIONS, NULL },
+       .tosec   = { ALL_EXIT_SECTIONS, NULL },
+       .mismatch = DATA_TO_EXIT,
+},
+/* Do not reference init code/data from devinit/cpuinit/meminit code/data */
+{
+       .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL },
+       .tosec   = { INIT_SECTIONS, NULL },
+       .mismatch = XXXINIT_TO_INIT,
+},
+/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
+{
+       .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL },
+       .tosec   = { EXIT_SECTIONS, NULL },
+       .mismatch = XXXEXIT_TO_EXIT,
+},
+/* Do not use exit code/data from init code */
+{
+       .fromsec = { ALL_INIT_SECTIONS, NULL },
+       .tosec   = { ALL_EXIT_SECTIONS, NULL },
+       .mismatch = INIT_TO_EXIT,
+},
+/* Do not use init code/data from exit code */
+{
+       .fromsec = { ALL_EXIT_SECTIONS, NULL },
+       .tosec   = { ALL_INIT_SECTIONS, NULL },
+       .mismatch = EXIT_TO_INIT,
+},
+/* Do not export init/exit functions or data */
+{
+       .fromsec = { "__ksymtab*", NULL },
+       .tosec   = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL },
+       .mismatch = EXPORT_TO_INIT_EXIT
+}
+};
+
+static int section_mismatch(const char *fromsec, const char *tosec)
+{
+       int i;
+       int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
+       const struct sectioncheck *check = &sectioncheck[0];
+
+       for (i = 0; i < elems; i++) {
+               if (match(fromsec, check->fromsec) &&
+                   match(tosec, check->tosec))
+                       return check->mismatch;
+               check++;
+       }
+       return NO_MISMATCH;
 }
 
 /**
@@ -669,7 +916,8 @@ static int data_section(const char *name)
  *   the pattern is identified by:
  *   tosec   = init or exit section
  *   fromsec = data section
- *   atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer
+ *   atsym = *driver, *_template, *_sht, *_ops, *_probe,
+ *           *probe_one, *_console, *_timer
  *
  * Pattern 3:
  *   Whitelist all refereces from .text.head to .init.data
@@ -684,77 +932,36 @@ static int data_section(const char *name)
  *   This pattern is identified by
  *   refsymname = __init_begin, _sinittext, _einittext
  *
- * Pattern 5:
- *   Xtensa uses literal sections for constants that are accessed PC-relative.
- *   Literal sections may safely reference their text sections.
- *   (Note that the name for the literal section omits any trailing '.text')
- *   tosec = <section>[.text]
- *   fromsec = <section>.literal
  **/
-static int secref_whitelist(const char *modname, const char *tosec,
-                           const char *fromsec, const char *atsym,
-                           const char *refsymname)
+static int secref_whitelist(const char *fromsec, const char *fromsym,
+                           const char *tosec, const char *tosym)
 {
-       int len;
-       const char **s;
-       const char *pat2sym[] = {
-               "driver",
-               "_template", /* scsi uses *_template a lot */
-               "_timer",    /* arm uses ops structures named _timer a lot */
-               "_sht",      /* scsi also used *_sht to some extent */
-               "_ops",
-               "_probe",
-               "_probe_one",
-               "_console",
-               NULL
-       };
-
-       const char *pat3refsym[] = {
-               "__init_begin",
-               "_sinittext",
-               "_einittext",
-               NULL
-       };
-
        /* Check for pattern 0 */
-       if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) ||
-           (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) ||
-           (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0))
-               return 1;
+       if (match(fromsec, initref_sections))
+               return 0;
 
        /* Check for pattern 1 */
-       if ((strcmp(tosec, ".init.data") == 0) &&
-           (strncmp(fromsec, ".data", strlen(".data")) == 0) &&
-           (strncmp(atsym, "__param", strlen("__param")) == 0))
-               return 1;
+       if (match(tosec, init_data_sections) &&
+           match(fromsec, data_sections) &&
+           (strncmp(fromsym, "__param", strlen("__param")) == 0))
+               return 0;
 
        /* Check for pattern 2 */
-       if ((init_section(tosec) || exit_section(tosec)) && data_section(fromsec))
-               for (s = pat2sym; *s; s++)
-                       if (strrcmp(atsym, *s) == 0)
-                               return 1;
+       if (match(tosec, init_exit_sections) &&
+           match(fromsec, data_sections) &&
+           match(fromsym, symbol_white_list))
+               return 0;
 
        /* Check for pattern 3 */
-       if ((strcmp(fromsec, ".text.head") == 0) &&
-               ((strcmp(tosec, ".init.data") == 0) ||
-               (strcmp(tosec, ".init.text") == 0)))
-       return 1;
+       if (match(fromsec, head_sections) &&
+           match(tosec, init_sections))
+               return 0;
 
        /* Check for pattern 4 */
-       for (s = pat3refsym; *s; s++)
-               if (strcmp(refsymname, *s) == 0)
-                       return 1;
-
-       /* Check for pattern 5 */
-       if (strrcmp(tosec, ".text") == 0)
-               len = strlen(tosec) - strlen(".text");
-       else
-               len = strlen(tosec);
-       if ((strncmp(tosec, fromsec, len) == 0) && (strlen(fromsec) > len) &&
-           (strcmp(fromsec + len, ".literal") == 0))
-               return 1;
+       if (match(tosym, linker_symbols))
+               return 0;
 
-       return 0;
+       return 1;
 }
 
 /**
@@ -764,10 +971,13 @@ static int secref_whitelist(const char *modname, const char *tosec,
  * 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,
+static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
                                Elf_Sym *relsym)
 {
        Elf_Sym *sym;
+       Elf_Sym *near = NULL;
+       Elf64_Sword distance = 20;
+       Elf64_Sword d;
 
        if (relsym->st_name != 0)
                return relsym;
@@ -778,8 +988,20 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr,
                        continue;
                if (sym->st_value == addr)
                        return sym;
+               /* Find a symbol nearby - addr are maybe negative */
+               d = sym->st_value - addr;
+               if (d < 0)
+                       d = addr - sym->st_value;
+               if (d < distance) {
+                       distance = d;
+                       near = sym;
+               }
        }
-       return NULL;
+       /* We need a close match */
+       if (distance < 20)
+               return near;
+       else
+               return NULL;
 }
 
 static inline int is_arm_mapping_symbol(const char *str)
@@ -812,121 +1034,245 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
  * 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)
+static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
+                                const char *sec)
 {
        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;
+       Elf_Sym *near = NULL;
+       Elf_Addr distance = ~0;
 
        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;
+               symsec = sec_name(elf, sym->st_shndx);
                if (strcmp(symsec, sec) != 0)
                        continue;
                if (!is_valid_name(elf, sym))
                        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) {
-                               *before = sym;
+                       if ((addr - sym->st_value) < distance) {
+                               distance = addr - sym->st_value;
+                               near = sym;
+                       } else if ((addr - sym->st_value) == distance) {
+                               near = sym;
                        }
                }
+       }
+       return near;
+}
+
+/*
+ * Convert a section name to the function/data attribute
+ * .init.text => __init
+ * .cpuinit.data => __cpudata
+ * .memexitconst => __memconst
+ * etc.
+*/
+static char *sec2annotation(const char *s)
+{
+       if (match(s, init_exit_sections)) {
+               char *p = malloc(20);
+               char *r = p;
+
+               *p++ = '_';
+               *p++ = '_';
+               if (*s == '.')
+                       s++;
+               while (*s && *s != '.')
+                       *p++ = *s++;
+               *p = '\0';
+               if (*s == '.')
+                       s++;
+               if (strstr(s, "rodata") != NULL)
+                       strcat(p, "const ");
+               else if (strstr(s, "data") != NULL)
+                       strcat(p, "data ");
                else
-               {
-                       if ((sym->st_value - addr) < afterdiff) {
-                               afterdiff = sym->st_value - addr;
-                               *after = sym;
-                       }
-                       else if ((sym->st_value - addr) == afterdiff) {
-                               *after = sym;
-                       }
-               }
+                       strcat(p, " ");
+               return r; /* we leak her but we do not care */
+       } else {
+               return "";
        }
 }
 
-/**
+static int is_function(Elf_Sym *sym)
+{
+       if (sym)
+               return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
+       else
+               return 0;
+}
+
+/*
  * 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)
+ */
+static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
+                                const char *fromsec,
+                                unsigned long long fromaddr,
+                                const char *fromsym,
+                                int from_is_func,
+                                const char *tosec, const char *tosym,
+                                int to_is_func)
 {
-       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 (secref_whitelist(modname, secname, fromsec,
-                            before ? elf->strtab + before->st_name : "",
-                            refsymname))
+       const char *from, *from_p;
+       const char *to, *to_p;
+       from = from_is_func ? "function" : "variable";
+       from_p = from_is_func ? "()" : "";
+       to = to_is_func ? "function" : "variable";
+       to_p = to_is_func ? "()" : "";
+
+       fprintf(stderr, "WARNING: %s(%s+0x%llx): Section mismatch in"
+                       " reference from the %s %s%s to the %s %s:%s%s\n",
+                        modname, fromsec, fromaddr, from, fromsym, from_p,
+                       to, tosec, tosym, to_p);
+
+       sec_mismatch_count++;
+       if (!sec_mismatch_verbose)
                return;
 
-       if (before && after) {
-               warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
-                    "(between '%s' and '%s')\n",
-                    modname, fromsec, (unsigned long long)r.r_offset,
-                    secname, refsymname,
-                    elf->strtab + before->st_name,
-                    elf->strtab + after->st_name);
-       } else if (before) {
-               warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
-                    "(after '%s')\n",
-                    modname, fromsec, (unsigned long long)r.r_offset,
-                    secname, refsymname,
-                    elf->strtab + before->st_name);
-       } else if (after) {
-               warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
-                    "before '%s' (at offset -0x%llx)\n",
-                    modname, fromsec, (unsigned long long)r.r_offset,
-                    secname, refsymname,
-                    elf->strtab + after->st_name);
-       } else {
-               warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n",
-                    modname, fromsec, (unsigned long long)r.r_offset,
-                    secname, refsymname);
+       switch (mismatch) {
+       case TEXT_TO_INIT:
+               fprintf(stderr,
+               "The function %s %s() references\n"
+               "the %s %s%s%s.\n"
+               "This is often because %s lacks a %s\n"
+               "annotation or the annotation of %s is wrong.\n",
+               sec2annotation(fromsec), fromsym,
+               to, sec2annotation(tosec), tosym, to_p,
+               fromsym, sec2annotation(tosec), tosym);
+               break;
+       case DATA_TO_INIT: {
+               const char **s = symbol_white_list;
+               fprintf(stderr,
+               "The variable %s references\n"
+               "the %s %s%s%s\n"
+               "If the reference is valid then annotate the\n"
+               "variable with __init* (see linux/init.h) "
+               "or name the variable:\n",
+               fromsym, to, sec2annotation(tosec), tosym, to_p);
+               while (*s)
+                       fprintf(stderr, "%s, ", *s++);
+               fprintf(stderr, "\n");
+               break;
+       }
+       case TEXT_TO_EXIT:
+               fprintf(stderr,
+               "The function %s() references a %s in an exit section.\n"
+               "Often the %s %s%s has valid usage outside the exit section\n"
+               "and the fix is to remove the %sannotation of %s.\n",
+               fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
+               break;
+       case DATA_TO_EXIT: {
+               const char **s = symbol_white_list;
+               fprintf(stderr,
+               "The variable %s references\n"
+               "the %s %s%s%s\n"
+               "If the reference is valid then annotate the\n"
+               "variable with __exit* (see linux/init.h) or "
+               "name the variable:\n",
+               fromsym, to, sec2annotation(tosec), tosym, to_p);
+               while (*s)
+                       fprintf(stderr, "%s, ", *s++);
+               fprintf(stderr, "\n");
+               break;
+       }
+       case XXXINIT_TO_INIT:
+       case XXXEXIT_TO_EXIT:
+               fprintf(stderr,
+               "The %s %s%s%s references\n"
+               "a %s %s%s%s.\n"
+               "If %s is only used by %s then\n"
+               "annotate %s with a matching annotation.\n",
+               from, sec2annotation(fromsec), fromsym, from_p,
+               to, sec2annotation(tosec), tosym, to_p,
+               fromsym, tosym, fromsym);
+               break;
+       case INIT_TO_EXIT:
+               fprintf(stderr,
+               "The %s %s%s%s references\n"
+               "a %s %s%s%s.\n"
+               "This is often seen when error handling "
+               "in the init function\n"
+               "uses functionality in the exit path.\n"
+               "The fix is often to remove the %sannotation of\n"
+               "%s%s so it may be used outside an exit section.\n",
+               from, sec2annotation(fromsec), fromsym, from_p,
+               to, sec2annotation(tosec), tosym, to_p,
+               sec2annotation(tosec), tosym, to_p);
+               break;
+       case EXIT_TO_INIT:
+               fprintf(stderr,
+               "The %s %s%s%s references\n"
+               "a %s %s%s%s.\n"
+               "This is often seen when error handling "
+               "in the exit function\n"
+               "uses functionality in the init path.\n"
+               "The fix is often to remove the %sannotation of\n"
+               "%s%s so it may be used outside an init section.\n",
+               from, sec2annotation(fromsec), fromsym, from_p,
+               to, sec2annotation(tosec), tosym, to_p,
+               sec2annotation(tosec), tosym, to_p);
+               break;
+       case EXPORT_TO_INIT_EXIT:
+               fprintf(stderr,
+               "The symbol %s is exported and annotated %s\n"
+               "Fix this by removing the %sannotation of %s "
+               "or drop the export.\n",
+               tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
+       case NO_MISMATCH:
+               /* To get warnings on missing members */
+               break;
+       }
+       fprintf(stderr, "\n");
+}
+
+static void check_section_mismatch(const char *modname, struct elf_info *elf,
+                                   Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
+{
+       const char *tosec;
+       enum mismatch mismatch;
+
+       tosec = sec_name(elf, sym->st_shndx);
+       mismatch = section_mismatch(fromsec, tosec);
+       if (mismatch != NO_MISMATCH) {
+               Elf_Sym *to;
+               Elf_Sym *from;
+               const char *tosym;
+               const char *fromsym;
+
+               from = find_elf_symbol2(elf, r->r_offset, fromsec);
+               fromsym = sym_name(elf, from);
+               to = find_elf_symbol(elf, r->r_addend, sym);
+               tosym = sym_name(elf, to);
+
+               /* check whitelist - we may ignore it */
+               if (secref_whitelist(fromsec, fromsym, tosec, tosym)) {
+                       report_sec_mismatch(modname, mismatch,
+                          fromsec, r->r_offset, fromsym,
+                          is_function(from), tosec, tosym,
+                          is_function(to));
+               }
        }
 }
 
 static unsigned int *reloc_location(struct elf_info *elf,
-                                          int rsection, Elf_Rela *r)
+                                   Elf_Shdr *sechdr, Elf_Rela *r)
 {
        Elf_Shdr *sechdrs = elf->sechdrs;
-       int section = sechdrs[rsection].sh_info;
+       int section = sechdr->sh_info;
 
        return (void *)elf->hdr + sechdrs[section].sh_offset +
                (r->r_offset - sechdrs[section].sh_addr);
 }
 
-static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
+static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 {
        unsigned int r_typ = ELF_R_TYPE(r->r_info);
-       unsigned int *location = reloc_location(elf, rsection, r);
+       unsigned int *location = reloc_location(elf, sechdr, r);
 
        switch (r_typ) {
        case R_386_32:
@@ -942,19 +1288,21 @@ static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
        return 0;
 }
 
-static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
+static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 {
        unsigned int r_typ = ELF_R_TYPE(r->r_info);
 
        switch (r_typ) {
        case R_ARM_ABS32:
                /* From ARM ABI: (S + A) | T */
-               r->r_addend = (int)(long)(elf->symtab_start + ELF_R_SYM(r->r_info));
+               r->r_addend = (int)(long)
+                             (elf->symtab_start + ELF_R_SYM(r->r_info));
                break;
        case R_ARM_PC24:
                /* From ARM ABI: ((S + A) | T) - P */
-               r->r_addend = (int)(long)(elf->hdr + elf->sechdrs[rsection].sh_offset +
-                                         (r->r_offset - elf->sechdrs[rsection].sh_addr));
+               r->r_addend = (int)(long)(elf->hdr +
+                             sechdr->sh_offset +
+                             (r->r_offset - sechdr->sh_addr));
                break;
        default:
                return 1;
@@ -962,10 +1310,10 @@ static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
        return 0;
 }
 
-static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
+static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 {
        unsigned int r_typ = ELF_R_TYPE(r->r_info);
-       unsigned int *location = reloc_location(elf, rsection, r);
+       unsigned int *location = reloc_location(elf, sechdr, r);
        unsigned int inst;
 
        if (r_typ == R_MIPS_HI16)
@@ -985,6 +1333,108 @@ static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
        return 0;
 }
 
+static void section_rela(const char *modname, struct elf_info *elf,
+                         Elf_Shdr *sechdr)
+{
+       Elf_Sym  *sym;
+       Elf_Rela *rela;
+       Elf_Rela r;
+       unsigned int r_sym;
+       const char *fromsec;
+
+       Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
+       Elf_Rela *stop  = (void *)start + sechdr->sh_size;
+
+       fromsec = sech_name(elf, sechdr);
+       fromsec += strlen(".rela");
+       /* if from section (name) is know good then skip it */
+       if (check_section(modname, fromsec))
+               return;
+
+       for (rela = start; rela < stop; rela++) {
+               r.r_offset = TO_NATIVE(rela->r_offset);
+#if KERNEL_ELFCLASS == ELFCLASS64
+               if (elf->hdr->e_machine == EM_MIPS) {
+                       unsigned int r_typ;
+                       r_sym = ELF64_MIPS_R_SYM(rela->r_info);
+                       r_sym = TO_NATIVE(r_sym);
+                       r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
+                       r.r_info = ELF64_R_INFO(r_sym, r_typ);
+               } else {
+                       r.r_info = TO_NATIVE(rela->r_info);
+                       r_sym = ELF_R_SYM(r.r_info);
+               }
+#else
+               r.r_info = TO_NATIVE(rela->r_info);
+