aarch64 - Set the mode for the unspec in speculation_tracker insn.
[platform/upstream/linaro-gcc.git] / gcc / esan.c
1 /* EfficiencySanitizer.
2    Copyright (C) 2011-2018 Free Software Foundation, Inc.
3    Contributed by Denis Khalikov.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "memmodel.h"
28 #include "gimple.h"
29 #include "tree-pass.h"
30 #include "cgraph.h"
31 #include "fold-const.h"
32 #include "gimplify.h"
33 #include "gimple-iterator.h"
34 #include "gimplify-me.h"
35 #include "tree-cfg.h"
36 #include "tree-iterator.h"
37 #include "esan.h"
38 #include "stringpool.h"
39 #include "attribs.h"
40 #include "builtins.h"
41 #include "asan.h"
42 #include "output.h"
43 #include "stor-layout.h"
44 #include "ssa.h"
45 #include "gimple-fold.h"
46
47 /* The size taken from llvm part.  */
48 static const unsigned max_struct_field_counter_name_size = 512;
49 static char field_counter_name[max_struct_field_counter_name_size];
50 static char counter_prefix[] = "struct.";
51
52 /* Struct represents internal information about processed
53    record types.  */
54 struct esan_type
55 {
56   esan_type ()
57     : type (NULL_TREE), array_type (NULL_TREE), field_counter_name (NULL),
58       fields_count (0)
59   {
60   }
61
62   esan_type (tree t, tree a)
63     : type (t), array_type (a), field_counter_name (NULL), fields_count (0)
64   {
65   }
66
67   esan_type (const int value)
68   {
69     if (!value)
70       type = array_type = NULL_TREE;
71   }
72
73   tree type;
74   tree array_type;
75   char *field_counter_name;
76   size_t fields_count;
77 };
78
79 /* Represents the type, field and index related to them.
80    Why do we need this type at all ?
81
82    Assume we have following classes A, B, C as A <- B <- C,
83    and field access load %reg, &C->A_field, so we should
84    go recurively and find actual type A and field index
85    inside the A class.
86    This struct hepls to solve that problem.
87 */
88 struct esan_field_index
89 {
90   esan_field_index () : type (NULL_TREE), field (NULL_TREE), index (0) {}
91
92   esan_field_index (tree base_type, tree base_field, size_t base_index)
93     : type (base_type), field (base_field), index (base_index)
94   {
95   }
96
97   esan_field_index (const esan_field_index &other)
98   {
99     type = other.type;
100     field = other.field;
101     index = other.index;
102   }
103
104   esan_field_index &
105   operator= (const esan_field_index &other)
106   {
107     if (this == &other)
108       return *this;
109
110     type = other.type;
111     field = other.field;
112     index = other.index;
113     return *this;
114   }
115
116   tree type;
117   tree field;
118   size_t index;
119 };
120
121 /* FIXME: use hash_set<K, K_Traits> instead vec<T>
122    to improve search from O(n) to O(1).  */
123 static vec<esan_type> vec_esan_type;
124
125 static tree
126 get_memory_access_decl (bool is_store, unsigned size)
127 {
128   /*  Choose an appropriate builtin.  */
129   enum built_in_function fcode;
130   if (size <= 1)
131     fcode
132       = is_store ? BUILT_IN_ESAN_ALIGNED_STORE1 : BUILT_IN_ESAN_ALIGNED_LOAD1;
133   else if (size <= 3)
134     fcode
135       = is_store ? BUILT_IN_ESAN_ALIGNED_STORE2 : BUILT_IN_ESAN_ALIGNED_LOAD2;
136   else if (size <= 7)
137     fcode
138       = is_store ? BUILT_IN_ESAN_ALIGNED_STORE4 : BUILT_IN_ESAN_ALIGNED_LOAD4;
139   else if (size <= 15)
140     fcode
141       = is_store ? BUILT_IN_ESAN_ALIGNED_STORE8 : BUILT_IN_ESAN_ALIGNED_LOAD8;
142   else
143     fcode
144       = is_store ? BUILT_IN_ESAN_ALIGNED_STORE16 : BUILT_IN_ESAN_ALIGNED_LOAD16;
145   return builtin_decl_implicit (fcode);
146 }
147
148 static void
149 instrument_expr (gimple_stmt_iterator gsi, tree expr, bool is_store)
150 {
151   tree base, expr_ptr;
152   basic_block bb;
153   HOST_WIDE_INT size;
154   gimple *stmt, *g;
155   gimple_seq seq;
156   location_t loc;
157   unsigned int align;
158
159   size = int_size_in_bytes (TREE_TYPE (expr));
160   /*  Can't instrument memory accesses in case of size <= 0.  */
161   if (size <= 0)
162     return;
163
164   HOST_WIDE_INT unused_bitsize, unused_bitpos;
165   tree offset;
166   machine_mode mode;
167   int unsignedp, reversep, volatilep = 0;
168
169   base = get_inner_reference (expr, &unused_bitsize, &unused_bitpos, &offset,
170                               &mode, &unsignedp, &reversep, &volatilep, false);
171
172   if (TREE_READONLY (base) || (VAR_P (base) && DECL_HARD_REGISTER (base)))
173     return;
174
175   stmt = gsi_stmt (gsi);
176   loc = gimple_location (stmt);
177   align = get_object_alignment (expr);
178   /*  In this case we can't instrument memmory access.  */
179   if (align < BITS_PER_UNIT)
180     return;
181
182   /*  In this case we need folded ptr to expression.  */
183   expr_ptr = build_fold_addr_expr (unshare_expr (expr));
184
185   expr_ptr = force_gimple_operand (expr_ptr, &seq, true, NULL_TREE);
186   /* Build the esan's builtin.  */
187   g = gimple_build_call (get_memory_access_decl (is_store, size), 1, expr_ptr);
188   /* Set location.  */
189   gimple_set_location (g, loc);
190   gimple_seq_add_stmt_without_update (&seq, g);
191
192   if (is_gimple_call (stmt) && is_store)
193     {
194       /*  Could be a fallthrough edge.  */
195       if (is_ctrl_altering_stmt (stmt))
196         {
197           edge e;
198
199           bb = gsi_bb (gsi);
200           e = find_fallthru_edge (bb->succs);
201           if (e)
202             gsi_insert_seq_on_edge_immediate (e, seq);
203         }
204       else
205         /*  Insert after the call on store.  */
206         gsi_insert_seq_after (&gsi, seq, GSI_NEW_STMT);
207     }
208   else
209     /*  Insert before.  */
210     gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
211 }
212
213 static void
214 maybe_instrument_working_set_gimple (gimple_stmt_iterator *gsi)
215 {
216   gimple *stmt;
217   tree rhs, lhs;
218
219   stmt = gsi_stmt (*gsi);
220
221   if (is_gimple_call (stmt))
222     return;
223
224   if (is_gimple_assign (stmt) && !gimple_clobber_p (stmt))
225     {
226       if (gimple_store_p (stmt))
227         {
228           lhs = gimple_assign_lhs (stmt);
229           instrument_expr (*gsi, lhs, true);
230         }
231       if (gimple_assign_load_p (stmt))
232         {
233           rhs = gimple_assign_rhs1 (stmt);
234           instrument_expr (*gsi, rhs, false);
235         }
236     }
237 }
238
239 static size_t type_count;
240 static size_t default_count;
241
242 /* Function generates unique id.  */
243 static size_t
244 gen_unique_id (char *buff, size_t *t_count)
245 {
246   size_t size = 1;
247   size_t count = *t_count;
248   while (count)
249     {
250       *buff++ = '0' + count % 10;
251       count /= 10;
252       ++size;
253     }
254   *t_count += 1;
255   return size;
256 }
257
258 static int
259 convert_to_type_id (char *buff, tree field_type)
260 {
261   switch (TREE_CODE (field_type))
262     {
263     case INTEGER_TYPE:
264       *buff = '1';
265       return 1;
266     case REAL_TYPE:
267       *buff = '2';
268       return 1;
269     case COMPLEX_TYPE:
270       *buff = '3';
271       return 1;
272     case VECTOR_TYPE:
273       *buff = '4';
274       return 1;
275     case ENUMERAL_TYPE:
276       *buff = '5';
277       return 1;
278     case BOOLEAN_TYPE:
279       *buff = '6';
280       return 1;
281     case POINTER_TYPE:
282       {
283         *buff++ = '8';
284         return gen_unique_id (buff, &type_count);
285       }
286     default:
287       {
288         *buff++ = '9';
289         return gen_unique_id (buff, &default_count);
290       }
291     }
292 }
293
294 static void
295 reverse (char *buff, size_t len)
296 {
297   if (!len)
298     return;
299
300   size_t start, end;
301
302   for (start = 0, end = len - 1; start < end; ++start, --end)
303     {
304       char temp = buff[end];
305       buff[end] = buff[start];
306       buff[start] = temp;
307     }
308 }
309
310 static size_t
311 unique_id_size (size_t t_count)
312 {
313   size_t size = 1;
314   while (t_count)
315     {
316       t_count /= 10;
317       ++size;
318     }
319   return size;
320 }
321
322 static size_t
323 field_type_size (tree field)
324 {
325   if (TREE_CODE (field) == FIELD_DECL)
326     {
327       switch (TREE_CODE (TREE_TYPE (field)))
328         {
329         case INTEGER_TYPE:
330         case REAL_TYPE:
331         case COMPLEX_TYPE:
332         case VECTOR_TYPE:
333         case ENUMERAL_TYPE:
334         case BOOLEAN_TYPE:
335           return 1;
336         case POINTER_TYPE:
337           {
338             return unique_id_size (type_count);
339           }
340         default:
341           {
342             return unique_id_size (default_count);
343           }
344         }
345     }
346   /* Skip nested types.  */
347   return 0;
348 }
349
350 /* Functions creates struct field counter name consistent with
351    llvm part, because runtime relies on it.  */
352 static ssize_t
353 create_struct_field_counter_name (tree type, size_t *count)
354 {
355   tree field;
356   size_t offset, start;
357   const char *type_name;
358
359   /* Could be NULL type identifier.  */
360   if (!TYPE_IDENTIFIER (type))
361     return -1;
362
363   type_name = IDENTIFIER_POINTER (TYPE_IDENTIFIER (type));
364   *count = offset = start = 0;
365
366   memset (field_counter_name, 0, max_struct_field_counter_name_size);
367
368   size_t counter_prefix_len = strlen (counter_prefix);
369   memcpy (field_counter_name, counter_prefix, counter_prefix_len);
370   offset += counter_prefix_len;
371
372   size_t type_name_len = strlen (type_name);
373
374   if (type_name_len + counter_prefix_len >= max_struct_field_counter_name_size)
375     return -1;
376
377   memcpy (field_counter_name + offset, type_name, type_name_len);
378   offset += type_name_len;
379
380   start = offset;
381
382   for (field = TYPE_FIELDS (type); field
383                                    /* offset + sizeof (field) + sizeof ($).  */
384                                    && (offset + field_type_size (field) + 1)
385                                         < max_struct_field_counter_name_size;
386        field = DECL_CHAIN (field))
387     {
388       if (TREE_CODE (field) == FIELD_DECL)
389         {
390           offset += convert_to_type_id (field_counter_name + offset,
391                                         TREE_TYPE (field));
392           field_counter_name[offset++] = '$';
393           /* Don't count nested types as a field.  */
394           if (TREE_CODE (TREE_TYPE (field)) != RECORD_TYPE)
395             ++*count;
396         }
397     }
398
399   /* This is strangely, but llvm part writes fields id in reverse order.  */
400   reverse (field_counter_name + start, offset - start);
401   return offset;
402 }
403
404 /* This should be kept consistent with LLVM's EfficiencySanitizer StructInfo.
405    struct StructInfo {
406      const char *StructName;
407      u32 Size;
408      u32 NumFields;
409      u32 *FieldOffset;           // auxiliary struct field info.
410      u32 *FieldSize;             // auxiliary struct field info.
411      const char **FieldTypeName; // auxiliary struct field info.
412      u64 *FieldCounters;
413      u64 *ArrayCounter;
414    };  */
415
416 /* Cached strcut_info_type tree.  */
417 static tree esan_struct_info_type;
418
419 /* Returns struct_info_type tree.  */
420 static tree
421 esan_get_struct_info_type (void)
422 {
423   /* Decription taken from llvm.  */
424   static const unsigned int count = 8;
425   static const char *field_names[count]
426     = {"StructName", "Size",      "NumFields",     "FieldOffset",
427        "FieldSize",  "FieldTypeName", "FieldCounters", "ArrayCounters"};
428   tree fields[count], ret;
429
430   if (esan_struct_info_type)
431     return esan_struct_info_type;
432
433   tree range_type = build_range_type (sizetype, size_zero_node, NULL_TREE);
434   /* StructName is a ptr to char with flex size.  */
435   tree flex_char_arr_type = build_array_type (char_type_node, range_type);
436   /* FieldOffset and FieldSize ptrs.  */
437   tree flex_uint_arr_type = build_array_type (unsigned_type_node, range_type);
438   /* FieldCounter and ArrayCounter.  */
439   tree flex_luint_arr_type
440     = build_array_type (long_long_unsigned_type_node, range_type);
441
442   ret = make_node (RECORD_TYPE);
443   for (unsigned int i = 0; i < count; ++i)
444     {
445       switch (i)
446         {
447         case 0:
448         case 5:
449           fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
450                                   get_identifier (field_names[i]),
451                                   build_pointer_type (flex_char_arr_type));
452           break;
453         case 1:
454         case 2:
455           fields[i]
456             = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
457                           get_identifier (field_names[i]), unsigned_type_node);
458           break;
459         case 3:
460         case 4:
461           fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
462                                   get_identifier (field_names[i]),
463                                   build_pointer_type (flex_uint_arr_type));
464           break;
465         case 6:
466         case 7:
467           fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
468                                   get_identifier (field_names[i]),
469                                   build_pointer_type (flex_luint_arr_type));
470           break;
471         default:
472           break;
473         }
474
475       DECL_CONTEXT (fields[i]) = ret;
476       if (i)
477         DECL_CHAIN (fields[i - 1]) = fields[i];
478     }
479
480   tree type_decl = build_decl (input_location, TYPE_DECL,
481                                get_identifier ("__esan_strcut_type_info"), ret);
482
483   DECL_IGNORED_P (type_decl) = 1;
484   DECL_ARTIFICIAL (type_decl) = 1;
485   TYPE_FIELDS (ret) = fields[0];
486   TYPE_NAME (ret) = type_decl;
487   TYPE_STUB_DECL (ret) = type_decl;
488   layout_type (ret);
489   esan_struct_info_type = ret;
490   return ret;
491 }
492
493 /* This should be kept consistent with LLVM's EfficiencySanitizer CacheFragInfo.
494    The tool-specific information per compilation unit (module).
495    struct CacheFragInfo {
496      const char *UnitName;
497      u32 NumStructs;
498      StructInfo *Structs;
499    };  */
500
501 static tree esan_cache_frag_info_type;
502
503 static tree
504 esan_get_cache_frag_info_type (void)
505 {
506   static const unsigned int count = 3;
507   static const char *field_names[count] = {"UnitName", "NumStructs", "Structs"};
508   tree fields[count], ret;
509
510   if (esan_cache_frag_info_type)
511     return esan_cache_frag_info_type;
512
513   tree esan_struct_type_info = esan_get_struct_info_type ();
514
515   tree range_type = build_range_type (sizetype, size_zero_node, NULL_TREE);
516   /* StructInfo Array Type.  */
517   tree struct_info_arr_type
518     = build_array_type (esan_struct_type_info, range_type);
519
520   /* Unit Name.  */
521   tree flex_char_arr_type = build_array_type (char_type_node, range_type);
522
523   ret = make_node (RECORD_TYPE);
524
525   for (unsigned int i = 0; i < count; ++i)
526     {
527       switch (i)
528         {
529         case 0:
530           fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
531                                   get_identifier (field_names[i]),
532                                   build_pointer_type (flex_char_arr_type));
533           break;
534         case 1:
535           fields[i]
536             = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
537                           get_identifier (field_names[i]), unsigned_type_node);
538           break;
539         case 2:
540           fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
541                                   get_identifier (field_names[i]),
542                                   build_pointer_type (struct_info_arr_type));
543           break;
544         default:
545           break;
546         }
547       DECL_CONTEXT (fields[i]) = ret;
548       if (i)
549         DECL_CHAIN (fields[i - 1]) = fields[i];
550     }
551
552   tree type_decl
553     = build_decl (input_location, TYPE_DECL,
554                   get_identifier ("__esan_cache_frag_info_type"), ret);
555
556   DECL_IGNORED_P (type_decl) = 1;
557   DECL_ARTIFICIAL (type_decl) = 1;
558   TYPE_FIELDS (ret) = fields[0];
559   TYPE_NAME (ret) = type_decl;
560   TYPE_STUB_DECL (ret) = type_decl;
561   layout_type (ret);
562   esan_cache_frag_info_type = ret;
563   return ret;
564 }
565
566 static unsigned int esan_ids[2];
567 static tree esan_array_counter_type;
568
569 static tree
570 esan_get_array_counter_type (void)
571 {
572   tree ret;
573
574   if (esan_array_counter_type)
575     return esan_array_counter_type;
576
577   tree range_type = build_range_type (sizetype, size_zero_node, NULL_TREE);
578   ret = build_array_type (long_long_unsigned_type_node, range_type);
579
580   esan_array_counter_type = ret;
581   return ret;
582 }
583
584 static void
585 esan_add_struct (tree array_addr, vec<constructor_elt, va_gc> *v,
586                  size_t fields_count, char *field_counter_name_type,
587                  size_t struct_size)
588 {
589   /* Create StructName.  */
590   const char *struct_name = field_counter_name_type;
591   size_t struct_name_len = strlen (struct_name) + 1;
592   tree struct_name_tree = build_string (struct_name_len, struct_name);
593   TREE_TYPE (struct_name_tree)
594     = build_array_type_nelts (char_type_node, struct_name_len);
595   TREE_READONLY (struct_name_tree) = 1;
596   TREE_STATIC (struct_name_tree) = 1;
597
598   /* Create StructInfo type.  */
599   tree dtype = esan_get_struct_info_type ();
600
601   /* Create an instance of StructInfo.  */
602   char tmp_name[32];
603   ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lesan_type", esan_ids[0]++);
604   tree decl
605     = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name), dtype);
606   TREE_STATIC (decl) = 1;
607   TREE_PUBLIC (decl) = 0;
608   TREE_READONLY (decl) = 1;
609   DECL_ARTIFICIAL (decl) = 1;
610   DECL_IGNORED_P (decl) = 1;
611   DECL_EXTERNAL (decl) = 0;
612
613   /* Initialize created struct.  */
614   tree ctor = build_constructor_va (
615     dtype, 8, NULL_TREE, build_fold_addr_expr (struct_name_tree), NULL_TREE,
616     build_int_cst (unsigned_type_node, struct_size), NULL_TREE,
617     build_int_cst (unsigned_type_node, fields_count), NULL_TREE,
618     build_zero_cst (long_long_unsigned_type_node), NULL_TREE,
619     build_zero_cst (long_long_unsigned_type_node), NULL_TREE,
620     build_zero_cst (long_long_unsigned_type_node), NULL_TREE, array_addr,
621     NULL_TREE, build_zero_cst (long_long_unsigned_type_node));
622
623   TREE_CONSTANT (ctor) = 1;
624   TREE_STATIC (ctor) = 1;
625   DECL_INITIAL (decl) = ctor;
626   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ctor);
627 }
628
629 /* Go recursively and find the actual class type and field index inside it.  */
630 static esan_field_index
631 esan_get_field_index_internal (tree base_type, tree field, bool *found)
632 {
633   tree field_it = TYPE_FIELDS (base_type);
634   esan_field_index field_index (base_type, field, 0);
635
636   for (; field_it && !*found; field_it = DECL_CHAIN (field_it))
637     {
638       if (TREE_CODE (field_it) == FIELD_DECL)
639         {
640           if (TREE_CODE (TREE_TYPE (field_it)) == RECORD_TYPE)
641             {
642               esan_field_index nested_field_index
643                 = esan_get_field_index_internal (TREE_TYPE (field_it), field,
644                                                  found);
645               if (*found)
646                 return nested_field_index;
647             }
648           else if (field_it == field)
649             *found = true;
650           else
651             ++field_index.index;
652         }
653     }
654   return *found ? field_index : esan_field_index (NULL_TREE, NULL_TREE, 0);
655 }
656
657 static bool
658 esan_get_field_index (tree base_type, tree field, esan_field_index *field_index)
659 {
660   bool found = false;
661   /* At this momet we don't really know the record type where field is defined,
662      so can't cash the previous search.  */
663   *field_index = esan_get_field_index_internal (base_type, field, &found);
664   return found;
665 }
666
667 static ssize_t
668 esan_vec_contains_type (tree type)
669 {
670   ssize_t index = 0;
671
672   if (type == NULL_TREE)
673     return -1;
674
675   esan_type esan_type_instance;
676   /* This is O(n) cost, but I think we can improve it to ~ O(1)
677      by using a hash_set.  */
678   while (vec_esan_type.iterate (index, &esan_type_instance))
679     {
680       if ((TYPE_IDENTIFIER (type)) == TYPE_IDENTIFIER (esan_type_instance.type))
681         return index;
682       ++index;
683     }
684   return -1;
685 }
686
687 bool
688 esan_expand_record_access_ifn (gimple_stmt_iterator *gsip)
689 {
690   tree field;
691   size_t fields_count;
692   esan_field_index field_index_internal;
693
694   tree base, base_type;
695   gimple_stmt_iterator gsi, gsi_origin;
696   gimple *stmt;
697   location_t loc;
698
699   /* Expand internal ESAN_ACCESS.  */
700   gsi_origin = gsi = *gsip;
701   stmt = gsi_stmt (gsi);
702   loc = gimple_location (stmt);
703   base = gimple_call_arg (stmt, 0);
704   field = gimple_call_arg (stmt, 1);
705   esan_type esan_type_instance;
706
707   tree array = NULL_TREE;
708   tree ptr = NULL_TREE;
709
710   /* In case we packed pointer type into integer to allow some level of
711      optimization work properly.  */
712   base_type = TREE_CODE (base) == INTEGER_CST ? TREE_TYPE (TREE_TYPE (base))
713                                               : TREE_TYPE (base);
714
715   /* Don't forget to verify field index, before creating the fields counter
716      array.  */
717   if (!base_type
718       || !esan_get_field_index (base_type, field, &field_index_internal))
719     {
720       unlink_stmt_vdef (stmt);
721       return gsi_remove (&gsi_origin, true);
722     }
723
724   size_t field_index = field_index_internal.index;
725   base_type = TYPE_MAIN_VARIANT (field_index_internal.type);
726
727   ssize_t index = esan_vec_contains_type (base_type);
728
729   /* In case we have not found type in the pool of types
730      and field has valid index, we should
731      create fields counter array and add type to the pool of types.  */
732   if (index == -1)
733     {
734       fields_count = 0;
735       ssize_t field_counter_name_len
736         = create_struct_field_counter_name (base_type, &fields_count);
737
738       if (field_counter_name_len == -1)
739         goto finish;
740
741       char *field_counter_name_type
742         = (char *) xmalloc (field_counter_name_len + 1);
743       memset (field_counter_name_type, 0, field_counter_name_len + 1);
744       memcpy (field_counter_name_type, field_counter_name,
745               field_counter_name_len + 1);
746
747       tree atype = esan_get_array_counter_type ();
748       array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
749                           get_identifier (field_counter_name), atype);
750
751       TREE_STATIC (array) = 1;
752       TREE_PUBLIC (array) = 1;
753       DECL_ARTIFICIAL (array) = 1;
754       DECL_IGNORED_P (array) = 1;
755       DECL_WEAK (array) = 1;
756       DECL_SIZE (array) = build_int_cst (
757         integer_type_node,
758         fields_count * tree_to_uhwi (TYPE_SIZE (long_long_unsigned_type_node)));
759
760       DECL_SIZE_UNIT (array)
761         = build_int_cst (integer_type_node,
762                          fields_count
763                            * tree_to_uhwi (
764                                TYPE_SIZE_UNIT (long_long_unsigned_type_node)));
765       DECL_EXTERNAL (array) = 0;
766
767       tree counter_ctor
768         = build_constructor_va (atype, 1, NULL_TREE, build_zero_cst (atype));
769       TREE_CONSTANT (counter_ctor) = 1;
770       TREE_STATIC (counter_ctor) = 1;
771       DECL_INITIAL (array) = counter_ctor;
772       varpool_node::finalize_decl (array);
773
774       ptr = build_fold_addr_expr (array);
775       esan_type_instance.type = base_type;
776       esan_type_instance.array_type = array;
777       esan_type_instance.field_counter_name = field_counter_name_type;
778       esan_type_instance.fields_count = fields_count;
779       vec_esan_type.safe_push (esan_type_instance);
780     }
781   /* We have already added the type into the pool, so fields counter
782      array was created.  */
783   else if (index >= 0)
784     {
785       if (vec_esan_type.iterate (index, &esan_type_instance))
786         ptr = build_fold_addr_expr (esan_type_instance.array_type);
787       else
788         goto finish;
789     }
790   {
791     gimple *g;
792     /* Field number + sizeof (long int).  */
793     tree offset = build_int_cst (unsigned_type_node,
794                                  field_index
795                                    * tree_to_uhwi (TYPE_SIZE_UNIT (
796                                        long_long_unsigned_type_node)));
797     /* array + offset.  */
798     g = gimple_build_assign (make_ssa_name (pointer_sized_int_node), PLUS_EXPR,
799                              ptr, offset);
800     gimple_set_location (g, loc);
801     gsi_insert_before (gsip, g, GSI_SAME_STMT);
802     ptr = gimple_assign_lhs (g);
803
804     tree call_decl = builtin_decl_implicit (BUILT_IN_ESAN_INCREMENT);
805
806     g = gimple_build_call (call_decl, 1, ptr);
807     gimple_set_location (g, loc);
808     gsi_insert_before (gsip, g, GSI_SAME_STMT);
809     /* FIXME Inline __esan_increment for the better performance.  */
810   }
811 finish:
812   unlink_stmt_vdef (stmt);
813   return gsi_remove (&gsi_origin, true);
814 }
815
816 static void
817 instrument_record_field_access (tree mem, tree base, gimple_stmt_iterator *iter,
818                                 tree field, const enum tree_code code)
819 {
820   tree t;
821   gcall *g;
822
823   t = TREE_OPERAND (base, 0);
824
825   if ((code == MEM_REF && !POINTER_TYPE_P (TREE_TYPE (t))) || !field)
826     return;
827
828   /* Don't instrument union accesses. */
829   if ((TREE_CODE (TREE_TYPE (base)) != RECORD_TYPE) || mem == base)
830     return;
831
832   /* Pack the pointer to integer, so other pass will keep it the same. */
833   g = gimple_build_call_internal (
834     IFN_ESAN_RECORD_ACCESS, 2,
835     (code == MEM_REF && POINTER_TYPE_P (TREE_TYPE (t)))
836       ? build_int_cst (build_pointer_type (TREE_TYPE (base)), 0)
837       : base,
838     field);
839
840   gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
841   gsi_insert_before (iter, g, GSI_SAME_STMT);
842 }
843
844 static void
845 instrument_record_access (gimple_stmt_iterator *gsi, tree expr, bool is_store)
846 {
847   tree field, t, base;
848   HOST_WIDE_INT unused_bitsize, unused_bitpos;
849   tree offset;
850   machine_mode mode;
851   int unsignedp, reversep, volatilep = 0;
852
853   gimple *stmt = gsi_stmt (*gsi);
854
855   HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (expr));
856
857   if (size <= 0)
858     return;
859
860   tree base_tree
861     = get_inner_reference (expr, &unused_bitsize, &unused_bitpos, &offset,
862                            &mode, &unsignedp, &reversep, &volatilep, false);
863
864   if (TREE_READONLY (base_tree)
865       || (VAR_P (base_tree) && DECL_HARD_REGISTER (base_tree)))
866     return;
867
868   if (get_object_alignment (expr) < BITS_PER_UNIT)
869     return;
870
871   t = is_store ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
872   base = get_base_address (t);
873   field = NULL_TREE;
874
875   /* Get the field.  */
876   if (TREE_CODE (t) == COMPONENT_REF)
877     field = TREE_OPERAND (t, 1);
878
879   const enum tree_code code = TREE_CODE (base);
880
881   if ((code == MEM_REF && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
882       || code == VAR_DECL)
883     instrument_record_field_access (t, base, gsi, field, code);
884 }
885
886 static void
887 maybe_instrument_cache_frag_gimple (gimple_stmt_iterator *gsi)
888 {
889   gimple *stmt;
890   tree lhs, rhs;
891   stmt = gsi_stmt (*gsi);
892
893   if (is_gimple_call (stmt))
894     return;
895
896   if (is_gimple_assign (stmt) && !gimple_clobber_p (stmt))
897     {
898       if (gimple_store_p (stmt))
899         {
900           lhs = gimple_assign_lhs (stmt);
901           instrument_record_access (gsi, lhs, true);
902         }
903       else if (gimple_assign_load_p (stmt))
904         {
905           rhs = gimple_assign_rhs1 (stmt);
906           instrument_record_access (gsi, rhs, false);
907         }
908     }
909 }
910
911 static void
912 instrument_memory_accesses (void)
913 {
914   basic_block bb;
915   gimple_stmt_iterator gsi;
916
917   /*  So, walk through all basic blocks
918       and try to instrument memory accesses.  */
919   FOR_EACH_BB_FN (bb, cfun)
920     {
921       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
922         {
923           if (flag_sanitize & SANITIZE_EFFICIENCY_WORKING_SET)
924             maybe_instrument_working_set_gimple (&gsi);
925           else if (flag_sanitize & SANITIZE_EFFICIENCY_CACHE_FRAG)
926             maybe_instrument_cache_frag_gimple (&gsi);
927         }
928     }
929 }
930
931 /* EfficiencySanitizer instrumentation pass.  */
932
933 static unsigned
934 esan_pass (void)
935 {
936   initialize_sanitizer_builtins ();
937   instrument_memory_accesses ();
938   return 0;
939 }
940
941 /* Creates an arrray of StructInfo structs and CacheInfo struct.
942    Inserts __esan_init () into the list of CTORs and
943    __esan_exit() into the listof DCTORs. */
944
945 void
946 esan_finish_file (void)
947 {
948   tree ctor_statements = NULL_TREE;
949   tree dctor_statements = NULL_TREE;
950   initialize_sanitizer_builtins ();
951   tree tool_id = NULL_TREE;
952
953   tree init_decl = builtin_decl_implicit (BUILT_IN_ESAN_INIT);
954   tree exit_decl = builtin_decl_implicit (BUILT_IN_ESAN_EXIT);
955
956   if (flag_sanitize & SANITIZE_EFFICIENCY_CACHE_FRAG)
957     {
958       esan_type esan_type_instance;
959       size_t index = 0;
960       size_t num_types = vec_esan_type.length ();
961       vec<constructor_elt, va_gc> *v;
962       vec_alloc (v, num_types);
963
964       /* Create StructInfo struct for the every struct we have instrumented.  */
965       while (vec_esan_type.iterate (index, &esan_type_instance))
966         {
967           tree ptr = build_fold_addr_expr (esan_type_instance.array_type);
968           esan_add_struct (ptr, v, esan_type_instance.fields_count,
969                            esan_type_instance.field_counter_name,
970                            int_size_in_bytes (esan_type_instance.type));
971
972           /* Was allocated by xmalloc, so free the memory.  */
973           free (esan_type_instance.field_counter_name);
974           ++index;
975         }
976
977       /* Create module name string.  */
978       size_t module_name_len = strlen (main_input_filename) + 1;
979       tree module_name_str
980         = build_string (module_name_len, main_input_filename);
981       TREE_TYPE (module_name_str)
982         = build_array_type_nelts (char_type_node, module_name_len);
983       TREE_READONLY (module_name_str) = 1;
984       TREE_STATIC (module_name_str) = 1;
985
986       tool_id = build_int_cst (unsigned_type_node, 1);
987       /* First, create the array of struct info type.  */
988       tree stype = esan_get_struct_info_type ();
989
990       stype = build_array_type_nelts (stype, num_types);
991
992       char tmp_info_name[32];
993       ASM_GENERATE_INTERNAL_LABEL (tmp_info_name, "Lesan_info", 0);
994
995       tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
996                              get_identifier (tmp_info_name), stype);
997
998       TREE_STATIC (var) = 1;
999       TREE_PUBLIC (var) = 0;
1000       TREE_READONLY (var) = 1;
1001       DECL_ARTIFICIAL (var) = 1;
1002       DECL_IGNORED_P (var) = 1;
1003       DECL_EXTERNAL (var) = 0;
1004
1005       tree ctor = build_constructor (stype, v);
1006
1007       TREE_CONSTANT (ctor) = 1;
1008       TREE_STATIC (ctor) = 1;
1009       DECL_INITIAL (var) = ctor;
1010
1011       varpool_node::finalize_decl (var);
1012
1013       tree ctype = esan_get_cache_frag_info_type ();
1014       char tmp_cache_name[32];
1015       ASM_GENERATE_INTERNAL_LABEL (tmp_cache_name, "Lesan_cache", 0);
1016
1017       tree c_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1018                                get_identifier (tmp_cache_name), ctype);
1019       TREE_STATIC (c_var) = 1;
1020       TREE_PUBLIC (c_var) = 0;
1021       DECL_ARTIFICIAL (c_var) = 1;
1022       DECL_IGNORED_P (c_var) = 1;
1023       DECL_EXTERNAL (c_var) = 0;
1024
1025       tree c_ctor
1026         = build_constructor_va (ctype, 3, NULL_TREE,
1027                                 build_fold_addr_expr (module_name_str),
1028                                 NULL_TREE,
1029                                 build_int_cst (unsigned_type_node, num_types),
1030                                 NULL_TREE, build_fold_addr_expr (var));
1031
1032       TREE_CONSTANT (c_ctor) = 1;
1033       TREE_STATIC (c_ctor) = 1;
1034       DECL_INITIAL (c_var) = c_ctor;
1035       varpool_node::finalize_decl (c_var);
1036
1037       append_to_statement_list (
1038         build_call_expr (init_decl, 2, build_int_cst (unsigned_type_node, 1),
1039                          build_fold_addr_expr (c_var)),
1040         &ctor_statements);
1041       cgraph_build_static_cdtor ('I', ctor_statements,
1042                                  MAX_RESERVED_INIT_PRIORITY - 1);
1043
1044       append_to_statement_list (build_call_expr (exit_decl, 1,
1045                                                  build_fold_addr_expr (c_var)),
1046                                 &dctor_statements);
1047       cgraph_build_static_cdtor ('D', dctor_statements,
1048                                  MAX_RESERVED_INIT_PRIORITY - 1);
1049     }
1050   else if (flag_sanitize & SANITIZE_EFFICIENCY_WORKING_SET)
1051     {
1052       tool_id = build_int_cst (unsigned_type_node, 2);
1053       append_to_statement_list (
1054         build_call_expr (init_decl, 2, build_int_cst (unsigned_type_node, 2),
1055                          build_zero_cst (long_unsigned_type_node)),
1056         &ctor_statements);
1057       cgraph_build_static_cdtor ('I', ctor_statements,
1058                                  MAX_RESERVED_INIT_PRIORITY - 1);
1059       append_to_statement_list (build_call_expr (exit_decl, 0),
1060                                 &dctor_statements);
1061       cgraph_build_static_cdtor ('D', dctor_statements,
1062                                  MAX_RESERVED_INIT_PRIORITY - 1);
1063     }
1064
1065   tree tool_id_type = build_array_type_nelts (unsigned_type_node, 1);
1066
1067   /* Runtime part relies on __esan_which_tool global, which
1068      informs the runtime about what part of runtime library should run.  */
1069   tree tool_id_decl
1070     = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1071                   get_identifier ("__esan_which_tool"), tool_id_type);
1072   TREE_STATIC (tool_id_decl) = 1;
1073   TREE_PUBLIC (tool_id_decl) = 1;
1074   DECL_WEAK (tool_id_decl) = 1;
1075   DECL_ARTIFICIAL (tool_id_decl) = 1;
1076   DECL_IGNORED_P (tool_id_decl) = 1;
1077   DECL_EXTERNAL (tool_id_decl) = 0;
1078
1079   tree tool_id_ctor
1080     = build_constructor_va (TREE_TYPE (tool_id_decl), 1, NULL_TREE, tool_id);
1081   TREE_CONSTANT (tool_id_ctor) = 1;
1082   TREE_STATIC (tool_id_ctor) = 1;
1083   DECL_INITIAL (tool_id_decl) = tool_id_ctor;
1084   varpool_node::finalize_decl (tool_id_decl);
1085 }
1086
1087 /* The pass descriptor.  */
1088
1089 namespace {
1090
1091 const pass_data pass_data_esan = {
1092   GIMPLE_PASS,           /* type */
1093   "esan",                /* name */
1094   OPTGROUP_NONE,         /* optinfo_flags */
1095   TV_NONE,               /* tv_id */
1096   (PROP_ssa | PROP_cfg), /* properties_required */
1097   0,                     /* properties_provided */
1098   0,                     /* properties_destroyed */
1099   0,                     /* todo_flags_start */
1100   TODO_update_ssa,       /* todo_flags_finish */
1101 };
1102
1103 class pass_esan : public gimple_opt_pass
1104 {
1105 public:
1106   pass_esan (gcc::context *ctxt)
1107     : gimple_opt_pass (pass_data_esan, ctxt) {}
1108
1109   /* opt_pass methods: */
1110   opt_pass *
1111   clone () { return new pass_esan (m_ctxt); }
1112
1113   virtual bool
1114   gate (function *)
1115   {
1116     return (
1117       (flag_sanitize
1118        & (SANITIZE_EFFICIENCY_WORKING_SET | SANITIZE_EFFICIENCY_CACHE_FRAG))
1119       != 0);
1120   }
1121
1122   virtual unsigned int
1123   execute (function *) { return esan_pass (); }
1124
1125 }; // class pass_esan
1126
1127 } // namespace
1128
1129 gimple_opt_pass *
1130 make_pass_esan (gcc::context *ctxt)
1131 {
1132   return new pass_esan (ctxt);
1133 }
1134
1135 namespace {
1136
1137 const pass_data pass_data_esan_O0 = {
1138   GIMPLE_PASS,           /* type */
1139   "esan0",               /* name */
1140   OPTGROUP_NONE,         /* optinfo_flags */
1141   TV_NONE,               /* tv_id */
1142   (PROP_ssa | PROP_cfg), /* properties_required */
1143   0,                     /* properties_provided */
1144   0,                     /* properties_destroyed */
1145   0,                     /* todo_flags_start */
1146   TODO_update_ssa,       /* todo_flags_finish */
1147 };
1148
1149 class pass_esan_O0 : public gimple_opt_pass
1150 {
1151 public:
1152   pass_esan_O0 (gcc::context *ctxt)
1153     : gimple_opt_pass (pass_data_esan_O0, ctxt) {}
1154
1155   /* opt_pass methods: */
1156   virtual bool
1157   gate (function *)
1158   {
1159     return (
1160       (flag_sanitize
1161        & (SANITIZE_EFFICIENCY_WORKING_SET | SANITIZE_EFFICIENCY_CACHE_FRAG))
1162         != 0
1163       && !optimize);
1164   }
1165
1166   virtual unsigned int
1167   execute (function *) { return esan_pass (); }
1168
1169 }; // class pass_esan_O0
1170
1171 } // namespace
1172
1173 gimple_opt_pass *
1174 make_pass_esan_O0 (gcc::context *ctxt)
1175 {
1176   return new pass_esan_O0 (ctxt);
1177 }