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]

vxworks dynamic tls relocs


This is the final part of adding vxworks tls support. The vxworks dynamic loader has builtin knowledge of the structure of the .tls_vars section, and expects it to be statically relocated. If active dynamic relocations remain for that section, things go badly wrong. Fortunately for each architecture there is only one reloc type that is valid in the .tls_vars sections (a 32 or 64 bit absolute reloc pointing to the contents of the .tls_data section).

This patch changes each backend's relocate_section routine to detect when we're generating a shared vxworks object and processing a .tls_vars input section. In that case we process the expected relocations statically and nullify the dynamic relocation by turning it into a NOP reloc.

We have to detect the .tls_vars section by name, there are no particular section flags to detect it (vxworks TLS is not like regular TLS). Nullifying the dynamic reloc seemed the simplest approach to take, rather than change the size of the dynamic reloc section.

ok?

In case I've not mentioned it, gcc vxwork TLS support is waiting on GCC to go back to stage 1 after 4.3 branches.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

2007-11-13  Nathan Sidwell  <nathan@codesourcery.com>

	bfd/
	* elf32-ppc.c (ppc_elf_relocate_section): Resolve relocations that
	occur in vxworks .tls_vars sections statically.  Emit NONE dynamic
	relocation.
	* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
	* elf32-sh.c (sh_elf_relocate_section): Likewise.
	* elf32-arm.c (elf32_arm_final_link_relocate): Likewise.
	* elf32-i386.c (elf_i386_relocate_section): Likewise.
	* elfxx-mips.c (mips_elf_create_dynamic_relocation): Nullify
	relocation in vxworks .tls_vars section.

	ld/testsuite/
	* ld-vxworks/tls-3.d: New.
	* ld-vxworks/tls-3.s: New.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.130
