* 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).