On Sat, Oct 25, 2025 at 4:42 PM H.J. Lu <[email protected]> wrote: ... > Here is the v4 patch. > > Add a new target hook, stack_protect_guard_symbol, to support the user > provided stack protection guard as an internal symbol. If the hook is > true, > > 1. Make __stack_chk_guard an internal C/C++ symbol. > 2. Declare __stack_chk_guard as a size_t variable if size_t has the same > size as pointer so that it can be initialized as an integer. > 3. If the user declared variable matches __stack_chk_guard, merge it > with __stack_chk_guard, including its visibility attribute. > 4. Define the __stack_protection_guard_is_internal_symbol__ macro to > indicate that __stack_chk_guard is an internal symbol. > > gcc/ > > PR c/121911 > * target.def (stack_protect_guard_symbol): New target hook. > * targhooks.cc (default_stack_protect_guard): If > targetm.stack_protect_guard_symbol is true, make it an internal > symbol and use size_type_node if it has the same size as > ptr_type_node. > * tree.cc (build_common_tree_nodes): If stack protector is > enabled and targetm.stack_protect_guard_symbol is true, call > targetm.stack_protect_guard. > * config/i386/i386.cc (TARGET_STACK_PROTECT_GUARD_SYMBOL): New. > * doc/tm.texi: Regenerated. > * doc/tm.texi.in (TARGET_STACK_PROTECT_GUARD_SYMBOL): New. > > gcc/c-family/ > > PR c/121911 > * c-common.cc (matching_stack_protect_guard_decl_p): New. > * c-common.h (matching_stack_protect_guard_decl_p): Likewise. > * c-cppbuiltin.cc (c_cpp_builtins): Define the > __stack_protection_guard_is_internal_symbol__ macro if > targetm.stack_protect_guard_symbol is true. > > gcc/c/ > > PR c/121911 > * c-decl.cc: Include "c-family/c-common.h". > (merge_decls): Add a bool argument to keep the old type and copy > the old type if true. > (duplicate_decls): If the old decl is the stack protect guard and > the new decl matches the old decl, keep the type of the old decl. > > gcc/cp/ > > PR c/121911 > * decl.cc: Include "c-family/c-common.h". > (duplicate_decls): 2 types match if the old decl is the stack > protect guard and the new decl matches the old decl. > > gcc/testsuite/ > > PR c/121911 > * g++.target/i386/ssp-global-1.C: New test. > * g++.target/i386/ssp-global-2.C: Likewise. > * g++.target/i386/ssp-global-3.C: Likewise. > * g++.target/i386/ssp-global-4.C: Likewise. > * g++.target/i386/ssp-global-hidden-1.C: Likewise. > * g++.target/i386/ssp-global-hidden-2.C: Likewise. > * g++.target/i386/ssp-global-hidden-3.C: Likewise. > * gcc.target/i386/ssp-global-2.c: Likewise. > * gcc.target/i386/ssp-global-3.c: Likewise. > * gcc.target/i386/ssp-global-4.c: Likewise. > * gcc.target/i386/ssp-global-hidden-1.c: Likewise. > * gcc.target/i386/ssp-global-hidden-2.c: Likewise. > * gcc.target/i386/ssp-global-hidden-3.c: Likewise. >
Here is the v5 patch. The main difference is that __stack_chk_guard is an internal symbol with C linkage now. --- Add a new target hook, stack_protect_guard_symbol, to support the user provided stack protection guard as an internal symbol. If the hook returns true, 1. Make __stack_chk_guard an internal C/C++ symbol. 2. Declare __stack_chk_guard as a size_t variable if size_t has the same size as pointer so that it can be initialized as an integer. 3. If the user declared variable matches __stack_chk_guard, merge it with __stack_chk_guard, including its visibility attribute. 4. Define the __stack_protection_guard_is_internal_symbol__ macro to indicate that __stack_chk_guard is an internal symbol. gcc/ PR c/121911 * target.def (stack_protect_guard_symbol): New target hook. * targhooks.cc (default_stack_protect_guard): If the stack_protect_guard_symbol hook returns true, use size_type_node if it has the same size as ptr_type_node. * config/i386/i386.cc (ix86_stack_protect_guard_symbol): New. (TARGET_STACK_PROTECT_GUARD_SYMBOL): Likewise. * doc/tm.texi: Regenerated. * doc/tm.texi.in (TARGET_STACK_PROTECT_GUARD_SYMBOL): New. gcc/c-family/ PR c/121911 * c-common.cc (stack_protect_guard_decl): New. (pushing_stack_protect_guard_decl): Likewise. (c_stack_protect_guard_decl_p): Likewise. (duplicate_stack_protect_guard_decl_p): Likewise. (c_common_nodes_and_builtins): If the stack_protect_guard_symbol hook returns true, call targetm.stack_protect_guard. * c-common.h (c_stack_protect_guard_decl_p): New. (duplicate_stack_protect_guard_decl_p): Likewise. * c-cppbuiltin.cc (c_cpp_builtins): Define the __stack_protection_guard_is_internal_symbol__ macro if the stack_protect_guard_symbol hook returns. gcc/c/ PR c/121911 * c-decl.cc: Include "c-family/c-common.h". (merge_decls): Add a bool argument to keep the old type and copy the old type if true. (duplicate_decls): If the old decl is the stack protect guard and the new decl matches the old decl, keep the type of the old decl. gcc/cp/ PR c/121911 * cp-objcp-common.cc (cp_pushdecl): Change the stack protection guard symbol to C linkage. * decl.cc: Include "c-family/c-common.h". (duplicate_decls): 2 types match if the old decl is the stack protect guard and the new decl matches the old decl. gcc/testsuite/ PR c/121911 * g++.target/i386/ssp-global-1.C: New test. * g++.target/i386/ssp-global-2.C: Likewise. * g++.target/i386/ssp-global-3.C: Likewise. * g++.target/i386/ssp-global-4.C: Likewise. * g++.target/i386/ssp-global-hidden-1.C: Likewise. * g++.target/i386/ssp-global-hidden-2.C: Likewise. * g++.target/i386/ssp-global-hidden-3.C: Likewise. * gcc.target/i386/ssp-global-2.c: Likewise. * gcc.target/i386/ssp-global-3.c: Likewise. * gcc.target/i386/ssp-global-4.c: Likewise. * gcc.target/i386/ssp-global-hidden-1.c: Likewise. * gcc.target/i386/ssp-global-hidden-2.c: Likewise. * gcc.target/i386/ssp-global-hidden-3.c: Likewise. -- H.J.
From 6e23c0d75f5da0a41d33a4538debcf0649190a19 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <[email protected]> Date: Fri, 12 Sep 2025 18:52:39 -0700 Subject: [PATCH v5] c/c++: Make stack protection guard an internal symbol Add a new target hook, stack_protect_guard_symbol, to support the user provided stack protection guard as an internal symbol. If the hook returns true, 1. Make __stack_chk_guard an internal C/C++ symbol. 2. Declare __stack_chk_guard as a size_t variable if size_t has the same size as pointer so that it can be initialized as an integer. 3. If the user declared variable matches __stack_chk_guard, merge it with __stack_chk_guard, including its visibility attribute. 4. Define the __stack_protection_guard_is_internal_symbol__ macro to indicate that __stack_chk_guard is an internal symbol. gcc/ PR c/121911 * target.def (stack_protect_guard_symbol): New target hook. * targhooks.cc (default_stack_protect_guard): If the stack_protect_guard_symbol hook returns true, use size_type_node if it has the same size as ptr_type_node. * config/i386/i386.cc (ix86_stack_protect_guard_symbol): New. (TARGET_STACK_PROTECT_GUARD_SYMBOL): Likewise. * doc/tm.texi: Regenerated. * doc/tm.texi.in (TARGET_STACK_PROTECT_GUARD_SYMBOL): New. gcc/c-family/ PR c/121911 * c-common.cc (stack_protect_guard_decl): New. (pushing_stack_protect_guard_decl): Likewise. (c_stack_protect_guard_decl_p): Likewise. (duplicate_stack_protect_guard_decl_p): Likewise. (c_common_nodes_and_builtins): If the stack_protect_guard_symbol hook returns true, call targetm.stack_protect_guard. * c-common.h (c_stack_protect_guard_decl_p): New. (duplicate_stack_protect_guard_decl_p): Likewise. * c-cppbuiltin.cc (c_cpp_builtins): Define the __stack_protection_guard_is_internal_symbol__ macro if the stack_protect_guard_symbol hook returns. gcc/c/ PR c/121911 * c-decl.cc: Include "c-family/c-common.h". (merge_decls): Add a bool argument to keep the old type and copy the old type if true. (duplicate_decls): If the old decl is the stack protect guard and the new decl matches the old decl, keep the type of the old decl. gcc/cp/ PR c/121911 * cp-objcp-common.cc (cp_pushdecl): Change the stack protection guard symbol to C linkage. * decl.cc: Include "c-family/c-common.h". (duplicate_decls): 2 types match if the old decl is the stack protect guard and the new decl matches the old decl. gcc/testsuite/ PR c/121911 * g++.target/i386/ssp-global-1.C: New test. * g++.target/i386/ssp-global-2.C: Likewise. * g++.target/i386/ssp-global-3.C: Likewise. * g++.target/i386/ssp-global-4.C: Likewise. * g++.target/i386/ssp-global-hidden-1.C: Likewise. * g++.target/i386/ssp-global-hidden-2.C: Likewise. * g++.target/i386/ssp-global-hidden-3.C: Likewise. * gcc.target/i386/ssp-global-2.c: Likewise. * gcc.target/i386/ssp-global-3.c: Likewise. * gcc.target/i386/ssp-global-4.c: Likewise. * gcc.target/i386/ssp-global-hidden-1.c: Likewise. * gcc.target/i386/ssp-global-hidden-2.c: Likewise. * gcc.target/i386/ssp-global-hidden-3.c: Likewise. Signed-off-by: H.J. Lu <[email protected]> --- gcc/c-family/c-common.cc | 48 +++++++++++++++++ gcc/c-family/c-common.h | 3 ++ gcc/c-family/c-cppbuiltin.cc | 5 ++ gcc/c/c-decl.cc | 22 +++++--- gcc/config/i386/i386.cc | 12 +++++ gcc/cp/cp-objcp-common.cc | 5 ++ gcc/cp/decl.cc | 6 ++- gcc/doc/tm.texi | 7 +++ gcc/doc/tm.texi.in | 2 + gcc/target.def | 11 ++++ gcc/targhooks.cc | 22 ++++++-- gcc/testsuite/g++.target/i386/ssp-global-1.C | 35 +++++++++++++ gcc/testsuite/g++.target/i386/ssp-global-2.C | 35 +++++++++++++ gcc/testsuite/g++.target/i386/ssp-global-3.C | 4 ++ gcc/testsuite/g++.target/i386/ssp-global-4.C | 4 ++ .../g++.target/i386/ssp-global-hidden-1.C | 50 ++++++++++++++++++ .../g++.target/i386/ssp-global-hidden-2.C | 20 ++++++++ .../g++.target/i386/ssp-global-hidden-3.C | 51 +++++++++++++++++++ gcc/testsuite/gcc.target/i386/ssp-global-2.c | 35 +++++++++++++ gcc/testsuite/gcc.target/i386/ssp-global-3.c | 10 ++++ gcc/testsuite/gcc.target/i386/ssp-global-4.c | 10 ++++ .../gcc.target/i386/ssp-global-hidden-1.c | 49 ++++++++++++++++++ .../gcc.target/i386/ssp-global-hidden-2.c | 20 ++++++++ .../gcc.target/i386/ssp-global-hidden-3.c | 50 ++++++++++++++++++ 24 files changed, 505 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-1.C create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-2.C create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-3.C create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-4.C create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C create mode 100644 gcc/testsuite/g++.target/i386/ssp-global-hidden-3.C create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-2.c create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-3.c create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-4.c create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c create mode 100644 gcc/testsuite/gcc.target/i386/ssp-global-hidden-3.c diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index f2eed033706..b33b639c95c 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -299,6 +299,12 @@ bool in_late_binary_op; cpp_finish (), we need to do so. */ bool override_libcpp_locations; +/* The stack protection guard. */ +static tree stack_protect_guard_decl; + +/* True if the stack protection guard is being pushed. */ +static bool pushing_stack_protect_guard_decl; + /* Information about how a function name is generated. */ struct fname_var_t { @@ -4847,6 +4853,16 @@ c_common_nodes_and_builtins (void) } } + /* Call the target stack_protect_guard hook if the stack protection + guard should be an internal symbol. */ + if (targetm.stack_protect_guard_symbol ()) + { + stack_protect_guard_decl = targetm.stack_protect_guard (); + pushing_stack_protect_guard_decl = true; + lang_hooks.decls.pushdecl (stack_protect_guard_decl); + pushing_stack_protect_guard_decl = false; + } + if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) { va_list_arg_type_node = va_list_ref_type_node = @@ -10592,4 +10608,36 @@ c_hardbool_type_attr_1 (tree type, tree *false_value, tree *true_value) return attr; } +/* Return true if DECL is the internal stack protection guard symbol. */ + +bool +c_stack_protect_guard_decl_p (tree decl) +{ + return (pushing_stack_protect_guard_decl + || decl == stack_protect_guard_decl); +} + +/* Return true if for matched NEWDECL and OLDDECL, OLDDECL is the + internal stack protection guard symbol. */ + +bool +duplicate_stack_protect_guard_decl_p (tree newdecl, tree olddecl) +{ + if (newdecl != error_mark_node + && c_stack_protect_guard_decl_p (olddecl)) + { + /* Allow different integer types with the same size. */ + tree oldtype = TREE_TYPE (olddecl); + tree newtype = TREE_TYPE (newdecl); + if (TYPE_CANONICAL (newtype) == TYPE_CANONICAL (oldtype) + || (TREE_CODE (newtype) == INTEGER_TYPE + && TREE_CODE (oldtype) == INTEGER_TYPE + && (TYPE_PRECISION (newtype) + == TYPE_PRECISION (oldtype)))) + return true; + } + + return false; +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index bedbd4a94b0..a982058c6d0 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1726,6 +1726,9 @@ extern bool compatible_types_for_indirection_note_p (tree type1, tree type2); extern tree braced_lists_to_strings (tree, tree); +extern bool c_stack_protect_guard_decl_p (tree); +extern bool duplicate_stack_protect_guard_decl_p (tree, tree); + #if CHECKING_P namespace selftest { /* Declarations for specific families of tests within c-family, diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 6b22f9e60b1..eaf11ffb6d0 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1191,6 +1191,11 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_exceptions=199711L"); } + /* Define this to indicate that the stack protection guard symbol, + "__stack_chk_guard", is an internal symbol. */ + if (targetm.stack_protect_guard_symbol ()) + cpp_define (pfile, "__stack_protection_guard_is_internal_symbol__"); + /* Represents the C++ ABI version, always defined so it can be used while preprocessing C and assembler. */ if (flag_abi_version == 0) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 061892ac95b..f6b302087e6 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "toplev.h" #include "debug.h" +#include "c-family/c-common.h" #include "c-family/c-objc.h" #include "c-family/c-pragma.h" #include "c-family/c-ubsan.h" @@ -2743,7 +2744,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, diagnostics. */ static void -merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) +merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype, + bool keep_oldtype = false) { bool new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != NULL_TREE); @@ -2830,9 +2832,12 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) } /* Merge the data types specified in the two decls. */ - TREE_TYPE (newdecl) - = TREE_TYPE (olddecl) - = composite_type (newtype, oldtype); + if (keep_oldtype) + TREE_TYPE (newdecl) = TREE_TYPE (olddecl); + else + TREE_TYPE (newdecl) + = TREE_TYPE (olddecl) + = composite_type (newtype, oldtype); /* Lay the type out, unless already done. */ if (!comptypes (oldtype, TREE_TYPE (newdecl))) @@ -3206,8 +3211,13 @@ static bool duplicate_decls (tree newdecl, tree olddecl) { tree newtype = NULL, oldtype = NULL; + bool keep_oldtype = false; - if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype)) + /* Keep the internal stack protection guard type. */ + if (duplicate_stack_protect_guard_decl_p (newdecl, olddecl)) + keep_oldtype = true; + else if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, + &oldtype)) { /* Avoid `unused variable' and other warnings for OLDDECL. */ suppress_warning (olddecl, OPT_Wunused); @@ -3225,7 +3235,7 @@ duplicate_decls (tree newdecl, tree olddecl) return false; } - merge_decls (newdecl, olddecl, newtype, oldtype); + merge_decls (newdecl, olddecl, newtype, oldtype, keep_oldtype); /* The NEWDECL will no longer be needed. diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 587b2bd0c1d..0d35d9bd120 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -25221,6 +25221,14 @@ ix86_stack_protect_guard (void) return default_stack_protect_guard (); } +/* Implement TARGET_STACK_PROTECT_GUARD_SYMBOL. */ + +static bool +ix86_stack_protect_guard_symbol (void) +{ + return TARGET_SSP_GLOBAL_GUARD; +} + static bool ix86_stack_protect_runtime_enabled_p (void) { @@ -28162,6 +28170,10 @@ ix86_libgcc_floating_mode_supported_p #undef TARGET_STACK_PROTECT_GUARD #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard +#undef TARGET_STACK_PROTECT_GUARD_SYMBOL +#define TARGET_STACK_PROTECT_GUARD_SYMBOL \ + ix86_stack_protect_guard_symbol + #undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P \ ix86_stack_protect_runtime_enabled_p diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc index c7e88cb7bfe..d6363f8d0b4 100644 --- a/gcc/cp/cp-objcp-common.cc +++ b/gcc/cp/cp-objcp-common.cc @@ -521,6 +521,11 @@ tree cp_pushdecl (tree decl) { DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); + if (c_stack_protect_guard_decl_p (decl)) + { + retrofit_lang_decl (decl); + SET_DECL_LANGUAGE (decl, lang_c); + } return pushdecl (decl); } diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 2089e4c21ac..1dde1ef4af5 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "decl.h" #include "intl.h" #include "toplev.h" +#include "c-family/c-common.h" #include "c-family/c-objc.h" #include "c-family/c-pragma.h" #include "c-family/c-ubsan.h" @@ -1805,7 +1806,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) if (newdecl == olddecl) return olddecl; - types_match = decls_match (newdecl, olddecl); + if (duplicate_stack_protect_guard_decl_p (newdecl, olddecl)) + types_match = 1; + else + types_match = decls_match (newdecl, olddecl); /* If either the type of the new decl or the type of the old decl is an error_mark_node, then that implies that we have already issued an diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index fd208f53844..ab1ce3805a6 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5408,6 +5408,13 @@ The default version of this hook creates a variable called @samp{__stack_chk_guard}, which is normally defined in @file{libgcc2.c}. @end deftypefn +@deftypefn {Target Hook} bool TARGET_STACK_PROTECT_GUARD_SYMBOL (void) +Usually, the compiler uses an external variable @samp{__stack_chk_guard} +defined in @file{libgcc2.c} as the stack protection guard symbol. Define +this hook to return true if a user provided definition of +@samp{__stack_chk_guard} is used. +@end deftypefn + @deftypefn {Target Hook} tree TARGET_STACK_PROTECT_FAIL (void) This hook returns a @code{CALL_EXPR} that alerts the runtime that the stack protect guard variable has been modified. This expression should diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 14315dd5080..2db947e3afd 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3808,6 +3808,8 @@ generic code. @hook TARGET_STACK_PROTECT_GUARD +@hook TARGET_STACK_PROTECT_GUARD_SYMBOL + @hook TARGET_STACK_PROTECT_FAIL @hook TARGET_STACK_PROTECT_RUNTIME_ENABLED_P diff --git a/gcc/target.def b/gcc/target.def index f288329ffca..fa5e4c42410 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4637,6 +4637,17 @@ The default version of this hook creates a variable called\n\ tree, (void), default_stack_protect_guard) +/* Return true if the user provided stack protection guard definition of + __stack_chk_guard is used. */ +DEFHOOK +(stack_protect_guard_symbol, + "Usually, the compiler uses an external variable @samp{__stack_chk_guard}\n\ +defined in @file{libgcc2.c} as the stack protection guard symbol. Define\n\ +this hook to return true if a user provided definition of\n\ +@samp{__stack_chk_guard} is used.", + bool, (void), + hook_bool_void_false) + /* This target hook allows the operating system to override the CALL_EXPR that is invoked when a check vs the guard variable fails. */ DEFHOOK diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index 1873d572ba3..326100cc59f 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -924,9 +924,17 @@ default_stack_protect_guard (void) { rtx x; + /* If __stack_chk_guard is an internal symbol, use size_type_node + if it has the same size as ptr_type_node so that the guard + symbol can be initialized as an integer. */ + if (targetm.stack_protect_guard_symbol () + && (TYPE_PRECISION (size_type_node) + == TYPE_PRECISION (ptr_type_node))) + t = size_type_node; + else + t = ptr_type_node; t = build_decl (UNKNOWN_LOCATION, - VAR_DECL, get_identifier ("__stack_chk_guard"), - ptr_type_node); + VAR_DECL, get_identifier ("__stack_chk_guard"), t); TREE_STATIC (t) = 1; TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; @@ -937,8 +945,14 @@ default_stack_protect_guard (void) /* Do not share RTL as the declaration is visible outside of current function. */ - x = DECL_RTL (t); - RTX_FLAG (x, used) = 1; + if (mode_mem_attrs[(int) DECL_MODE (t)]) + { + /* NB: Don't call make_decl_rtl when mode_mem_attrs isn't + initialized. -save-temps won't initialize mode_mem_attrs + and make_decl_rtl will fail. */ + x = DECL_RTL (t); + RTX_FLAG (x, used) = 1; + } stack_chk_guard_decl = t; } diff --git a/gcc/testsuite/g++.target/i386/ssp-global-1.C b/gcc/testsuite/g++.target/i386/ssp-global-1.C new file mode 100644 index 00000000000..086a0a1d9ae --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-1.C @@ -0,0 +1,35 @@ +/* { dg-do run { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */ + +#include <stdlib.h> + +#ifdef __LP64__ +const unsigned long int __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +const unsigned long int __stack_chk_guard = 0xdd2cc927UL; +#endif + +extern "C" void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} diff --git a/gcc/testsuite/g++.target/i386/ssp-global-2.C b/gcc/testsuite/g++.target/i386/ssp-global-2.C new file mode 100644 index 00000000000..9ae28f554c9 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-2.C @@ -0,0 +1,35 @@ +/* { dg-do run { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */ + +#include <stdlib.h> + +#ifdef __LP64__ +long int __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +int __stack_chk_guard = 0xdd2cc927UL; +#endif + +extern "C" void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} diff --git a/gcc/testsuite/g++.target/i386/ssp-global-3.C b/gcc/testsuite/g++.target/i386/ssp-global-3.C new file mode 100644 index 00000000000..e0e2e7d7f9b --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-3.C @@ -0,0 +1,4 @@ +/* { dg-do compile { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */ + +extern char *__stack_chk_guard; /* { dg-error "conflicting declaration 'char. __stack_chk_guard'" } */ diff --git a/gcc/testsuite/g++.target/i386/ssp-global-4.C b/gcc/testsuite/g++.target/i386/ssp-global-4.C new file mode 100644 index 00000000000..cc842b3d538 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-4.C @@ -0,0 +1,4 @@ +/* { dg-do compile { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */ + +extern char __stack_chk_guard; /* { dg-error "conflicting declaration 'char __stack_chk_guard'" } */ diff --git a/gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C b/gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C new file mode 100644 index 00000000000..7d203a35309 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C @@ -0,0 +1,50 @@ +/* { dg-do run { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global -save-temps" } */ + +#ifndef __stack_protection_guard_is_internal_symbol__ +# error "__stack_protection_guard_is_internal_symbol__ isn't defined" +#endif + +#include <stdlib.h> +#include <stddef.h> + +extern "C" +__attribute__ ((visibility ("hidden"))) +#ifdef __LP64__ +const size_t __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +const size_t __stack_chk_guard = 0xdd2cc927UL; +#endif + +extern "C" void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ + /* { dg-final { scan-assembler ".quad 3280087301477736604" { target { lp64 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ + /* { dg-final { scan-assembler ".long -584267481" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C b/gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C new file mode 100644 index 00000000000..8b4e806edf1 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-hidden-2.C @@ -0,0 +1,20 @@ +/* { dg-do compile { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global" } */ + +#include <stddef.h> + +extern const size_t __stack_chk_guard; +__attribute__ ((visibility ("hidden"))) +extern const size_t __stack_chk_guard; + +void +smash (char *p, int i) +{ + p[i] = 42; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ diff --git a/gcc/testsuite/g++.target/i386/ssp-global-hidden-3.C b/gcc/testsuite/g++.target/i386/ssp-global-hidden-3.C new file mode 100644 index 00000000000..ca0508cac1d --- /dev/null +++ b/gcc/testsuite/g++.target/i386/ssp-global-hidden-3.C @@ -0,0 +1,51 @@ +/* { dg-do run { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -mstack-protector-guard=global -save-temps" } */ + +#ifndef __stack_protection_guard_is_internal_symbol__ +# error "__stack_protection_guard_is_internal_symbol__ isn't defined" +#endif + +#include <stdlib.h> +#include <stddef.h> + +extern "C" +__attribute__ ((visibility ("hidden"))) +#ifdef __LP64__ +const size_t __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +const size_t __stack_chk_guard = 0xdd2cc927UL; +#endif + +extern "C" void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +__attribute__ ((optimize ("stack-protector-all"))) +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ + /* { dg-final { scan-assembler ".quad 3280087301477736604" { target { lp64 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ + /* { dg-final { scan-assembler ".long -584267481" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-2.c b/gcc/testsuite/gcc.target/i386/ssp-global-2.c new file mode 100644 index 00000000000..11b69909327 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-2.c @@ -0,0 +1,35 @@ +/* { dg-do run { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */ + +#include <stdlib.h> + +#ifdef __LP64__ +long int __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +int __stack_chk_guard = 0xdd2cc927UL; +#endif + +void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-3.c b/gcc/testsuite/gcc.target/i386/ssp-global-3.c new file mode 100644 index 00000000000..b276e3f5833 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-3.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */ + +extern char *__stack_chk_guard; /* { dg-error "conflicting types for '__stack_chk_guard';" } */ + +char +foo (void) +{ + return *__stack_chk_guard; +} diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-4.c b/gcc/testsuite/gcc.target/i386/ssp-global-4.c new file mode 100644 index 00000000000..cf375b704f2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-4.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */ + +extern char __stack_chk_guard; /* { dg-error "conflicting types for '__stack_chk_guard';" } */ + +void +smash (char *p, int i) +{ + p[i] = 42; +} diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c new file mode 100644 index 00000000000..092d68f049c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-1.c @@ -0,0 +1,49 @@ +/* { dg-do run { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global -save-temps" } */ + +#ifndef __stack_protection_guard_is_internal_symbol__ +# error "__stack_protection_guard_is_internal_symbol__ isn't defined" +#endif + +#include <stdlib.h> +#include <stddef.h> + +__attribute__ ((visibility ("hidden"))) +#ifdef __LP64__ +const size_t __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +const size_t __stack_chk_guard = 0xdd2cc927UL; +#endif + +void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ + /* { dg-final { scan-assembler ".quad 3280087301477736604" { target { lp64 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ + /* { dg-final { scan-assembler ".long -584267481" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c new file mode 100644 index 00000000000..8b4e806edf1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global" } */ + +#include <stddef.h> + +extern const size_t __stack_chk_guard; +__attribute__ ((visibility ("hidden"))) +extern const size_t __stack_chk_guard; + +void +smash (char *p, int i) +{ + p[i] = 42; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/ssp-global-hidden-3.c b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-3.c new file mode 100644 index 00000000000..f73856c581f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ssp-global-hidden-3.c @@ -0,0 +1,50 @@ +/* { dg-do run { target { fstack_protector && fpic } } } */ +/* { dg-options "-O2 -fPIC -mstack-protector-guard=global -save-temps" } */ + +#ifndef __stack_protection_guard_is_internal_symbol__ +# error "__stack_protection_guard_is_internal_symbol__ isn't defined" +#endif + +#include <stdlib.h> +#include <stddef.h> + +__attribute__ ((visibility ("hidden"))) +#ifdef __LP64__ +const size_t __stack_chk_guard = 0x2d853605a4d9a09cUL; +#else +const size_t __stack_chk_guard = 0xdd2cc927UL; +#endif + +void +__stack_chk_fail (void) +{ + exit (0); /* pass */ +} + +__attribute__ ((noipa)) +void +smash (char *p, int i) +{ + p[i] = 42; +} + +__attribute__ ((optimize ("stack-protector-all"))) +int +main (void) +{ + char foo[255]; + + /* smash stack */ + for (int i = 0; i <= 400; i++) + smash (foo, i); + + return 1; +} + +/* { dg-final { scan-hidden "__stack_chk_guard" } } */ +/* { dg-final { scan-assembler "__stack_chk_guard\\(%rip\\)" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOTPCREL" { target { ! ia32 } } } } */ + /* { dg-final { scan-assembler ".quad 3280087301477736604" { target { lp64 } } } } */ +/* { dg-final { scan-assembler "__stack_chk_guard@GOTOFF" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "__stack_chk_guard@GOT\\(" { target ia32 } } } */ + /* { dg-final { scan-assembler ".long -584267481" { target { ! lp64 } } } } */ -- 2.51.0
