blob: 9e66b3417a1e32599d1638064528e10fa7660501 [file] [log] [blame]
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +00001//===-- 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//===----------------------------------------------------------------------===//
Evgeniy Stepanov24e13722013-03-19 14:33:38 +000014
15#include "sanitizer_common/sanitizer_platform.h"
Evgeniy Stepanov30e110e2013-03-19 14:54:17 +000016#if SANITIZER_WINDOWS
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000017#include <windows.h>
18
19#include <dbghelp.h>
Alexey Samsonovb823e3c2012-02-22 14:07:06 +000020#include <stdlib.h>
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000021
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000022#include "asan_interceptors.h"
23#include "asan_internal.h"
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000024#include "asan_thread.h"
Alexey Samsonovde08c022012-06-19 09:21:57 +000025#include "sanitizer_common/sanitizer_libc.h"
Dmitry Vyukovf4f51f22013-01-14 07:51:39 +000026#include "sanitizer_common/sanitizer_mutex.h"
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000027
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +000028extern "C" {
29 SANITIZER_INTERFACE_ATTRIBUTE
Timur Iskhodzhanovdef895b2013-09-23 11:19:43 +000030 int __asan_should_detect_stack_use_after_return() {
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +000031 __asan_init();
32 return __asan_option_detect_stack_use_after_return;
33 }
34}
35
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000036namespace __asan {
37
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000038// ---------------------- Stacktraces, symbols, etc. ---------------- {{{1
Dmitry Vyukovf4f51f22013-01-14 07:51:39 +000039static BlockingMutex dbghelp_lock(LINKER_INITIALIZED);
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000040static bool dbghelp_initialized = false;
41#pragma comment(lib, "dbghelp.lib")
42
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000043// ---------------------- TSD ---------------- {{{1
44static bool tsd_key_inited = false;
45
Kostya Serebryany3f4c3872012-05-31 14:35:53 +000046static __declspec(thread) void *fake_tsd = 0;
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000047
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}
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000062
Sergey Matveeve86e35f2013-10-14 12:01:05 +000063void PlatformTSDDtor(void *tsd) {
64 AsanThread::TSDDtor(tsd);
65}
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000066// ---------------------- Various stuff ---------------- {{{1
Alexander Potapenkoeb8c46e2012-08-24 09:22:05 +000067void MaybeReexec() {
68 // No need to re-exec on Windows.
69}
70
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000071void *AsanDoesNotSupportStaticLinkage() {
Timur Iskhodzhanov2716a612012-03-12 11:45:09 +000072#if defined(_DEBUG)
73#error Please build the runtime with a non-debug CRT: /MD or /MT
Timur Iskhodzhanov07bb9f12012-02-22 13:59:49 +000074#endif
Kostya Serebryany3f4c3872012-05-31 14:35:53 +000075 return 0;
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000076}
77
Alexander Potapenkof03d8af2012-04-05 10:54:52 +000078void SetAlternateSignalStack() {
79 // FIXME: Decide what to do on Windows.
80}
81
82void UnsetAlternateSignalStack() {
83 // FIXME: Decide what to do on Windows.
84}
85
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000086void InstallSignalHandlers() {
87 // FIXME: Decide what to do on Windows.
88}
89
Alexander Potapenko75b19eb2012-07-23 14:07:58 +000090void AsanPlatformThreadInit() {
91 // Nothing here for now.
92}
93
Alexey Samsonov57db4ba2013-01-17 15:45:28 +000094void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
Alexey Samsonov08700282012-11-23 09:46:34 +000095 UNIMPLEMENTED();
96}
97
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +000098} // namespace __asan
99
Alexey Samsonov1ca53572012-10-02 12:11:17 +0000100// ---------------------- Interface ---------------- {{{1
101using namespace __asan; // NOLINT
102
Alexey Samsonov0ec37a62012-10-02 12:35:42 +0000103extern "C" {
104SANITIZER_INTERFACE_ATTRIBUTE NOINLINE
Alexey Samsonov1ca53572012-10-02 12:11:17 +0000105bool __asan_symbolize(const void *addr, char *out_buffer, int buffer_size) {
Dmitry Vyukovf4f51f22013-01-14 07:51:39 +0000106 BlockingMutexLock lock(&dbghelp_lock);
Alexey Samsonov1ca53572012-10-02 12:11:17 +0000107 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}
Alexey Samsonov0ec37a62012-10-02 12:35:42 +0000145} // extern "C"
Alexey Samsonov1ca53572012-10-02 12:11:17 +0000146
147
Timur Iskhodzhanov3e81fe42012-02-09 17:20:14 +0000148#endif // _WIN32