summaryrefslogtreecommitdiff
path: root/gcc/ipa-chkp.c
diff options
context:
space:
mode:
authorienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-17 13:45:55 +0000
committerienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-17 13:45:55 +0000
commitf21337ef57463b10070852e9e38f4b364c29a616 (patch)
treebc2f2a46968faabdbe890355b0f2b9b151a106bb /gcc/ipa-chkp.c
parent3bbe8db09c0e074f83a19566ba596679f8a50cd2 (diff)
downloadgcc-f21337ef57463b10070852e9e38f4b364c29a616.tar.gz
* tree-core.h (built_in_class): Add builtin codes to be used
by Pointer Bounds Checker for instrumented builtin functions. * tree-streamer-in.c: Include ipa-chkp.h. (streamer_get_builtin_tree): Created instrumented decl if required. * ipa-chkp.h (chkp_maybe_clone_builtin_fndecl): New. * ipa-chkp.c (chkp_build_instrumented_fndecl): Support builtin function decls. (chkp_maybe_clone_builtin_fndecl): New. (chkp_maybe_create_clone): Support builtin function decls. (chkp_versioning): Clone builtin functions. * tree-chkp.c (chkp_instrument_normal_builtin): New. (chkp_add_bounds_to_call_stmt): Support builtin functions. (chkp_replace_function_pointer): Likewise. * builtins.c (expand_builtin_memcpy_args): New. (expand_builtin_memcpy): Call expand_builtin_memcpy_args. (expand_builtin_memcpy_with_bounds): New. (expand_builtin_mempcpy_with_bounds): New. (expand_builtin_mempcpy_args): Add orig_exp arg. Support BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK (expand_builtin_memset_with_bounds): New. (expand_builtin_memset_args): Support BUILT_IN_CHKP_MEMSET_NOBND_NOCHK. (expand_builtin_with_bounds): New. * builtins.h (expand_builtin_with_bounds): New. * expr.c (expand_expr_real_1): Support instrumented builtin calls. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217655 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-chkp.c')
-rw-r--r--gcc/ipa-chkp.c99
1 files changed, 97 insertions, 2 deletions
diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
index 19a989453b6..46b2139758a 100644
--- a/gcc/ipa-chkp.c
+++ b/gcc/ipa-chkp.c
@@ -129,6 +129,16 @@ chkp_build_instrumented_fndecl (tree fndecl)
make own copy. */
DECL_ATTRIBUTES (new_decl) = copy_list (DECL_ATTRIBUTES (fndecl));
+ /* Change builtin function code. */
+ if (DECL_BUILT_IN (new_decl))
+ {
+ gcc_assert (DECL_BUILT_IN_CLASS (new_decl) == BUILT_IN_NORMAL);
+ gcc_assert (DECL_FUNCTION_CODE (new_decl) < BEGIN_CHKP_BUILTINS);
+ DECL_FUNCTION_CODE (new_decl)
+ = (enum built_in_function)(DECL_FUNCTION_CODE (new_decl)
+ + BEGIN_CHKP_BUILTINS + 1);
+ }
+
return new_decl;
}
@@ -354,6 +364,33 @@ chkp_add_bounds_params_to_function (tree fndecl)
chkp_copy_function_type_adding_bounds (TREE_TYPE (fndecl));
}
+/* Return an instrumentation clone for builtin function
+ FNDECL. Create one if needed. */
+
+tree
+chkp_maybe_clone_builtin_fndecl (tree fndecl)
+{
+ tree clone;
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+
+ gcc_assert (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && fcode < BEGIN_CHKP_BUILTINS);
+
+ fcode = (enum built_in_function) (fcode + BEGIN_CHKP_BUILTINS + 1);
+ clone = builtin_decl_explicit (fcode);
+ if (clone)
+ return clone;
+
+ clone = chkp_build_instrumented_fndecl (fndecl);
+ chkp_add_bounds_params_to_function (clone);
+
+ gcc_assert (DECL_FUNCTION_CODE (clone) == fcode);
+
+ set_builtin_decl (fcode, clone, false);
+
+ return clone;
+}
+
/* Return clone created for instrumentation of NODE or NULL. */
cgraph_node *
@@ -364,6 +401,54 @@ chkp_maybe_create_clone (tree fndecl)
gcc_assert (!node->instrumentation_clone);
+ if (DECL_BUILT_IN (fndecl)
+ && (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL
+ || DECL_FUNCTION_CODE (fndecl) >= BEGIN_CHKP_BUILTINS))
+ return NULL;
+
+ clone = node->instrumented_version;
+
+ /* Some instrumented builtin function calls may be optimized and
+ cgraph nodes may be removed as unreachable. Later optimizations
+ may generate new calls to removed functions and in this case
+ we have to recreate cgraph node. FUNCTION_DECL for instrumented
+ builtin still exists and should be reused in such case. */
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && fndecl == builtin_decl_explicit (DECL_FUNCTION_CODE (fndecl))
+ && !clone)
+ {
+ enum built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
+ tree new_decl;
+
+ fncode = (enum built_in_function) (fncode + BEGIN_CHKP_BUILTINS + 1);
+ new_decl = builtin_decl_explicit (fncode);
+
+ /* We've actually already created an instrumented clone once.
+ Restore it. */
+ if (new_decl)
+ {
+ clone = cgraph_node::get (new_decl);
+
+ if (!clone)
+ {
+ gcc_assert (!gimple_has_body_p (fndecl));
+ clone = cgraph_node::get_create (new_decl);
+ clone->externally_visible = node->externally_visible;
+ clone->local = node->local;
+ clone->address_taken = node->address_taken;
+ clone->thunk = node->thunk;
+ clone->alias = node->alias;
+ clone->weakref = node->weakref;
+ clone->cpp_implicit_alias = node->cpp_implicit_alias;
+ clone->orig_decl = fndecl;
+ clone->instrumentation_clone = true;
+ }
+
+ clone->instrumented_version = node;
+ node->instrumented_version = clone;
+ }
+ }
+
if (!clone)
{
tree new_decl = chkp_build_instrumented_fndecl (fndecl);
@@ -408,6 +493,15 @@ chkp_maybe_create_clone (tree fndecl)
actually copies args list from the original decl. */
chkp_add_bounds_params_to_function (new_decl);
+ /* Remember builtin fndecl. */
+ if (DECL_BUILT_IN_CLASS (clone->decl) == BUILT_IN_NORMAL
+ && fndecl == builtin_decl_explicit (DECL_FUNCTION_CODE (fndecl)))
+ {
+ gcc_assert (!builtin_decl_explicit (DECL_FUNCTION_CODE (clone->decl)));
+ set_builtin_decl (DECL_FUNCTION_CODE (clone->decl),
+ clone->decl, false);
+ }
+
/* Clones have the same comdat group as originals. */
if (node->same_comdat_group
|| DECL_ONE_ONLY (node->decl))
@@ -487,8 +581,9 @@ chkp_versioning (void)
&& (!flag_chkp_instrument_marked_only
|| lookup_attribute ("bnd_instrument",
DECL_ATTRIBUTES (node->decl)))
- /* No builtins instrumentation for now. */
- && DECL_BUILT_IN_CLASS (node->decl) == NOT_BUILT_IN)
+ && (!DECL_BUILT_IN (node->decl)
+ || (DECL_BUILT_IN_CLASS (node->decl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (node->decl) < BEGIN_CHKP_BUILTINS)))
chkp_maybe_create_clone (node->decl);
}