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