compiler: only build thunk struct type when it is needed
[official-gcc.git] / gcc / asan.cc
blob8276f12cc69438b99aa87cf318963397da344ec9
1 /* AddressSanitizer, a fast memory error detector.
2 Copyright (C) 2012-2022 Free Software Foundation, Inc.
3 Contributed by Kostya Serebryany <kcc@google.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "target.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "gimple.h"
30 #include "cfghooks.h"
31 #include "alloc-pool.h"
32 #include "tree-pass.h"
33 #include "memmodel.h"
34 #include "tm_p.h"
35 #include "ssa.h"
36 #include "stringpool.h"
37 #include "tree-ssanames.h"
38 #include "optabs.h"
39 #include "emit-rtl.h"
40 #include "cgraph.h"
41 #include "gimple-pretty-print.h"
42 #include "alias.h"
43 #include "fold-const.h"
44 #include "cfganal.h"
45 #include "gimplify.h"
46 #include "gimple-iterator.h"
47 #include "varasm.h"
48 #include "stor-layout.h"
49 #include "tree-iterator.h"
50 #include "stringpool.h"
51 #include "attribs.h"
52 #include "asan.h"
53 #include "dojump.h"
54 #include "explow.h"
55 #include "expr.h"
56 #include "output.h"
57 #include "langhooks.h"
58 #include "cfgloop.h"
59 #include "gimple-builder.h"
60 #include "gimple-fold.h"
61 #include "ubsan.h"
62 #include "builtins.h"
63 #include "fnmatch.h"
64 #include "tree-inline.h"
65 #include "tree-ssa.h"
66 #include "tree-eh.h"
68 /* AddressSanitizer finds out-of-bounds and use-after-free bugs
69 with <2x slowdown on average.
71 The tool consists of two parts:
72 instrumentation module (this file) and a run-time library.
73 The instrumentation module adds a run-time check before every memory insn.
74 For a 8- or 16- byte load accessing address X:
75 ShadowAddr = (X >> 3) + Offset
76 ShadowValue = *(char*)ShadowAddr; // *(short*) for 16-byte access.
77 if (ShadowValue)
78 __asan_report_load8(X);
79 For a load of N bytes (N=1, 2 or 4) from address X:
80 ShadowAddr = (X >> 3) + Offset
81 ShadowValue = *(char*)ShadowAddr;
82 if (ShadowValue)
83 if ((X & 7) + N - 1 > ShadowValue)
84 __asan_report_loadN(X);
85 Stores are instrumented similarly, but using __asan_report_storeN functions.
86 A call too __asan_init_vN() is inserted to the list of module CTORs.
87 N is the version number of the AddressSanitizer API. The changes between the
88 API versions are listed in libsanitizer/asan/asan_interface_internal.h.
90 The run-time library redefines malloc (so that redzone are inserted around
91 the allocated memory) and free (so that reuse of free-ed memory is delayed),
92 provides __asan_report* and __asan_init_vN functions.
94 Read more:
95 http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
97 The current implementation supports detection of out-of-bounds and
98 use-after-free in the heap, on the stack and for global variables.
100 [Protection of stack variables]
102 To understand how detection of out-of-bounds and use-after-free works
103 for stack variables, lets look at this example on x86_64 where the
104 stack grows downward:
107 foo ()
109 char a[24] = {0};
110 int b[2] = {0};
112 a[5] = 1;
113 b[1] = 2;
115 return a[5] + b[1];
118 For this function, the stack protected by asan will be organized as
119 follows, from the top of the stack to the bottom:
121 Slot 1/ [red zone of 32 bytes called 'RIGHT RedZone']
123 Slot 2/ [8 bytes of red zone, that adds up to the space of 'a' to make
124 the next slot be 32 bytes aligned; this one is called Partial
125 Redzone; this 32 bytes alignment is an asan constraint]
127 Slot 3/ [24 bytes for variable 'a']
129 Slot 4/ [red zone of 32 bytes called 'Middle RedZone']
131 Slot 5/ [24 bytes of Partial Red Zone (similar to slot 2]
133 Slot 6/ [8 bytes for variable 'b']
135 Slot 7/ [32 bytes of Red Zone at the bottom of the stack, called
136 'LEFT RedZone']
138 The 32 bytes of LEFT red zone at the bottom of the stack can be
139 decomposed as such:
141 1/ The first 8 bytes contain a magical asan number that is always
142 0x41B58AB3.
144 2/ The following 8 bytes contains a pointer to a string (to be
145 parsed at runtime by the runtime asan library), which format is
146 the following:
148 "<function-name> <space> <num-of-variables-on-the-stack>
149 (<32-bytes-aligned-offset-in-bytes-of-variable> <space>
150 <length-of-var-in-bytes> ){n} "
152 where '(...){n}' means the content inside the parenthesis occurs 'n'
153 times, with 'n' being the number of variables on the stack.
155 3/ The following 8 bytes contain the PC of the current function which
156 will be used by the run-time library to print an error message.
158 4/ The following 8 bytes are reserved for internal use by the run-time.
160 The shadow memory for that stack layout is going to look like this:
162 - content of shadow memory 8 bytes for slot 7: 0xF1F1F1F1.
163 The F1 byte pattern is a magic number called
164 ASAN_STACK_MAGIC_LEFT and is a way for the runtime to know that
165 the memory for that shadow byte is part of a the LEFT red zone
166 intended to seat at the bottom of the variables on the stack.
168 - content of shadow memory 8 bytes for slots 6 and 5:
169 0xF4F4F400. The F4 byte pattern is a magic number
170 called ASAN_STACK_MAGIC_PARTIAL. It flags the fact that the
171 memory region for this shadow byte is a PARTIAL red zone
172 intended to pad a variable A, so that the slot following
173 {A,padding} is 32 bytes aligned.
175 Note that the fact that the least significant byte of this
176 shadow memory content is 00 means that 8 bytes of its
177 corresponding memory (which corresponds to the memory of
178 variable 'b') is addressable.
180 - content of shadow memory 8 bytes for slot 4: 0xF2F2F2F2.
181 The F2 byte pattern is a magic number called
182 ASAN_STACK_MAGIC_MIDDLE. It flags the fact that the memory
183 region for this shadow byte is a MIDDLE red zone intended to
184 seat between two 32 aligned slots of {variable,padding}.
186 - content of shadow memory 8 bytes for slot 3 and 2:
187 0xF4000000. This represents is the concatenation of
188 variable 'a' and the partial red zone following it, like what we
189 had for variable 'b'. The least significant 3 bytes being 00
190 means that the 3 bytes of variable 'a' are addressable.
192 - content of shadow memory 8 bytes for slot 1: 0xF3F3F3F3.
193 The F3 byte pattern is a magic number called
194 ASAN_STACK_MAGIC_RIGHT. It flags the fact that the memory
195 region for this shadow byte is a RIGHT red zone intended to seat
196 at the top of the variables of the stack.
198 Note that the real variable layout is done in expand_used_vars in
199 cfgexpand.cc. As far as Address Sanitizer is concerned, it lays out
200 stack variables as well as the different red zones, emits some
201 prologue code to populate the shadow memory as to poison (mark as
202 non-accessible) the regions of the red zones and mark the regions of
203 stack variables as accessible, and emit some epilogue code to
204 un-poison (mark as accessible) the regions of red zones right before
205 the function exits.
207 [Protection of global variables]
209 The basic idea is to insert a red zone between two global variables
210 and install a constructor function that calls the asan runtime to do
211 the populating of the relevant shadow memory regions at load time.
213 So the global variables are laid out as to insert a red zone between
214 them. The size of the red zones is so that each variable starts on a
215 32 bytes boundary.
217 Then a constructor function is installed so that, for each global
218 variable, it calls the runtime asan library function
219 __asan_register_globals_with an instance of this type:
221 struct __asan_global
223 // Address of the beginning of the global variable.
224 const void *__beg;
226 // Initial size of the global variable.
227 uptr __size;
229 // Size of the global variable + size of the red zone. This
230 // size is 32 bytes aligned.
231 uptr __size_with_redzone;
233 // Name of the global variable.
234 const void *__name;
236 // Name of the module where the global variable is declared.
237 const void *__module_name;
239 // 1 if it has dynamic initialization, 0 otherwise.
240 uptr __has_dynamic_init;
242 // A pointer to struct that contains source location, could be NULL.
243 __asan_global_source_location *__location;
246 A destructor function that calls the runtime asan library function
247 _asan_unregister_globals is also installed. */
249 static unsigned HOST_WIDE_INT asan_shadow_offset_value;
250 static bool asan_shadow_offset_computed;
251 static vec<char *> sanitized_sections;
252 static tree last_alloca_addr;
254 /* Set of variable declarations that are going to be guarded by
255 use-after-scope sanitizer. */
257 hash_set<tree> *asan_handled_variables = NULL;
259 hash_set <tree> *asan_used_labels = NULL;
261 /* Global variables for HWASAN stack tagging. */
262 /* hwasan_frame_tag_offset records the offset from the frame base tag that the
263 next object should have. */
264 static uint8_t hwasan_frame_tag_offset = 0;
265 /* hwasan_frame_base_ptr is a pointer with the same address as
266 `virtual_stack_vars_rtx` for the current frame, and with the frame base tag
267 stored in it. N.b. this global RTX does not need to be marked GTY, but is
268 done so anyway. The need is not there since all uses are in just one pass
269 (cfgexpand) and there are no calls to ggc_collect between the uses. We mark
270 it GTY(()) anyway to allow the use of the variable later on if needed by
271 future features. */
272 static GTY(()) rtx hwasan_frame_base_ptr = NULL_RTX;
273 /* hwasan_frame_base_init_seq is the sequence of RTL insns that will initialize
274 the hwasan_frame_base_ptr. When the hwasan_frame_base_ptr is requested, we
275 generate this sequence but do not emit it. If the sequence was created it
276 is emitted once the function body has been expanded.
278 This delay is because the frame base pointer may be needed anywhere in the
279 function body, or needed by the expand_used_vars function. Emitting once in
280 a known place is simpler than requiring the emission of the instructions to
281 be know where it should go depending on the first place the hwasan frame
282 base is needed. */
283 static GTY(()) rtx_insn *hwasan_frame_base_init_seq = NULL;
285 /* Structure defining the extent of one object on the stack that HWASAN needs
286 to tag in the corresponding shadow stack space.
288 The range this object spans on the stack is between `untagged_base +
289 nearest_offset` and `untagged_base + farthest_offset`.
290 `tagged_base` is an rtx containing the same value as `untagged_base` but
291 with a random tag stored in the top byte. We record both `untagged_base`
292 and `tagged_base` so that `hwasan_emit_prologue` can use both without having
293 to emit RTL into the instruction stream to re-calculate one from the other.
294 (`hwasan_emit_prologue` needs to use both bases since the
295 __hwasan_tag_memory call it emits uses an untagged value, and it calculates
296 the tag to store in shadow memory based on the tag_offset plus the tag in
297 tagged_base). */
298 struct hwasan_stack_var
300 rtx untagged_base;
301 rtx tagged_base;
302 poly_int64 nearest_offset;
303 poly_int64 farthest_offset;
304 uint8_t tag_offset;
307 /* Variable recording all stack variables that HWASAN needs to tag.
308 Does not need to be marked as GTY(()) since every use is in the cfgexpand
309 pass and gcc_collect is not called in the middle of that pass. */
310 static vec<hwasan_stack_var> hwasan_tagged_stack_vars;
313 /* Sets shadow offset to value in string VAL. */
315 bool
316 set_asan_shadow_offset (const char *val)
318 char *endp;
320 errno = 0;
321 #ifdef HAVE_LONG_LONG
322 asan_shadow_offset_value = strtoull (val, &endp, 0);
323 #else
324 asan_shadow_offset_value = strtoul (val, &endp, 0);
325 #endif
326 if (!(*val != '\0' && *endp == '\0' && errno == 0))
327 return false;
329 asan_shadow_offset_computed = true;
331 return true;
334 /* Set list of user-defined sections that need to be sanitized. */
336 void
337 set_sanitized_sections (const char *sections)
339 char *pat;
340 unsigned i;
341 FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
342 free (pat);
343 sanitized_sections.truncate (0);
345 for (const char *s = sections; *s; )
347 const char *end;
348 for (end = s; *end && *end != ','; ++end);
349 size_t len = end - s;
350 sanitized_sections.safe_push (xstrndup (s, len));
351 s = *end ? end + 1 : end;
355 bool
356 asan_mark_p (gimple *stmt, enum asan_mark_flags flag)
358 return (gimple_call_internal_p (stmt, IFN_ASAN_MARK)
359 && tree_to_uhwi (gimple_call_arg (stmt, 0)) == flag);
362 bool
363 asan_sanitize_stack_p (void)
365 return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_stack);
368 bool
369 asan_sanitize_allocas_p (void)
371 return (asan_sanitize_stack_p () && param_asan_protect_allocas);
374 bool
375 asan_instrument_reads (void)
377 return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_reads);
380 bool
381 asan_instrument_writes (void)
383 return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_writes);
386 bool
387 asan_memintrin (void)
389 return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_memintrin);
393 /* Checks whether section SEC should be sanitized. */
395 static bool
396 section_sanitized_p (const char *sec)
398 char *pat;
399 unsigned i;
400 FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
401 if (fnmatch (pat, sec, FNM_PERIOD) == 0)
402 return true;
403 return false;
406 /* Returns Asan shadow offset. */
408 static unsigned HOST_WIDE_INT
409 asan_shadow_offset ()
411 if (!asan_shadow_offset_computed)
413 asan_shadow_offset_computed = true;
414 asan_shadow_offset_value = targetm.asan_shadow_offset ();
416 return asan_shadow_offset_value;
419 /* Returns Asan shadow offset has been set. */
420 bool
421 asan_shadow_offset_set_p ()
423 return asan_shadow_offset_computed;
426 alias_set_type asan_shadow_set = -1;
428 /* Pointer types to 1, 2 or 4 byte integers in shadow memory. A separate
429 alias set is used for all shadow memory accesses. */
430 static GTY(()) tree shadow_ptr_types[3];
432 /* Decl for __asan_option_detect_stack_use_after_return. */
433 static GTY(()) tree asan_detect_stack_use_after_return;
435 /* Hashtable support for memory references used by gimple
436 statements. */
438 /* This type represents a reference to a memory region. */
439 struct asan_mem_ref
441 /* The expression of the beginning of the memory region. */
442 tree start;
444 /* The size of the access. */
445 HOST_WIDE_INT access_size;
448 object_allocator <asan_mem_ref> asan_mem_ref_pool ("asan_mem_ref");
450 /* Initializes an instance of asan_mem_ref. */
452 static void
453 asan_mem_ref_init (asan_mem_ref *ref, tree start, HOST_WIDE_INT access_size)
455 ref->start = start;
456 ref->access_size = access_size;
459 /* Allocates memory for an instance of asan_mem_ref into the memory
460 pool returned by asan_mem_ref_get_alloc_pool and initialize it.
461 START is the address of (or the expression pointing to) the
462 beginning of memory reference. ACCESS_SIZE is the size of the
463 access to the referenced memory. */
465 static asan_mem_ref*
466 asan_mem_ref_new (tree start, HOST_WIDE_INT access_size)
468 asan_mem_ref *ref = asan_mem_ref_pool.allocate ();
470 asan_mem_ref_init (ref, start, access_size);
471 return ref;
474 /* This builds and returns a pointer to the end of the memory region
475 that starts at START and of length LEN. */
477 tree
478 asan_mem_ref_get_end (tree start, tree len)
480 if (len == NULL_TREE || integer_zerop (len))
481 return start;
483 if (!ptrofftype_p (len))
484 len = convert_to_ptrofftype (len);
486 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (start), start, len);
489 /* Return a tree expression that represents the end of the referenced
490 memory region. Beware that this function can actually build a new
491 tree expression. */
493 tree
494 asan_mem_ref_get_end (const asan_mem_ref *ref, tree len)
496 return asan_mem_ref_get_end (ref->start, len);
499 struct asan_mem_ref_hasher : nofree_ptr_hash <asan_mem_ref>
501 static inline hashval_t hash (const asan_mem_ref *);
502 static inline bool equal (const asan_mem_ref *, const asan_mem_ref *);
505 /* Hash a memory reference. */
507 inline hashval_t
508 asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
510 return iterative_hash_expr (mem_ref->start, 0);
513 /* Compare two memory references. We accept the length of either
514 memory references to be NULL_TREE. */
516 inline bool
517 asan_mem_ref_hasher::equal (const asan_mem_ref *m1,
518 const asan_mem_ref *m2)
520 return operand_equal_p (m1->start, m2->start, 0);
523 static hash_table<asan_mem_ref_hasher> *asan_mem_ref_ht;
525 /* Returns a reference to the hash table containing memory references.
526 This function ensures that the hash table is created. Note that
527 this hash table is updated by the function
528 update_mem_ref_hash_table. */
530 static hash_table<asan_mem_ref_hasher> *
531 get_mem_ref_hash_table ()
533 if (!asan_mem_ref_ht)
534 asan_mem_ref_ht = new hash_table<asan_mem_ref_hasher> (10);
536 return asan_mem_ref_ht;
539 /* Clear all entries from the memory references hash table. */
541 static void
542 empty_mem_ref_hash_table ()
544 if (asan_mem_ref_ht)
545 asan_mem_ref_ht->empty ();
548 /* Free the memory references hash table. */
550 static void
551 free_mem_ref_resources ()
553 delete asan_mem_ref_ht;
554 asan_mem_ref_ht = NULL;
556 asan_mem_ref_pool.release ();
559 /* Return true iff the memory reference REF has been instrumented. */
561 static bool
562 has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
564 asan_mem_ref r;
565 asan_mem_ref_init (&r, ref, access_size);
567 asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r);
568 return saved_ref && saved_ref->access_size >= access_size;
571 /* Return true iff the memory reference REF has been instrumented. */
573 static bool
574 has_mem_ref_been_instrumented (const asan_mem_ref *ref)
576 return has_mem_ref_been_instrumented (ref->start, ref->access_size);
579 /* Return true iff access to memory region starting at REF and of
580 length LEN has been instrumented. */
582 static bool
583 has_mem_ref_been_instrumented (const asan_mem_ref *ref, tree len)
585 HOST_WIDE_INT size_in_bytes
586 = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
588 return size_in_bytes != -1
589 && has_mem_ref_been_instrumented (ref->start, size_in_bytes);
592 /* Set REF to the memory reference present in a gimple assignment
593 ASSIGNMENT. Return true upon successful completion, false
594 otherwise. */
596 static bool
597 get_mem_ref_of_assignment (const gassign *assignment,
598 asan_mem_ref *ref,
599 bool *ref_is_store)
601 gcc_assert (gimple_assign_single_p (assignment));
603 if (gimple_store_p (assignment)
604 && !gimple_clobber_p (assignment))
606 ref->start = gimple_assign_lhs (assignment);
607 *ref_is_store = true;
609 else if (gimple_assign_load_p (assignment))
611 ref->start = gimple_assign_rhs1 (assignment);
612 *ref_is_store = false;
614 else
615 return false;
617 ref->access_size = int_size_in_bytes (TREE_TYPE (ref->start));
618 return true;
621 /* Return address of last allocated dynamic alloca. */
623 static tree
624 get_last_alloca_addr ()
626 if (last_alloca_addr)
627 return last_alloca_addr;
629 last_alloca_addr = create_tmp_reg (ptr_type_node, "last_alloca_addr");
630 gassign *g = gimple_build_assign (last_alloca_addr, null_pointer_node);
631 edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
632 gsi_insert_on_edge_immediate (e, g);
633 return last_alloca_addr;
636 /* Insert __asan_allocas_unpoison (top, bottom) call before
637 __builtin_stack_restore (new_sp) call.
638 The pseudocode of this routine should look like this:
639 top = last_alloca_addr;
640 bot = new_sp;
641 __asan_allocas_unpoison (top, bot);
642 last_alloca_addr = new_sp;
643 __builtin_stack_restore (new_sp);
644 In general, we can't use new_sp as bot parameter because on some
645 architectures SP has non zero offset from dynamic stack area. Moreover, on
646 some architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each
647 particular function only after all callees were expanded to rtl.
648 The most noticeable example is PowerPC{,64}, see
649 http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#DYNAM-STACK.
650 To overcome the issue we use following trick: pass new_sp as a second
651 parameter to __asan_allocas_unpoison and rewrite it during expansion with
652 new_sp + (virtual_dynamic_stack_rtx - sp) later in
653 expand_asan_emit_allocas_unpoison function.
655 HWASAN needs to do very similar, the eventual pseudocode should be:
656 __hwasan_tag_memory (virtual_stack_dynamic_rtx,
658 new_sp - sp);
659 __builtin_stack_restore (new_sp)
661 Need to use the same trick to handle STACK_DYNAMIC_OFFSET as described
662 above. */
664 static void
665 handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
667 if (!iter
668 || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()))
669 return;
671 tree restored_stack = gimple_call_arg (call, 0);
673 gimple *g;
675 if (hwasan_sanitize_allocas_p ())
677 enum internal_fn fn = IFN_HWASAN_ALLOCA_UNPOISON;
678 /* There is only one piece of information `expand_HWASAN_ALLOCA_UNPOISON`
679 needs to work. This is the length of the area that we're
680 deallocating. Since the stack pointer is known at expand time, the
681 position of the new stack pointer after deallocation is enough
682 information to calculate this length. */
683 g = gimple_build_call_internal (fn, 1, restored_stack);
685 else
687 tree last_alloca = get_last_alloca_addr ();
688 tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
689 g = gimple_build_call (fn, 2, last_alloca, restored_stack);
690 gsi_insert_before (iter, g, GSI_SAME_STMT);
691 g = gimple_build_assign (last_alloca, restored_stack);
694 gsi_insert_before (iter, g, GSI_SAME_STMT);
697 /* Deploy and poison redzones around __builtin_alloca call. To do this, we
698 should replace this call with another one with changed parameters and
699 replace all its uses with new address, so
700 addr = __builtin_alloca (old_size, align);
701 is replaced by
702 left_redzone_size = max (align, ASAN_RED_ZONE_SIZE);
703 Following two statements are optimized out if we know that
704 old_size & (ASAN_RED_ZONE_SIZE - 1) == 0, i.e. alloca doesn't need partial
705 redzone.
706 misalign = old_size & (ASAN_RED_ZONE_SIZE - 1);
707 partial_redzone_size = ASAN_RED_ZONE_SIZE - misalign;
708 right_redzone_size = ASAN_RED_ZONE_SIZE;
709 additional_size = left_redzone_size + partial_redzone_size +
710 right_redzone_size;
711 new_size = old_size + additional_size;
712 new_alloca = __builtin_alloca (new_size, max (align, 32))
713 __asan_alloca_poison (new_alloca, old_size)
714 addr = new_alloca + max (align, ASAN_RED_ZONE_SIZE);
715 last_alloca_addr = new_alloca;
716 ADDITIONAL_SIZE is added to make new memory allocation contain not only
717 requested memory, but also left, partial and right redzones as well as some
718 additional space, required by alignment. */
720 static void
721 handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter)
723 if (!iter
724 || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()))
725 return;
727 gassign *g;
728 gcall *gg;
729 tree callee = gimple_call_fndecl (call);
730 tree lhs = gimple_call_lhs (call);
731 tree old_size = gimple_call_arg (call, 0);
732 tree ptr_type = lhs ? TREE_TYPE (lhs) : ptr_type_node;
733 tree partial_size = NULL_TREE;
734 unsigned int align
735 = DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
736 ? 0 : tree_to_uhwi (gimple_call_arg (call, 1));
738 bool throws = false;
739 edge e = NULL;
740 if (stmt_can_throw_internal (cfun, call))
742 if (!lhs)
743 return;
744 throws = true;
745 e = find_fallthru_edge (gsi_bb (*iter)->succs);
748 if (hwasan_sanitize_allocas_p ())
750 gimple_seq stmts = NULL;
751 location_t loc = gimple_location (gsi_stmt (*iter));
753 HWASAN needs a different expansion.
755 addr = __builtin_alloca (size, align);
757 should be replaced by
759 new_size = size rounded up to HWASAN_TAG_GRANULE_SIZE byte alignment;
760 untagged_addr = __builtin_alloca (new_size, align);
761 tag = __hwasan_choose_alloca_tag ();
762 addr = ifn_HWASAN_SET_TAG (untagged_addr, tag);
763 __hwasan_tag_memory (untagged_addr, tag, new_size);
765 /* Ensure alignment at least HWASAN_TAG_GRANULE_SIZE bytes so we start on
766 a tag granule. */
767 align = align > HWASAN_TAG_GRANULE_SIZE ? align : HWASAN_TAG_GRANULE_SIZE;
769 tree old_size = gimple_call_arg (call, 0);
770 tree new_size = gimple_build_round_up (&stmts, loc, size_type_node,
771 old_size,
772 HWASAN_TAG_GRANULE_SIZE);
774 /* Make the alloca call */
775 tree untagged_addr
776 = gimple_build (&stmts, loc,
777 as_combined_fn (BUILT_IN_ALLOCA_WITH_ALIGN), ptr_type,
778 new_size, build_int_cst (size_type_node, align));
780 /* Choose the tag.
781 Here we use an internal function so we can choose the tag at expand
782 time. We need the decision to be made after stack variables have been
783 assigned their tag (i.e. once the hwasan_frame_tag_offset variable has
784 been set to one after the last stack variables tag). */
785 tree tag = gimple_build (&stmts, loc, CFN_HWASAN_CHOOSE_TAG,
786 unsigned_char_type_node);
788 /* Add tag to pointer. */
789 tree addr
790 = gimple_build (&stmts, loc, CFN_HWASAN_SET_TAG, ptr_type,
791 untagged_addr, tag);
793 /* Tag shadow memory.
794 NOTE: require using `untagged_addr` here for libhwasan API. */
795 gimple_build (&stmts, loc, as_combined_fn (BUILT_IN_HWASAN_TAG_MEM),
796 void_type_node, untagged_addr, tag, new_size);
798 /* Insert the built up code sequence into the original instruction stream
799 the iterator points to. */
800 gsi_insert_seq_before (iter, stmts, GSI_SAME_STMT);
802 /* Finally, replace old alloca ptr with NEW_ALLOCA. */
803 replace_call_with_value (iter, addr);
804 return;
807 tree last_alloca = get_last_alloca_addr ();
808 const HOST_WIDE_INT redzone_mask = ASAN_RED_ZONE_SIZE - 1;
810 /* If ALIGN > ASAN_RED_ZONE_SIZE, we embed left redzone into first ALIGN
811 bytes of allocated space. Otherwise, align alloca to ASAN_RED_ZONE_SIZE
812 manually. */
813 align = MAX (align, ASAN_RED_ZONE_SIZE * BITS_PER_UNIT);
815 tree alloca_rz_mask = build_int_cst (size_type_node, redzone_mask);
816 tree redzone_size = build_int_cst (size_type_node, ASAN_RED_ZONE_SIZE);
818 /* Extract lower bits from old_size. */
819 wide_int size_nonzero_bits = get_nonzero_bits (old_size);
820 wide_int rz_mask
821 = wi::uhwi (redzone_mask, wi::get_precision (size_nonzero_bits));
822 wide_int old_size_lower_bits = wi::bit_and (size_nonzero_bits, rz_mask);
824 /* If alloca size is aligned to ASAN_RED_ZONE_SIZE, we don't need partial
825 redzone. Otherwise, compute its size here. */
826 if (wi::ne_p (old_size_lower_bits, 0))
828 /* misalign = size & (ASAN_RED_ZONE_SIZE - 1)
829 partial_size = ASAN_RED_ZONE_SIZE - misalign. */
830 g = gimple_build_assign (make_ssa_name (size_type_node, NULL),
831 BIT_AND_EXPR, old_size, alloca_rz_mask);
832 gsi_insert_before (iter, g, GSI_SAME_STMT);
833 tree misalign = gimple_assign_lhs (g);
834 g = gimple_build_assign (make_ssa_name (size_type_node, NULL), MINUS_EXPR,
835 redzone_size, misalign);
836 gsi_insert_before (iter, g, GSI_SAME_STMT);
837 partial_size = gimple_assign_lhs (g);
840 /* additional_size = align + ASAN_RED_ZONE_SIZE. */
841 tree additional_size = build_int_cst (size_type_node, align / BITS_PER_UNIT
842 + ASAN_RED_ZONE_SIZE);
843 /* If alloca has partial redzone, include it to additional_size too. */
844 if (partial_size)
846 /* additional_size += partial_size. */
847 g = gimple_build_assign (make_ssa_name (size_type_node), PLUS_EXPR,
848 partial_size, additional_size);
849 gsi_insert_before (iter, g, GSI_SAME_STMT);
850 additional_size = gimple_assign_lhs (g);
853 /* new_size = old_size + additional_size. */
854 g = gimple_build_assign (make_ssa_name (size_type_node), PLUS_EXPR, old_size,
855 additional_size);
856 gsi_insert_before (iter, g, GSI_SAME_STMT);
857 tree new_size = gimple_assign_lhs (g);
859 /* Build new __builtin_alloca call:
860 new_alloca_with_rz = __builtin_alloca (new_size, align). */
861 tree fn = builtin_decl_implicit (BUILT_IN_ALLOCA_WITH_ALIGN);
862 gg = gimple_build_call (fn, 2, new_size,
863 build_int_cst (size_type_node, align));
864 tree new_alloca_with_rz = make_ssa_name (ptr_type, gg);
865 gimple_call_set_lhs (gg, new_alloca_with_rz);
866 if (throws)
868 gimple_call_set_lhs (call, NULL);
869 gsi_replace (iter, gg, true);
871 else
872 gsi_insert_before (iter, gg, GSI_SAME_STMT);
874 /* new_alloca = new_alloca_with_rz + align. */
875 g = gimple_build_assign (make_ssa_name (ptr_type), POINTER_PLUS_EXPR,
876 new_alloca_with_rz,
877 build_int_cst (size_type_node,
878 align / BITS_PER_UNIT));
879 gimple_stmt_iterator gsi = gsi_none ();
880 if (throws)
882 gsi_insert_on_edge_immediate (e, g);
883 gsi = gsi_for_stmt (g);
885 else
886 gsi_insert_before (iter, g, GSI_SAME_STMT);
887 tree new_alloca = gimple_assign_lhs (g);
889 /* Poison newly created alloca redzones:
890 __asan_alloca_poison (new_alloca, old_size). */
891 fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCA_POISON);
892 gg = gimple_build_call (fn, 2, new_alloca, old_size);
893 if (throws)
894 gsi_insert_after (&gsi, gg, GSI_NEW_STMT);
895 else
896 gsi_insert_before (iter, gg, GSI_SAME_STMT);
898 /* Save new_alloca_with_rz value into last_alloca to use it during
899 allocas unpoisoning. */
900 g = gimple_build_assign (last_alloca, new_alloca_with_rz);
901 if (throws)
902 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
903 else
904 gsi_insert_before (iter, g, GSI_SAME_STMT);
906 /* Finally, replace old alloca ptr with NEW_ALLOCA. */
907 if (throws)
909 g = gimple_build_assign (lhs, new_alloca);
910 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
912 else
913 replace_call_with_value (iter, new_alloca);
916 /* Return the memory references contained in a gimple statement
917 representing a builtin call that has to do with memory access. */
919 static bool
920 get_mem_refs_of_builtin_call (gcall *call,
921 asan_mem_ref *src0,
922 tree *src0_len,
923 bool *src0_is_store,
924 asan_mem_ref *src1,
925 tree *src1_len,
926 bool *src1_is_store,
927 asan_mem_ref *dst,
928 tree *dst_len,
929 bool *dst_is_store,
930 bool *dest_is_deref,
931 bool *intercepted_p,
932 gimple_stmt_iterator *iter = NULL)
934 gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
936 tree callee = gimple_call_fndecl (call);
937 tree source0 = NULL_TREE, source1 = NULL_TREE,
938 dest = NULL_TREE, len = NULL_TREE;
939 bool is_store = true, got_reference_p = false;
940 HOST_WIDE_INT access_size = 1;
942 *intercepted_p = asan_intercepted_p ((DECL_FUNCTION_CODE (callee)));
944 switch (DECL_FUNCTION_CODE (callee))
946 /* (s, s, n) style memops. */
947 case BUILT_IN_BCMP:
948 case BUILT_IN_MEMCMP:
949 source0 = gimple_call_arg (call, 0);
950 source1 = gimple_call_arg (call, 1);
951 len = gimple_call_arg (call, 2);
952 break;
954 /* (src, dest, n) style memops. */
955 case BUILT_IN_BCOPY:
956 source0 = gimple_call_arg (call, 0);
957 dest = gimple_call_arg (call, 1);
958 len = gimple_call_arg (call, 2);
959 break;
961 /* (dest, src, n) style memops. */
962 case BUILT_IN_MEMCPY:
963 case BUILT_IN_MEMCPY_CHK:
964 case BUILT_IN_MEMMOVE:
965 case BUILT_IN_MEMMOVE_CHK:
966 case BUILT_IN_MEMPCPY:
967 case BUILT_IN_MEMPCPY_CHK:
968 dest = gimple_call_arg (call, 0);
969 source0 = gimple_call_arg (call, 1);
970 len = gimple_call_arg (call, 2);
971 break;
973 /* (dest, n) style memops. */
974 case BUILT_IN_BZERO:
975 dest = gimple_call_arg (call, 0);
976 len = gimple_call_arg (call, 1);
977 break;
979 /* (dest, x, n) style memops*/
980 case BUILT_IN_MEMSET:
981 case BUILT_IN_MEMSET_CHK:
982 dest = gimple_call_arg (call, 0);
983 len = gimple_call_arg (call, 2);
984 break;
986 case BUILT_IN_STRLEN:
987 /* Special case strlen here since its length is taken from its return
988 value.
990 The approach taken by the sanitizers is to check a memory access
991 before it's taken. For ASAN strlen is intercepted by libasan, so no
992 check is inserted by the compiler.
994 This function still returns `true` and provides a length to the rest
995 of the ASAN pass in order to record what areas have been checked,
996 avoiding superfluous checks later on.
998 HWASAN does not intercept any of these internal functions.
999 This means that checks for memory accesses must be inserted by the
1000 compiler.
1001 strlen is a special case, because we can tell the length from the
1002 return of the function, but that is not known until after the function
1003 has returned.
1005 Hence we can't check the memory access before it happens.
1006 We could check the memory access after it has already happened, but
1007 for now we choose to just ignore `strlen` calls.
1008 This decision was simply made because that means the special case is
1009 limited to this one case of this one function. */
1010 if (hwasan_sanitize_p ())
1011 return false;
1012 source0 = gimple_call_arg (call, 0);
1013 len = gimple_call_lhs (call);
1014 break;
1016 case BUILT_IN_STACK_RESTORE:
1017 handle_builtin_stack_restore (call, iter);
1018 break;
1020 CASE_BUILT_IN_ALLOCA:
1021 handle_builtin_alloca (call, iter);
1022 break;
1023 /* And now the __atomic* and __sync builtins.
1024 These are handled differently from the classical memory
1025 access builtins above. */
1027 case BUILT_IN_ATOMIC_LOAD_1:
1028 is_store = false;
1029 /* FALLTHRU */
1030 case BUILT_IN_SYNC_FETCH_AND_ADD_1:
1031 case BUILT_IN_SYNC_FETCH_AND_SUB_1:
1032 case BUILT_IN_SYNC_FETCH_AND_OR_1:
1033 case BUILT_IN_SYNC_FETCH_AND_AND_1:
1034 case BUILT_IN_SYNC_FETCH_AND_XOR_1:
1035 case BUILT_IN_SYNC_FETCH_AND_NAND_1:
1036 case BUILT_IN_SYNC_ADD_AND_FETCH_1:
1037 case BUILT_IN_SYNC_SUB_AND_FETCH_1:
1038 case BUILT_IN_SYNC_OR_AND_FETCH_1:
1039 case BUILT_IN_SYNC_AND_AND_FETCH_1:
1040 case BUILT_IN_SYNC_XOR_AND_FETCH_1:
1041 case BUILT_IN_SYNC_NAND_AND_FETCH_1:
1042 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
1043 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
1044 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
1045 case BUILT_IN_SYNC_LOCK_RELEASE_1:
1046 case BUILT_IN_ATOMIC_EXCHANGE_1:
1047 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
1048 case BUILT_IN_ATOMIC_STORE_1:
1049 case BUILT_IN_ATOMIC_ADD_FETCH_1:
1050 case BUILT_IN_ATOMIC_SUB_FETCH_1:
1051 case BUILT_IN_ATOMIC_AND_FETCH_1:
1052 case BUILT_IN_ATOMIC_NAND_FETCH_1:
1053 case BUILT_IN_ATOMIC_XOR_FETCH_1:
1054 case BUILT_IN_ATOMIC_OR_FETCH_1:
1055 case BUILT_IN_ATOMIC_FETCH_ADD_1:
1056 case BUILT_IN_ATOMIC_FETCH_SUB_1:
1057 case BUILT_IN_ATOMIC_FETCH_AND_1:
1058 case BUILT_IN_ATOMIC_FETCH_NAND_1:
1059 case BUILT_IN_ATOMIC_FETCH_XOR_1:
1060 case BUILT_IN_ATOMIC_FETCH_OR_1:
1061 access_size = 1;
1062 goto do_atomic;
1064 case BUILT_IN_ATOMIC_LOAD_2:
1065 is_store = false;
1066 /* FALLTHRU */
1067 case BUILT_IN_SYNC_FETCH_AND_ADD_2:
1068 case BUILT_IN_SYNC_FETCH_AND_SUB_2:
1069 case BUILT_IN_SYNC_FETCH_AND_OR_2:
1070 case BUILT_IN_SYNC_FETCH_AND_AND_2:
1071 case BUILT_IN_SYNC_FETCH_AND_XOR_2:
1072 case BUILT_IN_SYNC_FETCH_AND_NAND_2:
1073 case BUILT_IN_SYNC_ADD_AND_FETCH_2:
1074 case BUILT_IN_SYNC_SUB_AND_FETCH_2:
1075 case BUILT_IN_SYNC_OR_AND_FETCH_2:
1076 case BUILT_IN_SYNC_AND_AND_FETCH_2:
1077 case BUILT_IN_SYNC_XOR_AND_FETCH_2:
1078 case BUILT_IN_SYNC_NAND_AND_FETCH_2:
1079 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
1080 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
1081 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
1082 case BUILT_IN_SYNC_LOCK_RELEASE_2:
1083 case BUILT_IN_ATOMIC_EXCHANGE_2:
1084 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
1085 case BUILT_IN_ATOMIC_STORE_2:
1086 case BUILT_IN_ATOMIC_ADD_FETCH_2:
1087 case BUILT_IN_ATOMIC_SUB_FETCH_2:
1088 case BUILT_IN_ATOMIC_AND_FETCH_2:
1089 case BUILT_IN_ATOMIC_NAND_FETCH_2:
1090 case BUILT_IN_ATOMIC_XOR_FETCH_2:
1091 case BUILT_IN_ATOMIC_OR_FETCH_2:
1092 case BUILT_IN_ATOMIC_FETCH_ADD_2:
1093 case BUILT_IN_ATOMIC_FETCH_SUB_2:
1094 case BUILT_IN_ATOMIC_FETCH_AND_2:
1095 case BUILT_IN_ATOMIC_FETCH_NAND_2:
1096 case BUILT_IN_ATOMIC_FETCH_XOR_2:
1097 case BUILT_IN_ATOMIC_FETCH_OR_2:
1098 access_size = 2;
1099 goto do_atomic;
1101 case BUILT_IN_ATOMIC_LOAD_4:
1102 is_store = false;
1103 /* FALLTHRU */
1104 case BUILT_IN_SYNC_FETCH_AND_ADD_4:
1105 case BUILT_IN_SYNC_FETCH_AND_SUB_4:
1106 case BUILT_IN_SYNC_FETCH_AND_OR_4:
1107 case BUILT_IN_SYNC_FETCH_AND_AND_4:
1108 case BUILT_IN_SYNC_FETCH_AND_XOR_4:
1109 case BUILT_IN_SYNC_FETCH_AND_NAND_4:
1110 case BUILT_IN_SYNC_ADD_AND_FETCH_4:
1111 case BUILT_IN_SYNC_SUB_AND_FETCH_4:
1112 case BUILT_IN_SYNC_OR_AND_FETCH_4:
1113 case BUILT_IN_SYNC_AND_AND_FETCH_4:
1114 case BUILT_IN_SYNC_XOR_AND_FETCH_4:
1115 case BUILT_IN_SYNC_NAND_AND_FETCH_4:
1116 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
1117 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
1118 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
1119 case BUILT_IN_SYNC_LOCK_RELEASE_4:
1120 case BUILT_IN_ATOMIC_EXCHANGE_4:
1121 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
1122 case BUILT_IN_ATOMIC_STORE_4:
1123 case BUILT_IN_ATOMIC_ADD_FETCH_4:
1124 case BUILT_IN_ATOMIC_SUB_FETCH_4:
1125 case BUILT_IN_ATOMIC_AND_FETCH_4:
1126 case BUILT_IN_ATOMIC_NAND_FETCH_4:
1127 case BUILT_IN_ATOMIC_XOR_FETCH_4:
1128 case BUILT_IN_ATOMIC_OR_FETCH_4:
1129 case BUILT_IN_ATOMIC_FETCH_ADD_4:
1130 case BUILT_IN_ATOMIC_FETCH_SUB_4:
1131 case BUILT_IN_ATOMIC_FETCH_AND_4:
1132 case BUILT_IN_ATOMIC_FETCH_NAND_4:
1133 case BUILT_IN_ATOMIC_FETCH_XOR_4:
1134 case BUILT_IN_ATOMIC_FETCH_OR_4:
1135 access_size = 4;
1136 goto do_atomic;
1138 case BUILT_IN_ATOMIC_LOAD_8:
1139 is_store = false;
1140 /* FALLTHRU */
1141 case BUILT_IN_SYNC_FETCH_AND_ADD_8:
1142 case BUILT_IN_SYNC_FETCH_AND_SUB_8:
1143 case BUILT_IN_SYNC_FETCH_AND_OR_8:
1144 case BUILT_IN_SYNC_FETCH_AND_AND_8:
1145 case BUILT_IN_SYNC_FETCH_AND_XOR_8:
1146 case BUILT_IN_SYNC_FETCH_AND_NAND_8:
1147 case BUILT_IN_SYNC_ADD_AND_FETCH_8:
1148 case BUILT_IN_SYNC_SUB_AND_FETCH_8:
1149 case BUILT_IN_SYNC_OR_AND_FETCH_8:
1150 case BUILT_IN_SYNC_AND_AND_FETCH_8:
1151 case BUILT_IN_SYNC_XOR_AND_FETCH_8:
1152 case BUILT_IN_SYNC_NAND_AND_FETCH_8:
1153 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
1154 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
1155 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
1156 case BUILT_IN_SYNC_LOCK_RELEASE_8:
1157 case BUILT_IN_ATOMIC_EXCHANGE_8:
1158 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
1159 case BUILT_IN_ATOMIC_STORE_8:
1160 case BUILT_IN_ATOMIC_ADD_FETCH_8:
1161 case BUILT_IN_ATOMIC_SUB_FETCH_8:
1162 case BUILT_IN_ATOMIC_AND_FETCH_8:
1163 case BUILT_IN_ATOMIC_NAND_FETCH_8:
1164 case BUILT_IN_ATOMIC_XOR_FETCH_8:
1165 case BUILT_IN_ATOMIC_OR_FETCH_8:
1166 case BUILT_IN_ATOMIC_FETCH_ADD_8:
1167 case BUILT_IN_ATOMIC_FETCH_SUB_8:
1168 case BUILT_IN_ATOMIC_FETCH_AND_8:
1169 case BUILT_IN_ATOMIC_FETCH_NAND_8:
1170 case BUILT_IN_ATOMIC_FETCH_XOR_8:
1171 case BUILT_IN_ATOMIC_FETCH_OR_8:
1172 access_size = 8;
1173 goto do_atomic;
1175 case BUILT_IN_ATOMIC_LOAD_16:
1176 is_store = false;
1177 /* FALLTHRU */
1178 case BUILT_IN_SYNC_FETCH_AND_ADD_16:
1179 case BUILT_IN_SYNC_FETCH_AND_SUB_16:
1180 case BUILT_IN_SYNC_FETCH_AND_OR_16:
1181 case BUILT_IN_SYNC_FETCH_AND_AND_16:
1182 case BUILT_IN_SYNC_FETCH_AND_XOR_16:
1183 case BUILT_IN_SYNC_FETCH_AND_NAND_16:
1184 case BUILT_IN_SYNC_ADD_AND_FETCH_16:
1185 case BUILT_IN_SYNC_SUB_AND_FETCH_16:
1186 case BUILT_IN_SYNC_OR_AND_FETCH_16:
1187 case BUILT_IN_SYNC_AND_AND_FETCH_16:
1188 case BUILT_IN_SYNC_XOR_AND_FETCH_16:
1189 case BUILT_IN_SYNC_NAND_AND_FETCH_16:
1190 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
1191 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
1192 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
1193 case BUILT_IN_SYNC_LOCK_RELEASE_16:
1194 case BUILT_IN_ATOMIC_EXCHANGE_16:
1195 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
1196 case BUILT_IN_ATOMIC_STORE_16:
1197 case BUILT_IN_ATOMIC_ADD_FETCH_16:
1198 case BUILT_IN_ATOMIC_SUB_FETCH_16:
1199 case BUILT_IN_ATOMIC_AND_FETCH_16:
1200 case BUILT_IN_ATOMIC_NAND_FETCH_16:
1201 case BUILT_IN_ATOMIC_XOR_FETCH_16:
1202 case BUILT_IN_ATOMIC_OR_FETCH_16:
1203 case BUILT_IN_ATOMIC_FETCH_ADD_16:
1204 case BUILT_IN_ATOMIC_FETCH_SUB_16:
1205 case BUILT_IN_ATOMIC_FETCH_AND_16:
1206 case BUILT_IN_ATOMIC_FETCH_NAND_16:
1207 case BUILT_IN_ATOMIC_FETCH_XOR_16:
1208 case BUILT_IN_ATOMIC_FETCH_OR_16:
1209 access_size = 16;
1210 /* FALLTHRU */
1211 do_atomic:
1213 dest = gimple_call_arg (call, 0);
1214 /* DEST represents the address of a memory location.
1215 instrument_derefs wants the memory location, so lets
1216 dereference the address DEST before handing it to
1217 instrument_derefs. */
1218 tree type = build_nonstandard_integer_type (access_size
1219 * BITS_PER_UNIT, 1);
1220 dest = build2 (MEM_REF, type, dest,
1221 build_int_cst (build_pointer_type (char_type_node), 0));
1222 break;
1225 default:
1226 /* The other builtins memory access are not instrumented in this
1227 function because they either don't have any length parameter,
1228 or their length parameter is just a limit. */
1229 break;
1232 if (len != NULL_TREE)
1234 if (source0 != NULL_TREE)
1236 src0->start = source0;
1237 src0->access_size = access_size;
1238 *src0_len = len;
1239 *src0_is_store = false;
1242 if (source1 != NULL_TREE)
1244 src1->start = source1;
1245 src1->access_size = access_size;
1246 *src1_len = len;
1247 *src1_is_store = false;
1250 if (dest != NULL_TREE)
1252 dst->start = dest;
1253 dst->access_size = access_size;
1254 *dst_len = len;
1255 *dst_is_store = true;
1258 got_reference_p = true;
1260 else if (dest)
1262 dst->start = dest;
1263 dst->access_size = access_size;
1264 *dst_len = NULL_TREE;
1265 *dst_is_store = is_store;
1266 *dest_is_deref = true;
1267 got_reference_p = true;
1270 return got_reference_p;
1273 /* Return true iff a given gimple statement has been instrumented.
1274 Note that the statement is "defined" by the memory references it
1275 contains. */
1277 static bool
1278 has_stmt_been_instrumented_p (gimple *stmt)
1280 if (gimple_assign_single_p (stmt))
1282 bool r_is_store;
1283 asan_mem_ref r;
1284 asan_mem_ref_init (&r, NULL, 1);
1286 if (get_mem_ref_of_assignment (as_a <gassign *> (stmt), &r,
1287 &r_is_store))
1289 if (!has_mem_ref_been_instrumented (&r))
1290 return false;
1291 if (r_is_store && gimple_assign_load_p (stmt))
1293 asan_mem_ref src;
1294 asan_mem_ref_init (&src, NULL, 1);
1295 src.start = gimple_assign_rhs1 (stmt);
1296 src.access_size = int_size_in_bytes (TREE_TYPE (src.start));
1297 if (!has_mem_ref_been_instrumented (&src))
1298 return false;
1300 return true;
1303 else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
1305 asan_mem_ref src0, src1, dest;
1306 asan_mem_ref_init (&src0, NULL, 1);
1307 asan_mem_ref_init (&src1, NULL, 1);
1308 asan_mem_ref_init (&dest, NULL, 1);
1310 tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
1311 bool src0_is_store = false, src1_is_store = false,
1312 dest_is_store = false, dest_is_deref = false, intercepted_p = true;
1313 if (get_mem_refs_of_builtin_call (as_a <gcall *> (stmt),
1314 &src0, &src0_len, &src0_is_store,
1315 &src1, &src1_len, &src1_is_store,
1316 &dest, &dest_len, &dest_is_store,
1317 &dest_is_deref, &intercepted_p))
1319 if (src0.start != NULL_TREE
1320 && !has_mem_ref_been_instrumented (&src0, src0_len))
1321 return false;
1323 if (src1.start != NULL_TREE
1324 && !has_mem_ref_been_instrumented (&src1, src1_len))
1325 return false;
1327 if (dest.start != NULL_TREE
1328 && !has_mem_ref_been_instrumented (&dest, dest_len))
1329 return false;
1331 return true;
1334 else if (is_gimple_call (stmt) && gimple_store_p (stmt))
1336 asan_mem_ref r;
1337 asan_mem_ref_init (&r, NULL, 1);
1339 r.start = gimple_call_lhs (stmt);
1340 r.access_size = int_size_in_bytes (TREE_TYPE (r.start));
1341 return has_mem_ref_been_instrumented (&r);
1344 return false;
1347 /* Insert a memory reference into the hash table. */
1349 static void
1350 update_mem_ref_hash_table (tree ref, HOST_WIDE_INT access_size)
1352 hash_table<asan_mem_ref_hasher> *ht = get_mem_ref_hash_table ();
1354 asan_mem_ref r;
1355 asan_mem_ref_init (&r, ref, access_size);
1357 asan_mem_ref **slot = ht->find_slot (&r, INSERT);
1358 if (*slot == NULL || (*slot)->access_size < access_size)
1359 *slot = asan_mem_ref_new (ref, access_size);
1362 /* Initialize shadow_ptr_types array. */
1364 static void
1365 asan_init_shadow_ptr_types (void)
1367 asan_shadow_set = new_alias_set ();
1368 tree types[3] = { signed_char_type_node, short_integer_type_node,
1369 integer_type_node };
1371 for (unsigned i = 0; i < 3; i++)
1373 shadow_ptr_types[i] = build_distinct_type_copy (types[i]);
1374 TYPE_ALIAS_SET (shadow_ptr_types[i]) = asan_shadow_set;
1375 shadow_ptr_types[i] = build_pointer_type (shadow_ptr_types[i]);
1378 initialize_sanitizer_builtins ();
1381 /* Create ADDR_EXPR of STRING_CST with the PP pretty printer text. */
1383 static tree
1384 asan_pp_string (pretty_printer *pp)
1386 const char *buf = pp_formatted_text (pp);
1387 size_t len = strlen (buf);
1388 tree ret = build_string (len + 1, buf);
1389 TREE_TYPE (ret)
1390 = build_array_type (TREE_TYPE (shadow_ptr_types[0]),
1391 build_index_type (size_int (len)));
1392 TREE_READONLY (ret) = 1;
1393 TREE_STATIC (ret) = 1;
1394 return build1 (ADDR_EXPR, shadow_ptr_types[0], ret);
1397 /* Clear shadow memory at SHADOW_MEM, LEN bytes. Can't call a library call here
1398 though. */
1400 static void
1401 asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
1403 rtx_insn *insn, *insns, *jump;
1404 rtx_code_label *top_label;
1405 rtx end, addr, tmp;
1407 gcc_assert ((len & 3) == 0);
1408 start_sequence ();
1409 clear_storage (shadow_mem, GEN_INT (len), BLOCK_OP_NORMAL);
1410 insns = get_insns ();
1411 end_sequence ();
1412 for (insn = insns; insn; insn = NEXT_INSN (insn))
1413 if (CALL_P (insn))
1414 break;
1415 if (insn == NULL_RTX)
1417 emit_insn (insns);
1418 return;
1421 top_label = gen_label_rtx ();
1422 addr = copy_to_mode_reg (Pmode, XEXP (shadow_mem, 0));
1423 shadow_mem = adjust_automodify_address (shadow_mem, SImode, addr, 0);
1424 end = force_reg (Pmode, plus_constant (Pmode, addr, len));
1425 emit_label (top_label);
1427 emit_move_insn (shadow_mem, const0_rtx);
1428 tmp = expand_simple_binop (Pmode, PLUS, addr, gen_int_mode (4, Pmode), addr,
1429 true, OPTAB_LIB_WIDEN);
1430 if (tmp != addr)
1431 emit_move_insn (addr, tmp);
1432 emit_cmp_and_jump_insns (addr, end, LT, NULL_RTX, Pmode, true, top_label);
1433 jump = get_last_insn ();
1434 gcc_assert (JUMP_P (jump));
1435 add_reg_br_prob_note (jump,
1436 profile_probability::guessed_always ()
1437 .apply_scale (80, 100));
1440 void
1441 asan_function_start (void)
1443 section *fnsec = function_section (current_function_decl);
1444 switch_to_section (fnsec);
1445 ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LASANPC",
1446 current_function_funcdef_no);
1449 /* Return number of shadow bytes that are occupied by a local variable
1450 of SIZE bytes. */
1452 static unsigned HOST_WIDE_INT
1453 shadow_mem_size (unsigned HOST_WIDE_INT size)
1455 /* It must be possible to align stack variables to granularity
1456 of shadow memory. */
1457 gcc_assert (BITS_PER_UNIT
1458 * ASAN_SHADOW_GRANULARITY <= MAX_SUPPORTED_STACK_ALIGNMENT);
1460 return ROUND_UP (size, ASAN_SHADOW_GRANULARITY) / ASAN_SHADOW_GRANULARITY;
1463 /* Always emit 4 bytes at a time. */
1464 #define RZ_BUFFER_SIZE 4
1466 /* ASAN redzone buffer container that handles emission of shadow bytes. */
1467 class asan_redzone_buffer
1469 public:
1470 /* Constructor. */
1471 asan_redzone_buffer (rtx shadow_mem, HOST_WIDE_INT prev_offset):
1472 m_shadow_mem (shadow_mem), m_prev_offset (prev_offset),
1473 m_original_offset (prev_offset), m_shadow_bytes (RZ_BUFFER_SIZE)
1476 /* Emit VALUE shadow byte at a given OFFSET. */
1477 void emit_redzone_byte (HOST_WIDE_INT offset, unsigned char value);
1479 /* Emit RTX emission of the content of the buffer. */
1480 void flush_redzone_payload (void);
1482 private:
1483 /* Flush if the content of the buffer is full
1484 (equal to RZ_BUFFER_SIZE). */
1485 void flush_if_full (void);
1487 /* Memory where we last emitted a redzone payload. */
1488 rtx m_shadow_mem;
1490 /* Relative offset where we last emitted a redzone payload. */
1491 HOST_WIDE_INT m_prev_offset;
1493 /* Relative original offset. Used for checking only. */
1494 HOST_WIDE_INT m_original_offset;
1496 public:
1497 /* Buffer with redzone payload. */
1498 auto_vec<unsigned char> m_shadow_bytes;
1501 /* Emit VALUE shadow byte at a given OFFSET. */
1503 void
1504 asan_redzone_buffer::emit_redzone_byte (HOST_WIDE_INT offset,
1505 unsigned char value)
1507 gcc_assert ((offset & (ASAN_SHADOW_GRANULARITY - 1)) == 0);
1508 gcc_assert (offset >= m_prev_offset);
1510 HOST_WIDE_INT off
1511 = m_prev_offset + ASAN_SHADOW_GRANULARITY * m_shadow_bytes.length ();
1512 if (off == offset)
1513 /* Consecutive shadow memory byte. */;
1514 else if (offset < m_prev_offset + (HOST_WIDE_INT) (ASAN_SHADOW_GRANULARITY
1515 * RZ_BUFFER_SIZE)
1516 && !m_shadow_bytes.is_empty ())
1518 /* Shadow memory byte with a small gap. */
1519 for (; off < offset; off += ASAN_SHADOW_GRANULARITY)
1520 m_shadow_bytes.safe_push (0);
1522 else
1524 if (!m_shadow_bytes.is_empty ())
1525 flush_redzone_payload ();
1527 /* Maybe start earlier in order to use aligned store. */
1528 HOST_WIDE_INT align = (offset - m_prev_offset) % ASAN_RED_ZONE_SIZE;
1529 if (align)
1531 offset -= align;
1532 for (unsigned i = 0; i < align / BITS_PER_UNIT; i++)
1533 m_shadow_bytes.safe_push (0);
1536 /* Adjust m_prev_offset and m_shadow_mem. */
1537 HOST_WIDE_INT diff = offset - m_prev_offset;
1538 m_shadow_mem = adjust_address (m_shadow_mem, VOIDmode,
1539 diff >> ASAN_SHADOW_SHIFT);
1540 m_prev_offset = offset;
1542 m_shadow_bytes.safe_push (value);
1543 flush_if_full ();
1546 /* Emit RTX emission of the content of the buffer. */
1548 void
1549 asan_redzone_buffer::flush_redzone_payload (void)
1551 gcc_assert (WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN);
1553 if (m_shadow_bytes.is_empty ())
1554 return;
1556 /* Be sure we always emit to an aligned address. */
1557 gcc_assert (((m_prev_offset - m_original_offset)
1558 & (ASAN_RED_ZONE_SIZE - 1)) == 0);
1560 /* Fill it to RZ_BUFFER_SIZE bytes with zeros if needed. */
1561 unsigned l = m_shadow_bytes.length ();
1562 for (unsigned i = 0; i <= RZ_BUFFER_SIZE - l; i++)
1563 m_shadow_bytes.safe_push (0);
1565 if (dump_file && (dump_flags & TDF_DETAILS))
1566 fprintf (dump_file,
1567 "Flushing rzbuffer at offset %" PRId64 " with: ", m_prev_offset);
1569 unsigned HOST_WIDE_INT val = 0;
1570 for (unsigned i = 0; i < RZ_BUFFER_SIZE; i++)
1572 unsigned char v
1573 = m_shadow_bytes[BYTES_BIG_ENDIAN ? RZ_BUFFER_SIZE - i - 1 : i];
1574 val |= (unsigned HOST_WIDE_INT)v << (BITS_PER_UNIT * i);
1575 if (dump_file && (dump_flags & TDF_DETAILS))
1576 fprintf (dump_file, "%02x ", v);
1579 if (dump_file && (dump_flags & TDF_DETAILS))
1580 fprintf (dump_file, "\n");
1582 rtx c = gen_int_mode (val, SImode);
1583 m_shadow_mem = adjust_address (m_shadow_mem, SImode, 0);
1584 emit_move_insn (m_shadow_mem, c);
1585 m_shadow_bytes.truncate (0);
1588 /* Flush if the content of the buffer is full
1589 (equal to RZ_BUFFER_SIZE). */
1591 void
1592 asan_redzone_buffer::flush_if_full (void)
1594 if (m_shadow_bytes.length () == RZ_BUFFER_SIZE)
1595 flush_redzone_payload ();
1599 /* HWAddressSanitizer (hwasan) is a probabilistic method for detecting
1600 out-of-bounds and use-after-free bugs.
1601 Read more:
1602 http://code.google.com/p/address-sanitizer/
1604 Similar to AddressSanitizer (asan) it consists of two parts: the
1605 instrumentation module in this file, and a run-time library.
1607 The instrumentation module adds a run-time check before every memory insn in
1608 the same manner as asan (see the block comment for AddressSanitizer above).
1609 Currently, hwasan only adds out-of-line instrumentation, where each check is
1610 implemented as a function call to the run-time library. Hence a check for a
1611 load of N bytes from address X would be implemented with a function call to
1612 __hwasan_loadN(X), and checking a store of N bytes from address X would be
1613 implemented with a function call to __hwasan_storeN(X).
1615 The main difference between hwasan and asan is in the information stored to
1616 help this checking. Both sanitizers use a shadow memory area which stores
1617 data recording the state of main memory at a corresponding address.
1619 For hwasan, each 16 byte granule in main memory has a corresponding 1 byte
1620 in shadow memory. This shadow address can be calculated with equation:
1621 (addr >> log_2(HWASAN_TAG_GRANULE_SIZE))
1622 + __hwasan_shadow_memory_dynamic_address;
1623 The conversion between real and shadow memory for asan is given in the block
1624 comment at the top of this file.
1625 The description of how this shadow memory is laid out for asan is in the
1626 block comment at the top of this file, here we describe how this shadow
1627 memory is used for hwasan.
1629 For hwasan, each variable is assigned a byte-sized 'tag'. The extent of
1630 the shadow memory for that variable is filled with the assigned tag, and
1631 every pointer referencing that variable has its top byte set to the same
1632 tag. The run-time library redefines malloc so that every allocation returns
1633 a tagged pointer and tags the corresponding shadow memory with the same tag.
1635 On each pointer dereference the tag found in the pointer is compared to the
1636 tag found in the shadow memory corresponding to the accessed memory address.
1637 If these tags are found to differ then this memory access is judged to be
1638 invalid and a report is generated.
1640 This method of bug detection is not perfect -- it can not catch every bad
1641 access -- but catches them probabilistically instead. There is always the
1642 possibility that an invalid memory access will happen to access memory
1643 tagged with the same tag as the pointer that this access used.
1644 The chances of this are approx. 0.4% for any two uncorrelated objects.
1646 Random tag generation can mitigate this problem by decreasing the
1647 probability that an invalid access will be missed in the same manner over
1648 multiple runs. i.e. if two objects are tagged the same in one run of the
1649 binary they are unlikely to be tagged the same in the next run.
1650 Both heap and stack allocated objects have random tags by default.
1652 [16 byte granule implications]
1653 Since the shadow memory only has a resolution on real memory of 16 bytes,
1654 invalid accesses that are within the same 16 byte granule as a valid
1655 address will not be caught.
1657 There is a "short-granule" feature in the runtime library which does catch
1658 such accesses, but this feature is not implemented for stack objects (since
1659 stack objects are allocated and tagged by compiler instrumentation, and
1660 this feature has not yet been implemented in GCC instrumentation).
1662 Another outcome of this 16 byte resolution is that each tagged object must
1663 be 16 byte aligned. If two objects were to share any 16 byte granule in
1664 memory, then they both would have to be given the same tag, and invalid
1665 accesses to one using a pointer to the other would be undetectable.
1667 [Compiler instrumentation]
1668 Compiler instrumentation ensures that two adjacent buffers on the stack are
1669 given different tags, this means an access to one buffer using a pointer
1670 generated from the other (e.g. through buffer overrun) will have mismatched
1671 tags and be caught by hwasan.
1673 We don't randomly tag every object on the stack, since that would require
1674 keeping many registers to record each tag. Instead we randomly generate a
1675 tag for each function frame, and each new stack object uses a tag offset
1676 from that frame tag.
1677 i.e. each object is tagged as RFT + offset, where RFT is the "random frame
1678 tag" generated for this frame.
1679 This means that randomisation does not peturb the difference between tags
1680 on tagged stack objects within a frame, but this is mitigated by the fact
1681 that objects with the same tag within a frame are very far apart
1682 (approx. 2^HWASAN_TAG_SIZE objects apart).
1684 As a demonstration, using the same example program as in the asan block
1685 comment above:
1688 foo ()
1690 char a[24] = {0};
1691 int b[2] = {0};
1693 a[5] = 1;
1694 b[1] = 2;
1696 return a[5] + b[1];
1699 On AArch64 the stack will be ordered as follows for the above function:
1701 Slot 1/ [24 bytes for variable 'a']
1702 Slot 2/ [8 bytes padding for alignment]
1703 Slot 3/ [8 bytes for variable 'b']
1704 Slot 4/ [8 bytes padding for alignment]
1706 (The padding is there to ensure 16 byte alignment as described in the 16
1707 byte granule implications).
1709 While the shadow memory will be ordered as follows:
1711 - 2 bytes (representing 32 bytes in real memory) tagged with RFT + 1.
1712 - 1 byte (representing 16 bytes in real memory) tagged with RFT + 2.
1714 And any pointer to "a" will have the tag RFT + 1, and any pointer to "b"
1715 will have the tag RFT + 2.
1717 [Top Byte Ignore requirements]
1718 Hwasan requires the ability to store an 8 bit tag in every pointer. There
1719 is no instrumentation done to remove this tag from pointers before
1720 dereferencing, which means the hardware must ignore this tag during memory
1721 accesses.
1723 Architectures where this feature is available should indicate this using
1724 the TARGET_MEMTAG_CAN_TAG_ADDRESSES hook.
1726 [Stack requires cleanup on unwinding]
1727 During normal operation of a hwasan sanitized program more space in the
1728 shadow memory becomes tagged as the stack grows. As the stack shrinks this
1729 shadow memory space must become untagged. If it is not untagged then when
1730 the stack grows again (during other function calls later on in the program)
1731 objects on the stack that are usually not tagged (e.g. parameters passed on
1732 the stack) can be placed in memory whose shadow space is tagged with
1733 something else, and accesses can cause false positive reports.
1735 Hence we place untagging code on every epilogue of functions which tag some
1736 stack objects.
1738 Moreover, the run-time library intercepts longjmp & setjmp to untag when
1739 the stack is unwound this way.
1741 C++ exceptions are not yet handled, which means this sanitizer can not
1742 handle C++ code that throws exceptions -- it will give false positives
1743 after an exception has been thrown. The implementation that the hwasan
1744 library has for handling these relies on the frame pointer being after any
1745 local variables. This is not generally the case for GCC. */
1748 /* Returns whether we are tagging pointers and checking those tags on memory
1749 access. */
1750 bool
1751 hwasan_sanitize_p ()
1753 return sanitize_flags_p (SANITIZE_HWADDRESS);
1756 /* Are we tagging the stack? */
1757 bool
1758 hwasan_sanitize_stack_p ()
1760 return (hwasan_sanitize_p () && param_hwasan_instrument_stack);
1763 /* Are we tagging alloca objects? */
1764 bool
1765 hwasan_sanitize_allocas_p (void)
1767 return (hwasan_sanitize_stack_p () && param_hwasan_instrument_allocas);
1770 /* Should we instrument reads? */
1771 bool
1772 hwasan_instrument_reads (void)
1774 return (hwasan_sanitize_p () && param_hwasan_instrument_reads);
1777 /* Should we instrument writes? */
1778 bool
1779 hwasan_instrument_writes (void)
1781 return (hwasan_sanitize_p () && param_hwasan_instrument_writes);
1784 /* Should we instrument builtin calls? */
1785 bool
1786 hwasan_memintrin (void)
1788 return (hwasan_sanitize_p () && param_hwasan_instrument_mem_intrinsics);
1791 /* Insert code to protect stack vars. The prologue sequence should be emitted
1792 directly, epilogue sequence returned. BASE is the register holding the
1793 stack base, against which OFFSETS array offsets are relative to, OFFSETS
1794 array contains pairs of offsets in reverse order, always the end offset
1795 of some gap that needs protection followed by starting offset,
1796 and DECLS is an array of representative decls for each var partition.
1797 LENGTH is the length of the OFFSETS array, DECLS array is LENGTH / 2 - 1
1798 elements long (OFFSETS include gap before the first variable as well
1799 as gaps after each stack variable). PBASE is, if non-NULL, some pseudo
1800 register which stack vars DECL_RTLs are based on. Either BASE should be
1801 assigned to PBASE, when not doing use after return protection, or
1802 corresponding address based on __asan_stack_malloc* return value. */
1804 rtx_insn *
1805 asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
1806 HOST_WIDE_INT *offsets, tree *decls, int length)
1808 rtx shadow_base, shadow_mem, ret, mem, orig_base;
1809 rtx_code_label *lab;
1810 rtx_insn *insns;
1811 char buf[32];
1812 HOST_WIDE_INT base_offset = offsets[length - 1];
1813 HOST_WIDE_INT base_align_bias = 0, offset, prev_offset;
1814 HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset;
1815 HOST_WIDE_INT last_offset, last_size, last_size_aligned;
1816 int l;
1817 unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT;
1818 tree str_cst, decl, id;
1819 int use_after_return_class = -1;
1821 if (shadow_ptr_types[0] == NULL_TREE)
1822 asan_init_shadow_ptr_types ();
1824 expanded_location cfun_xloc
1825 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
1827 /* First of all, prepare the description string. */
1828 pretty_printer asan_pp;
1830 pp_decimal_int (&asan_pp, length / 2 - 1);
1831 pp_space (&asan_pp);
1832 for (l = length - 2; l; l -= 2)
1834 tree decl = decls[l / 2 - 1];
1835 pp_wide_integer (&asan_pp, offsets[l] - base_offset);
1836 pp_space (&asan_pp);
1837 pp_wide_integer (&asan_pp, offsets[l - 1] - offsets[l]);
1838 pp_space (&asan_pp);
1840 expanded_location xloc
1841 = expand_location (DECL_SOURCE_LOCATION (decl));
1842 char location[32];
1844 if (xloc.file == cfun_xloc.file)
1845 sprintf (location, ":%d", xloc.line);
1846 else
1847 location[0] = '\0';
1849 if (DECL_P (decl) && DECL_NAME (decl))
1851 unsigned idlen
1852 = IDENTIFIER_LENGTH (DECL_NAME (decl)) + strlen (location);
1853 pp_decimal_int (&asan_pp, idlen);
1854 pp_space (&asan_pp);
1855 pp_tree_identifier (&asan_pp, DECL_NAME (decl));
1856 pp_string (&asan_pp, location);
1858 else
1859 pp_string (&asan_pp, "9 <unknown>");
1861 if (l > 2)
1862 pp_space (&asan_pp);
1864 str_cst = asan_pp_string (&asan_pp);
1866 /* Emit the prologue sequence. */
1867 if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase
1868 && param_asan_use_after_return)
1870 use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
1871 /* __asan_stack_malloc_N guarantees alignment
1872 N < 6 ? (64 << N) : 4096 bytes. */
1873 if (alignb > (use_after_return_class < 6
1874 ? (64U << use_after_return_class) : 4096U))
1875 use_after_return_class = -1;
1876 else if (alignb > ASAN_RED_ZONE_SIZE && (asan_frame_size & (alignb - 1)))
1877 base_align_bias = ((asan_frame_size + alignb - 1)
1878 & ~(alignb - HOST_WIDE_INT_1)) - asan_frame_size;
1881 /* Align base if target is STRICT_ALIGNMENT. */
1882 if (STRICT_ALIGNMENT)
1884 const HOST_WIDE_INT align
1885 = (GET_MODE_ALIGNMENT (SImode) / BITS_PER_UNIT) << ASAN_SHADOW_SHIFT;
1886 base = expand_binop (Pmode, and_optab, base, gen_int_mode (-align, Pmode),
1887 NULL_RTX, 1, OPTAB_DIRECT);
1890 if (use_after_return_class == -1 && pbase)
1891 emit_move_insn (pbase, base);
1893 base = expand_binop (Pmode, add_optab, base,
1894 gen_int_mode (base_offset - base_align_bias, Pmode),
1895 NULL_RTX, 1, OPTAB_DIRECT);
1896 orig_base = NULL_RTX;
1897 if (use_after_return_class != -1)
1899 if (asan_detect_stack_use_after_return == NULL_TREE)
1901 id = get_identifier ("__asan_option_detect_stack_use_after_return");
1902 decl = build_decl (BUILTINS_LOCATION, VAR_DECL, id,
1903 integer_type_node);
1904 SET_DECL_ASSEMBLER_NAME (decl, id);
1905 TREE_ADDRESSABLE (decl) = 1;
1906 DECL_ARTIFICIAL (decl) = 1;
1907 DECL_IGNORED_P (decl) = 1;
1908 DECL_EXTERNAL (decl) = 1;
1909 TREE_STATIC (decl) = 1;
1910 TREE_PUBLIC (decl) = 1;
1911 TREE_USED (decl) = 1;
1912 asan_detect_stack_use_after_return = decl;
1914 orig_base = gen_reg_rtx (Pmode);
1915 emit_move_insn (orig_base, base);
1916 ret = expand_normal (asan_detect_stack_use_after_return);
1917 lab = gen_label_rtx ();
1918 emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
1919 VOIDmode, 0, lab,
1920 profile_probability::very_likely ());
1921 snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
1922 use_after_return_class);
1923 ret = init_one_libfunc (buf);
1924 ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode,
1925 GEN_INT (asan_frame_size
1926 + base_align_bias),
1927 TYPE_MODE (pointer_sized_int_node));
1928 /* __asan_stack_malloc_[n] returns a pointer to fake stack if succeeded
1929 and NULL otherwise. Check RET value is NULL here and jump over the
1930 BASE reassignment in this case. Otherwise, reassign BASE to RET. */
1931 emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
1932 VOIDmode, 0, lab,
1933 profile_probability:: very_unlikely ());
1934 ret = convert_memory_address (Pmode, ret);
1935 emit_move_insn (base, ret);
1936 emit_label (lab);
1937 emit_move_insn (pbase, expand_binop (Pmode, add_optab, base,
1938 gen_int_mode (base_align_bias
1939 - base_offset, Pmode),
1940 NULL_RTX, 1, OPTAB_DIRECT));
1942 mem = gen_rtx_MEM (ptr_mode, base);
1943 mem = adjust_address (mem, VOIDmode, base_align_bias);
1944 emit_move_insn (mem, gen_int_mode (ASAN_STACK_FRAME_MAGIC, ptr_mode));
1945 mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
1946 emit_move_insn (mem, expand_normal (str_cst));
1947 mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
1948 ASM_GENERATE_INTERNAL_LABEL (buf, "LASANPC", current_function_funcdef_no);
1949 id = get_identifier (buf);
1950 decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
1951 VAR_DECL, id, char_type_node);
1952 SET_DECL_ASSEMBLER_NAME (decl, id);
1953 TREE_ADDRESSABLE (decl) = 1;
1954 TREE_READONLY (decl) = 1;
1955 DECL_ARTIFICIAL (decl) = 1;
1956 DECL_IGNORED_P (decl) = 1;
1957 TREE_STATIC (decl) = 1;
1958 TREE_PUBLIC (decl) = 0;
1959 TREE_USED (decl) = 1;
1960 DECL_INITIAL (decl) = decl;
1961 TREE_ASM_WRITTEN (decl) = 1;
1962 TREE_ASM_WRITTEN (id) = 1;
1963 emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
1964 shadow_base = expand_binop (Pmode, lshr_optab, base,
1965 gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT),
1966 NULL_RTX, 1, OPTAB_DIRECT);
1967 shadow_base
1968 = plus_constant (Pmode, shadow_base,
1969 asan_shadow_offset ()
1970 + (base_align_bias >> ASAN_SHADOW_SHIFT));
1971 gcc_assert (asan_shadow_set != -1
1972 && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
1973 shadow_mem = gen_rtx_MEM (SImode, shadow_base);
1974 set_mem_alias_set (shadow_mem, asan_shadow_set);
1975 if (STRICT_ALIGNMENT)
1976 set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
1977 prev_offset = base_offset;
1979 asan_redzone_buffer rz_buffer (shadow_mem, prev_offset);
1980 for (l = length; l; l -= 2)
1982 if (l == 2)
1983 cur_shadow_byte = ASAN_STACK_MAGIC_RIGHT;
1984 offset = offsets[l - 1];
1986 bool extra_byte = (offset - base_offset) & (ASAN_SHADOW_GRANULARITY - 1);
1987 /* If a red-zone is not aligned to ASAN_SHADOW_GRANULARITY then
1988 the previous stack variable has size % ASAN_SHADOW_GRANULARITY != 0.
1989 In that case we have to emit one extra byte that will describe
1990 how many bytes (our of ASAN_SHADOW_GRANULARITY) can be accessed. */
1991 if (extra_byte)
1993 HOST_WIDE_INT aoff
1994 = base_offset + ((offset - base_offset)
1995 & ~(ASAN_SHADOW_GRANULARITY - HOST_WIDE_INT_1));
1996 rz_buffer.emit_redzone_byte (aoff, offset - aoff);
1997 offset = aoff + ASAN_SHADOW_GRANULARITY;
2000 /* Calculate size of red zone payload. */
2001 while (offset < offsets[l - 2])
2003 rz_buffer.emit_redzone_byte (offset, cur_shadow_byte);
2004 offset += ASAN_SHADOW_GRANULARITY;
2007 cur_shadow_byte = ASAN_STACK_MAGIC_MIDDLE;
2010 /* As the automatic variables are aligned to
2011 ASAN_RED_ZONE_SIZE / ASAN_SHADOW_GRANULARITY, the buffer should be
2012 flushed here. */
2013 gcc_assert (rz_buffer.m_shadow_bytes.is_empty ());
2015 do_pending_stack_adjust ();
2017 /* Construct epilogue sequence. */
2018 start_sequence ();
2020 lab = NULL;
2021 if (use_after_return_class != -1)
2023 rtx_code_label *lab2 = gen_label_rtx ();
2024 char c = (char) ASAN_STACK_MAGIC_USE_AFTER_RET;
2025 emit_cmp_and_jump_insns (orig_base, base, EQ, NULL_RTX,
2026 VOIDmode, 0, lab2,
2027 profile_probability::very_likely ());
2028 shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
2029 set_mem_alias_set (shadow_mem, asan_shadow_set);
2030 mem = gen_rtx_MEM (ptr_mode, base);
2031 mem = adjust_address (mem, VOIDmode, base_align_bias);
2032 emit_move_insn (mem, gen_int_mode (ASAN_STACK_RETIRED_MAGIC, ptr_mode));
2033 unsigned HOST_WIDE_INT sz = asan_frame_size >> ASAN_SHADOW_SHIFT;
2034 if (use_after_return_class < 5
2035 && can_store_by_pieces (sz, builtin_memset_read_str, &c,
2036 BITS_PER_UNIT, true))
2038 /* Emit:
2039 memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);
2040 **SavedFlagPtr(FakeStack, class_id) = 0
2042 store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c,
2043 BITS_PER_UNIT, true, RETURN_BEGIN);
2045 unsigned HOST_WIDE_INT offset
2046 = (1 << (use_after_return_class + 6));
2047 offset -= GET_MODE_SIZE (ptr_mode);
2048 mem = gen_rtx_MEM (ptr_mode, base);
2049 mem = adjust_address (mem, ptr_mode, offset);
2050 rtx addr = gen_reg_rtx (ptr_mode);
2051 emit_move_insn (addr, mem);
2052 addr = convert_memory_address (Pmode, addr);
2053 mem = gen_rtx_MEM (QImode, addr);
2054 emit_move_insn (mem, const0_rtx);
2056 else if (use_after_return_class >= 5
2057 || !set_storage_via_setmem (shadow_mem,
2058 GEN_INT (sz),
2059 gen_int_mode (c, QImode),
2060 BITS_PER_UNIT, BITS_PER_UNIT,
2061 -1, sz, sz, sz))
2063 snprintf (buf, sizeof buf, "__asan_stack_free_%d",
2064 use_after_return_class);
2065 ret = init_one_libfunc (buf);
2066 rtx addr = convert_memory_address (ptr_mode, base);
2067 rtx orig_addr = convert_memory_address (ptr_mode, orig_base);
2068 emit_library_call (ret, LCT_NORMAL, ptr_mode, addr, ptr_mode,
2069 GEN_INT (asan_frame_size + base_align_bias),
2070 TYPE_MODE (pointer_sized_int_node),
2071 orig_addr, ptr_mode);
2073 lab = gen_label_rtx ();
2074 emit_jump (lab);
2075 emit_label (lab2);
2078 shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
2079 set_mem_alias_set (shadow_mem, asan_shadow_set);
2081 if (STRICT_ALIGNMENT)
2082 set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
2084 prev_offset = base_offset;
2085 last_offset = base_offset;
2086 last_size = 0;
2087 last_size_aligned = 0;
2088 for (l = length; l; l -= 2)
2090 offset = base_offset + ((offsets[l - 1] - base_offset)
2091 & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
2092 if (last_offset + last_size_aligned < offset)
2094 shadow_mem = adjust_address (shadow_mem, VOIDmode,
2095 (last_offset - prev_offset)
2096 >> ASAN_SHADOW_SHIFT);
2097 prev_offset = last_offset;
2098 asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT);
2099 last_offset = offset;
2100 last_size = 0;
2102 else
2103 last_size = offset - last_offset;
2104 last_size += base_offset + ((offsets[l - 2] - base_offset)
2105 & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
2106 - offset;
2108 /* Unpoison shadow memory that corresponds to a variable that is
2109 is subject of use-after-return sanitization. */
2110 if (l > 2)
2112 decl = decls[l / 2 - 2];
2113 if (asan_handled_variables != NULL
2114 && asan_handled_variables->contains (decl))
2116 HOST_WIDE_INT size = offsets[l - 3] - offsets[l - 2];
2117 if (dump_file && (dump_flags & TDF_DETAILS))
2119 const char *n = (DECL_NAME (decl)
2120 ? IDENTIFIER_POINTER (DECL_NAME (decl))
2121 : "<unknown>");
2122 fprintf (dump_file, "Unpoisoning shadow stack for variable: "
2123 "%s (%" PRId64 " B)\n", n, size);
2126 last_size += size & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1);
2129 last_size_aligned
2130 = ((last_size + (ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
2131 & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
2133 if (last_size_aligned)
2135 shadow_mem = adjust_address (shadow_mem, VOIDmode,
2136 (last_offset - prev_offset)
2137 >> ASAN_SHADOW_SHIFT);
2138 asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT);
2141 /* Clean-up set with instrumented stack variables. */
2142 delete asan_handled_variables;
2143 asan_handled_variables = NULL;
2144 delete asan_used_labels;
2145 asan_used_labels = NULL;
2147 do_pending_stack_adjust ();
2148 if (lab)
2149 emit_label (lab);
2151 insns = get_insns ();
2152 end_sequence ();
2153 return insns;
2156 /* Emit __asan_allocas_unpoison (top, bot) call. The BASE parameter corresponds
2157 to BOT argument, for TOP virtual_stack_dynamic_rtx is used. NEW_SEQUENCE
2158 indicates whether we're emitting new instructions sequence or not. */
2160 rtx_insn *
2161 asan_emit_allocas_unpoison (rtx top, rtx bot, rtx_insn *before)
2163 if (before)
2164 push_to_sequence (before);
2165 else
2166 start_sequence ();
2167 rtx ret = init_one_libfunc ("__asan_allocas_unpoison");
2168 top = convert_memory_address (ptr_mode, top);
2169 bot = convert_memory_address (ptr_mode, bot);
2170 emit_library_call (ret, LCT_NORMAL, ptr_mode,
2171 top, ptr_mode, bot, ptr_mode);
2173 do_pending_stack_adjust ();
2174 rtx_insn *insns = get_insns ();
2175 end_sequence ();
2176 return insns;
2179 /* Return true if DECL, a global var, might be overridden and needs
2180 therefore a local alias. */
2182 static bool
2183 asan_needs_local_alias (tree decl)
2185 return DECL_WEAK (decl) || !targetm.binds_local_p (decl);
2188 /* Return true if DECL, a global var, is an artificial ODR indicator symbol
2189 therefore doesn't need protection. */
2191 static bool
2192 is_odr_indicator (tree decl)
2194 return (DECL_ARTIFICIAL (decl)
2195 && lookup_attribute ("asan odr indicator", DECL_ATTRIBUTES (decl)));
2198 /* Return true if DECL is a VAR_DECL that should be protected
2199 by Address Sanitizer, by appending a red zone with protected
2200 shadow memory after it and aligning it to at least
2201 ASAN_RED_ZONE_SIZE bytes. */
2203 bool
2204 asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
2206 if (!param_asan_globals)
2207 return false;
2209 rtx rtl, symbol;
2211 if (TREE_CODE (decl) == STRING_CST)
2213 /* Instrument all STRING_CSTs except those created
2214 by asan_pp_string here. */
2215 if (shadow_ptr_types[0] != NULL_TREE
2216 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
2217 && TREE_TYPE (TREE_TYPE (decl)) == TREE_TYPE (shadow_ptr_types[0]))
2218 return false;
2219 return true;
2221 if (!VAR_P (decl)
2222 /* TLS vars aren't statically protectable. */
2223 || DECL_THREAD_LOCAL_P (decl)
2224 /* Externs will be protected elsewhere. */
2225 || DECL_EXTERNAL (decl)
2226 /* PR sanitizer/81697: For architectures that use section anchors first
2227 call to asan_protect_global may occur before DECL_RTL (decl) is set.
2228 We should ignore DECL_RTL_SET_P then, because otherwise the first call
2229 to asan_protect_global will return FALSE and the following calls on the
2230 same decl after setting DECL_RTL (decl) will return TRUE and we'll end
2231 up with inconsistency at runtime. */
2232 || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)
2233 /* Comdat vars pose an ABI problem, we can't know if
2234 the var that is selected by the linker will have
2235 padding or not. */
2236 || DECL_ONE_ONLY (decl)
2237 /* Similarly for common vars. People can use -fno-common.
2238 Note: Linux kernel is built with -fno-common, so we do instrument
2239 globals there even if it is C. */
2240 || (DECL_COMMON (decl) && TREE_PUBLIC (decl))
2241 /* Don't protect if using user section, often vars placed
2242 into user section from multiple TUs are then assumed
2243 to be an array of such vars, putting padding in there
2244 breaks this assumption. */
2245 || (DECL_SECTION_NAME (decl) != NULL
2246 && !symtab_node::get (decl)->implicit_section
2247 && !section_sanitized_p (DECL_SECTION_NAME (decl)))
2248 || DECL_SIZE (decl) == 0
2249 || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT
2250 || TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
2251 || !valid_constant_size_p (DECL_SIZE_UNIT (decl))
2252 || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE
2253 || TREE_TYPE (decl) == ubsan_get_source_location_type ()
2254 || is_odr_indicator (decl))
2255 return false;
2257 if (!ignore_decl_rtl_set_p || DECL_RTL_SET_P (decl))
2260 rtl = DECL_RTL (decl);
2261 if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
2262 return false;
2263 symbol = XEXP (rtl, 0);
2265 if (CONSTANT_POOL_ADDRESS_P (symbol)
2266 || TREE_CONSTANT_POOL_ADDRESS_P (symbol))
2267 return false;
2270 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
2271 return false;
2273 if (!TARGET_SUPPORTS_ALIASES && asan_needs_local_alias (decl))
2274 return false;
2276 return true;
2279 /* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16,_n}.
2280 IS_STORE is either 1 (for a store) or 0 (for a load). */
2282 static tree
2283 report_error_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
2284 int *nargs)
2286 gcc_assert (!hwasan_sanitize_p ());
2288 static enum built_in_function report[2][2][6]
2289 = { { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
2290 BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
2291 BUILT_IN_ASAN_REPORT_LOAD16, BUILT_IN_ASAN_REPORT_LOAD_N },
2292 { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
2293 BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
2294 BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } },
2295 { { BUILT_IN_ASAN_REPORT_LOAD1_NOABORT,
2296 BUILT_IN_ASAN_REPORT_LOAD2_NOABORT,
2297 BUILT_IN_ASAN_REPORT_LOAD4_NOABORT,
2298 BUILT_IN_ASAN_REPORT_LOAD8_NOABORT,
2299 BUILT_IN_ASAN_REPORT_LOAD16_NOABORT,
2300 BUILT_IN_ASAN_REPORT_LOAD_N_NOABORT },
2301 { BUILT_IN_ASAN_REPORT_STORE1_NOABORT,
2302 BUILT_IN_ASAN_REPORT_STORE2_NOABORT,
2303 BUILT_IN_ASAN_REPORT_STORE4_NOABORT,
2304 BUILT_IN_ASAN_REPORT_STORE8_NOABORT,
2305 BUILT_IN_ASAN_REPORT_STORE16_NOABORT,
2306 BUILT_IN_ASAN_REPORT_STORE_N_NOABORT } } };
2307 if (size_in_bytes == -1)
2309 *nargs = 2;
2310 return builtin_decl_implicit (report[recover_p][is_store][5]);
2312 *nargs = 1;
2313 int size_log2 = exact_log2 (size_in_bytes);
2314 return builtin_decl_implicit (report[recover_p][is_store][size_log2]);
2317 /* Construct a function tree for __asan_{load,store}{1,2,4,8,16,_n}.
2318 IS_STORE is either 1 (for a store) or 0 (for a load). */
2320 static tree
2321 check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
2322 int *nargs)
2324 static enum built_in_function check[2][2][6]
2325 = { { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2,
2326 BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8,
2327 BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN },
2328 { BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2,
2329 BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8,
2330 BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } },
2331 { { BUILT_IN_ASAN_LOAD1_NOABORT,
2332 BUILT_IN_ASAN_LOAD2_NOABORT,
2333 BUILT_IN_ASAN_LOAD4_NOABORT,
2334 BUILT_IN_ASAN_LOAD8_NOABORT,
2335 BUILT_IN_ASAN_LOAD16_NOABORT,
2336 BUILT_IN_ASAN_LOADN_NOABORT },
2337 { BUILT_IN_ASAN_STORE1_NOABORT,
2338 BUILT_IN_ASAN_STORE2_NOABORT,
2339 BUILT_IN_ASAN_STORE4_NOABORT,
2340 BUILT_IN_ASAN_STORE8_NOABORT,
2341 BUILT_IN_ASAN_STORE16_NOABORT,
2342 BUILT_IN_ASAN_STOREN_NOABORT } } };
2343 if (size_in_bytes == -1)
2345 *nargs = 2;
2346 return builtin_decl_implicit (check[recover_p][is_store][5]);
2348 *nargs = 1;
2349 int size_log2 = exact_log2 (size_in_bytes);
2350 return builtin_decl_implicit (check[recover_p][is_store][size_log2]);
2353 /* Split the current basic block and create a condition statement
2354 insertion point right before or after the statement pointed to by
2355 ITER. Return an iterator to the point at which the caller might
2356 safely insert the condition statement.
2358 THEN_BLOCK must be set to the address of an uninitialized instance
2359 of basic_block. The function will then set *THEN_BLOCK to the
2360 'then block' of the condition statement to be inserted by the
2361 caller.
2363 If CREATE_THEN_FALLTHRU_EDGE is false, no edge will be created from
2364 *THEN_BLOCK to *FALLTHROUGH_BLOCK.
2366 Similarly, the function will set *FALLTRHOUGH_BLOCK to the 'else
2367 block' of the condition statement to be inserted by the caller.
2369 Note that *FALLTHROUGH_BLOCK is a new block that contains the
2370 statements starting from *ITER, and *THEN_BLOCK is a new empty
2371 block.
2373 *ITER is adjusted to point to always point to the first statement
2374 of the basic block * FALLTHROUGH_BLOCK. That statement is the
2375 same as what ITER was pointing to prior to calling this function,
2376 if BEFORE_P is true; otherwise, it is its following statement. */
2378 gimple_stmt_iterator
2379 create_cond_insert_point (gimple_stmt_iterator *iter,
2380 bool before_p,
2381 bool then_more_likely_p,
2382 bool create_then_fallthru_edge,
2383 basic_block *then_block,
2384 basic_block *fallthrough_block)
2386 gimple_stmt_iterator gsi = *iter;
2388 if (!gsi_end_p (gsi) && before_p)
2389 gsi_prev (&gsi);
2391 basic_block cur_bb = gsi_bb (*iter);
2393 edge e = split_block (cur_bb, gsi_stmt (gsi));
2395 /* Get a hold on the 'condition block', the 'then block' and the
2396 'else block'. */
2397 basic_block cond_bb = e->src;
2398 basic_block fallthru_bb = e->dest;
2399 basic_block then_bb = create_empty_bb (cond_bb);
2400 if (current_loops)
2402 add_bb_to_loop (then_bb, cond_bb->loop_father);
2403 loops_state_set (LOOPS_NEED_FIXUP);
2406 /* Set up the newly created 'then block'. */
2407 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
2408 profile_probability fallthrough_probability
2409 = then_more_likely_p
2410 ? profile_probability::very_unlikely ()
2411 : profile_probability::very_likely ();
2412 e->probability = fallthrough_probability.invert ();
2413 then_bb->count = e->count ();
2414 if (create_then_fallthru_edge)
2415 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
2417 /* Set up the fallthrough basic block. */
2418 e = find_edge (cond_bb, fallthru_bb);
2419 e->flags = EDGE_FALSE_VALUE;
2420 e->probability = fallthrough_probability;
2422 /* Update dominance info for the newly created then_bb; note that
2423 fallthru_bb's dominance info has already been updated by
2424 split_bock. */
2425 if (dom_info_available_p (CDI_DOMINATORS))
2426 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
2428 *then_block = then_bb;
2429 *fallthrough_block = fallthru_bb;
2430 *iter = gsi_start_bb (fallthru_bb);
2432 return gsi_last_bb (cond_bb);
2435 /* Insert an if condition followed by a 'then block' right before the
2436 statement pointed to by ITER. The fallthrough block -- which is the
2437 else block of the condition as well as the destination of the
2438 outcoming edge of the 'then block' -- starts with the statement
2439 pointed to by ITER.
2441 COND is the condition of the if.
2443 If THEN_MORE_LIKELY_P is true, the probability of the edge to the
2444 'then block' is higher than the probability of the edge to the
2445 fallthrough block.
2447 Upon completion of the function, *THEN_BB is set to the newly
2448 inserted 'then block' and similarly, *FALLTHROUGH_BB is set to the
2449 fallthrough block.
2451 *ITER is adjusted to still point to the same statement it was
2452 pointing to initially. */
2454 static void
2455 insert_if_then_before_iter (gcond *cond,
2456 gimple_stmt_iterator *iter,
2457 bool then_more_likely_p,
2458 basic_block *then_bb,
2459 basic_block *fallthrough_bb)
2461 gimple_stmt_iterator cond_insert_point =
2462 create_cond_insert_point (iter,
2463 /*before_p=*/true,
2464 then_more_likely_p,
2465 /*create_then_fallthru_edge=*/true,
2466 then_bb,
2467 fallthrough_bb);
2468 gsi_insert_after (&cond_insert_point, cond, GSI_NEW_STMT);
2471 /* Build (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().
2472 If RETURN_ADDRESS is set to true, return memory location instread
2473 of a value in the shadow memory. */
2475 static tree
2476 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
2477 tree base_addr, tree shadow_ptr_type,
2478 bool return_address = false)
2480 tree t, uintptr_type = TREE_TYPE (base_addr);
2481 tree shadow_type = TREE_TYPE (shadow_ptr_type);
2482 gimple *g;
2484 t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT);
2485 g = gimple_build_assign (make_ssa_name (uintptr_type), RSHIFT_EXPR,
2486 base_addr, t);
2487 gimple_set_location (g, location);
2488 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2490 t = build_int_cst (uintptr_type, asan_shadow_offset ());
2491 g = gimple_build_assign (make_ssa_name (uintptr_type), PLUS_EXPR,
2492 gimple_assign_lhs (g), t);
2493 gimple_set_location (g, location);
2494 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2496 g = gimple_build_assign (make_ssa_name (shadow_ptr_type), NOP_EXPR,
2497 gimple_assign_lhs (g));
2498 gimple_set_location (g, location);
2499 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2501 if (!return_address)
2503 t = build2 (MEM_REF, shadow_type, gimple_assign_lhs (g),
2504 build_int_cst (shadow_ptr_type, 0));
2505 g = gimple_build_assign (make_ssa_name (shadow_type), MEM_REF, t);
2506 gimple_set_location (g, location);
2507 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2510 return gimple_assign_lhs (g);
2513 /* BASE can already be an SSA_NAME; in that case, do not create a
2514 new SSA_NAME for it. */
2516 static tree
2517 maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
2518 bool before_p)
2520 STRIP_USELESS_TYPE_CONVERSION (base);
2521 if (TREE_CODE (base) == SSA_NAME)
2522 return base;
2523 gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (base)), base);
2524 gimple_set_location (g, loc);
2525 if (before_p)
2526 gsi_insert_before (iter, g, GSI_SAME_STMT);
2527 else
2528 gsi_insert_after (iter, g, GSI_NEW_STMT);
2529 return gimple_assign_lhs (g);
2532 /* LEN can already have necessary size and precision;
2533 in that case, do not create a new variable. */
2535 tree
2536 maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
2537 bool before_p)
2539 if (ptrofftype_p (len))
2540 return len;
2541 gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
2542 NOP_EXPR, len);
2543 gimple_set_location (g, loc);
2544 if (before_p)
2545 gsi_insert_before (iter, g, GSI_SAME_STMT);
2546 else
2547 gsi_insert_after (iter, g, GSI_NEW_STMT);
2548 return gimple_assign_lhs (g);
2551 /* Instrument the memory access instruction BASE. Insert new
2552 statements before or after ITER.
2554 Note that the memory access represented by BASE can be either an
2555 SSA_NAME, or a non-SSA expression. LOCATION is the source code
2556 location. IS_STORE is TRUE for a store, FALSE for a load.
2557 BEFORE_P is TRUE for inserting the instrumentation code before
2558 ITER, FALSE for inserting it after ITER. IS_SCALAR_ACCESS is TRUE
2559 for a scalar memory access and FALSE for memory region access.
2560 NON_ZERO_P is TRUE if memory region is guaranteed to have non-zero
2561 length. ALIGN tells alignment of accessed memory object.
2563 START_INSTRUMENTED and END_INSTRUMENTED are TRUE if start/end of
2564 memory region have already been instrumented.
2566 If BEFORE_P is TRUE, *ITER is arranged to still point to the
2567 statement it was pointing to prior to calling this function,
2568 otherwise, it points to the statement logically following it. */
2570 static void
2571 build_check_stmt (location_t loc, tree base, tree len,
2572 HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
2573 bool is_non_zero_len, bool before_p, bool is_store,
2574 bool is_scalar_access, unsigned int align = 0)
2576 gimple_stmt_iterator gsi = *iter;
2577 gimple *g;
2579 gcc_assert (!(size_in_bytes > 0 && !is_non_zero_len));
2580 gcc_assert (size_in_bytes == -1 || size_in_bytes >= 1);
2582 gsi = *iter;
2584 base = unshare_expr (base);
2585 base = maybe_create_ssa_name (loc, base, &gsi, before_p);
2587 if (len)
2589 len = unshare_expr (len);
2590 len = maybe_cast_to_ptrmode (loc, len, iter, before_p);
2592 else
2594 gcc_assert (size_in_bytes != -1);
2595 len = build_int_cst (pointer_sized_int_node, size_in_bytes);
2598 if (size_in_bytes > 1)
2600 if ((size_in_bytes & (size_in_bytes - 1)) != 0
2601 || size_in_bytes > 16)
2602 is_scalar_access = false;
2603 else if (align && align < size_in_bytes * BITS_PER_UNIT)
2605 /* On non-strict alignment targets, if
2606 16-byte access is just 8-byte aligned,
2607 this will result in misaligned shadow
2608 memory 2 byte load, but otherwise can
2609 be handled using one read. */
2610 if (size_in_bytes != 16
2611 || STRICT_ALIGNMENT
2612 || align < 8 * BITS_PER_UNIT)
2613 is_scalar_access = false;
2617 HOST_WIDE_INT flags = 0;
2618 if (is_store)
2619 flags |= ASAN_CHECK_STORE;
2620 if (is_non_zero_len)
2621 flags |= ASAN_CHECK_NON_ZERO_LEN;
2622 if (is_scalar_access)
2623 flags |= ASAN_CHECK_SCALAR_ACCESS;
2625 enum internal_fn fn = hwasan_sanitize_p ()
2626 ? IFN_HWASAN_CHECK
2627 : IFN_ASAN_CHECK;
2629 g = gimple_build_call_internal (fn, 4,
2630 build_int_cst (integer_type_node, flags),
2631 base, len,
2632 build_int_cst (integer_type_node,
2633 align / BITS_PER_UNIT));
2634 gimple_set_location (g, loc);
2635 if (before_p)
2636 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2637 else
2639 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
2640 gsi_next (&gsi);
2641 *iter = gsi;
2645 /* If T represents a memory access, add instrumentation code before ITER.
2646 LOCATION is source code location.
2647 IS_STORE is either TRUE (for a store) or FALSE (for a load). */
2649 static void
2650 instrument_derefs (gimple_stmt_iterator *iter, tree t,
2651 location_t location, bool is_store)
2653 if (is_store && !(asan_instrument_writes () || hwasan_instrument_writes ()))
2654 return;
2655 if (!is_store && !(asan_instrument_reads () || hwasan_instrument_reads ()))
2656 return;
2658 tree type, base;
2659 HOST_WIDE_INT size_in_bytes;
2660 if (location == UNKNOWN_LOCATION)
2661 location = EXPR_LOCATION (t);
2663 type = TREE_TYPE (t);
2664 switch (TREE_CODE (t))
2666 case ARRAY_REF:
2667 case COMPONENT_REF:
2668 case INDIRECT_REF:
2669 case MEM_REF:
2670 case VAR_DECL:
2671 case BIT_FIELD_REF:
2672 break;
2673 /* FALLTHRU */
2674 default:
2675 return;
2678 size_in_bytes = int_size_in_bytes (type);
2679 if (size_in_bytes <= 0)
2680 return;
2682 poly_int64 bitsize, bitpos;
2683 tree offset;
2684 machine_mode mode;
2685 int unsignedp, reversep, volatilep = 0;
2686 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
2687 &unsignedp, &reversep, &volatilep);
2689 if (TREE_CODE (t) == COMPONENT_REF
2690 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
2692 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
2693 instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
2694 TREE_OPERAND (t, 0), repr,
2695 TREE_OPERAND (t, 2)),
2696 location, is_store);
2697 return;
2700 if (!multiple_p (bitpos, BITS_PER_UNIT)
2701 || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
2702 return;
2704 if (VAR_P (inner) && DECL_HARD_REGISTER (inner))
2705 return;
2707 poly_int64 decl_size;
2708 if ((VAR_P (inner) || TREE_CODE (inner) == RESULT_DECL)
2709 && offset == NULL_TREE
2710 && DECL_SIZE (inner)
2711 && poly_int_tree_p (DECL_SIZE (inner), &decl_size)
2712 && known_subrange_p (bitpos, bitsize, 0, decl_size))
2714 if (VAR_P (inner) && DECL_THREAD_LOCAL_P (inner))
2715 return;
2716 /* If we're not sanitizing globals and we can tell statically that this
2717 access is inside a global variable, then there's no point adding
2718 instrumentation to check the access. N.b. hwasan currently never
2719 sanitizes globals. */
2720 if ((hwasan_sanitize_p () || !param_asan_globals)
2721 && is_global_var (inner))
2722 return;
2723 if (!TREE_STATIC (inner))
2725 /* Automatic vars in the current function will be always
2726 accessible. */
2727 if (decl_function_context (inner) == current_function_decl
2728 && (!asan_sanitize_use_after_scope ()
2729 || !TREE_ADDRESSABLE (inner)))
2730 return;
2732 /* Always instrument external vars, they might be dynamically
2733 initialized. */
2734 else if (!DECL_EXTERNAL (inner))
2736 /* For static vars if they are known not to be dynamically
2737 initialized, they will be always accessible. */
2738 varpool_node *vnode = varpool_node::get (inner);
2739 if (vnode && !vnode->dynamically_initialized)
2740 return;
2744 if (DECL_P (inner)
2745 && decl_function_context (inner) == current_function_decl
2746 && !TREE_ADDRESSABLE (inner))
2747 mark_addressable (inner);
2749 base = build_fold_addr_expr (t);
2750 if (!has_mem_ref_been_instrumented (base, size_in_bytes))
2752 unsigned int align = get_object_alignment (t);
2753 build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter,
2754 /*is_non_zero_len*/size_in_bytes > 0, /*before_p=*/true,
2755 is_store, /*is_scalar_access*/true, align);
2756 update_mem_ref_hash_table (base, size_in_bytes);
2757 update_mem_ref_hash_table (t, size_in_bytes);
2762 /* Insert a memory reference into the hash table if access length
2763 can be determined in compile time. */
2765 static void
2766 maybe_update_mem_ref_hash_table (tree base, tree len)
2768 if (!POINTER_TYPE_P (TREE_TYPE (base))
2769 || !INTEGRAL_TYPE_P (TREE_TYPE (len)))
2770 return;
2772 HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
2774 if (size_in_bytes != -1)
2775 update_mem_ref_hash_table (base, size_in_bytes);
2778 /* Instrument an access to a contiguous memory region that starts at
2779 the address pointed to by BASE, over a length of LEN (expressed in
2780 the sizeof (*BASE) bytes). ITER points to the instruction before
2781 which the instrumentation instructions must be inserted. LOCATION
2782 is the source location that the instrumentation instructions must
2783 have. If IS_STORE is true, then the memory access is a store;
2784 otherwise, it's a load. */
2786 static void
2787 instrument_mem_region_access (tree base, tree len,
2788 gimple_stmt_iterator *iter,
2789 location_t location, bool is_store)
2791 if (!POINTER_TYPE_P (TREE_TYPE (base))
2792 || !INTEGRAL_TYPE_P (TREE_TYPE (len))
2793 || integer_zerop (len))
2794 return;
2796 HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
2798 if ((size_in_bytes == -1)
2799 || !has_mem_ref_been_instrumented (base, size_in_bytes))
2801 build_check_stmt (location, base, len, size_in_bytes, iter,
2802 /*is_non_zero_len*/size_in_bytes > 0, /*before_p*/true,
2803 is_store, /*is_scalar_access*/false, /*align*/0);
2806 maybe_update_mem_ref_hash_table (base, len);
2807 *iter = gsi_for_stmt (gsi_stmt (*iter));
2810 /* Instrument the call to a built-in memory access function that is
2811 pointed to by the iterator ITER.
2813 Upon completion, return TRUE iff *ITER has been advanced to the
2814 statement following the one it was originally pointing to. */
2816 static bool
2817 instrument_builtin_call (gimple_stmt_iterator *iter)
2819 if (!(asan_memintrin () || hwasan_memintrin ()))
2820 return false;
2822 bool iter_advanced_p = false;
2823 gcall *call = as_a <gcall *> (gsi_stmt (*iter));
2825 gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
2827 location_t loc = gimple_location (call);
2829 asan_mem_ref src0, src1, dest;
2830 asan_mem_ref_init (&src0, NULL, 1);
2831 asan_mem_ref_init (&src1, NULL, 1);
2832 asan_mem_ref_init (&dest, NULL, 1);
2834 tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
2835 bool src0_is_store = false, src1_is_store = false, dest_is_store = false,
2836 dest_is_deref = false, intercepted_p = true;
2838 if (get_mem_refs_of_builtin_call (call,
2839 &src0, &src0_len, &src0_is_store,
2840 &src1, &src1_len, &src1_is_store,
2841 &dest, &dest_len, &dest_is_store,
2842 &dest_is_deref, &intercepted_p, iter))
2844 if (dest_is_deref)
2846 instrument_derefs (iter, dest.start, loc, dest_is_store);
2847 gsi_next (iter);
2848 iter_advanced_p = true;
2850 else if (!intercepted_p
2851 && (src0_len || src1_len || dest_len))
2853 if (src0.start != NULL_TREE)
2854 instrument_mem_region_access (src0.start, src0_len,
2855 iter, loc, /*is_store=*/false);
2856 if (src1.start != NULL_TREE)
2857 instrument_mem_region_access (src1.start, src1_len,
2858 iter, loc, /*is_store=*/false);
2859 if (dest.start != NULL_TREE)
2860 instrument_mem_region_access (dest.start, dest_len,
2861 iter, loc, /*is_store=*/true);
2863 *iter = gsi_for_stmt (call);
2864 gsi_next (iter);
2865 iter_advanced_p = true;
2867 else
2869 if (src0.start != NULL_TREE)
2870 maybe_update_mem_ref_hash_table (src0.start, src0_len);
2871 if (src1.start != NULL_TREE)
2872 maybe_update_mem_ref_hash_table (src1.start, src1_len);
2873 if (dest.start != NULL_TREE)
2874 maybe_update_mem_ref_hash_table (dest.start, dest_len);
2877 return iter_advanced_p;
2880 /* Instrument the assignment statement ITER if it is subject to
2881 instrumentation. Return TRUE iff instrumentation actually
2882 happened. In that case, the iterator ITER is advanced to the next
2883 logical expression following the one initially pointed to by ITER,
2884 and the relevant memory reference that which access has been
2885 instrumented is added to the memory references hash table. */
2887 static bool
2888 maybe_instrument_assignment (gimple_stmt_iterator *iter)
2890 gimple *s = gsi_stmt (*iter);
2892 gcc_assert (gimple_assign_single_p (s));
2894 tree ref_expr = NULL_TREE;
2895 bool is_store, is_instrumented = false;
2897 if (gimple_store_p (s))
2899 ref_expr = gimple_assign_lhs (s);
2900 is_store = true;
2901 instrument_derefs (iter, ref_expr,
2902 gimple_location (s),
2903 is_store);
2904 is_instrumented = true;
2907 if (gimple_assign_load_p (s))
2909 ref_expr = gimple_assign_rhs1 (s);
2910 is_store = false;
2911 instrument_derefs (iter, ref_expr,
2912 gimple_location (s),
2913 is_store);
2914 is_instrumented = true;
2917 if (is_instrumented)
2918 gsi_next (iter);
2920 return is_instrumented;
2923 /* Instrument the function call pointed to by the iterator ITER, if it
2924 is subject to instrumentation. At the moment, the only function
2925 calls that are instrumented are some built-in functions that access
2926 memory. Look at instrument_builtin_call to learn more.
2928 Upon completion return TRUE iff *ITER was advanced to the statement
2929 following the one it was originally pointing to. */
2931 static bool
2932 maybe_instrument_call (gimple_stmt_iterator *iter)
2934 gimple *stmt = gsi_stmt (*iter);
2935 bool is_builtin = gimple_call_builtin_p (stmt, BUILT_IN_NORMAL);
2937 if (is_builtin && instrument_builtin_call (iter))
2938 return true;
2940 if (gimple_call_noreturn_p (stmt))
2942 if (is_builtin)
2944 tree callee = gimple_call_fndecl (stmt);
2945 switch (DECL_FUNCTION_CODE (callee))
2947 case BUILT_IN_UNREACHABLE:
2948 case BUILT_IN_TRAP:
2949 /* Don't instrument these. */
2950 return false;
2951 default:
2952 break;
2955 /* If a function does not return, then we must handle clearing up the
2956 shadow stack accordingly. For ASAN we can simply set the entire stack
2957 to "valid" for accesses by setting the shadow space to 0 and all
2958 accesses will pass checks. That means that some bad accesses may be
2959 missed, but we will not report any false positives.
2961 This is not possible for HWASAN. Since there is no "always valid" tag
2962 we can not set any space to "always valid". If we were to clear the
2963 entire shadow stack then code resuming from `longjmp` or a caught
2964 exception would trigger false positives when correctly accessing
2965 variables on the stack. Hence we need to handle things like
2966 `longjmp`, thread exit, and exceptions in a different way. These
2967 problems must be handled externally to the compiler, e.g. in the
2968 language runtime. */
2969 if (! hwasan_sanitize_p ())
2971 tree decl = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN);
2972 gimple *g = gimple_build_call (decl, 0);
2973 gimple_set_location (g, gimple_location (stmt));
2974 gsi_insert_before (iter, g, GSI_SAME_STMT);
2978 bool instrumented = false;
2979 if (gimple_store_p (stmt))
2981 tree ref_expr = gimple_call_lhs (stmt);
2982 instrument_derefs (iter, ref_expr,
2983 gimple_location (stmt),
2984 /*is_store=*/true);
2986 instrumented = true;
2989 /* Walk through gimple_call arguments and check them id needed. */
2990 unsigned args_num = gimple_call_num_args (stmt);
2991 for (unsigned i = 0; i < args_num; ++i)
2993 tree arg = gimple_call_arg (stmt, i);
2994 /* If ARG is not a non-aggregate register variable, compiler in general
2995 creates temporary for it and pass it as argument to gimple call.
2996 But in some cases, e.g. when we pass by value a small structure that
2997 fits to register, compiler can avoid extra overhead by pulling out
2998 these temporaries. In this case, we should check the argument. */
2999 if (!is_gimple_reg (arg) && !is_gimple_min_invariant (arg))
3001 instrument_derefs (iter, arg,
3002 gimple_location (stmt),
3003 /*is_store=*/false);
3004 instrumented = true;
3007 if (instrumented)
3008 gsi_next (iter);
3009 return instrumented;
3012 /* Walk each instruction of all basic block and instrument those that
3013 represent memory references: loads, stores, or function calls.
3014 In a given basic block, this function avoids instrumenting memory
3015 references that have already been instrumented. */
3017 static void
3018 transform_statements (void)
3020 basic_block bb, last_bb = NULL;
3021 gimple_stmt_iterator i;
3022 int saved_last_basic_block = last_basic_block_for_fn (cfun);
3024 FOR_EACH_BB_FN (bb, cfun)
3026 basic_block prev_bb = bb;
3028 if (bb->index >= saved_last_basic_block) continue;
3030 /* Flush the mem ref hash table, if current bb doesn't have
3031 exactly one predecessor, or if that predecessor (skipping
3032 over asan created basic blocks) isn't the last processed
3033 basic block. Thus we effectively flush on extended basic
3034 block boundaries. */
3035 while (single_pred_p (prev_bb))
3037 prev_bb = single_pred (prev_bb);
3038 if (prev_bb->index < saved_last_basic_block)
3039 break;
3041 if (prev_bb != last_bb)
3042 empty_mem_ref_hash_table ();
3043 last_bb = bb;
3045 for (i = gsi_start_bb (bb); !gsi_end_p (i);)
3047 gimple *s = gsi_stmt (i);
3049 if (has_stmt_been_instrumented_p (s))
3050 gsi_next (&i);
3051 else if (gimple_assign_single_p (s)
3052 && !gimple_clobber_p (s)
3053 && maybe_instrument_assignment (&i))
3054 /* Nothing to do as maybe_instrument_assignment advanced
3055 the iterator I. */;
3056 else if (is_gimple_call (s) && maybe_instrument_call (&i))
3057 /* Nothing to do as maybe_instrument_call
3058 advanced the iterator I. */;
3059 else
3061 /* No instrumentation happened.
3063 If the current instruction is a function call that
3064 might free something, let's forget about the memory
3065 references that got instrumented. Otherwise we might
3066 miss some instrumentation opportunities. Do the same
3067 for a ASAN_MARK poisoning internal function. */
3068 if (is_gimple_call (s)
3069 && (!nonfreeing_call_p (s)
3070 || asan_mark_p (s, ASAN_MARK_POISON)))
3071 empty_mem_ref_hash_table ();
3073 gsi_next (&i);
3077 free_mem_ref_resources ();
3080 /* Build
3081 __asan_before_dynamic_init (module_name)
3083 __asan_after_dynamic_init ()
3084 call. */
3086 tree
3087 asan_dynamic_init_call (bool after_p)
3089 if (shadow_ptr_types[0] == NULL_TREE)
3090 asan_init_shadow_ptr_types ();
3092 tree fn = builtin_decl_implicit (after_p
3093 ? BUILT_IN_ASAN_AFTER_DYNAMIC_INIT
3094 : BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT);
3095 tree module_name_cst = NULL_TREE;
3096 if (!after_p)
3098 pretty_printer module_name_pp;
3099 pp_string (&module_name_pp, main_input_filename);
3101 module_name_cst = asan_pp_string (&module_name_pp);
3102 module_name_cst = fold_convert (const_ptr_type_node,
3103 module_name_cst);
3106 return build_call_expr (fn, after_p ? 0 : 1, module_name_cst);
3109 /* Build
3110 struct __asan_global
3112 const void *__beg;
3113 uptr __size;
3114 uptr __size_with_redzone;
3115 const void *__name;
3116 const void *__module_name;
3117 uptr __has_dynamic_init;
3118 __asan_global_source_location *__location;
3119 char *__odr_indicator;
3120 } type. */
3122 static tree
3123 asan_global_struct (void)
3125 static const char *field_names[]
3126 = { "__beg", "__size", "__size_with_redzone",
3127 "__name", "__module_name", "__has_dynamic_init", "__location",
3128 "__odr_indicator" };
3129 tree fields[ARRAY_SIZE (field_names)], ret;
3130 unsigned i;
3132 ret = make_node (RECORD_TYPE);
3133 for (i = 0; i < ARRAY_SIZE (field_names); i++)
3135 fields[i]
3136 = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
3137 get_identifier (field_names[i]),
3138 (i == 0 || i == 3) ? const_ptr_type_node
3139 : pointer_sized_int_node);
3140 DECL_CONTEXT (fields[i]) = ret;
3141 if (i)
3142 DECL_CHAIN (fields[i - 1]) = fields[i];
3144 tree type_decl = build_decl (input_location, TYPE_DECL,
3145 get_identifier ("__asan_global"), ret);
3146 DECL_IGNORED_P (type_decl) = 1;
3147 DECL_ARTIFICIAL (type_decl) = 1;
3148 TYPE_FIELDS (ret) = fields[0];
3149 TYPE_NAME (ret) = type_decl;
3150 TYPE_STUB_DECL (ret) = type_decl;
3151 TYPE_ARTIFICIAL (ret) = 1;
3152 layout_type (ret);
3153 return ret;
3156 /* Create and return odr indicator symbol for DECL.
3157 TYPE is __asan_global struct type as returned by asan_global_struct. */
3159 static tree
3160 create_odr_indicator (tree decl, tree type)
3162 char *name;
3163 tree uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
3164 tree decl_name
3165 = (HAS_DECL_ASSEMBLER_NAME_P (decl) ? DECL_ASSEMBLER_NAME (decl)
3166 : DECL_NAME (decl));
3167 /* DECL_NAME theoretically might be NULL. Bail out with 0 in this case. */
3168 if (decl_name == NULL_TREE)
3169 return build_int_cst (uptr, 0);
3170 const char *dname = IDENTIFIER_POINTER (decl_name);
3171 if (HAS_DECL_ASSEMBLER_NAME_P (decl))
3172 dname = targetm.strip_name_encoding (dname);
3173 size_t len = strlen (dname) + sizeof ("__odr_asan_");
3174 name = XALLOCAVEC (char, len);
3175 snprintf (name, len, "__odr_asan_%s", dname);
3176 #ifndef NO_DOT_IN_LABEL
3177 name[sizeof ("__odr_asan") - 1] = '.';
3178 #elif !defined(NO_DOLLAR_IN_LABEL)
3179 name[sizeof ("__odr_asan") - 1] = '$';
3180 #endif
3181 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (name),
3182 char_type_node);
3183 TREE_ADDRESSABLE (var) = 1;
3184 TREE_READONLY (var) = 0;
3185 TREE_THIS_VOLATILE (var) = 1;
3186 DECL_ARTIFICIAL (var) = 1;
3187 DECL_IGNORED_P (var) = 1;
3188 TREE_STATIC (var) = 1;
3189 TREE_PUBLIC (var) = 1;
3190 DECL_VISIBILITY (var) = DECL_VISIBILITY (decl);
3191 DECL_VISIBILITY_SPECIFIED (var) = DECL_VISIBILITY_SPECIFIED (decl);
3193 TREE_USED (var) = 1;
3194 tree ctor = build_constructor_va (TREE_TYPE (var), 1, NULL_TREE,
3195 build_int_cst (unsigned_type_node, 0));
3196 TREE_CONSTANT (ctor) = 1;
3197 TREE_STATIC (ctor) = 1;
3198 DECL_INITIAL (var) = ctor;
3199 DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("asan odr indicator"),
3200 NULL, DECL_ATTRIBUTES (var));
3201 make_decl_rtl (var);
3202 varpool_node::finalize_decl (var);
3203 return fold_convert (uptr, build_fold_addr_expr (var));
3206 /* Return true if DECL, a global var, might be overridden and needs
3207 an additional odr indicator symbol. */
3209 static bool
3210 asan_needs_odr_indicator_p (tree decl)
3212 /* Don't emit ODR indicators for kernel because:
3213 a) Kernel is written in C thus doesn't need ODR indicators.
3214 b) Some kernel code may have assumptions about symbols containing specific
3215 patterns in their names. Since ODR indicators contain original names
3216 of symbols they are emitted for, these assumptions would be broken for
3217 ODR indicator symbols. */
3218 return (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS)
3219 && !DECL_ARTIFICIAL (decl)
3220 && !DECL_WEAK (decl)
3221 && TREE_PUBLIC (decl));
3224 /* Append description of a single global DECL into vector V.
3225 TYPE is __asan_global struct type as returned by asan_global_struct. */
3227 static void
3228 asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
3230 tree init, uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
3231 unsigned HOST_WIDE_INT size;
3232 tree str_cst, module_name_cst, refdecl = decl;
3233 vec<constructor_elt, va_gc> *vinner = NULL;
3235 pretty_printer asan_pp, module_name_pp;
3237 if (DECL_NAME (decl))
3238 pp_tree_identifier (&asan_pp, DECL_NAME (decl));
3239 else
3240 pp_string (&asan_pp, "<unknown>");
3241 str_cst = asan_pp_string (&asan_pp);
3243 pp_string (&module_name_pp, main_input_filename);
3244 module_name_cst = asan_pp_string (&module_name_pp);
3246 if (asan_needs_local_alias (decl))
3248 char buf[20];
3249 ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", vec_safe_length (v) + 1);
3250 refdecl = build_decl (DECL_SOURCE_LOCATION (decl),
3251 VAR_DECL, get_identifier (buf), TREE_TYPE (decl));
3252 TREE_ADDRESSABLE (refdecl) = TREE_ADDRESSABLE (decl);
3253 TREE_READONLY (refdecl) = TREE_READONLY (decl);
3254 TREE_THIS_VOLATILE (refdecl) = TREE_THIS_VOLATILE (decl);
3255 DECL_NOT_GIMPLE_REG_P (refdecl) = DECL_NOT_GIMPLE_REG_P (decl);
3256 DECL_ARTIFICIAL (refdecl) = DECL_ARTIFICIAL (decl);
3257 DECL_IGNORED_P (refdecl) = DECL_IGNORED_P (decl);
3258 TREE_STATIC (refdecl) = 1;
3259 TREE_PUBLIC (refdecl) = 0;
3260 TREE_USED (refdecl) = 1;
3261 assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl));
3264 tree odr_indicator_ptr
3265 = (asan_needs_odr_indicator_p (decl) ? create_odr_indicator (decl, type)
3266 : build_int_cst (uptr, 0));
3267 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3268 fold_convert (const_ptr_type_node,
3269 build_fold_addr_expr (refdecl)));
3270 size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
3271 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
3272 size += asan_red_zone_size (size);
3273 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
3274 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3275 fold_convert (const_ptr_type_node, str_cst));
3276 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3277 fold_convert (const_ptr_type_node, module_name_cst));
3278 varpool_node *vnode = varpool_node::get (decl);
3279 int has_dynamic_init = 0;
3280 /* FIXME: Enable initialization order fiasco detection in LTO mode once
3281 proper fix for PR 79061 will be applied. */
3282 if (!in_lto_p)
3283 has_dynamic_init = vnode ? vnode->dynamically_initialized : 0;
3284 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3285 build_int_cst (uptr, has_dynamic_init));
3286 tree locptr = NULL_TREE;
3287 location_t loc = DECL_SOURCE_LOCATION (decl);
3288 expanded_location xloc = expand_location (loc);
3289 if (xloc.file != NULL)
3291 static int lasanloccnt = 0;
3292 char buf[25];
3293 ASM_GENERATE_INTERNAL_LABEL (buf, "LASANLOC", ++lasanloccnt);
3294 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
3295 ubsan_get_source_location_type ());
3296 TREE_STATIC (var) = 1;
3297 TREE_PUBLIC (var) = 0;
3298 DECL_ARTIFICIAL (var) = 1;
3299 DECL_IGNORED_P (var) = 1;
3300 pretty_printer filename_pp;
3301 pp_string (&filename_pp, xloc.file);
3302 tree str = asan_pp_string (&filename_pp);
3303 tree ctor = build_constructor_va (TREE_TYPE (var), 3,
3304 NULL_TREE, str, NULL_TREE,
3305 build_int_cst (unsigned_type_node,
3306 xloc.line), NULL_TREE,
3307 build_int_cst (unsigned_type_node,
3308 xloc.column));
3309 TREE_CONSTANT (ctor) = 1;
3310 TREE_STATIC (ctor) = 1;
3311 DECL_INITIAL (var) = ctor;
3312 varpool_node::finalize_decl (var);
3313 locptr = fold_convert (uptr, build_fold_addr_expr (var));
3315 else
3316 locptr = build_int_cst (uptr, 0);
3317 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr);
3318 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, odr_indicator_ptr);
3319 init = build_constructor (type, vinner);
3320 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
3323 /* Initialize sanitizer.def builtins if the FE hasn't initialized them. */
3324 void
3325 initialize_sanitizer_builtins (void)
3327 tree decl;
3329 if (builtin_decl_implicit_p (BUILT_IN_ASAN_INIT))
3330 return;
3332 tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE);
3333 tree BT_FN_VOID_PTR
3334 = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
3335 tree BT_FN_VOID_CONST_PTR
3336 = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
3337 tree BT_FN_VOID_PTR_PTR
3338 = build_function_type_list (void_type_node, ptr_type_node,
3339 ptr_type_node, NULL_TREE);
3340 tree BT_FN_VOID_PTR_PTR_PTR
3341 = build_function_type_list (void_type_node, ptr_type_node,
3342 ptr_type_node, ptr_type_node, NULL_TREE);
3343 tree BT_FN_VOID_PTR_PTRMODE
3344 = build_function_type_list (void_type_node, ptr_type_node,
3345 pointer_sized_int_node, NULL_TREE);
3346 tree BT_FN_VOID_INT
3347 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
3348 tree BT_FN_SIZE_CONST_PTR_INT
3349 = build_function_type_list (size_type_node, const_ptr_type_node,
3350 integer_type_node, NULL_TREE);
3352 tree BT_FN_VOID_UINT8_UINT8
3353 = build_function_type_list (void_type_node, unsigned_char_type_node,
3354 unsigned_char_type_node, NULL_TREE);
3355 tree BT_FN_VOID_UINT16_UINT16
3356 = build_function_type_list (void_type_node, uint16_type_node,
3357 uint16_type_node, NULL_TREE);
3358 tree BT_FN_VOID_UINT32_UINT32
3359 = build_function_type_list (void_type_node, uint32_type_node,
3360 uint32_type_node, NULL_TREE);
3361 tree BT_FN_VOID_UINT64_UINT64
3362 = build_function_type_list (void_type_node, uint64_type_node,
3363 uint64_type_node, NULL_TREE);
3364 tree BT_FN_VOID_FLOAT_FLOAT
3365 = build_function_type_list (void_type_node, float_type_node,
3366 float_type_node, NULL_TREE);
3367 tree BT_FN_VOID_DOUBLE_DOUBLE
3368 = build_function_type_list (void_type_node, double_type_node,
3369 double_type_node, NULL_TREE);
3370 tree BT_FN_VOID_UINT64_PTR
3371 = build_function_type_list (void_type_node, uint64_type_node,
3372 ptr_type_node, NULL_TREE);
3374 tree BT_FN_PTR_CONST_PTR_UINT8
3375 = build_function_type_list (ptr_type_node, const_ptr_type_node,
3376 unsigned_char_type_node, NULL_TREE);
3377 tree BT_FN_VOID_PTR_UINT8_PTRMODE
3378 = build_function_type_list (void_type_node, ptr_type_node,
3379 unsigned_char_type_node,
3380 pointer_sized_int_node, NULL_TREE);
3382 tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
3383 tree BT_FN_IX_CONST_VPTR_INT[5];
3384 tree BT_FN_IX_VPTR_IX_INT[5];
3385 tree BT_FN_VOID_VPTR_IX_INT[5];
3386 tree vptr
3387 = build_pointer_type (build_qualified_type (void_type_node,
3388 TYPE_QUAL_VOLATILE));
3389 tree cvptr
3390 = build_pointer_type (build_qualified_type (void_type_node,
3391 TYPE_QUAL_VOLATILE
3392 |TYPE_QUAL_CONST));
3393 tree boolt
3394 = lang_hooks.types.type_for_size (BOOL_TYPE_SIZE, 1);
3395 int i;
3396 for (i = 0; i < 5; i++)
3398 tree ix = build_nonstandard_integer_type (BITS_PER_UNIT * (1 << i), 1);
3399 BT_FN_BOOL_VPTR_PTR_IX_INT_INT[i]
3400 = build_function_type_list (boolt, vptr, ptr_type_node, ix,
3401 integer_type_node, integer_type_node,
3402 NULL_TREE);
3403 BT_FN_IX_CONST_VPTR_INT[i]
3404 = build_function_type_list (ix, cvptr, integer_type_node, NULL_TREE);
3405 BT_FN_IX_VPTR_IX_INT[i]
3406 = build_function_type_list (ix, vptr, ix, integer_type_node,
3407 NULL_TREE);
3408 BT_FN_VOID_VPTR_IX_INT[i]
3409 = build_function_type_list (void_type_node, vptr, ix,
3410 integer_type_node, NULL_TREE);
3412 #define BT_FN_BOOL_VPTR_PTR_I1_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[0]
3413 #define BT_FN_I1_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[0]
3414 #define BT_FN_I1_VPTR_I1_INT BT_FN_IX_VPTR_IX_INT[0]
3415 #define BT_FN_VOID_VPTR_I1_INT BT_FN_VOID_VPTR_IX_INT[0]
3416 #define BT_FN_BOOL_VPTR_PTR_I2_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[1]
3417 #define BT_FN_I2_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[1]
3418 #define BT_FN_I2_VPTR_I2_INT BT_FN_IX_VPTR_IX_INT[1]
3419 #define BT_FN_VOID_VPTR_I2_INT BT_FN_VOID_VPTR_IX_INT[1]
3420 #define BT_FN_BOOL_VPTR_PTR_I4_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[2]
3421 #define BT_FN_I4_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[2]
3422 #define BT_FN_I4_VPTR_I4_INT BT_FN_IX_VPTR_IX_INT[2]
3423 #define BT_FN_VOID_VPTR_I4_INT BT_FN_VOID_VPTR_IX_INT[2]
3424 #define BT_FN_BOOL_VPTR_PTR_I8_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[3]
3425 #define BT_FN_I8_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[3]
3426 #define BT_FN_I8_VPTR_I8_INT BT_FN_IX_VPTR_IX_INT[3]
3427 #define BT_FN_VOID_VPTR_I8_INT BT_FN_VOID_VPTR_IX_INT[3]
3428 #define BT_FN_BOOL_VPTR_PTR_I16_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[4]
3429 #define BT_FN_I16_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[4]
3430 #define BT_FN_I16_VPTR_I16_INT BT_FN_IX_VPTR_IX_INT[4]
3431 #define BT_FN_VOID_VPTR_I16_INT BT_FN_VOID_VPTR_IX_INT[4]
3432 #undef ATTR_NOTHROW_LIST
3433 #define ATTR_NOTHROW_LIST ECF_NOTHROW
3434 #undef ATTR_NOTHROW_LEAF_LIST
3435 #define ATTR_NOTHROW_LEAF_LIST ECF_NOTHROW | ECF_LEAF
3436 #undef ATTR_TMPURE_NOTHROW_LEAF_LIST
3437 #define ATTR_TMPURE_NOTHROW_LEAF_LIST ECF_TM_PURE | ATTR_NOTHROW_LEAF_LIST
3438 #undef ATTR_NORETURN_NOTHROW_LEAF_LIST
3439 #define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
3440 #undef ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
3441 #define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST \
3442 ECF_CONST | ATTR_NORETURN_NOTHROW_LEAF_LIST
3443 #undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
3444 #define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
3445 ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
3446 #undef ATTR_COLD_NOTHROW_LEAF_LIST
3447 #define ATTR_COLD_NOTHROW_LEAF_LIST \
3448 /* ECF_COLD missing */ ATTR_NOTHROW_LEAF_LIST
3449 #undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
3450 #define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
3451 /* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
3452 #undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
3453 #define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
3454 /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
3455 #undef ATTR_PURE_NOTHROW_LEAF_LIST
3456 #define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
3457 #undef DEF_BUILTIN_STUB
3458 #define DEF_BUILTIN_STUB(ENUM, NAME)
3459 #undef DEF_SANITIZER_BUILTIN_1
3460 #define DEF_SANITIZER_BUILTIN_1(ENUM, NAME, TYPE, ATTRS) \
3461 do { \
3462 decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM, \
3463 BUILT_IN_NORMAL, NAME, NULL_TREE); \
3464 set_call_expr_flags (decl, ATTRS); \
3465 set_builtin_decl (ENUM, decl, true); \
3466 } while (0)
3467 #undef DEF_SANITIZER_BUILTIN
3468 #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
3469 DEF_SANITIZER_BUILTIN_1 (ENUM, NAME, TYPE, ATTRS);
3471 #include "sanitizer.def"
3473 /* -fsanitize=object-size uses __builtin_dynamic_object_size and
3474 __builtin_object_size, but they might not be available for e.g. Fortran at
3475 this point. We use DEF_SANITIZER_BUILTIN here only as a convenience
3476 macro. */
3477 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
3479 if (!builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
3480 DEF_SANITIZER_BUILTIN_1 (BUILT_IN_OBJECT_SIZE, "object_size",
3481 BT_FN_SIZE_CONST_PTR_INT,
3482 ATTR_PURE_NOTHROW_LEAF_LIST);
3483 if (!builtin_decl_implicit_p (BUILT_IN_DYNAMIC_OBJECT_SIZE))
3484 DEF_SANITIZER_BUILTIN_1 (BUILT_IN_DYNAMIC_OBJECT_SIZE,
3485 "dynamic_object_size",
3486 BT_FN_SIZE_CONST_PTR_INT,
3487 ATTR_PURE_NOTHROW_LEAF_LIST);
3490 #undef DEF_SANITIZER_BUILTIN_1
3491 #undef DEF_SANITIZER_BUILTIN
3492 #undef DEF_BUILTIN_STUB
3495 /* Called via htab_traverse. Count number of emitted
3496 STRING_CSTs in the constant hash table. */
3499 count_string_csts (constant_descriptor_tree **slot,
3500 unsigned HOST_WIDE_INT *data)
3502 struct constant_descriptor_tree *desc = *slot;
3503 if (TREE_CODE (desc->value) == STRING_CST
3504 && TREE_ASM_WRITTEN (desc->value)
3505 && asan_protect_global (desc->value))
3506 ++*data;
3507 return 1;
3510 /* Helper structure to pass two parameters to
3511 add_string_csts. */
3513 struct asan_add_string_csts_data
3515 tree type;
3516 vec<constructor_elt, va_gc> *v;
3519 /* Called via hash_table::traverse. Call asan_add_global
3520 on emitted STRING_CSTs from the constant hash table. */
3523 add_string_csts (constant_descriptor_tree **slot,
3524 asan_add_string_csts_data *aascd)
3526 struct constant_descriptor_tree *desc = *slot;
3527 if (TREE_CODE (desc->value) == STRING_CST
3528 && TREE_ASM_WRITTEN (desc->value)
3529 && asan_protect_global (desc->value))
3531 asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)),
3532 aascd->type, aascd->v);
3534 return 1;
3537 /* Needs to be GTY(()), because cgraph_build_static_cdtor may
3538 invoke ggc_collect. */
3539 static GTY(()) tree asan_ctor_statements;
3541 /* Module-level instrumentation.
3542 - Insert __asan_init_vN() into the list of CTORs.
3543 - TODO: insert redzones around globals.
3546 void
3547 asan_finish_file (void)
3549 varpool_node *vnode;
3550 unsigned HOST_WIDE_INT gcount = 0;
3552 if (shadow_ptr_types[0] == NULL_TREE)
3553 asan_init_shadow_ptr_types ();
3554 /* Avoid instrumenting code in the asan ctors/dtors.
3555 We don't need to insert padding after the description strings,
3556 nor after .LASAN* array. */
3557 flag_sanitize &= ~SANITIZE_ADDRESS;
3559 /* For user-space we want asan constructors to run first.
3560 Linux kernel does not support priorities other than default, and the only
3561 other user of constructors is coverage. So we run with the default
3562 priority. */
3563 int priority = flag_sanitize & SANITIZE_USER_ADDRESS
3564 ? MAX_RESERVED_INIT_PRIORITY - 1 : DEFAULT_INIT_PRIORITY;
3566 if (flag_sanitize & SANITIZE_USER_ADDRESS)
3568 tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
3569 append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
3570 fn = builtin_decl_implicit (BUILT_IN_ASAN_VERSION_MISMATCH_CHECK);
3571 append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
3573 FOR_EACH_DEFINED_VARIABLE (vnode)
3574 if (TREE_ASM_WRITTEN (vnode->decl)
3575 && asan_protect_global (vnode->decl))
3576 ++gcount;
3577 hash_table<tree_descriptor_hasher> *const_desc_htab = constant_pool_htab ();
3578 const_desc_htab->traverse<unsigned HOST_WIDE_INT *, count_string_csts>
3579 (&gcount);
3580 if (gcount)
3582 tree type = asan_global_struct (), var, ctor;
3583 tree dtor_statements = NULL_TREE;
3584 vec<constructor_elt, va_gc> *v;
3585 char buf[20];
3587 type = build_array_type_nelts (type, gcount);
3588 ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", 0);
3589 var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
3590 type);
3591 TREE_STATIC (var) = 1;
3592 TREE_PUBLIC (var) = 0;
3593 DECL_ARTIFICIAL (var) = 1;
3594 DECL_IGNORED_P (var) = 1;
3595 vec_alloc (v, gcount);
3596 FOR_EACH_DEFINED_VARIABLE (vnode)
3597 if (TREE_ASM_WRITTEN (vnode->decl)
3598 && asan_protect_global (vnode->decl))
3599 asan_add_global (vnode->decl, TREE_TYPE (type), v);
3600 struct asan_add_string_csts_data aascd;
3601 aascd.type = TREE_TYPE (type);
3602 aascd.v = v;
3603 const_desc_htab->traverse<asan_add_string_csts_data *, add_string_csts>
3604 (&aascd);
3605 ctor = build_constructor (type, v);
3606 TREE_CONSTANT (ctor) = 1;
3607 TREE_STATIC (ctor) = 1;
3608 DECL_INITIAL (var) = ctor;
3609 SET_DECL_ALIGN (var, MAX (DECL_ALIGN (var),
3610 ASAN_SHADOW_GRANULARITY * BITS_PER_UNIT));
3612 varpool_node::finalize_decl (var);
3614 tree fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
3615 tree gcount_tree = build_int_cst (pointer_sized_int_node, gcount);
3616 append_to_statement_list (build_call_expr (fn, 2,
3617 build_fold_addr_expr (var),
3618 gcount_tree),
3619 &asan_ctor_statements);
3621 fn = builtin_decl_implicit (BUILT_IN_ASAN_UNREGISTER_GLOBALS);
3622 append_to_statement_list (build_call_expr (fn, 2,
3623 build_fold_addr_expr (var),
3624 gcount_tree),
3625 &dtor_statements);
3626 cgraph_build_static_cdtor ('D', dtor_statements, priority);
3628 if (asan_ctor_statements)
3629 cgraph_build_static_cdtor ('I', asan_ctor_statements, priority);
3630 flag_sanitize |= SANITIZE_ADDRESS;
3633 /* Poison or unpoison (depending on IS_CLOBBER variable) shadow memory based
3634 on SHADOW address. Newly added statements will be added to ITER with
3635 given location LOC. We mark SIZE bytes in shadow memory, where
3636 LAST_CHUNK_SIZE is greater than zero in situation where we are at the
3637 end of a variable. */
3639 static void
3640 asan_store_shadow_bytes (gimple_stmt_iterator *iter, location_t loc,
3641 tree shadow,
3642 unsigned HOST_WIDE_INT base_addr_offset,
3643 bool is_clobber, unsigned size,
3644 unsigned last_chunk_size)
3646 tree shadow_ptr_type;
3648 switch (size)
3650 case 1:
3651 shadow_ptr_type = shadow_ptr_types[0];
3652 break;
3653 case 2:
3654 shadow_ptr_type = shadow_ptr_types[1];
3655 break;
3656 case 4:
3657 shadow_ptr_type = shadow_ptr_types[2];
3658 break;
3659 default:
3660 gcc_unreachable ();
3663 unsigned char c = (char) is_clobber ? ASAN_STACK_MAGIC_USE_AFTER_SCOPE : 0;
3664 unsigned HOST_WIDE_INT val = 0;
3665 unsigned last_pos = size;
3666 if (last_chunk_size && !is_clobber)
3667 last_pos = BYTES_BIG_ENDIAN ? 0 : size - 1;
3668 for (unsigned i = 0; i < size; ++i)
3670 unsigned char shadow_c = c;
3671 if (i == last_pos)
3672 shadow_c = last_chunk_size;
3673 val |= (unsigned HOST_WIDE_INT) shadow_c << (BITS_PER_UNIT * i);
3676 /* Handle last chunk in unpoisoning. */
3677 tree magic = build_int_cst (TREE_TYPE (shadow_ptr_type), val);
3679 tree dest = build2 (MEM_REF, TREE_TYPE (shadow_ptr_type), shadow,
3680 build_int_cst (shadow_ptr_type, base_addr_offset));
3682 gimple *g = gimple_build_assign (dest, magic);
3683 gimple_set_location (g, loc);
3684 gsi_insert_after (iter, g, GSI_NEW_STMT);
3687 /* Expand the ASAN_MARK builtins. */
3689 bool
3690 asan_expand_mark_ifn (gimple_stmt_iterator *iter)
3692 gimple *g = gsi_stmt (*iter);
3693 location_t loc = gimple_location (g);
3694 HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (g, 0));
3695 bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
3697 tree base = gimple_call_arg (g, 1);
3698 gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
3699 tree decl = TREE_OPERAND (base, 0);
3701 /* For a nested function, we can have: ASAN_MARK (2, &FRAME.2.fp_input, 4) */
3702 if (TREE_CODE (decl) == COMPONENT_REF
3703 && DECL_NONLOCAL_FRAME (TREE_OPERAND (decl, 0)))
3704 decl = TREE_OPERAND (decl, 0);
3706 gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
3708 if (hwasan_sanitize_p ())
3710 gcc_assert (param_hwasan_instrument_stack);
3711 gimple_seq stmts = NULL;
3712 /* Here we swap ASAN_MARK calls for HWASAN_MARK.
3713 This is because we are using the approach of using ASAN_MARK as a
3714 synonym until here.
3715 That approach means we don't yet have to duplicate all the special
3716 cases for ASAN_MARK and ASAN_POISON with the exact same handling but
3717 called HWASAN_MARK etc.
3719 N.b. __asan_poison_stack_memory (which implements ASAN_MARK for ASAN)
3720 rounds the size up to its shadow memory granularity, while
3721 __hwasan_tag_memory (which implements the same for HWASAN) does not.
3722 Hence we emit HWASAN_MARK with an aligned size unlike ASAN_MARK. */
3723 tree len = gimple_call_arg (g, 2);
3724 tree new_len = gimple_build_round_up (&stmts, loc, size_type_node, len,
3725 HWASAN_TAG_GRANULE_SIZE);
3726 gimple_build (&stmts, loc, CFN_HWASAN_MARK,
3727 void_type_node, gimple_call_arg (g, 0),
3728 base, new_len);
3729 gsi_replace_with_seq (iter, stmts, true);
3730 return false;
3733 if (is_poison)
3735 if (asan_handled_variables == NULL)
3736 asan_handled_variables = new hash_set<tree> (16);
3737 asan_handled_variables->add (decl);
3739 tree len = gimple_call_arg (g, 2);
3741 gcc_assert (tree_fits_shwi_p (len));
3742 unsigned HOST_WIDE_INT size_in_bytes = tree_to_shwi (len);
3743 gcc_assert (size_in_bytes);
3745 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3746 NOP_EXPR, base);
3747 gimple_set_location (g, loc);
3748 gsi_replace (iter, g, false);
3749 tree base_addr = gimple_assign_lhs (g);
3751 /* Generate direct emission if size_in_bytes is small. */
3752 if (size_in_bytes
3753 <= (unsigned)param_use_after_scope_direct_emission_threshold)
3755 const unsigned HOST_WIDE_INT shadow_size
3756 = shadow_mem_size (size_in_bytes);
3757 const unsigned int shadow_align
3758 = (get_pointer_alignment (base) / BITS_PER_UNIT) >> ASAN_SHADOW_SHIFT;
3760 tree shadow = build_shadow_mem_access (iter, loc, base_addr,
3761 shadow_ptr_types[0], true);
3763 for (unsigned HOST_WIDE_INT offset = 0; offset < shadow_size;)
3765 unsigned size = 1;
3766 if (shadow_size - offset >= 4
3767 && (!STRICT_ALIGNMENT || shadow_align >= 4))
3768 size = 4;
3769 else if (shadow_size - offset >= 2
3770 && (!STRICT_ALIGNMENT || shadow_align >= 2))
3771 size = 2;
3773 unsigned HOST_WIDE_INT last_chunk_size = 0;
3774 unsigned HOST_WIDE_INT s = (offset + size) * ASAN_SHADOW_GRANULARITY;
3775 if (s > size_in_bytes)
3776 last_chunk_size = ASAN_SHADOW_GRANULARITY - (s - size_in_bytes);
3778 asan_store_shadow_bytes (iter, loc, shadow, offset, is_poison,
3779 size, last_chunk_size);
3780 offset += size;
3783 else
3785 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3786 NOP_EXPR, len);
3787 gimple_set_location (g, loc);
3788 gsi_insert_before (iter, g, GSI_SAME_STMT);
3789 tree sz_arg = gimple_assign_lhs (g);
3791 tree fun
3792 = builtin_decl_implicit (is_poison ? BUILT_IN_ASAN_POISON_STACK_MEMORY
3793 : BUILT_IN_ASAN_UNPOISON_STACK_MEMORY);
3794 g = gimple_build_call (fun, 2, base_addr, sz_arg);
3795 gimple_set_location (g, loc);
3796 gsi_insert_after (iter, g, GSI_NEW_STMT);
3799 return false;
3802 /* Expand the ASAN_{LOAD,STORE} builtins. */
3804 bool
3805 asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
3807 gcc_assert (!hwasan_sanitize_p ());
3808 gimple *g = gsi_stmt (*iter);
3809 location_t loc = gimple_location (g);
3810 bool recover_p;
3811 if (flag_sanitize & SANITIZE_USER_ADDRESS)
3812 recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
3813 else
3814 recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
3816 HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
3817 gcc_assert (flags < ASAN_CHECK_LAST);
3818 bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
3819 bool is_store = (flags & ASAN_CHECK_STORE) != 0;
3820 bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
3822 tree base = gimple_call_arg (g, 1);
3823 tree len = gimple_call_arg (g, 2);
3824 HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3));
3826 HOST_WIDE_INT size_in_bytes
3827 = is_scalar_access && tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
3829 if (use_calls)
3831 /* Instrument using callbacks. */
3832 gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3833 NOP_EXPR, base);
3834 gimple_set_location (g, loc);
3835 gsi_insert_before (iter, g, GSI_SAME_STMT);
3836 tree base_addr = gimple_assign_lhs (g);
3838 int nargs;
3839 tree fun = check_func (is_store, recover_p, size_in_bytes, &nargs);
3840 if (nargs == 1)
3841 g = gimple_build_call (fun, 1, base_addr);
3842 else
3844 gcc_assert (nargs == 2);
3845 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3846 NOP_EXPR, len);
3847 gimple_set_location (g, loc);
3848 gsi_insert_before (iter, g, GSI_SAME_STMT);
3849 tree sz_arg = gimple_assign_lhs (g);
3850 g = gimple_build_call (fun, nargs, base_addr, sz_arg);
3852 gimple_set_location (g, loc);
3853 gsi_replace (iter, g, false);
3854 return false;
3857 HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
3859 tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
3860 tree shadow_type = TREE_TYPE (shadow_ptr_type);
3862 gimple_stmt_iterator gsi = *iter;
3864 if (!is_non_zero_len)
3866 /* So, the length of the memory area to asan-protect is
3867 non-constant. Let's guard the generated instrumentation code
3868 like:
3870 if (len != 0)
3872 //asan instrumentation code goes here.
3874 // falltrough instructions, starting with *ITER. */
3876 g = gimple_build_cond (NE_EXPR,
3877 len,
3878 build_int_cst (TREE_TYPE (len), 0),
3879 NULL_TREE, NULL_TREE);
3880 gimple_set_location (g, loc);
3882 basic_block then_bb, fallthrough_bb;
3883 insert_if_then_before_iter (as_a <gcond *> (g), iter,
3884 /*then_more_likely_p=*/true,
3885 &then_bb, &fallthrough_bb);
3886 /* Note that fallthrough_bb starts with the statement that was
3887 pointed to by ITER. */
3889 /* The 'then block' of the 'if (len != 0) condition is where
3890 we'll generate the asan instrumentation code now. */
3891 gsi = gsi_last_bb (then_bb);
3894 /* Get an iterator on the point where we can add the condition
3895 statement for the instrumentation. */
3896 basic_block then_bb, else_bb;
3897 gsi = create_cond_insert_point (&gsi, /*before_p*/false,
3898 /*then_more_likely_p=*/false,
3899 /*create_then_fallthru_edge*/recover_p,
3900 &then_bb,
3901 &else_bb);
3903 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3904 NOP_EXPR, base);
3905 gimple_set_location (g, loc);
3906 gsi_insert_before (&gsi, g, GSI_NEW_STMT);
3907 tree base_addr = gimple_assign_lhs (g);
3909 tree t = NULL_TREE;
3910 if (real_size_in_bytes >= 8)
3912 tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
3913 shadow_ptr_type);
3914 t = shadow;
3916 else
3918 /* Slow path for 1, 2 and 4 byte accesses. */
3919 /* Test (shadow != 0)
3920 & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow). */
3921 tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
3922 shadow_ptr_type);
3923 gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
3924 gimple_seq seq = NULL;
3925 gimple_seq_add_stmt (&seq, shadow_test);
3926 /* Aligned (>= 8 bytes) can test just
3927 (real_size_in_bytes - 1 >= shadow), as base_addr & 7 is known
3928 to be 0. */
3929 if (align < 8)
3931 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
3932 base_addr, 7));
3933 gimple_seq_add_stmt (&seq,
3934 build_type_cast (shadow_type,
3935 gimple_seq_last (seq)));
3936 if (real_size_in_bytes > 1)
3937 gimple_seq_add_stmt (&seq,
3938 build_assign (PLUS_EXPR,
3939 gimple_seq_last (seq),
3940 real_size_in_bytes - 1));
3941 t = gimple_assign_lhs (gimple_seq_last_stmt (seq));
3943 else
3944 t = build_int_cst (shadow_type, real_size_in_bytes - 1);
3945 gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, t, shadow));
3946 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
3947 gimple_seq_last (seq)));
3948 t = gimple_assign_lhs (gimple_seq_last (seq));
3949 gimple_seq_set_location (seq, loc);
3950 gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
3952 /* For non-constant, misaligned or otherwise weird access sizes,
3953 check first and last byte. */
3954 if (size_in_bytes == -1)
3956 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3957 MINUS_EXPR, len,
3958 build_int_cst (pointer_sized_int_node, 1));
3959 gimple_set_location (g, loc);
3960 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3961 tree last = gimple_assign_lhs (g);
3962 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3963 PLUS_EXPR, base_addr, last);
3964 gimple_set_location (g, loc);
3965 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3966 tree base_end_addr = gimple_assign_lhs (g);
3968 tree shadow = build_shadow_mem_access (&gsi, loc, base_end_addr,
3969 shadow_ptr_type);
3970 gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
3971 gimple_seq seq = NULL;
3972 gimple_seq_add_stmt (&seq, shadow_test);
3973 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
3974 base_end_addr, 7));
3975 gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
3976 gimple_seq_last (seq)));
3977 gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
3978 gimple_seq_last (seq),
3979 shadow));
3980 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
3981 gimple_seq_last (seq)));
3982 gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
3983 gimple_seq_last (seq)));
3984 t = gimple_assign_lhs (gimple_seq_last (seq));
3985 gimple_seq_set_location (seq, loc);
3986 gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
3990 g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
3991 NULL_TREE, NULL_TREE);
3992 gimple_set_location (g, loc);
3993 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3995 /* Generate call to the run-time library (e.g. __asan_report_load8). */
3996 gsi = gsi_start_bb (then_bb);
3997 int nargs;
3998 tree fun = report_error_func (is_store, recover_p, size_in_bytes, &nargs);
3999 g = gimple_build_call (fun, nargs, base_addr, len);
4000 gimple_set_location (g, loc);
4001 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
4003 gsi_remove (iter, true);
4004 *iter = gsi_start_bb (else_bb);
4006 return true;
4009 /* Create ASAN shadow variable for a VAR_DECL which has been rewritten
4010 into SSA. Already seen VAR_DECLs are stored in SHADOW_VARS_MAPPING. */
4012 static tree
4013 create_asan_shadow_var (tree var_decl,
4014 hash_map<tree, tree> &shadow_vars_mapping)
4016 tree *slot = shadow_vars_mapping.get (var_decl);
4017 if (slot == NULL)
4019 tree shadow_var = copy_node (var_decl);
4021 copy_body_data id;
4022 memset (&id, 0, sizeof (copy_body_data));
4023 id.src_fn = id.dst_fn = current_function_decl;
4024 copy_decl_for_dup_finish (&id, var_decl, shadow_var);
4026 DECL_ARTIFICIAL (shadow_var) = 1;
4027 DECL_IGNORED_P (shadow_var) = 1;
4028 DECL_SEEN_IN_BIND_EXPR_P (shadow_var) = 0;
4029 gimple_add_tmp_var (shadow_var);
4031 shadow_vars_mapping.put (var_decl, shadow_var);
4032 return shadow_var;
4034 else
4035 return *slot;
4038 /* Expand ASAN_POISON ifn. */
4040 bool
4041 asan_expand_poison_ifn (gimple_stmt_iterator *iter,
4042 bool *need_commit_edge_insert,
4043 hash_map<tree, tree> &shadow_vars_mapping)
4045 gimple *g = gsi_stmt (*iter);
4046 tree poisoned_var = gimple_call_lhs (g);
4047 if (!poisoned_var || has_zero_uses (poisoned_var))
4049 gsi_remove (iter, true);
4050 return true;
4053 if (SSA_NAME_VAR (poisoned_var) == NULL_TREE)
4054 SET_SSA_NAME_VAR_OR_IDENTIFIER (poisoned_var,
4055 create_tmp_var (TREE_TYPE (poisoned_var)));
4057 tree shadow_var = create_asan_shadow_var (SSA_NAME_VAR (poisoned_var),
4058 shadow_vars_mapping);
4060 bool recover_p;
4061 if (flag_sanitize & SANITIZE_USER_ADDRESS)
4062 recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
4063 else
4064 recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
4065 tree size = DECL_SIZE_UNIT (shadow_var);
4066 gimple *poison_call
4067 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
4068 build_int_cst (integer_type_node,
4069 ASAN_MARK_POISON),
4070 build_fold_addr_expr (shadow_var), size);
4072 gimple *use;
4073 imm_use_iterator imm_iter;
4074 FOR_EACH_IMM_USE_STMT (use, imm_iter, poisoned_var)
4076 if (is_gimple_debug (use))
4077 continue;
4079 int nargs;
4080 bool store_p = gimple_call_internal_p (use, IFN_ASAN_POISON_USE);
4081 gcall *call;
4082 if (hwasan_sanitize_p ())
4084 tree fun = builtin_decl_implicit (BUILT_IN_HWASAN_TAG_MISMATCH4);
4085 /* NOTE: hwasan has no __hwasan_report_* functions like asan does.
4086 We use __hwasan_tag_mismatch4 with arguments that tell it the
4087 size of access and load to report all tag mismatches.
4089 The arguments to this function are:
4090 Address of invalid access.
4091 Bitfield containing information about the access
4092 (access_info)
4093 Pointer to a frame of registers
4094 (for use in printing the contents of registers in a dump)
4095 Not used yet -- to be used by inline instrumentation.
4096 Size of access.
4098 The access_info bitfield encodes the following pieces of
4099 information:
4100 - Is this a store or load?
4101 access_info & 0x10 => store
4102 - Should the program continue after reporting the error?
4103 access_info & 0x20 => recover
4104 - What size access is this (not used here since we can always
4105 pass the size in the last argument)
4107 if (access_info & 0xf == 0xf)
4108 size is taken from last argument.
4109 else
4110 size == 1 << (access_info & 0xf)
4112 The last argument contains the size of the access iff the
4113 access_info size indicator is 0xf (we always use this argument
4114 rather than storing the size in the access_info bitfield).
4116 See the function definition `__hwasan_tag_mismatch4` in
4117 libsanitizer/hwasan for the full definition.
4119 unsigned access_info = (0x20 * recover_p)
4120 + (0x10 * store_p)
4121 + (0xf);
4122 call = gimple_build_call (fun, 4,
4123 build_fold_addr_expr (shadow_var),
4124 build_int_cst (pointer_sized_int_node,
4125 access_info),
4126 build_int_cst (pointer_sized_int_node, 0),
4127 size);
4129 else
4131 tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size),
4132 &nargs);
4133 call = gimple_build_call (fun, 1,
4134 build_fold_addr_expr (shadow_var));
4136 gimple_set_location (call, gimple_location (use));
4137 gimple *call_to_insert = call;
4139 /* The USE can be a gimple PHI node. If so, insert the call on
4140 all edges leading to the PHI node. */
4141 if (is_a <gphi *> (use))
4143 gphi *phi = dyn_cast<gphi *> (use);
4144 for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
4145 if (gimple_phi_arg_def (phi, i) == poisoned_var)
4147 edge e = gimple_phi_arg_edge (phi, i);
4149 /* Do not insert on an edge we can't split. */
4150 if (e->flags & EDGE_ABNORMAL)
4151 continue;
4153 if (call_to_insert == NULL)
4154 call_to_insert = gimple_copy (call);
4156 gsi_insert_seq_on_edge (e, call_to_insert);
4157 *need_commit_edge_insert = true;
4158 call_to_insert = NULL;
4161 else
4163 gimple_stmt_iterator gsi = gsi_for_stmt (use);
4164 if (store_p)
4165 gsi_replace (&gsi, call, true);
4166 else
4167 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
4171 SSA_NAME_IS_DEFAULT_DEF (poisoned_var) = true;
4172 SSA_NAME_DEF_STMT (poisoned_var) = gimple_build_nop ();
4173 gsi_replace (iter, poison_call, false);
4175 return true;
4178 /* Instrument the current function. */
4180 static unsigned int
4181 asan_instrument (void)
4183 if (hwasan_sanitize_p ())
4185 transform_statements ();
4186 return 0;
4189 if (shadow_ptr_types[0] == NULL_TREE)
4190 asan_init_shadow_ptr_types ();
4191 transform_statements ();
4192 last_alloca_addr = NULL_TREE;
4193 return 0;
4196 static bool
4197 gate_asan (void)
4199 return sanitize_flags_p (SANITIZE_ADDRESS);
4202 namespace {
4204 const pass_data pass_data_asan =
4206 GIMPLE_PASS, /* type */
4207 "asan", /* name */
4208 OPTGROUP_NONE, /* optinfo_flags */
4209 TV_NONE, /* tv_id */
4210 ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
4211 0, /* properties_provided */
4212 0, /* properties_destroyed */
4213 0, /* todo_flags_start */
4214 TODO_update_ssa, /* todo_flags_finish */
4217 class pass_asan : public gimple_opt_pass
4219 public:
4220 pass_asan (gcc::context *ctxt)
4221 : gimple_opt_pass (pass_data_asan, ctxt)
4224 /* opt_pass methods: */
4225 opt_pass * clone () final override { return new pass_asan (m_ctxt); }
4226 bool gate (function *) final override
4228 return gate_asan () || gate_hwasan ();
4230 unsigned int execute (function *) final override
4232 return asan_instrument ();
4235 }; // class pass_asan
4237 } // anon namespace
4239 gimple_opt_pass *
4240 make_pass_asan (gcc::context *ctxt)
4242 return new pass_asan (ctxt);
4245 namespace {
4247 const pass_data pass_data_asan_O0 =
4249 GIMPLE_PASS, /* type */
4250 "asan0", /* name */
4251 OPTGROUP_NONE, /* optinfo_flags */
4252 TV_NONE, /* tv_id */
4253 ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
4254 0, /* properties_provided */
4255 0, /* properties_destroyed */
4256 0, /* todo_flags_start */
4257 TODO_update_ssa, /* todo_flags_finish */
4260 class pass_asan_O0 : public gimple_opt_pass
4262 public:
4263 pass_asan_O0 (gcc::context *ctxt)
4264 : gimple_opt_pass (pass_data_asan_O0, ctxt)
4267 /* opt_pass methods: */
4268 bool gate (function *) final override
4270 return !optimize && (gate_asan () || gate_hwasan ());
4272 unsigned int execute (function *) final override
4274 return asan_instrument ();
4277 }; // class pass_asan_O0
4279 } // anon namespace
4281 gimple_opt_pass *
4282 make_pass_asan_O0 (gcc::context *ctxt)
4284 return new pass_asan_O0 (ctxt);
4287 /* HWASAN */
4289 /* For stack tagging:
4291 Return the offset from the frame base tag that the "next" expanded object
4292 should have. */
4293 uint8_t
4294 hwasan_current_frame_tag ()
4296 return hwasan_frame_tag_offset;
4299 /* For stack tagging:
4301 Return the 'base pointer' for this function. If that base pointer has not
4302 yet been created then we create a register to hold it and record the insns
4303 to initialize the register in `hwasan_frame_base_init_seq` for later
4304 emission. */
4306 hwasan_frame_base ()
4308 if (! hwasan_frame_base_ptr)
4310 start_sequence ();
4311 hwasan_frame_base_ptr
4312 = force_reg (Pmode,
4313 targetm.memtag.insert_random_tag (virtual_stack_vars_rtx,
4314 NULL_RTX));
4315 hwasan_frame_base_init_seq = get_insns ();
4316 end_sequence ();
4319 return hwasan_frame_base_ptr;
4322 /* For stack tagging:
4324 Check whether this RTX is a standard pointer addressing the base of the
4325 stack variables for this frame. Returns true if the RTX is either
4326 virtual_stack_vars_rtx or hwasan_frame_base_ptr. */
4327 bool
4328 stack_vars_base_reg_p (rtx base)
4330 return base == virtual_stack_vars_rtx || base == hwasan_frame_base_ptr;
4333 /* For stack tagging:
4335 Emit frame base initialisation.
4336 If hwasan_frame_base has been used before here then
4337 hwasan_frame_base_init_seq contains the sequence of instructions to
4338 initialize it. This must be put just before the hwasan prologue, so we emit
4339 the insns before parm_birth_insn (which will point to the first instruction
4340 of the hwasan prologue if it exists).
4342 We update `parm_birth_insn` to point to the start of this initialisation
4343 since that represents the end of the initialisation done by
4344 expand_function_{start,end} functions and we want to maintain that. */
4345 void
4346 hwasan_maybe_emit_frame_base_init ()
4348 if (! hwasan_frame_base_init_seq)
4349 return;
4350 emit_insn_before (hwasan_frame_base_init_seq, parm_birth_insn);
4351 parm_birth_insn = hwasan_frame_base_init_seq;
4354 /* Record a compile-time constant size stack variable that HWASAN will need to
4355 tag. This record of the range of a stack variable will be used by
4356 `hwasan_emit_prologue` to emit the RTL at the start of each frame which will
4357 set tags in the shadow memory according to the assigned tag for each object.
4359 The range that the object spans in stack space should be described by the
4360 bounds `untagged_base + nearest_offset` and
4361 `untagged_base + farthest_offset`.
4362 `tagged_base` is the base address which contains the "base frame tag" for
4363 this frame, and from which the value to address this object with will be
4364 calculated.
4366 We record the `untagged_base` since the functions in the hwasan library we
4367 use to tag memory take pointers without a tag. */
4368 void
4369 hwasan_record_stack_var (rtx untagged_base, rtx tagged_base,
4370 poly_int64 nearest_offset, poly_int64 farthest_offset)
4372 hwasan_stack_var cur_var;
4373 cur_var.untagged_base = untagged_base;
4374 cur_var.tagged_base = tagged_base;
4375 cur_var.nearest_offset = nearest_offset;
4376 cur_var.farthest_offset = farthest_offset;
4377 cur_var.tag_offset = hwasan_current_frame_tag ();
4379 hwasan_tagged_stack_vars.safe_push (cur_var);
4382 /* Return the RTX representing the farthest extent of the statically allocated
4383 stack objects for this frame. If hwasan_frame_base_ptr has not been
4384 initialized then we are not storing any static variables on the stack in
4385 this frame. In this case we return NULL_RTX to represent that.
4387 Otherwise simply return virtual_stack_vars_rtx + frame_offset. */
4389 hwasan_get_frame_extent ()
4391 return (hwasan_frame_base_ptr
4392 ? plus_constant (Pmode, virtual_stack_vars_rtx, frame_offset)
4393 : NULL_RTX);
4396 /* For stack tagging:
4398 Increment the frame tag offset modulo the size a tag can represent. */
4399 void
4400 hwasan_increment_frame_tag ()
4402 uint8_t tag_bits = HWASAN_TAG_SIZE;
4403 gcc_assert (HWASAN_TAG_SIZE
4404 <= sizeof (hwasan_frame_tag_offset) * CHAR_BIT);
4405 hwasan_frame_tag_offset = (hwasan_frame_tag_offset + 1) % (1 << tag_bits);
4406 /* The "background tag" of the stack is zero by definition.
4407 This is the tag that objects like parameters passed on the stack and
4408 spilled registers are given. It is handy to avoid this tag for objects
4409 whose tags we decide ourselves, partly to ensure that buffer overruns
4410 can't affect these important variables (e.g. saved link register, saved
4411 stack pointer etc) and partly to make debugging easier (everything with a
4412 tag of zero is space allocated automatically by the compiler).
4414 This is not feasible when using random frame tags (the default
4415 configuration for hwasan) since the tag for the given frame is randomly
4416 chosen at runtime. In order to avoid any tags matching the stack
4417 background we would need to decide tag offsets at runtime instead of
4418 compile time (and pay the resulting performance cost).
4420 When not using random base tags for each frame (i.e. when compiled with
4421 `--param hwasan-random-frame-tag=0`) the base tag for each frame is zero.
4422 This means the tag that each object gets is equal to the
4423 hwasan_frame_tag_offset used in determining it.
4424 When this is the case we *can* ensure no object gets the tag of zero by
4425 simply ensuring no object has the hwasan_frame_tag_offset of zero.
4427 There is the extra complication that we only record the
4428 hwasan_frame_tag_offset here (which is the offset from the tag stored in
4429 the stack pointer). In the kernel, the tag in the stack pointer is 0xff
4430 rather than zero. This does not cause problems since tags of 0xff are
4431 never checked in the kernel. As mentioned at the beginning of this
4432 comment the background tag of the stack is zero by definition, which means
4433 that for the kernel we should skip offsets of both 0 and 1 from the stack
4434 pointer. Avoiding the offset of 0 ensures we use a tag which will be
4435 checked, avoiding the offset of 1 ensures we use a tag that is not the
4436 same as the background. */
4437 if (hwasan_frame_tag_offset == 0 && ! param_hwasan_random_frame_tag)
4438 hwasan_frame_tag_offset += 1;
4439 if (hwasan_frame_tag_offset == 1 && ! param_hwasan_random_frame_tag
4440 && sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS))
4441 hwasan_frame_tag_offset += 1;
4444 /* Clear internal state for the next function.
4445 This function is called before variables on the stack get expanded, in
4446 `init_vars_expansion`. */
4447 void
4448 hwasan_record_frame_init ()
4450 delete asan_used_labels;
4451 asan_used_labels = NULL;
4453 /* If this isn't the case then some stack variable was recorded *before*
4454 hwasan_record_frame_init is called, yet *after* the hwasan prologue for
4455 the previous frame was emitted. Such stack variables would not have
4456 their shadow stack filled in. */
4457 gcc_assert (hwasan_tagged_stack_vars.is_empty ());
4458 hwasan_frame_base_ptr = NULL_RTX;
4459 hwasan_frame_base_init_seq = NULL;
4461 /* When not using a random frame tag we can avoid the background stack
4462 color which gives the user a little better debug output upon a crash.
4463 Meanwhile, when using a random frame tag it will be nice to avoid adding
4464 tags for the first object since that is unnecessary extra work.
4465 Hence set the initial hwasan_frame_tag_offset to be 0 if using a random
4466 frame tag and 1 otherwise.
4468 As described in hwasan_increment_frame_tag, in the kernel the stack
4469 pointer has the tag 0xff. That means that to avoid 0xff and 0 (the tag
4470 which the kernel does not check and the background tag respectively) we
4471 start with a tag offset of 2. */
4472 hwasan_frame_tag_offset = param_hwasan_random_frame_tag
4474 : sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS) ? 2 : 1;
4477 /* For stack tagging:
4478 (Emits HWASAN equivalent of what is emitted by
4479 `asan_emit_stack_protection`).
4481 Emits the extra prologue code to set the shadow stack as required for HWASAN
4482 stack instrumentation.
4484 Uses the vector of recorded stack variables hwasan_tagged_stack_vars. When
4485 this function has completed hwasan_tagged_stack_vars is empty and all
4486 objects it had pointed to are deallocated. */
4487 void
4488 hwasan_emit_prologue ()
4490 /* We need untagged base pointers since libhwasan only accepts untagged
4491 pointers in __hwasan_tag_memory. We need the tagged base pointer to obtain
4492 the base tag for an offset. */
4494 if (hwasan_tagged_stack_vars.is_empty ())
4495 return;
4497 poly_int64 bot = 0, top = 0;
4498 for (hwasan_stack_var &cur : hwasan_tagged_stack_vars)
4500 poly_int64 nearest = cur.nearest_offset;
4501 poly_int64 farthest = cur.farthest_offset;
4503 if (known_ge (nearest, farthest))
4505 top = nearest;
4506 bot = farthest;
4508 else
4510 /* Given how these values are calculated, one must be known greater
4511 than the other. */
4512 gcc_assert (known_le (nearest, farthest));
4513 top = farthest;
4514 bot = nearest;
4516 poly_int64 size = (top - bot);
4518 /* Assert the edge of each variable is aligned to the HWASAN tag granule
4519 size. */
4520 gcc_assert (multiple_p (top, HWASAN_TAG_GRANULE_SIZE));
4521 gcc_assert (multiple_p (bot, HWASAN_TAG_GRANULE_SIZE));
4522 gcc_assert (multiple_p (size, HWASAN_TAG_GRANULE_SIZE));
4524 rtx fn = init_one_libfunc ("__hwasan_tag_memory");
4525 rtx base_tag = targetm.memtag.extract_tag (cur.tagged_base, NULL_RTX);
4526 rtx tag = plus_constant (QImode, base_tag, cur.tag_offset);
4527 tag = hwasan_truncate_to_tag_size (tag, NULL_RTX);
4529 rtx bottom = convert_memory_address (ptr_mode,
4530 plus_constant (Pmode,
4531 cur.untagged_base,
4532 bot));
4533 emit_library_call (fn, LCT_NORMAL, VOIDmode,
4534 bottom, ptr_mode,
4535 tag, QImode,
4536 gen_int_mode (size, ptr_mode), ptr_mode);
4538 /* Clear the stack vars, we've emitted the prologue for them all now. */
4539 hwasan_tagged_stack_vars.truncate (0);
4542 /* For stack tagging:
4544 Return RTL insns to clear the tags between DYNAMIC and VARS pointers
4545 into the stack. These instructions should be emitted at the end of
4546 every function.
4548 If `dynamic` is NULL_RTX then no insns are returned. */
4549 rtx_insn *
4550 hwasan_emit_untag_frame (rtx dynamic, rtx vars)
4552 if (! dynamic)
4553 return NULL;
4555 start_sequence ();
4557 dynamic = convert_memory_address (ptr_mode, dynamic);
4558 vars = convert_memory_address (ptr_mode, vars);
4560 rtx top_rtx;
4561 rtx bot_rtx;
4562 if (FRAME_GROWS_DOWNWARD)
4564 top_rtx = vars;
4565 bot_rtx = dynamic;
4567 else
4569 top_rtx = dynamic;
4570 bot_rtx = vars;
4573 rtx size_rtx = expand_simple_binop (ptr_mode, MINUS, top_rtx, bot_rtx,
4574 NULL_RTX, /* unsignedp = */0,
4575 OPTAB_DIRECT);
4577 rtx fn = init_one_libfunc ("__hwasan_tag_memory");
4578 emit_library_call (fn, LCT_NORMAL, VOIDmode,
4579 bot_rtx, ptr_mode,
4580 HWASAN_STACK_BACKGROUND, QImode,
4581 size_rtx, ptr_mode);
4583 do_pending_stack_adjust ();
4584 rtx_insn *insns = get_insns ();
4585 end_sequence ();
4586 return insns;
4589 /* Needs to be GTY(()), because cgraph_build_static_cdtor may
4590 invoke ggc_collect. */
4591 static GTY(()) tree hwasan_ctor_statements;
4593 /* Insert module initialization into this TU. This initialization calls the
4594 initialization code for libhwasan. */
4595 void
4596 hwasan_finish_file (void)
4598 /* Do not emit constructor initialization for the kernel.
4599 (the kernel has its own initialization already). */
4600 if (flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
4601 return;
4603 /* Avoid instrumenting code in the hwasan constructors/destructors. */
4604 flag_sanitize &= ~SANITIZE_HWADDRESS;
4605 int priority = MAX_RESERVED_INIT_PRIORITY - 1;
4606 tree fn = builtin_decl_implicit (BUILT_IN_HWASAN_INIT);
4607 append_to_statement_list (build_call_expr (fn, 0), &hwasan_ctor_statements);
4608 cgraph_build_static_cdtor ('I', hwasan_ctor_statements, priority);
4609 flag_sanitize |= SANITIZE_HWADDRESS;
4612 /* For stack tagging:
4614 Truncate `tag` to the number of bits that a tag uses (i.e. to
4615 HWASAN_TAG_SIZE). Store the result in `target` if it's convenient. */
4617 hwasan_truncate_to_tag_size (rtx tag, rtx target)
4619 gcc_assert (GET_MODE (tag) == QImode);
4620 if (HWASAN_TAG_SIZE != GET_MODE_PRECISION (QImode))
4622 gcc_assert (GET_MODE_PRECISION (QImode) > HWASAN_TAG_SIZE);
4623 rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << HWASAN_TAG_SIZE) - 1,
4624 QImode);
4625 tag = expand_simple_binop (QImode, AND, tag, mask, target,
4626 /* unsignedp = */1, OPTAB_WIDEN);
4627 gcc_assert (tag);
4629 return tag;
4632 /* Construct a function tree for __hwasan_{load,store}{1,2,4,8,16,_n}.
4633 IS_STORE is either 1 (for a store) or 0 (for a load). */
4634 static combined_fn
4635 hwasan_check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
4636 int *nargs)
4638 static enum built_in_function check[2][2][6]
4639 = { { { BUILT_IN_HWASAN_LOAD1, BUILT_IN_HWASAN_LOAD2,
4640 BUILT_IN_HWASAN_LOAD4, BUILT_IN_HWASAN_LOAD8,
4641 BUILT_IN_HWASAN_LOAD16, BUILT_IN_HWASAN_LOADN },
4642 { BUILT_IN_HWASAN_STORE1, BUILT_IN_HWASAN_STORE2,
4643 BUILT_IN_HWASAN_STORE4, BUILT_IN_HWASAN_STORE8,
4644 BUILT_IN_HWASAN_STORE16, BUILT_IN_HWASAN_STOREN } },
4645 { { BUILT_IN_HWASAN_LOAD1_NOABORT,
4646 BUILT_IN_HWASAN_LOAD2_NOABORT,
4647 BUILT_IN_HWASAN_LOAD4_NOABORT,
4648 BUILT_IN_HWASAN_LOAD8_NOABORT,
4649 BUILT_IN_HWASAN_LOAD16_NOABORT,
4650 BUILT_IN_HWASAN_LOADN_NOABORT },
4651 { BUILT_IN_HWASAN_STORE1_NOABORT,
4652 BUILT_IN_HWASAN_STORE2_NOABORT,
4653 BUILT_IN_HWASAN_STORE4_NOABORT,
4654 BUILT_IN_HWASAN_STORE8_NOABORT,
4655 BUILT_IN_HWASAN_STORE16_NOABORT,
4656 BUILT_IN_HWASAN_STOREN_NOABORT } } };
4657 if (size_in_bytes == -1)
4659 *nargs = 2;
4660 return as_combined_fn (check[recover_p][is_store][5]);
4662 *nargs = 1;
4663 int size_log2 = exact_log2 (size_in_bytes);
4664 gcc_assert (size_log2 >= 0 && size_log2 <= 5);
4665 return as_combined_fn (check[recover_p][is_store][size_log2]);
4668 /* Expand the HWASAN_{LOAD,STORE} builtins. */
4669 bool
4670 hwasan_expand_check_ifn (gimple_stmt_iterator *iter, bool)
4672 gimple *g = gsi_stmt (*iter);
4673 location_t loc = gimple_location (g);
4674 bool recover_p;
4675 if (flag_sanitize & SANITIZE_USER_HWADDRESS)
4676 recover_p = (flag_sanitize_recover & SANITIZE_USER_HWADDRESS) != 0;
4677 else
4678 recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_HWADDRESS) != 0;
4680 HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
4681 gcc_assert (flags < ASAN_CHECK_LAST);
4682 bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
4683 bool is_store = (flags & ASAN_CHECK_STORE) != 0;
4684 bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
4686 tree base = gimple_call_arg (g, 1);
4687 tree len = gimple_call_arg (g, 2);
4689 /* `align` is unused for HWASAN_CHECK, but we pass the argument anyway
4690 since that way the arguments match ASAN_CHECK. */
4691 /* HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3)); */
4693 unsigned HOST_WIDE_INT size_in_bytes
4694 = is_scalar_access ? tree_to_shwi (len) : -1;
4696 gimple_stmt_iterator gsi = *iter;
4698 if (!is_non_zero_len)
4700 /* So, the length of the memory area to hwasan-protect is
4701 non-constant. Let's guard the generated instrumentation code
4702 like:
4704 if (len != 0)
4706 // hwasan instrumentation code goes here.
4708 // falltrough instructions, starting with *ITER. */
4710 g = gimple_build_cond (NE_EXPR,
4711 len,
4712 build_int_cst (TREE_TYPE (len), 0),
4713 NULL_TREE, NULL_TREE);
4714 gimple_set_location (g, loc);
4716 basic_block then_bb, fallthrough_bb;
4717 insert_if_then_before_iter (as_a <gcond *> (g), iter,
4718 /*then_more_likely_p=*/true,
4719 &then_bb, &fallthrough_bb);
4720 /* Note that fallthrough_bb starts with the statement that was
4721 pointed to by ITER. */
4723 /* The 'then block' of the 'if (len != 0) condition is where
4724 we'll generate the hwasan instrumentation code now. */
4725 gsi = gsi_last_bb (then_bb);
4728 gimple_seq stmts = NULL;
4729 tree base_addr = gimple_build (&stmts, loc, NOP_EXPR,
4730 pointer_sized_int_node, base);
4732 int nargs = 0;
4733 combined_fn fn
4734 = hwasan_check_func (is_store, recover_p, size_in_bytes, &nargs);
4735 if (nargs == 1)
4736 gimple_build (&stmts, loc, fn, void_type_node, base_addr);
4737 else
4739 gcc_assert (nargs == 2);
4740 tree sz_arg = gimple_build (&stmts, loc, NOP_EXPR,
4741 pointer_sized_int_node, len);
4742 gimple_build (&stmts, loc, fn, void_type_node, base_addr, sz_arg);
4745 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
4746 gsi_remove (iter, true);
4747 *iter = gsi;
4748 return false;
4751 /* For stack tagging:
4753 Dummy: the HWASAN_MARK internal function should only ever be in the code
4754 after the sanopt pass. */
4755 bool
4756 hwasan_expand_mark_ifn (gimple_stmt_iterator *)
4758 gcc_unreachable ();
4761 bool
4762 gate_hwasan ()
4764 return hwasan_sanitize_p ();
4767 #include "gt-asan.h"