https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609
Bug ID: 77609 Summary: __attribute__((section(".note.foo"))) forces SHT_PROGBITS though the assembler would use SHT_NOTE Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: roland at gnu dot org Target Milestone: --- When __attribute__((section("name"))) is used, GCC insists on setting the section type explicitly. For various special section names, the assembler would use a special type, but GCC doesn't know about those rules and forces SHT_PROGBITS instead. An example is section names starting with ".note", which the assembler gives type SHT_NOTE but GCC fails to. This makes it impossible (without heinous shenanigans) to use an initialized C variable declaration to emit an (allocated) ELF note. GCC already has special cases for ".init_array", ".fini_array", and ".preinit_array", but that is a small subset of the full set of names (and name patterns) for which the assembler uses a special type. The existing special cases already rely on the assembler to choose the actual type. The default type of SHT_PROGBITS that GCC forces on all others is already the assembler's default for sections whose name is not special. So just letting the assembler choose in all cases does the right thing now and will do so in the future if any new types or special name patterns are added to the assembler. I'll attach a patch that does this. Test case: $ cat note.c #define VENDOR "foobar" struct mynote { struct Elf32_Nhdr { unsigned int n_namesz, n_descsz, n_type; } hdr; char name[sizeof(VENDOR)]; _Alignas(4) struct mynote_payload { short int x; } payload; }; __attribute__((used, section(".note.foo"))) static const struct mynote foonote = { .hdr = { .n_namesz = sizeof(VENDOR), .n_descsz = sizeof(struct mynote_payload), .n_type = 17, }, .name = VENDOR, .payload = { .x = 23, }, }; $ ./gcc/xgcc -Bgcc/ -c -save-temps ../../gcc/note.c $ cat note.s .file "note.c" ==> .section .note.foo,"a",@progbits .align 16 .type foonote, @object .size foonote, 24 foonote: .long 7 .long 2 .long 17 .string "foobar" .zero 1 .value 23 .zero 2 .ident "GCC: (GNU) 7.0.0 20160915 (experimental)" .section .note.GNU-stack,"",@progbits $ readelf -WSn note.o There are 10 section headers, starting at offset 0xd8: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 1 [ 2] .data PROGBITS 0000000000000000 000040 000000 00 WA 0 0 1 [ 3] .bss NOBITS 0000000000000000 000040 000000 00 WA 0 0 1 ==> [ 4] .note.foo PROGBITS 0000000000000000 000040 000018 00 A 0 0 16 [ 5] .comment PROGBITS 0000000000000000 000058 00002a 01 MS 0 0 1 [ 6] .note.GNU-stack PROGBITS 0000000000000000 000082 000000 00 0 0 1 [ 7] .shstrtab STRTAB 0000000000000000 000082 00004f 00 0 0 1 [ 8] .symtab SYMTAB 0000000000000000 000358 0000d8 18 9 9 8 [ 9] .strtab STRTAB 0000000000000000 000430 000010 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) $ After my fix: $ ./gcc/xgcc -Bgcc/ -c -save-temps ../../gcc/note.c $ cat note.s .file "note.c" ==> .section .note.foo,"a" .align 16 .type foonote, @object .size foonote, 24 foonote: .long 7 .long 2 .long 17 .string "foobar" .zero 1 .value 23 .zero 2 .ident "GCC: (GNU) 7.0.0 20160915 (experimental)" .section .note.GNU-stack,"",@progbits $ readelf -WSn note.o There are 10 section headers, starting at offset 0xd8: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 1 [ 2] .data PROGBITS 0000000000000000 000040 000000 00 WA 0 0 1 [ 3] .bss NOBITS 0000000000000000 000040 000000 00 WA 0 0 1 ==> [ 4] .note.foo NOTE 0000000000000000 000040 000018 00 A 0 0 16 [ 5] .comment PROGBITS 0000000000000000 000058 00002a 01 MS 0 0 1 [ 6] .note.GNU-stack PROGBITS 0000000000000000 000082 000000 00 0 0 1 [ 7] .shstrtab STRTAB 0000000000000000 000082 00004f 00 0 0 1 [ 8] .symtab SYMTAB 0000000000000000 000358 0000d8 18 9 9 8 [ 9] .strtab STRTAB 0000000000000000 000430 000010 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) Displaying notes found at file offset 0x00000040 with length 0x00000018: Owner Data size Description ==> foobar 0x00000002 Unknown note type: (0x00000011) $