re PR c++/19476 (Missed null checking elimination with new)
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_win.cc
blob695265594b3cd353ffdc38a53fccb7a90d3a99d0
1 //===-- sanitizer_win.cc --------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries and implements windows-specific functions from
10 // sanitizer_libc.h.
11 //===----------------------------------------------------------------------===//
12 #ifdef _WIN32
13 #define WIN32_LEAN_AND_MEAN
14 #define NOGDI
15 #include <stdlib.h>
16 #include <io.h>
17 #include <windows.h>
19 #include "sanitizer_common.h"
20 #include "sanitizer_libc.h"
21 #include "sanitizer_placement_new.h"
22 #include "sanitizer_mutex.h"
24 namespace __sanitizer {
26 // --------------------- sanitizer_common.h
27 uptr GetPageSize() {
28 return 1U << 14; // FIXME: is this configurable?
31 uptr GetMmapGranularity() {
32 return 1U << 16; // FIXME: is this configurable?
35 bool FileExists(const char *filename) {
36 UNIMPLEMENTED();
39 int GetPid() {
40 return GetProcessId(GetCurrentProcess());
43 uptr GetThreadSelf() {
44 return GetCurrentThreadId();
47 void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
48 uptr *stack_bottom) {
49 CHECK(stack_top);
50 CHECK(stack_bottom);
51 MEMORY_BASIC_INFORMATION mbi;
52 CHECK_NE(VirtualQuery(&mbi /* on stack */, &mbi, sizeof(mbi)), 0);
53 // FIXME: is it possible for the stack to not be a single allocation?
54 // Are these values what ASan expects to get (reserved, not committed;
55 // including stack guard page) ?
56 *stack_top = (uptr)mbi.BaseAddress + mbi.RegionSize;
57 *stack_bottom = (uptr)mbi.AllocationBase;
60 void *MmapOrDie(uptr size, const char *mem_type) {
61 void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
62 if (rv == 0) {
63 Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s\n",
64 size, size, mem_type);
65 CHECK("unable to mmap" && 0);
67 return rv;
70 void UnmapOrDie(void *addr, uptr size) {
71 if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) {
72 Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n",
73 size, size, addr);
74 CHECK("unable to unmap" && 0);
78 void *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
79 // FIXME: is this really "NoReserve"? On Win32 this does not matter much,
80 // but on Win64 it does.
81 void *p = VirtualAlloc((LPVOID)fixed_addr, size,
82 MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
83 if (p == 0)
84 Report("ERROR: Failed to allocate 0x%zx (%zd) bytes at %p (%d)\n",
85 size, size, fixed_addr, GetLastError());
86 return p;
89 void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
90 return MmapFixedNoReserve(fixed_addr, size);
93 void *Mprotect(uptr fixed_addr, uptr size) {
94 return VirtualAlloc((LPVOID)fixed_addr, size,
95 MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);
98 void FlushUnneededShadowMemory(uptr addr, uptr size) {
99 // This is almost useless on 32-bits.
100 // FIXME: add madvice-analog when we move to 64-bits.
103 bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
104 // FIXME: shall we do anything here on Windows?
105 return true;
108 void *MapFileToMemory(const char *file_name, uptr *buff_size) {
109 UNIMPLEMENTED();
112 const char *GetEnv(const char *name) {
113 static char env_buffer[32767] = {};
115 // Note: this implementation stores the result in a static buffer so we only
116 // allow it to be called just once.
117 static bool called_once = false;
118 if (called_once)
119 UNIMPLEMENTED();
120 called_once = true;
122 DWORD rv = GetEnvironmentVariableA(name, env_buffer, sizeof(env_buffer));
123 if (rv > 0 && rv < sizeof(env_buffer))
124 return env_buffer;
125 return 0;
128 const char *GetPwd() {
129 UNIMPLEMENTED();
132 u32 GetUid() {
133 UNIMPLEMENTED();
136 void DumpProcessMap() {
137 UNIMPLEMENTED();
140 void DisableCoreDumper() {
141 UNIMPLEMENTED();
144 void ReExec() {
145 UNIMPLEMENTED();
148 void PrepareForSandboxing() {
149 // Nothing here for now.
152 bool StackSizeIsUnlimited() {
153 UNIMPLEMENTED();
156 void SetStackSizeLimitInBytes(uptr limit) {
157 UNIMPLEMENTED();
160 void SleepForSeconds(int seconds) {
161 Sleep(seconds * 1000);
164 void SleepForMillis(int millis) {
165 Sleep(millis);
168 void Abort() {
169 abort();
170 _exit(-1); // abort is not NORETURN on Windows.
173 #ifndef SANITIZER_GO
174 int Atexit(void (*function)(void)) {
175 return atexit(function);
177 #endif
179 // ------------------ sanitizer_libc.h
180 void *internal_mmap(void *addr, uptr length, int prot, int flags,
181 int fd, u64 offset) {
182 UNIMPLEMENTED();
185 int internal_munmap(void *addr, uptr length) {
186 UNIMPLEMENTED();
189 int internal_close(fd_t fd) {
190 UNIMPLEMENTED();
193 int internal_isatty(fd_t fd) {
194 return _isatty(fd);
197 fd_t internal_open(const char *filename, int flags) {
198 UNIMPLEMENTED();
201 fd_t internal_open(const char *filename, int flags, u32 mode) {
202 UNIMPLEMENTED();
205 fd_t OpenFile(const char *filename, bool write) {
206 UNIMPLEMENTED();
209 uptr internal_read(fd_t fd, void *buf, uptr count) {
210 UNIMPLEMENTED();
213 uptr internal_write(fd_t fd, const void *buf, uptr count) {
214 if (fd != kStderrFd)
215 UNIMPLEMENTED();
216 HANDLE err = GetStdHandle(STD_ERROR_HANDLE);
217 if (err == 0)
218 return 0; // FIXME: this might not work on some apps.
219 DWORD ret;
220 if (!WriteFile(err, buf, count, &ret, 0))
221 return 0;
222 return ret;
225 int internal_stat(const char *path, void *buf) {
226 UNIMPLEMENTED();
229 int internal_lstat(const char *path, void *buf) {
230 UNIMPLEMENTED();
233 int internal_fstat(fd_t fd, void *buf) {
234 UNIMPLEMENTED();
237 uptr internal_filesize(fd_t fd) {
238 UNIMPLEMENTED();
241 int internal_dup2(int oldfd, int newfd) {
242 UNIMPLEMENTED();
245 uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
246 UNIMPLEMENTED();
249 int internal_sched_yield() {
250 Sleep(0);
251 return 0;
254 void internal__exit(int exitcode) {
255 _exit(exitcode);
258 // ---------------------- BlockingMutex ---------------- {{{1
259 const uptr LOCK_UNINITIALIZED = 0;
260 const uptr LOCK_READY = (uptr)-1;
262 BlockingMutex::BlockingMutex(LinkerInitialized li) {
263 // FIXME: see comments in BlockingMutex::Lock() for the details.
264 CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED);
266 CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_));
267 InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
268 owner_ = LOCK_READY;
271 void BlockingMutex::Lock() {
272 if (owner_ == LOCK_UNINITIALIZED) {
273 // FIXME: hm, global BlockingMutex objects are not initialized?!?
274 // This might be a side effect of the clang+cl+link Frankenbuild...
275 new(this) BlockingMutex((LinkerInitialized)(LINKER_INITIALIZED + 1));
277 // FIXME: If it turns out the linker doesn't invoke our
278 // constructors, we should probably manually Lock/Unlock all the global
279 // locks while we're starting in one thread to avoid double-init races.
281 EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
282 CHECK_EQ(owner_, LOCK_READY);
283 owner_ = GetThreadSelf();
286 void BlockingMutex::Unlock() {
287 CHECK_EQ(owner_, GetThreadSelf());
288 owner_ = LOCK_READY;
289 LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
292 } // namespace __sanitizer
294 #endif // _WIN32