xref: /freebsd/contrib/llvm-project/compiler-rt/lib/asan/asan_internal.h (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric //===-- asan_internal.h -----------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is a part of AddressSanitizer, an address sanity checker.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // ASan-private header which defines various general utilities.
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric #ifndef ASAN_INTERNAL_H
140b57cec5SDimitry Andric #define ASAN_INTERNAL_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "asan_flags.h"
170b57cec5SDimitry Andric #include "asan_interface_internal.h"
180b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_common.h"
190b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_internal_defs.h"
200b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_libc.h"
21*81ad6265SDimitry Andric #include "sanitizer_common/sanitizer_stacktrace.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
24*81ad6265SDimitry Andric #  error \
25*81ad6265SDimitry Andric       "The AddressSanitizer run-time should not be instrumented by AddressSanitizer"
260b57cec5SDimitry Andric #endif
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric // Build-time configuration options.
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric // If set, asan will intercept C++ exception api call(s).
310b57cec5SDimitry Andric #ifndef ASAN_HAS_EXCEPTIONS
320b57cec5SDimitry Andric #  define ASAN_HAS_EXCEPTIONS 1
330b57cec5SDimitry Andric #endif
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric // If set, values like allocator chunk size, as well as defaults for some flags
360b57cec5SDimitry Andric // will be changed towards less memory overhead.
370b57cec5SDimitry Andric #ifndef ASAN_LOW_MEMORY
38fe6060f1SDimitry Andric #  if SANITIZER_IOS || SANITIZER_ANDROID
390b57cec5SDimitry Andric #    define ASAN_LOW_MEMORY 1
400b57cec5SDimitry Andric #  else
410b57cec5SDimitry Andric #    define ASAN_LOW_MEMORY 0
420b57cec5SDimitry Andric #  endif
430b57cec5SDimitry Andric #endif
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric #ifndef ASAN_DYNAMIC
460b57cec5SDimitry Andric #  ifdef PIC
470b57cec5SDimitry Andric #    define ASAN_DYNAMIC 1
480b57cec5SDimitry Andric #  else
490b57cec5SDimitry Andric #    define ASAN_DYNAMIC 0
500b57cec5SDimitry Andric #  endif
510b57cec5SDimitry Andric #endif
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric // All internal functions in asan reside inside the __asan namespace
540b57cec5SDimitry Andric // to avoid namespace collisions with the user programs.
550b57cec5SDimitry Andric // Separate namespace also makes it simpler to distinguish the asan run-time
560b57cec5SDimitry Andric // functions from the instrumented user code in a profile.
570b57cec5SDimitry Andric namespace __asan {
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric class AsanThread;
600b57cec5SDimitry Andric using __sanitizer::StackTrace;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric void AsanInitFromRtl();
630b57cec5SDimitry Andric 
6468d75effSDimitry Andric // asan_win.cpp
650b57cec5SDimitry Andric void InitializePlatformExceptionHandlers();
660b57cec5SDimitry Andric // Returns whether an address is a valid allocated system heap block.
670b57cec5SDimitry Andric // 'addr' must point to the beginning of the block.
680b57cec5SDimitry Andric bool IsSystemHeapAddress(uptr addr);
690b57cec5SDimitry Andric 
7068d75effSDimitry Andric // asan_rtl.cpp
710b57cec5SDimitry Andric void PrintAddressSpaceLayout();
720b57cec5SDimitry Andric void NORETURN ShowStatsAndAbort();
730b57cec5SDimitry Andric 
7468d75effSDimitry Andric // asan_shadow_setup.cpp
750b57cec5SDimitry Andric void InitializeShadowMemory();
760b57cec5SDimitry Andric 
7768d75effSDimitry Andric // asan_malloc_linux.cpp / asan_malloc_mac.cpp
780b57cec5SDimitry Andric void ReplaceSystemMalloc();
790b57cec5SDimitry Andric 
80fe6060f1SDimitry Andric // asan_linux.cpp / asan_mac.cpp / asan_win.cpp
810b57cec5SDimitry Andric uptr FindDynamicShadowStart();
820b57cec5SDimitry Andric void *AsanDoesNotSupportStaticLinkage();
830b57cec5SDimitry Andric void AsanCheckDynamicRTPrereqs();
840b57cec5SDimitry Andric void AsanCheckIncompatibleRT();
850b57cec5SDimitry Andric 
865ffd83dbSDimitry Andric // Unpoisons platform-specific stacks.
875ffd83dbSDimitry Andric // Returns true if all stacks have been unpoisoned.
885ffd83dbSDimitry Andric bool PlatformUnpoisonStacks();
895ffd83dbSDimitry Andric 
905ffd83dbSDimitry Andric // asan_rtl.cpp
915ffd83dbSDimitry Andric // Unpoison a region containing a stack.
925ffd83dbSDimitry Andric // Performs a sanity check and warns if the bounds don't look right.
935ffd83dbSDimitry Andric // The warning contains the type string to identify the stack type.
945ffd83dbSDimitry Andric void UnpoisonStack(uptr bottom, uptr top, const char *type);
955ffd83dbSDimitry Andric 
9668d75effSDimitry Andric // asan_thread.cpp
970b57cec5SDimitry Andric AsanThread *CreateMainThread();
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric // Support function for __asan_(un)register_image_globals. Searches for the
1000b57cec5SDimitry Andric // loaded image containing `needle' and then enumerates all global metadata
1010b57cec5SDimitry Andric // structures declared in that image, applying `op' (e.g.,
1020b57cec5SDimitry Andric // __asan_(un)register_globals) to them.
1030b57cec5SDimitry Andric typedef void (*globals_op_fptr)(__asan_global *, uptr);
1040b57cec5SDimitry Andric void AsanApplyToGlobals(globals_op_fptr op, const void *needle);
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric void AsanOnDeadlySignal(int, void *siginfo, void *context);
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric void ReadContextStack(void *context, uptr *stack, uptr *ssize);
1090b57cec5SDimitry Andric void StopInitOrderChecking();
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric // Wrapper for TLS/TSD.
1120b57cec5SDimitry Andric void AsanTSDInit(void (*destructor)(void *tsd));
1130b57cec5SDimitry Andric void *AsanTSDGet();
1140b57cec5SDimitry Andric void AsanTSDSet(void *tsd);
1150b57cec5SDimitry Andric void PlatformTSDDtor(void *tsd);
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric void AppendToErrorMessageBuffer(const char *buffer);
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric void *AsanDlSymNext(const char *sym);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric // Returns `true` iff most of ASan init process should be skipped due to the
1220b57cec5SDimitry Andric // ASan library being loaded via `dlopen()`. Platforms may perform any
1230b57cec5SDimitry Andric // `dlopen()` specific initialization inside this function.
1240b57cec5SDimitry Andric bool HandleDlopenInit();
1250b57cec5SDimitry Andric 
126*81ad6265SDimitry Andric void InstallAtExitCheckLeaks();
127*81ad6265SDimitry Andric 
1280b57cec5SDimitry Andric #define ASAN_ON_ERROR() \
129*81ad6265SDimitry Andric   if (&__asan_on_error) \
130*81ad6265SDimitry Andric   __asan_on_error()
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric extern int asan_inited;
1330b57cec5SDimitry Andric // Used to avoid infinite recursion in __asan_init().
1340b57cec5SDimitry Andric extern bool asan_init_is_running;
1350b57cec5SDimitry Andric extern void (*death_callback)(void);
136*81ad6265SDimitry Andric // These magic values are written to shadow for better error
137*81ad6265SDimitry Andric // reporting.
1380b57cec5SDimitry Andric const int kAsanHeapLeftRedzoneMagic = 0xfa;
1390b57cec5SDimitry Andric const int kAsanHeapFreeMagic = 0xfd;
1400b57cec5SDimitry Andric const int kAsanStackLeftRedzoneMagic = 0xf1;
1410b57cec5SDimitry Andric const int kAsanStackMidRedzoneMagic = 0xf2;
1420b57cec5SDimitry Andric const int kAsanStackRightRedzoneMagic = 0xf3;
1430b57cec5SDimitry Andric const int kAsanStackAfterReturnMagic = 0xf5;
1440b57cec5SDimitry Andric const int kAsanInitializationOrderMagic = 0xf6;
1450b57cec5SDimitry Andric const int kAsanUserPoisonedMemoryMagic = 0xf7;
1460b57cec5SDimitry Andric const int kAsanContiguousContainerOOBMagic = 0xfc;
1470b57cec5SDimitry Andric const int kAsanStackUseAfterScopeMagic = 0xf8;
1480b57cec5SDimitry Andric const int kAsanGlobalRedzoneMagic = 0xf9;
1490b57cec5SDimitry Andric const int kAsanInternalHeapMagic = 0xfe;
1500b57cec5SDimitry Andric const int kAsanArrayCookieMagic = 0xac;
1510b57cec5SDimitry Andric const int kAsanIntraObjectRedzone = 0xbb;
1520b57cec5SDimitry Andric const int kAsanAllocaLeftMagic = 0xca;
1530b57cec5SDimitry Andric const int kAsanAllocaRightMagic = 0xcb;
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric static const uptr kCurrentStackFrameMagic = 0x41B58AB3;
1560b57cec5SDimitry Andric static const uptr kRetiredStackFrameMagic = 0x45E0360E;
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric }  // namespace __asan
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric #endif  // ASAN_INTERNAL_H
161