This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]