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 <ja...@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