Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Nov 2015 08:27:41 +0000 (UTC)
From:      Gerald Pfeifer <gerald@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r401086 - head/lang/gcc/files
Message-ID:  <201511090827.tA98Rfbj099339@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gerald
Date: Mon Nov  9 08:27:41 2015
New Revision: 401086
URL: https://svnweb.freebsd.org/changeset/ports/401086

Log:
  "Backport" the  -fstack-protector-strong patchset from lang/gcc48 to
  lang/gcc.
  
  PR:		203751, 186852 [1]
  Submitted by:	software-freebsd@interfasys.ch [1]

Added:
  head/lang/gcc/files/patch-stackprotector-gcc
     - copied unchanged from r401076, head/lang/gcc48/files/patch-stackprotector-gcc
  head/lang/gcc/files/patch-stackprotector-gcc_c-family
     - copied unchanged from r401076, head/lang/gcc48/files/patch-stackprotector-gcc_c-family
  head/lang/gcc/files/patch-stackprotector-gcc_doc
     - copied unchanged from r401076, head/lang/gcc48/files/patch-stackprotector-gcc_doc
  head/lang/gcc/files/patch-stackprotector-gcc_testsuite
     - copied unchanged from r401076, head/lang/gcc48/files/patch-stackprotector-gcc_testsuite

Copied: head/lang/gcc/files/patch-stackprotector-gcc (from r401076, head/lang/gcc48/files/patch-stackprotector-gcc)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lang/gcc/files/patch-stackprotector-gcc	Mon Nov  9 08:27:41 2015	(r401086, copy of r401076, head/lang/gcc48/files/patch-stackprotector-gcc)
@@ -0,0 +1,157 @@
+--- gcc/cfgexpand.c.orig
++++ gcc/cfgexpand.c
+@@ -1291,6 +1291,12 @@
+     clear_tree_used (t);
+ }
+ 
++ enum {
++   SPCT_FLAG_DEFAULT = 1,
++   SPCT_FLAG_ALL = 2,
++   SPCT_FLAG_STRONG = 3
++ };
++
+ /* Examine TYPE and determine a bit mask of the following features.  */
+ 
+ #define SPCT_HAS_LARGE_CHAR_ARRAY	1
+@@ -1360,7 +1366,8 @@
+   if (bits & SPCT_HAS_SMALL_CHAR_ARRAY)
+     has_short_buffer = true;
+ 
+-  if (flag_stack_protect == 2)
++  if (flag_stack_protect == SPCT_FLAG_ALL
++      || flag_stack_protect == SPCT_FLAG_STRONG)
+     {
+       if ((bits & (SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_LARGE_CHAR_ARRAY))
+ 	  && !(bits & SPCT_HAS_AGGREGATE))
+@@ -1514,6 +1521,27 @@
+   return size;
+ }
+ 
++/* Helper routine to check if a record or union contains an array field. */
++
++static int
++record_or_union_type_has_array_p (const_tree tree_type)
++{
++  tree fields = TYPE_FIELDS (tree_type);
++  tree f;
++
++  for (f = fields; f; f = DECL_CHAIN (f))
++    if (TREE_CODE (f) == FIELD_DECL)
++	  {
++	    tree field_type = TREE_TYPE (f);
++	    if (RECORD_OR_UNION_TYPE_P (field_type)
++	        && record_or_union_type_has_array_p (field_type))
++		  return 1;
++	    if (TREE_CODE (field_type) == ARRAY_TYPE)
++	      return 1;
++	  }
++  return 0;
++}
++
+ /* Expand all variables used in the function.  */
+ 
+ static rtx
+@@ -1525,6 +1553,7 @@
+   struct pointer_map_t *ssa_name_decls;
+   unsigned i;
+   unsigned len;
++  bool gen_stack_protect_signal = false;
+ 
+   /* Compute the phase of the stack frame for this function.  */
+   {
+@@ -1575,6 +1604,24 @@
+ 	}
+     }
+   pointer_map_destroy (ssa_name_decls);
++   
++  if (flag_stack_protect == SPCT_FLAG_STRONG)
++    FOR_EACH_LOCAL_DECL (cfun, i, var)
++      if (!is_global_var (var))
++        {
++	      tree var_type = TREE_TYPE (var);
++	      /* Examine local referenced variables that have their addresses taken,
++	         contain an array, or are arrays.  */
++	      if (TREE_CODE (var) == VAR_DECL
++	          && (TREE_CODE (var_type) == ARRAY_TYPE
++	          || TREE_ADDRESSABLE (var)
++	          || (RECORD_OR_UNION_TYPE_P (var_type)
++	          && record_or_union_type_has_array_p (var_type))))
++	        {
++	          gen_stack_protect_signal = true;
++	          break;
++	        }
++        }
+ 
+   /* At this point all variables on the local_decls with TREE_USED
+      set are not associated with any block scope.  Lay them out.  */
+@@ -1662,12 +1709,32 @@
+ 	dump_stack_var_partition ();
+     }
+ 
+-  /* There are several conditions under which we should create a
+-     stack guard: protect-all, alloca used, protected decls present.  */
+-  if (flag_stack_protect == 2
+-      || (flag_stack_protect
+-	  && (cfun->calls_alloca || has_protected_decls)))
+-    create_stack_guard ();
++  /* Create stack guard, if
++     a) "-fstack-protector-all" - always;
++     b) "-fstack-protector-strong" - if there are arrays, memory
++     references to local variables, alloca used, or protected decls present;
++     c) "-fstack-protector" - if alloca used, or protected decls present  */
++	 
++  switch (flag_stack_protect)
++    {
++    case SPCT_FLAG_ALL:
++      create_stack_guard ();
++      break;
++
++    case SPCT_FLAG_STRONG:
++      if (gen_stack_protect_signal
++	      || cfun->calls_alloca || has_protected_decls)
++	    create_stack_guard ();
++      break;
++
++    case SPCT_FLAG_DEFAULT:
++      if (cfun->calls_alloca || has_protected_decls)
++	    create_stack_guard ();
++      break;
++
++    default:
++      ;
++    }
+ 
+   /* Assign rtl to each variable based on these partitions.  */
+   if (stack_vars_num > 0)
+@@ -1688,7 +1755,7 @@
+ 	  expand_stack_vars (stack_protect_decl_phase_1, &data);
+ 
+ 	  /* Phase 2 contains other kinds of arrays.  */
+-	  if (flag_stack_protect == 2)
++	  if (flag_stack_protect == SPCT_FLAG_ALL)
+ 	    expand_stack_vars (stack_protect_decl_phase_2, &data);
+ 	}
+ 
+--- gcc/common.opt.orig
++++ gcc/common.opt
+@@ -1942,6 +1942,10 @@ fstack-protector-all
+ Common Report RejectNegative Var(flag_stack_protect, 2)
+ Use a stack protection method for every function
+ 
++fstack-protector-strong
++Common Report RejectNegative Var(flag_stack_protect, 3)
++Use a smart stack protection method for certain functions
++
+ fstack-usage
+ Common RejectNegative Var(flag_stack_usage)
+ Output stack usage information on a per-function basis
+--- gcc/gcc.c.orig
++++ gcc/gcc.c
+@@ -655,7 +655,7 @@ proper position among the other output files.  */
+ #ifdef TARGET_LIBC_PROVIDES_SSP
+ #define LINK_SSP_SPEC "%{fstack-protector:}"
+ #else
+-#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}"
++#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-strong|fstack-protector-all:-lssp_nonshared -lssp}"
+ #endif
+ #endif

