diff options
author | Alan Modra <amodra@gmail.com> | 2012-05-24 06:20:52 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-05-24 06:20:52 +0000 |
commit | 4bbe044a207dcc84ee1c39df6f23c5662d94fc9f (patch) | |
tree | 386bd9b23b9f6f116a9d143e3d1dbc4568381c59 /bfd/elf64-ppc.c | |
parent | d50bd42bda1bbc81eab52d4ca966a08550f2e19f (diff) | |
download | gdb-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.c | 27 |
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. */ |