17f9c5a220b2768a450696bbd157a0e6f2e9ceea3Alexey Samsonov//===-- sanitizer_win.cc --------------------------------------------------===// 2c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// 3c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// The LLVM Compiler Infrastructure 4c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// 5c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// This file is distributed under the University of Illinois Open Source 6c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// License. See LICENSE.TXT for details. 7c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// 8c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov//===----------------------------------------------------------------------===// 9c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// 10c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer 11c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// run-time libraries and implements windows-specific functions from 12c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov// sanitizer_libc.h. 13c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov//===----------------------------------------------------------------------===// 14c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov#ifdef _WIN32 15c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov#include <windows.h> 16c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov 179929ffd1c4737d2c50829dcefcb0b8f1926a05ffAlexey Samsonov#include "sanitizer_common.h" 18c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov#include "sanitizer_libc.h" 19c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov 20c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonovnamespace __sanitizer { 21c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov 22e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov// --------------------- sanitizer_common.h 23230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovint GetPid() { 24230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov return GetProcessId(GetCurrentProcess()); 25230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 26230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 27fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovuptr GetThreadSelf() { 28fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov return GetCurrentThreadId(); 29fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 30fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 31ed996f79710f532bf231537e44d5c8c9c9d57e8dAlexey Samsonovvoid GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, 32e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov uptr *stack_bottom) { 33e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov CHECK(stack_top); 34e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov CHECK(stack_bottom); 35e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov MEMORY_BASIC_INFORMATION mbi; 366985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany CHECK_NE(VirtualQuery(&mbi /* on stack */, &mbi, sizeof(mbi)), 0); 37e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov // FIXME: is it possible for the stack to not be a single allocation? 38e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov // Are these values what ASan expects to get (reserved, not committed; 39e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov // including stack guard page) ? 40e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov *stack_top = (uptr)mbi.BaseAddress + mbi.RegionSize; 41e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov *stack_bottom = (uptr)mbi.AllocationBase; 42e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov} 43e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov 44e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov 45a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonovvoid *MmapOrDie(uptr size, const char *mem_type) { 46230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 47a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov if (rv == 0) { 48a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s\n", 49a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov size, size, mem_type); 50a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov CHECK("unable to mmap" && 0); 51a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov } 52230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov return rv; 53230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 54230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 55230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid UnmapOrDie(void *addr, uptr size) { 568c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) { 57a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n", 58a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov size, size, addr); 59a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov CHECK("unable to unmap" && 0); 608c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov } 61230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 62230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 63f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size) { 64f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov return VirtualAlloc((LPVOID)fixed_addr, size, 65f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 66f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov} 67f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 68f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *Mprotect(uptr fixed_addr, uptr size) { 69f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov return VirtualAlloc((LPVOID)fixed_addr, size, 70f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); 71f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov} 72f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 73dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonovbool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { 74dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov // FIXME: shall we do anything here on Windows? 75dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov return true; 76dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov} 77dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov 78a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonovvoid *MapFileToMemory(const char *file_name, uptr *buff_size) { 79a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov UNIMPLEMENTED(); 80985aaaaf208f43e4b47625e21e9ebc434c5462e3Alexey Samsonov return 0; 81a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov} 82a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov 833dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonovconst char *GetEnv(const char *name) { 843dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov static char env_buffer[32767] = {}; 853dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov 863dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov // Note: this implementation stores the result in a static buffer so we only 873dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov // allow it to be called just once. 883dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov static bool called_once = false; 893dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov if (called_once) 903dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov UNIMPLEMENTED(); 913dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov called_once = true; 923dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov 933dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov DWORD rv = GetEnvironmentVariableA(name, env_buffer, sizeof(env_buffer)); 943dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov if (rv > 0 && rv < sizeof(env_buffer)) 953dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov return env_buffer; 963dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov return 0; 973dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov} 983dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov 990969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovconst char *GetPwd() { 1000969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov UNIMPLEMENTED(); 10169021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 1020969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov} 1030969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov 104be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DumpProcessMap() { 105be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov UNIMPLEMENTED(); 106be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov} 107be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 108be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DisableCoreDumper() { 109be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov UNIMPLEMENTED(); 110be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov} 111be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 112fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid SleepForSeconds(int seconds) { 113fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov Sleep(seconds * 1000); 114fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 115fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 1160969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovvoid SleepForMillis(int millis) { 1170969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov Sleep(millis); 1180969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov} 1190969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov 120fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Exit(int exitcode) { 121fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov _exit(exitcode); 122fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 123fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 124fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Abort() { 125fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov abort(); 126fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov _exit(-1); // abort is not NORETURN on Windows. 127fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 128fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 129fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovint Atexit(void (*function)(void)) { 130fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov return atexit(function); 131fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 132fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 133e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov// ------------------ sanitizer_libc.h 134c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonovvoid *internal_mmap(void *addr, uptr length, int prot, int flags, 135c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov int fd, u64 offset) { 1368c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 13769021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 138c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov} 139c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov 1401f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovint internal_munmap(void *addr, uptr length) { 1418c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 14269021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 1431f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov} 1441f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 145a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonovint internal_close(fd_t fd) { 1468c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 14769021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 148a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov} 149a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov 150c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonovfd_t internal_open(const char *filename, bool write) { 1518c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 15269021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 153c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov} 154c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov 155a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonovuptr internal_read(fd_t fd, void *buf, uptr count) { 1568c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 15769021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 158a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov} 159a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov 160a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonovuptr internal_write(fd_t fd, const void *buf, uptr count) { 1618c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov if (fd != 2) 1628c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 163a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov HANDLE err = GetStdHandle(STD_ERROR_HANDLE); 164a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov if (err == 0) 165a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov return 0; // FIXME: this might not work on some apps. 166a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov DWORD ret; 167a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov if (!WriteFile(err, buf, count, &ret, 0)) 168a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov return 0; 169a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov return ret; 170a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov} 171a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov 1728e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonovuptr internal_filesize(fd_t fd) { 1738c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 17469021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 1758e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov} 1768e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov 1778e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonovint internal_dup2(int oldfd, int newfd) { 1788c53e54ef9e713953ec9495e82e5c330b96e49f3Alexey Samsonov UNIMPLEMENTED(); 17969021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 1808e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov} 1818e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov 182d1b8f588d6b712b6ff2b3d58c73d71614f520122Alexey Samsonovuptr internal_readlink(const char *path, char *buf, uptr bufsize) { 183d1b8f588d6b712b6ff2b3d58c73d71614f520122Alexey Samsonov UNIMPLEMENTED(); 184d1b8f588d6b712b6ff2b3d58c73d71614f520122Alexey Samsonov return 0; 185d1b8f588d6b712b6ff2b3d58c73d71614f520122Alexey Samsonov} 186d1b8f588d6b712b6ff2b3d58c73d71614f520122Alexey Samsonov 1870969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovint internal_sched_yield() { 1880969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov UNIMPLEMENTED(); 18969021355c0ac8a0d9b546fb3db1136b1b2db0616Dmitry Vyukov return 0; 1900969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov} 1910969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov 192c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov} // namespace __sanitizer 193c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov 194c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov#endif // _WIN32 195