]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ubsan.c
tree-core.h: Include symtab.h.
[thirdparty/gcc.git] / gcc / ubsan.c
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
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 "alias.h"
25 #include "backend.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "rtl.h"
29 #include "ssa.h"
30 #include "options.h"
31 #include "fold-const.h"
32 #include "stor-layout.h"
33 #include "cfganal.h"
34 #include "cgraph.h"
35 #include "tree-pass.h"
36 #include "tree-pretty-print.h"
37 #include "internal-fn.h"
38 #include "gimple-iterator.h"
39 #include "gimple-walk.h"
40 #include "output.h"
41 #include "tm_p.h"
42 #include "toplev.h"
43 #include "cfgloop.h"
44 #include "ubsan.h"
45 #include "c-family/c-common.h"
46 #include "flags.h"
47 #include "insn-config.h"
48 #include "expmed.h"
49 #include "dojump.h"
50 #include "explow.h"
51 #include "calls.h"
52 #include "emit-rtl.h"
53 #include "varasm.h"
54 #include "stmt.h"
55 #include "expr.h"
56 #include "asan.h"
57 #include "gimplify-me.h"
58 #include "intl.h"
59 #include "realmpfr.h"
60 #include "dfp.h"
61 #include "builtins.h"
62 #include "tree-object-size.h"
63 #include "tree-eh.h"
64 #include "tree-cfg.h"
65
66 /* Map from a tree to a VAR_DECL tree. */
67
68 struct GTY((for_user)) tree_type_map {
69 struct tree_map_base type;
70 tree decl;
71 };
72
73 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
74 {
75 static inline hashval_t
76 hash (tree_type_map *t)
77 {
78 return TYPE_UID (t->type.from);
79 }
80
81 static inline bool
82 equal (tree_type_map *a, tree_type_map *b)
83 {
84 return a->type.from == b->type.from;
85 }
86
87 static int
88 keep_cache_entry (tree_type_map *&m)
89 {
90 return ggc_marked_p (m->type.from);
91 }
92 };
93
94 static GTY ((cache))
95 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
96
97 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
98
99 static tree
100 decl_for_type_lookup (tree type)
101 {
102 /* If the hash table is not initialized yet, create it now. */
103 if (decl_tree_for_type == NULL)
104 {
105 decl_tree_for_type
106 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
107 /* That also means we don't have to bother with the lookup. */
108 return NULL_TREE;
109 }
110
111 struct tree_type_map *h, in;
112 in.type.from = type;
113
114 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
115 return h ? h->decl : NULL_TREE;
116 }
117
118 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
119
120 static void
121 decl_for_type_insert (tree type, tree decl)
122 {
123 struct tree_type_map *h;
124
125 h = ggc_alloc<tree_type_map> ();
126 h->type.from = type;
127 h->decl = decl;
128 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
129 }
130
131 /* Helper routine, which encodes a value in the pointer_sized_int_node.
132 Arguments with precision <= POINTER_SIZE are passed directly,
133 the rest is passed by reference. T is a value we are to encode.
134 IN_EXPAND_P is true if this function is called during expansion. */
135
136 tree
137 ubsan_encode_value (tree t, bool in_expand_p)
138 {
139 tree type = TREE_TYPE (t);
140 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
141 if (bitsize <= POINTER_SIZE)
142 switch (TREE_CODE (type))
143 {
144 case BOOLEAN_TYPE:
145 case ENUMERAL_TYPE:
146 case INTEGER_TYPE:
147 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
148 case REAL_TYPE:
149 {
150 tree itype = build_nonstandard_integer_type (bitsize, true);
151 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
152 return fold_convert (pointer_sized_int_node, t);
153 }
154 default:
155 gcc_unreachable ();
156 }
157 else
158 {
159 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
160 {
161 /* The reason for this is that we don't want to pessimize
162 code by making vars unnecessarily addressable. */
163 tree var = create_tmp_var (type);
164 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
165 if (in_expand_p)
166 {
167 rtx mem
168 = assign_stack_temp_for_type (TYPE_MODE (type),
169 GET_MODE_SIZE (TYPE_MODE (type)),
170 type);
171 SET_DECL_RTL (var, mem);
172 expand_assignment (var, t, false);
173 return build_fold_addr_expr (var);
174 }
175 t = build_fold_addr_expr (var);
176 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
177 }
178 else
179 return build_fold_addr_expr (t);
180 }
181 }
182
183 /* Cached ubsan_get_type_descriptor_type () return value. */
184 static GTY(()) tree ubsan_type_descriptor_type;
185
186 /* Build
187 struct __ubsan_type_descriptor
188 {
189 unsigned short __typekind;
190 unsigned short __typeinfo;
191 char __typename[];
192 }
193 type. */
194
195 static tree
196 ubsan_get_type_descriptor_type (void)
197 {
198 static const char *field_names[3]
199 = { "__typekind", "__typeinfo", "__typename" };
200 tree fields[3], ret;
201
202 if (ubsan_type_descriptor_type)
203 return ubsan_type_descriptor_type;
204
205 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
206 tree flex_arr_type = build_array_type (char_type_node, itype);
207
208 ret = make_node (RECORD_TYPE);
209 for (int i = 0; i < 3; i++)
210 {
211 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
212 get_identifier (field_names[i]),
213 (i == 2) ? flex_arr_type
214 : short_unsigned_type_node);
215 DECL_CONTEXT (fields[i]) = ret;
216 if (i)
217 DECL_CHAIN (fields[i - 1]) = fields[i];
218 }
219 tree type_decl = build_decl (input_location, TYPE_DECL,
220 get_identifier ("__ubsan_type_descriptor"),
221 ret);
222 DECL_IGNORED_P (type_decl) = 1;
223 DECL_ARTIFICIAL (type_decl) = 1;
224 TYPE_FIELDS (ret) = fields[0];
225 TYPE_NAME (ret) = type_decl;
226 TYPE_STUB_DECL (ret) = type_decl;
227 layout_type (ret);
228 ubsan_type_descriptor_type = ret;
229 return ret;
230 }
231
232 /* Cached ubsan_get_source_location_type () return value. */
233 static GTY(()) tree ubsan_source_location_type;
234
235 /* Build
236 struct __ubsan_source_location
237 {
238 const char *__filename;
239 unsigned int __line;
240 unsigned int __column;
241 }
242 type. */
243
244 tree
245 ubsan_get_source_location_type (void)
246 {
247 static const char *field_names[3]
248 = { "__filename", "__line", "__column" };
249 tree fields[3], ret;
250 if (ubsan_source_location_type)
251 return ubsan_source_location_type;
252
253 tree const_char_type = build_qualified_type (char_type_node,
254 TYPE_QUAL_CONST);
255
256 ret = make_node (RECORD_TYPE);
257 for (int i = 0; i < 3; i++)
258 {
259 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
260 get_identifier (field_names[i]),
261 (i == 0) ? build_pointer_type (const_char_type)
262 : unsigned_type_node);
263 DECL_CONTEXT (fields[i]) = ret;
264 if (i)
265 DECL_CHAIN (fields[i - 1]) = fields[i];
266 }
267 tree type_decl = build_decl (input_location, TYPE_DECL,
268 get_identifier ("__ubsan_source_location"),
269 ret);
270 DECL_IGNORED_P (type_decl) = 1;
271 DECL_ARTIFICIAL (type_decl) = 1;
272 TYPE_FIELDS (ret) = fields[0];
273 TYPE_NAME (ret) = type_decl;
274 TYPE_STUB_DECL (ret) = type_decl;
275 layout_type (ret);
276 ubsan_source_location_type = ret;
277 return ret;
278 }
279
280 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
281 type with its fields filled from a location_t LOC. */
282
283 static tree
284 ubsan_source_location (location_t loc)
285 {
286 expanded_location xloc;
287 tree type = ubsan_get_source_location_type ();
288
289 xloc = expand_location (loc);
290 tree str;
291 if (xloc.file == NULL)
292 {
293 str = build_int_cst (ptr_type_node, 0);
294 xloc.line = 0;
295 xloc.column = 0;
296 }
297 else
298 {
299 /* Fill in the values from LOC. */
300 size_t len = strlen (xloc.file) + 1;
301 str = build_string (len, xloc.file);
302 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
303 TREE_READONLY (str) = 1;
304 TREE_STATIC (str) = 1;
305 str = build_fold_addr_expr (str);
306 }
307 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
308 build_int_cst (unsigned_type_node,
309 xloc.line), NULL_TREE,
310 build_int_cst (unsigned_type_node,
311 xloc.column));
312 TREE_CONSTANT (ctor) = 1;
313 TREE_STATIC (ctor) = 1;
314
315 return ctor;
316 }
317
318 /* This routine returns a magic number for TYPE. */
319
320 static unsigned short
321 get_ubsan_type_info_for_type (tree type)
322 {
323 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
324 if (TREE_CODE (type) == REAL_TYPE)
325 return tree_to_uhwi (TYPE_SIZE (type));
326 else if (INTEGRAL_TYPE_P (type))
327 {
328 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
329 gcc_assert (prec != -1);
330 return (prec << 1) | !TYPE_UNSIGNED (type);
331 }
332 else
333 return 0;
334 }
335
336 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
337 descriptor. It first looks into the hash table; if not found,
338 create the VAR_DECL, put it into the hash table and return the
339 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
340 an enum controlling how we want to print the type. */
341
342 tree
343 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
344 {
345 /* See through any typedefs. */
346 type = TYPE_MAIN_VARIANT (type);
347
348 tree decl = decl_for_type_lookup (type);
349 /* It is possible that some of the earlier created DECLs were found
350 unused, in that case they weren't emitted and varpool_node::get
351 returns NULL node on them. But now we really need them. Thus,
352 renew them here. */
353 if (decl != NULL_TREE && varpool_node::get (decl))
354 return build_fold_addr_expr (decl);
355
356 tree dtype = ubsan_get_type_descriptor_type ();
357 tree type2 = type;
358 const char *tname = NULL;
359 pretty_printer pretty_name;
360 unsigned char deref_depth = 0;
361 unsigned short tkind, tinfo;
362
363 /* Get the name of the type, or the name of the pointer type. */
364 if (pstyle == UBSAN_PRINT_POINTER)
365 {
366 gcc_assert (POINTER_TYPE_P (type));
367 type2 = TREE_TYPE (type);
368
369 /* Remove any '*' operators from TYPE. */
370 while (POINTER_TYPE_P (type2))
371 deref_depth++, type2 = TREE_TYPE (type2);
372
373 if (TREE_CODE (type2) == METHOD_TYPE)
374 type2 = TYPE_METHOD_BASETYPE (type2);
375 }
376
377 /* If an array, get its type. */
378 type2 = strip_array_types (type2);
379
380 if (pstyle == UBSAN_PRINT_ARRAY)
381 {
382 while (POINTER_TYPE_P (type2))
383 deref_depth++, type2 = TREE_TYPE (type2);
384 }
385
386 if (TYPE_NAME (type2) != NULL)
387 {
388 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
389 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
390 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
391 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
392 }
393
394 if (tname == NULL)
395 /* We weren't able to determine the type name. */
396 tname = "<unknown>";
397
398 if (pstyle == UBSAN_PRINT_POINTER)
399 {
400 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
401 TYPE_VOLATILE (type2) ? "volatile " : "",
402 TYPE_READONLY (type2) ? "const " : "",
403 TYPE_RESTRICT (type2) ? "restrict " : "",
404 TYPE_ATOMIC (type2) ? "_Atomic " : "",
405 TREE_CODE (type2) == RECORD_TYPE
406 ? "struct "
407 : TREE_CODE (type2) == UNION_TYPE
408 ? "union " : "", tname,
409 deref_depth == 0 ? "" : " ");
410 while (deref_depth-- > 0)
411 pp_star (&pretty_name);
412 pp_quote (&pretty_name);
413 }
414 else if (pstyle == UBSAN_PRINT_ARRAY)
415 {
416 /* Pretty print the array dimensions. */
417 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
418 tree t = type;
419 pp_printf (&pretty_name, "'%s ", tname);
420 while (deref_depth-- > 0)
421 pp_star (&pretty_name);
422 while (TREE_CODE (t) == ARRAY_TYPE)
423 {
424 pp_left_bracket (&pretty_name);
425 tree dom = TYPE_DOMAIN (t);
426 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
427 {
428 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
429 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
430 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
431 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
432 else
433 pp_wide_int (&pretty_name,
434 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
435 TYPE_SIGN (TREE_TYPE (dom)));
436 }
437 else
438 /* ??? We can't determine the variable name; print VLA unspec. */
439 pp_star (&pretty_name);
440 pp_right_bracket (&pretty_name);
441 t = TREE_TYPE (t);
442 }
443 pp_quote (&pretty_name);
444
445 /* Save the tree with stripped types. */
446 type = t;
447 }
448 else
449 pp_printf (&pretty_name, "'%s'", tname);
450
451 switch (TREE_CODE (type))
452 {
453 case BOOLEAN_TYPE:
454 case ENUMERAL_TYPE:
455 case INTEGER_TYPE:
456 tkind = 0x0000;
457 break;
458 case REAL_TYPE:
459 /* FIXME: libubsan right now only supports float, double and
460 long double type formats. */
461 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
462 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
463 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
464 tkind = 0x0001;
465 else
466 tkind = 0xffff;
467 break;
468 default:
469 tkind = 0xffff;
470 break;
471 }
472 tinfo = get_ubsan_type_info_for_type (type);
473
474 /* Create a new VAR_DECL of type descriptor. */
475 const char *tmp = pp_formatted_text (&pretty_name);
476 size_t len = strlen (tmp) + 1;
477 tree str = build_string (len, tmp);
478 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
479 TREE_READONLY (str) = 1;
480 TREE_STATIC (str) = 1;
481
482 char tmp_name[32];
483 static unsigned int type_var_id_num;
484 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
485 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
486 dtype);
487 TREE_STATIC (decl) = 1;
488 TREE_PUBLIC (decl) = 0;
489 DECL_ARTIFICIAL (decl) = 1;
490 DECL_IGNORED_P (decl) = 1;
491 DECL_EXTERNAL (decl) = 0;
492 DECL_SIZE (decl)
493 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
494 DECL_SIZE_UNIT (decl)
495 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
496 TYPE_SIZE_UNIT (TREE_TYPE (str)));
497
498 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
499 build_int_cst (short_unsigned_type_node,
500 tkind), NULL_TREE,
501 build_int_cst (short_unsigned_type_node,
502 tinfo), NULL_TREE, str);
503 TREE_CONSTANT (ctor) = 1;
504 TREE_STATIC (ctor) = 1;
505 DECL_INITIAL (decl) = ctor;
506 varpool_node::finalize_decl (decl);
507
508 /* Save the VAR_DECL into the hash table. */
509 decl_for_type_insert (type, decl);
510
511 return build_fold_addr_expr (decl);
512 }
513
514 /* Create a structure for the ubsan library. NAME is a name of the new
515 structure. LOCCNT is number of locations, PLOC points to array of
516 locations. The arguments in ... are of __ubsan_type_descriptor type
517 and there are at most two of them, followed by NULL_TREE, followed
518 by optional extra arguments and another NULL_TREE. */
519
520 tree
521 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
522 {
523 va_list args;
524 tree ret, t;
525 tree fields[6];
526 vec<tree, va_gc> *saved_args = NULL;
527 size_t i = 0;
528 int j;
529
530 /* Firstly, create a pointer to type descriptor type. */
531 tree td_type = ubsan_get_type_descriptor_type ();
532 td_type = build_pointer_type (td_type);
533
534 /* Create the structure type. */
535 ret = make_node (RECORD_TYPE);
536 for (j = 0; j < loccnt; j++)
537 {
538 gcc_checking_assert (i < 2);
539 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
540 ubsan_get_source_location_type ());
541 DECL_CONTEXT (fields[i]) = ret;
542 if (i)
543 DECL_CHAIN (fields[i - 1]) = fields[i];
544 i++;
545 }
546
547 va_start (args, ploc);
548 for (t = va_arg (args, tree); t != NULL_TREE;
549 i++, t = va_arg (args, tree))
550 {
551 gcc_checking_assert (i < 4);
552 /* Save the tree arguments for later use. */
553 vec_safe_push (saved_args, t);
554 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
555 td_type);
556 DECL_CONTEXT (fields[i]) = ret;
557 if (i)
558 DECL_CHAIN (fields[i - 1]) = fields[i];
559 }
560
561 for (t = va_arg (args, tree); t != NULL_TREE;
562 i++, t = va_arg (args, tree))
563 {
564 gcc_checking_assert (i < 6);
565 /* Save the tree arguments for later use. */
566 vec_safe_push (saved_args, t);
567 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
568 TREE_TYPE (t));
569 DECL_CONTEXT (fields[i]) = ret;
570 if (i)
571 DECL_CHAIN (fields[i - 1]) = fields[i];
572 }
573 va_end (args);
574
575 tree type_decl = build_decl (input_location, TYPE_DECL,
576 get_identifier (name), ret);
577 DECL_IGNORED_P (type_decl) = 1;
578 DECL_ARTIFICIAL (type_decl) = 1;
579 TYPE_FIELDS (ret) = fields[0];
580 TYPE_NAME (ret) = type_decl;
581 TYPE_STUB_DECL (ret) = type_decl;
582 layout_type (ret);
583
584 /* Now, fill in the type. */
585 char tmp_name[32];
586 static unsigned int ubsan_var_id_num;
587 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
588 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
589 ret);
590 TREE_STATIC (var) = 1;
591 TREE_PUBLIC (var) = 0;
592 DECL_ARTIFICIAL (var) = 1;
593 DECL_IGNORED_P (var) = 1;
594 DECL_EXTERNAL (var) = 0;
595
596 vec<constructor_elt, va_gc> *v;
597 vec_alloc (v, i);
598 tree ctor = build_constructor (ret, v);
599
600 /* If desirable, set the __ubsan_source_location element. */
601 for (j = 0; j < loccnt; j++)
602 {
603 location_t loc = LOCATION_LOCUS (ploc[j]);
604 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
605 }
606
607 size_t nelts = vec_safe_length (saved_args);
608 for (i = 0; i < nelts; i++)
609 {
610 t = (*saved_args)[i];
611 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
612 }
613
614 TREE_CONSTANT (ctor) = 1;
615 TREE_STATIC (ctor) = 1;
616 DECL_INITIAL (var) = ctor;
617 varpool_node::finalize_decl (var);
618
619 return var;
620 }
621
622 /* Instrument the __builtin_unreachable call. We just call the libubsan
623 routine instead. */
624
625 bool
626 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
627 {
628 gimple g;
629 location_t loc = gimple_location (gsi_stmt (*gsi));
630
631 if (flag_sanitize_undefined_trap_on_error)
632 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
633 else
634 {
635 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
636 NULL_TREE, NULL_TREE);
637 data = build_fold_addr_expr_loc (loc, data);
638 tree fn
639 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
640 g = gimple_build_call (fn, 1, data);
641 }
642 gimple_set_location (g, loc);
643 gsi_replace (gsi, g, false);
644 return false;
645 }
646
647 /* Return true if T is a call to a libubsan routine. */
648
649 bool
650 is_ubsan_builtin_p (tree t)
651 {
652 return TREE_CODE (t) == FUNCTION_DECL
653 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
654 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
655 "__builtin___ubsan_", 18) == 0;
656 }
657
658 /* Create a callgraph edge for statement STMT. */
659
660 static void
661 ubsan_create_edge (gimple stmt)
662 {
663 gcall *call_stmt = dyn_cast <gcall *> (stmt);
664 basic_block bb = gimple_bb (stmt);
665 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
666 cgraph_node *node = cgraph_node::get (current_function_decl);
667 tree decl = gimple_call_fndecl (call_stmt);
668 if (decl)
669 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
670 freq);
671 }
672
673 /* Expand the UBSAN_BOUNDS special builtin function. */
674
675 bool
676 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
677 {
678 gimple stmt = gsi_stmt (*gsi);
679 location_t loc = gimple_location (stmt);
680 gcc_assert (gimple_call_num_args (stmt) == 3);
681
682 /* Pick up the arguments of the UBSAN_BOUNDS call. */
683 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
684 tree index = gimple_call_arg (stmt, 1);
685 tree orig_index_type = TREE_TYPE (index);
686 tree bound = gimple_call_arg (stmt, 2);
687
688 gimple_stmt_iterator gsi_orig = *gsi;
689
690 /* Create condition "if (index > bound)". */
691 basic_block then_bb, fallthru_bb;
692 gimple_stmt_iterator cond_insert_point
693 = create_cond_insert_point (gsi, false, false, true,
694 &then_bb, &fallthru_bb);
695 index = fold_convert (TREE_TYPE (bound), index);
696 index = force_gimple_operand_gsi (&cond_insert_point, index,
697 true, NULL_TREE,
698 false, GSI_NEW_STMT);
699 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
700 gimple_set_location (g, loc);
701 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
702
703 /* Generate __ubsan_handle_out_of_bounds call. */
704 *gsi = gsi_after_labels (then_bb);
705 if (flag_sanitize_undefined_trap_on_error)
706 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
707 else
708 {
709 tree data
710 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
711 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
712 ubsan_type_descriptor (orig_index_type),
713 NULL_TREE, NULL_TREE);
714 data = build_fold_addr_expr_loc (loc, data);
715 enum built_in_function bcode
716 = (flag_sanitize_recover & SANITIZE_BOUNDS)
717 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
718 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
719 tree fn = builtin_decl_explicit (bcode);
720 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
721 true, NULL_TREE, true,
722 GSI_SAME_STMT);
723 g = gimple_build_call (fn, 2, data, val);
724 }
725 gimple_set_location (g, loc);
726 gsi_insert_before (gsi, g, GSI_SAME_STMT);
727
728 /* Get rid of the UBSAN_BOUNDS call from the IR. */
729 unlink_stmt_vdef (stmt);
730 gsi_remove (&gsi_orig, true);
731
732 /* Point GSI to next logical statement. */
733 *gsi = gsi_start_bb (fallthru_bb);
734 return true;
735 }
736
737 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
738 argument which is a constant, because the middle-end treats pointer
739 conversions as useless and therefore the type of the first argument
740 could be changed to any other pointer type. */
741
742 bool
743 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
744 {
745 gimple_stmt_iterator gsi = *gsip;
746 gimple stmt = gsi_stmt (gsi);
747 location_t loc = gimple_location (stmt);
748 gcc_assert (gimple_call_num_args (stmt) == 3);
749 tree ptr = gimple_call_arg (stmt, 0);
750 tree ckind = gimple_call_arg (stmt, 1);
751 tree align = gimple_call_arg (stmt, 2);
752 tree check_align = NULL_TREE;
753 bool check_null;
754
755 basic_block cur_bb = gsi_bb (gsi);
756
757 gimple g;
758 if (!integer_zerop (align))
759 {
760 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
761 if (compare_tree_int (align, ptralign) == 1)
762 {
763 check_align = make_ssa_name (pointer_sized_int_node);
764 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
765 gimple_set_location (g, loc);
766 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
767 }
768 }
769 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
770
771 if (check_align == NULL_TREE && !check_null)
772 {
773 gsi_remove (gsip, true);
774 /* Unlink the UBSAN_NULLs vops before replacing it. */
775 unlink_stmt_vdef (stmt);
776 return true;
777 }
778
779 /* Split the original block holding the pointer dereference. */
780 edge e = split_block (cur_bb, stmt);
781
782 /* Get a hold on the 'condition block', the 'then block' and the
783 'else block'. */
784 basic_block cond_bb = e->src;
785 basic_block fallthru_bb = e->dest;
786 basic_block then_bb = create_empty_bb (cond_bb);
787 add_bb_to_loop (then_bb, cond_bb->loop_father);
788 loops_state_set (LOOPS_NEED_FIXUP);
789
790 /* Make an edge coming from the 'cond block' into the 'then block';
791 this edge is unlikely taken, so set up the probability accordingly. */
792 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
793 e->probability = PROB_VERY_UNLIKELY;
794
795 /* Connect 'then block' with the 'else block'. This is needed
796 as the ubsan routines we call in the 'then block' are not noreturn.
797 The 'then block' only has one outcoming edge. */
798 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
799
800 /* Set up the fallthrough basic block. */
801 e = find_edge (cond_bb, fallthru_bb);
802 e->flags = EDGE_FALSE_VALUE;
803 e->count = cond_bb->count;
804 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
805
806 /* Update dominance info for the newly created then_bb; note that
807 fallthru_bb's dominance info has already been updated by
808 split_block. */
809 if (dom_info_available_p (CDI_DOMINATORS))
810 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
811
812 /* Put the ubsan builtin call into the newly created BB. */
813 if (flag_sanitize_undefined_trap_on_error)
814 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
815 else
816 {
817 enum built_in_function bcode
818 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
819 | (check_null ? SANITIZE_NULL : 0)))
820 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
821 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
822 tree fn = builtin_decl_implicit (bcode);
823 tree data
824 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
825 ubsan_type_descriptor (TREE_TYPE (ckind),
826 UBSAN_PRINT_POINTER),
827 NULL_TREE,
828 align,
829 fold_convert (unsigned_char_type_node, ckind),
830 NULL_TREE);
831 data = build_fold_addr_expr_loc (loc, data);
832 g = gimple_build_call (fn, 2, data,
833 check_align ? check_align
834 : build_zero_cst (pointer_sized_int_node));
835 }
836 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
837 gimple_set_location (g, loc);
838 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
839
840 /* Unlink the UBSAN_NULLs vops before replacing it. */
841 unlink_stmt_vdef (stmt);
842
843 if (check_null)
844 {
845 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
846 NULL_TREE, NULL_TREE);
847 gimple_set_location (g, loc);
848
849 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
850 gsi_replace (&gsi, g, false);
851 stmt = g;
852 }
853
854 if (check_align)
855 {
856 if (check_null)
857 {
858 /* Split the block with the condition again. */
859 e = split_block (cond_bb, stmt);
860 basic_block cond1_bb = e->src;
861 basic_block cond2_bb = e->dest;
862
863 /* Make an edge coming from the 'cond1 block' into the 'then block';
864 this edge is unlikely taken, so set up the probability
865 accordingly. */
866 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
867 e->probability = PROB_VERY_UNLIKELY;
868
869 /* Set up the fallthrough basic block. */
870 e = find_edge (cond1_bb, cond2_bb);
871 e->flags = EDGE_FALSE_VALUE;
872 e->count = cond1_bb->count;
873 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
874
875 /* Update dominance info. */
876 if (dom_info_available_p (CDI_DOMINATORS))
877 {
878 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
879 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
880 }
881
882 gsi2 = gsi_start_bb (cond2_bb);
883 }
884
885 tree mask = build_int_cst (pointer_sized_int_node,
886 tree_to_uhwi (align) - 1);
887 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
888 BIT_AND_EXPR, check_align, mask);
889 gimple_set_location (g, loc);
890 if (check_null)
891 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
892 else
893 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
894
895 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
896 build_int_cst (pointer_sized_int_node, 0),
897 NULL_TREE, NULL_TREE);
898 gimple_set_location (g, loc);
899 if (check_null)
900 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
901 else
902 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
903 gsi_replace (&gsi, g, false);
904 }
905 return false;
906 }
907
908 #define OBJSZ_MAX_OFFSET (1024 * 16)
909
910 /* Expand UBSAN_OBJECT_SIZE internal call. */
911
912 bool
913 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
914 {
915 gimple stmt = gsi_stmt (*gsi);
916 location_t loc = gimple_location (stmt);
917 gcc_assert (gimple_call_num_args (stmt) == 4);
918
919 tree ptr = gimple_call_arg (stmt, 0);
920 tree offset = gimple_call_arg (stmt, 1);
921 tree size = gimple_call_arg (stmt, 2);
922 tree ckind = gimple_call_arg (stmt, 3);
923 gimple_stmt_iterator gsi_orig = *gsi;
924 gimple g;
925
926 /* See if we can discard the check. */
927 if (TREE_CODE (size) != INTEGER_CST
928 || integer_all_onesp (size))
929 /* Yes, __builtin_object_size couldn't determine the
930 object size. */;
931 else if (TREE_CODE (offset) == INTEGER_CST
932 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
933 && wi::les_p (wi::to_widest (offset), -1))
934 /* The offset is in range [-16K, -1]. */;
935 else
936 {
937 /* if (offset > objsize) */
938 basic_block then_bb, fallthru_bb;
939 gimple_stmt_iterator cond_insert_point
940 = create_cond_insert_point (gsi, false, false, true,
941 &then_bb, &fallthru_bb);
942 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
943 gimple_set_location (g, loc);
944 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
945
946 /* If the offset is small enough, we don't need the second
947 run-time check. */
948 if (TREE_CODE (offset) == INTEGER_CST
949 && wi::ges_p (wi::to_widest (offset), 0)
950 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
951 *gsi = gsi_after_labels (then_bb);
952 else
953 {
954 /* Don't issue run-time error if (ptr > ptr + offset). That
955 may happen when computing a POINTER_PLUS_EXPR. */
956 basic_block then2_bb, fallthru2_bb;
957
958 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
959 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
960 true, &then2_bb,
961 &fallthru2_bb);
962 /* Convert the pointer to an integer type. */
963 tree p = make_ssa_name (pointer_sized_int_node);
964 g = gimple_build_assign (p, NOP_EXPR, ptr);
965 gimple_set_location (g, loc);
966 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
967 p = gimple_assign_lhs (g);
968 /* Compute ptr + offset. */
969 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
970 PLUS_EXPR, p, offset);
971 gimple_set_location (g, loc);
972 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
973 /* Now build the conditional and put it into the IR. */
974 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
975 NULL_TREE, NULL_TREE);
976 gimple_set_location (g, loc);
977 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
978 *gsi = gsi_after_labels (then2_bb);
979 }
980
981 /* Generate __ubsan_handle_type_mismatch call. */
982 if (flag_sanitize_undefined_trap_on_error)
983 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
984 else
985 {
986 tree data
987 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
988 ubsan_type_descriptor (TREE_TYPE (ptr),
989 UBSAN_PRINT_POINTER),
990 NULL_TREE,
991 build_zero_cst (pointer_sized_int_node),
992 ckind,
993 NULL_TREE);
994 data = build_fold_addr_expr_loc (loc, data);
995 enum built_in_function bcode
996 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
997 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
998 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
999 tree p = make_ssa_name (pointer_sized_int_node);
1000 g = gimple_build_assign (p, NOP_EXPR, ptr);
1001 gimple_set_location (g, loc);
1002 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1003 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1004 }
1005 gimple_set_location (g, loc);
1006 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1007
1008 /* Point GSI to next logical statement. */
1009 *gsi = gsi_start_bb (fallthru_bb);
1010
1011 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1012 unlink_stmt_vdef (stmt);
1013 gsi_remove (&gsi_orig, true);
1014 return true;
1015 }
1016
1017 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1018 unlink_stmt_vdef (stmt);
1019 gsi_remove (gsi, true);
1020 return true;
1021 }
1022
1023 /* Cached __ubsan_vptr_type_cache decl. */
1024 static GTY(()) tree ubsan_vptr_type_cache_decl;
1025
1026 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1027 argument which is a constant, because the middle-end treats pointer
1028 conversions as useless and therefore the type of the first argument
1029 could be changed to any other pointer type. */
1030
1031 bool
1032 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1033 {
1034 gimple_stmt_iterator gsi = *gsip;
1035 gimple stmt = gsi_stmt (gsi);
1036 location_t loc = gimple_location (stmt);
1037 gcc_assert (gimple_call_num_args (stmt) == 5);
1038 tree op = gimple_call_arg (stmt, 0);
1039 tree vptr = gimple_call_arg (stmt, 1);
1040 tree str_hash = gimple_call_arg (stmt, 2);
1041 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1042 tree ckind_tree = gimple_call_arg (stmt, 4);
1043 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1044 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1045 gimple g;
1046 basic_block fallthru_bb = NULL;
1047
1048 if (ckind == UBSAN_DOWNCAST_POINTER)
1049 {
1050 /* Guard everything with if (op != NULL) { ... }. */
1051 basic_block then_bb;
1052 gimple_stmt_iterator cond_insert_point
1053 = create_cond_insert_point (gsip, false, false, true,
1054 &then_bb, &fallthru_bb);
1055 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1056 NULL_TREE, NULL_TREE);
1057 gimple_set_location (g, loc);
1058 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1059 *gsip = gsi_after_labels (then_bb);
1060 gsi_remove (&gsi, false);
1061 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1062 gsi = *gsip;
1063 }
1064
1065 tree htype = TREE_TYPE (str_hash);
1066 tree cst = wide_int_to_tree (htype,
1067 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1068 | 0xeb382d69, 64));
1069 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1070 vptr, str_hash);
1071 gimple_set_location (g, loc);
1072 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1073 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1074 gimple_assign_lhs (g), cst);
1075 gimple_set_location (g, loc);
1076 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1077 tree t1 = gimple_assign_lhs (g);
1078 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1079 t1, build_int_cst (integer_type_node, 47));
1080 gimple_set_location (g, loc);
1081 tree t2 = gimple_assign_lhs (g);
1082 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1083 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1084 vptr, t1);
1085 gimple_set_location (g, loc);
1086 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1087 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1088 t2, gimple_assign_lhs (g));
1089 gimple_set_location (g, loc);
1090 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1091 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1092 gimple_assign_lhs (g), cst);
1093 gimple_set_location (g, loc);
1094 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1095 tree t3 = gimple_assign_lhs (g);
1096 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1097 t3, build_int_cst (integer_type_node, 47));
1098 gimple_set_location (g, loc);
1099 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1100 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1101 t3, gimple_assign_lhs (g));
1102 gimple_set_location (g, loc);
1103 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1104 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1105 gimple_assign_lhs (g), cst);
1106 gimple_set_location (g, loc);
1107 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1108 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1109 {
1110 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1111 NOP_EXPR, gimple_assign_lhs (g));
1112 gimple_set_location (g, loc);
1113 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1114 }
1115 tree hash = gimple_assign_lhs (g);
1116
1117 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1118 {
1119 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1120 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1121 get_identifier ("__ubsan_vptr_type_cache"),
1122 atype);
1123 DECL_ARTIFICIAL (array) = 1;
1124 DECL_IGNORED_P (array) = 1;
1125 TREE_PUBLIC (array) = 1;
1126 TREE_STATIC (array) = 1;
1127 DECL_EXTERNAL (array) = 1;
1128 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1129 DECL_VISIBILITY_SPECIFIED (array) = 1;
1130 varpool_node::finalize_decl (array);
1131 ubsan_vptr_type_cache_decl = array;
1132 }
1133
1134 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1135 BIT_AND_EXPR, hash,
1136 build_int_cst (pointer_sized_int_node, 127));
1137 gimple_set_location (g, loc);
1138 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1139
1140 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1141 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1142 NULL_TREE, NULL_TREE);
1143 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1144 ARRAY_REF, c);
1145 gimple_set_location (g, loc);
1146 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1147
1148 basic_block then_bb, fallthru2_bb;
1149 gimple_stmt_iterator cond_insert_point
1150 = create_cond_insert_point (gsip, false, false, true,
1151 &then_bb, &fallthru2_bb);
1152 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1153 NULL_TREE, NULL_TREE);
1154 gimple_set_location (g, loc);
1155 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1156 *gsip = gsi_after_labels (then_bb);
1157 if (fallthru_bb == NULL)
1158 fallthru_bb = fallthru2_bb;
1159
1160 tree data
1161 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1162 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1163 build_int_cst (unsigned_char_type_node, ckind),
1164 NULL_TREE);
1165 data = build_fold_addr_expr_loc (loc, data);
1166 enum built_in_function bcode
1167 = (flag_sanitize_recover & SANITIZE_VPTR)
1168 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1169 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1170
1171 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1172 gimple_set_location (g, loc);
1173 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1174
1175 /* Point GSI to next logical statement. */
1176 *gsip = gsi_start_bb (fallthru_bb);
1177
1178 /* Get rid of the UBSAN_VPTR call from the IR. */
1179 unlink_stmt_vdef (stmt);
1180 gsi_remove (&gsi, true);
1181 return true;
1182 }
1183
1184 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1185 whether the pointer is on the left hand side of the assignment. */
1186
1187 static void
1188 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1189 bool is_lhs)
1190 {
1191 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1192 unsigned int align = 0;
1193 if (flag_sanitize & SANITIZE_ALIGNMENT)
1194 {
1195 align = min_align_of_type (TREE_TYPE (base));
1196 if (align <= 1)
1197 align = 0;
1198 }
1199 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1200 return;
1201 tree t = TREE_OPERAND (base, 0);
1202 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1203 return;
1204 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1205 ikind = UBSAN_MEMBER_ACCESS;
1206 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1207 tree alignt = build_int_cst (pointer_sized_int_node, align);
1208 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1209 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1210 gsi_insert_before (iter, g, GSI_SAME_STMT);
1211 }
1212
1213 /* Perform the pointer instrumentation. */
1214
1215 static void
1216 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1217 {
1218 gimple stmt = gsi_stmt (gsi);
1219 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1220 tree base = get_base_address (t);
1221 const enum tree_code code = TREE_CODE (base);
1222 if (code == MEM_REF
1223 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1224 instrument_mem_ref (t, base, &gsi, is_lhs);
1225 }
1226
1227 /* Build an ubsan builtin call for the signed-integer-overflow
1228 sanitization. CODE says what kind of builtin are we building,
1229 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1230 are operands of the binary operation. */
1231
1232 tree
1233 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1234 tree op0, tree op1)
1235 {
1236 if (flag_sanitize_undefined_trap_on_error)
1237 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1238
1239 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1240 ubsan_type_descriptor (lhstype), NULL_TREE,
1241 NULL_TREE);
1242 enum built_in_function fn_code;
1243
1244 switch (code)
1245 {
1246 case PLUS_EXPR:
1247 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1248 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1249 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1250 break;
1251 case MINUS_EXPR:
1252 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1253 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1254 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1255 break;
1256 case MULT_EXPR:
1257 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1258 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1259 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1260 break;
1261 case NEGATE_EXPR:
1262 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1263 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1264 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1265 break;
1266 default:
1267 gcc_unreachable ();
1268 }
1269 tree fn = builtin_decl_explicit (fn_code);
1270 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1271 build_fold_addr_expr_loc (loc, data),
1272 ubsan_encode_value (op0, true),
1273 op1 ? ubsan_encode_value (op1, true)
1274 : NULL_TREE);
1275 }
1276
1277 /* Perform the signed integer instrumentation. GSI is the iterator
1278 pointing at statement we are trying to instrument. */
1279
1280 static void
1281 instrument_si_overflow (gimple_stmt_iterator gsi)
1282 {
1283 gimple stmt = gsi_stmt (gsi);
1284 tree_code code = gimple_assign_rhs_code (stmt);
1285 tree lhs = gimple_assign_lhs (stmt);
1286 tree lhstype = TREE_TYPE (lhs);
1287 tree a, b;
1288 gimple g;
1289
1290 /* If this is not a signed operation, don't instrument anything here.
1291 Also punt on bit-fields. */
1292 if (!INTEGRAL_TYPE_P (lhstype)
1293 || TYPE_OVERFLOW_WRAPS (lhstype)
1294 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1295 return;
1296
1297 switch (code)
1298 {
1299 case MINUS_EXPR:
1300 case PLUS_EXPR:
1301 case MULT_EXPR:
1302 /* Transform
1303 i = u {+,-,*} 5;
1304 into
1305 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1306 a = gimple_assign_rhs1 (stmt);
1307 b = gimple_assign_rhs2 (stmt);
1308 g = gimple_build_call_internal (code == PLUS_EXPR
1309 ? IFN_UBSAN_CHECK_ADD
1310 : code == MINUS_EXPR
1311 ? IFN_UBSAN_CHECK_SUB
1312 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1313 gimple_call_set_lhs (g, lhs);
1314 gsi_replace (&gsi, g, false);
1315 break;
1316 case NEGATE_EXPR:
1317 /* Represent i = -u;
1318 as
1319 i = UBSAN_CHECK_SUB (0, u); */
1320 a = build_int_cst (lhstype, 0);
1321 b = gimple_assign_rhs1 (stmt);
1322 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1323 gimple_call_set_lhs (g, lhs);
1324 gsi_replace (&gsi, g, false);
1325 break;
1326 case ABS_EXPR:
1327 /* Transform i = ABS_EXPR<u>;
1328 into
1329 _N = UBSAN_CHECK_SUB (0, u);
1330 i = ABS_EXPR<_N>; */
1331 a = build_int_cst (lhstype, 0);
1332 b = gimple_assign_rhs1 (stmt);
1333 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1334 a = make_ssa_name (lhstype);
1335 gimple_call_set_lhs (g, a);
1336 gimple_set_location (g, gimple_location (stmt));
1337 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1338 gimple_assign_set_rhs1 (stmt, a);
1339 update_stmt (stmt);
1340 break;
1341 default:
1342 break;
1343 }
1344 }
1345
1346 /* Instrument loads from (non-bitfield) bool and C++ enum values
1347 to check if the memory value is outside of the range of the valid
1348 type values. */
1349
1350 static void
1351 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1352 {
1353 gimple stmt = gsi_stmt (*gsi);
1354 tree rhs = gimple_assign_rhs1 (stmt);
1355 tree type = TREE_TYPE (rhs);
1356 tree minv = NULL_TREE, maxv = NULL_TREE;
1357
1358 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1359 {
1360 minv = boolean_false_node;
1361 maxv = boolean_true_node;
1362 }
1363 else if (TREE_CODE (type) == ENUMERAL_TYPE
1364 && (flag_sanitize & SANITIZE_ENUM)
1365 && TREE_TYPE (type) != NULL_TREE
1366 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1367 && (TYPE_PRECISION (TREE_TYPE (type))
1368 < GET_MODE_PRECISION (TYPE_MODE (type))))
1369 {
1370 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1371 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1372 }
1373 else
1374 return;
1375
1376 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1377 HOST_WIDE_INT bitsize, bitpos;
1378 tree offset;
1379 machine_mode mode;
1380 int volatilep = 0, unsignedp = 0;
1381 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1382 &unsignedp, &volatilep, false);
1383 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1384
1385 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1386 || (bitpos % modebitsize) != 0
1387 || bitsize != modebitsize
1388 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1389 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1390 return;
1391
1392 bool ends_bb = stmt_ends_bb_p (stmt);
1393 location_t loc = gimple_location (stmt);
1394 tree lhs = gimple_assign_lhs (stmt);
1395 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1396 tree atype = reference_alias_ptr_type (rhs);
1397 gimple g = gimple_build_assign (make_ssa_name (ptype),
1398 build_fold_addr_expr (rhs));
1399 gimple_set_location (g, loc);
1400 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1401 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1402 build_int_cst (atype, 0));
1403 tree urhs = make_ssa_name (utype);
1404 if (ends_bb)
1405 {
1406 gimple_assign_set_lhs (stmt, urhs);
1407 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1408 gimple_set_location (g, loc);
1409 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1410 gsi_insert_on_edge_immediate (e, g);
1411 gimple_assign_set_rhs_from_tree (gsi, mem);
1412 update_stmt (stmt);
1413 *gsi = gsi_for_stmt (g);
1414 g = stmt;
1415 }
1416 else
1417 {
1418 g = gimple_build_assign (urhs, mem);
1419 gimple_set_location (g, loc);
1420 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1421 }
1422 minv = fold_convert (utype, minv);
1423 maxv = fold_convert (utype, maxv);
1424 if (!integer_zerop (minv))
1425 {
1426 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1427 gimple_set_location (g, loc);
1428 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1429 }
1430
1431 gimple_stmt_iterator gsi2 = *gsi;
1432 basic_block then_bb, fallthru_bb;
1433 *gsi = create_cond_insert_point (gsi, true, false, true,
1434 &then_bb, &fallthru_bb);
1435 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1436 int_const_binop (MINUS_EXPR, maxv, minv),
1437 NULL_TREE, NULL_TREE);
1438 gimple_set_location (g, loc);
1439 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1440
1441 if (!ends_bb)
1442 {
1443 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1444 update_stmt (stmt);
1445 }
1446
1447 gsi2 = gsi_after_labels (then_bb);
1448 if (flag_sanitize_undefined_trap_on_error)
1449 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1450 else
1451 {
1452 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1453 ubsan_type_descriptor (type), NULL_TREE,
1454 NULL_TREE);
1455 data = build_fold_addr_expr_loc (loc, data);
1456 enum built_in_function bcode
1457 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1458 ? SANITIZE_BOOL : SANITIZE_ENUM))
1459 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1460 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1461 tree fn = builtin_decl_explicit (bcode);
1462
1463 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1464 true, NULL_TREE, true,
1465 GSI_SAME_STMT);
1466 g = gimple_build_call (fn, 2, data, val);
1467 }
1468 gimple_set_location (g, loc);
1469 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1470 ubsan_create_edge (g);
1471 *gsi = gsi_for_stmt (stmt);
1472 }
1473
1474 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1475 destination, EXPR is floating-point expression. ARG is what to pass
1476 the libubsan call as value, often EXPR itself. */
1477
1478 tree
1479 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1480 {
1481 tree expr_type = TREE_TYPE (expr);
1482 tree t, tt, fn, min, max;
1483 machine_mode mode = TYPE_MODE (expr_type);
1484 int prec = TYPE_PRECISION (type);
1485 bool uns_p = TYPE_UNSIGNED (type);
1486
1487 /* Float to integer conversion first truncates toward zero, so
1488 even signed char c = 127.875f; is not problematic.
1489 Therefore, we should complain only if EXPR is unordered or smaller
1490 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1491 TYPE_MAX_VALUE + 1.0. */
1492 if (REAL_MODE_FORMAT (mode)->b == 2)
1493 {
1494 /* For maximum, TYPE_MAX_VALUE might not be representable
1495 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1496 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1497 either representable or infinity. */
1498 REAL_VALUE_TYPE maxval = dconst1;
1499 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1500 real_convert (&maxval, mode, &maxval);
1501 max = build_real (expr_type, maxval);
1502
1503 /* For unsigned, assume -1.0 is always representable. */
1504 if (uns_p)
1505 min = build_minus_one_cst (expr_type);
1506 else
1507 {
1508 /* TYPE_MIN_VALUE is generally representable (or -inf),
1509 but TYPE_MIN_VALUE - 1.0 might not be. */
1510 REAL_VALUE_TYPE minval = dconstm1, minval2;
1511 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1512 real_convert (&minval, mode, &minval);
1513 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1514 real_convert (&minval2, mode, &minval2);
1515 if (real_compare (EQ_EXPR, &minval, &minval2)
1516 && !real_isinf (&minval))
1517 {
1518 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1519 rounds to TYPE_MIN_VALUE, we need to subtract
1520 more. As REAL_MODE_FORMAT (mode)->p is the number
1521 of base digits, we want to subtract a number that
1522 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1523 times smaller than minval. */
1524 minval2 = dconst1;
1525 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1526 SET_REAL_EXP (&minval2,
1527 REAL_EXP (&minval2) + prec - 1
1528 - REAL_MODE_FORMAT (mode)->p + 1);
1529 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1530 real_convert (&minval2, mode, &minval2);
1531 }
1532 min = build_real (expr_type, minval2);
1533 }
1534 }
1535 else if (REAL_MODE_FORMAT (mode)->b == 10)
1536 {
1537 /* For _Decimal128 up to 34 decimal digits, - sign,
1538 dot, e, exponent. */
1539 char buf[64];
1540 mpfr_t m;
1541 int p = REAL_MODE_FORMAT (mode)->p;
1542 REAL_VALUE_TYPE maxval, minval;
1543
1544 /* Use mpfr_snprintf rounding to compute the smallest
1545 representable decimal number greater or equal than
1546 1 << (prec - !uns_p). */
1547 mpfr_init2 (m, prec + 2);
1548 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1549 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1550 decimal_real_from_string (&maxval, buf);
1551 max = build_real (expr_type, maxval);
1552
1553 /* For unsigned, assume -1.0 is always representable. */
1554 if (uns_p)
1555 min = build_minus_one_cst (expr_type);
1556 else
1557 {
1558 /* Use mpfr_snprintf rounding to compute the largest
1559 representable decimal number less or equal than
1560 (-1 << (prec - 1)) - 1. */
1561 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1562 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1563 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1564 decimal_real_from_string (&minval, buf);
1565 min = build_real (expr_type, minval);
1566 }
1567 mpfr_clear (m);
1568 }
1569 else
1570 return NULL_TREE;
1571
1572 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1573 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1574 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1575 if (integer_zerop (t))
1576 return NULL_TREE;
1577
1578 if (flag_sanitize_undefined_trap_on_error)
1579 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1580 else
1581 {
1582 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1583 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1584 NULL, ubsan_type_descriptor (expr_type),
1585 ubsan_type_descriptor (type), NULL_TREE,
1586 NULL_TREE);
1587 enum built_in_function bcode
1588 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1589 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1590 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1591 fn = builtin_decl_explicit (bcode);
1592 fn = build_call_expr_loc (loc, fn, 2,
1593 build_fold_addr_expr_loc (loc, data),
1594 ubsan_encode_value (arg, false));
1595 }
1596
1597 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1598 }
1599
1600 /* Instrument values passed to function arguments with nonnull attribute. */
1601
1602 static void
1603 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1604 {
1605 gimple stmt = gsi_stmt (*gsi);
1606 location_t loc[2];
1607 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1608 while for nonnull sanitization it is clear. */
1609 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1610 flag_delete_null_pointer_checks = 1;
1611 loc[0] = gimple_location (stmt);
1612 loc[1] = UNKNOWN_LOCATION;
1613 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1614 {
1615 tree arg = gimple_call_arg (stmt, i);
1616 if (POINTER_TYPE_P (TREE_TYPE (arg))
1617 && infer_nonnull_range (stmt, arg, false, true))
1618 {
1619 gimple g;
1620 if (!is_gimple_val (arg))
1621 {
1622 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1623 gimple_set_location (g, loc[0]);
1624 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1625 arg = gimple_assign_lhs (g);
1626 }
1627
1628 basic_block then_bb, fallthru_bb;
1629 *gsi = create_cond_insert_point (gsi, true, false, true,
1630 &then_bb, &fallthru_bb);
1631 g = gimple_build_cond (EQ_EXPR, arg,
1632 build_zero_cst (TREE_TYPE (arg)),
1633 NULL_TREE, NULL_TREE);
1634 gimple_set_location (g, loc[0]);
1635 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1636
1637 *gsi = gsi_after_labels (then_bb);
1638 if (flag_sanitize_undefined_trap_on_error)
1639 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1640 else
1641 {
1642 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1643 2, loc, NULL_TREE,
1644 build_int_cst (integer_type_node,
1645 i + 1),
1646 NULL_TREE);
1647 data = build_fold_addr_expr_loc (loc[0], data);
1648 enum built_in_function bcode
1649 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1650 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1651 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1652 tree fn = builtin_decl_explicit (bcode);
1653
1654 g = gimple_build_call (fn, 1, data);
1655 }
1656 gimple_set_location (g, loc[0]);
1657 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1658 ubsan_create_edge (g);
1659 }
1660 *gsi = gsi_for_stmt (stmt);
1661 }
1662 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1663 }
1664
1665 /* Instrument returns in functions with returns_nonnull attribute. */
1666
1667 static void
1668 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1669 {
1670 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1671 location_t loc[2];
1672 tree arg = gimple_return_retval (stmt);
1673 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1674 while for nonnull return sanitization it is clear. */
1675 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1676 flag_delete_null_pointer_checks = 1;
1677 loc[0] = gimple_location (stmt);
1678 loc[1] = UNKNOWN_LOCATION;
1679 if (arg
1680 && POINTER_TYPE_P (TREE_TYPE (arg))
1681 && is_gimple_val (arg)
1682 && infer_nonnull_range (stmt, arg, false, true))
1683 {
1684 basic_block then_bb, fallthru_bb;
1685 *gsi = create_cond_insert_point (gsi, true, false, true,
1686 &then_bb, &fallthru_bb);
1687 gimple g = gimple_build_cond (EQ_EXPR, arg,
1688 build_zero_cst (TREE_TYPE (arg)),
1689 NULL_TREE, NULL_TREE);
1690 gimple_set_location (g, loc[0]);
1691 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1692
1693 *gsi = gsi_after_labels (then_bb);
1694 if (flag_sanitize_undefined_trap_on_error)
1695 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1696 else
1697 {
1698 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1699 2, loc, NULL_TREE, NULL_TREE);
1700 data = build_fold_addr_expr_loc (loc[0], data);
1701 enum built_in_function bcode
1702 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1703 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1704 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1705 tree fn = builtin_decl_explicit (bcode);
1706
1707 g = gimple_build_call (fn, 1, data);
1708 }
1709 gimple_set_location (g, loc[0]);
1710 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1711 ubsan_create_edge (g);
1712 *gsi = gsi_for_stmt (stmt);
1713 }
1714 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1715 }
1716
1717 /* Instrument memory references. Here we check whether the pointer
1718 points to an out-of-bounds location. */
1719
1720 static void
1721 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1722 {
1723 gimple stmt = gsi_stmt (*gsi);
1724 location_t loc = gimple_location (stmt);
1725 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1726 tree type;
1727 tree index = NULL_TREE;
1728 HOST_WIDE_INT size_in_bytes;
1729
1730 type = TREE_TYPE (t);
1731 if (VOID_TYPE_P (type))
1732 return;
1733
1734 switch (TREE_CODE (t))
1735 {
1736 case COMPONENT_REF:
1737 if (TREE_CODE (t) == COMPONENT_REF
1738 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1739 {
1740 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1741 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1742 repr, NULL_TREE);
1743 }
1744 break;
1745 case ARRAY_REF:
1746 index = TREE_OPERAND (t, 1);
1747 break;
1748 case INDIRECT_REF:
1749 case MEM_REF:
1750 case VAR_DECL:
1751 case PARM_DECL:
1752 case RESULT_DECL:
1753 break;
1754 default:
1755 return;
1756 }
1757
1758 size_in_bytes = int_size_in_bytes (type);
1759 if (size_in_bytes <= 0)
1760 return;
1761
1762 HOST_WIDE_INT bitsize, bitpos;
1763 tree offset;
1764 machine_mode mode;
1765 int volatilep = 0, unsignedp = 0;
1766 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1767 &unsignedp, &volatilep, false);
1768
1769 if (bitpos % BITS_PER_UNIT != 0
1770 || bitsize != size_in_bytes * BITS_PER_UNIT)
1771 return;
1772
1773 bool decl_p = DECL_P (inner);
1774 tree base;
1775 if (decl_p)
1776 base = inner;
1777 else if (TREE_CODE (inner) == MEM_REF)
1778 base = TREE_OPERAND (inner, 0);
1779 else
1780 return;
1781 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1782
1783 while (TREE_CODE (base) == SSA_NAME)
1784 {
1785 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1786 if (gimple_assign_ssa_name_copy_p (def_stmt)
1787 || (gimple_assign_cast_p (def_stmt)
1788 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1789 || (is_gimple_assign (def_stmt)
1790 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1791 {
1792 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1793 if (TREE_CODE (rhs1) == SSA_NAME
1794 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1795 break;
1796 else
1797 base = rhs1;
1798 }
1799 else
1800 break;
1801 }
1802
1803 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1804 return;
1805
1806 tree sizet;
1807 tree base_addr = base;
1808 gimple bos_stmt = NULL;
1809 if (decl_p)
1810 base_addr = build1 (ADDR_EXPR,
1811 build_pointer_type (TREE_TYPE (base)), base);
1812 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1813 if (size != (unsigned HOST_WIDE_INT) -1)
1814 sizet = build_int_cst (sizetype, size);
1815 else if (optimize)
1816 {
1817 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1818 loc = input_location;
1819 /* Generate __builtin_object_size call. */
1820 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1821 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1822 integer_zero_node);
1823 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1824 GSI_SAME_STMT);
1825 /* If the call above didn't end up being an integer constant, go one
1826 statement back and get the __builtin_object_size stmt. Save it,
1827 we might need it later. */
1828 if (SSA_VAR_P (sizet))
1829 {
1830 gsi_prev (gsi);
1831 bos_stmt = gsi_stmt (*gsi);
1832
1833 /* Move on to where we were. */
1834 gsi_next (gsi);
1835 }
1836 }
1837 else
1838 return;
1839
1840 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1841 call. */
1842 /* ptr + sizeof (*ptr) - base */
1843 t = fold_build2 (MINUS_EXPR, sizetype,
1844 fold_convert (pointer_sized_int_node, ptr),
1845 fold_convert (pointer_sized_int_node, base_addr));
1846 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1847
1848 /* Perhaps we can omit the check. */
1849 if (TREE_CODE (t) == INTEGER_CST
1850 && TREE_CODE (sizet) == INTEGER_CST
1851 && tree_int_cst_le (t, sizet))
1852 return;
1853
1854 if (index != NULL_TREE
1855 && TREE_CODE (index) == SSA_NAME
1856 && TREE_CODE (sizet) == INTEGER_CST)
1857 {
1858 gimple def = SSA_NAME_DEF_STMT (index);
1859 if (is_gimple_assign (def)
1860 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1861 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1862 {
1863 tree cst = gimple_assign_rhs2 (def);
1864 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1865 TYPE_SIZE_UNIT (type));
1866 if (tree_int_cst_sgn (cst) >= 0
1867 && tree_int_cst_lt (cst, sz))
1868 return;
1869 }
1870 }
1871
1872 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1873 ubsan_create_edge (bos_stmt);
1874
1875 /* We have to emit the check. */
1876 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1877 GSI_SAME_STMT);
1878 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1879 GSI_SAME_STMT);
1880 tree ckind = build_int_cst (unsigned_char_type_node,
1881 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1882 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1883 ptr, t, sizet, ckind);
1884 gimple_set_location (g, loc);
1885 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1886 }
1887
1888 /* True if we want to play UBSan games in the current function. */
1889
1890 bool
1891 do_ubsan_in_current_function ()
1892 {
1893 return (current_function_decl != NULL_TREE
1894 && !lookup_attribute ("no_sanitize_undefined",
1895 DECL_ATTRIBUTES (current_function_decl)));
1896 }
1897
1898 namespace {
1899
1900 const pass_data pass_data_ubsan =
1901 {
1902 GIMPLE_PASS, /* type */
1903 "ubsan", /* name */
1904 OPTGROUP_NONE, /* optinfo_flags */
1905 TV_TREE_UBSAN, /* tv_id */
1906 ( PROP_cfg | PROP_ssa ), /* properties_required */
1907 0, /* properties_provided */
1908 0, /* properties_destroyed */
1909 0, /* todo_flags_start */
1910 TODO_update_ssa, /* todo_flags_finish */
1911 };
1912
1913 class pass_ubsan : public gimple_opt_pass
1914 {
1915 public:
1916 pass_ubsan (gcc::context *ctxt)
1917 : gimple_opt_pass (pass_data_ubsan, ctxt)
1918 {}
1919
1920 /* opt_pass methods: */
1921 virtual bool gate (function *)
1922 {
1923 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1924 | SANITIZE_BOOL | SANITIZE_ENUM
1925 | SANITIZE_ALIGNMENT
1926 | SANITIZE_NONNULL_ATTRIBUTE
1927 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1928 | SANITIZE_OBJECT_SIZE)
1929 && do_ubsan_in_current_function ();
1930 }
1931
1932 virtual unsigned int execute (function *);
1933
1934 }; // class pass_ubsan
1935
1936 unsigned int
1937 pass_ubsan::execute (function *fun)
1938 {
1939 basic_block bb;
1940 gimple_stmt_iterator gsi;
1941
1942 initialize_sanitizer_builtins ();
1943
1944 FOR_EACH_BB_FN (bb, fun)
1945 {
1946 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1947 {
1948 gimple stmt = gsi_stmt (gsi);
1949 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1950 {
1951 gsi_next (&gsi);
1952 continue;
1953 }
1954
1955 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1956 && is_gimple_assign (stmt))
1957 instrument_si_overflow (gsi);
1958
1959 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1960 {
1961 if (gimple_store_p (stmt))
1962 instrument_null (gsi, true);
1963 if (gimple_assign_load_p (stmt))
1964 instrument_null (gsi, false);
1965 }
1966
1967 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1968 && gimple_assign_load_p (stmt))
1969 {
1970 instrument_bool_enum_load (&gsi);
1971 bb = gimple_bb (stmt);
1972 }
1973
1974 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1975 && is_gimple_call (stmt)
1976 && !gimple_call_internal_p (stmt))
1977 {
1978 instrument_nonnull_arg (&gsi);
1979 bb = gimple_bb (stmt);
1980 }
1981
1982 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1983 && gimple_code (stmt) == GIMPLE_RETURN)
1984 {
1985 instrument_nonnull_return (&gsi);
1986 bb = gimple_bb (stmt);
1987 }
1988
1989 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1990 {
1991 if (gimple_store_p (stmt))
1992 instrument_object_size (&gsi, true);
1993 if (gimple_assign_load_p (stmt))
1994 instrument_object_size (&gsi, false);
1995 }
1996
1997 gsi_next (&gsi);
1998 }
1999 }
2000 return 0;
2001 }
2002
2003 } // anon namespace
2004
2005 gimple_opt_pass *
2006 make_pass_ubsan (gcc::context *ctxt)
2007 {
2008 return new pass_ubsan (ctxt);
2009 }
2010
2011 #include "gt-ubsan.h"