aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-08-14 09:25:17 +0930
committerAlan Modra <amodra@gmail.com>2017-08-14 09:25:17 +0930
commit79a94a2ad1e6e2f227de07427481e4bb8be84504 (patch)
tree9cdf64ff2ae956d9ffd96d87bc1404eee27f933e /bfd/elflink.c
parent34c4758cc210e2ca042b0373938e57fd6844f89d (diff)
downloadgdb-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.c29
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);