On Sun, Feb 1, 2026 at 10:27 AM Jason Merrill <[email protected]> wrote:
>
> On 1/31/26 8:11 PM, H.J. Lu wrote:
> > Change in the v8 patch:
> >
> > 1.  __stack_chk_guard must be an uintptr_t variable.
> > 2.  Remove c_stack_protect_guard_decl_p and
> > duplicate_stack_protect_guard_decl_p.
>
> Thanks.
>
> > @@ -926,7 +926,7 @@ default_stack_protect_guard (void)
> >
> >        t = build_decl (UNKNOWN_LOCATION,
> >                     VAR_DECL, get_identifier ("__stack_chk_guard"),
> > -                   ptr_type_node);
> > +                   lang_hooks.types.type_for_mode (ptr_mode, 1));
>
> Should this change be conditional on
> targetm.stack_protect_guard_symbol_p ()?

Changed.

> > +  /* Define this to indicate that the stack protection guard symbol,
> > +     "__stack_chk_guard", is an internal symbol.  */
> > +  if (targetm.stack_protect_guard_symbol_p ())
> > +    cpp_define (pfile, "__stack_protection_guard_is_internal_symbol__");
>
> Why "internal"?  I read "internal" as internal linkage, i.e. "static",
> and in the testcases the symbols all have external linkage, and it's
> based on TARGET_SSP_GLOBAL_GUARD.
>
> Maybe the macro should be something like
> __stack_protection_guard_declared__?

Changed.

Here is the v9 patch.

-- 
H.J.

Add a new target hook, stack_protect_guard_symbol_p, to support the user
provided stack protection guard as a global symbol.  If the hook returns
true,

1. Declare __stack_chk_guard as a global uintptr_t variable so that it
can be initialized as an integer.
2. If the user declared variable matches __stack_chk_guard, merge it with
__stack_chk_guard, including its visibility attribute.
3. Define the __stack_protection_guard_declared__ macro to indicate that
__stack_chk_guard is declared as a global symbol.

gcc/

PR c/121911
* target.def (stack_protect_guard_symbol_p): New target hook.
* targhooks.cc (default_stack_protect_guard): Use the type of
uintptr_t, instead of ptr_type_node, if the
stack_protect_guard_symbol_p hook returns true.
* config/i386/i386.cc (ix86_stack_protect_guard_symbol_p): New.
(TARGET_STACK_PROTECT_GUARD_SYMBOL_P): Likewise.
* doc/tm.texi: Regenerated.
* doc/tm.texi.in (TARGET_STACK_PROTECT_GUARD_SYMBOL_P): New.

gcc/c-family/

PR c/121911
* c-common.cc (c_common_nodes_and_builtins): If the
stack_protect_guard_symbol_p hook returns true, declare a global
symbol for stack protection guard.
* c-cppbuiltin.cc (c_cpp_builtins): Define the
__stack_protection_guard_declared__ macro if the
stack_protect_guard_symbol_p hook returns true.

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-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.
* gcc.target/i386/ssp-global.c: Include <stdint.h>.
(__stack_chk_guard): Change its type to uintptr_t.
From 99b7343d5a4a04502f4e1bf43c841f19a1d67e1f Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Fri, 12 Sep 2025 18:52:39 -0700
Subject: [PATCH v9] c/c++: Declare stack protection guard as a global symbol

Add a new target hook, stack_protect_guard_symbol_p, to support the user
provided stack protection guard as a global symbol.  If the hook returns
true,

1. Declare __stack_chk_guard as a global uintptr_t variable so that it
can be initialized as an integer.
2. If the user declared variable matches __stack_chk_guard, merge it with
__stack_chk_guard, including its visibility attribute.
3. Define the __stack_protection_guard_declared__ macro to indicate that
__stack_chk_guard is declared as a global symbol.

gcc/

	PR c/121911
	* target.def (stack_protect_guard_symbol_p): New target hook.
	* targhooks.cc (default_stack_protect_guard): Use the type of
	uintptr_t, instead of ptr_type_node, if the
	stack_protect_guard_symbol_p hook returns true.
	* config/i386/i386.cc (ix86_stack_protect_guard_symbol_p): New.
	(TARGET_STACK_PROTECT_GUARD_SYMBOL_P): Likewise.
	* doc/tm.texi: Regenerated.
	* doc/tm.texi.in (TARGET_STACK_PROTECT_GUARD_SYMBOL_P): New.

