The .note.gnu.property SHT_NOTE uses wrong alignment and padding on ELFCLASS64. This breaks note parsers which will see garbage data inside a NOTE and might flag the ELF file as invalid or stop parsing any note data (since they cannot know how to skip the note). Unlike what gabi says, GNU always uses 4 byte alignment and padding, plus 32bit sizes for namesz and descrsz in notes independent from ELF class. gabi says to use 8 byte alignment and padding, plus 64bit sizes for ELFCLASS64, but others (except HPUX it seems) also don't follow that. Nobody uses 8 byte alignment/padding and 32bit sizes. This was discussed on the gnu-gabi and gabi mailinglists: https://sourceware.org/ml/gnu-gabi/2017-q4/msg00028.html Proposed fix: diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index 2549dd0..647931b 100644 --- a/bfd/elf-properties.c +++ b/bfd/elf-properties.c @@ -394,7 +394,8 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) unsigned int descsz; bfd_byte *contents; Elf_External_Note *e_note; - unsigned int align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4; + /* Note GNU SHT_NOTEs are always 4 byte aligned. */ + unsigned int align_size = 4; sec = bfd_get_section_by_name (first_pbfd, NOTE_GNU_PROPERTY_SECTION_NAME); diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index a7db5d9..e6d45f3 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -2424,7 +2424,12 @@ _bfd_x86_elf_link_setup_gnu_properties if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create GNU property section\n")); - if (!bfd_set_section_alignment (ebfd, sec, class_align)) + /* GNU ABI always aligns and pads SHT_NOTES 4 bytes. Using + 32bit sizes for name_sz and desc_sz. Independent from + the ELF class. This is different from gabi, which uses + alignement and padding of 8 bytes, plus 64bit sizes for + ELFCLASS64. Changing this breaks existing NOTE parsers. */ + if (!bfd_set_section_alignment (ebfd, sec, 2)) { error_alignment: info->callbacks->einfo (_("%F%A: failed to align section\n"),
(In reply to Mark Wielaard from comment #0) > The .note.gnu.property SHT_NOTE uses wrong alignment and padding on > ELFCLASS64. This breaks note parsers which will see garbage data inside a > NOTE and might flag the ELF file as invalid or stop parsing any note data > (since they cannot know how to skip the note). > > Unlike what gabi says, GNU always uses 4 byte alignment and padding, plus > 32bit sizes for namesz and descrsz in notes independent from ELF class. > > gabi says to use 8 byte alignment and padding, plus 64bit sizes for > ELFCLASS64, but others (except HPUX it seems) also don't follow that. Nobody > uses 8 byte alignment/padding and 32bit sizes. > > This was discussed on the gnu-gabi and gabi mailinglists: > https://sourceware.org/ml/gnu-gabi/2017-q4/msg00028.html > > Proposed fix: > > diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c > index 2549dd0..647931b 100644 > --- a/bfd/elf-properties.c > +++ b/bfd/elf-properties.c > @@ -394,7 +394,8 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info > *info) > unsigned int descsz; > bfd_byte *contents; > Elf_External_Note *e_note; > - unsigned int align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4; > + /* Note GNU SHT_NOTEs are always 4 byte aligned. */ > + unsigned int align_size = 4; > According to gABI, SHT_NOTE should be aligned to ELFCLASS64. In any case, you can check note alignment by looking up the alignment field in its header. In elf.c, there are static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset, size_t align) { char *p; /* NB: CORE PT_NOTE segments may have p_align values of 0 or 1. gABI specifies that PT_NOTE alignment should be aligned to 4 bytes for 32-bit objects and to 8 bytes for 64-bit objects. If align is less than 4, we use 4 byte alignment. */ if (align < 4) align = 4; These tools can be updated to follow gABI without breaking backward compatibility.