linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] build system: section garbage collection for vmlinux
@ 2007-09-11 20:05 Denys Vlasenko
  2007-09-11 20:07 ` [PATCH 1/4] " Denys Vlasenko
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Denys Vlasenko @ 2007-09-11 20:05 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

Build system: section garbage collection for vmlinux

Newer gcc and binutils can do dead code and data removal
at link time. It is achieved using combination of
-ffunction-sections -fdata-sections options for gcc and
--gc-sections for ld.

Theory of operation:

Option -ffunction-sections instructs gcc to place each function
(including static ones) in it's own section named .text.function_name
instead of placing all functions in one big .text section.

At link time, ld normally coalesce all such sections into one
output section .text again. It is achieved by having *(.text.*) spec
along with *(.text) spec in built-in linker scripts.

If ld is invoked with --gc-sections, it tracks references, starting
from entry point and marks all input sections which are reachable
from there. Then it discards all input sections which are not marked.

This isn't buying much if you have one big .text section per .o module,
because even one referenced function will pull in entire section.
You need -ffunction-sections in order to split .text into per-function
sections and make --gc-sections much more useful.

-fdata-sections is analogous: it places each global or static variable
into .data.variable_name, .rodata.variable_name or .bss.variable_name.

How to use it in kernel:

First, we need to adapt existing code for new section names.
Basically, we need to stop using section names of the form
.text.xxxx
.data.xxxx
.rodata.xxxx
.bss.xxxx
in the kernel for - otherwise section placement done by kernel's
custom linker scripts produces broken vmlinux and vdso images.

Second, kernel linker scripts need to be adapted by adding KEEP(xxx)
directives around sections which are not directly referenced, but are
nevertheless used (initcalls, altinstructions, etc).

These patches fix section names and add
CONFIG_DISCARD_UNUSED_SECTIONS. It is not enabled
unconditionally because only newest binutils have
ld --gc-sections which is stable enough for kernel use.
IOW: this is an experimental feature for now.

Patches are conservative and mark a lot of things with
KEEP() directive in linker script, inhibiting GC for them.

With CONFIG_MODULES=y, all EXPORT_SYMBOLed functions
are not discarded.

In this case size savings typically look like this:

   text    data     bss     dec     hex filename
5159478 1005139  406784 6571401  644589 linux-2.6.23-rc4.org/vmlinux
5131822  996090  401439 6529351  63a147 linux-2.6.23-rc4.gc/vmlinux

In this particular case, 402 objects were discarded, saving 42 kb.

With CONFIG_MODULE not set, size savings are bigger - around 10%
of vmlinux size.

Linker is unable to discard more because current infrastructure
is a bit flawed in this regard. It prevents some unused code
from being detected. In particular:
KEEP(__ex_table) -> .fixup -> get_user and friends
KEEP(.smp_locks) -> lock prefixes

I am working on improving this, thanks to suggestions from lkml readers.

Patches were run-tested on x86_64, and likely do not work on any other arch
(need to add KEEP() to arch/*/kernel/vmlinux.lds.S for each arch).

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/4] build system: section garbage collection for vmlinux
  2007-09-11 20:05 [PATCH 0/4] build system: section garbage collection for vmlinux Denys Vlasenko
@ 2007-09-11 20:07 ` Denys Vlasenko
  2007-09-11 20:10   ` [PATCH 2/4] " Denys Vlasenko
  2007-09-11 21:47   ` [PATCH 1/4] " Daniel Walker
  2007-09-11 21:03 ` [PATCH 0/4] " Andi Kleen
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 18+ messages in thread
From: Denys Vlasenko @ 2007-09-11 20:07 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]

This patch is needed for --gc-sections to work, regardless
of which final form that support will have.

This patch renames .text.xxx and .data.xxx sections
into .xxx.text and .xxx.data, respectively.

.bss.page_aligned (the only .bss.xxx -like section we have)
is renamed .bss.k.page_aligned. ".page_aligned.bss"
wouldn't work - gcc will assign such section attributes
which make it unmergeable with .bss. In fact, binutils ld
had a bug and instead of complaining was producing
broken vmlinux. The bug is fixed in binutils. Amazingly
fast reaction from binutils folks to bug reports! Thanks!

.bss.k.page_aligned is more-or-less ok, since it cannot collide
with gcc-produced sections due to second dot in the name. However,
should we want to do this in linker script:

.bss : { *(.bss) *(.bss.*) *(.bss.k.page_aligned))

it wouldn't work. But currently we don't need that.

If patch doesn't apply to a newer kernel,
you can regenerate it by running linux-2.6.23-rc4.0.fixname.sh
in a kernel free and rediffing it against unmodified one.

Please apply.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

[-- Attachment #2: linux-2.6.23-rc4.0.fixname.sh --]
[-- Type: application/x-shellscript, Size: 1061 bytes --]

[-- Attachment #3: linux-2.6.23-rc4.1.fixname.patch.bz2 --]
[-- Type: application/x-bzip2, Size: 14440 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2/4] build system: section garbage collection for vmlinux
  2007-09-11 20:07 ` [PATCH 1/4] " Denys Vlasenko
@ 2007-09-11 20:10   ` Denys Vlasenko
  2007-09-11 20:11     ` [PATCH 3/4] " Denys Vlasenko
  2007-09-11 21:47   ` [PATCH 1/4] " Daniel Walker
  1 sibling, 1 reply; 18+ messages in thread
From: Denys Vlasenko @ 2007-09-11 20:10 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 264 bytes --]

This patch fixes x86_64 vdso image so that it builds with --gc-sections.

Then it fixes comment in arch/i386/kernel/vmlinux.lds.S
and adds comments to other linker scripts about .bss.

Please apply.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

[-- Attachment #2: linux-2.6.23-rc4.2.lds.patch --]
[-- Type: text/x-diff, Size: 3738 bytes --]

--- linux-2.6.23-rc4.gc1/arch/x86_64/vdso/vdso.lds.S	Sat Sep  8 22:06:52 2007
+++ linux-2.6.23-rc4.gc2/arch/x86_64/vdso/vdso.lds.S	Sat Sep  8 22:07:05 2007
@@ -26,11 +26,11 @@
      is insufficient, ld -shared will barf.  Just increase it here.  */
   . = VDSO_PRELINK + VDSO_TEXT_OFFSET;
 
-  .text           : { *(.text) }		:text
+  .text           : { *(.text) *(.text.*) }	:text
   .ptr.text       : { *(.ptr.text) }		:text
   . = VDSO_PRELINK + 0x900;
-  .data           : { *(.data) }		:text
-  .bss            : { *(.bss) }			:text
+  .data           : { *(.data) *(.data.*) }	:text
+  .bss            : { *(.bss) *(.bss.*) }	:text
 
   .altinstructions : { *(.altinstructions) }			:text
   .altinstr_replacement  : { *(.altinstr_replacement) }	:text
diff -urpN linux-2.6.23-rc4.gc1/arch/i386/kernel/vmlinux.lds.S linux-2.6.23-rc4.gc2/arch/i386/kernel/vmlinux.lds.S
--- linux-2.6.23-rc4.gc1/arch/i386/kernel/vmlinux.lds.S	2007-09-10 18:54:38.000000000 +0100
+++ linux-2.6.23-rc4.gc2/arch/i386/kernel/vmlinux.lds.S	2007-09-10 19:09:24.000000000 +0100
@@ -2,17 +2,10 @@
  * 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
+ * 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.
- */
-
-/* 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.
+ * change if kernel is relocated, make the symbol section relative
+ * by putting it inside the section definition.
  */
 #define LOAD_OFFSET __PAGE_OFFSET
 
@@ -192,6 +185,9 @@ SECTIONS
   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
 	__init_end = .;
 	__bss_start = .;		/* BSS */
+        /* 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)
 	. = ALIGN(4);
diff -urpN linux-2.6.23-rc4.gc1/arch/sh/kernel/vmlinux.lds.S linux-2.6.23-rc4.gc2/arch/sh/kernel/vmlinux.lds.S
--- linux-2.6.23-rc4.gc1/arch/sh/kernel/vmlinux.lds.S	2007-09-10 18:54:38.000000000 +0100
+++ linux-2.6.23-rc4.gc2/arch/sh/kernel/vmlinux.lds.S	2007-09-10 19:09:24.000000000 +0100
@@ -104,6 +104,9 @@ SECTIONS
   .bss : {
 	__init_end = .;
 	__bss_start = .;		/* BSS */
+        /* 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)
 	. = ALIGN(4);
diff -urpN linux-2.6.23-rc4.gc1/arch/xtensa/kernel/vmlinux.lds.S linux-2.6.23-rc4.gc2/arch/xtensa/kernel/vmlinux.lds.S
--- linux-2.6.23-rc4.gc1/arch/xtensa/kernel/vmlinux.lds.S	2007-09-10 18:54:38.000000000 +0100
+++ linux-2.6.23-rc4.gc2/arch/xtensa/kernel/vmlinux.lds.S	2007-09-10 19:09:24.000000000 +0100
@@ -255,6 +255,9 @@ SECTIONS
 
   /* BSS section */
   _bss_start = .;
+  /* 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_end = .;
 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/4] build system: section garbage collection for vmlinux
  2007-09-11 20:10   ` [PATCH 2/4] " Denys Vlasenko
@ 2007-09-11 20:11     ` Denys Vlasenko
  2007-09-11 20:22       ` [PATCH 4/4] " Denys Vlasenko
  0 siblings, 1 reply; 18+ messages in thread
From: Denys Vlasenko @ 2007-09-11 20:11 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 328 bytes --]

This patch makes modpost able to process object files with more than
64k sections. Needed for huge kernel builds (allyesconfig, for example)
with --gc-sections.

This patch basically fixes modpost, it isn't specific
for section garbage collection.

Please apply.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

[-- Attachment #2: linux-2.6.23-rc4.3.modpost_fix.patch --]
[-- Type: text/x-diff, Size: 8818 bytes --]

--- linux-2.6.23-rc4.gc2/scripts/mod/file2alias.c	Sun Sep  2 17:29:37 2007
+++ linux-2.6.23-rc4.gc3/scripts/mod/file2alias.c	Sat Sep  8 22:07:54 2007
@@ -529,11 +529,11 @@
 	void *symval;
 
 	/* We're looking for a section relative symbol */
-	if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
+	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
 		return;
 
 	symval = (void *)info->hdr
-		+ info->sechdrs[sym->st_shndx].sh_offset
+		+ info->sechdrs[get_secindex(info, sym)].sh_offset
 		+ sym->st_value;
 
 	if (sym_is(symname, "__mod_pci_device_table"))
--- linux-2.6.23-rc4.gc2/scripts/mod/modpost.c	Sat Sep  8 22:06:52 2007
+++ linux-2.6.23-rc4.gc3/scripts/mod/modpost.c	Sat Sep  8 22:07:54 2007
@@ -235,7 +235,7 @@
 	return export_unknown;
 }
 
-static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
+static enum export export_from_sec(struct elf_info *elf, unsigned sec)
 {
 	if (sec == elf->export_sec)
 		return export_plain;
@@ -353,6 +353,8 @@
 	Elf_Ehdr *hdr;
 	Elf_Shdr *sechdrs;
 	Elf_Sym  *sym;
+	const char *secstrings;
+	unsigned int symtab_idx = ~0U;
 
 	hdr = grab_file(filename, &info->size);
 	if (!hdr) {
@@ -372,6 +374,7 @@
 		/* Not an ELF file - silently ignore it */
 		return 0;
 	}
+
 	/* Fix endianness in ELF header */
 	hdr->e_shoff    = TO_NATIVE(hdr->e_shoff);
 	hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
@@ -381,8 +384,18 @@
 	sechdrs = (void *)hdr + hdr->e_shoff;
 	info->sechdrs = sechdrs;
 
+	/* Fixups for more than 64k sections */
+	info->num_sections = hdr->e_shnum;
+	if (info->num_sections == SHN_UNDEF) { /* more than 64k sections? */
+		/* doesn't need shndx2secindex() */
+		info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
+	}
+	info->secindex_strings = hdr->e_shstrndx;
+	if (info->secindex_strings == SHN_XINDEX)
+		info->secindex_strings = shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
+
 	/* Fix endianness in section headers */
-	for (i = 0; i < hdr->e_shnum; i++) {
+	for (i = 0; i < info->num_sections; i++) {
 		sechdrs[i].sh_type   = TO_NATIVE(sechdrs[i].sh_type);
 		sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
 		sechdrs[i].sh_size   = TO_NATIVE(sechdrs[i].sh_size);
@@ -392,9 +405,8 @@
 		sechdrs[i].sh_addr   = TO_NATIVE(sechdrs[i].sh_addr);
 	}
 	/* Find symbol table. */
-	for (i = 1; i < hdr->e_shnum; i++) {
-		const char *secstrings
-			= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+	secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
+	for (i = 1; i < info->num_sections; i++) {
 		const char *secname;
 
 		if (sechdrs[i].sh_offset > info->size) {
@@ -416,14 +428,29 @@
 		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
 			info->export_gpl_future_sec = i;
 
-		if (sechdrs[i].sh_type != SHT_SYMTAB)
-			continue;
+		if (sechdrs[i].sh_type == SHT_SYMTAB) {
+			symtab_idx = i;
+			info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
+			info->symtab_stop  = (void *)hdr + sechdrs[i].sh_offset
+				                         + sechdrs[i].sh_size;
+			info->strtab       = (void *)hdr +
+			             sechdrs[shndx2secindex(sechdrs[i].sh_link)].sh_offset;
+		}
 
-		info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
-		info->symtab_stop  = (void *)hdr + sechdrs[i].sh_offset
-			                         + sechdrs[i].sh_size;
-		info->strtab       = (void *)hdr +
-			             sechdrs[sechdrs[i].sh_link].sh_offset;
+		/* 32bit section no. table? ("more than 64k sections") */
+		if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
+			uint32_t *p32;
+			info->symtab_shndx = (void *)hdr + sechdrs[i].sh_offset;
+			if (symtab_idx != shndx2secindex(sechdrs[i].sh_link))
+				fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
+					filename,
+					shndx2secindex(sechdrs[i].sh_link),
+					symtab_idx);
+			/* Fix endianness */
+			p32 = (void*)info->symtab_shndx + sechdrs[i].sh_size;
+			while (--p32 >= info->symtab_shndx)
+				*p32 = TO_NATIVE(*p32);
+		}
 	}
 	if (!info->symtab_start) {
 		fatal("%s has no symtab?\n", filename);
@@ -450,7 +477,7 @@
 			       Elf_Sym *sym, const char *symname)
 {
 	unsigned int crc;
-	enum export export = export_from_sec(info, sym->st_shndx);
+	enum export export = export_from_sec(info, get_secindex(info, sym));
 
 	switch (sym->st_shndx) {
 	case SHN_COMMON:
@@ -758,11 +785,14 @@
 				Elf_Sym *relsym)
 {
 	Elf_Sym *sym;
+	unsigned relsym_secindex;
 
 	if (relsym->st_name != 0)
 		return relsym;
+
+	relsym_secindex = get_secindex(elf, relsym);
 	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
-		if (sym->st_shndx != relsym->st_shndx)
+		if (get_secindex(elf, sym) != relsym_secindex)
 			continue;
 		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
 			continue;
@@ -811,7 +841,7 @@
 	Elf_Addr beforediff = ~0;
 	Elf_Addr afterdiff = ~0;
 	const char *secstrings = (void *)hdr +
-				 elf->sechdrs[hdr->e_shstrndx].sh_offset;
+				 elf->sechdrs[elf->secindex_strings].sh_offset;
 
 	*before = NULL;
 	*after = NULL;
@@ -819,9 +849,9 @@
 	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
 		const char *symsec;
 
-		if (sym->st_shndx >= SHN_LORESERVE)
+		if (is_shndx_special(sym->st_shndx))
 			continue;
-		symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name;
+		symsec = secstrings + elf->sechdrs[get_secindex(elf, sym)].sh_name;
 		if (strcmp(symsec, sec) != 0)
 			continue;
 		if (!is_valid_name(elf, sym))
@@ -862,8 +892,8 @@
 	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;
+				 sechdrs[elf->secindex_strings].sh_offset;
+	const char *secname = secstrings + sechdrs[get_secindex(elf, sym)].sh_name;
 
 	find_symbols_between(elf, r.r_offset, fromsec, &before, &after);
 
@@ -997,10 +1027,10 @@
 	Elf_Ehdr *hdr = elf->hdr;
 	Elf_Shdr *sechdrs = elf->sechdrs;
 	const char *secstrings = (void *)hdr +
-				 sechdrs[hdr->e_shstrndx].sh_offset;
+				 sechdrs[elf->secindex_strings].sh_offset;
 
 	/* Walk through all sections */
-	for (i = 0; i < hdr->e_shnum; i++) {
+	for (i = 0; i < elf->num_sections; i++) {
 		const char *name = secstrings + sechdrs[i].sh_name;
 		const char *secname;
 		Elf_Rela r;
@@ -1034,11 +1064,11 @@
 				r.r_addend = TO_NATIVE(rela->r_addend);
 				sym = elf->symtab_start + r_sym;
 				/* Skip special sections */
-				if (sym->st_shndx >= SHN_LORESERVE)
+				if (is_shndx_special(sym->st_shndx))
 					continue;
 
 				secname = secstrings +
-					sechdrs[sym->st_shndx].sh_name;
+					sechdrs[get_secindex(elf, sym)].sh_name;
 				if (section(secname))
 					warn_sec_mismatch(modname, name,
 							  elf, sym, r);
@@ -1085,11 +1115,11 @@
 				}
 				sym = elf->symtab_start + r_sym;
 				/* Skip special sections */
-				if (sym->st_shndx >= SHN_LORESERVE)
+				if (is_shndx_special(sym->st_shndx))
 					continue;
 
 				secname = secstrings +
-					sechdrs[sym->st_shndx].sh_name;
+					sechdrs[get_secindex(elf, sym)].sh_name;
 				if (section(secname))
 					warn_sec_mismatch(modname, name,
 							  elf, sym, r);
--- linux-2.6.23-rc4.gc2/scripts/mod/modpost.h	Sun Sep  2 17:29:37 2007
+++ linux-2.6.23-rc4.gc3/scripts/mod/modpost.h	Sat Sep  8 22:07:54 2007
@@ -127,7 +127,48 @@
 	const char   *strtab;
 	char	     *modinfo;
 	unsigned int modinfo_len;
+
+	/* support for 32bit section numbers */
+
+	unsigned int num_sections; /* max_secindex + 1 */
+	unsigned int secindex_strings;
+	/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
+	 * take shndx from symtab_shndx[N] instead */
+	uint32_t     *symtab_shndx;
 };
+
+static inline int is_shndx_special(unsigned i)
+{
+	return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
+}
+
+/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus:
+ * shndx == 0               <=> sechdrs[0]
+ * ......
+ * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1]
+ * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE]
+ * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1]
+ * ......
+ * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff,
+ * so basically we map  0000..feff -> 0000..feff
+ *                      ff00..ffff -> (you are a bad boy, dont do it)
+ *                     10000..xxxx -> ff00..(xxxx-0x100)
+ */
+static inline unsigned shndx2secindex(unsigned i)
+{
+	if (i <= SHN_HIRESERVE)
+		return i;
+	return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
+}
+
+/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
+static inline unsigned get_secindex(struct elf_info *info, Elf_Sym *sym)
+{
+	if (sym->st_shndx != SHN_XINDEX)
+		return sym->st_shndx;
+	return shndx2secindex(info->symtab_shndx[sym - info->symtab_start]);
+}
+
 
 /* file2alias.c */
 void handle_moddevtable(struct module *mod, struct elf_info *info,

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 4/4] build system: section garbage collection for vmlinux
  2007-09-11 20:11     ` [PATCH 3/4] " Denys Vlasenko
@ 2007-09-11 20:22       ` Denys Vlasenko
  0 siblings, 0 replies; 18+ messages in thread
From: Denys Vlasenko @ 2007-09-11 20:22 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 484 bytes --]

This is the core patch of the series.

It adds CONFIG_DISCARD_UNUSED_SECTIONS,
adds KEEP() directives to linker scripts,
adds custom module linker script which is needed
to avoid having modules with many small sections.
Modules got a bit smaller too, as a result.

This patch is slighty more risky than first three,
probably need to go into -mm first.
It should be safe with CONFIG_DISCARD_UNUSED_SECTIONS off, though.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

[-- Attachment #2: linux-2.6.23-rc4.4.gc.patch --]
[-- Type: text/x-diff, Size: 20971 bytes --]

diff -urpN linux-2.6.23-rc4.gc3/Makefile linux-2.6.23-rc4.gc4/Makefile
--- linux-2.6.23-rc4.gc3/Makefile	2007-08-31 18:58:29.000000000 +0100
+++ linux-2.6.23-rc4.gc4/Makefile	2007-09-11 21:12:31.000000000 +0100
@@ -508,6 +508,11 @@ CFLAGS          += $(call cc-option, -fn
 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
 CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
 
diff -urpN linux-2.6.23-rc4.gc3/arch/frv/Makefile linux-2.6.23-rc4.gc4/arch/frv/Makefile
--- linux-2.6.23-rc4.gc3/arch/frv/Makefile	2007-08-31 18:31:02.000000000 +0100
+++ linux-2.6.23-rc4.gc4/arch/frv/Makefile	2007-09-11 20:34:22.000000000 +0100
@@ -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.
+# $(LINKFLAGS) seems to be unused.
+ifdef CONFIG_DISCARD_UNUSED_SECTIONS
 CFLAGS		+= -ffunction-sections -fdata-sections
 LINKFLAGS	+= --gc-sections
 endif
diff -urpN linux-2.6.23-rc4.gc3/arch/x86_64/kernel/modules.lds linux-2.6.23-rc4.gc4/arch/x86_64/kernel/modules.lds
--- linux-2.6.23-rc4.gc3/arch/x86_64/kernel/modules.lds	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.23-rc4.gc4/arch/x86_64/kernel/modules.lds	2007-09-11 21:19:20.000000000 +0100
@@ -0,0 +1,123 @@
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+
+/*
+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 (none for x86_64 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.23-rc4.gc3/arch/x86_64/kernel/vmlinux.lds.S linux-2.6.23-rc4.gc4/arch/x86_64/kernel/vmlinux.lds.S
--- linux-2.6.23-rc4.gc3/arch/x86_64/kernel/vmlinux.lds.S	2007-09-11 20:30:02.000000000 +0100
+++ linux-2.6.23-rc4.gc4/arch/x86_64/kernel/vmlinux.lds.S	2007-09-11 20:34:22.000000000 +0100
@@ -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 */
@@ -44,8 +44,9 @@ SECTIONS
   _etext = .;			/* End of text section */
 
   . = ALIGN(16);		/* Exception table */
+  /* Points to potentially-faulting insns and corresponding .fixups */
   __start___ex_table = .;
-  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { KEEP(*(__ex_table)) }
   __stop___ex_table = .;
 
   NOTES :text :note
@@ -91,34 +92,34 @@ 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) }
-  .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2))
-		{ *(.vsyscall_2) }
+  .vsyscall_1 VSYSCALL_ADDR + 1024: AT(VLOAD(.vsyscall_1))
+		{ KEEP(*(.vsyscall_1)) }
+  .vsyscall_2 VSYSCALL_ADDR + 2048: AT(VLOAD(.vsyscall_2))
+		{ KEEP(*(.vsyscall_2)) }
 
