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)
        $

Reply via email to