From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21414 invoked by alias); 13 Nov 2007 12:47:55 -0000 Received: (qmail 21404 invoked by uid 22791); 13 Nov 2007 12:47:53 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 13 Nov 2007 12:47:43 +0000 Received: (qmail 13957 invoked from network); 13 Nov 2007 12:47:41 -0000 Received: from unknown (HELO ?192.168.44.101?) (nathan@127.0.0.2) by mail.codesourcery.com with ESMTPA; 13 Nov 2007 12:47:41 -0000 Message-ID: <47399CE5.4070902@codesourcery.com> Date: Tue, 13 Nov 2007 12:47:00 -0000 From: Nathan Sidwell User-Agent: Thunderbird 1.5.0.14pre (X11/20071023) MIME-Version: 1.0 To: binutils Subject: vxworks dynamic tls relocs Content-Type: multipart/mixed; boundary="------------050101070302040407060100" Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2007-11/txt/msg00134.txt.bz2 This is a multi-part message in MIME format. --------------050101070302040407060100 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1230 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 --------------050101070302040407060100 Content-Type: text/x-patch; name="tls-dynrelocs.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="tls-dynrelocs.patch" Content-length: 11473 2007-11-13 Nathan Sidwell 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 + --------------050101070302040407060100--