ubsan.h (ubsan_get_source_location): New prototype.
authorJakub Jelinek <jakub@gcc.gnu.org>
Mon, 6 Oct 2014 07:44:13 +0000 (09:44 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 6 Oct 2014 07:44:13 +0000 (09:44 +0200)
* 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.

From-SVN: r215916

gcc/asan.c
gcc/ubsan.c
gcc/ubsan.h

index 247661a528da9eb92c286014add584d84a1638e6..fca4ee6fb3f280c3f3877a2a75081dd564f9a712 100644 (file)
@@ -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);
@@ -2226,8 +2227,38 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *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);
 }
index e3128ad6177027f75f3c036abcebd674a33d61dd..c9a72ad47202e1c6e9b4539ac9cf49eb99175cd8 100644 (file)
@@ -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 loccnt, const location_t *ploc, ...)
     {
       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];
index cd269408cf2a4cfa1eb723bc9d010810cdd76de9..d0b404f63e4e1ba191840f31704badeed8d2b472 100644 (file)
@@ -47,6 +47,6 @@ extern tree ubsan_encode_value (tree, bool = false);
 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  */
-