aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2009-08-10 13:38:44 +0000
committerNathan Sidwell <nathan@codesourcery.com>2009-08-10 13:38:44 +0000
commit01017ef89a902536817c86aa0d0562184807a954 (patch)
tree7479f8fca97167522f03259c9c82e7804c762753
parent023e4e81acd973bf79e07681690ca4196bf2e37d (diff)
downloadgdb-01017ef89a902536817c86aa0d0562184807a954.zip
gdb-01017ef89a902536817c86aa0d0562184807a954.tar.gz
gdb-01017ef89a902536817c86aa0d0562184807a954.tar.bz2
bfd/
* 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.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-ppc.c36
-rw-r--r--ld/testsuite/ChangeLog7
-rw-r--r--ld/testsuite/ld-powerpc/powerpc.exp6
-rw-r--r--ld/testsuite/ld-powerpc/relax.d15
-rw-r--r--ld/testsuite/ld-powerpc/relax.s6
-rw-r--r--ld/testsuite/ld-powerpc/relaxr.d25
7 files changed, 87 insertions, 14 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cc9850c..b2a331c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 2925039..ae031df 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -5857,23 +5857,25 @@ ppc_elf_hash_symbol (struct elf_link_hash_entry *h)
#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)
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index d0e1699..29457a6 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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.
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index bc63a46..edfab3f 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -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
index 0000000..2f09522
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/relax.d
@@ -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
index 0000000..2e05569
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/relax.s
@@ -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
index 0000000..62fa8ae
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/relaxr.d
@@ -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