This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, Pointer Bounds Checker 20/x] Follow transparent alias chains
- From: Ilya Enkovich <enkovich dot gnu at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 2 Jun 2014 19:15:16 +0400
- Subject: [PATCH, Pointer Bounds Checker 20/x] Follow transparent alias chains
- Authentication-results: sourceware.org; auth=none
Hi,
In the most case we follow transparent alias chains wne assemble names. But in some cases it is not performed. For instrumented functions it is critical and following patch fixes that. It also adds a visibility inheritance for instrtumented functions.
Bootstrapped and tested on linux-x86_64.
Thanks,
Ilya
--
gcc/
2014-06-02 Ilya Enkovich <ilya.enkovich@intel.com>
* varasm.c: Include tree-chkp.h.
(ultimate_transparent_alias_target): Move up.
(make_decl_rtl): For instrumented function use
name of the original decl.
(assemble_start_function): Mark function as global
in case it is instrumentation clone of the global
function.
(do_assemble_alias): Follow transparent alias chain
for identifier. Check if original alias is public.
(maybe_assemble_visibility): Use visibility of the
original function for instrumented version.
(default_unique_section): Likewise.
diff --git a/gcc/varasm.c b/gcc/varasm.c
index fcae2fa..d473bc7 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "asan.h"
#include "basic-block.h"
+#include "tree-chkp.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
@@ -1200,6 +1201,30 @@ use_blocks_for_decl_p (tree decl)
return targetm.use_blocks_for_decl_p (decl);
}
+/* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at *ALIAS
+ until we find an identifier that is not itself a transparent alias.
+ Modify the alias passed to it by reference (and all aliases on the
+ way to the ultimate target), such that they do not have to be
+ followed again, and return the ultimate target of the alias
+ chain. */
+
+static inline tree
+ultimate_transparent_alias_target (tree *alias)
+{
+ tree target = *alias;
+
+ if (IDENTIFIER_TRANSPARENT_ALIAS (target))
+ {
+ gcc_assert (TREE_CHAIN (target));
+ target = ultimate_transparent_alias_target (&TREE_CHAIN (target));
+ gcc_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target)
+ && ! TREE_CHAIN (target));
+ *alias = target;
+ }
+
+ return target;
+}
+
/* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL. DECL should
have static storage duration. In other words, it should not be an
automatic variable, including PARM_DECLs.
@@ -1214,6 +1239,7 @@ make_decl_rtl (tree decl)
{
const char *name = 0;
int reg_number;
+ tree id;
rtx x;
/* Check that we are not being given an automatic variable. */
@@ -1271,7 +1297,12 @@ make_decl_rtl (tree decl)
return;
}
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ id = DECL_ASSEMBLER_NAME (decl);
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && cgraph_get_node (decl)
+ && cgraph_get_node (decl)->instrumentation_clone)
+ ultimate_transparent_alias_target (&id);
+ name = IDENTIFIER_POINTER (id);
if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL
&& DECL_REGISTER (decl))
@@ -1699,7 +1730,10 @@ assemble_start_function (tree decl, const char *fnname)
/* Make function name accessible from other files, if appropriate. */
- if (TREE_PUBLIC (decl))
+ if (TREE_PUBLIC (decl)
+ || (cgraph_get_node (decl)->instrumentation_clone
+ && cgraph_get_node (decl)->instrumented_version
+ && TREE_PUBLIC (cgraph_get_node (decl)->instrumented_version->decl)))
{
notice_global_symbol (decl);
@@ -2386,30 +2420,6 @@ mark_decl_referenced (tree decl)
}
-/* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at *ALIAS
- until we find an identifier that is not itself a transparent alias.
- Modify the alias passed to it by reference (and all aliases on the
- way to the ultimate target), such that they do not have to be
- followed again, and return the ultimate target of the alias
- chain. */
-
-static inline tree
-ultimate_transparent_alias_target (tree *alias)
-{
- tree target = *alias;
-
- if (IDENTIFIER_TRANSPARENT_ALIAS (target))
- {
- gcc_assert (TREE_CHAIN (target));
- target = ultimate_transparent_alias_target (&TREE_CHAIN (target));
- gcc_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target)
- && ! TREE_CHAIN (target));
- *alias = target;
- }
-
- return target;
-}
-
/* Output to FILE (an assembly file) a reference to NAME. If NAME
starts with a *, the rest of NAME is output verbatim. Otherwise
NAME is transformed in a target-specific way (usually by the
@@ -5544,6 +5554,9 @@ vec<alias_pair, va_gc> *alias_pairs;
void
do_assemble_alias (tree decl, tree target)
{
+ tree orig_decl = decl;
+ tree id;
+
/* Emulated TLS had better not get this var. */
gcc_assert (!(!targetm.have_tls
&& TREE_CODE (decl) == VAR_DECL
@@ -5552,12 +5565,21 @@ do_assemble_alias (tree decl, tree target)
if (TREE_ASM_WRITTEN (decl))
return;
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && cgraph_get_node (decl)->instrumentation_clone
+ && cgraph_get_node (decl)->instrumented_version)
+ orig_decl = cgraph_get_node (decl)->instrumented_version->decl;
+
+ id = DECL_ASSEMBLER_NAME (decl);
+ ultimate_transparent_alias_target (&id);
+
/* We must force creation of DECL_RTL for debug info generation, even though
we don't use it here. */
make_decl_rtl (decl);
TREE_ASM_WRITTEN (decl) = 1;
TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1;
+ TREE_ASM_WRITTEN (id) = 1;
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
{
@@ -5568,7 +5590,7 @@ do_assemble_alias (tree decl, tree target)
#ifdef ASM_OUTPUT_WEAKREF
ASM_OUTPUT_WEAKREF (asm_out_file, decl,
- IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
+ IDENTIFIER_POINTER (id),
IDENTIFIER_POINTER (target));
#else
if (!TARGET_SUPPORTS_WEAK)
@@ -5584,7 +5606,7 @@ do_assemble_alias (tree decl, tree target)
#ifdef ASM_OUTPUT_DEF
/* Make name accessible from other files, if appropriate. */
- if (TREE_PUBLIC (decl))
+ if (TREE_PUBLIC (decl) || TREE_PUBLIC (orig_decl))
{
globalize_decl (decl);
maybe_assemble_visibility (decl);
@@ -5594,7 +5616,7 @@ do_assemble_alias (tree decl, tree target)
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
if (targetm.has_ifunc_p ())
ASM_OUTPUT_TYPE_DIRECTIVE
- (asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
+ (asm_out_file, IDENTIFIER_POINTER (id),
IFUNC_ASM_TYPE);
else
#endif
@@ -5606,7 +5628,7 @@ do_assemble_alias (tree decl, tree target)
ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, decl, target);
# else
ASM_OUTPUT_DEF (asm_out_file,
- IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
+ IDENTIFIER_POINTER (id),
IDENTIFIER_POINTER (target));
# endif
#elif defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
@@ -5614,7 +5636,7 @@ do_assemble_alias (tree decl, tree target)
const char *name;
tree *p, t;
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ name = IDENTIFIER_POINTER (id);
# ifdef ASM_WEAKEN_DECL
ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
# else
@@ -5623,7 +5645,8 @@ do_assemble_alias (tree decl, tree target)
/* Remove this function from the pending weak list so that
we do not emit multiple .weak directives for it. */
for (p = &weak_decls; (t = *p) ; )
- if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
+ if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t))
+ || id == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
*p = TREE_CHAIN (t);
else
p = &TREE_CHAIN (t);
@@ -5632,8 +5655,7 @@ do_assemble_alias (tree decl, tree target)
list, for the same reason. */
for (p = &weakref_targets; (t = *p) ; )
{
- if (DECL_ASSEMBLER_NAME (decl)
- == ultimate_transparent_alias_target (&TREE_VALUE (t)))
+ if (id == ultimate_transparent_alias_target (&TREE_VALUE (t)))
*p = TREE_CHAIN (t);
else
p = &TREE_CHAIN (t);
@@ -5899,6 +5921,12 @@ maybe_assemble_visibility (tree decl)
{
enum symbol_visibility vis = DECL_VISIBILITY (decl);
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && cgraph_get_node (decl)
+ && cgraph_get_node (decl)->instrumentation_clone
+ && cgraph_get_node (decl)->instrumented_version)
+ vis = DECL_VISIBILITY (cgraph_get_node (decl)->instrumented_version->decl);
+
if (vis != VISIBILITY_DEFAULT)
{
targetm.asm_out.assemble_visibility (decl, vis);
@@ -6463,6 +6491,7 @@ default_unique_section (tree decl, int reloc)
bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
const char *prefix, *name, *linkonce;
char *string;
+ tree id;
switch (categorize_decl_for_section (decl, reloc))
{
@@ -6512,7 +6541,9 @@ default_unique_section (tree decl, int reloc)
gcc_unreachable ();
}
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ id = DECL_ASSEMBLER_NAME (decl);
+ ultimate_transparent_alias_target (&id);
+ name = IDENTIFIER_POINTER (id);
name = targetm.strip_name_encoding (name);
/* If we're using one_only, then there needs to be a .gnu.linkonce