]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/asan.c
Support C++-specific selftests
[thirdparty/gcc.git] / gcc / asan.c
CommitLineData
37d6f666 1/* AddressSanitizer, a fast memory error detector.
cbe34bb5 2 Copyright (C) 2012-2017 Free Software Foundation, Inc.
37d6f666
WM
3 Contributed by Kostya Serebryany <kcc@google.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
c7131fb2 25#include "backend.h"
957060b5
AM
26#include "target.h"
27#include "rtl.h"
4d648807 28#include "tree.h"
c7131fb2 29#include "gimple.h"
957060b5
AM
30#include "cfghooks.h"
31#include "alloc-pool.h"
32#include "tree-pass.h"
4d0cdd0c 33#include "memmodel.h"
957060b5 34#include "tm_p.h"
c7775327 35#include "ssa.h"
957060b5
AM
36#include "stringpool.h"
37#include "tree-ssanames.h"
957060b5
AM
38#include "optabs.h"
39#include "emit-rtl.h"
40#include "cgraph.h"
41#include "gimple-pretty-print.h"
42#include "alias.h"
40e23961 43#include "fold-const.h"
60393bbc 44#include "cfganal.h"
45b0be94 45#include "gimplify.h"
5be5c238 46#include "gimple-iterator.h"
d8a2d370
DN
47#include "varasm.h"
48#include "stor-layout.h"
37d6f666 49#include "tree-iterator.h"
37d6f666 50#include "asan.h"
36566b39
PK
51#include "dojump.h"
52#include "explow.h"
f3ddd692 53#include "expr.h"
8240018b 54#include "output.h"
0e668eaf 55#include "langhooks.h"
a9e0d843 56#include "cfgloop.h"
ff2a63a7 57#include "gimple-builder.h"
b9a55b13 58#include "ubsan.h"
b5ebc991 59#include "params.h"
9b2b7279 60#include "builtins.h"
860503d8 61#include "fnmatch.h"
c7775327 62#include "tree-inline.h"
37d6f666 63
497a1c66
JJ
64/* AddressSanitizer finds out-of-bounds and use-after-free bugs
65 with <2x slowdown on average.
66
67 The tool consists of two parts:
68 instrumentation module (this file) and a run-time library.
69 The instrumentation module adds a run-time check before every memory insn.
70 For a 8- or 16- byte load accessing address X:
71 ShadowAddr = (X >> 3) + Offset
72 ShadowValue = *(char*)ShadowAddr; // *(short*) for 16-byte access.
73 if (ShadowValue)
74 __asan_report_load8(X);
75 For a load of N bytes (N=1, 2 or 4) from address X:
76 ShadowAddr = (X >> 3) + Offset
77 ShadowValue = *(char*)ShadowAddr;
78 if (ShadowValue)
79 if ((X & 7) + N - 1 > ShadowValue)
80 __asan_report_loadN(X);
81 Stores are instrumented similarly, but using __asan_report_storeN functions.
ef1b3fda
KS
82 A call too __asan_init_vN() is inserted to the list of module CTORs.
83 N is the version number of the AddressSanitizer API. The changes between the
84 API versions are listed in libsanitizer/asan/asan_interface_internal.h.
497a1c66
JJ
85
86 The run-time library redefines malloc (so that redzone are inserted around
87 the allocated memory) and free (so that reuse of free-ed memory is delayed),
ef1b3fda 88 provides __asan_report* and __asan_init_vN functions.
497a1c66
JJ
89
90 Read more:
91 http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
92
93 The current implementation supports detection of out-of-bounds and
94 use-after-free in the heap, on the stack and for global variables.
95
96 [Protection of stack variables]
97
98 To understand how detection of out-of-bounds and use-after-free works
99 for stack variables, lets look at this example on x86_64 where the
100 stack grows downward:
f3ddd692
JJ
101
102 int
103 foo ()
104 {
105 char a[23] = {0};
106 int b[2] = {0};
107
108 a[5] = 1;
109 b[1] = 2;
110
111 return a[5] + b[1];
112 }
113
497a1c66
JJ
114 For this function, the stack protected by asan will be organized as
115 follows, from the top of the stack to the bottom:
f3ddd692 116
497a1c66 117 Slot 1/ [red zone of 32 bytes called 'RIGHT RedZone']
f3ddd692 118
497a1c66
JJ
119 Slot 2/ [8 bytes of red zone, that adds up to the space of 'a' to make
120 the next slot be 32 bytes aligned; this one is called Partial
121 Redzone; this 32 bytes alignment is an asan constraint]
f3ddd692 122
497a1c66 123 Slot 3/ [24 bytes for variable 'a']
f3ddd692 124
497a1c66 125 Slot 4/ [red zone of 32 bytes called 'Middle RedZone']
f3ddd692 126
497a1c66 127 Slot 5/ [24 bytes of Partial Red Zone (similar to slot 2]
f3ddd692 128
497a1c66 129 Slot 6/ [8 bytes for variable 'b']
f3ddd692 130
497a1c66
JJ
131 Slot 7/ [32 bytes of Red Zone at the bottom of the stack, called
132 'LEFT RedZone']
f3ddd692 133
497a1c66
JJ
134 The 32 bytes of LEFT red zone at the bottom of the stack can be
135 decomposed as such:
f3ddd692
JJ
136
137 1/ The first 8 bytes contain a magical asan number that is always
138 0x41B58AB3.
139
140 2/ The following 8 bytes contains a pointer to a string (to be
141 parsed at runtime by the runtime asan library), which format is
142 the following:
143
144 "<function-name> <space> <num-of-variables-on-the-stack>
145 (<32-bytes-aligned-offset-in-bytes-of-variable> <space>
146 <length-of-var-in-bytes> ){n} "
147
148 where '(...){n}' means the content inside the parenthesis occurs 'n'
149 times, with 'n' being the number of variables on the stack.
c1f5ce48 150
ef1b3fda
KS
151 3/ The following 8 bytes contain the PC of the current function which
152 will be used by the run-time library to print an error message.
f3ddd692 153
ef1b3fda 154 4/ The following 8 bytes are reserved for internal use by the run-time.
f3ddd692 155
497a1c66 156 The shadow memory for that stack layout is going to look like this:
f3ddd692
JJ
157
158 - content of shadow memory 8 bytes for slot 7: 0xF1F1F1F1.
159 The F1 byte pattern is a magic number called
160 ASAN_STACK_MAGIC_LEFT and is a way for the runtime to know that
161 the memory for that shadow byte is part of a the LEFT red zone
162 intended to seat at the bottom of the variables on the stack.
163
164 - content of shadow memory 8 bytes for slots 6 and 5:
165 0xF4F4F400. The F4 byte pattern is a magic number
166 called ASAN_STACK_MAGIC_PARTIAL. It flags the fact that the
167 memory region for this shadow byte is a PARTIAL red zone
168 intended to pad a variable A, so that the slot following
169 {A,padding} is 32 bytes aligned.
170
171 Note that the fact that the least significant byte of this
172 shadow memory content is 00 means that 8 bytes of its
173 corresponding memory (which corresponds to the memory of
174 variable 'b') is addressable.
175
176 - content of shadow memory 8 bytes for slot 4: 0xF2F2F2F2.
177 The F2 byte pattern is a magic number called
178 ASAN_STACK_MAGIC_MIDDLE. It flags the fact that the memory
179 region for this shadow byte is a MIDDLE red zone intended to
180 seat between two 32 aligned slots of {variable,padding}.
181
182 - content of shadow memory 8 bytes for slot 3 and 2:
497a1c66 183 0xF4000000. This represents is the concatenation of
f3ddd692
JJ
184 variable 'a' and the partial red zone following it, like what we
185 had for variable 'b'. The least significant 3 bytes being 00
186 means that the 3 bytes of variable 'a' are addressable.
187
497a1c66 188 - content of shadow memory 8 bytes for slot 1: 0xF3F3F3F3.
f3ddd692
JJ
189 The F3 byte pattern is a magic number called
190 ASAN_STACK_MAGIC_RIGHT. It flags the fact that the memory
191 region for this shadow byte is a RIGHT red zone intended to seat
192 at the top of the variables of the stack.
193
497a1c66
JJ
194 Note that the real variable layout is done in expand_used_vars in
195 cfgexpand.c. As far as Address Sanitizer is concerned, it lays out
196 stack variables as well as the different red zones, emits some
197 prologue code to populate the shadow memory as to poison (mark as
198 non-accessible) the regions of the red zones and mark the regions of
199 stack variables as accessible, and emit some epilogue code to
200 un-poison (mark as accessible) the regions of red zones right before
201 the function exits.
8240018b 202
497a1c66 203 [Protection of global variables]
8240018b 204
497a1c66
JJ
205 The basic idea is to insert a red zone between two global variables
206 and install a constructor function that calls the asan runtime to do
207 the populating of the relevant shadow memory regions at load time.
8240018b 208
497a1c66
JJ
209 So the global variables are laid out as to insert a red zone between
210 them. The size of the red zones is so that each variable starts on a
211 32 bytes boundary.
8240018b 212
497a1c66
JJ
213 Then a constructor function is installed so that, for each global
214 variable, it calls the runtime asan library function
215 __asan_register_globals_with an instance of this type:
8240018b
JJ
216
217 struct __asan_global
218 {
219 // Address of the beginning of the global variable.
220 const void *__beg;
221
222 // Initial size of the global variable.
223 uptr __size;
224
225 // Size of the global variable + size of the red zone. This
226 // size is 32 bytes aligned.
227 uptr __size_with_redzone;
228
229 // Name of the global variable.
230 const void *__name;
231
ef1b3fda
KS
232 // Name of the module where the global variable is declared.
233 const void *__module_name;
234
59b36ecf 235 // 1 if it has dynamic initialization, 0 otherwise.
8240018b 236 uptr __has_dynamic_init;
866e32ad
KS
237
238 // A pointer to struct that contains source location, could be NULL.
239 __asan_global_source_location *__location;
8240018b
JJ
240 }
241
497a1c66
JJ
242 A destructor function that calls the runtime asan library function
243 _asan_unregister_globals is also installed. */
f3ddd692 244
fd960af2
YG
245static unsigned HOST_WIDE_INT asan_shadow_offset_value;
246static bool asan_shadow_offset_computed;
860503d8 247static vec<char *> sanitized_sections;
fd960af2 248
6dc4a604
ML
249/* Set of variable declarations that are going to be guarded by
250 use-after-scope sanitizer. */
251
252static hash_set<tree> *asan_handled_variables = NULL;
253
254hash_set <tree> *asan_used_labels = NULL;
255
fd960af2
YG
256/* Sets shadow offset to value in string VAL. */
257
258bool
259set_asan_shadow_offset (const char *val)
260{
261 char *endp;
c1f5ce48 262
fd960af2
YG
263 errno = 0;
264#ifdef HAVE_LONG_LONG
265 asan_shadow_offset_value = strtoull (val, &endp, 0);
266#else
267 asan_shadow_offset_value = strtoul (val, &endp, 0);
268#endif
269 if (!(*val != '\0' && *endp == '\0' && errno == 0))
270 return false;
271
272 asan_shadow_offset_computed = true;
273
274 return true;
275}
276
18af8d16
YG
277/* Set list of user-defined sections that need to be sanitized. */
278
279void
860503d8 280set_sanitized_sections (const char *sections)
18af8d16 281{
860503d8
YG
282 char *pat;
283 unsigned i;
284 FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
285 free (pat);
286 sanitized_sections.truncate (0);
287
288 for (const char *s = sections; *s; )
289 {
290 const char *end;
291 for (end = s; *end && *end != ','; ++end);
292 size_t len = end - s;
293 sanitized_sections.safe_push (xstrndup (s, len));
294 s = *end ? end + 1 : end;
295 }
18af8d16
YG
296}
297
56b7aede
ML
298bool
299asan_mark_p (gimple *stmt, enum asan_mark_flags flag)
300{
301 return (gimple_call_internal_p (stmt, IFN_ASAN_MARK)
302 && tree_to_uhwi (gimple_call_arg (stmt, 0)) == flag);
303}
304
6dc4a604
ML
305bool
306asan_sanitize_stack_p (void)
307{
45b2222a 308 return (sanitize_flags_p (SANITIZE_ADDRESS) && ASAN_STACK);
6dc4a604
ML
309}
310
18af8d16
YG
311/* Checks whether section SEC should be sanitized. */
312
313static bool
314section_sanitized_p (const char *sec)
315{
860503d8
YG
316 char *pat;
317 unsigned i;
318 FOR_EACH_VEC_ELT (sanitized_sections, i, pat)
319 if (fnmatch (pat, sec, FNM_PERIOD) == 0)
320 return true;
18af8d16
YG
321 return false;
322}
323
fd960af2
YG
324/* Returns Asan shadow offset. */
325
326static unsigned HOST_WIDE_INT
327asan_shadow_offset ()
328{
329 if (!asan_shadow_offset_computed)
330 {
331 asan_shadow_offset_computed = true;
332 asan_shadow_offset_value = targetm.asan_shadow_offset ();
333 }
334 return asan_shadow_offset_value;
335}
336
f3ddd692 337alias_set_type asan_shadow_set = -1;
37d6f666 338
6dc4a604 339/* Pointer types to 1, 2 or 4 byte integers in shadow memory. A separate
f6d98484 340 alias set is used for all shadow memory accesses. */
6dc4a604 341static GTY(()) tree shadow_ptr_types[3];
f6d98484 342
e361382f
JJ
343/* Decl for __asan_option_detect_stack_use_after_return. */
344static GTY(()) tree asan_detect_stack_use_after_return;
345
bdcbe80c
DS
346/* Hashtable support for memory references used by gimple
347 statements. */
348
349/* This type represents a reference to a memory region. */
350struct asan_mem_ref
351{
688010ba 352 /* The expression of the beginning of the memory region. */
bdcbe80c
DS
353 tree start;
354
40f9f6bb
JJ
355 /* The size of the access. */
356 HOST_WIDE_INT access_size;
c1f5ce48
ML
357};
358
fcb87c50 359object_allocator <asan_mem_ref> asan_mem_ref_pool ("asan_mem_ref");
bdcbe80c
DS
360
361/* Initializes an instance of asan_mem_ref. */
362
363static void
40f9f6bb 364asan_mem_ref_init (asan_mem_ref *ref, tree start, HOST_WIDE_INT access_size)
bdcbe80c
DS
365{
366 ref->start = start;
367 ref->access_size = access_size;
368}
369
370/* Allocates memory for an instance of asan_mem_ref into the memory
371 pool returned by asan_mem_ref_get_alloc_pool and initialize it.
372 START is the address of (or the expression pointing to) the
373 beginning of memory reference. ACCESS_SIZE is the size of the
374 access to the referenced memory. */
375
376static asan_mem_ref*
40f9f6bb 377asan_mem_ref_new (tree start, HOST_WIDE_INT access_size)
bdcbe80c 378{
fb0b2914 379 asan_mem_ref *ref = asan_mem_ref_pool.allocate ();
bdcbe80c
DS
380
381 asan_mem_ref_init (ref, start, access_size);
382 return ref;
383}
384
385/* This builds and returns a pointer to the end of the memory region
386 that starts at START and of length LEN. */
387
388tree
389asan_mem_ref_get_end (tree start, tree len)
390{
391 if (len == NULL_TREE || integer_zerop (len))
392 return start;
393
a2f581e1
YG
394 if (!ptrofftype_p (len))
395 len = convert_to_ptrofftype (len);
396
bdcbe80c
DS
397 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (start), start, len);
398}
399
400/* Return a tree expression that represents the end of the referenced
401 memory region. Beware that this function can actually build a new
402 tree expression. */
403
404tree
405asan_mem_ref_get_end (const asan_mem_ref *ref, tree len)
406{
407 return asan_mem_ref_get_end (ref->start, len);
408}
409
8d67ee55 410struct asan_mem_ref_hasher : nofree_ptr_hash <asan_mem_ref>
bdcbe80c 411{
67f58944
TS
412 static inline hashval_t hash (const asan_mem_ref *);
413 static inline bool equal (const asan_mem_ref *, const asan_mem_ref *);
bdcbe80c
DS
414};
415
416/* Hash a memory reference. */
417
418inline hashval_t
419asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
420{
bdea98ca 421 return iterative_hash_expr (mem_ref->start, 0);
bdcbe80c
DS
422}
423
424/* Compare two memory references. We accept the length of either
425 memory references to be NULL_TREE. */
426
427inline bool
428asan_mem_ref_hasher::equal (const asan_mem_ref *m1,
429 const asan_mem_ref *m2)
430{
bdea98ca 431 return operand_equal_p (m1->start, m2->start, 0);
bdcbe80c
DS
432}
433
c203e8a7 434static hash_table<asan_mem_ref_hasher> *asan_mem_ref_ht;
bdcbe80c
DS
435
436/* Returns a reference to the hash table containing memory references.
437 This function ensures that the hash table is created. Note that
438 this hash table is updated by the function
439 update_mem_ref_hash_table. */
440
c203e8a7 441static hash_table<asan_mem_ref_hasher> *
bdcbe80c
DS
442get_mem_ref_hash_table ()
443{
c203e8a7
TS
444 if (!asan_mem_ref_ht)
445 asan_mem_ref_ht = new hash_table<asan_mem_ref_hasher> (10);
bdcbe80c
DS
446
447 return asan_mem_ref_ht;
448}
449
450/* Clear all entries from the memory references hash table. */
451
452static void
453empty_mem_ref_hash_table ()
454{
c203e8a7
TS
455 if (asan_mem_ref_ht)
456 asan_mem_ref_ht->empty ();
bdcbe80c
DS
457}
458
459/* Free the memory references hash table. */
460
461static void
462free_mem_ref_resources ()
463{
c203e8a7
TS
464 delete asan_mem_ref_ht;
465 asan_mem_ref_ht = NULL;
bdcbe80c 466
fb0b2914 467 asan_mem_ref_pool.release ();
bdcbe80c
DS
468}
469
470/* Return true iff the memory reference REF has been instrumented. */
471
472static bool
40f9f6bb 473has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
bdcbe80c
DS
474{
475 asan_mem_ref r;
476 asan_mem_ref_init (&r, ref, access_size);
477
bdea98ca
MO
478 asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r);
479 return saved_ref && saved_ref->access_size >= access_size;
bdcbe80c
DS
480}
481
482/* Return true iff the memory reference REF has been instrumented. */
483
484static bool
485has_mem_ref_been_instrumented (const asan_mem_ref *ref)
486{
487 return has_mem_ref_been_instrumented (ref->start, ref->access_size);
488}
489
490/* Return true iff access to memory region starting at REF and of
491 length LEN has been instrumented. */
492
493static bool
494has_mem_ref_been_instrumented (const asan_mem_ref *ref, tree len)
495{
bdea98ca
MO
496 HOST_WIDE_INT size_in_bytes
497 = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
bdcbe80c 498
bdea98ca
MO
499 return size_in_bytes != -1
500 && has_mem_ref_been_instrumented (ref->start, size_in_bytes);
bdcbe80c
DS
501}
502
503/* Set REF to the memory reference present in a gimple assignment
504 ASSIGNMENT. Return true upon successful completion, false
505 otherwise. */
506
507static bool
538dd0b7 508get_mem_ref_of_assignment (const gassign *assignment,
bdcbe80c
DS
509 asan_mem_ref *ref,
510 bool *ref_is_store)
511{
512 gcc_assert (gimple_assign_single_p (assignment));
513
5d751b0c
JJ
514 if (gimple_store_p (assignment)
515 && !gimple_clobber_p (assignment))
bdcbe80c
DS
516 {
517 ref->start = gimple_assign_lhs (assignment);
518 *ref_is_store = true;
519 }
520 else if (gimple_assign_load_p (assignment))
521 {
522 ref->start = gimple_assign_rhs1 (assignment);
523 *ref_is_store = false;
524 }
525 else
526 return false;
527
528 ref->access_size = int_size_in_bytes (TREE_TYPE (ref->start));
529 return true;
530}
531
532/* Return the memory references contained in a gimple statement
533 representing a builtin call that has to do with memory access. */
534
535static bool
538dd0b7 536get_mem_refs_of_builtin_call (const gcall *call,
bdcbe80c
DS
537 asan_mem_ref *src0,
538 tree *src0_len,
539 bool *src0_is_store,
540 asan_mem_ref *src1,
541 tree *src1_len,
542 bool *src1_is_store,
543 asan_mem_ref *dst,
544 tree *dst_len,
545 bool *dst_is_store,
bdea98ca
MO
546 bool *dest_is_deref,
547 bool *intercepted_p)
bdcbe80c
DS
548{
549 gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
550
551 tree callee = gimple_call_fndecl (call);
552 tree source0 = NULL_TREE, source1 = NULL_TREE,
553 dest = NULL_TREE, len = NULL_TREE;
554 bool is_store = true, got_reference_p = false;
40f9f6bb 555 HOST_WIDE_INT access_size = 1;
bdcbe80c 556
bdea98ca
MO
557 *intercepted_p = asan_intercepted_p ((DECL_FUNCTION_CODE (callee)));
558
bdcbe80c
DS
559 switch (DECL_FUNCTION_CODE (callee))
560 {
561 /* (s, s, n) style memops. */
562 case BUILT_IN_BCMP:
563 case BUILT_IN_MEMCMP:
564 source0 = gimple_call_arg (call, 0);
565 source1 = gimple_call_arg (call, 1);
566 len = gimple_call_arg (call, 2);
567 break;
568
569 /* (src, dest, n) style memops. */
570 case BUILT_IN_BCOPY:
571 source0 = gimple_call_arg (call, 0);
572 dest = gimple_call_arg (call, 1);
573 len = gimple_call_arg (call, 2);
574 break;
575
576 /* (dest, src, n) style memops. */
577 case BUILT_IN_MEMCPY:
578 case BUILT_IN_MEMCPY_CHK:
579 case BUILT_IN_MEMMOVE:
580 case BUILT_IN_MEMMOVE_CHK:
581 case BUILT_IN_MEMPCPY:
582 case BUILT_IN_MEMPCPY_CHK:
583 dest = gimple_call_arg (call, 0);
584 source0 = gimple_call_arg (call, 1);
585 len = gimple_call_arg (call, 2);
586 break;
587
588 /* (dest, n) style memops. */
589 case BUILT_IN_BZERO:
590 dest = gimple_call_arg (call, 0);
591 len = gimple_call_arg (call, 1);
592 break;
593
594 /* (dest, x, n) style memops*/
595 case BUILT_IN_MEMSET:
596 case BUILT_IN_MEMSET_CHK:
597 dest = gimple_call_arg (call, 0);
598 len = gimple_call_arg (call, 2);
599 break;
600
601 case BUILT_IN_STRLEN:
602 source0 = gimple_call_arg (call, 0);
603 len = gimple_call_lhs (call);
9e463823 604 break;
bdcbe80c
DS
605
606 /* And now the __atomic* and __sync builtins.
607 These are handled differently from the classical memory memory
608 access builtins above. */
609
610 case BUILT_IN_ATOMIC_LOAD_1:
bdcbe80c 611 is_store = false;
9e463823 612 /* FALLTHRU */
bdcbe80c 613 case BUILT_IN_SYNC_FETCH_AND_ADD_1:
bdcbe80c 614 case BUILT_IN_SYNC_FETCH_AND_SUB_1:
bdcbe80c 615 case BUILT_IN_SYNC_FETCH_AND_OR_1:
bdcbe80c 616 case BUILT_IN_SYNC_FETCH_AND_AND_1:
bdcbe80c 617 case BUILT_IN_SYNC_FETCH_AND_XOR_1:
bdcbe80c 618 case BUILT_IN_SYNC_FETCH_AND_NAND_1:
bdcbe80c 619 case BUILT_IN_SYNC_ADD_AND_FETCH_1:
bdcbe80c 620 case BUILT_IN_SYNC_SUB_AND_FETCH_1:
bdcbe80c 621 case BUILT_IN_SYNC_OR_AND_FETCH_1:
bdcbe80c 622 case BUILT_IN_SYNC_AND_AND_FETCH_1:
bdcbe80c 623 case BUILT_IN_SYNC_XOR_AND_FETCH_1:
bdcbe80c 624 case BUILT_IN_SYNC_NAND_AND_FETCH_1:
bdcbe80c 625 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
bdcbe80c 626 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
bdcbe80c 627 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
bdcbe80c 628 case BUILT_IN_SYNC_LOCK_RELEASE_1:
bdcbe80c 629 case BUILT_IN_ATOMIC_EXCHANGE_1:
bdcbe80c 630 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
bdcbe80c 631 case BUILT_IN_ATOMIC_STORE_1:
bdcbe80c 632 case BUILT_IN_ATOMIC_ADD_FETCH_1:
bdcbe80c 633 case BUILT_IN_ATOMIC_SUB_FETCH_1:
bdcbe80c 634 case BUILT_IN_ATOMIC_AND_FETCH_1:
bdcbe80c 635 case BUILT_IN_ATOMIC_NAND_FETCH_1:
bdcbe80c 636 case BUILT_IN_ATOMIC_XOR_FETCH_1:
bdcbe80c 637 case BUILT_IN_ATOMIC_OR_FETCH_1:
bdcbe80c 638 case BUILT_IN_ATOMIC_FETCH_ADD_1:
bdcbe80c 639 case BUILT_IN_ATOMIC_FETCH_SUB_1:
bdcbe80c 640 case BUILT_IN_ATOMIC_FETCH_AND_1:
bdcbe80c 641 case BUILT_IN_ATOMIC_FETCH_NAND_1:
bdcbe80c 642 case BUILT_IN_ATOMIC_FETCH_XOR_1:
bdcbe80c 643 case BUILT_IN_ATOMIC_FETCH_OR_1:
9e463823
JJ
644 access_size = 1;
645 goto do_atomic;
646
647 case BUILT_IN_ATOMIC_LOAD_2:
648 is_store = false;
649 /* FALLTHRU */
650 case BUILT_IN_SYNC_FETCH_AND_ADD_2:
651 case BUILT_IN_SYNC_FETCH_AND_SUB_2:
652 case BUILT_IN_SYNC_FETCH_AND_OR_2:
653 case BUILT_IN_SYNC_FETCH_AND_AND_2:
654 case BUILT_IN_SYNC_FETCH_AND_XOR_2:
655 case BUILT_IN_SYNC_FETCH_AND_NAND_2:
656 case BUILT_IN_SYNC_ADD_AND_FETCH_2:
657 case BUILT_IN_SYNC_SUB_AND_FETCH_2:
658 case BUILT_IN_SYNC_OR_AND_FETCH_2:
659 case BUILT_IN_SYNC_AND_AND_FETCH_2:
660 case BUILT_IN_SYNC_XOR_AND_FETCH_2:
661 case BUILT_IN_SYNC_NAND_AND_FETCH_2:
662 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
663 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
664 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
665 case BUILT_IN_SYNC_LOCK_RELEASE_2:
666 case BUILT_IN_ATOMIC_EXCHANGE_2:
667 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
668 case BUILT_IN_ATOMIC_STORE_2:
669 case BUILT_IN_ATOMIC_ADD_FETCH_2:
670 case BUILT_IN_ATOMIC_SUB_FETCH_2:
671 case BUILT_IN_ATOMIC_AND_FETCH_2:
672 case BUILT_IN_ATOMIC_NAND_FETCH_2:
673 case BUILT_IN_ATOMIC_XOR_FETCH_2:
674 case BUILT_IN_ATOMIC_OR_FETCH_2:
675 case BUILT_IN_ATOMIC_FETCH_ADD_2:
676 case BUILT_IN_ATOMIC_FETCH_SUB_2:
677 case BUILT_IN_ATOMIC_FETCH_AND_2:
678 case BUILT_IN_ATOMIC_FETCH_NAND_2:
679 case BUILT_IN_ATOMIC_FETCH_XOR_2:
bdcbe80c 680 case BUILT_IN_ATOMIC_FETCH_OR_2:
9e463823
JJ
681 access_size = 2;
682 goto do_atomic;
683
684 case BUILT_IN_ATOMIC_LOAD_4:
685 is_store = false;
686 /* FALLTHRU */
687 case BUILT_IN_SYNC_FETCH_AND_ADD_4:
688 case BUILT_IN_SYNC_FETCH_AND_SUB_4:
689 case BUILT_IN_SYNC_FETCH_AND_OR_4:
690 case BUILT_IN_SYNC_FETCH_AND_AND_4:
691 case BUILT_IN_SYNC_FETCH_AND_XOR_4:
692 case BUILT_IN_SYNC_FETCH_AND_NAND_4:
693 case BUILT_IN_SYNC_ADD_AND_FETCH_4:
694 case BUILT_IN_SYNC_SUB_AND_FETCH_4:
695 case BUILT_IN_SYNC_OR_AND_FETCH_4:
696 case BUILT_IN_SYNC_AND_AND_FETCH_4:
697 case BUILT_IN_SYNC_XOR_AND_FETCH_4:
698 case BUILT_IN_SYNC_NAND_AND_FETCH_4:
699 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
700 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
701 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
702 case BUILT_IN_SYNC_LOCK_RELEASE_4:
703 case BUILT_IN_ATOMIC_EXCHANGE_4:
704 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
705 case BUILT_IN_ATOMIC_STORE_4:
706 case BUILT_IN_ATOMIC_ADD_FETCH_4:
707 case BUILT_IN_ATOMIC_SUB_FETCH_4:
708 case BUILT_IN_ATOMIC_AND_FETCH_4:
709 case BUILT_IN_ATOMIC_NAND_FETCH_4:
710 case BUILT_IN_ATOMIC_XOR_FETCH_4:
711 case BUILT_IN_ATOMIC_OR_FETCH_4:
712 case BUILT_IN_ATOMIC_FETCH_ADD_4:
713 case BUILT_IN_ATOMIC_FETCH_SUB_4:
714 case BUILT_IN_ATOMIC_FETCH_AND_4:
715 case BUILT_IN_ATOMIC_FETCH_NAND_4:
716 case BUILT_IN_ATOMIC_FETCH_XOR_4:
bdcbe80c 717 case BUILT_IN_ATOMIC_FETCH_OR_4:
9e463823
JJ
718 access_size = 4;
719 goto do_atomic;
720
721 case BUILT_IN_ATOMIC_LOAD_8:
722 is_store = false;
723 /* FALLTHRU */
724 case BUILT_IN_SYNC_FETCH_AND_ADD_8:
725 case BUILT_IN_SYNC_FETCH_AND_SUB_8:
726 case BUILT_IN_SYNC_FETCH_AND_OR_8:
727 case BUILT_IN_SYNC_FETCH_AND_AND_8:
728 case BUILT_IN_SYNC_FETCH_AND_XOR_8:
729 case BUILT_IN_SYNC_FETCH_AND_NAND_8:
730 case BUILT_IN_SYNC_ADD_AND_FETCH_8:
731 case BUILT_IN_SYNC_SUB_AND_FETCH_8:
732 case BUILT_IN_SYNC_OR_AND_FETCH_8:
733 case BUILT_IN_SYNC_AND_AND_FETCH_8:
734 case BUILT_IN_SYNC_XOR_AND_FETCH_8:
735 case BUILT_IN_SYNC_NAND_AND_FETCH_8:
736 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
737 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
738 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
739 case BUILT_IN_SYNC_LOCK_RELEASE_8:
740 case BUILT_IN_ATOMIC_EXCHANGE_8:
741 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
742 case BUILT_IN_ATOMIC_STORE_8:
743 case BUILT_IN_ATOMIC_ADD_FETCH_8:
744 case BUILT_IN_ATOMIC_SUB_FETCH_8:
745 case BUILT_IN_ATOMIC_AND_FETCH_8:
746 case BUILT_IN_ATOMIC_NAND_FETCH_8:
747 case BUILT_IN_ATOMIC_XOR_FETCH_8:
748 case BUILT_IN_ATOMIC_OR_FETCH_8:
749 case BUILT_IN_ATOMIC_FETCH_ADD_8:
750 case BUILT_IN_ATOMIC_FETCH_SUB_8:
751 case BUILT_IN_ATOMIC_FETCH_AND_8:
752 case BUILT_IN_ATOMIC_FETCH_NAND_8:
753 case BUILT_IN_ATOMIC_FETCH_XOR_8:
bdcbe80c 754 case BUILT_IN_ATOMIC_FETCH_OR_8:
9e463823
JJ
755 access_size = 8;
756 goto do_atomic;
757
758 case BUILT_IN_ATOMIC_LOAD_16:
759 is_store = false;
760 /* FALLTHRU */
761 case BUILT_IN_SYNC_FETCH_AND_ADD_16:
762 case BUILT_IN_SYNC_FETCH_AND_SUB_16:
763 case BUILT_IN_SYNC_FETCH_AND_OR_16:
764 case BUILT_IN_SYNC_FETCH_AND_AND_16:
765 case BUILT_IN_SYNC_FETCH_AND_XOR_16:
766 case BUILT_IN_SYNC_FETCH_AND_NAND_16:
767 case BUILT_IN_SYNC_ADD_AND_FETCH_16:
768 case BUILT_IN_SYNC_SUB_AND_FETCH_16:
769 case BUILT_IN_SYNC_OR_AND_FETCH_16:
770 case BUILT_IN_SYNC_AND_AND_FETCH_16:
771 case BUILT_IN_SYNC_XOR_AND_FETCH_16:
772 case BUILT_IN_SYNC_NAND_AND_FETCH_16:
773 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
774 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
775 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
776 case BUILT_IN_SYNC_LOCK_RELEASE_16:
777 case BUILT_IN_ATOMIC_EXCHANGE_16:
778 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
779 case BUILT_IN_ATOMIC_STORE_16:
780 case BUILT_IN_ATOMIC_ADD_FETCH_16:
781 case BUILT_IN_ATOMIC_SUB_FETCH_16:
782 case BUILT_IN_ATOMIC_AND_FETCH_16:
783 case BUILT_IN_ATOMIC_NAND_FETCH_16:
784 case BUILT_IN_ATOMIC_XOR_FETCH_16:
785 case BUILT_IN_ATOMIC_OR_FETCH_16:
786 case BUILT_IN_ATOMIC_FETCH_ADD_16:
787 case BUILT_IN_ATOMIC_FETCH_SUB_16:
788 case BUILT_IN_ATOMIC_FETCH_AND_16:
789 case BUILT_IN_ATOMIC_FETCH_NAND_16:
790 case BUILT_IN_ATOMIC_FETCH_XOR_16:
bdcbe80c 791 case BUILT_IN_ATOMIC_FETCH_OR_16:
9e463823
JJ
792 access_size = 16;
793 /* FALLTHRU */
794 do_atomic:
bdcbe80c
DS
795 {
796 dest = gimple_call_arg (call, 0);
797 /* DEST represents the address of a memory location.
798 instrument_derefs wants the memory location, so lets
799 dereference the address DEST before handing it to
800 instrument_derefs. */
9e463823
JJ
801 tree type = build_nonstandard_integer_type (access_size
802 * BITS_PER_UNIT, 1);
803 dest = build2 (MEM_REF, type, dest,
804 build_int_cst (build_pointer_type (char_type_node), 0));
805 break;
bdcbe80c
DS
806 }
807
808 default:
809 /* The other builtins memory access are not instrumented in this
810 function because they either don't have any length parameter,
811 or their length parameter is just a limit. */
812 break;
813 }
814
815 if (len != NULL_TREE)
816 {
817 if (source0 != NULL_TREE)
818 {
819 src0->start = source0;
820 src0->access_size = access_size;
821 *src0_len = len;
822 *src0_is_store = false;
823 }
824
825 if (source1 != NULL_TREE)
826 {
827 src1->start = source1;
828 src1->access_size = access_size;
829 *src1_len = len;
830 *src1_is_store = false;
831 }
832
833 if (dest != NULL_TREE)
834 {
835 dst->start = dest;
836 dst->access_size = access_size;
837 *dst_len = len;
838 *dst_is_store = true;
839 }
840
841 got_reference_p = true;
842 }
b41288b3
JJ
843 else if (dest)
844 {
845 dst->start = dest;
846 dst->access_size = access_size;
847 *dst_len = NULL_TREE;
848 *dst_is_store = is_store;
849 *dest_is_deref = true;
850 got_reference_p = true;
851 }
bdcbe80c 852
b41288b3 853 return got_reference_p;
bdcbe80c
DS
854}
855
856/* Return true iff a given gimple statement has been instrumented.
857 Note that the statement is "defined" by the memory references it
858 contains. */
859
860static bool
355fe088 861has_stmt_been_instrumented_p (gimple *stmt)
bdcbe80c
DS
862{
863 if (gimple_assign_single_p (stmt))
864 {
865 bool r_is_store;
866 asan_mem_ref r;
867 asan_mem_ref_init (&r, NULL, 1);
868
538dd0b7
DM
869 if (get_mem_ref_of_assignment (as_a <gassign *> (stmt), &r,
870 &r_is_store))
bdcbe80c
DS
871 return has_mem_ref_been_instrumented (&r);
872 }
873 else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
874 {
875 asan_mem_ref src0, src1, dest;
876 asan_mem_ref_init (&src0, NULL, 1);
877 asan_mem_ref_init (&src1, NULL, 1);
878 asan_mem_ref_init (&dest, NULL, 1);
879
880 tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
881 bool src0_is_store = false, src1_is_store = false,
bdea98ca 882 dest_is_store = false, dest_is_deref = false, intercepted_p = true;
538dd0b7 883 if (get_mem_refs_of_builtin_call (as_a <gcall *> (stmt),
bdcbe80c
DS
884 &src0, &src0_len, &src0_is_store,
885 &src1, &src1_len, &src1_is_store,
886 &dest, &dest_len, &dest_is_store,
bdea98ca 887 &dest_is_deref, &intercepted_p))
bdcbe80c
DS
888 {
889 if (src0.start != NULL_TREE
890 && !has_mem_ref_been_instrumented (&src0, src0_len))
891 return false;
892
893 if (src1.start != NULL_TREE
894 && !has_mem_ref_been_instrumented (&src1, src1_len))
895 return false;
896
897 if (dest.start != NULL_TREE
898 && !has_mem_ref_been_instrumented (&dest, dest_len))
899 return false;
900
901 return true;
902 }
903 }
7db337c2
ML
904 else if (is_gimple_call (stmt) && gimple_store_p (stmt))
905 {
906 asan_mem_ref r;
907 asan_mem_ref_init (&r, NULL, 1);
908
909 r.start = gimple_call_lhs (stmt);
910 r.access_size = int_size_in_bytes (TREE_TYPE (r.start));
911 return has_mem_ref_been_instrumented (&r);
912 }
913
bdcbe80c
DS
914 return false;
915}
916
917/* Insert a memory reference into the hash table. */
918
919static void
40f9f6bb 920update_mem_ref_hash_table (tree ref, HOST_WIDE_INT access_size)
bdcbe80c 921{
c203e8a7 922 hash_table<asan_mem_ref_hasher> *ht = get_mem_ref_hash_table ();
bdcbe80c
DS
923
924 asan_mem_ref r;
925 asan_mem_ref_init (&r, ref, access_size);
926
c203e8a7 927 asan_mem_ref **slot = ht->find_slot (&r, INSERT);
bdea98ca 928 if (*slot == NULL || (*slot)->access_size < access_size)
bdcbe80c
DS
929 *slot = asan_mem_ref_new (ref, access_size);
930}
931
94fce891
JJ
932/* Initialize shadow_ptr_types array. */
933
934static void
935asan_init_shadow_ptr_types (void)
936{
937 asan_shadow_set = new_alias_set ();
6dc4a604
ML
938 tree types[3] = { signed_char_type_node, short_integer_type_node,
939 integer_type_node };
940
941 for (unsigned i = 0; i < 3; i++)
942 {
943 shadow_ptr_types[i] = build_distinct_type_copy (types[i]);
944 TYPE_ALIAS_SET (shadow_ptr_types[i]) = asan_shadow_set;
945 shadow_ptr_types[i] = build_pointer_type (shadow_ptr_types[i]);
946 }
947
94fce891
JJ
948 initialize_sanitizer_builtins ();
949}
950
11a877b3 951/* Create ADDR_EXPR of STRING_CST with the PP pretty printer text. */
8240018b
JJ
952
953static tree
11a877b3 954asan_pp_string (pretty_printer *pp)
8240018b 955{
11a877b3 956 const char *buf = pp_formatted_text (pp);
8240018b
JJ
957 size_t len = strlen (buf);
958 tree ret = build_string (len + 1, buf);
959 TREE_TYPE (ret)
94fce891
JJ
960 = build_array_type (TREE_TYPE (shadow_ptr_types[0]),
961 build_index_type (size_int (len)));
8240018b
JJ
962 TREE_READONLY (ret) = 1;
963 TREE_STATIC (ret) = 1;
94fce891 964 return build1 (ADDR_EXPR, shadow_ptr_types[0], ret);
8240018b
JJ
965}
966
f3ddd692
JJ
967/* Return a CONST_INT representing 4 subsequent shadow memory bytes. */
968
969static rtx
970asan_shadow_cst (unsigned char shadow_bytes[4])
971{
972 int i;
973 unsigned HOST_WIDE_INT val = 0;
974 gcc_assert (WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN);
975 for (i = 0; i < 4; i++)
976 val |= (unsigned HOST_WIDE_INT) shadow_bytes[BYTES_BIG_ENDIAN ? 3 - i : i]
977 << (BITS_PER_UNIT * i);
dcad1dd3 978 return gen_int_mode (val, SImode);
f3ddd692
JJ
979}
980
aeb7e7c1
JJ
981/* Clear shadow memory at SHADOW_MEM, LEN bytes. Can't call a library call here
982 though. */
983
984static void
985asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
986{
3a965f61
DM
987 rtx_insn *insn, *insns, *jump;
988 rtx_code_label *top_label;
989 rtx end, addr, tmp;
aeb7e7c1
JJ
990
991 start_sequence ();
992 clear_storage (shadow_mem, GEN_INT (len), BLOCK_OP_NORMAL);
993 insns = get_insns ();
994 end_sequence ();
995 for (insn = insns; insn; insn = NEXT_INSN (insn))
996 if (CALL_P (insn))
997 break;
998 if (insn == NULL_RTX)
999 {
1000 emit_insn (insns);
1001 return;
1002 }
1003
1004 gcc_assert ((len & 3) == 0);
1005 top_label = gen_label_rtx ();
57d4d653 1006 addr = copy_to_mode_reg (Pmode, XEXP (shadow_mem, 0));
aeb7e7c1
JJ
1007 shadow_mem = adjust_automodify_address (shadow_mem, SImode, addr, 0);
1008 end = force_reg (Pmode, plus_constant (Pmode, addr, len));
1009 emit_label (top_label);
1010
1011 emit_move_insn (shadow_mem, const0_rtx);
2f1cd2eb 1012 tmp = expand_simple_binop (Pmode, PLUS, addr, gen_int_mode (4, Pmode), addr,
c62ccb9a 1013 true, OPTAB_LIB_WIDEN);
aeb7e7c1
JJ
1014 if (tmp != addr)
1015 emit_move_insn (addr, tmp);
1016 emit_cmp_and_jump_insns (addr, end, LT, NULL_RTX, Pmode, true, top_label);
1017 jump = get_last_insn ();
1018 gcc_assert (JUMP_P (jump));
e5af9ddd 1019 add_int_reg_note (jump, REG_BR_PROB, REG_BR_PROB_BASE * 80 / 100);
aeb7e7c1
JJ
1020}
1021
ef1b3fda
KS
1022void
1023asan_function_start (void)
1024{
1025 section *fnsec = function_section (current_function_decl);
1026 switch_to_section (fnsec);
1027 ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LASANPC",
c62ccb9a 1028 current_function_funcdef_no);
ef1b3fda
KS
1029}
1030
6dc4a604
ML
1031/* Return number of shadow bytes that are occupied by a local variable
1032 of SIZE bytes. */
1033
1034static unsigned HOST_WIDE_INT
1035shadow_mem_size (unsigned HOST_WIDE_INT size)
1036{
1037 return ROUND_UP (size, ASAN_SHADOW_GRANULARITY) / ASAN_SHADOW_GRANULARITY;
1038}
1039
f3ddd692
JJ
1040/* Insert code to protect stack vars. The prologue sequence should be emitted
1041 directly, epilogue sequence returned. BASE is the register holding the
1042 stack base, against which OFFSETS array offsets are relative to, OFFSETS
1043 array contains pairs of offsets in reverse order, always the end offset
1044 of some gap that needs protection followed by starting offset,
1045 and DECLS is an array of representative decls for each var partition.
1046 LENGTH is the length of the OFFSETS array, DECLS array is LENGTH / 2 - 1
1047 elements long (OFFSETS include gap before the first variable as well
e361382f
JJ
1048 as gaps after each stack variable). PBASE is, if non-NULL, some pseudo
1049 register which stack vars DECL_RTLs are based on. Either BASE should be
1050 assigned to PBASE, when not doing use after return protection, or
1051 corresponding address based on __asan_stack_malloc* return value. */
f3ddd692 1052
3a4abd2f 1053rtx_insn *
e361382f
JJ
1054asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
1055 HOST_WIDE_INT *offsets, tree *decls, int length)
f3ddd692 1056{
19f8b229
TS
1057 rtx shadow_base, shadow_mem, ret, mem, orig_base;
1058 rtx_code_label *lab;
3a4abd2f 1059 rtx_insn *insns;
47d5beb4 1060 char buf[32];
f3ddd692 1061 unsigned char shadow_bytes[4];
e361382f
JJ
1062 HOST_WIDE_INT base_offset = offsets[length - 1];
1063 HOST_WIDE_INT base_align_bias = 0, offset, prev_offset;
1064 HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset;
7b972538 1065 HOST_WIDE_INT last_offset, last_size;
f3ddd692
JJ
1066 int l;
1067 unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT;
ef1b3fda 1068 tree str_cst, decl, id;
e361382f 1069 int use_after_return_class = -1;
f3ddd692 1070
94fce891
JJ
1071 if (shadow_ptr_types[0] == NULL_TREE)
1072 asan_init_shadow_ptr_types ();
1073
f3ddd692 1074 /* First of all, prepare the description string. */
11a877b3 1075 pretty_printer asan_pp;
da6ca2b5 1076
8240018b
JJ
1077 pp_decimal_int (&asan_pp, length / 2 - 1);
1078 pp_space (&asan_pp);
f3ddd692
JJ
1079 for (l = length - 2; l; l -= 2)
1080 {
1081 tree decl = decls[l / 2 - 1];
8240018b
JJ
1082 pp_wide_integer (&asan_pp, offsets[l] - base_offset);
1083 pp_space (&asan_pp);
1084 pp_wide_integer (&asan_pp, offsets[l - 1] - offsets[l]);
1085 pp_space (&asan_pp);
f3ddd692
JJ
1086 if (DECL_P (decl) && DECL_NAME (decl))
1087 {
8240018b
JJ
1088 pp_decimal_int (&asan_pp, IDENTIFIER_LENGTH (DECL_NAME (decl)));
1089 pp_space (&asan_pp);
b066401f 1090 pp_tree_identifier (&asan_pp, DECL_NAME (decl));
f3ddd692
JJ
1091 }
1092 else
8240018b
JJ
1093 pp_string (&asan_pp, "9 <unknown>");
1094 pp_space (&asan_pp);
f3ddd692 1095 }
11a877b3 1096 str_cst = asan_pp_string (&asan_pp);
f3ddd692
JJ
1097
1098 /* Emit the prologue sequence. */
b5ebc991
MO
1099 if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase
1100 && ASAN_USE_AFTER_RETURN)
e361382f
JJ
1101 {
1102 use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
1103 /* __asan_stack_malloc_N guarantees alignment
c62ccb9a 1104 N < 6 ? (64 << N) : 4096 bytes. */
e361382f
JJ
1105 if (alignb > (use_after_return_class < 6
1106 ? (64U << use_after_return_class) : 4096U))
1107 use_after_return_class = -1;
1108 else if (alignb > ASAN_RED_ZONE_SIZE && (asan_frame_size & (alignb - 1)))
1109 base_align_bias = ((asan_frame_size + alignb - 1)
1110 & ~(alignb - HOST_WIDE_INT_1)) - asan_frame_size;
1111 }
e5dcd695
LZ
1112 /* Align base if target is STRICT_ALIGNMENT. */
1113 if (STRICT_ALIGNMENT)
1114 base = expand_binop (Pmode, and_optab, base,
1115 gen_int_mode (-((GET_MODE_ALIGNMENT (SImode)
1116 << ASAN_SHADOW_SHIFT)
1117 / BITS_PER_UNIT), Pmode), NULL_RTX,
1118 1, OPTAB_DIRECT);
1119
e361382f
JJ
1120 if (use_after_return_class == -1 && pbase)
1121 emit_move_insn (pbase, base);
e5dcd695 1122
2f1cd2eb 1123 base = expand_binop (Pmode, add_optab, base,
e361382f 1124 gen_int_mode (base_offset - base_align_bias, Pmode),
f3ddd692 1125 NULL_RTX, 1, OPTAB_DIRECT);
e361382f
JJ
1126 orig_base = NULL_RTX;
1127 if (use_after_return_class != -1)
1128 {
1129 if (asan_detect_stack_use_after_return == NULL_TREE)
1130 {
1131 id = get_identifier ("__asan_option_detect_stack_use_after_return");
1132 decl = build_decl (BUILTINS_LOCATION, VAR_DECL, id,
1133 integer_type_node);
1134 SET_DECL_ASSEMBLER_NAME (decl, id);
1135 TREE_ADDRESSABLE (decl) = 1;
1136 DECL_ARTIFICIAL (decl) = 1;
1137 DECL_IGNORED_P (decl) = 1;
1138 DECL_EXTERNAL (decl) = 1;
1139 TREE_STATIC (decl) = 1;
1140 TREE_PUBLIC (decl) = 1;
1141 TREE_USED (decl) = 1;
1142 asan_detect_stack_use_after_return = decl;
1143 }
1144 orig_base = gen_reg_rtx (Pmode);
1145 emit_move_insn (orig_base, base);
1146 ret = expand_normal (asan_detect_stack_use_after_return);
1147 lab = gen_label_rtx ();
e361382f 1148 emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
357067f2
JH
1149 VOIDmode, 0, lab,
1150 profile_probability::very_likely ());
e361382f
JJ
1151 snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
1152 use_after_return_class);
1153 ret = init_one_libfunc (buf);
89e302b8 1154 ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 1,
e361382f
JJ
1155 GEN_INT (asan_frame_size
1156 + base_align_bias),
89e302b8
MO
1157 TYPE_MODE (pointer_sized_int_node));
1158 /* __asan_stack_malloc_[n] returns a pointer to fake stack if succeeded
1159 and NULL otherwise. Check RET value is NULL here and jump over the
1160 BASE reassignment in this case. Otherwise, reassign BASE to RET. */
89e302b8 1161 emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
357067f2
JH
1162 VOIDmode, 0, lab,
1163 profile_probability:: very_unlikely ());
e361382f
JJ
1164 ret = convert_memory_address (Pmode, ret);
1165 emit_move_insn (base, ret);
1166 emit_label (lab);
1167 emit_move_insn (pbase, expand_binop (Pmode, add_optab, base,
1168 gen_int_mode (base_align_bias
1169 - base_offset, Pmode),
1170 NULL_RTX, 1, OPTAB_DIRECT));
1171 }
f3ddd692 1172 mem = gen_rtx_MEM (ptr_mode, base);
e361382f 1173 mem = adjust_address (mem, VOIDmode, base_align_bias);
69db2d57 1174 emit_move_insn (mem, gen_int_mode (ASAN_STACK_FRAME_MAGIC, ptr_mode));
f3ddd692
JJ
1175 mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
1176 emit_move_insn (mem, expand_normal (str_cst));
ef1b3fda
KS
1177 mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
1178 ASM_GENERATE_INTERNAL_LABEL (buf, "LASANPC", current_function_funcdef_no);
1179 id = get_identifier (buf);
1180 decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
c62ccb9a 1181 VAR_DECL, id, char_type_node);
ef1b3fda
KS
1182 SET_DECL_ASSEMBLER_NAME (decl, id);
1183 TREE_ADDRESSABLE (decl) = 1;
1184 TREE_READONLY (decl) = 1;
1185 DECL_ARTIFICIAL (decl) = 1;
1186 DECL_IGNORED_P (decl) = 1;
1187 TREE_STATIC (decl) = 1;
1188 TREE_PUBLIC (decl) = 0;
1189 TREE_USED (decl) = 1;
8c8b21e4
JJ
1190 DECL_INITIAL (decl) = decl;
1191 TREE_ASM_WRITTEN (decl) = 1;
1192 TREE_ASM_WRITTEN (id) = 1;
ef1b3fda 1193 emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
f3ddd692
JJ
1194 shadow_base = expand_binop (Pmode, lshr_optab, base,
1195 GEN_INT (ASAN_SHADOW_SHIFT),
1196 NULL_RTX, 1, OPTAB_DIRECT);
e361382f
JJ
1197 shadow_base
1198 = plus_constant (Pmode, shadow_base,
fd960af2 1199 asan_shadow_offset ()
e361382f 1200 + (base_align_bias >> ASAN_SHADOW_SHIFT));
f3ddd692
JJ
1201 gcc_assert (asan_shadow_set != -1
1202 && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
1203 shadow_mem = gen_rtx_MEM (SImode, shadow_base);
1204 set_mem_alias_set (shadow_mem, asan_shadow_set);
e5dcd695
LZ
1205 if (STRICT_ALIGNMENT)
1206 set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
f3ddd692
JJ
1207 prev_offset = base_offset;
1208 for (l = length; l; l -= 2)
1209 {
1210 if (l == 2)
1211 cur_shadow_byte = ASAN_STACK_MAGIC_RIGHT;
1212 offset = offsets[l - 1];
1213 if ((offset - base_offset) & (ASAN_RED_ZONE_SIZE - 1))
1214 {
1215 int i;
1216 HOST_WIDE_INT aoff
1217 = base_offset + ((offset - base_offset)
1218 & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
1219 shadow_mem = adjust_address (shadow_mem, VOIDmode,
1220 (aoff - prev_offset)
1221 >> ASAN_SHADOW_SHIFT);
1222 prev_offset = aoff;
6dc4a604 1223 for (i = 0; i < 4; i++, aoff += ASAN_SHADOW_GRANULARITY)
f3ddd692
JJ
1224 if (aoff < offset)
1225 {
6dc4a604 1226 if (aoff < offset - (HOST_WIDE_INT)ASAN_SHADOW_GRANULARITY + 1)
f3ddd692
JJ
1227 shadow_bytes[i] = 0;
1228 else
1229 shadow_bytes[i] = offset - aoff;
1230 }
1231 else
fbdb92eb 1232 shadow_bytes[i] = ASAN_STACK_MAGIC_MIDDLE;
f3ddd692
JJ
1233 emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes));
1234 offset = aoff;
1235 }
1236 while (offset <= offsets[l - 2] - ASAN_RED_ZONE_SIZE)
1237 {
1238 shadow_mem = adjust_address (shadow_mem, VOIDmode,
1239 (offset - prev_offset)
1240 >> ASAN_SHADOW_SHIFT);
1241 prev_offset = offset;
1242 memset (shadow_bytes, cur_shadow_byte, 4);
1243 emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes));
1244 offset += ASAN_RED_ZONE_SIZE;
1245 }
1246 cur_shadow_byte = ASAN_STACK_MAGIC_MIDDLE;
1247 }
1248 do_pending_stack_adjust ();
1249
1250 /* Construct epilogue sequence. */
1251 start_sequence ();
1252
19f8b229 1253 lab = NULL;
e361382f
JJ
1254 if (use_after_return_class != -1)
1255 {
19f8b229 1256 rtx_code_label *lab2 = gen_label_rtx ();
e361382f 1257 char c = (char) ASAN_STACK_MAGIC_USE_AFTER_RET;
e361382f 1258 emit_cmp_and_jump_insns (orig_base, base, EQ, NULL_RTX,
357067f2
JH
1259 VOIDmode, 0, lab2,
1260 profile_probability::very_likely ());
e361382f
JJ
1261 shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
1262 set_mem_alias_set (shadow_mem, asan_shadow_set);
1263 mem = gen_rtx_MEM (ptr_mode, base);
1264 mem = adjust_address (mem, VOIDmode, base_align_bias);
1265 emit_move_insn (mem, gen_int_mode (ASAN_STACK_RETIRED_MAGIC, ptr_mode));
1266 unsigned HOST_WIDE_INT sz = asan_frame_size >> ASAN_SHADOW_SHIFT;
1267 if (use_after_return_class < 5
1268 && can_store_by_pieces (sz, builtin_memset_read_str, &c,
1269 BITS_PER_UNIT, true))
1270 store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c,
1271 BITS_PER_UNIT, true, 0);
1272 else if (use_after_return_class >= 5
1273 || !set_storage_via_setmem (shadow_mem,
1274 GEN_INT (sz),
1275 gen_int_mode (c, QImode),
1276 BITS_PER_UNIT, BITS_PER_UNIT,
1277 -1, sz, sz, sz))
1278 {
1279 snprintf (buf, sizeof buf, "__asan_stack_free_%d",
1280 use_after_return_class);
1281 ret = init_one_libfunc (buf);
1282 rtx addr = convert_memory_address (ptr_mode, base);
1283 rtx orig_addr = convert_memory_address (ptr_mode, orig_base);
1284 emit_library_call (ret, LCT_NORMAL, ptr_mode, 3, addr, ptr_mode,
1285 GEN_INT (asan_frame_size + base_align_bias),
1286 TYPE_MODE (pointer_sized_int_node),
1287 orig_addr, ptr_mode);
1288 }
1289 lab = gen_label_rtx ();
1290 emit_jump (lab);
1291 emit_label (lab2);
1292 }
1293
f3ddd692
JJ
1294 shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
1295 set_mem_alias_set (shadow_mem, asan_shadow_set);
e5dcd695
LZ
1296
1297 if (STRICT_ALIGNMENT)
1298 set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
1299
7b972538 1300 prev_offset = base_offset;
f3ddd692 1301 last_offset = base_offset;
7b972538
ML
1302 last_size = 0;
1303 for (l = length; l; l -= 2)
f3ddd692 1304 {
7b972538
ML
1305 offset = base_offset + ((offsets[l - 1] - base_offset)
1306 & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
1307 if (last_offset + last_size != offset)
f3ddd692 1308 {
7b972538
ML
1309 shadow_mem = adjust_address (shadow_mem, VOIDmode,
1310 (last_offset - prev_offset)
1311 >> ASAN_SHADOW_SHIFT);
1312 prev_offset = last_offset;
1313 asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT);
1314 last_offset = offset;
1315 last_size = 0;
1316 }
1317 last_size += base_offset + ((offsets[l - 2] - base_offset)
1318 & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
1319 - offset;
6dc4a604 1320
7b972538
ML
1321 /* Unpoison shadow memory that corresponds to a variable that is
1322 is subject of use-after-return sanitization. */
1323 if (l > 2)
1324 {
1325 decl = decls[l / 2 - 2];
6dc4a604
ML
1326 if (asan_handled_variables != NULL
1327 && asan_handled_variables->contains (decl))
1328 {
7b972538 1329 HOST_WIDE_INT size = offsets[l - 3] - offsets[l - 2];
6dc4a604
ML
1330 if (dump_file && (dump_flags & TDF_DETAILS))
1331 {
1332 const char *n = (DECL_NAME (decl)
1333 ? IDENTIFIER_POINTER (DECL_NAME (decl))
1334 : "<unknown>");
1335 fprintf (dump_file, "Unpoisoning shadow stack for variable: "
7b972538 1336 "%s (%" PRId64 " B)\n", n, size);
6dc4a604
ML
1337 }
1338
7b972538 1339 last_size += size & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1);
6dc4a604 1340 }
f3ddd692 1341 }
7b972538
ML
1342 }
1343 if (last_size)
1344 {
1345 shadow_mem = adjust_address (shadow_mem, VOIDmode,
1346 (last_offset - prev_offset)
1347 >> ASAN_SHADOW_SHIFT);
1348 asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT);
f3ddd692
JJ
1349 }
1350
6dc4a604
ML
1351 /* Clean-up set with instrumented stack variables. */
1352 delete asan_handled_variables;
1353 asan_handled_variables = NULL;
1354 delete asan_used_labels;
1355 asan_used_labels = NULL;
1356
f3ddd692 1357 do_pending_stack_adjust ();
e361382f
JJ
1358 if (lab)
1359 emit_label (lab);
f3ddd692 1360
3a4abd2f 1361 insns = get_insns ();
f3ddd692 1362 end_sequence ();
3a4abd2f 1363 return insns;
f3ddd692
JJ
1364}
1365
8240018b
JJ
1366/* Return true if DECL, a global var, might be overridden and needs
1367 therefore a local alias. */
1368
1369static bool
1370asan_needs_local_alias (tree decl)
1371{
1372 return DECL_WEAK (decl) || !targetm.binds_local_p (decl);
1373}
1374
84b0769e
MO
1375/* Return true if DECL, a global var, is an artificial ODR indicator symbol
1376 therefore doesn't need protection. */
1377
1378static bool
1379is_odr_indicator (tree decl)
1380{
1381 return (DECL_ARTIFICIAL (decl)
1382 && lookup_attribute ("asan odr indicator", DECL_ATTRIBUTES (decl)));
1383}
1384
8240018b
JJ
1385/* Return true if DECL is a VAR_DECL that should be protected
1386 by Address Sanitizer, by appending a red zone with protected
1387 shadow memory after it and aligning it to at least
1388 ASAN_RED_ZONE_SIZE bytes. */
1389
1390bool
1391asan_protect_global (tree decl)
1392{
b5ebc991
MO
1393 if (!ASAN_GLOBALS)
1394 return false;
1395
8240018b 1396 rtx rtl, symbol;
8240018b 1397
94fce891
JJ
1398 if (TREE_CODE (decl) == STRING_CST)
1399 {
1400 /* Instrument all STRING_CSTs except those created
1401 by asan_pp_string here. */
1402 if (shadow_ptr_types[0] != NULL_TREE
1403 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
1404 && TREE_TYPE (TREE_TYPE (decl)) == TREE_TYPE (shadow_ptr_types[0]))
1405 return false;
1406 return true;
1407 }
8813a647 1408 if (!VAR_P (decl)
8240018b
JJ
1409 /* TLS vars aren't statically protectable. */
1410 || DECL_THREAD_LOCAL_P (decl)
1411 /* Externs will be protected elsewhere. */
1412 || DECL_EXTERNAL (decl)
8240018b
JJ
1413 || !DECL_RTL_SET_P (decl)
1414 /* Comdat vars pose an ABI problem, we can't know if
1415 the var that is selected by the linker will have
1416 padding or not. */
1417 || DECL_ONE_ONLY (decl)
f1d15bb9
DV
1418 /* Similarly for common vars. People can use -fno-common.
1419 Note: Linux kernel is built with -fno-common, so we do instrument
1420 globals there even if it is C. */
a8a6fd74 1421 || (DECL_COMMON (decl) && TREE_PUBLIC (decl))
8240018b
JJ
1422 /* Don't protect if using user section, often vars placed
1423 into user section from multiple TUs are then assumed
1424 to be an array of such vars, putting padding in there
1425 breaks this assumption. */
f961457f 1426 || (DECL_SECTION_NAME (decl) != NULL
18af8d16
YG
1427 && !symtab_node::get (decl)->implicit_section
1428 && !section_sanitized_p (DECL_SECTION_NAME (decl)))
8240018b
JJ
1429 || DECL_SIZE (decl) == 0
1430 || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT
1431 || !valid_constant_size_p (DECL_SIZE_UNIT (decl))
21a82048 1432 || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE
84b0769e
MO
1433 || TREE_TYPE (decl) == ubsan_get_source_location_type ()
1434 || is_odr_indicator (decl))
8240018b
JJ
1435 return false;
1436
1437 rtl = DECL_RTL (decl);
1438 if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
1439 return false;
1440 symbol = XEXP (rtl, 0);
1441
1442 if (CONSTANT_POOL_ADDRESS_P (symbol)
1443 || TREE_CONSTANT_POOL_ADDRESS_P (symbol))
1444 return false;
1445
8240018b
JJ
1446 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
1447 return false;
1448
1449#ifndef ASM_OUTPUT_DEF
1450 if (asan_needs_local_alias (decl))
1451 return false;
1452#endif
1453
497a1c66 1454 return true;
8240018b
JJ
1455}
1456
40f9f6bb
JJ
1457/* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16,_n}.
1458 IS_STORE is either 1 (for a store) or 0 (for a load). */
37d6f666
WM
1459
1460static tree
fed4de37
YG
1461report_error_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
1462 int *nargs)
37d6f666 1463{
fed4de37
YG
1464 static enum built_in_function report[2][2][6]
1465 = { { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
1466 BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
1467 BUILT_IN_ASAN_REPORT_LOAD16, BUILT_IN_ASAN_REPORT_LOAD_N },
1468 { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
1469 BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
1470 BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } },
1471 { { BUILT_IN_ASAN_REPORT_LOAD1_NOABORT,
1472 BUILT_IN_ASAN_REPORT_LOAD2_NOABORT,
1473 BUILT_IN_ASAN_REPORT_LOAD4_NOABORT,
1474 BUILT_IN_ASAN_REPORT_LOAD8_NOABORT,
1475 BUILT_IN_ASAN_REPORT_LOAD16_NOABORT,
1476 BUILT_IN_ASAN_REPORT_LOAD_N_NOABORT },
1477 { BUILT_IN_ASAN_REPORT_STORE1_NOABORT,
1478 BUILT_IN_ASAN_REPORT_STORE2_NOABORT,
1479 BUILT_IN_ASAN_REPORT_STORE4_NOABORT,
1480 BUILT_IN_ASAN_REPORT_STORE8_NOABORT,
1481 BUILT_IN_ASAN_REPORT_STORE16_NOABORT,
1482 BUILT_IN_ASAN_REPORT_STORE_N_NOABORT } } };
8946c29e
YG
1483 if (size_in_bytes == -1)
1484 {
1485 *nargs = 2;
fed4de37 1486 return builtin_decl_implicit (report[recover_p][is_store][5]);
8946c29e
YG
1487 }
1488 *nargs = 1;
fed4de37
YG
1489 int size_log2 = exact_log2 (size_in_bytes);
1490 return builtin_decl_implicit (report[recover_p][is_store][size_log2]);
37d6f666
WM
1491}
1492
8946c29e
YG
1493/* Construct a function tree for __asan_{load,store}{1,2,4,8,16,_n}.
1494 IS_STORE is either 1 (for a store) or 0 (for a load). */
1495
1496static tree
fed4de37
YG
1497check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
1498 int *nargs)
8946c29e 1499{
fed4de37
YG
1500 static enum built_in_function check[2][2][6]
1501 = { { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2,
1502 BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8,
1503 BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN },
1504 { BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2,
1505 BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8,
1506 BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } },
1507 { { BUILT_IN_ASAN_LOAD1_NOABORT,
1508 BUILT_IN_ASAN_LOAD2_NOABORT,
1509 BUILT_IN_ASAN_LOAD4_NOABORT,
1510 BUILT_IN_ASAN_LOAD8_NOABORT,
1511 BUILT_IN_ASAN_LOAD16_NOABORT,
1512 BUILT_IN_ASAN_LOADN_NOABORT },
1513 { BUILT_IN_ASAN_STORE1_NOABORT,
1514 BUILT_IN_ASAN_STORE2_NOABORT,
1515 BUILT_IN_ASAN_STORE4_NOABORT,
1516 BUILT_IN_ASAN_STORE8_NOABORT,
1517 BUILT_IN_ASAN_STORE16_NOABORT,
1518 BUILT_IN_ASAN_STOREN_NOABORT } } };
8946c29e
YG
1519 if (size_in_bytes == -1)
1520 {
1521 *nargs = 2;
fed4de37 1522 return builtin_decl_implicit (check[recover_p][is_store][5]);
8946c29e
YG
1523 }
1524 *nargs = 1;
fed4de37
YG
1525 int size_log2 = exact_log2 (size_in_bytes);
1526 return builtin_decl_implicit (check[recover_p][is_store][size_log2]);
8946c29e
YG
1527}
1528
01452015 1529/* Split the current basic block and create a condition statement
25ae5027
DS
1530 insertion point right before or after the statement pointed to by
1531 ITER. Return an iterator to the point at which the caller might
1532 safely insert the condition statement.
01452015
DS
1533
1534 THEN_BLOCK must be set to the address of an uninitialized instance
1535 of basic_block. The function will then set *THEN_BLOCK to the
1536 'then block' of the condition statement to be inserted by the
1537 caller.
1538
c4bfe8bf
JJ
1539 If CREATE_THEN_FALLTHRU_EDGE is false, no edge will be created from
1540 *THEN_BLOCK to *FALLTHROUGH_BLOCK.
1541
01452015
DS
1542 Similarly, the function will set *FALLTRHOUGH_BLOCK to the 'else
1543 block' of the condition statement to be inserted by the caller.
1544
1545 Note that *FALLTHROUGH_BLOCK is a new block that contains the
1546 statements starting from *ITER, and *THEN_BLOCK is a new empty
1547 block.
1548
25ae5027
DS
1549 *ITER is adjusted to point to always point to the first statement
1550 of the basic block * FALLTHROUGH_BLOCK. That statement is the
1551 same as what ITER was pointing to prior to calling this function,
1552 if BEFORE_P is true; otherwise, it is its following statement. */
01452015 1553
ac0ff9f2 1554gimple_stmt_iterator
25ae5027
DS
1555create_cond_insert_point (gimple_stmt_iterator *iter,
1556 bool before_p,
1557 bool then_more_likely_p,
c4bfe8bf 1558 bool create_then_fallthru_edge,
25ae5027
DS
1559 basic_block *then_block,
1560 basic_block *fallthrough_block)
01452015
DS
1561{
1562 gimple_stmt_iterator gsi = *iter;
1563
25ae5027 1564 if (!gsi_end_p (gsi) && before_p)
01452015
DS
1565 gsi_prev (&gsi);
1566
1567 basic_block cur_bb = gsi_bb (*iter);
1568
1569 edge e = split_block (cur_bb, gsi_stmt (gsi));
1570
1571 /* Get a hold on the 'condition block', the 'then block' and the
1572 'else block'. */
1573 basic_block cond_bb = e->src;
1574 basic_block fallthru_bb = e->dest;
1575 basic_block then_bb = create_empty_bb (cond_bb);
a9e0d843
RB
1576 if (current_loops)
1577 {
1578 add_bb_to_loop (then_bb, cond_bb->loop_father);
1579 loops_state_set (LOOPS_NEED_FIXUP);
1580 }
01452015
DS
1581
1582 /* Set up the newly created 'then block'. */
1583 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
1584 int fallthrough_probability
1585 = then_more_likely_p
1586 ? PROB_VERY_UNLIKELY
1587 : PROB_ALWAYS - PROB_VERY_UNLIKELY;
357067f2
JH
1588 e->probability = profile_probability::from_reg_br_prob_base
1589 (PROB_ALWAYS - fallthrough_probability);
c4bfe8bf
JJ
1590 if (create_then_fallthru_edge)
1591 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
01452015
DS
1592
1593 /* Set up the fallthrough basic block. */
1594 e = find_edge (cond_bb, fallthru_bb);
1595 e->flags = EDGE_FALSE_VALUE;
1596 e->count = cond_bb->count;
357067f2
JH
1597 e->probability
1598 = profile_probability::from_reg_br_prob_base (fallthrough_probability);
01452015
DS
1599
1600 /* Update dominance info for the newly created then_bb; note that
1601 fallthru_bb's dominance info has already been updated by
1602 split_bock. */
1603 if (dom_info_available_p (CDI_DOMINATORS))
1604 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
1605
1606 *then_block = then_bb;
1607 *fallthrough_block = fallthru_bb;
1608 *iter = gsi_start_bb (fallthru_bb);
1609
1610 return gsi_last_bb (cond_bb);
1611}
1612
25ae5027
DS
1613/* Insert an if condition followed by a 'then block' right before the
1614 statement pointed to by ITER. The fallthrough block -- which is the
1615 else block of the condition as well as the destination of the
1616 outcoming edge of the 'then block' -- starts with the statement
1617 pointed to by ITER.
1618
497a1c66 1619 COND is the condition of the if.
25ae5027
DS
1620
1621 If THEN_MORE_LIKELY_P is true, the probability of the edge to the
1622 'then block' is higher than the probability of the edge to the
1623 fallthrough block.
1624
1625 Upon completion of the function, *THEN_BB is set to the newly
1626 inserted 'then block' and similarly, *FALLTHROUGH_BB is set to the
1627 fallthrough block.
1628
1629 *ITER is adjusted to still point to the same statement it was
1630 pointing to initially. */
1631
1632static void
538dd0b7 1633insert_if_then_before_iter (gcond *cond,
25ae5027
DS
1634 gimple_stmt_iterator *iter,
1635 bool then_more_likely_p,
1636 basic_block *then_bb,
1637 basic_block *fallthrough_bb)
1638{
1639 gimple_stmt_iterator cond_insert_point =
1640 create_cond_insert_point (iter,
1641 /*before_p=*/true,
1642 then_more_likely_p,
c4bfe8bf 1643 /*create_then_fallthru_edge=*/true,
25ae5027
DS
1644 then_bb,
1645 fallthrough_bb);
1646 gsi_insert_after (&cond_insert_point, cond, GSI_NEW_STMT);
1647}
1648
6dc4a604
ML
1649/* Build (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().
1650 If RETURN_ADDRESS is set to true, return memory location instread
1651 of a value in the shadow memory. */
40f9f6bb
JJ
1652
1653static tree
1654build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
6dc4a604
ML
1655 tree base_addr, tree shadow_ptr_type,
1656 bool return_address = false)
40f9f6bb
JJ
1657{
1658 tree t, uintptr_type = TREE_TYPE (base_addr);
1659 tree shadow_type = TREE_TYPE (shadow_ptr_type);
355fe088 1660 gimple *g;
40f9f6bb
JJ
1661
1662 t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT);
0d0e4a03
JJ
1663 g = gimple_build_assign (make_ssa_name (uintptr_type), RSHIFT_EXPR,
1664 base_addr, t);
40f9f6bb
JJ
1665 gimple_set_location (g, location);
1666 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1667
fd960af2 1668 t = build_int_cst (uintptr_type, asan_shadow_offset ());
0d0e4a03
JJ
1669 g = gimple_build_assign (make_ssa_name (uintptr_type), PLUS_EXPR,
1670 gimple_assign_lhs (g), t);
40f9f6bb
JJ
1671 gimple_set_location (g, location);
1672 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1673
0d0e4a03
JJ
1674 g = gimple_build_assign (make_ssa_name (shadow_ptr_type), NOP_EXPR,
1675 gimple_assign_lhs (g));
40f9f6bb
JJ
1676 gimple_set_location (g, location);
1677 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1678
6dc4a604
ML
1679 if (!return_address)
1680 {
1681 t = build2 (MEM_REF, shadow_type, gimple_assign_lhs (g),
1682 build_int_cst (shadow_ptr_type, 0));
1683 g = gimple_build_assign (make_ssa_name (shadow_type), MEM_REF, t);
1684 gimple_set_location (g, location);
1685 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1686 }
1687
40f9f6bb
JJ
1688 return gimple_assign_lhs (g);
1689}
1690
8946c29e
YG
1691/* BASE can already be an SSA_NAME; in that case, do not create a
1692 new SSA_NAME for it. */
1693
1694static tree
1695maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
1696 bool before_p)
1697{
1698 if (TREE_CODE (base) == SSA_NAME)
1699 return base;
355fe088 1700 gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (base)),
0d0e4a03 1701 TREE_CODE (base), base);
8946c29e
YG
1702 gimple_set_location (g, loc);
1703 if (before_p)
1704 gsi_insert_before (iter, g, GSI_SAME_STMT);
1705 else
1706 gsi_insert_after (iter, g, GSI_NEW_STMT);
1707 return gimple_assign_lhs (g);
1708}
1709
a2f581e1
YG
1710/* LEN can already have necessary size and precision;
1711 in that case, do not create a new variable. */
1712
1713tree
1714maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
1715 bool before_p)
1716{
1717 if (ptrofftype_p (len))
1718 return len;
355fe088 1719 gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
0d0e4a03 1720 NOP_EXPR, len);
a2f581e1
YG
1721 gimple_set_location (g, loc);
1722 if (before_p)
1723 gsi_insert_before (iter, g, GSI_SAME_STMT);
1724 else
1725 gsi_insert_after (iter, g, GSI_NEW_STMT);
1726 return gimple_assign_lhs (g);
1727}
1728
dc29bf1e 1729/* Instrument the memory access instruction BASE. Insert new
25ae5027 1730 statements before or after ITER.
dc29bf1e
DS
1731
1732 Note that the memory access represented by BASE can be either an
1733 SSA_NAME, or a non-SSA expression. LOCATION is the source code
1734 location. IS_STORE is TRUE for a store, FALSE for a load.
25ae5027 1735 BEFORE_P is TRUE for inserting the instrumentation code before
8946c29e
YG
1736 ITER, FALSE for inserting it after ITER. IS_SCALAR_ACCESS is TRUE
1737 for a scalar memory access and FALSE for memory region access.
1738 NON_ZERO_P is TRUE if memory region is guaranteed to have non-zero
1739 length. ALIGN tells alignment of accessed memory object.
1740
1741 START_INSTRUMENTED and END_INSTRUMENTED are TRUE if start/end of
1742 memory region have already been instrumented.
25ae5027
DS
1743
1744 If BEFORE_P is TRUE, *ITER is arranged to still point to the
1745 statement it was pointing to prior to calling this function,
1746 otherwise, it points to the statement logically following it. */
37d6f666
WM
1747
1748static void
c62ccb9a 1749build_check_stmt (location_t loc, tree base, tree len,
8946c29e 1750 HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
c62ccb9a 1751 bool is_non_zero_len, bool before_p, bool is_store,
bdea98ca 1752 bool is_scalar_access, unsigned int align = 0)
37d6f666 1753{
8946c29e 1754 gimple_stmt_iterator gsi = *iter;
355fe088 1755 gimple *g;
8946c29e 1756
c62ccb9a 1757 gcc_assert (!(size_in_bytes > 0 && !is_non_zero_len));
8946c29e 1758
c62ccb9a
YG
1759 gsi = *iter;
1760
1761 base = unshare_expr (base);
1762 base = maybe_create_ssa_name (loc, base, &gsi, before_p);
1763
8946c29e 1764 if (len)
a2f581e1
YG
1765 {
1766 len = unshare_expr (len);
1767 len = maybe_cast_to_ptrmode (loc, len, iter, before_p);
1768 }
8946c29e
YG
1769 else
1770 {
1771 gcc_assert (size_in_bytes != -1);
1772 len = build_int_cst (pointer_sized_int_node, size_in_bytes);
1773 }
1774
1775 if (size_in_bytes > 1)
b3f1051b 1776 {
8946c29e
YG
1777 if ((size_in_bytes & (size_in_bytes - 1)) != 0
1778 || size_in_bytes > 16)
c62ccb9a 1779 is_scalar_access = false;
8946c29e
YG
1780 else if (align && align < size_in_bytes * BITS_PER_UNIT)
1781 {
1782 /* On non-strict alignment targets, if
1783 16-byte access is just 8-byte aligned,
1784 this will result in misaligned shadow
1785 memory 2 byte load, but otherwise can
1786 be handled using one read. */
1787 if (size_in_bytes != 16
1788 || STRICT_ALIGNMENT
1789 || align < 8 * BITS_PER_UNIT)
c62ccb9a 1790 is_scalar_access = false;
40f9f6bb 1791 }
f6d98484 1792 }
37d6f666 1793
c62ccb9a
YG
1794 HOST_WIDE_INT flags = 0;
1795 if (is_store)
1796 flags |= ASAN_CHECK_STORE;
1797 if (is_non_zero_len)
1798 flags |= ASAN_CHECK_NON_ZERO_LEN;
1799 if (is_scalar_access)
1800 flags |= ASAN_CHECK_SCALAR_ACCESS;
c62ccb9a 1801
f434eb69 1802 g = gimple_build_call_internal (IFN_ASAN_CHECK, 4,
c62ccb9a 1803 build_int_cst (integer_type_node, flags),
f434eb69
MZ
1804 base, len,
1805 build_int_cst (integer_type_node,
1806 align / BITS_PER_UNIT));
c62ccb9a
YG
1807 gimple_set_location (g, loc);
1808 if (before_p)
1809 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
8946c29e
YG
1810 else
1811 {
8946c29e 1812 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
c62ccb9a
YG
1813 gsi_next (&gsi);
1814 *iter = gsi;
8946c29e 1815 }
37d6f666
WM
1816}
1817
1818/* If T represents a memory access, add instrumentation code before ITER.
1819 LOCATION is source code location.
25ae5027 1820 IS_STORE is either TRUE (for a store) or FALSE (for a load). */
37d6f666
WM
1821
1822static void
1823instrument_derefs (gimple_stmt_iterator *iter, tree t,
bdcbe80c 1824 location_t location, bool is_store)
37d6f666 1825{
b5ebc991
MO
1826 if (is_store && !ASAN_INSTRUMENT_WRITES)
1827 return;
1828 if (!is_store && !ASAN_INSTRUMENT_READS)
1829 return;
1830
37d6f666 1831 tree type, base;
f6d98484 1832 HOST_WIDE_INT size_in_bytes;
c3da4956
MO
1833 if (location == UNKNOWN_LOCATION)
1834 location = EXPR_LOCATION (t);
37d6f666
WM
1835
1836 type = TREE_TYPE (t);
37d6f666
WM
1837 switch (TREE_CODE (t))
1838 {
1839 case ARRAY_REF:
1840 case COMPONENT_REF:
1841 case INDIRECT_REF:
1842 case MEM_REF:
59b36ecf 1843 case VAR_DECL:
913f32a1 1844 case BIT_FIELD_REF:
37d6f666 1845 break;
59b36ecf 1846 /* FALLTHRU */
37d6f666
WM
1847 default:
1848 return;
1849 }
f6d98484
JJ
1850
1851 size_in_bytes = int_size_in_bytes (type);
40f9f6bb 1852 if (size_in_bytes <= 0)
f6d98484
JJ
1853 return;
1854
f6d98484
JJ
1855 HOST_WIDE_INT bitsize, bitpos;
1856 tree offset;
ef4bddc2 1857 machine_mode mode;
ee45a32d
EB
1858 int unsignedp, reversep, volatilep = 0;
1859 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
25b75a48 1860 &unsignedp, &reversep, &volatilep);
87d1d65a
YG
1861
1862 if (TREE_CODE (t) == COMPONENT_REF
1863 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1fe04fdc 1864 {
87d1d65a
YG
1865 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1866 instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
1867 TREE_OPERAND (t, 0), repr,
7cd200f6
JJ
1868 TREE_OPERAND (t, 2)),
1869 location, is_store);
1fe04fdc
JJ
1870 return;
1871 }
87d1d65a
YG
1872
1873 if (bitpos % BITS_PER_UNIT
1874 || bitsize != size_in_bytes * BITS_PER_UNIT)
40f9f6bb 1875 return;
f6d98484 1876
6dc61b45
ML
1877 if (VAR_P (inner) && DECL_HARD_REGISTER (inner))
1878 return;
1879
8813a647 1880 if (VAR_P (inner)
59b36ecf
JJ
1881 && offset == NULL_TREE
1882 && bitpos >= 0
1883 && DECL_SIZE (inner)
1884 && tree_fits_shwi_p (DECL_SIZE (inner))
1885 && bitpos + bitsize <= tree_to_shwi (DECL_SIZE (inner)))
1886 {
1887 if (DECL_THREAD_LOCAL_P (inner))
1888 return;
6b98fab5
MZ
1889 if (!ASAN_GLOBALS && is_global_var (inner))
1890 return;
59b36ecf
JJ
1891 if (!TREE_STATIC (inner))
1892 {
1893 /* Automatic vars in the current function will be always
1894 accessible. */
6dc4a604
ML
1895 if (decl_function_context (inner) == current_function_decl
1896 && (!asan_sanitize_use_after_scope ()
1897 || !TREE_ADDRESSABLE (inner)))
59b36ecf
JJ
1898 return;
1899 }
1900 /* Always instrument external vars, they might be dynamically
1901 initialized. */
1902 else if (!DECL_EXTERNAL (inner))
1903 {
1904 /* For static vars if they are known not to be dynamically
1905 initialized, they will be always accessible. */
9041d2e6 1906 varpool_node *vnode = varpool_node::get (inner);
59b36ecf
JJ
1907 if (vnode && !vnode->dynamically_initialized)
1908 return;
1909 }
1910 }
1911
f6d98484 1912 base = build_fold_addr_expr (t);
bdcbe80c
DS
1913 if (!has_mem_ref_been_instrumented (base, size_in_bytes))
1914 {
8946c29e
YG
1915 unsigned int align = get_object_alignment (t);
1916 build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter,
c62ccb9a 1917 /*is_non_zero_len*/size_in_bytes > 0, /*before_p=*/true,
8946c29e 1918 is_store, /*is_scalar_access*/true, align);
bdcbe80c
DS
1919 update_mem_ref_hash_table (base, size_in_bytes);
1920 update_mem_ref_hash_table (t, size_in_bytes);
1921 }
1922
25ae5027
DS
1923}
1924
bdea98ca
MO
1925/* Insert a memory reference into the hash table if access length
1926 can be determined in compile time. */
1927
1928static void
1929maybe_update_mem_ref_hash_table (tree base, tree len)
1930{
1931 if (!POINTER_TYPE_P (TREE_TYPE (base))
1932 || !INTEGRAL_TYPE_P (TREE_TYPE (len)))
1933 return;
1934
1935 HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
1936
1937 if (size_in_bytes != -1)
1938 update_mem_ref_hash_table (base, size_in_bytes);
1939}
1940
25ae5027
DS
1941/* Instrument an access to a contiguous memory region that starts at
1942 the address pointed to by BASE, over a length of LEN (expressed in
1943 the sizeof (*BASE) bytes). ITER points to the instruction before
1944 which the instrumentation instructions must be inserted. LOCATION
1945 is the source location that the instrumentation instructions must
1946 have. If IS_STORE is true, then the memory access is a store;
1947 otherwise, it's a load. */
1948
1949static void
1950instrument_mem_region_access (tree base, tree len,
1951 gimple_stmt_iterator *iter,
1952 location_t location, bool is_store)
1953{
c63d3b96
JJ
1954 if (!POINTER_TYPE_P (TREE_TYPE (base))
1955 || !INTEGRAL_TYPE_P (TREE_TYPE (len))
1956 || integer_zerop (len))
25ae5027
DS
1957 return;
1958
8946c29e 1959 HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
bdcbe80c 1960
bdea98ca
MO
1961 if ((size_in_bytes == -1)
1962 || !has_mem_ref_been_instrumented (base, size_in_bytes))
1963 {
1964 build_check_stmt (location, base, len, size_in_bytes, iter,
1965 /*is_non_zero_len*/size_in_bytes > 0, /*before_p*/true,
1966 is_store, /*is_scalar_access*/false, /*align*/0);
1967 }
b41288b3 1968
bdea98ca 1969 maybe_update_mem_ref_hash_table (base, len);
b41288b3 1970 *iter = gsi_for_stmt (gsi_stmt (*iter));
bdcbe80c 1971}
25ae5027 1972
bdcbe80c
DS
1973/* Instrument the call to a built-in memory access function that is
1974 pointed to by the iterator ITER.
25ae5027 1975
bdcbe80c
DS
1976 Upon completion, return TRUE iff *ITER has been advanced to the
1977 statement following the one it was originally pointing to. */
25ae5027 1978
bdcbe80c
DS
1979static bool
1980instrument_builtin_call (gimple_stmt_iterator *iter)
1981{
b5ebc991
MO
1982 if (!ASAN_MEMINTRIN)
1983 return false;
1984
bdcbe80c 1985 bool iter_advanced_p = false;
538dd0b7 1986 gcall *call = as_a <gcall *> (gsi_stmt (*iter));
25ae5027 1987
bdcbe80c 1988 gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
25ae5027 1989
bdcbe80c 1990 location_t loc = gimple_location (call);
25ae5027 1991
bdea98ca
MO
1992 asan_mem_ref src0, src1, dest;
1993 asan_mem_ref_init (&src0, NULL, 1);
1994 asan_mem_ref_init (&src1, NULL, 1);
1995 asan_mem_ref_init (&dest, NULL, 1);
bdcbe80c 1996
bdea98ca
MO
1997 tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
1998 bool src0_is_store = false, src1_is_store = false, dest_is_store = false,
1999 dest_is_deref = false, intercepted_p = true;
bdcbe80c 2000
bdea98ca
MO
2001 if (get_mem_refs_of_builtin_call (call,
2002 &src0, &src0_len, &src0_is_store,
2003 &src1, &src1_len, &src1_is_store,
2004 &dest, &dest_len, &dest_is_store,
2005 &dest_is_deref, &intercepted_p))
2006 {
2007 if (dest_is_deref)
bdcbe80c 2008 {
bdea98ca
MO
2009 instrument_derefs (iter, dest.start, loc, dest_is_store);
2010 gsi_next (iter);
2011 iter_advanced_p = true;
2012 }
2013 else if (!intercepted_p
2014 && (src0_len || src1_len || dest_len))
2015 {
2016 if (src0.start != NULL_TREE)
2017 instrument_mem_region_access (src0.start, src0_len,
2018 iter, loc, /*is_store=*/false);
2019 if (src1.start != NULL_TREE)
2020 instrument_mem_region_access (src1.start, src1_len,
2021 iter, loc, /*is_store=*/false);
2022 if (dest.start != NULL_TREE)
2023 instrument_mem_region_access (dest.start, dest_len,
2024 iter, loc, /*is_store=*/true);
2025
2026 *iter = gsi_for_stmt (call);
2027 gsi_next (iter);
2028 iter_advanced_p = true;
2029 }
2030 else
2031 {
2032 if (src0.start != NULL_TREE)
2033 maybe_update_mem_ref_hash_table (src0.start, src0_len);
2034 if (src1.start != NULL_TREE)
2035 maybe_update_mem_ref_hash_table (src1.start, src1_len);
2036 if (dest.start != NULL_TREE)
2037 maybe_update_mem_ref_hash_table (dest.start, dest_len);
bdcbe80c 2038 }
25ae5027 2039 }
bdcbe80c 2040 return iter_advanced_p;
25ae5027
DS
2041}
2042
2043/* Instrument the assignment statement ITER if it is subject to
bdcbe80c
DS
2044 instrumentation. Return TRUE iff instrumentation actually
2045 happened. In that case, the iterator ITER is advanced to the next
2046 logical expression following the one initially pointed to by ITER,
2047 and the relevant memory reference that which access has been
2048 instrumented is added to the memory references hash table. */
25ae5027 2049
bdcbe80c
DS
2050static bool
2051maybe_instrument_assignment (gimple_stmt_iterator *iter)
25ae5027 2052{
355fe088 2053 gimple *s = gsi_stmt (*iter);
25ae5027
DS
2054
2055 gcc_assert (gimple_assign_single_p (s));
2056
bdcbe80c
DS
2057 tree ref_expr = NULL_TREE;
2058 bool is_store, is_instrumented = false;
2059
52f2e7e1 2060 if (gimple_store_p (s))
bdcbe80c
DS
2061 {
2062 ref_expr = gimple_assign_lhs (s);
2063 is_store = true;
2064 instrument_derefs (iter, ref_expr,
2065 gimple_location (s),
2066 is_store);
2067 is_instrumented = true;
2068 }
c1f5ce48 2069
52f2e7e1 2070 if (gimple_assign_load_p (s))
bdcbe80c
DS
2071 {
2072 ref_expr = gimple_assign_rhs1 (s);
2073 is_store = false;
2074 instrument_derefs (iter, ref_expr,
2075 gimple_location (s),
2076 is_store);
2077 is_instrumented = true;
2078 }
2079
2080 if (is_instrumented)
2081 gsi_next (iter);
2082
2083 return is_instrumented;
25ae5027
DS
2084}
2085
2086/* Instrument the function call pointed to by the iterator ITER, if it
2087 is subject to instrumentation. At the moment, the only function
2088 calls that are instrumented are some built-in functions that access
2089 memory. Look at instrument_builtin_call to learn more.
2090
2091 Upon completion return TRUE iff *ITER was advanced to the statement
2092 following the one it was originally pointing to. */
2093
2094static bool
2095maybe_instrument_call (gimple_stmt_iterator *iter)
2096{
355fe088 2097 gimple *stmt = gsi_stmt (*iter);
bdcbe80c
DS
2098 bool is_builtin = gimple_call_builtin_p (stmt, BUILT_IN_NORMAL);
2099
2100 if (is_builtin && instrument_builtin_call (iter))
2b2571c9 2101 return true;
bdcbe80c 2102
2b2571c9
JJ
2103 if (gimple_call_noreturn_p (stmt))
2104 {
2105 if (is_builtin)
2106 {
2107 tree callee = gimple_call_fndecl (stmt);
2108 switch (DECL_FUNCTION_CODE (callee))
2109 {
2110 case BUILT_IN_UNREACHABLE:
2111 case BUILT_IN_TRAP:
2112 /* Don't instrument these. */
2113 return false;
083e891e
MP
2114 default:
2115 break;
2b2571c9
JJ
2116 }
2117 }
2118 tree decl = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN);
355fe088 2119 gimple *g = gimple_build_call (decl, 0);
2b2571c9
JJ
2120 gimple_set_location (g, gimple_location (stmt));
2121 gsi_insert_before (iter, g, GSI_SAME_STMT);
2122 }
7db337c2 2123
c3da4956 2124 bool instrumented = false;
7db337c2
ML
2125 if (gimple_store_p (stmt))
2126 {
2127 tree ref_expr = gimple_call_lhs (stmt);
2128 instrument_derefs (iter, ref_expr,
2129 gimple_location (stmt),
2130 /*is_store=*/true);
2131
c3da4956 2132 instrumented = true;
7db337c2
ML
2133 }
2134
c3da4956
MO
2135 /* Walk through gimple_call arguments and check them id needed. */
2136 unsigned args_num = gimple_call_num_args (stmt);
2137 for (unsigned i = 0; i < args_num; ++i)
2138 {
2139 tree arg = gimple_call_arg (stmt, i);
2140 /* If ARG is not a non-aggregate register variable, compiler in general
2141 creates temporary for it and pass it as argument to gimple call.
2142 But in some cases, e.g. when we pass by value a small structure that
2143 fits to register, compiler can avoid extra overhead by pulling out
2144 these temporaries. In this case, we should check the argument. */
2145 if (!is_gimple_reg (arg) && !is_gimple_min_invariant (arg))
2146 {
2147 instrument_derefs (iter, arg,
2148 gimple_location (stmt),
2149 /*is_store=*/false);
2150 instrumented = true;
2151 }
2152 }
2153 if (instrumented)
2154 gsi_next (iter);
2155 return instrumented;
37d6f666
WM
2156}
2157
bdcbe80c
DS
2158/* Walk each instruction of all basic block and instrument those that
2159 represent memory references: loads, stores, or function calls.
2160 In a given basic block, this function avoids instrumenting memory
2161 references that have already been instrumented. */
37d6f666
WM
2162
2163static void
2164transform_statements (void)
2165{
c4bfe8bf 2166 basic_block bb, last_bb = NULL;
37d6f666 2167 gimple_stmt_iterator i;
8b1c6fd7 2168 int saved_last_basic_block = last_basic_block_for_fn (cfun);
37d6f666 2169
11cd3bed 2170 FOR_EACH_BB_FN (bb, cfun)
37d6f666 2171 {
c4bfe8bf 2172 basic_block prev_bb = bb;
bdcbe80c 2173
37d6f666 2174 if (bb->index >= saved_last_basic_block) continue;
c4bfe8bf
JJ
2175
2176 /* Flush the mem ref hash table, if current bb doesn't have
2177 exactly one predecessor, or if that predecessor (skipping
2178 over asan created basic blocks) isn't the last processed
2179 basic block. Thus we effectively flush on extended basic
2180 block boundaries. */
2181 while (single_pred_p (prev_bb))
2182 {
2183 prev_bb = single_pred (prev_bb);
2184 if (prev_bb->index < saved_last_basic_block)
2185 break;
2186 }
2187 if (prev_bb != last_bb)
2188 empty_mem_ref_hash_table ();
2189 last_bb = bb;
2190
25ae5027 2191 for (i = gsi_start_bb (bb); !gsi_end_p (i);)
497a1c66 2192 {
355fe088 2193 gimple *s = gsi_stmt (i);
25ae5027 2194
bdcbe80c
DS
2195 if (has_stmt_been_instrumented_p (s))
2196 gsi_next (&i);
2197 else if (gimple_assign_single_p (s)
e1e160c1 2198 && !gimple_clobber_p (s)
bdcbe80c
DS
2199 && maybe_instrument_assignment (&i))
2200 /* Nothing to do as maybe_instrument_assignment advanced
2201 the iterator I. */;
2202 else if (is_gimple_call (s) && maybe_instrument_call (&i))
2203 /* Nothing to do as maybe_instrument_call
2204 advanced the iterator I. */;
2205 else
25ae5027 2206 {
bdcbe80c
DS
2207 /* No instrumentation happened.
2208
c4bfe8bf
JJ
2209 If the current instruction is a function call that
2210 might free something, let's forget about the memory
2211 references that got instrumented. Otherwise we might
6dc4a604
ML
2212 miss some instrumentation opportunities. Do the same
2213 for a ASAN_MARK poisoning internal function. */
2214 if (is_gimple_call (s)
56b7aede
ML
2215 && (!nonfreeing_call_p (s)
2216 || asan_mark_p (s, ASAN_MARK_POISON)))
bdcbe80c
DS
2217 empty_mem_ref_hash_table ();
2218
2219 gsi_next (&i);
25ae5027 2220 }
497a1c66 2221 }
37d6f666 2222 }
bdcbe80c 2223 free_mem_ref_resources ();
37d6f666
WM
2224}
2225
59b36ecf
JJ
2226/* Build
2227 __asan_before_dynamic_init (module_name)
2228 or
2229 __asan_after_dynamic_init ()
2230 call. */
2231
2232tree
2233asan_dynamic_init_call (bool after_p)
2234{
185faecb
JJ
2235 if (shadow_ptr_types[0] == NULL_TREE)
2236 asan_init_shadow_ptr_types ();
2237
59b36ecf
JJ
2238 tree fn = builtin_decl_implicit (after_p
2239 ? BUILT_IN_ASAN_AFTER_DYNAMIC_INIT
2240 : BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT);
2241 tree module_name_cst = NULL_TREE;
2242 if (!after_p)
2243 {
2244 pretty_printer module_name_pp;
2245 pp_string (&module_name_pp, main_input_filename);
2246
59b36ecf
JJ
2247 module_name_cst = asan_pp_string (&module_name_pp);
2248 module_name_cst = fold_convert (const_ptr_type_node,
2249 module_name_cst);
2250 }
2251
2252 return build_call_expr (fn, after_p ? 0 : 1, module_name_cst);
2253}
2254
8240018b
JJ
2255/* Build
2256 struct __asan_global
2257 {
2258 const void *__beg;
2259 uptr __size;
2260 uptr __size_with_redzone;
2261 const void *__name;
ef1b3fda 2262 const void *__module_name;
8240018b 2263 uptr __has_dynamic_init;
866e32ad 2264 __asan_global_source_location *__location;
fbdb92eb 2265 char *__odr_indicator;
8240018b
JJ
2266 } type. */
2267
2268static tree
2269asan_global_struct (void)
2270{
84b0769e 2271 static const char *field_names[]
8240018b 2272 = { "__beg", "__size", "__size_with_redzone",
84b0769e
MO
2273 "__name", "__module_name", "__has_dynamic_init", "__location",
2274 "__odr_indicator" };
2275 tree fields[ARRAY_SIZE (field_names)], ret;
2276 unsigned i;
8240018b
JJ
2277
2278 ret = make_node (RECORD_TYPE);
84b0769e 2279 for (i = 0; i < ARRAY_SIZE (field_names); i++)
8240018b
JJ
2280 {
2281 fields[i]
2282 = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
2283 get_identifier (field_names[i]),
2284 (i == 0 || i == 3) ? const_ptr_type_node
de5a5fa1 2285 : pointer_sized_int_node);
8240018b
JJ
2286 DECL_CONTEXT (fields[i]) = ret;
2287 if (i)
2288 DECL_CHAIN (fields[i - 1]) = fields[i];
2289 }
bebcdc67
MP
2290 tree type_decl = build_decl (input_location, TYPE_DECL,
2291 get_identifier ("__asan_global"), ret);
2292 DECL_IGNORED_P (type_decl) = 1;
2293 DECL_ARTIFICIAL (type_decl) = 1;
8240018b 2294 TYPE_FIELDS (ret) = fields[0];
bebcdc67
MP
2295 TYPE_NAME (ret) = type_decl;
2296 TYPE_STUB_DECL (ret) = type_decl;
8240018b
JJ
2297 layout_type (ret);
2298 return ret;
2299}
2300
84b0769e
MO
2301/* Create and return odr indicator symbol for DECL.
2302 TYPE is __asan_global struct type as returned by asan_global_struct. */
2303
2304static tree
2305create_odr_indicator (tree decl, tree type)
2306{
2307 char *name;
2308 tree uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
2309 tree decl_name
2310 = (HAS_DECL_ASSEMBLER_NAME_P (decl) ? DECL_ASSEMBLER_NAME (decl)
2311 : DECL_NAME (decl));
2312 /* DECL_NAME theoretically might be NULL. Bail out with 0 in this case. */
2313 if (decl_name == NULL_TREE)
2314 return build_int_cst (uptr, 0);
2315 size_t len = strlen (IDENTIFIER_POINTER (decl_name)) + sizeof ("__odr_asan_");
2316 name = XALLOCAVEC (char, len);
2317 snprintf (name, len, "__odr_asan_%s", IDENTIFIER_POINTER (decl_name));
2318#ifndef NO_DOT_IN_LABEL
2319 name[sizeof ("__odr_asan") - 1] = '.';
2320#elif !defined(NO_DOLLAR_IN_LABEL)
2321 name[sizeof ("__odr_asan") - 1] = '$';
2322#endif
2323 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (name),
2324 char_type_node);
2325 TREE_ADDRESSABLE (var) = 1;
2326 TREE_READONLY (var) = 0;
2327 TREE_THIS_VOLATILE (var) = 1;
2328 DECL_GIMPLE_REG_P (var) = 0;
2329 DECL_ARTIFICIAL (var) = 1;
2330 DECL_IGNORED_P (var) = 1;
2331 TREE_STATIC (var) = 1;
2332 TREE_PUBLIC (var) = 1;
2333 DECL_VISIBILITY (var) = DECL_VISIBILITY (decl);
2334 DECL_VISIBILITY_SPECIFIED (var) = DECL_VISIBILITY_SPECIFIED (decl);
2335
2336 TREE_USED (var) = 1;
2337 tree ctor = build_constructor_va (TREE_TYPE (var), 1, NULL_TREE,
2338 build_int_cst (unsigned_type_node, 0));
2339 TREE_CONSTANT (ctor) = 1;
2340 TREE_STATIC (ctor) = 1;
2341 DECL_INITIAL (var) = ctor;
2342 DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("asan odr indicator"),
2343 NULL, DECL_ATTRIBUTES (var));
2344 make_decl_rtl (var);
2345 varpool_node::finalize_decl (var);
2346 return fold_convert (uptr, build_fold_addr_expr (var));
2347}
2348
2349/* Return true if DECL, a global var, might be overridden and needs
2350 an additional odr indicator symbol. */
2351
2352static bool
2353asan_needs_odr_indicator_p (tree decl)
2354{
0acd830b
MO
2355 /* Don't emit ODR indicators for kernel because:
2356 a) Kernel is written in C thus doesn't need ODR indicators.
2357 b) Some kernel code may have assumptions about symbols containing specific
2358 patterns in their names. Since ODR indicators contain original names
2359 of symbols they are emitted for, these assumptions would be broken for
2360 ODR indicator symbols. */
2361 return (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2362 && !DECL_ARTIFICIAL (decl)
2363 && !DECL_WEAK (decl)
2364 && TREE_PUBLIC (decl));
84b0769e
MO
2365}
2366
8240018b
JJ
2367/* Append description of a single global DECL into vector V.
2368 TYPE is __asan_global struct type as returned by asan_global_struct. */
2369
2370static void
9771b263 2371asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
8240018b
JJ
2372{
2373 tree init, uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
2374 unsigned HOST_WIDE_INT size;
ef1b3fda 2375 tree str_cst, module_name_cst, refdecl = decl;
9771b263 2376 vec<constructor_elt, va_gc> *vinner = NULL;
8240018b 2377
ef1b3fda 2378 pretty_printer asan_pp, module_name_pp;
8240018b 2379
8240018b 2380 if (DECL_NAME (decl))
b066401f 2381 pp_tree_identifier (&asan_pp, DECL_NAME (decl));
8240018b
JJ
2382 else
2383 pp_string (&asan_pp, "<unknown>");
11a877b3 2384 str_cst = asan_pp_string (&asan_pp);
8240018b 2385
f1860ba9 2386 pp_string (&module_name_pp, main_input_filename);
ef1b3fda
KS
2387 module_name_cst = asan_pp_string (&module_name_pp);
2388
8240018b
JJ
2389 if (asan_needs_local_alias (decl))
2390 {
2391 char buf[20];
9771b263 2392 ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", vec_safe_length (v) + 1);
8240018b
JJ
2393 refdecl = build_decl (DECL_SOURCE_LOCATION (decl),
2394 VAR_DECL, get_identifier (buf), TREE_TYPE (decl));
2395 TREE_ADDRESSABLE (refdecl) = TREE_ADDRESSABLE (decl);
2396 TREE_READONLY (refdecl) = TREE_READONLY (decl);
2397 TREE_THIS_VOLATILE (refdecl) = TREE_THIS_VOLATILE (decl);
2398 DECL_GIMPLE_REG_P (refdecl) = DECL_GIMPLE_REG_P (decl);
2399 DECL_ARTIFICIAL (refdecl) = DECL_ARTIFICIAL (decl);
2400 DECL_IGNORED_P (refdecl) = DECL_IGNORED_P (decl);
2401 TREE_STATIC (refdecl) = 1;
2402 TREE_PUBLIC (refdecl) = 0;
2403 TREE_USED (refdecl) = 1;
2404 assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl));
2405 }
2406
84b0769e
MO
2407 tree odr_indicator_ptr
2408 = (asan_needs_odr_indicator_p (decl) ? create_odr_indicator (decl, type)
2409 : build_int_cst (uptr, 0));
8240018b
JJ
2410 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
2411 fold_convert (const_ptr_type_node,
2412 build_fold_addr_expr (refdecl)));
ae7e9ddd 2413 size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
8240018b
JJ
2414 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
2415 size += asan_red_zone_size (size);
2416 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
2417 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
2418 fold_convert (const_ptr_type_node, str_cst));
ef1b3fda
KS
2419 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
2420 fold_convert (const_ptr_type_node, module_name_cst));
9041d2e6 2421 varpool_node *vnode = varpool_node::get (decl);
f1860ba9
MO
2422 int has_dynamic_init = 0;
2423 /* FIXME: Enable initialization order fiasco detection in LTO mode once
2424 proper fix for PR 79061 will be applied. */
2425 if (!in_lto_p)
2426 has_dynamic_init = vnode ? vnode->dynamically_initialized : 0;
59b36ecf
JJ
2427 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
2428 build_int_cst (uptr, has_dynamic_init));
21a82048
JJ
2429 tree locptr = NULL_TREE;
2430 location_t loc = DECL_SOURCE_LOCATION (decl);
2431 expanded_location xloc = expand_location (loc);
2432 if (xloc.file != NULL)
2433 {
2434 static int lasanloccnt = 0;
2435 char buf[25];
2436 ASM_GENERATE_INTERNAL_LABEL (buf, "LASANLOC", ++lasanloccnt);
2437 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
2438 ubsan_get_source_location_type ());
2439 TREE_STATIC (var) = 1;
2440 TREE_PUBLIC (var) = 0;
2441 DECL_ARTIFICIAL (var) = 1;
2442 DECL_IGNORED_P (var) = 1;
2443 pretty_printer filename_pp;
2444 pp_string (&filename_pp, xloc.file);
2445 tree str = asan_pp_string (&filename_pp);
2446 tree ctor = build_constructor_va (TREE_TYPE (var), 3,
2447 NULL_TREE, str, NULL_TREE,
2448 build_int_cst (unsigned_type_node,
2449 xloc.line), NULL_TREE,
2450 build_int_cst (unsigned_type_node,
2451 xloc.column));
2452 TREE_CONSTANT (ctor) = 1;
2453 TREE_STATIC (ctor) = 1;
2454 DECL_INITIAL (var) = ctor;
2455 varpool_node::finalize_decl (var);
2456 locptr = fold_convert (uptr, build_fold_addr_expr (var));
2457 }
2458 else
2459 locptr = build_int_cst (uptr, 0);
2460 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr);
84b0769e 2461 CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, odr_indicator_ptr);
8240018b
JJ
2462 init = build_constructor (type, vinner);
2463 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
2464}
2465
0e668eaf
JJ
2466/* Initialize sanitizer.def builtins if the FE hasn't initialized them. */
2467void
2468initialize_sanitizer_builtins (void)
2469{
2470 tree decl;
2471
2472 if (builtin_decl_implicit_p (BUILT_IN_ASAN_INIT))
2473 return;
2474
2475 tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE);
2476 tree BT_FN_VOID_PTR
2477 = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
59b36ecf
JJ
2478 tree BT_FN_VOID_CONST_PTR
2479 = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
b906f4ca
MP
2480 tree BT_FN_VOID_PTR_PTR
2481 = build_function_type_list (void_type_node, ptr_type_node,
2482 ptr_type_node, NULL_TREE);
de5a5fa1
MP
2483 tree BT_FN_VOID_PTR_PTR_PTR
2484 = build_function_type_list (void_type_node, ptr_type_node,
2485 ptr_type_node, ptr_type_node, NULL_TREE);
0e668eaf
JJ
2486 tree BT_FN_VOID_PTR_PTRMODE
2487 = build_function_type_list (void_type_node, ptr_type_node,
de5a5fa1 2488 pointer_sized_int_node, NULL_TREE);
c954bddd
JJ
2489 tree BT_FN_VOID_INT
2490 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
0bae64d5
MP
2491 tree BT_FN_SIZE_CONST_PTR_INT
2492 = build_function_type_list (size_type_node, const_ptr_type_node,
2493 integer_type_node, NULL_TREE);
c954bddd
JJ
2494 tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
2495 tree BT_FN_IX_CONST_VPTR_INT[5];
2496 tree BT_FN_IX_VPTR_IX_INT[5];
2497 tree BT_FN_VOID_VPTR_IX_INT[5];
2498 tree vptr
2499 = build_pointer_type (build_qualified_type (void_type_node,
2500 TYPE_QUAL_VOLATILE));
2501 tree cvptr
2502 = build_pointer_type (build_qualified_type (void_type_node,
2503 TYPE_QUAL_VOLATILE
2504 |TYPE_QUAL_CONST));
2505 tree boolt
2506 = lang_hooks.types.type_for_size (BOOL_TYPE_SIZE, 1);
2507 int i;
2508 for (i = 0; i < 5; i++)
2509 {
2510 tree ix = build_nonstandard_integer_type (BITS_PER_UNIT * (1 << i), 1);
2511 BT_FN_BOOL_VPTR_PTR_IX_INT_INT[i]
2512 = build_function_type_list (boolt, vptr, ptr_type_node, ix,
2513 integer_type_node, integer_type_node,
2514 NULL_TREE);
2515 BT_FN_IX_CONST_VPTR_INT[i]
2516 = build_function_type_list (ix, cvptr, integer_type_node, NULL_TREE);
2517 BT_FN_IX_VPTR_IX_INT[i]
2518 = build_function_type_list (ix, vptr, ix, integer_type_node,
2519 NULL_TREE);
2520 BT_FN_VOID_VPTR_IX_INT[i]
2521 = build_function_type_list (void_type_node, vptr, ix,
2522 integer_type_node, NULL_TREE);
2523 }
2524#define BT_FN_BOOL_VPTR_PTR_I1_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[0]
2525#define BT_FN_I1_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[0]
2526#define BT_FN_I1_VPTR_I1_INT BT_FN_IX_VPTR_IX_INT[0]
2527#define BT_FN_VOID_VPTR_I1_INT BT_FN_VOID_VPTR_IX_INT[0]
2528#define BT_FN_BOOL_VPTR_PTR_I2_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[1]
2529#define BT_FN_I2_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[1]
2530#define BT_FN_I2_VPTR_I2_INT BT_FN_IX_VPTR_IX_INT[1]
2531#define BT_FN_VOID_VPTR_I2_INT BT_FN_VOID_VPTR_IX_INT[1]
2532#define BT_FN_BOOL_VPTR_PTR_I4_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[2]
2533#define BT_FN_I4_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[2]
2534#define BT_FN_I4_VPTR_I4_INT BT_FN_IX_VPTR_IX_INT[2]
2535#define BT_FN_VOID_VPTR_I4_INT BT_FN_VOID_VPTR_IX_INT[2]
2536#define BT_FN_BOOL_VPTR_PTR_I8_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[3]
2537#define BT_FN_I8_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[3]
2538#define BT_FN_I8_VPTR_I8_INT BT_FN_IX_VPTR_IX_INT[3]
2539#define BT_FN_VOID_VPTR_I8_INT BT_FN_VOID_VPTR_IX_INT[3]
2540#define BT_FN_BOOL_VPTR_PTR_I16_INT_INT BT_FN_BOOL_VPTR_PTR_IX_INT_INT[4]
2541#define BT_FN_I16_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[4]
2542#define BT_FN_I16_VPTR_I16_INT BT_FN_IX_VPTR_IX_INT[4]
2543#define BT_FN_VOID_VPTR_I16_INT BT_FN_VOID_VPTR_IX_INT[4]
0e668eaf
JJ
2544#undef ATTR_NOTHROW_LEAF_LIST
2545#define ATTR_NOTHROW_LEAF_LIST ECF_NOTHROW | ECF_LEAF
bc77608b
JJ
2546#undef ATTR_TMPURE_NOTHROW_LEAF_LIST
2547#define ATTR_TMPURE_NOTHROW_LEAF_LIST ECF_TM_PURE | ATTR_NOTHROW_LEAF_LIST
0e668eaf
JJ
2548#undef ATTR_NORETURN_NOTHROW_LEAF_LIST
2549#define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
4088b790
MP
2550#undef ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
2551#define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST \
2552 ECF_CONST | ATTR_NORETURN_NOTHROW_LEAF_LIST
bc77608b
JJ
2553#undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
2554#define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
2555 ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
de5a5fa1
MP
2556#undef ATTR_COLD_NOTHROW_LEAF_LIST
2557#define ATTR_COLD_NOTHROW_LEAF_LIST \
2558 /* ECF_COLD missing */ ATTR_NOTHROW_LEAF_LIST
2559#undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
2560#define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
2561 /* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
4088b790
MP
2562#undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
2563#define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
2564 /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
0bae64d5
MP
2565#undef ATTR_PURE_NOTHROW_LEAF_LIST
2566#define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
8f91e6e0
JJ
2567#undef DEF_BUILTIN_STUB
2568#define DEF_BUILTIN_STUB(ENUM, NAME)
0e668eaf
JJ
2569#undef DEF_SANITIZER_BUILTIN
2570#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
a74560eb
MP
2571 do { \
2572 decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM, \
2573 BUILT_IN_NORMAL, NAME, NULL_TREE); \
2574 set_call_expr_flags (decl, ATTRS); \
2575 set_builtin_decl (ENUM, decl, true); \
2576 } while (0);
0e668eaf
JJ
2577
2578#include "sanitizer.def"
2579
0bae64d5
MP
2580 /* -fsanitize=object-size uses __builtin_object_size, but that might
2581 not be available for e.g. Fortran at this point. We use
2582 DEF_SANITIZER_BUILTIN here only as a convenience macro. */
2583 if ((flag_sanitize & SANITIZE_OBJECT_SIZE)
2584 && !builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
2585 DEF_SANITIZER_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size",
2586 BT_FN_SIZE_CONST_PTR_INT,
2587 ATTR_PURE_NOTHROW_LEAF_LIST)
2588
0e668eaf 2589#undef DEF_SANITIZER_BUILTIN
8f91e6e0 2590#undef DEF_BUILTIN_STUB
0e668eaf
JJ
2591}
2592
94fce891
JJ
2593/* Called via htab_traverse. Count number of emitted
2594 STRING_CSTs in the constant hash table. */
2595
2a22f99c
TS
2596int
2597count_string_csts (constant_descriptor_tree **slot,
2598 unsigned HOST_WIDE_INT *data)
94fce891 2599{
2a22f99c 2600 struct constant_descriptor_tree *desc = *slot;
94fce891
JJ
2601 if (TREE_CODE (desc->value) == STRING_CST
2602 && TREE_ASM_WRITTEN (desc->value)
2603 && asan_protect_global (desc->value))
2a22f99c 2604 ++*data;
94fce891
JJ
2605 return 1;
2606}
2607
2608/* Helper structure to pass two parameters to
2609 add_string_csts. */
2610
2611struct asan_add_string_csts_data
2612{
2613 tree type;
2614 vec<constructor_elt, va_gc> *v;
2615};
2616
2a22f99c 2617/* Called via hash_table::traverse. Call asan_add_global
94fce891
JJ
2618 on emitted STRING_CSTs from the constant hash table. */
2619
2a22f99c
TS
2620int
2621add_string_csts (constant_descriptor_tree **slot,
2622 asan_add_string_csts_data *aascd)
94fce891 2623{
2a22f99c 2624 struct constant_descriptor_tree *desc = *slot;
94fce891
JJ
2625 if (TREE_CODE (desc->value) == STRING_CST
2626 && TREE_ASM_WRITTEN (desc->value)
2627 && asan_protect_global (desc->value))
2628 {
94fce891
JJ
2629 asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)),
2630 aascd->type, aascd->v);
2631 }
2632 return 1;
2633}
2634
8240018b
JJ
2635/* Needs to be GTY(()), because cgraph_build_static_cdtor may
2636 invoke ggc_collect. */
2637static GTY(()) tree asan_ctor_statements;
2638
37d6f666 2639/* Module-level instrumentation.
ef1b3fda 2640 - Insert __asan_init_vN() into the list of CTORs.
37d6f666
WM
2641 - TODO: insert redzones around globals.
2642 */
2643
2644void
2645asan_finish_file (void)
2646{
2c8326a5 2647 varpool_node *vnode;
8240018b
JJ
2648 unsigned HOST_WIDE_INT gcount = 0;
2649
94fce891
JJ
2650 if (shadow_ptr_types[0] == NULL_TREE)
2651 asan_init_shadow_ptr_types ();
2652 /* Avoid instrumenting code in the asan ctors/dtors.
2653 We don't need to insert padding after the description strings,
2654 nor after .LASAN* array. */
de5a5fa1 2655 flag_sanitize &= ~SANITIZE_ADDRESS;
0e668eaf 2656
f1d15bb9
DV
2657 /* For user-space we want asan constructors to run first.
2658 Linux kernel does not support priorities other than default, and the only
2659 other user of constructors is coverage. So we run with the default
2660 priority. */
2661 int priority = flag_sanitize & SANITIZE_USER_ADDRESS
2662 ? MAX_RESERVED_INIT_PRIORITY - 1 : DEFAULT_INIT_PRIORITY;
2663
c6d129b0
YG
2664 if (flag_sanitize & SANITIZE_USER_ADDRESS)
2665 {
2666 tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
2667 append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
89e302b8
MO
2668 fn = builtin_decl_implicit (BUILT_IN_ASAN_VERSION_MISMATCH_CHECK);
2669 append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
c6d129b0 2670 }
8240018b 2671 FOR_EACH_DEFINED_VARIABLE (vnode)
67348ccc
DM
2672 if (TREE_ASM_WRITTEN (vnode->decl)
2673 && asan_protect_global (vnode->decl))
8240018b 2674 ++gcount;
2a22f99c
TS
2675 hash_table<tree_descriptor_hasher> *const_desc_htab = constant_pool_htab ();
2676 const_desc_htab->traverse<unsigned HOST_WIDE_INT *, count_string_csts>
2677 (&gcount);
8240018b
JJ
2678 if (gcount)
2679 {
0e668eaf 2680 tree type = asan_global_struct (), var, ctor;
8240018b 2681 tree dtor_statements = NULL_TREE;
9771b263 2682 vec<constructor_elt, va_gc> *v;
8240018b
JJ
2683 char buf[20];
2684
2685 type = build_array_type_nelts (type, gcount);
2686 ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", 0);
2687 var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf),
2688 type);
2689 TREE_STATIC (var) = 1;
2690 TREE_PUBLIC (var) = 0;
2691 DECL_ARTIFICIAL (var) = 1;
2692 DECL_IGNORED_P (var) = 1;
9771b263 2693 vec_alloc (v, gcount);
8240018b 2694 FOR_EACH_DEFINED_VARIABLE (vnode)
67348ccc
DM
2695 if (TREE_ASM_WRITTEN (vnode->decl)
2696 && asan_protect_global (vnode->decl))
2697 asan_add_global (vnode->decl, TREE_TYPE (type), v);
94fce891
JJ
2698 struct asan_add_string_csts_data aascd;
2699 aascd.type = TREE_TYPE (type);
2700 aascd.v = v;
2a22f99c
TS
2701 const_desc_htab->traverse<asan_add_string_csts_data *, add_string_csts>
2702 (&aascd);
8240018b
JJ
2703 ctor = build_constructor (type, v);
2704 TREE_CONSTANT (ctor) = 1;
2705 TREE_STATIC (ctor) = 1;
2706 DECL_INITIAL (var) = ctor;
9041d2e6 2707 varpool_node::finalize_decl (var);
8240018b 2708
c6d129b0 2709 tree fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
de5a5fa1 2710 tree gcount_tree = build_int_cst (pointer_sized_int_node, gcount);
0e668eaf 2711 append_to_statement_list (build_call_expr (fn, 2,
8240018b 2712 build_fold_addr_expr (var),
de5a5fa1 2713 gcount_tree),
8240018b
JJ
2714 &asan_ctor_statements);
2715
0e668eaf
JJ
2716 fn = builtin_decl_implicit (BUILT_IN_ASAN_UNREGISTER_GLOBALS);
2717 append_to_statement_list (build_call_expr (fn, 2,
8240018b 2718 build_fold_addr_expr (var),
de5a5fa1 2719 gcount_tree),
8240018b 2720 &dtor_statements);
f1d15bb9 2721 cgraph_build_static_cdtor ('D', dtor_statements, priority);
8240018b 2722 }
c6d129b0 2723 if (asan_ctor_statements)
f1d15bb9 2724 cgraph_build_static_cdtor ('I', asan_ctor_statements, priority);
de5a5fa1 2725 flag_sanitize |= SANITIZE_ADDRESS;
f6d98484
JJ
2726}
2727
6dc4a604
ML
2728/* Poison or unpoison (depending on IS_CLOBBER variable) shadow memory based
2729 on SHADOW address. Newly added statements will be added to ITER with
2730 given location LOC. We mark SIZE bytes in shadow memory, where
2731 LAST_CHUNK_SIZE is greater than zero in situation where we are at the
2732 end of a variable. */
2733
2734static void
2735asan_store_shadow_bytes (gimple_stmt_iterator *iter, location_t loc,
2736 tree shadow,
2737 unsigned HOST_WIDE_INT base_addr_offset,
2738 bool is_clobber, unsigned size,
2739 unsigned last_chunk_size)
2740{
2741 tree shadow_ptr_type;
2742
2743 switch (size)
2744 {
2745 case 1:
2746 shadow_ptr_type = shadow_ptr_types[0];
2747 break;
2748 case 2:
2749 shadow_ptr_type = shadow_ptr_types[1];
2750 break;
2751 case 4:
2752 shadow_ptr_type = shadow_ptr_types[2];
2753 break;
2754 default:
2755 gcc_unreachable ();
2756 }
2757
2758 unsigned char c = (char) is_clobber ? ASAN_STACK_MAGIC_USE_AFTER_SCOPE : 0;
2759 unsigned HOST_WIDE_INT val = 0;
47a11342
JJ
2760 unsigned last_pos = size;
2761 if (last_chunk_size && !is_clobber)
2762 last_pos = BYTES_BIG_ENDIAN ? 0 : size - 1;
6dc4a604
ML
2763 for (unsigned i = 0; i < size; ++i)
2764 {
2765 unsigned char shadow_c = c;
47a11342 2766 if (i == last_pos)
6dc4a604
ML
2767 shadow_c = last_chunk_size;
2768 val |= (unsigned HOST_WIDE_INT) shadow_c << (BITS_PER_UNIT * i);
2769 }
2770
2771 /* Handle last chunk in unpoisoning. */
2772 tree magic = build_int_cst (TREE_TYPE (shadow_ptr_type), val);
2773
2774 tree dest = build2 (MEM_REF, TREE_TYPE (shadow_ptr_type), shadow,
2775 build_int_cst (shadow_ptr_type, base_addr_offset));
2776
2777 gimple *g = gimple_build_assign (dest, magic);
2778 gimple_set_location (g, loc);
2779 gsi_insert_after (iter, g, GSI_NEW_STMT);
2780}
2781
2782/* Expand the ASAN_MARK builtins. */
2783
2784bool
2785asan_expand_mark_ifn (gimple_stmt_iterator *iter)
2786{
2787 gimple *g = gsi_stmt (*iter);
2788 location_t loc = gimple_location (g);
56b7aede
ML
2789 HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (g, 0));
2790 bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
6dc4a604
ML
2791
2792 tree base = gimple_call_arg (g, 1);
2793 gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
2794 tree decl = TREE_OPERAND (base, 0);
fb61d96c
ML
2795
2796 /* For a nested function, we can have: ASAN_MARK (2, &FRAME.2.fp_input, 4) */
2797 if (TREE_CODE (decl) == COMPONENT_REF
2798 && DECL_NONLOCAL_FRAME (TREE_OPERAND (decl, 0)))
2799 decl = TREE_OPERAND (decl, 0);
2800
6dc4a604 2801 gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
7b972538
ML
2802
2803 if (is_poison)
2804 {
2805 if (asan_handled_variables == NULL)
2806 asan_handled_variables = new hash_set<tree> (16);
2807 asan_handled_variables->add (decl);
2808 }
6dc4a604
ML
2809 tree len = gimple_call_arg (g, 2);
2810
2811 gcc_assert (tree_fits_shwi_p (len));
2812 unsigned HOST_WIDE_INT size_in_bytes = tree_to_shwi (len);
2813 gcc_assert (size_in_bytes);
2814
2815 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
2816 NOP_EXPR, base);
2817 gimple_set_location (g, loc);
2818 gsi_replace (iter, g, false);
2819 tree base_addr = gimple_assign_lhs (g);
2820
2821 /* Generate direct emission if size_in_bytes is small. */
2822 if (size_in_bytes <= ASAN_PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD)
2823 {
2824 unsigned HOST_WIDE_INT shadow_size = shadow_mem_size (size_in_bytes);
2825
2826 tree shadow = build_shadow_mem_access (iter, loc, base_addr,
2827 shadow_ptr_types[0], true);
2828
2829 for (unsigned HOST_WIDE_INT offset = 0; offset < shadow_size;)
2830 {
2831 unsigned size = 1;
2832 if (shadow_size - offset >= 4)
2833 size = 4;
2834 else if (shadow_size - offset >= 2)
2835 size = 2;
2836
2837 unsigned HOST_WIDE_INT last_chunk_size = 0;
2838 unsigned HOST_WIDE_INT s = (offset + size) * ASAN_SHADOW_GRANULARITY;
2839 if (s > size_in_bytes)
2840 last_chunk_size = ASAN_SHADOW_GRANULARITY - (s - size_in_bytes);
2841
56b7aede 2842 asan_store_shadow_bytes (iter, loc, shadow, offset, is_poison,
6dc4a604
ML
2843 size, last_chunk_size);
2844 offset += size;
2845 }
2846 }
2847 else
2848 {
2849 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
2850 NOP_EXPR, len);
2851 gimple_set_location (g, loc);
2852 gsi_insert_before (iter, g, GSI_SAME_STMT);
2853 tree sz_arg = gimple_assign_lhs (g);
2854
5594a028
ML
2855 tree fun
2856 = builtin_decl_implicit (is_poison ? BUILT_IN_ASAN_POISON_STACK_MEMORY
2857 : BUILT_IN_ASAN_UNPOISON_STACK_MEMORY);
6dc4a604
ML
2858 g = gimple_build_call (fun, 2, base_addr, sz_arg);
2859 gimple_set_location (g, loc);
2860 gsi_insert_after (iter, g, GSI_NEW_STMT);
2861 }
2862
2863 return false;
2864}
2865
c62ccb9a
YG
2866/* Expand the ASAN_{LOAD,STORE} builtins. */
2867
06cefae9 2868bool
c62ccb9a
YG
2869asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
2870{
355fe088 2871 gimple *g = gsi_stmt (*iter);
c62ccb9a 2872 location_t loc = gimple_location (g);
b59e2a49
MO
2873 bool recover_p;
2874 if (flag_sanitize & SANITIZE_USER_ADDRESS)
2875 recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
2876 else
2877 recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
fed4de37 2878
c62ccb9a
YG
2879 HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
2880 gcc_assert (flags < ASAN_CHECK_LAST);
2881 bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
2882 bool is_store = (flags & ASAN_CHECK_STORE) != 0;
2883 bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
c62ccb9a
YG
2884
2885 tree base = gimple_call_arg (g, 1);
2886 tree len = gimple_call_arg (g, 2);
f434eb69 2887 HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3));
c62ccb9a
YG
2888
2889 HOST_WIDE_INT size_in_bytes
2890 = is_scalar_access && tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
2891
2892 if (use_calls)
2893 {
2894 /* Instrument using callbacks. */
355fe088 2895 gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
0d0e4a03 2896 NOP_EXPR, base);
c62ccb9a
YG
2897 gimple_set_location (g, loc);
2898 gsi_insert_before (iter, g, GSI_SAME_STMT);
2899 tree base_addr = gimple_assign_lhs (g);
2900
2901 int nargs;
fed4de37 2902 tree fun = check_func (is_store, recover_p, size_in_bytes, &nargs);
c62ccb9a
YG
2903 if (nargs == 1)
2904 g = gimple_build_call (fun, 1, base_addr);
2905 else
2906 {
2907 gcc_assert (nargs == 2);
0d0e4a03
JJ
2908 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
2909 NOP_EXPR, len);
c62ccb9a
YG
2910 gimple_set_location (g, loc);
2911 gsi_insert_before (iter, g, GSI_SAME_STMT);
2912 tree sz_arg = gimple_assign_lhs (g);
2913 g = gimple_build_call (fun, nargs, base_addr, sz_arg);
2914 }
2915 gimple_set_location (g, loc);
2916 gsi_replace (iter, g, false);
2917 return false;
2918 }
2919
2920 HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
2921
c62ccb9a
YG
2922 tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
2923 tree shadow_type = TREE_TYPE (shadow_ptr_type);
2924
2925 gimple_stmt_iterator gsi = *iter;
2926
2927 if (!is_non_zero_len)
2928 {
2929 /* So, the length of the memory area to asan-protect is
2930 non-constant. Let's guard the generated instrumentation code
2931 like:
2932
2933 if (len != 0)
2934 {
2935 //asan instrumentation code goes here.
2936 }
2937 // falltrough instructions, starting with *ITER. */
2938
2939 g = gimple_build_cond (NE_EXPR,
2940 len,
2941 build_int_cst (TREE_TYPE (len), 0),
2942 NULL_TREE, NULL_TREE);
2943 gimple_set_location (g, loc);
2944
2945 basic_block then_bb, fallthrough_bb;
538dd0b7
DM
2946 insert_if_then_before_iter (as_a <gcond *> (g), iter,
2947 /*then_more_likely_p=*/true,
2948 &then_bb, &fallthrough_bb);
c62ccb9a
YG
2949 /* Note that fallthrough_bb starts with the statement that was
2950 pointed to by ITER. */
2951
2952 /* The 'then block' of the 'if (len != 0) condition is where
2953 we'll generate the asan instrumentation code now. */
2954 gsi = gsi_last_bb (then_bb);
2955 }
2956
2957 /* Get an iterator on the point where we can add the condition
2958 statement for the instrumentation. */
2959 basic_block then_bb, else_bb;
2960 gsi = create_cond_insert_point (&gsi, /*before_p*/false,
2961 /*then_more_likely_p=*/false,
fed4de37 2962 /*create_then_fallthru_edge*/recover_p,
c62ccb9a
YG
2963 &then_bb,
2964 &else_bb);
2965
0d0e4a03
JJ
2966 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
2967 NOP_EXPR, base);
c62ccb9a
YG
2968 gimple_set_location (g, loc);
2969 gsi_insert_before (&gsi, g, GSI_NEW_STMT);
2970 tree base_addr = gimple_assign_lhs (g);
2971
2972 tree t = NULL_TREE;
2973 if (real_size_in_bytes >= 8)
2974 {
2975 tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
2976 shadow_ptr_type);
2977 t = shadow;
2978 }
2979 else
2980 {
2981 /* Slow path for 1, 2 and 4 byte accesses. */
bdea98ca
MO
2982 /* Test (shadow != 0)
2983 & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow). */
2984 tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
2985 shadow_ptr_type);
355fe088 2986 gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
bdea98ca
MO
2987 gimple_seq seq = NULL;
2988 gimple_seq_add_stmt (&seq, shadow_test);
2989 /* Aligned (>= 8 bytes) can test just
2990 (real_size_in_bytes - 1 >= shadow), as base_addr & 7 is known
2991 to be 0. */
2992 if (align < 8)
c62ccb9a 2993 {
bdea98ca
MO
2994 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
2995 base_addr, 7));
2996 gimple_seq_add_stmt (&seq,
2997 build_type_cast (shadow_type,
2998 gimple_seq_last (seq)));
2999 if (real_size_in_bytes > 1)
3000 gimple_seq_add_stmt (&seq,
3001 build_assign (PLUS_EXPR,
3002 gimple_seq_last (seq),
3003 real_size_in_bytes - 1));
3004 t = gimple_assign_lhs (gimple_seq_last_stmt (seq));
c62ccb9a 3005 }
bdea98ca
MO
3006 else
3007 t = build_int_cst (shadow_type, real_size_in_bytes - 1);
3008 gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, t, shadow));
3009 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
3010 gimple_seq_last (seq)));
3011 t = gimple_assign_lhs (gimple_seq_last (seq));
3012 gimple_seq_set_location (seq, loc);
3013 gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
c62ccb9a
YG
3014
3015 /* For non-constant, misaligned or otherwise weird access sizes,
bdea98ca
MO
3016 check first and last byte. */
3017 if (size_in_bytes == -1)
c62ccb9a 3018 {
0d0e4a03
JJ
3019 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3020 MINUS_EXPR, len,
3021 build_int_cst (pointer_sized_int_node, 1));
c62ccb9a
YG
3022 gimple_set_location (g, loc);
3023 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3024 tree last = gimple_assign_lhs (g);
0d0e4a03
JJ
3025 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
3026 PLUS_EXPR, base_addr, last);
c62ccb9a
YG
3027 gimple_set_location (g, loc);
3028 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3029 tree base_end_addr = gimple_assign_lhs (g);
3030
3031 tree shadow = build_shadow_mem_access (&gsi, loc, base_end_addr,
3032 shadow_ptr_type);
355fe088 3033 gimple *shadow_test = build_assign (NE_EXPR, shadow, 0);
c62ccb9a
YG
3034 gimple_seq seq = NULL;
3035 gimple_seq_add_stmt (&seq, shadow_test);
3036 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
3037 base_end_addr, 7));
3038 gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
3039 gimple_seq_last (seq)));
3040 gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
3041 gimple_seq_last (seq),
3042 shadow));
3043 gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
3044 gimple_seq_last (seq)));
bdea98ca
MO
3045 gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
3046 gimple_seq_last (seq)));
c62ccb9a
YG
3047 t = gimple_assign_lhs (gimple_seq_last (seq));
3048 gimple_seq_set_location (seq, loc);
3049 gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
3050 }
3051 }
3052
3053 g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
3054 NULL_TREE, NULL_TREE);
3055 gimple_set_location (g, loc);
3056 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3057
3058 /* Generate call to the run-time library (e.g. __asan_report_load8). */
3059 gsi = gsi_start_bb (then_bb);
3060 int nargs;
fed4de37 3061 tree fun = report_error_func (is_store, recover_p, size_in_bytes, &nargs);
c62ccb9a
YG
3062 g = gimple_build_call (fun, nargs, base_addr, len);
3063 gimple_set_location (g, loc);
3064 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3065
3066 gsi_remove (iter, true);
3067 *iter = gsi_start_bb (else_bb);
3068
3069 return true;
3070}
3071
c7775327
ML
3072/* Create ASAN shadow variable for a VAR_DECL which has been rewritten
3073 into SSA. Already seen VAR_DECLs are stored in SHADOW_VARS_MAPPING. */
3074
3075static tree
3076create_asan_shadow_var (tree var_decl,
3077 hash_map<tree, tree> &shadow_vars_mapping)
3078{
3079 tree *slot = shadow_vars_mapping.get (var_decl);
3080 if (slot == NULL)
3081 {
3082 tree shadow_var = copy_node (var_decl);
3083
3084 copy_body_data id;
3085 memset (&id, 0, sizeof (copy_body_data));
3086 id.src_fn = id.dst_fn = current_function_decl;
3087 copy_decl_for_dup_finish (&id, var_decl, shadow_var);
3088
3089 DECL_ARTIFICIAL (shadow_var) = 1;
3090 DECL_IGNORED_P (shadow_var) = 1;
3091 DECL_SEEN_IN_BIND_EXPR_P (shadow_var) = 0;
3092 gimple_add_tmp_var (shadow_var);
3093
3094 shadow_vars_mapping.put (var_decl, shadow_var);
3095 return shadow_var;
3096 }
3097 else
3098 return *slot;
3099}
3100
f6b9f2ff
ML
3101/* Expand ASAN_POISON ifn. */
3102
c7775327
ML
3103bool
3104asan_expand_poison_ifn (gimple_stmt_iterator *iter,
3105 bool *need_commit_edge_insert,
3106 hash_map<tree, tree> &shadow_vars_mapping)
3107{
3108 gimple *g = gsi_stmt (*iter);
3109 tree poisoned_var = gimple_call_lhs (g);
a50a32aa 3110 if (!poisoned_var || has_zero_uses (poisoned_var))
c7775327
ML
3111 {
3112 gsi_remove (iter, true);
3113 return true;
3114 }
3115
a50a32aa
ML
3116 if (SSA_NAME_VAR (poisoned_var) == NULL_TREE)
3117 SET_SSA_NAME_VAR_OR_IDENTIFIER (poisoned_var,
3118 create_tmp_var (TREE_TYPE (poisoned_var)));
3119
f6b9f2ff
ML
3120 tree shadow_var = create_asan_shadow_var (SSA_NAME_VAR (poisoned_var),
3121 shadow_vars_mapping);
c7775327
ML
3122
3123 bool recover_p;
3124 if (flag_sanitize & SANITIZE_USER_ADDRESS)
3125 recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
3126 else
3127 recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
3128 tree size = DECL_SIZE_UNIT (shadow_var);
3129 gimple *poison_call
3130 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
3131 build_int_cst (integer_type_node,
3132 ASAN_MARK_POISON),
3133 build_fold_addr_expr (shadow_var), size);
3134
f6b9f2ff 3135 gimple *use;
c7775327 3136 imm_use_iterator imm_iter;
f6b9f2ff 3137 FOR_EACH_IMM_USE_STMT (use, imm_iter, poisoned_var)
c7775327 3138 {
c7775327
ML
3139 if (is_gimple_debug (use))
3140 continue;
3141
3142 int nargs;
f6b9f2ff
ML
3143 bool store_p = gimple_call_internal_p (use, IFN_ASAN_POISON_USE);
3144 tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size),
c7775327
ML
3145 &nargs);
3146
3147 gcall *call = gimple_build_call (fun, 1,
3148 build_fold_addr_expr (shadow_var));
3149 gimple_set_location (call, gimple_location (use));
3150 gimple *call_to_insert = call;
3151
3152 /* The USE can be a gimple PHI node. If so, insert the call on
3153 all edges leading to the PHI node. */
3154 if (is_a <gphi *> (use))
3155 {
3156 gphi *phi = dyn_cast<gphi *> (use);
3157 for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
3158 if (gimple_phi_arg_def (phi, i) == poisoned_var)
3159 {
3160 edge e = gimple_phi_arg_edge (phi, i);
3161
3162 if (call_to_insert == NULL)
3163 call_to_insert = gimple_copy (call);
3164
3165 gsi_insert_seq_on_edge (e, call_to_insert);
3166 *need_commit_edge_insert = true;
3167 call_to_insert = NULL;
3168 }
3169 }
3170 else
3171 {
3172 gimple_stmt_iterator gsi = gsi_for_stmt (use);
f6b9f2ff
ML
3173 if (store_p)
3174 gsi_replace (&gsi, call, true);
3175 else
3176 gsi_insert_before (&gsi, call, GSI_NEW_STMT);
c7775327
ML
3177 }
3178 }
3179
3180 SSA_NAME_IS_DEFAULT_DEF (poisoned_var) = true;
3181 SSA_NAME_DEF_STMT (poisoned_var) = gimple_build_nop ();
3182 gsi_replace (iter, poison_call, false);
3183
3184 return true;
3185}
3186
37d6f666
WM
3187/* Instrument the current function. */
3188
3189static unsigned int
3190asan_instrument (void)
3191{
f6d98484 3192 if (shadow_ptr_types[0] == NULL_TREE)
94fce891 3193 asan_init_shadow_ptr_types ();
37d6f666 3194 transform_statements ();
37d6f666
WM
3195 return 0;
3196}
3197
3198static bool
3199gate_asan (void)
3200{
45b2222a 3201 return sanitize_flags_p (SANITIZE_ADDRESS);
37d6f666
WM
3202}
3203
27a4cd48
DM
3204namespace {
3205
3206const pass_data pass_data_asan =
37d6f666 3207{
27a4cd48
DM
3208 GIMPLE_PASS, /* type */
3209 "asan", /* name */
3210 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
3211 TV_NONE, /* tv_id */
3212 ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
3213 0, /* properties_provided */
3214 0, /* properties_destroyed */
3215 0, /* todo_flags_start */
3bea341f 3216 TODO_update_ssa, /* todo_flags_finish */
37d6f666 3217};
f6d98484 3218
27a4cd48
DM
3219class pass_asan : public gimple_opt_pass
3220{
3221public:
c3284718
RS
3222 pass_asan (gcc::context *ctxt)
3223 : gimple_opt_pass (pass_data_asan, ctxt)
27a4cd48
DM
3224 {}
3225
3226 /* opt_pass methods: */
65d3284b 3227 opt_pass * clone () { return new pass_asan (m_ctxt); }
1a3d085c 3228 virtual bool gate (function *) { return gate_asan (); }
be55bfe6 3229 virtual unsigned int execute (function *) { return asan_instrument (); }
27a4cd48
DM
3230
3231}; // class pass_asan
3232
3233} // anon namespace
3234
3235gimple_opt_pass *
3236make_pass_asan (gcc::context *ctxt)
3237{
3238 return new pass_asan (ctxt);
3239}
3240
27a4cd48
DM
3241namespace {
3242
3243const pass_data pass_data_asan_O0 =
dfb9e332 3244{
27a4cd48
DM
3245 GIMPLE_PASS, /* type */
3246 "asan0", /* name */
3247 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
3248 TV_NONE, /* tv_id */
3249 ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
3250 0, /* properties_provided */
3251 0, /* properties_destroyed */
3252 0, /* todo_flags_start */
3bea341f 3253 TODO_update_ssa, /* todo_flags_finish */
dfb9e332
JJ
3254};
3255
27a4cd48
DM
3256class pass_asan_O0 : public gimple_opt_pass
3257{
3258public:
c3284718
RS
3259 pass_asan_O0 (gcc::context *ctxt)
3260 : gimple_opt_pass (pass_data_asan_O0, ctxt)
27a4cd48
DM
3261 {}
3262
3263 /* opt_pass methods: */
1a3d085c 3264 virtual bool gate (function *) { return !optimize && gate_asan (); }
be55bfe6 3265 virtual unsigned int execute (function *) { return asan_instrument (); }
27a4cd48
DM
3266
3267}; // class pass_asan_O0
3268
3269} // anon namespace
3270
3271gimple_opt_pass *
3272make_pass_asan_O0 (gcc::context *ctxt)
3273{
3274 return new pass_asan_O0 (ctxt);
3275}
3276
f6d98484 3277#include "gt-asan.h"