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 28 namespace __asan { 29 30 // ---------------------- Stacktraces, symbols, etc. ---------------- {{{1 31 static BlockingMutex dbghelp_lock(LINKER_INITIALIZED); 32 static bool dbghelp_initialized = false; 33 #pragma comment(lib, "dbghelp.lib") 34 35 // ---------------------- TSD ---------------- {{{1 36 static bool tsd_key_inited = false; 37 38 static __declspec(thread) void *fake_tsd = 0; 39 40 void AsanTSDInit(void (*destructor)(void *tsd)) { 41 // FIXME: we're ignoring the destructor for now. 42 tsd_key_inited = true; 43 } 44 45 void *AsanTSDGet() { 46 CHECK(tsd_key_inited); 47 return fake_tsd; 48 } 49 50 void AsanTSDSet(void *tsd) { 51 CHECK(tsd_key_inited); 52 fake_tsd = tsd; 53 } 54 55 // ---------------------- Various stuff ---------------- {{{1 56 void MaybeReexec() { 57 // No need to re-exec on Windows. 58 } 59 60 void *AsanDoesNotSupportStaticLinkage() { 61 #if defined(_DEBUG) 62 #error Please build the runtime with a non-debug CRT: /MD or /MT 63 #endif 64 return 0; 65 } 66 67 void SetAlternateSignalStack() { 68 // FIXME: Decide what to do on Windows. 69 } 70 71 void UnsetAlternateSignalStack() { 72 // FIXME: Decide what to do on Windows. 73 } 74 75 void InstallSignalHandlers() { 76 // FIXME: Decide what to do on Windows. 77 } 78 79 void AsanPlatformThreadInit() { 80 // Nothing here for now. 81 } 82 83 void ReadContextStack(void *context, uptr *stack, uptr *ssize) { 84 UNIMPLEMENTED(); 85 } 86 87 } // namespace __asan 88 89 // ---------------------- Interface ---------------- {{{1 90 using namespace __asan; // NOLINT 91 92 extern "C" { 93 SANITIZER_INTERFACE_ATTRIBUTE NOINLINE 94 bool __asan_symbolize(const void *addr, char *out_buffer, int buffer_size) { 95 BlockingMutexLock lock(&dbghelp_lock); 96 if (!dbghelp_initialized) { 97 SymSetOptions(SYMOPT_DEFERRED_LOADS | 98 SYMOPT_UNDNAME | 99 SYMOPT_LOAD_LINES); 100 CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE)); 101 // FIXME: We don't call SymCleanup() on exit yet - should we? 102 dbghelp_initialized = true; 103 } 104 105 // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx 106 char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; 107 PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; 108 symbol->SizeOfStruct = sizeof(SYMBOL_INFO); 109 symbol->MaxNameLen = MAX_SYM_NAME; 110 DWORD64 offset = 0; 111 BOOL got_objname = SymFromAddr(GetCurrentProcess(), 112 (DWORD64)addr, &offset, symbol); 113 if (!got_objname) 114 return false; 115 116 DWORD unused; 117 IMAGEHLP_LINE64 info; 118 info.SizeOfStruct = sizeof(IMAGEHLP_LINE64); 119 BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), 120 (DWORD64)addr, &unused, &info); 121 int written = 0; 122 out_buffer[0] = '\0'; 123 // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too. 124 if (got_fileline) { 125 written += internal_snprintf(out_buffer + written, buffer_size - written, 126 " %s %s:%d", symbol->Name, 127 info.FileName, info.LineNumber); 128 } else { 129 written += internal_snprintf(out_buffer + written, buffer_size - written, 130 " %s+0x%p", symbol->Name, offset); 131 } 132 return true; 133 } 134 } // extern "C" 135 136 137 #endif // _WIN32 138