diff options
author | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-17 13:45:55 +0000 |
---|---|---|
committer | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-17 13:45:55 +0000 |
commit | f21337ef57463b10070852e9e38f4b364c29a616 (patch) | |
tree | bc2f2a46968faabdbe890355b0f2b9b151a106bb /gcc/ipa-chkp.c | |
parent | 3bbe8db09c0e074f83a19566ba596679f8a50cd2 (diff) | |
download | gcc-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.c | 99 |
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); } |