Copied: head/lang/gcc/files/patch-stackprotector-gcc_c-family (from r401076, head/lang/gcc48/files/patch-stackprotector-gcc_c-family)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lang/gcc/files/patch-stackprotector-gcc_c-family	Mon Nov  9 08:27:41 2015	(r401086, copy of r401076, head/lang/gcc48/files/patch-stackprotector-gcc_c-family)
@@ -0,0 +1,11 @@
+--- gcc/c-family/c-cppbuiltin.c.orig
++++ gcc/c-family/c-cppbuiltin.c
+@@ -888,6 +888,8 @@ c_cpp_builtins (cpp_reader *pfile)
+   /* Make the choice of the stack protector runtime visible to source code.
+      The macro names and values here were chosen for compatibility with an
+      earlier implementation, i.e. ProPolice.  */
++  if (flag_stack_protect == 3)
++    cpp_define (pfile, "__SSP_STRONG__=3");
+   if (flag_stack_protect == 2)
+     cpp_define (pfile, "__SSP_ALL__=2");
+   else if (flag_stack_protect == 1)

Copied: head/lang/gcc/files/patch-stackprotector-gcc_doc (from r401076, head/lang/gcc48/files/patch-stackprotector-gcc_doc)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lang/gcc/files/patch-stackprotector-gcc_doc	Mon Nov  9 08:27:41 2015	(r401086, copy of r401076, head/lang/gcc48/files/patch-stackprotector-gcc_doc)
@@ -0,0 +1,39 @@
+--- gcc/doc/cpp.texi.orig
++++ gcc/doc/cpp.texi
+@@ -2349,6 +2349,10 @@ use.
+ This macro is defined, with value 2, when @option{-fstack-protector-all} is
+ in use.
+ 
++@item __SSP_STRONG__
++This macro is defined, with value 3, when @option{-fstack-protector-strong} is
++in use.
++
+ @item __SANITIZE_ADDRESS__
+ This macro is defined, with value 1, when @option{-fsanitize=address} is
+ in use.
+--- gcc/doc/invoke.texi.orig
++++ gcc/doc/invoke.texi
+@@ -407,8 +407,8 @@ Objective-C and Objective-C++ Dialects}.
+ -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol
+ -fshrink-wrap -fsignaling-nans -fsingle-precision-constant @gol
+ -fsplit-ivs-in-unroller -fsplit-wide-types -fstack-protector @gol
+--fstack-protector-all -fstrict-aliasing -fstrict-overflow @gol
+--fthread-jumps -ftracer -ftree-bit-ccp @gol
++-fstack-protector-all -fstack-protector-strong -fstrict-aliasing @gol
++-fstrict-overflow -fthread-jumps -ftracer -ftree-bit-ccp @gol
+ -ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
+ -ftree-coalesce-inline-vars -ftree-coalesce-vars -ftree-copy-prop @gol
+ -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse @gol
+@@ -8957,6 +8957,12 @@ If a guard check fails, an error message is printed and the program exits.
+ @opindex fstack-protector-all
+ Like @option{-fstack-protector} except that all functions are protected.
+ 
++@item -fstack-protector-strong
++@opindex fstack-protector-strong
++Like @option{-fstack-protector} but includes additional functions to
++be protected --- those that have local array definitions, or have
++references to local frame addresses.
++
+ @item -fsection-anchors
+ @opindex fsection-anchors
+ Try to reduce the number of symbolic address calculations by using

