diff options
author | Alan Modra <amodra@gmail.com> | 2017-08-14 09:25:17 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-08-14 09:25:17 +0930 |
commit | 79a94a2ad1e6e2f227de07427481e4bb8be84504 (patch) | |
tree | 9cdf64ff2ae956d9ffd96d87bc1404eee27f933e /bfd/elflink.c | |
parent | 34c4758cc210e2ca042b0373938e57fd6844f89d (diff) | |
download | gdb-79a94a2ad1e6e2f227de07427481e4bb8be84504.zip gdb-79a94a2ad1e6e2f227de07427481e4bb8be84504.tar.gz gdb-79a94a2ad1e6e2f227de07427481e4bb8be84504.tar.bz2 |
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.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index 424de21..f9886dc 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); |