Index: gcc/targhooks.c --- gcc/targhooks.c.orig +++ gcc/targhooks.c @@ -64,6 +64,7 @@ along with GCC; see the file COPYING3. If not see #include "optabs.h" #include "regs.h" #include "recog.h" +#include "c-family/c-common.h" #include "diagnostic-core.h" #include "fold-const.h" #include "stor-layout.h" @@ -866,7 +867,7 @@ default_stack_protect_guard (void) rtx x; t = build_decl (UNKNOWN_LOCATION, - VAR_DECL, get_identifier ("__stack_chk_guard"), + VAR_DECL, get_identifier ("__guard_local"), ptr_type_node); TREE_STATIC (t) = 1; TREE_PUBLIC (t) = 1; @@ -875,6 +876,8 @@ default_stack_protect_guard (void) TREE_THIS_VOLATILE (t) = 1; DECL_ARTIFICIAL (t) = 1; DECL_IGNORED_P (t) = 1; + DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; + DECL_VISIBILITY_SPECIFIED (t) = 1; /* Do not share RTL as the declaration is visible outside of current function. */ @@ -887,67 +890,72 @@ default_stack_protect_guard (void) return t; } -static GTY(()) tree stack_chk_fail_decl; +static GTY(()) int stack_protect_labelno; tree default_external_stack_protect_fail (void) { - tree t = stack_chk_fail_decl; + tree t, func, type, init, stack_smash_handler; + const char *tmp_name; + char *name; + size_t length; + char name_buf[32]; - if (t == NULL_TREE) - { - t = build_function_type_list (void_type_node, NULL_TREE); - t = build_decl (UNKNOWN_LOCATION, - FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t); - TREE_STATIC (t) = 1; - TREE_PUBLIC (t) = 1; - DECL_EXTERNAL (t) = 1; - TREE_USED (t) = 1; - TREE_THIS_VOLATILE (t) = 1; - TREE_NOTHROW (t) = 1; - DECL_ARTIFICIAL (t) = 1; - DECL_IGNORED_P (t) = 1; - DECL_VISIBILITY (t) = VISIBILITY_DEFAULT; - DECL_VISIBILITY_SPECIFIED (t) = 1; + name = (char *)xmalloc(32); + if (NULL == (tmp_name = fname_as_string (0))) { + strlcpy (name, "*unknown*", 32); + } else { + strlcpy (name, tmp_name, 32); + } + + length = strlen (name); + /* Build a decl for __func__. */ + type = build_array_type (char_type_node, + build_index_type (size_int (length))); + type = build_qualified_type (type, TYPE_QUAL_CONST); - stack_chk_fail_decl = t; - } + init = build_string (length + 1, name); + free ((char *) name); + TREE_TYPE (init) = type; - return build_call_expr (t, 0); + func = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, type); + TREE_STATIC (func) = 1; + TREE_READONLY (func) = 1; + DECL_ARTIFICIAL (func) = 1; + ASM_GENERATE_INTERNAL_LABEL (name_buf, "LSSH", stack_protect_labelno++); + DECL_NAME (func) = get_identifier (name_buf); + DECL_INITIAL (func) = init; + + assemble_variable (func, 0, 0, 0); + + /* Build a decl for __stack_smash_handler. */ + t = build_pointer_type (TREE_TYPE (func)); + t = build_function_type_list (void_type_node, t, NULL_TREE); + t = build_decl (UNKNOWN_LOCATION, + FUNCTION_DECL, get_identifier ("__stack_smash_handler"), t); + /* t = build_fn_decl ("__stack_smash_handler", t); */ + TREE_STATIC (t) = 1; + TREE_PUBLIC (t) = 1; + DECL_EXTERNAL (t) = 1; + TREE_USED (t) = 1; + TREE_THIS_VOLATILE (t) = 1; + TREE_NOTHROW (t) = 1; + DECL_ARTIFICIAL (t) = 1; + DECL_IGNORED_P (t) = 1; + DECL_VISIBILITY (t) = VISIBILITY_DEFAULT; + DECL_VISIBILITY_SPECIFIED (t) = 1; + + stack_smash_handler = t; + + /* Generate a call to __stack_smash_handler(__func__). */ + t = build_fold_addr_expr (func); + return build_call_expr (stack_smash_handler, 1, t); } tree default_hidden_stack_protect_fail (void) { -#ifndef HAVE_GAS_HIDDEN return default_external_stack_protect_fail (); -#else - tree t = stack_chk_fail_decl; - - if (!flag_pic) - return default_external_stack_protect_fail (); - - if (t == NULL_TREE) - { - t = build_function_type_list (void_type_node, NULL_TREE); - t = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, - get_identifier ("__stack_chk_fail_local"), t); - TREE_STATIC (t) = 1; - TREE_PUBLIC (t) = 1; - DECL_EXTERNAL (t) = 1; - TREE_USED (t) = 1; - TREE_THIS_VOLATILE (t) = 1; - TREE_NOTHROW (t) = 1; - DECL_ARTIFICIAL (t) = 1; - DECL_IGNORED_P (t) = 1; - DECL_VISIBILITY_SPECIFIED (t) = 1; - DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; - - stack_chk_fail_decl = t; - } - - return build_call_expr (t, 0); -#endif } bool