Seems to happen with 3.3,3.4, Short test case courtesy of A.Pinski: static void __attribute__ ((__section__ (".init.text"))) pci_fixup_i450nx(void) { } static int __attribute__ ((__section__ (".init.text"))) toshiba_ohci1394_dmi_table[] = { }; causes with gcc (without -O2); t.c:4: error: toshiba_ohci1394_dmi_table causes a section type conflict (the longer test case which I attach shows it with optimization too) On the big file the actual function (it has a lot of these) depends on optimization level and compiler version
Created attachment 10081 [details] Long test case directly from Linux kernel, shows the error in more circumstances
(In reply to comment #0) > Seems to happen with 3.3,3.4, > > Short test case courtesy of A.Pinski: > > static void __attribute__ ((__section__ (".init.text"))) pci_fixup_i450nx(void) > { } > static int __attribute__ ((__section__ (".init.text"))) > toshiba_ohci1394_dmi_table[] = { }; > > causes with gcc (without -O2); > t.c:4: error: toshiba_ohci1394_dmi_table causes a section type conflict without `static` it also fails on 4.1/powerpc.
Confirmed for the short testcase at -O0. Finding one for the -O2 issue.
I wonder if this is really a regression at all here is the testcase for -O2: struct pci_fixup { void (*hook)(void); }; static void __attribute__ ((__section__ (".init.text"))) pci_fixup_ide_bases(void) {} static const struct pci_fixup __pci_fixup_PCI_ANY_IDPCI_ANY_IDpci_fixup_ide_bases __attribute__((__used__)) __attribute__((__section__(".pci_fixup_header"))) = { pci_fixup_ide_bases }; static int __attribute__ ((__section__ (".init.text"))) toshiba_ohci1394_dmi_table[] = {}; static void __attribute__ ((__section__ (".init.text"))) pci_pre_fixup_toshiba_ohci1394(void) { dmi_check_system(toshiba_ohci1394_dmi_table); } static const struct pci_fixup __pci_fixup_PCI_VENDOR_ID_TI0x8032pci_pre_fixup_toshiba_ohci1394 __attribute__((__used__)) __attribute__((__section__(".pci_fixup_header"))) = {pci_pre_fixup_toshiba_ohci1394 }; ---- This fails with 2.95.3 3.0.4 3.3.3 3.4.0, 4.0.0 and 4.1.0.
This is a showstopper, unless we can convince ourselves that this is not a bug, or, at least, not a regression.
Short story... Your kernel code is broken. init functions go in .init.text, but init data goes in .init.data, not .init.text. See the Documentation/Docbook/kernel-hacking.tmpl file in any recent kernel. Long story... The more we use ELF, the more important it is to get the details right. One of the details we did not get right in the beginning is section type info. Given something like int __attribute__ ((section ("foo"))) bar () { } int __attribute__ ((section ("foo"))) baz = 1; An old compiler like gcc-2.95 will emit .section bar,"ax",@progbits but this is clearly wrong, because we have both code and writable data in the same section, and that section is not marked writable. Newer compiler versions check for this, and correctly emit an error when they see section type conflicts like this, as we can't emit both writable data and code into the same section. So the error you are getting here is expected, and correct. This bug happens not to affect the kernel's use of section in this specific case, so it worked by accident with older compiler versions. It will not and should not work with current compiler versions, and hence the current kernel has support for separate init text and init data sections. It might be useful if the attribute section syntax was extended so that people can specify what kind of section they want, but I don't see any real advantage to doing that. You shouldn't be mixing data and code in the same section anyways. Ideally, you should be using a comdat group here, but we have no syntax for that either. I think that would be a more useful attribute section syntax extension. There is no need for it to solve this particular problem though. You just need to use the right sections in your code.
So this is invalid after all.