From: Alan Modra Date: Mon, 2 Mar 2009 13:52:34 +0000 (+0000) Subject: backport 2009-01-26 Nathan Sidwell X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=636e2656d81c549fa48c4f95c7363d669eff53c5;p=thirdparty%2Fbinutils-gdb.git backport 2009-01-26 Nathan Sidwell --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bc02ce85f46..8e7c0594d65 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,11 @@ 2009-03-02 Alan Modra + 2009-01-26 Nathan Sidwell + * elf32-ppc.c (ppc_elf_relax_section): Add space for relocs + describing the trampolines. + (ppc_elf_relocate_section): Update relocs to describe the + trampolines. + 2009-01-22 Alan Modra PR 6832 * dwarf2.c (find_line): Don't update stash->sec_info_ptr until diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 55348aefa39..cec819d1b58 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5600,7 +5600,7 @@ ppc_elf_relax_section (bfd *abfd, Elf_Internal_Rela *internal_relocs = NULL; Elf_Internal_Rela *irel, *irelend; struct one_fixup *fixups = NULL; - bfd_boolean changed; + unsigned changes = 0; struct ppc_elf_link_hash_table *htab; bfd_size_type trampoff; asection *got2; @@ -5847,6 +5847,7 @@ ppc_elf_relax_section (bfd *abfd, fixups = f; trampoff += size; + changes++; } else { @@ -5897,7 +5898,6 @@ ppc_elf_relax_section (bfd *abfd, } /* Write out the trampolines. */ - changed = fixups != NULL; if (fixups != NULL) { const int *stub; @@ -5963,7 +5963,7 @@ ppc_elf_relax_section (bfd *abfd, if (contents != NULL && elf_section_data (isec)->this_hdr.contents != contents) { - if (!changed && !link_info->keep_memory) + if (!changes && !link_info->keep_memory) free (contents); else { @@ -5972,15 +5972,35 @@ ppc_elf_relax_section (bfd *abfd, } } - if (elf_section_data (isec)->relocs != internal_relocs) + if (changes != 0) { - if (!changed) + /* Append sufficient NOP relocs so we can write out relocation + information for the trampolines. */ + Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count) + * sizeof (*new_relocs)); + unsigned ix; + + if (!new_relocs) + goto error_return; + memcpy (new_relocs, internal_relocs, + isec->reloc_count * sizeof (*new_relocs)); + for (ix = changes; ix--;) + { + irel = new_relocs + ix + isec->reloc_count; + + irel->r_info = ELF32_R_INFO (0, R_PPC_NONE); + } + if (internal_relocs != elf_section_data (isec)->relocs) free (internal_relocs); - else - elf_section_data (isec)->relocs = internal_relocs; + elf_section_data (isec)->relocs = new_relocs; + isec->reloc_count += changes; + elf_section_data (isec)->rel_hdr.sh_size + += changes * elf_section_data (isec)->rel_hdr.sh_entsize; } + else if (elf_section_data (isec)->relocs != internal_relocs) + free (internal_relocs); - *again = changed; + *again = changes != 0; return TRUE; error_return: @@ -6986,6 +7006,17 @@ ppc_elf_relocate_section (bfd *output_bfd, bfd_put_32 (output_bfd, t0, contents + rel->r_offset); bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4); + + /* Rewrite the reloc and convert one of the trailing nop + relocs to describe this relocation. */ + BFD_ASSERT (ELF32_R_TYPE (relend[-1].r_info) == R_PPC_NONE); + /* The relocs are at the bottom 2 bytes */ + rel[0].r_offset += 2; + memmove (rel + 1, rel, (relend - rel - 1) * sizeof (*rel)); + rel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA); + rel[1].r_offset += 4; + rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO); + rel++; } continue; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index af588564ebc..45015f58905 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2009-03-02 Alan Modra + 2009-01-26 Nathan Sidwell + * ld-powerpc/powerpc.exp: Add vxworks relax testcase. + * ld-powerpc/vxworks-relax.s, ld-powerpc/vxworks-relax.rd: New. + * ld-powerpc/vxworks1.ld: Add .pad and .far input sections. + * ld-powerpc/vxworks1.rd: Correct regexp for undefined symbols. + 2009-01-11 Jan Kratochvil * ld-elf/linkoncerdiff.d, ld-elf/linkoncerdiff1.s, ld-elf/linkoncerdiff2.s: New. diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index af812a042c1..1630cd71d74 100644 --- a/ld/testsuite/ld-powerpc/powerpc.exp +++ b/ld/testsuite/ld-powerpc/powerpc.exp @@ -49,6 +49,11 @@ if {[istarget "*-*-vxworks"]} { "-mregnames" {vxworks2.s} {{readelf --segments vxworks2-static.sd}} "vxworks2"} + {"VxWorks relax test" + "-Tvxworks1.ld --relax -q" + "-mregnames" {vxworks-relax.s} + {{readelf --relocs vxworks-relax.rd}} + "vxworks-relax"} } run_ld_link_tests $ppcvxtests run_dump_test "vxworks1-static" diff --git a/ld/testsuite/ld-powerpc/vxworks1.ld b/ld/testsuite/ld-powerpc/vxworks1.ld index ce750b00fad..3106d552406 100644 --- a/ld/testsuite/ld-powerpc/vxworks1.ld +++ b/ld/testsuite/ld-powerpc/vxworks1.ld @@ -14,7 +14,7 @@ SECTIONS .plt : { *(.plt) } . = ALIGN (0x400); - .text : { *(.text) } + .text : { *(.text) *(.pad) *(.far) } . = ALIGN (0x10000); .dynamic : { *(.dynamic) } diff --git a/ld/testsuite/ld-powerpc/vxworks1.rd b/ld/testsuite/ld-powerpc/vxworks1.rd index 27d240454c3..b8591a86997 100644 --- a/ld/testsuite/ld-powerpc/vxworks1.rd +++ b/ld/testsuite/ld-powerpc/vxworks1.rd @@ -1,8 +1,8 @@ Relocation section '\.rela\.plt' at offset .* contains 2 entries: Offset Info Type Sym\.Value Sym\. Name \+ Addend -0009040c .*15 R_PPC_JMP_SLOT 00080820 sglobal \+ 0 -00090410 .*15 R_PPC_JMP_SLOT 00080840 foo \+ 0 +0009040c .*15 R_PPC_JMP_SLOT 00000000 sglobal \+ 0 +00090410 .*15 R_PPC_JMP_SLOT 00000000 foo \+ 0 Relocation section '\.rela\.text' at offset .* contains 3 entries: Offset Info Type Sym\.Value Sym\. Name \+ Addend