[PATCH 2/4] module linker script: coalesce function and data sections

From: Denys Vlasenko
Date: Wed Jul 28 2010 - 19:49:24 EST


gcc -ffunction-sections -fdata-sections places each function foo
into separate section .text.foo, and every data object bar into
separate section .data.bar, .rodata.bar or .bss.bar.

This fix prevents kernel modules from having unnecessarily many
sections and thus prevents module size growth when we pass
-ffunction-sections -fdata-sections to gcc.

Module linker script needs to avoid collecting special kernel sections,
therefore it uses more restrictive patterns like *(.text.[A-Za-z0-9_$^]*)
instead of simplistic *(.text.*): special kernel sections like
.text..page_aligned contain double dots and won't be accidentally
matched by them.

Signed-off-by: Denys Vlasenko <vda.linux@xxxxxxxxxxxxxx>
Acked-by: Sam Ravnborg <sam@xxxxxxxxxxxx>
---
scripts/module-common.lds | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/scripts/module-common.lds b/scripts/module-common.lds
index 47a1f9a..4a197e8 100644
--- a/scripts/module-common.lds
+++ b/scripts/module-common.lds
@@ -3,6 +3,29 @@
* Archs are free to supply their own linker scripts. ld will
* combine them automatically.
*/
+
+/* .data.foo are generated by gcc itself with -fdata-sections,
+ * whereas double-dot sections (like .data..percpu) are generated
+ * by kernel's magic macros.
+ *
+ * Since this script does not specify what to do with double-dot sections,
+ * ld -r will coalesce all .data..foo input sections into one .data..foo
+ * output section, all .data..bar input sections into one .data..bar
+ * output section and so on. This is exactly what we want.
+ *
+ * Same goes for .text, .bss and .rodata. In case of .rodata, various
+ * .rodata.foo sections are generated by gcc even without -fdata-sections
+ */
+
SECTIONS {
+
+ /* Coalesce sections produced by gcc -ffunction-sections */
+ .text 0 : AT(0) { *(.text .text.[A-Za-z0-9_$^]*) }
+
+ /* Coalesce sections produced by gcc -fdata-sections */
+ .rodata 0 : AT(0) { *(.rodata .rodata.[A-Za-z0-9_$^]*) }
+ .data 0 : AT(0) { *(.data .data.[A-Za-z0-9_$^]*) }
+ .bss 0 : AT(0) { *(.bss .bss.[A-Za-z0-9_$^]*) }
+
/DISCARD/ : { *(.discard) }
}
--
1.6.2.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/