This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: Support TLS with Sun as on Solaris 2/x86
- From: Rainer Orth <ro at CeBiTec dot Uni-Bielefeld dot DE>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 15 Mar 2010 20:47:13 +0100
- Subject: Re: PATCH: Support TLS with Sun as on Solaris 2/x86
- References: <yddy6iik808.fsf@CeBiTec.Uni-Bielefeld.DE>
Apart from Ralf's helpful hint about the use of changequote, this patch
hasn't seen any review in three weeks:
http://gcc.gnu.org/ml/gcc-patches/2010-02/msg00999.html
Since the original submission, I've made a few minor changes:
* The current uses of TARGET_SUN_TLS and support for the Sun TLS dialect
has been moved to different patch which needs TARGET_SUN_TLS with a
new meaning:
http://gcc.gnu.org/ml/gcc-patches/2010-03/msg00614.html
* With proper use of changequote, AC_DEFINE(TLS_SECTION_ASM_FLAG) could
be moved where it belongs.
Otherwise, it's unchanged and still passes testing on
i386-pc-solaris2.11 with Sun as and gas.
Ok for mainline now?
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
2010-02-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
gcc:
* configure.ac (i[34567]86-*-*): Handle Solaris 2/x86 TLS support
and Sun as TLS syntax.
(TLS_SECTION_ASM_FLAG) [on_solaris && !gas_flag]: Define.
* configure: Regenerate.
* config.in: Regenerate.
* varasm.c (TLS_SECTION_ASM_FLAG): Define default.
(default_elf_asm_named_section): Use it.
* config/i386/i386.c (output_pic_addr_const): Lowercase @DTPOFF.
(i386_output_dwarf_dtprel): Likewise.
(output_addr_const_extra): Likewise.
(output_pic_addr_const): Lowercase @GOTTPOFF.
(output_addr_const_extra): Likewise.
(output_pic_addr_const): Lowercase @GOTNTPOFF.
(output_addr_const_extra): Likewise.
(output_pic_addr_const): Lowercase @INDNTPOFF.
(output_addr_const_extra): Likewise.
(output_pic_addr_const): Lowercase @NTPOFF.
(output_addr_const_extra): Likewise.
(output_pic_addr_const): Lowercase @TPOFF.
(output_addr_const_extra): Likewise.
* config/i386/i386.md (*tls_global_dynamic_32_gnu): Lowercase
@TLSGD.
(*tls_global_dynamic_64): Likewise.
(*tls_local_dynamic_base_32_gnu): Lowercase @TLSLDM.
(*tls_local_dynamic_base_64): Lowercase @TLSLD.
* defaults.h (TLS_COMMON_ASM_OP): Provide default.
(ASM_OUTPUT_TLS_COMMON): Use it.
* config/i386/sol2-gas.h (TLS_COMMON_ASM_OP): Undef.
PR target/38118
* config/sparc/sol2.h (ASM_OUTPUT_ALIGNED_COMMON): Move ...
* config/sol2.h (ASM_OUTPUT_ALIGNED_COMMON): ... here.
* config/i386/sol2-10.h (ASM_OUTPUT_ALIGNED_COMMON): Redefine.
* config/i386/sol2.h (TARGET_SUN_TLS): Redefine.
(ASM_DECLARE_OBJECT_NAME) [!USE_GAS]: Redefine.
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/config/i386/i386.c Mon Mar 15 20:37:42 2010 +0100
@@ -10861,29 +10861,29 @@
break;
case UNSPEC_GOTTPOFF:
/* FIXME: This might be @TPOFF in Sun ld too. */
- fputs ("@GOTTPOFF", file);
+ fputs ("@gottpoff", file);
break;
case UNSPEC_TPOFF:
- fputs ("@TPOFF", file);
+ fputs ("@tpoff", file);
break;
case UNSPEC_NTPOFF:
if (TARGET_64BIT)
- fputs ("@TPOFF", file);
- else
- fputs ("@NTPOFF", file);
+ fputs ("@tpoff", file);
+ else
+ fputs ("@ntpoff", file);
break;
case UNSPEC_DTPOFF:
- fputs ("@DTPOFF", file);
+ fputs ("@dtpoff", file);
break;
case UNSPEC_GOTNTPOFF:
if (TARGET_64BIT)
fputs (ASSEMBLER_DIALECT == ASM_ATT ?
- "@GOTTPOFF(%rip)": "@GOTTPOFF[rip]", file);
- else
- fputs ("@GOTNTPOFF", file);
+ "@gottpoff(%rip)": "@gottpoff[rip]", file);
+ else
+ fputs ("@gotntpoff", file);
break;
case UNSPEC_INDNTPOFF:
- fputs ("@INDNTPOFF", file);
+ fputs ("@indntpoff", file);
break;
#if TARGET_MACHO
case UNSPEC_MACHOPIC_OFFSET:
@@ -10910,7 +10910,7 @@
{
fputs (ASM_LONG, file);
output_addr_const (file, x);
- fputs ("@DTPOFF", file);
+ fputs ("@dtpoff", file);
switch (size)
{
case 4:
@@ -12187,34 +12187,34 @@
case UNSPEC_GOTTPOFF:
output_addr_const (file, op);
/* FIXME: This might be @TPOFF in Sun ld. */
- fputs ("@GOTTPOFF", file);
+ fputs ("@gottpoff", file);
break;
case UNSPEC_TPOFF:
output_addr_const (file, op);
- fputs ("@TPOFF", file);
+ fputs ("@tpoff", file);
break;
case UNSPEC_NTPOFF:
output_addr_const (file, op);
if (TARGET_64BIT)
- fputs ("@TPOFF", file);
- else
- fputs ("@NTPOFF", file);
+ fputs ("@tpoff", file);
+ else
+ fputs ("@ntpoff", file);
break;
case UNSPEC_DTPOFF:
output_addr_const (file, op);
- fputs ("@DTPOFF", file);
+ fputs ("@dtpoff", file);
break;
case UNSPEC_GOTNTPOFF:
output_addr_const (file, op);
if (TARGET_64BIT)
fputs (ASSEMBLER_DIALECT == ASM_ATT ?
- "@GOTTPOFF(%rip)" : "@GOTTPOFF[rip]", file);
- else
- fputs ("@GOTNTPOFF", file);
+ "@gottpoff(%rip)" : "@gottpoff[rip]", file);
+ else
+ fputs ("@gotntpoff", file);
break;
case UNSPEC_INDNTPOFF:
output_addr_const (file, op);
- fputs ("@INDNTPOFF", file);
+ fputs ("@indntpoff", file);
break;
#if TARGET_MACHO
case UNSPEC_MACHOPIC_OFFSET:
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/config/i386/i386.md
--- a/gcc/config/i386/i386.md Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/config/i386/i386.md Mon Mar 15 20:37:42 2010 +0100
@@ -14521,7 +14521,7 @@
(clobber (match_scratch:SI 5 "=c"))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_GNU_TLS"
- "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
+ "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
[(set_attr "type" "multi")
(set_attr "length" "12")])
@@ -14560,7 +14560,7 @@
(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
UNSPEC_TLS_GD)]
"TARGET_64BIT"
- { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
+ { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
[(set_attr "type" "multi")
(set_attr "length" "16")])
@@ -14589,7 +14589,7 @@
(clobber (match_scratch:SI 4 "=c"))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_GNU_TLS"
- "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
+ "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
[(set_attr "type" "multi")
(set_attr "length" "11")])
@@ -14624,7 +14624,7 @@
(match_operand:DI 2 "" "")))
(unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
"TARGET_64BIT"
- "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
+ "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
[(set_attr "type" "multi")
(set_attr "length" "12")])
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/config/i386/sol2-10.h
--- a/gcc/config/i386/sol2-10.h Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/config/i386/sol2-10.h Mon Mar 15 20:37:42 2010 +0100
@@ -50,6 +50,21 @@
} while (0)
#endif
+/* As in sol2.h, override the default from i386/x86-64.h to work around
+ Sun as TLS bug. */
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+ do \
+ { \
+ if (TARGET_SUN_TLS \
+ && in_section \
+ && ((in_section->common.flags & (SECTION_TLS | SECTION_BSS)) \
+ == (SECTION_TLS | SECTION_BSS))) \
+ switch_to_section (bss_section); \
+ x86_elf_aligned_common (FILE, NAME, SIZE, ALIGN); \
+ } \
+ while (0)
+
#undef NO_PROFILE_COUNTERS
#undef MCOUNT_NAME
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/config/i386/sol2-gas.h
--- a/gcc/config/i386/sol2-gas.h Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/config/i386/sol2-gas.h Mon Mar 15 20:37:42 2010 +0100
@@ -26,3 +26,6 @@
/* Undefine this so that BNSYM/ENSYM pairs are emitted by STABS+. */
#undef NO_DBX_BNSYM_ENSYM
+
+/* Restore default; gas doesn't understand Sun as .tcomm. */
+#undef TLS_COMMON_ASM_OP
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/config/i386/sol2.h
--- a/gcc/config/i386/sol2.h Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/config/i386/sol2.h Mon Mar 15 20:37:42 2010 +0100
@@ -96,6 +96,43 @@
#undef TARGET_SUN_TLS
#define TARGET_SUN_TLS 1
+/* Follow Sun requirements for TLS code sequences and use Sun assembler TLS
+ syntax. */
+#undef TARGET_SUN_TLS
+#define TARGET_SUN_TLS 1
+
+/* The Sun assembler uses .tcomm for TLS common sections. */
+#define TLS_COMMON_ASM_OP ".tcomm"
+
+/* Similar to the Sun assembler on SPARC, the native assembler requires
+ TLS objects to be declared as @tls_obj (not @tls_object). Unlike SPARC,
+ gas doesn't understand this variant. */
+#ifndef USE_GAS
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ HOST_WIDE_INT size; \
+ \
+ if (targetm.have_tls && DECL_THREAD_LOCAL_P (DECL)) \
+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "tls_obj"); \
+ else \
+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
+ \
+ size_directive_output = 0; \
+ if (!flag_inhibit_size_directive \
+ && (DECL) && DECL_SIZE (DECL)) \
+ { \
+ size_directive_output = 1; \
+ size = int_size_in_bytes (TREE_TYPE (DECL)); \
+ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
+ } \
+ \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ } \
+ while (0)
+#endif
+
/* The Solaris assembler cannot grok .stabd directives. */
#undef NO_DBX_BNSYM_ENSYM
#define NO_DBX_BNSYM_ENSYM 1
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/config/sol2.h
--- a/gcc/config/sol2.h Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/config/sol2.h Mon Mar 15 20:37:42 2010 +0100
@@ -1,6 +1,7 @@
/* Operating system specific defines to be used when targeting GCC for any
Solaris 2 system.
- Copyright 2002, 2003, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -265,6 +266,24 @@
} \
while (0)
+/* Solaris 'as' has a bug: a .common directive in .tbss section
+ behaves as .tls_common rather than normal non-TLS .common. */
+#undef ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
+ do \
+ { \
+ if (TARGET_SUN_TLS \
+ && in_section \
+ && ((in_section->common.flags & (SECTION_TLS | SECTION_BSS)) \
+ == (SECTION_TLS | SECTION_BSS))) \
+ switch_to_section (bss_section); \
+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
+ assemble_name ((FILE), (NAME)); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
+ (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ } \
+ while (0)
+
extern GTY(()) tree solaris_pending_aligns;
extern GTY(()) tree solaris_pending_inits;
extern GTY(()) tree solaris_pending_finis;
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/config/sparc/sol2.h
--- a/gcc/config/sparc/sol2.h Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/config/sparc/sol2.h Mon Mar 15 20:37:42 2010 +0100
@@ -177,24 +177,6 @@
} \
while (0)
-/* Solaris 'as' has a bug: a .common directive in .tbss section
- behaves as .tls_common rather than normal non-TLS .common. */
-#undef ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
- do \
- { \
- if (TARGET_SUN_TLS \
- && in_section \
- && ((in_section->common.flags & (SECTION_TLS | SECTION_BSS)) \
- == (SECTION_TLS | SECTION_BSS))) \
- switch_to_section (bss_section); \
- fprintf ((FILE), "%s", COMMON_ASM_OP); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
- (SIZE), (ALIGN) / BITS_PER_UNIT); \
- } \
- while (0)
-
/* Use Solaris ELF section syntax. */
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION sparc_solaris_elf_asm_named_section
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/configure.ac
--- a/gcc/configure.ac Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/configure.ac Mon Mar 15 20:37:42 2010 +0100
@@ -2,7 +2,7 @@
# Process this file with autoconf to generate a configuration script.
# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-# 2007, 2008, 2009 Free Software Foundation, Inc.
+# 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
#This file is part of GCC.
@@ -2573,25 +2573,54 @@
tls_first_minor=17
;;
i[34567]86-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
+ case "$target" in
+ i[34567]86-*-solaris2.[56789]*)
+ # TLS was introduced in the Solaris 9 4/04 release but
+ # we do not enable it by default on Solaris 9 either.
+ if test "x$enable_tls" = xyes ; then
+ on_solaris=yes
+ else
+ enable_tls=no;
+ fi
+ ;;
+ i[34567]86-*-solaris2.*)
+ on_solaris=yes
+ ;;
+ *)
+ on_solaris=no
+ ;;
+ esac
+ if test x$on_solaris = xyes && test x$gas_flag = xno; then
+ conftest_s='
+ .section .tdata,"awt",@progbits'
+ tls_first_major=0
+ tls_first_minor=0
+changequote([,])dnl
+ AC_DEFINE(TLS_SECTION_ASM_FLAG, 't',
+[Define to the flag used to mark TLS sections if the default (`T') doesn't work.])
+changequote(,)dnl
+ else
+ conftest_s='
+ .section ".tdata","awT",@progbits'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="--fatal-warnings"
+ fi
+ conftest_s="$conftest_s
foo: .long 25
.text
movl %gs:0, %eax
- leal foo@TLSGD(,%ebx,1), %eax
- leal foo@TLSLDM(%ebx), %eax
- leal foo@DTPOFF(%eax), %edx
- movl foo@GOTTPOFF(%ebx), %eax
- subl foo@GOTTPOFF(%ebx), %eax
- addl foo@GOTNTPOFF(%ebx), %eax
- movl foo@INDNTPOFF, %eax
- movl $foo@TPOFF, %eax
- subl $foo@TPOFF, %eax
- leal foo@NTPOFF(%ecx), %eax'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt=--fatal-warnings
- ;;
+ leal foo@tlsgd(,%ebx,1), %eax
+ leal foo@tlsldm(%ebx), %eax
+ leal foo@dtpoff(%eax), %edx
+ movl foo@gottpoff(%ebx), %eax
+ subl foo@gottpoff(%ebx), %eax
+ addl foo@gotntpoff(%ebx), %eax
+ movl foo@indntpoff, %eax
+ movl \$foo@tpoff, %eax
+ subl \$foo@tpoff, %eax
+ leal foo@ntpoff(%ecx), %eax"
+ ;;
x86_64-*-*)
conftest_s='
.section ".tdata","awT",@progbits
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/defaults.h
--- a/gcc/defaults.h Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/defaults.h Mon Mar 15 20:37:42 2010 +0100
@@ -1,6 +1,6 @@
/* Definitions of various defaults for tm.h macros.
Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2007, 2008, 2009
+ 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com)
@@ -118,11 +118,15 @@
#endif
#endif
+#ifndef TLS_COMMON_ASM_OP
+#define TLS_COMMON_ASM_OP ".tls_common"
+#endif
+
#if defined (HAVE_AS_TLS) && !defined (ASM_OUTPUT_TLS_COMMON)
#define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE) \
do \
{ \
- fprintf ((FILE), "\t.tls_common\t"); \
+ fprintf ((FILE), "\t%s\t", TLS_COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
(SIZE), DECL_ALIGN (DECL) / BITS_PER_UNIT); \
diff -r 23c3eb7bf33a -r 691312c2b30c gcc/varasm.c
--- a/gcc/varasm.c Mon Mar 15 20:37:41 2010 +0100
+++ b/gcc/varasm.c Mon Mar 15 20:37:42 2010 +0100
@@ -6031,6 +6031,10 @@
gcc_unreachable ();
}
+#ifndef TLS_SECTION_ASM_FLAG
+#define TLS_SECTION_ASM_FLAG 'T'
+#endif
+
void
default_elf_asm_named_section (const char *name, unsigned int flags,
tree decl ATTRIBUTE_UNUSED)
@@ -6061,7 +6065,7 @@
if (flags & SECTION_STRINGS)
*f++ = 'S';
if (flags & SECTION_TLS)
- *f++ = 'T';
+ *f++ = TLS_SECTION_ASM_FLAG;
if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
*f++ = 'G';
*f = '\0';