-  .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) }
+  .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { KEEP(*(.vgetcpu_mode)) }
   vgetcpu_mode = VVIRT(.vgetcpu_mode);
 
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) }
+  .jiffies : AT(VLOAD(.jiffies)) { KEEP(*(.jiffies)) }
   jiffies = VVIRT(.jiffies);
 
-  .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3))
-		{ *(.vsyscall_3) }
+  .vsyscall_3 VSYSCALL_ADDR + 3072: AT(VLOAD(.vsyscall_3))
+		{ KEEP(*(.vsyscall_3)) }
 
   . = VSYSCALL_VIRT_ADDR + 4096;
 
@@ -141,11 +142,12 @@ SECTIONS
   }
 
   /* might get freed after init */
+
   . = ALIGN(4096);
   __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);
@@ -155,15 +157,15 @@ SECTIONS
   __init_begin = .;
   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
 	_sinittext = .;
-	*(.init.text)
+	*(.init.text) /* no need to KEEP */
 	_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,34 +174,34 @@ 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
+  /* .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) }
 
 /* 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,7 +212,7 @@ 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 = .;
 
@@ -218,6 +220,7 @@ SECTIONS
   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
 	*(.bss.k.page_aligned)
 	*(.bss)
+	*(SORT_BY_ALIGNMENT(.bss.*))
 	}
   __bss_stop = .;
 
diff -urpN linux-2.6.23-rc4.gc3/include/asm-generic/vmlinux.lds.h linux-2.6.23-rc4.gc4/include/asm-generic/vmlinux.lds.h
--- linux-2.6.23-rc4.gc3/include/asm-generic/vmlinux.lds.h	2007-09-11 20:30:02.000000000 +0100
+++ linux-2.6.23-rc4.gc4/include/asm-generic/vmlinux.lds.h	2007-09-11 20:34:22.000000000 +0100
@@ -6,19 +6,26 @@
 #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)
 
 #define RO_DATA(align)							\
 	. = ALIGN((align));						\
 	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
 		VMLINUX_SYMBOL(__start_rodata) = .;			\
-		*(.rodata) *(.rodata.*)					\
+		*(.rodata) *(SORT_BY_ALIGNMENT(.rodata.*))		\
 		*(__vermagic)		/* Kernel version magic */	\
 	}								\
 									\
@@ -28,109 +35,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) = .;			\
 	}								\
@@ -144,7 +152,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) = .;		\
 	}
 
@@ -153,6 +161,7 @@
 #define TEXT_TEXT							\
 		ALIGN_FUNCTION();					\
 		*(.text)						\
+		*(SORT_BY_ALIGNMENT(.text.*))				\
 		*(.init.refok.text)
 
 /* sched.text is aling to function alignment to secure we have same
@@ -231,23 +240,23 @@
 	}
 
 #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.23-rc4.gc3/init/Kconfig linux-2.6.23-rc4.gc4/init/Kconfig
--- linux-2.6.23-rc4.gc3/init/Kconfig	2007-08-31 18:31:05.000000000 +0100
+++ linux-2.6.23-rc4.gc4/init/Kconfig	2007-09-11 21:14:46.000000000 +0100
@@ -347,6 +347,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_64
+
+	  If unsure, say N.
+
 config SYSCTL
 	bool
 
diff -urpN linux-2.6.23-rc4.gc3/scripts/Makefile.modpost linux-2.6.23-rc4.gc4/scripts/Makefile.modpost
--- linux-2.6.23-rc4.gc3/scripts/Makefile.modpost	2007-08-31 18:31:05.000000000 +0100
+++ linux-2.6.23-rc4.gc4/scripts/Makefile.modpost	2007-09-11 20:33:24.000000000 +0100
@@ -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/$(ARCH)/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)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/4] build system: section garbage collection for vmlinux
  2007-09-11 20:05 [PATCH 0/4] build system: section garbage collection for vmlinux Denys Vlasenko
  2007-09-11 20:07 ` [PATCH 1/4] " Denys Vlasenko
@ 2007-09-11 21:03 ` Andi Kleen
  2007-09-12 20:19   ` Denys Vlasenko
  2007-09-13 18:26 ` Abhishek Sagar
       [not found] ` <20071118230057.GA6303@uranus.ravnborg.org>
  3 siblings, 1 reply; 18+ messages in thread
From: Andi Kleen @ 2007-09-11 21:03 UTC (permalink / raw)
  To: Denys Vlasenko; +Cc: Sam Ravnborg, linux-kernel

Denys Vlasenko <vda.linux@googlemail.com> writes:
> 
>    text    data     bss     dec     hex filename
> 5159478 1005139  406784 6571401  644589 linux-2.6.23-rc4.org/vmlinux
> 5131822  996090  401439 6529351  63a147 linux-2.6.23-rc4.gc/vmlinux
> 
> In this particular case, 402 objects were discarded, saving 42 kb.

I wonder how many of those are 100% unused on all configurations? 
That could be an useful janitor task to clean up

-Andi

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/4] build system: section garbage collection for vmlinux
  2007-09-11 20:07 ` [PATCH 1/4] " Denys Vlasenko
  2007-09-11 20:10   ` [PATCH 2/4] " Denys Vlasenko
@ 2007-09-11 21:47   ` Daniel Walker
  2007-09-12 20:18     ` Denys Vlasenko
  1 sibling, 1 reply; 18+ messages in thread
From: Daniel Walker @ 2007-09-11 21:47 UTC (permalink / raw)
  To: Denys Vlasenko; +Cc: Sam Ravnborg, linux-kernel

On Tue, 2007-09-11 at 21:07 +0100, Denys Vlasenko wrote:
> This patch is needed for --gc-sections to work, regardless
> of which final form that support will have.
> 
> This patch renames .text.xxx and .data.xxx sections
> into .xxx.text and .xxx.data, respectively.

I think you'll have better luck with this if you focus on a single
architecture (i386 would be best) .. 

Daniel


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/4] build system: section garbage collection for vmlinux
  2007-09-11 21:47   ` [PATCH 1/4] " Daniel Walker
@ 2007-09-12 20:18     ` Denys Vlasenko
  2007-09-12 20:52       ` Daniel Walker
  0 siblings, 1 reply; 18+ messages in thread
From: Denys Vlasenko @ 2007-09-12 20:18 UTC (permalink / raw)
  To: Daniel Walker; +Cc: Sam Ravnborg, linux-kernel

On Tuesday 11 September 2007 22:47, Daniel Walker wrote:
> On Tue, 2007-09-11 at 21:07 +0100, Denys Vlasenko wrote:
> > This patch is needed for --gc-sections to work, regardless
> > of which final form that support will have.
> > 
> > This patch renames .text.xxx and .data.xxx sections
> > into .xxx.text and .xxx.data, respectively.
> 
> I think you'll have better luck with this if you focus on a single
> architecture (i386 would be best) .. 

I did exactly that. I focused on x86_64.

Of course, section name fixes cannot be done per-arch, as they
are scattered across entire tree.

Apart from that, it was x86_64 only.

By now, I also have patches for i386 in hand too.
--
vda

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/4] build system: section garbage collection for vmlinux
  2007-09-11 21:03 ` [PATCH 0/4] " Andi Kleen
@ 2007-09-12 20:19   ` Denys Vlasenko
  0 siblings, 0 replies; 18+ messages in thread
From: Denys Vlasenko @ 2007-09-12 20:19 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Sam Ravnborg, linux-kernel

On Tuesday 11 September 2007 22:03, Andi Kleen wrote:
> Denys Vlasenko <vda.linux@googlemail.com> writes:
> > 
> >    text    data     bss     dec     hex filename
> > 5159478 1005139  406784 6571401  644589 linux-2.6.23-rc4.org/vmlinux
> > 5131822  996090  401439 6529351  63a147 linux-2.6.23-rc4.gc/vmlinux
> > 
> > In this particular case, 402 objects were discarded, saving 42 kb.
> 
> I wonder how many of those are 100% unused on all configurations? 
> That could be an useful janitor task to clean up

With CONFIG_DISCARD_UNUSED_SECTIONS=y ld will helpfully flood you
with the list of discarded stuff. I pass --print-gc-sections to it.
--
vda

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/4] build system: section garbage collection for vmlinux
  2007-09-12 20:18     ` Denys Vlasenko
@ 2007-09-12 20:52       ` Daniel Walker
  0 siblings, 0 replies; 18+ messages in thread
From: Daniel Walker @ 2007-09-12 20:52 UTC (permalink / raw)
  To: Denys Vlasenko; +Cc: Sam Ravnborg, linux-kernel

On Wed, 2007-09-12 at 21:18 +0100, Denys Vlasenko wrote:
> On Tuesday 11 September 2007 22:47, Daniel Walker wrote:
> > On Tue, 2007-09-11 at 21:07 +0100, Denys Vlasenko wrote:
> > > This patch is needed for --gc-sections to work, regardless
> > > of which final form that support will have.
> > > 
> > > This patch renames .text.xxx and .data.xxx sections
> > > into .xxx.text and .xxx.data, respectively.
> > 
> > I think you'll have better luck with this if you focus on a single
> > architecture (i386 would be best) .. 
> 
> I did exactly that. I focused on x86_64.
> 
> Of course, section name fixes cannot be done per-arch, as they
> are scattered across entire tree.

This is want I'm talking about .. Why can't you do this per
architecture?

Daniel


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/4] build system: section garbage collection for vmlinux
  2007-09-11 20:05 [PATCH 0/4] build system: section garbage collection for vmlinux Denys Vlasenko
  2007-09-11 20:07 ` [PATCH 1/4] " Denys Vlasenko
  2007-09-11 21:03 ` [PATCH 0/4] " Andi Kleen
@ 2007-09-13 18:26 ` Abhishek Sagar
  2007-09-13 18:35   ` Sam Ravnborg
       [not found] ` <20071118230057.GA6303@uranus.ravnborg.org>
  3 siblings, 1 reply; 18+ messages in thread
From: Abhishek Sagar @ 2007-09-13 18:26 UTC (permalink / raw)
  To: Denys Vlasenko; +Cc: Sam Ravnborg, linux-kernel

On 9/12/07, Denys Vlasenko <vda.linux@googlemail.com> wrote:
> Patches were run-tested on x86_64, and likely do not work on any other arch
> (need to add KEEP() to arch/*/kernel/vmlinux.lds.S for each arch).

This is good stuff. I had been using a ported variant of this
optimization for ARM on quite an older 2.6 kernel for a while now. I
derived that port from:
http://lkml.org/lkml/2006/6/4/169

With some tweaks it worked for me. Could you also have a look at the
mentioned link and see if that's a superset of what you're trying to
achieve?

--
Abhishek Sagar

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/4] build system: section garbage collection for vmlinux
  2007-09-13 18:26 ` Abhishek Sagar
@ 2007-09-13 18:35   ` Sam Ravnborg
  2007-09-14 18:06     ` Abhishek Sagar
  0 siblings, 1 reply; 18+ messages in thread
From: Sam Ravnborg @ 2007-09-13 18:35 UTC (permalink / raw)
  To: Abhishek Sagar; +Cc: Denys Vlasenko, linux-kernel

Hi Abhisshek.

On Thu, Sep 13, 2007 at 11:56:14PM +0530, Abhishek Sagar wrote:
> On 9/12/07, Denys Vlasenko <vda.linux@googlemail.com> wrote:
> > Patches were run-tested on x86_64, and likely do not work on any other arch
> > (need to add KEEP() to arch/*/kernel/vmlinux.lds.S for each arch).
> 
> This is good stuff. I had been using a ported variant of this
> optimization for ARM on quite an older 2.6 kernel for a while now. I
> derived that port from:
> http://lkml.org/lkml/2006/6/4/169
> 
> With some tweaks it worked for me.
Could you post your tweaked version - against an older kernel is OK.

	Sam

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/4] build system: section garbage collection for vmlinux
  2007-09-13 18:35   ` Sam Ravnborg
@ 2007-09-14 18:06     ` Abhishek Sagar
  0 siblings, 0 replies; 18+ messages in thread
From: Abhishek Sagar @ 2007-09-14 18:06 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: Denys Vlasenko, linux-kernel

On 9/14/07, Sam Ravnborg <sam@ravnborg.org> wrote:
> > With some tweaks it worked for me.
> Could you post your tweaked version - against an older kernel is OK.

The inlined patch should apply cleanly on top of the patch posted on
the link I mentioned before. The *.S files are the ones I chose to
bring them under the purview of --ffunction-sections. My observation
remains that if a fine-grained function/data/exported-symbol level
garbage collection can be incorporated into the build environment,
then it'll be something really useful.

--
Abhishek Sagar

---
diff -upNr linux_orig-2.6.12/arch/arm/kernel/armksyms.c
linux-2.6.12/arch/arm/kernel/armksyms.c
--- linux_orig-2.6.12/arch/arm/kernel/armksyms.c	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/kernel/armksyms.c	2007-09-14 09:00:03.000000000 +0530
@@ -44,10 +44,17 @@ extern void fp_enter(void);
  * This has a special calling convention; it doesn't
  * modify any of the usual registers, except for LR.
  */
+#ifndef CONFIG_GCSECTIONS
 #define EXPORT_SYMBOL_ALIAS(sym,orig)		\
  const struct kernel_symbol __ksymtab_##sym	\
   __attribute__((section("__ksymtab"))) =	\
     { (unsigned long)&orig, #sym };
+#else
+#define EXPORT_SYMBOL_ALIAS(sym,orig)            \
+ const struct kernel_symbol __ksymtab_##sym      \
+  __attribute__((section("___ksymtab_" #sym))) = \
+    { (unsigned long)&orig, #sym };
+#endif /* CONFIG_GCSECTIONS */

 /*
  * floating point math emulator support.
diff -upNr linux_orig-2.6.12/arch/arm/kernel/iwmmxt.S
linux-2.6.12/arch/arm/kernel/iwmmxt.S
--- linux_orig-2.6.12/arch/arm/kernel/iwmmxt.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/kernel/iwmmxt.S	2007-09-14 09:21:01.000000000 +0530
@@ -55,7 +55,11 @@
  *
  * called from prefetch exception handler with interrupts disabled
  */
-
+#ifdef CONFIG_GCSECTIONS
+	       .section ".text.iwmmxt_task_enable"
+#else
+	       .text
+#endif
 ENTRY(iwmmxt_task_enable)

 	mrc	p15, 0, r2, c15, c1, 0
diff -upNr linux_orig-2.6.12/arch/arm/kernel/vmlinux.lds.S
linux-2.6.12/arch/arm/kernel/vmlinux.lds.S
--- linux_orig-2.6.12/arch/arm/kernel/vmlinux.lds.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/kernel/vmlinux.lds.S	2007-09-14
08:58:30.000000000 +0530
@@ -20,50 +20,50 @@ SECTIONS
 	.init : {			/* Init code and data		*/
 		_stext = .;
 			_sinittext = .;
-			*(.init.text)
+			KEEP(*(.init.text))
 			_einittext = .;
 		__proc_info_begin = .;
-			*(.proc.info)
+			KEEP(*(.proc.info))
 		__proc_info_end = .;
 		__arch_info_begin = .;
-			*(.arch.info)
+			KEEP(*(.arch.info))
 		__arch_info_end = .;
 		__tagtable_begin = .;
-			*(.taglist)
+			KEEP(*(.taglist))
 		__tagtable_end = .;
 		. = ALIGN(16);
 		__setup_start = .;
-			*(.init.setup)
+			KEEP(*(.init.setup))
 		__setup_end = .;
 		__early_begin = .;
-			*(__early_param)
+			KEEP(*(__early_param))
 		__early_end = .;
 		__initcall_start = .;
-			*(.initcall1.init)
-			*(.initcall2.init)
-			*(.initcall3.init)
-			*(.initcall4.init)
-			*(.initcall5.init)
-			*(.initcall6.init)
-			*(.initcall7.init)
+			KEEP(*(.initcall1.init))
+			KEEP(*(.initcall2.init))
+			KEEP(*(.initcall3.init))
+			KEEP(*(.initcall4.init))
+			KEEP(*(.initcall5.init))
+			KEEP(*(.initcall6.init))
+			KEEP(*(.initcall7.init))
 		__initcall_end = .;
 		__con_initcall_start = .;
-			*(.con_initcall.init)
+			KEEP(*(.con_initcall.init))
 		__con_initcall_end = .;
 		__security_initcall_start = .;
-			*(.security_initcall.init)
+			KEEP(*(.security_initcall.init))
 		__security_initcall_end = .;
 		. = ALIGN(32);
 		__initramfs_start = .;
-			usr/built-in.o(.init.ramfs)
+			KEEP(usr/built-in.o(.init.ramfs))
 		__initramfs_end = .;
 		. = ALIGN(64);
 		__per_cpu_start = .;
-			*(.data.percpu)
+			KEEP(*(.data.percpu))
 		__per_cpu_end = .;
 #ifndef CONFIG_XIP_KERNEL
 		__init_begin = _stext;
-		*(.init.data)
+		KEEP(*(.init.data))
 		. = ALIGN(4096);
 		__init_end = .;
 #endif
@@ -78,6 +78,8 @@ SECTIONS
 	.text : {			/* Real text segment		*/
 		_text = .;		/* Text and read-only data	*/
 			*(.text)
+			*(.text.*)
+			#include "vmlinux.ldskeep.h"
 			SCHED_TEXT
 			LOCK_TEXT
 			*(.fixup)
@@ -92,12 +94,42 @@ SECTIONS
 	. = ALIGN(16);
 	__ex_table : {			/* Exception table		*/
 		__start___ex_table = .;
-			*(__ex_table)
+			KEEP(*(__ex_table))
 		__stop___ex_table = .;
 	}

 	RODATA

+#ifdef CONFIG_GCSECTIONS
+	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {
+		VMLINUX_SYMBOL(__start___ksymtab) = .;		
+                #include "keep.ksymtab.txt"
+		VMLINUX_SYMBOL(__stop___ksymtab) = .;		
+	}							
+								
+	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {
+		VMLINUX_SYMBOL(__start___ksymtab_gpl) = .;		
+                #include "keep.ksymtabgpl.txt"
+		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;
+	}
+
+	__kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {
+		VMLINUX_SYMBOL(__start___kcrctab) = .;
+		KEEP(*(__kcrctab))
+		VMLINUX_SYMBOL(__stop___kcrctab) = .;
+	}
+
+	__kcrctab_gpl     : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) {
+		VMLINUX_SYMBOL(__start___kcrctab_gpl) = .;
+		KEEP(*(__kcrctab_gpl))
+		VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .;
+	}
+
+        __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {
+		#include "keep.ksymstrings.txt"
+	}
+#endif /* CONFIG_GCSECTIONS */
+
 	_etext = .;			/* End of text and rodata section */

 #ifdef CONFIG_XIP_KERNEL
@@ -120,14 +152,14 @@ SECTIONS
 #ifdef CONFIG_XIP_KERNEL
 		. = ALIGN(4096);
 		__init_begin = .;
-		*(.init.data)
+		KEEP(*(.init.data))
 		. = ALIGN(4096);
 		__init_end = .;
 #endif

 		. = ALIGN(4096);
 		__nosave_begin = .;
-		*(.data.nosave)
+		KEEP(*(.data.nosave))
 		. = ALIGN(4096);
 		__nosave_end = .;

@@ -135,12 +167,13 @@ SECTIONS
 		 * then the cacheline aligned data
 		 */
 		. = ALIGN(32);
-		*(.data.cacheline_aligned)
+		KEEP(*(.data.cacheline_aligned))

 		/*
 		 * and the usual data section
 		 */
 		*(.data)
+		*(.data.*)
 		CONSTRUCTORS

 		_edata = .;
@@ -149,6 +182,7 @@ SECTIONS
 	.bss : {
 		__bss_start = .;	/* BSS				*/
 		*(.bss)
+		*(.bss.*)
 		*(COMMON)
 		_end = .;
 	}
diff -upNr linux_orig-2.6.12/arch/arm/lib/copy_page.S
linux-2.6.12/arch/arm/lib/copy_page.S
--- linux_orig-2.6.12/arch/arm/lib/copy_page.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/copy_page.S	2007-09-14 09:18:29.000000000 +0530
@@ -15,7 +15,11 @@

 #define COPY_COUNT (PAGE_SZ/64 PLD( -1 ))

-		.text
+#ifdef CONFIG_GCSECTIONS
+                .section ".text.copy_page"
+#else
+                .text
+#endif
 		.align	5
 /*
  * StrongARM optimised copy_page routine
diff -upNr linux_orig-2.6.12/arch/arm/lib/csumipv6.S
linux-2.6.12/arch/arm/lib/csumipv6.S
--- linux_orig-2.6.12/arch/arm/lib/csumipv6.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/csumipv6.S	2007-09-14 09:11:20.000000000 +0530
@@ -10,7 +10,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>

-		.text
+#ifdef CONFIG_GCSECTIONS
+               .section ".text.__csum_ipv6_magic"
+#else
+               .text
+#endif

 ENTRY(__csum_ipv6_magic)
 		str	lr, [sp, #-4]!
diff -upNr linux_orig-2.6.12/arch/arm/lib/csumpartialcopyuser.S
linux-2.6.12/arch/arm/lib/csumpartialcopyuser.S
--- linux_orig-2.6.12/arch/arm/lib/csumpartialcopyuser.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/csumpartialcopyuser.S	2007-09-14
09:17:34.000000000 +0530
@@ -15,7 +15,11 @@
 #include <asm/errno.h>
 #include <asm/constants.h>

-		.text
+#ifdef CONFIG_GCSECTIONS
+                .section ".text.csum_partial_copy_from_user"
+#else
+                .text
+#endif

 		.macro	save_regs
 		stmfd	sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc}
diff -upNr linux_orig-2.6.12/arch/arm/lib/csumpartial.S
linux-2.6.12/arch/arm/lib/csumpartial.S
--- linux_orig-2.6.12/arch/arm/lib/csumpartial.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/csumpartial.S	2007-09-14 09:10:34.000000000 +0530
@@ -10,7 +10,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>

-		.text
+#ifdef CONFIG_GCSECTIONS
+        .section ".text.csum_partial"
+#else
+        .text
+#endif

 /*
  * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
diff -upNr linux_orig-2.6.12/arch/arm/lib/memchr.S
linux-2.6.12/arch/arm/lib/memchr.S
--- linux_orig-2.6.12/arch/arm/lib/memchr.S	2005-06-18 01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/memchr.S	2007-09-14 09:11:56.000000000 +0530
@@ -12,7 +12,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>

-	.text
+#ifdef CONFIG_GCSECTIONS
+       .section ".text.memchr"
+#else
+       .text
+#endif
 	.align	5
 ENTRY(memchr)
 1:	subs	r2, r2, #1
diff -upNr linux_orig-2.6.12/arch/arm/lib/memset.S
linux-2.6.12/arch/arm/lib/memset.S
--- linux_orig-2.6.12/arch/arm/lib/memset.S	2005-06-18 01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/memset.S	2007-09-14 09:10:16.000000000 +0530
@@ -12,7 +12,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>

-	.text
+#ifdef CONFIG_GCSECTIONS
+        .section ".text.memset"
+#else
+        .text
+#endif
 	.align	5
 	.word	0

diff -upNr linux_orig-2.6.12/arch/arm/lib/memzero.S
linux-2.6.12/arch/arm/lib/memzero.S
--- linux_orig-2.6.12/arch/arm/lib/memzero.S	2005-06-18 01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/memzero.S	2007-09-14 09:19:58.000000000 +0530
@@ -10,7 +10,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>

-	.text
+#ifdef CONFIG_GCSECTIONS
+        .section ".text.__memzero"
+#else
+        .text
+#endif
 	.align	5
 	.word	0
 /*
diff -upNr linux_orig-2.6.12/arch/arm/lib/strchr.S
linux-2.6.12/arch/arm/lib/strchr.S
--- linux_orig-2.6.12/arch/arm/lib/strchr.S	2005-06-18 01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/strchr.S	2007-09-14 09:09:56.000000000 +0530
@@ -12,7 +12,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>

-		.text
+#ifdef CONFIG_GCSECTIONS
+                 .section ".text.strchr"
+#else
+                 .text
+#endif
 		.align	5
 ENTRY(strchr)
 		and	r1, r1, #0xff
diff -upNr linux_orig-2.6.12/arch/arm/lib/strncpy_from_user.S
linux-2.6.12/arch/arm/lib/strncpy_from_user.S
--- linux_orig-2.6.12/arch/arm/lib/strncpy_from_user.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/strncpy_from_user.S	2007-09-14
09:19:20.000000000 +0530
@@ -11,7 +11,11 @@
 #include <asm/assembler.h>
 #include <asm/errno.h>

-	.text
+#ifdef CONFIG_GCSECTIONS
+        .section ".text.__arch_strncpy_from_user"
+#else
+        .text
+#endif
 	.align	5

 /*
diff -upNr linux_orig-2.6.12/arch/arm/lib/strnlen_user.S
linux-2.6.12/arch/arm/lib/strnlen_user.S
--- linux_orig-2.6.12/arch/arm/lib/strnlen_user.S	2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/strnlen_user.S	2007-09-14 09:10:42.000000000 +0530
@@ -11,7 +11,11 @@
 #include <asm/assembler.h>
 #include <asm/errno.h>

-	.text
+#ifdef CONFIG_GCSECTIONS
+        .section ".text.__arch_strnlen_user"
+#else
+        .text
+#endif
 	.align	5

 /* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)
diff -upNr linux_orig-2.6.12/arch/arm/lib/strrchr.S
linux-2.6.12/arch/arm/lib/strrchr.S
--- linux_orig-2.6.12/arch/arm/lib/strrchr.S	2005-06-18 01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/lib/strrchr.S	2007-09-14 09:10:06.000000000 +0530
@@ -12,7 +12,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>

-		.text
+#ifdef CONFIG_GCSECTIONS
+                 .section ".text.strrchr"
+#else
+                 .text
+#endif /* CONFIG_GCSECTIONS */
 		.align	5
 ENTRY(strrchr)
 		mov	r3, #0

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 0/3] build system: section garbage collection
       [not found] ` <20071118230057.GA6303@uranus.ravnborg.org>
