This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
vxworks dynamic tls relocs
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sources dot redhat dot com>
- Date: Tue, 13 Nov 2007 12:47:33 +0000
- Subject: 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
+