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.@�vcd���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