]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/asan.h
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / asan.h
CommitLineData
37d6f666 1/* AddressSanitizer, a fast memory error detector.
99dee823 2 Copyright (C) 2011-2021 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#ifndef TREE_ASAN
22#define TREE_ASAN
23
ef1b3fda 24extern void asan_function_start (void);
f3ddd692 25extern void asan_finish_file (void);
3a4abd2f
DM
26extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int,
27 HOST_WIDE_INT *, tree *, int);
e3174bdf 28extern rtx_insn *asan_emit_allocas_unpoison (rtx, rtx, rtx_insn *);
1069dc25 29extern bool asan_protect_global (tree, bool ignore_decl_rtl_set_p = false);
0e668eaf 30extern void initialize_sanitizer_builtins (void);
59b36ecf 31extern tree asan_dynamic_init_call (bool);
06cefae9 32extern bool asan_expand_check_ifn (gimple_stmt_iterator *, bool);
6dc4a604 33extern bool asan_expand_mark_ifn (gimple_stmt_iterator *);
c7775327
ML
34extern bool asan_expand_poison_ifn (gimple_stmt_iterator *, bool *,
35 hash_map<tree, tree> &);
f3ddd692 36
0854b584
MM
37extern void hwasan_record_frame_init ();
38extern void hwasan_record_stack_var (rtx, rtx, poly_int64, poly_int64);
39extern void hwasan_emit_prologue ();
40extern rtx_insn *hwasan_emit_untag_frame (rtx, rtx);
41extern rtx hwasan_get_frame_extent ();
42extern rtx hwasan_frame_base ();
43extern void hwasan_maybe_emit_frame_base_init (void);
44extern bool stack_vars_base_reg_p (rtx);
45extern uint8_t hwasan_current_frame_tag ();
46extern void hwasan_increment_frame_tag ();
47extern rtx hwasan_truncate_to_tag_size (rtx, rtx);
48extern void hwasan_finish_file (void);
49extern bool hwasan_sanitize_p (void);
50extern bool hwasan_sanitize_stack_p (void);
51extern bool hwasan_sanitize_allocas_p (void);
93a73251
MM
52extern bool hwasan_expand_check_ifn (gimple_stmt_iterator *, bool);
53extern bool hwasan_expand_mark_ifn (gimple_stmt_iterator *);
54extern bool gate_hwasan (void);
0854b584 55
ac0ff9f2
JJ
56extern gimple_stmt_iterator create_cond_insert_point
57 (gimple_stmt_iterator *, bool, bool, bool, basic_block *, basic_block *);
58
f3ddd692
JJ
59/* Alias set for accessing the shadow memory. */
60extern alias_set_type asan_shadow_set;
37d6f666 61
6dc4a604
ML
62/* Hash set of labels that are either used in a goto, or their address
63 has been taken. */
64extern hash_set <tree> *asan_used_labels;
65
dfe06d3e 66/* Shadow memory is found at
fd960af2 67 (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset (). */
dfe06d3e 68#define ASAN_SHADOW_SHIFT 3
6dc4a604 69#define ASAN_SHADOW_GRANULARITY (1UL << ASAN_SHADOW_SHIFT)
dfe06d3e 70
f3ddd692
JJ
71/* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
72 up to 2 * ASAN_RED_ZONE_SIZE - 1 bytes. */
73#define ASAN_RED_ZONE_SIZE 32
74
6e644a50
ML
75/* Stack variable use more compact red zones. The size includes also
76 size of variable itself. */
77
78#define ASAN_MIN_RED_ZONE_SIZE 16
79
f3ddd692
JJ
80/* Shadow memory values for stack protection. Left is below protected vars,
81 the first pointer in stack corresponding to that offset contains
82 ASAN_STACK_FRAME_MAGIC word, the second pointer to a string describing
83 the frame. Middle is for padding in between variables, right is
84 above the last protected variable and partial immediately after variables
85 up to ASAN_RED_ZONE_SIZE alignment. */
6dc4a604
ML
86#define ASAN_STACK_MAGIC_LEFT 0xf1
87#define ASAN_STACK_MAGIC_MIDDLE 0xf2
88#define ASAN_STACK_MAGIC_RIGHT 0xf3
6dc4a604
ML
89#define ASAN_STACK_MAGIC_USE_AFTER_RET 0xf5
90#define ASAN_STACK_MAGIC_USE_AFTER_SCOPE 0xf8
f3ddd692 91
e361382f
JJ
92#define ASAN_STACK_FRAME_MAGIC 0x41b58ab3
93#define ASAN_STACK_RETIRED_MAGIC 0x45e0360e
f3ddd692 94
f6b9f2ff
ML
95#define ASAN_USE_AFTER_SCOPE_ATTRIBUTE "use after scope memory"
96
0854b584
MM
97/* NOTE: The values below and the hooks under targetm.memtag define an ABI and
98 are hard-coded to these values in libhwasan, hence they can't be changed
99 independently here. */
100/* How many bits are used to store a tag in a pointer.
101 The default version uses the entire top byte of a pointer (i.e. 8 bits). */
102#define HWASAN_TAG_SIZE targetm.memtag.tag_size ()
103/* Tag Granule of HWASAN shadow stack.
104 This is the size in real memory that each byte in the shadow memory refers
105 to. I.e. if a variable is X bytes long in memory then its tag in shadow
106 memory will span X / HWASAN_TAG_GRANULE_SIZE bytes.
107 Most variables will need to be aligned to this amount since two variables
108 that are neighbors in memory and share a tag granule would need to share the
109 same tag (the shared tag granule can only store one tag). */
110#define HWASAN_TAG_GRANULE_SIZE targetm.memtag.granule_size ()
111/* Define the tag for the stack background.
112 This defines what tag the stack pointer will be and hence what tag all
113 variables that are not given special tags are (e.g. spilled registers,
114 and parameters passed on the stack). */
115#define HWASAN_STACK_BACKGROUND gen_int_mode (0, QImode)
116
6dc4a604
ML
117/* Various flags for Asan builtins. */
118enum asan_check_flags
f3ddd692 119{
6dc4a604
ML
120 ASAN_CHECK_STORE = 1 << 0,
121 ASAN_CHECK_SCALAR_ACCESS = 1 << 1,
122 ASAN_CHECK_NON_ZERO_LEN = 1 << 2,
123 ASAN_CHECK_LAST = 1 << 3
124};
125
126/* Flags for Asan check builtins. */
56b7aede
ML
127#define IFN_ASAN_MARK_FLAGS DEF(POISON), DEF(UNPOISON)
128
6dc4a604
ML
129enum asan_mark_flags
130{
56b7aede
ML
131#define DEF(X) ASAN_MARK_##X
132 IFN_ASAN_MARK_FLAGS
133#undef DEF
6dc4a604 134};
f3ddd692 135
56b7aede
ML
136/* Return true if STMT is ASAN_MARK with FLAG as first argument. */
137extern bool asan_mark_p (gimple *stmt, enum asan_mark_flags flag);
138
8240018b
JJ
139/* Return the size of padding needed to insert after a protected
140 decl of SIZE. */
141
142static inline unsigned int
143asan_red_zone_size (unsigned int size)
144{
145 unsigned int c = size & (ASAN_RED_ZONE_SIZE - 1);
146 return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
147}
148
6e644a50
ML
149/* Return how much a stack variable occupis on a stack
150 including a space for red zone. */
151
152static inline unsigned HOST_WIDE_INT
153asan_var_and_redzone_size (unsigned HOST_WIDE_INT size)
154{
155 if (size <= 4)
156 return 16;
157 else if (size <= 16)
158 return 32;
159 else if (size <= 128)
160 return size + 32;
161 else if (size <= 512)
162 return size + 64;
163 else if (size <= 4096)
164 return size + 128;
165 else
166 return size + 256;
167}
168
fd960af2
YG
169extern bool set_asan_shadow_offset (const char *);
170
2ca1b6d0
KC
171extern bool asan_shadow_offset_set_p ();
172
18af8d16
YG
173extern void set_sanitized_sections (const char *);
174
6dc4a604
ML
175extern bool asan_sanitize_stack_p (void);
176
5094f7d5
MO
177extern bool asan_sanitize_allocas_p (void);
178
bf9f9292
ML
179extern hash_set<tree> *asan_handled_variables;
180
bdea98ca
MO
181/* Return TRUE if builtin with given FCODE will be intercepted by
182 libasan. */
183
184static inline bool
185asan_intercepted_p (enum built_in_function fcode)
186{
93a73251
MM
187 if (hwasan_sanitize_p ())
188 return false;
189
bdea98ca
MO
190 return fcode == BUILT_IN_INDEX
191 || fcode == BUILT_IN_MEMCHR
192 || fcode == BUILT_IN_MEMCMP
193 || fcode == BUILT_IN_MEMCPY
194 || fcode == BUILT_IN_MEMMOVE
195 || fcode == BUILT_IN_MEMSET
196 || fcode == BUILT_IN_STRCASECMP
197 || fcode == BUILT_IN_STRCAT
198 || fcode == BUILT_IN_STRCHR
199 || fcode == BUILT_IN_STRCMP
200 || fcode == BUILT_IN_STRCPY
201 || fcode == BUILT_IN_STRDUP
202 || fcode == BUILT_IN_STRLEN
203 || fcode == BUILT_IN_STRNCASECMP
204 || fcode == BUILT_IN_STRNCAT
205 || fcode == BUILT_IN_STRNCMP
0290a292
MO
206 || fcode == BUILT_IN_STRCSPN
207 || fcode == BUILT_IN_STRPBRK
208 || fcode == BUILT_IN_STRSPN
209 || fcode == BUILT_IN_STRSTR
bdea98ca
MO
210 || fcode == BUILT_IN_STRNCPY;
211}
6dc4a604
ML
212
213/* Return TRUE if we should instrument for use-after-scope sanity checking. */
214
215static inline bool
216asan_sanitize_use_after_scope (void)
217{
93a73251
MM
218 return (flag_sanitize_address_use_after_scope
219 && (asan_sanitize_stack_p () || hwasan_sanitize_stack_p ()));
6dc4a604
ML
220}
221
6dc4a604
ML
222/* Return true if DECL should be guarded on the stack. */
223
224static inline bool
225asan_protect_stack_decl (tree decl)
226{
227 return DECL_P (decl)
228 && (!DECL_ARTIFICIAL (decl)
229 || (asan_sanitize_use_after_scope () && TREE_ADDRESSABLE (decl)));
230}
231
45b2222a
ML
232/* Return true when flag_sanitize & FLAG is non-zero. If FN is non-null,
233 remove all flags mentioned in "no_sanitize" of DECL_ATTRIBUTES. */
234
235static inline bool
236sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl)
237{
238 unsigned int result_flags = flag_sanitize & flag;
239 if (result_flags == 0)
240 return false;
241
242 if (fn != NULL_TREE)
243 {
244 tree value = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (fn));
245 if (value)
246 result_flags &= ~tree_to_uhwi (TREE_VALUE (value));
247 }
248
249 return result_flags;
250}
251
cec4d4a6
ML
252/* Return true when coverage sanitization should happend for FN function. */
253
254static inline bool
255sanitize_coverage_p (const_tree fn = current_function_decl)
256{
257 return (flag_sanitize_coverage
90ac6edc
ML
258 && (fn == NULL_TREE
259 || lookup_attribute ("no_sanitize_coverage",
260 DECL_ATTRIBUTES (fn)) == NULL_TREE));
cec4d4a6
ML
261}
262
37d6f666 263#endif /* TREE_ASAN */