* ld-powerpc/powerpc.exp: Add vxworks relax testcase.
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 26 Jan 2009 15:27:04 +0000 (15:27 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Mon, 26 Jan 2009 15:27:04 +0000 (15:27 +0000)
* 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.

bfd/ChangeLog
bfd/elf32-ppc.c
ld/testsuite/ChangeLog
ld/testsuite/ld-powerpc/powerpc.exp
ld/testsuite/ld-powerpc/vxworks-relax.rd [new file with mode: 0644]
ld/testsuite/ld-powerpc/vxworks-relax.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/vxworks1.ld
ld/testsuite/ld-powerpc/vxworks1.rd

index 705b5b6..5873b1b 100644 (file)
@@ -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
index 432605b..b04bea4 100644 (file)
@@ -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;
 
index b708780..78b39cd 100644 (file)
@@ -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.
index af812a0..1630cd7 100644 (file)
@@ -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 (file)
index 0000000..e28094c
--- /dev/null
@@ -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 (file)
index 0000000..b4ebb9a
--- /dev/null
@@ -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
index ce750b0..3106d55 100644 (file)
@@ -14,7 +14,7 @@ SECTIONS
   .plt : { *(.plt) }
 
   . = ALIGN (0x400);
-  .text : { *(.text) }
+  .text : { *(.text) *(.pad) *(.far) }
 
   . = ALIGN (0x10000);
   .dynamic : { *(.dynamic) }
index 27d2404..b8591a8 100644 (file)
@@ -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