@ 2007-11-24 23:14   ` Denys Vlasenko
  2007-11-24 23:17     ` [PATCH 1/3] build system: section garbage collection - rename sections Denys Vlasenko
                       ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Denys Vlasenko @ 2007-11-24 23:14 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

Hi Sam,

On Sunday 18 November 2007 15:00, Sam Ravnborg wrote:
> On Tue, Sep 11, 2007 at 09:05:33PM +0100, Denys Vlasenko wrote:
> > Build system: section garbage collection for vmlinux
> >
> > Newer gcc and binutils can do dead code and data removal
> > at link time. It is achieved using combination of
> > -ffunction-sections -fdata-sections options for gcc and
> > --gc-sections for ld.
>
> ...
> Hi Denys.
>
> We are now well pass the merge window and I like this patchset to show up
> in -mm. But I'm lacking time myself and wondered if you can send an updated
> version based on the latest -git tree from Linus?

Got around to do this.

1.fixname:
    Rename all special sections with names like .text.xxxx, .data.xxxx and
    .rodata.xxxx to .xxxx.text/data/rodata. This makes it possible to
    not mix up these sections with gcc-generated ones
    when gcc -ffunction-sections -fdata-sections is used.
    .bss.xxxx cannot be treated this way, because for section names
    linke .xxxx.bss gcc won't create section with correct attribute.
    Thus .bss.xxxxx sections are renamed .bss.k.xxxxx.

2.modpost
    Update scripts/mod/* machinery to correctly handle the case
    when we have more than 64k sections.

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.

Patches are against yesterday's Linus git tree and should be applied in order.
They should not have any effect at all if DISCARD_UNUSED_SECTIONS is off.
DISCARD_UNUSED_SECTIONS is marked DANGEROUS for now.
It is likely to not work on arches other than x86 (modules.lds needs to be 
added for each arch).

Compile and run tested on 32-bit x86 (running this kernel now).

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/3] build system: section garbage collection - rename sections
  2007-11-24 23:14   ` [PATCH 0/3] build system: section garbage collection Denys Vlasenko
@ 2007-11-24 23:17     ` Denys Vlasenko
  2008-06-24  7:29       ` Matthieu CASTET
  2007-11-24 23:17     ` [PATCH 2/3] build system: section garbage collection - modpost fix Denys Vlasenko
  2007-11-24 23:18     ` [PATCH 3/3] build system: section garbage collection - main part Denys Vlasenko
  2 siblings, 1 reply; 18+ messages in thread
From: Denys Vlasenko @ 2007-11-24 23:17 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 600 bytes --]

On Saturday 24 November 2007 15:14, Denys Vlasenko wrote:
> 1.fixname:
>     Rename all special sections with names like .text.xxxx, .data.xxxx and
>     .rodata.xxxx to .xxxx.text/data/rodata. This makes it possible to
>     not mix up these sections with gcc-generated ones
>     when gcc -ffunction-sections -fdata-sections is used.
>     .bss.xxxx cannot be treated this way, because for section names
>     linke .xxxx.bss gcc won't create section with correct attribute.
>     Thus .bss.xxxxx sections are renamed .bss.k.xxxxx.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-- 
vda

[-- Attachment #2: linux-2.6-linus_git.1.fixname.patch --]
[-- Type: text/x-diff, Size: 105601 bytes --]

diff -urpN linux-2.6.org/Documentation/mutex-design.txt linux-2.6.gc1/Documentation/mutex-design.txt
--- linux-2.6.org/Documentation/mutex-design.txt	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/Documentation/mutex-design.txt	2007-11-23 20:55:46.000000000 -0800
@@ -66,14 +66,14 @@ of advantages of mutexes:
 
     c0377ccb <mutex_lock>:
     c0377ccb:       f0 ff 08                lock decl (%eax)
-    c0377cce:       78 0e                   js     c0377cde <.text.lock.mutex>
+    c0377cce:       78 0e                   js     c0377cde <.lock.mutex.text>
     c0377cd0:       c3                      ret
 
    the unlocking fastpath is equally tight:
 
     c0377cd1 <mutex_unlock>:
     c0377cd1:       f0 ff 00                lock incl (%eax)
-    c0377cd4:       7e 0f                   jle    c0377ce5 <.text.lock.mutex+0x7>
+    c0377cd4:       7e 0f                   jle    c0377ce5 <.lock.mutex.text+0x7>
     c0377cd6:       c3                      ret
 
  - 'struct mutex' semantics are well-defined and are enforced if
diff -urpN linux-2.6.org/arch/alpha/kernel/head.S linux-2.6.gc1/arch/alpha/kernel/head.S
--- linux-2.6.org/arch/alpha/kernel/head.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/alpha/kernel/head.S	2007-11-23 20:55:40.000000000 -0800
@@ -10,7 +10,7 @@
 #include <asm/system.h>
 #include <asm/asm-offsets.h>
 
-.section .text.head, "ax"
+.section .head.text, "ax"
 .globl swapper_pg_dir
 .globl _stext
 swapper_pg_dir=SWAPPER_PGD
diff -urpN linux-2.6.org/arch/alpha/kernel/init_task.c linux-2.6.gc1/arch/alpha/kernel/init_task.c
--- linux-2.6.org/arch/alpha/kernel/init_task.c	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/alpha/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -19,5 +19,5 @@ EXPORT_SYMBOL(init_mm);
 EXPORT_SYMBOL(init_task);
 
 union thread_union init_thread_union
-	__attribute__((section(".data.init_thread")))
+	__attribute__((section(".init_thread.data")))
 	= { INIT_THREAD_INFO(init_task) };
diff -urpN linux-2.6.org/arch/alpha/kernel/vmlinux.lds.S linux-2.6.gc1/arch/alpha/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/alpha/kernel/vmlinux.lds.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/alpha/kernel/vmlinux.lds.S	2007-11-23 20:55:55.000000000 -0800
@@ -16,7 +16,7 @@ SECTIONS
 
 	_text = .;	/* Text and read-only data */
 	.text : {
-	*(.text.head)
+	*(.head.text)
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
@@ -93,18 +93,18 @@ SECTIONS
 	/* Freed after init ends here */
 
 	/* Note 2 page alignment above.  */
-	.data.init_thread : {
-		*(.data.init_thread)
+	.init_thread.data : {
+		*(.init_thread.data)
 	}
 
 	. = ALIGN(PAGE_SIZE);
-	.data.page_aligned : {
-		*(.data.page_aligned)
+	.page_aligned.data : {
+		*(.page_aligned.data)
 	}
 
 	. = ALIGN(64);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
+	.cacheline_aligned.data : {
+		*(.cacheline_aligned.data)
 	}
 
 	_data = .;
diff -urpN linux-2.6.org/arch/arm/kernel/head-nommu.S linux-2.6.gc1/arch/arm/kernel/head-nommu.S
--- linux-2.6.org/arch/arm/kernel/head-nommu.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/kernel/head-nommu.S	2007-11-23 20:55:40.000000000 -0800
@@ -33,7 +33,7 @@
  * numbers for r1.
  *
  */
-	.section ".text.head", "ax"
+	.section ".head.text", "ax"
 	.type	stext, %function
 ENTRY(stext)
 	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
diff -urpN linux-2.6.org/arch/arm/kernel/head.S linux-2.6.gc1/arch/arm/kernel/head.S
--- linux-2.6.org/arch/arm/kernel/head.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/kernel/head.S	2007-11-23 20:55:40.000000000 -0800
@@ -77,7 +77,7 @@
  * crap here - that's what the boot loader (or in extreme, well justified
  * circumstances, zImage) is for.
  */
-	.section ".text.head", "ax"
+	.section ".head.text", "ax"
 	.type	stext, %function
 ENTRY(stext)
 	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
diff -urpN linux-2.6.org/arch/arm/kernel/init_task.c linux-2.6.gc1/arch/arm/kernel/init_task.c
--- linux-2.6.org/arch/arm/kernel/init_task.c	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -31,7 +31,7 @@ EXPORT_SYMBOL(init_mm);
  * The things we do for performance..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/arm/kernel/vmlinux.lds.S linux-2.6.gc1/arch/arm/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/arm/kernel/vmlinux.lds.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/kernel/vmlinux.lds.S	2007-11-23 20:55:54.000000000 -0800
@@ -23,10 +23,10 @@ SECTIONS
 #else
 	. = PAGE_OFFSET + TEXT_OFFSET;
 #endif
-	.text.head : {
+	.head.text : {
 		_stext = .;
 		_sinittext = .;
-		*(.text.head)
+		*(.head.text)
 	}
 
 	.init : {			/* Init code and data		*/
@@ -65,8 +65,8 @@ SECTIONS
 #endif
 		. = ALIGN(4096);
 		__per_cpu_start = .;
-			*(.data.percpu)
-			*(.data.percpu.shared_aligned)
+			*(.percpu.data)
+			*(.percpu.shared_aligned.data)
 		__per_cpu_end = .;
 #ifndef CONFIG_XIP_KERNEL
 		__init_begin = _stext;
@@ -124,7 +124,7 @@ SECTIONS
 		 * first, the init task union, aligned
 		 * to an 8192 byte boundary.
 		 */
-		*(.data.init_task)
+		*(.init_task.data)
 
 #ifdef CONFIG_XIP_KERNEL
 		. = ALIGN(4096);
@@ -136,7 +136,7 @@ SECTIONS
 
 		. = ALIGN(4096);
 		__nosave_begin = .;
-		*(.data.nosave)
+		*(.nosave.data)
 		. = ALIGN(4096);
 		__nosave_end = .;
 
@@ -144,7 +144,7 @@ SECTIONS
 		 * then the cacheline aligned data
 		 */
 		. = ALIGN(32);
-		*(.data.cacheline_aligned)
+		*(.cacheline_aligned.data)
 
 		/*
 		 * The exception fixup table (might need resorting at runtime)
diff -urpN linux-2.6.org/arch/arm/mm/proc-v6.S linux-2.6.gc1/arch/arm/mm/proc-v6.S
--- linux-2.6.org/arch/arm/mm/proc-v6.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/mm/proc-v6.S	2007-11-23 20:55:45.000000000 -0800
@@ -168,7 +168,7 @@ cpu_v6_name:
 	.asciz	"ARMv6-compatible processor"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	.section ".init.text", #alloc, #execinstr
 
 /*
  *	__v6_setup
diff -urpN linux-2.6.org/arch/arm/mm/proc-v7.S linux-2.6.gc1/arch/arm/mm/proc-v7.S
--- linux-2.6.org/arch/arm/mm/proc-v7.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/mm/proc-v7.S	2007-11-23 20:55:45.000000000 -0800
@@ -146,7 +146,7 @@ cpu_v7_name:
 	.ascii	"ARMv7 Processor"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	.section ".init.text", #alloc, #execinstr
 
 /*
  *	__v7_setup
diff -urpN linux-2.6.org/arch/arm/mm/tlb-v6.S linux-2.6.gc1/arch/arm/mm/tlb-v6.S
--- linux-2.6.org/arch/arm/mm/tlb-v6.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/mm/tlb-v6.S	2007-11-23 20:55:45.000000000 -0800
@@ -87,7 +87,7 @@ ENTRY(v6wbi_flush_kern_tlb_range)
 	mcr	p15, 0, r2, c7, c5, 4		@ prefetch flush
 	mov	pc, lr
 
-	.section ".text.init", #alloc, #execinstr
+	.section ".init.text", #alloc, #execinstr
 
 	.type	v6wbi_tlb_fns, #object
 ENTRY(v6wbi_tlb_fns)
diff -urpN linux-2.6.org/arch/arm/mm/tlb-v7.S linux-2.6.gc1/arch/arm/mm/tlb-v7.S
--- linux-2.6.org/arch/arm/mm/tlb-v7.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/arm/mm/tlb-v7.S	2007-11-23 20:55:45.000000000 -0800
@@ -78,7 +78,7 @@ ENTRY(v7wbi_flush_kern_tlb_range)
 	isb
 	mov	pc, lr
 
-	.section ".text.init", #alloc, #execinstr
+	.section ".init.text", #alloc, #execinstr
 
 	.type	v7wbi_tlb_fns, #object
 ENTRY(v7wbi_tlb_fns)
diff -urpN linux-2.6.org/arch/avr32/kernel/init_task.c linux-2.6.gc1/arch/avr32/kernel/init_task.c
--- linux-2.6.org/arch/avr32/kernel/init_task.c	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/avr32/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -25,7 +25,7 @@ EXPORT_SYMBOL(init_mm);
  * Initial thread structure. Must be aligned on an 8192-byte boundary.
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/avr32/kernel/vmlinux.lds.S linux-2.6.gc1/arch/avr32/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/avr32/kernel/vmlinux.lds.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/avr32/kernel/vmlinux.lds.S	2007-11-23 20:55:53.000000000 -0800
@@ -105,11 +105,11 @@ SECTIONS
 		/*
 		 * First, the init task union, aligned to an 8K boundary.
 		 */
-		*(.data.init_task)
+		*(.init_task.data)
 
 		/* Then, the cacheline aligned data */
 		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.cacheline_aligned)
+		*(.cacheline_aligned.data)
 
 		/* And the rest... */
 		*(.data.rel*)
diff -urpN linux-2.6.org/arch/blackfin/kernel/init_task.c linux-2.6.gc1/arch/blackfin/kernel/init_task.c
--- linux-2.6.org/arch/blackfin/kernel/init_task.c	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/blackfin/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -57,5 +57,5 @@ EXPORT_SYMBOL(init_task);
  * "init_task" linker map entry.
  */
 union thread_union init_thread_union
-    __attribute__ ((__section__(".data.init_task"))) = {
+    __attribute__ ((__section__(".init_task.data"))) = {
 INIT_THREAD_INFO(init_task)};
diff -urpN linux-2.6.org/arch/blackfin/kernel/vmlinux.lds.S linux-2.6.gc1/arch/blackfin/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/blackfin/kernel/vmlinux.lds.S	2007-11-23 18:55:08.000000000 -0800
+++ linux-2.6.gc1/arch/blackfin/kernel/vmlinux.lds.S	2007-11-23 20:55:53.000000000 -0800
@@ -72,10 +72,10 @@ SECTIONS
 		 */
 		__sdata = .;
 		. = ALIGN(THREAD_SIZE);
-		*(.data.init_task)
+		*(.init_task.data)
 
 		. = ALIGN(32);
-		*(.data.cacheline_aligned)
+		*(.cacheline_aligned.data)
 
 		DATA_DATA
 		*(.data.*)
diff -urpN linux-2.6.org/arch/cris/arch-v10/kernel/head.S linux-2.6.gc1/arch/cris/arch-v10/kernel/head.S
--- linux-2.6.org/arch/cris/arch-v10/kernel/head.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/cris/arch-v10/kernel/head.S	2007-11-23 20:55:53.000000000 -0800
@@ -74,7 +74,7 @@
  * Tweak "notice" to reflect that both r8 r9 are used
  *
  * Revision 1.33  2001/05/15 06:40:05  hp
- * Put bulk of code in .text.init, data in .data.init
+ * Put bulk of code in .init.text, data in .init.data
  *
  * Revision 1.32  2001/05/15 06:18:56  hp
  * Execute review comment: s/bcc/bhs/g; s/bcs/blo/g
diff -urpN linux-2.6.org/arch/cris/arch-v10/vmlinux.lds.S linux-2.6.gc1/arch/cris/arch-v10/vmlinux.lds.S
--- linux-2.6.org/arch/cris/arch-v10/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/cris/arch-v10/vmlinux.lds.S	2007-11-23 20:55:56.000000000 -0800
@@ -50,7 +50,7 @@ SECTIONS
 	_edata = . ;
 
 	. = ALIGN(8192);              /* init_task and stack, must be aligned */
-  	.data.init_task : { *(.data.init_task) }
+  	.init_task.data : { *(.init_task.data) }
 
   	. = ALIGN(8192);              /* Init code and data */
   	__init_begin = .;
@@ -112,8 +112,8 @@ SECTIONS
 
 	/* Sections to be discarded */
   	/DISCARD/ : {
-        	*(.text.exit)
-        	*(.data.exit)
+        	*(.exit.text)
+        	*(.exit.data)
 		*(.exitcall.exit)
         }
 
diff -urpN linux-2.6.org/arch/cris/arch-v32/vmlinux.lds.S linux-2.6.gc1/arch/cris/arch-v32/vmlinux.lds.S
--- linux-2.6.org/arch/cris/arch-v32/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/cris/arch-v32/vmlinux.lds.S	2007-11-23 20:55:56.000000000 -0800
@@ -55,7 +55,7 @@ SECTIONS
 	_edata = . ;
 
 	. = ALIGN(8192);	/* init_task and stack, must be aligned. */
-  	.data.init_task : { *(.data.init_task) }
+  	.init_task.data : { *(.init_task.data) }
 
   	. = ALIGN(8192);	/* Init code and data. */
   	__init_begin = .;
@@ -124,8 +124,8 @@ SECTIONS
 
 	/* Sections to be discarded */
   	/DISCARD/ : {
-        	*(.text.exit)
-        	*(.data.exit)
+        	*(.exit.text)
+        	*(.exit.data)
 		*(.exitcall.exit)
         }
 
diff -urpN linux-2.6.org/arch/cris/kernel/process.c linux-2.6.gc1/arch/cris/kernel/process.c
--- linux-2.6.org/arch/cris/kernel/process.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/cris/kernel/process.c	2007-11-23 20:55:53.000000000 -0800
@@ -153,7 +153,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/frv/kernel/head-mmu-fr451.S linux-2.6.gc1/arch/frv/kernel/head-mmu-fr451.S
--- linux-2.6.org/arch/frv/kernel/head-mmu-fr451.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/frv/kernel/head-mmu-fr451.S	2007-11-23 20:55:45.000000000 -0800
@@ -31,7 +31,7 @@
 #define __400_LCR	0xfe000100
 #define __400_LSBR	0xfe000c00
 
-	.section	.text.init,"ax"
+	.section	.init.text,"ax"
 	.balign		4
 
 ###############################################################################
diff -urpN linux-2.6.org/arch/frv/kernel/head-uc-fr401.S linux-2.6.gc1/arch/frv/kernel/head-uc-fr401.S
--- linux-2.6.org/arch/frv/kernel/head-uc-fr401.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/frv/kernel/head-uc-fr401.S	2007-11-23 20:55:45.000000000 -0800
@@ -30,7 +30,7 @@
 #define __400_LCR	0xfe000100
 #define __400_LSBR	0xfe000c00
 
-	.section	.text.init,"ax"
+	.section	.init.text,"ax"
 	.balign		4
 
 ###############################################################################
diff -urpN linux-2.6.org/arch/frv/kernel/head-uc-fr451.S linux-2.6.gc1/arch/frv/kernel/head-uc-fr451.S
--- linux-2.6.org/arch/frv/kernel/head-uc-fr451.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/frv/kernel/head-uc-fr451.S	2007-11-23 20:55:45.000000000 -0800
@@ -30,7 +30,7 @@
 #define __400_LCR	0xfe000100
 #define __400_LSBR	0xfe000c00
 
-	.section	.text.init,"ax"
+	.section	.init.text,"ax"
 	.balign		4
 
 ###############################################################################
diff -urpN linux-2.6.org/arch/frv/kernel/head-uc-fr555.S linux-2.6.gc1/arch/frv/kernel/head-uc-fr555.S
--- linux-2.6.org/arch/frv/kernel/head-uc-fr555.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/frv/kernel/head-uc-fr555.S	2007-11-23 20:55:45.000000000 -0800
@@ -29,7 +29,7 @@
 #define __551_LCR	0xfeff1100
 #define __551_LSBR	0xfeff1c00
 
-	.section	.text.init,"ax"
+	.section	.init.text,"ax"
 	.balign		4
 
 ###############################################################################
diff -urpN linux-2.6.org/arch/frv/kernel/head.S linux-2.6.gc1/arch/frv/kernel/head.S
--- linux-2.6.org/arch/frv/kernel/head.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/frv/kernel/head.S	2007-11-23 20:55:45.000000000 -0800
@@ -27,7 +27,7 @@
 #   command line string
 #
 ###############################################################################
-	.section	.text.head,"ax"
+	.section	.head.text,"ax"
 	.balign		4
 
 	.globl		_boot, __head_reference
@@ -541,7 +541,7 @@ __head_end:
 	.size		_boot, .-_boot
 
 	# provide a point for GDB to place a break
-	.section	.text.start,"ax"
+	.section	.start.text,"ax"
 	.globl		_start
 	.balign		4
 _start:
diff -urpN linux-2.6.org/arch/frv/kernel/init_task.c linux-2.6.gc1/arch/frv/kernel/init_task.c
--- linux-2.6.org/arch/frv/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/frv/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -26,7 +26,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/frv/kernel/vmlinux.lds.S linux-2.6.gc1/arch/frv/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/frv/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/frv/kernel/vmlinux.lds.S	2007-11-23 20:55:57.000000000 -0800
@@ -26,7 +26,7 @@ SECTIONS
 
   _sinittext = .;
   .init.text : {
-	*(.text.head)
+	*(.head.text)
 #ifndef CONFIG_DEBUG_INFO
 	*(.init.text)
 	*(.exit.text)
@@ -71,9 +71,9 @@ SECTIONS
 
   /* put sections together that have massive alignment issues */
   . = ALIGN(THREAD_SIZE);
-  .data.init_task : {
+  .init_task.data : {
 	  /* init task record & stack */
-	  *(.data.init_task)
+	  *(.init_task.data)
   }
 
   .trap : {
@@ -87,10 +87,10 @@ SECTIONS
   }
 
   . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
+  .page_aligned.data : { *(.idt.data) }
 
   . = ALIGN(L1_CACHE_BYTES);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .cacheline_aligned.data : { *(.cacheline_aligned.data) }
 
   /* Text and read-only data */
   . = ALIGN(4);
@@ -98,7 +98,7 @@ SECTIONS
   _stext = .;
   .text : {
 	*(
-		.text.start .text.*
+		.start.text .text.*
 #ifdef CONFIG_DEBUG_INFO
 	.init.text
 	.exit.text
diff -urpN linux-2.6.org/arch/h8300/boot/compressed/head.S linux-2.6.gc1/arch/h8300/boot/compressed/head.S
--- linux-2.6.org/arch/h8300/boot/compressed/head.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/h8300/boot/compressed/head.S	2007-11-23 20:55:45.000000000 -0800
@@ -9,7 +9,7 @@
 
 #define SRAM_START 0xff4000
 
-	.section	.text.startup
+	.section	.startup.text
 	.global	startup
 startup:
 	mov.l	#SRAM_START+0x8000, sp
diff -urpN linux-2.6.org/arch/h8300/boot/compressed/vmlinux.lds linux-2.6.gc1/arch/h8300/boot/compressed/vmlinux.lds
--- linux-2.6.org/arch/h8300/boot/compressed/vmlinux.lds	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/h8300/boot/compressed/vmlinux.lds	2007-11-23 20:55:45.000000000 -0800
@@ -4,7 +4,7 @@ SECTIONS
         {
         __stext = . ;
 	__text = .;
-	       *(.text.startup)
+	       *(.startup.text)
 	       *(.text)
         __etext = . ;
         }
diff -urpN linux-2.6.org/arch/h8300/kernel/init_task.c linux-2.6.gc1/arch/h8300/kernel/init_task.c
--- linux-2.6.org/arch/h8300/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/h8300/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -38,6 +38,6 @@ EXPORT_SYMBOL(init_task);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
diff -urpN linux-2.6.org/arch/h8300/kernel/vmlinux.lds.S linux-2.6.gc1/arch/h8300/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/h8300/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/h8300/kernel/vmlinux.lds.S	2007-11-23 20:55:53.000000000 -0800
@@ -101,7 +101,7 @@ SECTIONS
 	___data_start = . ;
 
 	. = ALIGN(0x2000) ;
-		*(.data.init_task)
+		*(.init_task.data)
 	. = ALIGN(0x4) ;
 		DATA_DATA
 	. = ALIGN(0x4) ;
diff -urpN linux-2.6.org/arch/ia64/kernel/Makefile linux-2.6.gc1/arch/ia64/kernel/Makefile
--- linux-2.6.org/arch/ia64/kernel/Makefile	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/Makefile	2007-11-23 22:17:55.000000000 -0800
@@ -66,7 +66,7 @@ GATECFLAGS_gate-syms.o = -r
 $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
 	$(call if_changed,gate)
 
-# gate-data.o contains the gate DSO image as data in section .data.gate.
+# gate-data.o contains the gate DSO image as data in section .gate.data
 # We must build gate.so before we can assemble it.
 # Note: kbuild does not track this dependency due to usage of .incbin
 $(obj)/gate-data.o: $(obj)/gate.so
diff -urpN linux-2.6.org/arch/ia64/kernel/gate-data.S linux-2.6.gc1/arch/ia64/kernel/gate-data.S
--- linux-2.6.org/arch/ia64/kernel/gate-data.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/gate-data.S	2007-11-23 20:55:59.000000000 -0800
@@ -1,3 +1,3 @@
-	.section .data.gate, "aw"
+	.section .gate.data, "aw"
 
 	.incbin "arch/ia64/kernel/gate.so"
diff -urpN linux-2.6.org/arch/ia64/kernel/gate.S linux-2.6.gc1/arch/ia64/kernel/gate.S
--- linux-2.6.org/arch/ia64/kernel/gate.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/gate.S	2007-11-23 20:55:56.000000000 -0800
@@ -20,18 +20,18 @@
  * to targets outside the shared object) and to avoid multi-phase kernel builds, we
  * simply create minimalistic "patch lists" in special ELF sections.
  */
-	.section ".data.patch.fsyscall_table", "a"
+	.section ".patch.fsyscall_table.data", "a"
 	.previous
 #define LOAD_FSYSCALL_TABLE(reg)			\
 [1:]	movl reg=0;					\
-	.xdata4 ".data.patch.fsyscall_table", 1b-.
+	.xdata4 ".patch.fsyscall_table.data", 1b-.
 
-	.section ".data.patch.brl_fsys_bubble_down", "a"
+	.section ".patch.brl_fsys_bubble_down.data", "a"
 	.previous
 #define BRL_COND_FSYS_BUBBLE_DOWN(pr)			\
 [1:](pr)brl.cond.sptk 0;				\
 	;;						\
-	.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
+	.xdata4 ".patch.brl_fsys_bubble_down.data", 1b-.
 
 GLOBAL_ENTRY(__kernel_syscall_via_break)
 	.prologue
diff -urpN linux-2.6.org/arch/ia64/kernel/gate.lds.S linux-2.6.gc1/arch/ia64/kernel/gate.lds.S
--- linux-2.6.org/arch/ia64/kernel/gate.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/gate.lds.S	2007-11-23 20:55:56.000000000 -0800
@@ -32,21 +32,21 @@ SECTIONS
 	 */
 	. = GATE_ADDR + 0x500;
 
-	.data.patch		: {
+	.patch.data		: {
 		__start_gate_mckinley_e9_patchlist = .;
-		*(.data.patch.mckinley_e9)
+		*(.patch.mckinley_e9.data)
 		__end_gate_mckinley_e9_patchlist = .;
 
 		__start_gate_vtop_patchlist = .;
-		*(.data.patch.vtop)
+		*(.patch.vtop.data)
 		__end_gate_vtop_patchlist = .;
 
 		__start_gate_fsyscall_patchlist = .;
-		*(.data.patch.fsyscall_table)
+		*(.patch.fsyscall_table.data)
 		__end_gate_fsyscall_patchlist = .;
 
 		__start_gate_brl_fsys_bubble_down_patchlist = .;
-		*(.data.patch.brl_fsys_bubble_down)
+		*(.patch.brl_fsys_bubble_down.data)
 		__end_gate_brl_fsys_bubble_down_patchlist = .;
 	}						:readable
 
diff -urpN linux-2.6.org/arch/ia64/kernel/head.S linux-2.6.gc1/arch/ia64/kernel/head.S
--- linux-2.6.org/arch/ia64/kernel/head.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/head.S	2007-11-23 20:55:41.000000000 -0800
@@ -178,7 +178,7 @@ swapper_pg_dir:
 halt_msg:
 	stringz "Halting kernel\n"
 
-	.section .text.head,"ax"
+	.section .head.text,"ax"
 
 	.global start_ap
 
diff -urpN linux-2.6.org/arch/ia64/kernel/init_task.c linux-2.6.gc1/arch/ia64/kernel/init_task.c
--- linux-2.6.org/arch/ia64/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -29,7 +29,7 @@ EXPORT_SYMBOL(init_mm);
  * Initial task structure.
  *
  * We need to make sure that this is properly aligned due to the way process stacks are
- * handled. This is done by having a special ".data.init_task" section...
+ * handled. This is done by having a special ".init_task.data" section...
  */
 #define init_thread_info	init_task_mem.s.thread_info
 
@@ -39,7 +39,7 @@ union {
 		struct thread_info thread_info;
 	} s;
 	unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
-} init_task_mem asm ("init_task") __attribute__((section(".data.init_task"))) = {{
+} init_task_mem asm ("init_task") __attribute__((section(".init_task.data"))) = {{
 	.task =		INIT_TASK(init_task_mem.s.task),
 	.thread_info =	INIT_THREAD_INFO(init_task_mem.s.task)
 }};
diff -urpN linux-2.6.org/arch/ia64/kernel/ivt.S linux-2.6.gc1/arch/ia64/kernel/ivt.S
--- linux-2.6.org/arch/ia64/kernel/ivt.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/ivt.S	2007-11-23 20:55:51.000000000 -0800
@@ -75,7 +75,7 @@
 	mov r19=n;;			/* prepare to save predicates */		\
 	br.sptk.many dispatch_to_fault_handler
 
-	.section .text.ivt,"ax"
+	.section .ivt.text,"ax"
 
 	.align 32768	// align on 32KB boundary
 	.global ia64_ivt
diff -urpN linux-2.6.org/arch/ia64/kernel/vmlinux.lds.S linux-2.6.gc1/arch/ia64/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/ia64/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ia64/kernel/vmlinux.lds.S	2007-11-23 20:55:59.000000000 -0800
@@ -9,7 +9,7 @@
 
 #define IVT_TEXT							\
 		VMLINUX_SYMBOL(__start_ivt_text) = .;			\
-		*(.text.ivt)						\
+		*(.ivt.text)						\
 		VMLINUX_SYMBOL(__end_ivt_text) = .;
 
 OUTPUT_FORMAT("elf64-ia64-little")
@@ -52,13 +52,13 @@ SECTIONS
 	KPROBES_TEXT
 	*(.gnu.linkonce.t*)
     }
-  .text.head : AT(ADDR(.text.head) - LOAD_OFFSET)
-	{ *(.text.head) }
+  .head.text : AT(ADDR(.head.text) - LOAD_OFFSET)
+	{ *(.head.text) }
   .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
 	{ *(.text2) }
 #ifdef CONFIG_SMP
-  .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET)
-	{ *(.text.lock) }
+  .lock.text : AT(ADDR(.lock.text) - LOAD_OFFSET)
+	{ *(.lock.text) }
 #endif
   _etext = .;
 
@@ -85,10 +85,10 @@ SECTIONS
 	  __stop___mca_table = .;
 	}
 
-  .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET)
+  .patch.phys_stack_reg.data : AT(ADDR(.patch.phys_stack_reg.data) - LOAD_OFFSET)
 	{
 	  __start___phys_stack_reg_patchlist = .;
-	  *(.data.patch.phys_stack_reg)
+	  *(.patch.phys_stack_reg.data)
 	  __end___phys_stack_reg_patchlist = .;
 	}
 
@@ -149,17 +149,17 @@ SECTIONS
 	  __initcall_end = .;
 	}
 
-  .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
+  .patch.vtop.data : AT(ADDR(.patch.vtop.data) - LOAD_OFFSET)
 	{
 	  __start___vtop_patchlist = .;
-	  *(.data.patch.vtop)
+	  *(.patch.vtop.data)
 	  __end___vtop_patchlist = .;
 	}
 
-  .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET)
+  .patch.mckinley_e9.data : AT(ADDR(.patch.mckinley_e9.data) - LOAD_OFFSET)
 	{
 	  __start___mckinley_e9_bundles = .;
-	  *(.data.patch.mckinley_e9)
+	  *(.patch.mckinley_e9.data)
 	  __end___mckinley_e9_bundles = .;
 	}
 
@@ -187,34 +187,34 @@ SECTIONS
   __init_end = .;
 
   /* The initial task and kernel stack */
-  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET)
-	{ *(.data.init_task) }
+  .init_task.data : AT(ADDR(.init_task.data) - LOAD_OFFSET)
+	{ *(.init_task.data) }
 
-  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET)
+  .page_aligned.data : AT(ADDR(.page_aligned.data) - LOAD_OFFSET)
         { *(__special_page_section)
 	  __start_gate_section = .;
-	  *(.data.gate)
+	  *(.gate.data)
 	  __stop_gate_section = .;
 	}
   . = ALIGN(PAGE_SIZE);		/* make sure the gate page doesn't expose
   				 * kernel data
 				 */
 
