Line data Source code
1 : /* AddressSanitizer, a fast memory error detector.
2 : Copyright (C) 2012-2026 Free Software Foundation, Inc.
3 : Contributed by Kostya Serebryany <kcc@google.com>
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 :
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 "optabs.h"
38 : #include "emit-rtl.h"
39 : #include "cgraph.h"
40 : #include "gimple-pretty-print.h"
41 : #include "alias.h"
42 : #include "fold-const.h"
43 : #include "cfganal.h"
44 : #include "gimplify.h"
45 : #include "gimple-iterator.h"
46 : #include "varasm.h"
47 : #include "stor-layout.h"
48 : #include "tree-iterator.h"
49 : #include "attribs.h"
50 : #include "asan.h"
51 : #include "dojump.h"
52 : #include "explow.h"
53 : #include "expr.h"
54 : #include "output.h"
55 : #include "langhooks.h"
56 : #include "cfgloop.h"
57 : #include "gimple-builder.h"
58 : #include "gimple-fold.h"
59 : #include "ubsan.h"
60 : #include "builtins.h"
61 : #include "fnmatch.h"
62 : #include "tree-inline.h"
63 : #include "tree-ssa.h"
64 : #include "tree-eh.h"
65 : #include "diagnostic-core.h"
66 :
67 : /* AddressSanitizer finds out-of-bounds and use-after-free bugs
68 : with <2x slowdown on average.
69 :
70 : The tool consists of two parts:
71 : instrumentation module (this file) and a run-time library.
72 : The instrumentation module adds a run-time check before every memory insn.
73 : For a 8- or 16- byte load accessing address X:
74 : ShadowAddr = (X >> 3) + Offset
75 : ShadowValue = *(char*)ShadowAddr; // *(short*) for 16-byte access.
76 : if (ShadowValue)
77 : __asan_report_load8(X);
78 : For a load of N bytes (N=1, 2 or 4) from address X:
79 : ShadowAddr = (X >> 3) + Offset
80 : ShadowValue = *(char*)ShadowAddr;
81 : if (ShadowValue)
82 : if ((X & 7) + N - 1 > ShadowValue)
83 : __asan_report_loadN(X);
84 : Stores are instrumented similarly, but using __asan_report_storeN functions.
85 : A call too __asan_init_vN() is inserted to the list of module CTORs.
86 : N is the version number of the AddressSanitizer API. The changes between the
87 : API versions are listed in libsanitizer/asan/asan_interface_internal.h.
88 :
89 : The run-time library redefines malloc (so that redzone are inserted around
90 : the allocated memory) and free (so that reuse of free-ed memory is delayed),
91 : provides __asan_report* and __asan_init_vN functions.
92 :
93 : Read more:
94 : http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
95 :
96 : The current implementation supports detection of out-of-bounds and
97 : use-after-free in the heap, on the stack and for global variables.
98 :
99 : [Protection of stack variables]
100 :
101 : To understand how detection of out-of-bounds and use-after-free works
102 : for stack variables, lets look at this example on x86_64 where the
103 : stack grows downward:
104 :
105 : int
106 : foo ()
107 : {
108 : char a[24] = {0};
109 : int b[2] = {0};
110 :
111 : a[5] = 1;
112 : b[1] = 2;
113 :
114 : return a[5] + b[1];
115 : }
116 :
117 : For this function, the stack protected by asan will be organized as
118 : follows, from the top of the stack to the bottom:
119 :
120 : Slot 1/ [red zone of 32 bytes called 'RIGHT RedZone']
121 :
122 : Slot 2/ [8 bytes of red zone, that adds up to the space of 'a' to make
123 : the next slot be 32 bytes aligned; this one is called Partial
124 : Redzone; this 32 bytes alignment is an asan constraint]
125 :
126 : Slot 3/ [24 bytes for variable 'a']
127 :
128 : Slot 4/ [red zone of 32 bytes called 'Middle RedZone']
129 :
130 : Slot 5/ [24 bytes of Partial Red Zone (similar to slot 2]
131 :
132 : Slot 6/ [8 bytes for variable 'b']
133 :
134 : Slot 7/ [32 bytes of Red Zone at the bottom of the stack, called
135 : 'LEFT RedZone']
136 :
137 : The 32 bytes of LEFT red zone at the bottom of the stack can be
138 : decomposed as such:
139 :
140 : 1/ The first 8 bytes contain a magical asan number that is always
141 : 0x41B58AB3.
142 :
143 : 2/ The following 8 bytes contains a pointer to a string (to be
144 : parsed at runtime by the runtime asan library), which format is
145 : the following:
146 :
147 : "<function-name> <space> <num-of-variables-on-the-stack>
148 : (<32-bytes-aligned-offset-in-bytes-of-variable> <space>
149 : <length-of-var-in-bytes> ){n} "
150 :
151 : where '(...){n}' means the content inside the parenthesis occurs 'n'
152 : times, with 'n' being the number of variables on the stack.
153 :
154 : 3/ The following 8 bytes contain the PC of the current function which
155 : will be used by the run-time library to print an error message.
156 :
157 : 4/ The following 8 bytes are reserved for internal use by the run-time.
158 :
159 : The shadow memory for that stack layout is going to look like this:
160 :
161 : - content of shadow memory 8 bytes for slot 7: 0xF1F1F1F1.
162 : The F1 byte pattern is a magic number called
163 : ASAN_STACK_MAGIC_LEFT and is a way for the runtime to know that
164 : the memory for that shadow byte is part of a the LEFT red zone
165 : intended to seat at the bottom of the variables on the stack.
166 :
167 : - content of shadow memory 8 bytes for slots 6 and 5:
168 : 0xF4F4F400. The F4 byte pattern is a magic number
169 : called ASAN_STACK_MAGIC_PARTIAL. It flags the fact that the
170 : memory region for this shadow byte is a PARTIAL red zone
171 : intended to pad a variable A, so that the slot following
172 : {A,padding} is 32 bytes aligned.
173 :
174 : Note that the fact that the least significant byte of this
175 : shadow memory content is 00 means that 8 bytes of its
176 : corresponding memory (which corresponds to the memory of
177 : variable 'b') is addressable.
178 :
179 : - content of shadow memory 8 bytes for slot 4: 0xF2F2F2F2.
180 : The F2 byte pattern is a magic number called
181 : ASAN_STACK_MAGIC_MIDDLE. It flags the fact that the memory
182 : region for this shadow byte is a MIDDLE red zone intended to
183 : seat between two 32 aligned slots of {variable,padding}.
184 :
185 : - content of shadow memory 8 bytes for slot 3 and 2:
186 : 0xF4000000. This represents is the concatenation of
187 : variable 'a' and the partial red zone following it, like what we
188 : had for variable 'b'. The least significant 3 bytes being 00
189 : means that the 3 bytes of variable 'a' are addressable.
190 :
191 : - content of shadow memory 8 bytes for slot 1: 0xF3F3F3F3.
192 : The F3 byte pattern is a magic number called
193 : ASAN_STACK_MAGIC_RIGHT. It flags the fact that the memory
194 : region for this shadow byte is a RIGHT red zone intended to seat
195 : at the top of the variables of the stack.
196 :
197 : Note that the real variable layout is done in expand_used_vars in
198 : cfgexpand.cc. As far as Address Sanitizer is concerned, it lays out
199 : stack variables as well as the different red zones, emits some
200 : prologue code to populate the shadow memory as to poison (mark as
201 : non-accessible) the regions of the red zones and mark the regions of
202 : stack variables as accessible, and emit some epilogue code to
203 : un-poison (mark as accessible) the regions of red zones right before
204 : the function exits.
205 :
206 : [Protection of global variables]
207 :
208 : The basic idea is to insert a red zone between two global variables
209 : and install a constructor function that calls the asan runtime to do
210 : the populating of the relevant shadow memory regions at load time.
211 :
212 : So the global variables are laid out as to insert a red zone between
213 : them. The size of the red zones is so that each variable starts on a
214 : 32 bytes boundary.
215 :
216 : Then a constructor function is installed so that, for each global
217 : variable, it calls the runtime asan library function
218 : __asan_register_globals_with an instance of this type:
219 :
220 : struct __asan_global
221 : {
222 : // Address of the beginning of the global variable.
223 : const void *__beg;
224 :
225 : // Initial size of the global variable.
226 : uptr __size;
227 :
228 : // Size of the global variable + size of the red zone. This
229 : // size is 32 bytes aligned.
230 : uptr __size_with_redzone;
231 :
232 : // Name of the global variable.
233 : const void *__name;
234 :
235 : // Name of the module where the global variable is declared.
236 : const void *__module_name;
237 :
238 : // 1 if it has dynamic initialization, 0 otherwise.
239 : uptr __has_dynamic_init;
240 :
241 : // A pointer to struct that contains source location, could be NULL.
242 : __asan_global_source_location *__location;
243 : }
244 :
245 : A destructor function that calls the runtime asan library function
246 : _asan_unregister_globals is also installed. */
247 :
248 : static unsigned HOST_WIDE_INT asan_shadow_offset_value;
249 : static bool asan_shadow_offset_computed;
250 : static vec<char *> sanitized_sections;
251 : static tree last_alloca_addr;
252 :
253 : /* Set of variable declarations that are going to be guarded by
254 : use-after-scope sanitizer. */
255 :
256 : hash_set<tree> *asan_handled_variables = NULL;
257 :
258 : hash_set <tree> *asan_used_labels = NULL;
259 :
260 : /* Global variables for HWASAN stack tagging. */
261 : /* hwasan_frame_tag_offset records the offset from the frame base tag that the
262 : next object should have. */
263 : static uint8_t hwasan_frame_tag_offset = 0;
264 : /* hwasan_frame_base_ptr is a pointer with the same address as
265 : `virtual_stack_vars_rtx` for the current frame, and with the frame base tag
266 : stored in it. N.b. this global RTX does not need to be marked GTY, but is
267 : done so anyway. The need is not there since all uses are in just one pass
268 : (cfgexpand) and there are no calls to ggc_collect between the uses. We mark
269 : it GTY(()) anyway to allow the use of the variable later on if needed by
270 : future features. */
271 : static GTY(()) rtx hwasan_frame_base_ptr = NULL_RTX;
272 : /* hwasan_frame_base_init_seq is the sequence of RTL insns that will initialize
273 : the hwasan_frame_base_ptr. When the hwasan_frame_base_ptr is requested, we
274 : generate this sequence but do not emit it. If the sequence was created it
275 : is emitted once the function body has been expanded.
276 :
277 : This delay is because the frame base pointer may be needed anywhere in the
278 : function body, or needed by the expand_used_vars function. Emitting once in
279 : a known place is simpler than requiring the emission of the instructions to
280 : be know where it should go depending on the first place the hwasan frame
281 : base is needed. */
282 : static GTY(()) rtx_insn *hwasan_frame_base_init_seq = NULL;
283 :
284 : /* Structure defining the extent of one object on the stack that HWASAN needs
285 : to tag in the corresponding shadow stack space.
286 :
287 : The range this object spans on the stack is between `untagged_base +
288 : nearest_offset` and `untagged_base + farthest_offset`.
289 : `tagged_base` is an rtx containing the same value as `untagged_base` but
290 : with a random tag stored in the top byte. We record both `untagged_base`
291 : and `tagged_base` so that `hwasan_emit_prologue` can use both without having
292 : to emit RTL into the instruction stream to re-calculate one from the other.
293 : (`hwasan_emit_prologue` needs to use both bases since the
294 : __hwasan_tag_memory call it emits uses an untagged value, and it calculates
295 : the tag to store in shadow memory based on the tag_offset plus the tag in
296 : tagged_base). */
297 : struct hwasan_stack_var
298 : {
299 : rtx untagged_base;
300 : rtx tagged_base;
301 : poly_int64 nearest_offset;
302 : poly_int64 farthest_offset;
303 : uint8_t tag_offset;
304 : };
305 :
306 : /* Variable recording all stack variables that HWASAN needs to tag.
307 : Does not need to be marked as GTY(()) since every use is in the cfgexpand
308 : pass and gcc_collect is not called in the middle of that pass. */
309 : static vec<hwasan_stack_var> hwasan_tagged_stack_vars;
310 :
311 :
312 : /* Sets shadow offset to value in string VAL. */
313 :
314 : bool
315 11 : set_asan_shadow_offset (const char *val)
316 : {
317 11 : char *endp;
318 :
319 11 : errno = 0;
320 : #ifdef HAVE_LONG_LONG
321 11 : asan_shadow_offset_value = strtoull (val, &endp, 0);
322 : #else
323 : asan_shadow_offset_value = strtoul (val, &endp, 0);
324 : #endif
325 11 : if (!(*val != '\0' && *endp == '\0' && errno == 0))
326 : return false;
327 :
328 11 : asan_shadow_offset_computed = true;
329 :
330 11 : return true;
331 : }
332 :
333 : /* Set list of user-defined sections that need to be sanitized. */
334 :
335 : void
336 40 : set_sanitized_sections (const char *sections)
337 : {
338 40 : char *pat;
339 40 : unsigned i;
340 50 : FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
341 10 : free (pat);
342 40 : sanitized_sections.truncate (0);
343 :
344 130 : for (const char *s = sections; *s; )
345 : {
346 : const char *end;
347 220 : for (end = s; *end && *end != ','; ++end);
348 50 : size_t len = end - s;
349 50 : sanitized_sections.safe_push (xstrndup (s, len));
350 50 : s = *end ? end + 1 : end;
351 : }
352 40 : }
353 :
354 : bool
355 105957 : asan_mark_p (gimple *stmt, enum asan_mark_flags flag)
356 : {
357 105957 : return (gimple_call_internal_p (stmt, IFN_ASAN_MARK)
358 105957 : && tree_to_uhwi (gimple_call_arg (stmt, 0)) == flag);
359 : }
360 :
361 : bool
362 21136548 : asan_sanitize_stack_p (void)
363 : {
364 21136548 : return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_stack);
365 : }
366 :
367 : bool
368 1512569 : asan_sanitize_allocas_p (void)
369 : {
370 1512569 : return (asan_sanitize_stack_p () && param_asan_protect_allocas);
371 : }
372 :
373 : bool
374 13727 : asan_instrument_reads (void)
375 : {
376 13727 : return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_reads);
377 : }
378 :
379 : bool
380 12688 : asan_instrument_writes (void)
381 : {
382 12688 : return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_writes);
383 : }
384 :
385 : bool
386 4411 : asan_memintrin (void)
387 : {
388 4411 : return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_memintrin);
389 : }
390 :
391 :
392 : /* Support for --param asan-kernel-mem-intrinsic-prefix=1. */
393 : static GTY(()) rtx asan_memfn_rtls[3];
394 :
395 : rtx
396 42 : asan_memfn_rtl (tree fndecl)
397 : {
398 42 : int i;
399 42 : const char *f, *p;
400 42 : char buf[sizeof ("__hwasan_memmove")];
401 :
402 42 : switch (DECL_FUNCTION_CODE (fndecl))
403 : {
404 : case BUILT_IN_MEMCPY: i = 0; f = "memcpy"; break;
405 14 : case BUILT_IN_MEMSET: i = 1; f = "memset"; break;
406 14 : case BUILT_IN_MEMMOVE: i = 2; f = "memmove"; break;
407 0 : default: gcc_unreachable ();
408 : }
409 42 : if (asan_memfn_rtls[i] == NULL_RTX)
410 : {
411 42 : tree save_name = DECL_NAME (fndecl);
412 42 : tree save_assembler_name = DECL_ASSEMBLER_NAME (fndecl);
413 42 : rtx save_rtl = DECL_RTL (fndecl);
414 42 : if (flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
415 : p = "__hwasan_";
416 : else
417 42 : p = "__asan_";
418 42 : strcpy (buf, p);
419 42 : strcat (buf, f);
420 42 : DECL_NAME (fndecl) = get_identifier (buf);
421 42 : DECL_ASSEMBLER_NAME_RAW (fndecl) = NULL_TREE;
422 42 : SET_DECL_RTL (fndecl, NULL_RTX);
423 42 : asan_memfn_rtls[i] = DECL_RTL (fndecl);
424 42 : DECL_NAME (fndecl) = save_name;
425 42 : DECL_ASSEMBLER_NAME_RAW (fndecl) = save_assembler_name;
426 42 : SET_DECL_RTL (fndecl, save_rtl);
427 : }
428 42 : return asan_memfn_rtls[i];
429 : }
430 :
431 :
432 : /* Checks whether section SEC should be sanitized. */
433 :
434 : static bool
435 270 : section_sanitized_p (const char *sec)
436 : {
437 270 : char *pat;
438 270 : unsigned i;
439 420 : FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
440 330 : if (fnmatch (pat, sec, FNM_PERIOD) == 0)
441 : return true;
442 : return false;
443 : }
444 :
445 : /* Returns Asan shadow offset. */
446 :
447 : static unsigned HOST_WIDE_INT
448 23689 : asan_shadow_offset ()
449 : {
450 23689 : if (!asan_shadow_offset_computed)
451 : {
452 1747 : asan_shadow_offset_computed = true;
453 1747 : asan_shadow_offset_value = targetm.asan_shadow_offset ();
454 : }
455 23689 : return asan_shadow_offset_value;
456 : }
457 :
458 : static bool
459 30102 : asan_dynamic_shadow_offset_p ()
460 : {
461 30102 : return (asan_shadow_offset_value == 0)
462 30102 : && targetm.asan_dynamic_shadow_offset_p ();
463 : }
464 :
465 : /* Returns Asan shadow offset has been set. */
466 : bool
467 0 : asan_shadow_offset_set_p ()
468 : {
469 0 : return asan_shadow_offset_computed;
470 : }
471 :
472 : alias_set_type asan_shadow_set = -1;
473 :
474 : /* Pointer types to 1, 2 or 4 byte integers in shadow memory. A separate
475 : alias set is used for all shadow memory accesses. */
476 : static GTY(()) tree shadow_ptr_types[3];
477 :
478 : /* Decl for __asan_option_detect_stack_use_after_return. */
479 : static GTY(()) tree asan_detect_stack_use_after_return;
480 :
481 : static GTY (()) tree asan_shadow_memory_dynamic_address;
482 :
483 : /* Local copy for the asan_shadow_memory_dynamic_address within the
484 : function. */
485 : static GTY (()) tree asan_local_shadow_memory_dynamic_address;
486 :
487 : static tree
488 0 : get_asan_shadow_memory_dynamic_address_decl ()
489 : {
490 0 : if (asan_shadow_memory_dynamic_address == NULL_TREE)
491 : {
492 0 : tree id, decl;
493 0 : id = get_identifier ("__asan_shadow_memory_dynamic_address");
494 0 : decl
495 0 : = build_decl (BUILTINS_LOCATION, VAR_DECL, id, pointer_sized_int_node);
496 0 : SET_DECL_ASSEMBLER_NAME (decl, id);
497 0 : TREE_ADDRESSABLE (decl) = 1;
498 0 : DECL_ARTIFICIAL (decl) = 1;
499 0 : DECL_IGNORED_P (decl) = 1;
500 0 : DECL_EXTERNAL (decl) = 1;
501 0 : TREE_STATIC (decl) = 1;
502 0 : TREE_PUBLIC (decl) = 1;
503 0 : TREE_USED (decl) = 1;
504 0 : asan_shadow_memory_dynamic_address = decl;
505 : }
506 :
507 0 : return asan_shadow_memory_dynamic_address;
508 : }
509 :
510 : void
511 6413 : asan_maybe_insert_dynamic_shadow_at_function_entry (function *fun)
512 : {
513 6413 : asan_local_shadow_memory_dynamic_address = NULL_TREE;
514 6413 : if (!asan_dynamic_shadow_offset_p ())
515 : return;
516 :
517 0 : gimple *g;
518 :
519 0 : tree lhs = create_tmp_var (pointer_sized_int_node,
520 : "__local_asan_shadow_memory_dynamic_address");
521 :
522 0 : g = gimple_build_assign (lhs, get_asan_shadow_memory_dynamic_address_decl ());
523 0 : gimple_set_location (g, fun->function_start_locus);
524 0 : edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
525 0 : gsi_insert_on_edge_immediate (e, g);
526 :
527 0 : asan_local_shadow_memory_dynamic_address = lhs;
528 : }
529 :
530 : /* Hashtable support for memory references used by gimple
531 : statements. */
532 :
533 : /* This type represents a reference to a memory region. */
534 : struct asan_mem_ref
535 : {
536 : /* The expression of the beginning of the memory region. */
537 : tree start;
538 :
539 : /* The size of the access. */
540 : HOST_WIDE_INT access_size;
541 : };
542 :
543 : object_allocator <asan_mem_ref> asan_mem_ref_pool ("asan_mem_ref");
544 :
545 : /* Initializes an instance of asan_mem_ref. */
546 :
547 : static void
548 159468 : asan_mem_ref_init (asan_mem_ref *ref, tree start, HOST_WIDE_INT access_size)
549 : {
550 159535 : ref->start = start;
551 159535 : ref->access_size = access_size;
552 0 : }
553 :
554 : /* Allocates memory for an instance of asan_mem_ref into the memory
555 : pool returned by asan_mem_ref_get_alloc_pool and initialize it.
556 : START is the address of (or the expression pointing to) the
557 : beginning of memory reference. ACCESS_SIZE is the size of the
558 : access to the referenced memory. */
559 :
560 : static asan_mem_ref*
561 37466 : asan_mem_ref_new (tree start, HOST_WIDE_INT access_size)
562 : {
563 0 : asan_mem_ref *ref = asan_mem_ref_pool.allocate ();
564 :
565 37466 : asan_mem_ref_init (ref, start, access_size);
566 37466 : return ref;
567 : }
568 :
569 : /* This builds and returns a pointer to the end of the memory region
570 : that starts at START and of length LEN. */
571 :
572 : tree
573 0 : asan_mem_ref_get_end (tree start, tree len)
574 : {
575 0 : if (len == NULL_TREE || integer_zerop (len))
576 : return start;
577 :
578 0 : if (!ptrofftype_p (len))
579 0 : len = convert_to_ptrofftype (len);
580 :
581 0 : return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (start), start, len);
582 : }
583 :
584 : /* Return a tree expression that represents the end of the referenced
585 : memory region. Beware that this function can actually build a new
586 : tree expression. */
587 :
588 : tree
589 0 : asan_mem_ref_get_end (const asan_mem_ref *ref, tree len)
590 : {
591 0 : return asan_mem_ref_get_end (ref->start, len);
592 : }
593 :
594 : struct asan_mem_ref_hasher : nofree_ptr_hash <asan_mem_ref>
595 : {
596 : static inline hashval_t hash (const asan_mem_ref *);
597 : static inline bool equal (const asan_mem_ref *, const asan_mem_ref *);
598 : };
599 :
600 : /* Hash a memory reference. */
601 :
602 : inline hashval_t
603 253877 : asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
604 : {
605 253877 : return iterative_hash_expr (mem_ref->start, 0);
606 : }
607 :
608 : /* Compare two memory references. We accept the length of either
609 : memory references to be NULL_TREE. */
610 :
611 : inline bool
612 192559 : asan_mem_ref_hasher::equal (const asan_mem_ref *m1,
613 : const asan_mem_ref *m2)
614 : {
615 192559 : return operand_equal_p (m1->start, m2->start, 0);
616 : }
617 :
618 : static hash_table<asan_mem_ref_hasher> *asan_mem_ref_ht;
619 :
620 : /* Returns a reference to the hash table containing memory references.
621 : This function ensures that the hash table is created. Note that
622 : this hash table is updated by the function
623 : update_mem_ref_hash_table. */
624 :
625 : static hash_table<asan_mem_ref_hasher> *
626 83054 : get_mem_ref_hash_table ()
627 : {
628 83054 : if (!asan_mem_ref_ht)
629 3526 : asan_mem_ref_ht = new hash_table<asan_mem_ref_hasher> (10);
630 :
631 83054 : return asan_mem_ref_ht;
632 : }
633 :
634 : /* Clear all entries from the memory references hash table. */
635 :
636 : static void
637 37327 : empty_mem_ref_hash_table ()
638 : {
639 37327 : if (asan_mem_ref_ht)
640 20739 : asan_mem_ref_ht->empty ();
641 37327 : }
642 :
643 : /* Free the memory references hash table. */
644 :
645 : static void
646 6594 : free_mem_ref_resources ()
647 : {
648 6594 : delete asan_mem_ref_ht;
649 6594 : asan_mem_ref_ht = NULL;
650 :
651 6594 : asan_mem_ref_pool.release ();
652 6594 : }
653 :
654 : /* Return true iff the memory reference REF has been instrumented. */
655 :
656 : static bool
657 45576 : has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
658 : {
659 45576 : asan_mem_ref r;
660 45576 : asan_mem_ref_init (&r, ref, access_size);
661 :
662 45576 : asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r);
663 45576 : return saved_ref && saved_ref->access_size >= access_size;
664 : }
665 :
666 : /* Return true iff the memory reference REF has been instrumented. */
667 :
668 : static bool
669 26682 : has_mem_ref_been_instrumented (const asan_mem_ref *ref)
670 : {
671 0 : return has_mem_ref_been_instrumented (ref->start, ref->access_size);
672 : }
673 :
674 : /* Return true iff access to memory region starting at REF and of
675 : length LEN has been instrumented. */
676 :
677 : static bool
678 963 : has_mem_ref_been_instrumented (const asan_mem_ref *ref, tree len)
679 : {
680 963 : HOST_WIDE_INT size_in_bytes
681 963 : = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
682 :
683 251 : return size_in_bytes != -1
684 251 : && has_mem_ref_been_instrumented (ref->start, size_in_bytes);
685 : }
686 :
687 : /* Set REF to the memory reference present in a gimple assignment
688 : ASSIGNMENT. Return true upon successful completion, false
689 : otherwise. */
690 :
691 : static bool
692 30138 : get_mem_ref_of_assignment (const gassign *assignment,
693 : asan_mem_ref *ref,
694 : bool *ref_is_store)
695 : {
696 30138 : gcc_assert (gimple_assign_single_p (assignment));
697 :
698 30138 : if (gimple_store_p (assignment)
699 30138 : && !gimple_clobber_p (assignment))
700 : {
701 13052 : ref->start = gimple_assign_lhs (assignment);
702 13052 : *ref_is_store = true;
703 : }
704 17086 : else if (gimple_assign_load_p (assignment))
705 : {
706 13563 : ref->start = gimple_assign_rhs1 (assignment);
707 13563 : *ref_is_store = false;
708 : }
709 : else
710 : return false;
711 :
712 26615 : ref->access_size = int_size_in_bytes (TREE_TYPE (ref->start));
713 26615 : return true;
714 : }
715 :
716 : /* Return address of last allocated dynamic alloca. */
717 :
718 : static tree
719 400 : get_last_alloca_addr ()
720 : {
721 400 : if (last_alloca_addr)
722 : return last_alloca_addr;
723 :
724 187 : last_alloca_addr = create_tmp_reg (ptr_type_node, "last_alloca_addr");
725 187 : gassign *g = gimple_build_assign (last_alloca_addr, null_pointer_node);
726 187 : edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
727 187 : gsi_insert_on_edge_immediate (e, g);
728 187 : return last_alloca_addr;
729 : }
730 :
731 : /* Insert __asan_allocas_unpoison (top, bottom) call before
732 : __builtin_stack_restore (new_sp) call.
733 : The pseudocode of this routine should look like this:
734 : top = last_alloca_addr;
735 : bot = new_sp;
736 : __asan_allocas_unpoison (top, bot);
737 : last_alloca_addr = new_sp;
738 : __builtin_stack_restore (new_sp);
739 : In general, we can't use new_sp as bot parameter because on some
740 : architectures SP has non zero offset from dynamic stack area. Moreover, on
741 : some architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each
742 : particular function only after all callees were expanded to rtl.
743 : The most noticeable example is PowerPC{,64}, see
744 : http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#DYNAM-STACK.
745 : To overcome the issue we use following trick: pass new_sp as a second
746 : parameter to __asan_allocas_unpoison and rewrite it during expansion with
747 : new_sp + (virtual_dynamic_stack_rtx - sp) later in
748 : expand_asan_emit_allocas_unpoison function.
749 :
750 : HWASAN needs to do very similar, the eventual pseudocode should be:
751 : __hwasan_tag_memory (virtual_stack_dynamic_rtx,
752 : 0,
753 : new_sp - sp);
754 : __builtin_stack_restore (new_sp)
755 :
756 : Need to use the same trick to handle STACK_DYNAMIC_OFFSET as described
757 : above. */
758 :
759 : static void
760 410 : handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
761 : {
762 410 : if (!iter
763 412 : || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()
764 2 : || memtag_sanitize_allocas_p ()))
765 : return;
766 :
767 203 : tree restored_stack = gimple_call_arg (call, 0);
768 :
769 203 : gimple *g;
770 :
771 203 : if (hwasan_sanitize_allocas_p () || memtag_sanitize_allocas_p ())
772 : {
773 0 : enum internal_fn fn = IFN_HWASAN_ALLOCA_UNPOISON;
774 : /* There is only one piece of information `expand_HWASAN_ALLOCA_UNPOISON`
775 : needs to work. This is the length of the area that we're
776 : deallocating. Since the stack pointer is known at expand time, the
777 : position of the new stack pointer after deallocation is enough
778 : information to calculate this length. */
779 0 : g = gimple_build_call_internal (fn, 1, restored_stack);
780 : }
781 : else
782 : {
783 203 : tree last_alloca = get_last_alloca_addr ();
784 203 : tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
785 203 : g = gimple_build_call (fn, 2, last_alloca, restored_stack);
786 203 : gsi_insert_before (iter, g, GSI_SAME_STMT);
787 203 : g = gimple_build_assign (last_alloca, restored_stack);
788 : }
789 :
790 203 : gsi_insert_before (iter, g, GSI_SAME_STMT);
791 : }
792 :
793 : /* Deploy and poison redzones around __builtin_alloca call. To do this, we
794 : should replace this call with another one with changed parameters and
795 : replace all its uses with new address, so
796 : addr = __builtin_alloca (old_size, align);
797 : is replaced by
798 : left_redzone_size = max (align, ASAN_RED_ZONE_SIZE);
799 : Following two statements are optimized out if we know that
800 : old_size & (ASAN_RED_ZONE_SIZE - 1) == 0, i.e. alloca doesn't need partial
801 : redzone.
802 : misalign = old_size & (ASAN_RED_ZONE_SIZE - 1);
803 : partial_redzone_size = ASAN_RED_ZONE_SIZE - misalign;
804 : right_redzone_size = ASAN_RED_ZONE_SIZE;
805 : additional_size = left_redzone_size + partial_redzone_size +
806 : right_redzone_size;
807 : new_size = old_size + additional_size;
808 : new_alloca = __builtin_alloca (new_size, max (align, 32))
809 : __asan_alloca_poison (new_alloca, old_size)
810 : addr = new_alloca + max (align, ASAN_RED_ZONE_SIZE);
811 : last_alloca_addr = new_alloca;
812 : ADDITIONAL_SIZE is added to make new memory allocation contain not only
813 : requested memory, but also left, partial and right redzones as well as some
814 : additional space, required by alignment. */
815 :
816 : static void
817 398 : handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter)
818 : {
819 398 : if (!iter
820 400 : || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()
821 2 : || memtag_sanitize_allocas_p ()))
822 201 : return;
823 :
824 197 : gassign *g;
825 197 : gcall *gg;
826 197 : tree callee = gimple_call_fndecl (call);
827 197 : tree lhs = gimple_call_lhs (call);
828 197 : tree old_size = gimple_call_arg (call, 0);
829 197 : tree ptr_type = lhs ? TREE_TYPE (lhs) : ptr_type_node;
830 197 : tree partial_size = NULL_TREE;
831 197 : unsigned int align
832 197 : = DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
833 390 : ? 0 : tree_to_uhwi (gimple_call_arg (call, 1));
834 :
835 197 : bool throws = false;
836 197 : edge e = NULL;
837 197 : if (stmt_can_throw_internal (cfun, call))
838 : {
839 9 : if (!lhs)
840 : return;
841 9 : throws = true;
842 9 : e = find_fallthru_edge (gsi_bb (*iter)->succs);
843 : }
844 :
845 197 : if (hwasan_sanitize_allocas_p () || memtag_sanitize_allocas_p ())
846 : {
847 0 : gimple_seq stmts = NULL;
848 0 : location_t loc = gimple_location (gsi_stmt (*iter));
849 : /* HWASAN and MEMTAG need a different expansion.
850 :
851 : addr = __builtin_alloca (size, align);
852 :
853 : in case of HWASAN, should be replaced by
854 :
855 : new_size = size rounded up to HWASAN_TAG_GRANULE_SIZE byte alignment;
856 : untagged_addr = __builtin_alloca (new_size, align);
857 : tag = __hwasan_choose_alloca_tag ();
858 : addr = ifn_HWASAN_SET_TAG (untagged_addr, tag);
859 : __hwasan_tag_memory (untagged_addr, tag, new_size);
860 :
861 : in case of MEMTAG, should be replaced by
862 :
863 : new_size = size rounded up to HWASAN_TAG_GRANULE_SIZE byte alignment;
864 : untagged_addr = __builtin_alloca (new_size, align);
865 : addr = ifn_HWASAN_ALLOCA_POISON (untagged_addr, new_size);
866 :
867 : where a new tag is chosen and set on untagged_addr when
868 : HWASAN_ALLOCA_POISON is expanded. */
869 :
870 : /* Ensure alignment at least HWASAN_TAG_GRANULE_SIZE bytes so we start on
871 : a tag granule. */
872 0 : align = align > HWASAN_TAG_GRANULE_SIZE ? align : HWASAN_TAG_GRANULE_SIZE;
873 :
874 0 : tree old_size = gimple_call_arg (call, 0);
875 0 : tree new_size = gimple_build_round_up (&stmts, loc, size_type_node,
876 : old_size,
877 0 : HWASAN_TAG_GRANULE_SIZE);
878 :
879 : /* Make the alloca call */
880 0 : tree untagged_addr
881 0 : = gimple_build (&stmts, loc,
882 : as_combined_fn (BUILT_IN_ALLOCA_WITH_ALIGN), ptr_type,
883 0 : new_size, build_int_cst (size_type_node, align));
884 :
885 0 : tree addr;
886 :
887 0 : if (memtag_sanitize_p ())
888 0 : addr = gimple_build (&stmts, loc, CFN_HWASAN_ALLOCA_POISON, ptr_type,
889 : untagged_addr, new_size);
890 : else
891 : {
892 : /* Choose the tag.
893 : Here we use an internal function so we can choose the tag at expand
894 : time. We need the decision to be made after stack variables have been
895 : assigned their tag (i.e. once the hwasan_frame_tag_offset variable has
896 : been set to one after the last stack variables tag). */
897 0 : tree tag = gimple_build (&stmts, loc, CFN_HWASAN_CHOOSE_TAG,
898 : unsigned_char_type_node);
899 :
900 : /* Add tag to pointer. */
901 0 : addr = gimple_build (&stmts, loc, CFN_HWASAN_SET_TAG, ptr_type,
902 : untagged_addr, tag);
903 :
904 : /* Tag shadow memory.
905 : NOTE: require using `untagged_addr` here for libhwasan API. */
906 0 : gimple_build (&stmts, loc, as_combined_fn (BUILT_IN_HWASAN_TAG_MEM),
907 : void_type_node, untagged_addr, tag, new_size);
908 : }
909 :
910 : /* Insert the built up code sequence into the original instruction stream
911 : the iterator points to. */
912 0 : gsi_insert_seq_before (iter, stmts, GSI_SAME_STMT);
913 :
914 : /* Finally, replace old alloca ptr with NEW_ALLOCA. */
915 0 : replace_call_with_value (iter, addr);
916 0 : return;
917 : }
918 :
919 197 : tree last_alloca = get_last_alloca_addr ();
920 197 : const HOST_WIDE_INT redzone_mask = ASAN_RED_ZONE_SIZE - 1;
921 :
922 : /* If ALIGN > ASAN_RED_ZONE_SIZE, we embed left redzone into first ALIGN
923 : bytes of allocated space. Otherwise, align alloca to ASAN_RED_ZONE_SIZE
924 : manually. */
925 197 : align = MAX (align, ASAN_RED_ZONE_SIZE * BITS_PER_UNIT);
926 :
927 197 : tree alloca_rz_mask = build_int_cst (size_type_node, redzone_mask);
928 197 : tree redzone_size = build_int_cst (size_type_node, ASAN_RED_ZONE_SIZE);
929 :
930 : /* Extract lower bits from old_size. */
931 197 : wide_int size_nonzero_bits = get_nonzero_bits (old_size);
932 197 : wide_int rz_mask
933 197 : = wi::uhwi (redzone_mask, wi::get_precision (size_nonzero_bits));
934 197 : wide_int old_size_lower_bits = wi::bit_and (size_nonzero_bits, rz_mask);
935 :
936 : /* If alloca size is aligned to ASAN_RED_ZONE_SIZE, we don't need partial
937 : redzone. Otherwise, compute its size here. */
938 197 : if (wi::ne_p (old_size_lower_bits, 0))
939 : {
940 : /* misalign = size & (ASAN_RED_ZONE_SIZE - 1)
941 : partial_size = ASAN_RED_ZONE_SIZE - misalign. */
942 194 : g = gimple_build_assign (make_ssa_name (size_type_node, NULL),
943 : BIT_AND_EXPR, old_size, alloca_rz_mask);
944 194 : gsi_insert_before (iter, g, GSI_SAME_STMT);
945 194 : tree misalign = gimple_assign_lhs (g);
946 194 : g = gimple_build_assign (make_ssa_name (size_type_node, NULL), MINUS_EXPR,
947 : redzone_size, misalign);
948 194 : gsi_insert_before (iter, g, GSI_SAME_STMT);
949 194 : partial_size = gimple_assign_lhs (g);
950 : }
951 :
952 : /* additional_size = align + ASAN_RED_ZONE_SIZE. */
953 394 : tree additional_size = build_int_cst (size_type_node, align / BITS_PER_UNIT
954 197 : + ASAN_RED_ZONE_SIZE);
955 : /* If alloca has partial redzone, include it to additional_size too. */
956 197 : if (partial_size)
957 : {
958 : /* additional_size += partial_size. */
959 194 : g = gimple_build_assign (make_ssa_name (size_type_node), PLUS_EXPR,
960 : partial_size, additional_size);
961 194 : gsi_insert_before (iter, g, GSI_SAME_STMT);
962 194 : additional_size = gimple_assign_lhs (g);
963 : }
964 :
965 : /* new_size = old_size + additional_size. */
966 197 : g = gimple_build_assign (make_ssa_name (size_type_node), PLUS_EXPR, old_size,
967 : additional_size);
968 197 : gsi_insert_before (iter, g, GSI_SAME_STMT);
969 197 : tree new_size = gimple_assign_lhs (g);
970 :
971 : /* Build new __builtin_alloca call:
972 : new_alloca_with_rz = __builtin_alloca (new_size, align). */
973 197 : tree fn = builtin_decl_implicit (BUILT_IN_ALLOCA_WITH_ALIGN);
974 197 : gg = gimple_build_call (fn, 2, new_size,
975 197 : build_int_cst (size_type_node, align));
976 197 : tree new_alloca_with_rz = make_ssa_name (ptr_type, gg);
977 197 : gimple_call_set_lhs (gg, new_alloca_with_rz);
978 197 : if (throws)
979 : {
980 9 : gimple_call_set_lhs (call, NULL);
981 9 : gsi_replace (iter, gg, true);
982 : }
983 : else
984 188 : gsi_insert_before (iter, gg, GSI_SAME_STMT);
985 :
986 : /* new_alloca = new_alloca_with_rz + align. */
987 197 : g = gimple_build_assign (make_ssa_name (ptr_type), POINTER_PLUS_EXPR,
988 : new_alloca_with_rz,
989 : build_int_cst (size_type_node,
990 197 : align / BITS_PER_UNIT));
991 197 : gimple_stmt_iterator gsi = gsi_none ();
992 197 : if (throws)
993 : {
994 9 : gsi_insert_on_edge_immediate (e, g);
995 9 : gsi = gsi_for_stmt (g);
996 : }
997 : else
998 188 : gsi_insert_before (iter, g, GSI_SAME_STMT);
999 197 : tree new_alloca = gimple_assign_lhs (g);
1000 :
1001 : /* Poison newly created alloca redzones:
1002 : __asan_alloca_poison (new_alloca, old_size). */
1003 197 : fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCA_POISON);
1004 197 : gg = gimple_build_call (fn, 2, new_alloca, old_size);
1005 197 : if (throws)
1006 9 : gsi_insert_after (&gsi, gg, GSI_NEW_STMT);
1007 : else
1008 188 : gsi_insert_before (iter, gg, GSI_SAME_STMT);
1009 :
1010 : /* Save new_alloca_with_rz value into last_alloca to use it during
1011 : allocas unpoisoning. */
1012 197 : g = gimple_build_assign (last_alloca, new_alloca_with_rz);
1013 197 : if (throws)
1014 9 : gsi_insert_after (&gsi, g, GSI_NEW_STMT);
1015 : else
1016 188 : gsi_insert_before (iter, g, GSI_SAME_STMT);
1017 :
1018 : /* Finally, replace old alloca ptr with NEW_ALLOCA. */
1019 197 : if (throws)
1020 : {
1021 9 : g = gimple_build_assign (lhs, new_alloca);
1022 9 : gsi_insert_after (&gsi, g, GSI_NEW_STMT);
1023 : }
1024 : else
1025 188 : replace_call_with_value (iter, new_alloca);
1026 197 : }
1027 :
1028 : /* Return the memory references contained in a gimple statement
1029 : representing a builtin call that has to do with memory access. */
1030 :
1031 : static bool
1032 8810 : get_mem_refs_of_builtin_call (gcall *call,
1033 : asan_mem_ref *src0,
1034 : tree *src0_len,
1035 : bool *src0_is_store,
1036 : asan_mem_ref *src1,
1037 : tree *src1_len,
1038 : bool *src1_is_store,
1039 : asan_mem_ref *dst,
1040 : tree *dst_len,
1041 : bool *dst_is_store,
1042 : bool *dest_is_deref,
1043 : bool *intercepted_p,
1044 : gimple_stmt_iterator *iter = NULL)
1045 : {
1046 8810 : gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
1047 :
1048 8810 : tree callee = gimple_call_fndecl (call);
1049 8810 : tree source0 = NULL_TREE, source1 = NULL_TREE,
1050 8810 : dest = NULL_TREE, len = NULL_TREE;
1051 8810 : bool is_store = true, got_reference_p = false;
1052 8810 : HOST_WIDE_INT access_size = 1;
1053 :
1054 8810 : *intercepted_p = asan_intercepted_p ((DECL_FUNCTION_CODE (callee)));
1055 :
1056 8810 : switch (DECL_FUNCTION_CODE (callee))
1057 : {
1058 : /* (s, s, n) style memops. */
1059 112 : case BUILT_IN_BCMP:
1060 112 : case BUILT_IN_MEMCMP:
1061 112 : source0 = gimple_call_arg (call, 0);
1062 112 : source1 = gimple_call_arg (call, 1);
1063 112 : len = gimple_call_arg (call, 2);
1064 112 : break;
1065 :
1066 : /* (src, dest, n) style memops. */
1067 0 : case BUILT_IN_BCOPY:
1068 0 : source0 = gimple_call_arg (call, 0);
1069 0 : dest = gimple_call_arg (call, 1);
1070 0 : len = gimple_call_arg (call, 2);
1071 0 : break;
1072 :
1073 : /* (dest, src, n) style memops. */
1074 1250 : case BUILT_IN_MEMCPY:
1075 1250 : case BUILT_IN_MEMCPY_CHK:
1076 1250 : case BUILT_IN_MEMMOVE:
1077 1250 : case BUILT_IN_MEMMOVE_CHK:
1078 1250 : case BUILT_IN_MEMPCPY:
1079 1250 : case BUILT_IN_MEMPCPY_CHK:
1080 1250 : dest = gimple_call_arg (call, 0);
1081 1250 : source0 = gimple_call_arg (call, 1);
1082 1250 : len = gimple_call_arg (call, 2);
1083 1250 : break;
1084 :
1085 : /* (dest, n) style memops. */
1086 0 : case BUILT_IN_BZERO:
1087 0 : dest = gimple_call_arg (call, 0);
1088 0 : len = gimple_call_arg (call, 1);
1089 0 : break;
1090 :
1091 : /* (dest, x, n) style memops*/
1092 388 : case BUILT_IN_MEMSET:
1093 388 : case BUILT_IN_MEMSET_CHK:
1094 388 : dest = gimple_call_arg (call, 0);
1095 388 : len = gimple_call_arg (call, 2);
1096 388 : break;
1097 :
1098 104 : case BUILT_IN_STRLEN:
1099 : /* Special case strlen here since its length is taken from its return
1100 : value.
1101 :
1102 : The approach taken by the sanitizers is to check a memory access
1103 : before it's taken. For ASAN strlen is intercepted by libasan, so no
1104 : check is inserted by the compiler.
1105 :
1106 : This function still returns `true` and provides a length to the rest
1107 : of the ASAN pass in order to record what areas have been checked,
1108 : avoiding superfluous checks later on.
1109 :
1110 : HWASAN does not intercept any of these internal functions.
1111 : This means that checks for memory accesses must be inserted by the
1112 : compiler.
1113 : strlen is a special case, because we can tell the length from the
1114 : return of the function, but that is not known until after the function
1115 : has returned.
1116 :
1117 : Hence we can't check the memory access before it happens.
1118 : We could check the memory access after it has already happened, but
1119 : for now we choose to just ignore `strlen` calls.
1120 : This decision was simply made because that means the special case is
1121 : limited to this one case of this one function. */
1122 104 : if (hwassist_sanitize_p ())
1123 : return false;
1124 72 : source0 = gimple_call_arg (call, 0);
1125 72 : len = gimple_call_lhs (call);
1126 72 : break;
1127 :
1128 410 : case BUILT_IN_STACK_RESTORE:
1129 410 : handle_builtin_stack_restore (call, iter);
1130 410 : break;
1131 :
1132 398 : CASE_BUILT_IN_ALLOCA:
1133 398 : handle_builtin_alloca (call, iter);
1134 398 : break;
1135 : /* And now the __atomic* and __sync builtins.
1136 : These are handled differently from the classical memory
1137 : access builtins above. */
1138 :
1139 0 : case BUILT_IN_ATOMIC_LOAD_1:
1140 0 : is_store = false;
1141 : /* FALLTHRU */
1142 0 : case BUILT_IN_SYNC_FETCH_AND_ADD_1:
1143 0 : case BUILT_IN_SYNC_FETCH_AND_SUB_1:
1144 0 : case BUILT_IN_SYNC_FETCH_AND_OR_1:
1145 0 : case BUILT_IN_SYNC_FETCH_AND_AND_1:
1146 0 : case BUILT_IN_SYNC_FETCH_AND_XOR_1:
1147 0 : case BUILT_IN_SYNC_FETCH_AND_NAND_1:
1148 0 : case BUILT_IN_SYNC_ADD_AND_FETCH_1:
1149 0 : case BUILT_IN_SYNC_SUB_AND_FETCH_1:
1150 0 : case BUILT_IN_SYNC_OR_AND_FETCH_1:
1151 0 : case BUILT_IN_SYNC_AND_AND_FETCH_1:
1152 0 : case BUILT_IN_SYNC_XOR_AND_FETCH_1:
1153 0 : case BUILT_IN_SYNC_NAND_AND_FETCH_1:
1154 0 : case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
1155 0 : case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
1156 0 : case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
1157 0 : case BUILT_IN_SYNC_LOCK_RELEASE_1:
1158 0 : case BUILT_IN_ATOMIC_EXCHANGE_1:
1159 0 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
1160 0 : case BUILT_IN_ATOMIC_STORE_1:
1161 0 : case BUILT_IN_ATOMIC_ADD_FETCH_1:
1162 0 : case BUILT_IN_ATOMIC_SUB_FETCH_1:
1163 0 : case BUILT_IN_ATOMIC_AND_FETCH_1:
1164 0 : case BUILT_IN_ATOMIC_NAND_FETCH_1:
1165 0 : case BUILT_IN_ATOMIC_XOR_FETCH_1:
1166 0 : case BUILT_IN_ATOMIC_OR_FETCH_1:
1167 0 : case BUILT_IN_ATOMIC_FETCH_ADD_1:
1168 0 : case BUILT_IN_ATOMIC_FETCH_SUB_1:
1169 0 : case BUILT_IN_ATOMIC_FETCH_AND_1:
1170 0 : case BUILT_IN_ATOMIC_FETCH_NAND_1:
1171 0 : case BUILT_IN_ATOMIC_FETCH_XOR_1:
1172 0 : case BUILT_IN_ATOMIC_FETCH_OR_1:
1173 0 : access_size = 1;
1174 0 : goto do_atomic;
1175 :
1176 0 : case BUILT_IN_ATOMIC_LOAD_2:
1177 0 : is_store = false;
1178 : /* FALLTHRU */
1179 0 : case BUILT_IN_SYNC_FETCH_AND_ADD_2:
1180 0 : case BUILT_IN_SYNC_FETCH_AND_SUB_2:
1181 0 : case BUILT_IN_SYNC_FETCH_AND_OR_2:
1182 0 : case BUILT_IN_SYNC_FETCH_AND_AND_2:
1183 0 : case BUILT_IN_SYNC_FETCH_AND_XOR_2:
1184 0 : case BUILT_IN_SYNC_FETCH_AND_NAND_2:
1185 0 : case BUILT_IN_SYNC_ADD_AND_FETCH_2:
1186 0 : case BUILT_IN_SYNC_SUB_AND_FETCH_2:
1187 0 : case BUILT_IN_SYNC_OR_AND_FETCH_2:
1188 0 : case BUILT_IN_SYNC_AND_AND_FETCH_2:
1189 0 : case BUILT_IN_SYNC_XOR_AND_FETCH_2:
1190 0 : case BUILT_IN_SYNC_NAND_AND_FETCH_2:
1191 0 : case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
1192 0 : case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
1193 0 : case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
1194 0 : case BUILT_IN_SYNC_LOCK_RELEASE_2:
1195 0 : case BUILT_IN_ATOMIC_EXCHANGE_2:
1196 0 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
1197 0 : case BUILT_IN_ATOMIC_STORE_2:
1198 0 : case BUILT_IN_ATOMIC_ADD_FETCH_2:
1199 0 : case BUILT_IN_ATOMIC_SUB_FETCH_2:
1200 0 : case BUILT_IN_ATOMIC_AND_FETCH_2:
1201 0 : case BUILT_IN_ATOMIC_NAND_FETCH_2:
1202 0 : case BUILT_IN_ATOMIC_XOR_FETCH_2:
1203 0 : case BUILT_IN_ATOMIC_OR_FETCH_2:
1204 0 : case BUILT_IN_ATOMIC_FETCH_ADD_2:
1205 0 : case BUILT_IN_ATOMIC_FETCH_SUB_2:
1206 0 : case BUILT_IN_ATOMIC_FETCH_AND_2:
1207 0 : case BUILT_IN_ATOMIC_FETCH_NAND_2:
1208 0 : case BUILT_IN_ATOMIC_FETCH_XOR_2:
1209 0 : case BUILT_IN_ATOMIC_FETCH_OR_2:
1210 0 : access_size = 2;
1211 0 : goto do_atomic;
1212 :
1213 0 : case BUILT_IN_ATOMIC_LOAD_4:
1214 0 : is_store = false;
1215 : /* FALLTHRU */
1216 56 : case BUILT_IN_SYNC_FETCH_AND_ADD_4:
1217 56 : case BUILT_IN_SYNC_FETCH_AND_SUB_4:
1218 56 : case BUILT_IN_SYNC_FETCH_AND_OR_4:
1219 56 : case BUILT_IN_SYNC_FETCH_AND_AND_4:
1220 56 : case BUILT_IN_SYNC_FETCH_AND_XOR_4:
1221 56 : case BUILT_IN_SYNC_FETCH_AND_NAND_4:
1222 56 : case BUILT_IN_SYNC_ADD_AND_FETCH_4:
1223 56 : case BUILT_IN_SYNC_SUB_AND_FETCH_4:
1224 56 : case BUILT_IN_SYNC_OR_AND_FETCH_4:
1225 56 : case BUILT_IN_SYNC_AND_AND_FETCH_4:
1226 56 : case BUILT_IN_SYNC_XOR_AND_FETCH_4:
1227 56 : case BUILT_IN_SYNC_NAND_AND_FETCH_4:
1228 56 : case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
1229 56 : case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
1230 56 : case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
1231 56 : case BUILT_IN_SYNC_LOCK_RELEASE_4:
1232 56 : case BUILT_IN_ATOMIC_EXCHANGE_4:
1233 56 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
1234 56 : case BUILT_IN_ATOMIC_STORE_4:
1235 56 : case BUILT_IN_ATOMIC_ADD_FETCH_4:
1236 56 : case BUILT_IN_ATOMIC_SUB_FETCH_4:
1237 56 : case BUILT_IN_ATOMIC_AND_FETCH_4:
1238 56 : case BUILT_IN_ATOMIC_NAND_FETCH_4:
1239 56 : case BUILT_IN_ATOMIC_XOR_FETCH_4:
1240 56 : case BUILT_IN_ATOMIC_OR_FETCH_4:
1241 56 : case BUILT_IN_ATOMIC_FETCH_ADD_4:
1242 56 : case BUILT_IN_ATOMIC_FETCH_SUB_4:
1243 56 : case BUILT_IN_ATOMIC_FETCH_AND_4:
1244 56 : case BUILT_IN_ATOMIC_FETCH_NAND_4:
1245 56 : case BUILT_IN_ATOMIC_FETCH_XOR_4:
1246 56 : case BUILT_IN_ATOMIC_FETCH_OR_4:
1247 56 : access_size = 4;
1248 56 : goto do_atomic;
1249 :
1250 0 : case BUILT_IN_ATOMIC_LOAD_8:
1251 0 : is_store = false;
1252 : /* FALLTHRU */
1253 0 : case BUILT_IN_SYNC_FETCH_AND_ADD_8:
1254 0 : case BUILT_IN_SYNC_FETCH_AND_SUB_8:
1255 0 : case BUILT_IN_SYNC_FETCH_AND_OR_8:
1256 0 : case BUILT_IN_SYNC_FETCH_AND_AND_8:
1257 0 : case BUILT_IN_SYNC_FETCH_AND_XOR_8:
1258 0 : case BUILT_IN_SYNC_FETCH_AND_NAND_8:
1259 0 : case BUILT_IN_SYNC_ADD_AND_FETCH_8:
1260 0 : case BUILT_IN_SYNC_SUB_AND_FETCH_8:
1261 0 : case BUILT_IN_SYNC_OR_AND_FETCH_8:
1262 0 : case BUILT_IN_SYNC_AND_AND_FETCH_8:
1263 0 : case BUILT_IN_SYNC_XOR_AND_FETCH_8:
1264 0 : case BUILT_IN_SYNC_NAND_AND_FETCH_8:
1265 0 : case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
1266 0 : case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
1267 0 : case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
1268 0 : case BUILT_IN_SYNC_LOCK_RELEASE_8:
1269 0 : case BUILT_IN_ATOMIC_EXCHANGE_8:
1270 0 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
1271 0 : case BUILT_IN_ATOMIC_STORE_8:
1272 0 : case BUILT_IN_ATOMIC_ADD_FETCH_8:
1273 0 : case BUILT_IN_ATOMIC_SUB_FETCH_8:
1274 0 : case BUILT_IN_ATOMIC_AND_FETCH_8:
1275 0 : case BUILT_IN_ATOMIC_NAND_FETCH_8:
1276 0 : case BUILT_IN_ATOMIC_XOR_FETCH_8:
1277 0 : case BUILT_IN_ATOMIC_OR_FETCH_8:
1278 0 : case BUILT_IN_ATOMIC_FETCH_ADD_8:
1279 0 : case BUILT_IN_ATOMIC_FETCH_SUB_8:
1280 0 : case BUILT_IN_ATOMIC_FETCH_AND_8:
1281 0 : case BUILT_IN_ATOMIC_FETCH_NAND_8:
1282 0 : case BUILT_IN_ATOMIC_FETCH_XOR_8:
1283 0 : case BUILT_IN_ATOMIC_FETCH_OR_8:
1284 0 : access_size = 8;
1285 0 : goto do_atomic;
1286 :
1287 0 : case BUILT_IN_ATOMIC_LOAD_16:
1288 0 : is_store = false;
1289 : /* FALLTHRU */
1290 : case BUILT_IN_SYNC_FETCH_AND_ADD_16:
1291 : case BUILT_IN_SYNC_FETCH_AND_SUB_16:
1292 : case BUILT_IN_SYNC_FETCH_AND_OR_16:
1293 : case BUILT_IN_SYNC_FETCH_AND_AND_16:
1294 : case BUILT_IN_SYNC_FETCH_AND_XOR_16:
1295 : case BUILT_IN_SYNC_FETCH_AND_NAND_16:
1296 : case BUILT_IN_SYNC_ADD_AND_FETCH_16:
1297 : case BUILT_IN_SYNC_SUB_AND_FETCH_16:
1298 : case BUILT_IN_SYNC_OR_AND_FETCH_16:
1299 : case BUILT_IN_SYNC_AND_AND_FETCH_16:
1300 : case BUILT_IN_SYNC_XOR_AND_FETCH_16:
1301 : case BUILT_IN_SYNC_NAND_AND_FETCH_16:
1302 : case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
1303 : case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
1304 : case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
1305 : case BUILT_IN_SYNC_LOCK_RELEASE_16:
1306 : case BUILT_IN_ATOMIC_EXCHANGE_16:
1307 : case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
1308 : case BUILT_IN_ATOMIC_STORE_16:
1309 : case BUILT_IN_ATOMIC_ADD_FETCH_16:
1310 : case BUILT_IN_ATOMIC_SUB_FETCH_16:
1311 : case BUILT_IN_ATOMIC_AND_FETCH_16:
1312 : case BUILT_IN_ATOMIC_NAND_FETCH_16:
1313 : case BUILT_IN_ATOMIC_XOR_FETCH_16:
1314 : case BUILT_IN_ATOMIC_OR_FETCH_16:
1315 : case BUILT_IN_ATOMIC_FETCH_ADD_16:
1316 : case BUILT_IN_ATOMIC_FETCH_SUB_16:
1317 : case BUILT_IN_ATOMIC_FETCH_AND_16:
1318 : case BUILT_IN_ATOMIC_FETCH_NAND_16:
1319 : case BUILT_IN_ATOMIC_FETCH_XOR_16:
1320 : case BUILT_IN_ATOMIC_FETCH_OR_16:
1321 : access_size = 16;
1322 : /* FALLTHRU */
1323 56 : do_atomic:
1324 56 : {
1325 56 : dest = gimple_call_arg (call, 0);
1326 : /* DEST represents the address of a memory location.
1327 : instrument_derefs wants the memory location, so lets
1328 : dereference the address DEST before handing it to
1329 : instrument_derefs. */
1330 112 : tree type = build_nonstandard_integer_type (access_size
1331 56 : * BITS_PER_UNIT, 1);
1332 56 : dest = build2 (MEM_REF, type, dest,
1333 : build_int_cst (build_pointer_type (char_type_node), 0));
1334 56 : break;
1335 : }
1336 :
1337 : default:
1338 : /* The other builtins memory access are not instrumented in this
1339 : function because they either don't have any length parameter,
1340 : or their length parameter is just a limit. */
1341 : break;
1342 : }
1343 :
1344 2686 : if (len != NULL_TREE)
1345 : {
1346 1822 : if (source0 != NULL_TREE)
1347 : {
1348 1434 : src0->start = source0;
1349 1434 : src0->access_size = access_size;
1350 1434 : *src0_len = len;
1351 1434 : *src0_is_store = false;
1352 : }
1353 :
1354 1822 : if (source1 != NULL_TREE)
1355 : {
1356 112 : src1->start = source1;
1357 112 : src1->access_size = access_size;
1358 112 : *src1_len = len;
1359 112 : *src1_is_store = false;
1360 : }
1361 :
1362 1822 : if (dest != NULL_TREE)
1363 : {
1364 1638 : dst->start = dest;
1365 1638 : dst->access_size = access_size;
1366 1638 : *dst_len = len;
1367 1638 : *dst_is_store = true;
1368 : }
1369 :
1370 : got_reference_p = true;
1371 : }
1372 6956 : else if (dest)
1373 : {
1374 56 : dst->start = dest;
1375 56 : dst->access_size = access_size;
1376 56 : *dst_len = NULL_TREE;
1377 56 : *dst_is_store = is_store;
1378 56 : *dest_is_deref = true;
1379 56 : got_reference_p = true;
1380 : }
1381 :
1382 : return got_reference_p;
1383 : }
1384 :
1385 : /* Return true iff a given gimple statement has been instrumented.
1386 : Note that the statement is "defined" by the memory references it
1387 : contains. */
1388 :
1389 : static bool
1390 170168 : has_stmt_been_instrumented_p (gimple *stmt)
1391 : {
1392 170168 : if (gimple_assign_single_p (stmt))
1393 : {
1394 30138 : bool r_is_store;
1395 30138 : asan_mem_ref r;
1396 30138 : asan_mem_ref_init (&r, NULL, 1);
1397 :
1398 30138 : if (get_mem_ref_of_assignment (as_a <gassign *> (stmt), &r,
1399 : &r_is_store))
1400 : {
1401 26615 : if (!has_mem_ref_been_instrumented (&r))
1402 26615 : return false;
1403 1021 : if (r_is_store && gimple_assign_load_p (stmt))
1404 : {
1405 5 : asan_mem_ref src;
1406 5 : asan_mem_ref_init (&src, NULL, 1);
1407 5 : src.start = gimple_assign_rhs1 (stmt);
1408 5 : src.access_size = int_size_in_bytes (TREE_TYPE (src.start));
1409 5 : if (!has_mem_ref_been_instrumented (&src))
1410 : return false;
1411 : }
1412 1016 : return true;
1413 : }
1414 : }
1415 140030 : else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
1416 : {
1417 4423 : asan_mem_ref src0, src1, dest;
1418 4423 : asan_mem_ref_init (&src0, NULL, 1);
1419 4423 : asan_mem_ref_init (&src1, NULL, 1);
1420 4423 : asan_mem_ref_init (&dest, NULL, 1);
1421 :
1422 4423 : tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
1423 4423 : bool src0_is_store = false, src1_is_store = false,
1424 : dest_is_store = false, dest_is_deref = false, intercepted_p = true;
1425 4423 : if (get_mem_refs_of_builtin_call (as_a <gcall *> (stmt),
1426 : &src0, &src0_len, &src0_is_store,
1427 : &src1, &src1_len, &src1_is_store,
1428 : &dest, &dest_len, &dest_is_store,
1429 : &dest_is_deref, &intercepted_p))
1430 : {
1431 951 : if (src0.start != NULL_TREE
1432 951 : && !has_mem_ref_been_instrumented (&src0, src0_len))
1433 951 : return false;
1434 :
1435 240 : if (src1.start != NULL_TREE
1436 240 : && !has_mem_ref_been_instrumented (&src1, src1_len))
1437 : return false;
1438 :
1439 240 : if (dest.start != NULL_TREE
1440 240 : && !has_mem_ref_been_instrumented (&dest, dest_len))
1441 228 : return false;
1442 :
1443 : return true;
1444 : }
1445 : }
1446 135607 : else if (is_gimple_call (stmt)
1447 18363 : && gimple_store_p (stmt)
1448 135895 : && (gimple_call_builtin_p (stmt)
1449 288 : || gimple_call_internal_p (stmt)
1450 287 : || !aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
1451 287 : gimple_call_fntype (stmt))))
1452 : {
1453 62 : asan_mem_ref r;
1454 62 : asan_mem_ref_init (&r, NULL, 1);
1455 :
1456 62 : r.start = gimple_call_lhs (stmt);
1457 62 : r.access_size = int_size_in_bytes (TREE_TYPE (r.start));
1458 62 : return has_mem_ref_been_instrumented (&r);
1459 : }
1460 :
1461 : return false;
1462 : }
1463 :
1464 : /* Insert a memory reference into the hash table. */
1465 :
1466 : static void
1467 37478 : update_mem_ref_hash_table (tree ref, HOST_WIDE_INT access_size)
1468 : {
1469 37478 : hash_table<asan_mem_ref_hasher> *ht = get_mem_ref_hash_table ();
1470 :
1471 37478 : asan_mem_ref r;
1472 37478 : asan_mem_ref_init (&r, ref, access_size);
1473 :
1474 37478 : asan_mem_ref **slot = ht->find_slot (&r, INSERT);
1475 37478 : if (*slot == NULL || (*slot)->access_size < access_size)
1476 37466 : *slot = asan_mem_ref_new (ref, access_size);
1477 37478 : }
1478 :
1479 : /* Initialize shadow_ptr_types array. */
1480 :
1481 : static void
1482 2486 : asan_init_shadow_ptr_types (void)
1483 : {
1484 2486 : asan_shadow_set = new_alias_set ();
1485 2486 : tree types[3] = { signed_char_type_node, short_integer_type_node,
1486 2486 : integer_type_node };
1487 :
1488 9944 : for (unsigned i = 0; i < 3; i++)
1489 : {
1490 7458 : shadow_ptr_types[i] = build_distinct_type_copy (types[i]);
1491 7458 : TYPE_ALIAS_SET (shadow_ptr_types[i]) = asan_shadow_set;
1492 7458 : shadow_ptr_types[i] = build_pointer_type (shadow_ptr_types[i]);
1493 : }
1494 :
1495 2486 : initialize_sanitizer_builtins ();
1496 2486 : }
1497 :
1498 : /* Create ADDR_EXPR of STRING_CST with the PP pretty printer text. */
1499 :
1500 : static tree
1501 12313 : asan_pp_string (pretty_printer *pp)
1502 : {
1503 12313 : const char *buf = pp_formatted_text (pp);
1504 12313 : size_t len = strlen (buf);
1505 12313 : tree ret = build_string (len + 1, buf);
1506 24626 : TREE_TYPE (ret)
1507 12313 : = build_array_type (TREE_TYPE (shadow_ptr_types[0]),
1508 12313 : build_index_type (size_int (len)));
1509 12313 : TREE_READONLY (ret) = 1;
1510 12313 : TREE_STATIC (ret) = 1;
1511 12313 : return build1 (ADDR_EXPR, shadow_ptr_types[0], ret);
1512 : }
1513 :
1514 : /* Clear shadow memory at SHADOW_MEM, LEN bytes. Can't call a library call here
1515 : though. */
1516 :
1517 : static void
1518 2398 : asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
1519 : {
1520 2398 : rtx_insn *insn, *insns, *jump;
1521 2398 : rtx_code_label *top_label;
1522 2398 : rtx end, addr, tmp;
1523 :
1524 2398 : gcc_assert ((len & 3) == 0);
1525 2398 : start_sequence ();
1526 2398 : clear_storage (shadow_mem, GEN_INT (len), BLOCK_OP_NORMAL);
1527 2398 : insns = end_sequence ();
1528 8598 : for (insn = insns; insn; insn = NEXT_INSN (insn))
1529 3815 : if (CALL_P (insn))
1530 : break;
1531 2398 : if (insn == NULL_RTX)
1532 : {
1533 2385 : emit_insn (insns);
1534 2385 : return;
1535 : }
1536 :
1537 13 : top_label = gen_label_rtx ();
1538 13 : addr = copy_to_mode_reg (Pmode, XEXP (shadow_mem, 0));
1539 13 : shadow_mem = adjust_automodify_address (shadow_mem, SImode, addr, 0);
1540 13 : end = force_reg (Pmode, plus_constant (Pmode, addr, len));
1541 13 : emit_label (top_label);
1542 :
1543 13 : emit_move_insn (shadow_mem, const0_rtx);
1544 13 : tmp = expand_simple_binop (Pmode, PLUS, addr, gen_int_mode (4, Pmode), addr,
1545 : true, OPTAB_LIB_WIDEN);
1546 13 : if (tmp != addr)
1547 0 : emit_move_insn (addr, tmp);
1548 13 : emit_cmp_and_jump_insns (addr, end, LT, NULL_RTX, Pmode, true, top_label);
1549 13 : jump = get_last_insn ();
1550 13 : gcc_assert (JUMP_P (jump));
1551 13 : add_reg_br_prob_note (jump,
1552 26 : profile_probability::guessed_always ()
1553 : .apply_scale (80, 100));
1554 : }
1555 :
1556 : void
1557 6352 : asan_function_start (void)
1558 : {
1559 6352 : ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LASANPC", current_function_funcdef_no);
1560 6352 : }
1561 :
1562 : /* Return number of shadow bytes that are occupied by a local variable
1563 : of SIZE bytes. */
1564 :
1565 : static unsigned HOST_WIDE_INT
1566 2096 : shadow_mem_size (unsigned HOST_WIDE_INT size)
1567 : {
1568 : /* It must be possible to align stack variables to granularity
1569 : of shadow memory. */
1570 2096 : gcc_assert (BITS_PER_UNIT
1571 : * ASAN_SHADOW_GRANULARITY <= MAX_SUPPORTED_STACK_ALIGNMENT);
1572 :
1573 2096 : return ROUND_UP (size, ASAN_SHADOW_GRANULARITY) / ASAN_SHADOW_GRANULARITY;
1574 : }
1575 :
1576 : /* Always emit 4 bytes at a time. */
1577 : #define RZ_BUFFER_SIZE 4
1578 :
1579 : /* ASAN redzone buffer container that handles emission of shadow bytes. */
1580 3444 : class asan_redzone_buffer
1581 : {
1582 : public:
1583 : /* Constructor. */
1584 1722 : asan_redzone_buffer (rtx shadow_mem, HOST_WIDE_INT prev_offset):
1585 1722 : m_shadow_mem (shadow_mem), m_prev_offset (prev_offset),
1586 1722 : m_original_offset (prev_offset), m_shadow_bytes (RZ_BUFFER_SIZE)
1587 : {}
1588 :
1589 : /* Emit VALUE shadow byte at a given OFFSET. */
1590 : void emit_redzone_byte (HOST_WIDE_INT offset, unsigned char value);
1591 :
1592 : /* Emit RTX emission of the content of the buffer. */
1593 : void flush_redzone_payload (void);
1594 :
1595 : private:
1596 : /* Flush if the content of the buffer is full
1597 : (equal to RZ_BUFFER_SIZE). */
1598 : void flush_if_full (void);
1599 :
1600 : /* Memory where we last emitted a redzone payload. */
1601 : rtx m_shadow_mem;
1602 :
1603 : /* Relative offset where we last emitted a redzone payload. */
1604 : HOST_WIDE_INT m_prev_offset;
1605 :
1606 : /* Relative original offset. Used for checking only. */
1607 : HOST_WIDE_INT m_original_offset;
1608 :
1609 : public:
1610 : /* Buffer with redzone payload. */
1611 : auto_vec<unsigned char> m_shadow_bytes;
1612 : };
1613 :
1614 : /* Emit VALUE shadow byte at a given OFFSET. */
1615 :
1616 : void
1617 22777 : asan_redzone_buffer::emit_redzone_byte (HOST_WIDE_INT offset,
1618 : unsigned char value)
1619 : {
1620 22777 : gcc_assert ((offset & (ASAN_SHADOW_GRANULARITY - 1)) == 0);
1621 22777 : gcc_assert (offset >= m_prev_offset);
1622 :
1623 22777 : HOST_WIDE_INT off
1624 22777 : = m_prev_offset + ASAN_SHADOW_GRANULARITY * m_shadow_bytes.length ();
1625 22777 : if (off == offset)
1626 : /* Consecutive shadow memory byte. */;
1627 4720 : else if (offset < m_prev_offset + (HOST_WIDE_INT) (ASAN_SHADOW_GRANULARITY
1628 : * RZ_BUFFER_SIZE)
1629 4720 : && !m_shadow_bytes.is_empty ())
1630 : {
1631 : /* Shadow memory byte with a small gap. */
1632 68 : for (; off < offset; off += ASAN_SHADOW_GRANULARITY)
1633 34 : m_shadow_bytes.safe_push (0);
1634 : }
1635 : else
1636 : {
1637 4686 : if (!m_shadow_bytes.is_empty ())
1638 358 : flush_redzone_payload ();
1639 :
1640 : /* Maybe start earlier in order to use aligned store. */
1641 4686 : HOST_WIDE_INT align = (offset - m_prev_offset) % ASAN_RED_ZONE_SIZE;
1642 4686 : if (align)
1643 : {
1644 1284 : offset -= align;
1645 3389 : for (unsigned i = 0; i < align / BITS_PER_UNIT; i++)
1646 2105 : m_shadow_bytes.safe_push (0);
1647 : }
1648 :
1649 : /* Adjust m_prev_offset and m_shadow_mem. */
1650 4686 : HOST_WIDE_INT diff = offset - m_prev_offset;
1651 4686 : m_shadow_mem = adjust_address (m_shadow_mem, VOIDmode,
1652 : diff >> ASAN_SHADOW_SHIFT);
1653 4686 : m_prev_offset = offset;
1654 : }
1655 22777 : m_shadow_bytes.safe_push (value);
1656 22777 : flush_if_full ();
1657 22777 : }
1658 :
1659 : /* Emit RTX emission of the content of the buffer. */
1660 :
1661 : void
1662 6408 : asan_redzone_buffer::flush_redzone_payload (void)
1663 : {
1664 6408 : gcc_assert (WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN);
1665 :
1666 6408 : if (m_shadow_bytes.is_empty ())
1667 6408 : return;
1668 :
1669 : /* Be sure we always emit to an aligned address. */
1670 6408 : gcc_assert (((m_prev_offset - m_original_offset)
1671 : & (ASAN_RED_ZONE_SIZE - 1)) == 0);
1672 :
1673 : /* Fill it to RZ_BUFFER_SIZE bytes with zeros if needed. */
1674 : unsigned l = m_shadow_bytes.length ();
1675 13532 : for (unsigned i = 0; i <= RZ_BUFFER_SIZE - l; i++)
1676 7124 : m_shadow_bytes.safe_push (0);
1677 :
1678 6408 : if (dump_file && (dump_flags & TDF_DETAILS))
1679 0 : fprintf (dump_file,
1680 : "Flushing rzbuffer at offset %" PRId64 " with: ", m_prev_offset);
1681 :
1682 6408 : unsigned HOST_WIDE_INT val = 0;
1683 32040 : for (unsigned i = 0; i < RZ_BUFFER_SIZE; i++)
1684 : {
1685 25632 : unsigned char v
1686 25632 : = m_shadow_bytes[BYTES_BIG_ENDIAN ? RZ_BUFFER_SIZE - i - 1 : i];
1687 25632 : val |= (unsigned HOST_WIDE_INT)v << (BITS_PER_UNIT * i);
1688 25632 : if (dump_file && (dump_flags & TDF_DETAILS))
1689 0 : fprintf (dump_file, "%02x ", v);
1690 : }
1691 :
1692 6408 : if (dump_file && (dump_flags & TDF_DETAILS))
1693 0 : fprintf (dump_file, "\n");
1694 :
1695 6408 : rtx c = gen_int_mode (val, SImode);
1696 6408 : m_shadow_mem = adjust_address (m_shadow_mem, SImode, 0);
1697 6408 : emit_move_insn (m_shadow_mem, c);
1698 6408 : m_shadow_bytes.truncate (0);
1699 : }
1700 :
1701 : /* Flush if the content of the buffer is full
1702 : (equal to RZ_BUFFER_SIZE). */
1703 :
1704 : void
1705 22777 : asan_redzone_buffer::flush_if_full (void)
1706 : {
1707 22777 : if (m_shadow_bytes.length () == RZ_BUFFER_SIZE)
1708 6050 : flush_redzone_payload ();
1709 22777 : }
1710 :
1711 :
1712 : /* HWAddressSanitizer (hwasan) is a probabilistic method for detecting
1713 : out-of-bounds and use-after-free bugs.
1714 : Read more:
1715 : http://code.google.com/p/address-sanitizer/
1716 :
1717 : Similar to AddressSanitizer (asan) it consists of two parts: the
1718 : instrumentation module in this file, and a run-time library.
1719 :
1720 : The instrumentation module adds a run-time check before every memory insn in
1721 : the same manner as asan (see the block comment for AddressSanitizer above).
1722 : Currently, hwasan only adds out-of-line instrumentation, where each check is
1723 : implemented as a function call to the run-time library. Hence a check for a
1724 : load of N bytes from address X would be implemented with a function call to
1725 : __hwasan_loadN(X), and checking a store of N bytes from address X would be
1726 : implemented with a function call to __hwasan_storeN(X).
1727 :
1728 : The main difference between hwasan and asan is in the information stored to
1729 : help this checking. Both sanitizers use a shadow memory area which stores
1730 : data recording the state of main memory at a corresponding address.
1731 :
1732 : For hwasan, each 16 byte granule in main memory has a corresponding 1 byte
1733 : in shadow memory. This shadow address can be calculated with equation:
1734 : (addr >> log_2(HWASAN_TAG_GRANULE_SIZE))
1735 : + __hwasan_shadow_memory_dynamic_address;
1736 : The conversion between real and shadow memory for asan is given in the block
1737 : comment at the top of this file.
1738 : The description of how this shadow memory is laid out for asan is in the
1739 : block comment at the top of this file, here we describe how this shadow
1740 : memory is used for hwasan.
1741 :
1742 : For hwasan, each variable is assigned a byte-sized 'tag'. The extent of
1743 : the shadow memory for that variable is filled with the assigned tag, and
1744 : every pointer referencing that variable has its top byte set to the same
1745 : tag. The run-time library redefines malloc so that every allocation returns
1746 : a tagged pointer and tags the corresponding shadow memory with the same tag.
1747 :
1748 : On each pointer dereference the tag found in the pointer is compared to the
1749 : tag found in the shadow memory corresponding to the accessed memory address.
1750 : If these tags are found to differ then this memory access is judged to be
1751 : invalid and a report is generated.
1752 :
1753 : This method of bug detection is not perfect -- it can not catch every bad
1754 : access -- but catches them probabilistically instead. There is always the
1755 : possibility that an invalid memory access will happen to access memory
1756 : tagged with the same tag as the pointer that this access used.
1757 : The chances of this are approx. 0.4% for any two uncorrelated objects.
1758 :
1759 : Random tag generation can mitigate this problem by decreasing the
1760 : probability that an invalid access will be missed in the same manner over
1761 : multiple runs. i.e. if two objects are tagged the same in one run of the
1762 : binary they are unlikely to be tagged the same in the next run.
1763 : Both heap and stack allocated objects have random tags by default.
1764 :
1765 : [16 byte granule implications]
1766 : Since the shadow memory only has a resolution on real memory of 16 bytes,
1767 : invalid accesses that are within the same 16 byte granule as a valid
1768 : address will not be caught.
1769 :
1770 : There is a "short-granule" feature in the runtime library which does catch
1771 : such accesses, but this feature is not implemented for stack objects (since
1772 : stack objects are allocated and tagged by compiler instrumentation, and
1773 : this feature has not yet been implemented in GCC instrumentation).
1774 :
1775 : Another outcome of this 16 byte resolution is that each tagged object must
1776 : be 16 byte aligned. If two objects were to share any 16 byte granule in
1777 : memory, then they both would have to be given the same tag, and invalid
1778 : accesses to one using a pointer to the other would be undetectable.
1779 :
1780 : [Compiler instrumentation]
1781 : Compiler instrumentation ensures that two adjacent buffers on the stack are
1782 : given different tags, this means an access to one buffer using a pointer
1783 : generated from the other (e.g. through buffer overrun) will have mismatched
1784 : tags and be caught by hwasan.
1785 :
1786 : We don't randomly tag every object on the stack, since that would require
1787 : keeping many registers to record each tag. Instead we randomly generate a
1788 : tag for each function frame, and each new stack object uses a tag offset
1789 : from that frame tag.
1790 : i.e. each object is tagged as RFT + offset, where RFT is the "random frame
1791 : tag" generated for this frame.
1792 : This means that randomisation does not peturb the difference between tags
1793 : on tagged stack objects within a frame, but this is mitigated by the fact
1794 : that objects with the same tag within a frame are very far apart
1795 : (approx. 2^HWASAN_TAG_SIZE objects apart).
1796 :
1797 : As a demonstration, using the same example program as in the asan block
1798 : comment above:
1799 :
1800 : int
1801 : foo ()
1802 : {
1803 : char a[24] = {0};
1804 : int b[2] = {0};
1805 :
1806 : a[5] = 1;
1807 : b[1] = 2;
1808 :
1809 : return a[5] + b[1];
1810 : }
1811 :
1812 : On AArch64 the stack will be ordered as follows for the above function:
1813 :
1814 : Slot 1/ [24 bytes for variable 'a']
1815 : Slot 2/ [8 bytes padding for alignment]
1816 : Slot 3/ [8 bytes for variable 'b']
1817 : Slot 4/ [8 bytes padding for alignment]
1818 :
1819 : (The padding is there to ensure 16 byte alignment as described in the 16
1820 : byte granule implications).
1821 :
1822 : While the shadow memory will be ordered as follows:
1823 :
1824 : - 2 bytes (representing 32 bytes in real memory) tagged with RFT + 1.
1825 : - 1 byte (representing 16 bytes in real memory) tagged with RFT + 2.
1826 :
1827 : And any pointer to "a" will have the tag RFT + 1, and any pointer to "b"
1828 : will have the tag RFT + 2.
1829 :
1830 : [Top Byte Ignore requirements]
1831 : Hwasan requires the ability to store an 8 bit tag in every pointer. There
1832 : is no instrumentation done to remove this tag from pointers before
1833 : dereferencing, which means the hardware must ignore this tag during memory
1834 : accesses.
1835 :
1836 : Architectures where this feature is available should indicate this using
1837 : the TARGET_MEMTAG_CAN_TAG_ADDRESSES hook.
1838 :
1839 : [Stack requires cleanup on unwinding]
1840 : During normal operation of a hwasan sanitized program more space in the
1841 : shadow memory becomes tagged as the stack grows. As the stack shrinks this
1842 : shadow memory space must become untagged. If it is not untagged then when
1843 : the stack grows again (during other function calls later on in the program)
1844 : objects on the stack that are usually not tagged (e.g. parameters passed on
1845 : the stack) can be placed in memory whose shadow space is tagged with
1846 : something else, and accesses can cause false positive reports.
1847 :
1848 : Hence we place untagging code on every epilogue of functions which tag some
1849 : stack objects.
1850 :
1851 : Moreover, the run-time library intercepts longjmp & setjmp to untag when
1852 : the stack is unwound this way.
1853 :
1854 : C++ exceptions are not yet handled, which means this sanitizer can not
1855 : handle C++ code that throws exceptions -- it will give false positives
1856 : after an exception has been thrown. The implementation that the hwasan
1857 : library has for handling these relies on the frame pointer being after any
1858 : local variables. This is not generally the case for GCC. */
1859 :
1860 :
1861 : /* Returns whether we are tagging pointers and checking those tags on memory
1862 : access. */
1863 : bool
1864 36857417 : hwasan_sanitize_p ()
1865 : {
1866 36857417 : return sanitize_flags_p (SANITIZE_HWADDRESS);
1867 : }
1868 :
1869 : /* Are we tagging the stack? */
1870 : bool
1871 34987087 : hwasan_sanitize_stack_p ()
1872 : {
1873 34987087 : return (hwasan_sanitize_p () && param_hwasan_instrument_stack);
1874 : }
1875 :
1876 : /* Are we tagging alloca objects? */
1877 : bool
1878 1512391 : hwasan_sanitize_allocas_p (void)
1879 : {
1880 1512391 : return (hwasan_sanitize_stack_p () && param_hwasan_instrument_allocas);
1881 : }
1882 :
1883 : /* Should we instrument reads? */
1884 : bool
1885 371 : hwasan_instrument_reads (void)
1886 : {
1887 371 : return (hwasan_sanitize_p () && param_hwasan_instrument_reads);
1888 : }
1889 :
1890 : /* Should we instrument writes? */
1891 : bool
1892 213 : hwasan_instrument_writes (void)
1893 : {
1894 213 : return (hwasan_sanitize_p () && param_hwasan_instrument_writes);
1895 : }
1896 :
1897 : /* Should we instrument builtin calls? */
1898 : bool
1899 94 : hwasan_memintrin (void)
1900 : {
1901 94 : return (hwasan_sanitize_p () && param_hwasan_instrument_mem_intrinsics);
1902 : }
1903 :
1904 : /* MEMoryTAGging sanitizer (MEMTAG) uses a hardware based capability known as
1905 : memory tagging to detect memory safety vulnerabilities. Similar to HWASAN,
1906 : it is also a probabilistic method.
1907 :
1908 : MEMTAG relies on the optional extension in armv8.5a known as MTE (Memory
1909 : Tagging Extension). The extension is available in AArch64 only and
1910 : introduces two types of tags:
1911 : - Logical Address Tag - bits 56-59 (TARGET_MEMTAG_TAG_BITSIZE) of the
1912 : virtual address.
1913 : - Allocation Tag - 4 bits for each tag granule (TARGET_MEMTAG_GRANULE_SIZE
1914 : set to 16 bytes), stored separately.
1915 : Load / store instructions raise an exception if tags differ, thereby
1916 : providing a faster way (than HWASAN) to detect memory safety issues.
1917 : Further, new instructions are available in MTE to manipulate (generate,
1918 : update address with) tags. Load / store instructions with SP base register
1919 : and immediate offset do not check tags.
1920 :
1921 : PS: Currently, MEMTAG sanitizer is capable of stack (variable / memory)
1922 : tagging only.
1923 :
1924 : In general, detecting stack-related memory bugs requires the compiler to:
1925 : - ensure that each tag granule is only used by one variable at a time.
1926 : This includes alloca.
1927 : - Tag/Color: put tags into each stack variable pointer.
1928 : - Untag: the function epilogue will retag the memory.
1929 :
1930 : MEMTAG sanitizer is based off the HWASAN sanitizer implementation
1931 : internally. Similar to HWASAN:
1932 : - Assigning an independently random tag to each variable is carried out by
1933 : keeping a tagged base pointer. A tagged base pointer allows addressing
1934 : variables with (addr offset, tag offset).
1935 : */
1936 :
1937 : /* Returns whether we are tagging pointers and checking those tags on memory
1938 : access. */
1939 : bool
1940 3106743 : memtag_sanitize_p ()
1941 : {
1942 3106743 : return sanitize_flags_p (SANITIZE_MEMTAG);
1943 : }
1944 :
1945 : /* Are we tagging the stack? */
1946 : bool
1947 33456605 : memtag_sanitize_stack_p ()
1948 : {
1949 33456605 : return (sanitize_flags_p (SANITIZE_MEMTAG_STACK));
1950 : }
1951 :
1952 : /* Are we tagging alloca objects? */
1953 : bool
1954 404 : memtag_sanitize_allocas_p (void)
1955 : {
1956 404 : return (memtag_sanitize_stack_p () && param_memtag_instrument_allocas);
1957 : }
1958 :
1959 : /* Are we taggin mem intrinsics? */
1960 : bool
1961 24 : memtag_memintrin (void)
1962 : {
1963 24 : return (memtag_sanitize_p () && param_memtag_instrument_mem_intrinsics);
1964 : }
1965 :
1966 : /* Returns whether we are tagging pointers and checking those tags on memory
1967 : access. */
1968 : bool
1969 90725 : hwassist_sanitize_p ()
1970 : {
1971 90725 : return (hwasan_sanitize_p () || memtag_sanitize_p ());
1972 : }
1973 :
1974 : /* Are we tagging stack objects for hwasan or memtag? */
1975 : bool
1976 33460956 : hwassist_sanitize_stack_p ()
1977 : {
1978 33460956 : return (hwasan_sanitize_stack_p () || memtag_sanitize_stack_p ());
1979 : }
1980 :
1981 : /* Insert code to protect stack vars. The prologue sequence should be emitted
1982 : directly, epilogue sequence returned. BASE is the register holding the
1983 : stack base, against which OFFSETS array offsets are relative to, OFFSETS
1984 : array contains pairs of offsets in reverse order, always the end offset
1985 : of some gap that needs protection followed by starting offset,
1986 : and DECLS is an array of representative decls for each var partition.
1987 : LENGTH is the length of the OFFSETS array, DECLS array is LENGTH / 2 - 1
1988 : elements long (OFFSETS include gap before the first variable as well
1989 : as gaps after each stack variable). PBASE is, if non-NULL, some pseudo
1990 : register which stack vars DECL_RTLs are based on. Either BASE should be
1991 : assigned to PBASE, when not doing use after return protection, or
1992 : corresponding address based on __asan_stack_malloc* return value. */
1993 :
1994 : rtx_insn *
1995 1722 : asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
1996 : HOST_WIDE_INT *offsets, tree *decls, int length)
1997 : {
1998 1722 : rtx shadow_base, shadow_mem, ret, mem, orig_base;
1999 1722 : rtx_code_label *lab;
2000 1722 : rtx_insn *insns;
2001 1722 : char buf[32];
2002 1722 : HOST_WIDE_INT base_offset = offsets[length - 1];
2003 1722 : HOST_WIDE_INT base_align_bias = 0, offset, prev_offset;
2004 1722 : HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset;
2005 1722 : HOST_WIDE_INT last_offset, last_size, last_size_aligned;
2006 1722 : int l;
2007 1722 : unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT;
2008 1722 : tree str_cst, decl, id;
2009 1722 : int use_after_return_class = -1;
2010 :
2011 : /* Don't emit anything when doing error recovery, the assertions
2012 : might fail e.g. if a function had a frame offset overflow. */
2013 1722 : if (seen_error ())
2014 : return NULL;
2015 :
2016 1722 : if (shadow_ptr_types[0] == NULL_TREE)
2017 0 : asan_init_shadow_ptr_types ();
2018 :
2019 1722 : expanded_location cfun_xloc
2020 1722 : = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
2021 :
2022 : /* First of all, prepare the description string. */
2023 1722 : pretty_printer asan_pp;
2024 :
2025 1722 : pp_decimal_int (&asan_pp, length / 2 - 1);
2026 1722 : pp_space (&asan_pp);
2027 5028 : for (l = length - 2; l; l -= 2)
2028 : {
2029 3306 : tree decl = decls[l / 2 - 1];
2030 3306 : pp_wide_integer (&asan_pp, offsets[l] - base_offset);
2031 3306 : pp_space (&asan_pp);
2032 3306 : pp_wide_integer (&asan_pp, offsets[l - 1] - offsets[l]);
2033 3306 : pp_space (&asan_pp);
2034 :
2035 3306 : expanded_location xloc
2036 3306 : = expand_location (DECL_SOURCE_LOCATION (decl));
2037 3306 : char location[32];
2038 :
2039 3306 : if (xloc.file == cfun_xloc.file)
2040 3082 : sprintf (location, ":%d", xloc.line);
2041 : else
2042 224 : location[0] = '\0';
2043 :
2044 3306 : if (DECL_P (decl) && DECL_NAME (decl))
2045 : {
2046 2758 : unsigned idlen
2047 2758 : = IDENTIFIER_LENGTH (DECL_NAME (decl)) + strlen (location);
2048 2758 : pp_decimal_int (&asan_pp, idlen);
2049 2758 : pp_space (&asan_pp);
2050 2758 : pp_tree_identifier (&asan_pp, DECL_NAME (decl));
2051 2758 : pp_string (&asan_pp, location);
2052 : }
2053 : else
2054 548 : pp_string (&asan_pp, "9 <unknown>");
2055 :
2056 3306 : if (l > 2)
2057 1584 : pp_space (&asan_pp);
2058 : }
2059 1722 : str_cst = asan_pp_string (&asan_pp);
2060 :
2061 3383 : gcc_checking_assert (offsets[0] == (crtl->stack_protect_guard
2062 : ? -ASAN_RED_ZONE_SIZE : 0));
2063 : /* Emit the prologue sequence. */
2064 1722 : if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase
2065 1691 : && param_asan_use_after_return)
2066 : {
2067 1657 : HOST_WIDE_INT adjusted_frame_size = asan_frame_size;
2068 : /* The stack protector guard is allocated at the top of the frame
2069 : and cfgexpand.cc then uses align_frame_offset (ASAN_RED_ZONE_SIZE);
2070 : while in that case we can still use asan_frame_size, we need to take
2071 : that into account when computing base_align_bias. */
2072 1657 : if (alignb > ASAN_RED_ZONE_SIZE && crtl->stack_protect_guard)
2073 28 : adjusted_frame_size += ASAN_RED_ZONE_SIZE;
2074 1657 : use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
2075 : /* __asan_stack_malloc_N guarantees alignment
2076 : N < 6 ? (64 << N) : 4096 bytes. */
2077 1657 : if (alignb > (use_after_return_class < 6
2078 1657 : ? (64U << use_after_return_class) : 4096U))
2079 : use_after_return_class = -1;
2080 1657 : else if (alignb > ASAN_RED_ZONE_SIZE
2081 54 : && (adjusted_frame_size & (alignb - 1)))
2082 : {
2083 28 : base_align_bias
2084 28 : = ((adjusted_frame_size + alignb - 1)
2085 28 : & ~(alignb - HOST_WIDE_INT_1)) - adjusted_frame_size;
2086 28 : use_after_return_class
2087 28 : = floor_log2 (asan_frame_size + base_align_bias - 1) - 5;
2088 28 : if (use_after_return_class > 10)
2089 : {
2090 65 : base_align_bias = 0;
2091 65 : use_after_return_class = -1;
2092 : }
2093 : }
2094 : }
2095 :
2096 : /* Align base if target is STRICT_ALIGNMENT. */
2097 1722 : if (STRICT_ALIGNMENT)
2098 : {
2099 : const HOST_WIDE_INT align
2100 : = (GET_MODE_ALIGNMENT (SImode) / BITS_PER_UNIT) << ASAN_SHADOW_SHIFT;
2101 : base = expand_binop (Pmode, and_optab, base, gen_int_mode (-align, Pmode),
2102 : NULL_RTX, 1, OPTAB_DIRECT);
2103 : }
2104 :
2105 1722 : if (use_after_return_class == -1 && pbase)
2106 65 : emit_move_insn (pbase, base);
2107 :
2108 1722 : base = expand_binop (Pmode, add_optab, base,
2109 1722 : gen_int_mode (base_offset - base_align_bias, Pmode),
2110 : NULL_RTX, 1, OPTAB_DIRECT);
2111 1722 : orig_base = NULL_RTX;
2112 1722 : if (use_after_return_class != -1)
2113 : {
2114 1657 : if (asan_detect_stack_use_after_return == NULL_TREE)
2115 : {
2116 1210 : id = get_identifier ("__asan_option_detect_stack_use_after_return");
2117 1210 : decl = build_decl (BUILTINS_LOCATION, VAR_DECL, id,
2118 : integer_type_node);
2119 1210 : SET_DECL_ASSEMBLER_NAME (decl, id);
2120 1210 : TREE_ADDRESSABLE (decl) = 1;
2121 1210 : DECL_ARTIFICIAL (decl) = 1;
2122 1210 : DECL_IGNORED_P (decl) = 1;
2123 1210 : DECL_EXTERNAL (decl) = 1;
2124 1210 : TREE_STATIC (decl) = 1;
2125 1210 : TREE_PUBLIC (decl) = 1;
2126 1210 : TREE_USED (decl) = 1;
2127 1210 : asan_detect_stack_use_after_return = decl;
2128 : }
2129 1657 : orig_base = gen_reg_rtx (Pmode);
2130 1657 : emit_move_insn (orig_base, base);
2131 1657 : ret = expand_normal (asan_detect_stack_use_after_return);
2132 1657 : lab = gen_label_rtx ();
2133 1657 : emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
2134 : VOIDmode, 0, lab,
2135 : profile_probability::very_likely ());
2136 1657 : snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
2137 : use_after_return_class);
2138 1657 : ret = init_one_libfunc (buf);
2139 1657 : ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode,
2140 : GEN_INT (asan_frame_size
2141 : + base_align_bias),
2142 1657 : TYPE_MODE (pointer_sized_int_node));
2143 : /* __asan_stack_malloc_[n] returns a pointer to fake stack if succeeded
2144 : and NULL otherwise. Check RET value is NULL here and jump over the
2145 : BASE reassignment in this case. Otherwise, reassign BASE to RET. */
2146 1657 : emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
2147 : VOIDmode, 0, lab,
2148 : profile_probability:: very_unlikely ());
2149 1657 : ret = convert_memory_address (Pmode, ret);
2150 1657 : emit_move_insn (base, ret);
2151 1657 : emit_label (lab);
2152 1657 : emit_move_insn (pbase, expand_binop (Pmode, add_optab, base,
2153 : gen_int_mode (base_align_bias
2154 1657 : - base_offset, Pmode),
2155 : NULL_RTX, 1, OPTAB_DIRECT));
2156 : }
2157 1722 : mem = gen_rtx_MEM (ptr_mode, base);
2158 1722 : mem = adjust_address (mem, VOIDmode, base_align_bias);
2159 1722 : emit_move_insn (mem, gen_int_mode (ASAN_STACK_FRAME_MAGIC, ptr_mode));
2160 3444 : mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
2161 1722 : emit_move_insn (mem, expand_normal (str_cst));
2162 3444 : mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
2163 1722 : ASM_GENERATE_INTERNAL_LABEL (buf, "LASANPC", current_function_funcdef_no);
2164 1722 : id = get_identifier (buf);
2165 1722 : decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
2166 : VAR_DECL, id, char_type_node);
2167 1722 : SET_DECL_ASSEMBLER_NAME (decl, id);
2168 1722 : TREE_ADDRESSABLE (decl) = 1;
2169 1722 : TREE_READONLY (decl) = 1;
2170 1722 : DECL_ARTIFICIAL (decl) = 1;
2171 1722 : DECL_IGNORED_P (decl) = 1;
2172 1722 : TREE_STATIC (decl) = 1;
2173 1722 : TREE_PUBLIC (decl) = 0;
2174 1722 : TREE_USED (decl) = 1;
2175 1722 : DECL_INITIAL (decl) = decl;
2176 1722 : TREE_ASM_WRITTEN (decl) = 1;
2177 1722 : TREE_ASM_WRITTEN (id) = 1;
2178 1722 : DECL_ALIGN_RAW (decl) = DECL_ALIGN_RAW (current_function_decl);
2179 1722 : emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
2180 1722 : shadow_base = expand_binop (Pmode, lshr_optab, base,
2181 1722 : gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT),
2182 : NULL_RTX, 1, OPTAB_DIRECT);
2183 1722 : if (asan_dynamic_shadow_offset_p ())
2184 : {
2185 0 : ret = expand_normal (get_asan_shadow_memory_dynamic_address_decl ());
2186 0 : shadow_base
2187 0 : = expand_simple_binop (Pmode, PLUS, shadow_base, ret, NULL_RTX,
2188 : /* unsignedp = */ 1, OPTAB_WIDEN);
2189 0 : shadow_base = plus_constant (Pmode, shadow_base,
2190 0 : (base_align_bias >> ASAN_SHADOW_SHIFT));
2191 : }
2192 : else
2193 : {
2194 1722 : shadow_base = plus_constant (Pmode, shadow_base,
2195 1722 : asan_shadow_offset ()
2196 1722 : + (base_align_bias >> ASAN_SHADOW_SHIFT));
2197 : }
2198 1722 : gcc_assert (asan_shadow_set != -1
2199 : && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
2200 1722 : shadow_mem = gen_rtx_MEM (SImode, shadow_base);
2201 1722 : set_mem_alias_set (shadow_mem, asan_shadow_set);
2202 1722 : if (STRICT_ALIGNMENT)
2203 : set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
2204 1722 : prev_offset = base_offset;
2205 :
2206 1722 : asan_redzone_buffer rz_buffer (shadow_mem, prev_offset);
2207 8472 : for (l = length; l; l -= 2)
2208 : {
2209 5028 : if (l == 2)
2210 1722 : cur_shadow_byte = ASAN_STACK_MAGIC_RIGHT;
2211 5028 : offset = offsets[l - 1];
2212 :
2213 5028 : bool extra_byte = (offset - base_offset) & (ASAN_SHADOW_GRANULARITY - 1);
2214 : /* If a red-zone is not aligned to ASAN_SHADOW_GRANULARITY then
2215 : the previous stack variable has size % ASAN_SHADOW_GRANULARITY != 0.
2216 : In that case we have to emit one extra byte that will describe
2217 : how many bytes (our of ASAN_SHADOW_GRANULARITY) can be accessed. */
2218 5028 : if (extra_byte)
2219 : {
2220 1498 : HOST_WIDE_INT aoff
2221 1498 : = base_offset + ((offset - base_offset)
2222 1498 : & ~(ASAN_SHADOW_GRANULARITY - HOST_WIDE_INT_1));
2223 1498 : rz_buffer.emit_redzone_byte (aoff, offset - aoff);
2224 1498 : offset = aoff + ASAN_SHADOW_GRANULARITY;
2225 : }
2226 :
2227 : /* Calculate size of red zone payload. */
2228 26307 : while (offset < offsets[l - 2])
2229 : {
2230 21279 : rz_buffer.emit_redzone_byte (offset, cur_shadow_byte);
2231 21279 : offset += ASAN_SHADOW_GRANULARITY;
2232 : }
2233 :
2234 5028 : cur_shadow_byte = ASAN_STACK_MAGIC_MIDDLE;
2235 : }
2236 :
2237 : /* As the automatic variables are aligned to
2238 : ASAN_RED_ZONE_SIZE / ASAN_SHADOW_GRANULARITY, the buffer should be
2239 : flushed here. */
2240 1722 : gcc_assert (rz_buffer.m_shadow_bytes.is_empty ());
2241 :
2242 1722 : do_pending_stack_adjust ();
2243 :
2244 : /* Construct epilogue sequence. */
2245 1722 : start_sequence ();
2246 :
2247 1722 : lab = NULL;
2248 1722 : if (use_after_return_class != -1)
2249 : {
2250 1657 : rtx_code_label *lab2 = gen_label_rtx ();
2251 1657 : char c = (char) ASAN_STACK_MAGIC_USE_AFTER_RET;
2252 1657 : emit_cmp_and_jump_insns (orig_base, base, EQ, NULL_RTX,
2253 : VOIDmode, 0, lab2,
2254 : profile_probability::very_likely ());
2255 1657 : shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
2256 1657 : set_mem_alias_set (shadow_mem, asan_shadow_set);
2257 1657 : mem = gen_rtx_MEM (ptr_mode, base);
2258 1657 : mem = adjust_address (mem, VOIDmode, base_align_bias);
2259 1657 : emit_move_insn (mem, gen_int_mode (ASAN_STACK_RETIRED_MAGIC, ptr_mode));
2260 1657 : unsigned HOST_WIDE_INT sz = asan_frame_size >> ASAN_SHADOW_SHIFT;
2261 1657 : bool asan_stack_free_emitted_p = false;
2262 1657 : if (use_after_return_class < 5
2263 1657 : && can_store_by_pieces (sz, builtin_memset_read_str, &c,
2264 : BITS_PER_UNIT, true))
2265 : /* Emit memset (ShadowBase, kAsanStackAfterReturnMagic, ShadowSize). */
2266 1532 : store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c,
2267 : BITS_PER_UNIT, true, RETURN_BEGIN);
2268 125 : else if (use_after_return_class >= 5
2269 142 : || !set_storage_via_setmem (shadow_mem,
2270 : GEN_INT (sz),
2271 17 : gen_int_mode (c, QImode),
2272 : BITS_PER_UNIT, BITS_PER_UNIT,
2273 : -1, sz, sz, sz))
2274 : {
2275 108 : snprintf (buf, sizeof buf, "__asan_stack_free_%d",
2276 : use_after_return_class);
2277 108 : ret = init_one_libfunc (buf);
2278 108 : rtx addr = convert_memory_address (ptr_mode, base);
2279 108 : rtx orig_addr = convert_memory_address (ptr_mode, orig_base);
2280 216 : emit_library_call (ret, LCT_NORMAL, ptr_mode, addr, ptr_mode,
2281 : GEN_INT (asan_frame_size + base_align_bias),
2282 108 : TYPE_MODE (pointer_sized_int_node),
2283 : orig_addr, ptr_mode);
2284 108 : asan_stack_free_emitted_p = true;
2285 : }
2286 1657 : if (!asan_stack_free_emitted_p)
2287 : {
2288 : /* Emit **SavedFlagPtr (FakeStack, class_id) = 0. */
2289 1549 : unsigned HOST_WIDE_INT offset = (1 << (use_after_return_class + 6));
2290 1549 : offset -= GET_MODE_SIZE (ptr_mode);
2291 1549 : mem = gen_rtx_MEM (ptr_mode, base);
2292 1549 : mem = adjust_address (mem, ptr_mode, offset);
2293 1549 : rtx addr = gen_reg_rtx (ptr_mode);
2294 1549 : emit_move_insn (addr, mem);
2295 1549 : addr = convert_memory_address (Pmode, addr);
2296 1549 : mem = gen_rtx_MEM (QImode, addr);
2297 1549 : emit_move_insn (mem, const0_rtx);
2298 : }
2299 1657 : lab = gen_label_rtx ();
2300 1657 : emit_jump (lab);
2301 1657 : emit_label (lab2);
2302 : }
2303 :
2304 1722 : shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
2305 1722 : set_mem_alias_set (shadow_mem, asan_shadow_set);
2306 :
2307 1722 : if (STRICT_ALIGNMENT)
2308 : set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
2309 :
2310 1722 : prev_offset = base_offset;
2311 1722 : last_offset = base_offset;
2312 1722 : last_size = 0;
2313 1722 : last_size_aligned = 0;
2314 8472 : for (l = length; l; l -= 2)
2315 : {
2316 5028 : offset = base_offset + ((offsets[l - 1] - base_offset)
2317 5028 : & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
2318 5028 : if (last_offset + last_size_aligned < offset)
2319 : {
2320 676 : shadow_mem = adjust_address (shadow_mem, VOIDmode,
2321 : (last_offset - prev_offset)
2322 : >> ASAN_SHADOW_SHIFT);
2323 676 : prev_offset = last_offset;
2324 676 : asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT);
2325 676 : last_offset = offset;
2326 676 : last_size = 0;
2327 : }
2328 : else
2329 4352 : last_size = offset - last_offset;
2330 5028 : last_size += base_offset + ((offsets[l - 2] - base_offset)
2331 5028 : & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
2332 5028 : - offset;
2333 :
2334 : /* Unpoison shadow memory that corresponds to a variable that is
2335 : is subject of use-after-return sanitization. */
2336 5028 : if (l > 2)
2337 : {
2338 3306 : decl = decls[l / 2 - 2];
2339 3306 : if (asan_handled_variables != NULL
2340 3306 : && asan_handled_variables->contains (decl))
2341 : {
2342 871 : HOST_WIDE_INT size = offsets[l - 3] - offsets[l - 2];
2343 871 : if (dump_file && (dump_flags & TDF_DETAILS))
2344 : {
2345 0 : const char *n = (DECL_NAME (decl)
2346 0 : ? IDENTIFIER_POINTER (DECL_NAME (decl))
2347 0 : : "<unknown>");
2348 0 : fprintf (dump_file, "Unpoisoning shadow stack for variable: "
2349 : "%s (%" PRId64 " B)\n", n, size);
2350 : }
2351 :
2352 871 : last_size += size & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1);
2353 : }
2354 : }
2355 5028 : last_size_aligned
2356 5028 : = ((last_size + (ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
2357 : & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
2358 : }
2359 1722 : if (last_size_aligned)
2360 : {
2361 1722 : shadow_mem = adjust_address (shadow_mem, VOIDmode,
2362 : (last_offset - prev_offset)
2363 : >> ASAN_SHADOW_SHIFT);
2364 1722 : asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT);
2365 : }
2366 :
2367 : /* Clean-up set with instrumented stack variables. */
2368 2109 : delete asan_handled_variables;
2369 1722 : asan_handled_variables = NULL;
2370 1817 : delete asan_used_labels;
2371 1722 : asan_used_labels = NULL;
2372 :
2373 1722 : do_pending_stack_adjust ();
2374 1722 : if (lab)
2375 1657 : emit_label (lab);
2376 :
2377 1722 : insns = end_sequence ();
2378 1722 : return insns;
2379 1722 : }
2380 :
2381 : /* Emit __asan_allocas_unpoison (top, bot) call. The BASE parameter corresponds
2382 : to BOT argument, for TOP virtual_stack_dynamic_rtx is used. NEW_SEQUENCE
2383 : indicates whether we're emitting new instructions sequence or not. */
2384 :
2385 : rtx_insn *
2386 178 : asan_emit_allocas_unpoison (rtx top, rtx bot, rtx_insn *before)
2387 : {
2388 178 : if (before)
2389 38 : push_to_sequence (before);
2390 : else
2391 140 : start_sequence ();
2392 178 : rtx ret = init_one_libfunc ("__asan_allocas_unpoison");
2393 178 : top = convert_memory_address (ptr_mode, top);
2394 178 : bot = convert_memory_address (ptr_mode, bot);
2395 178 : emit_library_call (ret, LCT_NORMAL, ptr_mode,
2396 : top, ptr_mode, bot, ptr_mode);
2397 :
2398 178 : do_pending_stack_adjust ();
2399 178 : return end_sequence ();
2400 : }
2401 :
2402 : /* Return true if DECL, a global var, might be overridden and needs
2403 : therefore a local alias. */
2404 :
2405 : static bool
2406 4156 : asan_needs_local_alias (tree decl)
2407 : {
2408 4156 : return DECL_WEAK (decl) || !targetm.binds_local_p (decl);
2409 : }
2410 :
2411 : /* Return true if DECL, a global var, is an artificial ODR indicator symbol
2412 : therefore doesn't need protection. */
2413 :
2414 : static bool
2415 8651 : is_odr_indicator (tree decl)
2416 : {
2417 8651 : return (DECL_ARTIFICIAL (decl)
2418 8651 : && lookup_attribute ("asan odr indicator", DECL_ATTRIBUTES (decl)));
2419 : }
2420 :
2421 : /* Return true if DECL is a VAR_DECL that should be protected
2422 : by Address Sanitizer, by appending a red zone with protected
2423 : shadow memory after it and aligning it to at least
2424 : ASAN_RED_ZONE_SIZE bytes. */
2425 :
2426 : bool
2427 22843 : asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
2428 : {
2429 22843 : if (!param_asan_globals)
2430 : return false;
2431 :
2432 22680 : rtx rtl, symbol;
2433 :
2434 22680 : if (TREE_CODE (decl) == STRING_CST)
2435 : {
2436 : /* Instrument all STRING_CSTs except those created
2437 : by asan_pp_string here. */
2438 13578 : if (shadow_ptr_types[0] != NULL_TREE
2439 13544 : && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
2440 27122 : && TREE_TYPE (TREE_TYPE (decl)) == TREE_TYPE (shadow_ptr_types[0]))
2441 : return false;
2442 6822 : return true;
2443 : }
2444 9102 : if (!VAR_P (decl)
2445 : /* TLS vars aren't statically protectable. */
2446 9102 : || DECL_THREAD_LOCAL_P (decl)
2447 : /* Externs will be protected elsewhere. */
2448 9096 : || DECL_EXTERNAL (decl)
2449 : /* PR sanitizer/81697: For architectures that use section anchors first
2450 : call to asan_protect_global may occur before DECL_RTL (decl) is set.
2451 : We should ignore DECL_RTL_SET_P then, because otherwise the first call
2452 : to asan_protect_global will return FALSE and the following calls on the
2453 : same decl after setting DECL_RTL (decl) will return TRUE and we'll end
2454 : up with inconsistency at runtime. */
2455 9096 : || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)
2456 : /* Comdat vars pose an ABI problem, we can't know if
2457 : the var that is selected by the linker will have
2458 : padding or not. */
2459 9084 : || DECL_ONE_ONLY (decl)
2460 : /* Similarly for common vars. People can use -fno-common.
2461 : Note: Linux kernel is built with -fno-common, so we do instrument
2462 : globals there even if it is C. */
2463 8801 : || (DECL_COMMON (decl) && TREE_PUBLIC (decl))
2464 : /* Don't protect if using user section, often vars placed
2465 : into user section from multiple TUs are then assumed
2466 : to be an array of such vars, putting padding in there
2467 : breaks this assumption. */
2468 8801 : || (DECL_SECTION_NAME (decl) != NULL
2469 270 : && !symtab_node::get (decl)->implicit_section
2470 270 : && !section_sanitized_p (DECL_SECTION_NAME (decl)))
2471 : /* Don't protect variables in non-generic address-space. */
2472 8711 : || !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)))
2473 8709 : || DECL_SIZE (decl) == 0
2474 8709 : || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT
2475 8709 : || TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
2476 8709 : || !valid_constant_size_p (DECL_SIZE_UNIT (decl))
2477 8709 : || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE
2478 8651 : || TREE_TYPE (decl) == ubsan_get_source_location_type ()
2479 17753 : || is_odr_indicator (decl))
2480 : return false;
2481 :
2482 8651 : if (!ignore_decl_rtl_set_p || DECL_RTL_SET_P (decl))
2483 : {
2484 :
2485 8651 : rtl = DECL_RTL (decl);
2486 8651 : if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
2487 : return false;
2488 8651 : symbol = XEXP (rtl, 0);
2489 :
2490 8651 : if (CONSTANT_POOL_ADDRESS_P (symbol)
2491 8651 : || TREE_CONSTANT_POOL_ADDRESS_P (symbol))
2492 : return false;
2493 : }
2494 :
2495 8651 : if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
2496 0 : return false;
2497 :
2498 : if (!TARGET_SUPPORTS_ALIASES && asan_needs_local_alias (decl))
2499 : return false;
2500 :
2501 : return true;
2502 : }
2503 :
2504 : /* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16,_n}.
2505 : IS_STORE is either 1 (for a store) or 0 (for a load). */
2506 :
2507 : static tree
2508 18922 : report_error_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
2509 : int *nargs)
2510 : {
2511 18922 : gcc_assert (!hwassist_sanitize_p ());
2512 :
2513 18922 : static enum built_in_function report[2][2][6]
2514 : = { { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
2515 : BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
2516 : BUILT_IN_ASAN_REPORT_LOAD16, BUILT_IN_ASAN_REPORT_LOAD_N },
2517 : { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
2518 : BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
2519 : BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } },
2520 : { { BUILT_IN_ASAN_REPORT_LOAD1_NOABORT,
2521 : BUILT_IN_ASAN_REPORT_LOAD2_NOABORT,
2522 : BUILT_IN_ASAN_REPORT_LOAD4_NOABORT,
2523 : BUILT_IN_ASAN_REPORT_LOAD8_NOABORT,
2524 : BUILT_IN_ASAN_REPORT_LOAD16_NOABORT,
2525 : BUILT_IN_ASAN_REPORT_LOAD_N_NOABORT },
2526 : { BUILT_IN_ASAN_REPORT_STORE1_NOABORT,
2527 : BUILT_IN_ASAN_REPORT_STORE2_NOABORT,
2528 : BUILT_IN_ASAN_REPORT_STORE4_NOABORT,
2529 : BUILT_IN_ASAN_REPORT_STORE8_NOABORT,
2530 : BUILT_IN_ASAN_REPORT_STORE16_NOABORT,
2531 : BUILT_IN_ASAN_REPORT_STORE_N_NOABORT } } };
2532 18922 : if (size_in_bytes == -1)
2533 : {
2534 1008 : *nargs = 2;
2535 1008 : return builtin_decl_implicit (report[recover_p][is_store][5]);
2536 : }
2537 17914 : int size_log2 = exact_log2 (size_in_bytes);
2538 17914 : if (size_log2 == -1 || size_log2 >= 5)
2539 : {
2540 28 : *nargs = 2;
2541 28 : return builtin_decl_implicit (report[recover_p][is_store][5]);
2542 : }
2543 17886 : *nargs = 1;
2544 17886 : return builtin_decl_implicit (report[recover_p][is_store][size_log2]);
2545 : }
2546 :
2547 : /* Construct a function tree for __asan_{load,store}{1,2,4,8,16,_n}.
2548 : IS_STORE is either 1 (for a store) or 0 (for a load). */
2549 :
2550 : static tree
2551 103 : check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
2552 : int *nargs)
2553 : {
2554 103 : static enum built_in_function check[2][2][6]
2555 : = { { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2,
2556 : BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8,
2557 : BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN },
2558 : { BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2,
2559 : BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8,
2560 : BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } },
2561 : { { BUILT_IN_ASAN_LOAD1_NOABORT,
2562 : BUILT_IN_ASAN_LOAD2_NOABORT,
2563 : BUILT_IN_ASAN_LOAD4_NOABORT,
2564 : BUILT_IN_ASAN_LOAD8_NOABORT,
2565 : BUILT_IN_ASAN_LOAD16_NOABORT,
2566 : BUILT_IN_ASAN_LOADN_NOABORT },
2567 : { BUILT_IN_ASAN_STORE1_NOABORT,
2568 : BUILT_IN_ASAN_STORE2_NOABORT,
2569 : BUILT_IN_ASAN_STORE4_NOABORT,
2570 : BUILT_IN_ASAN_STORE8_NOABORT,
2571 : BUILT_IN_ASAN_STORE16_NOABORT,
2572 : BUILT_IN_ASAN_STOREN_NOABORT } } };
2573 103 : if (size_in_bytes == -1)
2574 : {
2575 28 : *nargs = 2;
2576 28 : return builtin_decl_implicit (check[recover_p][is_store][5]);
2577 : }
2578 75 : *nargs = 1;
2579 75 : int size_log2 = exact_log2 (size_in_bytes);
2580 75 : return builtin_decl_implicit (check[recover_p][is_store][size_log2]);
2581 : }
2582 :
2583 : /* Split the current basic block and create a condition statement
2584 : insertion point right before or after the statement pointed to by
2585 : ITER. Return an iterator to the point at which the caller might
2586 : safely insert the condition statement.
2587 :
2588 : THEN_BLOCK must be set to the address of an uninitialized instance
2589 : of basic_block. The function will then set *THEN_BLOCK to the
2590 : 'then block' of the condition statement to be inserted by the
2591 : caller.
2592 :
2593 : If CREATE_THEN_FALLTHRU_EDGE is false, no edge will be created from
2594 : *THEN_BLOCK to *FALLTHROUGH_BLOCK.
2595 :
2596 : Similarly, the function will set *FALLTRHOUGH_BLOCK to the 'else
2597 : block' of the condition statement to be inserted by the caller.
2598 :
2599 : Note that *FALLTHROUGH_BLOCK is a new block that contains the
2600 : statements starting from *ITER, and *THEN_BLOCK is a new empty
2601 : block.
2602 :
2603 : *ITER is adjusted to point to always point to the first statement
2604 : of the basic block * FALLTHROUGH_BLOCK. That statement is the
2605 : same as what ITER was pointing to prior to calling this function,
2606 : if BEFORE_P is true; otherwise, it is its following statement. */
2607 :
2608 : gimple_stmt_iterator
2609 23118 : create_cond_insert_point (gimple_stmt_iterator *iter,
2610 : bool before_p,
2611 : bool then_more_likely_p,
2612 : bool create_then_fallthru_edge,
2613 : basic_block *then_block,
2614 : basic_block *fallthrough_block)
2615 : {
2616 23118 : gimple_stmt_iterator gsi = *iter;
2617 :
2618 23118 : if (!gsi_end_p (gsi) && before_p)
2619 1275 : gsi_prev (&gsi);
2620 :
2621 23118 : basic_block cur_bb = gsi_bb (*iter);
2622 :
2623 23118 : edge e = split_block (cur_bb, gsi_stmt (gsi));
2624 :
2625 : /* Get a hold on the 'condition block', the 'then block' and the
2626 : 'else block'. */
2627 23118 : basic_block cond_bb = e->src;
2628 23118 : basic_block fallthru_bb = e->dest;
2629 23118 : basic_block then_bb = create_empty_bb (cond_bb);
2630 23118 : if (current_loops)
2631 : {
2632 23118 : add_bb_to_loop (then_bb, cond_bb->loop_father);
2633 23118 : loops_state_set (LOOPS_NEED_FIXUP);
2634 : }
2635 :
2636 : /* Set up the newly created 'then block'. */
2637 23118 : e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
2638 23118 : profile_probability fallthrough_probability
2639 : = then_more_likely_p
2640 23118 : ? profile_probability::very_unlikely ()
2641 23118 : : profile_probability::very_likely ();
2642 23118 : e->probability = fallthrough_probability.invert ();
2643 23118 : then_bb->count = e->count ();
2644 23118 : if (create_then_fallthru_edge)
2645 4377 : make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
2646 :
2647 : /* Set up the fallthrough basic block. */
2648 23118 : e = find_edge (cond_bb, fallthru_bb);
2649 23118 : e->flags = EDGE_FALSE_VALUE;
2650 23118 : e->probability = fallthrough_probability;
2651 :
2652 : /* Update dominance info for the newly created then_bb; note that
2653 : fallthru_bb's dominance info has already been updated by
2654 : split_bock. */
2655 23118 : if (dom_info_available_p (CDI_DOMINATORS))
2656 21671 : set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
2657 :
2658 23118 : *then_block = then_bb;
2659 23118 : *fallthrough_block = fallthru_bb;
2660 23118 : *iter = gsi_start_bb (fallthru_bb);
2661 :
2662 23118 : return gsi_last_bb (cond_bb);
2663 : }
2664 :
2665 : /* Insert an if condition followed by a 'then block' right before the
2666 : statement pointed to by ITER. The fallthrough block -- which is the
2667 : else block of the condition as well as the destination of the
2668 : outcoming edge of the 'then block' -- starts with the statement
2669 : pointed to by ITER.
2670 :
2671 : COND is the condition of the if.
2672 :
2673 : If THEN_MORE_LIKELY_P is true, the probability of the edge to the
2674 : 'then block' is higher than the probability of the edge to the
2675 : fallthrough block.
2676 :
2677 : Upon completion of the function, *THEN_BB is set to the newly
2678 : inserted 'then block' and similarly, *FALLTHROUGH_BB is set to the
2679 : fallthrough block.
2680 :
2681 : *ITER is adjusted to still point to the same statement it was
2682 : pointing to initially. */
2683 :
2684 : static void
2685 0 : insert_if_then_before_iter (gcond *cond,
2686 : gimple_stmt_iterator *iter,
2687 : bool then_more_likely_p,
2688 : basic_block *then_bb,
2689 : basic_block *fallthrough_bb)
2690 : {
2691 0 : gimple_stmt_iterator cond_insert_point =
2692 0 : create_cond_insert_point (iter,
2693 : /*before_p=*/true,
2694 : then_more_likely_p,
2695 : /*create_then_fallthru_edge=*/true,
2696 : then_bb,
2697 : fallthrough_bb);
2698 0 : gsi_insert_after (&cond_insert_point, cond, GSI_NEW_STMT);
2699 0 : }
2700 :
2701 : /* Build (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().
2702 : If RETURN_ADDRESS is set to true, return memory location instead
2703 : of a value in the shadow memory. */
2704 :
2705 : static tree
2706 21967 : build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
2707 : tree base_addr, tree shadow_ptr_type,
2708 : bool return_address = false)
2709 : {
2710 21967 : tree t, uintptr_type = TREE_TYPE (base_addr);
2711 21967 : tree shadow_type = TREE_TYPE (shadow_ptr_type);
2712 21967 : gimple *g;
2713 :
2714 21967 : t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT);
2715 21967 : g = gimple_build_assign (make_ssa_name (uintptr_type), RSHIFT_EXPR,
2716 : base_addr, t);
2717 21967 : gimple_set_location (g, location);
2718 21967 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
2719 :
2720 21967 : if (asan_dynamic_shadow_offset_p ())
2721 0 : t = asan_local_shadow_memory_dynamic_address;
2722 : else
2723 21967 : t = build_int_cst (uintptr_type, asan_shadow_offset ());
2724 21967 : g = gimple_build_assign (make_ssa_name (uintptr_type), PLUS_EXPR,
2725 : gimple_assign_lhs (g), t);
2726 21967 : gimple_set_location (g, location);
2727 21967 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
2728 :
2729 21967 : g = gimple_build_assign (make_ssa_name (shadow_ptr_type), NOP_EXPR,
2730 : gimple_assign_lhs (g));
2731 21967 : gimple_set_location (g, location);
2732 21967 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
2733 :
2734 21967 : if (!return_address)
2735 : {
2736 19871 : t = build2 (MEM_REF, shadow_type, gimple_assign_lhs (g),
2737 : build_int_cst (shadow_ptr_type, 0));
2738 19871 : g = gimple_build_assign (make_ssa_name (shadow_type), MEM_REF, t);
2739 19871 : gimple_set_location (g, location);
2740 19871 : gsi_insert_after (gsi, g, GSI_NEW_STMT);
2741 : }
2742 :
2743 21967 : return gimple_assign_lhs (g);
2744 : }
2745 :
2746 : /* BASE can already be an SSA_NAME; in that case, do not create a
2747 : new SSA_NAME for it. */
2748 :
2749 : static tree
2750 18546 : maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
2751 : bool before_p)
2752 : {
2753 18546 : STRIP_USELESS_TYPE_CONVERSION (base);
2754 18546 : if (TREE_CODE (base) == SSA_NAME)
2755 : return base;
2756 16462 : gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (base)), base);
2757 16462 : gimple_set_location (g, loc);
2758 16462 : if (before_p)
2759 16462 : gsi_safe_insert_before (iter, g);
2760 : else
2761 0 : gsi_insert_after (iter, g, GSI_NEW_STMT);
2762 16462 : return gimple_assign_lhs (g);
2763 : }
2764 :
2765 : /* LEN can already have necessary size and precision;
2766 : in that case, do not create a new variable. */
2767 :
2768 : tree
2769 0 : maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
2770 : bool before_p)
2771 : {
2772 0 : if (ptrofftype_p (len))
2773 : return len;
2774 0 : gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
2775 : NOP_EXPR, len);
2776 0 : gimple_set_location (g, loc);
2777 0 : if (before_p)
2778 0 : gsi_safe_insert_before (iter, g);
2779 : else
2780 0 : gsi_insert_after (iter, g, GSI_NEW_STMT);
2781 0 : return gimple_assign_lhs (g);
2782 : }
2783 :
2784 : /* Instrument the memory access instruction BASE. Insert new
2785 : statements before or after ITER.
2786 :
2787 : Note that the memory access represented by BASE can be either an
2788 : SSA_NAME, or a non-SSA expression. LOCATION is the source code
2789 : location. IS_STORE is TRUE for a store, FALSE for a load.
2790 : BEFORE_P is TRUE for inserting the instrumentation code before
2791 : ITER, FALSE for inserting it after ITER. IS_SCALAR_ACCESS is TRUE
2792 : for a scalar memory access and FALSE for memory region access.
2793 : NON_ZERO_P is TRUE if memory region is guaranteed to have non-zero
2794 : length. ALIGN tells alignment of accessed memory object.
2795 :
2796 : START_INSTRUMENTED and END_INSTRUMENTED are TRUE if start/end of
2797 : memory region have already been instrumented.
2798 :
2799 : If BEFORE_P is TRUE, *ITER is arranged to still point to the
2800 : statement it was pointing to prior to calling this function,
2801 : otherwise, it points to the statement logically following it. */
2802 :
2803 : static void
2804 18546 : build_check_stmt (location_t loc, tree base, tree len,
2805 : HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
2806 : bool is_non_zero_len, bool before_p, bool is_store,
2807 : bool is_scalar_access, unsigned int align = 0)
2808 : {
2809 18546 : gimple *g;
2810 :
2811 18546 : gcc_assert (!(size_in_bytes > 0 && !is_non_zero_len));
2812 18546 : gcc_assert (size_in_bytes == -1 || size_in_bytes >= 1);
2813 :
2814 18546 : base = unshare_expr (base);
2815 18546 : base = maybe_create_ssa_name (loc, base, iter, before_p);
2816 :
2817 18546 : if (len)
2818 : {
2819 0 : len = unshare_expr (len);
2820 0 : len = maybe_cast_to_ptrmode (loc, len, iter, before_p);
2821 : }
2822 : else
2823 : {
2824 18546 : gcc_assert (size_in_bytes != -1);
2825 18546 : len = build_int_cst (pointer_sized_int_node, size_in_bytes);
2826 : }
2827 :
2828 18546 : if (size_in_bytes > 1)
2829 : {
2830 15801 : if ((size_in_bytes & (size_in_bytes - 1)) != 0
2831 15487 : || size_in_bytes > 16)
2832 : is_scalar_access = false;
2833 15124 : else if (align && align < size_in_bytes * BITS_PER_UNIT)
2834 : {
2835 : /* On non-strict alignment targets, if
2836 : 16-byte access is just 8-byte aligned,
2837 : this will result in misaligned shadow
2838 : memory 2 byte load, but otherwise can
2839 : be handled using one read. */
2840 282 : if (size_in_bytes != 16
2841 : || STRICT_ALIGNMENT
2842 149 : || align < 8 * BITS_PER_UNIT)
2843 18546 : is_scalar_access = false;
2844 : }
2845 : }
2846 :
2847 18546 : HOST_WIDE_INT flags = 0;
2848 18546 : if (is_store)
2849 9380 : flags |= ASAN_CHECK_STORE;
2850 18546 : if (is_non_zero_len)
2851 18546 : flags |= ASAN_CHECK_NON_ZERO_LEN;
2852 18546 : if (is_scalar_access)
2853 17727 : flags |= ASAN_CHECK_SCALAR_ACCESS;
2854 :
2855 18546 : enum internal_fn fn = hwassist_sanitize_p ()
2856 18546 : ? IFN_HWASAN_CHECK
2857 18168 : : IFN_ASAN_CHECK;
2858 :
2859 18546 : g = gimple_build_call_internal (fn, 4,
2860 18546 : build_int_cst (integer_type_node, flags),
2861 : base, len,
2862 : build_int_cst (integer_type_node,
2863 18546 : align / BITS_PER_UNIT));
2864 18546 : gimple_set_location (g, loc);
2865 18546 : if (before_p)
2866 18546 : gsi_safe_insert_before (iter, g);
2867 : else
2868 : {
2869 0 : gsi_insert_after (iter, g, GSI_NEW_STMT);
2870 0 : gsi_next (iter);
2871 : }
2872 18546 : }
2873 :
2874 : /* If T represents a memory access, add instrumentation code before ITER.
2875 : LOCATION is source code location.
2876 : IS_STORE is either TRUE (for a store) or FALSE (for a load). */
2877 :
2878 : static void
2879 26415 : instrument_derefs (gimple_stmt_iterator *iter, tree t,
2880 : location_t location, bool is_store)
2881 : {
2882 26415 : if (is_store && !(asan_instrument_writes () || hwasan_instrument_writes ()))
2883 7772 : return;
2884 26373 : if (!is_store && !(asan_instrument_reads () || hwasan_instrument_reads ()))
2885 : return;
2886 :
2887 26317 : tree type, base;
2888 26317 : HOST_WIDE_INT size_in_bytes;
2889 26317 : if (location == UNKNOWN_LOCATION)
2890 377 : location = EXPR_LOCATION (t);
2891 :
2892 26317 : type = TREE_TYPE (t);
2893 26317 : switch (TREE_CODE (t))
2894 : {
2895 26125 : case ARRAY_REF:
2896 26125 : case COMPONENT_REF:
2897 26125 : case INDIRECT_REF:
2898 26125 : case MEM_REF:
2899 26125 : case VAR_DECL:
2900 26125 : case BIT_FIELD_REF:
2901 26125 : break;
2902 : /* FALLTHRU */
2903 : default:
2904 : return;
2905 : }
2906 :
2907 26125 : size_in_bytes = int_size_in_bytes (type);
2908 26125 : if (size_in_bytes <= 0)
2909 : return;
2910 :
2911 26125 : poly_int64 bitsize, bitpos;
2912 26125 : tree offset;
2913 26125 : machine_mode mode;
2914 26125 : int unsignedp, reversep, volatilep = 0;
2915 26125 : tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
2916 : &unsignedp, &reversep, &volatilep);
2917 :
2918 26125 : if (TREE_CODE (t) == COMPONENT_REF
2919 26125 : && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
2920 : {
2921 72 : tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
2922 72 : instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
2923 72 : TREE_OPERAND (t, 0), repr,
2924 72 : TREE_OPERAND (t, 2)),
2925 : location, is_store);
2926 72 : return;
2927 : }
2928 :
2929 26053 : if (!multiple_p (bitpos, BITS_PER_UNIT)
2930 26053 : || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
2931 : return;
2932 :
2933 26053 : if (VAR_P (inner) && DECL_HARD_REGISTER (inner))
2934 : return;
2935 :
2936 : /* Accesses to non-generic address-spaces should not be instrumented. */
2937 26047 : if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (inner))))
2938 : return;
2939 :
2940 26037 : poly_int64 decl_size;
2941 26037 : if ((VAR_P (inner)
2942 11075 : || (TREE_CODE (inner) == RESULT_DECL
2943 145 : && !aggregate_value_p (inner, current_function_decl)))
2944 14962 : && offset == NULL_TREE
2945 14372 : && DECL_SIZE (inner)
2946 14372 : && poly_int_tree_p (DECL_SIZE (inner), &decl_size)
2947 52074 : && known_subrange_p (bitpos, bitsize, 0, decl_size))
2948 : {
2949 14353 : if (VAR_P (inner) && DECL_THREAD_LOCAL_P (inner))
2950 : return;
2951 : /* If we're not sanitizing globals and we can tell statically that this
2952 : access is inside a global variable, then there's no point adding
2953 : instrumentation to check the access. N.b. hwasan currently never
2954 : sanitizes globals. */
2955 28528 : if ((hwassist_sanitize_p () || !param_asan_globals)
2956 14431 : && is_global_var (inner))
2957 : return;
2958 14167 : if (!TREE_STATIC (inner))
2959 : {
2960 : /* Automatic vars in the current function will be always
2961 : accessible. */
2962 9286 : if (decl_function_context (inner) == current_function_decl
2963 9286 : && (!asan_sanitize_use_after_scope ()
2964 8495 : || !TREE_ADDRESSABLE (inner)))
2965 : return;
2966 : }
2967 : /* Always instrument external vars, they might be dynamically
2968 : initialized. */
2969 4881 : else if (!DECL_EXTERNAL (inner))
2970 : {
2971 : /* For static vars if they are known not to be dynamically
2972 : initialized, they will be always accessible. */
2973 4872 : varpool_node *vnode = varpool_node::get (inner);
2974 4872 : if (vnode && !vnode->dynamically_initialized)
2975 : return;
2976 : }
2977 : }
2978 :
2979 18643 : if (DECL_P (inner)
2980 7739 : && decl_function_context (inner) == current_function_decl
2981 25689 : && !TREE_ADDRESSABLE (inner))
2982 110 : mark_addressable (inner);
2983 :
2984 18643 : base = build_fold_addr_expr (t);
2985 18643 : if (!has_mem_ref_been_instrumented (base, size_in_bytes))
2986 : {
2987 18546 : unsigned int align = get_object_alignment (t);
2988 18546 : build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter,
2989 : /*is_non_zero_len*/size_in_bytes > 0, /*before_p=*/true,
2990 : is_store, /*is_scalar_access*/true, align);
2991 18546 : update_mem_ref_hash_table (base, size_in_bytes);
2992 18546 : update_mem_ref_hash_table (t, size_in_bytes);
2993 : }
2994 :
2995 : }
2996 :
2997 : /* Insert a memory reference into the hash table if access length
2998 : can be determined in compile time. */
2999 :
3000 : static void
3001 1574 : maybe_update_mem_ref_hash_table (tree base, tree len)
3002 : {
3003 1640 : if (!POINTER_TYPE_P (TREE_TYPE (base))
3004 1640 : || !INTEGRAL_TYPE_P (TREE_TYPE (len)))
3005 : return;
3006 :
3007 1574 : HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
3008 :
3009 386 : if (size_in_bytes != -1)
3010 386 : update_mem_ref_hash_table (base, size_in_bytes);
3011 : }
3012 :
3013 : /* Instrument an access to a contiguous memory region that starts at
3014 : the address pointed to by BASE, over a length of LEN (expressed in
3015 : the sizeof (*BASE) bytes). ITER points to the instruction before
3016 : which the instrumentation instructions must be inserted. LOCATION
3017 : is the source location that the instrumentation instructions must
3018 : have. If IS_STORE is true, then the memory access is a store;
3019 : otherwise, it's a load. */
3020 :
3021 : static void
3022 0 : instrument_mem_region_access (tree base, tree len,
3023 : gimple_stmt_iterator *iter,
3024 : location_t location, bool is_store)
3025 : {
3026 0 : if (!POINTER_TYPE_P (TREE_TYPE (base))
3027 0 : || !INTEGRAL_TYPE_P (TREE_TYPE (len))
3028 0 : || integer_zerop (len))
3029 : return;
3030 :
3031 0 : HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
3032 :
3033 0 : if ((size_in_bytes == -1)
3034 0 : || !has_mem_ref_been_instrumented (base, size_in_bytes))
3035 : {
3036 0 : build_check_stmt (location, base, len, size_in_bytes, iter,
3037 : /*is_non_zero_len*/size_in_bytes > 0, /*before_p*/true,
3038 : is_store, /*is_scalar_access*/false, /*align*/0);
3039 : }
3040 :
3041 0 : maybe_update_mem_ref_hash_table (base, len);
3042 0 : *iter = gsi_for_stmt (gsi_stmt (*iter));
3043 : }
3044 :
3045 : /* Instrument the call to a built-in memory access function that is
3046 : pointed to by the iterator ITER.
3047 :
3048 : Upon completion, return TRUE iff *ITER has been advanced to the
3049 : statement following the one it was originally pointing to. */
3050 :
3051 : static bool
3052 4411 : instrument_builtin_call (gimple_stmt_iterator *iter)
3053 : {
3054 4435 : if (!(asan_memintrin () || hwasan_memintrin ()
3055 24 : || memtag_memintrin ()))
3056 : return false;
3057 :
3058 4387 : bool iter_advanced_p = false;
3059 4387 : gcall *call = as_a <gcall *> (gsi_stmt (*iter));
3060 :
3061 4387 : gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
3062 :
3063 4387 : location_t loc = gimple_location (call);
3064 :
3065 4387 : asan_mem_ref src0, src1, dest;
3066 4387 : asan_mem_ref_init (&src0, NULL, 1);
3067 4387 : asan_mem_ref_init (&src1, NULL, 1);
3068 4387 : asan_mem_ref_init (&dest, NULL, 1);
3069 :
3070 4387 : tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
3071 4387 : bool src0_is_store = false, src1_is_store = false, dest_is_store = false,
3072 4387 : dest_is_deref = false, intercepted_p = true;
3073 :
3074 4387 : if (get_mem_refs_of_builtin_call (call,
3075 : &src0, &src0_len, &src0_is_store,
3076 : &src1, &src1_len, &src1_is_store,
3077 : &dest, &dest_len, &dest_is_store,
3078 : &dest_is_deref, &intercepted_p, iter))
3079 : {
3080 927 : if (dest_is_deref)
3081 : {
3082 28 : instrument_derefs (iter, dest.start, loc, dest_is_store);
3083 28 : gsi_next (iter);
3084 28 : iter_advanced_p = true;
3085 : }
3086 899 : else if (!intercepted_p
3087 0 : && (src0_len || src1_len || dest_len))
3088 : {
3089 0 : if (src0.start != NULL_TREE)
3090 0 : instrument_mem_region_access (src0.start, src0_len,
3091 : iter, loc, /*is_store=*/false);
3092 0 : if (src1.start != NULL_TREE)
3093 0 : instrument_mem_region_access (src1.start, src1_len,
3094 : iter, loc, /*is_store=*/false);
3095 0 : if (dest.start != NULL_TREE)
3096 0 : instrument_mem_region_access (dest.start, dest_len,
3097 : iter, loc, /*is_store=*/true);
3098 :
3099 0 : *iter = gsi_for_stmt (call);
3100 0 : gsi_next (iter);
3101 0 : iter_advanced_p = true;
3102 : }
3103 : else
3104 : {
3105 899 : if (src0.start != NULL_TREE)
3106 711 : maybe_update_mem_ref_hash_table (src0.start, src0_len);
3107 899 : if (src1.start != NULL_TREE)
3108 50 : maybe_update_mem_ref_hash_table (src1.start, src1_len);
3109 899 : if (dest.start != NULL_TREE)
3110 813 : maybe_update_mem_ref_hash_table (dest.start, dest_len);
3111 : }
3112 : }
3113 : return iter_advanced_p;
3114 : }
3115 :
3116 : /* Instrument the assignment statement ITER if it is subject to
3117 : instrumentation. Return TRUE iff instrumentation actually
3118 : happened. In that case, the iterator ITER is advanced to the next
3119 : logical expression following the one initially pointed to by ITER,
3120 : and the relevant memory reference that which access has been
3121 : instrumented is added to the memory references hash table. */
3122 :
3123 : static bool
3124 28158 : maybe_instrument_assignment (gimple_stmt_iterator *iter)
3125 : {
3126 28158 : gimple *s = gsi_stmt (*iter);
3127 :
3128 28158 : gcc_assert (gimple_assign_single_p (s));
3129 :
3130 28158 : tree ref_expr = NULL_TREE;
3131 28158 : bool is_store, is_instrumented = false;
3132 :
3133 28158 : if (gimple_store_p (s))
3134 : {
3135 12591 : ref_expr = gimple_assign_lhs (s);
3136 12591 : is_store = true;
3137 12591 : instrument_derefs (iter, ref_expr,
3138 : gimple_location (s),
3139 : is_store);
3140 12591 : is_instrumented = true;
3141 : }
3142 :
3143 28158 : if (gimple_assign_load_p (s))
3144 : {
3145 13563 : ref_expr = gimple_assign_rhs1 (s);
3146 13563 : is_store = false;
3147 13563 : instrument_derefs (iter, ref_expr,
3148 : gimple_location (s),
3149 : is_store);
3150 13563 : is_instrumented = true;
3151 : }
3152 :
3153 28158 : if (is_instrumented)
3154 25599 : gsi_next (iter);
3155 :
3156 28158 : return is_instrumented;
3157 : }
3158 :
3159 : /* Instrument the function call pointed to by the iterator ITER, if it
3160 : is subject to instrumentation. At the moment, the only function
3161 : calls that are instrumented are some built-in functions that access
3162 : memory. Look at instrument_builtin_call to learn more.
3163 :
3164 : Upon completion return TRUE iff *ITER was advanced to the statement
3165 : following the one it was originally pointing to. */
3166 :
3167 : static bool
3168 22774 : maybe_instrument_call (gimple_stmt_iterator *iter)
3169 : {
3170 22774 : gimple *stmt = gsi_stmt (*iter);
3171 22774 : bool is_builtin = gimple_call_builtin_p (stmt, BUILT_IN_NORMAL);
3172 :
3173 22774 : if (is_builtin && instrument_builtin_call (iter))
3174 : return true;
3175 :
3176 22746 : if (gimple_call_noreturn_p (stmt))
3177 : {
3178 1131 : if (is_builtin)
3179 : {
3180 320 : tree callee = gimple_call_fndecl (stmt);
3181 320 : switch (DECL_FUNCTION_CODE (callee))
3182 : {
3183 : case BUILT_IN_UNREACHABLE:
3184 : case BUILT_IN_UNREACHABLE_TRAP:
3185 : case BUILT_IN_TRAP:
3186 : case BUILT_IN_ASAN_REPORT_LOAD1:
3187 : case BUILT_IN_ASAN_REPORT_LOAD2:
3188 : case BUILT_IN_ASAN_REPORT_LOAD4:
3189 : case BUILT_IN_ASAN_REPORT_LOAD8:
3190 : case BUILT_IN_ASAN_REPORT_LOAD16:
3191 : case BUILT_IN_ASAN_REPORT_LOAD_N:
3192 : case BUILT_IN_ASAN_REPORT_STORE1:
3193 : case BUILT_IN_ASAN_REPORT_STORE2:
3194 : case BUILT_IN_ASAN_REPORT_STORE4:
3195 : case BUILT_IN_ASAN_REPORT_STORE8:
3196 : case BUILT_IN_ASAN_REPORT_STORE16:
3197 : case BUILT_IN_ASAN_REPORT_STORE_N:
3198 : /* Don't instrument these. */
3199 : return false;
3200 : default:
3201 : break;
3202 : }
3203 : }
3204 951 : if (gimple_call_internal_p (stmt, IFN_ABNORMAL_DISPATCHER))
3205 : /* Don't instrument this. */
3206 : return false;
3207 : /* If a function does not return, then we must handle clearing up the
3208 : shadow stack accordingly. For ASAN we can simply set the entire stack
3209 : to "valid" for accesses by setting the shadow space to 0 and all
3210 : accesses will pass checks. That means that some bad accesses may be
3211 : missed, but we will not report any false positives.
3212 :
3213 : This is not possible for HWASAN. Since there is no "always valid" tag
3214 : we can not set any space to "always valid". If we were to clear the
3215 : entire shadow stack then code resuming from `longjmp` or a caught
3216 : exception would trigger false positives when correctly accessing
3217 : variables on the stack. Hence we need to handle things like
3218 : `longjmp`, thread exit, and exceptions in a different way. These
3219 : problems must be handled externally to the compiler, e.g. in the
3220 : language runtime. */
3221 866 : if (! hwassist_sanitize_p ())
3222 : {
3223 832 : tree decl = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN);
3224 832 : gimple *g = gimple_build_call (decl, 0);
3225 832 : gimple_set_location (g, gimple_location (stmt));
3226 832 : gsi_safe_insert_before (iter, g);
3227 : }
3228 : }
3229 :
3230 22481 : bool instrumented = false;
3231 22481 : if (gimple_store_p (stmt)
3232 22481 : && (gimple_call_builtin_p (stmt)
3233 288 : || gimple_call_internal_p (stmt)
3234 287 : || !aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
3235 287 : gimple_call_fntype (stmt))))
3236 : {
3237 62 : tree ref_expr = gimple_call_lhs (stmt);
3238 62 : instrument_derefs (iter, ref_expr,
3239 : gimple_location (stmt),
3240 : /*is_store=*/true);
3241 :
3242 62 : instrumented = true;
3243 : }
3244 :
3245 : /* Walk through gimple_call arguments and check them id needed. */
3246 22481 : unsigned args_num = gimple_call_num_args (stmt);
3247 92914 : for (unsigned i = 0; i < args_num; ++i)
3248 : {
3249 47952 : tree arg = gimple_call_arg (stmt, i);
3250 : /* If ARG is not a non-aggregate register variable, compiler in general
3251 : creates temporary for it and pass it as argument to gimple call.
3252 : But in some cases, e.g. when we pass by value a small structure that
3253 : fits to register, compiler can avoid extra overhead by pulling out
3254 : these temporaries. In this case, we should check the argument. */
3255 47952 : if (!is_gimple_reg (arg) && !is_gimple_min_invariant (arg))
3256 : {
3257 99 : instrument_derefs (iter, arg,
3258 : gimple_location (stmt),
3259 : /*is_store=*/false);
3260 99 : instrumented = true;
3261 : }
3262 : }
3263 22481 : if (instrumented)
3264 155 : gsi_next (iter);
3265 : return instrumented;
3266 : }
3267 :
3268 : /* Walk each instruction of all basic block and instrument those that
3269 : represent memory references: loads, stores, or function calls.
3270 : In a given basic block, this function avoids instrumenting memory
3271 : references that have already been instrumented. */
3272 :
3273 : static void
3274 6594 : transform_statements (void)
3275 : {
3276 6594 : basic_block bb, last_bb = NULL;
3277 6594 : gimple_stmt_iterator i;
3278 6594 : int saved_last_basic_block = last_basic_block_for_fn (cfun);
3279 :
3280 38143 : FOR_EACH_BB_FN (bb, cfun)
3281 : {
3282 31549 : basic_block prev_bb = bb;
3283 :
3284 31549 : if (bb->index >= saved_last_basic_block) continue;
3285 :
3286 : /* Flush the mem ref hash table, if current bb doesn't have
3287 : exactly one predecessor, or if that predecessor (skipping
3288 : over asan created basic blocks) isn't the last processed
3289 : basic block. Thus we effectively flush on extended basic
3290 : block boundaries. */
3291 31547 : while (single_pred_p (prev_bb))
3292 : {
3293 25598 : prev_bb = single_pred (prev_bb);
3294 25598 : if (prev_bb->index < saved_last_basic_block)
3295 : break;
3296 : }
3297 31541 : if (prev_bb != last_bb)
3298 21264 : empty_mem_ref_hash_table ();
3299 31541 : last_bb = bb;
3300 :
3301 233250 : for (i = gsi_start_bb (bb); !gsi_end_p (i);)
3302 : {
3303 170168 : gimple *s = gsi_stmt (i);
3304 :
3305 170168 : if (has_stmt_been_instrumented_p (s))
3306 1028 : gsi_next (&i);
3307 169140 : else if (gimple_assign_single_p (s)
3308 29122 : && !gimple_clobber_p (s)
3309 197298 : && maybe_instrument_assignment (&i))
3310 : /* Nothing to do as maybe_instrument_assignment advanced
3311 : the iterator I. */;
3312 143541 : else if (is_gimple_call (s) && maybe_instrument_call (&i))
3313 : /* Nothing to do as maybe_instrument_call
3314 : advanced the iterator I. */;
3315 : else
3316 : {
3317 : /* No instrumentation happened.
3318 :
3319 : If the current instruction is a function call that
3320 : might free something, let's forget about the memory
3321 : references that got instrumented. Otherwise we might
3322 : miss some instrumentation opportunities. Do the same
3323 : for a ASAN_MARK poisoning internal function. */
3324 143358 : if (is_gimple_call (s)
3325 143358 : && (!nonfreeing_call_p (s)
3326 6528 : || asan_mark_p (s, ASAN_MARK_POISON)))
3327 16063 : empty_mem_ref_hash_table ();
3328 :
3329 143358 : gsi_next (&i);
3330 : }
3331 : }
3332 : }
3333 6594 : free_mem_ref_resources ();
3334 6594 : }
3335 :
3336 : /* Build
3337 : __asan_before_dynamic_init (module_name)
3338 : or
3339 : __asan_after_dynamic_init ()
3340 : call. */
3341 :
3342 : tree
3343 42 : asan_dynamic_init_call (bool after_p)
3344 : {
3345 42 : if (shadow_ptr_types[0] == NULL_TREE)
3346 21 : asan_init_shadow_ptr_types ();
3347 :
3348 63 : tree fn = builtin_decl_implicit (after_p
3349 : ? BUILT_IN_ASAN_AFTER_DYNAMIC_INIT
3350 : : BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT);
3351 42 : tree module_name_cst = NULL_TREE;
3352 42 : if (!after_p)
3353 : {
3354 21 : pretty_printer module_name_pp;
3355 21 : pp_string (&module_name_pp, main_input_filename);
3356 :
3357 21 : module_name_cst = asan_pp_string (&module_name_pp);
3358 21 : module_name_cst = fold_convert (const_ptr_type_node,
3359 : module_name_cst);
3360 21 : }
3361 :
3362 42 : return build_call_expr (fn, after_p ? 0 : 1, module_name_cst);
3363 : }
3364 :
3365 : /* Build
3366 : struct __asan_global
3367 : {
3368 : const void *__beg;
3369 : uptr __size;
3370 : uptr __size_with_redzone;
3371 : const void *__name;
3372 : const void *__module_name;
3373 : uptr __has_dynamic_init;
3374 : __asan_global_source_location *__location;
3375 : char *__odr_indicator;
3376 : } type. */
3377 :
3378 : static tree
3379 1090 : asan_global_struct (void)
3380 : {
3381 1090 : static const char *field_names[]
3382 : = { "__beg", "__size", "__size_with_redzone",
3383 : "__name", "__module_name", "__has_dynamic_init", "__location",
3384 : "__odr_indicator" };
3385 1090 : tree fields[ARRAY_SIZE (field_names)], ret;
3386 1090 : unsigned i;
3387 :
3388 1090 : ret = make_node (RECORD_TYPE);
3389 10900 : for (i = 0; i < ARRAY_SIZE (field_names); i++)
3390 : {
3391 8720 : fields[i]
3392 8720 : = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
3393 : get_identifier (field_names[i]),
3394 8720 : (i == 0 || i == 3) ? const_ptr_type_node
3395 : : pointer_sized_int_node);
3396 8720 : DECL_CONTEXT (fields[i]) = ret;
3397 8720 : if (i)
3398 7630 : DECL_CHAIN (fields[i - 1]) = fields[i];
3399 : }
3400 1090 : tree type_decl = build_decl (input_location, TYPE_DECL,
3401 : get_identifier ("__asan_global"), ret);
3402 1090 : DECL_IGNORED_P (type_decl) = 1;
3403 1090 : DECL_ARTIFICIAL (type_decl) = 1;
3404 1090 : TYPE_FIELDS (ret) = fields[0];
3405 1090 : TYPE_NAME (ret) = type_decl;
3406 1090 : TYPE_STUB_DECL (ret) = type_decl;
3407 1090 : TYPE_ARTIFICIAL (ret) = 1;
3408 1090 : layout_type (ret);
3409 1090 : return ret;
3410 : }
3411 :
3412 : /* Create and return odr indicator symbol for DECL.
3413 : TYPE is __asan_global struct type as returned by asan_global_struct. */
3414 :
3415 : static tree
3416 1264 : create_odr_indicator (tree decl, tree type)
3417 : {
3418 1264 : char *name;
3419 1264 : tree uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
3420 1264 : tree decl_name
3421 1264 : = (HAS_DECL_ASSEMBLER_NAME_P (decl) ? DECL_ASSEMBLER_NAME (decl)
3422 0 : : DECL_NAME (decl));
3423 : /* DECL_NAME theoretically might be NULL. Bail out with 0 in this case. */
3424 1264 : if (decl_name == NULL_TREE)
3425 0 : return build_int_cst (uptr, 0);
3426 1264 : const char *dname = IDENTIFIER_POINTER (decl_name);
3427 1264 : if (HAS_DECL_ASSEMBLER_NAME_P (decl))
3428 1264 : dname = targetm.strip_name_encoding (dname);
3429 1264 : size_t len = strlen (dname) + sizeof ("__odr_asan_");
3430 1264 : name = XALLOCAVEC (char, len);
3431 1264 : snprintf (name, len, "__odr_asan_%s", dname);
3432 : #ifndef NO_DOT_IN_LABEL
3433 1264 : name[sizeof ("__odr_asan") - 1] = '.';
3434 : #elif !defined(NO_DOLLAR_IN_LABEL)
3435 : name[sizeof ("__odr_asan") - 1] = '$';
3436 : #endif
3437 1264 : tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (name),
3438 : char_type_node);
3439 1264 : TREE_ADDRESSABLE (var) = 1;
3440 1264 : TREE_READONLY (var) = 0;
3441 1264 : TREE_THIS_VOLATILE (var) = 1;
3442 1264 : DECL_ARTIFICIAL (var) = 1;
3443 1264 : DECL_IGNORED_P (var) = 1;
3444 1264 : TREE_STATIC (var) = 1;
3445 1264 : TREE_PUBLIC (var) = 1;
3446 1264 : DECL_VISIBILITY (var) = DECL_VISIBILITY (decl);
3447 1264 : DECL_VISIBILITY_SPECIFIED (var) = DECL_VISIBILITY_SPECIFIED (decl);
3448 :
3449 1264 : TREE_USED (var) = 1;
3450 1264 : tree ctor = build_constructor_va (TREE_TYPE (var), 1, NULL_TREE,
3451 : build_int_cst (unsigned_type_node, 0));
3452 1264 : TREE_CONSTANT (ctor) = 1;
3453 1264 : TREE_STATIC (ctor) = 1;
3454 1264 : DECL_INITIAL (var) = ctor;
3455 1264 : DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("asan odr indicator"),
3456 1264 : NULL, DECL_ATTRIBUTES (var));
3457 1264 : make_decl_rtl (var);
3458 1264 : varpool_node::finalize_decl (var);
3459 1264 : return fold_convert (uptr, build_fold_addr_expr (var));
3460 : }
3461 :
3462 : /* Return true if DECL, a global var, might be overridden and needs
3463 : an additional odr indicator symbol. */
3464 :
3465 : static bool
3466 4156 : asan_needs_odr_indicator_p (tree decl)
3467 : {
3468 : /* Don't emit ODR indicators for kernel because:
3469 : a) Kernel is written in C thus doesn't need ODR indicators.
3470 : b) Some kernel code may have assumptions about symbols containing specific
3471 : patterns in their names. Since ODR indicators contain original names
3472 : of symbols they are emitted for, these assumptions would be broken for
3473 : ODR indicator symbols. */
3474 4156 : return (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS)
3475 4156 : && !DECL_ARTIFICIAL (decl)
3476 1676 : && !DECL_WEAK (decl)
3477 5832 : && TREE_PUBLIC (decl));
3478 : }
3479 :
3480 : /* Append description of a single global DECL into vector V.
3481 : TYPE is __asan_global struct type as returned by asan_global_struct. */
3482 :
3483 : static void
3484 4156 : asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
3485 : {
3486 4156 : tree init, uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
3487 4156 : unsigned HOST_WIDE_INT size;
3488 4156 : tree str_cst, module_name_cst, refdecl = decl;
3489 4156 : vec<constructor_elt, va_gc> *vinner = NULL;
3490 :
3491 4156 : pretty_printer asan_pp, module_name_pp;
3492 :
3493 4156 : if (DECL_NAME (decl))
3494 4156 : pp_tree_identifier (&asan_pp, DECL_NAME (decl));
3495 : else
3496 0 : pp_string (&asan_pp, "<unknown>");
3497 4156 : str_cst = asan_pp_string (&asan_pp);
3498 :
3499 4156 : if (!in_lto_p)
3500 3732 : pp_string (&module_name_pp, main_input_filename);
3501 : else
3502 : {
3503 424 : const_tree tu = get_ultimate_context ((const_tree)decl);
3504 424 : if (tu != NULL_TREE)
3505 291 : pp_string (&module_name_pp, IDENTIFIER_POINTER (DECL_NAME (tu)));
3506 : else
3507 133 : pp_string (&module_name_pp, aux_base_name);
3508 : }
3509 :
3510 4156 : module_name_cst = asan_pp_string (&module_name_pp);
3511 :
3512 4156 : if (asan_needs_local_alias (decl))
3513 : {
3514 0 : char buf[20];
3515 0 : ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", vec_safe_length (v) + 1);
3516 0 : refdecl = build_decl (DECL_SOURCE_LOCATION (decl),
3517 0 : VAR_DECL, get_identifier (buf), TREE_TYPE (decl));
3518 0 : TREE_ADDRESSABLE (refdecl) = TREE_ADDRESSABLE (decl);
3519 0 : TREE_READONLY (refdecl) = TREE_READONLY (decl);
3520 0 : TREE_THIS_VOLATILE (refdecl) = TREE_THIS_VOLATILE (decl);
3521 0 : DECL_NOT_GIMPLE_REG_P (refdecl) = DECL_NOT_GIMPLE_REG_P (decl);
3522 0 : DECL_ARTIFICIAL (refdecl) = DECL_ARTIFICIAL (decl);
3523 0 : DECL_IGNORED_P (refdecl) = DECL_IGNORED_P (decl);
3524 0 : TREE_STATIC (refdecl) = 1;
3525 0 : TREE_PUBLIC (refdecl) = 0;
3526 0 : TREE_USED (refdecl) = 1;
3527 0 : assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl));
3528 : }
3529 :
3530 4156 : tree odr_indicator_ptr
3531 4156 : = (asan_needs_odr_indicator_p (decl) ? create_odr_indicator (decl, type)
3532 2892 : : build_int_cst (uptr, 0));
3533 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3534 : fold_convert (const_ptr_type_node,
3535 : build_fold_addr_expr (refdecl)));
3536 4156 : size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
3537 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
3538 4156 : size += asan_red_zone_size (size);
3539 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
3540 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3541 : fold_convert (const_ptr_type_node, str_cst));
3542 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3543 : fold_convert (const_ptr_type_node, module_name_cst));
3544 4156 : varpool_node *vnode = varpool_node::get (decl);
3545 4156 : int has_dynamic_init = 0;
3546 : /* FIXME: Enable initialization order fiasco detection in LTO mode once
3547 : proper fix for PR 79061 will be applied. */
3548 4156 : if (!in_lto_p)
3549 3732 : has_dynamic_init = vnode ? vnode->dynamically_initialized : 0;
3550 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
3551 : build_int_cst (uptr, has_dynamic_init));
3552 4156 : tree locptr = NULL_TREE;
3553 4156 : location_t loc = DECL_SOURCE_LOCATION (decl);
3554 4156 : expanded_location xloc = expand_location (loc);
3555 4156 : if (xloc.file != NULL)
3556 : {
3557 2258 : static int lasanloccnt = 0;
3558 2258 : char buf[25];
3559 2258 : ASM_GENERATE_INTERNAL_LABEL (buf, "LASANLOC", ++lasanloccnt);
3560 2258 : tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
3561 : ubsan_get_source_location_type ());
3562 2258 : TREE_STATIC (var) = 1;
3563 2258 : TREE_PUBLIC (var) = 0;
3564 2258 : DECL_ARTIFICIAL (var) = 1;
3565 2258 : DECL_IGNORED_P (var) = 1;
3566 2258 : pretty_printer filename_pp;
3567 2258 : pp_string (&filename_pp, xloc.file);
3568 2258 : tree str = asan_pp_string (&filename_pp);
3569 2258 : tree ctor = build_constructor_va (TREE_TYPE (var), 3,
3570 : NULL_TREE, str, NULL_TREE,
3571 : build_int_cst (unsigned_type_node,
3572 2258 : xloc.line), NULL_TREE,
3573 : build_int_cst (unsigned_type_node,
3574 2258 : xloc.column));
3575 2258 : TREE_CONSTANT (ctor) = 1;
3576 2258 : TREE_STATIC (ctor) = 1;
3577 2258 : DECL_INITIAL (var) = ctor;
3578 2258 : varpool_node::finalize_decl (var);
3579 2258 : locptr = fold_convert (uptr, build_fold_addr_expr (var));
3580 2258 : }
3581 : else
3582 1898 : locptr = build_int_cst (uptr, 0);
3583 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr);
3584 4156 : CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, odr_indicator_ptr);
3585 4156 : init = build_constructor (type, vinner);
3586 4156 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
3587 4156 : }
3588 :
3589 : /* Initialize sanitizer.def builtins if the FE hasn't initialized them. */
3590 : void
3591 38317 : initialize_sanitizer_builtins (void)
3592 : {
3593 38317 : tree decl;
3594 :
3595 38317 : if (builtin_decl_implicit_p (BUILT_IN_ASAN_INIT))
3596 38225 : return;
3597 :
3598 92 : tree ptrmode_type = (*lang_hooks.types.type_for_mode) (ptr_mode, 0);
3599 92 : tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE);
3600 92 : tree BT_FN_VOID_PTR
3601 92 : = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
3602 92 : tree BT_FN_VOID_CONST_PTR
3603 92 : = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
3604 92 : tree BT_FN_VOID_PTR_PTR
3605 92 : = build_function_type_list (void_type_node, ptr_type_node,
3606 : ptr_type_node, NULL_TREE);
3607 92 : tree BT_FN_VOID_PTR_PTR_PTR
3608 92 : = build_function_type_list (void_type_node, ptr_type_node,
3609 : ptr_type_node, ptr_type_node, NULL_TREE);
3610 92 : tree BT_FN_VOID_PTR_PTRMODE
3611 92 : = build_function_type_list (void_type_node, ptr_type_node,
3612 : ptrmode_type, NULL_TREE);
3613 92 : tree BT_FN_VOID_INT
3614 92 : = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
3615 92 : tree BT_FN_SIZE_CONST_PTR_INT
3616 92 : = build_function_type_list (size_type_node, const_ptr_type_node,
3617 : integer_type_node, NULL_TREE);
3618 :
3619 92 : tree BT_FN_VOID_UINT8_UINT8
3620 92 : = build_function_type_list (void_type_node, unsigned_char_type_node,
3621 : unsigned_char_type_node, NULL_TREE);
3622 92 : tree BT_FN_VOID_UINT16_UINT16
3623 92 : = build_function_type_list (void_type_node, uint16_type_node,
3624 : uint16_type_node, NULL_TREE);
3625 92 : tree BT_FN_VOID_UINT32_UINT32
3626 92 : = build_function_type_list (void_type_node, uint32_type_node,
3627 : uint32_type_node, NULL_TREE);
3628 92 : tree BT_FN_VOID_UINT64_UINT64
3629 92 : = build_function_type_list (void_type_node, uint64_type_node,
3630 : uint64_type_node, NULL_TREE);
3631 92 : tree BT_FN_VOID_FLOAT_FLOAT
3632 92 : = build_function_type_list (void_type_node, float_type_node,
3633 : float_type_node, NULL_TREE);
3634 92 : tree BT_FN_VOID_DOUBLE_DOUBLE
3635 92 : = build_function_type_list (void_type_node, double_type_node,
3636 : double_type_node, NULL_TREE);
3637 92 : tree BT_FN_VOID_UINT64_PTR
3638 92 : = build_function_type_list (void_type_node, uint64_type_node,
3639 : ptr_type_node, NULL_TREE);
3640 :
3641 92 : tree BT_FN_PTR_CONST_PTR_UINT8
3642 92 : = build_function_type_list (ptr_type_node, const_ptr_type_node,
3643 : unsigned_char_type_node, NULL_TREE);
3644 92 : tree BT_FN_VOID_PTR_UINT8_PTRMODE
3645 92 : = build_function_type_list (void_type_node, ptr_type_node,
3646 : unsigned_char_type_node,
3647 : ptrmode_type, NULL_TREE);
3648 :
3649 92 : tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
3650 92 : tree BT_FN_IX_CONST_VPTR_INT[5];
3651 92 : tree BT_FN_IX_VPTR_IX_INT[5];
3652 92 : tree BT_FN_VOID_VPTR_IX_INT[5];
3653 92 : tree vptr
3654 92 : = build_pointer_type (build_qualified_type (void_type_node,
3655 : TYPE_QUAL_VOLATILE));
3656 92 : tree cvptr
3657 92 : = build_pointer_type (build_qualified_type (void_type_node,
3658 : TYPE_QUAL_VOLATILE
3659 : |TYPE_QUAL_CONST));
3660 92 : tree boolt
3661 92 : = lang_hooks.types.type_for_size (BOOL_TYPE_SIZE, 1);
3662 92 : int i;
3663 644 : for (i = 0; i < 5; i++)
3664 : {
3665 460 : tree ix = build_nonstandard_integer_type (BITS_PER_UNIT * (1 << i), 1);
3666 460 : BT_FN_BOOL_VPTR_PTR_IX_INT_INT[i]
3667 460 : = build_function_type_list (boolt, vptr, ptr_type_node, ix,
3668 : integer_type_node, integer_type_node,
3669 : NULL_TREE);
3670 460 : BT_FN_IX_CONST_VPTR_INT[i]
3671 460 : = build_function_type_list (ix, cvptr, integer_type_node, NULL_TREE);
3672 460 : BT_FN_IX_VPTR_IX_INT[i]
3673 460 : = build_function_type_list (ix, vptr, ix, integer_type_node,
3674 : NULL_TREE);
3675 460 : BT_FN_VOID_VPTR_IX_INT[i]
3676 460 : = build_function_type_list (void_type_node, vptr, ix,
3677 : integer_type_node, NULL_TREE);
3678 : }
3679 : #define BT_FN_BOOL_VPTR_PTR_I1_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[0]
3680 : #define BT_FN_I1_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[0]
3681 : #define BT_FN_I1_VPTR_I1_INT BT_FN_IX_VPTR_IX_INT[0]
3682 : #define BT_FN_VOID_VPTR_I1_INT BT_FN_VOID_VPTR_IX_INT[0]
3683 : #define BT_FN_BOOL_VPTR_PTR_I2_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[1]
3684 : #define BT_FN_I2_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[1]
3685 : #define BT_FN_I2_VPTR_I2_INT BT_FN_IX_VPTR_IX_INT[1]
3686 : #define BT_FN_VOID_VPTR_I2_INT BT_FN_VOID_VPTR_IX_INT[1]
3687 : #define BT_FN_BOOL_VPTR_PTR_I4_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[2]
3688 : #define BT_FN_I4_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[2]
3689 : #define BT_FN_I4_VPTR_I4_INT BT_FN_IX_VPTR_IX_INT[2]
3690 : #define BT_FN_VOID_VPTR_I4_INT BT_FN_VOID_VPTR_IX_INT[2]
3691 : #define BT_FN_BOOL_VPTR_PTR_I8_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[3]
3692 : #define BT_FN_I8_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[3]
3693 : #define BT_FN_I8_VPTR_I8_INT BT_FN_IX_VPTR_IX_INT[3]
3694 : #define BT_FN_VOID_VPTR_I8_INT BT_FN_VOID_VPTR_IX_INT[3]
3695 : #define BT_FN_BOOL_VPTR_PTR_I16_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[4]
3696 : #define BT_FN_I16_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[4]
3697 : #define BT_FN_I16_VPTR_I16_INT BT_FN_IX_VPTR_IX_INT[4]
3698 : #define BT_FN_VOID_VPTR_I16_INT BT_FN_VOID_VPTR_IX_INT[4]
3699 : #undef ATTR_NOTHROW_LIST
3700 : #define ATTR_NOTHROW_LIST ECF_NOTHROW
3701 : #undef ATTR_NOTHROW_LEAF_LIST
3702 : #define ATTR_NOTHROW_LEAF_LIST ECF_NOTHROW | ECF_LEAF
3703 : #undef ATTR_TMPURE_NOTHROW_LEAF_LIST
3704 : #define ATTR_TMPURE_NOTHROW_LEAF_LIST ECF_TM_PURE | ATTR_NOTHROW_LEAF_LIST
3705 : #undef ATTR_NORETURN_NOTHROW_LEAF_LIST
3706 : #define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
3707 : #undef ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
3708 : #define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST \
3709 : ECF_CONST | ATTR_NORETURN_NOTHROW_LEAF_LIST
3710 : #undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
3711 : #define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
3712 : ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
3713 : #undef ATTR_COLD_NOTHROW_LEAF_LIST
3714 : #define ATTR_COLD_NOTHROW_LEAF_LIST \
3715 : /* ECF_COLD missing */ ATTR_NOTHROW_LEAF_LIST
3716 : #undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
3717 : #define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
3718 : /* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
3719 : #undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
3720 : #define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
3721 : /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
3722 : #undef ATTR_PURE_NOTHROW_LEAF_LIST
3723 : #define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
3724 : #undef DEF_BUILTIN_STUB
3725 : #define DEF_BUILTIN_STUB(ENUM, NAME)
3726 : #undef DEF_SANITIZER_BUILTIN_1
3727 : #define DEF_SANITIZER_BUILTIN_1(ENUM, NAME, TYPE, ATTRS) \
3728 : do { \
3729 : decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM, \
3730 : BUILT_IN_NORMAL, NAME, NULL_TREE); \
3731 : set_call_expr_flags (decl, ATTRS); \
3732 : set_builtin_decl (ENUM, decl, true); \
3733 : } while (0)
3734 : #undef DEF_SANITIZER_BUILTIN
3735 : #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
3736 : DEF_SANITIZER_BUILTIN_1 (ENUM, NAME, TYPE, ATTRS);
3737 :
3738 : #include "sanitizer.def"
3739 :
3740 : /* -fsanitize=object-size uses __builtin_dynamic_object_size and
3741 : __builtin_object_size, but they might not be available for e.g. Fortran at
3742 : this point. We use DEF_SANITIZER_BUILTIN here only as a convenience
3743 : macro. */
3744 92 : if (flag_sanitize & SANITIZE_OBJECT_SIZE)
3745 : {
3746 21 : if (!builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
3747 15 : DEF_SANITIZER_BUILTIN_1 (BUILT_IN_OBJECT_SIZE, "object_size",
3748 : BT_FN_SIZE_CONST_PTR_INT,
3749 : ATTR_PURE_NOTHROW_LEAF_LIST);
3750 113 : if (!builtin_decl_implicit_p (BUILT_IN_DYNAMIC_OBJECT_SIZE))
3751 15 : DEF_SANITIZER_BUILTIN_1 (BUILT_IN_DYNAMIC_OBJECT_SIZE,
3752 : "dynamic_object_size",
3753 : BT_FN_SIZE_CONST_PTR_INT,
3754 : ATTR_PURE_NOTHROW_LEAF_LIST);
3755 : }
3756 :
3757 : #undef DEF_SANITIZER_BUILTIN_1
3758 : #undef DEF_SANITIZER_BUILTIN
3759 : #undef DEF_BUILTIN_STUB
3760 : }
3761 :
3762 : /* Called via htab_traverse. Count number of emitted
3763 : STRING_CSTs in the constant hash table. */
3764 :
3765 : int
3766 3403 : count_string_csts (constant_descriptor_tree **slot,
3767 : unsigned HOST_WIDE_INT *data)
3768 : {
3769 3403 : struct constant_descriptor_tree *desc = *slot;
3770 3403 : if (TREE_CODE (desc->value) == STRING_CST
3771 3369 : && TREE_ASM_WRITTEN (desc->value)
3772 6772 : && asan_protect_global (desc->value))
3773 1698 : ++*data;
3774 3403 : return 1;
3775 : }
3776 :
3777 : /* Helper structure to pass two parameters to
3778 : add_string_csts. */
3779 :
3780 : struct asan_add_string_csts_data
3781 : {
3782 : tree type;
3783 : vec<constructor_elt, va_gc> *v;
3784 : };
3785 :
3786 : /* Called via hash_table::traverse. Call asan_add_global
3787 : on emitted STRING_CSTs from the constant hash table. */
3788 :
3789 : int
3790 3477 : add_string_csts (constant_descriptor_tree **slot,
3791 : asan_add_string_csts_data *aascd)
3792 : {
3793 3477 : struct constant_descriptor_tree *desc = *slot;
3794 3477 : if (TREE_CODE (desc->value) == STRING_CST
3795 3450 : && TREE_ASM_WRITTEN (desc->value)
3796 6927 : && asan_protect_global (desc->value))
3797 : {
3798 1698 : asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)),
3799 : aascd->type, aascd->v);
3800 : }
3801 3477 : return 1;
3802 : }
3803 :
3804 : /* Needs to be GTY(()), because cgraph_build_static_cdtor may
3805 : invoke ggc_collect. */
3806 : static GTY(()) tree asan_ctor_statements;
3807 :
3808 : /* Module-level instrumentation.
3809 : - Insert __asan_init_vN() into the list of CTORs.
3810 : - TODO: insert redzones around globals.
3811 : */
3812 :
3813 : void
3814 2483 : asan_finish_file (void)
3815 : {
3816 2483 : varpool_node *vnode;
3817 2483 : unsigned HOST_WIDE_INT gcount = 0;
3818 :
3819 2483 : if (shadow_ptr_types[0] == NULL_TREE)
3820 109 : asan_init_shadow_ptr_types ();
3821 : /* Avoid instrumenting code in the asan ctors/dtors.
3822 : We don't need to insert padding after the description strings,
3823 : nor after .LASAN* array. */
3824 2483 : flag_sanitize &= ~SANITIZE_ADDRESS;
3825 :
3826 : /* For user-space we want asan constructors to run first.
3827 : Linux kernel does not support priorities other than default, and the only
3828 : other user of constructors is coverage. So we run with the default
3829 : priority. */
3830 126 : int priority = flag_sanitize & SANITIZE_USER_ADDRESS
3831 2483 : ? MAX_RESERVED_INIT_PRIORITY - 1 : DEFAULT_INIT_PRIORITY;
3832 :
3833 2483 : if (flag_sanitize & SANITIZE_USER_ADDRESS)
3834 : {
3835 2357 : tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
3836 2357 : append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
3837 2357 : fn = builtin_decl_implicit (BUILT_IN_ASAN_VERSION_MISMATCH_CHECK);
3838 2357 : append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
3839 : }
3840 5160 : FOR_EACH_DEFINED_VARIABLE (vnode)
3841 2677 : if (TREE_ASM_WRITTEN (vnode->decl)
3842 2677 : && asan_protect_global (vnode->decl))
3843 2458 : ++gcount;
3844 2483 : hash_table<tree_descriptor_hasher> *const_desc_htab = constant_pool_htab ();
3845 2483 : const_desc_htab->traverse<unsigned HOST_WIDE_INT *, count_string_csts>
3846 5886 : (&gcount);
3847 2483 : if (gcount)
3848 : {
3849 1090 : tree type = asan_global_struct (), var, ctor;
3850 1090 : tree dtor_statements = NULL_TREE;
3851 1090 : vec<constructor_elt, va_gc> *v;
3852 1090 : char buf[20];
3853 :
3854 1090 : type = build_array_type_nelts (type, gcount);
3855 1090 : ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", 0);
3856 1090 : var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
3857 : type);
3858 1090 : TREE_STATIC (var) = 1;
3859 1090 : TREE_PUBLIC (var) = 0;
3860 1090 : DECL_ARTIFICIAL (var) = 1;
3861 1090 : DECL_IGNORED_P (var) = 1;
3862 1090 : vec_alloc (v, gcount);
3863 3685 : FOR_EACH_DEFINED_VARIABLE (vnode)
3864 2595 : if (TREE_ASM_WRITTEN (vnode->decl)
3865 2595 : && asan_protect_global (vnode->decl))
3866 2458 : asan_add_global (vnode->decl, TREE_TYPE (type), v);
3867 1090 : struct asan_add_string_csts_data aascd;
3868 1090 : aascd.type = TREE_TYPE (type);
3869 1090 : aascd.v = v;
3870 1090 : const_desc_htab->traverse<asan_add_string_csts_data *, add_string_csts>
3871 4567 : (&aascd);
3872 1090 : ctor = build_constructor (type, v);
3873 1090 : TREE_CONSTANT (ctor) = 1;
3874 1090 : TREE_STATIC (ctor) = 1;
3875 1090 : DECL_INITIAL (var) = ctor;
3876 1090 : SET_DECL_ALIGN (var, MAX (DECL_ALIGN (var),
3877 : ASAN_SHADOW_GRANULARITY * BITS_PER_UNIT));
3878 :
3879 1090 : varpool_node::finalize_decl (var);
3880 :
3881 1090 : tree fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
3882 1090 : tree gcount_tree = build_int_cst (pointer_sized_int_node, gcount);
3883 1090 : append_to_statement_list (build_call_expr (fn, 2,
3884 : build_fold_addr_expr (var),
3885 : gcount_tree),
3886 : &asan_ctor_statements);
3887 :
3888 1090 : fn = builtin_decl_implicit (BUILT_IN_ASAN_UNREGISTER_GLOBALS);
3889 1090 : append_to_statement_list (build_call_expr (fn, 2,
3890 : build_fold_addr_expr (var),
3891 : gcount_tree),
3892 : &dtor_statements);
3893 1090 : cgraph_build_static_cdtor ('D', dtor_statements, priority);
3894 : }
3895 2483 : if (asan_ctor_statements)
3896 2357 : cgraph_build_static_cdtor ('I', asan_ctor_statements, priority);
3897 2483 : flag_sanitize |= SANITIZE_ADDRESS;
3898 2483 : }
3899 :
3900 : /* Poison or unpoison (depending on IS_CLOBBER variable) shadow memory based
3901 : on SHADOW address. Newly added statements will be added to ITER with
3902 : given location LOC. We mark SIZE bytes in shadow memory, where
3903 : LAST_CHUNK_SIZE is greater than zero in situation where we are at the
3904 : end of a variable. */
3905 :
3906 : static void
3907 2193 : asan_store_shadow_bytes (gimple_stmt_iterator *iter, location_t loc,
3908 : tree shadow,
3909 : unsigned HOST_WIDE_INT base_addr_offset,
3910 : bool is_clobber, unsigned size,
3911 : unsigned last_chunk_size)
3912 : {
3913 2193 : tree shadow_ptr_type;
3914 :
3915 2193 : switch (size)
3916 : {
3917 1422 : case 1:
3918 1422 : shadow_ptr_type = shadow_ptr_types[0];
3919 1422 : break;
3920 272 : case 2:
3921 272 : shadow_ptr_type = shadow_ptr_types[1];
3922 272 : break;
3923 499 : case 4:
3924 499 : shadow_ptr_type = shadow_ptr_types[2];
3925 499 : break;
3926 0 : default:
3927 0 : gcc_unreachable ();
3928 : }
3929 :
3930 2193 : unsigned char c = (char) is_clobber ? ASAN_STACK_MAGIC_USE_AFTER_SCOPE : 0;
3931 2193 : unsigned HOST_WIDE_INT val = 0;
3932 2193 : unsigned last_pos = size;
3933 2193 : if (last_chunk_size && !is_clobber)
3934 322 : last_pos = BYTES_BIG_ENDIAN ? 0 : size - 1;
3935 6155 : for (unsigned i = 0; i < size; ++i)
3936 : {
3937 3962 : unsigned char shadow_c = c;
3938 3962 : if (i == last_pos)
3939 322 : shadow_c = last_chunk_size;
3940 3962 : val |= (unsigned HOST_WIDE_INT) shadow_c << (BITS_PER_UNIT * i);
3941 : }
3942 :
3943 : /* Handle last chunk in unpoisoning. */
3944 2193 : tree magic = build_int_cst (TREE_TYPE (shadow_ptr_type), val);
3945 :
3946 2193 : tree dest = build2 (MEM_REF, TREE_TYPE (shadow_ptr_type), shadow,
3947 2193 : build_int_cst (shadow_ptr_type, base_addr_offset));
3948 :
3949 2193 : gimple *g = gimple_build_assign (dest, magic);
3950 2193 : gimple_set_location (g, loc);
3951 2193 : gsi_insert_after (iter, g, GSI_NEW_STMT);
3952 2193 : }
3953 :
3954 : /* Expand the ASAN_MARK builtins. */
3955 :
3956 : bool
3957 2149 : asan_expand_mark_ifn (gimple_stmt_iterator *iter)
3958 : {
3959 2149 : gimple *g = gsi_stmt (*iter);
3960 2149 : location_t loc = gimple_location (g);
3961 2149 : HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (g, 0));
3962 2149 : bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
3963 :
3964 2149 : tree base = gimple_call_arg (g, 1);
3965 2149 : gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
3966 2149 : tree decl = TREE_OPERAND (base, 0);
3967 :
3968 : /* For a nested function, we can have: ASAN_MARK (2, &FRAME.2.fp_input, 4) */
3969 2149 : if (TREE_CODE (decl) == COMPONENT_REF
3970 2149 : && DECL_NONLOCAL_FRAME (TREE_OPERAND (decl, 0)))
3971 1 : decl = TREE_OPERAND (decl, 0);
3972 :
3973 2149 : gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
3974 :
3975 2149 : if (hwassist_sanitize_p ())
3976 : {
3977 0 : gcc_assert (param_hwasan_instrument_stack);
3978 0 : gimple_seq stmts = NULL;
3979 : /* Here we swap ASAN_MARK calls for HWASAN_MARK.
3980 : This is because we are using the approach of using ASAN_MARK as a
3981 : synonym until here.
3982 : That approach means we don't yet have to duplicate all the special
3983 : cases for ASAN_MARK and ASAN_POISON with the exact same handling but
3984 : called HWASAN_MARK etc.
3985 :
3986 : N.b. __asan_poison_stack_memory (which implements ASAN_MARK for ASAN)
3987 : rounds the size up to its shadow memory granularity, while
3988 : __hwasan_tag_memory (which implements the same for HWASAN) does not.
3989 : Hence we emit HWASAN_MARK with an aligned size unlike ASAN_MARK. */
3990 0 : tree len = gimple_call_arg (g, 2);
3991 0 : tree new_len = gimple_build_round_up (&stmts, loc, size_type_node, len,
3992 0 : HWASAN_TAG_GRANULE_SIZE);
3993 0 : gimple_build (&stmts, loc, CFN_HWASAN_MARK,
3994 : void_type_node, gimple_call_arg (g, 0),
3995 : base, new_len);
3996 0 : gsi_replace_with_seq (iter, stmts, true);
3997 0 : return false;
3998 : }
3999 :
4000 2149 : if (is_poison)
4001 : {
4002 1412 : if (asan_handled_variables == NULL)
4003 387 : asan_handled_variables = new hash_set<tree> (16);
4004 1412 : asan_handled_variables->add (decl);
4005 : }
4006 2149 : tree len = gimple_call_arg (g, 2);
4007 :
4008 2149 : gcc_assert (poly_int_tree_p (len));
4009 :
4010 2149 : g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
4011 : NOP_EXPR, base);
4012 2149 : gimple_set_location (g, loc);
4013 2149 : gsi_replace (iter, g, false);
4014 2149 : tree base_addr = gimple_assign_lhs (g);
4015 :
4016 : /* Generate direct emission if size_in_bytes is small. */
4017 2149 : unsigned threshold = param_use_after_scope_direct_emission_threshold;
4018 2149 : if (tree_fits_uhwi_p (len) && tree_to_uhwi (len) <= threshold)
4019 : {
4020 2096 : unsigned HOST_WIDE_INT size_in_bytes = tree_to_uhwi (len);
4021 2096 : const unsigned HOST_WIDE_INT shadow_size
4022 2096 : = shadow_mem_size (size_in_bytes);
4023 2096 : const unsigned int shadow_align
4024 2096 : = (get_pointer_alignment (base) / BITS_PER_UNIT) >> ASAN_SHADOW_SHIFT;
4025 :
4026 2096 : tree shadow = build_shadow_mem_access (iter, loc, base_addr,
4027 : shadow_ptr_types[0], true);
4028 :
4029 6385 : for (unsigned HOST_WIDE_INT offset = 0; offset < shadow_size;)
4030 : {
4031 2193 : unsigned size = 1;
4032 2193 : if (shadow_size - offset >= 4
4033 : && (!STRICT_ALIGNMENT || shadow_align >= 4))
4034 : size = 4;
4035 1694 : else if (shadow_size - offset >= 2
4036 : && (!STRICT_ALIGNMENT || shadow_align >= 2))
4037 272 : size = 2;
4038 :
4039 2193 : unsigned HOST_WIDE_INT last_chunk_size = 0;
4040 2193 : unsigned HOST_WIDE_INT s = (offset + size) * ASAN_SHADOW_GRANULARITY;
4041 2193 : if (s > size_in_bytes)
4042 1152 : last_chunk_size = ASAN_SHADOW_GRANULARITY - (s - size_in_bytes);
4043 :
4044 2193 : asan_store_shadow_bytes (iter, loc, shadow, offset, is_poison,
4045 : size, last_chunk_size);
4046 2193 : offset += size;
4047 : }
4048 : }
4049 : else
4050 : {
4051 53 : g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
4052 : NOP_EXPR, len);
4053 53 : gimple_set_location (g, loc);
4054 53 : gsi_safe_insert_before (iter, g);
4055 53 : tree sz_arg = gimple_assign_lhs (g);
4056 :
4057 53 : tree fun
4058 71 : = builtin_decl_implicit (is_poison ? BUILT_IN_ASAN_POISON_STACK_MEMORY
4059 : : BUILT_IN_ASAN_UNPOISON_STACK_MEMORY);
4060 53 : g = gimple_build_call (fun, 2, base_addr, sz_arg);
4061 53 : gimple_set_location (g, loc);
4062 53 : gsi_insert_after (iter, g, GSI_NEW_STMT);
4063 : }
4064 :
4065 : return false;
4066 : }
4067 :
4068 : /* Expand the ASAN_{LOAD,STORE} builtins. */
4069 :
4070 : bool
4071 18966 : asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
4072 : {
4073 18966 : gcc_assert (!hwassist_sanitize_p ());
4074 18966 : gimple *g = gsi_stmt (*iter);
4075 18966 : location_t loc = gimple_location (g);
4076 18966 : bool recover_p;
4077 18966 : if (flag_sanitize & SANITIZE_USER_ADDRESS)
4078 18921 : recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
4079 : else
4080 45 : recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
4081 :
4082 18966 : HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
4083 18966 : gcc_assert (flags < ASAN_CHECK_LAST);
4084 18966 : bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
4085 18966 : bool is_store = (flags & ASAN_CHECK_STORE) != 0;
4086 18966 : bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
4087 :
4088 18966 : tree base = gimple_call_arg (g, 1);
4089 18966 : tree len = gimple_call_arg (g, 2);
4090 18966 : HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3));
4091 :
4092 36896 : HOST_WIDE_INT size_in_bytes
4093 18966 : = is_scalar_access && tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
4094 :
4095 18966 : if (use_calls)
4096 : {
4097 : /* Instrument using callbacks. */
4098 103 : gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
4099 : NOP_EXPR, base);
4100 103 : gimple_set_location (g, loc);
4101 103 : gsi_insert_before (iter, g, GSI_SAME_STMT);
4102 103 : tree base_addr = gimple_assign_lhs (g);
4103 :
4104 103 : int nargs;
4105 103 : tree fun = check_func (is_store, recover_p, size_in_bytes, &nargs);
4106 103 : if (nargs == 1)
4107 75 : g = gimple_build_call (fun, 1, base_addr);
4108 : else
4109 : {
4110 28 : gcc_assert (nargs == 2);
4111 28 : g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
4112 : NOP_EXPR, len);
4113 28 : gimple_set_location (g, loc);
4114 28 : gsi_insert_before (iter, g, GSI_SAME_STMT);
4115 28 : tree sz_arg = gimple_assign_lhs (g);
4116 28 : g = gimple_build_call (fun, nargs, base_addr, sz_arg);
4117 : }
4118 103 : gimple_set_location (g, loc);
4119 103 : gsi_replace (iter, g, false);
4120 103 : return false;
4121 : }
4122 :
4123 18863 : HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
4124 :
4125 17855 : tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
4126 18863 : tree shadow_type = TREE_TYPE (shadow_ptr_type);
4127 :
4128 18863 : gimple_stmt_iterator gsi = *iter;
4129 :
4130 18863 : if (!is_non_zero_len)
4131 : {
4132 : /* So, the length of the memory area to asan-protect is
4133 : non-constant. Let's guard the generated instrumentation code
4134 : like:
4135 :
4136 : if (len != 0)
4137 : {
4138 : //asan instrumentation code goes here.
4139 : }
4140 : // fallthrough instructions, starting with *ITER. */
4141 :
4142 0 : g = gimple_build_cond (NE_EXPR,
4143 : len,
4144 0 : build_int_cst (TREE_TYPE (len), 0),
4145 : NULL_TREE, NULL_TREE);
4146 0 : gimple_set_location (g, loc);
4147 :
4148 0 : basic_block then_bb, fallthrough_bb;
4149 0 : insert_if_then_before_iter (as_a <gcond *> (g), iter,
4150 : /*then_more_likely_p=*/true,
4151 : &then_bb, &fallthrough_bb);
4152 : /* Note that fallthrough_bb starts with the statement that was
4153 : pointed to by ITER. */
4154 :
4155 : /* The 'then block' of the 'if (len != 0) condition is where
4156 : we'll generate the asan instrumentation code now. */
4157 0 : gsi = gsi_last_bb (then_bb);
4158 : }
4159 :
4160 : /* Get an iterator on the point where we can add the condition
4161 : statement for the instrumentation. */
4162 18863 : basic_block then_bb, else_bb;
4163 18863 : gsi = create_cond_insert_point (&gsi, /*before_p*/false,
4164 : /*then_more_likely_p=*/false,
4165 : /*create_then_fallthru_edge*/recover_p,
4166 : &then_bb,
4167 : &else_bb);
4168 :
4169 18863 : g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
4170 : NOP_EXPR, base);
4171 18863 : gimple_set_location (g, loc);
4172 18863 : gsi_insert_before (&gsi, g, GSI_NEW_STMT);
4173 18863 : tree base_addr = gimple_assign_lhs (g);
4174 :
4175 18863 : tree t = NULL_TREE;
4176 18863 : if (real_size_in_bytes >= 8)
4177 : {
4178 12244 : tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
4179 : shadow_ptr_type);
4180 12244 : t = shadow;
4181 : }
4182 : else
4183 : {
4184 : /* Slow path for 1, 2 and 4 byte accesses. */
4185 : /* Test (shadow != 0)
4186 : & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow). */
4187 6619 : tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
4188 : shadow_ptr_type);
4189 6619 : gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
4190 6619 : gimple_seq seq = NULL;
4191 6619 : gimple_seq_add_stmt (&seq, shadow_test);
4192 : /* Aligned (>= 8 bytes) can test just
4193 : (real_size_in_bytes - 1 >= shadow), as base_addr & 7 is known
4194 : to be 0. */
4195 6619 : if (align < 8)
4196 : {
4197 4655 : gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
4198 : base_addr, 7));
4199 4655 : gimple_seq_add_stmt (&seq,
4200 9310 : build_type_cast (shadow_type,
4201 : gimple_seq_last (seq)));
4202 4655 : if (real_size_in_bytes > 1)
4203 1857 : gimple_seq_add_stmt (&seq,
4204 1857 : build_assign (PLUS_EXPR,
4205 : gimple_seq_last (seq),
4206 1857 : real_size_in_bytes - 1));
4207 9310 : t = gimple_assign_lhs (gimple_seq_last_stmt (seq));
4208 : }
4209 : else
4210 1964 : t = build_int_cst (shadow_type, real_size_in_bytes - 1);
4211 6619 : gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, t, shadow));
4212 13238 : gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
4213 : gimple_seq_last (seq)));
4214 13238 : t = gimple_assign_lhs (gimple_seq_last (seq));
4215 6619 : gimple_seq_set_location (seq, loc);
4216 6619 : gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
4217 :
4218 : /* For non-constant, misaligned or otherwise weird access sizes,
4219 : check first and last byte. */
4220 6619 : if (size_in_bytes == -1)
4221 : {
4222 1008 : g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
4223 : MINUS_EXPR, len,
4224 : build_int_cst (pointer_sized_int_node, 1));
4225 1008 : gimple_set_location (g, loc);
4226 1008 : gsi_insert_after (&gsi, g, GSI_NEW_STMT);
4227 1008 : tree last = gimple_assign_lhs (g);
4228 1008 : g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
4229 : PLUS_EXPR, base_addr, last);
4230 1008 : gimple_set_location (g, loc);
4231 1008 : gsi_insert_after (&gsi, g, GSI_NEW_STMT);
4232 1008 : tree base_end_addr = gimple_assign_lhs (g);
4233 :
4234 1008 : tree shadow = build_shadow_mem_access (&gsi, loc, base_end_addr,
4235 : shadow_ptr_type);
4236 1008 : gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
4237 1008 : gimple_seq seq = NULL;
4238 1008 : gimple_seq_add_stmt (&seq, shadow_test);
4239 1008 : gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
4240 : base_end_addr, 7));
4241 2016 : gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
4242 : gimple_seq_last (seq)));
4243 2016 : gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
4244 : gimple_seq_last (seq),
4245 : shadow));
4246 2016 : gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
4247 : gimple_seq_last (seq)));
4248 2016 : gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
4249 : gimple_seq_last (seq)));
4250 2016 : t = gimple_assign_lhs (gimple_seq_last (seq));
4251 1008 : gimple_seq_set_location (seq, loc);
4252 1008 : gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
4253 : }
4254 : }
4255 :
4256 18863 : g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
4257 : NULL_TREE, NULL_TREE);
4258 18863 : gimple_set_location (g, loc);
4259 18863 : gsi_insert_after (&gsi, g, GSI_NEW_STMT);
4260 :
4261 : /* Generate call to the run-time library (e.g. __asan_report_load8). */
4262 18863 : gsi = gsi_start_bb (then_bb);
4263 18863 : int nargs;
4264 18863 : tree fun = report_error_func (is_store, recover_p, size_in_bytes, &nargs);
4265 18863 : g = gimple_build_call (fun, nargs, base_addr, len);
4266 18863 : gimple_set_location (g, loc);
4267 18863 : gsi_insert_after (&gsi, g, GSI_NEW_STMT);
4268 :
4269 18863 : gsi_remove (iter, true);
4270 18863 : *iter = gsi_start_bb (else_bb);
4271 :
4272 18863 : return true;
4273 : }
4274 :
4275 : /* Create ASAN shadow variable for a VAR_DECL which has been rewritten
4276 : into SSA. Already seen VAR_DECLs are stored in SHADOW_VARS_MAPPING. */
4277 :
4278 : static tree
4279 59 : create_asan_shadow_var (tree var_decl,
4280 : hash_map<tree, tree> &shadow_vars_mapping)
4281 : {
4282 59 : tree *slot = shadow_vars_mapping.get (var_decl);
4283 59 : if (slot == NULL)
4284 : {
4285 59 : tree shadow_var = copy_node (var_decl);
4286 :
4287 59 : copy_body_data id;
4288 59 : memset (&id, 0, sizeof (copy_body_data));
4289 59 : id.src_fn = id.dst_fn = current_function_decl;
4290 59 : copy_decl_for_dup_finish (&id, var_decl, shadow_var);
4291 :
4292 59 : DECL_ARTIFICIAL (shadow_var) = 1;
4293 59 : DECL_IGNORED_P (shadow_var) = 1;
4294 59 : DECL_SEEN_IN_BIND_EXPR_P (shadow_var) = 0;
4295 59 : gimple_add_tmp_var (shadow_var);
4296 :
4297 59 : shadow_vars_mapping.put (var_decl, shadow_var);
4298 59 : return shadow_var;
4299 : }
4300 : else
4301 0 : return *slot;
4302 : }
4303 :
4304 : /* Expand ASAN_POISON ifn. */
4305 :
4306 : bool
4307 64 : asan_expand_poison_ifn (gimple_stmt_iterator *iter,
4308 : bool *need_commit_edge_insert,
4309 : hash_map<tree, tree> &shadow_vars_mapping)
4310 : {
4311 64 : gimple *g = gsi_stmt (*iter);
4312 64 : tree poisoned_var = gimple_call_lhs (g);
4313 64 : if (!poisoned_var || has_zero_uses (poisoned_var))
4314 : {
4315 5 : gsi_remove (iter, true);
4316 5 : return true;
4317 : }
4318 :
4319 59 : if (SSA_NAME_VAR (poisoned_var) == NULL_TREE)
4320 0 : SET_SSA_NAME_VAR_OR_IDENTIFIER (poisoned_var,
4321 : create_tmp_var (TREE_TYPE (poisoned_var)));
4322 :
4323 59 : tree shadow_var = create_asan_shadow_var (SSA_NAME_VAR (poisoned_var),
4324 : shadow_vars_mapping);
4325 :
4326 59 : bool recover_p;
4327 59 : if (flag_sanitize & SANITIZE_USER_ADDRESS)
4328 59 : recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
4329 : else
4330 0 : recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
4331 59 : tree size = DECL_SIZE_UNIT (shadow_var);
4332 59 : gimple *poison_call
4333 59 : = gimple_build_call_internal (IFN_ASAN_MARK, 3,
4334 : build_int_cst (integer_type_node,
4335 : ASAN_MARK_POISON),
4336 : build_fold_addr_expr (shadow_var), size);
4337 :
4338 59 : gimple *use;
4339 59 : imm_use_iterator imm_iter;
4340 177 : FOR_EACH_IMM_USE_STMT (use, imm_iter, poisoned_var)
4341 : {
4342 118 : if (is_gimple_debug (use))
4343 59 : continue;
4344 :
4345 59 : int nargs;
4346 59 : bool store_p = gimple_call_internal_p (use, IFN_ASAN_POISON_USE);
4347 59 : gcall *call;
4348 59 : if (hwassist_sanitize_p ())
4349 : {
4350 0 : tree fun = builtin_decl_implicit (BUILT_IN_HWASAN_TAG_MISMATCH4);
4351 : /* NOTE: hwasan has no __hwasan_report_* functions like asan does.
4352 : We use __hwasan_tag_mismatch4 with arguments that tell it the
4353 : size of access and load to report all tag mismatches.
4354 :
4355 : The arguments to this function are:
4356 : Address of invalid access.
4357 : Bitfield containing information about the access
4358 : (access_info)
4359 : Pointer to a frame of registers
4360 : (for use in printing the contents of registers in a dump)
4361 : Not used yet -- to be used by inline instrumentation.
4362 : Size of access.
4363 :
4364 : The access_info bitfield encodes the following pieces of
4365 : information:
4366 : - Is this a store or load?
4367 : access_info & 0x10 => store
4368 : - Should the program continue after reporting the error?
4369 : access_info & 0x20 => recover
4370 : - What size access is this (not used here since we can always
4371 : pass the size in the last argument)
4372 :
4373 : if (access_info & 0xf == 0xf)
4374 : size is taken from last argument.
4375 : else
4376 : size == 1 << (access_info & 0xf)
4377 :
4378 : The last argument contains the size of the access iff the
4379 : access_info size indicator is 0xf (we always use this argument
4380 : rather than storing the size in the access_info bitfield).
4381 :
4382 : See the function definition `__hwasan_tag_mismatch4` in
4383 : libsanitizer/hwasan for the full definition.
4384 : */
4385 0 : unsigned access_info = (0x20 * recover_p)
4386 0 : + (0x10 * store_p)
4387 0 : + (0xf);
4388 0 : call = gimple_build_call (fun, 4,
4389 : build_fold_addr_expr (shadow_var),
4390 : build_int_cst (pointer_sized_int_node,
4391 0 : access_info),
4392 : build_int_cst (pointer_sized_int_node, 0),
4393 : size);
4394 : }
4395 : else
4396 : {
4397 59 : tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size),
4398 : &nargs);
4399 59 : tree ptrmode_type
4400 59 : = (nargs == 2 ? (*lang_hooks.types.type_for_mode) (ptr_mode, 0)
4401 : : NULL_TREE);
4402 87 : call = gimple_build_call (fun, nargs,
4403 : build_fold_addr_expr (shadow_var),
4404 : nargs == 2
4405 28 : ? fold_convert (ptrmode_type, size)
4406 : : NULL_TREE);
4407 : }
4408 59 : gimple_set_location (call, gimple_location (use));
4409 59 : gimple *call_to_insert = call;
4410 :
4411 : /* The USE can be a gimple PHI node. If so, insert the call on
4412 : all edges leading to the PHI node. */
4413 59 : if (is_a <gphi *> (use))
4414 : {
4415 : gphi *phi = dyn_cast<gphi *> (use);
4416 20 : for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
4417 15 : if (gimple_phi_arg_def (phi, i) == poisoned_var)
4418 : {
4419 5 : edge e = gimple_phi_arg_edge (phi, i);
4420 :
4421 : /* Do not insert on an edge we can't split. */
4422 5 : if (e->flags & EDGE_ABNORMAL)
4423 5 : continue;
4424 :
4425 0 : if (call_to_insert == NULL)
4426 0 : call_to_insert = gimple_copy (call);
4427 :
4428 0 : gsi_insert_seq_on_edge (e, call_to_insert);
4429 0 : *need_commit_edge_insert = true;
4430 0 : call_to_insert = NULL;
4431 : }
4432 : }
4433 : else
4434 : {
4435 54 : gimple_stmt_iterator gsi = gsi_for_stmt (use);
4436 54 : if (store_p)
4437 18 : gsi_replace (&gsi, call, true);
4438 : else
4439 36 : gsi_insert_before (&gsi, call, GSI_NEW_STMT);
4440 : }
4441 59 : }
4442 :
4443 59 : SSA_NAME_IS_DEFAULT_DEF (poisoned_var) = true;
4444 59 : SSA_NAME_DEF_STMT (poisoned_var) = gimple_build_nop ();
4445 59 : gsi_replace (iter, poison_call, false);
4446 :
4447 59 : return true;
4448 : }
4449 :
4450 : /* Instrument the current function. */
4451 :
4452 : static unsigned int
4453 6594 : asan_instrument (void)
4454 : {
4455 6594 : if (hwassist_sanitize_p ())
4456 : {
4457 463 : initialize_sanitizer_builtins ();
4458 463 : transform_statements ();
4459 463 : return 0;
4460 : }
4461 :
4462 6131 : if (shadow_ptr_types[0] == NULL_TREE)
4463 2356 : asan_init_shadow_ptr_types ();
4464 6131 : transform_statements ();
4465 6131 : last_alloca_addr = NULL_TREE;
4466 6131 : return 0;
4467 : }
4468 :
4469 : static bool
4470 1512293 : gate_asan (void)
4471 : {
4472 447451 : return sanitize_flags_p (SANITIZE_ADDRESS);
4473 : }
4474 :
4475 : namespace {
4476 :
4477 : const pass_data pass_data_asan =
4478 : {
4479 : GIMPLE_PASS, /* type */
4480 : "asan", /* name */
4481 : OPTGROUP_NONE, /* optinfo_flags */
4482 : TV_NONE, /* tv_id */
4483 : ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
4484 : 0, /* properties_provided */
4485 : 0, /* properties_destroyed */
4486 : 0, /* todo_flags_start */
4487 : TODO_update_ssa, /* todo_flags_finish */
4488 : };
4489 :
4490 : class pass_asan : public gimple_opt_pass
4491 : {
4492 : public:
4493 589174 : pass_asan (gcc::context *ctxt)
4494 1178348 : : gimple_opt_pass (pass_data_asan, ctxt)
4495 : {}
4496 :
4497 : /* opt_pass methods: */
4498 294587 : opt_pass * clone () final override { return new pass_asan (m_ctxt); }
4499 1064842 : bool gate (function *) final override
4500 : {
4501 1064842 : return gate_asan () || gate_hwasan () || gate_memtag ();
4502 : }
4503 5181 : unsigned int execute (function *) final override
4504 : {
4505 5181 : return asan_instrument ();
4506 : }
4507 :
4508 : }; // class pass_asan
4509 :
4510 : } // anon namespace
4511 :
4512 : gimple_opt_pass *
4513 294587 : make_pass_asan (gcc::context *ctxt)
4514 : {
4515 294587 : return new pass_asan (ctxt);
4516 : }
4517 :
4518 : namespace {
4519 :
4520 : const pass_data pass_data_asan_O0 =
4521 : {
4522 : GIMPLE_PASS, /* type */
4523 : "asan0", /* name */
4524 : OPTGROUP_NONE, /* optinfo_flags */
4525 : TV_NONE, /* tv_id */
4526 : ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
4527 : 0, /* properties_provided */
4528 : 0, /* properties_destroyed */
4529 : 0, /* todo_flags_start */
4530 : TODO_update_ssa, /* todo_flags_finish */
4531 : };
4532 :
4533 : class pass_asan_O0 : public gimple_opt_pass
4534 : {
4535 : public:
4536 294587 : pass_asan_O0 (gcc::context *ctxt)
4537 589174 : : gimple_opt_pass (pass_data_asan_O0, ctxt)
4538 : {}
4539 :
4540 : /* opt_pass methods: */
4541 1512174 : bool gate (function *) final override
4542 : {
4543 1959625 : return !optimize && (gate_asan () || gate_hwasan () || gate_memtag ());
4544 : }
4545 1413 : unsigned int execute (function *) final override
4546 : {
4547 1413 : return asan_instrument ();
4548 : }
4549 :
4550 : }; // class pass_asan_O0
4551 :
4552 : } // anon namespace
4553 :
4554 : gimple_opt_pass *
4555 294587 : make_pass_asan_O0 (gcc::context *ctxt)
4556 : {
4557 294587 : return new pass_asan_O0 (ctxt);
4558 : }
4559 :
4560 : /* HWASAN */
4561 :
4562 : /* For stack tagging:
4563 :
4564 : Return the offset from the frame base tag that the "next" expanded object
4565 : should have. */
4566 : uint8_t
4567 178 : hwasan_current_frame_tag ()
4568 : {
4569 178 : return hwasan_frame_tag_offset;
4570 : }
4571 :
4572 : /* For stack tagging:
4573 :
4574 : Return the 'base pointer' for this function. If that base pointer has not
4575 : yet been created then we create a register to hold it and record the insns
4576 : to initialize the register in `hwasan_frame_base_init_seq` for later
4577 : emission. */
4578 : rtx
4579 89 : hwasan_frame_base ()
4580 : {
4581 89 : if (! hwasan_frame_base_ptr)
4582 : {
4583 63 : start_sequence ();
4584 63 : hwasan_frame_base_ptr
4585 63 : = force_reg (Pmode,
4586 63 : targetm.memtag.insert_random_tag (virtual_stack_vars_rtx,
4587 : NULL_RTX));
4588 63 : hwasan_frame_base_init_seq = end_sequence ();
4589 : }
4590 :
4591 89 : return hwasan_frame_base_ptr;
4592 : }
4593 :
4594 : /* For stack tagging:
4595 :
4596 : Check whether this RTX is a standard pointer addressing the base of the
4597 : stack variables for this frame. Returns true if the RTX is either
4598 : virtual_stack_vars_rtx or hwasan_frame_base_ptr. */
4599 : bool
4600 2026743 : stack_vars_base_reg_p (rtx base)
4601 : {
4602 2026743 : return base == virtual_stack_vars_rtx || base == hwasan_frame_base_ptr;
4603 : }
4604 :
4605 : /* For stack tagging:
4606 :
4607 : Emit frame base initialisation.
4608 : If hwasan_frame_base has been used before here then
4609 : hwasan_frame_base_init_seq contains the sequence of instructions to
4610 : initialize it. This must be put just before the hwasan prologue, so we emit
4611 : the insns before parm_birth_insn (which will point to the first instruction
4612 : of the hwasan prologue if it exists).
4613 :
4614 : We update `parm_birth_insn` to point to the start of this initialisation
4615 : since that represents the end of the initialisation done by
4616 : expand_function_{start,end} functions and we want to maintain that. */
4617 : void
4618 379 : hwasan_maybe_emit_frame_base_init ()
4619 : {
4620 379 : if (! hwasan_frame_base_init_seq)
4621 : return;
4622 16 : emit_insn_before (hwasan_frame_base_init_seq, parm_birth_insn);
4623 16 : parm_birth_insn = hwasan_frame_base_init_seq;
4624 : }
4625 :
4626 : /* Record a compile-time constant size stack variable that HWASAN will need to
4627 : tag. This record of the range of a stack variable will be used by
4628 : `hwasan_emit_prologue` to emit the RTL at the start of each frame which will
4629 : set tags in the shadow memory according to the assigned tag for each object.
4630 :
4631 : The range that the object spans in stack space should be described by the
4632 : bounds `untagged_base + nearest_offset` and
4633 : `untagged_base + farthest_offset`.
4634 : `tagged_base` is the base address which contains the "base frame tag" for
4635 : this frame, and from which the value to address this object with will be
4636 : calculated.
4637 :
4638 : We record the `untagged_base` since the functions in the hwasan library we
4639 : use to tag memory take pointers without a tag. */
4640 : void
4641 89 : hwasan_record_stack_var (rtx untagged_base, rtx tagged_base,
4642 : poly_int64 nearest_offset, poly_int64 farthest_offset)
4643 : {
4644 89 : hwasan_stack_var cur_var;
4645 89 : cur_var.untagged_base = untagged_base;
4646 89 : cur_var.tagged_base = tagged_base;
4647 89 : cur_var.nearest_offset = nearest_offset;
4648 89 : cur_var.farthest_offset = farthest_offset;
4649 89 : cur_var.tag_offset = hwasan_current_frame_tag ();
4650 :
4651 89 : hwasan_tagged_stack_vars.safe_push (cur_var);
4652 89 : }
4653 :
4654 : /* Return the RTX representing the farthest extent of the statically allocated
4655 : stack objects for this frame. If hwasan_frame_base_ptr has not been
4656 : initialized then we are not storing any static variables on the stack in
4657 : this frame. In this case we return NULL_RTX to represent that.
4658 :
4659 : Otherwise simply return virtual_stack_vars_rtx + frame_offset. */
4660 : rtx
4661 379 : hwasan_get_frame_extent ()
4662 : {
4663 379 : return (hwasan_frame_base_ptr
4664 379 : ? plus_constant (Pmode, virtual_stack_vars_rtx, frame_offset)
4665 379 : : NULL_RTX);
4666 : }
4667 :
4668 : /* For stack tagging:
4669 :
4670 : Increment the frame tag offset modulo the size a tag can represent. */
4671 : void
4672 89 : hwasan_increment_frame_tag ()
4673 : {
4674 89 : uint8_t tag_bits = HWASAN_TAG_SIZE;
4675 89 : gcc_assert (HWASAN_TAG_SIZE
4676 : <= sizeof (hwasan_frame_tag_offset) * CHAR_BIT);
4677 89 : hwasan_frame_tag_offset = (hwasan_frame_tag_offset + 1) % (1 << tag_bits);
4678 : /* The "background tag" of the stack is zero by definition.
4679 : This is the tag that objects like parameters passed on the stack and
4680 : spilled registers are given. It is handy to avoid this tag for objects
4681 : whose tags we decide ourselves, partly to ensure that buffer overruns
4682 : can't affect these important variables (e.g. saved link register, saved
4683 : stack pointer etc) and partly to make debugging easier (everything with a
4684 : tag of zero is space allocated automatically by the compiler).
4685 :
4686 : This is not feasible when using random frame tags (the default
4687 : configuration for hwasan) since the tag for the given frame is randomly
4688 : chosen at runtime. In order to avoid any tags matching the stack
4689 : background we would need to decide tag offsets at runtime instead of
4690 : compile time (and pay the resulting performance cost).
4691 :
4692 : When not using random base tags for each frame (i.e. when compiled with
4693 : `--param hwasan-random-frame-tag=0`) the base tag for each frame is zero.
4694 : This means the tag that each object gets is equal to the
4695 : hwasan_frame_tag_offset used in determining it.
4696 : When this is the case we *can* ensure no object gets the tag of zero by
4697 : simply ensuring no object has the hwasan_frame_tag_offset of zero.
4698 :
4699 : There is the extra complication that we only record the
4700 : hwasan_frame_tag_offset here (which is the offset from the tag stored in
4701 : the stack pointer). In the kernel, the tag in the stack pointer is 0xff
4702 : rather than zero. This does not cause problems since tags of 0xff are
4703 : never checked in the kernel. As mentioned at the beginning of this
4704 : comment the background tag of the stack is zero by definition, which means
4705 : that for the kernel we should skip offsets of both 0 and 1 from the stack
4706 : pointer. Avoiding the offset of 0 ensures we use a tag which will be
4707 : checked, avoiding the offset of 1 ensures we use a tag that is not the
4708 : same as the background. */
4709 89 : if (hwasan_frame_tag_offset == 0 && ! param_hwasan_random_frame_tag)
4710 0 : hwasan_frame_tag_offset += 1;
4711 16 : if (hwasan_frame_tag_offset == 1 && ! param_hwasan_random_frame_tag
4712 89 : && sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS))
4713 0 : hwasan_frame_tag_offset += 1;
4714 89 : }
4715 :
4716 : /* Clear internal state for the next function.
4717 : This function is called before variables on the stack get expanded, in
4718 : `init_vars_expansion`. */
4719 : void
4720 1123 : hwasan_record_frame_init ()
4721 : {
4722 1123 : delete asan_used_labels;
4723 1123 : asan_used_labels = NULL;
4724 :
4725 : /* If this isn't the case then some stack variable was recorded *before*
4726 : hwasan_record_frame_init is called, yet *after* the hwasan prologue for
4727 : the previous frame was emitted. Such stack variables would not have
4728 : their shadow stack filled in. */
4729 1123 : gcc_assert (hwasan_tagged_stack_vars.is_empty ());
4730 1123 : hwasan_frame_base_ptr = NULL_RTX;
4731 1123 : hwasan_frame_base_init_seq = NULL;
4732 :
4733 : /* When not using a random frame tag we can avoid the background stack
4734 : color which gives the user a little better debug output upon a crash.
4735 : Meanwhile, when using a random frame tag it will be nice to avoid adding
4736 : tags for the first object since that is unnecessary extra work.
4737 : Hence set the initial hwasan_frame_tag_offset to be 0 if using a random
4738 : frame tag and 1 otherwise.
4739 :
4740 : As described in hwasan_increment_frame_tag, in the kernel the stack
4741 : pointer has the tag 0xff. That means that to avoid 0xff and 0 (the tag
4742 : which the kernel does not check and the background tag respectively) we
4743 : start with a tag offset of 2. */
4744 2096 : hwasan_frame_tag_offset = param_hwasan_random_frame_tag
4745 : ? 0
4746 973 : : sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS) ? 2 : 1;
4747 1123 : }
4748 :
4749 : /* For stack tagging:
4750 : (Emits HWASAN equivalent of what is emitted by
4751 : `asan_emit_stack_protection`).
4752 :
4753 : Emits the extra prologue code to set the shadow stack as required for HWASAN
4754 : stack instrumentation.
4755 :
4756 : Uses the vector of recorded stack variables hwasan_tagged_stack_vars. When
4757 : this function has completed hwasan_tagged_stack_vars is empty and all
4758 : objects it had pointed to are deallocated. */
4759 : void
4760 379 : hwasan_emit_prologue ()
4761 : {
4762 : /* We need untagged base pointers since libhwasan only accepts untagged
4763 : pointers in __hwasan_tag_memory. We need the tagged base pointer to obtain
4764 : the base tag for an offset. */
4765 :
4766 379 : if (hwasan_tagged_stack_vars.is_empty ())
4767 379 : return;
4768 :
4769 63 : poly_int64 bot = 0, top = 0;
4770 152 : for (hwasan_stack_var &cur : hwasan_tagged_stack_vars)
4771 : {
4772 89 : poly_int64 nearest = cur.nearest_offset;
4773 89 : poly_int64 farthest = cur.farthest_offset;
4774 :
4775 89 : if (known_ge (nearest, farthest))
4776 : {
4777 : top = nearest;
4778 : bot = farthest;
4779 : }
4780 : else
4781 : {
4782 : /* Given how these values are calculated, one must be known greater
4783 : than the other. */
4784 0 : gcc_assert (known_le (nearest, farthest));
4785 0 : top = farthest;
4786 0 : bot = nearest;
4787 : }
4788 89 : poly_int64 size = (top - bot);
4789 :
4790 : /* Assert the edge of each variable is aligned to the HWASAN tag granule
4791 : size. */
4792 178 : gcc_assert (multiple_p (top, HWASAN_TAG_GRANULE_SIZE));
4793 178 : gcc_assert (multiple_p (bot, HWASAN_TAG_GRANULE_SIZE));
4794 178 : gcc_assert (multiple_p (size, HWASAN_TAG_GRANULE_SIZE));
4795 :
4796 89 : rtx base_tag = targetm.memtag.extract_tag (cur.tagged_base, NULL_RTX);
4797 :
4798 89 : rtx bottom = convert_memory_address (ptr_mode,
4799 : plus_constant (Pmode,
4800 : cur.untagged_base,
4801 : bot));
4802 89 : if (memtag_sanitize_p ())
4803 : {
4804 0 : expand_operand ops[3];
4805 0 : rtx tagged_addr = gen_reg_rtx (ptr_mode);
4806 :
4807 : /* Check if the required target instructions are present. */
4808 0 : gcc_assert (targetm.have_compose_tag ());
4809 0 : gcc_assert (targetm.have_tag_memory ());
4810 :
4811 : /* The AArch64 has addg/subg instructions which are working directly
4812 : on a tagged pointer. */
4813 0 : create_output_operand (&ops[0], tagged_addr, ptr_mode);
4814 0 : create_input_operand (&ops[1], base_tag, ptr_mode);
4815 0 : create_integer_operand (&ops[2], cur.tag_offset);
4816 0 : expand_insn (targetm.code_for_compose_tag, 3, ops);
4817 :
4818 0 : emit_insn (targetm.gen_tag_memory (bottom, tagged_addr,
4819 : gen_int_mode (size, ptr_mode)));
4820 : }
4821 : else
4822 : {
4823 89 : rtx fn = init_one_libfunc ("__hwasan_tag_memory");
4824 89 : rtx tag = plus_constant (QImode, base_tag, cur.tag_offset);
4825 89 : tag = hwasan_truncate_to_tag_size (tag, NULL_RTX);
4826 89 : emit_library_call (fn, LCT_NORMAL, VOIDmode,
4827 : bottom, ptr_mode,
4828 : tag, QImode,
4829 : gen_int_mode (size, ptr_mode), ptr_mode);
4830 : }
4831 : }
4832 : /* Clear the stack vars, we've emitted the prologue for them all now. */
4833 63 : hwasan_tagged_stack_vars.truncate (0);
4834 : }
4835 :
4836 : /* For stack tagging:
4837 :
4838 : Return RTL insns to clear the tags between DYNAMIC and VARS pointers
4839 : into the stack. These instructions should be emitted at the end of
4840 : every function.
4841 :
4842 : If `dynamic` is NULL_RTX then no insns are returned. */
4843 : rtx_insn *
4844 379 : hwasan_emit_untag_frame (rtx dynamic, rtx vars)
4845 : {
4846 379 : if (! dynamic)
4847 : return NULL;
4848 :
4849 63 : start_sequence ();
4850 :
4851 63 : dynamic = convert_memory_address (ptr_mode, dynamic);
4852 63 : vars = convert_memory_address (ptr_mode, vars);
4853 :
4854 63 : rtx top_rtx;
4855 63 : rtx bot_rtx;
4856 63 : if (FRAME_GROWS_DOWNWARD)
4857 : {
4858 63 : top_rtx = vars;
4859 63 : bot_rtx = dynamic;
4860 : }
4861 : else
4862 : {
4863 : top_rtx = dynamic;
4864 : bot_rtx = vars;
4865 : }
4866 :
4867 63 : rtx size_rtx = simplify_gen_binary (MINUS, ptr_mode, top_rtx, bot_rtx);
4868 63 : if (!CONST_INT_P (size_rtx))
4869 0 : size_rtx = force_reg (ptr_mode, size_rtx);
4870 :
4871 63 : if (memtag_sanitize_p ())
4872 0 : emit_insn (targetm.gen_tag_memory (bot_rtx, HWASAN_STACK_BACKGROUND,
4873 : size_rtx));
4874 : else
4875 : {
4876 63 : rtx fn = init_one_libfunc ("__hwasan_tag_memory");
4877 63 : emit_library_call (fn, LCT_NORMAL, VOIDmode,
4878 : bot_rtx, ptr_mode,
4879 : HWASAN_STACK_BACKGROUND, QImode,
4880 : size_rtx, ptr_mode);
4881 : }
4882 :
4883 63 : do_pending_stack_adjust ();
4884 63 : return end_sequence ();
4885 : }
4886 :
4887 : /* Needs to be GTY(()), because cgraph_build_static_cdtor may
4888 : invoke ggc_collect. */
4889 : static GTY(()) tree hwasan_ctor_statements;
4890 :
4891 : /* Insert module initialization into this TU. This initialization calls the
4892 : initialization code for libhwasan. */
4893 : void
4894 265 : hwasan_finish_file (void)
4895 : {
4896 : /* Do not emit constructor initialization for the kernel.
4897 : (the kernel has its own initialization already). */
4898 265 : if (flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
4899 : return;
4900 :
4901 251 : initialize_sanitizer_builtins ();
4902 :
4903 : /* Avoid instrumenting code in the hwasan constructors/destructors. */
4904 251 : flag_sanitize &= ~SANITIZE_HWADDRESS;
4905 251 : int priority = MAX_RESERVED_INIT_PRIORITY - 1;
4906 251 : tree fn = builtin_decl_implicit (BUILT_IN_HWASAN_INIT);
4907 251 : append_to_statement_list (build_call_expr (fn, 0), &hwasan_ctor_statements);
4908 251 : cgraph_build_static_cdtor ('I', hwasan_ctor_statements, priority);
4909 251 : flag_sanitize |= SANITIZE_HWADDRESS;
4910 : }
4911 :
4912 : /* For stack tagging:
4913 :
4914 : Truncate `tag` to the number of bits that a tag uses (i.e. to
4915 : HWASAN_TAG_SIZE). Store the result in `target` if it's convenient. */
4916 : rtx
4917 89 : hwasan_truncate_to_tag_size (rtx tag, rtx target)
4918 : {
4919 89 : gcc_assert (GET_MODE (tag) == QImode);
4920 89 : if (HWASAN_TAG_SIZE != GET_MODE_PRECISION (QImode))
4921 : {
4922 89 : gcc_assert (GET_MODE_PRECISION (QImode) > HWASAN_TAG_SIZE);
4923 89 : rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << HWASAN_TAG_SIZE) - 1,
4924 : QImode);
4925 89 : tag = expand_simple_binop (QImode, AND, tag, mask, target,
4926 : /* unsignedp = */1, OPTAB_WIDEN);
4927 89 : gcc_assert (tag);
4928 : }
4929 89 : return tag;
4930 : }
4931 :
4932 : /* Construct a function tree for __hwasan_{load,store}{1,2,4,8,16,_n}.
4933 : IS_STORE is either 1 (for a store) or 0 (for a load). */
4934 : static combined_fn
4935 378 : hwasan_check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
4936 : int *nargs)
4937 : {
4938 378 : static enum built_in_function check[2][2][6]
4939 : = { { { BUILT_IN_HWASAN_LOAD1, BUILT_IN_HWASAN_LOAD2,
4940 : BUILT_IN_HWASAN_LOAD4, BUILT_IN_HWASAN_LOAD8,
4941 : BUILT_IN_HWASAN_LOAD16, BUILT_IN_HWASAN_LOADN },
4942 : { BUILT_IN_HWASAN_STORE1, BUILT_IN_HWASAN_STORE2,
4943 : BUILT_IN_HWASAN_STORE4, BUILT_IN_HWASAN_STORE8,
4944 : BUILT_IN_HWASAN_STORE16, BUILT_IN_HWASAN_STOREN } },
4945 : { { BUILT_IN_HWASAN_LOAD1_NOABORT,
4946 : BUILT_IN_HWASAN_LOAD2_NOABORT,
4947 : BUILT_IN_HWASAN_LOAD4_NOABORT,
4948 : BUILT_IN_HWASAN_LOAD8_NOABORT,
4949 : BUILT_IN_HWASAN_LOAD16_NOABORT,
4950 : BUILT_IN_HWASAN_LOADN_NOABORT },
4951 : { BUILT_IN_HWASAN_STORE1_NOABORT,
4952 : BUILT_IN_HWASAN_STORE2_NOABORT,
4953 : BUILT_IN_HWASAN_STORE4_NOABORT,
4954 : BUILT_IN_HWASAN_STORE8_NOABORT,
4955 : BUILT_IN_HWASAN_STORE16_NOABORT,
4956 : BUILT_IN_HWASAN_STOREN_NOABORT } } };
4957 378 : if (size_in_bytes == -1)
4958 : {
4959 0 : *nargs = 2;
4960 0 : return as_combined_fn (check[recover_p][is_store][5]);
4961 : }
4962 378 : *nargs = 1;
4963 378 : int size_log2 = exact_log2 (size_in_bytes);
4964 378 : gcc_assert (size_log2 >= 0 && size_log2 <= 5);
4965 378 : return as_combined_fn (check[recover_p][is_store][size_log2]);
4966 : }
4967 :
4968 : /* Expand the HWASAN_{LOAD,STORE} builtins. */
4969 : bool
4970 378 : hwasan_expand_check_ifn (gimple_stmt_iterator *iter, bool)
4971 : {
4972 378 : gimple *g = gsi_stmt (*iter);
4973 378 : location_t loc = gimple_location (g);
4974 378 : bool recover_p;
4975 378 : if (flag_sanitize & SANITIZE_USER_HWADDRESS)
4976 318 : recover_p = (flag_sanitize_recover & SANITIZE_USER_HWADDRESS) != 0;
4977 : else
4978 60 : recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_HWADDRESS) != 0;
4979 :
4980 378 : HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
4981 378 : gcc_assert (flags < ASAN_CHECK_LAST);
4982 378 : bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
4983 378 : bool is_store = (flags & ASAN_CHECK_STORE) != 0;
4984 378 : bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
4985 :
4986 378 : tree base = gimple_call_arg (g, 1);
4987 378 : tree len = gimple_call_arg (g, 2);
4988 :
4989 : /* `align` is unused for HWASAN_CHECK, but we pass the argument anyway
4990 : since that way the arguments match ASAN_CHECK. */
4991 : /* HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3)); */
4992 :
4993 1134 : unsigned HOST_WIDE_INT size_in_bytes
4994 378 : = is_scalar_access ? tree_to_shwi (len) : -1;
4995 :
4996 378 : gimple_stmt_iterator gsi = *iter;
4997 :
4998 378 : if (!is_non_zero_len)
4999 : {
5000 : /* So, the length of the memory area to hwasan-protect is
5001 : non-constant. Let's guard the generated instrumentation code
5002 : like:
5003 :
5004 : if (len != 0)
5005 : {
5006 : // hwasan instrumentation code goes here.
5007 : }
5008 : // fallthrough instructions, starting with *ITER. */
5009 :
5010 0 : g = gimple_build_cond (NE_EXPR,
5011 : len,
5012 0 : build_int_cst (TREE_TYPE (len), 0),
5013 : NULL_TREE, NULL_TREE);
5014 0 : gimple_set_location (g, loc);
5015 :
5016 0 : basic_block then_bb, fallthrough_bb;
5017 0 : insert_if_then_before_iter (as_a <gcond *> (g), iter,
5018 : /*then_more_likely_p=*/true,
5019 : &then_bb, &fallthrough_bb);
5020 : /* Note that fallthrough_bb starts with the statement that was
5021 : pointed to by ITER. */
5022 :
5023 : /* The 'then block' of the 'if (len != 0) condition is where
5024 : we'll generate the hwasan instrumentation code now. */
5025 0 : gsi = gsi_last_bb (then_bb);
5026 : }
5027 :
5028 378 : gimple_seq stmts = NULL;
5029 378 : tree base_addr = gimple_build (&stmts, loc, NOP_EXPR,
5030 : pointer_sized_int_node, base);
5031 :
5032 378 : int nargs = 0;
5033 378 : combined_fn fn
5034 378 : = hwasan_check_func (is_store, recover_p, size_in_bytes, &nargs);
5035 378 : if (nargs == 1)
5036 378 : gimple_build (&stmts, loc, fn, void_type_node, base_addr);
5037 : else
5038 : {
5039 0 : gcc_assert (nargs == 2);
5040 0 : tree sz_arg = gimple_build (&stmts, loc, NOP_EXPR,
5041 : pointer_sized_int_node, len);
5042 0 : gimple_build (&stmts, loc, fn, void_type_node, base_addr, sz_arg);
5043 : }
5044 :
5045 378 : gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
5046 378 : gsi_remove (iter, true);
5047 378 : *iter = gsi;
5048 378 : return false;
5049 : }
5050 :
5051 : /* For stack tagging:
5052 :
5053 : Dummy: the HWASAN_MARK internal function should only ever be in the code
5054 : after the sanopt pass. */
5055 : bool
5056 0 : hwasan_expand_mark_ifn (gimple_stmt_iterator *)
5057 : {
5058 0 : gcc_unreachable ();
5059 : }
5060 :
5061 : bool
5062 1743526 : gate_hwasan ()
5063 : {
5064 1743526 : return hwasan_sanitize_p ();
5065 : }
5066 :
5067 : bool
5068 1505699 : gate_memtag ()
5069 : {
5070 1505699 : return memtag_sanitize_p ();
5071 : }
5072 :
5073 : #include "gt-asan.h"
|