From: Alan Modra Date: Sun, 13 Aug 2017 23:55:17 +0000 (+0930) Subject: PR21441, Unnecessary padding of .eh_frame section X-Git-Tag: binutils-2_29_1.1~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8fd7cca5b0ed5a2f2099428586359f5cdff2063d;p=thirdparty%2Fbinutils-gdb.git 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. (cherry picked from commit 79a94a2ad1e6e2f227de07427481e4bb8be84504) --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 40bcac93e3e..73377b91733 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-09-04 Nick Clifton 2017-09-18 H.J. Lu 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 736fb4c2f7f..6bab097b057 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -13831,6 +13831,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) { @@ -13856,6 +13857,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 f513008c2e1..56ce18b85a6 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-09-18 H.J. Lu PR ld/21924 diff --git a/ld/testsuite/ld-x86-64/pr21038a-now.d b/ld/testsuite/ld-x86-64/pr21038a-now.d index ebc512887a1..6948ded162d 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 81b26cb53c9..7b1b7dcd4c1 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