-  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET)
-        { *(.data.read_mostly) }
+  .read_mostly.data : AT(ADDR(.read_mostly.data) - LOAD_OFFSET)
+        { *(.read_mostly.data) }
 
-  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET)
-        { *(.data.cacheline_aligned) }
+  .cacheline_aligned.data : AT(ADDR(.cacheline_aligned.data) - LOAD_OFFSET)
+        { *(.cacheline_aligned.data) }
 
   /* Per-cpu data: */
   percpu : { } :percpu
   . = ALIGN(PERCPU_PAGE_SIZE);
   __phys_per_cpu_start = .;
-  .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
+  .percpu.data PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
 	{
 		__per_cpu_start = .;
-		*(.data.percpu)
-		*(.data.percpu.shared_aligned)
+		*(.percpu.data)
+		*(.percpu.shared_aligned.data)
 		__per_cpu_end = .;
 	}
   . = __phys_per_cpu_start + PERCPU_PAGE_SIZE;	/* ensure percpu data fits
diff -urpN linux-2.6.org/arch/m32r/kernel/init_task.c linux-2.6.gc1/arch/m32r/kernel/init_task.c
--- linux-2.6.org/arch/m32r/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m32r/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -27,7 +27,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/m32r/kernel/vmlinux.lds.S linux-2.6.gc1/arch/m32r/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/m32r/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m32r/kernel/vmlinux.lds.S	2007-11-23 20:55:57.000000000 -0800
@@ -56,20 +56,20 @@ SECTIONS
 
   . = ALIGN(4096);
   __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
+  .data_nosave : { *(.nosave.data) }
   . = ALIGN(4096);
   __nosave_end = .;
 
   . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
+  .page_aligned.data : { *(.idt.data) }
 
   . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .cacheline_aligned.data : { *(.cacheline_aligned.data) }
 
   _edata = .;			/* End of data section */
 
   . = ALIGN(8192);		/* init_task */
-  .data.init_task : { *(.data.init_task) }
+  .init_task.data : { *(.init_task.data) }
 
   /* will be freed after init */
   . = ALIGN(4096);		/* Init code and data */
diff -urpN linux-2.6.org/arch/m68k/kernel/head.S linux-2.6.gc1/arch/m68k/kernel/head.S
--- linux-2.6.org/arch/m68k/kernel/head.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68k/kernel/head.S	2007-11-23 20:55:41.000000000 -0800
@@ -577,7 +577,7 @@ func_define	putn,1
 #endif
 .endm
 
-.section ".text.head","ax"
+.section ".head.text","ax"
 ENTRY(_stext)
 /*
  * Version numbers of the bootinfo interface
diff -urpN linux-2.6.org/arch/m68k/kernel/process.c linux-2.6.gc1/arch/m68k/kernel/process.c
--- linux-2.6.org/arch/m68k/kernel/process.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68k/kernel/process.c	2007-11-23 20:55:53.000000000 -0800
@@ -50,7 +50,7 @@ struct mm_struct init_mm = INIT_MM(init_
 EXPORT_SYMBOL(init_mm);
 
 union thread_union init_thread_union
-__attribute__((section(".data.init_task"), aligned(THREAD_SIZE)))
+__attribute__((section(".init_task.data"), aligned(THREAD_SIZE)))
        = { INIT_THREAD_INFO(init_task) };
 
 /* initial task structure */
diff -urpN linux-2.6.org/arch/m68k/kernel/sun3-head.S linux-2.6.gc1/arch/m68k/kernel/sun3-head.S
--- linux-2.6.org/arch/m68k/kernel/sun3-head.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68k/kernel/sun3-head.S	2007-11-23 20:55:41.000000000 -0800
@@ -29,7 +29,7 @@ kernel_pmd_table:              .skip 0x2
 .globl kernel_pg_dir
 .equ    kernel_pg_dir,kernel_pmd_table
 
-	.section .text.head
+	.section .head.text
 ENTRY(_stext)
 ENTRY(_start)
 
diff -urpN linux-2.6.org/arch/m68k/kernel/vmlinux-std.lds linux-2.6.gc1/arch/m68k/kernel/vmlinux-std.lds
--- linux-2.6.org/arch/m68k/kernel/vmlinux-std.lds	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68k/kernel/vmlinux-std.lds	2007-11-23 20:55:53.000000000 -0800
@@ -11,7 +11,7 @@ SECTIONS
   . = 0x1000;
   _text = .;			/* Text and read-only data */
   .text : {
-	*(.text.head)
+	*(.head.text)
 	TEXT_TEXT
 	SCHED_TEXT
 	LOCK_TEXT
@@ -36,7 +36,7 @@ SECTIONS
   .bss : { *(.bss) }		/* BSS */
 
   . = ALIGN(16);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) } :data
+  .cacheline_aligned.data : { *(.cacheline_aligned.data) } :data
 
   _edata = .;			/* End of data section */
 
@@ -76,7 +76,7 @@ SECTIONS
   . = ALIGN(8192);
   __init_end = .;
 
-  .data.init_task : { *(.data.init_task) }	/* The initial task and kernel stack */
+  .init_task.data : { *(.init_task.data) }	/* The initial task and kernel stack */
 
   _end = . ;
 
diff -urpN linux-2.6.org/arch/m68k/kernel/vmlinux-sun3.lds linux-2.6.gc1/arch/m68k/kernel/vmlinux-sun3.lds
--- linux-2.6.org/arch/m68k/kernel/vmlinux-sun3.lds	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68k/kernel/vmlinux-sun3.lds	2007-11-23 20:55:53.000000000 -0800
@@ -11,7 +11,7 @@ SECTIONS
   . = 0xE002000;
   _text = .;			/* Text and read-only data */
   .text : {
-	*(.text.head)
+	*(.head.text)
 	TEXT_TEXT
 	SCHED_TEXT
 	LOCK_TEXT
@@ -68,7 +68,7 @@ __init_begin = .;
 #endif
 	. = ALIGN(8192);
 	__init_end = .;
-	.data.init.task : { *(.data.init_task) }
+	.init.task.data : { *(.init_task.data) }
 
 
   .bss : { *(.bss) }		/* BSS */
diff -urpN linux-2.6.org/arch/m68knommu/kernel/init_task.c linux-2.6.gc1/arch/m68knommu/kernel/init_task.c
--- linux-2.6.org/arch/m68knommu/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68knommu/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -38,6 +38,6 @@ EXPORT_SYMBOL(init_task);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
diff -urpN linux-2.6.org/arch/m68knommu/kernel/vmlinux.lds.S linux-2.6.gc1/arch/m68knommu/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/m68knommu/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68knommu/kernel/vmlinux.lds.S	2007-11-23 20:55:53.000000000 -0800
@@ -55,7 +55,7 @@ SECTIONS {
 	.romvec : {
 		__rom_start = . ;
 		_romvec = .;
-		*(.data.initvect)
+		*(.initvect.data)
 	} > romvec
 #endif
 
@@ -64,7 +64,7 @@ SECTIONS {
 		_stext = . ;
 		TEXT_TEXT
 		SCHED_TEXT
-        	*(.text.lock)
+        	*(.lock.text)
 
 		. = ALIGN(16);          /* Exception table              */
 		__start___ex_table = .;
@@ -135,7 +135,7 @@ SECTIONS {
 		_sdata = . ;
 		DATA_DATA
 		. = ALIGN(8192) ;
-		*(.data.init_task)
+		*(.init_task.data)
 		_edata = . ;
 	} > DATA
 
diff -urpN linux-2.6.org/arch/m68knommu/platform/68360/head-ram.S linux-2.6.gc1/arch/m68knommu/platform/68360/head-ram.S
--- linux-2.6.org/arch/m68knommu/platform/68360/head-ram.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68knommu/platform/68360/head-ram.S	2007-11-23 20:55:53.000000000 -0800
@@ -280,7 +280,7 @@ _dprbase:
      * and then overwritten as needed.
      */
  
-.section ".data.initvect","awx"
+.section ".initvect.data","awx"
     .long   RAMEND	/* Reset: Initial Stack Pointer                 - 0.  */
     .long   _start      /* Reset: Initial Program Counter               - 1.  */
     .long   buserr      /* Bus Error                                    - 2.  */
diff -urpN linux-2.6.org/arch/m68knommu/platform/68360/head-rom.S linux-2.6.gc1/arch/m68knommu/platform/68360/head-rom.S
--- linux-2.6.org/arch/m68knommu/platform/68360/head-rom.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/m68knommu/platform/68360/head-rom.S	2007-11-23 20:55:53.000000000 -0800
@@ -291,7 +291,7 @@ _dprbase:
      * and then overwritten as needed.
      */
  
-.section ".data.initvect","awx"
+.section ".initvect.data","awx"
     .long   RAMEND	/* Reset: Initial Stack Pointer                 - 0.  */
     .long   _start      /* Reset: Initial Program Counter               - 1.  */
     .long   buserr      /* Bus Error                                    - 2.  */
diff -urpN linux-2.6.org/arch/mips/kernel/init_task.c linux-2.6.gc1/arch/mips/kernel/init_task.c
--- linux-2.6.org/arch/mips/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/mips/kernel/init_task.c	2007-11-23 20:55:53.000000000 -0800
@@ -28,7 +28,7 @@ EXPORT_SYMBOL(init_mm);
  * The things we do for performance..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"),
+	__attribute__((__section__(".init_task.data"),
 	               __aligned__(THREAD_SIZE))) =
 		{ INIT_THREAD_INFO(init_task) };
 
diff -urpN linux-2.6.org/arch/mips/kernel/vmlinux.lds.S linux-2.6.gc1/arch/mips/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/mips/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/mips/kernel/vmlinux.lds.S	2007-11-23 20:55:54.000000000 -0800
@@ -76,7 +76,7 @@ SECTIONS
 		 * object file alignment.  Using 32768
 		 */
 		. = ALIGN(_PAGE_SIZE);
-		*(.data.init_task)
+		*(.init_task.data)
 
 		DATA_DATA
 		CONSTRUCTORS
@@ -98,14 +98,14 @@ SECTIONS
 	. = ALIGN(_PAGE_SIZE);
 	.data_nosave : {
 		__nosave_begin = .;
-		*(.data.nosave)
+		*(.nosave.data)
 	}
 	. = ALIGN(_PAGE_SIZE);
 	__nosave_end = .;
 
 	. = ALIGN(32);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
+	.cacheline_aligned.data : {
+		*(.cacheline_aligned.data)
 	}
 	_edata =  .;			/* End of data section */
 
diff -urpN linux-2.6.org/arch/mips/lasat/image/head.S linux-2.6.gc1/arch/mips/lasat/image/head.S
--- linux-2.6.org/arch/mips/lasat/image/head.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/mips/lasat/image/head.S	2007-11-23 20:55:45.000000000 -0800
@@ -1,7 +1,7 @@
 #include <asm/lasat/head.h>
 
 	.text
-	.section .text.start, "ax"
+	.section .start.text, "ax"
 	.set noreorder
 	.set mips3
 
diff -urpN linux-2.6.org/arch/mips/lasat/image/romscript.normal linux-2.6.gc1/arch/mips/lasat/image/romscript.normal
--- linux-2.6.org/arch/mips/lasat/image/romscript.normal	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/mips/lasat/image/romscript.normal	2007-11-23 20:55:45.000000000 -0800
@@ -4,7 +4,7 @@ SECTIONS
 {
   .text :
   {
-    *(.text.start)
+    *(.start.text)
   }
 
   /* Data in ROM */
diff -urpN linux-2.6.org/arch/parisc/kernel/init_task.c linux-2.6.gc1/arch/parisc/kernel/init_task.c
--- linux-2.6.org/arch/parisc/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/parisc/kernel/init_task.c	2007-11-23 20:56:00.000000000 -0800
@@ -50,7 +50,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union
-	__attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) =
+	__attribute__((aligned(128))) __attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 #if PT_NLEVELS == 3
@@ -59,11 +59,11 @@ union thread_union init_thread_union
  * guarantee that global objects will be laid out in memory in the same order 
  * as the order of declaration, so put these in different sections and use
  * the linker script to order them. */
-pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data.vm0.pmd"), aligned(PAGE_SIZE)));
+pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".vm0.pmd.data"), aligned(PAGE_SIZE)));
 #endif
 
-pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data.vm0.pgd"), aligned(PAGE_SIZE)));
-pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data.vm0.pte"), aligned(PAGE_SIZE)));
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".vm0.pgd.data"), aligned(PAGE_SIZE)));
+pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".vm0.pte.data"), aligned(PAGE_SIZE)));
 
 /*
  * Initial task structure.
diff -urpN linux-2.6.org/arch/parisc/kernel/vmlinux.lds.S linux-2.6.gc1/arch/parisc/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/parisc/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/parisc/kernel/vmlinux.lds.S	2007-11-23 20:56:00.000000000 -0800
@@ -53,10 +53,10 @@ SECTIONS
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
-		*(.text.do_softirq)
-		*(.text.sys_exit)
-		*(.text.do_sigaltstack)
-		*(.text.do_fork)
+		*(.do_softirq.text)
+		*(.sys_exit.text)
+		*(.do_sigaltstack.text)
+		*(.do_fork.text)
 		*(.text.*)
 		*(.fixup)
 		*(.lock.text)		/* out-of-line lock text */
@@ -94,8 +94,8 @@ SECTIONS
 
 	/* rarely changed data like cpu maps */
 	. = ALIGN(16);
-	.data.read_mostly : {
-		*(.data.read_mostly)
+	.read_mostly.data : {
+		*(.read_mostly.data)
 	}
 
 	. = ALIGN(L1_CACHE_BYTES);
@@ -106,14 +106,14 @@ SECTIONS
 	}
 
 	. = ALIGN(L1_CACHE_BYTES);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
+	.cacheline_aligned.data : {
+		*(.cacheline_aligned.data)
 	}
 
 	/* PA-RISC locks requires 16-byte alignment */
 	. = ALIGN(16);