diff -c -3 -p -r1.130 elf32-arm.c
*** bfd/elf32-arm.c	8 Nov 2007 13:51:06 -0000	1.130
--- bfd/elf32-arm.c	12 Nov 2007 18:26:08 -0000
*************** elf32_arm_final_link_relocate (reloc_how
*** 4668,4673 ****
--- 4668,4683 ----
  
  	  if (skip)
  	    memset (&outrel, 0, sizeof outrel);
+ 	  else if (info->shared && elf32_arm_hash_table (info)->vxworks_p
+ 		   && !strcmp (input_section->output_section->name,
+ 			       ".tls_vars"))
+ 	    {
+ 	      /* We have to handle relocations in vxworks .tls_vars
+      		 sections specially, because the dynamic loader is
+      		 'weird'.  */
+ 	      outrel.r_info = ELF32_R_INFO (0, R_ARM_NONE);
+ 	      relocate = TRUE;
+ 	    }
  	  else if (h != NULL
  		   && h->dynindx != -1
  		   && (!info->shared
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.183
diff -c -3 -p -r1.183 elf32-i386.c
*** bfd/elf32-i386.c	8 Nov 2007 13:51:06 -0000	1.183
--- bfd/elf32-i386.c	12 Nov 2007 18:26:11 -0000
*************** elf_i386_relocate_section (bfd *output_b
*** 2498,2503 ****
--- 2498,2504 ----
    bfd_vma *local_tlsdesc_gotents;
    Elf_Internal_Rela *rel;
    Elf_Internal_Rela *relend;
+   bfd_boolean is_vxworks_tls;
  
    htab = elf_i386_hash_table (info);
    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
*************** elf_i386_relocate_section (bfd *output_b
*** 2505,2510 ****
--- 2506,2517 ----
    local_got_offsets = elf_local_got_offsets (input_bfd);
    local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd);
  
+   /* We have to handle relocations in vxworks .tls_vars sections
+      specially, because the dynamic loader is 'weird'.  */
+   is_vxworks_tls = (htab->is_vxworks && info->shared
+ 		    && !strcmp (input_section->output_section->name,
+ 				".tls_vars"));
+ 
    rel = relocs;
    relend = relocs + input_section->reloc_count;
    for (; rel < relend; rel++)
*************** elf_i386_relocate_section (bfd *output_b
*** 2847,2852 ****
--- 2854,2865 ----
  
  	      if (skip)
  		memset (&outrel, 0, sizeof outrel);
+ 	      else if (is_vxworks_tls)
+ 		{
+ 		  /* Relocation is done magically by the loader.  */
+ 		  relocate = TRUE;
+ 		  outrel.r_info = ELF32_R_INFO (0, R_386_NONE);
+ 		}
  	      else if (h != NULL
  		       && h->dynindx != -1
  		       && (r_type == R_386_PC32
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.224
diff -c -3 -p -r1.224 elf32-ppc.c
*** bfd/elf32-ppc.c	8 Nov 2007 13:51:06 -0000	1.224
--- bfd/elf32-ppc.c	12 Nov 2007 18:26:16 -0000
*************** ppc_elf_relocate_section (bfd *output_bf
*** 5758,5763 ****
--- 5758,5764 ----
    bfd_vma *local_got_offsets;
    bfd_boolean ret = TRUE;
    bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
+   bfd_boolean is_vxworks_tls;
  
  #ifdef DEBUG
    _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, "
*************** ppc_elf_relocate_section (bfd *output_bf
*** 5777,5782 ****
--- 5778,5790 ----
    local_got_offsets = elf_local_got_offsets (input_bfd);
    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    sym_hashes = elf_sym_hashes (input_bfd);
+ 
+   /* We have to handle relocations in vxworks .tls_vars sections
+      specially, because the dynamic loader is 'weird'.  */
+   is_vxworks_tls = (htab->is_vxworks && info->shared
+ 		    && !strcmp (input_section->output_section->name,
+ 				".tls_vars"));
+ 
    rel = relocs;
    relend = relocs + input_section->reloc_count;
    for (; rel < relend; rel++)
*************** ppc_elf_relocate_section (bfd *output_bf
*** 6474,6479 ****
--- 6482,6493 ----
  
  	      if (skip)
  		memset (&outrel, 0, sizeof outrel);
+ 	      else if (is_vxworks_tls)
+ 		{
+ 		  outrel.r_info = ELF32_R_INFO (0, R_PPC_NONE);
+ 		  outrel.r_addend = relocation;
+ 		  skip = 1;
+ 		}
  	      else if (!SYMBOL_REFERENCES_LOCAL (info, h))
  		{
  		  unresolved_reloc = FALSE;
*************** ppc_elf_relocate_section (bfd *output_bf
*** 6541,6547 ****
  		{
  		  relocation = howto->pc_relative ? outrel.r_offset : 0;
  		  addend = 0;
- 		  break;
  		}
  	    }
  	  break;
--- 6555,6560 ----
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.154
diff -c -3 -p -r1.154 elf32-sh.c
*** bfd/elf32-sh.c	8 Nov 2007 13:51:06 -0000	1.154
--- bfd/elf32-sh.c	12 Nov 2007 18:26:20 -0000
*************** sh_elf_relocate_section (bfd *output_bfd
*** 3167,3172 ****
--- 3167,3173 ----
    asection *splt;
    asection *sreloc;
    asection *srelgot;
+   bfd_boolean is_vxworks_tls;
  
    htab = sh_elf_hash_table (info);
    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
*************** sh_elf_relocate_section (bfd *output_bfd
*** 3180,3185 ****
--- 3181,3192 ----
    sreloc = NULL;
    srelgot = NULL;
  
+   /* We have to handle relocations in vxworks .tls_vars sections
+      specially, because the dynamic loader is 'weird'.  */
+   is_vxworks_tls = (htab->vxworks_p && info->shared
+ 		    && !strcmp (input_section->output_section->name,
+ 				".tls_vars"));
+ 
    rel = relocs;
    relend = relocs + input_section->reloc_count;
    for (; rel < relend; rel++)
*************** sh_elf_relocate_section (bfd *output_bfd
*** 3631,3636 ****
--- 3638,3649 ----
  
  	      if (skip)
  		memset (&outrel, 0, sizeof outrel);
+ 	      else if (is_vxworks_tls)
+ 		{
+ 		  outrel.r_info = ELF32_R_INFO (0, R_SH_NONE);
+ 		  outrel.r_addend = relocation;
+ 		  relocate = TRUE;
+ 		}
  	      else if (r_type == R_SH_REL32)
  		{
  		  BFD_ASSERT (h != NULL && h->dynindx != -1);
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.219
diff -c -3 -p -r1.219 elfxx-mips.c
*** bfd/elfxx-mips.c	8 Nov 2007 13:51:06 -0000	1.219
--- bfd/elfxx-mips.c	12 Nov 2007 18:26:30 -0000
*************** mips_elf_create_dynamic_relocation (bfd 
*** 4871,4878 ****
      *addendp += symbol;
  
    if (htab->is_vxworks)
!     /* VxWorks uses non-relative relocations for this.  */
!     outrel[0].r_info = ELF32_R_INFO (indx, R_MIPS_32);
    else
      /* The relocation is always an REL32 relocation because we don't
         know where the shared library will wind up at load-time.  */
--- 4871,4892 ----
      *addendp += symbol;
  
    if (htab->is_vxworks)
!     {
!       if (info->shared
! 	  && !strcmp (input_section->output_section->name, ".tls_vars"))
! 	{
! 	  /* We have to handle relocations in vxworks .tls_vars sections
! 	     specially, because the dynamic loader is 'weird'.  */
! 	  outrel[0].r_info = ELF32_R_INFO (0, R_MIPS_NONE);
! 	  outrel[0].r_addend = 0;
! 	}
!       else
! 	{
! 	  /* VxWorks uses non-relative relocations for this.  */
! 	  outrel[0].r_info = ELF32_R_INFO (indx, R_MIPS_32);
! 	  outrel[0].r_addend = *addendp;
! 	}
!     }
    else
      /* The relocation is always an REL32 relocation because we don't
         know where the shared library will wind up at load-time.  */
*************** mips_elf_create_dynamic_relocation (bfd 
*** 4919,4925 ****
    else if (htab->is_vxworks)
      {
        /* VxWorks uses RELA rather than REL dynamic relocations.  */
-       outrel[0].r_addend = *addendp;
        bfd_elf32_swap_reloca_out
  	(output_bfd, &outrel[0],
  	 (sreloc->contents
--- 4933,4938 ----
*************** _bfd_mips_elf_relocate_section (bfd *out
*** 7740,7745 ****
--- 7753,7759 ----
    const struct elf_backend_data *bed;
  
    bed = get_elf_backend_data (output_bfd);
+ 
    relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
    for (rel = relocs; rel < relend; ++rel)
      {
*************** _bfd_mips_elf_relocate_section (bfd *out
*** 8145,8151 ****
  					 contents, require_jalx))
  	return FALSE;
      }
- 
    return TRUE;
  }
  
--- 8159,8164 ----
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.36
diff -c -3 -p -r1.36 elfxx-sparc.c
*** bfd/elfxx-sparc.c	8 Nov 2007 13:51:06 -0000	1.36
--- bfd/elfxx-sparc.c	12 Nov 2007 18:26:35 -0000
*************** _bfd_sparc_elf_relocate_section (bfd *ou
*** 2481,2486 ****
--- 2481,2487 ----
    Elf_Internal_Rela *rel;
    Elf_Internal_Rela *relend;
    int num_relocs;
+   bfd_boolean is_vxworks_tls;
  
    htab = _bfd_sparc_elf_hash_table (info);
    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
*************** _bfd_sparc_elf_relocate_section (bfd *ou
*** 2494,2499 ****
--- 2495,2506 ----
  
    sreloc = elf_section_data (input_section)->sreloc;
  
+   /* We have to handle relocations in vxworks .tls_vars sections
+      specially, because the dynamic loader is 'weird'.  */
+   is_vxworks_tls = (htab->is_vxworks && info->shared
+ 		    && !strcmp (input_section->output_section->name,
+ 				".tls_vars"));
+ 
    rel = relocs;
    if (ABI_64_P (output_bfd))
      num_relocs = NUM_SHDR_ENTRIES (& elf_section_data (input_section)->rel_hdr);
*************** _bfd_sparc_elf_relocate_section (bfd *ou
*** 2845,2850 ****
--- 2852,2863 ----
  
  	      if (skip)
  		memset (&outrel, 0, sizeof outrel);
+ 	      else if (is_vxworks_tls)
+ 		{
+ 		  outrel.r_info = ELF32_R_INFO (0, R_SPARC_NONE);
+ 		  outrel.r_addend = relocation;
+ 		  relocate = TRUE;
+ 		}
  	      /* h->dynindx may be -1 if the symbol was marked to
  		 become local.  */
  	      else if (h != NULL && ! is_plt
Index: ld/testsuite/ld-vxworks/tls-3.d
===================================================================
RCS file: ld/testsuite/ld-vxworks/tls-3.d
diff -N ld/testsuite/ld-vxworks/tls-3.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-vxworks/tls-3.d	12 Nov 2007 18:26:42 -0000
***************
*** 0 ****
--- 1,9 ----
+ # source: tls-3.s
+ # ld: -shared -z now
+ # objdump: -R
+ 
+ #...
+ DYNAMIC RELOCATION RECORDS
+ OFFSET.*
+ [0-9a-f]+ R_[A-Z0-9]+_NONE *\*ABS\*(\+0x[0-9a-f]+)?
+ 
Index: ld/testsuite/ld-vxworks/tls-3.s
===================================================================
RCS file: ld/testsuite/ld-vxworks/tls-3.s
diff -N ld/testsuite/ld-vxworks/tls-3.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-vxworks/tls-3.s	12 Nov 2007 18:26:42 -0000
***************
*** 0 ****
--- 1,19 ----
+ 	.globl	foo
+ foo:
+ 
+ 	.section	.tls_data,"a"
+ 	.p2align	2
+ 	.type	i,%object
+ 	.size	i,4
+ i:
+ 	.space	4
+ 	.globl	__tls__i
+ 	.section	.tls_vars,"a"
+ 	.p2align	2
+ 	.type	__tls__i,%object
+ 	.size	__tls__i,12
+ __tls__i:
+ 	.4byte	i
+ 	.4byte	0
+ 	.4byte	4
+ 

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