powerpc long branch trampolines
Alan Modra
amodra@gmail.com
Tue Jul 6 09:28:00 GMT 2010
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
More information about the Binutils
mailing list