diff options
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 106 | ||||
-rw-r--r-- | bfd/elflink.c | 8 |
3 files changed, 73 insertions, 50 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6271710..a92ebe8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2012-05-22 Alan Modra <amodra@gmail.com> + + * elflink.c (bfd_elf_discard_info): Look for next .eh_frame if + first one is zero size or discarded. + * elf32-ppc.c (ppc_elf_size_dynamic_sections): Set most of + glink_eh_frame contents here.. + (ppc_elf_finish_dynamic_sections): ..rather than here. Just set + offset to .glink. + 2012-05-22 H.J. Lu <hongjiu.lu@intel.com> PR ld/13909 diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index fabd065..9665d39 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -6393,6 +6393,66 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, } #undef add_dynamic_entry + if (htab->glink_eh_frame != NULL + && htab->glink_eh_frame->contents != NULL) + { + unsigned char *p = htab->glink_eh_frame->contents; + bfd_vma val; + + 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); + p += sizeof (glink_eh_frame_cie); + /* FDE length. */ + val = htab->glink_eh_frame->size - 4 - sizeof (glink_eh_frame_cie); + bfd_put_32 (htab->elf.dynobj, val, p); + p += 4; + /* CIE pointer. */ + val = p - htab->glink_eh_frame->contents; + bfd_put_32 (htab->elf.dynobj, val, p); + p += 4; + /* Offset to .glink. Set later. */ + p += 4; + /* .glink size. */ + bfd_put_32 (htab->elf.dynobj, htab->glink->size, p); + p += 4; + /* Augmentation. */ + p += 1; + + if (info->shared + && htab->elf.dynamic_sections_created) + { + bfd_vma adv = (htab->glink->size - GLINK_PLTRESOLVE + 8) >> 2; + if (adv < 64) + *p++ = DW_CFA_advance_loc + adv; + else if (adv < 256) + { + *p++ = DW_CFA_advance_loc1; + *p++ = adv; + } + else if (adv < 65536) + { + *p++ = DW_CFA_advance_loc2; + bfd_put_16 (htab->elf.dynobj, adv, p); + p += 2; + } + else + { + *p++ = DW_CFA_advance_loc4; + bfd_put_32 (htab->elf.dynobj, adv, p); + p += 4; + } + *p++ = DW_CFA_register; + *p++ = 65; + p++; + *p++ = DW_CFA_advance_loc + 4; + *p++ = DW_CFA_restore_extended; + *p++ = 65; + } + BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4) + == htab->glink_eh_frame->size); + } + return TRUE; } @@ -9573,17 +9633,10 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, unsigned char *p = htab->glink_eh_frame->contents; bfd_vma val; - 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); p += sizeof (glink_eh_frame_cie); /* FDE length. */ - val = htab->glink_eh_frame->size - 4 - sizeof (glink_eh_frame_cie); - bfd_put_32 (htab->elf.dynobj, val, p); p += 4; /* CIE pointer. */ - val = p - htab->glink_eh_frame->contents; - bfd_put_32 (htab->elf.dynobj, val, p); p += 4; /* Offset to .glink. */ val = (htab->glink->output_section->vma @@ -9592,45 +9645,6 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, + htab->glink_eh_frame->output_offset); val -= p - htab->glink_eh_frame->contents; bfd_put_32 (htab->elf.dynobj, val, p); - p += 4; - /* .glink size. */ - bfd_put_32 (htab->elf.dynobj, htab->glink->size, p); - p += 4; - /* Augmentation. */ - p += 1; - - if (info->shared - && htab->elf.dynamic_sections_created) - { - bfd_vma adv = (htab->glink->size - GLINK_PLTRESOLVE + 8) >> 2; - if (adv < 64) - *p++ = DW_CFA_advance_loc + adv; - else if (adv < 256) - { - *p++ = DW_CFA_advance_loc1; - *p++ = adv; - } - else if (adv < 65536) - { - *p++ = DW_CFA_advance_loc2; - bfd_put_16 (htab->elf.dynobj, adv, p); - p += 2; - } - else - { - *p++ = DW_CFA_advance_loc4; - bfd_put_32 (htab->elf.dynobj, adv, p); - p += 4; - } - *p++ = DW_CFA_register; - *p++ = 65; - p++; - *p++ = DW_CFA_advance_loc + 4; - *p++ = DW_CFA_restore_extended; - *p++ = 65; - } - BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4) - == htab->glink_eh_frame->size); if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME && !_bfd_elf_write_section_eh_frame (output_bfd, info, diff --git a/bfd/elflink.c b/bfd/elflink.c index 42f27a0..f18b9df 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12489,10 +12489,10 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) if (!info->relocatable) { eh = bfd_get_section_by_name (abfd, ".eh_frame"); - if (eh != NULL - && (eh->size == 0 - || bfd_is_abs_section (eh->output_section))) - eh = NULL; + while (eh != NULL + && (eh->size == 0 + || bfd_is_abs_section (eh->output_section))) + eh = bfd_get_next_section_by_name (eh); } stab = bfd_get_section_by_name (abfd, ".stab"); |