This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
powerpc long branch trampolines
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Cc: Yaakov Yaari <YAARI at il dot ibm dot com>
- Date: Tue, 6 Jul 2010 18:57:53 +0930
- Subject: powerpc long branch trampolines
This changes powerpc32 long branch trampolines slightly. In most
cases the branch around the trampolines is unnecessary; It's only
when execution falls off the end of a section that we need to ensure
that we don't run into a stub instead. As far as I know, this is only
needed for those horrible pasted function fragments in .init or
.fini.
You might think it's better to be safe than sorry, always add the
branch, but this can confuse some code analysis and optimization
tools.
bfd/
* elf32-ppc.c (ppc_elf_relax_section): Insert branch around
trampolines only for .init and .fini sections.
ld/testsuite/
* ld-powerpc/relax.s: Add branch back to _start.
* ld-powerpc/relax.d: Update.
* ld-powerpc/relaxr.d: Update.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.284
diff -u -p -r1.284 elf32-ppc.c
--- bfd/elf32-ppc.c 5 Jul 2010 13:34:27 -0000 1.284
+++ bfd/elf32-ppc.c 6 Jul 2010 08:50:34 -0000
@@ -5967,6 +5967,7 @@ ppc_elf_relax_section (bfd *abfd,
struct ppc_elf_link_hash_table *htab;
bfd_size_type trampoff;
asection *got2;
+ bfd_boolean maybe_pasted;
*again = FALSE;
@@ -5985,8 +5986,11 @@ ppc_elf_relax_section (bfd *abfd,
return TRUE;
trampoff = (isec->size + 3) & (bfd_vma) -4;
+ maybe_pasted = (strcmp (isec->output_section->name, ".init") == 0
+ || strcmp (isec->output_section->name, ".fini") == 0);
/* Space for a branch around any trampolines. */
- trampoff += 4;
+ if (maybe_pasted)
+ trampoff += 4;
symtab_hdr = &elf_symtab_hdr (abfd);
@@ -6311,7 +6315,6 @@ ppc_elf_relax_section (bfd *abfd,
{
const int *stub;
bfd_byte *dest;
- bfd_vma val;
int i, size;
do
@@ -6327,12 +6330,15 @@ ppc_elf_relax_section (bfd *abfd,
goto error_return;
isec->size = (isec->size + 3) & (bfd_vma) -4;
- /* Branch around the trampolines. */
- val = B + trampoff - isec->size;
dest = contents + isec->size;
+ /* Branch around the trampolines. */
+ if (maybe_pasted)
+ {
+ bfd_vma val = B + trampoff - isec->size;
+ bfd_put_32 (abfd, val, dest);
+ dest += 4;
+ }
isec->size = trampoff;
- bfd_put_32 (abfd, val, dest);
- dest += 4;
if (link_info->shared)
{
Index: ld/testsuite/ld-powerpc/relax.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/relax.d,v
retrieving revision 1.2
diff -u -p -r1.2 relax.d
--- ld/testsuite/ld-powerpc/relax.d 23 Aug 2009 09:43:35 -0000 1.2
+++ ld/testsuite/ld-powerpc/relax.d 6 Jul 2010 08:51:23 -0000
@@ -8,7 +8,7 @@ Disassembly of section .text:
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 <.*>
+ 10: 4b ff ff f0 b 0 <.*>
14: 3d 80 80 00 lis r12,-32768
18: 39 8c 12 34 addi r12,r12,4660
1c: 7d 89 03 a6 mtctr r12
Index: ld/testsuite/ld-powerpc/relax.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/relax.s,v
retrieving revision 1.1
diff -u -p -r1.1 relax.s
--- ld/testsuite/ld-powerpc/relax.s 10 Aug 2009 13:38:44 -0000 1.1
+++ ld/testsuite/ld-powerpc/relax.s 6 Jul 2010 08:51:23 -0000
@@ -4,3 +4,4 @@ _start:
bl far
bl near
bl far
+ b _start
Index: ld/testsuite/ld-powerpc/relaxr.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/relaxr.d,v
retrieving revision 1.2
diff -u -p -r1.2 relaxr.d
--- ld/testsuite/ld-powerpc/relaxr.d 23 Aug 2009 09:43:35 -0000 1.2
+++ ld/testsuite/ld-powerpc/relaxr.d 6 Jul 2010 08:51:23 -0000
@@ -10,7 +10,8 @@ Disassembly of section .text:
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>
+ 10: 48 00 00 00 b 10 <_start\+0x10>
+ 10: R_PPC_REL24 _start
14: 3d 80 00 00 lis r12,0
16: R_PPC_ADDR16_HA near
18: 39 8c 00 00 addi r12,r12,0
--
Alan Modra
Australia Development Lab, IBM