llvm/compiler-rt/lib/msan/msan_interceptors.cpp

//===-- msan_interceptors.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of MemorySanitizer.
//
// Interceptors for standard library functions.
//
// FIXME: move as many interceptors as possible into
// sanitizer_common/sanitizer_common_interceptors.h
//===----------------------------------------------------------------------===//

#define SANITIZER_COMMON_NO_REDEFINE_BUILTINS

#include "interception/interception.h"
#include "msan.h"
#include "msan_chained_origin_depot.h"
#include "msan_dl.h"
#include "msan_origin.h"
#include "msan_poisoning.h"
#include "msan_report.h"
#include "msan_thread.h"
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_allocator_dlsym.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_errno.h"
#include "sanitizer_common/sanitizer_errno_codes.h"
#include "sanitizer_common/sanitizer_glibc_version.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_vector.h"

#if SANITIZER_NETBSD
#define fstat
#define gettimeofday
#define getrusage
#define tzset
#endif

#include <stdarg.h>
// ACHTUNG! No other system header includes in this file.
// Ideally, we should get rid of stdarg.h as well.

usingnamespace__msan;

memory_order;
atomic_load;
atomic_store;
atomic_uintptr_t;

DECLARE_REAL()
DECLARE_REAL()
DECLARE_REAL()
DECLARE_REAL()

// True if this is a nested interceptor.
static THREADLOCAL int in_interceptor_scope;

void __msan_scoped_disable_interceptor_checks() {}
void __msan_scoped_enable_interceptor_checks() {}

struct InterceptorScope {};

bool IsInInterceptorScope() {}

struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {};

#define ENSURE_MSAN_INITED()

// Check that [x, x+n) range is unpoisoned.
#define CHECK_UNPOISONED_0(x, n)

// Check that [x, x+n) range is unpoisoned unless we are in a nested
// interceptor.
#define CHECK_UNPOISONED(x, n)

#define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n)

#define CHECK_UNPOISONED_STRING(x, n)

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
            void *file) {}
#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
#else
#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
#endif

#if !SANITIZER_NETBSD
INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {}
#define MSAN_MAYBE_INTERCEPT_MEMPCPY
#else
#define MSAN_MAYBE_INTERCEPT_MEMPCPY
#endif

INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {}

INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {}

INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {}
#define MSAN_MAYBE_INTERCEPT_MEMALIGN
#else
#define MSAN_MAYBE_INTERCEPT_MEMALIGN
#endif

INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {}

#if !SANITIZER_NETBSD
INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {}
#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
#else
#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
#endif

INTERCEPTOR(void *, valloc, SIZE_T size) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void *, pvalloc, SIZE_T size) {}
#define MSAN_MAYBE_INTERCEPT_PVALLOC
#else
#define MSAN_MAYBE_INTERCEPT_PVALLOC
#endif

INTERCEPTOR(void, free, void *ptr) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void, cfree, void *ptr) {}
#define MSAN_MAYBE_INTERCEPT_CFREE
#else
#define MSAN_MAYBE_INTERCEPT_CFREE
#endif

#if !SANITIZER_NETBSD
INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {}
#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE
#else
#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE
#endif

#if (!SANITIZER_FREEBSD && !SANITIZER_NETBSD) || __GLIBC_PREREQ(2, 33)
template <class T>
static NOINLINE void clear_mallinfo(T *sret) {}
#endif

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
// Interceptors use NRVO and assume that sret will be pre-allocated in
// caller frame.
INTERCEPTOR(__sanitizer_struct_mallinfo, mallinfo,) {}
#define MSAN_MAYBE_INTERCEPT_MALLINFO
#else
#define MSAN_MAYBE_INTERCEPT_MALLINFO
#endif

#if __GLIBC_PREREQ(2, 33)
INTERCEPTOR(__sanitizer_struct_mallinfo2, mallinfo2) {}
#define MSAN_MAYBE_INTERCEPT_MALLINFO2
#else
#define MSAN_MAYBE_INTERCEPT_MALLINFO2
#endif

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, mallopt, int cmd, int value) {}
#define MSAN_MAYBE_INTERCEPT_MALLOPT
#else
#define MSAN_MAYBE_INTERCEPT_MALLOPT
#endif

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void, malloc_stats, void) {}
#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
#else
#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
#endif

INTERCEPTOR(char *, strcpy, char *dest, const char *src) {}

INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {}

#if !SANITIZER_NETBSD
INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {}

INTERCEPTOR(char *, stpncpy, char *dest, const char *src, SIZE_T n) {}
#define MSAN_MAYBE_INTERCEPT_STPCPY
#define MSAN_MAYBE_INTERCEPT_STPNCPY
#else
#define MSAN_MAYBE_INTERCEPT_STPCPY
#define MSAN_MAYBE_INTERCEPT_STPNCPY
#endif