Copied: head/lang/gcc/files/patch-stackprotector-gcc_testsuite (from r401076, head/lang/gcc48/files/patch-stackprotector-gcc_testsuite)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lang/gcc/files/patch-stackprotector-gcc_testsuite	Mon Nov  9 08:27:41 2015	(r401086, copy of r401076, head/lang/gcc48/files/patch-stackprotector-gcc_testsuite)
@@ -0,0 +1,176 @@
+--- /dev/null
++++ gcc/testsuite/g++.dg/fstack-protector-strong.C
+@@ -0,0 +1,35 @@
++/* Test that stack protection is done on chosen functions. */
++
++/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
++/* { dg-options "-O2 -fstack-protector-strong" } */
++
++class A
++{
++public:
++  A() {}
++  ~A() {}
++  void method();
++  int state;
++};
++
++/* Frame address exposed to A::method via "this". */
++int
++foo1 ()
++{
++  A a;
++  a.method ();
++  return a.state;
++}
++
++/* Possible destroying foo2's stack via &a. */
++int
++global_func (A& a);
++
++/* Frame address exposed to global_func. */
++int foo2 ()
++{
++  A a;
++  return global_func (a);
++}
++
++/* { dg-final { scan-assembler-times "stack_chk_fail" 2 } } */
+--- /dev/null
++++ gcc/testsuite/gcc.dg/fstack-protector-strong.c
+@@ -0,0 +1,135 @@
++/* Test that stack protection is done on chosen functions. */
++
++/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
++/* { dg-options "-O2 -fstack-protector-strong" } */
++
++#include<string.h>
++#include<stdlib.h>
++
++extern int g0;
++extern int* pg0;
++int
++goo (int *);
++int
++hoo (int);
++
++/* Function frame address escaped function call. */
++int
++foo1 ()
++{
++  int i;
++  return goo (&i);
++}
++
++struct ArrayStruct
++{
++  int a;
++  int array[10];
++};
++
++struct AA
++{
++  int b;
++  struct ArrayStruct as;
++};
++
++/* Function frame contains array. */
++int
++foo2 ()
++{
++  struct AA aa;
++  int i;
++  for (i = 0; i < 10; ++i)
++    {
++      aa.as.array[i] = i * (i-1) + i / 2;
++    }
++  return aa.as.array[5];
++}
++
++/* Address computation based on a function frame address. */
++int
++foo3 ()
++{
++  int a;
++  int *p;
++  p = &a + 5;
++  return goo (p);
++}
++
++/* Address cast based on a function frame address. */
++int
++foo4 ()
++{
++  int a;
++  return goo (g0 << 2 ? (int *)(3 * (long)(void *)(&a)) : 0);
++}
++
++/* Address cast based on a local array. */
++int
++foo5 ()
++{
++  short array[10];
++  return goo ((int *)(array + 5));
++}
++
++struct BB
++{
++  int one;
++  int two;
++  int three;
++};
++
++/* Address computaton based on a function frame address.*/
++int
++foo6 ()
++{
++  struct BB bb;
++  return goo (&bb.one + sizeof(int));
++}
++
++/* Function frame address escaped via global variable. */
++int
++foo7 ()
++{
++  int a;
++  pg0 = &a;
++  goo (pg0);
++  return *pg0;
++}
++
++/* Check that this covers -fstack-protector. */
++int
++foo8 ()
++{
++  char base[100];
++  memcpy ((void *)base, (const void *)pg0, 105);
++  return (int)(base[32]);
++}
++
++/* Check that this covers -fstack-protector. */
++int
++foo9 ()
++{
++  char* p = alloca (100);
++  return goo ((int *)(p + 50));
++}
++
++int
++global2 (struct BB* pbb);
++
++/* Address taken on struct. */
++int
++foo10 ()
++{
++  struct BB bb;
++  int i;
++  bb.one = global2 (&bb);
++  for (i = 0; i < 10; ++i)
++    {
++      bb.two = bb.one + bb.two;
++      bb.three = bb.one + bb.two + bb.three;
++    }
++  return bb.three;
++}
++
++/* { dg-final { scan-assembler-times "stack_chk_fail" 10 } } */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511090827.tA98Rfbj099339>