}
}
+ /* 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 =
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)
{
#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
@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
@hook TARGET_STACK_PROTECT_GUARD
+@hook TARGET_STACK_PROTECT_GUARD_SYMBOL_P
+
@hook TARGET_STACK_PROTECT_FAIL
@hook TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
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
{
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;
/* 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;
}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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'" } */
--- /dev/null
+/* { 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'" } */
--- /dev/null
+/* { dg-do run { target { fstack_protector && fpic } } } */
+/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global -save-temps" } */
+
+#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 } } } } */
--- /dev/null
+/* { 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 } } } */
--- /dev/null
+/* { dg-do run { target { fstack_protector && fpic } } } */
+/* { dg-options "-O2 -fPIC -mstack-protector-guard=global -save-temps" } */
+
+#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 } } } } */
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { dg-do run { target { fstack_protector && fpic } } } */
+/* { dg-options "-O2 -fPIC -fstack-protector-all -mstack-protector-guard=global -save-temps" } */
+
+#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 } } } } */
--- /dev/null
+/* { 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 } } } */
--- /dev/null
+/* { dg-do run { target { fstack_protector && fpic } } } */
+/* { dg-options "-O2 -fPIC -mstack-protector-guard=global -save-temps" } */
+
+#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 } } } } */
/* { 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