lkml.org 
[lkml]   [2007]   [Nov]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/3] build system: section garbage collection - main part
    Date
    On Saturday 24 November 2007 15:14, Denys Vlasenko wrote:
    > 3.gc
    > The meat of the patchset is here.
    > Introduce config option DISCARD_UNUSED_SECTIONS.
    > If it is selected:
    > Pass -ffunction-sections -fdata-sections to gcc and
    > --gc-sections --print-gc-sections to ld.
    > Use arch/$(SRCARCH)/kernel/modules.lds.S linker script for linking *.ko
    > files.
    > Generate linker map files for vmlinux and modules.
    > Add *(.text.*), *(.data.*) wildcards to linker scripts to accomodate
    > new kinds of sections generated by gcc.
    > Add KEEP(<sections>) directives to sections which must not be
    > discarded. Fix arch/frv/Makefile to use DISCARD_UNUSED_SECTIONS instead
    > of what seems to be a vestigial custom solution.

    Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
    --
    vda
    diff -urpN linux-2.6.gc2/Makefile linux-2.6.gc3/Makefile
    --- linux-2.6.gc2/Makefile 2007-11-23 18:55:08.000000000 -0800
    +++ linux-2.6.gc3/Makefile 2007-11-24 14:46:38.000000000 -0800
    @@ -526,6 +526,11 @@ KBUILD_CFLAGS += $(call cc-optio
    NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
    CHECKFLAGS += $(NOSTDINC_FLAGS)

    +ifdef CONFIG_DISCARD_UNUSED_SECTIONS
    +CFLAGS += $(call cc-option, -ffunction-sections -fdata-sections)
    +LDFLAGS_vmlinux += --gc-sections --print-gc-sections -Map vmlinux.map
    +endif
    +
    # warn about C99 declaration after statement
    KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)

    @@ -924,6 +929,7 @@ prepare: prepare0
    # done in arch/$(ARCH)/kernel/Makefile

    export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
    +export CPPFLAGS_modules.lds += -P -C -U$(ARCH)

    # The asm symlink changes when $(ARCH) changes.
    # Detect this and ask user to run make mrproper
    diff -urpN linux-2.6.gc2/arch/alpha/boot/bootloader.lds linux-2.6.gc3/arch/alpha/boot/bootloader.lds
    --- linux-2.6.gc2/arch/alpha/boot/bootloader.lds 2007-11-23 18:55:08.000000000 -0800
    +++ linux-2.6.gc3/arch/alpha/boot/bootloader.lds 2007-11-23 21:22:59.000000000 -0800
    @@ -4,17 +4,17 @@ printk = srm_printk;
    SECTIONS
    {
    . = 0x20000000;
    - .text : { *(.text) }
    + .text : { *(.text) *(.text.*) }
    _etext = .;
    PROVIDE (etext = .);
    .rodata : { *(.rodata) *(.rodata.*) }
    - .data : { *(.data) CONSTRUCTORS }
    + .data : { *(.data) *(.data.*) CONSTRUCTORS }
    .got : { *(.got) }
    .sdata : { *(.sdata) }
    _edata = .;
    PROVIDE (edata = .);
    .sbss : { *(.sbss) *(.scommon) }
    - .bss : { *(.bss) *(COMMON) }
    + .bss : { *(.bss) *(.bss.*) *(COMMON) }
    _end = . ;
    PROVIDE (end = .);

    diff -urpN linux-2.6.gc2/arch/alpha/kernel/vmlinux.lds.S linux-2.6.gc3/arch/alpha/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/alpha/kernel/vmlinux.lds.S 2007-11-23 20:55:55.000000000 -0800
    +++ linux-2.6.gc3/arch/alpha/kernel/vmlinux.lds.S 2007-11-23 21:30:54.000000000 -0800
    @@ -129,6 +129,7 @@ SECTIONS
    }
    .bss : {
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    }
    __bss_stop = .;
    diff -urpN linux-2.6.gc2/arch/arm/boot/bootp/bootp.lds linux-2.6.gc3/arch/arm/boot/bootp/bootp.lds
    --- linux-2.6.gc2/arch/arm/boot/bootp/bootp.lds 2007-11-23 18:55:08.000000000 -0800
    +++ linux-2.6.gc3/arch/arm/boot/bootp/bootp.lds 2007-11-23 21:23:15.000000000 -0800
    @@ -15,7 +15,7 @@ SECTIONS
    .text : {
    _stext = .;
    *(.start)
    - *(.text)
    + *(.text .text.*)
    initrd_size = initrd_end - initrd_start;
    _etext = .;
    }
    diff -urpN linux-2.6.gc2/arch/arm/boot/compressed/vmlinux.lds.in linux-2.6.gc3/arch/arm/boot/compressed/vmlinux.lds.in
    --- linux-2.6.gc2/arch/arm/boot/compressed/vmlinux.lds.in 2007-11-23 18:55:08.000000000 -0800
    +++ linux-2.6.gc3/arch/arm/boot/compressed/vmlinux.lds.in 2007-11-23 21:24:25.000000000 -0800
    @@ -35,12 +35,12 @@ SECTIONS
    .got : { *(.got) }
    _got_end = .;
    .got.plt : { *(.got.plt) }
    - .data : { *(.data) }
    + .data : { *(.data) *(.data.*) }
    _edata = .;

    . = BSS_START;
    __bss_start = .;
    - .bss : { *(.bss) }
    + .bss : { *(.bss) *(.bss.*) }
    _end = .;

    .stack (NOLOAD) : { *(.stack) }
    diff -urpN linux-2.6.gc2/arch/arm/kernel/vmlinux.lds.S linux-2.6.gc3/arch/arm/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/arm/kernel/vmlinux.lds.S 2007-11-23 20:55:54.000000000 -0800
    +++ linux-2.6.gc3/arch/arm/kernel/vmlinux.lds.S 2007-11-23 21:31:04.000000000 -0800
    @@ -169,6 +169,7 @@ SECTIONS
    .bss : {
    __bss_start = .; /* BSS */
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    _end = .;
    }
    diff -urpN linux-2.6.gc2/arch/avr32/kernel/vmlinux.lds.S linux-2.6.gc3/arch/avr32/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/avr32/kernel/vmlinux.lds.S 2007-11-23 20:55:53.000000000 -0800
    +++ linux-2.6.gc3/arch/avr32/kernel/vmlinux.lds.S 2007-11-23 21:31:12.000000000 -0800
    @@ -124,6 +124,7 @@ SECTIONS
    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
    __bss_start = .;
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    . = ALIGN(8);
    __bss_stop = .;
    diff -urpN linux-2.6.gc2/arch/cris/arch-v10/vmlinux.lds.S linux-2.6.gc3/arch/cris/arch-v10/vmlinux.lds.S
    --- linux-2.6.gc2/arch/cris/arch-v10/vmlinux.lds.S 2007-11-23 20:55:56.000000000 -0800
    +++ linux-2.6.gc3/arch/cris/arch-v10/vmlinux.lds.S 2007-11-23 21:31:19.000000000 -0800
    @@ -104,6 +104,7 @@ SECTIONS
    .bss : {
    *(COMMON)
    *(.bss)
    + *(.bss.*)
    }

    . = ALIGN (0x20);
    diff -urpN linux-2.6.gc2/arch/cris/arch-v32/vmlinux.lds.S linux-2.6.gc3/arch/cris/arch-v32/vmlinux.lds.S
    --- linux-2.6.gc2/arch/cris/arch-v32/vmlinux.lds.S 2007-11-23 20:55:56.000000000 -0800
    +++ linux-2.6.gc3/arch/cris/arch-v32/vmlinux.lds.S 2007-11-23 21:31:26.000000000 -0800
    @@ -116,6 +116,7 @@ SECTIONS
    .bss : {
    *(COMMON)
    *(.bss)
    + *(.bss.*)
    }

    . = ALIGN (0x20);
    diff -urpN linux-2.6.gc2/arch/frv/Makefile linux-2.6.gc3/arch/frv/Makefile
    --- linux-2.6.gc2/arch/frv/Makefile 2007-11-23 18:55:09.000000000 -0800
    +++ linux-2.6.gc3/arch/frv/Makefile 2007-11-23 21:50:49.000000000 -0800
    @@ -52,7 +52,9 @@ endif

    #LDFLAGS_vmlinux := -Map linkmap.txt

    -ifdef CONFIG_GC_SECTIONS
    +# Is this needed? We do this already in kernel's top-level Makefile.
    +# Also $(LINKFLAGS) seems to be unused.
    +ifdef CONFIG_DISCARD_UNUSED_SECTIONS
    KBUILD_CFLAGS += -ffunction-sections -fdata-sections
    LINKFLAGS += --gc-sections
    endif
    diff -urpN linux-2.6.gc2/arch/h8300/boot/compressed/vmlinux.lds linux-2.6.gc3/arch/h8300/boot/compressed/vmlinux.lds
    --- linux-2.6.gc2/arch/h8300/boot/compressed/vmlinux.lds 2007-11-23 20:55:45.000000000 -0800
    +++ linux-2.6.gc3/arch/h8300/boot/compressed/vmlinux.lds 2007-11-23 21:25:10.000000000 -0800
    @@ -5,13 +5,13 @@ SECTIONS
    __stext = . ;
    __text = .;
    *(.startup.text)
    - *(.text)
    + *(.text) *(.text.*)
    __etext = . ;
    }

    .rodata :
    {
    - *(.rodata)
    + *(.rodata) *(.rodata.*)
    }
    .data :

    diff -urpN linux-2.6.gc2/arch/ia64/hp/sim/boot/bootloader.lds linux-2.6.gc3/arch/ia64/hp/sim/boot/bootloader.lds
    --- linux-2.6.gc2/arch/ia64/hp/sim/boot/bootloader.lds 2007-11-23 18:55:09.000000000 -0800
    +++ linux-2.6.gc3/arch/ia64/hp/sim/boot/bootloader.lds 2007-11-23 21:25:44.000000000 -0800
    @@ -7,13 +7,13 @@ SECTIONS
    . = 0x100000;

    _text = .;
    - .text : { *(__ivt_section) *(.text) }
    + .text : { *(__ivt_section) *(.text) *(.text.*) }
    _etext = .;

    /* Global data */
    _data = .;
    .rodata : { *(.rodata) *(.rodata.*) }
    - .data : { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
    + .data : { *(.data) *(.data.*) *(.gnu.linkonce.d*) CONSTRUCTORS }
    __gp = ALIGN (8) + 0x200000;
    .got : { *(.got.plt) *(.got) }
    /* We want the small data sections together, so single-instruction offsets
    @@ -24,7 +24,7 @@ SECTIONS

    _bss = .;
    .sbss : { *(.sbss) *(.scommon) }
    - .bss : { *(.bss) *(COMMON) }
    + .bss : { *(.bss) *(.bss.*) *(COMMON) }
    . = ALIGN(64 / 8);
    _end = . ;

    diff -urpN linux-2.6.gc2/arch/ia64/kernel/vmlinux.lds.S linux-2.6.gc3/arch/ia64/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/ia64/kernel/vmlinux.lds.S 2007-11-23 20:55:59.000000000 -0800
    +++ linux-2.6.gc3/arch/ia64/kernel/vmlinux.lds.S 2007-11-23 21:31:52.000000000 -0800
    @@ -244,7 +244,7 @@ SECTIONS
    .sbss : AT(ADDR(.sbss) - LOAD_OFFSET)
    { *(.sbss) *(.scommon) }
    .bss : AT(ADDR(.bss) - LOAD_OFFSET)
    - { *(.bss) *(COMMON) }
    + { *(.bss) *(.bss.*) *(COMMON) }

    _end = .;

    diff -urpN linux-2.6.gc2/arch/ia64/scripts/check-segrel.lds linux-2.6.gc3/arch/ia64/scripts/check-segrel.lds
    --- linux-2.6.gc2/arch/ia64/scripts/check-segrel.lds 2007-11-23 18:55:09.000000000 -0800
    +++ linux-2.6.gc3/arch/ia64/scripts/check-segrel.lds 2007-11-23 21:28:43.000000000 -0800
    @@ -1,9 +1,9 @@
    SECTIONS {
    . = SIZEOF_HEADERS;
    - .rodata : { *(.rodata) } :ro
    + .rodata : { *(.rodata) *(.rodata.*) } :ro
    .note : { *(.note*) }
    . = 0xa0000;
    - .data : { *(.data) } :dat
    + .data : { *(.data) *(.data.*) } :dat
    /DISCARD/ : { *(*) }
    }
    PHDRS {
    diff -urpN linux-2.6.gc2/arch/m32r/boot/compressed/vmlinux.lds.S linux-2.6.gc3/arch/m32r/boot/compressed/vmlinux.lds.S
    --- linux-2.6.gc2/arch/m32r/boot/compressed/vmlinux.lds.S 2007-11-23 18:55:09.000000000 -0800
    +++ linux-2.6.gc3/arch/m32r/boot/compressed/vmlinux.lds.S 2007-11-23 21:27:15.000000000 -0800
    @@ -6,12 +6,12 @@ SECTIONS
    . = CONFIG_MEMORY_START + 0x00400000;

    _text = .;
    - .text : { *(.text) } = 0
    + .text : { *(.text) *(.text.*) } = 0
    .rodata : { *(.rodata) *(.rodata.*) }
    _etext = .;

    . = ALIGN(32 / 8);
    - .data : { *(.data) }
    + .data : { *(.data) *(.data.*) }
    . = ALIGN(32 / 8);
    _got = .;
    .got : { *(.got) _egot = .; *(.got.*) }
    @@ -19,7 +19,7 @@ SECTIONS

    . = ALIGN(32 / 8);
    __bss_start = .;
    - .bss : { *(.bss) *(.sbss) }
    + .bss : { *(.bss) *(.bss.*) *(.sbss) }
    . = ALIGN(32 / 8);
    _ebss = .;
    . = ALIGN(4096);
    diff -urpN linux-2.6.gc2/arch/m32r/kernel/vmlinux.lds.S linux-2.6.gc3/arch/m32r/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/m32r/kernel/vmlinux.lds.S 2007-11-23 20:55:57.000000000 -0800
    +++ linux-2.6.gc3/arch/m32r/kernel/vmlinux.lds.S 2007-11-23 21:32:02.000000000 -0800
    @@ -116,7 +116,7 @@ SECTIONS
    /* freed after init ends here */

    __bss_start = .; /* BSS */
    - .bss : { *(.bss) }
    + .bss : { *(.bss) *(.bss.*) }
    . = ALIGN(4);
    __bss_stop = .;

    diff -urpN linux-2.6.gc2/arch/m68k/kernel/vmlinux-std.lds linux-2.6.gc3/arch/m68k/kernel/vmlinux-std.lds
    --- linux-2.6.gc2/arch/m68k/kernel/vmlinux-std.lds 2007-11-23 20:55:53.000000000 -0800
    +++ linux-2.6.gc3/arch/m68k/kernel/vmlinux-std.lds 2007-11-23 21:32:16.000000000 -0800
    @@ -33,7 +33,7 @@ SECTIONS
    CONSTRUCTORS
    }

    - .bss : { *(.bss) } /* BSS */
    + .bss : { *(.bss) *(.bss.*) } /* BSS */

    . = ALIGN(16);
    .cacheline_aligned.data : { *(.cacheline_aligned.data) } :data
    diff -urpN linux-2.6.gc2/arch/m68k/kernel/vmlinux-sun3.lds linux-2.6.gc3/arch/m68k/kernel/vmlinux-sun3.lds
    --- linux-2.6.gc2/arch/m68k/kernel/vmlinux-sun3.lds 2007-11-23 20:55:53.000000000 -0800
    +++ linux-2.6.gc3/arch/m68k/kernel/vmlinux-sun3.lds 2007-11-23 21:32:10.000000000 -0800
    @@ -71,7 +71,7 @@ __init_begin = .;
    .init.task.data : { *(.init_task.data) }


    - .bss : { *(.bss) } /* BSS */
    + .bss : { *(.bss) *(.bss.*) } /* BSS */

    _end = . ;

    diff -urpN linux-2.6.gc2/arch/m68knommu/kernel/vmlinux.lds.S linux-2.6.gc3/arch/m68knommu/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/m68knommu/kernel/vmlinux.lds.S 2007-11-23 20:55:53.000000000 -0800
    +++ linux-2.6.gc3/arch/m68knommu/kernel/vmlinux.lds.S 2007-11-23 21:32:23.000000000 -0800
    @@ -179,6 +179,7 @@ SECTIONS {
    . = ALIGN(4);
    _sbss = . ;
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    . = ALIGN(4) ;
    _ebss = . ;
    diff -urpN linux-2.6.gc2/arch/mips/kernel/vmlinux.lds.S linux-2.6.gc3/arch/mips/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/mips/kernel/vmlinux.lds.S 2007-11-23 20:55:54.000000000 -0800
    +++ linux-2.6.gc3/arch/mips/kernel/vmlinux.lds.S 2007-11-23 21:32:30.000000000 -0800
    @@ -169,6 +169,7 @@ SECTIONS
    }
    .bss : {
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    }
    __bss_stop = .;
    diff -urpN linux-2.6.gc2/arch/parisc/kernel/vmlinux.lds.S linux-2.6.gc3/arch/parisc/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/parisc/kernel/vmlinux.lds.S 2007-11-23 20:56:00.000000000 -0800
    +++ linux-2.6.gc3/arch/parisc/kernel/vmlinux.lds.S 2007-11-23 21:32:37.000000000 -0800
    @@ -141,6 +141,7 @@ SECTIONS
    }
    .bss : {
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    }
    __bss_stop = .;
    diff -urpN linux-2.6.gc2/arch/powerpc/boot/zImage.coff.lds.S linux-2.6.gc3/arch/powerpc/boot/zImage.coff.lds.S
    --- linux-2.6.gc2/arch/powerpc/boot/zImage.coff.lds.S 2007-11-23 18:55:09.000000000 -0800
    +++ linux-2.6.gc3/arch/powerpc/boot/zImage.coff.lds.S 2007-11-23 21:22:04.000000000 -0800
    @@ -7,7 +7,7 @@ SECTIONS
    _start = .;
    .text :
    {
    - *(.text)
    + *(.text .text.*)
    *(.fixup)
    }
    _etext = .;
    @@ -41,7 +41,7 @@ SECTIONS
    .bss :
    {
    *(.sbss)
    - *(.bss)
    + *(.bss .bss.*)
    }
    _end = . ;

    diff -urpN linux-2.6.gc2/arch/powerpc/boot/zImage.lds.S linux-2.6.gc3/arch/powerpc/boot/zImage.lds.S
    --- linux-2.6.gc2/arch/powerpc/boot/zImage.lds.S 2007-11-23 18:55:09.000000000 -0800
    +++ linux-2.6.gc3/arch/powerpc/boot/zImage.lds.S 2007-11-23 21:32:48.000000000 -0800
    @@ -8,6 +8,7 @@ SECTIONS
    .text :
    {
    *(.text)
    + *(.text.*)
    *(.fixup)
    }
    _etext = .;
    @@ -46,6 +47,7 @@ SECTIONS
    {
    *(.sbss)
    *(.bss)
    + *(.bss.*)
    }
    . = ALIGN(4096);
    _end = . ;
    diff -urpN linux-2.6.gc2/arch/powerpc/boot/zImage.ps3.lds.S linux-2.6.gc3/arch/powerpc/boot/zImage.ps3.lds.S
    --- linux-2.6.gc2/arch/powerpc/boot/zImage.ps3.lds.S 2007-11-23 18:55:09.000000000 -0800
    +++ linux-2.6.gc3/arch/powerpc/boot/zImage.ps3.lds.S 2007-11-23 21:26:51.000000000 -0800
    @@ -21,6 +21,7 @@ SECTIONS
    .text :
    {
    *(.text)
    + *(.text.*)
    *(.fixup)
    }
    _etext = .;
    @@ -44,6 +45,7 @@ SECTIONS
    {
    *(.sbss)
    *(.bss)
    + *(.bss.*)
    }
    . = ALIGN(4096);
    _end = . ;
    diff -urpN linux-2.6.gc2/arch/powerpc/kernel/vmlinux.lds.S linux-2.6.gc3/arch/powerpc/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/powerpc/kernel/vmlinux.lds.S 2007-11-23 20:55:55.000000000 -0800
    +++ linux-2.6.gc3/arch/powerpc/kernel/vmlinux.lds.S 2007-11-23 21:32:54.000000000 -0800
    @@ -37,7 +37,7 @@ SECTIONS
    ALIGN_FUNCTION();
    *(.head.text)
    _text = .;
    - *(.text .fixup .init.refok.text .exit.text.refok)
    + *(.text *(.text.*) .fixup .init.refok.text .exit.text.refok)
    SCHED_TEXT
    LOCK_TEXT
    KPROBES_TEXT
    @@ -240,6 +240,7 @@ SECTIONS
    *(.sbss) *(.scommon)
    *(.dynbss)
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    __bss_stop = .;
    }
    diff -urpN linux-2.6.gc2/arch/ppc/kernel/vmlinux.lds.S linux-2.6.gc3/arch/ppc/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/ppc/kernel/vmlinux.lds.S 2007-11-23 20:55:54.000000000 -0800
    +++ linux-2.6.gc3/arch/ppc/kernel/vmlinux.lds.S 2007-11-23 21:33:01.000000000 -0800
    @@ -154,6 +154,7 @@ SECTIONS
    *(.sbss) *(.scommon)
    *(.dynbss)
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    }
    __bss_stop = .;
    diff -urpN linux-2.6.gc2/arch/s390/kernel/vmlinux.lds.S linux-2.6.gc3/arch/s390/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/s390/kernel/vmlinux.lds.S 2007-11-23 20:55:57.000000000 -0800
    +++ linux-2.6.gc3/arch/s390/kernel/vmlinux.lds.S 2007-11-23 21:33:07.000000000 -0800
    @@ -142,6 +142,7 @@ SECTIONS
    .bss : {
    __bss_start = .;
    *(.bss)
    + *(.bss.*)
    . = ALIGN(2);
    __bss_stop = .;
    }
    diff -urpN linux-2.6.gc2/arch/sh/kernel/vmlinux.lds.S linux-2.6.gc3/arch/sh/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/sh/kernel/vmlinux.lds.S 2007-11-23 22:00:09.000000000 -0800
    +++ linux-2.6.gc3/arch/sh/kernel/vmlinux.lds.S 2007-11-23 21:33:16.000000000 -0800
    @@ -115,8 +115,17 @@ SECTIONS
    .bss : {
    __init_end = .;
    __bss_start = .; /* BSS */
    +
    + /* Why such strage name - .bss.k.page_aligned?
    + * .bss.page_aligned may clash with a section produced by gcc -fdata_sections.
    + * .bss_page_aligned, .page_aligned_bss will not work because
    + * we must use .bss.xxx section names for zero-initialized sections
    + * we want to combine into bss, otherwise gcc does not set
    + * 'nobits' flag for the section, and it cannot be merged into bss.
    + */
    *(.bss.k.page_aligned)
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = .; /* uClinux MTD sucks */
    diff -urpN linux-2.6.gc2/arch/sh/kernel/vsyscall/vsyscall.lds.S linux-2.6.gc3/arch/sh/kernel/vsyscall/vsyscall.lds.S
    --- linux-2.6.gc2/arch/sh/kernel/vsyscall/vsyscall.lds.S 2007-11-23 18:55:10.000000000 -0800
    +++ linux-2.6.gc3/arch/sh/kernel/vsyscall/vsyscall.lds.S 2007-11-23 21:21:33.000000000 -0800
    @@ -35,7 +35,7 @@ SECTIONS
    */
    . = 0x400;

    - .text : { *(.text) } :text =0x90909090
    + .text : { *(.text .text.*) } :text =0x90909090
    .note : { *(.note.*) } :text :note
    .eh_frame_hdr : { *(.eh_frame_hdr ) } :text :eh_frame_hdr
    .eh_frame : {
    diff -urpN linux-2.6.gc2/arch/sh64/boot/compressed/vmlinux.lds.S linux-2.6.gc3/arch/sh64/boot/compressed/vmlinux.lds.S
    --- linux-2.6.gc2/arch/sh64/boot/compressed/vmlinux.lds.S 2007-11-23 18:55:10.000000000 -0800
    +++ linux-2.6.gc3/arch/sh64/boot/compressed/vmlinux.lds.S 2007-11-23 21:30:14.000000000 -0800
    @@ -32,7 +32,7 @@ SECTIONS
    *(.gnu.warning)
    } = NOP
    . = ALIGN(4);
    - .rodata : { *(.rodata) }
    + .rodata : { *(.rodata) *(.rodata.*) }

    /* There is no 'real' reason for eight byte alignment, four would work
    * as well, but gdb downloads much (*4) faster with this.
    @@ -47,6 +47,7 @@ SECTIONS
    {
    _data = .;
    *(.data)
    + *(.data.*)
    }
    _data_image = LOADADDR(.data);/* Address of data section in ROM */

    @@ -58,6 +59,7 @@ SECTIONS
    __bss_start = .; /* BSS */
    .bss : {
    *(.bss)
    + *(.bss.*)
    }
    . = ALIGN(4);
    _end = . ;
    diff -urpN linux-2.6.gc2/arch/sh64/kernel/vmlinux.lds.S linux-2.6.gc3/arch/sh64/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/sh64/kernel/vmlinux.lds.S 2007-11-23 20:55:55.000000000 -0800
    +++ linux-2.6.gc3/arch/sh64/kernel/vmlinux.lds.S 2007-11-23 21:33:26.000000000 -0800
    @@ -124,6 +124,7 @@ SECTIONS
    __bss_start = .; /* BSS */
    .bss : C_PHYS(.bss) {
    *(.bss)
    + *(.bss.*)
    }
    . = ALIGN(8);
    _end = . ;
    diff -urpN linux-2.6.gc2/arch/sparc/kernel/vmlinux.lds.S linux-2.6.gc3/arch/sparc/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/sparc/kernel/vmlinux.lds.S 2007-11-23 20:55:53.000000000 -0800
    +++ linux-2.6.gc3/arch/sparc/kernel/vmlinux.lds.S 2007-11-23 21:34:37.000000000 -0800
    @@ -97,6 +97,7 @@ SECTIONS
    .bss : {
    *(.dynbss)
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    }
    _end = . ;
    diff -urpN linux-2.6.gc2/arch/sparc64/kernel/vmlinux.lds.S linux-2.6.gc3/arch/sparc64/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/sparc64/kernel/vmlinux.lds.S 2007-11-23 20:55:53.000000000 -0800
    +++ linux-2.6.gc3/arch/sparc64/kernel/vmlinux.lds.S 2007-11-23 21:34:31.000000000 -0800
    @@ -131,6 +131,7 @@ SECTIONS
    .bss : {
    *(.dynbss)
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    }
    _end = . ;
    diff -urpN linux-2.6.gc2/arch/um/kernel/uml.lds.S linux-2.6.gc3/arch/um/kernel/uml.lds.S
    --- linux-2.6.gc2/arch/um/kernel/uml.lds.S 2007-11-23 20:55:54.000000000 -0800
    +++ linux-2.6.gc3/arch/um/kernel/uml.lds.S 2007-11-23 21:34:25.000000000 -0800
    @@ -91,6 +91,7 @@ SECTIONS
    {
    *(.dynbss)
    *(.bss)
    + *(.bss.*)
    *(COMMON)
    }
    _end = .;
    diff -urpN linux-2.6.gc2/arch/v850/kernel/vmlinux.lds.S linux-2.6.gc3/arch/v850/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/v850/kernel/vmlinux.lds.S 2007-11-23 20:55:56.000000000 -0800
    +++ linux-2.6.gc3/arch/v850/kernel/vmlinux.lds.S 2007-11-23 21:34:18.000000000 -0800
    @@ -127,6 +127,7 @@
    #define BSS_CONTENTS \
    __sbss = . ; \
    *(.bss) \
    + *(.bss.*) \
    *(COMMON) \
    . = ALIGN (4) ; \
    __init_stack_end = . ; \
    diff -urpN linux-2.6.gc2/arch/x86/kernel/Makefile_32 linux-2.6.gc3/arch/x86/kernel/Makefile_32
    --- linux-2.6.gc2/arch/x86/kernel/Makefile_32 2007-11-23 22:16:54.000000000 -0800
    +++ linux-2.6.gc3/arch/x86/kernel/Makefile_32 2007-11-23 22:16:43.000000000 -0800
    @@ -2,8 +2,9 @@
    # Makefile for the linux kernel.
    #

    -extra-y := head_32.o init_task.o vmlinux.lds
    +extra-y := head_32.o init_task.o vmlinux.lds modules.lds
    CPPFLAGS_vmlinux.lds += -Ui386
    +CPPFLAGS_modules.lds += -Ui386

    obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
    ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
    diff -urpN linux-2.6.gc2/arch/x86/kernel/Makefile_64 linux-2.6.gc3/arch/x86/kernel/Makefile_64
    --- linux-2.6.gc2/arch/x86/kernel/Makefile_64 2007-11-23 22:17:07.000000000 -0800
    +++ linux-2.6.gc3/arch/x86/kernel/Makefile_64 2007-11-23 22:16:43.000000000 -0800
    @@ -2,8 +2,10 @@
    # Makefile for the linux kernel.
    #

    -extra-y := head_64.o head64.o init_task.o vmlinux.lds
    +extra-y := head_64.o head64.o init_task.o vmlinux.lds modules.lds
    CPPFLAGS_vmlinux.lds += -Ux86_64
    +CPPFLAGS_modules.lds += -Ux86_64
    +
    EXTRA_AFLAGS := -traditional

    obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
    diff -urpN linux-2.6.gc2/arch/x86/kernel/modules.lds.S linux-2.6.gc3/arch/x86/kernel/modules.lds.S
    --- linux-2.6.gc2/arch/x86/kernel/modules.lds.S 1969-12-31 16:00:00.000000000 -0800
    +++ linux-2.6.gc3/arch/x86/kernel/modules.lds.S 2007-11-23 22:16:04.000000000 -0800
    @@ -0,0 +1,128 @@
    +#ifdef CONFIG_X86_32
    +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    +OUTPUT_ARCH(i386)
    +#else
    +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
    +OUTPUT_ARCH(i386:x86-64)
    +#endif
    +
    +/*
    +This linker script is used if CONFIG_DISCARD_UNUSED_SECTIONS=y.
    +We are trying to minimize number of sections in .ko file
    +by coalescing .text.x, rodata.x, .data.x and bss.x input
    +sections into one output section each.
    +
    +Kernel module loader (kernel/module.c) needs to see the following sections:
    +
    +.init*
    +.exit*
    +.gnu.linkonce.this_module
    +.percpu.data
    +.modinfo
    +__ksymtab_gpl_future
    +__ksymtab_gpl
    +__ksymtab_unused_gpl
    +__ksymtab_unused
    +__ksymtab
    +__kcrctab_gpl_future
    +__kcrctab_gpl
    +__kcrctab_unused_gpl
    +__kcrctab_unused
    +__kcrctab
    +__param
    +__ex_table
    +__obsparm
    +__versions
    +.debug (?!)
    +$ARCH_UNWIND_SECTION_NAME (none for x86 yet)
    +
    +They must not be coalesced into sections with other names.
    +
    +*/
    +
    +SECTIONS
    +{
    + /* ro, code */
    +
    + /* .fixup and .altinstr_replacement work just fine
    + * without dedicated sections */
    + .text : {
    + *(SORT_BY_ALIGNMENT(.text*))
    + /* __ex_table points here */
    + *(SORT_BY_ALIGNMENT(.fixup*))
    + /* .altinstructions points here */
    + *(SORT_BY_ALIGNMENT(.altinstr_replacement*))
    + }
    + /* only if CONFIG_MODULE_UNLOAD */
    + .exit.text : { *(SORT_BY_ALIGNMENT(.exit.text)) }
    + /* end CONFIG_MODULE_UNLOAD */
    +
    + /* ro, data */
    +
    + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) }
    + /* Kernel searches through this table when it needs to handle an exception */
    + __ex_table : { *(__ex_table*) }
    + /* These two tables are not currently handled by in-kernel module loader,
    + * but likely will be in future kernels */
    + .altinstructions : { *(.altinstructions*) }
    + .smp_locks : { *(.smp_locks*) }
    + /* Used by depmod in order to generate modules.dep, modules.symbols */
    + __ksymtab_strings : { *(SORT_BY_ALIGNMENT(__ksymtab_strings)) }
    + /* EXPORT_SYMBOLs exported in this module */
    + __ksymtab_gpl_future : { *(__ksymtab_gpl_future) }
    + __ksymtab_gpl : { *(__ksymtab_gpl) }
    + __ksymtab_unused_gpl : { *(__ksymtab_unused_gpl) }
    + __ksymtab_unused : { *(__ksymtab_unused) }
    + __ksymtab : { *(__ksymtab) }
    + /* only if CONFIG_MODVERSIONS */
    + __kcrctab_gpl_future : { *(__kcrctab_gpl_future) }
    + __kcrctab_gpl : { *(__kcrctab_gpl) }
    + __kcrctab_unused_gpl : { *(__kcrctab_unused_gpl) }
    + __kcrctab_unused : { *(__kcrctab_unused) }
    + __kcrctab : { *(__kcrctab) }
    + /* from *.mod.c: const struct modversion_info ____versions[] */
    + __versions : { *(__versions) }
    + /* end CONFIG_MODVERSIONS */
    + __param : { *(.__param) }
    + __obsparm : { *(.__obsparm) }
    + /* from *.mod.c: const char __module_depends[] "depends=mod1,mod2" */
    + .modinfo : { *(SORT_BY_ALIGNMENT(.modinfo)) }
    + /* ld segfaults if we give it --build-id and then discard this section */
    + .note.gnu.build-id : { *(.note.gnu.build-id) }
    +
    + /* rw, data */
    +
    + .data : {
    + *(SORT_BY_ALIGNMENT(.cacheline_aligned.data))
    + *(SORT_BY_ALIGNMENT(.data*))
    + *(SORT_BY_ALIGNMENT(.read_mostly.data))
    + }
    + /* from *.mod.c: struct module __this_module */
    + .gnu.linkonce.this_module : { *(.gnu.linkonce.this_module) }
    +
    + /* only if CONFIG_SMP */
    + .percpu.data : { *(SORT_BY_ALIGNMENT(.percpu.data)) }
    + /* end CONFIG_SMP */
    +
    + /* only if CONFIG_MODULE_UNLOAD */
    + .exit.data : { *(SORT_BY_ALIGNMENT(.exit.data)) }
    + /* end CONFIG_MODULE_UNLOAD */
    +
    + /* rw, data initialized to 0 */
    +
    + .bss : { *(SORT_BY_ALIGNMENT(.bss*)) }
    +
    + /* init code/data. discarded at the end of sys_init_module() */
    +
    + .init.text : { *(SORT_BY_ALIGNMENT(.init.text)) }
    + .init.data : { *(SORT_BY_ALIGNMENT(.init.data)) }
    +
    + /* Be bold and resist the temptation to pull junk "by default" */
    +
    + /DISCARD/ : { *(*) }
    +
    + /* If you are going to revive these, please add comment why it is needed */
    + /* .debug : { *(.debug) } */
    + /* .comment : { *(.comment) } */
    + /* .note.GNU-stack : { *(.note.GNU-stack) } */
    +}
    diff -urpN linux-2.6.gc2/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.gc3/arch/x86/kernel/vmlinux_32.lds.S
    --- linux-2.6.gc2/arch/x86/kernel/vmlinux_32.lds.S 2007-11-23 22:00:09.000000000 -0800
    +++ linux-2.6.gc3/arch/x86/kernel/vmlinux_32.lds.S 2007-11-23 21:48:58.000000000 -0800
    @@ -2,14 +2,7 @@
    * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
    *
    * Don't define absolute symbols until and unless you know that symbol
    - * value is should remain constant even if kernel image is relocated
    - * at run time. Absolute symbols are not relocated. If symbol value should
    - * change if kernel is relocated, make the symbol section relative and
    - * put it inside the section definition.
    - */
    -
    -/* Don't define absolute symbols until and unless you know that symbol
    - * value is should remain constant even if kernel image is relocated
    + * value should remain constant even if kernel image is relocated
    * at run time. Absolute symbols are not relocated. If symbol value should
    * change if kernel is relocated, make the symbol section relative and
    * put it inside the section definition.
    @@ -39,7 +32,7 @@ SECTIONS

    .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
    _text = .; /* Text and read-only data */
    - *(.head.text)
    + KEEP(*(.head.text))
    } :text = 0x9090

    /* read-only */
    @@ -48,16 +41,17 @@ SECTIONS
    SCHED_TEXT
    LOCK_TEXT
    KPROBES_TEXT
    - *(.fixup)
    + *(.fixup) /* no need to KEEP, every .fixup is referenced by __ex_table */
    *(.gnu.warning)
    _etext = .; /* End of text section */
    } :text = 0x9090

    . = ALIGN(16); /* Exception table */
    __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
    - __start___ex_table = .;
    - *(__ex_table)
    - __stop___ex_table = .;
    + /* Points to potentially-faulting insns and corresponding .fixups */
    + __start___ex_table = .;
    + KEEP(*(__ex_table))
    + __stop___ex_table = .;
    }

    NOTES :text :note
    @@ -67,7 +61,7 @@ SECTIONS
    . = ALIGN(4);
    .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
    __tracedata_start = .;
    - *(.tracedata)
    + KEEP(*(.tracedata)) /* really need to KEEP? */
    __tracedata_end = .;
    }

    @@ -83,7 +77,7 @@ SECTIONS
    . = ALIGN(4096);
    .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
    __nosave_begin = .;
    - *(.nosave.data)
    + *(.nosave.data) /* not saved by suspend */
    . = ALIGN(4096);
    __nosave_end = .;
    }
    @@ -115,7 +109,7 @@ SECTIONS
    . = ALIGN(4096);
    .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
    __smp_locks = .;
    - *(.smp_locks)
    + KEEP(*(.smp_locks)) /* points to lock prefixes */
    __smp_locks_end = .;
    }
    /* will be freed after init
    @@ -134,11 +128,11 @@ SECTIONS
    *(.init.text)
    _einittext = .;
    }
    - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
    + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } /* no need to KEEP */
    . = ALIGN(16);
    .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
    __setup_start = .;
    - *(.init.setup)
    + KEEP(*(.init.setup)) /* obsolete_checksetup() walks it */
    __setup_end = .;
    }
    .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
    @@ -148,26 +142,26 @@ SECTIONS
    }
    .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
    __con_initcall_start = .;
    - *(.con_initcall.init)
    + KEEP(*(.con_initcall.init)) /* console_init() walks it */
    __con_initcall_end = .;
    }
    SECURITY_INIT
    . = ALIGN(4);
    .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
    __alt_instructions = .;
    - *(.altinstructions)
    + KEEP(*(.altinstructions)) /* alternative_instructions() walks it */
    __alt_instructions_end = .;
    }
    .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
    - *(.altinstr_replacement)
    + KEEP(*(.altinstr_replacement))
    }
    . = ALIGN(4);
    .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
    __parainstructions = .;
    - *(.parainstructions)
    + KEEP(*(.parainstructions)) /* really need to KEEP? */
    __parainstructions_end = .;
    }
    - /* .exit.text is discard at runtime, not link time, to deal with references
    + /* .exit.text is discarded 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) }
    @@ -175,7 +169,7 @@ SECTIONS
    . = ALIGN(4096);
    .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
    __initramfs_start = .;
    - *(.init.ramfs)
    + KEEP(*(.init.ramfs))
    __initramfs_end = .;
    }
    #endif
    @@ -192,8 +186,17 @@ SECTIONS
    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
    __init_end = .;
    __bss_start = .; /* BSS */
    +
    + /* Why such strage name - .bss.k.page_aligned?
    + * .bss.page_aligned may clash with a section produced by gcc -fdata_sections.
    + * .bss_page_aligned, .page_aligned_bss will not work because
    + * we must use .bss.xxx section names for zero-initialized sections
    + * we want to combine into bss, otherwise gcc does not set
    + * 'nobits' flag for the section, and it cannot be merged into bss.
    + */
    *(.bss.k.page_aligned)
    *(.bss)
    + *(SORT_BY_ALIGNMENT(.bss.*))
    . = ALIGN(4);
    __bss_stop = .;
    _end = . ;
    diff -urpN linux-2.6.gc2/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.gc3/arch/x86/kernel/vmlinux_64.lds.S
    --- linux-2.6.gc2/arch/x86/kernel/vmlinux_64.lds.S 2007-11-23 22:00:09.000000000 -0800
    +++ linux-2.6.gc3/arch/x86/kernel/vmlinux_64.lds.S 2007-11-23 21:49:45.000000000 -0800
    @@ -28,14 +28,14 @@ SECTIONS
    _text = .; /* Text and read-only data */
    .text : AT(ADDR(.text) - LOAD_OFFSET) {
    /* First the code that has to be first for bootstrapping */
    - *(.head.text)
    + KEEP(*(.head.text))
    _stext = .;
    /* Then the rest */
    TEXT_TEXT
    SCHED_TEXT
    LOCK_TEXT
    KPROBES_TEXT
    - *(.fixup)
    + *(.fixup) /* no need to KEEP, every .fixup is referenced by __ex_table */
    *(.gnu.warning)
    } :text = 0x9090
    /* out-of-line lock text */
    @@ -45,7 +45,8 @@ SECTIONS

    . = ALIGN(16); /* Exception table */
    __start___ex_table = .;
    - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
    + /* Points to potentially-faulting insns and corresponding .fixups */
    + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { KEEP(*(__ex_table)) }
    __stop___ex_table = .;

    NOTES :text :note
    @@ -57,7 +58,7 @@ SECTIONS
    . = ALIGN(4);
    .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
    __tracedata_start = .;
    - *(.tracedata)
    + KEEP(*(.tracedata)) /* really need to KEEP? */
    __tracedata_end = .;
    }

    @@ -91,24 +92,24 @@ SECTIONS
    #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)

    . = VSYSCALL_ADDR;
    - .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user
    + .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { KEEP(*(.vsyscall_0)) } :user
    __vsyscall_0 = VSYSCALL_VIRT_ADDR;

    . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
    - .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) { *(.vsyscall_fn) }
    + .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) { KEEP(*(.vsyscall_fn)) }
    . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
    .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data))
    - { *(.vsyscall_gtod_data) }
    + { KEEP(*(.vsyscall_gtod_data)) }
    vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
    .vsyscall_clock : AT(VLOAD(.vsyscall_clock))
    - { *(.vsyscall_clock) }
    + { KEEP(*(.vsyscall_clock)) }
    vsyscall_clock = VVIRT(.vsyscall_clock);


    .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1))
    - { *(.vsyscall_1) }
    + { KEEP(*(.vsyscall_1)) }
    .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2))
    - { *(.vsyscall_2) }
    + { KEEP(*(.vsyscall_2)) }

    .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) }
    vgetcpu_mode = VVIRT(.vgetcpu_mode);
    @@ -118,7 +119,7 @@ SECTIONS
    jiffies = VVIRT(.jiffies);

    .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3))
    - { *(.vsyscall_3) }
    + { KEEP(*(.vsyscall_3)) }

    . = VSYSCALL_VIRT_ADDR + 4096;

    @@ -145,7 +146,7 @@ SECTIONS
    __smp_alt_begin = .;
    __smp_locks = .;
    .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
    - *(.smp_locks)
    + KEEP(*(.smp_locks)) /* points to lock prefixes */
    }
    __smp_locks_end = .;
    . = ALIGN(4096);
    @@ -159,11 +160,11 @@ SECTIONS
    _einittext = .;
    }
    __initdata_begin = .;
    - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
    + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } /* no need to KEEP */
    __initdata_end = .;
    . = ALIGN(16);
    __setup_start = .;
    - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
    + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { KEEP(*(.init.setup)) } /* obsolete_checksetup() walks it */
    __setup_end = .;
    __initcall_start = .;
    .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
    @@ -172,18 +173,18 @@ SECTIONS
    __initcall_end = .;
    __con_initcall_start = .;
    .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
    - *(.con_initcall.init)
    + KEEP(*(.con_initcall.init)) /* console_init() walks it */
    }
    __con_initcall_end = .;
    SECURITY_INIT
    . = ALIGN(8);
    __alt_instructions = .;
    .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
    - *(.altinstructions)
    + KEEP(*(.altinstructions)) /* alternative_instructions() walks it */
    }
    __alt_instructions_end = .;
    .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
    - *(.altinstr_replacement)
    + KEEP(*(.altinstr_replacement))
    }
    /* .exit.text is discard at runtime, not link time, to deal with references
    from .altinstructions and .eh_frame */
    @@ -192,14 +193,14 @@ SECTIONS

    /* vdso blob that is mapped into user space */
    vdso_start = . ;
    - .vdso : AT(ADDR(.vdso) - LOAD_OFFSET) { *(.vdso) }
    + .vdso : AT(ADDR(.vdso) - LOAD_OFFSET) { KEEP(*(.vdso)) }
    . = ALIGN(4096);
    vdso_end = .;

    #ifdef CONFIG_BLK_DEV_INITRD
    . = ALIGN(4096);
    __initramfs_start = .;
    - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
    + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { KEEP(*(.init.ramfs)) }
    __initramfs_end = .;
    #endif

    @@ -210,14 +211,23 @@ SECTIONS

    . = ALIGN(4096);
    __nosave_begin = .;
    - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.nosave.data) }
    + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.nosave.data) } /* not saved by suspend */
    . = ALIGN(4096);
    __nosave_end = .;

    __bss_start = .; /* BSS */
    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
    +
    + /* Why such strage name - .bss.k.page_aligned?
    + * .bss.page_aligned may clash with a section produced by gcc -fdata_sections.
    + * .bss_page_aligned, .page_aligned_bss will not work because
    + * we must use .bss.xxx section names for zero-initialized sections
    + * we want to combine into bss, otherwise gcc does not set
    + * 'nobits' flag for the section, and it cannot be merged into bss.
    + */
    *(.bss.k.page_aligned)
    *(.bss)
    + *(SORT_BY_ALIGNMENT(.bss.*))
    }
    __bss_stop = .;

    diff -urpN linux-2.6.gc2/arch/x86/kernel/vsyscall_32.lds.S linux-2.6.gc3/arch/x86/kernel/vsyscall_32.lds.S
    --- linux-2.6.gc2/arch/x86/kernel/vsyscall_32.lds.S 2007-11-23 18:55:10.000000000 -0800
    +++ linux-2.6.gc3/arch/x86/kernel/vsyscall_32.lds.S 2007-11-23 22:05:37.000000000 -0800
    @@ -23,10 +23,10 @@ SECTIONS
    is insufficient, ld -shared will barf. Just increase it here. */
    . = VDSO_PRELINK_asm + 0x400;

    - .text : { *(.text) } :text =0x90909090
    + .text : { *(.text .text.*) } :text =0x90909090
    .note : { *(.note.*) } :text :note
    .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
    - .eh_frame : { KEEP (*(.eh_frame)) } :text
    + .eh_frame : { KEEP(*(.eh_frame)) } :text
    .dynamic : { *(.dynamic) } :text :dynamic
    .useless : {
    *(.got.plt) *(.got)
    diff -urpN linux-2.6.gc2/arch/xtensa/kernel/vmlinux.lds.S linux-2.6.gc3/arch/xtensa/kernel/vmlinux.lds.S
    --- linux-2.6.gc2/arch/xtensa/kernel/vmlinux.lds.S 2007-11-23 22:00:09.000000000 -0800
    +++ linux-2.6.gc3/arch/xtensa/kernel/vmlinux.lds.S 2007-11-23 21:33:37.000000000 -0800
    @@ -255,7 +255,15 @@ SECTIONS

    /* BSS section */
    _bss_start = .;
    - .bss : { *(.bss.k.page_aligned) *(.bss) }
    +
    + /* Why such strage name - .bss.k.page_aligned?
    + * .bss.page_aligned may clash with a section produced by gcc -fdata_sections.
    + * .bss_page_aligned, .page_aligned_bss will not work because
    + * we must use .bss.xxx section names for zero-initialized sections
    + * we want to combine into bss, otherwise gcc does not set
    + * 'nobits' flag for the section, and it cannot be merged into bss.
    + */
    + .bss : { *(.bss.k.page_aligned) *(.bss) *(.bss.*) }
    _bss_end = .;

    _end = .;
    diff -urpN linux-2.6.gc2/include/asm-generic/vmlinux.lds.h linux-2.6.gc3/include/asm-generic/vmlinux.lds.h
    --- linux-2.6.gc2/include/asm-generic/vmlinux.lds.h 2007-11-23 20:55:54.000000000 -0800
    +++ linux-2.6.gc3/include/asm-generic/vmlinux.lds.h 2007-11-23 21:15:24.000000000 -0800
    @@ -6,12 +6,19 @@
    #define VMLINUX_SYMBOL(_sym_) _sym_
    #endif

    +#ifndef CONFIG_DISCARD_UNUSED_SECTIONS
    +/* Don't confuse old ld with new stuff */
    +#define KEEP(x) x
    +#define SORT_BY_ALIGNMENT(x) x
    +#endif
    +
    /* Align . to a 8 byte boundary equals to maximum function alignment. */
    #define ALIGN_FUNCTION() . = ALIGN(8)

    /* .data section */
    #define DATA_DATA \
    *(.data) \
    + *(SORT_BY_ALIGNMENT(.data.*)) \
    *(.init.refok.data) \
    . = ALIGN(8); \
    VMLINUX_SYMBOL(__start___markers) = .; \
    @@ -22,7 +29,7 @@
    . = ALIGN((align)); \
    .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start_rodata) = .; \
    - *(.rodata) *(.rodata.*) \
    + *(.rodata) *(SORT_BY_ALIGNMENT(.rodata.*)) \
    *(__vermagic) /* Kernel version magic */ \
    *(__markers_strings) /* Markers: strings */ \
    } \
    @@ -33,109 +40,110 @@
    \
    /* PCI quirks */ \
    .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \
    + /* walked by pci_fixup_device() */ \
    VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \
    - *(.pci_fixup_early) \
    + KEEP(*(.pci_fixup_early)) \
    VMLINUX_SYMBOL(__end_pci_fixups_early) = .; \
    VMLINUX_SYMBOL(__start_pci_fixups_header) = .; \
    - *(.pci_fixup_header) \
    + KEEP(*(.pci_fixup_header)) \
    VMLINUX_SYMBOL(__end_pci_fixups_header) = .; \
    VMLINUX_SYMBOL(__start_pci_fixups_final) = .; \
    - *(.pci_fixup_final) \
    + KEEP(*(.pci_fixup_final)) \
    VMLINUX_SYMBOL(__end_pci_fixups_final) = .; \
    VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \
    - *(.pci_fixup_enable) \
    + KEEP(*(.pci_fixup_enable)) \
    VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \
    VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \
    - *(.pci_fixup_resume) \
    + KEEP(*(.pci_fixup_resume)) \
    VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
    } \
    \
    /* RapidIO route ops */ \
    .rio_route : AT(ADDR(.rio_route) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start_rio_route_ops) = .; \
    - *(.rio_route_ops) \
    + KEEP(*(.rio_route_ops)) \
    VMLINUX_SYMBOL(__end_rio_route_ops) = .; \
    } \
    \
    /* Kernel symbol table: Normal symbols */ \
    __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___ksymtab) = .; \
    - *(__ksymtab) \
    + KEEP(*(__ksymtab)) \
    VMLINUX_SYMBOL(__stop___ksymtab) = .; \
    } \
    \
    /* Kernel symbol table: GPL-only symbols */ \
    __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \
    - *(__ksymtab_gpl) \
    + KEEP(*(__ksymtab_gpl)) \
    VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
    } \
    \
    /* Kernel symbol table: Normal unused symbols */ \
    __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \
    - *(__ksymtab_unused) \
    + KEEP(*(__ksymtab_unused)) \
    VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \
    } \
    \
    /* Kernel symbol table: GPL-only unused symbols */ \
    __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \
    - *(__ksymtab_unused_gpl) \
    + KEEP(*(__ksymtab_unused_gpl)) \
    VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \
    } \
    \
    /* Kernel symbol table: GPL-future-only symbols */ \
    __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
    - *(__ksymtab_gpl_future) \
    + KEEP(*(__ksymtab_gpl_future)) \
    VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \
    } \
    \
    /* Kernel symbol table: Normal symbols */ \
    __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___kcrctab) = .; \
    - *(__kcrctab) \
    + KEEP(*(__kcrctab)) \
    VMLINUX_SYMBOL(__stop___kcrctab) = .; \
    } \
    \
    /* Kernel symbol table: GPL-only symbols */ \
    __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \
    - *(__kcrctab_gpl) \
    + KEEP(*(__kcrctab_gpl)) \
    VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \
    } \
    \
    /* Kernel symbol table: Normal unused symbols */ \
    __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \
    - *(__kcrctab_unused) \
    + KEEP(*(__kcrctab_unused)) \
    VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \
    } \
    \
    /* Kernel symbol table: GPL-only unused symbols */ \
    __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \
    - *(__kcrctab_unused_gpl) \
    + KEEP(*(__kcrctab_unused_gpl)) \
    VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \
    } \
    \
    /* Kernel symbol table: GPL-future-only symbols */ \
    __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \
    - *(__kcrctab_gpl_future) \
    + KEEP(*(__kcrctab_gpl_future)) \
    VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \
    } \
    \
    /* Kernel symbol table: strings */ \
    __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
    - *(__ksymtab_strings) \
    + KEEP(*(__ksymtab_strings)) \
    } \
    \
    /* Built-in module parameters. */ \
    __param : AT(ADDR(__param) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___param) = .; \
    - *(__param) \
    + KEEP(*(__param)) \
    VMLINUX_SYMBOL(__stop___param) = .; \
    VMLINUX_SYMBOL(__end_rodata) = .; \
    } \
    @@ -149,7 +157,7 @@
    #define SECURITY_INIT \
    .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__security_initcall_start) = .; \
    - *(.security_initcall.init) \
    + KEEP(*(.security_initcall.init)) \
    VMLINUX_SYMBOL(__security_initcall_end) = .; \
    }

    @@ -158,6 +166,7 @@
    #define TEXT_TEXT \
    ALIGN_FUNCTION(); \
    *(.text) \
    + *(SORT_BY_ALIGNMENT(.text.*)) \
    *(.init.refok.text) \
    *(.exit.text.refok)

    @@ -166,6 +175,7 @@
    #define SCHED_TEXT \
    ALIGN_FUNCTION(); \
    VMLINUX_SYMBOL(__sched_text_start) = .; \
    + /* No need to KEEP */ \
    *(.sched.text) \
    VMLINUX_SYMBOL(__sched_text_end) = .;

    @@ -174,12 +184,14 @@
    #define LOCK_TEXT \
    ALIGN_FUNCTION(); \
    VMLINUX_SYMBOL(__lock_text_start) = .; \
    + /* No need to KEEP */ \
    *(.spinlock.text) \
    VMLINUX_SYMBOL(__lock_text_end) = .;

    #define KPROBES_TEXT \
    ALIGN_FUNCTION(); \
    VMLINUX_SYMBOL(__kprobes_text_start) = .; \
    + /* No need to KEEP */ \
    *(.kprobes.text) \
    VMLINUX_SYMBOL(__kprobes_text_end) = .;

    @@ -225,35 +237,37 @@
    . = ALIGN(8); \
    __bug_table : AT(ADDR(__bug_table) - LOAD_OFFSET) { \
    __start___bug_table = .; \
    - *(__bug_table) \
    + /* Support for BUG() */ \
    + KEEP(*(__bug_table)) \
    __stop___bug_table = .; \
    }

    #define NOTES \
    .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start_notes) = .; \
    - *(.note.*) \
    + /* For /sys/kernel/notes */ \
    + KEEP(*(.note.*)) \
    VMLINUX_SYMBOL(__stop_notes) = .; \
    }

    #define INITCALLS \
    - *(.initcall0.init) \
    - *(.initcall0s.init) \
    - *(.initcall1.init) \
    - *(.initcall1s.init) \
    - *(.initcall2.init) \
    - *(.initcall2s.init) \
    - *(.initcall3.init) \
    - *(.initcall3s.init) \
    - *(.initcall4.init) \
    - *(.initcall4s.init) \
    - *(.initcall5.init) \
    - *(.initcall5s.init) \
    - *(.initcallrootfs.init) \
    - *(.initcall6.init) \
    - *(.initcall6s.init) \
    - *(.initcall7.init) \
    - *(.initcall7s.init)
    + KEEP(*(.initcall0.init)) /* do_initcalls() walks them */ \
    + KEEP(*(.initcall0s.init)) \
    + KEEP(*(.initcall1.init)) \
    + KEEP(*(.initcall1s.init)) \
    + KEEP(*(.initcall2.init)) \
    + KEEP(*(.initcall2s.init)) \
    + KEEP(*(.initcall3.init)) \
    + KEEP(*(.initcall3s.init)) \
    + KEEP(*(.initcall4.init)) \
    + KEEP(*(.initcall4s.init)) \
    + KEEP(*(.initcall5.init)) \
    + KEEP(*(.initcall5s.init)) \
    + KEEP(*(.initcallrootfs.init)) \
    + KEEP(*(.initcall6.init)) \
    + KEEP(*(.initcall6s.init)) \
    + KEEP(*(.initcall7.init)) \
    + KEEP(*(.initcall7s.init))

    #define PERCPU(align) \
    . = ALIGN(align); \
    diff -urpN linux-2.6.gc2/init/Kconfig linux-2.6.gc3/init/Kconfig
    --- linux-2.6.gc2/init/Kconfig 2007-11-23 18:55:26.000000000 -0800
    +++ linux-2.6.gc3/init/Kconfig 2007-11-23 22:22:31.000000000 -0800
    @@ -425,6 +425,23 @@ config CC_OPTIMIZE_FOR_SIZE

    If unsure, say N.

    +config DISCARD_UNUSED_SECTIONS
    + bool "Discard unused code/data sections (DANGEROUS)"
    + default n
    + depends on EXPERIMENTAL
    + help
    + Enabling this option will pass --ffunction-sections -fdata-sections
    + to gcc and --gc-sections to ld, resulting in a smaller kernel.
    +
    + WARNING: --gc-sections support is very new and considered highly
    + experimental for now. You need at least binutils 2.18,
    + and even then surprises are likely.
    +
    + This option also requires architecture-specific changes.
    + Currently working architectures: x86
    +
    + If unsure, say N.
    +
    config SYSCTL
    bool

    diff -urpN linux-2.6.gc2/scripts/Makefile.modpost linux-2.6.gc3/scripts/Makefile.modpost
    --- linux-2.6.gc2/scripts/Makefile.modpost 2007-11-23 18:55:26.000000000 -0800
    +++ linux-2.6.gc3/scripts/Makefile.modpost 2007-11-24 14:46:38.000000000 -0800
    @@ -97,9 +97,15 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c
    targets += $(modules:.ko=.mod.o)

    # Step 6), final link of the modules
    +ifdef CONFIG_DISCARD_UNUSED_SECTIONS
    +quiet_cmd_ld_ko_o = LD [M] $@
    + cmd_ld_ko_o = $(LD) -r -T arch/$(SRCARCH)/kernel/modules.lds $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ -Map $@.map \
    + $(filter-out FORCE,$^)
    +else
    quiet_cmd_ld_ko_o = LD [M] $@
    cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
    $(filter-out FORCE,$^)
    +endif

    $(modules): %.ko :%.o %.mod.o FORCE
    $(call if_changed,ld_ko_o)
    \
     
     \ /
      Last update: 2007-11-25 00:21    [W:0.130 / U:0.752 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site