summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-09-10 10:56:36 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-09-10 10:56:36 +0000
commitc6eebf721ef39cd501b72356dcfcc517ac3da9bc (patch)
tree6c57aa5062b779e31c3084f649a3de49d2bf6fbf /gnu
parentfe229282140b36bac29b62e9f1d2dc4cd8acfb1b (diff)
Makde gcc handle __stack_smash_handler similarly to memcpy and memset when
creating calls: cache the RTL, let a declaration alter the asm spec, and set the same RTL attributes. For all three, let a declaration set the ELF visibility. ok miod@
Diffstat (limited to 'gnu')
-rw-r--r--gnu/gcc/gcc/c-common.c4
-rw-r--r--gnu/gcc/gcc/c-decl.c24
-rw-r--r--gnu/gcc/gcc/expr.c18
-rw-r--r--gnu/gcc/gcc/expr.h5
-rw-r--r--gnu/gcc/gcc/targhooks.c59
5 files changed, 71 insertions, 39 deletions
diff --git a/gnu/gcc/gcc/c-common.c b/gnu/gcc/gcc/c-common.c
index 68db97e8c05..be20dd52c65 100644
--- a/gnu/gcc/gcc/c-common.c
+++ b/gnu/gcc/gcc/c-common.c
@@ -3416,9 +3416,9 @@ set_builtin_user_assembler_name (tree decl, const char *asmspec)
builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
set_user_assembler_name (builtin, asmspec);
if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
- init_block_move_fn (asmspec);
+ init_block_move_fn (decl, asmspec);
else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
- init_block_clear_fn (asmspec);
+ init_block_clear_fn (decl, asmspec);
}
/* The number of named compound-literals generated thus far. */
diff --git a/gnu/gcc/gcc/c-decl.c b/gnu/gcc/gcc/c-decl.c
index 042a2e1291c..f09ffd96a04 100644
--- a/gnu/gcc/gcc/c-decl.c
+++ b/gnu/gcc/gcc/c-decl.c
@@ -3484,16 +3484,6 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
TREE_USED (decl) = 1;
}
- /* If this is a function and an assembler name is specified, reset DECL_RTL
- so we can give it its new name. Also, update built_in_decls if it
- was a normal built-in. */
- if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
- {
- if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
- set_builtin_user_assembler_name (decl, asmspec);
- set_user_assembler_name (decl, asmspec);
- }
-
/* If #pragma weak was used, mark the decl weak now. */
maybe_apply_pragma_weak (decl);
@@ -3513,12 +3503,24 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
if (asmspec)
{
+ /* If this is a function and an assembler name is specified,
+ reset DECL_RTL so we can give it its new name. Also,
+ update built_in_decls if it was a normal built-in. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ set_builtin_user_assembler_name (decl, asmspec);
+ else if (strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
+ "__stack_smash_handler") == 0)
+ init_stack_smash_fn (decl, asmspec);
+ set_user_assembler_name (decl, asmspec);
+ }
/* If this is not a static variable, issue a warning.
It doesn't make any sense to give an ASMSPEC for an
ordinary, non-register local variable. Historically,
GCC has accepted -- but ignored -- the ASMSPEC in
this case. */
- if (!DECL_FILE_SCOPE_P (decl)
+ else if (!DECL_FILE_SCOPE_P (decl)
&& TREE_CODE (decl) == VAR_DECL
&& !C_DECL_REGISTER (decl)
&& !TREE_STATIC (decl))
diff --git a/gnu/gcc/gcc/expr.c b/gnu/gcc/gcc/expr.c
index c6bc4263b86..8c5c80e1f66 100644
--- a/gnu/gcc/gcc/expr.c
+++ b/gnu/gcc/gcc/expr.c
@@ -1393,7 +1393,7 @@ emit_block_move_via_libcall (rtx dst, rtx src, rtx size, bool tailcall)
static GTY(()) tree block_move_fn;
void
-init_block_move_fn (const char *asmspec)
+init_block_move_fn (tree decl, const char *asmspec)
{
if (!block_move_fn)
{
@@ -1409,7 +1409,10 @@ init_block_move_fn (const char *asmspec)
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
- DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
+ if (decl != NULL_TREE && DECL_VISIBILITY_SPECIFIED (decl))
+ DECL_VISIBILITY (fn) = DECL_VISIBILITY (decl);
+ else
+ DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
DECL_VISIBILITY_SPECIFIED (fn) = 1;
block_move_fn = fn;
@@ -1425,7 +1428,7 @@ emit_block_move_libcall_fn (int for_call)
static bool emitted_extern;
if (!block_move_fn)
- init_block_move_fn (NULL);
+ init_block_move_fn (NULL_TREE, NULL);
if (for_call && !emitted_extern)
{
@@ -2597,7 +2600,7 @@ clear_storage_via_libcall (rtx object, rtx size, bool tailcall)
static GTY(()) tree block_clear_fn;
void
-init_block_clear_fn (const char *asmspec)
+init_block_clear_fn (tree decl, const char *asmspec)
{
if (!block_clear_fn)
{
@@ -2613,7 +2616,10 @@ init_block_clear_fn (const char *asmspec)
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
- DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
+ if (decl != NULL_TREE && DECL_VISIBILITY_SPECIFIED (decl))
+ DECL_VISIBILITY (fn) = DECL_VISIBILITY (decl);
+ else
+ DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
DECL_VISIBILITY_SPECIFIED (fn) = 1;
block_clear_fn = fn;
@@ -2629,7 +2635,7 @@ clear_storage_libcall_fn (int for_call)
static bool emitted_extern;
if (!block_clear_fn)
- init_block_clear_fn (NULL);
+ init_block_clear_fn (NULL_TREE, NULL);
if (for_call && !emitted_extern)
{
diff --git a/gnu/gcc/gcc/expr.h b/gnu/gcc/gcc/expr.h
index 42b98937a82..c4434850c93 100644
--- a/gnu/gcc/gcc/expr.h
+++ b/gnu/gcc/gcc/expr.h
@@ -373,8 +373,9 @@ enum block_op_methods
BLOCK_OP_TAILCALL
};
-extern void init_block_move_fn (const char *);
-extern void init_block_clear_fn (const char *);
+extern void init_block_move_fn (tree, const char *);
+extern void init_block_clear_fn (tree, const char *);
+extern void init_stack_smash_fn (tree, const char *);
extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
diff --git a/gnu/gcc/gcc/targhooks.c b/gnu/gcc/gcc/targhooks.c
index 802df49b2cd..ce7bdbd9fa3 100644
--- a/gnu/gcc/gcc/targhooks.c
+++ b/gnu/gcc/gcc/targhooks.c
@@ -393,10 +393,49 @@ static GTY(()) int stack_protect_labelno;
#include "c-common.h"
+static GTY(()) tree stack_smash_fn;
+
+void
+init_stack_smash_fn (tree decl, const char *asmspec)
+{
+ if (!stack_smash_fn)
+ {
+ tree args, fn;
+
+ fn = get_identifier ("__stack_smash_handler");
+ args = build_function_type_list (void_type_node, ptr_type_node,
+ NULL_TREE);
+ fn = build_decl (FUNCTION_DECL, fn, args);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ TREE_THIS_VOLATILE (fn) = 1;
+ TREE_NOTHROW (fn) = 1;
+ if (decl != NULL_TREE && DECL_VISIBILITY_SPECIFIED (decl))
+ DECL_VISIBILITY (fn) = DECL_VISIBILITY (decl);
+ else
+ DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
+ DECL_VISIBILITY_SPECIFIED (fn) = 1;
+ stack_smash_fn = fn;
+ }
+
+ if (asmspec)
+ set_user_assembler_name (stack_smash_fn, asmspec);
+}
+
+static tree
+emit_stack_smash_libcall_fn (void)
+{
+ if (!stack_smash_fn)
+ init_stack_smash_fn (NULL_TREE, NULL);
+
+ return stack_smash_fn;
+}
+
tree
default_external_stack_protect_fail (void)
{
- tree t, func, type, init, stack_smash_handler;
+ tree t, func, type, init;
const char *name = fname_as_string (0);
size_t length = strlen (name);
char name_buf[32];
@@ -420,26 +459,10 @@ default_external_stack_protect_fail (void)
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);
- t = build_decl (FUNCTION_DECL, get_identifier ("__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);
t = tree_cons (NULL, t, NULL);
- return build_function_call_expr (stack_smash_handler, t);
+ return build_function_call_expr (emit_stack_smash_libcall_fn (), t);
}
tree