From patchwork Mon May 23 17:22:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rainer Orth X-Patchwork-Id: 97017 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D9822B6FB3 for ; Tue, 24 May 2011 03:22:27 +1000 (EST) Received: (qmail 17171 invoked by alias); 23 May 2011 17:22:24 -0000 Received: (qmail 17159 invoked by uid 22791); 23 May 2011 17:22:22 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from snape.CeBiTec.Uni-Bielefeld.DE (HELO smtp-relay.CeBiTec.Uni-Bielefeld.DE) (129.70.160.84) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 23 May 2011 17:22:07 +0000 Received: from localhost (localhost.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) by smtp-relay.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTP id 87A77DB7; Mon, 23 May 2011 19:22:05 +0200 (CEST) Received: from smtp-relay.CeBiTec.Uni-Bielefeld.DE ([127.0.0.1]) by localhost (malfoy.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 0-TxBexWR9tq; Mon, 23 May 2011 19:22:00 +0200 (CEST) Received: from manam.CeBiTec.Uni-Bielefeld.DE (manam.CeBiTec.Uni-Bielefeld.DE [129.70.161.120]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp-relay.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTPS id D8AE9DB6; Mon, 23 May 2011 19:22:00 +0200 (CEST) Received: (from ro@localhost) by manam.CeBiTec.Uni-Bielefeld.DE (8.14.4+Sun/8.14.4/Submit) id p4NHM0TD015845; Mon, 23 May 2011 19:22:00 +0200 (MEST) From: Rainer Orth To: gcc-patches@gcc.gnu.org Cc: Uros Bizjak Subject: [build] Fix Solaris 2/x86 GD/LD TLS code sequences with Sun ld Date: Mon, 23 May 2011 19:22:00 +0200 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (usg-unix-v) MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org As described in [testsuite] Provide TLS access model testcases http://gcc.gnu.org/ml/gcc-patches/2011-05/msg01601.html both the 32 and 64-bit TLS GD and LD execution tests fail on Solaris 2 with Sun ld unless you have a very recent Solaris 11 version (snv_164). This happens because the code sequences emitted by GCC don't match those expected by Sun ld: 32-bit x86: Thread-Local Variable Access http://download.oracle.com/docs/cd/E19963-01/html/819-0690/chapter8-20.html#gentextid-20367 For GD, one needs to use call x@tlsgdplt here, but call ___tls_get_addr@plt works, too. For LD, one really needs call x@tlsldmplt. The corresponding R_386_TLS_GD_PLT and R_386_TLS_LDM_PLT relocations are not yet handled by binutils. x64: Thread-Local Variable Access http://download.oracle.com/docs/cd/E19963-01/html/819-0690/chapter8-20.html#chapter8-60 For both GD and LD, one needs to use call __tls_get_addr@plt. The following patch handles this: * It autoconfigures support for the @tlsgdplt and @tlsldmplt relocations: Sun as supports them, while gas doesn't yet. I've got a patch in the works to fix this: while the gas part is easy, I have serious problems getting the ld side to work properly. Unfortunately, I doubt the binutils maintainers will accept such partial support for the relocs. * I'm using a new 'p' code to control the printing of @plt. 'P' doesn't work since this is needed in both PIC and non-PIC code. Bootstrapped without regressions on i386-pc-solaris2.10. Ok for mainline? Rainer 2010-12-30 Rainer Orth * configure.ac (gcc_cv_as_ix86_tlsgdplt): Check for @tlsgdplt (HAVE_AS_IX86_TLSGDPTL): Define. (gcc_cv_as_ix86_tlsldmplt): Check for @tlsldmplt. (HAVE_AS_IX86_TLSLDMPLT): Define. * configure: Regenerate. * config.in: Regenerate. * config/i386/i386.c (output_pic_addr_const): Handle code 'p' like 'P'. (ix86_print_operand): Handle code 'p'. * config/i386/i386.md (*tls_global_dynamic_32_gnu): Use @tlsgdplt if TARGET_SUN_TLS && HAVE_AS_IX86_TLSGDPLT. Use 'p' code. (*tls_global_dynamic_64): Use 'p' code. (*tls_local_dynamic_base_32_gnu): Use @tlsldmplt if TARGET_SUN_TLS && HAVE_AS_IX86_TLSLDMPLT. Use 'p' code. (*tls_local_dynamic_base_64): Use 'p' code. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13209,7 +13209,7 @@ output_pic_addr_const (FILE *file, rtx x assemble_name (file, name); } if (!TARGET_MACHO && !(TARGET_64BIT && DEFAULT_ABI == MS_ABI) - && code == 'P' && ! SYMBOL_REF_LOCAL_P (x)) + && (code == 'P' || code == 'p') && ! SYMBOL_REF_LOCAL_P (x)) fputs ("@PLT", file); break; @@ -13917,6 +13917,7 @@ get_some_local_dynamic_name (void) d -- print duplicated register operand for AVX instruction. D -- print condition for SSE cmp instruction. P -- if PIC, print an @PLT suffix. + p -- print an @PLT suffix for Sun ld. X -- don't print any sort of PIC '@' suffix for a symbol. & -- print some in-use local-dynamic symbol name. H -- print a memory address offset by 8; used for sse high-parts @@ -14122,6 +14123,7 @@ ix86_print_operand (FILE *file, rtx x, i case 'x': case 'X': case 'P': + case 'p': break; case 's': @@ -14426,7 +14428,8 @@ ix86_print_operand (FILE *file, rtx x, i else if (MEM_P (x)) { /* No `byte ptr' prefix for call instructions or BLKmode operands. */ - if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P' + if (ASSEMBLER_DIALECT == ASM_INTEL + && code != 'X' && code != 'P' && code != 'p' && GET_MODE (x) != BLKmode) { const char * size; @@ -14462,9 +14465,13 @@ ix86_print_operand (FILE *file, rtx x, i x = XEXP (x, 0); /* Avoid (%rip) for call operands. */ - if (CONSTANT_ADDRESS_P (x) && code == 'P' + if (CONSTANT_ADDRESS_P (x) && (code == 'P' || code == 'p') && !CONST_INT_P (x)) - output_addr_const (file, x); + { + output_addr_const (file, x); + if (code == 'p' && TARGET_SUN_TLS) + fputs ("@PLT", file); + } else if (this_is_asm_operands && ! address_operand (x, VOIDmode)) output_operand_lossage ("invalid constraints for operand"); else @@ -14521,7 +14528,7 @@ ix86_print_operand (FILE *file, rtx x, i x = const0_rtx; } - if (code != 'P') + if (code != 'P' && code != 'p') { if (CONST_INT_P (x) || GET_CODE (x) == CONST_DOUBLE) { @@ -14542,7 +14549,11 @@ ix86_print_operand (FILE *file, rtx x, i else if (flag_pic || MACHOPIC_INDIRECT) output_pic_addr_const (file, x, code); else - output_addr_const (file, x); + { + output_addr_const (file, x); + if (code == 'p' && TARGET_SUN_TLS) + fputs ("@PLT", file); + } } } diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -53,6 +53,7 @@ ;; d -- print duplicated register operand for AVX instruction. ;; D -- print condition for SSE cmp instruction. ;; P -- if PIC, print an @PLT suffix. +;; p -- if Sun ld, print an @PLT suffix. ;; X -- don't print any sort of PIC '@' suffix for a symbol. ;; & -- print some in-use local-dynamic symbol name. ;; H -- print a memory address offset by 8; used for sse high-parts @@ -12367,7 +12368,10 @@ { output_asm_insn ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands); - return "call\t%P3"; + if (TARGET_SUN_TLS && HAVE_AS_IX86_TLSGDPLT) + return "call\t%a2@tlsgdplt"; + else + return "call\t%p3"; } [(set_attr "type" "multi") (set_attr "length" "12")]) @@ -12397,7 +12401,7 @@ ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands); fputs (ASM_SHORT "0x6666\n", asm_out_file); fputs ("\trex64\n", asm_out_file); - return "call\t%P2"; + return "call\t%p2"; } [(set_attr "type" "multi") (set_attr "length" "16")]) @@ -12424,7 +12428,10 @@ { output_asm_insn ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); - return "call\t%P2"; + if (TARGET_SUN_TLS && HAVE_AS_IX86_TLSLDMPLT) + return "call\t%&@tlsldmplt"; + else + return "call\t%p2"; } [(set_attr "type" "multi") (set_attr "length" "11")]) @@ -12450,7 +12457,7 @@ { output_asm_insn ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); - return "call\t%P1"; + return "call\t%p1"; } [(set_attr "type" "multi") (set_attr "length" "12")]) diff --git a/gcc/configure.ac b/gcc/configure.ac --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3653,6 +3653,20 @@ foo: nop [AC_DEFINE(HAVE_AS_IX86_REP_LOCK_PREFIX, 1, [Define if the assembler supports 'rep , lock '.])]) + gcc_GAS_CHECK_FEATURE([R_386_TLS_GD_PLT reloc], + gcc_cv_as_ix86_tlsgdplt,,, + [call tls_gd@tlsgdplt]) + AC_DEFINE_UNQUOTED(HAVE_AS_IX86_TLSGDPLT, + [`if test $gcc_cv_as_ix86_tlsgdplt = yes; then echo 1; else echo 0; fi`], + [Define 0/1 if your assembler supports @tlsgdplt.]) + + gcc_GAS_CHECK_FEATURE([R_386_TLS_LDM_PLT reloc], + gcc_cv_as_ix86_tlsldmplt,,, + [call tls_ld@tlsldmplt]) + AC_DEFINE_UNQUOTED(HAVE_AS_IX86_TLSLDMPLT, + [`if test $gcc_cv_as_ix86_tlsldmplt = yes; then echo 1; else echo 0; fi`], + [Define 0/1 if your assembler supports @tlsldmplt.]) + ;; ia64*-*-*)