INTERCEPTOR(char *, strdup, char *src) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(char *, __strdup, char *src) {}
#define MSAN_MAYBE_INTERCEPT___STRDUP
#else
#define MSAN_MAYBE_INTERCEPT___STRDUP
#endif

#if !SANITIZER_NETBSD
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {}
#define MSAN_MAYBE_INTERCEPT_GCVT
#else
#define MSAN_MAYBE_INTERCEPT_GCVT
#endif

INTERCEPTOR(char *, strcat, char *dest, const char *src) {}

INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {}

// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to
// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.
#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...)

// On s390x, long double return values are passed via implicit reference,
// which needs to be unpoisoned.  We make the implicit pointer explicit.
#define INTERCEPTOR_STRTO_SRET_BODY(func, sret, ...)

#define INTERCEPTOR_STRTO(ret_type, func, char_type)

#define INTERCEPTOR_STRTO_SRET(ret_type, func, char_type)

#define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type)

#define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type)

#define INTERCEPTOR_STRTO_SRET_LOC(ret_type, func, char_type)

#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type)

#if SANITIZER_NETBSD
#define INTERCEPTORS_STRTO

#define INTERCEPTORS_STRTO_SRET

#define INTERCEPTORS_STRTO_BASE

#else
#define INTERCEPTORS_STRTO(ret_type, func, char_type)

#define INTERCEPTORS_STRTO_SRET(ret_type, func, char_type)

#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type)
#endif

INTERCEPTORS_STRTO()
INTERCEPTORS_STRTO()
#ifdef __s390x__
INTERCEPTORS_STRTO_SRET(long double, strtold, char)
#else
INTERCEPTORS_STRTO()
#endif
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()

INTERCEPTORS_STRTO()
INTERCEPTORS_STRTO()
#ifdef __s390x__
INTERCEPTORS_STRTO_SRET(long double, wcstold, wchar_t)
#else
INTERCEPTORS_STRTO()
#endif
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()

#if SANITIZER_GLIBC
INTERCEPTORS_STRTO()
INTERCEPTORS_STRTO()
#ifdef __s390x__
INTERCEPTORS_STRTO_SRET(long double, __isoc23_strtold, char)
#else
INTERCEPTORS_STRTO()
#endif
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()

INTERCEPTORS_STRTO()
INTERCEPTORS_STRTO()
#ifdef __s390x__
INTERCEPTORS_STRTO_SRET(long double, __isoc23_wcstold, wchar_t)
#else
INTERCEPTORS_STRTO()
#endif
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
INTERCEPTORS_STRTO_BASE()
#endif

#if SANITIZER_NETBSD
#define INTERCEPT_STRTO
#else
#define INTERCEPT_STRTO(func)

#define INTERCEPT_STRTO_VER(func, ver)
#endif


// FIXME: support *wprintf in common format interceptors.
INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {}

INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {}

#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...)

INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
            __sanitizer_tm *tm) {}

INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
            __sanitizer_tm *tm, void *loc) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
            __sanitizer_tm *tm, void *loc) {}
#define MSAN_MAYBE_INTERCEPT___STRFTIME_L
#else
#define MSAN_MAYBE_INTERCEPT___STRFTIME_L
#endif

INTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,
            __sanitizer_tm *tm) {}

INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
            __sanitizer_tm *tm, void *loc) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
            __sanitizer_tm *tm, void *loc) {}
#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L
#else
#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L
#endif

INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {}

INTERCEPTOR(SIZE_T, mbrtowc, wchar_t *dest, const char *src, SIZE_T n,
            void *ps) {}

// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {}

#if !SANITIZER_NETBSD
INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {}
#define MSAN_MAYBE_INTERCEPT_WMEMPCPY
#else
#define MSAN_MAYBE_INTERCEPT_WMEMPCPY
#endif

INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {}

INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {}

INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {}

INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {}

#if !SANITIZER_NETBSD
INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {}
#define MSAN_MAYBE_INTERCEPT_FCVT
#else
#define MSAN_MAYBE_INTERCEPT_FCVT
#endif

INTERCEPTOR(char *, getenv, char *name) {}

extern char **environ;

static void UnpoisonEnviron() {}

INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {}

INTERCEPTOR(int, putenv, char *string) {}

#define SANITIZER_STAT_LINUX
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX
INTERCEPTOR(int, fstat, int fd, void *buf) {}
#define MSAN_MAYBE_INTERCEPT_FSTAT
#else
#define MSAN_MAYBE_INTERCEPT_FSTAT
#endif

