16d1862363c88c183b0ed7740fca876342cf0474bStephen Hines//===-- asan_win_dll_thunk.cc ---------------------------------------------===//
268cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//
368cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//                     The LLVM Compiler Infrastructure
468cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//
568cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// This file is distributed under the University of Illinois Open Source
668cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// License. See LICENSE.TXT for details.
768cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//
868cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//===----------------------------------------------------------------------===//
968cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//
1068cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// This file is a part of AddressSanitizer, an address sanity checker.
1168cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//
1268cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// This file defines a family of thunks that should be statically linked into
1368cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// the DLLs that have ASan instrumentation in order to delegate the calls to the
1468cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// shared runtime that lives in the main binary.
15799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// See https://github.com/google/sanitizers/issues/209 for the details.
1668cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov//===----------------------------------------------------------------------===//
1768cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
1868cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// Only compile this code when buidling asan_dll_thunk.lib
1968cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// Using #ifdef rather than relying on Makefiles etc.
2068cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// simplifies the build procedure.
2168cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov#ifdef ASAN_DLL_THUNK
226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "asan_init_version.h"
236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include "interception/interception.h"
2468cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// ---------- Function interception helper functions and macros ----------- {{{1
2643e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanovextern "C" {
2743e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanovvoid *__stdcall GetModuleHandleA(const char *module_name);
2843e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanovvoid *__stdcall GetProcAddress(void *module, const char *proc_name);
2943e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanovvoid abort();
3043e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov}
3168cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
32799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic uptr getRealProcAddressOrDie(const char *name) {
33799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  uptr ret =
34799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      __interception::InternalGetProcAddress((void *)GetModuleHandleA(0), name);
3568cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov  if (!ret)
3668cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov    abort();
3768cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov  return ret;
3868cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov}
3968cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// We need to intercept some functions (e.g. ASan interface, memory allocator --
412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// let's call them "hooks") exported by the DLL thunk and forward the hooks to
422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// the runtime in the main module.
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// However, we don't want to keep two lists of these hooks.
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// To avoid that, the list of hooks should be defined using the
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// INTERCEPT_WHEN_POSSIBLE macro. Then, all these hooks can be intercepted
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// at once by calling INTERCEPT_HOOKS().
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Use macro+template magic to automatically generate the list of hooks.
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Each hook at line LINE defines a template class with a static
502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FunctionInterceptor<LINE>::Execute() method intercepting the hook.
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The default implementation of FunctionInterceptor<LINE> is to call
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// the Execute() method corresponding to the previous line.
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestemplate<int LINE>
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct FunctionInterceptor {
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  static void Execute() { FunctionInterceptor<LINE-1>::Execute(); }
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// There shouldn't be any hooks with negative definition line number.
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestemplate<>
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct FunctionInterceptor<0> {
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  static void Execute() {}
622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPT_WHEN_POSSIBLE(main_function, dll_function)                   \
65799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  template <> struct FunctionInterceptor<__LINE__> {                           \
662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    static void Execute() {                                                    \
67799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      uptr wrapper = getRealProcAddressOrDie(main_function);                   \
68799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      if (!__interception::OverrideFunction((uptr)dll_function, wrapper, 0))   \
692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        abort();                                                               \
70799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      FunctionInterceptor<__LINE__ - 1>::Execute();                            \
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }                                                                          \
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  };
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Special case of hooks -- ASan own interface functions.  Those are only called
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// after __asan_init, thus an empty implementation is sufficient.
762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERFACE_FUNCTION(name)                                               \
776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  extern "C" __declspec(noinline) void name() {                                \
786a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    volatile int prevent_icf = (__LINE__ << 8); (void)prevent_icf;             \
796a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    __debugbreak();                                                            \
806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  }                                                                            \
812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name)
822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// INTERCEPT_HOOKS must be used after the last INTERCEPT_WHEN_POSSIBLE.
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPT_HOOKS FunctionInterceptor<__LINE__>::Execute
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// We can't define our own version of strlen etc. because that would lead to
872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// link-time or even type mismatch errors.  Instead, we can declare a function
882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// just to be able to get its address.  Me may miss the first few calls to the
892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// functions since it can be called before __asan_init, but that would lead to
902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// false negatives in the startup code before user's global initializers, which
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// isn't a big deal.
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPT_LIBRARY_FUNCTION(name)                                       \
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  extern "C" void name();                                                      \
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(WRAPPER_NAME(name), name)
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Disable compiler warnings that show up if we declare our own version
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// of a compiler intrinsic (e.g. strlen).
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#pragma warning(disable: 4391)
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#pragma warning(disable: 4392)
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void InterceptHooks();
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// }}}
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// ---------- Function wrapping helpers ----------------------------------- {{{1
10543e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_V_V(name)                                                         \
10668cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov  extern "C" void name() {                                                     \
10768cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov    typedef void (*fntype)();                                                  \
108a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
10968cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov    fn();                                                                      \
1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
11268cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
11343e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_V_W(name)                                                         \
11468cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov  extern "C" void name(void *arg) {                                            \
11568cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov    typedef void (*fntype)(void *arg);                                         \
116a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
11768cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov    fn(arg);                                                                   \
1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
12068cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
12143e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_V_WW(name)                                                        \
12268cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov  extern "C" void name(void *arg1, void *arg2) {                               \
12368cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov    typedef void (*fntype)(void *, void *);                                    \
124a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
12568cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov    fn(arg1, arg2);                                                            \
1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
12843e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
129c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov#define WRAP_V_WWW(name)                                                       \
130c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov  extern "C" void name(void *arg1, void *arg2, void *arg3) {                   \
131c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov    typedef void *(*fntype)(void *, void *, void *);                           \
132a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
133c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov    fn(arg1, arg2, arg3);                                                      \
1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
136c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov
137c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov#define WRAP_W_V(name)                                                         \
138c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov  extern "C" void *name() {                                                    \
139c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov    typedef void *(*fntype)();                                                 \
140a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
141c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov    return fn();                                                               \
1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
144c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov
14543e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_W_W(name)                                                         \
14643e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov  extern "C" void *name(void *arg) {                                           \
14743e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    typedef void *(*fntype)(void *arg);                                        \
148a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
14943e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    return fn(arg);                                                            \
1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
15243e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
15343e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_W_WW(name)                                                        \
15443e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov  extern "C" void *name(void *arg1, void *arg2) {                              \
15543e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    typedef void *(*fntype)(void *, void *);                                   \
156a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
15743e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    return fn(arg1, arg2);                                                     \
1582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
16043e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
16143e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_W_WWW(name)                                                       \
16243e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov  extern "C" void *name(void *arg1, void *arg2, void *arg3) {                  \
16343e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    typedef void *(*fntype)(void *, void *, void *);                           \
164a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
16543e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    return fn(arg1, arg2, arg3);                                               \
1662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
16843e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
16943e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_W_WWWW(name)                                                      \
17043e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov  extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4) {      \
17143e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    typedef void *(*fntype)(void *, void *, void *, void *);                   \
172a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
17343e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    return fn(arg1, arg2, arg3, arg4);                                         \
1742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
17643e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
17743e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_W_WWWWW(name)                                                     \
17843e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov  extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4,        \
17943e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov                        void *arg5) {                                          \
18043e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    typedef void *(*fntype)(void *, void *, void *, void *, void *);           \
181a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
18243e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    return fn(arg1, arg2, arg3, arg4, arg5);                                   \
1832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
18543e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
18643e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov#define WRAP_W_WWWWWW(name)                                                    \
18743e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov  extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4,        \
18843e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov                        void *arg5, void *arg6) {                              \
18943e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    typedef void *(*fntype)(void *, void *, void *, void *, void *, void *);   \
190a8b8e964d7b94cae465df77642465901b1b3079dTimur Iskhodzhanov    static fntype fn = (fntype)getRealProcAddressOrDie(#name);                 \
19143e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov    return fn(arg1, arg2, arg3, arg4, arg5, arg6);                             \
1922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }                                                                            \
1932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_WHEN_POSSIBLE(#name, name);
19468cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// }}}
19568cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
19643e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov// ----------------- ASan own interface functions --------------------
1972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Don't use the INTERFACE_FUNCTION machinery for this function as we actually
1982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// want to call it in the __asan_init interceptor.
199c11fa095b344c1423ba76822d5bde122b1676223Timur IskhodzhanovWRAP_W_V(__asan_should_detect_stack_use_after_return)
200c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov
201c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanovextern "C" {
202c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov  int __asan_option_detect_stack_use_after_return;
203c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov
204c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov  // Manually wrap __asan_init as we need to initialize
205c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov  // __asan_option_detect_stack_use_after_return afterwards.
2066a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  void __asan_init() {
207c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov    typedef void (*fntype)();
2082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    static fntype fn = 0;
2096a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    // __asan_init is expected to be called by only one thread.
2102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (fn) return;
2112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
212799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    fn = (fntype)getRealProcAddressOrDie("__asan_init");
213c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov    fn();
214c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov    __asan_option_detect_stack_use_after_return =
215def895b9ed81b37a99660a2ddfc2c45d229000a4Timur Iskhodzhanov        (__asan_should_detect_stack_use_after_return() != 0);
2162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    InterceptHooks();
218c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov  }
219c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov}
22068cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
221799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarextern "C" void __asan_version_mismatch_check() {
222799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  // Do nothing.
223799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
224799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
2252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_handle_no_return)
2262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_store1)
2282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_store2)
2292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_store4)
2302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_store8)
2312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_store16)
2322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_store_n)
2332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_load1)
2352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_load2)
2362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_load4)
2372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_load8)
2382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_load16)
2392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_report_load_n)
2402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2416d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_store1)
2426d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_store2)
2436d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_store4)
2446d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_store8)
2456d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_store16)
2466d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_storeN)
2476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2486d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_load1)
2496d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_load2)
2506d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_load4)
2516d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_load8)
2526d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_load16)
2536d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_loadN)
2546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_memcpy);
2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_memset);
2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_memmove);
2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
259799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERFACE_FUNCTION(__asan_alloca_poison);
260799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERFACE_FUNCTION(__asan_allocas_unpoison);
261799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_register_globals)
2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_unregister_globals)
2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_before_dynamic_init)
2662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_after_dynamic_init)
2672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_poison_stack_memory)
2692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_unpoison_stack_memory)
2702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_poison_memory_region)
2722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_unpoison_memory_region)
2732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2746d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_address_is_poisoned)
2756d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERFACE_FUNCTION(__asan_region_is_poisoned)
2766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_get_current_fake_stack)
2782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_addr_is_in_fake_stack)
2792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_0)
2812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_1)
2822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_2)
2832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_3)
2842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_4)
2852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_5)
2862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_6)
2872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_7)
2882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_8)
2892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_9)
2902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_malloc_10)
2912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_0)
2932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_1)
2942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_2)
2952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_4)
2962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_5)
2972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_6)
2982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_7)
2992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_8)
3002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_9)
3012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERFACE_FUNCTION(__asan_stack_free_10)
302c11fa095b344c1423ba76822d5bde122b1676223Timur Iskhodzhanov
30386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// FIXME: we might want to have a sanitizer_win_dll_thunk?
30486277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container)
305799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address)
30686277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov)
30786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov_dump)
30886277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov_indir_call16)
30986277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov_init)
3106a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov_module_init)
31186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov_trace_basic_block)
31286277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov_trace_func_enter)
313cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_cov_trace_cmp)
314799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_cov_trace_switch)
31586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_cov_with_check)
31686277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_allocated_size)
31786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_coverage_guards)
318c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_get_coverage_pc_buffer)
31986277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes)
32086277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size)
32186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_free_bytes)
32286277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_heap_size)
32386277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_ownership)
324799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_get_total_unique_caller_callee_pairs)
32586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage)
32686277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes)
32786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file)
32886277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_print_stack_trace)
32986277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_ptr_cmp)
33086277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_ptr_sub)
33186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_report_error_summary)
33286277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_reset_coverage)
3337c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_get_number_of_counters)
3347c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_update_counter_bitset_and_clear_counters)
33586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_sandbox_on_notify)
33686277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_set_death_callback)
33786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_set_report_path)
338c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_set_report_fd)
33986277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_unaligned_load16)
34086277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_unaligned_load32)
34186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_unaligned_load64)
34286277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_unaligned_store16)
34386277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_unaligned_store32)
34486277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_unaligned_store64)
34586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)
346c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks)
347c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_start_switch_fiber)
348c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERFACE_FUNCTION(__sanitizer_finish_switch_fiber)
3496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
35068cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov// TODO(timurrrr): Add more interface functions on the as-needed basis.
35168cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
35243e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov// ----------------- Memory allocation functions ---------------------
35343e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_V_W(free)
354c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarWRAP_V_W(_free_base)
35543e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_V_WW(_free_dbg)
35643e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
35743e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_W(malloc)
358c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarWRAP_W_W(_malloc_base)
35943e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_WWWW(_malloc_dbg)
36043e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
36143e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_WW(calloc)
362c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarWRAP_W_WW(_calloc_base)
36343e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_WWWWW(_calloc_dbg)
36443e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_WWW(_calloc_impl)
36543e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
36643e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_WW(realloc)
367c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarWRAP_W_WW(_realloc_base)
36843e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_WWW(_realloc_dbg)
36943e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_WWW(_recalloc)
37043e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
37143e62df906327f6ffa492edb933af1195143d149Timur IskhodzhanovWRAP_W_W(_msize)
3722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesWRAP_W_W(_expand)
3732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesWRAP_W_W(_expand_dbg)
3742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// TODO(timurrrr): Might want to add support for _aligned_* allocation
3762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// functions to detect a bit more bugs.  Those functions seem to wrap malloc().
37743e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov
37843e62df906327f6ffa492edb933af1195143d149Timur Iskhodzhanov// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).
37968cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov
3802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(atoi);
3812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(atol);
3826d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPT_LIBRARY_FUNCTION(_except_handler3);
3836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
3846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// _except_handler4 checks -GS cookie which is different for each module, so we
3856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
3866d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
3876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  __asan_handle_no_return();
3886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return REAL(_except_handler4)(a, b, c, d);
3896d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
3906d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
3912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(frexp);
3922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(longjmp);
3932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(memchr);
3942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(memcmp);
3952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(memcpy);
3962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(memmove);
3972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(memset);
3982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strcat);  // NOLINT
3992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strchr);
4002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strcmp);
4012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strcpy);  // NOLINT
402cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPT_LIBRARY_FUNCTION(strcspn);
403c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPT_LIBRARY_FUNCTION(strdup);
4042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strlen);
4052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strncat);
4062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strncmp);
4072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strncpy);
4082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strnlen);
409cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPT_LIBRARY_FUNCTION(strpbrk);
410c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPT_LIBRARY_FUNCTION(strrchr);
411cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPT_LIBRARY_FUNCTION(strspn);
412cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarINTERCEPT_LIBRARY_FUNCTION(strstr);
4132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(strtol);
4142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPT_LIBRARY_FUNCTION(wcslen);
4152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
4166a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// Must be after all the interceptor declarations due to the way INTERCEPT_HOOKS
4176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// is defined.
4182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid InterceptHooks() {
4192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_HOOKS();
4206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  INTERCEPT_FUNCTION(_except_handler4);
4212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
4222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
4236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// We want to call __asan_init before C/C++ initializers/constructors are
4246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// executed, otherwise functions like memset might be invoked.
4256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// For some strange reason, merely linking in asan_preinit.cc doesn't work
4266a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// as the callback is never called...  Is link.exe doing something too smart?
4276a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
4286a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// In DLLs, the callbacks are expected to return 0,
4296a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// otherwise CRT initialization fails.
4306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesstatic int call_asan_init() {
4316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __asan_init();
4326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  return 0;
4336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
4346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#pragma section(".CRT$XIB", long, read)  // NOLINT
4356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = call_asan_init;
4366a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
43768cd60c77470fd6e0f86bad1e4c68796d516cc06Timur Iskhodzhanov#endif // ASAN_DLL_THUNK
438