public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* vxworks dynamic tls relocs
@ 2007-11-13 12:47 Nathan Sidwell
  2007-11-13 23:39 ` Alan Modra
  0 siblings, 1 reply; 4+ messages in thread
From: Nathan Sidwell @ 2007-11-13 12:47 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1230 bytes --]

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


[-- Attachment #2: tls-dynrelocs.patch --]
[-- Type: text/x-patch, Size: 11473 bytes --]

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;
  }
  \f
--- 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
+ 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: vxworks dynamic tls relocs
  2007-11-13 12:47 vxworks dynamic tls relocs Nathan Sidwell
@ 2007-11-13 23:39 ` Alan Modra
  2007-12-19 16:18   ` Nathan Sidwell
  0 siblings, 1 reply; 4+ messages in thread
From: Alan Modra @ 2007-11-13 23:39 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: binutils

On Tue, Nov 13, 2007 at 12:47:33PM +0000, Nathan Sidwell wrote:
> Nullifying the dynamic reloc seemed the simplest approach to take, rather 
> than change the size of the dynamic reloc section.

It is only marginally more difficult to do this without generating
those NONE relocs.  For example, in elf32-ppc.c allocate_dynrelocs
around line 4802, add

    if (htab->is_vxworks && info->shared)
      {
	struct ppc_elf_dyn_relocs **pp;

	for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
	  {
	    if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
	      *pp = p->next;
	    else
	      pp = &p->next;
	  }
      }

then in ppc_elf_relocate_section change the "dodyn" condition to

	  if ((input_section->flags & SEC_ALLOC) == 0
	      || is_vxworks_tls)
	    break;

Please take a look at doing it this way.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: vxworks dynamic tls relocs
  2007-11-13 23:39 ` Alan Modra
@ 2007-12-19 16:18   ` Nathan Sidwell
  2007-12-22  9:17     ` Alan Modra
  0 siblings, 1 reply; 4+ messages in thread
From: Nathan Sidwell @ 2007-12-19 16:18 UTC (permalink / raw)
  To: Nathan Sidwell, binutils

Alan Modra wrote:
> On Tue, Nov 13, 2007 at 12:47:33PM +0000, Nathan Sidwell wrote:
>> Nullifying the dynamic reloc seemed the simplest approach to take, rather 
>> than change the size of the dynamic reloc section.
> 
> It is only marginally more difficult to do this without generating
> those NONE relocs.  For example, in elf32-ppc.c allocate_dynrelocs
> around line 4802, add
> 
>     if (htab->is_vxworks && info->shared)

sorry for the late followup. I tried your suggestion and it doesn't appear to 
work.  the problem is that location in allocate_dynrelocs is never reached.  We 
exit earlier:
   if (eh->dyn_relocs == NULL)
     return TRUE;

any clues?

nathan

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: vxworks dynamic tls relocs
  2007-12-19 16:18   ` Nathan Sidwell
@ 2007-12-22  9:17     ` Alan Modra
  0 siblings, 0 replies; 4+ messages in thread
From: Alan Modra @ 2007-12-22  9:17 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: binutils

On Wed, Dec 19, 2007 at 04:17:47PM +0000, Nathan Sidwell wrote:
> sorry for the late followup. I tried your suggestion and it doesn't appear 
> to work.  the problem is that location in allocate_dynrelocs is never 
> reached.  We exit earlier:
>   if (eh->dyn_relocs == NULL)
>     return TRUE;

Hmm.  I missed another place that needs to handle .tls_vars specially.
I'm guessing that all your .tls_vars dynamic relocs are on local syms,
and counted via local_dynrel.  You'll need to throw away some relocs
around line 4938 of elf32-ppc.c

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-12-22  9:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-13 12:47 vxworks dynamic tls relocs Nathan Sidwell
2007-11-13 23:39 ` Alan Modra
2007-12-19 16:18   ` Nathan Sidwell
2007-12-22  9:17     ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).