From 8860955fbe0eaf412839ef492a67415613001ac5 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sun, 19 Dec 2004 23:24:46 +0000 Subject: [PATCH] * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add opd_relocs. (opd_entry_value): Use opd_relocs if available. (ppc64_elf_relocate_section): Don't set reloc_done. Instead copy .opd relocations to opd_relocs. (ppc64_elf_edit_toc): Set rel_hdr.sh_size after editing relocs. --- bfd/ChangeLog | 14 +++++++++++--- bfd/elf64-ppc.c | 41 ++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 70af752..ecce14f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2004-12-20 Alan Modra + + * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add opd_relocs. + (opd_entry_value): Use opd_relocs if available. + (ppc64_elf_relocate_section): Don't set reloc_done. Instead + copy .opd relocations to opd_relocs. + (ppc64_elf_edit_toc): Set rel_hdr.sh_size after editing relocs. + 2004-12-16 Richard Sandiford * reloc.c (BFD_RELOC_V850_LO16_SPLIT_OFFSET): New bfd_reloc_code_type. @@ -17,7 +25,7 @@ 2004-12-14 Tomer Levi - * elf32-crx.c (elf32_crx_relax_delete_bytes): Add 'struct bfd_link_info *' + * elf32-crx.c (elf32_crx_relax_delete_bytes): Add 'struct bfd_link_info *' to prototype, to make hash info available. Prevent wrapped symbols from being adjusted twice. @@ -44,8 +52,8 @@ (group_signature): Update calls. * elf-bfd.h (bfd_elf_sym_name): Update. * elf32-ppc.c (ppc_elf_relocate_section): Update. - * elf64-ppc.c (ppc64_elf_edit_opd, ppc64_elf_edit_toc) - (ppc64_elf_relocate_section): Update + * elf64-ppc.c (ppc64_elf_edit_opd, ppc64_elf_edit_toc): Update. + (ppc64_elf_relocate_section): Update. * elflink.c (elf_link_input_bfd): Update. 2004-12-10 Jakub Jelinek diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 08cfdac..8bf140c 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -2380,6 +2380,9 @@ struct ppc64_elf_obj_tdata bfd_signed_vma refcount; bfd_vma offset; } tlsld_got; + + /* A copy of relocs before they are modified for --emit-relocs. */ + Elf_Internal_Rela *opd_relocs; }; #define ppc64_elf_tdata(bfd) \ @@ -4696,7 +4699,7 @@ opd_entry_value (asection *opd_sec, bfd_vma *code_off) { bfd *opd_bfd = opd_sec->owner; - Elf_Internal_Rela *relocs, *save_relocs = NULL; + Elf_Internal_Rela *relocs; Elf_Internal_Rela *lo, *hi, *look; bfd_vma val; @@ -4726,17 +4729,12 @@ opd_entry_value (asection *opd_sec, return val; } - /* If the .opd relocs have been adjusted for output, then we need to - re-read the original relocs rather than use the cached ones. */ - if (opd_sec->reloc_done) - { - save_relocs = elf_section_data (opd_sec)->relocs; - elf_section_data (opd_sec)->relocs = NULL; - } + relocs = ppc64_elf_tdata (opd_bfd)->opd_relocs; + if (relocs == NULL) + relocs = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, TRUE); /* Go find the opd reloc at the sym address. */ - lo = relocs = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, - !opd_sec->reloc_done); + lo = relocs; BFD_ASSERT (lo != NULL); hi = lo + opd_sec->reloc_count - 1; /* ignore last reloc */ val = (bfd_vma) -1; @@ -4807,11 +4805,6 @@ opd_entry_value (asection *opd_sec, } } - if (opd_sec->reloc_done) - { - elf_section_data (opd_sec)->relocs = save_relocs; - free (relocs); - } return val; } @@ -6996,6 +6989,9 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) ++wrel; } toc->reloc_count = wrel - relstart; + elf_section_data (toc)->rel_hdr.sh_size + = toc->reloc_count * elf_section_data (toc)->rel_hdr.sh_entsize; + BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL); /* Adjust addends for relocs against the toc section sym. */ for (sec = ibfd->sections; sec != NULL; sec = sec->next) @@ -10440,8 +10436,19 @@ ppc64_elf_relocate_section (bfd *output_bfd, /* If we're emitting relocations, then shortly after this function returns, reloc offsets and addends for this section will be adjusted. Worse, reloc symbol indices will be for the output - file rather than the input. Let opd_entry_value know. */ - input_section->reloc_done = info->emitrelocations; + file rather than the input. Save a copy of the relocs for + opd_entry_value. */ + if (is_opd && info->emitrelocations) + { + bfd_size_type amt; + amt = input_section->reloc_count * sizeof (Elf_Internal_Rela); + rel = bfd_alloc (input_bfd, amt); + BFD_ASSERT (ppc64_elf_tdata (input_bfd)->opd_relocs == NULL); + ppc64_elf_tdata (input_bfd)->opd_relocs = rel; + if (rel == NULL) + return FALSE; + memcpy (rel, relocs, amt); + } return ret; } -- 2.7.4