ELF: Group PT_NOTE segments by section alignments

Alignments of SHT_NOTE sections can be 8 bytes for 64-bit ELF files.  We
should put all adjacent SHT_NOTE sections with the same section alignment
into a single PT_NOTE segment even when the section alignment != 4 bytes.
Also check SHT_NOTE section type instead of section name.

	PR ld/23658
	* elf.c (get_program_header_size): Put all adjacent SHT_NOTE
	sections with the same section alignment into a single PT_NOTE
	segment.  Check SHT_NOTE section type instead of section name.
	(_bfd_elf_map_sections_to_segments): Likewise.
This commit is contained in:
H.J. Lu 2018-10-03 13:22:26 -07:00
parent e66cfcef72
commit 23e463ed7c
2 changed files with 37 additions and 30 deletions

View file

@ -1,3 +1,11 @@
2018-10-03 H.J. Lu <hongjiu.lu@intel.com>
PR ld/23658
* elf.c (get_program_header_size): Put all adjacent SHT_NOTE
sections with the same section alignment into a single PT_NOTE
segment. Check SHT_NOTE section type instead of section name.
(_bfd_elf_map_sections_to_segments): Likewise.
2018-10-03 Millan Wolff <mail@milianw.de> 2018-10-03 Millan Wolff <mail@milianw.de>
PR 23715 PR 23715

View file

@ -4371,23 +4371,22 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
for (s = abfd->sections; s != NULL; s = s->next) for (s = abfd->sections; s != NULL; s = s->next)
{ {
if ((s->flags & SEC_LOAD) != 0 if ((s->flags & SEC_LOAD) != 0
&& CONST_STRNEQ (s->name, ".note")) && elf_section_type (s) == SHT_NOTE)
{ {
unsigned int alignment_power;
/* We need a PT_NOTE segment. */ /* We need a PT_NOTE segment. */
++segs; ++segs;
/* Try to create just one PT_NOTE segment /* Try to create just one PT_NOTE segment for all adjacent
for all adjacent loadable .note* sections. loadable SHT_NOTE sections. gABI requires that within a
gABI requires that within a PT_NOTE segment PT_NOTE segment (and also inside of each SHT_NOTE section)
(and also inside of each SHT_NOTE section) each note should have the same alignment. So we check
each note is padded to a multiple of 4 size, whether the sections are correctly aligned. */
so we check whether the sections are correctly alignment_power = s->alignment_power;
aligned. */ while (s->next != NULL
if (s->alignment_power == 2) && s->next->alignment_power == alignment_power
while (s->next != NULL && (s->next->flags & SEC_LOAD) != 0
&& s->next->alignment_power == 2 && elf_section_type (s->next) == SHT_NOTE)
&& (s->next->flags & SEC_LOAD) != 0 s = s->next;
&& CONST_STRNEQ (s->next->name, ".note"))
s = s->next;
} }
} }
@ -4885,33 +4884,33 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
pm = &m->next; pm = &m->next;
} }
/* For each batch of consecutive loadable .note sections, /* For each batch of consecutive loadable SHT_NOTE sections,
add a PT_NOTE segment. We don't use bfd_get_section_by_name, add a PT_NOTE segment. We don't use bfd_get_section_by_name,
because if we link together nonloadable .note sections and because if we link together nonloadable .note sections and
loadable .note sections, we will generate two .note sections loadable .note sections, we will generate two .note sections
in the output file. FIXME: Using names for section types is in the output file. */
bogus anyhow. */
for (s = abfd->sections; s != NULL; s = s->next) for (s = abfd->sections; s != NULL; s = s->next)
{ {
if ((s->flags & SEC_LOAD) != 0 if ((s->flags & SEC_LOAD) != 0
&& CONST_STRNEQ (s->name, ".note")) && elf_section_type (s) == SHT_NOTE)
{ {
asection *s2; asection *s2;
unsigned int alignment_power = s->alignment_power;
count = 1; count = 1;
amt = sizeof (struct elf_segment_map); amt = sizeof (struct elf_segment_map);
if (s->alignment_power == 2) for (s2 = s; s2->next != NULL; s2 = s2->next)
for (s2 = s; s2->next != NULL; s2 = s2->next) {
{ if (s2->next->alignment_power == alignment_power
if (s2->next->alignment_power == 2 && (s2->next->flags & SEC_LOAD) != 0
&& (s2->next->flags & SEC_LOAD) != 0 && elf_section_type (s2->next) == SHT_NOTE
&& CONST_STRNEQ (s2->next->name, ".note") && align_power (s2->lma + s2->size,
&& align_power (s2->lma + s2->size, 2) alignment_power)
== s2->next->lma) == s2->next->lma)
count++; count++;
else else
break; break;
} }
amt += (count - 1) * sizeof (asection *); amt += (count - 1) * sizeof (asection *);
m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
if (m == NULL) if (m == NULL)