sanitizer_win.cc revision 0969bcf2c936126b1f6e636b978aade8fc207437
1//===-- sanitizer_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 shared between AddressSanitizer and ThreadSanitizer 11// run-time libraries and implements windows-specific functions from 12// sanitizer_libc.h. 13//===----------------------------------------------------------------------===// 14#ifdef _WIN32 15#include <windows.h> 16 17#include "sanitizer_common.h" 18#include "sanitizer_libc.h" 19 20namespace __sanitizer { 21 22// --------------------- sanitizer_common.h 23int GetPid() { 24 return GetProcessId(GetCurrentProcess()); 25} 26 27uptr GetThreadSelf() { 28 return GetCurrentThreadId(); 29} 30 31void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, 32 uptr *stack_bottom) { 33 CHECK(stack_top); 34 CHECK(stack_bottom); 35 MEMORY_BASIC_INFORMATION mbi; 36 CHECK(VirtualQuery(&mbi /* on stack */, &mbi, sizeof(mbi)) != 0); 37 // FIXME: is it possible for the stack to not be a single allocation? 38 // Are these values what ASan expects to get (reserved, not committed; 39 // including stack guard page) ? 40 *stack_top = (uptr)mbi.BaseAddress + mbi.RegionSize; 41 *stack_bottom = (uptr)mbi.AllocationBase; 42} 43 44 45void *MmapOrDie(uptr size, const char *mem_type) { 46 void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 47 if (rv == 0) { 48 Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s\n", 49 size, size, mem_type); 50 CHECK("unable to mmap" && 0); 51 } 52 return rv; 53} 54 55void UnmapOrDie(void *addr, uptr size) { 56 if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) { 57 Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n", 58 size, size, addr); 59 CHECK("unable to unmap" && 0); 60 } 61} 62 63void *MmapFixedNoReserve(uptr fixed_addr, uptr size) { 64 return VirtualAlloc((LPVOID)fixed_addr, size, 65 MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 66} 67 68void *Mprotect(uptr fixed_addr, uptr size) { 69 return VirtualAlloc((LPVOID)fixed_addr, size, 70 MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); 71} 72 73bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { 74 // FIXME: shall we do anything here on Windows? 75 return true; 76} 77 78const char *GetEnv(const char *name) { 79 static char env_buffer[32767] = {}; 80 81 // Note: this implementation stores the result in a static buffer so we only 82 // allow it to be called just once. 83 static bool called_once = false; 84 if (called_once) 85 UNIMPLEMENTED(); 86 called_once = true; 87 88 DWORD rv = GetEnvironmentVariableA(name, env_buffer, sizeof(env_buffer)); 89 if (rv > 0 && rv < sizeof(env_buffer)) 90 return env_buffer; 91 return 0; 92} 93 94const char *GetPwd() { 95 UNIMPLEMENTED(); 96} 97 98void DumpProcessMap() { 99 UNIMPLEMENTED(); 100} 101 102void DisableCoreDumper() { 103 UNIMPLEMENTED(); 104} 105 106void SleepForSeconds(int seconds) { 107 Sleep(seconds * 1000); 108} 109 110void SleepForMillis(int millis) { 111 Sleep(millis); 112} 113 114void Exit(int exitcode) { 115 _exit(exitcode); 116} 117 118void Abort() { 119 abort(); 120 _exit(-1); // abort is not NORETURN on Windows. 121} 122 123int Atexit(void (*function)(void)) { 124 return atexit(function); 125} 126 127int AtomicInc(int *a) { 128 return InterlockedExchangeAdd((LONG*)a, 1) + 1; 129} 130 131u16 AtomicExchange(u16 *a, u16 new_val) { 132 // InterlockedExchange16 seems unavailable on some MSVS installations. 133 // Everybody stand back, I pretend to know inline assembly! 134 // FIXME: I assume VC is smart enough to save/restore eax/ecx? 135 __asm { 136 mov eax, a 137 mov cx, new_val 138 xchg [eax], cx ; NOLINT 139 mov new_val, cx 140 } 141 return new_val; 142} 143 144u8 AtomicExchange(u8 *a, u8 new_val) { 145 // FIXME: can we do this with a proper xchg intrinsic? 146 u8 t = *a; 147 *a = new_val; 148 return t; 149} 150 151// ------------------ sanitizer_libc.h 152void *internal_mmap(void *addr, uptr length, int prot, int flags, 153 int fd, u64 offset) { 154 UNIMPLEMENTED(); 155} 156 157int internal_munmap(void *addr, uptr length) { 158 UNIMPLEMENTED(); 159} 160 161int internal_close(fd_t fd) { 162 UNIMPLEMENTED(); 163} 164 165fd_t internal_open(const char *filename, bool write) { 166 UNIMPLEMENTED(); 167} 168 169uptr internal_read(fd_t fd, void *buf, uptr count) { 170 UNIMPLEMENTED(); 171} 172 173uptr internal_write(fd_t fd, const void *buf, uptr count) { 174 if (fd != 2) 175 UNIMPLEMENTED(); 176 HANDLE err = GetStdHandle(STD_ERROR_HANDLE); 177 if (err == 0) 178 return 0; // FIXME: this might not work on some apps. 179 DWORD ret; 180 if (!WriteFile(err, buf, count, &ret, 0)) 181 return 0; 182 return ret; 183} 184 185uptr internal_filesize(fd_t fd) { 186 UNIMPLEMENTED(); 187} 188 189int internal_dup2(int oldfd, int newfd) { 190 UNIMPLEMENTED(); 191} 192 193int internal_sched_yield() { 194 UNIMPLEMENTED(); 195} 196 197int internal_sscanf(const char *str, const char *format, ...) { 198 UNIMPLEMENTED(); 199} 200 201} // namespace __sanitizer 202 203#endif // _WIN32 204