diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 47 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/powerpc.exp | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/vxworks-relax.rd | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/vxworks-relax.s | 13 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/vxworks1.ld | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/vxworks1.rd | 4 |
8 files changed, 83 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 705b5b69..5873b1b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2009-01-26 Nathan Sidwell <nathan@codesourcery.com> + + * 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-25 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> * elf-hppa.h (elf_hppa_final_link_relocate): Add check to ensure that diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 432605b..b04bea4 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5576,7 +5576,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; @@ -5823,6 +5823,7 @@ ppc_elf_relax_section (bfd *abfd, fixups = f; trampoff += size; + changes++; } else { @@ -5873,7 +5874,6 @@ ppc_elf_relax_section (bfd *abfd, } /* Write out the trampolines. */ - changed = fixups != NULL; if (fixups != NULL) { const int *stub; @@ -5939,7 +5939,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 { @@ -5948,15 +5948,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: @@ -6950,6 +6970,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 b708780..78b39cd 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-01-26 Nathan Sidwell <nathan@codesourcery.com> + + * 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-26 Andrew Stubbs <ams@codesourcery.com> * ld-arm/attr-merge-3.attr: Update following gas change. diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index af812a0..1630cd7 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/vxworks-relax.rd b/ld/testsuite/ld-powerpc/vxworks-relax.rd new file mode 100644 index 0000000..e28094c --- /dev/null +++ b/ld/testsuite/ld-powerpc/vxworks-relax.rd @@ -0,0 +1,9 @@ + +Relocation section '.rela.text' at offset 0x4010150 contains 6 entries: + Offset Info Type Sym.Value Sym. Name \+ Addend +00080012 00000106 R_PPC_ADDR16_HA 00080000 .text \+ 4000020 +00080016 00000104 R_PPC_ADDR16_LO 00080000 .text \+ 4000020 +00080006 00000106 R_PPC_ADDR16_HA 00080000 .text \+ 4000020 +0008000a 00000104 R_PPC_ADDR16_LO 00080000 .text \+ 4000020 +0408002a 00000306 R_PPC_ADDR16_HA 00080000 _start \+ 0 +0408002e 00000304 R_PPC_ADDR16_LO 00080000 _start \+ 0 diff --git a/ld/testsuite/ld-powerpc/vxworks-relax.s b/ld/testsuite/ld-powerpc/vxworks-relax.s new file mode 100644 index 0000000..b4ebb9a --- /dev/null +++ b/ld/testsuite/ld-powerpc/vxworks-relax.s @@ -0,0 +1,13 @@ + .globl _start +_start: + bl elsewhere + lis 9,elsewhere@ha + la 0,elsewhere@l(9) + + + .section .far,"ax",@progbits +elsewhere: + bl _start + + .section .pad + .space 0x4000000 diff --git a/ld/testsuite/ld-powerpc/vxworks1.ld b/ld/testsuite/ld-powerpc/vxworks1.ld index ce750b0..3106d55 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 27d2404..b8591a8 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 |