-	.data.lock_aligned : {
-		*(.data.lock_aligned)
+	.lock_aligned.data : {
+		*(.lock_aligned.data)
 	}
 
 	/* nosave data is really only used for software suspend...it's here
@@ -122,7 +122,7 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	__nosave_begin = .;
 	.data_nosave : {
-		*(.data.nosave)
+		*(.nosave.data)
 	}
 	. = ALIGN(PAGE_SIZE);
 	__nosave_end = .;
@@ -135,9 +135,9 @@ SECTIONS
 	/* page table entries need to be PAGE_SIZE aligned */
 	. = ALIGN(PAGE_SIZE);
 	.data.vmpages : {
-		*(.data.vm0.pmd)
-		*(.data.vm0.pgd)
-		*(.data.vm0.pte)
+		*(.vm0.pmd.data)
+		*(.vm0.pgd.data)
+		*(.vm0.pte.data)
 	}
 	.bss : {
 		*(.bss)
@@ -149,8 +149,8 @@ SECTIONS
 	/* assembler code expects init_task to be 16k aligned */
 	. = ALIGN(16384);
 	/* init_task */
-	.data.init_task : {
-		*(.data.init_task)
+	.init_task.data : {
+		*(.init_task.data)
 	}
 
 #ifdef CONFIG_64BIT
diff -urpN linux-2.6.org/arch/powerpc/kernel/head_32.S linux-2.6.gc1/arch/powerpc/kernel/head_32.S
--- linux-2.6.org/arch/powerpc/kernel/head_32.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/head_32.S	2007-11-23 20:55:41.000000000 -0800
@@ -48,7 +48,7 @@
 	mtspr	SPRN_DBAT##n##L,RB;	\
 1:
 
-	.section	.text.head, "ax"
+	.section	.head.text, "ax"
 	.stabs	"arch/powerpc/kernel/",N_SO,0,0,0f
 	.stabs	"head_32.S",N_SO,0,0,0f
 0:
diff -urpN linux-2.6.org/arch/powerpc/kernel/head_40x.S linux-2.6.gc1/arch/powerpc/kernel/head_40x.S
--- linux-2.6.org/arch/powerpc/kernel/head_40x.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/head_40x.S	2007-11-23 20:55:41.000000000 -0800
@@ -52,7 +52,7 @@
  *
  * This is all going to change RSN when we add bi_recs.......  -- Dan
  */
-	.section	.text.head, "ax"
+	.section	.head.text, "ax"
 _ENTRY(_stext);
 _ENTRY(_start);
 
diff -urpN linux-2.6.org/arch/powerpc/kernel/head_44x.S linux-2.6.gc1/arch/powerpc/kernel/head_44x.S
--- linux-2.6.org/arch/powerpc/kernel/head_44x.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/head_44x.S	2007-11-23 20:55:41.000000000 -0800
@@ -50,7 +50,7 @@
  *   r7 - End of kernel command line string
  *
  */
-	.section	.text.head, "ax"
+	.section	.head.text, "ax"
 _ENTRY(_stext);
 _ENTRY(_start);
 	/*
diff -urpN linux-2.6.org/arch/powerpc/kernel/head_8xx.S linux-2.6.gc1/arch/powerpc/kernel/head_8xx.S
--- linux-2.6.org/arch/powerpc/kernel/head_8xx.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/head_8xx.S	2007-11-23 20:55:41.000000000 -0800
@@ -38,7 +38,7 @@
 #else
 #define DO_8xx_CPU6(val, reg)
 #endif
-	.section	.text.head, "ax"
+	.section	.head.text, "ax"
 _ENTRY(_stext);
 _ENTRY(_start);
 
diff -urpN linux-2.6.org/arch/powerpc/kernel/head_fsl_booke.S linux-2.6.gc1/arch/powerpc/kernel/head_fsl_booke.S
--- linux-2.6.org/arch/powerpc/kernel/head_fsl_booke.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/head_fsl_booke.S	2007-11-23 20:55:41.000000000 -0800
@@ -52,7 +52,7 @@
  *   r7 - End of kernel command line string
  *
  */
-	.section	.text.head, "ax"
+	.section	.head.text, "ax"
 _ENTRY(_stext);
 _ENTRY(_start);
 	/*
diff -urpN linux-2.6.org/arch/powerpc/kernel/init_task.c linux-2.6.gc1/arch/powerpc/kernel/init_task.c
--- linux-2.6.org/arch/powerpc/kernel/init_task.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -23,7 +23,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/powerpc/kernel/machine_kexec_64.c linux-2.6.gc1/arch/powerpc/kernel/machine_kexec_64.c
--- linux-2.6.org/arch/powerpc/kernel/machine_kexec_64.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/machine_kexec_64.c	2007-11-23 20:55:54.000000000 -0800
@@ -250,7 +250,7 @@ static void kexec_prepare_cpus(void)
  * current, but that audit has not been performed.
  */
 union thread_union kexec_stack
-	__attribute__((__section__(".data.init_task"))) = { };
+	__attribute__((__section__(".init_task.data"))) = { };
 
 /* Our assembly helper, in kexec_stub.S */
 extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
diff -urpN linux-2.6.org/arch/powerpc/kernel/vdso.c linux-2.6.gc1/arch/powerpc/kernel/vdso.c
--- linux-2.6.org/arch/powerpc/kernel/vdso.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/vdso.c	2007-11-23 20:55:55.000000000 -0800
@@ -73,7 +73,7 @@ static int vdso_ready;
 static union {
 	struct vdso_data	data;
 	u8			page[PAGE_SIZE];
-} vdso_data_store __attribute__((__section__(".data.page_aligned")));
+} vdso_data_store __attribute__((__section__(".page_aligned.data")));
 struct vdso_data *vdso_data = &vdso_data_store.data;
 
 /* Format of the patch table */
diff -urpN linux-2.6.org/arch/powerpc/kernel/vdso32/vdso32_wrapper.S linux-2.6.gc1/arch/powerpc/kernel/vdso32/vdso32_wrapper.S
--- linux-2.6.org/arch/powerpc/kernel/vdso32/vdso32_wrapper.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/vdso32/vdso32_wrapper.S	2007-11-23 20:55:55.000000000 -0800
@@ -1,7 +1,7 @@
 #include <linux/init.h>
 #include <asm/page.h>
 
-	.section ".data.page_aligned"
+	.section ".page_aligned.data"
 
 	.globl vdso32_start, vdso32_end
 	.balign PAGE_SIZE
diff -urpN linux-2.6.org/arch/powerpc/kernel/vdso64/vdso64_wrapper.S linux-2.6.gc1/arch/powerpc/kernel/vdso64/vdso64_wrapper.S
--- linux-2.6.org/arch/powerpc/kernel/vdso64/vdso64_wrapper.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/vdso64/vdso64_wrapper.S	2007-11-23 20:55:55.000000000 -0800
@@ -1,7 +1,7 @@
 #include <linux/init.h>
 #include <asm/page.h>
 
-	.section ".data.page_aligned"
+	.section ".page_aligned.data"
 
 	.globl vdso64_start, vdso64_end
 	.balign PAGE_SIZE
diff -urpN linux-2.6.org/arch/powerpc/kernel/vmlinux.lds.S linux-2.6.gc1/arch/powerpc/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/powerpc/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/powerpc/kernel/vmlinux.lds.S	2007-11-23 20:55:55.000000000 -0800
@@ -35,9 +35,9 @@ SECTIONS
 	/* Text and gots */
 	.text : {
 		ALIGN_FUNCTION();
-		*(.text.head)
+		*(.head.text)
 		_text = .;
-		*(.text .fixup .text.init.refok .exit.text.refok)
+		*(.text .fixup .init.refok.text .exit.text.refok)
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
@@ -144,10 +144,10 @@ SECTIONS
 	}
 #endif
 	. = ALIGN(PAGE_SIZE);
-	.data.percpu : {
+	.percpu.data : {
 		__per_cpu_start = .;
-		*(.data.percpu)
-		*(.data.percpu.shared_aligned)
+		*(.percpu.data)
+		*(.percpu.shared_aligned.data)
 		__per_cpu_end = .;
 	}
 
@@ -205,28 +205,28 @@ SECTIONS
 #else
 	. = ALIGN(16384);
 #endif
-	.data.init_task : {
-		*(.data.init_task)
+	.init_task.data : {
+		*(.init_task.data)
 	}
 
 	. = ALIGN(PAGE_SIZE);
-	.data.page_aligned : {
-		*(.data.page_aligned)
+	.page_aligned.data : {
+		*(.page_aligned.data)
 	}
 
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
+	.cacheline_aligned.data : {
+		*(.cacheline_aligned.data)
 	}
 
 	. = ALIGN(L1_CACHE_BYTES);
-	.data.read_mostly : {
-		*(.data.read_mostly)
+	.read_mostly.data : {
+		*(.read_mostly.data)
 	}
 
 	. = ALIGN(PAGE_SIZE);
 	__data_nosave : {
 		__nosave_begin = .;
-		*(.data.nosave)
+		*(.nosave.data)
 		. = ALIGN(PAGE_SIZE);
 		__nosave_end = .;
 	}
diff -urpN linux-2.6.org/arch/ppc/boot/ld.script linux-2.6.gc1/arch/ppc/boot/ld.script
--- linux-2.6.org/arch/ppc/boot/ld.script	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ppc/boot/ld.script	2007-11-23 20:55:59.000000000 -0800
@@ -41,7 +41,7 @@ SECTIONS
   {
     *(.data)
     *(.data1)
-    *(.data.boot)
+    *(.boot.data)
     *(.sdata)
     *(.sdata2)
     *(.got.plt) *(.got)
diff -urpN linux-2.6.org/arch/ppc/boot/simple/misc-embedded.c linux-2.6.gc1/arch/ppc/boot/simple/misc-embedded.c
--- linux-2.6.org/arch/ppc/boot/simple/misc-embedded.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ppc/boot/simple/misc-embedded.c	2007-11-23 20:55:59.000000000 -0800
@@ -60,7 +60,7 @@ unsigned long com_port;
 
 /* We need to make sure that this is before the images to ensure
  * that it's in a mapped location. - Tom */
-bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
+bd_t hold_resid_buf __attribute__ ((__section__ (".boot.data")));
 bd_t *hold_residual = &hold_resid_buf;
 
 extern unsigned long serial_init(int chan, bd_t *bp);
diff -urpN linux-2.6.org/arch/ppc/boot/simple/openbios.c linux-2.6.gc1/arch/ppc/boot/simple/openbios.c
--- linux-2.6.org/arch/ppc/boot/simple/openbios.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ppc/boot/simple/openbios.c	2007-11-23 20:55:59.000000000 -0800
@@ -41,7 +41,7 @@ extern unsigned long decompress_kernel(u
 
 /* We need to make sure that this is before the images to ensure
  * that it's in a mapped location. */
-bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
+bd_t hold_resid_buf __attribute__ ((__section__ (".boot.data")));
 bd_t *hold_residual = &hold_resid_buf;
 
 typedef struct openbios_board_info {
diff -urpN linux-2.6.org/arch/ppc/boot/simple/pibs.c linux-2.6.gc1/arch/ppc/boot/simple/pibs.c
--- linux-2.6.org/arch/ppc/boot/simple/pibs.c	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ppc/boot/simple/pibs.c	2007-11-23 20:55:59.000000000 -0800
@@ -16,7 +16,7 @@ extern unsigned long decompress_kernel(u
 
 /* We need to make sure that this is before the images to ensure
  * that it's in a mapped location. - Tom */
-bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
+bd_t hold_resid_buf __attribute__ ((__section__ (".boot.data")));
 bd_t *hold_residual = &hold_resid_buf;
 
 /* String functions lifted from lib/vsprintf.c and lib/ctype.c */
diff -urpN linux-2.6.org/arch/ppc/kernel/vmlinux.lds.S linux-2.6.gc1/arch/ppc/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/ppc/kernel/vmlinux.lds.S	2007-11-23 18:55:09.000000000 -0800
+++ linux-2.6.gc1/arch/ppc/kernel/vmlinux.lds.S	2007-11-23 20:55:54.000000000 -0800
@@ -78,18 +78,18 @@ SECTIONS
 
   . = ALIGN(4096);
   __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
+  .data_nosave : { *(.nosave.data) }
   . = ALIGN(4096);
   __nosave_end = .;
 
   . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .cacheline_aligned.data : { *(.cacheline_aligned.data) }
 
   _edata  =  .;
   PROVIDE (edata = .);
 
   . = ALIGN(8192);
-  .data.init_task : { *(.data.init_task) }
+  .init_task.data : { *(.init_task.data) }
 
   NOTES
 
diff -urpN linux-2.6.org/arch/s390/kernel/head.S linux-2.6.gc1/arch/s390/kernel/head.S
--- linux-2.6.org/arch/s390/kernel/head.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/s390/kernel/head.S	2007-11-23 20:55:41.000000000 -0800
@@ -35,7 +35,7 @@
 #define ARCH_OFFSET	0
 #endif
 
-.section ".text.head","ax"
+.section ".head.text","ax"
 #ifndef CONFIG_IPL
 	.org   0
 	.long  0x00080000,0x80000000+startup	# Just a restart PSW
diff -urpN linux-2.6.org/arch/s390/kernel/init_task.c linux-2.6.gc1/arch/s390/kernel/init_task.c
--- linux-2.6.org/arch/s390/kernel/init_task.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/s390/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -32,7 +32,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/s390/kernel/vmlinux.lds.S linux-2.6.gc1/arch/s390/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/s390/kernel/vmlinux.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/s390/kernel/vmlinux.lds.S	2007-11-23 20:55:57.000000000 -0800
@@ -22,7 +22,7 @@ SECTIONS
 	. = 0x00000000;
 	.text : {
 	_text = .;		/* Text and read-only data */
-		*(.text.head)
+		*(.head.text)
 	TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
@@ -60,30 +60,30 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	.data_nosave : {
 	__nosave_begin = .;
-		*(.data.nosave)
+		*(.nosave.data)
 	}
 	. = ALIGN(PAGE_SIZE);
 	__nosave_end = .;
 
 	. = ALIGN(PAGE_SIZE);
-	.data.page_aligned : {
-		*(.data.idt)
+	.page_aligned.data : {
+		*(.idt.data)
 	}
 
 	. = ALIGN(0x100);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
+	.cacheline_aligned.data : {
+		*(.cacheline_aligned.data)
 	}
 
 	. = ALIGN(0x100);
-	.data.read_mostly : {
-		*(.data.read_mostly)
+	.read_mostly.data : {
+		*(.read_mostly.data)
 	}
 	_edata = .;		/* End of data section */
 
 	. = ALIGN(2 * PAGE_SIZE);	/* init_task */
-	.data.init_task : {
-		*(.data.init_task)
+	.init_task.data : {
+		*(.init_task.data)
 	}
 
 	/* will be freed after init */
diff -urpN linux-2.6.org/arch/sh/kernel/head.S linux-2.6.gc1/arch/sh/kernel/head.S
--- linux-2.6.org/arch/sh/kernel/head.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh/kernel/head.S	2007-11-23 20:55:41.000000000 -0800
@@ -36,7 +36,7 @@ ENTRY(empty_zero_page)
 1:
 	.skip	PAGE_SIZE - empty_zero_page - 1b
 
-	.section	.text.head, "ax"
+	.section	.head.text, "ax"
 
 /*
  * Condition at the entry of _stext:
diff -urpN linux-2.6.org/arch/sh/kernel/init_task.c linux-2.6.gc1/arch/sh/kernel/init_task.c
--- linux-2.6.org/arch/sh/kernel/init_task.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -23,7 +23,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/sh/kernel/irq.c linux-2.6.gc1/arch/sh/kernel/irq.c
--- linux-2.6.org/arch/sh/kernel/irq.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh/kernel/irq.c	2007-11-23 20:56:00.000000000 -0800
@@ -158,10 +158,10 @@ asmlinkage int do_IRQ(unsigned int irq, 
 
 #ifdef CONFIG_IRQSTACKS
 static char softirq_stack[NR_CPUS * THREAD_SIZE]
-		__attribute__((__section__(".bss.page_aligned")));
+		__attribute__((__section__(".bss.k.page_aligned")));
 
 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
-		__attribute__((__section__(".bss.page_aligned")));
+		__attribute__((__section__(".bss.k.page_aligned")));
 
 /*
  * allocate per-cpu stacks for hardirq and for softirq processing
diff -urpN linux-2.6.org/arch/sh/kernel/vmlinux.lds.S linux-2.6.gc1/arch/sh/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/sh/kernel/vmlinux.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh/kernel/vmlinux.lds.S	2007-11-23 21:59:58.000000000 -0800
@@ -23,7 +23,7 @@ SECTIONS
 	} = 0
 
 	.text : {
-		*(.text.head)
+		*(.head.text)
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
@@ -45,19 +45,19 @@ SECTIONS
 
 	. = ALIGN(THREAD_SIZE);
 	.data : {			/* Data */
-		*(.data.init_task)
+		*(.init_task.data)
 
 		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.cacheline_aligned)
+		*(.cacheline_aligned.data)
 
 		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.read_mostly)
+		*(.read_mostly.data)
 
 		. = ALIGN(PAGE_SIZE);
-		*(.data.page_aligned)
+		*(.page_aligned.data)
 
 		__nosave_begin = .;
-		*(.data.nosave)
+		*(.nosave.data)
 		. = ALIGN(PAGE_SIZE);
 		__nosave_end = .;
 
@@ -115,7 +115,7 @@ SECTIONS
 	.bss : {
 		__init_end = .;
 		__bss_start = .;		/* BSS */
-		*(.bss.page_aligned)
+		*(.bss.k.page_aligned)
 		*(.bss)
 		*(COMMON)
 		. = ALIGN(4);
diff -urpN linux-2.6.org/arch/sh64/kernel/entry.S linux-2.6.gc1/arch/sh64/kernel/entry.S
--- linux-2.6.org/arch/sh64/kernel/entry.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh64/kernel/entry.S	2007-11-23 20:55:45.000000000 -0800
@@ -2036,10 +2036,10 @@ asm_uaccess_end:
 
 
 /*
- * --- .text.init Section
+ * --- .init.text Section
  */
 
-	.section	.text.init, "ax"
+	.section	.init.text, "ax"
 
 /*
  * void trap_init (void)
diff -urpN linux-2.6.org/arch/sh64/kernel/head.S linux-2.6.gc1/arch/sh64/kernel/head.S
--- linux-2.6.org/arch/sh64/kernel/head.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh64/kernel/head.S	2007-11-23 20:55:41.000000000 -0800
@@ -124,7 +124,7 @@ empty_bad_pte_table:
 fpu_in_use:	.quad	0
 
 
-	.section	.text.head, "ax"
+	.section	.head.text, "ax"
 	.balign L1_CACHE_BYTES
 /*
  * Condition at the entry of __stext:
diff -urpN linux-2.6.org/arch/sh64/kernel/init_task.c linux-2.6.gc1/arch/sh64/kernel/init_task.c
--- linux-2.6.org/arch/sh64/kernel/init_task.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh64/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -34,7 +34,7 @@ struct pt_regs fake_swapper_regs;
  * special "init_task" linker map entry..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff -urpN linux-2.6.org/arch/sh64/kernel/vmlinux.lds.S linux-2.6.gc1/arch/sh64/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/sh64/kernel/vmlinux.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sh64/kernel/vmlinux.lds.S	2007-11-23 20:55:55.000000000 -0800
@@ -46,7 +46,7 @@ SECTIONS
 	} = 0
 
   .text : C_PHYS(.text) {
-  	*(.text.head)
+  	*(.head.text)
 	TEXT_TEXT
 	*(.text64)
         *(.text..SHmedia32)
@@ -78,17 +78,17 @@ SECTIONS
 	}
 
   . = ALIGN(PAGE_SIZE);
-  .data.page_aligned : C_PHYS(.data.page_aligned) { *(.data.page_aligned) }
+  .page_aligned.data : C_PHYS(.page_aligned.data) { *(.page_aligned.data) }
 
   PERCPU(PAGE_SIZE)
 
   . = ALIGN(L1_CACHE_BYTES);
-  .data.cacheline_aligned : C_PHYS(.data.cacheline_aligned) { *(.data.cacheline_aligned) }
+  .cacheline_aligned.data : C_PHYS(.cacheline_aligned.data) { *(.cacheline_aligned.data) }
 
   _edata = .;			/* End of data section */
 
   . = ALIGN(THREAD_SIZE);	/* init_task: structure size aligned */
-  .data.init_task : C_PHYS(.data.init_task) { *(.data.init_task) }
+  .init_task.data : C_PHYS(.init_task.data) { *(.init_task.data) }
 
   . = ALIGN(PAGE_SIZE);		/* Init code and data */
   __init_begin = .;
diff -urpN linux-2.6.org/arch/sparc/boot/btfixupprep.c linux-2.6.gc1/arch/sparc/boot/btfixupprep.c
--- linux-2.6.org/arch/sparc/boot/btfixupprep.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sparc/boot/btfixupprep.c	2007-11-23 20:55:54.000000000 -0800
@@ -171,7 +171,7 @@ main1:
 			}
 		} else if (buffer[nbase+4] != '_')
 			continue;
-		if (!strcmp (sect, ".text.exit"))
+		if (!strcmp (sect, ".exit.text"))
 			continue;
 		if (strcmp (sect, ".text") &&
 		    strcmp (sect, ".init.text") &&
@@ -325,7 +325,7 @@ main1:
 		(*rr)->next = NULL;
 	}
 	printf("! Generated by btfixupprep. Do not edit.\n\n");
-	printf("\t.section\t\".data.init\",#alloc,#write\n\t.align\t4\n\n");
+	printf("\t.section\t\".init.data\",#alloc,#write\n\t.align\t4\n\n");
 	printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n");
 	for (i = 0; i < last; i++) {
 		f = array + i;
diff -urpN linux-2.6.org/arch/sparc/kernel/head.S linux-2.6.gc1/arch/sparc/kernel/head.S
--- linux-2.6.org/arch/sparc/kernel/head.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sparc/kernel/head.S	2007-11-23 20:55:45.000000000 -0800
@@ -746,7 +746,7 @@ go_to_highmem:
 		 nop
 
 /* The code above should be at beginning and we have to take care about
- * short jumps, as branching to .text.init section from .text is usually
+ * short jumps, as branching to .init.text section from .text is usually
  * impossible */
 		__INIT
 /* Acquire boot time privileged register values, this will help debugging.
diff -urpN linux-2.6.org/arch/sparc/kernel/vmlinux.lds.S linux-2.6.gc1/arch/sparc/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/sparc/kernel/vmlinux.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sparc/kernel/vmlinux.lds.S	2007-11-23 20:55:53.000000000 -0800
@@ -86,8 +86,8 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
 	. = ALIGN(32);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
+	.cacheline_aligned.data : {
+		*(.cacheline_aligned.data)
 	}
 
 	__bss_start = .;
diff -urpN linux-2.6.org/arch/sparc64/kernel/head.S linux-2.6.gc1/arch/sparc64/kernel/head.S
--- linux-2.6.org/arch/sparc64/kernel/head.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sparc64/kernel/head.S	2007-11-23 20:55:45.000000000 -0800
@@ -458,7 +458,7 @@ jump_to_sun4u_init:
 	jmpl    %g2 + %g0, %g0
 	 nop
 
-	.section	.text.init.refok
+	.section	.init.refok.text
 sun4u_init:
 	BRANCH_IF_SUN4V(g1, sun4v_init)
 
diff -urpN linux-2.6.org/arch/sparc64/kernel/vmlinux.lds.S linux-2.6.gc1/arch/sparc64/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/sparc64/kernel/vmlinux.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/sparc64/kernel/vmlinux.lds.S	2007-11-23 20:55:53.000000000 -0800
@@ -32,12 +32,12 @@ SECTIONS
 		*(.data1)
 	}
 	. = ALIGN(64);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
+	.cacheline_aligned.data : {
+		*(.cacheline_aligned.data)
 	}
 	. = ALIGN(64);
-	.data.read_mostly : {
-		*(.data.read_mostly)
+	.read_mostly.data : {
+		*(.read_mostly.data)
 	}
 	_edata = .;
 	PROVIDE (edata = .);
diff -urpN linux-2.6.org/arch/um/kernel/dyn.lds.S linux-2.6.gc1/arch/um/kernel/dyn.lds.S
--- linux-2.6.org/arch/um/kernel/dyn.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/um/kernel/dyn.lds.S	2007-11-23 20:55:54.000000000 -0800
@@ -96,9 +96,9 @@ SECTIONS
   .fini_array     : { *(.fini_array) }
   .data           : {
     . = ALIGN(KERNEL_STACK_SIZE);		/* init_task */
-    *(.data.init_task)
+    *(.init_task.data)
     . = ALIGN(KERNEL_STACK_SIZE);
-    *(.data.init_irqstack)
+    *(.init_irqstack.data)
     DATA_DATA
     *(.data.* .gnu.linkonce.d.*)
     SORT(CONSTRUCTORS)
diff -urpN linux-2.6.org/arch/um/kernel/init_task.c linux-2.6.gc1/arch/um/kernel/init_task.c
--- linux-2.6.org/arch/um/kernel/init_task.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/um/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -36,9 +36,9 @@ EXPORT_SYMBOL(init_task);
  */
 
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 union thread_union cpu0_irqstack
-	__attribute__((__section__(".data.init_irqstack"))) =
+	__attribute__((__section__(".init_irqstack.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
diff -urpN linux-2.6.org/arch/um/kernel/uml.lds.S linux-2.6.gc1/arch/um/kernel/uml.lds.S
--- linux-2.6.org/arch/um/kernel/uml.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/um/kernel/uml.lds.S	2007-11-23 20:55:54.000000000 -0800
@@ -52,9 +52,9 @@ SECTIONS
   .data    :
   {
     . = ALIGN(KERNEL_STACK_SIZE);		/* init_task */
-    *(.data.init_task)
+    *(.init_task.data)
     . = ALIGN(KERNEL_STACK_SIZE);
-    *(.data.init_irqstack)
+    *(.init_irqstack.data)
     DATA_DATA
     *(.gnu.linkonce.d*)
     CONSTRUCTORS
diff -urpN linux-2.6.org/arch/v850/kernel/init_task.c linux-2.6.gc1/arch/v850/kernel/init_task.c
--- linux-2.6.org/arch/v850/kernel/init_task.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/v850/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -45,5 +45,5 @@ EXPORT_SYMBOL(init_task);
  * "init_task" linker map entry.
  */
 union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
diff -urpN linux-2.6.org/arch/v850/kernel/vmlinux.lds.S linux-2.6.gc1/arch/v850/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/v850/kernel/vmlinux.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/v850/kernel/vmlinux.lds.S	2007-11-23 20:55:56.000000000 -0800
@@ -95,8 +95,8 @@
 		TEXT_TEXT						      \
 		SCHED_TEXT						      \
 			*(.exit.text)	/* 2.5 convention */		      \
-			*(.text.exit)	/* 2.4 convention */		      \
-			*(.text.lock)					      \
+			*(.exit.text)	/* 2.4 convention */		      \
+			*(.lock.text)					      \
 			*(.exitcall.exit)				      \
 		__real_etext = . ;	/* There may be data after here.  */  \
 		RODATA_CONTENTS						      \
@@ -115,11 +115,11 @@
 		__sdata = . ;						      \
 		DATA_DATA						      \
 			*(.exit.data)	/* 2.5 convention */		      \
-			*(.data.exit)	/* 2.4 convention */		      \
+			*(.exit.data)	/* 2.4 convention */		      \
 		. = ALIGN (16) ;					      \
-		*(.data.cacheline_aligned)				      \
+		*(.cacheline_aligned.data)				      \
 		. = ALIGN (0x2000) ;					      \
-        	*(.data.init_task)					      \
+        	*(.init_task.data)					      \
 		. = ALIGN (0x2000) ;					      \
 		__edata = . ;
 
@@ -160,8 +160,8 @@
 			*(.init.text)	/* 2.5 convention */		      \
 			__einittext = .;				      \
 			*(.init.data)					      \
-			*(.text.init)	/* 2.4 convention */		      \
-			*(.data.init)					      \
+			*(.init.text)	/* 2.4 convention */		      \
+			*(.init.data)					      \
 		INITCALL_CONTENTS					      \
 		INITRAMFS_CONTENTS
 
@@ -171,7 +171,7 @@
 		. = ALIGN (4096) ;					      \
 		__init_start = . ;					      \
 			*(.init.data)	/* 2.5 convention */		      \
-			*(.data.init)	/* 2.4 convention */		      \
+			*(.init.data)	/* 2.4 convention */		      \
 		__init_end = . ;					      \
 		. = ALIGN (4096) ;
 
@@ -181,7 +181,7 @@
 			_sinittext = .;					      \
 			*(.init.text)	/* 2.5 convention */		      \
 			_einittext = .;					      \
-			*(.text.init)	/* 2.4 convention */		      \
+			*(.init.text)	/* 2.4 convention */		      \
 		INITCALL_CONTENTS					      \
 		INITRAMFS_CONTENTS
 
diff -urpN linux-2.6.org/arch/x86/boot/compressed/head_32.S linux-2.6.gc1/arch/x86/boot/compressed/head_32.S
--- linux-2.6.org/arch/x86/boot/compressed/head_32.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/boot/compressed/head_32.S	2007-11-23 20:55:41.000000000 -0800
@@ -29,7 +29,7 @@
 #include <asm/boot.h>
 #include <asm/asm-offsets.h>
 
-.section ".text.head","ax",@progbits
+.section ".head.text","ax",@progbits
 	.globl startup_32
 
 startup_32:
diff -urpN linux-2.6.org/arch/x86/boot/compressed/head_64.S linux-2.6.gc1/arch/x86/boot/compressed/head_64.S
--- linux-2.6.org/arch/x86/boot/compressed/head_64.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/boot/compressed/head_64.S	2007-11-23 20:55:41.000000000 -0800
@@ -31,7 +31,7 @@
 #include <asm/msr.h>
 #include <asm/asm-offsets.h>
 
-.section ".text.head"
+.section ".head.text"
 	.code32
 	.globl startup_32
 
diff -urpN linux-2.6.org/arch/x86/boot/compressed/vmlinux_32.lds linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_32.lds
--- linux-2.6.org/arch/x86/boot/compressed/vmlinux_32.lds	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_32.lds	2007-11-23 20:55:58.000000000 -0800
@@ -7,13 +7,13 @@ SECTIONS
          * address 0.
 	 */
 	. =  0 	;
-	.text.head : {
+	.head.text : {
 		_head = . ;
-		*(.text.head)
+		*(.head.text)
 		_ehead = . ;
 	}
-	.data.compressed : {
-		*(.data.compressed)
+	.compressed.data : {
+		*(.compressed.data)
 	}
 	.text :	{
 		_text = .; 	/* Text */
diff -urpN linux-2.6.org/arch/x86/boot/compressed/vmlinux_32.scr linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_32.scr
--- linux-2.6.org/arch/x86/boot/compressed/vmlinux_32.scr	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_32.scr	2007-11-23 20:55:58.000000000 -0800
@@ -1,6 +1,6 @@
 SECTIONS
 {
-  .data.compressed : {
+  .compressed.data : {
 	input_len = .;
 	LONG(input_data_end - input_data) input_data = .; 
 	*(.data) 
diff -urpN linux-2.6.org/arch/x86/boot/compressed/vmlinux_64.lds linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_64.lds
--- linux-2.6.org/arch/x86/boot/compressed/vmlinux_64.lds	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_64.lds	2007-11-23 20:55:50.000000000 -0800
@@ -9,9 +9,9 @@ SECTIONS
 	. = 0;
 	.text :	{
 		_head = . ;
-		*(.text.head)
+		*(.head.text)
 		_ehead = . ;
-		*(.text.compressed)
+		*(.compressed.text)
 		_text = .; 	/* Text */
 		*(.text)
 		*(.text.*)
diff -urpN linux-2.6.org/arch/x86/boot/compressed/vmlinux_64.scr linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_64.scr
--- linux-2.6.org/arch/x86/boot/compressed/vmlinux_64.scr	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/boot/compressed/vmlinux_64.scr	2007-11-23 20:55:50.000000000 -0800
@@ -1,6 +1,6 @@
 SECTIONS
 {
-  .text.compressed : {
+  .compressed.text : {
 	input_len = .;
 	LONG(input_data_end - input_data) input_data = .;
 	*(.data)
diff -urpN linux-2.6.org/arch/x86/ia32/vsyscall-sigreturn.S linux-2.6.gc1/arch/x86/ia32/vsyscall-sigreturn.S
--- linux-2.6.org/arch/x86/ia32/vsyscall-sigreturn.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/ia32/vsyscall-sigreturn.S	2007-11-23 20:55:49.000000000 -0800
@@ -8,7 +8,7 @@
  */
 
 	.code32
-	.section .text.sigreturn,"ax"
+	.section .sigreturn.text,"ax"
 	.balign 32
 	.globl __kernel_sigreturn
 	.type __kernel_sigreturn,@function
@@ -20,7 +20,7 @@ __kernel_sigreturn:
 .LEND_sigreturn:
 	.size __kernel_sigreturn,.-.LSTART_sigreturn
 
-	.section .text.rtsigreturn,"ax"
+	.section .rtsigreturn.text,"ax"
 	.balign 32
 	.globl __kernel_rt_sigreturn
 	.type __kernel_rt_sigreturn,@function
diff -urpN linux-2.6.org/arch/x86/ia32/vsyscall-syscall.S linux-2.6.gc1/arch/x86/ia32/vsyscall-syscall.S
--- linux-2.6.org/arch/x86/ia32/vsyscall-syscall.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/ia32/vsyscall-syscall.S	2007-11-23 20:55:50.000000000 -0800
@@ -8,7 +8,7 @@
 
 	.code32
 	.text
-	.section .text.vsyscall,"ax"
+	.section .vsyscall.text,"ax"
 	.globl __kernel_vsyscall
 	.type __kernel_vsyscall,@function
 __kernel_vsyscall:
diff -urpN linux-2.6.org/arch/x86/ia32/vsyscall-sysenter.S linux-2.6.gc1/arch/x86/ia32/vsyscall-sysenter.S
--- linux-2.6.org/arch/x86/ia32/vsyscall-sysenter.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/ia32/vsyscall-sysenter.S	2007-11-23 20:55:50.000000000 -0800
@@ -7,7 +7,7 @@
 
 	.code32
 	.text
-	.section .text.vsyscall,"ax"
+	.section .vsyscall.text,"ax"
 	.globl __kernel_vsyscall
 	.type __kernel_vsyscall,@function
 __kernel_vsyscall:
diff -urpN linux-2.6.org/arch/x86/ia32/vsyscall.lds linux-2.6.gc1/arch/x86/ia32/vsyscall.lds
--- linux-2.6.org/arch/x86/ia32/vsyscall.lds	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/ia32/vsyscall.lds	2007-11-23 20:55:50.000000000 -0800
@@ -24,18 +24,18 @@ SECTIONS
      is insufficient, ld -shared will barf.  Just increase it here.  */
   . = VSYSCALL_BASE + 0x400;
   
-  .text.vsyscall   : { *(.text.vsyscall) } 	:text =0x90909090
+  .vsyscall.text   : { *(.vsyscall.text) } 	:text =0x90909090
 
   /* This is an 32bit object and we cannot easily get the offsets
      into the 64bit kernel. Just hardcode them here. This assumes
      that all the stubs don't need more than 0x100 bytes. */
   . = VSYSCALL_BASE + 0x500;
 
-  .text.sigreturn  : { *(.text.sigreturn) }	:text =0x90909090
+  .sigreturn.text  : { *(.sigreturn.text) }	:text =0x90909090
 
   . = VSYSCALL_BASE + 0x600;
 
-  .text.rtsigreturn : { *(.text.rtsigreturn) }   :text =0x90909090
+  .rtsigreturn.text : { *(.rtsigreturn.text) }   :text =0x90909090
 	
   .note		  : { *(.note.*) }		:text :note
   .eh_frame_hdr   : { *(.eh_frame_hdr) }	:text :eh_frame_hdr
diff -urpN linux-2.6.org/arch/x86/kernel/head_32.S linux-2.6.gc1/arch/x86/kernel/head_32.S
--- linux-2.6.org/arch/x86/kernel/head_32.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/head_32.S	2007-11-23 20:56:00.000000000 -0800
@@ -77,7 +77,7 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + 
  * any particular GDT layout, because we load our own as soon as we
  * can.
  */
-.section .text.head,"ax",@progbits
+.section .head.text,"ax",@progbits
 ENTRY(startup_32)
 	/* check to see if KEEP_SEGMENTS flag is meaningful */
 	cmpw $0x207, BP_version(%esi)
@@ -551,7 +551,7 @@ ENTRY(_stext)
 /*
  * BSS section
  */
-.section ".bss.page_aligned","wa"
+.section ".bss.k.page_aligned","wa"
 	.align PAGE_SIZE_asm
 ENTRY(swapper_pg_dir)
 	.fill 1024,4,0
diff -urpN linux-2.6.org/arch/x86/kernel/head_64.S linux-2.6.gc1/arch/x86/kernel/head_64.S
--- linux-2.6.org/arch/x86/kernel/head_64.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/head_64.S	2007-11-23 20:56:00.000000000 -0800
@@ -25,7 +25,7 @@
  */
 
 	.text
-	.section .text.head
+	.section .head.text
 	.code64
 	.globl startup_64
 startup_64:
@@ -378,7 +378,7 @@ ENTRY(phys_base)
  * Also sysret mandates a special GDT layout 
  */
 		 		
-	.section .data.page_aligned, "aw"
+	.section .page_aligned.data, "aw"
 	.align PAGE_SIZE
 
 /* The TLS descriptors are currently at a different place compared to i386.
@@ -410,7 +410,7 @@ gdt_end:	
 ENTRY(idt_table)
 	.skip 256 * 16
 
-	.section .bss.page_aligned, "aw", @nobits
+	.section .bss.k.page_aligned, "aw", @nobits
 	.align PAGE_SIZE
 ENTRY(empty_zero_page)
 	.skip PAGE_SIZE
diff -urpN linux-2.6.org/arch/x86/kernel/init_task.c linux-2.6.gc1/arch/x86/kernel/init_task.c
--- linux-2.6.org/arch/x86/kernel/init_task.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -25,7 +25,7 @@ EXPORT_SYMBOL(init_mm);
  * "init_task" linker map entry..
  */
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
@@ -39,7 +39,7 @@ EXPORT_SYMBOL(init_task);
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
  * no more per-task TSS's. The TSS size is kept cacheline-aligned
- * so they are allowed to end up in the .data.cacheline_aligned
+ * so they are allowed to end up in the .cacheline_aligned.data
  * section. Since TSS's are completely CPU-local, we want them
  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
  */
diff -urpN linux-2.6.org/arch/x86/kernel/irq_32.c linux-2.6.gc1/arch/x86/kernel/irq_32.c
--- linux-2.6.org/arch/x86/kernel/irq_32.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/irq_32.c	2007-11-23 20:56:00.000000000 -0800
@@ -148,10 +148,10 @@ fastcall unsigned int do_IRQ(struct pt_r
 #ifdef CONFIG_4KSTACKS
 
 static char softirq_stack[NR_CPUS * THREAD_SIZE]
-		__attribute__((__section__(".bss.page_aligned")));
+		__attribute__((__section__(".bss.k.page_aligned")));
 
 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
-		__attribute__((__section__(".bss.page_aligned")));
+		__attribute__((__section__(".bss.k.page_aligned")));
 
 /*
  * allocate per-cpu stacks for hardirq and for softirq processing
diff -urpN linux-2.6.org/arch/x86/kernel/setup64.c linux-2.6.gc1/arch/x86/kernel/setup64.c
--- linux-2.6.org/arch/x86/kernel/setup64.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/setup64.c	2007-11-23 20:56:00.000000000 -0800
@@ -34,7 +34,7 @@ struct x8664_pda boot_cpu_pda[NR_CPUS] _
 
 struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
 
-char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
+char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.k.page_aligned")));
 
 unsigned long __supported_pte_mask __read_mostly = ~0UL;
 static int do_not_nx __cpuinitdata = 0;
@@ -148,7 +148,7 @@ void pda_init(int cpu)
 } 
 
 char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]
-__attribute__((section(".bss.page_aligned")));
+__attribute__((section(".bss.k.page_aligned")));
 
 extern asmlinkage void ignore_sysret(void);
 
diff -urpN linux-2.6.org/arch/x86/kernel/traps_32.c linux-2.6.gc1/arch/x86/kernel/traps_32.c
--- linux-2.6.org/arch/x86/kernel/traps_32.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/traps_32.c	2007-11-23 20:55:57.000000000 -0800
@@ -76,7 +76,7 @@ char ignore_fpu_irq = 0;
  * F0 0F bug workaround.. We have a special link segment
  * for this.
  */
-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
+struct desc_struct idt_table[256] __attribute__((__section__(".idt.data"))) = { {0, 0}, };
 
 asmlinkage void divide_error(void);
 asmlinkage void debug(void);
diff -urpN linux-2.6.org/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.gc1/arch/x86/kernel/vmlinux_32.lds.S
--- linux-2.6.org/arch/x86/kernel/vmlinux_32.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/vmlinux_32.lds.S	2007-11-23 21:59:58.000000000 -0800
@@ -37,9 +37,9 @@ SECTIONS
   . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
   phys_startup_32 = startup_32 - LOAD_OFFSET;
 
-  .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
+  .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
   	_text = .;			/* Text and read-only data */
-	*(.text.head)
+	*(.head.text)
   } :text = 0x9090
 
   /* read-only */
@@ -83,32 +83,32 @@ SECTIONS
   . = ALIGN(4096);
   .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
   	__nosave_begin = .;
-	*(.data.nosave)
+	*(.nosave.data)
   	. = ALIGN(4096);
   	__nosave_end = .;
   }
 
   . = ALIGN(4096);
-  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
-	*(.data.page_aligned)
-	*(.data.idt)
+  .page_aligned.data : AT(ADDR(.page_aligned.data) - LOAD_OFFSET) {
+	*(.page_aligned.data)
+	*(.idt.data)
   }
 
   . = ALIGN(32);
-  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
-	*(.data.cacheline_aligned)
+  .cacheline_aligned.data : AT(ADDR(.cacheline_aligned.data) - LOAD_OFFSET) {
+	*(.cacheline_aligned.data)
   }
 
   /* rarely changed data like cpu maps */
   . = ALIGN(32);
-  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
-	*(.data.read_mostly)
+  .read_mostly.data : AT(ADDR(.read_mostly.data) - LOAD_OFFSET) {
+	*(.read_mostly.data)
 	_edata = .;		/* End of data section */
   }
 
   . = ALIGN(THREAD_SIZE);	/* init_task */
-  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-	*(.data.init_task)
+  .init_task.data : AT(ADDR(.init_task.data) - LOAD_OFFSET) {
+	*(.init_task.data)
   }
 
   /* might get freed after init */
@@ -180,10 +180,10 @@ SECTIONS
   }
 #endif
   . = ALIGN(4096);
-  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
+  .percpu.data  : AT(ADDR(.percpu.data) - LOAD_OFFSET) {
 	__per_cpu_start = .;
-	*(.data.percpu)
-	*(.data.percpu.shared_aligned)
+	*(.percpu.data)
+	*(.percpu.shared_aligned.data)
 	__per_cpu_end = .;
   }
   . = ALIGN(4096);
@@ -192,7 +192,7 @@ SECTIONS
   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
 	__init_end = .;
 	__bss_start = .;		/* BSS */
-	*(.bss.page_aligned)
+	*(.bss.k.page_aligned)
 	*(.bss)
 	. = ALIGN(4);
 	__bss_stop = .;
diff -urpN linux-2.6.org/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.gc1/arch/x86/kernel/vmlinux_64.lds.S
--- linux-2.6.org/arch/x86/kernel/vmlinux_64.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/kernel/vmlinux_64.lds.S	2007-11-23 21:59:58.000000000 -0800
@@ -28,7 +28,7 @@ SECTIONS
   _text = .;			/* Text and read-only data */
   .text :  AT(ADDR(.text) - LOAD_OFFSET) {
 	/* First the code that has to be first for bootstrapping */
-	*(.text.head)
+	*(.head.text)
 	_stext = .;
 	/* Then the rest */
 	TEXT_TEXT
@@ -39,7 +39,7 @@ SECTIONS
 	*(.gnu.warning)
 	} :text = 0x9090
   				/* out-of-line lock text */
-  .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
+  .lock.text : AT(ADDR(.lock.text) - LOAD_OFFSET) { *(.lock.text) }
 
   _etext = .;			/* End of text section */
 
@@ -72,17 +72,17 @@ SECTIONS
 
   . = ALIGN(PAGE_SIZE);
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
-	*(.data.cacheline_aligned)
+  .cacheline_aligned.data : AT(ADDR(.cacheline_aligned.data) - LOAD_OFFSET) {
+	*(.cacheline_aligned.data)
   }
   . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
-  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
-  	*(.data.read_mostly)
+  .read_mostly.data : AT(ADDR(.read_mostly.data) - LOAD_OFFSET) {
+  	*(.read_mostly.data)
   }
 
 #define VSYSCALL_ADDR (-10*1024*1024)
-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.read_mostly.data) + SIZEOF(.read_mostly.data) + 4095) & ~(4095))
+#define VSYSCALL_VIRT_ADDR ((ADDR(.read_mostly.data) + SIZEOF(.read_mostly.data) + 4095) & ~(4095))
 
 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
@@ -131,13 +131,13 @@ SECTIONS
 #undef VVIRT
 
   . = ALIGN(8192);		/* init_task */
-  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-	*(.data.init_task)
+  .init_task.data : AT(ADDR(.init_task.data) - LOAD_OFFSET) {
+	*(.init_task.data)
   }:data.init
 
   . = ALIGN(4096);
-  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
-	*(.data.page_aligned)
+  .page_aligned.data : AT(ADDR(.page_aligned.data) - LOAD_OFFSET) {
+	*(.page_aligned.data)
   }
 
   /* might get freed after init */
@@ -210,13 +210,13 @@ SECTIONS
 
   . = ALIGN(4096);
   __nosave_begin = .;
-  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.nosave.data) }
   . = ALIGN(4096);
   __nosave_end = .;
 
   __bss_start = .;		/* BSS */
   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-	*(.bss.page_aligned)
+	*(.bss.k.page_aligned)
 	*(.bss)
 	}
   __bss_stop = .;
diff -urpN linux-2.6.org/arch/x86/xen/xen-head.S linux-2.6.gc1/arch/x86/xen/xen-head.S
--- linux-2.6.org/arch/x86/xen/xen-head.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/x86/xen/xen-head.S	2007-11-23 20:56:00.000000000 -0800
@@ -15,7 +15,7 @@ ENTRY(startup_xen)
 	jmp xen_start_kernel
 .popsection
 
-.pushsection .bss.page_aligned
+.pushsection .bss.k.page_aligned
 	.align PAGE_SIZE_asm
 ENTRY(hypercall_page)
 	.skip 0x1000
diff -urpN linux-2.6.org/arch/xtensa/kernel/head.S linux-2.6.gc1/arch/xtensa/kernel/head.S
--- linux-2.6.org/arch/xtensa/kernel/head.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/xtensa/kernel/head.S	2007-11-23 20:56:00.000000000 -0800
@@ -234,7 +234,7 @@ should_never_return:
  * BSS section
  */
 	
-.section ".bss.page_aligned", "w"
+.section ".bss.k.page_aligned", "w"
 ENTRY(swapper_pg_dir)
 	.fill	PAGE_SIZE, 1, 0
 ENTRY(empty_zero_page)
diff -urpN linux-2.6.org/arch/xtensa/kernel/init_task.c linux-2.6.gc1/arch/xtensa/kernel/init_task.c
--- linux-2.6.org/arch/xtensa/kernel/init_task.c	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/xtensa/kernel/init_task.c	2007-11-23 20:55:54.000000000 -0800
@@ -30,7 +30,7 @@ struct mm_struct init_mm = INIT_MM(init_
 EXPORT_SYMBOL(init_mm);
 
 union thread_union init_thread_union
-	__attribute__((__section__(".data.init_task"))) =
+	__attribute__((__section__(".init_task.data"))) =
 { INIT_THREAD_INFO(init_task) };
 
 struct task_struct init_task = INIT_TASK(init_task);
diff -urpN linux-2.6.org/arch/xtensa/kernel/vmlinux.lds.S linux-2.6.gc1/arch/xtensa/kernel/vmlinux.lds.S
--- linux-2.6.org/arch/xtensa/kernel/vmlinux.lds.S	2007-11-23 18:55:10.000000000 -0800
+++ linux-2.6.gc1/arch/xtensa/kernel/vmlinux.lds.S	2007-11-23 21:59:58.000000000 -0800
@@ -121,14 +121,14 @@ SECTIONS
     DATA_DATA
     CONSTRUCTORS
     . = ALIGN(XCHAL_ICACHE_LINESIZE);
-    *(.data.cacheline_aligned)
+    *(.cacheline_aligned.data)
   }
 
   _edata = .;
 
   /* The initial task */
   . = ALIGN(8192);
-  .data.init_task : { *(.data.init_task) }
+  .init_task.data : { *(.init_task.data) }
 
   /* Initialization code and data: */
 
@@ -255,7 +255,7 @@ SECTIONS
 
   /* BSS section */
   _bss_start = .;
-  .bss : { *(.bss.page_aligned) *(.bss) }
+  .bss : { *(.bss.k.page_aligned) *(.bss) }
   _bss_end = .;
 
   _end = .;
diff -urpN linux-2.6.org/include/asm-frv/init.h linux-2.6.gc1/include/asm-frv/init.h
--- linux-2.6.org/include/asm-frv/init.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-frv/init.h	2007-11-23 20:55:54.000000000 -0800
@@ -1,12 +1,12 @@
 #ifndef _ASM_INIT_H
 #define _ASM_INIT_H
 
-#define __init __attribute__ ((__section__ (".text.init")))
-#define __initdata __attribute__ ((__section__ (".data.init")))
+#define __init __attribute__ ((__section__ (".init.text")))
+#define __initdata __attribute__ ((__section__ (".init.data")))
 /* For assembly routines */
-#define __INIT		.section	".text.init",#alloc,#execinstr
+#define __INIT		.section	".init.text",#alloc,#execinstr
 #define __FINIT		.previous
-#define __INITDATA	.section	".data.init",#alloc,#write
+#define __INITDATA	.section	".init.data",#alloc,#write
 
 #endif
 
diff -urpN linux-2.6.org/include/asm-generic/percpu.h linux-2.6.gc1/include/asm-generic/percpu.h
--- linux-2.6.org/include/asm-generic/percpu.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-generic/percpu.h	2007-11-23 20:55:52.000000000 -0800
@@ -12,10 +12,10 @@ extern unsigned long __per_cpu_offset[NR
 
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name) \
-    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
+    __attribute__((__section__(".percpu.data"))) __typeof__(type) per_cpu__##name
 
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		\
-    __attribute__((__section__(".data.percpu.shared_aligned"))) \
+    __attribute__((__section__(".percpu.shared_aligned.data"))) \
     __typeof__(type) per_cpu__##name				\
     ____cacheline_aligned_in_smp
 
diff -urpN linux-2.6.org/include/asm-generic/vmlinux.lds.h linux-2.6.gc1/include/asm-generic/vmlinux.lds.h
--- linux-2.6.org/include/asm-generic/vmlinux.lds.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-generic/vmlinux.lds.h	2007-11-23 20:55:54.000000000 -0800
@@ -12,7 +12,7 @@
 /* .data section */
 #define DATA_DATA							\
 	*(.data)							\
-	*(.data.init.refok)						\
+	*(.init.refok.data)						\
 	. = ALIGN(8);							\
 	VMLINUX_SYMBOL(__start___markers) = .;				\
 	*(__markers)							\
@@ -158,7 +158,7 @@
 #define TEXT_TEXT							\
 		ALIGN_FUNCTION();					\
 		*(.text)						\
-		*(.text.init.refok)					\
+		*(.init.refok.text)					\
 		*(.exit.text.refok)
 
 /* sched.text is aling to function alignment to secure we have same
@@ -258,8 +258,8 @@
 #define PERCPU(align)							\
 	. = ALIGN(align);						\
 	__per_cpu_start = .;						\
-	.data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {		\
-		*(.data.percpu)						\
-		*(.data.percpu.shared_aligned)				\
+	.percpu.data  : AT(ADDR(.percpu.data) - LOAD_OFFSET) {		\
+		*(.percpu.data)						\
+		*(.percpu.shared_aligned.data)				\
 	}								\
 	__per_cpu_end = .;
diff -urpN linux-2.6.org/include/asm-ia64/asmmacro.h linux-2.6.gc1/include/asm-ia64/asmmacro.h
--- linux-2.6.org/include/asm-ia64/asmmacro.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-ia64/asmmacro.h	2007-11-23 20:55:56.000000000 -0800
@@ -70,12 +70,12 @@ name:
  * path (ivt.S - TLB miss processing) or in places where it might not be
  * safe to use a "tpa" instruction (mca_asm.S - error recovery).
  */
-	.section ".data.patch.vtop", "a"	// declare section & section attributes
+	.section ".patch.vtop.data", "a"	// declare section & section attributes
 	.previous
 
 #define	LOAD_PHYSICAL(pr, reg, obj)		\
 [1:](pr)movl reg = obj;				\
-	.xdata4 ".data.patch.vtop", 1b-.
+	.xdata4 ".patch.vtop.data", 1b-.
 
 /*
  * For now, we always put in the McKinley E9 workaround.  On CPUs that don't need it,
@@ -84,11 +84,11 @@ name:
 #define DO_MCKINLEY_E9_WORKAROUND
 
 #ifdef DO_MCKINLEY_E9_WORKAROUND
-	.section ".data.patch.mckinley_e9", "a"
+	.section ".patch.mckinley_e9.data", "a"
 	.previous
 /* workaround for Itanium 2 Errata 9: */
 # define FSYS_RETURN					\
-	.xdata4 ".data.patch.mckinley_e9", 1f-.;	\
+	.xdata4 ".patch.mckinley_e9.data", 1f-.;	\
 1:{ .mib;						\
 	nop.m 0;					\
 	mov r16=ar.pfs;					\
@@ -107,11 +107,11 @@ name:
  * If physical stack register size is different from DEF_NUM_STACK_REG,
  * dynamically patch the kernel for correct size.
  */
-	.section ".data.patch.phys_stack_reg", "a"
+	.section ".patch.phys_stack_reg.data", "a"
 	.previous
 #define LOAD_PHYS_STACK_REG_SIZE(reg)			\
 [1:]	adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0;	\
-	.xdata4 ".data.patch.phys_stack_reg", 1b-.
+	.xdata4 ".patch.phys_stack_reg.data", 1b-.
 
 /*
  * Up until early 2004, use of .align within a function caused bad unwind info.
diff -urpN linux-2.6.org/include/asm-ia64/cache.h linux-2.6.gc1/include/asm-ia64/cache.h
--- linux-2.6.org/include/asm-ia64/cache.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-ia64/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -24,6 +24,6 @@
 # define SMP_CACHE_BYTES	(1 << 3)
 #endif
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".read_mostly.data")))
 
 #endif /* _ASM_IA64_CACHE_H */
diff -urpN linux-2.6.org/include/asm-ia64/percpu.h linux-2.6.gc1/include/asm-ia64/percpu.h
--- linux-2.6.org/include/asm-ia64/percpu.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-ia64/percpu.h	2007-11-23 20:55:52.000000000 -0800
@@ -26,12 +26,12 @@
 
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name)				\
-	__attribute__((__section__(".data.percpu")))		\
+	__attribute__((__section__(".percpu.data")))		\
 	__SMALL_ADDR_AREA __typeof__(type) per_cpu__##name
 
 #ifdef CONFIG_SMP
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)			\
-	__attribute__((__section__(".data.percpu.shared_aligned")))	\
+	__attribute__((__section__(".percpu.shared_aligned.data")))	\
 	__SMALL_ADDR_AREA __typeof__(type) per_cpu__##name		\
 	____cacheline_aligned_in_smp
 #else
diff -urpN linux-2.6.org/include/asm-m68knommu/semaphore.h linux-2.6.gc1/include/asm-m68knommu/semaphore.h
--- linux-2.6.org/include/asm-m68knommu/semaphore.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-m68knommu/semaphore.h	2007-11-23 20:55:46.000000000 -0800
@@ -117,7 +117,7 @@ static inline int down_trylock(struct se
 		"jmi 2f\n\t"
 		"clrl %0\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
+		".section .lock.text,\"ax\"\n"
 		".even\n"
 		"2:\tpea 1b\n\t"
 		"jbra __down_failed_trylock\n"
diff -urpN linux-2.6.org/include/asm-parisc/cache.h linux-2.6.gc1/include/asm-parisc/cache.h
--- linux-2.6.org/include/asm-parisc/cache.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-parisc/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -28,7 +28,7 @@
 
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".read_mostly.data")))
 
 void parisc_cache_init(void);	/* initializes cache-flushing */
 void disable_sr_hashing_asm(int); /* low level support for above */
diff -urpN linux-2.6.org/include/asm-parisc/system.h linux-2.6.gc1/include/asm-parisc/system.h
--- linux-2.6.org/include/asm-parisc/system.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-parisc/system.h	2007-11-23 20:55:55.000000000 -0800
@@ -174,7 +174,7 @@ static inline void set_eiem(unsigned lon
 })
 
 #ifdef CONFIG_SMP
-# define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
+# define __lock_aligned __attribute__((__section__(".lock_aligned.data")))
 #endif
 
 #define arch_align_stack(x) (x)
diff -urpN linux-2.6.org/include/asm-powerpc/cache.h linux-2.6.gc1/include/asm-powerpc/cache.h
--- linux-2.6.org/include/asm-powerpc/cache.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-powerpc/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -35,7 +35,7 @@ extern struct ppc64_caches ppc64_caches;
 #endif /* __powerpc64__ && ! __ASSEMBLY__ */
 
 #if !defined(__ASSEMBLY__)
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".read_mostly.data")))
 #endif
 
 #endif /* __KERNEL__ */
diff -urpN linux-2.6.org/include/asm-powerpc/page_64.h linux-2.6.gc1/include/asm-powerpc/page_64.h
--- linux-2.6.org/include/asm-powerpc/page_64.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-powerpc/page_64.h	2007-11-23 20:55:55.000000000 -0800
@@ -158,7 +158,7 @@ do {						\
 #else
 #define __page_aligned \
 	__attribute__((__aligned__(PAGE_SIZE), \
-		__section__(".data.page_aligned")))
+		__section__(".page_aligned.data")))
 #endif
 
 #define VM_DATA_DEFAULT_FLAGS \
diff -urpN linux-2.6.org/include/asm-powerpc/percpu.h linux-2.6.gc1/include/asm-powerpc/percpu.h
--- linux-2.6.org/include/asm-powerpc/percpu.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-powerpc/percpu.h	2007-11-23 20:55:52.000000000 -0800
@@ -18,10 +18,10 @@
 
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name) \
-    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
+    __attribute__((__section__(".percpu.data"))) __typeof__(type) per_cpu__##name
 
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		\
-    __attribute__((__section__(".data.percpu.shared_aligned"))) \
+    __attribute__((__section__(".percpu.shared_aligned.data"))) \
     __typeof__(type) per_cpu__##name				\
     ____cacheline_aligned_in_smp
 
diff -urpN linux-2.6.org/include/asm-powerpc/ppc_asm.h linux-2.6.gc1/include/asm-powerpc/ppc_asm.h
--- linux-2.6.org/include/asm-powerpc/ppc_asm.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-powerpc/ppc_asm.h	2007-11-23 20:55:45.000000000 -0800
@@ -156,7 +156,7 @@ name: \
 GLUE(.,name):
 
 #define _INIT_GLOBAL(name) \
-	.section ".text.init.refok"; \
+	.section ".init.refok.text"; \
 	.align 2 ; \
 	.globl name; \
 	.globl GLUE(.,name); \
@@ -196,7 +196,7 @@ name: \
 GLUE(.,name):
 
 #define _INIT_STATIC(name) \
-	.section ".text.init.refok"; \
+	.section ".init.refok.text"; \
 	.align 2 ; \
 	.section ".opd","aw"; \
 name: \
diff -urpN linux-2.6.org/include/asm-s390/cache.h linux-2.6.gc1/include/asm-s390/cache.h
--- linux-2.6.org/include/asm-s390/cache.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-s390/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -14,6 +14,6 @@
 #define L1_CACHE_BYTES     256
 #define L1_CACHE_SHIFT     8
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".read_mostly.data")))
 
 #endif
diff -urpN linux-2.6.org/include/asm-s390/percpu.h linux-2.6.gc1/include/asm-s390/percpu.h
--- linux-2.6.org/include/asm-s390/percpu.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-s390/percpu.h	2007-11-23 20:55:52.000000000 -0800
@@ -38,11 +38,11 @@ extern unsigned long __per_cpu_offset[NR
 
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name) \
-    __attribute__((__section__(".data.percpu"))) \
+    __attribute__((__section__(".percpu.data"))) \
     __typeof__(type) per_cpu__##name
 
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		\
-    __attribute__((__section__(".data.percpu.shared_aligned"))) \
+    __attribute__((__section__(".percpu.shared_aligned.data"))) \
     __typeof__(type) per_cpu__##name				\
     ____cacheline_aligned_in_smp
 
diff -urpN linux-2.6.org/include/asm-sh/cache.h linux-2.6.gc1/include/asm-sh/cache.h
--- linux-2.6.org/include/asm-sh/cache.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-sh/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -19,7 +19,7 @@
 
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".read_mostly.data")))
 
 #ifndef __ASSEMBLY__
 struct cache_info {
diff -urpN linux-2.6.org/include/asm-sh64/cache.h linux-2.6.gc1/include/asm-sh64/cache.h
--- linux-2.6.org/include/asm-sh64/cache.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-sh64/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -26,7 +26,7 @@
 #else
 #define __cacheline_aligned					\
   __attribute__((__aligned__(L1_CACHE_BYTES),			\
-		 __section__(".data.cacheline_aligned")))
+		 __section__(".cacheline_aligned.data")))
 #endif
 
 /*
diff -urpN linux-2.6.org/include/asm-sparc64/cache.h linux-2.6.gc1/include/asm-sparc64/cache.h
--- linux-2.6.org/include/asm-sparc64/cache.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-sparc64/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -13,6 +13,6 @@
 #define        SMP_CACHE_BYTES_SHIFT	6
 #define        SMP_CACHE_BYTES		(1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".read_mostly.data")))
 
 #endif
diff -urpN linux-2.6.org/include/asm-sparc64/percpu.h linux-2.6.gc1/include/asm-sparc64/percpu.h
--- linux-2.6.org/include/asm-sparc64/percpu.h	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-sparc64/percpu.h	2007-11-23 20:55:52.000000000 -0800
@@ -18,10 +18,10 @@ extern unsigned long __per_cpu_shift;
 
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name) \
-    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
+    __attribute__((__section__(".percpu.data"))) __typeof__(type) per_cpu__##name
 
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		\
-    __attribute__((__section__(".data.percpu.shared_aligned"))) \
+    __attribute__((__section__(".percpu.shared_aligned.data"))) \
     __typeof__(type) per_cpu__##name				\
     ____cacheline_aligned_in_smp
 
diff -urpN linux-2.6.org/include/asm-um/common.lds.S linux-2.6.gc1/include/asm-um/common.lds.S
--- linux-2.6.org/include/asm-um/common.lds.S	2007-11-23 18:55:25.000000000 -0800
+++ linux-2.6.gc1/include/asm-um/common.lds.S	2007-11-23 20:55:52.000000000 -0800
@@ -49,9 +49,9 @@
   }
 
   . = ALIGN(32);
-  .data.percpu : {
+  .percpu.data : {
 	__per_cpu_start = . ;
-	*(.data.percpu)
+	*(.percpu.data)
 	__per_cpu_end = . ;
   }
 	
diff -urpN linux-2.6.org/include/asm-x86/cache.h linux-2.6.gc1/include/asm-x86/cache.h
--- linux-2.6.org/include/asm-x86/cache.h	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/include/asm-x86/cache.h	2007-11-23 20:55:55.000000000 -0800
@@ -5,7 +5,7 @@
 #define L1_CACHE_SHIFT	(CONFIG_X86_L1_CACHE_SHIFT)
 #define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".read_mostly.data")))
 
 #ifdef CONFIG_X86_VSMP
 /* vSMP Internode cacheline shift */
@@ -13,7 +13,7 @@
 #ifdef CONFIG_SMP
 #define __cacheline_aligned_in_smp					\
 	__attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))	\
