summaryrefslogtreecommitdiff
path: root/gcc/libgcc2.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-06-27 00:41:16 -0700
committerJakub Jelinek <jakub@gcc.gnu.org>2005-06-27 09:41:16 +0200
commit7d69de618e732d343228a07d797a30e39a6363f4 (patch)
treeec9a39649967b762606a254cf15ed23a12ed7401 /gcc/libgcc2.c
parent2bcf2e2bf17d13a20c587d056f3426fda0106379 (diff)
downloadgcc-7d69de618e732d343228a07d797a30e39a6363f4.tar.gz
c-cppbuiltin.c (c_cpp_builtins): Add __SSP_ALL__ and __SSP__.
* c-cppbuiltin.c (c_cpp_builtins): Add __SSP_ALL__ and __SSP__. * cfgexpand.c: Include params.h. (has_protected_decls, has_short_buffer): New. (expand_stack_vars): Take a predicate to determine what to expand. (defer_stack_allocation): True when flag_stack_protect on. (SPCT_HAS_LARGE_CHAR_ARRAY, SPCT_HAS_SMALL_CHAR_ARRAY): New. (SPCT_HAS_ARRAY, SPCT_HAS_AGGREGATE): New. (stack_protect_classify_type, stack_protect_decl_phase): New. (stack_protect_decl_phase_1, stack_protect_decl_phase_2): New. (add_stack_protection_conflicts, create_stack_guard): New. (expand_used_vars): Add stack protection logic. (tree_expand_cfg): Likewise. * common.opt (Wstack-protector): New. (fstack-protector, fstack-protector-all): New. * function.c: Include predict.h. (assign_parm_adjust_stack_rtl): Zap stack_parm when stack protect wants to copy the parameter into the stack frame. (stack_protect_prologue, stack_protect_epilogue): New. (expand_function_end): Call stack_protect_epilogue. Do sjlj_emit_function_exit_after after naked_return_label. * function.h (struct function): Add stack_protect_guard. * params.def (PARAM_SSP_BUFFER_SIZE): New. * toplev.c (process_options): Disable flag_stack_protect and/or warn_stack_protect based on FRAME_GROWS_DOWNWARD. * tree.h (stack_protect_prologue): Declare. * target-def.h (TARGET_STACK_PROTECT_GUARD): New. (TARGET_STACK_PROTECT_FAIL): New. (TARGET_INITIALIZER): Add them. * target.h (struct gcc_target): Add stack_protect_guard and stack_protect_fail. * targhooks.c: Include ggc.h, gty header. (stack_chk_guard_decl, default_stack_protect_guard): New. (stack_chk_fail_decl, default_external_stack_protect_fail): New. (default_hidden_stack_protect_fail): New. * targhooks.h (default_stack_protect_guard): Declare. (default_external_stack_protect_fail): Declare. (default_hidden_stack_protect_fail): Declare. * config/i386/i386.c (TARGET_STACK_PROTECT_FAIL): New. * config/i386/i386.md (UNSPEC_SP_SET, UNSPEC_SP_TEST): New. (trap): Use ud2. (conditional_trap, conditional_trap_1): Remove. (stack_protect_set, stack_protect_set_si, stack_protect_set_di): New. (stack_protect_test, stack_protect_test_si, stack_protect_test_di): New. * doc/md.texi (stack_protect_set, stack_protect_test): New. * doc/tm.texi (TARGET_STACK_PROTECT_GUARD): New. (TARGET_STACK_PROTECT_FAIL): New. * libgcc-std.ver (GCC_4.1.0): New. * libgcc.h (__stack_chk_guard): Declare. (__stack_chk_fail, __stack_chk_fail_local): Declare. * libgcc2.c (L_stack_chk, L_stack_chk_local): New. * mklibgcc.in (lib2funcs): Add them. From-SVN: r101348
Diffstat (limited to 'gcc/libgcc2.c')
-rw-r--r--gcc/libgcc2.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 3108bff6729..a49c8c128f9 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -2015,3 +2015,141 @@ func_ptr __DTOR_LIST__[2];
#endif
#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
#endif /* L_ctors */
+
+#ifdef L_stack_chk
+#ifndef TARGET_LIBC_PROVIDES_SSP
+
+#ifndef inhibit_libc
+# include <string.h>
+# include <unistd.h>
+# include <fcntl.h>
+# ifdef HAVE_PATHS_H
+# include <paths.h>
+# endif
+# ifndef _PATH_TTY
+# define _PATH_TTY "/dev/tty"
+# endif
+# ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+# endif
+#endif
+
+void *__stack_chk_guard = 0;
+
+static void __attribute__ ((constructor))
+__guard_setup (void)
+{
+ unsigned char *p;
+
+ if (__stack_chk_guard != 0)
+ return;
+
+#ifndef inhibit_libc
+ {
+ int fd = open ("/dev/urandom", O_RDONLY);
+ if (fd != -1)
+ {
+ ssize_t size = read (fd, &__stack_chk_guard,
+ sizeof (__stack_chk_guard));
+ close (fd);
+ if (size == sizeof(__stack_chk_guard))
+ return;
+ }
+ }
+#endif
+
+ /* If a random generator can't be used, the protector switches the guard
+ to the "terminator canary". */
+ p = (unsigned char *)&__stack_chk_guard;
+ p[sizeof(__stack_chk_guard)-1] = 255;
+ p[sizeof(__stack_chk_guard)-2] = '\n';
+ p[0] = 0;
+}
+
+void
+__stack_chk_fail (void)
+{
+#ifndef inhibit_libc
+# ifdef __GNU_LIBRARY__
+ extern char * __progname;
+# else
+ static const char __progname[] = "";
+# endif
+
+ int fd;
+
+ /* Print error message directly to the tty. This avoids Bad Things
+ happening if stderr is redirected. */
+ fd = open (_PATH_TTY, O_WRONLY);
+ if (fd != -1)
+ {
+ static const char msg1[] = "*** stack smashing detected ***: ";
+ static const char msg2[] = " terminated\n";
+ size_t progname_len, len;
+ char *buf, *p;
+
+ progname_len = strlen (__progname);
+ len = sizeof(msg1)-1 + progname_len + sizeof(msg2)-1 + 1;
+ p = buf = alloca (len);
+
+ memcpy (p, msg1, sizeof(msg1)-1);
+ p += sizeof(msg1)-1;
+ memcpy (p, __progname, progname_len);
+ p += progname_len;
+ memcpy (p, msg2, sizeof(msg2));
+
+ while (len > 0)
+ {
+ ssize_t wrote = write (fd, buf, len);
+ if (wrote < 0)
+ break;
+ len -= wrote;
+ }
+ close (fd);
+ }
+
+# ifdef HAVE_SYSLOG_H
+ /* Only send the error to syslog if there was no tty available. */
+ else
+ syslog (LOG_CRIT, "stack smashing detected: terminated");
+# endif /* HAVE_SYSLOG_H */
+#endif /* inhibit_libc */
+
+ /* Try very hard to exit. Note that signals may be blocked preventing
+ the first two options from working. The use of volatile is here to
+ prevent optimizers from "knowing" that __builtin_trap is called first,
+ and that it doesn't return, and so "obviously" the rest of the code
+ is dead. */
+ {
+ volatile int state;
+ for (state = 0; ; state++)
+ switch (state)
+ {
+ case 0:
+ __builtin_trap ();
+ break;
+ case 1:
+ *(volatile int *)-1L = 0;
+ break;
+ case 2:
+ _exit (127);
+ break;
+ }
+ }
+}
+#endif /* TARGET_LIBC_PROVIDES_SSP */
+#endif /* L_stack_chk */
+
+#ifdef L_stack_chk_local
+#ifndef TARGET_LIBC_PROVIDES_SSP
+/* Some targets can avoid loading a GP for calls to hidden functions.
+ Using this entry point may avoid the load of a GP entirely for the
+ function, making the overall code smaller. */
+
+void
+__stack_chk_fail_local (void)
+{
+ __stack_chk_fail ();
+}
+#endif /* TARGET_LIBC_PROVIDES_SSP */
+#endif /* L_stack_chk_local */