From 01017ef89a902536817c86aa0d0562184807a954 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 10 Aug 2009 13:38:44 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 6 ++++++ bfd/elf32-ppc.c | 36 ++++++++++++++++++++++-------------- ld/testsuite/ChangeLog | 7 +++++++ ld/testsuite/ld-powerpc/powerpc.exp | 6 ++++++ ld/testsuite/ld-powerpc/relax.d | 15 +++++++++++++++ ld/testsuite/ld-powerpc/relax.s | 6 ++++++ ld/testsuite/ld-powerpc/relaxr.d | 25 +++++++++++++++++++++++++ 7 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 ld/testsuite/ld-powerpc/relax.d create mode 100644 ld/testsuite/ld-powerpc/relax.s create mode 100644 ld/testsuite/ld-powerpc/relaxr.d 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 + + * 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 * 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 + + * 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 * 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 + 4: 48 00 00 11 bl 14 <_start\+0x14> + 8: 48 00 43 19 bl 4320 + 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 -- 2.7.4