-	__attribute__((__section__(".data.page_aligned")))
+	__attribute__((__section__(".page_aligned.data")))
 #endif
 #endif
 
diff -urpN linux-2.6.org/include/asm-x86/percpu_32.h linux-2.6.gc1/include/asm-x86/percpu_32.h
--- linux-2.6.org/include/asm-x86/percpu_32.h	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/include/asm-x86/percpu_32.h	2007-11-23 20:55:52.000000000 -0800
@@ -52,10 +52,10 @@ extern unsigned long __per_cpu_offset[];
 /* Separate out the type, so (int[3], foo) works. */
 #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
 #define DEFINE_PER_CPU(type, name) \
-    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
+    __attribute__((__section__(".percpu.data"))) __typeof__(type) per_cpu__##name
 
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		\
-    __attribute__((__section__(".data.percpu.shared_aligned"))) \
+    __attribute__((__section__(".percpu.shared_aligned.data"))) \
     __typeof__(type) per_cpu__##name				\
     ____cacheline_aligned_in_smp
 
diff -urpN linux-2.6.org/include/asm-x86/percpu_64.h linux-2.6.gc1/include/asm-x86/percpu_64.h
--- linux-2.6.org/include/asm-x86/percpu_64.h	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/include/asm-x86/percpu_64.h	2007-11-23 20:55:52.000000000 -0800
@@ -18,10 +18,10 @@
 
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name) \
-    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
+    __attribute__((__section__(".percpu.data"))) __typeof__(type) per_cpu__##name
 
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)		\
-    __attribute__((__section__(".data.percpu.shared_aligned"))) \
+    __attribute__((__section__(".percpu.shared_aligned.data"))) \
     __typeof__(type) per_cpu__##name				\
     ____cacheline_internodealigned_in_smp
 
