This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ppc relax for vxworks
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sources dot redhat dot com>
- Date: Fri, 23 Jan 2009 15:51:59 +0000
- Subject: ppc relax for vxworks
Hi,
vxworks rtps contain relocations, so that the loader can relocate them. This
does not play nicely with relax, which uses some internal reloc codes to
describe the relaxing. These internal codes end up in the executable, and bad
things happen. When the internal codes are renumbered between releases, even
weirder things happen :)
This patch alters ppc's relax handling so it generates correct relocs describing
the trampolines. With this patch static rtps can be relaxed.
tested on powerpc-vxworks, ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
2009-01-21 Nathan Sidwell <nathan@codesourcery.com>
bfd/
* elf32-ppc.c (ppc_elf_relax_section): Add space for relocs
describing the trampolines.
(ppc_elf_relocate_section): Update relocs to describe the
trampolines.
ld/testsuite/
* ld-powerpc/powerpc.exp: Add vxworks relax testcase.
* ld-powerpc/vxworks-relax.s, ld-powerpc/vxworks-relax.rd: New.
* ld-powerpc/vxworks1.ld: Add .pad and .far input sections.
* ld-powerpc/vxworks1.rd: Correct regexp for undefined symbols.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.249
diff -c -3 -p -r1.249 elf32-ppc.c
*** bfd/elf32-ppc.c 25 Nov 2008 13:03:55 -0000 1.249
--- bfd/elf32-ppc.c 21 Jan 2009 15:40:16 -0000
*************** ppc_elf_relax_section (bfd *abfd,
*** 5576,5582 ****
Elf_Internal_Rela *internal_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
struct one_fixup *fixups = NULL;
! bfd_boolean changed;
struct ppc_elf_link_hash_table *htab;
bfd_size_type trampoff;
asection *got2;
--- 5576,5582 ----
Elf_Internal_Rela *internal_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
struct one_fixup *fixups = NULL;
! unsigned changes = 0;
struct ppc_elf_link_hash_table *htab;
bfd_size_type trampoff;
asection *got2;
*************** ppc_elf_relax_section (bfd *abfd,
*** 5823,5828 ****
--- 5823,5829 ----
fixups = f;
trampoff += size;
+ changes++;
}
else
{
*************** ppc_elf_relax_section (bfd *abfd,
*** 5873,5879 ****
}
/* Write out the trampolines. */
- changed = fixups != NULL;
if (fixups != NULL)
{
const int *stub;
--- 5874,5879 ----
*************** ppc_elf_relax_section (bfd *abfd,
*** 5939,5945 ****
if (contents != NULL
&& elf_section_data (isec)->this_hdr.contents != contents)
{
! if (!changed && !link_info->keep_memory)
free (contents);
else
{
--- 5939,5945 ----
if (contents != NULL
&& elf_section_data (isec)->this_hdr.contents != contents)
{
! if (!changes && !link_info->keep_memory)
free (contents);
else
{
*************** ppc_elf_relax_section (bfd *abfd,
*** 5948,5962 ****
}
}
! if (elf_section_data (isec)->relocs != internal_relocs)
{
! if (!changed)
free (internal_relocs);
! else
! elf_section_data (isec)->relocs = internal_relocs;
}
! *again = changed;
return TRUE;
error_return:
--- 5948,5982 ----
}
}
! if (changes != 0)
{
! /* Append sufficient NOP relocs so we can write out relocation
! information for the trampolines. */
! Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
! * sizeof (*new_relocs));
! unsigned ix;
!
! if (!new_relocs)
! goto error_return;
! memcpy (new_relocs, internal_relocs,
! isec->reloc_count * sizeof (*new_relocs));
! for (ix = changes; ix--;)
! {
! irel = new_relocs + ix + isec->reloc_count;
!
! irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
! }
! if (internal_relocs != elf_section_data (isec)->relocs)
free (internal_relocs);
! elf_section_data (isec)->relocs = new_relocs;
! isec->reloc_count += changes;
! elf_section_data (isec)->rel_hdr.sh_size
! += changes * elf_section_data (isec)->rel_hdr.sh_entsize;
}
+ else if (elf_section_data (isec)->relocs != internal_relocs)
+ free (internal_relocs);
! *again = changes != 0;
return TRUE;
error_return:
*************** ppc_elf_relocate_section (bfd *output_bf
*** 6950,6955 ****
--- 6970,6996 ----
bfd_put_32 (output_bfd, t0, contents + rel->r_offset);
bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4);
+
+ /* Rewrite the reloc and convert one of the trailing nop
+ relocs to describe this relocation. */
+ BFD_ASSERT (ELF32_R_TYPE (relend[-1].r_info) == R_PPC_NONE);
+ /* The relocs are at the bottom 2 bytes */
+ rel[0].r_offset += 2;
+ memmove (rel + 1, rel, (relend - rel - 1) * sizeof (*rel));
+ rel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA);
+ rel[1].r_offset += 4;
+ rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
+ rel++;
}
continue;
Index: ld/testsuite/ld-powerpc/powerpc.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/powerpc.exp,v
retrieving revision 1.23
diff -c -3 -p -r1.23 powerpc.exp
*** ld/testsuite/ld-powerpc/powerpc.exp 10 Oct 2008 20:55:36 -0000 1.23
--- ld/testsuite/ld-powerpc/powerpc.exp 21 Jan 2009 15:40:19 -0000
*************** if {[istarget "*-*-vxworks"]} {
*** 49,54 ****
--- 49,59 ----
"-mregnames" {vxworks2.s}
{{readelf --segments vxworks2-static.sd}}
"vxworks2"}
+ {"VxWorks relax test"
+ "-Tvxworks1.ld --relax -q"
+ "-mregnames" {vxworks-relax.s}
+ {{readelf --relocs vxworks-relax.rd}}
+ "vxworks-relax"}
}
run_ld_link_tests $ppcvxtests
run_dump_test "vxworks1-static"
Index: ld/testsuite/ld-powerpc/vxworks-relax.rd
===================================================================
RCS file: ld/testsuite/ld-powerpc/vxworks-relax.rd
diff -N ld/testsuite/ld-powerpc/vxworks-relax.rd
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-powerpc/vxworks-relax.rd 21 Jan 2009 15:40:19 -0000
***************
*** 0 ****
--- 1,9 ----
+
+ Relocation section '.rela.text' at offset 0x4010150 contains 6 entries:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+ 00080012 00000106 R_PPC_ADDR16_HA 00080000 .text \+ 4000020
+ 00080016 00000104 R_PPC_ADDR16_LO 00080000 .text \+ 4000020
+ 00080006 00000106 R_PPC_ADDR16_HA 00080000 .text \+ 4000020
+ 0008000a 00000104 R_PPC_ADDR16_LO 00080000 .text \+ 4000020
+ 0408002a 00000306 R_PPC_ADDR16_HA 00080000 _start \+ 0
+ 0408002e 00000304 R_PPC_ADDR16_LO 00080000 _start \+ 0
Index: ld/testsuite/ld-powerpc/vxworks-relax.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/vxworks-relax.s
diff -N ld/testsuite/ld-powerpc/vxworks-relax.s
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-powerpc/vxworks-relax.s 21 Jan 2009 15:40:19 -0000
***************
*** 0 ****
--- 1,13 ----
+ .globl _start
+ _start:
+ bl elsewhere
+ lis 9,elsewhere@ha
+ la 0,elsewhere@l(9)
+
+
+ .section .far,"ax",@progbits
+ elsewhere:
+ bl _start
+
+ .section .pad
+ .space 0x4000000
Index: ld/testsuite/ld-powerpc/vxworks1.ld
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/vxworks1.ld,v
retrieving revision 1.4
diff -c -3 -p -r1.4 vxworks1.ld
*** ld/testsuite/ld-powerpc/vxworks1.ld 15 May 2007 12:22:34 -0000 1.4
--- ld/testsuite/ld-powerpc/vxworks1.ld 21 Jan 2009 15:40:19 -0000
*************** SECTIONS
*** 14,20 ****
.plt : { *(.plt) }
. = ALIGN (0x400);
! .text : { *(.text) }
. = ALIGN (0x10000);
.dynamic : { *(.dynamic) }
--- 14,20 ----
.plt : { *(.plt) }
. = ALIGN (0x400);
! .text : { *(.text) *(.pad) *(.far) }
. = ALIGN (0x10000);
.dynamic : { *(.dynamic) }
Index: ld/testsuite/ld-powerpc/vxworks1.rd
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/vxworks1.rd,v
retrieving revision 1.2
diff -c -3 -p -r1.2 vxworks1.rd
*** ld/testsuite/ld-powerpc/vxworks1.rd 2 Mar 2006 15:16:27 -0000 1.2
--- ld/testsuite/ld-powerpc/vxworks1.rd 21 Jan 2009 15:40:19 -0000
***************
*** 1,8 ****
Relocation section '\.rela\.plt' at offset .* contains 2 entries:
Offset Info Type Sym\.Value Sym\. Name \+ Addend
! 0009040c .*15 R_PPC_JMP_SLOT 00080820 sglobal \+ 0
! 00090410 .*15 R_PPC_JMP_SLOT 00080840 foo \+ 0
Relocation section '\.rela\.text' at offset .* contains 3 entries:
Offset Info Type Sym\.Value Sym\. Name \+ Addend
--- 1,8 ----
Relocation section '\.rela\.plt' at offset .* contains 2 entries:
Offset Info Type Sym\.Value Sym\. Name \+ Addend
! 0009040c .*15 R_PPC_JMP_SLOT 00000000 sglobal \+ 0
! 00090410 .*15 R_PPC_JMP_SLOT 00000000 foo \+ 0
Relocation section '\.rela\.text' at offset .* contains 3 entries:
Offset Info Type Sym\.Value Sym\. Name \+ Addend