This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
vxworks tls
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sources dot redhat dot com>
- Cc: Alan Modra <amodra at bigpond dot net dot au>
- Date: Mon, 24 Mar 2008 17:42:50 +0000
- Subject: vxworks tls
Alan,
sorry for the long delay on this. Here's an update of my attempt at eliding
dynamic relocations from vxworks .tls_vars sections. Your suggestion appears to
be good, and this implements it for arm, i86, sh, powerpc and sparc. MIPS is
somewhat different and I've not figured out how to apply the changes there yet.
I thought I'd better get this bit posted for review first.
To remind you, the vxworks dynamic loader knows what .tls_vars sections look
like, and gets confused if regular relocs are present.
ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
2008-03-24 Nathan Sidwell <nathan@codesourcery.com>
bfd/
* elf32-arm.c (elf32_arm_final_link_relocate): Skip dynamic relocs
in vxworks tls_vars sections.
(allocate_dynrelocs, elf32_arm_size_dynamic_sections): Likewise.
* elf32-i386.c (allocate_dynrelocs,
elf_i386_size_dynamic_sections, elf_i386_relocate_section): Likewise.
* elf32-ppc.c (allocate_dynrelocs, ppc_elf_size_dynamic_sections,
ppc_elf_relocate_section): Likewise.
* elf32-sh.c (allocate_dynrelocs, sh_elf_size_dynamic_sections,
sh_elf_relocate_section): Likewise.
* elfxx-sparc.c (allocate_dynrelocs,
_bfd_sparc_elf_size_dynamic_sections,
_bfd_sparc_elf_relocate_section): Likewise.
ld/testsuite/
* ld-vxworks/tls-3.s: New.
* ld-vxworks/tls-3.d: New.
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.140
diff -c -3 -p -r1.140 elf32-arm.c
*** bfd/elf32-arm.c 12 Mar 2008 08:36:58 -0000 1.140
--- bfd/elf32-arm.c 24 Mar 2008 17:35:02 -0000
*************** elf32_arm_final_link_relocate (reloc_how
*** 4752,4757 ****
--- 4752,4760 ----
run time. */
if ((info->shared || globals->root.is_relocatable_executable)
&& (input_section->flags & SEC_ALLOC)
+ && !(elf32_arm_hash_table (info)->vxworks_p
+ && strcmp (input_section->output_section->name,
+ ".tls_vars") == 0)
&& ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI)
|| !SYMBOL_CALLS_LOCAL (info, h))
&& (h == NULL
*************** allocate_dynrelocs (struct elf_link_hash
*** 8577,8582 ****
--- 8580,8598 ----
}
}
+ if (elf32_arm_hash_table (info)->vxworks_p)
+ {
+ struct elf32_arm_relocs_copied **pp;
+
+ for (pp = &eh->relocs_copied; (p = *pp) != NULL; )
+ {
+ if (strcmp (p->section->output_section->name, ".tls_vars") == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
/* Also discard relocs on undefined weak syms with non-default
visibility. */
if (eh->relocs_copied != NULL
*************** elf32_arm_size_dynamic_sections (bfd * o
*** 8728,8733 ****
--- 8744,8750 ----
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
asection *srel;
+ bfd_boolean is_vxworks = elf32_arm_hash_table (info)->vxworks_p;
if (! is_arm_elf (ibfd))
continue;
*************** elf32_arm_size_dynamic_sections (bfd * o
*** 8746,8751 ****
--- 8763,8775 ----
linker script /DISCARD/, so we'll be discarding
the relocs too. */
}
+ else if (is_vxworks
+ && strcmp (p->section->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
else if (p->count != 0)
{
srel = elf_section_data (p->section)->sreloc;
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.186
diff -c -3 -p -r1.186 elf32-i386.c
*** bfd/elf32-i386.c 16 Mar 2008 22:26:23 -0000 1.186
--- bfd/elf32-i386.c 24 Mar 2008 17:35:06 -0000
*************** allocate_dynrelocs (struct elf_link_hash
*** 2030,2037 ****
}
}
/* Also discard relocs on undefined weak syms with non-default
! visibility. */
if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefweak)
{
--- 2030,2049 ----
}
}
+ if (htab->is_vxworks)
+ {
+ struct elf_i386_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;
+ }
+ }
+
/* Also discard relocs on undefined weak syms with non-default
! visibility. */
if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefweak)
{
*************** elf_i386_size_dynamic_sections (bfd *out
*** 2182,2187 ****
--- 2194,2206 ----
linker script /DISCARD/, so we'll be discarding
the relocs too. */
}
+ else if (htab->is_vxworks
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
else if (p->count != 0)
{
srel = elf_section_data (p->sec)->sreloc;
*************** elf_i386_relocate_section (bfd *output_b
*** 2502,2507 ****
--- 2521,2527 ----
bfd_vma *local_tlsdesc_gotents;
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
+ bfd_boolean is_vxworks_tls;
BFD_ASSERT (is_i386_elf (input_bfd));
*************** elf_i386_relocate_section (bfd *output_b
*** 2510,2515 ****
--- 2530,2540 ----
sym_hashes = elf_sym_hashes (input_bfd);
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;
*************** elf_i386_relocate_section (bfd *output_b
*** 2837,2843 ****
case R_386_32:
case R_386_PC32:
! if ((input_section->flags & SEC_ALLOC) == 0)
break;
if ((info->shared
--- 2862,2869 ----
case R_386_32:
case R_386_PC32:
! if ((input_section->flags & SEC_ALLOC) == 0
! || is_vxworks_tls)
break;
if ((info->shared
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.234
diff -c -3 -p -r1.234 elf32-ppc.c
*** bfd/elf32-ppc.c 2 Mar 2008 22:15:39 -0000 1.234
--- bfd/elf32-ppc.c 24 Mar 2008 17:35:11 -0000
*************** allocate_dynrelocs (struct elf_link_hash
*** 4811,4816 ****
--- 4811,4829 ----
}
}
+ if (htab->is_vxworks)
+ {
+ 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;
+ }
+ }
+
/* Discard relocs on undefined symbols that must be local. */
if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefined
*************** ppc_elf_size_dynamic_sections (bfd *outp
*** 4962,4967 ****
--- 4975,4987 ----
linker script /DISCARD/, so we'll be discarding
the relocs too. */
}
+ else if (htab->is_vxworks
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
else if (p->count != 0)
{
elf_section_data (p->sec)->sreloc->size
*************** ppc_elf_relocate_section (bfd *output_bf
*** 5800,5805 ****
--- 5820,5826 ----
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
*** 5819,5824 ****
--- 5840,5850 ----
local_got_offsets = elf_local_got_offsets (input_bfd);
symtab_hdr = &elf_symtab_hdr (input_bfd);
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
*** 6461,6467 ****
/* fall through */
dodyn:
! if ((input_section->flags & SEC_ALLOC) == 0)
break;
if ((info->shared
--- 6487,6494 ----
/* fall through */
dodyn:
! if ((input_section->flags & SEC_ALLOC) == 0
! || is_vxworks_tls)
break;
if ((info->shared
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.156
diff -c -3 -p -r1.156 elf32-sh.c
*** bfd/elf32-sh.c 12 Feb 2008 11:32:30 -0000 1.156
--- bfd/elf32-sh.c 24 Mar 2008 17:35:15 -0000
*************** allocate_dynrelocs (struct elf_link_hash
*** 2817,2822 ****
--- 2817,2835 ----
}
}
+ if (htab->vxworks_p)
+ {
+ struct elf_sh_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;
+ }
+ }
+
/* Also discard relocs on undefined weak syms with non-default
visibility. */
if (eh->dyn_relocs != NULL
*************** sh_elf_size_dynamic_sections (bfd *outpu
*** 2977,2982 ****
--- 2990,3002 ----
linker script /DISCARD/, so we'll be discarding
the relocs too. */
}
+ else if (htab->vxworks_p
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
else if (p->count != 0)
{
srel = elf_section_data (p->sec)->sreloc;
*************** sh_elf_relocate_section (bfd *output_bfd
*** 3166,3171 ****
--- 3186,3192 ----
asection *splt;
asection *sreloc;
asection *srelgot;
+ bfd_boolean is_vxworks_tls;
BFD_ASSERT (is_sh_elf (input_bfd));
*************** sh_elf_relocate_section (bfd *output_bfd
*** 3180,3185 ****
--- 3201,3211 ----
splt = htab->splt;
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;
*************** sh_elf_relocate_section (bfd *output_bfd
*** 3586,3591 ****
--- 3612,3618 ----
|| h->root.type != bfd_link_hash_undefweak)
&& r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0
+ && !is_vxworks_tls
&& (r_type == R_SH_DIR32
|| !SYMBOL_CALLS_LOCAL (info, h)))
{
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.38
diff -c -3 -p -r1.38 elfxx-sparc.c
*** bfd/elfxx-sparc.c 12 Feb 2008 11:32:31 -0000 1.38
--- bfd/elfxx-sparc.c 24 Mar 2008 17:35:18 -0000
*************** allocate_dynrelocs (struct elf_link_hash
*** 2016,2021 ****
--- 2016,2034 ----
}
}
+ if (htab->is_vxworks)
+ {
+ struct _bfd_sparc_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;
+ }
+ }
+
/* Also discard relocs on undefined weak syms with non-default
visibility. */
if (eh->dyn_relocs != NULL
*************** _bfd_sparc_elf_size_dynamic_sections (bf
*** 2178,2183 ****
--- 2191,2203 ----
linker script /DISCARD/, so we'll be discarding
the relocs too. */
}
+ else if (htab->is_vxworks
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
else if (p->count != 0)
{
srel = elf_section_data (p->sec)->sreloc;
*************** _bfd_sparc_elf_relocate_section (bfd *ou
*** 2488,2493 ****
--- 2508,2514 ----
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_symtab_hdr (input_bfd);
*************** _bfd_sparc_elf_relocate_section (bfd *ou
*** 2500,2505 ****
--- 2521,2531 ----
got_base = elf_hash_table (info)->hgot->root.u.def.value;
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))
*************** _bfd_sparc_elf_relocate_section (bfd *ou
*** 2766,2772 ****
case R_SPARC_L44:
case R_SPARC_UA64:
r_sparc_plt32:
! if ((input_section->flags & SEC_ALLOC) == 0)
break;
if ((info->shared
--- 2792,2799 ----
case R_SPARC_L44:
case R_SPARC_UA64:
r_sparc_plt32:
! if ((input_section->flags & SEC_ALLOC) == 0
! || is_vxworks_tls)
break;
if ((info->shared
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 24 Mar 2008 17:35:18 -0000
***************
*** 0 ****
--- 1,7 ----
+ # source: tls-3.s
+ # ld: -shared -z now
+ # objdump: -R
+
+ #...
+ DYNAMIC RELOCATION RECORDS \(none\)
+
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 24 Mar 2008 17:35:18 -0000
***************
*** 0 ****
--- 1,34 ----
+ .globl foo
+ foo:
+
+ .section .tls_data,"a"
+ .p2align 2
+
+ .type i,%object
+ .size i,4
+ i:
+ .space 4
+
+ .globl j
+ .type j,%object
+ .size j,4
+ j:
+ .space 4
+
+ .section .tls_vars,"a"
+ .p2align 2
+ .type __tls__i,%object
+ .size __tls__i,12
+ __tls__i:
+ .4byte i
+ .4byte 0
+ .4byte 4
+
+ .globl __tls__j
+ .type __tls__j,%object
+ .size __tls__j,12
+ __tls__j:
+ .4byte j
+ .4byte 0
+ .4byte 4
+