bfd/
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 10 Aug 2009 13:38:44 +0000 (13:38 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Mon, 10 Aug 2009 13:38:44 +0000 (13:38 +0000)
* elf32-ppc.c (shared_stub_entry, stub_entry): Use r12, not r11.
(ppc_elf_relax_section): Use symbol index to distinguish
relocatable stubs.

ld/testsuite/
* ld-powerpc/relax.s: New.
* ld-powerpc/relax.d: New.
* ld-powerpc/relaxr.d: New.
* ld-powerpc/powerpc.exp: Add new tests.

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

index cc9850c4af7c075e662e1ebd2323c23169252dfc..b2a331c23a0136295c5c832c9072eadd95f81b3a 100644 (file)
@@ -1,3 +1,9 @@
+2009-08-10  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * elf32-ppc.c (shared_stub_entry, stub_entry): Use r12, not r11.
+       (ppc_elf_relax_section): Use symbol index to distinguish
+       relocatable stubs.
+
 2009-08-10  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-ppc.c (ppc_elf_relax_section): Ignore non-code sections.
index 292503945c07338ea54091744e49cec13fa9fa65..ae031df477f939a401182e0585626af340f4ca30 100644 (file)
@@ -5857,23 +5857,25 @@ ppc_elf_hash_symbol (struct elf_link_hash_entry *h)
 \f
 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
+/* Relaxation trampolines.  r12 is available for clobbering (r11, is
+   used for some functions that are allowed to break the ABI).  */
 static const int shared_stub_entry[] =
   {
     0x7c0802a6, /* mflr 0 */
     0x429f0005, /* bcl 20, 31, .Lxxx */
-    0x7d6802a6, /* mflr 11 */
-    0x3d6b0000, /* addis 11, 11, (xxx-.Lxxx)@ha */
-    0x396b0018, /* addi 11, 11, (xxx-.Lxxx)@l */
+    0x7d8802a6, /* mflr 12 */
+    0x3d8c0000, /* addis 12, 12, (xxx-.Lxxx)@ha */
+    0x398c0008, /* addi 12, 12, (xxx-.Lxxx)@l */
     0x7c0803a6, /* mtlr 0 */
-    0x7d6903a6, /* mtctr 11 */
+    0x7d8903a6, /* mtctr 12 */
     0x4e800420, /* bctr */
   };
 
 static const int stub_entry[] =
   {
-    0x3d600000, /* lis 11,xxx@ha */
-    0x396b0000, /* addi 11,11,xxx@l */
-    0x7d6903a6, /* mtctr 11 */
+    0x3d800000, /* lis 12,xxx@ha */
+    0x398c0000, /* addi 12,12,xxx@l */
+    0x7d8903a6, /* mtctr 12 */
     0x4e800420, /* bctr */
   };
 
@@ -5887,6 +5889,8 @@ ppc_elf_relax_section (bfd *abfd,
   {
     struct one_fixup *next;
     asection *tsec;
+    /* Final link, can use the symbol offset.  For a
+       relocatable link we use the symbol's index.  */
     bfd_vma toff;
     bfd_vma trampoff;
   };
@@ -5937,7 +5941,7 @@ ppc_elf_relax_section (bfd *abfd,
   for (irel = internal_relocs; irel < irelend; irel++)
     {
       unsigned long r_type = ELF32_R_TYPE (irel->r_info);
-      bfd_vma symaddr, reladdr, toff, roff;
+      bfd_vma reladdr, toff, roff;
       asection *tsec;
       struct one_fixup *f;
       size_t insn_offset = 0;
@@ -6019,7 +6023,7 @@ ppc_elf_relax_section (bfd *abfd,
                   || h->root.type == bfd_link_hash_undefweak)
            {
              tsec = bfd_und_section_ptr;
-             toff = 0;
+             toff = link_info->relocatable ? indx : 0;
            }
          else
            continue;
@@ -6120,8 +6124,6 @@ ppc_elf_relax_section (bfd *abfd,
       if (tsec->output_section == NULL)
        continue;
 
-      symaddr = tsec->output_section->vma + tsec->output_offset + toff;
-
       roff = irel->r_offset;
       reladdr = isec->output_section->vma + isec->output_offset + roff;
 
@@ -6130,9 +6132,15 @@ ppc_elf_relax_section (bfd *abfd,
          && (!link_info->relocatable
              /* A relocatable link may have sections moved during
                 final link, so do not presume they remain in range.  */
-             || tsec->output_section == isec->output_section)
-         && symaddr - reladdr + max_branch_offset < 2 * max_branch_offset)
-       continue;
+             || tsec->output_section == isec->output_section))
+       {
+         bfd_vma symaddr, reladdr;
+
+         symaddr = tsec->output_section->vma + tsec->output_offset + toff;
+         reladdr = isec->output_section->vma + isec->output_offset + roff;
+         if (symaddr - reladdr + max_branch_offset < 2 * max_branch_offset)
+           continue;
+       }
 
       /* Look for an existing fixup to this address.  */
       for (f = fixups; f ; f = f->next)
index d0e1699d7f8e4ab87391eb2535eb6b33f52343f8..29457a6f8fb2da7b0f40d77ebe7d753950531457 100644 (file)
@@ -1,3 +1,10 @@
+2009-08-10  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * ld-powerpc/relax.s: New.
+       * ld-powerpc/relax.d: New.
+       * ld-powerpc/relaxr.d: New.
+       * ld-powerpc/powerpc.exp: Add new tests.
+
 2009-08-06  Nathan Sidwell  <nathan@codesourcery.com>
 
        * ld-arm/arm-elf.exp: Add new test.
index bc63a467fbe1c1a2bfd3dafbd73a62b7d0a41c30..edfab3ff77c9b1ac3b4c822a3cf4d5f551f03c5d 100644 (file)
@@ -158,6 +158,12 @@ set ppc64elftests {
       "tlsmark"}
     {"sym@tocbase" "-shared -melf64ppc" "-a64" {symtocbase-1.s symtocbase-2.s}
        {{objdump -dj.data symtocbase.d}} "symtocbase.so"}
+    {"relaxing" "-melf32ppc --relax -Ttext=0 --defsym far=0x80001234 --defsym near=0x00004320" "" "relax.s"
+     {{objdump -dr relax.d}}
+      "relax"}
+    {"relocatable relaxing" "-melf32ppc -r --relax" "" "relax.s"
+     {{objdump -dr relaxr.d}}
+      "relax"}
 }
 
 
diff --git a/ld/testsuite/ld-powerpc/relax.d b/ld/testsuite/ld-powerpc/relax.d
new file mode 100644 (file)
index 0000000..2f09522
--- /dev/null
@@ -0,0 +1,15 @@
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+00000000 <_start>:
+   0:  48 00 43 21     bl      4320 <near>
+   4:  48 00 00 11     bl      14 <_start\+0x14>
+   8:  48 00 43 19     bl      4320 <near>
+   c:  48 00 00 09     bl      14 <_start\+0x14>
+  10:  48 00 00 14     b       24 <.*>
+  14:  3d 80 80 00     lis     r12,-32768
+  18:  39 8c 12 34     addi    r12,r12,4660
+  1c:  7d 89 03 a6     mtctr   r12
+  20:  4e 80 04 20     bctr
diff --git a/ld/testsuite/ld-powerpc/relax.s b/ld/testsuite/ld-powerpc/relax.s
new file mode 100644 (file)
index 0000000..2e05569
--- /dev/null
@@ -0,0 +1,6 @@
+       .globl _start
+_start:
+       bl near
+       bl far
+       bl near
+       bl far
diff --git a/ld/testsuite/ld-powerpc/relaxr.d b/ld/testsuite/ld-powerpc/relaxr.d
new file mode 100644 (file)
index 0000000..62fa8ae
--- /dev/null
@@ -0,0 +1,25 @@
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+00000000 <_start>:
+   0:  48 00 00 15     bl      14 <_start\+0x14>
+   4:  48 00 00 21     bl      24 <_start\+0x24>
+   8:  48 00 00 0d     bl      14 <_start\+0x14>
+                       8: R_PPC_NONE   \*ABS\*
+   c:  48 00 00 19     bl      24 <_start\+0x24>
+                       c: R_PPC_NONE   \*ABS\*
+  10:  48 00 00 24     b       34 <_start\+0x34>
+  14:  3d 80 00 00     lis     r12,0
+                       16: R_PPC_ADDR16_HA     near
+  18:  39 8c 00 00     addi    r12,r12,0
+                       1a: R_PPC_ADDR16_LO     near
+  1c:  7d 89 03 a6     mtctr   r12
+  20:  4e 80 04 20     bctr
+  24:  3d 80 00 00     lis     r12,0
+                       26: R_PPC_ADDR16_HA     far
+  28:  39 8c 00 00     addi    r12,r12,0
+                       2a: R_PPC_ADDR16_LO     far
+  2c:  7d 89 03 a6     mtctr   r12
+  30:  4e 80 04 20     bctr