This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Provide global var location info for asan
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Konstantin Serebryany <konstantin dot s dot serebryany at gmail dot com>, Dodji Seketeli <dseketel at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Dmitry Vyukov <dvyukov at google dot com>, Marek Polacek <polacek at redhat dot com>, "H.J. Lu" <hjl dot tools at gmail dot com>, Yuri Gribov <tetra2005 at gmail dot com>, Alexey Samsonov <samsonov at google dot com>
- Date: Wed, 24 Sep 2014 12:38:05 +0200
- Subject: [PATCH] Provide global var location info for asan
- Authentication-results: sourceware.org; auth=none
- References: <CAGQ9bdyur_BejoirTygZfTs0O7VdfEHB6uWAcoqh9tukvv3BXA at mail dot gmail dot com> <CAGQ9bdyo8V6Q_CHtfz=5uo32yic05Aws0w6kuLVpH359W6fpKw at mail dot gmail dot com> <20140923141657 dot GL17454 at tucnak dot redhat dot com> <CAGQ9bdx7+1MbhhYVzL=BjmcUKqa56cwDfs_w5cvSiCBkfa+MQg at mail dot gmail dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Tue, Sep 23, 2014 at 11:03:55AM -0700, Konstantin Serebryany wrote:
> >> (asan_add_global): Ditto.
> >
> > I'll handle creation of location aggregates as follow-up.
Here it is, only lightly tested so far:
int a = 1;
int b = 2;
int c = 3;
int *
foo (int x)
{
return x ? &b : &c;
}
int
main ()
{
char *p = (char *) foo (1);
int x = p[sizeof (int)];
asm ("" : : "r" (x));
return 0;
}
used to print:
0x000000601104 is located 60 bytes to the left of global variable 'a' defined in 'aa.c' (0x601140) of size 4
0x000000601104 is located 0 bytes to the right of global variable 'b' defined in 'aa.c' (0x601100) of size 4
but now does:
0x000000601104 is located 60 bytes to the left of global variable 'a' defined in 'aa.c:1:5' (0x601140) of size 4
0x000000601104 is located 0 bytes to the right of global variable 'b' defined in 'aa.c:2:5' (0x601100) of size 4
I think this test is too fragile for the testsuite though, the order of the
vars in the data section can be arbitrary etc.
make -j16 -k check-gcc check-g++ check-gfortran RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} asan.exp'
passed.
For Marek: the patch also uses just one __ubsan_source_location
RECORD_TYPE everywhere, I've been really surprised we created a new type
node each time we needed it.
Ok for trunk?
2014-09-24 Jakub Jelinek <jakub@redhat.com>
* ubsan.h (ubsan_get_source_location): New prototype.
* ubsan.c (ubsan_source_location_type): New variable.
Function renamed to ...
(ubsan_get_source_location_type): ... this. Cache
return value in ubsan_source_location_type variable.
(ubsan_source_location, ubsan_create_data): Use
ubsan_get_source_location_type instead of
ubsan_source_location_type.
* asan.c (asan_protect_global): Don't protect globals
with ubsan_get_source_location_type () type.
(asan_add_global): Provide global decl location info
if possible.
--- gcc/ubsan.h.jj 2014-09-24 08:26:49.635418299 +0200
+++ gcc/ubsan.h 2014-09-24 11:35:05.231330166 +0200
@@ -47,6 +47,6 @@ extern tree ubsan_encode_value (tree, bo
extern bool is_ubsan_builtin_p (tree);
extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, tree);
extern tree ubsan_instrument_float_cast (location_t, tree, tree);
+extern tree ubsan_get_source_location_type (void);
#endif /* GCC_UBSAN_H */
-
--- gcc/ubsan.c.jj 2014-09-24 08:26:49.639418278 +0200
+++ gcc/ubsan.c 2014-09-24 11:35:56.662054997 +0200
@@ -197,6 +197,9 @@ ubsan_type_descriptor_type (void)
return ret;
}
+/* Cached ubsan_get_source_location_type () return value. */
+static GTY(()) tree ubsan_source_location_type;
+
/* Build
struct __ubsan_source_location
{
@@ -206,12 +209,15 @@ ubsan_type_descriptor_type (void)
}
type. */
-static tree
-ubsan_source_location_type (void)
+tree
+ubsan_get_source_location_type (void)
{
static const char *field_names[3]
= { "__filename", "__line", "__column" };
tree fields[3], ret;
+ if (ubsan_source_location_type)
+ return ubsan_source_location_type;
+
tree const_char_type = build_qualified_type (char_type_node,
TYPE_QUAL_CONST);
@@ -229,6 +235,7 @@ ubsan_source_location_type (void)
TYPE_FIELDS (ret) = fields[0];
TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
layout_type (ret);
+ ubsan_source_location_type = ret;
return ret;
}
@@ -239,7 +246,7 @@ static tree
ubsan_source_location (location_t loc)
{
expanded_location xloc;
- tree type = ubsan_source_location_type ();
+ tree type = ubsan_get_source_location_type ();
xloc = expand_location (loc);
tree str;
@@ -484,7 +491,7 @@ ubsan_create_data (const char *name, int
{
gcc_checking_assert (i < 2);
fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
- ubsan_source_location_type ());
+ ubsan_get_source_location_type ());
DECL_CONTEXT (fields[i]) = ret;
if (i)
DECL_CHAIN (fields[i - 1]) = fields[i];
--- gcc/asan.c.jj 2014-09-24 11:13:43.548211574 +0200
+++ gcc/asan.c 2014-09-24 12:06:13.122500445 +0200
@@ -1316,7 +1316,8 @@ asan_protect_global (tree decl)
|| DECL_SIZE (decl) == 0
|| ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT
|| !valid_constant_size_p (DECL_SIZE_UNIT (decl))
- || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE)
+ || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE
+ || TREE_TYPE (decl) == ubsan_get_source_location_type ())
return false;
rtl = DECL_RTL (decl);
@@ -2224,8 +2225,38 @@ asan_add_global (tree decl, tree type, v
int has_dynamic_init = vnode ? vnode->dynamically_initialized : 0;
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
build_int_cst (uptr, has_dynamic_init));
- CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
- build_int_cst (uptr, 0));
+ tree locptr = NULL_TREE;
+ location_t loc = DECL_SOURCE_LOCATION (decl);
+ expanded_location xloc = expand_location (loc);
+ if (xloc.file != NULL)
+ {
+ static int lasanloccnt = 0;
+ char buf[25];
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LASANLOC", ++lasanloccnt);
+ tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
+ ubsan_get_source_location_type ());
+ TREE_STATIC (var) = 1;
+ TREE_PUBLIC (var) = 0;
+ DECL_ARTIFICIAL (var) = 1;
+ DECL_IGNORED_P (var) = 1;
+ pretty_printer filename_pp;
+ pp_string (&filename_pp, xloc.file);
+ tree str = asan_pp_string (&filename_pp);
+ tree ctor = build_constructor_va (TREE_TYPE (var), 3,
+ NULL_TREE, str, NULL_TREE,
+ build_int_cst (unsigned_type_node,
+ xloc.line), NULL_TREE,
+ build_int_cst (unsigned_type_node,
+ xloc.column));
+ TREE_CONSTANT (ctor) = 1;
+ TREE_STATIC (ctor) = 1;
+ DECL_INITIAL (var) = ctor;
+ varpool_node::finalize_decl (var);
+ locptr = fold_convert (uptr, build_fold_addr_expr (var));
+ }
+ else
+ locptr = build_int_cst (uptr, 0);
+ CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr);
init = build_constructor (type, vinner);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
}
Jakub