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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of gcc/asan.h