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