PR21441, Unnecessary padding of .eh_frame section

Until all .eh_frame sections have been edited we don't know their
sizes.  So it isn't possible to properly decide whether a non-empty
.eh_frame section follows a given section until editing is complete.

bfd/
	PR 21441
	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't add
	alignment padding here.
	* elflink.c (bfd_elf_discard_info): Add .eh_frame padding here
	in a reverse pass over sections.
ld/
	PR 21441
	* testsuite/ld-x86-64/pr21038a.d: Adjust.
	* testsuite/ld-x86-64/pr21038a-now.d: Adjust.
This commit is contained in:
Alan Modra 2017-08-14 09:25:17 +09:30
parent 34c4758cc2
commit 79a94a2ad1
6 changed files with 45 additions and 19 deletions

View File

@ -1,3 +1,11 @@
2017-08-14 Alan Modra <amodra@gmail.com>
PR 21441
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't add
alignment padding here.
* elflink.c (bfd_elf_discard_info): Add .eh_frame padding here
in a reverse pass over sections.
2017-08-11 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/21943

View File

@ -1594,16 +1594,7 @@ _bfd_elf_discard_section_eh_frame
offset += size_of_output_cie_fde (ent);
}
/* Pad the last FDE out to the output section alignment if there are
following sections, in order to ensure no padding between this
section and the next. (Relies on the output section alignment
being the maximum of all input sections alignments, which is the
case unless someone is overriding alignment via scripts.) */
eh_alignment = 4;
if (sec->map_head.s != NULL
&& (sec->map_head.s->size != 4
|| sec->map_head.s->map_head.s != NULL))
eh_alignment = 1 << sec->output_section->alignment_power;
offset = (offset + eh_alignment - 1) & -eh_alignment;
sec->rawsize = sec->size;
sec->size = offset;

View File

@ -13836,6 +13836,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
{
asection *i;
int eh_changed = 0;
unsigned int eh_alignment;
for (i = o->map_head.s; i != NULL; i = i->map_head.s)
{
@ -13861,6 +13862,34 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
fini_reloc_cookie_for_section (&cookie, i);
}
eh_alignment = 1 << o->alignment_power;
if (eh_alignment > 4)
{
/* Skip over zero terminator, and prevent empty sections
from adding alignment padding at the end. */
for (i = o->map_tail.s; i != NULL; i = i->map_tail.s)
if (i->size == 0)
i->flags |= SEC_EXCLUDE;
else if (i->size > 4)
break;
/* The last non-empty eh_frame section doesn't need padding. */
if (i != NULL)
i = i->map_tail.s;
/* Any prior sections must pad the last FDE out to the
output section alignment. Otherwise we might have zero
padding between sections, which would be seen as a
terminator. */
for (; i != NULL; i = i->map_tail.s)
{
bfd_size_type size = (i->size + eh_alignment - 1) & -eh_alignment;
if (i->size != size)
{
i->size = size;
changed = 1;
eh_changed = 1;
}
}
}
if (eh_changed)
elf_link_hash_traverse (elf_hash_table (info),
_bfd_elf_adjust_eh_frame_global_symbol, NULL);

View File

@ -1,3 +1,9 @@
2017-08-14 Alan Modra <amodra@gmail.com>
PR 21441
* testsuite/ld-x86-64/pr21038a.d: Adjust.
* testsuite/ld-x86-64/pr21038a-now.d: Adjust.
2017-08-13 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-i386/i386.exp: Run pr21884-nacl.

View File

@ -41,11 +41,7 @@ Contents of the .eh_frame section:
DW_CFA_nop
DW_CFA_nop
0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop

View File

@ -40,11 +40,7 @@ Contents of the .eh_frame section:
DW_CFA_nop
DW_CFA_nop
0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop