diff -urpN linux-2.6.23-rc4.gc5/arch/i386/kernel/modules.lds linux-2.6.23-rc4.gc6/arch/i386/kernel/modules.lds --- linux-2.6.23-rc4.gc5/arch/i386/kernel/modules.lds 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.23-rc4.gc6/arch/i386/kernel/modules.lds 2007-09-12 19:49:10.000000000 +0100 @@ -0,0 +1,123 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) + +/* +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. + +This script may be usable without CONFIG_DISCARD_UNUSED_SECTIONS too. + +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 + +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.23-rc4.gc5/arch/i386/kernel/vmlinux.lds.S linux-2.6.23-rc4.gc6/arch/i386/kernel/vmlinux.lds.S --- linux-2.6.23-rc4.gc5/arch/i386/kernel/vmlinux.lds.S 2007-09-12 19:46:32.000000000 +0100 +++ linux-2.6.23-rc4.gc6/arch/i386/kernel/vmlinux.lds.S 2007-09-12 19:51:42.000000000 +0100 @@ -32,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 */ @@ -41,6 +41,7 @@ SECTIONS SCHED_TEXT LOCK_TEXT KPROBES_TEXT + /* No need to KEEP - referenced by __ex_table */ *(.fixup) *(.gnu.warning) _etext = .; /* End of text section */ @@ -49,7 +50,7 @@ SECTIONS . = ALIGN(16); /* Exception table */ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { __start___ex_table = .; - *(__ex_table) + KEEP(*(__ex_table)) __stop___ex_table = .; } @@ -60,7 +61,8 @@ SECTIONS . = ALIGN(4); .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { __tracedata_start = .; - *(.tracedata) + /* Resume debug tracing */ + KEEP(*(.tracedata)) __tracedata_end = .; } @@ -71,11 +73,12 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ DATA_DATA CONSTRUCTORS - } :data + } :data . = ALIGN(4096); .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { __nosave_begin = .; + /* No need to KEEP */ *(.nosave.data) . = ALIGN(4096); __nosave_end = .; @@ -108,19 +111,13 @@ SECTIONS . = ALIGN(4096); .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { __smp_locks = .; - *(.smp_locks) + KEEP(*(.smp_locks)) __smp_locks_end = .; } - /* will be freed after init - * Following ALIGN() is required to make sure no other data falls on the - * same page where __smp_alt_end is pointing as that page might be freed - * after boot. Always make sure that ALIGN() directive is present after - * the section which contains __smp_alt_end. - */ - . = ALIGN(4096); - /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ + /* Will be freed after init */ + /* Init code and data */ + . = ALIGN(4096); .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { __init_begin = .; _sinittext = .; @@ -131,7 +128,9 @@ SECTIONS . = ALIGN(16); .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { __setup_start = .; - *(.init.setup) + /* __setup_param() macro produces these, + * obsolete_checksetup() processes them */ + KEEP(*(.init.setup)) __setup_end = .; } .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { @@ -141,46 +140,50 @@ SECTIONS } .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { __con_initcall_start = .; - *(.con_initcall.init) + KEEP(*(.con_initcall.init)) __con_initcall_end = .; } SECURITY_INIT . = ALIGN(4); .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { __alt_instructions = .; - *(.altinstructions) + KEEP(*(.altinstructions)) __alt_instructions_end = .; } .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { + /* No need to KEEP - referenced by .altinstructions */ *(.altinstr_replacement) } . = ALIGN(4); .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { __parainstructions = .; - *(.parainstructions) + KEEP(*(.parainstructions)) __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) } + #if defined(CONFIG_BLK_DEV_INITRD) . = ALIGN(4096); .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { __initramfs_start = .; - *(.init.ramfs) + KEEP(*(.init.ramfs)) __initramfs_end = .; } #endif + . = ALIGN(4096); - .percpu.data : AT(ADDR(.percpu.data) - LOAD_OFFSET) { + .percpu.data : AT(ADDR(.percpu.data) - LOAD_OFFSET) { __per_cpu_start = .; *(.percpu.data) *(.percpu.shared_aligned.data) __per_cpu_end = .; } . = ALIGN(4096); - /* freed after init ends here */ + + /* End of "freed after init" portion */ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { __init_end = .; @@ -189,7 +192,7 @@ 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 = . ; @@ -201,7 +204,7 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { *(.exitcall.exit) - } + } STABS_DEBUG diff -urpN linux-2.6.23-rc4.gc5/init/Kconfig linux-2.6.23-rc4.gc6/init/Kconfig --- linux-2.6.23-rc4.gc5/init/Kconfig 2007-09-12 19:46:32.000000000 +0100 +++ linux-2.6.23-rc4.gc6/init/Kconfig 2007-09-12 21:23:39.000000000 +0100 @@ -360,7 +360,7 @@ config DISCARD_UNUSED_SECTIONS and even then surprises are likely. This option also requires architecture-specific changes. - Currently working architectures: x86_64 + Currently working architectures: x86_64, i386 If unsure, say N.