use templates instead of gengtype for typed allocation functions
[official-gcc.git] / gcc / ubsan.c
blob11461d00abd314efd5c927f1ccf917e89deeb8c0
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2014 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
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.
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.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "stor-layout.h"
26 #include "stringpool.h"
27 #include "cgraph.h"
28 #include "tree-pass.h"
29 #include "tree-ssa-alias.h"
30 #include "tree-pretty-print.h"
31 #include "internal-fn.h"
32 #include "gimple-expr.h"
33 #include "gimple.h"
34 #include "gimple-iterator.h"
35 #include "gimple-ssa.h"
36 #include "gimple-walk.h"
37 #include "hashtab.h"
38 #include "output.h"
39 #include "tm_p.h"
40 #include "toplev.h"
41 #include "cfgloop.h"
42 #include "ubsan.h"
43 #include "c-family/c-common.h"
44 #include "rtl.h"
45 #include "expr.h"
46 #include "tree-ssanames.h"
47 #include "asan.h"
48 #include "gimplify-me.h"
49 #include "intl.h"
51 /* Map from a tree to a VAR_DECL tree. */
53 struct GTY(()) tree_type_map {
54 struct tree_map_base type;
55 tree decl;
58 #define tree_type_map_eq tree_map_base_eq
59 #define tree_type_map_marked_p tree_map_base_marked_p
61 /* Hash from a tree in a tree_type_map. */
63 unsigned int
64 tree_type_map_hash (const void *item)
66 return TYPE_UID (((const struct tree_type_map *)item)->type.from);
69 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map)))
70 htab_t decl_tree_for_type;
72 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
74 static tree
75 decl_for_type_lookup (tree type)
77 /* If the hash table is not initialized yet, create it now. */
78 if (decl_tree_for_type == NULL)
80 decl_tree_for_type = htab_create_ggc (10, tree_type_map_hash,
81 tree_type_map_eq, 0);
82 /* That also means we don't have to bother with the lookup. */
83 return NULL_TREE;
86 struct tree_type_map *h, in;
87 in.type.from = type;
89 h = (struct tree_type_map *)
90 htab_find_with_hash (decl_tree_for_type, &in, TYPE_UID (type));
91 return h ? h->decl : NULL_TREE;
94 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
96 static void
97 decl_for_type_insert (tree type, tree decl)
99 struct tree_type_map *h;
100 void **slot;
102 h = ggc_alloc<tree_type_map> ();
103 h->type.from = type;
104 h->decl = decl;
105 slot = htab_find_slot_with_hash (decl_tree_for_type, h, TYPE_UID (type),
106 INSERT);
107 *(struct tree_type_map **) slot = h;
110 /* Helper routine, which encodes a value in the pointer_sized_int_node.
111 Arguments with precision <= POINTER_SIZE are passed directly,
112 the rest is passed by reference. T is a value we are to encode.
113 IN_EXPAND_P is true if this function is called during expansion. */
115 tree
116 ubsan_encode_value (tree t, bool in_expand_p)
118 tree type = TREE_TYPE (t);
119 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
120 if (bitsize <= POINTER_SIZE)
121 switch (TREE_CODE (type))
123 case BOOLEAN_TYPE:
124 case ENUMERAL_TYPE:
125 case INTEGER_TYPE:
126 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
127 case REAL_TYPE:
129 tree itype = build_nonstandard_integer_type (bitsize, true);
130 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
131 return fold_convert (pointer_sized_int_node, t);
133 default:
134 gcc_unreachable ();
136 else
138 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
140 /* The reason for this is that we don't want to pessimize
141 code by making vars unnecessarily addressable. */
142 tree var = create_tmp_var (type, NULL);
143 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
144 if (in_expand_p)
146 rtx mem
147 = assign_stack_temp_for_type (TYPE_MODE (type),
148 GET_MODE_SIZE (TYPE_MODE (type)),
149 type);
150 SET_DECL_RTL (var, mem);
151 expand_assignment (var, t, false);
152 return build_fold_addr_expr (var);
154 t = build_fold_addr_expr (var);
155 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
157 else
158 return build_fold_addr_expr (t);
162 /* Build
163 struct __ubsan_type_descriptor
165 unsigned short __typekind;
166 unsigned short __typeinfo;
167 char __typename[];
169 type. */
171 static tree
172 ubsan_type_descriptor_type (void)
174 static const char *field_names[3]
175 = { "__typekind", "__typeinfo", "__typename" };
176 tree fields[3], ret;
177 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
178 tree flex_arr_type = build_array_type (char_type_node, itype);
180 ret = make_node (RECORD_TYPE);
181 for (int i = 0; i < 3; i++)
183 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
184 get_identifier (field_names[i]),
185 (i == 2) ? flex_arr_type
186 : short_unsigned_type_node);
187 DECL_CONTEXT (fields[i]) = ret;
188 if (i)
189 DECL_CHAIN (fields[i - 1]) = fields[i];
191 TYPE_FIELDS (ret) = fields[0];
192 TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
193 layout_type (ret);
194 return ret;
197 /* Build
198 struct __ubsan_source_location
200 const char *__filename;
201 unsigned int __line;
202 unsigned int __column;
204 type. */
206 static tree
207 ubsan_source_location_type (void)
209 static const char *field_names[3]
210 = { "__filename", "__line", "__column" };
211 tree fields[3], ret;
212 tree const_char_type = build_qualified_type (char_type_node,
213 TYPE_QUAL_CONST);
215 ret = make_node (RECORD_TYPE);
216 for (int i = 0; i < 3; i++)
218 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
219 get_identifier (field_names[i]),
220 (i == 0) ? build_pointer_type (const_char_type)
221 : unsigned_type_node);
222 DECL_CONTEXT (fields[i]) = ret;
223 if (i)
224 DECL_CHAIN (fields[i - 1]) = fields[i];
226 TYPE_FIELDS (ret) = fields[0];
227 TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
228 layout_type (ret);
229 return ret;
232 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
233 type with its fields filled from a location_t LOC. */
235 static tree
236 ubsan_source_location (location_t loc)
238 expanded_location xloc;
239 tree type = ubsan_source_location_type ();
241 xloc = expand_location (loc);
242 if (xloc.file == NULL)
243 xloc.file = "<unknown>";
245 /* Fill in the values from LOC. */
246 size_t len = strlen (xloc.file);
247 tree str = build_string (len + 1, xloc.file);
248 TREE_TYPE (str) = build_array_type (char_type_node,
249 build_index_type (size_int (len)));
250 TREE_READONLY (str) = 1;
251 TREE_STATIC (str) = 1;
252 str = build_fold_addr_expr (str);
253 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
254 build_int_cst (unsigned_type_node,
255 xloc.line), NULL_TREE,
256 build_int_cst (unsigned_type_node,
257 xloc.column));
258 TREE_CONSTANT (ctor) = 1;
259 TREE_STATIC (ctor) = 1;
261 return ctor;
264 /* This routine returns a magic number for TYPE. */
266 static unsigned short
267 get_ubsan_type_info_for_type (tree type)
269 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
270 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
271 gcc_assert (prec != -1);
272 return (prec << 1) | !TYPE_UNSIGNED (type);
275 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
276 descriptor. It first looks into the hash table; if not found,
277 create the VAR_DECL, put it into the hash table and return the
278 ADDR_EXPR of it. TYPE describes a particular type. WANT_POINTER_TYPE_P
279 means whether we are interested in the pointer type and not the pointer
280 itself. */
282 tree
283 ubsan_type_descriptor (tree type, bool want_pointer_type_p)
285 /* See through any typedefs. */
286 type = TYPE_MAIN_VARIANT (type);
288 tree decl = decl_for_type_lookup (type);
289 /* It is possible that some of the earlier created DECLs were found
290 unused, in that case they weren't emitted and varpool_get_node
291 returns NULL node on them. But now we really need them. Thus,
292 renew them here. */
293 if (decl != NULL_TREE && varpool_get_node (decl))
294 return build_fold_addr_expr (decl);
296 tree dtype = ubsan_type_descriptor_type ();
297 tree type2 = type;
298 const char *tname = NULL;
299 char *pretty_name;
300 unsigned char deref_depth = 0;
301 unsigned short tkind, tinfo;
303 /* Get the name of the type, or the name of the pointer type. */
304 if (want_pointer_type_p)
306 gcc_assert (POINTER_TYPE_P (type));
307 type2 = TREE_TYPE (type);
309 /* Remove any '*' operators from TYPE. */
310 while (POINTER_TYPE_P (type2))
311 deref_depth++, type2 = TREE_TYPE (type2);
313 if (TREE_CODE (type2) == METHOD_TYPE)
314 type2 = TYPE_METHOD_BASETYPE (type2);
317 /* If an array, get its type. */
318 type2 = strip_array_types (type2);
320 if (TYPE_NAME (type2) != NULL)
322 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
323 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
324 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
325 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
328 if (tname == NULL)
329 /* We weren't able to determine the type name. */
330 tname = "<unknown>";
332 /* Decorate the type name with '', '*', "struct", or "union". */
333 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
334 if (want_pointer_type_p)
336 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
337 TYPE_VOLATILE (type2) ? "volatile " : "",
338 TYPE_READONLY (type2) ? "const " : "",
339 TYPE_RESTRICT (type2) ? "restrict " : "",
340 TYPE_ATOMIC (type2) ? "_Atomic " : "",
341 TREE_CODE (type2) == RECORD_TYPE
342 ? "struct "
343 : TREE_CODE (type2) == UNION_TYPE
344 ? "union " : "", tname,
345 deref_depth == 0 ? "" : " ");
346 while (deref_depth-- > 0)
347 pretty_name[pos++] = '*';
348 pretty_name[pos++] = '\'';
349 pretty_name[pos] = '\0';
351 else
352 sprintf (pretty_name, "'%s'", tname);
354 switch (TREE_CODE (type))
356 case BOOLEAN_TYPE:
357 case ENUMERAL_TYPE:
358 case INTEGER_TYPE:
359 tkind = 0x0000;
360 break;
361 case REAL_TYPE:
362 tkind = 0x0001;
363 break;
364 default:
365 tkind = 0xffff;
366 break;
368 tinfo = get_ubsan_type_info_for_type (type);
370 /* Create a new VAR_DECL of type descriptor. */
371 char tmp_name[32];
372 static unsigned int type_var_id_num;
373 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
374 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
375 dtype);
376 TREE_STATIC (decl) = 1;
377 TREE_PUBLIC (decl) = 0;
378 DECL_ARTIFICIAL (decl) = 1;
379 DECL_IGNORED_P (decl) = 1;
380 DECL_EXTERNAL (decl) = 0;
382 size_t len = strlen (pretty_name);
383 tree str = build_string (len + 1, pretty_name);
384 TREE_TYPE (str) = build_array_type (char_type_node,
385 build_index_type (size_int (len)));
386 TREE_READONLY (str) = 1;
387 TREE_STATIC (str) = 1;
388 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
389 build_int_cst (short_unsigned_type_node,
390 tkind), NULL_TREE,
391 build_int_cst (short_unsigned_type_node,
392 tinfo), NULL_TREE, str);
393 TREE_CONSTANT (ctor) = 1;
394 TREE_STATIC (ctor) = 1;
395 DECL_INITIAL (decl) = ctor;
396 varpool_finalize_decl (decl);
398 /* Save the VAR_DECL into the hash table. */
399 decl_for_type_insert (type, decl);
401 return build_fold_addr_expr (decl);
404 /* Create a structure for the ubsan library. NAME is a name of the new
405 structure. The arguments in ... are of __ubsan_type_descriptor type
406 and there are at most two of them. MISMATCH are data used by ubsan
407 pointer checking. */
409 tree
410 ubsan_create_data (const char *name, const location_t *ploc,
411 const struct ubsan_mismatch_data *mismatch, ...)
413 va_list args;
414 tree ret, t;
415 tree fields[5];
416 vec<tree, va_gc> *saved_args = NULL;
417 size_t i = 0;
418 location_t loc = UNKNOWN_LOCATION;
420 /* Firstly, create a pointer to type descriptor type. */
421 tree td_type = ubsan_type_descriptor_type ();
422 TYPE_READONLY (td_type) = 1;
423 td_type = build_pointer_type (td_type);
425 /* Create the structure type. */
426 ret = make_node (RECORD_TYPE);
427 if (ploc != NULL)
429 loc = LOCATION_LOCUS (*ploc);
430 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
431 ubsan_source_location_type ());
432 DECL_CONTEXT (fields[i]) = ret;
433 i++;
436 va_start (args, mismatch);
437 for (t = va_arg (args, tree); t != NULL_TREE;
438 i++, t = va_arg (args, tree))
440 gcc_checking_assert (i < 3);
441 /* Save the tree arguments for later use. */
442 vec_safe_push (saved_args, t);
443 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
444 td_type);
445 DECL_CONTEXT (fields[i]) = ret;
446 if (i)
447 DECL_CHAIN (fields[i - 1]) = fields[i];
449 va_end (args);
451 if (mismatch != NULL)
453 /* We have to add two more decls. */
454 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
455 pointer_sized_int_node);
456 DECL_CONTEXT (fields[i]) = ret;
457 DECL_CHAIN (fields[i - 1]) = fields[i];
458 i++;
460 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
461 unsigned_char_type_node);
462 DECL_CONTEXT (fields[i]) = ret;
463 DECL_CHAIN (fields[i - 1]) = fields[i];
464 i++;
467 TYPE_FIELDS (ret) = fields[0];
468 TYPE_NAME (ret) = get_identifier (name);
469 layout_type (ret);
471 /* Now, fill in the type. */
472 char tmp_name[32];
473 static unsigned int ubsan_var_id_num;
474 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
475 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
476 ret);
477 TREE_STATIC (var) = 1;
478 TREE_PUBLIC (var) = 0;
479 DECL_ARTIFICIAL (var) = 1;
480 DECL_IGNORED_P (var) = 1;
481 DECL_EXTERNAL (var) = 0;
483 vec<constructor_elt, va_gc> *v;
484 vec_alloc (v, i);
485 tree ctor = build_constructor (ret, v);
487 /* If desirable, set the __ubsan_source_location element. */
488 if (ploc != NULL)
489 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
491 size_t nelts = vec_safe_length (saved_args);
492 for (i = 0; i < nelts; i++)
494 t = (*saved_args)[i];
495 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
498 if (mismatch != NULL)
500 /* Append the pointer data. */
501 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->align);
502 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->ckind);
505 TREE_CONSTANT (ctor) = 1;
506 TREE_STATIC (ctor) = 1;
507 DECL_INITIAL (var) = ctor;
508 varpool_finalize_decl (var);
510 return var;
513 /* Instrument the __builtin_unreachable call. We just call the libubsan
514 routine instead. */
516 tree
517 ubsan_instrument_unreachable (location_t loc)
519 if (flag_sanitize_undefined_trap_on_error)
520 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
522 initialize_sanitizer_builtins ();
523 tree data = ubsan_create_data ("__ubsan_unreachable_data", &loc, NULL,
524 NULL_TREE);
525 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
526 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
529 /* Return true if T is a call to a libubsan routine. */
531 bool
532 is_ubsan_builtin_p (tree t)
534 gcc_checking_assert (TREE_CODE (t) == FUNCTION_DECL);
535 return strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
536 "__builtin___ubsan_", 18) == 0;
539 /* Expand UBSAN_NULL internal call. */
541 void
542 ubsan_expand_null_ifn (gimple_stmt_iterator gsi)
544 gimple stmt = gsi_stmt (gsi);
545 location_t loc = gimple_location (stmt);
546 gcc_assert (gimple_call_num_args (stmt) == 2);
547 tree ptr = gimple_call_arg (stmt, 0);
548 tree ckind = gimple_call_arg (stmt, 1);
550 basic_block cur_bb = gsi_bb (gsi);
552 /* Split the original block holding the pointer dereference. */
553 edge e = split_block (cur_bb, stmt);
555 /* Get a hold on the 'condition block', the 'then block' and the
556 'else block'. */
557 basic_block cond_bb = e->src;
558 basic_block fallthru_bb = e->dest;
559 basic_block then_bb = create_empty_bb (cond_bb);
560 if (current_loops)
562 add_bb_to_loop (then_bb, cond_bb->loop_father);
563 loops_state_set (LOOPS_NEED_FIXUP);
566 /* Make an edge coming from the 'cond block' into the 'then block';
567 this edge is unlikely taken, so set up the probability accordingly. */
568 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
569 e->probability = PROB_VERY_UNLIKELY;
571 /* Connect 'then block' with the 'else block'. This is needed
572 as the ubsan routines we call in the 'then block' are not noreturn.
573 The 'then block' only has one outcoming edge. */
574 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
576 /* Set up the fallthrough basic block. */
577 e = find_edge (cond_bb, fallthru_bb);
578 e->flags = EDGE_FALSE_VALUE;
579 e->count = cond_bb->count;
580 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
582 /* Update dominance info for the newly created then_bb; note that
583 fallthru_bb's dominance info has already been updated by
584 split_bock. */
585 if (dom_info_available_p (CDI_DOMINATORS))
586 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
588 /* Put the ubsan builtin call into the newly created BB. */
589 gimple g;
590 if (flag_sanitize_undefined_trap_on_error)
591 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
592 else
594 enum built_in_function bcode
595 = flag_sanitize_recover
596 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
597 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
598 tree fn = builtin_decl_implicit (bcode);
599 const struct ubsan_mismatch_data m
600 = { build_zero_cst (pointer_sized_int_node), ckind };
601 tree data = ubsan_create_data ("__ubsan_null_data", &loc, &m,
602 ubsan_type_descriptor (TREE_TYPE (ptr),
603 true), NULL_TREE);
604 data = build_fold_addr_expr_loc (loc, data);
605 g = gimple_build_call (fn, 2, data,
606 build_zero_cst (pointer_sized_int_node));
608 gimple_set_location (g, loc);
609 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
610 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
612 /* Unlink the UBSAN_NULLs vops before replacing it. */
613 unlink_stmt_vdef (stmt);
615 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
616 NULL_TREE, NULL_TREE);
617 gimple_set_location (g, loc);
619 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
620 gsi_replace (&gsi, g, false);
623 /* Instrument a member call. We check whether 'this' is NULL. */
625 static void
626 instrument_member_call (gimple_stmt_iterator *iter)
628 tree this_parm = gimple_call_arg (gsi_stmt (*iter), 0);
629 tree kind = build_int_cst (unsigned_char_type_node, UBSAN_MEMBER_CALL);
630 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, this_parm, kind);
631 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
632 gsi_insert_before (iter, g, GSI_SAME_STMT);
635 /* Instrument a memory reference. T is the pointer, IS_LHS says
636 whether the pointer is on the left hand side of the assignment. */
638 static void
639 instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
641 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
642 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
643 ikind = UBSAN_MEMBER_ACCESS;
644 tree kind = build_int_cst (unsigned_char_type_node, ikind);
645 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, t, kind);
646 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
647 gsi_insert_before (iter, g, GSI_SAME_STMT);
650 /* Perform the pointer instrumentation. */
652 static void
653 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
655 gimple stmt = gsi_stmt (gsi);
656 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
657 t = get_base_address (t);
658 const enum tree_code code = TREE_CODE (t);
659 if (code == MEM_REF
660 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
661 instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
662 else if (code == ADDR_EXPR
663 && POINTER_TYPE_P (TREE_TYPE (t))
664 && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
665 instrument_member_call (&gsi);
668 /* Build an ubsan builtin call for the signed-integer-overflow
669 sanitization. CODE says what kind of builtin are we building,
670 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
671 are operands of the binary operation. */
673 tree
674 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
675 tree op0, tree op1)
677 if (flag_sanitize_undefined_trap_on_error)
678 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
680 tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
681 ubsan_type_descriptor (lhstype, false),
682 NULL_TREE);
683 enum built_in_function fn_code;
685 switch (code)
687 case PLUS_EXPR:
688 fn_code = flag_sanitize_recover
689 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
690 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
691 break;
692 case MINUS_EXPR:
693 fn_code = flag_sanitize_recover
694 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
695 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
696 break;
697 case MULT_EXPR:
698 fn_code = flag_sanitize_recover
699 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
700 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
701 break;
702 case NEGATE_EXPR:
703 fn_code = flag_sanitize_recover
704 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
705 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
706 break;
707 default:
708 gcc_unreachable ();
710 tree fn = builtin_decl_explicit (fn_code);
711 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
712 build_fold_addr_expr_loc (loc, data),
713 ubsan_encode_value (op0, true),
714 op1 ? ubsan_encode_value (op1, true)
715 : NULL_TREE);
718 /* Perform the signed integer instrumentation. GSI is the iterator
719 pointing at statement we are trying to instrument. */
721 static void
722 instrument_si_overflow (gimple_stmt_iterator gsi)
724 gimple stmt = gsi_stmt (gsi);
725 tree_code code = gimple_assign_rhs_code (stmt);
726 tree lhs = gimple_assign_lhs (stmt);
727 tree lhstype = TREE_TYPE (lhs);
728 tree a, b;
729 gimple g;
731 /* If this is not a signed operation, don't instrument anything here.
732 Also punt on bit-fields. */
733 if (!INTEGRAL_TYPE_P (lhstype)
734 || TYPE_OVERFLOW_WRAPS (lhstype)
735 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
736 return;
738 switch (code)
740 case MINUS_EXPR:
741 case PLUS_EXPR:
742 case MULT_EXPR:
743 /* Transform
744 i = u {+,-,*} 5;
745 into
746 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
747 a = gimple_assign_rhs1 (stmt);
748 b = gimple_assign_rhs2 (stmt);
749 g = gimple_build_call_internal (code == PLUS_EXPR
750 ? IFN_UBSAN_CHECK_ADD
751 : code == MINUS_EXPR
752 ? IFN_UBSAN_CHECK_SUB
753 : IFN_UBSAN_CHECK_MUL, 2, a, b);
754 gimple_call_set_lhs (g, lhs);
755 gsi_replace (&gsi, g, false);
756 break;
757 case NEGATE_EXPR:
758 /* Represent i = -u;
760 i = UBSAN_CHECK_SUB (0, u); */
761 a = build_int_cst (lhstype, 0);
762 b = gimple_assign_rhs1 (stmt);
763 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
764 gimple_call_set_lhs (g, lhs);
765 gsi_replace (&gsi, g, false);
766 break;
767 case ABS_EXPR:
768 /* Transform i = ABS_EXPR<u>;
769 into
770 _N = UBSAN_CHECK_SUB (0, u);
771 i = ABS_EXPR<_N>; */
772 a = build_int_cst (lhstype, 0);
773 b = gimple_assign_rhs1 (stmt);
774 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
775 a = make_ssa_name (lhstype, NULL);
776 gimple_call_set_lhs (g, a);
777 gimple_set_location (g, gimple_location (stmt));
778 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
779 gimple_assign_set_rhs1 (stmt, a);
780 update_stmt (stmt);
781 break;
782 default:
783 break;
787 /* Instrument loads from (non-bitfield) bool and C++ enum values
788 to check if the memory value is outside of the range of the valid
789 type values. */
791 static void
792 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
794 gimple stmt = gsi_stmt (*gsi);
795 tree rhs = gimple_assign_rhs1 (stmt);
796 tree type = TREE_TYPE (rhs);
797 tree minv = NULL_TREE, maxv = NULL_TREE;
799 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
801 minv = boolean_false_node;
802 maxv = boolean_true_node;
804 else if (TREE_CODE (type) == ENUMERAL_TYPE
805 && (flag_sanitize & SANITIZE_ENUM)
806 && TREE_TYPE (type) != NULL_TREE
807 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
808 && (TYPE_PRECISION (TREE_TYPE (type))
809 < GET_MODE_PRECISION (TYPE_MODE (type))))
811 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
812 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
814 else
815 return;
817 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
818 HOST_WIDE_INT bitsize, bitpos;
819 tree offset;
820 enum machine_mode mode;
821 int volatilep = 0, unsignedp = 0;
822 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
823 &unsignedp, &volatilep, false);
824 tree utype = build_nonstandard_integer_type (modebitsize, 1);
826 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
827 || (bitpos % modebitsize) != 0
828 || bitsize != modebitsize
829 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
830 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
831 return;
833 location_t loc = gimple_location (stmt);
834 tree ptype = build_pointer_type (TREE_TYPE (rhs));
835 tree atype = reference_alias_ptr_type (rhs);
836 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
837 build_fold_addr_expr (rhs));
838 gimple_set_location (g, loc);
839 gsi_insert_before (gsi, g, GSI_SAME_STMT);
840 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
841 build_int_cst (atype, 0));
842 tree urhs = make_ssa_name (utype, NULL);
843 g = gimple_build_assign (urhs, mem);
844 gimple_set_location (g, loc);
845 gsi_insert_before (gsi, g, GSI_SAME_STMT);
846 minv = fold_convert (utype, minv);
847 maxv = fold_convert (utype, maxv);
848 if (!integer_zerop (minv))
850 g = gimple_build_assign_with_ops (MINUS_EXPR,
851 make_ssa_name (utype, NULL),
852 urhs, minv);
853 gimple_set_location (g, loc);
854 gsi_insert_before (gsi, g, GSI_SAME_STMT);
857 gimple_stmt_iterator gsi2 = *gsi;
858 basic_block then_bb, fallthru_bb;
859 *gsi = create_cond_insert_point (gsi, true, false, true,
860 &then_bb, &fallthru_bb);
861 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
862 int_const_binop (MINUS_EXPR, maxv, minv),
863 NULL_TREE, NULL_TREE);
864 gimple_set_location (g, loc);
865 gsi_insert_after (gsi, g, GSI_NEW_STMT);
867 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
868 update_stmt (stmt);
870 gsi2 = gsi_after_labels (then_bb);
871 if (flag_sanitize_undefined_trap_on_error)
872 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
873 else
875 tree data = ubsan_create_data ("__ubsan_invalid_value_data", &loc, NULL,
876 ubsan_type_descriptor (type, false),
877 NULL_TREE);
878 data = build_fold_addr_expr_loc (loc, data);
879 enum built_in_function bcode
880 = flag_sanitize_recover
881 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
882 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
883 tree fn = builtin_decl_explicit (bcode);
885 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
886 true, NULL_TREE, true,
887 GSI_SAME_STMT);
888 g = gimple_build_call (fn, 2, data, val);
890 gimple_set_location (g, loc);
891 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
894 namespace {
896 const pass_data pass_data_ubsan =
898 GIMPLE_PASS, /* type */
899 "ubsan", /* name */
900 OPTGROUP_NONE, /* optinfo_flags */
901 true, /* has_execute */
902 TV_TREE_UBSAN, /* tv_id */
903 ( PROP_cfg | PROP_ssa ), /* properties_required */
904 0, /* properties_provided */
905 0, /* properties_destroyed */
906 0, /* todo_flags_start */
907 TODO_update_ssa, /* todo_flags_finish */
910 class pass_ubsan : public gimple_opt_pass
912 public:
913 pass_ubsan (gcc::context *ctxt)
914 : gimple_opt_pass (pass_data_ubsan, ctxt)
917 /* opt_pass methods: */
918 virtual bool gate (function *)
920 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
921 | SANITIZE_BOOL | SANITIZE_ENUM);
924 virtual unsigned int execute (function *);
926 }; // class pass_ubsan
928 unsigned int
929 pass_ubsan::execute (function *fun)
931 basic_block bb;
932 gimple_stmt_iterator gsi;
934 initialize_sanitizer_builtins ();
936 FOR_EACH_BB_FN (bb, fun)
938 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
940 gimple stmt = gsi_stmt (gsi);
941 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
943 gsi_next (&gsi);
944 continue;
947 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
948 && is_gimple_assign (stmt))
949 instrument_si_overflow (gsi);
951 if (flag_sanitize & SANITIZE_NULL)
953 if (gimple_store_p (stmt))
954 instrument_null (gsi, true);
955 if (gimple_assign_load_p (stmt))
956 instrument_null (gsi, false);
959 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
960 && gimple_assign_load_p (stmt))
961 instrument_bool_enum_load (&gsi);
963 gsi_next (&gsi);
966 return 0;
969 } // anon namespace
971 gimple_opt_pass *
972 make_pass_ubsan (gcc::context *ctxt)
974 return new pass_ubsan (ctxt);
977 #include "gt-ubsan.h"