diff -urpN linux-2.6.org/include/linux/cache.h linux-2.6.gc1/include/linux/cache.h
--- linux-2.6.org/include/linux/cache.h	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/include/linux/cache.h	2007-11-23 20:55:53.000000000 -0800
@@ -31,7 +31,7 @@
 #ifndef __cacheline_aligned
 #define __cacheline_aligned					\
   __attribute__((__aligned__(SMP_CACHE_BYTES),			\
-		 __section__(".data.cacheline_aligned")))
+		 __section__(".cacheline_aligned.data")))
 #endif /* __cacheline_aligned */
 
 #ifndef __cacheline_aligned_in_smp
diff -urpN linux-2.6.org/include/linux/init.h linux-2.6.gc1/include/linux/init.h
--- linux-2.6.org/include/linux/init.h	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/include/linux/init.h	2007-11-23 20:55:54.000000000 -0800
@@ -55,8 +55,8 @@
  * 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 __init_refok     noinline __attribute__ ((__section__ (".init.refok.text")))
+#define __initdata_refok          __attribute__ ((__section__ (".init.refok.data")))
 #define __exit_refok     noinline __attribute__ ((__section__ (".exit.text.refok")))
 
 #ifdef MODULE
@@ -67,10 +67,10 @@
 
 /* For assembly routines */
 #define __INIT		.section	".init.text","ax"
-#define __INIT_REFOK	.section	".text.init.refok","ax"
+#define __INIT_REFOK	.section	".init.refok.text","ax"
 #define __FINIT		.previous
 #define __INITDATA	.section	".init.data","aw"
-#define __INITDATA_REFOK .section	".data.init.refok","aw"
+#define __INITDATA_REFOK .section	".init.refok.data","aw"
 
 #ifndef __ASSEMBLY__
 /*
@@ -242,7 +242,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 __attribute__ ((__section__ (".nosave.data")))
 
 /* This means "can be init if no module support, otherwise module load
    may call it." */
diff -urpN linux-2.6.org/include/linux/spinlock.h linux-2.6.gc1/include/linux/spinlock.h
--- linux-2.6.org/include/linux/spinlock.h	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/include/linux/spinlock.h	2007-11-23 20:55:46.000000000 -0800
@@ -59,7 +59,7 @@
 /*
  * Must define these before including other files, inline functions need them
  */
-#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME
+#define LOCK_SECTION_NAME ".lock..text"KBUILD_BASENAME
 
 #define LOCK_SECTION_START(extra)               \
         ".subsection 1\n\t"                     \
diff -urpN linux-2.6.org/kernel/module.c linux-2.6.gc1/kernel/module.c
--- linux-2.6.org/kernel/module.c	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/kernel/module.c	2007-11-23 20:55:52.000000000 -0800
@@ -422,7 +422,7 @@ static unsigned int find_pcpusec(Elf_Ehd
 				 Elf_Shdr *sechdrs,
 				 const char *secstrings)
 {
-	return find_sec(hdr, sechdrs, secstrings, ".data.percpu");
+	return find_sec(hdr, sechdrs, secstrings, ".percpu.data");
 }
 
 static int percpu_modinit(void)
diff -urpN linux-2.6.org/scripts/mod/modpost.c linux-2.6.gc1/scripts/mod/modpost.c
--- linux-2.6.org/scripts/mod/modpost.c	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc1/scripts/mod/modpost.c	2007-11-23 20:55:54.000000000 -0800
@@ -649,7 +649,7 @@ static int data_section(const char *name
  * Pattern 0:
  *   Do not warn if funtion/data are marked with __init_refok/__initdata_refok.
  *   The pattern is identified by:
- *   fromsec = .text.init.refok* | .data.init.refok*
+ *   fromsec = .init.refok.text* | .init.refok.data*
  *
  * Pattern 1:
  *   If a module parameter is declared __initdata and permissions=0
@@ -672,8 +672,8 @@ static int data_section(const char *name
  *   atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer
  *
  * Pattern 3:
- *   Whitelist all refereces from .text.head to .init.data
- *   Whitelist all refereces from .text.head to .init.text
+ *   Whitelist all refereces from .head.text to .init.data
+ *   Whitelist all refereces from .head.text to .init.text
  *
  * Pattern 4:
  *   Some symbols belong to init section but still it is ok to reference
@@ -717,9 +717,9 @@ static int secref_whitelist(const char *
 	};
 
 	/* Check for pattern 0 */
-	if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) ||
+	if ((strncmp(fromsec, ".init.refok.text", strlen(".init.refok.text")) == 0) ||
 	    (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) ||
-	    (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0))
+	    (strncmp(fromsec, ".init.refok.data", strlen(".init.refok.data")) == 0))
 		return 1;
 
 	/* Check for pattern 1 */
@@ -735,7 +735,7 @@ static int secref_whitelist(const char *
 				return 1;
 
 	/* Check for pattern 3 */
-	if ((strcmp(fromsec, ".text.head") == 0) &&
+	if ((strcmp(fromsec, ".head.text") == 0) &&
 		((strcmp(tosec, ".init.data") == 0) ||
 		(strcmp(tosec, ".init.text") == 0)))
 	return 1;
@@ -1196,7 +1196,7 @@ static int init_section_ref_ok(const cha
 		"__param",
 		".data.rel.ro",		/* used by parisc64 */
 		".init",
-		".text.lock",
+		".lock.text",
 		NULL
 	};
 	/* Start of section names */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2/3] build system: section garbage collection - modpost fix
  2007-11-24 23:14   ` [PATCH 0/3] build system: section garbage collection Denys Vlasenko
  2007-11-24 23:17     ` [PATCH 1/3] build system: section garbage collection - rename sections Denys Vlasenko
@ 2007-11-24 23:17     ` Denys Vlasenko
  2007-11-24 23:18     ` [PATCH 3/3] build system: section garbage collection - main part Denys Vlasenko
  2 siblings, 0 replies; 18+ messages in thread
From: Denys Vlasenko @ 2007-11-24 23:17 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 245 bytes --]

On Saturday 24 November 2007 15:14, Denys Vlasenko wrote:
> 2.modpost
>     Update scripts/mod/* machinery to correctly handle the case
>     when we have more than 64k sections.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-- 
vda

[-- Attachment #2: linux-2.6-linus_git.2.modpost_fix.patch --]
[-- Type: text/x-diff, Size: 9827 bytes --]

diff -urpN linux-2.6.gc1/scripts/mod/file2alias.c linux-2.6.gc2/scripts/mod/file2alias.c
--- linux-2.6.gc1/scripts/mod/file2alias.c	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc2/scripts/mod/file2alias.c	2007-11-23 21:10:04.000000000 -0800
@@ -585,7 +585,7 @@ void handle_moddevtable(struct module *m
 	char *zeros = NULL;
 
 	/* We're looking for a section relative symbol */
-	if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
+	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
 		return;
 
 	/* Handle all-NULL symbols allocated into .bss */
@@ -594,7 +594,7 @@ void handle_moddevtable(struct module *m
 		symval = zeros;
 	} else {
 		symval = (void *)info->hdr
-			+ info->sechdrs[sym->st_shndx].sh_offset
+			+ info->sechdrs[get_secindex(info, sym)].sh_offset
 			+ sym->st_value;
 	}
 
diff -urpN linux-2.6.gc1/scripts/mod/modpost.c linux-2.6.gc2/scripts/mod/modpost.c
--- linux-2.6.gc1/scripts/mod/modpost.c	2007-11-23 20:55:54.000000000 -0800
+++ linux-2.6.gc2/scripts/mod/modpost.c	2007-11-23 21:08:41.000000000 -0800
@@ -235,7 +235,7 @@ static enum export export_no(const char 
 	return export_unknown;
 }
 
-static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
+static enum export export_from_sec(struct elf_info *elf, unsigned sec)
 {
 	if (sec == elf->export_sec)
 		return export_plain;
@@ -356,6 +356,8 @@ static int parse_elf(struct elf_info *in
 	Elf_Ehdr *hdr;
 	Elf_Shdr *sechdrs;
 	Elf_Sym  *sym;
+	const char *secstrings;
+	unsigned int symtab_idx = ~0U;
 
 	hdr = grab_file(filename, &info->size);
 	if (!hdr) {
@@ -375,6 +377,7 @@ static int parse_elf(struct elf_info *in
 		/* Not an ELF file - silently ignore it */
 		return 0;
 	}
+
 	/* Fix endianness in ELF header */
 	hdr->e_shoff    = TO_NATIVE(hdr->e_shoff);
 	hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
@@ -390,8 +393,18 @@ static int parse_elf(struct elf_info *in
 		return 0;
 	}
 
+	/* Fixups for more than 64k sections */
+	info->num_sections = hdr->e_shnum;
+	if (info->num_sections == SHN_UNDEF) { /* more than 64k sections? */
+		/* doesn't need shndx2secindex() */
+		info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
+	}
+	info->secindex_strings = hdr->e_shstrndx;
+	if (info->secindex_strings == SHN_XINDEX)
+		info->secindex_strings = shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
+
 	/* Fix endianness in section headers */
-	for (i = 0; i < hdr->e_shnum; i++) {
+	for (i = 0; i < info->num_sections; i++) {
 		sechdrs[i].sh_type   = TO_NATIVE(sechdrs[i].sh_type);
 		sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
 		sechdrs[i].sh_size   = TO_NATIVE(sechdrs[i].sh_size);
@@ -401,9 +414,8 @@ static int parse_elf(struct elf_info *in
 		sechdrs[i].sh_addr   = TO_NATIVE(sechdrs[i].sh_addr);
 	}
 	/* Find symbol table. */
-	for (i = 1; i < hdr->e_shnum; i++) {
-		const char *secstrings
-			= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+	secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
+	for (i = 1; i < info->num_sections; i++) {
 		const char *secname;
 
 		if (sechdrs[i].sh_offset > info->size) {
@@ -425,14 +437,29 @@ static int parse_elf(struct elf_info *in
 		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
 			info->export_gpl_future_sec = i;
 
-		if (sechdrs[i].sh_type != SHT_SYMTAB)
-			continue;
+		if (sechdrs[i].sh_type == SHT_SYMTAB) {
+			symtab_idx = i;
+			info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
+			info->symtab_stop  = (void *)hdr + sechdrs[i].sh_offset
+				                         + sechdrs[i].sh_size;
+			info->strtab       = (void *)hdr +
+			             sechdrs[shndx2secindex(sechdrs[i].sh_link)].sh_offset;
+		}
 
-		info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
-		info->symtab_stop  = (void *)hdr + sechdrs[i].sh_offset
-			                         + sechdrs[i].sh_size;
-		info->strtab       = (void *)hdr +
-			             sechdrs[sechdrs[i].sh_link].sh_offset;
+		/* 32bit section no. table? ("more than 64k sections") */
+		if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
+			uint32_t *p32;
+			info->symtab_shndx = (void *)hdr + sechdrs[i].sh_offset;
+			if (symtab_idx != shndx2secindex(sechdrs[i].sh_link))
+				fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
+					filename,
+					shndx2secindex(sechdrs[i].sh_link),
+					symtab_idx);
+			/* Fix endianness */
+			p32 = (void*)info->symtab_shndx + sechdrs[i].sh_size;
+			while (--p32 >= info->symtab_shndx)
+				*p32 = TO_NATIVE(*p32);
+		}
 	}
 	if (!info->symtab_start) {
 		fatal("%s has no symtab?\n", filename);
@@ -459,7 +486,7 @@ static void handle_modversions(struct mo
 			       Elf_Sym *sym, const char *symname)
 {
 	unsigned int crc;
-	enum export export = export_from_sec(info, sym->st_shndx);
+	enum export export = export_from_sec(info, get_secindex(info, sym));
 
 	switch (sym->st_shndx) {
 	case SHN_COMMON:
@@ -768,11 +795,14 @@ static Elf_Sym *find_elf_symbol(struct e
 				Elf_Sym *relsym)
 {
 	Elf_Sym *sym;
+	unsigned relsym_secindex;
 
 	if (relsym->st_name != 0)
 		return relsym;
+
+	relsym_secindex = get_secindex(elf, relsym);
 	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
-		if (sym->st_shndx != relsym->st_shndx)
+		if (get_secindex(elf, sym) != relsym_secindex)
 			continue;
 		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
 			continue;
@@ -821,7 +851,7 @@ static void find_symbols_between(struct 
 	Elf_Addr beforediff = ~0;
 	Elf_Addr afterdiff = ~0;
 	const char *secstrings = (void *)hdr +
-				 elf->sechdrs[hdr->e_shstrndx].sh_offset;
+				 elf->sechdrs[elf->secindex_strings].sh_offset;
 
 	*before = NULL;
 	*after = NULL;
@@ -829,9 +859,9 @@ static void find_symbols_between(struct 
 	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
 		const char *symsec;
 
-		if (sym->st_shndx >= SHN_LORESERVE)
+		if (is_shndx_special(sym->st_shndx))
 			continue;
-		symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name;
+		symsec = secstrings + elf->sechdrs[get_secindex(elf, sym)].sh_name;
 		if (strcmp(symsec, sec) != 0)
 			continue;
 		if (!is_valid_name(elf, sym))
@@ -872,8 +902,8 @@ static void warn_sec_mismatch(const char
 	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;
+				 sechdrs[elf->secindex_strings].sh_offset;
+	const char *secname = secstrings + sechdrs[get_secindex(elf, sym)].sh_name;
 
 	find_symbols_between(elf, r.r_offset, fromsec, &before, &after);
 
@@ -1007,10 +1037,10 @@ static void check_sec_ref(struct module 
 	Elf_Ehdr *hdr = elf->hdr;
 	Elf_Shdr *sechdrs = elf->sechdrs;
 	const char *secstrings = (void *)hdr +
-				 sechdrs[hdr->e_shstrndx].sh_offset;
+				 sechdrs[elf->secindex_strings].sh_offset;
 
 	/* Walk through all sections */
-	for (i = 0; i < hdr->e_shnum; i++) {
+	for (i = 0; i < elf->num_sections; i++) {
 		const char *name = secstrings + sechdrs[i].sh_name;
 		const char *secname;
 		Elf_Rela r;
@@ -1044,11 +1074,11 @@ static void check_sec_ref(struct module 
 				r.r_addend = TO_NATIVE(rela->r_addend);
 				sym = elf->symtab_start + r_sym;
 				/* Skip special sections */
-				if (sym->st_shndx >= SHN_LORESERVE)
+				if (is_shndx_special(sym->st_shndx))
 					continue;
 
 				secname = secstrings +
-					sechdrs[sym->st_shndx].sh_name;
+					sechdrs[get_secindex(elf, sym)].sh_name;
 				if (section(secname))
 					warn_sec_mismatch(modname, name,
 							  elf, sym, r);
@@ -1095,11 +1125,11 @@ static void check_sec_ref(struct module 
 				}
 				sym = elf->symtab_start + r_sym;
 				/* Skip special sections */
-				if (sym->st_shndx >= SHN_LORESERVE)
+				if (is_shndx_special(sym->st_shndx))
 					continue;
 
 				secname = secstrings +
-					sechdrs[sym->st_shndx].sh_name;
+					sechdrs[get_secindex(elf, sym)].sh_name;
 				if (section(secname))
 					warn_sec_mismatch(modname, name,
 							  elf, sym, r);
diff -urpN linux-2.6.gc1/scripts/mod/modpost.h linux-2.6.gc2/scripts/mod/modpost.h
--- linux-2.6.gc1/scripts/mod/modpost.h	2007-11-23 18:55:26.000000000 -0800
+++ linux-2.6.gc2/scripts/mod/modpost.h	2007-11-23 21:08:41.000000000 -0800
@@ -127,8 +127,49 @@ struct elf_info {
 	const char   *strtab;
 	char	     *modinfo;
 	unsigned int modinfo_len;
+
+	/* support for 32bit section numbers */
+
+	unsigned int num_sections; /* max_secindex + 1 */
+	unsigned int secindex_strings;
+	/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
+	 * take shndx from symtab_shndx[N] instead */
+	uint32_t     *symtab_shndx;
 };
 
+static inline int is_shndx_special(unsigned i)
+{
+	return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
+}
+
+/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus:
+ * shndx == 0               <=> sechdrs[0]
+ * ......
+ * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1]
+ * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE]
+ * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1]
+ * ......
+ * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff,
+ * so basically we map  0000..feff -> 0000..feff
+ *                      ff00..ffff -> (you are a bad boy, dont do it)
+ *                     10000..xxxx -> ff00..(xxxx-0x100)
+ */
+static inline unsigned shndx2secindex(unsigned i)
+{
+	if (i <= SHN_HIRESERVE)
+		return i;
+	return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
+}
+
+/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
+static inline unsigned get_secindex(struct elf_info *info, Elf_Sym *sym)
+{
+	if (sym->st_shndx != SHN_XINDEX)
+		return sym->st_shndx;
+	return shndx2secindex(info->symtab_shndx[sym - info->symtab_start]);
+}
+
+
 /* file2alias.c */
 void handle_moddevtable(struct module *mod, struct elf_info *info,
 			Elf_Sym *sym, const char *symname);

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/3] build system: section garbage collection - main part
  2007-11-24 23:14   ` [PATCH 0/3] build system: section garbage collection Denys Vlasenko
  2007-11-24 23:17     ` [PATCH 1/3] build system: section garbage collection - rename sections Denys Vlasenko
  2007-11-24 23:17     ` [PATCH 2/3] build system: section garbage collection - modpost fix Denys Vlasenko
@ 2007-11-24 23:18     ` Denys Vlasenko
  2 siblings, 0 replies; 18+ messages in thread
From: Denys Vlasenko @ 2007-11-24 23:18 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 826 bytes --]

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

[-- Attachment #2: linux-2.6-linus_git.3.gc.patch --]
[-- Type: text/x-diff, Size: 47497 bytes --]

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)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/3] build system: section garbage collection - rename sections
  2007-11-24 23:17     ` [PATCH 1/3] build system: section garbage collection - rename sections Denys Vlasenko
@ 2008-06-24  7:29       ` Matthieu CASTET
  0 siblings, 0 replies; 18+ messages in thread
From: Matthieu CASTET @ 2008-06-24  7:29 UTC (permalink / raw)
  To: linux-kernel

Hi,

Denys Vlasenko <vda.linux <at> googlemail.com> writes:

> 
> On Saturday 24 November 2007 15:14, Denys Vlasenko wrote:
> > 1.fixname:
> >     Rename all special sections with names like .text.xxxx, .data.xxxx and
> >     .rodata.xxxx to .xxxx.text/data/rodata. This makes it possible to
> >     not mix up these sections with gcc-generated ones
> >     when gcc -ffunction-sections -fdata-sections is used.
> >     .bss.xxxx cannot be treated this way, because for section names
> >     linke .xxxx.bss gcc won't create section with correct attribute.
> >     Thus .bss.xxxxx sections are renamed .bss.k.xxxxx.
> 
> Signed-off-by: Denys Vlasenko <vda.linux <at> googlemail.com>
Why not rename all the section to .type.k.xxxxx ?
This will be more consistent between bss and other section. Also I find it
cleaner to have the section type first.

Matthieu 



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2008-06-24  7:30 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-11 20:05 [PATCH 0/4] build system: section garbage collection for vmlinux Denys Vlasenko
2007-09-11 20:07 ` [PATCH 1/4] " Denys Vlasenko
2007-09-11 20:10   ` [PATCH 2/4] " Denys Vlasenko
2007-09-11 20:11     ` [PATCH 3/4] " Denys Vlasenko
2007-09-11 20:22       ` [PATCH 4/4] " Denys Vlasenko
2007-09-11 21:47   ` [PATCH 1/4] " Daniel Walker
2007-09-12 20:18     ` Denys Vlasenko
2007-09-12 20:52       ` Daniel Walker
2007-09-11 21:03 ` [PATCH 0/4] " Andi Kleen
2007-09-12 20:19   ` Denys Vlasenko
2007-09-13 18:26 ` Abhishek Sagar
2007-09-13 18:35   ` Sam Ravnborg
2007-09-14 18:06     ` Abhishek Sagar
     [not found] ` <20071118230057.GA6303@uranus.ravnborg.org>
2007-11-24 23:14   ` [PATCH 0/3] build system: section garbage collection Denys Vlasenko
2007-11-24 23:17     ` [PATCH 1/3] build system: section garbage collection - rename sections Denys Vlasenko
2008-06-24  7:29       ` Matthieu CASTET
2007-11-24 23:17     ` [PATCH 2/3] build system: section garbage collection - modpost fix Denys Vlasenko
2007-11-24 23:18     ` [PATCH 3/3] build system: section garbage collection - main part Denys Vlasenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).