gcc/c-family/

	PR c/121911
	* c-common.cc (c_common_nodes_and_builtins): If the
	stack_protect_guard_symbol_p hook returns true, declare a global
	symbol for stack protection guard.
	* c-cppbuiltin.cc (c_cpp_builtins): Define the
	__stack_protection_guard_declared__ macro if the
	stack_protect_guard_symbol_p hook returns true.

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-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.
	* gcc.target/i386/ssp-global.c: Include <stdint.h>.
	(__stack_chk_guard): Change its type to uintptr_t.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/c-family/c-common.cc                      |  5 ++
 gcc/c-family/c-cppbuiltin.cc                  |  5 ++
 gcc/config/i386/i386.cc                       | 12 +++++
 gcc/doc/tm.texi                               |  7 +++
 gcc/doc/tm.texi.in                            |  2 +
 gcc/target.def                                | 11 ++++
 gcc/targhooks.cc                              | 17 +++++--
 gcc/testsuite/g++.target/i386/ssp-global-1.C  | 36 +++++++++++++
 gcc/testsuite/g++.target/i386/ssp-global-2.C  |  4 ++
 gcc/testsuite/g++.target/i386/ssp-global-3.C  |  4 ++
 .../g++.target/i386/ssp-global-hidden-1.C     | 49 ++++++++++++++++++
 .../g++.target/i386/ssp-global-hidden-2.C     | 20 ++++++++
 .../g++.target/i386/ssp-global-hidden-3.C     | 50 +++++++++++++++++++
 gcc/testsuite/gcc.target/i386/ssp-global-2.c  | 36 +++++++++++++
 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 +++++++++++++++++++
 gcc/testsuite/gcc.target/i386/ssp-global.c    |  5 +-
 20 files changed, 396 insertions(+), 6 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-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 7f891e1ef49..3d0557e02a0 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -4925,6 +4925,11 @@ c_common_nodes_and_builtins (void)
 	}
     }
 
