Hi, This patch hardcodes wrapper names because builtin assembler name may vary and cannot be used to build a wrapper name. Also don't use alias chain for wrappers. Bootstrapped and regtested for x86_64-unknown-linux-gnu. Going to apply it to trunk and gcc-5 if no objections appear.
Thanks, Ilya -- gcc/ 2015-05-12 Ilya Enkovich <ilya.enkov...@intel.com> * ipa-chkp.h (chkp_wrap_function): New. * ipa-chkp.c (chkp_wrap_function): Remove 'static'. (chkp_wrap_function_name): New. (chkp_build_instrumented_fndecl): Use chkp_wrap_function_name to get wrapper name. * lto-cgraph.c: Include ipa-chkp.h. (input_cgraph_1): Avoid alias chain for wrappers. gcc/testsuite/ 2015-05-12 Ilya Enkovich <ilya.enkov...@intel.com> * gcc.dg/lto/chkp-wrap-asm-name_0.c: New. diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c index 23e08cb..ac5eb35 100644 --- a/gcc/ipa-chkp.c +++ b/gcc/ipa-chkp.c @@ -104,7 +104,7 @@ along with GCC; see the file COPYING3. If not see /* 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) @@ -139,6 +139,51 @@ chkp_wrap_function (tree fndecl) 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 @@ -164,9 +209,8 @@ chkp_build_instrumented_fndecl (tree fndecl) 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 { diff --git a/gcc/ipa-chkp.h b/gcc/ipa-chkp.h index 6708fe9..547487e 100644 --- a/gcc/ipa-chkp.h +++ b/gcc/ipa-chkp.h @@ -24,5 +24,6 @@ extern tree chkp_copy_function_type_adding_bounds (tree orig_type); extern tree chkp_maybe_clone_builtin_fndecl (tree fndecl); extern cgraph_node *chkp_maybe_create_clone (tree fndecl); extern bool chkp_instrumentable_p (tree fndecl); +extern bool chkp_wrap_function (tree fndecl); #endif /* GCC_IPA_CHKP_H */ diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index ac50e4b..b306c28 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -80,6 +80,7 @@ along with GCC; see the file COPYING3. If not see #include "pass_manager.h" #include "ipa-utils.h" #include "omp-low.h" +#include "ipa-chkp.h" /* True when asm nodes has been output. */ bool asm_nodes_output = false; @@ -1616,10 +1617,13 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, cnode->instrumented_version->instrumented_version = cnode; } - /* Restore decl names reference. */ - IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (cnode->decl)) = 1; - TREE_CHAIN (DECL_ASSEMBLER_NAME (cnode->decl)) - = DECL_ASSEMBLER_NAME (cnode->orig_decl); + /* Restore decl names reference except for wrapper functions. */ + if (!chkp_wrap_function (cnode->orig_decl)) + { + tree name = DECL_ASSEMBLER_NAME (cnode->decl); + IDENTIFIER_TRANSPARENT_ALIAS (name) = 1; + TREE_CHAIN (name) = DECL_ASSEMBLER_NAME (cnode->orig_decl); + } } } diff --git a/gcc/testsuite/gcc.dg/lto/chkp-wrap-asm-name_0.c b/gcc/testsuite/gcc.dg/lto/chkp-wrap-asm-name_0.c new file mode 100644 index 0000000..6611bdb --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/chkp-wrap-asm-name_0.c @@ -0,0 +1,20 @@ +/* { dg-lto-do link } */ +/* { dg-require-effective-target mpx } */ +/* { dg-lto-options { { -O2 -flto -fcheck-pointer-bounds -mmpx } } } */ + +typedef long unsigned int size_t; + +extern size_t strlen (const char *); +extern __typeof (strlen) strlen __asm__ ("" "__hidden_strlen") __attribute__ ((visibility ("hidden"))); + +size_t +test1 (const char *p) { return strlen (p); } + +size_t +test2 (const char *p) { return __builtin_strlen (p); } + +int +main (int argc, const char **argv) +{ + return test1 (argv[0]) - test2 (argv[0]); +}