[sanitizers] convert some errant CRLF line endings to LF (#108454)
(nfc) https://github.com/llvm/llvm-project/pull/107899 Added some files with CRLF line endings. Mixed line endings are somewhat gross, so I've converted them all to unix.
This commit is contained in:
parent
7586aea9ed
commit
0265981b6e
@ -1,229 +1,229 @@
|
||||
//===-- asan_malloc_win_thunk.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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// Windows-specific malloc interception.
|
||||
// This is included statically for projects statically linking
|
||||
// with the C Runtime (/MT, /MTd) in order to provide ASAN-aware
|
||||
// versions of the C allocation functions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
# include "..\sanitizer_common\sanitizer_allocator_interface.h"
|
||||
// #include "asan_win_thunk_common.h"
|
||||
|
||||
// Preserve stack traces with noinline.
|
||||
# define STATIC_MALLOC_INTERFACE __declspec(noinline)
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllimport) size_t __cdecl __asan_msize(void *ptr);
|
||||
__declspec(dllimport) void __cdecl __asan_free(void *const ptr);
|
||||
__declspec(dllimport) void *__cdecl __asan_malloc(const size_t size);
|
||||
__declspec(dllimport) void *__cdecl __asan_calloc(const size_t nmemb,
|
||||
const size_t size);
|
||||
__declspec(dllimport) void *__cdecl __asan_realloc(void *const ptr,
|
||||
const size_t size);
|
||||
__declspec(dllimport) void *__cdecl __asan_recalloc(void *const ptr,
|
||||
const size_t nmemb,
|
||||
const size_t size);
|
||||
|
||||
// Avoid tailcall optimization to preserve stack frames.
|
||||
# pragma optimize("", off)
|
||||
|
||||
// _msize
|
||||
STATIC_MALLOC_INTERFACE size_t _msize(void *ptr) { return __asan_msize(ptr); }
|
||||
|
||||
STATIC_MALLOC_INTERFACE size_t _msize_base(void *ptr) {
|
||||
return __asan_msize(ptr);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE size_t _msize_dbg(void *ptr) {
|
||||
return __asan_msize(ptr);
|
||||
}
|
||||
|
||||
// free
|
||||
STATIC_MALLOC_INTERFACE void free(void *const ptr) { return __asan_free(ptr); }
|
||||
|
||||
STATIC_MALLOC_INTERFACE void _free_base(void *const ptr) {
|
||||
return __asan_free(ptr);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void _free_dbg(void *const ptr) {
|
||||
return __asan_free(ptr);
|
||||
}
|
||||
|
||||
// malloc
|
||||
STATIC_MALLOC_INTERFACE void *malloc(const size_t size) {
|
||||
return __asan_malloc(size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_malloc_base(const size_t size) {
|
||||
return __asan_malloc(size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_malloc_dbg(const size_t size) {
|
||||
return __asan_malloc(size);
|
||||
}
|
||||
|
||||
// calloc
|
||||
STATIC_MALLOC_INTERFACE void *calloc(const size_t nmemb, const size_t size) {
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_calloc_base(const size_t nmemb,
|
||||
const size_t size) {
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_calloc_impl(const size_t nmemb,
|
||||
const size_t size,
|
||||
int *const errno_tmp) {
|
||||
// Provided by legacy msvcrt.
|
||||
(void)errno_tmp;
|
||||
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_calloc_dbg(const size_t nmemb, const size_t size,
|
||||
int, const char *, int) {
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
// realloc
|
||||
STATIC_MALLOC_INTERFACE void *realloc(void *const ptr, const size_t size) {
|
||||
return __asan_realloc(ptr, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_realloc_base(void *const ptr,
|
||||
const size_t size) {
|
||||
return __asan_realloc(ptr, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_realloc_dbg(void *const ptr, const size_t size,
|
||||
int, const char *, int) {
|
||||
return __asan_realloc(ptr, size);
|
||||
}
|
||||
|
||||
// recalloc
|
||||
STATIC_MALLOC_INTERFACE void *_recalloc(void *const ptr, const size_t nmemb,
|
||||
const size_t size) {
|
||||
return __asan_recalloc(ptr, nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_recalloc_base(void *const ptr,
|
||||
const size_t nmemb,
|
||||
const size_t size) {
|
||||
return __asan_recalloc(ptr, nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_recalloc_dbg(void *const ptr, const size_t nmemb,
|
||||
const size_t size, int,
|
||||
const char *, int) {
|
||||
return __asan_recalloc(ptr, nmemb, size);
|
||||
}
|
||||
|
||||
// expand
|
||||
STATIC_MALLOC_INTERFACE void *_expand(void *, size_t) {
|
||||
// _expand is used in realloc-like functions to resize the buffer if possible.
|
||||
// We don't want memory to stand still while resizing buffers, so return 0.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_expand_dbg(void *, size_t, int, const char *,
|
||||
int) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We need to provide symbols for all the debug CRT functions if we decide to
|
||||
// provide any. Most of these functions make no sense under ASan and so we
|
||||
// make them no-ops.
|
||||
long _CrtSetBreakAlloc(long const) { return ~0; }
|
||||
|
||||
void _CrtSetDbgBlockType(void *const, int const) { return; }
|
||||
|
||||
typedef int(__cdecl *CRT_ALLOC_HOOK)(int, void *, size_t, int, long,
|
||||
const unsigned char *, int);
|
||||
|
||||
CRT_ALLOC_HOOK _CrtGetAllocHook() { return nullptr; }
|
||||
|
||||
CRT_ALLOC_HOOK _CrtSetAllocHook(CRT_ALLOC_HOOK const hook) { return hook; }
|
||||
|
||||
int _CrtCheckMemory() { return 1; }
|
||||
|
||||
int _CrtSetDbgFlag(int const new_bits) { return new_bits; }
|
||||
|
||||
typedef void (*CrtDoForAllClientObjectsCallback)(void *, void *);
|
||||
|
||||
void _CrtDoForAllClientObjects(CrtDoForAllClientObjectsCallback const,
|
||||
void *const) {
|
||||
return;
|
||||
}
|
||||
|
||||
int _CrtIsValidPointer(void const *const p, unsigned int const, int const) {
|
||||
return p != nullptr;
|
||||
}
|
||||
|
||||
int _CrtIsValidHeapPointer(void const *const block) {
|
||||
if (!block) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __sanitizer_get_ownership(block);
|
||||
}
|
||||
|
||||
int _CrtIsMemoryBlock(void const *const, unsigned const, long *const,
|
||||
char **const, int *const) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _CrtReportBlockType(void const *const) { return -1; }
|
||||
|
||||
typedef void(__cdecl *CRT_DUMP_CLIENT)(void *, size_t);
|
||||
|
||||
CRT_DUMP_CLIENT _CrtGetDumpClient() { return nullptr; }
|
||||
|
||||
CRT_DUMP_CLIENT _CrtSetDumpClient(CRT_DUMP_CLIENT new_client) {
|
||||
return new_client;
|
||||
}
|
||||
|
||||
void _CrtMemCheckpoint(void *const) { return; }
|
||||
|
||||
int _CrtMemDifference(void *const, void const *const, void const *const) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _CrtMemDumpAllObjectsSince(void const *const) { return; }
|
||||
|
||||
int _CrtDumpMemoryLeaks() { return 0; }
|
||||
|
||||
void _CrtMemDumpStatistics(void const *const) { return; }
|
||||
|
||||
int _crtDbgFlag{0};
|
||||
long _crtBreakAlloc{-1};
|
||||
CRT_DUMP_CLIENT _pfnDumpClient{nullptr};
|
||||
|
||||
int *__p__crtDbgFlag() { return &_crtDbgFlag; }
|
||||
|
||||
long *__p__crtBreakAlloc() { return &_crtBreakAlloc; }
|
||||
|
||||
// TODO: These were added upstream but conflict with definitions in ucrtbased.
|
||||
// int _CrtDbgReport(int, const char *, int, const char *, const char *, ...) {
|
||||
// ShowStatsAndAbort();
|
||||
// }
|
||||
//
|
||||
// int _CrtDbgReportW(int reportType, const wchar_t *, int, const wchar_t *,
|
||||
// const wchar_t *, ...) {
|
||||
// ShowStatsAndAbort();
|
||||
// }
|
||||
//
|
||||
// int _CrtSetReportMode(int, int) { return 0; }
|
||||
|
||||
} // extern "C"
|
||||
#endif // SANITIZER_STATIC_RUNTIME_THUNK
|
||||
//===-- asan_malloc_win_thunk.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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// Windows-specific malloc interception.
|
||||
// This is included statically for projects statically linking
|
||||
// with the C Runtime (/MT, /MTd) in order to provide ASAN-aware
|
||||
// versions of the C allocation functions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
# include "..\sanitizer_common\sanitizer_allocator_interface.h"
|
||||
// #include "asan_win_thunk_common.h"
|
||||
|
||||
// Preserve stack traces with noinline.
|
||||
# define STATIC_MALLOC_INTERFACE __declspec(noinline)
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllimport) size_t __cdecl __asan_msize(void *ptr);
|
||||
__declspec(dllimport) void __cdecl __asan_free(void *const ptr);
|
||||
__declspec(dllimport) void *__cdecl __asan_malloc(const size_t size);
|
||||
__declspec(dllimport) void *__cdecl __asan_calloc(const size_t nmemb,
|
||||
const size_t size);
|
||||
__declspec(dllimport) void *__cdecl __asan_realloc(void *const ptr,
|
||||
const size_t size);
|
||||
__declspec(dllimport) void *__cdecl __asan_recalloc(void *const ptr,
|
||||
const size_t nmemb,
|
||||
const size_t size);
|
||||
|
||||
// Avoid tailcall optimization to preserve stack frames.
|
||||
# pragma optimize("", off)
|
||||
|
||||
// _msize
|
||||
STATIC_MALLOC_INTERFACE size_t _msize(void *ptr) { return __asan_msize(ptr); }
|
||||
|
||||
STATIC_MALLOC_INTERFACE size_t _msize_base(void *ptr) {
|
||||
return __asan_msize(ptr);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE size_t _msize_dbg(void *ptr) {
|
||||
return __asan_msize(ptr);
|
||||
}
|
||||
|
||||
// free
|
||||
STATIC_MALLOC_INTERFACE void free(void *const ptr) { return __asan_free(ptr); }
|
||||
|
||||
STATIC_MALLOC_INTERFACE void _free_base(void *const ptr) {
|
||||
return __asan_free(ptr);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void _free_dbg(void *const ptr) {
|
||||
return __asan_free(ptr);
|
||||
}
|
||||
|
||||
// malloc
|
||||
STATIC_MALLOC_INTERFACE void *malloc(const size_t size) {
|
||||
return __asan_malloc(size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_malloc_base(const size_t size) {
|
||||
return __asan_malloc(size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_malloc_dbg(const size_t size) {
|
||||
return __asan_malloc(size);
|
||||
}
|
||||
|
||||
// calloc
|
||||
STATIC_MALLOC_INTERFACE void *calloc(const size_t nmemb, const size_t size) {
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_calloc_base(const size_t nmemb,
|
||||
const size_t size) {
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_calloc_impl(const size_t nmemb,
|
||||
const size_t size,
|
||||
int *const errno_tmp) {
|
||||
// Provided by legacy msvcrt.
|
||||
(void)errno_tmp;
|
||||
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_calloc_dbg(const size_t nmemb, const size_t size,
|
||||
int, const char *, int) {
|
||||
return __asan_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
// realloc
|
||||
STATIC_MALLOC_INTERFACE void *realloc(void *const ptr, const size_t size) {
|
||||
return __asan_realloc(ptr, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_realloc_base(void *const ptr,
|
||||
const size_t size) {
|
||||
return __asan_realloc(ptr, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_realloc_dbg(void *const ptr, const size_t size,
|
||||
int, const char *, int) {
|
||||
return __asan_realloc(ptr, size);
|
||||
}
|
||||
|
||||
// recalloc
|
||||
STATIC_MALLOC_INTERFACE void *_recalloc(void *const ptr, const size_t nmemb,
|
||||
const size_t size) {
|
||||
return __asan_recalloc(ptr, nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_recalloc_base(void *const ptr,
|
||||
const size_t nmemb,
|
||||
const size_t size) {
|
||||
return __asan_recalloc(ptr, nmemb, size);
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_recalloc_dbg(void *const ptr, const size_t nmemb,
|
||||
const size_t size, int,
|
||||
const char *, int) {
|
||||
return __asan_recalloc(ptr, nmemb, size);
|
||||
}
|
||||
|
||||
// expand
|
||||
STATIC_MALLOC_INTERFACE void *_expand(void *, size_t) {
|
||||
// _expand is used in realloc-like functions to resize the buffer if possible.
|
||||
// We don't want memory to stand still while resizing buffers, so return 0.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
STATIC_MALLOC_INTERFACE void *_expand_dbg(void *, size_t, int, const char *,
|
||||
int) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We need to provide symbols for all the debug CRT functions if we decide to
|
||||
// provide any. Most of these functions make no sense under ASan and so we
|
||||
// make them no-ops.
|
||||
long _CrtSetBreakAlloc(long const) { return ~0; }
|
||||
|
||||
void _CrtSetDbgBlockType(void *const, int const) { return; }
|
||||
|
||||
typedef int(__cdecl *CRT_ALLOC_HOOK)(int, void *, size_t, int, long,
|
||||
const unsigned char *, int);
|
||||
|
||||
CRT_ALLOC_HOOK _CrtGetAllocHook() { return nullptr; }
|
||||
|
||||
CRT_ALLOC_HOOK _CrtSetAllocHook(CRT_ALLOC_HOOK const hook) { return hook; }
|
||||
|
||||
int _CrtCheckMemory() { return 1; }
|
||||
|
||||
int _CrtSetDbgFlag(int const new_bits) { return new_bits; }
|
||||
|
||||
typedef void (*CrtDoForAllClientObjectsCallback)(void *, void *);
|
||||
|
||||
void _CrtDoForAllClientObjects(CrtDoForAllClientObjectsCallback const,
|
||||
void *const) {
|
||||
return;
|
||||
}
|
||||
|
||||
int _CrtIsValidPointer(void const *const p, unsigned int const, int const) {
|
||||
return p != nullptr;
|
||||
}
|
||||
|
||||
int _CrtIsValidHeapPointer(void const *const block) {
|
||||
if (!block) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __sanitizer_get_ownership(block);
|
||||
}
|
||||
|
||||
int _CrtIsMemoryBlock(void const *const, unsigned const, long *const,
|
||||
char **const, int *const) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _CrtReportBlockType(void const *const) { return -1; }
|
||||
|
||||
typedef void(__cdecl *CRT_DUMP_CLIENT)(void *, size_t);
|
||||
|
||||
CRT_DUMP_CLIENT _CrtGetDumpClient() { return nullptr; }
|
||||
|
||||
CRT_DUMP_CLIENT _CrtSetDumpClient(CRT_DUMP_CLIENT new_client) {
|
||||
return new_client;
|
||||
}
|
||||
|
||||
void _CrtMemCheckpoint(void *const) { return; }
|
||||
|
||||
int _CrtMemDifference(void *const, void const *const, void const *const) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _CrtMemDumpAllObjectsSince(void const *const) { return; }
|
||||
|
||||
int _CrtDumpMemoryLeaks() { return 0; }
|
||||
|
||||
void _CrtMemDumpStatistics(void const *const) { return; }
|
||||
|
||||
int _crtDbgFlag{0};
|
||||
long _crtBreakAlloc{-1};
|
||||
CRT_DUMP_CLIENT _pfnDumpClient{nullptr};
|
||||
|
||||
int *__p__crtDbgFlag() { return &_crtDbgFlag; }
|
||||
|
||||
long *__p__crtBreakAlloc() { return &_crtBreakAlloc; }
|
||||
|
||||
// TODO: These were added upstream but conflict with definitions in ucrtbased.
|
||||
// int _CrtDbgReport(int, const char *, int, const char *, const char *, ...) {
|
||||
// ShowStatsAndAbort();
|
||||
// }
|
||||
//
|
||||
// int _CrtDbgReportW(int reportType, const wchar_t *, int, const wchar_t *,
|
||||
// const wchar_t *, ...) {
|
||||
// ShowStatsAndAbort();
|
||||
// }
|
||||
//
|
||||
// int _CrtSetReportMode(int, int) { return 0; }
|
||||
|
||||
} // extern "C"
|
||||
#endif // SANITIZER_STATIC_RUNTIME_THUNK
|
||||
|
||||
@ -1,112 +1,112 @@
|
||||
//===-- asan_win_common_runtime_thunk.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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// This file defines things that need to be present in the application modules
|
||||
// to interact with the ASan DLL runtime correctly and can't be implemented
|
||||
// using the default "import library" generated when linking the DLL.
|
||||
//
|
||||
// This includes:
|
||||
// - Cloning shadow memory dynamic address from ASAN DLL
|
||||
// - Creating weak aliases to default implementation imported from asan dll
|
||||
// - Forwarding the detect_stack_use_after_return runtime option
|
||||
// - installing a custom SEH handler
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) || \
|
||||
defined(SANITIZER_STATIC_RUNTIME_THUNK)
|
||||
# define SANITIZER_IMPORT_INTERFACE 1
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include "asan_win_common_runtime_thunk.h"
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# include "sanitizer_common/sanitizer_win_defs.h"
|
||||
# include "sanitizer_common/sanitizer_win_thunk_interception.h"
|
||||
|
||||
// Define weak alias for all weak functions imported from asan dll.
|
||||
# define INTERFACE_FUNCTION(Name)
|
||||
# define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
|
||||
# include "asan_interface.inc"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Define a copy of __asan_option_detect_stack_use_after_return that should be
|
||||
// used when linking an MD runtime with a set of object files on Windows.
|
||||
//
|
||||
// The ASan MD runtime dllexports '__asan_option_detect_stack_use_after_return',
|
||||
// so normally we would just dllimport it. Unfortunately, the dllimport
|
||||
// attribute adds __imp_ prefix to the symbol name of a variable.
|
||||
// Since in general we don't know if a given TU is going to be used
|
||||
// with a MT or MD runtime and we don't want to use ugly __imp_ names on Windows
|
||||
// just to work around this issue, let's clone the variable that is constant
|
||||
// after initialization anyways.
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllimport) int __asan_should_detect_stack_use_after_return();
|
||||
int __asan_option_detect_stack_use_after_return;
|
||||
|
||||
__declspec(dllimport) void *__asan_get_shadow_memory_dynamic_address();
|
||||
void *__asan_shadow_memory_dynamic_address;
|
||||
|
||||
static void __asan_initialize_cloned_variables() {
|
||||
__asan_option_detect_stack_use_after_return =
|
||||
__asan_should_detect_stack_use_after_return();
|
||||
__asan_shadow_memory_dynamic_address =
|
||||
__asan_get_shadow_memory_dynamic_address();
|
||||
}
|
||||
}
|
||||
|
||||
static int asan_thunk_init() {
|
||||
__asan_initialize_cloned_variables();
|
||||
|
||||
# ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
__asan_initialize_static_thunk();
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void WINAPI asan_thread_init(void *mod, unsigned long reason,
|
||||
void *reserved) {
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
asan_thunk_init();
|
||||
}
|
||||
}
|
||||
|
||||
// Our cloned variables must be initialized before C/C++ constructors. If TLS
|
||||
// is used, our .CRT$XLAB initializer will run first. If not, our .CRT$XIB
|
||||
// initializer is needed as a backup.
|
||||
extern "C" __declspec(allocate(".CRT$XIB")) int (*__asan_thunk_init)() =
|
||||
asan_thunk_init;
|
||||
WIN_FORCE_LINK(__asan_thunk_init);
|
||||
|
||||
extern "C" __declspec(allocate(".CRT$XLAB")) void(WINAPI *__asan_tls_init)(
|
||||
void *, unsigned long, void *) = asan_thread_init;
|
||||
WIN_FORCE_LINK(__asan_tls_init);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ASan SEH handling.
|
||||
// We need to set the ASan-specific SEH handler at the end of CRT initialization
|
||||
// of each module (see also asan_win.cpp).
|
||||
extern "C" {
|
||||
__declspec(dllimport) int __asan_set_seh_filter();
|
||||
static int SetSEHFilter() { return __asan_set_seh_filter(); }
|
||||
|
||||
// Unfortunately, putting a pointer to __asan_set_seh_filter into
|
||||
// __asan_intercept_seh gets optimized out, so we have to use an extra function.
|
||||
extern "C" __declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
|
||||
SetSEHFilter;
|
||||
WIN_FORCE_LINK(__asan_seh_interceptor);
|
||||
}
|
||||
|
||||
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||
|
||||
#endif // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) ||
|
||||
// defined(SANITIZER_STATIC_RUNTIME_THUNK)
|
||||
//===-- asan_win_common_runtime_thunk.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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// This file defines things that need to be present in the application modules
|
||||
// to interact with the ASan DLL runtime correctly and can't be implemented
|
||||
// using the default "import library" generated when linking the DLL.
|
||||
//
|
||||
// This includes:
|
||||
// - Cloning shadow memory dynamic address from ASAN DLL
|
||||
// - Creating weak aliases to default implementation imported from asan dll
|
||||
// - Forwarding the detect_stack_use_after_return runtime option
|
||||
// - installing a custom SEH handler
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) || \
|
||||
defined(SANITIZER_STATIC_RUNTIME_THUNK)
|
||||
# define SANITIZER_IMPORT_INTERFACE 1
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include "asan_win_common_runtime_thunk.h"
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# include "sanitizer_common/sanitizer_win_defs.h"
|
||||
# include "sanitizer_common/sanitizer_win_thunk_interception.h"
|
||||
|
||||
// Define weak alias for all weak functions imported from asan dll.
|
||||
# define INTERFACE_FUNCTION(Name)
|
||||
# define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
|
||||
# include "asan_interface.inc"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Define a copy of __asan_option_detect_stack_use_after_return that should be
|
||||
// used when linking an MD runtime with a set of object files on Windows.
|
||||
//
|
||||
// The ASan MD runtime dllexports '__asan_option_detect_stack_use_after_return',
|
||||
// so normally we would just dllimport it. Unfortunately, the dllimport
|
||||
// attribute adds __imp_ prefix to the symbol name of a variable.
|
||||
// Since in general we don't know if a given TU is going to be used
|
||||
// with a MT or MD runtime and we don't want to use ugly __imp_ names on Windows
|
||||
// just to work around this issue, let's clone the variable that is constant
|
||||
// after initialization anyways.
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllimport) int __asan_should_detect_stack_use_after_return();
|
||||
int __asan_option_detect_stack_use_after_return;
|
||||
|
||||
__declspec(dllimport) void *__asan_get_shadow_memory_dynamic_address();
|
||||
void *__asan_shadow_memory_dynamic_address;
|
||||
|
||||
static void __asan_initialize_cloned_variables() {
|
||||
__asan_option_detect_stack_use_after_return =
|
||||
__asan_should_detect_stack_use_after_return();
|
||||
__asan_shadow_memory_dynamic_address =
|
||||
__asan_get_shadow_memory_dynamic_address();
|
||||
}
|
||||
}
|
||||
|
||||
static int asan_thunk_init() {
|
||||
__asan_initialize_cloned_variables();
|
||||
|
||||
# ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
__asan_initialize_static_thunk();
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void WINAPI asan_thread_init(void *mod, unsigned long reason,
|
||||
void *reserved) {
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
asan_thunk_init();
|
||||
}
|
||||
}
|
||||
|
||||
// Our cloned variables must be initialized before C/C++ constructors. If TLS
|
||||
// is used, our .CRT$XLAB initializer will run first. If not, our .CRT$XIB
|
||||
// initializer is needed as a backup.
|
||||
extern "C" __declspec(allocate(".CRT$XIB")) int (*__asan_thunk_init)() =
|
||||
asan_thunk_init;
|
||||
WIN_FORCE_LINK(__asan_thunk_init);
|
||||
|
||||
extern "C" __declspec(allocate(".CRT$XLAB")) void(WINAPI *__asan_tls_init)(
|
||||
void *, unsigned long, void *) = asan_thread_init;
|
||||
WIN_FORCE_LINK(__asan_tls_init);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ASan SEH handling.
|
||||
// We need to set the ASan-specific SEH handler at the end of CRT initialization
|
||||
// of each module (see also asan_win.cpp).
|
||||
extern "C" {
|
||||
__declspec(dllimport) int __asan_set_seh_filter();
|
||||
static int SetSEHFilter() { return __asan_set_seh_filter(); }
|
||||
|
||||
// Unfortunately, putting a pointer to __asan_set_seh_filter into
|
||||
// __asan_intercept_seh gets optimized out, so we have to use an extra function.
|
||||
extern "C" __declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
|
||||
SetSEHFilter;
|
||||
WIN_FORCE_LINK(__asan_seh_interceptor);
|
||||
}
|
||||
|
||||
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
||||
|
||||
#endif // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) ||
|
||||
// defined(SANITIZER_STATIC_RUNTIME_THUNK)
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
//===-- asan_win_common_runtime_thunk.h -------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// This file defines things that need to be present in the application modules
|
||||
// to interact with the ASan DLL runtime correctly and can't be implemented
|
||||
// using the default "import library" generated when linking the DLL.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if defined(SANITIZER_STATIC_RUNTIME_THUNK) || \
|
||||
defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
|
||||
# include "sanitizer_common/sanitizer_win_defs.h"
|
||||
|
||||
# pragma section(".CRT$XIB", long, \
|
||||
read) // C initializer (during C init before dyninit)
|
||||
# pragma section(".CRT$XID", long, \
|
||||
read) // First C initializer after CRT initializers
|
||||
# pragma section(".CRT$XCAB", long, \
|
||||
read) // First C++ initializer after startup initializers
|
||||
|
||||
# pragma section(".CRT$XTW", long, read) // First ASAN globals terminator
|
||||
# pragma section(".CRT$XTY", long, read) // Last ASAN globals terminator
|
||||
|
||||
# pragma section(".CRT$XLAB", long, read) // First TLS initializer
|
||||
|
||||
# ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
extern "C" void __asan_initialize_static_thunk();
|
||||
# endif
|
||||
|
||||
#endif // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
|
||||
//===-- asan_win_common_runtime_thunk.h -------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// This file defines things that need to be present in the application modules
|
||||
// to interact with the ASan DLL runtime correctly and can't be implemented
|
||||
// using the default "import library" generated when linking the DLL.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if defined(SANITIZER_STATIC_RUNTIME_THUNK) || \
|
||||
defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
|
||||
# include "sanitizer_common/sanitizer_win_defs.h"
|
||||
|
||||
# pragma section(".CRT$XIB", long, \
|
||||
read) // C initializer (during C init before dyninit)
|
||||
# pragma section(".CRT$XID", long, \
|
||||
read) // First C initializer after CRT initializers
|
||||
# pragma section(".CRT$XCAB", long, \
|
||||
read) // First C++ initializer after startup initializers
|
||||
|
||||
# pragma section(".CRT$XTW", long, read) // First ASAN globals terminator
|
||||
# pragma section(".CRT$XTY", long, read) // Last ASAN globals terminator
|
||||
|
||||
# pragma section(".CRT$XLAB", long, read) // First TLS initializer
|
||||
|
||||
# ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
extern "C" void __asan_initialize_static_thunk();
|
||||
# endif
|
||||
|
||||
#endif // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
|
||||
// defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
|
||||
@ -1,110 +1,110 @@
|
||||
//===-- asan_win_static_runtime_thunk.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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// This file defines a family of thunks that should be statically linked into
|
||||
// modules that are statically linked with the C Runtime in order to delegate
|
||||
// the calls to the ASAN runtime DLL.
|
||||
// See https://github.com/google/sanitizers/issues/209 for the details.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
# include "asan_init_version.h"
|
||||
# include "asan_interface_internal.h"
|
||||
# include "asan_win_common_runtime_thunk.h"
|
||||
# include "sanitizer_common/sanitizer_platform_interceptors.h"
|
||||
# include "sanitizer_common/sanitizer_win_defs.h"
|
||||
# include "sanitizer_common/sanitizer_win_thunk_interception.h"
|
||||
|
||||
# if defined(_MSC_VER) && !defined(__clang__)
|
||||
// Disable warnings such as: 'void memchr(void)': incorrect number of arguments
|
||||
// for intrinsic function, expected '3' arguments.
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4392)
|
||||
# endif
|
||||
|
||||
# define INTERCEPT_LIBRARY_FUNCTION_ASAN(X) \
|
||||
INTERCEPT_LIBRARY_FUNCTION(X, "__asan_wrap_" #X)
|
||||
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(atoi);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(atol);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(atoll);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(frexp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(longjmp);
|
||||
# if SANITIZER_INTERCEPT_MEMCHR
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memchr);
|
||||
# endif
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memcmp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memcpy);
|
||||
# ifndef _WIN64
|
||||
// memmove and memcpy share an implementation on amd64
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memmove);
|
||||
# endif
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memset);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcat);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strchr);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcmp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcpy);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcspn);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(_strdup);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strlen);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strncat);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strncmp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strncpy);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strnlen);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strpbrk);
|
||||
// INTERCEPT_LIBRARY_FUNCTION_ASAN(strrchr);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strspn);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strstr);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strtok);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strtol);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(wcslen);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(wcsnlen);
|
||||
|
||||
# if defined(_MSC_VER) && !defined(__clang__)
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
# ifdef _WIN64
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(__C_specific_handler);
|
||||
# else
|
||||
extern "C" void abort();
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler3);
|
||||
// _except_handler4 checks -GS cookie which is different for each module, so we
|
||||
// can't use INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler4), need to apply
|
||||
// manually
|
||||
extern "C" int _except_handler4(void *, void *, void *, void *);
|
||||
static int (*real_except_handler4)(void *, void *, void *,
|
||||
void *) = &_except_handler4;
|
||||
static int intercept_except_handler4(void *a, void *b, void *c, void *d) {
|
||||
__asan_handle_no_return();
|
||||
return real_except_handler4(a, b, c, d);
|
||||
}
|
||||
# endif
|
||||
|
||||
// Windows specific functions not included in asan_interface.inc.
|
||||
// INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
|
||||
// INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
|
||||
// INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)
|
||||
|
||||
extern "C" void __asan_initialize_static_thunk() {
|
||||
# ifndef _WIN64
|
||||
if (real_except_handler4 == &_except_handler4) {
|
||||
// Single threaded, no need for synchronization.
|
||||
if (!__sanitizer_override_function_by_addr(
|
||||
reinterpret_cast<__sanitizer::uptr>(&intercept_except_handler4),
|
||||
reinterpret_cast<__sanitizer::uptr>(&_except_handler4),
|
||||
reinterpret_cast<__sanitizer::uptr*>(&real_except_handler4))) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // SANITIZER_DLL_THUNK
|
||||
//===-- asan_win_static_runtime_thunk.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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// This file defines a family of thunks that should be statically linked into
|
||||
// modules that are statically linked with the C Runtime in order to delegate
|
||||
// the calls to the ASAN runtime DLL.
|
||||
// See https://github.com/google/sanitizers/issues/209 for the details.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef SANITIZER_STATIC_RUNTIME_THUNK
|
||||
# include "asan_init_version.h"
|
||||
# include "asan_interface_internal.h"
|
||||
# include "asan_win_common_runtime_thunk.h"
|
||||
# include "sanitizer_common/sanitizer_platform_interceptors.h"
|
||||
# include "sanitizer_common/sanitizer_win_defs.h"
|
||||
# include "sanitizer_common/sanitizer_win_thunk_interception.h"
|
||||
|
||||
# if defined(_MSC_VER) && !defined(__clang__)
|
||||
// Disable warnings such as: 'void memchr(void)': incorrect number of arguments
|
||||
// for intrinsic function, expected '3' arguments.
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4392)
|
||||
# endif
|
||||
|
||||
# define INTERCEPT_LIBRARY_FUNCTION_ASAN(X) \
|
||||
INTERCEPT_LIBRARY_FUNCTION(X, "__asan_wrap_" #X)
|
||||
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(atoi);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(atol);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(atoll);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(frexp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(longjmp);
|
||||
# if SANITIZER_INTERCEPT_MEMCHR
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memchr);
|
||||
# endif
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memcmp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memcpy);
|
||||
# ifndef _WIN64
|
||||
// memmove and memcpy share an implementation on amd64
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memmove);
|
||||
# endif
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(memset);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcat);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strchr);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcmp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcpy);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcspn);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(_strdup);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strlen);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strncat);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strncmp);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strncpy);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strnlen);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strpbrk);
|
||||
// INTERCEPT_LIBRARY_FUNCTION_ASAN(strrchr);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strspn);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strstr);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strtok);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(strtol);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(wcslen);
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(wcsnlen);
|
||||
|
||||
# if defined(_MSC_VER) && !defined(__clang__)
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
# ifdef _WIN64
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(__C_specific_handler);
|
||||
# else
|
||||
extern "C" void abort();
|
||||
INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler3);
|
||||
// _except_handler4 checks -GS cookie which is different for each module, so we
|
||||
// can't use INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler4), need to apply
|
||||
// manually
|
||||
extern "C" int _except_handler4(void *, void *, void *, void *);
|
||||
static int (*real_except_handler4)(void *, void *, void *,
|
||||
void *) = &_except_handler4;
|
||||
static int intercept_except_handler4(void *a, void *b, void *c, void *d) {
|
||||
__asan_handle_no_return();
|
||||
return real_except_handler4(a, b, c, d);
|
||||
}
|
||||
# endif
|
||||
|
||||
// Windows specific functions not included in asan_interface.inc.
|
||||
// INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
|
||||
// INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
|
||||
// INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)
|
||||
|
||||
extern "C" void __asan_initialize_static_thunk() {
|
||||
# ifndef _WIN64
|
||||
if (real_except_handler4 == &_except_handler4) {
|
||||
// Single threaded, no need for synchronization.
|
||||
if (!__sanitizer_override_function_by_addr(
|
||||
reinterpret_cast<__sanitizer::uptr>(&intercept_except_handler4),
|
||||
reinterpret_cast<__sanitizer::uptr>(&_except_handler4),
|
||||
reinterpret_cast<__sanitizer::uptr*>(&real_except_handler4))) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // SANITIZER_DLL_THUNK
|
||||
|
||||
@ -1,156 +1,156 @@
|
||||
//===-- sanitizer_win_interception.cpp -------------------- --*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Windows-specific export surface to provide interception for parts of the
|
||||
// runtime that are always statically linked, both for overriding user-defined
|
||||
// functions as well as registering weak functions that the ASAN runtime should
|
||||
// use over defaults.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "sanitizer_platform.h"
|
||||
#if SANITIZER_WINDOWS
|
||||
# include <stddef.h>
|
||||
|
||||
# include "interception/interception.h"
|
||||
# include "sanitizer_addrhashmap.h"
|
||||
# include "sanitizer_common.h"
|
||||
# include "sanitizer_internal_defs.h"
|
||||
# include "sanitizer_placement_new.h"
|
||||
# include "sanitizer_win_immortalize.h"
|
||||
# include "sanitizer_win_interception.h"
|
||||
|
||||
using namespace __sanitizer;
|
||||
|
||||
extern "C" void *__ImageBase;
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
static uptr GetSanitizerDllExport(const char *export_name) {
|
||||
const uptr function_address =
|
||||
__interception::InternalGetProcAddress(&__ImageBase, export_name);
|
||||
if (function_address == 0) {
|
||||
Report("ERROR: Failed to find sanitizer DLL export '%s'\n", export_name);
|
||||
CHECK("Failed to find sanitizer DLL export" && 0);
|
||||
}
|
||||
return function_address;
|
||||
}
|
||||
|
||||
struct WeakCallbackList {
|
||||
explicit constexpr WeakCallbackList(RegisterWeakFunctionCallback cb)
|
||||
: callback(cb), next(nullptr) {}
|
||||
|
||||
static void *operator new(size_t size) { return InternalAlloc(size); }
|
||||
|
||||
static void operator delete(void *p) { InternalFree(p); }
|
||||
|
||||
RegisterWeakFunctionCallback callback;
|
||||
WeakCallbackList *next;
|
||||
};
|
||||
using WeakCallbackMap = AddrHashMap<WeakCallbackList *, 11>;
|
||||
|
||||
static WeakCallbackMap *GetWeakCallbackMap() {
|
||||
return &immortalize<WeakCallbackMap>();
|
||||
}
|
||||
|
||||
void AddRegisterWeakFunctionCallback(uptr export_address,
|
||||
RegisterWeakFunctionCallback cb) {
|
||||
WeakCallbackMap::Handle h_find_or_create(GetWeakCallbackMap(), export_address,
|
||||
false, true);
|
||||
CHECK(h_find_or_create.exists());
|
||||
if (h_find_or_create.created()) {
|
||||
*h_find_or_create = new WeakCallbackList(cb);
|
||||
} else {
|
||||
(*h_find_or_create)->next = new WeakCallbackList(cb);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunWeakFunctionCallbacks(uptr export_address) {
|
||||
WeakCallbackMap::Handle h_find(GetWeakCallbackMap(), export_address, false,
|
||||
false);
|
||||
if (!h_find.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
WeakCallbackList *list = *h_find;
|
||||
do {
|
||||
list->callback();
|
||||
} while ((list = list->next));
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
extern "C" __declspec(dllexport) bool __cdecl __sanitizer_override_function(
|
||||
const char *export_name, const uptr user_function,
|
||||
uptr *const old_user_function) {
|
||||
CHECK(export_name);
|
||||
CHECK(user_function);
|
||||
|
||||
const uptr sanitizer_function = GetSanitizerDllExport(export_name);
|
||||
|
||||
const bool function_overridden = __interception::OverrideFunction(
|
||||
user_function, sanitizer_function, old_user_function);
|
||||
if (!function_overridden) {
|
||||
Report(
|
||||
"ERROR: Failed to override local function at '%p' with sanitizer "
|
||||
"function '%s'\n",
|
||||
user_function, export_name);
|
||||
CHECK("Failed to replace local function with sanitizer version." && 0);
|
||||
}
|
||||
|
||||
return function_overridden;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__declspec(dllexport) bool __cdecl __sanitizer_override_function_by_addr(
|
||||
const uptr source_function, const uptr target_function,
|
||||
uptr *const old_target_function) {
|
||||
CHECK(source_function);
|
||||
CHECK(target_function);
|
||||
|
||||
const bool function_overridden = __interception::OverrideFunction(
|
||||
target_function, source_function, old_target_function);
|
||||
if (!function_overridden) {
|
||||
Report(
|
||||
"ERROR: Failed to override function at '%p' with function at "
|
||||
"'%p'\n",
|
||||
target_function, source_function);
|
||||
CHECK("Failed to apply function override." && 0);
|
||||
}
|
||||
|
||||
return function_overridden;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__declspec(dllexport) bool __cdecl __sanitizer_register_weak_function(
|
||||
const char *export_name, const uptr user_function,
|
||||
uptr *const old_user_function) {
|
||||
CHECK(export_name);
|
||||
CHECK(user_function);
|
||||
|
||||
const uptr sanitizer_function = GetSanitizerDllExport(export_name);
|
||||
|
||||
const bool function_overridden = __interception::OverrideFunction(
|
||||
sanitizer_function, user_function, old_user_function);
|
||||
if (!function_overridden) {
|
||||
Report(
|
||||
"ERROR: Failed to register local function at '%p' to be used in "
|
||||
"place of sanitizer function '%s'\n.",
|
||||
user_function, export_name);
|
||||
CHECK("Failed to register weak function." && 0);
|
||||
}
|
||||
|
||||
// Note that thread-safety of RunWeakFunctionCallbacks in InitializeFlags
|
||||
// depends on __sanitizer_register_weak_functions being called during the
|
||||
// loader lock.
|
||||
RunWeakFunctionCallbacks(sanitizer_function);
|
||||
|
||||
return function_overridden;
|
||||
}
|
||||
|
||||
#endif // SANITIZER_WINDOWS
|
||||
//===-- sanitizer_win_interception.cpp -------------------- --*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Windows-specific export surface to provide interception for parts of the
|
||||
// runtime that are always statically linked, both for overriding user-defined
|
||||
// functions as well as registering weak functions that the ASAN runtime should
|
||||
// use over defaults.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "sanitizer_platform.h"
|
||||
#if SANITIZER_WINDOWS
|
||||
# include <stddef.h>
|
||||
|
||||
# include "interception/interception.h"
|
||||
# include "sanitizer_addrhashmap.h"
|
||||
# include "sanitizer_common.h"
|
||||
# include "sanitizer_internal_defs.h"
|
||||
# include "sanitizer_placement_new.h"
|
||||
# include "sanitizer_win_immortalize.h"
|
||||
# include "sanitizer_win_interception.h"
|
||||
|
||||
using namespace __sanitizer;
|
||||
|
||||
extern "C" void *__ImageBase;
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
static uptr GetSanitizerDllExport(const char *export_name) {
|
||||
const uptr function_address =
|
||||
__interception::InternalGetProcAddress(&__ImageBase, export_name);
|
||||
if (function_address == 0) {
|
||||
Report("ERROR: Failed to find sanitizer DLL export '%s'\n", export_name);
|
||||
CHECK("Failed to find sanitizer DLL export" && 0);
|
||||
}
|
||||
return function_address;
|
||||
}
|
||||
|
||||
struct WeakCallbackList {
|
||||
explicit constexpr WeakCallbackList(RegisterWeakFunctionCallback cb)
|
||||
: callback(cb), next(nullptr) {}
|
||||
|
||||
static void *operator new(size_t size) { return InternalAlloc(size); }
|
||||
|
||||
static void operator delete(void *p) { InternalFree(p); }
|
||||
|
||||
RegisterWeakFunctionCallback callback;
|
||||
WeakCallbackList *next;
|
||||
};
|
||||
using WeakCallbackMap = AddrHashMap<WeakCallbackList *, 11>;
|
||||
|
||||
static WeakCallbackMap *GetWeakCallbackMap() {
|
||||
return &immortalize<WeakCallbackMap>();
|
||||
}
|
||||
|
||||
void AddRegisterWeakFunctionCallback(uptr export_address,
|
||||
RegisterWeakFunctionCallback cb) {
|
||||
WeakCallbackMap::Handle h_find_or_create(GetWeakCallbackMap(), export_address,
|
||||
false, true);
|
||||
CHECK(h_find_or_create.exists());
|
||||
if (h_find_or_create.created()) {
|
||||
*h_find_or_create = new WeakCallbackList(cb);
|
||||
} else {
|
||||
(*h_find_or_create)->next = new WeakCallbackList(cb);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunWeakFunctionCallbacks(uptr export_address) {
|
||||
WeakCallbackMap::Handle h_find(GetWeakCallbackMap(), export_address, false,
|
||||
false);
|
||||
if (!h_find.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
WeakCallbackList *list = *h_find;
|
||||
do {
|
||||
list->callback();
|
||||
} while ((list = list->next));
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
extern "C" __declspec(dllexport) bool __cdecl __sanitizer_override_function(
|
||||
const char *export_name, const uptr user_function,
|
||||
uptr *const old_user_function) {
|
||||
CHECK(export_name);
|
||||
CHECK(user_function);
|
||||
|
||||
const uptr sanitizer_function = GetSanitizerDllExport(export_name);
|
||||
|
||||
const bool function_overridden = __interception::OverrideFunction(
|
||||
user_function, sanitizer_function, old_user_function);
|
||||
if (!function_overridden) {
|
||||
Report(
|
||||
"ERROR: Failed to override local function at '%p' with sanitizer "
|
||||
"function '%s'\n",
|
||||
user_function, export_name);
|
||||
CHECK("Failed to replace local function with sanitizer version." && 0);
|
||||
}
|
||||
|
||||
return function_overridden;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__declspec(dllexport) bool __cdecl __sanitizer_override_function_by_addr(
|
||||
const uptr source_function, const uptr target_function,
|
||||
uptr *const old_target_function) {
|
||||
CHECK(source_function);
|
||||
CHECK(target_function);
|
||||
|
||||
const bool function_overridden = __interception::OverrideFunction(
|
||||
target_function, source_function, old_target_function);
|
||||
if (!function_overridden) {
|
||||
Report(
|
||||
"ERROR: Failed to override function at '%p' with function at "
|
||||
"'%p'\n",
|
||||
target_function, source_function);
|
||||
CHECK("Failed to apply function override." && 0);
|
||||
}
|
||||
|
||||
return function_overridden;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__declspec(dllexport) bool __cdecl __sanitizer_register_weak_function(
|
||||
const char *export_name, const uptr user_function,
|
||||
uptr *const old_user_function) {
|
||||
CHECK(export_name);
|
||||
CHECK(user_function);
|
||||
|
||||
const uptr sanitizer_function = GetSanitizerDllExport(export_name);
|
||||
|
||||
const bool function_overridden = __interception::OverrideFunction(
|
||||
sanitizer_function, user_function, old_user_function);
|
||||
if (!function_overridden) {
|
||||
Report(
|
||||
"ERROR: Failed to register local function at '%p' to be used in "
|
||||
"place of sanitizer function '%s'\n.",
|
||||
user_function, export_name);
|
||||
CHECK("Failed to register weak function." && 0);
|
||||
}
|
||||
|
||||
// Note that thread-safety of RunWeakFunctionCallbacks in InitializeFlags
|
||||
// depends on __sanitizer_register_weak_functions being called during the
|
||||
// loader lock.
|
||||
RunWeakFunctionCallbacks(sanitizer_function);
|
||||
|
||||
return function_overridden;
|
||||
}
|
||||
|
||||
#endif // SANITIZER_WINDOWS
|
||||
|
||||
@ -1,32 +1,32 @@
|
||||
//===-- sanitizer_win_interception.h ---------------------- --*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Windows-specific export surface to provide interception for parts of the
|
||||
// runtime that are always statically linked, both for overriding user-defined
|
||||
// functions as well as registering weak functions that the ASAN runtime should
|
||||
// use over defaults.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SANITIZER_WIN_INTERCEPTION_H
|
||||
#define SANITIZER_WIN_INTERCEPTION_H
|
||||
|
||||
#include "sanitizer_platform.h"
|
||||
#if SANITIZER_WINDOWS
|
||||
|
||||
# include "sanitizer_common.h"
|
||||
# include "sanitizer_internal_defs.h"
|
||||
|
||||
namespace __sanitizer {
|
||||
using RegisterWeakFunctionCallback = void (*)();
|
||||
void AddRegisterWeakFunctionCallback(uptr export_address,
|
||||
RegisterWeakFunctionCallback cb);
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_WINDOWS
|
||||
//===-- sanitizer_win_interception.h ---------------------- --*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Windows-specific export surface to provide interception for parts of the
|
||||
// runtime that are always statically linked, both for overriding user-defined
|
||||
// functions as well as registering weak functions that the ASAN runtime should
|
||||
// use over defaults.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SANITIZER_WIN_INTERCEPTION_H
|
||||
#define SANITIZER_WIN_INTERCEPTION_H
|
||||
|
||||
#include "sanitizer_platform.h"
|
||||
#if SANITIZER_WINDOWS
|
||||
|
||||
# include "sanitizer_common.h"
|
||||
# include "sanitizer_internal_defs.h"
|
||||
|
||||
namespace __sanitizer {
|
||||
using RegisterWeakFunctionCallback = void (*)();
|
||||
void AddRegisterWeakFunctionCallback(uptr export_address,
|
||||
RegisterWeakFunctionCallback cb);
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_WINDOWS
|
||||
#endif // SANITIZER_WIN_INTERCEPTION_H
|
||||
@ -1,110 +1,110 @@
|
||||
//===-- sanitizer_win_thunk_interception.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 defines things that need to be present in the application modules
|
||||
// to interact with sanitizer DLL correctly and cannot be implemented using the
|
||||
// default "import library" generated when linking the DLL.
|
||||
//
|
||||
// This includes the common infrastructure required to intercept local functions
|
||||
// that must be replaced with sanitizer-aware versions, as well as the
|
||||
// registration of weak functions with the sanitizer DLL. With this in-place,
|
||||
// other sanitizer components can simply write to the .INTR and .WEAK sections.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if defined(SANITIZER_STATIC_RUNTIME_THUNK) || \
|
||||
defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
|
||||
# include "sanitizer_win_thunk_interception.h"
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
int override_function(const char *export_name, const uptr user_function) {
|
||||
if (!__sanitizer_override_function(export_name, user_function)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int register_weak(const char *export_name, const uptr user_function) {
|
||||
if (!__sanitizer_register_weak_function(export_name, user_function)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initialize_thunks(const sanitizer_thunk *first,
|
||||
const sanitizer_thunk *last) {
|
||||
for (const sanitizer_thunk *it = first; it < last; ++it) {
|
||||
if (*it) {
|
||||
(*it)();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace __sanitizer
|
||||
|
||||
# define INTERFACE_FUNCTION(Name)
|
||||
# define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
|
||||
# include "sanitizer_common_interface.inc"
|
||||
|
||||
# pragma section(".INTR$A", read) // intercept begin
|
||||
# pragma section(".INTR$Z", read) // intercept end
|
||||
# pragma section(".WEAK$A", read) // weak begin
|
||||
# pragma section(".WEAK$Z", read) // weak end
|
||||
|
||||
extern "C" {
|
||||
__declspec(allocate(
|
||||
".INTR$A")) sanitizer_thunk __sanitizer_intercept_thunk_begin;
|
||||
__declspec(allocate(".INTR$Z")) sanitizer_thunk __sanitizer_intercept_thunk_end;
|
||||
|
||||
__declspec(allocate(
|
||||
".WEAK$A")) sanitizer_thunk __sanitizer_register_weak_thunk_begin;
|
||||
__declspec(allocate(
|
||||
".WEAK$Z")) sanitizer_thunk __sanitizer_register_weak_thunk_end;
|
||||
}
|
||||
|
||||
extern "C" int __sanitizer_thunk_init() {
|
||||
// __sanitizer_static_thunk_init is expected to be called by only one thread.
|
||||
static bool flag = false;
|
||||
if (flag) {
|
||||
return 0;
|
||||
}
|
||||
flag = true;
|
||||
|
||||
__sanitizer::initialize_thunks(&__sanitizer_intercept_thunk_begin,
|
||||
&__sanitizer_intercept_thunk_end);
|
||||
__sanitizer::initialize_thunks(&__sanitizer_register_weak_thunk_begin,
|
||||
&__sanitizer_register_weak_thunk_end);
|
||||
|
||||
// In DLLs, the callbacks are expected to return 0,
|
||||
// otherwise CRT initialization fails.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We want to call dll_thunk_init before C/C++ initializers / constructors are
|
||||
// executed, otherwise functions like memset might be invoked.
|
||||
# pragma section(".CRT$XIB", long, read)
|
||||
__declspec(allocate(".CRT$XIB")) int (*__sanitizer_thunk_init_ptr)() =
|
||||
__sanitizer_thunk_init;
|
||||
|
||||
static void WINAPI sanitizer_thunk_thread_init(void *mod, unsigned long reason,
|
||||
void *reserved) {
|
||||
if (reason == /*DLL_PROCESS_ATTACH=*/1)
|
||||
__sanitizer_thunk_init();
|
||||
}
|
||||
|
||||
# pragma section(".CRT$XLAB", long, read)
|
||||
__declspec(allocate(".CRT$XLAB")) void(
|
||||
WINAPI *__sanitizer_thunk_thread_init_ptr)(void *, unsigned long, void *) =
|
||||
sanitizer_thunk_thread_init;
|
||||
|
||||
#endif // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
|
||||
//===-- sanitizer_win_thunk_interception.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 defines things that need to be present in the application modules
|
||||
// to interact with sanitizer DLL correctly and cannot be implemented using the
|
||||
// default "import library" generated when linking the DLL.
|
||||
//
|
||||
// This includes the common infrastructure required to intercept local functions
|
||||
// that must be replaced with sanitizer-aware versions, as well as the
|
||||
// registration of weak functions with the sanitizer DLL. With this in-place,
|
||||
// other sanitizer components can simply write to the .INTR and .WEAK sections.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if defined(SANITIZER_STATIC_RUNTIME_THUNK) || \
|
||||
defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
|
||||
# include "sanitizer_win_thunk_interception.h"
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
int override_function(const char *export_name, const uptr user_function) {
|
||||
if (!__sanitizer_override_function(export_name, user_function)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int register_weak(const char *export_name, const uptr user_function) {
|
||||
if (!__sanitizer_register_weak_function(export_name, user_function)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initialize_thunks(const sanitizer_thunk *first,
|
||||
const sanitizer_thunk *last) {
|
||||
for (const sanitizer_thunk *it = first; it < last; ++it) {
|
||||
if (*it) {
|
||||
(*it)();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace __sanitizer
|
||||
|
||||
# define INTERFACE_FUNCTION(Name)
|
||||
# define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
|
||||
# include "sanitizer_common_interface.inc"
|
||||
|
||||
# pragma section(".INTR$A", read) // intercept begin
|
||||
# pragma section(".INTR$Z", read) // intercept end
|
||||
# pragma section(".WEAK$A", read) // weak begin
|
||||
# pragma section(".WEAK$Z", read) // weak end
|
||||
|
||||
extern "C" {
|
||||
__declspec(allocate(
|
||||
".INTR$A")) sanitizer_thunk __sanitizer_intercept_thunk_begin;
|
||||
__declspec(allocate(".INTR$Z")) sanitizer_thunk __sanitizer_intercept_thunk_end;
|
||||
|
||||
__declspec(allocate(
|
||||
".WEAK$A")) sanitizer_thunk __sanitizer_register_weak_thunk_begin;
|
||||
__declspec(allocate(
|
||||
".WEAK$Z")) sanitizer_thunk __sanitizer_register_weak_thunk_end;
|
||||
}
|
||||
|
||||
extern "C" int __sanitizer_thunk_init() {
|
||||
// __sanitizer_static_thunk_init is expected to be called by only one thread.
|
||||
static bool flag = false;
|
||||
if (flag) {
|
||||
return 0;
|
||||
}
|
||||
flag = true;
|
||||
|
||||
__sanitizer::initialize_thunks(&__sanitizer_intercept_thunk_begin,
|
||||
&__sanitizer_intercept_thunk_end);
|
||||
__sanitizer::initialize_thunks(&__sanitizer_register_weak_thunk_begin,
|
||||
&__sanitizer_register_weak_thunk_end);
|
||||
|
||||
// In DLLs, the callbacks are expected to return 0,
|
||||
// otherwise CRT initialization fails.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We want to call dll_thunk_init before C/C++ initializers / constructors are
|
||||
// executed, otherwise functions like memset might be invoked.
|
||||
# pragma section(".CRT$XIB", long, read)
|
||||
__declspec(allocate(".CRT$XIB")) int (*__sanitizer_thunk_init_ptr)() =
|
||||
__sanitizer_thunk_init;
|
||||
|
||||
static void WINAPI sanitizer_thunk_thread_init(void *mod, unsigned long reason,
|
||||
void *reserved) {
|
||||
if (reason == /*DLL_PROCESS_ATTACH=*/1)
|
||||
__sanitizer_thunk_init();
|
||||
}
|
||||
|
||||
# pragma section(".CRT$XLAB", long, read)
|
||||
__declspec(allocate(".CRT$XLAB")) void(
|
||||
WINAPI *__sanitizer_thunk_thread_init_ptr)(void *, unsigned long, void *) =
|
||||
sanitizer_thunk_thread_init;
|
||||
|
||||
#endif // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
|
||||
// defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
|
||||
@ -1,22 +1,22 @@
|
||||
// RUN: %clang_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clang_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clang_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clang_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// When built as C on Linux, strndup is transformed to __strndup.
|
||||
// RUN: %clang_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// Unwind problem on arm: "main" is missing from the allocation stack trace.
|
||||
// RUN: %clang_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clang_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clang_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clang_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// When built as C on Linux, strndup is transformed to __strndup.
|
||||
// RUN: %clang_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// Unwind problem on arm: "main" is missing from the allocation stack trace.
|
||||
// UNSUPPORTED: target={{.*windows-msvc.*}},target=s390{{.*}},target=arm{{.*}} && !fast-unwinder-works
|
||||
|
||||
#include <string.h>
|
||||
|
||||
char kChars[] = { 'f', 'o', 'o' };
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *copy = strndup(kChars, 3);
|
||||
copy = strndup(kChars, 10);
|
||||
// CHECK: AddressSanitizer: global-buffer-overflow
|
||||
// CHECK: {{.*}}main {{.*}}.cpp:[[@LINE-2]]
|
||||
return *copy;
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
|
||||
char kChars[] = {'f', 'o', 'o'};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *copy = strndup(kChars, 3);
|
||||
copy = strndup(kChars, 10);
|
||||
// CHECK: AddressSanitizer: global-buffer-overflow
|
||||
// CHECK: {{.*}}main {{.*}}.cpp:[[@LINE-2]]
|
||||
return *copy;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user