From 79a94a2ad1e6e2f227de07427481e4bb8be84504 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 14 Aug 2017 09:25:17 +0930 Subject: [PATCH] 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. --- bfd/ChangeLog | 8 ++++++++ bfd/elf-eh-frame.c | 9 --------- bfd/elflink.c | 29 +++++++++++++++++++++++++++ ld/ChangeLog | 6 ++++++ ld/testsuite/ld-x86-64/pr21038a-now.d | 6 +----- ld/testsuite/ld-x86-64/pr21038a.d | 6 +----- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 356d19b498d..876461e4cf5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2017-08-14 Alan Modra + + 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 PR binutils/21943 diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 52ba9c62138..7e0d63f569d 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -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; diff --git a/bfd/elflink.c b/bfd/elflink.c index 424de21f0d9..f9886dc6457 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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); diff --git a/ld/ChangeLog b/ld/ChangeLog index aad32493af1..1b0746a0894 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2017-08-14 Alan Modra + + PR 21441 + * testsuite/ld-x86-64/pr21038a.d: Adjust. + * testsuite/ld-x86-64/pr21038a-now.d: Adjust. + 2017-08-13 H.J. Lu * testsuite/ld-i386/i386.exp: Run pr21884-nacl. diff --git a/ld/testsuite/ld-x86-64/pr21038a-now.d b/ld/testsuite/ld-x86-64/pr21038a-now.d index fb4ad8fa2e2..1d5bec1854e 100644 --- a/ld/testsuite/ld-x86-64/pr21038a-now.d +++ b/ld/testsuite/ld-x86-64/pr21038a-now.d @@ -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 diff --git a/ld/testsuite/ld-x86-64/pr21038a.d b/ld/testsuite/ld-x86-64/pr21038a.d index 2ed962a6a2e..01770ec671f 100644 --- a/ld/testsuite/ld-x86-64/pr21038a.d +++ b/ld/testsuite/ld-x86-64/pr21038a.d @@ -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 -- 2.30.2