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
--- Makefile 25 May 2014 21:45:39 -0000 1.35
+++ Makefile 25 May 2014 22:21:37 -0000
@@ -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 -0000
+++ patches/patch-gcc_c-family_c-cppbuiltin_c 24 May 2014 21:26:40 -0000
@@ -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.c Sat 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 -0000
+++ patches/patch-gcc_cfgexpand_c 24 May 2014 21:26:52 -0000
@@ -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.c Sat 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))
++ {
++ gimple stmt = gsi_stmt (gsi);
++ /* This assumes that calls to internal-only functions never
++ use a return slot. */
++ if (is_gimple_call (stmt)
++ && !gimple_call_internal_p (stmt)
++ && aggregate_value_p (TREE_TYPE (gimple_call_fntype (stmt)),
++ gimple_call_fndecl (stmt)))
++ return true;
++ }
++ return false;
++}
++
+ /* Expand all variables used in the function. */
+
+ static rtx
+@@ -1525,6 +1599,7 @@ expand_used_vars (void)
+ 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. */
+ {
+@@ -1576,6 +1651,10 @@ expand_used_vars (void)
+ }
+ pointer_map_destroy (ssa_name_decls);
+
++ if (flag_stack_protect == SPCT_FLAG_STRONG)
++ gen_stack_protect_signal
++ = stack_protect_decl_p () || stack_protect_return_slot_p ();
++
+ /* 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 +1741,26 @@ expand_used_vars (void)
+ 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 ();
++ 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)
Index: patches/patch-gcc_common_opt
===================================================================
RCS file: /home/cvs/ports/lang/gcc/4.8/patches/patch-gcc_common_opt,v
retrieving revision 1.1.1.1
diff -u -p -u -p -r1.1.1.1 patch-gcc_common_opt
--- patches/patch-gcc_common_opt 8 Apr 2013 08:20:25 -0000 1.1.1.1
+++ patches/patch-gcc_common_opt 24 May 2014 21:27:04 -0000
@@ -1,6 +1,11 @@
$OpenBSD: patch-gcc_common_opt,v 1.1.1.1 2013/04/08 08:20:25 pascal Exp $
---- gcc/common.opt.orig Thu Mar 14 10:13:36 2013
-+++ gcc/common.opt Mon Mar 25 22:55:38 2013
+
+Add stack protector strong support.
+
+http://repo.or.cz/w/official-gcc.git/commit/b156ec373ccf27f4fcce7972de5e043d35acea43
+
+--- gcc/common.opt.orig Thu Mar 14 05:13:36 2013
++++ gcc/common.opt Sat May 24 17:11:22 2014
@@ -572,6 +572,10 @@ Wlarger-than=
Common RejectNegative Joined UInteger Warning
-Wlarger-than=<number> Warn if an object is larger than <number> bytes
@@ -68,16 +73,26 @@ $OpenBSD: patch-gcc_common_opt,v 1.1.1.1
Generate position-independent code for executables if possible (large mode)
fpic
-@@ -1902,7 +1910,7 @@ Common RejectNegative Joined Var(common_deferred_optio
+@@ -1902,13 +1910,17 @@ Common RejectNegative Joined Var(common_deferred_optio
-fstack-limit-symbol=<name> Trap if the stack goes past symbol <name>
fstack-protector
-Common Report Var(flag_stack_protect, 1)
-+Common Report Var(flag_stack_protect, 1) Init(-1)
++Common Report Var(flag_stack_protect, 3) Init(-1)
Use propolice as a stack protection method
fstack-protector-all
-@@ -2307,7 +2315,7 @@ Common JoinedOrMissing Negative(gdwarf-)
+ 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
+@@ -2307,7 +2319,7 @@ Common JoinedOrMissing Negative(gdwarf-)
Generate debug information in COFF format
gdwarf-
@@ -86,7 +101,7 @@ $OpenBSD: patch-gcc_common_opt,v 1.1.1.1
Generate debug information in DWARF v2 (or later) format
ggdb
-@@ -2391,6 +2399,9 @@ no-canonical-prefixes
+@@ -2391,6 +2403,9 @@ no-canonical-prefixes
Driver
nodefaultlibs
Index: patches/patch-gcc_doc_cpp_texi
===================================================================
RCS file: patches/patch-gcc_doc_cpp_texi
diff -N patches/patch-gcc_doc_cpp_texi
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-gcc_doc_cpp_texi 24 May 2014 21:27:14 -0000
@@ -0,0 +1,19 @@
+$OpenBSD$
+
+Add stack protector strong support.
+
+http://repo.or.cz/w/official-gcc.git/commit/b156ec373ccf27f4fcce7972de5e043d35acea43
+
+--- gcc/doc/cpp.texi.orig Sat May 24 16:54:15 2014
++++ gcc/doc/cpp.texi Sat May 24 16:54:35 2014
+@@ -2347,6 +2347,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.
Index: patches/patch-gcc_doc_invoke_texi
===================================================================
RCS file: patches/patch-gcc_doc_invoke_texi
diff -N patches/patch-gcc_doc_invoke_texi
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-gcc_doc_invoke_texi 25 May 2014 22:26:47 -0000
@@ -0,0 +1,32 @@
+$OpenBSD$
+
+Add stack protector strong support.
+
+http://repo.or.cz/w/official-gcc.git/commit/b156ec373ccf27f4fcce7972de5e043d35acea43
+
+--- gcc/doc/invoke.texi.orig Mon Apr 28 06:05:29 2014
++++ gcc/doc/invoke.texi Sun May 25 18:26:14 2014
+@@ -406,8 +406,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
+@@ -8890,6 +8890,12 @@ If a guard check fails, an error message is printed an
+ @item -fstack-protector-all
+ @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
Index: patches/patch-gcc_toplev_c
===================================================================
RCS file: /home/cvs/ports/lang/gcc/4.8/patches/patch-gcc_toplev_c,v
retrieving revision 1.1.1.1
diff -u -p -u -p -r1.1.1.1 patch-gcc_toplev_c
--- patches/patch-gcc_toplev_c 8 Apr 2013 08:20:25 -0000 1.1.1.1
+++ patches/patch-gcc_toplev_c 24 May 2014 21:12:45 -0000
@@ -1,12 +1,12 @@
$OpenBSD: patch-gcc_toplev_c,v 1.1.1.1 2013/04/08 08:20:25 pascal Exp $
---- gcc/toplev.c.orig Thu Jan 10 21:38:27 2013
-+++ gcc/toplev.c Wed Jan 23 22:48:30 2013
+--- gcc/toplev.c.orig Thu Mar 28 04:29:51 2013
++++ gcc/toplev.c Sat May 24 17:12:16 2014
@@ -1519,6 +1519,8 @@ process_options (void)
/* Targets must be able to place spill slots at lower addresses. If the
target already uses a soft frame pointer, the transition is trivial. */
+ if (flag_stack_protect == -1)
-+ flag_stack_protect = FRAME_GROWS_DOWNWARD ? 1 : 0;
++ flag_stack_protect = FRAME_GROWS_DOWNWARD ? 3 : 0;
if (!FRAME_GROWS_DOWNWARD && flag_stack_protect)
{
warning (0, "-fstack-protector not supported for this target");