asan_win.cc revision 4c49666e611f06241bb8462cea7674d877241492
1402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//===-- asan_win.cc -------------------------------------------------------===// 2402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// 31M�O���// The LLVM Compiler Infrastructure 4402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// 5B��K������;�f嬟J�!dwSPvy�����ab�b�\�QO�// This file is distributed under the University of Illinois Open Source 6402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// License. See LICENSE.TXT for details. 7402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// 8402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//===----------------------------------------------------------------------===// 9402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// 107T��b,� G�// This file is a part of AddressSanitizer, an address sanity checker. 11402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// 12402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// Windows-specific details. 13jQ���wix]�;��(�{��h}淃r�A�k#j��//===----------------------------------------------------------------------===// 142���xe�!$��{��*g���#ifdef _WIN32 15402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#include <windows.h> 16Ng��mx�G�ԄCK�E 17402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#include <dbghelp.h> 18402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#include <stdlib.h> 19402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 20y��b%P�߭����#include <new> // FIXME: temporarily needed for placement new in AsanLock. 21402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 22402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#include "asan_interceptors.h" 23402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#include "asan_internal.h" 24402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#include "asan_lock.h" 25402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#include "asan_thread.h" 26402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 27402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollnamespace __asan { 28402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 29ls�.// ---------------------- Stacktraces, symbols, etc. ---------------- {{{1 30402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollstatic AsanLock dbghelp_lock(LINKER_INITIALIZED); 31402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollstatic bool dbghelp_initialized = false; 32402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#pragma comment(lib, "dbghelp.lib") 33402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 34AGvoid AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) { 35402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll max_size = max_s; 361�L� void *tmp[kStackTraceMax]; 37402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 38402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: CaptureStackBackTrace might be too slow for us. 39402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: Compare with StackWalk64. 40402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc 41RF:�"�j�CF����F�Y���ȗ�*�G=�=��Hb uptr cs_ret = CaptureStackBackTrace(1, max_size, tmp, 0), 42402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll offset = 0; 43402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // Skip the RTL frames by searching for the PC in the stacktrace. 443n0�g?��p�)�c~��iy�j.@�vcd���f� // FIXME: this doesn't work well for the malloc/free stacks yet. 45402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (uptr i = 0; i < cs_ret; i++) { 46402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (pc != (uptr)tmp[i]) 477BS����lS����:�� �b�`�����e㚣�-Do®l=��{�h��œ{$g~uMUe��]V�/���vݫ�����<���w���Ғ�K✺�F�x�����> continue; 48402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll offset = i; 49402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll break; 50402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 51402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 52402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll size = cs_ret - offset; 53402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (uptr i = 0; i < size; i++) 5407�&h.Έ� trace[i] = (uptr)tmp[i + offset]; 55T�P�A} 56402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 57402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollbool __asan_WinSymbolize(const void *addr, char *out_buffer, int buffer_size) { 58402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ScopedLock lock(&dbghelp_lock); 59QIjg̞� if (!dbghelp_initialized) { 60402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll SymSetOptions(SYMOPT_DEFERRED_LOADS | 6178{$�t'md�V�e� �\+��tk~z�?g.� SYMOPT_UNDNAME | 62402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll SYMOPT_LOAD_LINES); 63PK�ON-.NMQ(-��KW�J,*��q$&g�%�+�*躚�����R CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE)); 64402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: We don't call SymCleanup() on exit yet - should we? 65F! dbghelp_initialized = true; 66402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 67b��-�!� 68402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx 69402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; 70402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; 71402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll symbol->SizeOfStruct = sizeof(SYMBOL_INFO); 724e����%� symbol->MaxNameLen = MAX_SYM_NAME; 73402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll DWORD64 offset = 0; 74402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll BOOL got_objname = SymFromAddr(GetCurrentProcess(), 75402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll (DWORD64)addr, &offset, symbol); 76402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (!got_objname) 77on�e+ [K��ODף(��[�b�'Xs� ���J}(�T�+�#$T� return false; 78402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 79402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll DWORD unused; 80402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll IMAGEHLP_LINE64 info; 81402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll info.SizeOfStruct = sizeof(IMAGEHLP_LINE64); 82402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), 83402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll (DWORD64)addr, &unused, &info); 84402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int written = 0; 85402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll out_buffer[0] = '\0'; 86F����)�!�]���� // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too. 87rR if (got_fileline) { 88402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll written += SNPrintf(out_buffer + written, buffer_size - written, 89402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll " %s %s:%d", symbol->Name, 90402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll info.FileName, info.LineNumber); 91402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else { 92402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll written += SNPrintf(out_buffer + written, buffer_size - written, 93XX " %s+0x%p", symbol->Name, offset); 94402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 95402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return true; 96402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 97402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 98402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// ---------------------- AsanLock ---------------- {{{1 99lff�f�!�����e�A�, ��Q�@|���aenum LockState { 100402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll LOCK_UNINITIALIZED = 0, 101402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll LOCK_READY = -1, 102402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}; 103402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 104JH�㝸!����� [�<���-����)�[�I���ǛiHAsanLock::AsanLock(LinkerInitialized li) { 105402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: see comments in AsanLock::Lock() for the details. 106402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED); 107402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 108O|������(g�����q�P�% CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); 1095sΘ� ��@Ϻ��J�.(N InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); 110402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll owner_ = LOCK_READY; 111u�c��n�#�} 112402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 113402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid AsanLock::Lock() { 114402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (owner_ == LOCK_UNINITIALIZED) { 115402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: hm, global AsanLock objects are not initialized?!? 116402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // This might be a side effect of the clang+cl+link Frankenbuild... 117402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll new(this) AsanLock((LinkerInitialized)(LINKER_INITIALIZED + 1)); 118Py���yn�'}�yJ��tQ��l<L�-�@�w\��,�/O������;���x�,BQ�C�$ 119402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: If it turns out the linker doesn't invoke our 120402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // constructors, we should probably manually Lock/Unlock all the global 121402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // locks while we're starting in one thread to avoid double-init races. 122402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 123402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_); 124AW_z�j/�O}wv��?��@ CHECK(owner_ == LOCK_READY); 125402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll owner_ = GetThreadSelf(); 126402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 127N2��\+���Q 128402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid AsanLock::Unlock() { 129402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll CHECK(owner_ == GetThreadSelf()); 130402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll owner_ = LOCK_READY; 131402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_); 132R���a�"f} 133402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 134C��>����q�Q�i;:!�W�ѓ���Y�|�ul�=nx��.W<C�!IP���Ǭ�K="j��xn�N// ---------------------- TSD ---------------- {{{1 135w����uY �static bool tsd_key_inited = false; 136402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 137402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollstatic __declspec(thread) void *fake_tsd = 0; 138402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 139402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid AsanTSDInit(void (*destructor)(void *tsd)) { 140402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: we're ignoring the destructor for now. 141402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll tsd_key_inited = true; 142402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 143402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 144402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid *AsanTSDGet() { 145402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll CHECK(tsd_key_inited); 146402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return fake_tsd; 147402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 148402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 149402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid AsanTSDSet(void *tsd) { 150402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll CHECK(tsd_key_inited); 151402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll fake_tsd = tsd; 152402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 1536�Z�bq�j`�y��A/�G�q����mMv���àPݛ֔�UP��;�:�(����t 154402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// ---------------------- Various stuff ---------------- {{{1 155402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid *AsanDoesNotSupportStaticLinkage() { 156402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#if defined(_DEBUG) 157402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll#error Please build the runtime with a non-debug CRT: /MD or /MT 158u{��:�t;������.yb����X�d�d�^�Z&�ƫ ����x��#endif 159402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return 0; 160402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 161402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 162402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollbool AsanShadowRangeIsAvailable() { 163402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: shall we do anything here on Windows? 164402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return true; 165402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 166402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 167402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid SetAlternateSignalStack() { 168402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: Decide what to do on Windows. 169wBj��Op��+�AOk�X~�\-ʾB���ѴL���"���E*���~�} 170L@ 1716�M�U�;Fvoid UnsetAlternateSignalStack() { 172402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: Decide what to do on Windows. 173vkچw��C-��p|ۅ=���ۆv>��} 174402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 175402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid InstallSignalHandlers() { 176402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // FIXME: Decide what to do on Windows. 177402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 178402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 179yts��#UЦ\`S�,�L.��} // namespace __asan 180402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 181l�&-�y��l"'��s�-���#endif // _WIN32 182m2��u<�c.t�+�w�.��}�����Q<@�Y_�r��� .�Z