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