asan_win.cc revision e86e35fbe861e73c5991200510a028877427b3e7
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 int __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 63void PlatformTSDDtor(void *tsd) { 64 AsanThread::TSDDtor(tsd); 65} 66// ---------------------- Various stuff ---------------- {{{1 67void MaybeReexec() { 68 // No need to re-exec on Windows. 69} 70 71void *AsanDoesNotSupportStaticLinkage() { 72#if defined(_DEBUG) 73#error Please build the runtime with a non-debug CRT: /MD or /MT 74#endif 75 return 0; 76} 77 78void SetAlternateSignalStack() { 79 // FIXME: Decide what to do on Windows. 80} 81 82void UnsetAlternateSignalStack() { 83 // FIXME: Decide what to do on Windows. 84} 85 86void InstallSignalHandlers() { 87 // FIXME: Decide what to do on Windows. 88} 89 90void AsanPlatformThreadInit() { 91 // Nothing here for now. 92} 93 94void ReadContextStack(void *context, uptr *stack, uptr *ssize) { 95 UNIMPLEMENTED(); 96} 97 98} // namespace __asan 99 100// ---------------------- Interface ---------------- {{{1 101using namespace __asan; // NOLINT 102 103extern "C" { 104SANITIZER_INTERFACE_ATTRIBUTE NOINLINE 105bool __asan_symbolize(const void *addr, char *out_buffer, int buffer_size) { 106 BlockingMutexLock lock(&dbghelp_lock); 107 if (!dbghelp_initialized) { 108 SymSetOptions(SYMOPT_DEFERRED_LOADS | 109 SYMOPT_UNDNAME | 110 SYMOPT_LOAD_LINES); 111 CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE)); 112 // FIXME: We don't call SymCleanup() on exit yet - should we? 113 dbghelp_initialized = true; 114 } 115 116 // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx 117 char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; 118 PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; 119 symbol->SizeOfStruct = sizeof(SYMBOL_INFO); 120 symbol->MaxNameLen = MAX_SYM_NAME; 121 DWORD64 offset = 0; 122 BOOL got_objname = SymFromAddr(GetCurrentProcess(), 123 (DWORD64)addr, &offset, symbol); 124 if (!got_objname) 125 return false; 126 127 DWORD unused; 128 IMAGEHLP_LINE64 info; 129 info.SizeOfStruct = sizeof(IMAGEHLP_LINE64); 130 BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), 131 (DWORD64)addr, &unused, &info); 132 int written = 0; 133 out_buffer[0] = '\0'; 134 // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too. 135 if (got_fileline) { 136 written += internal_snprintf(out_buffer + written, buffer_size - written, 137 " %s %s:%d", symbol->Name, 138 info.FileName, info.LineNumber); 139 } else { 140 written += internal_snprintf(out_buffer + written, buffer_size - written, 141 " %s+0x%p", symbol->Name, offset); 142 } 143 return true; 144} 145} // extern "C" 146 147 148#endif // _WIN32 149