This patch from brad@ backports -fstack-protector-strong support from
4.9. It seems to work fine on amd64 amd powerpc, but I think it could
really use some more test coverage as it's a somewhat intrusive change.
Index: Makefile
===
RCS file: /home/cvs/ports/lang/gcc/4.8/Makefile,v
retrieving revision 1.35
diff -u -p -u -p -r1.35 Makefile
--- Makefile25 May 2014 21:45:39 - 1.35
+++ Makefile25 May 2014 22:21:37 -
@@ -31,13 +31,13 @@ PKGNAME-ada = gnat-${FULL_PKGVERSION}
#PKGNAME-go = gccgo-${FULL_PKGVERSION}
PKGSPEC-main = gcc->=4.8,<4.9
-#REVISION-main =
-#REVISION-c++ =
+REVISION-main = 0
+REVISION-c++ = 0
#REVISION-estdc=
-#REVISION-f95 =
-#REVISION-java =
-#REVISION-objc =
-#REVISION-ada =
+REVISION-f95 = 0
+REVISION-java = 0
+REVISION-objc = 0
+REVISION-ada = 0
#REVISION-go =
SHARED_LIBS = estdc++ 16.0 \
Index: patches/patch-gcc_c-family_c-cppbuiltin_c
===
RCS file: patches/patch-gcc_c-family_c-cppbuiltin_c
diff -N patches/patch-gcc_c-family_c-cppbuiltin_c
--- /dev/null 1 Jan 1970 00:00:00 -
+++ patches/patch-gcc_c-family_c-cppbuiltin_c 24 May 2014 21:26:40 -
@@ -0,0 +1,17 @@
+$OpenBSD$
+
+Add stack protector strong support.
+
+http://repo.or.cz/w/official-gcc.git/commit/b156ec373ccf27f4fcce7972de5e043d35acea43
+
+--- gcc/c-family/c-cppbuiltin.c.orig Sat May 24 16:46:19 2014
gcc/c-family/c-cppbuiltin.cSat May 24 16:48:30 2014
+@@ -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)
Index: patches/patch-gcc_cfgexpand_c
===
RCS file: patches/patch-gcc_cfgexpand_c
diff -N patches/patch-gcc_cfgexpand_c
--- /dev/null 1 Jan 1970 00:00:00 -
+++ patches/patch-gcc_cfgexpand_c 24 May 2014 21:26:52 -
@@ -0,0 +1,158 @@
+$OpenBSD$
+
+Add stack protector strong support.
+
+http://repo.or.cz/w/official-gcc.git/commit/b156ec373ccf27f4fcce7972de5e043d35acea43
+http://repo.or.cz/w/official-gcc.git/commit/ec4af1becd78ded46c41d650b910614836750a54
+
+--- gcc/cfgexpand.c.orig Sat May 24 16:48:49 2014
gcc/cfgexpand.cSat May 24 17:06:54 2014
+@@ -1291,6 +1291,12 @@ clear_tree_used (tree block)
+ 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 @@ stack_protect_decl_phase (tree decl)
+ 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,73 @@ estimated_stack_frame_size (struct cgraph_node *node)
+ 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;
++}
++
++/* Check if the current function has local referenced variables that
++ have their addresses taken, contain an array, or are arrays. */
++
++static bool
++stack_protect_decl_p ()
++{
++ unsigned i;
++ tree var;
++
++ FOR_EACH_LOCAL_DECL (cfun, i, var)
++if (!is_global_var (var))
++ {
++ tree var_type = TREE_TYPE (var);
++ 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
++return true;
++ }
++ return false;
++}
++
++/* Check if the current function has calls that use a return slot. */
++
++static bool
++stack_protect_return_slot_p ()
++{
++ basic_block bb;
++
++ FOR_ALL_BB_FN (bb, cfun)
++for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
++ !gsi_end_p (gsi); gsi_next (&gsi))
++ {
++