#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "vec.h"
-#include "double-int.h"
-#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "options.h"
-#include "wide-int.h"
-#include "inchash.h"
#include "tree.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "tm.h"
#include "hard-reg-set.h"
#include "function.h"
-#include "is-a.h"
+#include "calls.h"
#include "tree-ssa-alias.h"
#include "predict.h"
#include "basic-block.h"
#include "gimple.h"
-#include "ipa-ref.h"
#include "lto-streamer.h"
#include "cgraph.h"
#include "tree-chkp.h"
/* Return 1 calls to FNDECL should be replaced with
a call to wrapper function. */
-static bool
+bool
chkp_wrap_function (tree fndecl)
{
if (!flag_chkp_use_wrappers)
return false;
}
+static const char *
+chkp_wrap_function_name (tree fndecl)
+{
+ gcc_assert (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL);
+
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_STRLEN:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "strlen";
+ case BUILT_IN_STRCPY:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "strcpy";
+ case BUILT_IN_STRNCPY:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "strncpy";
+ case BUILT_IN_STPCPY:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "stpcpy";
+ case BUILT_IN_STPNCPY:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "stpncpy";
+ case BUILT_IN_STRCAT:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "strcat";
+ case BUILT_IN_STRNCAT:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "strncat";
+ case BUILT_IN_MEMCPY:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "memcpy";
+ case BUILT_IN_MEMPCPY:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "mempcpy";
+ case BUILT_IN_MEMSET:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "memset";
+ case BUILT_IN_MEMMOVE:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "memmove";
+ case BUILT_IN_BZERO:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "bzero";
+ case BUILT_IN_MALLOC:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "malloc";
+ case BUILT_IN_CALLOC:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "calloc";
+ case BUILT_IN_REALLOC:
+ return CHKP_WRAPPER_SYMBOL_PREFIX "realloc";
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return "";
+}
+
/* Build a clone of FNDECL with a modified name. */
static tree
instrumented version. */
if (chkp_wrap_function(fndecl))
{
- s = CHKP_WRAPPER_SYMBOL_PREFIX;
- s += IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl));
- new_name = get_identifier (s.c_str ());
+ new_name = get_identifier (chkp_wrap_function_name (fndecl));
+ DECL_VISIBILITY (new_decl) = VISIBILITY_DEFAULT;
}
else
{
chkp_copy_function_type_adding_bounds (tree orig_type)
{
tree type;
- tree arg_type, attrs, t;
+ tree arg_type, attrs;
unsigned len = list_length (TYPE_ARG_TYPES (orig_type));
unsigned *indexes = XALLOCAVEC (unsigned, len);
unsigned idx = 0, new_idx = 0;
if (!arg_type)
return orig_type;
- type = copy_node (orig_type);
+ type = build_distinct_type_copy (orig_type);
TYPE_ARG_TYPES (type) = copy_list (TYPE_ARG_TYPES (type));
for (arg_type = TYPE_ARG_TYPES (type);
TYPE_ATTRIBUTES (type) = attrs;
}
- t = TYPE_MAIN_VARIANT (orig_type);
- if (orig_type != t)
- {
- TYPE_MAIN_VARIANT (type) = t;
- TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (t);
- TYPE_NEXT_VARIANT (t) = type;
- }
- else
- {
- TYPE_MAIN_VARIANT (type) = type;
- TYPE_NEXT_VARIANT (type) = NULL;
- }
-
-
return type;
}
if (gimple_has_body_p (fndecl))
{
- /* If function will not be instrumented, then it's instrumented
- version is a thunk for the original. */
- if (!chkp_instrumentable_p (fndecl))
- {
- clone->remove_callees ();
- clone->remove_all_references ();
- clone->thunk.thunk_p = true;
- clone->thunk.add_pointer_bounds_args = true;
- clone->create_edge (node, NULL, 0, CGRAPH_FREQ_BASE);
- }
- else
- {
- tree_function_versioning (fndecl, new_decl, NULL, false,
- NULL, false, NULL, NULL);
- clone->lowered = true;
- }
+ gcc_assert (chkp_instrumentable_p (fndecl));
+ tree_function_versioning (fndecl, new_decl, NULL, false,
+ NULL, false, NULL, NULL);
+ clone->lowered = true;
}
/* New params are inserted after versioning because it
/* Clones have the same comdat group as originals. */
if (node->same_comdat_group
- || DECL_ONE_ONLY (node->decl))
+ || (DECL_ONE_ONLY (node->decl)
+ && !DECL_EXTERNAL (node->decl)))
clone->add_to_same_comdat_group (node);
if (gimple_has_body_p (fndecl))
/* Clone all aliases. */
for (i = 0; node->iterate_direct_aliases (i, ref); i++)
- {
- struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
- struct cgraph_node *chkp_alias
- = chkp_maybe_create_clone (alias->decl);
- chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
- }
+ chkp_maybe_create_clone (ref->referring->decl);
/* Clone all thunks. */
for (e = node->callers; e; e = e->next_caller)
if (e->caller->thunk.thunk_p
- && !e->caller->thunk.add_pointer_bounds_args)
+ && !e->caller->thunk.add_pointer_bounds_args
+ && !e->caller->instrumentation_clone)
{
struct cgraph_node *thunk
= chkp_maybe_create_clone (e->caller->decl);
ref = node->ref_list.first_reference ();
if (ref)
- chkp_maybe_create_clone (ref->referred->decl);
+ {
+ target = chkp_maybe_create_clone (ref->referred->decl);
+ clone->create_reference (target, IPA_REF_ALIAS);
+ }
if (node->alias_target)
{
0, CGRAPH_FREQ_BASE);
node->create_reference (node->instrumented_version,
IPA_REF_CHKP, NULL);
+ /* Thunk shouldn't be a cdtor. */
+ DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
+ DECL_STATIC_DESTRUCTOR (node->decl) = 0;
}
}