[RFC PATCH, i386]: Introduce address spaces to TLS stack protector guard value

Uros Bizjak ubizjak@gmail.com
Sun Aug 6 18:26:00 GMT 2017


Attached patch generates memory reference to a stack protector guard
value in a TLS block, using the correct address space. This reduces
number of stack protector patterns, since universal patterns are now
able to handle all memory references to stack protector guard value
(global or from TLS block).

2017-08-06  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.c (ix86_stack_protect_guard): Generate
    memory reference to a SSP offset in TLS address space.
    (ix86_print_operand) <case '@'>: Remove.
    (ix86_print_operand_punct_valid_p): Remove '@' code.
    * config/i386/i386.md (stack_tls_protect_set_<mode>): Remove.
    (stack_protect_set): Do not call gen_stack_tls_protect_set_<mode>.
    (stack_tls_protect_test_<mode>): Remove.
    (stack_protect_test): Do not call gen_stack_tls_protect_test_<mode>.

I'll leave patch here for a couple of days for eventual comments.
Hopefully, the memory reference is constructed in the right way.

A follow-up patch will add something like rs6000's
-mstack-protector-guard-offset= option to resolve PR 81708 [1].

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708

Uros.
-------------- next part --------------
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 250900)
+++ config/i386/i386.c	(working copy)
@@ -18624,7 +18624,6 @@ print_reg (rtx x, int code, FILE *file)
    + -- print a branch hint as 'cs' or 'ds' prefix
    ; -- print a semicolon (after prefixes due to bug in older gas).
    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
-   @ -- print a segment register of thread base pointer load
    ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
    ! -- print MPX prefix for jxx/call/ret instructions if required.
  */
@@ -19168,19 +19167,6 @@ ix86_print_operand (FILE *file, rtx x, int code)
 #endif
 	  return;
 
-	case '@':
-	  if (ASSEMBLER_DIALECT == ASM_ATT)
-	    putc ('%', file);
-
-	  /* The kernel uses a different segment register for performance
-	     reasons; a system call would not have to trash the userspace
-	     segment register, which would be expensive.  */
-	  if (TARGET_64BIT && ix86_cmodel != CM_KERNEL)
-	    fputs ("fs", file);
-	  else
-	    fputs ("gs", file);
-	  return;
-
 	case '~':
 	  putc (TARGET_AVX2 ? 'i' : 'f', file);
 	  return;
@@ -19339,8 +19325,8 @@ ix86_print_operand (FILE *file, rtx x, int code)
 static bool
 ix86_print_operand_punct_valid_p (unsigned char code)
 {
-  return (code == '@' || code == '*' || code == '+' || code == '&'
-	  || code == ';' || code == '~' || code == '^' || code == '!');
+  return (code == '*' || code == '+' || code == '&' || code == ';'
+	  || code == '~' || code == '^' || code == '!');
 }
 

 /* Print a memory operand whose address is ADDR.  */
@@ -45805,13 +45791,31 @@ ix86_mangle_type (const_tree type)
 }
 
 #ifdef TARGET_THREAD_SSP_OFFSET
-/* If using TLS guards, don't waste time creating and expanding
-   __stack_chk_guard decl and MEM as we are going to ignore it.  */
 static tree
 ix86_stack_protect_guard (void)
 {
   if (TARGET_SSP_TLS_GUARD)
-    return NULL_TREE;
+    {
+      tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1);
+      addr_space_t as = DEFAULT_TLS_SEG_REG;
+
+      /* The kernel uses a different segment register for performance
+	 reasons; a system call would not have to trash the userspace
+	 segment register, which would be expensive.  */
+      if (ix86_cmodel == CM_KERNEL)
+	as = ADDR_SPACE_SEG_GS;
+
+      int qual = ENCODE_QUAL_ADDR_SPACE (as);
+
+      tree type = build_qualified_type (type_node, qual);
+      tree asptrtype = build_pointer_type (type);
+      tree sspoff = build_int_cst (asptrtype, TARGET_THREAD_SSP_OFFSET);
+
+      tree t = build2 (MEM_REF, asptrtype, sspoff,
+		       build_int_cst (asptrtype, 0));
+      return t;
+    }
+
   return default_stack_protect_guard ();
 }
 #endif
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 250900)
+++ config/i386/i386.md	(working copy)
@@ -61,7 +61,6 @@
 ;; + -- print a branch hint as 'cs' or 'ds' prefix
 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
-;; @ -- print a segment register of thread base pointer load
 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
 
@@ -18718,16 +18717,9 @@
 {
   rtx (*insn)(rtx, rtx);
 
-#ifdef TARGET_THREAD_SSP_OFFSET
-  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
   insn = (TARGET_LP64
-	  ? gen_stack_tls_protect_set_di
-	  : gen_stack_tls_protect_set_si);
-#else
-  insn = (TARGET_LP64
 	  ? gen_stack_protect_set_di
 	  : gen_stack_protect_set_si);
-#endif
 
   emit_insn (insn (operands[0], operands[1]));
   DONE;
@@ -18743,16 +18735,6 @@
   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
   [(set_attr "type" "multi")])
 
-(define_insn "stack_tls_protect_set_<mode>"
-  [(set (match_operand:PTR 0 "memory_operand" "=m")
-	(unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
-		    UNSPEC_SP_TLS_SET))
-   (set (match_scratch:PTR 2 "=&r") (const_int 0))
-   (clobber (reg:CC FLAGS_REG))]
-  ""
-  "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
-  [(set_attr "type" "multi")])
-
 (define_expand "stack_protect_test"
   [(match_operand 0 "memory_operand")
    (match_operand 1 "memory_operand")
@@ -18763,16 +18745,9 @@
 
   rtx (*insn)(rtx, rtx, rtx);
 
-#ifdef TARGET_THREAD_SSP_OFFSET
-  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
   insn = (TARGET_LP64
-	  ? gen_stack_tls_protect_test_di
-	  : gen_stack_tls_protect_test_si);
-#else
-  insn = (TARGET_LP64
 	  ? gen_stack_protect_test_di
 	  : gen_stack_protect_test_si);
-#endif
 
   emit_insn (insn (flags, operands[0], operands[1]));
 
@@ -18791,16 +18766,6 @@
   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
   [(set_attr "type" "multi")])
 
-(define_insn "stack_tls_protect_test_<mode>"
-  [(set (match_operand:CCZ 0 "flags_reg_operand")
-	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
-		     (match_operand:PTR 2 "const_int_operand" "i")]
-		    UNSPEC_SP_TLS_TEST))
-   (clobber (match_scratch:PTR 3 "=r"))]
-  ""
-  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
-  [(set_attr "type" "multi")])
-
 (define_insn "sse4_2_crc32<mode>"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(unspec:SI


More information about the Gcc-patches mailing list