aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-05-24 06:20:52 +0000
committerAlan Modra <amodra@gmail.com>2012-05-24 06:20:52 +0000
commit4bbe044a207dcc84ee1c39df6f23c5662d94fc9f (patch)
tree386bd9b23b9f6f116a9d143e3d1dbc4568381c59 /bfd/elf64-ppc.c
parentd50bd42bda1bbc81eab52d4ca966a08550f2e19f (diff)
downloadgdb-4bbe044a207dcc84ee1c39df6f23c5662d94fc9f.zip
gdb-4bbe044a207dcc84ee1c39df6f23c5662d94fc9f.tar.gz
gdb-4bbe044a207dcc84ee1c39df6f23c5662d94fc9f.tar.bz2
PR ld/14158
* elf64-ppc.c (ppc64_elf_size_stubs): Round up glink_eh_frame size to output section alignment. (ppc64_elf_build_stubs): Likewise, and extend last FDE to cover.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 482cf4d..df1db6d 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -11664,7 +11664,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
&& !bfd_is_abs_section (htab->glink_eh_frame->output_section)
&& (htab->glink_eh_frame->flags & SEC_EXCLUDE) == 0)
{
- bfd_size_type size = 0;
+ size_t size = 0, align;
for (stub_sec = htab->stub_bfd->sections;
stub_sec != NULL;
@@ -11675,6 +11675,10 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
size += 24;
if (size != 0)
size += sizeof (glink_eh_frame_cie);
+ align = 1;
+ align <<= htab->glink_eh_frame->output_section->alignment_power;
+ align -= 1;
+ size = (size + align) & ~align;
htab->glink_eh_frame->rawsize = htab->glink_eh_frame->size;
htab->glink_eh_frame->size = size;
}
@@ -11916,17 +11920,21 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
&& htab->glink_eh_frame->size != 0)
{
bfd_vma val;
+ bfd_byte *last_fde;
+ size_t last_fde_len, size, align, pad;
p = bfd_zalloc (htab->glink_eh_frame->owner, htab->glink_eh_frame->size);
if (p == NULL)
return FALSE;
htab->glink_eh_frame->contents = p;
+ last_fde = p;
htab->glink_eh_frame->rawsize = htab->glink_eh_frame->size;
memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
/* CIE length (rewrite in case little-endian). */
- bfd_put_32 (htab->elf.dynobj, sizeof (glink_eh_frame_cie) - 4, p);
+ last_fde_len = sizeof (glink_eh_frame_cie) - 4;
+ bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
p += sizeof (glink_eh_frame_cie);
for (stub_sec = htab->stub_bfd->sections;
@@ -11934,6 +11942,8 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
stub_sec = stub_sec->next)
if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
{
+ last_fde = p;
+ last_fde_len = 16;
/* FDE length. */
bfd_put_32 (htab->elf.dynobj, 16, p);
p += 4;
@@ -11966,6 +11976,8 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
}
if (htab->glink != NULL && htab->glink->size != 0)
{
+ last_fde = p;
+ last_fde_len = 20;
/* FDE length. */
bfd_put_32 (htab->elf.dynobj, 20, p);
p += 4;
@@ -12003,7 +12015,16 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
*p++ = DW_CFA_restore_extended;
*p++ = 65;
}
- htab->glink_eh_frame->size = p - htab->glink_eh_frame->contents;
+ /* Subsume any padding into the last FDE if user .eh_frame
+ sections are aligned more than glink_eh_frame. Otherwise any
+ zero padding will be seen as a terminator. */
+ size = p - htab->glink_eh_frame->contents;
+ align = 1;
+ align <<= htab->glink_eh_frame->output_section->alignment_power;
+ align -= 1;
+ pad = ((size + align) & ~align) - size;
+ htab->glink_eh_frame->size = size + pad;
+ bfd_put_32 (htab->elf.dynobj, last_fde_len + pad, last_fde);
}
/* Build the stubs as directed by the stub hash table. */