On Sun, Oct 26, 2025 at 10:29:30AM +0800, H.J. Lu wrote: > 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 ()) Maybe a matter of taste: since stack_protect_guard_symbol() does not return an RTX symbol but is rather a predicate, maybe naming it differently like sp_guard_internal_symbol_p or something along the lines would make that more clear. > + { > + 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; ~~~^ Shouldn't this be also changed? Maybe something like bool is_internal = targetm.stack_protect_guard_symbol () && (TYPE_PRECISION (size_type_node) == TYPE_PRECISION (ptr_type_node)); if (is_internal) t = size_type_node; else t = ptr_type_node; ... DECL_EXTERNAL (t) = !is_internal; Cheers, Stefan > @@ -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 >