+  /* Call the target stack_protect_guard hook if the stack protection
+     guard is declared as a global symbol.  */
+  if (targetm.stack_protect_guard_symbol_p ())
+    lang_hooks.decls.pushdecl (targetm.stack_protect_guard ());
+
   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
     {
       va_list_arg_type_node = va_list_ref_type_node =
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 12ddfa22074..7a761a6a9aa 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1190,6 +1190,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 declared as a global symbol.  */
+  if (targetm.stack_protect_guard_symbol_p ())
+    cpp_define (pfile, "__stack_protection_guard_declared__");
+
   /* 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/config/i386/i386.cc b/gcc/config/i386/i386.cc
index ea050f37b57..aefe1040cdc 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -25246,6 +25246,14 @@ ix86_stack_protect_guard (void)
   return default_stack_protect_guard ();
 }
 
+/* Implement TARGET_STACK_PROTECT_GUARD_SYMBOL_P.  */
+
+static bool
+ix86_stack_protect_guard_symbol_p (void)
+{
+  return TARGET_SSP_GLOBAL_GUARD;
+}
+
 static bool
 ix86_stack_protect_runtime_enabled_p (void)
 {
@@ -28225,6 +28233,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_P
+#define TARGET_STACK_PROTECT_GUARD_SYMBOL_P \
+  ix86_stack_protect_guard_symbol_p
+
 #undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
 #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P \
   ix86_stack_protect_runtime_enabled_p
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 394a46fdbaa..76a9f918e18 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5425,6 +5425,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_P (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} with the @code{uintptr_t} type 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 274bb899d0c..1acda0c264c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3825,6 +3825,8 @@ generic code.
 
 @hook TARGET_STACK_PROTECT_GUARD
 
+@hook TARGET_STACK_PROTECT_GUARD_SYMBOL_P
+
 @hook TARGET_STACK_PROTECT_FAIL
 
 @hook TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
diff --git a/gcc/target.def b/gcc/target.def
index 206c94f8749..f5531f759a8 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4654,6 +4654,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_p,
+ "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} with the @code{uintptr_t} type 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 7cb48192255..b2e7a02d71c 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -924,9 +924,12 @@ default_stack_protect_guard (void)
     {
       rtx x;
 
+      if (targetm.stack_protect_guard_symbol_p ())
+	t = lang_hooks.types.type_for_mode (ptr_mode, 1);
+      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 +940,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..5f4d64e3573
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/ssp-global-1.C
@@ -0,0 +1,36 @@
+/* { dg-do run { target fstack_protector } } */
+/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __LP64__
+uintptr_t __stack_chk_guard = 0x2d853605a4d9a09cUL;
+#else
+uintptr_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;
+}
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..e0e2e7d7f9b
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/ssp-global-2.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-3.C b/gcc/testsuite/g++.target/i386/ssp-global-3.C
new file mode 100644
index 00000000000..cc842b3d538
--- /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-hidden-1.C b/gcc/testsuite/g++.target/i386/ssp-global-hidden-1.C
new file mode 100644
index 00000000000..1add7b5adb3
--- /dev/null
+++ b/gcc/testsuite/g++.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_declared__
+# error "__stack_protection_guard_declared__ isn't defined"
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+
+__attribute__ ((visibility ("hidden")))
+#ifdef __LP64__
+uintptr_t __stack_chk_guard = 0x2d853605a4d9a09cUL;
+#else
+uintptr_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..9fd3b1d00d4
--- /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 <stdint.h>
+
+extern uintptr_t __stack_chk_guard;
+__attribute__ ((visibility ("hidden")))
+extern uintptr_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..b5428b8b625
--- /dev/null
+++ b/gcc/testsuite/g++.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_declared__
+# error "__stack_protection_guard_declared__ isn't defined"
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+
+__attribute__ ((visibility ("hidden")))
+#ifdef __LP64__
+uintptr_t __stack_chk_guard = 0x2d853605a4d9a09cUL;
+#else
+uintptr_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..760991f82bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/ssp-global-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target fstack_protector } } */
+/* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __LP64__
+uintptr_t __stack_chk_guard = 0x2d853605a4d9a09cUL;
+#else
+uintptr_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;
+}
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..a7273c53e98
--- /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_declared__
+# error "__stack_protection_guard_declared__ isn't defined"
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+
+__attribute__ ((visibility ("hidden")))
+#ifdef __LP64__
+uintptr_t __stack_chk_guard = 0x2d853605a4d9a09cUL;
+#else
+uintptr_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..9fd3b1d00d4
--- /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 <stdint.h>
+
+extern uintptr_t __stack_chk_guard;
+__attribute__ ((visibility ("hidden")))
+extern uintptr_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..0b220e65157
--- /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_declared__
+# error "__stack_protection_guard_declared__ isn't defined"
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+
+__attribute__ ((visibility ("hidden")))
+#ifdef __LP64__
+uintptr_t __stack_chk_guard = 0x2d853605a4d9a09cUL;
+#else
+uintptr_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 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/ssp-global.c b/gcc/testsuite/gcc.target/i386/ssp-global.c
index 85a288c781c..760991f82bf 100644
--- a/gcc/testsuite/gcc.target/i386/ssp-global.c
+++ b/gcc/testsuite/gcc.target/i386/ssp-global.c
@@ -1,12 +1,13 @@
 /* { dg-do run { target fstack_protector } } */
 /* { dg-options "-O2 -fstack-protector-all -mstack-protector-guard=global" } */
 
+#include <stdint.h>
 #include <stdlib.h>
 
 #ifdef __LP64__
-const unsigned long int __stack_chk_guard = 0x2d853605a4d9a09cUL;
+uintptr_t __stack_chk_guard = 0x2d853605a4d9a09cUL;
 #else
-const unsigned long int __stack_chk_guard = 0xdd2cc927UL;
+uintptr_t __stack_chk_guard = 0xdd2cc927UL;
 #endif
 
 void
-- 
2.52.0

Reply via email to