#if SANITIZER_STAT_LINUX
INTERCEPTOR(int, fstat64, int fd, void *buf) {}
#define MSAN_MAYBE_INTERCEPT_FSTAT64
#else
#define MSAN_MAYBE_INTERCEPT_FSTAT64
#endif

#if SANITIZER_GLIBC
INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {}
#define MSAN_MAYBE_INTERCEPT___FXSTAT
#else
#define MSAN_MAYBE_INTERCEPT___FXSTAT
#endif

#if SANITIZER_GLIBC
INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {}
#define MSAN_MAYBE_INTERCEPT___FXSTAT64
#else
#define MSAN_MAYBE_INTERCEPT___FXSTAT64
#endif

#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX
INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {}
#define MSAN_MAYBE_INTERCEPT_FSTATAT
#else
#define MSAN_MAYBE_INTERCEPT_FSTATAT
#endif

#if SANITIZER_STAT_LINUX
INTERCEPTOR(int, fstatat64, int fd, char *pathname, void *buf, int flags) {}
#define MSAN_MAYBE_INTERCEPT_FSTATAT64
#else
#define MSAN_MAYBE_INTERCEPT_FSTATAT64
#endif

#if SANITIZER_GLIBC
INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
            int flags) {}
#define MSAN_MAYBE_INTERCEPT___FXSTATAT
#else
#define MSAN_MAYBE_INTERCEPT___FXSTATAT
#endif

#if SANITIZER_GLIBC
INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
            int flags) {}
#define MSAN_MAYBE_INTERCEPT___FXSTATAT64
#else
#define MSAN_MAYBE_INTERCEPT___FXSTATAT64
#endif

INTERCEPTOR(int, pipe, int pipefd[2]) {}

INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {}

INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {}
#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED
#else
#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED
#endif

#define INTERCEPTOR_GETRLIMIT_BODY(func, resource, rlim)

INTERCEPTOR(int, getrlimit, int resource, void *rlim) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, __getrlimit, int resource, void *rlim) {}

INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {}

INTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit,
            void *old_rlimit) {}

INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
            void *old_rlimit) {}

#define MSAN_MAYBE_INTERCEPT___GETRLIMIT
#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64
#define MSAN_MAYBE_INTERCEPT_PRLIMIT
#define MSAN_MAYBE_INTERCEPT_PRLIMIT64
#else
#define MSAN_MAYBE_INTERCEPT___GETRLIMIT
#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64
#define MSAN_MAYBE_INTERCEPT_PRLIMIT
#define MSAN_MAYBE_INTERCEPT_PRLIMIT64
#endif

INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {}

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
    int timeout) {}
#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
#else
#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
#endif

#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
    int timeout, void *sigmask) {}
#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
#else
#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
#endif

INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {}

INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {}

INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) {}

INTERCEPTOR(void *, malloc, SIZE_T size) {}

void __msan_allocated_memory(const void *data, uptr size) {}

void __msan_copy_shadow(void *dest, const void *src, uptr n) {}

void __sanitizer_dtor_callback(const void *data, uptr size) {}

void __sanitizer_dtor_callback_fields(const void *data, uptr size) {}

void __sanitizer_dtor_callback_vptr(const void *data) {}

template <class Mmap>
static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
                              int prot, int flags, int fd, OFF64_T offset) {}

INTERCEPTOR(int, getrusage, int who, void *usage) {}

class SignalHandlerScope {};

// sigactions_mu guarantees atomicity of sigaction() and signal() calls.
// Access to sigactions[] is gone with relaxed atomics to avoid data race with
// the signal handler.
const int kMaxSignals =;
static atomic_uintptr_t sigactions[kMaxSignals];
static StaticSpinMutex sigactions_mu;

static void SignalHandler(int signo) {}

static void SignalAction(int signo, void *si, void *uc) {}

static void read_sigaction(const __sanitizer_sigaction *act) {}

extern "C" int pthread_attr_init(void *attr);
extern "C" int pthread_attr_destroy(void *attr);

static void *MsanThreadStartFunc(void *arg) {}

INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
            void * param) {}

INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
            void (*dtor)(void *value)) {}

#if SANITIZER_NETBSD
INTERCEPTOR(int, __libc_thr_keycreate, __sanitizer_pthread_key_t *m,
            void (*dtor)(void *value))
ALIAS(WRAP(pthread_key_create));
#endif

INTERCEPTOR(int, pthread_join, void *thread, void **retval) {}

#if SANITIZER_GLIBC
INTERCEPTOR(int, pthread_tryjoin_np, void *thread, void **retval) {}

