Logan Chien | df4f766 | 2019-09-04 16:45:23 -0700 | [diff] [blame] | 1 | //===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file is a part of AddressSanitizer (ASan). |
| 10 | // |
| 11 | // Public interface header. |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | #ifndef SANITIZER_ASAN_INTERFACE_H |
| 14 | #define SANITIZER_ASAN_INTERFACE_H |
| 15 | |
| 16 | #include <sanitizer/common_interface_defs.h> |
| 17 | |
| 18 | #ifdef __cplusplus |
| 19 | extern "C" { |
| 20 | #endif |
| 21 | /// Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable. |
| 22 | /// |
| 23 | /// This memory must be previously allocated by your program. Instrumented |
| 24 | /// code is forbidden from accessing addresses in this region until it is |
| 25 | /// unpoisoned. This function is not guaranteed to poison the entire region - |
| 26 | /// it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan |
| 27 | /// alignment restrictions. |
| 28 | /// |
| 29 | /// \note This function is not thread-safe because no two threads can poison or |
| 30 | /// unpoison memory in the same memory region simultaneously. |
| 31 | /// |
| 32 | /// \param addr Start of memory region. |
| 33 | /// \param size Size of memory region. |
| 34 | void __asan_poison_memory_region(void const volatile *addr, size_t size); |
| 35 | |
| 36 | /// Marks a memory region (<c>[addr, addr+size)</c>) as addressable. |
| 37 | /// |
| 38 | /// This memory must be previously allocated by your program. Accessing |
| 39 | /// addresses in this region is allowed until this region is poisoned again. |
| 40 | /// This function could unpoison a super-region of <c>[addr, addr+size)</c> due |
| 41 | /// to ASan alignment restrictions. |
| 42 | /// |
| 43 | /// \note This function is not thread-safe because no two threads can |
| 44 | /// poison or unpoison memory in the same memory region simultaneously. |
| 45 | /// |
| 46 | /// \param addr Start of memory region. |
| 47 | /// \param size Size of memory region. |
| 48 | void __asan_unpoison_memory_region(void const volatile *addr, size_t size); |
| 49 | |
| 50 | // Macros provided for convenience. |
| 51 | #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) |
| 52 | /// Marks a memory region as unaddressable. |
| 53 | /// |
| 54 | /// \note Macro provided for convenience; defined as a no-op if ASan is not |
| 55 | /// enabled. |
| 56 | /// |
| 57 | /// \param addr Start of memory region. |
| 58 | /// \param size Size of memory region. |
| 59 | #define ASAN_POISON_MEMORY_REGION(addr, size) \ |
| 60 | __asan_poison_memory_region((addr), (size)) |
| 61 | |
| 62 | /// Marks a memory region as addressable. |
| 63 | /// |
| 64 | /// \note Macro provided for convenience; defined as a no-op if ASan is not |
| 65 | /// enabled. |
| 66 | /// |
| 67 | /// \param addr Start of memory region. |
| 68 | /// \param size Size of memory region. |
| 69 | #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ |
| 70 | __asan_unpoison_memory_region((addr), (size)) |
| 71 | #else |
| 72 | #define ASAN_POISON_MEMORY_REGION(addr, size) \ |
| 73 | ((void)(addr), (void)(size)) |
| 74 | #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ |
| 75 | ((void)(addr), (void)(size)) |
| 76 | #endif |
| 77 | |
| 78 | /// Checks if an address is poisoned. |
| 79 | /// |
| 80 | /// Returns 1 if <c><i>addr</i></c> is poisoned (that is, 1-byte read/write |
| 81 | /// access to this address would result in an error report from ASan). |
| 82 | /// Otherwise returns 0. |
| 83 | /// |
| 84 | /// \param addr Address to check. |
| 85 | /// |
| 86 | /// \retval 1 Address is poisoned. |
| 87 | /// \retval 0 Address is not poisoned. |
| 88 | int __asan_address_is_poisoned(void const volatile *addr); |
| 89 | |
| 90 | /// Checks if a region is poisoned. |
| 91 | /// |
| 92 | /// If at least one byte in <c>[beg, beg+size)</c> is poisoned, returns the |
| 93 | /// address of the first such byte. Otherwise returns 0. |
| 94 | /// |
| 95 | /// \param beg Start of memory region. |
| 96 | /// \param size Start of memory region. |
| 97 | /// \returns Address of first poisoned byte. |
| 98 | void *__asan_region_is_poisoned(void *beg, size_t size); |
| 99 | |
| 100 | /// Describes an address (useful for calling from the debugger). |
| 101 | /// |
| 102 | /// Prints the description of <c><i>addr</i></c>. |
| 103 | /// |
| 104 | /// \param addr Address to describe. |
| 105 | void __asan_describe_address(void *addr); |
| 106 | |
| 107 | /// Checks if an error has been or is being reported (useful for calling from |
| 108 | /// the debugger to get information about an ASan error). |
| 109 | /// |
| 110 | /// Returns 1 if an error has been (or is being) reported. Otherwise returns 0. |
| 111 | /// |
| 112 | /// \returns 1 if an error has been (or is being) reported. Otherwise returns |
| 113 | /// 0. |
| 114 | int __asan_report_present(void); |
| 115 | |
| 116 | /// Gets the PC (program counter) register value of an ASan error (useful for |
| 117 | /// calling from the debugger). |
| 118 | /// |
| 119 | /// Returns PC if an error has been (or is being) reported. |
| 120 | /// Otherwise returns 0. |
| 121 | /// |
| 122 | /// \returns PC value. |
| 123 | void *__asan_get_report_pc(void); |
| 124 | |
| 125 | /// Gets the BP (base pointer) register value of an ASan error (useful for |
| 126 | /// calling from the debugger). |
| 127 | /// |
| 128 | /// Returns BP if an error has been (or is being) reported. |
| 129 | /// Otherwise returns 0. |
| 130 | /// |
| 131 | /// \returns BP value. |
| 132 | void *__asan_get_report_bp(void); |
| 133 | |
| 134 | /// Gets the SP (stack pointer) register value of an ASan error (useful for |
| 135 | /// calling from the debugger). |
| 136 | /// |
| 137 | /// If an error has been (or is being) reported, returns SP. |
| 138 | /// Otherwise returns 0. |
| 139 | /// |
| 140 | /// \returns SP value. |
| 141 | void *__asan_get_report_sp(void); |
| 142 | |
| 143 | /// Gets the address of the report buffer of an ASan error (useful for calling |
| 144 | /// from the debugger). |
| 145 | /// |
| 146 | /// Returns the address of the report buffer if an error has been (or is being) |
| 147 | /// reported. Otherwise returns 0. |
| 148 | /// |
| 149 | /// \returns Address of report buffer. |
| 150 | void *__asan_get_report_address(void); |
| 151 | |
| 152 | /// Gets access type of an ASan error (useful for calling from the debugger). |
| 153 | /// |
| 154 | /// Returns access type (read or write) if an error has been (or is being) |
| 155 | /// reported. Otherwise returns 0. |
| 156 | /// |
| 157 | /// \returns Access type (0 = read, 1 = write). |
| 158 | int __asan_get_report_access_type(void); |
| 159 | |
| 160 | /// Gets access size of an ASan error (useful for calling from the debugger). |
| 161 | /// |
| 162 | /// Returns access size if an error has been (or is being) reported. Otherwise |
| 163 | /// returns 0. |
| 164 | /// |
| 165 | /// \returns Access size in bytes. |
| 166 | size_t __asan_get_report_access_size(void); |
| 167 | |
| 168 | /// Gets the bug description of an ASan error (useful for calling from a |
| 169 | /// debugger). |
| 170 | /// |
| 171 | /// \returns Returns a bug description if an error has been (or is being) |
| 172 | /// reported - for example, "heap-use-after-free". Otherwise returns an empty |
| 173 | /// string. |
| 174 | const char *__asan_get_report_description(void); |
| 175 | |
| 176 | /// Gets information about a pointer (useful for calling from the debugger). |
| 177 | /// |
| 178 | /// Returns the category of the given pointer as a constant string. |
| 179 | /// Possible return values are <c>global</c>, <c>stack</c>, <c>stack-fake</c>, |
| 180 | /// <c>heap</c>, <c>heap-invalid</c>, <c>shadow-low</c>, <c>shadow-gap</c>, |
| 181 | /// <c>shadow-high</c>, and <c>unknown</c>. |
| 182 | /// |
| 183 | /// If the return value is <c>global</c> or <c>stack</c>, tries to also return |
| 184 | /// the variable name, address, and size. If the return value is <c>heap</c>, |
| 185 | /// tries to return the chunk address and size. <c><i>name</i></c> should point |
| 186 | /// to an allocated buffer of size <c><i>name_size</i></c>. |
| 187 | /// |
| 188 | /// \param addr Address to locate. |
| 189 | /// \param name Buffer to store the variable's name. |
| 190 | /// \param name_size Size in bytes of the variable's name buffer. |
Sasha Smundak | 4b1f33a | 2021-01-11 15:05:07 -0800 | [diff] [blame] | 191 | /// \param[out] region_address Address of the region. |
| 192 | /// \param[out] region_size Size of the region in bytes. |
Logan Chien | df4f766 | 2019-09-04 16:45:23 -0700 | [diff] [blame] | 193 | /// |
| 194 | /// \returns Returns the category of the given pointer as a constant string. |
| 195 | const char *__asan_locate_address(void *addr, char *name, size_t name_size, |
| 196 | void **region_address, size_t *region_size); |
| 197 | |
| 198 | /// Gets the allocation stack trace and thread ID for a heap address (useful |
| 199 | /// for calling from the debugger). |
| 200 | /// |
| 201 | /// Stores up to <c><i>size</i></c> frames in <c><i>trace</i></c>. Returns |
| 202 | /// the number of stored frames or 0 on error. |
| 203 | /// |
| 204 | /// \param addr A heap address. |
| 205 | /// \param trace A buffer to store the stack trace. |
| 206 | /// \param size Size in bytes of the trace buffer. |
Sasha Smundak | 4b1f33a | 2021-01-11 15:05:07 -0800 | [diff] [blame] | 207 | /// \param[out] thread_id The thread ID of the address. |
Logan Chien | df4f766 | 2019-09-04 16:45:23 -0700 | [diff] [blame] | 208 | /// |
| 209 | /// \returns Returns the number of stored frames or 0 on error. |
| 210 | size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size, |
| 211 | int *thread_id); |
| 212 | |
| 213 | /// Gets the free stack trace and thread ID for a heap address (useful for |
| 214 | /// calling from the debugger). |
| 215 | /// |
| 216 | /// Stores up to <c><i>size</i></c> frames in <c><i>trace</i></c>. Returns |
| 217 | /// the number of stored frames or 0 on error. |
| 218 | /// |
| 219 | /// \param addr A heap address. |
| 220 | /// \param trace A buffer to store the stack trace. |
| 221 | /// \param size Size in bytes of the trace buffer. |
Sasha Smundak | 4b1f33a | 2021-01-11 15:05:07 -0800 | [diff] [blame] | 222 | /// \param[out] thread_id The thread ID of the address. |
Logan Chien | df4f766 | 2019-09-04 16:45:23 -0700 | [diff] [blame] | 223 | /// |
| 224 | /// \returns Returns the number of stored frames or 0 on error. |
| 225 | size_t __asan_get_free_stack(void *addr, void **trace, size_t size, |
| 226 | int *thread_id); |
| 227 | |
| 228 | /// Gets the current shadow memory mapping (useful for calling from the |
| 229 | /// debugger). |
| 230 | /// |
Sasha Smundak | 4b1f33a | 2021-01-11 15:05:07 -0800 | [diff] [blame] | 231 | /// \param[out] shadow_scale Shadow scale value. |
| 232 | /// \param[out] shadow_offset Offset value. |
Logan Chien | df4f766 | 2019-09-04 16:45:23 -0700 | [diff] [blame] | 233 | void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset); |
| 234 | |
| 235 | /// This is an internal function that is called to report an error. However, |
| 236 | /// it is still a part of the interface because you might want to set a |
| 237 | /// breakpoint on this function in the debugger. |
| 238 | /// |
| 239 | /// \param pc <c><i>pc</i></c> value of the ASan error. |
| 240 | /// \param bp <c><i>bp</i></c> value of the ASan error. |
| 241 | /// \param sp <c><i>sp</i></c> value of the ASan error. |
| 242 | /// \param addr Address of the ASan error. |
| 243 | /// \param is_write True if the error is a write error; false otherwise. |
| 244 | /// \param access_size Size of the memory access of the ASan error. |
| 245 | void __asan_report_error(void *pc, void *bp, void *sp, |
| 246 | void *addr, int is_write, size_t access_size); |
| 247 | |
| 248 | // Deprecated. Call __sanitizer_set_death_callback instead. |
| 249 | void __asan_set_death_callback(void (*callback)(void)); |
| 250 | |
| 251 | /// Sets the callback function to be called during ASan error reporting. |
| 252 | /// |
| 253 | /// The callback provides a string pointer to the report. |
| 254 | /// |
| 255 | /// \param callback User-provided function. |
| 256 | void __asan_set_error_report_callback(void (*callback)(const char *)); |
| 257 | |
| 258 | /// User-provided callback on ASan errors. |
| 259 | /// |
| 260 | /// You can provide a function that would be called immediately when ASan |
| 261 | /// detects an error. This is useful in cases when ASan detects an error but |
| 262 | /// your program crashes before the ASan report is printed. |
| 263 | void __asan_on_error(void); |
| 264 | |
| 265 | /// Prints accumulated statistics to <c>stderr</c> (useful for calling from the |
| 266 | /// debugger). |
| 267 | void __asan_print_accumulated_stats(void); |
| 268 | |
| 269 | /// User-provided default option settings. |
| 270 | /// |
| 271 | /// You can provide your own implementation of this function to return a string |
| 272 | /// containing ASan runtime options (for example, |
| 273 | /// <c>verbosity=1:halt_on_error=0</c>). |
| 274 | /// |
| 275 | /// \returns Default options string. |
| 276 | const char* __asan_default_options(void); |
| 277 | |
| 278 | // The following two functions facilitate garbage collection in presence of |
| 279 | // ASan's fake stack. |
| 280 | |
| 281 | /// Gets an opaque handler to the current thread's fake stack. |
| 282 | /// |
| 283 | /// Returns an opaque handler to be used by |
| 284 | /// <c>__asan_addr_is_in_fake_stack()</c>. Returns NULL if the current thread |
| 285 | /// does not have a fake stack. |
| 286 | /// |
| 287 | /// \returns An opaque handler to the fake stack or NULL. |
| 288 | void *__asan_get_current_fake_stack(void); |
| 289 | |
| 290 | /// Checks if an address belongs to a given fake stack. |
| 291 | /// |
| 292 | /// If <c><i>fake_stack</i></c> is non-NULL and <c><i>addr</i></c> belongs to a |
| 293 | /// fake frame in <c><i>fake_stack</i></c>, returns the address of the real |
| 294 | /// stack that corresponds to the fake frame and sets <c><i>beg</i></c> and |
| 295 | /// <c><i>end</i></c> to the boundaries of this fake frame. Otherwise returns |
| 296 | /// NULL and does not touch <c><i>beg</i></c> and <c><i>end</i></c>. |
| 297 | /// |
| 298 | /// If <c><i>beg</i></c> or <c><i>end</i></c> are NULL, they are not touched. |
| 299 | /// |
| 300 | /// \note This function can be called from a thread other than the owner of |
| 301 | /// <c><i>fake_stack</i></c>, but the owner thread needs to be alive. |
| 302 | /// |
| 303 | /// \param fake_stack An opaque handler to a fake stack. |
| 304 | /// \param addr Address to test. |
Sasha Smundak | 4b1f33a | 2021-01-11 15:05:07 -0800 | [diff] [blame] | 305 | /// \param[out] beg Beginning of fake frame. |
| 306 | /// \param[out] end End of fake frame. |
Logan Chien | df4f766 | 2019-09-04 16:45:23 -0700 | [diff] [blame] | 307 | /// \returns Stack address or NULL. |
| 308 | void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg, |
| 309 | void **end); |
| 310 | |
| 311 | /// Performs shadow memory cleanup of the current thread's stack before a |
| 312 | /// function marked with the <c>[[noreturn]]</c> attribute is called. |
| 313 | /// |
| 314 | /// To avoid false positives on the stack, must be called before no-return |
| 315 | /// functions like <c>_exit()</c> and <c>execl()</c>. |
| 316 | void __asan_handle_no_return(void); |
| 317 | |
Sasha Smundak | 746b022 | 2020-02-25 09:19:04 -0800 | [diff] [blame] | 318 | /// Update allocation stack trace for the given allocation to the current stack |
Pirama Arumuga Nainar | ec8c89d | 2022-02-23 09:26:16 -0800 | [diff] [blame] | 319 | /// trace. Returns 1 if successful, 0 if not. |
Sasha Smundak | 746b022 | 2020-02-25 09:19:04 -0800 | [diff] [blame] | 320 | int __asan_update_allocation_context(void* addr); |
| 321 | |
Logan Chien | df4f766 | 2019-09-04 16:45:23 -0700 | [diff] [blame] | 322 | #ifdef __cplusplus |
| 323 | } // extern "C" |
| 324 | #endif |
| 325 | |
| 326 | #endif // SANITIZER_ASAN_INTERFACE_H |