asan_win.cc revision c11fa095b344c1423ba76822d5bde122b1676223
1//===-- asan_win.cc -------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// Windows-specific details. 13//===----------------------------------------------------------------------===// 14 15#include "sanitizer_common/sanitizer_platform.h" 16#if SANITIZER_WINDOWS 17#include <windows.h> 18 19#include <dbghelp.h> 20#include <stdlib.h> 21 22#include "asan_interceptors.h" 23#include "asan_internal.h" 24#include "asan_thread.h" 25#include "sanitizer_common/sanitizer_libc.h" 26#include "sanitizer_common/sanitizer_mutex.h" 27 28extern "C" { 29 SANITIZER_INTERFACE_ATTRIBUTE 30 bool __asan_should_detect_stack_use_after_return() { 31 __asan_init(); 32 return __asan_option_detect_stack_use_after_return; 33 } 34} 35 36namespace __asan { 37 38// ---------------------- Stacktraces, symbols, etc. ---------------- {{{1 39static BlockingMutex dbghelp_lock(LINKER_INITIALIZED); 40static bool dbghelp_initialized = false; 41#pragma comment(lib, "dbghelp.lib") 42 43// ---------------------- TSD ---------------- {{{1 44static bool tsd_key_inited = false; 45 46static __declspec(thread) void *fake_tsd = 0; 47 48void AsanTSDInit(void (*destructor)(void *tsd)) { 49 // FIXME: we're ignoring the destructor for now. 50 tsd_key_inited = true; 51} 52 53void *AsanTSDGet() { 54 CHECK(tsd_key_inited); 55 return fake_tsd; 56} 57 58void AsanTSDSet(void *tsd) { 59 CHECK(tsd_key_inited); 60 fake_tsd = tsd; 61} 62 63// ---------------------- Various stuff ---------------- {{{1 64void MaybeReexec() { 65 // No need to re-exec on Windows. 66} 67 68void *AsanDoesNotSupportStaticLinkage() { 69#if defined(_DEBUG) 70#error Please build the runtime with a non-debug CRT: /MD or /MT 71#endif 72 return 0; 73} 74 75void SetAlternateSignalStack() { 76 // FIXME: Decide what to do on Windows. 77} 78 79void UnsetAlternateSignalStack() { 80 // FIXME: Decide what to do on Windows. 81} 82 83void InstallSignalHandlers() { 84 // FIXME: Decide what to do on Windows. 85} 86 87void AsanPlatformThreadInit() { 88 // Nothing here for now. 89} 90 91void ReadContextStack(void *context, uptr *stack, uptr *ssize) { 92 UNIMPLEMENTED(); 93} 94 95} // namespace __asan 96 97// ---------------------- Interface ---------------- {{{1 98using namespace __asan; // NOLINT 99 100extern "C" { 101SANITIZER_INTERFACE_ATTRIBUTE NOINLINE 102bool __asan_symbolize(const void *addr, char *out_buffer, int buffer_size) { 103 BlockingMutexLock lock(&dbghelp_lock); 104 if (!dbghelp_initialized) { 105 SymSetOptions(SYMOPT_DEFERRED_LOADS | 106 SYMOPT_UNDNAME | 107 SYMOPT_LOAD_LINES); 108 CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE)); 109 // FIXME: We don't call SymCleanup() on exit yet - should we? 110 dbghelp_initialized = true; 111 } 112 113 // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx 114 char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; 115 PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; 116 symbol->SizeOfStruct = sizeof(SYMBOL_INFO); 117 symbol->MaxNameLen = MAX_SYM_NAME; 118 DWORD64 offset = 0; 119 BOOL got_objname = SymFromAddr(GetCurrentProcess(), 120 (DWORD64)addr, &offset, symbol); 121 if (!got_objname) 122 return false; 123 124 DWORD unused; 125 IMAGEHLP_LINE64 info; 126 info.SizeOfStruct = sizeof(IMAGEHLP_LINE64); 127 BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), 128 (DWORD64)addr, &unused, &info); 129 int written = 0; 130 out_buffer[0] = '\0'; 131 // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too. 132 if (got_fileline) { 133 written += internal_snprintf(out_buffer + written, buffer_size - written, 134 " %s %s:%d", symbol->Name, 135 info.FileName, info.LineNumber); 136 } else { 137 written += internal_snprintf(out_buffer + written, buffer_size - written, 138 " %s+0x%p", symbol->Name, offset); 139 } 140 return true; 141} 142} // extern "C" 143 144 145#endif // _WIN32 146