INTERCEPTOR(int, pthread_timedjoin_np, void *thread, void **retval,
            const struct timespec *abstime) {}
#endif

DEFINE_INTERNAL_PTHREAD_FUNCTIONS

extern char *tzname[2];

INTERCEPTOR(void, tzset, int fake) {}

struct MSanAtExitRecord {};

struct InterceptorContext {};

alignas(64) static char interceptor_placeholder[sizeof(InterceptorContext)];
InterceptorContext *interceptor_ctx() {}

void MSanAtExitWrapper() {}

void MSanCxaAtExitWrapper(void *arg) {}

static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso);

// Unpoison argument shadow for C++ module destructors.
INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
            void *dso_handle) {}

// Unpoison argument shadow for C++ module destructors.
INTERCEPTOR(int, atexit, void (*func)()) {}

static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) {}

// NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly
// with MSan.
#if SANITIZER_LINUX
INTERCEPTOR(int, openpty, int *aparent, int *aworker, char *name,
            const void *termp, const void *winp) {}
#define MSAN_MAYBE_INTERCEPT_OPENPTY
#else
#define MSAN_MAYBE_INTERCEPT_OPENPTY
#endif

// NetBSD ships with forkpty(3) in -lutil, that needs to be prebuilt explicitly
// with MSan.
#if SANITIZER_LINUX
INTERCEPTOR(int, forkpty, int *aparent, char *name, const void *termp,
            const void *winp) {}
#define MSAN_MAYBE_INTERCEPT_FORKPTY
#else
#define MSAN_MAYBE_INTERCEPT_FORKPTY
#endif

struct MSanInterceptorContext {};

namespace __msan {

int OnExit() {}

} // namespace __msan

// A version of CHECK_UNPOISONED using a saved scope value. Used in common
// interceptors.
#define CHECK_UNPOISONED_CTX(ctx, x, n)

#define MSAN_INTERCEPT_FUNC(name)

#define MSAN_INTERCEPT_FUNC_VER(name, ver)
#define MSAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver)

#define COMMON_INTERCEPT_FUNCTION(name)
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver)
#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver)
#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count)
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)
#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size)
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)
#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path)
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd)
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd)
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd)
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name)
#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name)
#define COMMON_INTERCEPTOR_BLOCK_REAL(name)
#define COMMON_INTERCEPTOR_ON_EXIT(ctx)
#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)

#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED

#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)

#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size)
#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size)
#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size)

#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size)

#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \
                                     offset)

#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"
#include "sanitizer_common/sanitizer_common_interceptors.inc"

static uptr signal_impl(int signo, uptr cb);
static int sigaction_impl(int signo, const __sanitizer_sigaction *act,
                          __sanitizer_sigaction *oldact);

#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signo, act, oldact)

#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler)

#define SIGNAL_INTERCEPTOR_ENTER()

#include "sanitizer_common/sanitizer_signal_interceptors.inc"

static int sigaction_impl(int signo, const __sanitizer_sigaction *act,
                          __sanitizer_sigaction *oldact) {}

static uptr signal_impl(int signo, uptr cb) {}

#define COMMON_SYSCALL_PRE_READ_RANGE(p, s)
#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
#define COMMON_SYSCALL_POST_READ_RANGE(p, s)
#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s)
#include "sanitizer_common/sanitizer_common_syscalls.inc"
#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"

INTERCEPTOR(const char *, strsignal, int sig) {}

INTERCEPTOR(int, dladdr, void *addr, void *info) {}

#if SANITIZER_GLIBC
INTERCEPTOR(int, dladdr1, void *addr, void *info, void **extra_info,
            int flags) {}
#define MSAN_MAYBE_INTERCEPT_DLADDR1
#else
#define MSAN_MAYBE_INTERCEPT_DLADDR1
#endif

INTERCEPTOR(char *, dlerror, int fake) {}

dl_iterate_phdr_cb;
struct dl_iterate_phdr_data {};

static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
                                   void *data) {}

INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {}

INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {}

// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {}

// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {}

INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {}

// These interface functions reside here so that they can use
// REAL(memset), etc.
void __msan_unpoison(const void *a, uptr size) {}

void __msan_poison(const void *a, uptr size) {}

void __msan_poison_stack(void *a, uptr size) {}

void __msan_unpoison_param(uptr n) {}

void __msan_clear_and_unpoison(void *a, uptr size) {}

void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {}

void *__msan_memset(void *s, int c, SIZE_T n) {}

void *__msan_memmove(void *dest, const void *src, SIZE_T n) {}

void __msan_unpoison_string(const char* s) {}

namespace __msan {

void InitializeInterceptors() {}
} // namespace __msan