From owner-svn-ports-head@freebsd.org Mon Nov 9 08:27:42 2015 Return-Path: Delivered-To: svn-ports-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D1F5FA26117; Mon, 9 Nov 2015 08:27:42 +0000 (UTC) (envelope-from gerald@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AA0901B35; Mon, 9 Nov 2015 08:27:42 +0000 (UTC) (envelope-from gerald@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tA98RfEt099343; Mon, 9 Nov 2015 08:27:41 GMT (envelope-from gerald@FreeBSD.org) Received: (from gerald@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tA98Rfbj099339; Mon, 9 Nov 2015 08:27:41 GMT (envelope-from gerald@FreeBSD.org) Message-Id: <201511090827.tA98Rfbj099339@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: gerald set sender to gerald@FreeBSD.org using -f From: Gerald Pfeifer Date: Mon, 9 Nov 2015 08:27:41 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r401086 - head/lang/gcc/files X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Nov 2015 08:27:42 -0000 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 ++#include ++ ++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 } } */