diff options
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_win.cc')
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_win.cc | 184 |
1 files changed, 157 insertions, 27 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_win.cc index 6952655..0a5fe81 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win.cc +++ b/libsanitizer/sanitizer_common/sanitizer_win.cc @@ -9,7 +9,10 @@ // run-time libraries and implements windows-specific functions from // sanitizer_libc.h. //===----------------------------------------------------------------------===// -#ifdef _WIN32 + +#include "sanitizer_platform.h" +#if SANITIZER_WINDOWS + #define WIN32_LEAN_AND_MEAN #define NOGDI #include <stdlib.h> @@ -18,11 +21,14 @@ #include "sanitizer_common.h" #include "sanitizer_libc.h" -#include "sanitizer_placement_new.h" #include "sanitizer_mutex.h" +#include "sanitizer_placement_new.h" +#include "sanitizer_stacktrace.h" namespace __sanitizer { +#include "sanitizer_syscall_generic.inc" + // --------------------- sanitizer_common.h uptr GetPageSize() { return 1U << 14; // FIXME: is this configurable? @@ -32,18 +38,30 @@ uptr GetMmapGranularity() { return 1U << 16; // FIXME: is this configurable? } +uptr GetMaxVirtualAddress() { + SYSTEM_INFO si; + GetSystemInfo(&si); + return (uptr)si.lpMaximumApplicationAddress; +} + bool FileExists(const char *filename) { UNIMPLEMENTED(); } -int GetPid() { +uptr internal_getpid() { return GetProcessId(GetCurrentProcess()); } -uptr GetThreadSelf() { +// In contrast to POSIX, on Windows GetCurrentThreadId() +// returns a system-unique identifier. +uptr GetTid() { return GetCurrentThreadId(); } +uptr GetThreadSelf() { + return GetTid(); +} + void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, uptr *stack_bottom) { CHECK(stack_top); @@ -109,19 +127,38 @@ void *MapFileToMemory(const char *file_name, uptr *buff_size) { UNIMPLEMENTED(); } -const char *GetEnv(const char *name) { - static char env_buffer[32767] = {}; +static const int kMaxEnvNameLength = 128; +static const DWORD kMaxEnvValueLength = 32767; - // Note: this implementation stores the result in a static buffer so we only - // allow it to be called just once. - static bool called_once = false; - if (called_once) - UNIMPLEMENTED(); - called_once = true; +namespace { + +struct EnvVariable { + char name[kMaxEnvNameLength]; + char value[kMaxEnvValueLength]; +}; - DWORD rv = GetEnvironmentVariableA(name, env_buffer, sizeof(env_buffer)); - if (rv > 0 && rv < sizeof(env_buffer)) - return env_buffer; +} // namespace + +static const int kEnvVariables = 5; +static EnvVariable env_vars[kEnvVariables]; +static int num_env_vars; + +const char *GetEnv(const char *name) { + // Note: this implementation caches the values of the environment variables + // and limits their quantity. + for (int i = 0; i < num_env_vars; i++) { + if (0 == internal_strcmp(name, env_vars[i].name)) + return env_vars[i].value; + } + CHECK_LT(num_env_vars, kEnvVariables); + DWORD rv = GetEnvironmentVariableA(name, env_vars[num_env_vars].value, + kMaxEnvValueLength); + if (rv > 0 && rv < kMaxEnvValueLength) { + CHECK_LT(internal_strlen(name), kMaxEnvNameLength); + internal_strncpy(env_vars[num_env_vars].name, name, kMaxEnvNameLength); + num_env_vars++; + return env_vars[num_env_vars - 1].value; + } return 0; } @@ -157,6 +194,11 @@ void SetStackSizeLimitInBytes(uptr limit) { UNIMPLEMENTED(); } +char *FindPathToBinary(const char *name) { + // Nothing here for now. + return 0; +} + void SleepForSeconds(int seconds) { Sleep(seconds * 1000); } @@ -165,11 +207,20 @@ void SleepForMillis(int millis) { Sleep(millis); } +u64 NanoTime() { + return 0; +} + void Abort() { abort(); _exit(-1); // abort is not NORETURN on Windows. } +uptr GetListOfModules(LoadedModule *modules, uptr max_modules, + string_predicate_t filter) { + UNIMPLEMENTED(); +}; + #ifndef SANITIZER_GO int Atexit(void (*function)(void)) { return atexit(function); @@ -177,16 +228,16 @@ int Atexit(void (*function)(void)) { #endif // ------------------ sanitizer_libc.h -void *internal_mmap(void *addr, uptr length, int prot, int flags, - int fd, u64 offset) { +uptr internal_mmap(void *addr, uptr length, int prot, int flags, + int fd, u64 offset) { UNIMPLEMENTED(); } -int internal_munmap(void *addr, uptr length) { +uptr internal_munmap(void *addr, uptr length) { UNIMPLEMENTED(); } -int internal_close(fd_t fd) { +uptr internal_close(fd_t fd) { UNIMPLEMENTED(); } @@ -194,15 +245,15 @@ int internal_isatty(fd_t fd) { return _isatty(fd); } -fd_t internal_open(const char *filename, int flags) { +uptr internal_open(const char *filename, int flags) { UNIMPLEMENTED(); } -fd_t internal_open(const char *filename, int flags, u32 mode) { +uptr internal_open(const char *filename, int flags, u32 mode) { UNIMPLEMENTED(); } -fd_t OpenFile(const char *filename, bool write) { +uptr OpenFile(const char *filename, bool write) { UNIMPLEMENTED(); } @@ -222,15 +273,15 @@ uptr internal_write(fd_t fd, const void *buf, uptr count) { return ret; } -int internal_stat(const char *path, void *buf) { +uptr internal_stat(const char *path, void *buf) { UNIMPLEMENTED(); } -int internal_lstat(const char *path, void *buf) { +uptr internal_lstat(const char *path, void *buf) { UNIMPLEMENTED(); } -int internal_fstat(fd_t fd, void *buf) { +uptr internal_fstat(fd_t fd, void *buf) { UNIMPLEMENTED(); } @@ -238,7 +289,7 @@ uptr internal_filesize(fd_t fd) { UNIMPLEMENTED(); } -int internal_dup2(int oldfd, int newfd) { +uptr internal_dup2(int oldfd, int newfd) { UNIMPLEMENTED(); } @@ -246,7 +297,7 @@ uptr internal_readlink(const char *path, char *buf, uptr bufsize) { UNIMPLEMENTED(); } -int internal_sched_yield() { +uptr internal_sched_yield() { Sleep(0); return 0; } @@ -268,6 +319,12 @@ BlockingMutex::BlockingMutex(LinkerInitialized li) { owner_ = LOCK_READY; } +BlockingMutex::BlockingMutex() { + CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); + InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); + owner_ = LOCK_READY; +} + void BlockingMutex::Lock() { if (owner_ == LOCK_UNINITIALIZED) { // FIXME: hm, global BlockingMutex objects are not initialized?!? @@ -289,6 +346,79 @@ void BlockingMutex::Unlock() { LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_); } +void BlockingMutex::CheckLocked() { + CHECK_EQ(owner_, GetThreadSelf()); +} + +uptr GetTlsSize() { + return 0; +} + +void InitTlsSize() { +} + +void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, + uptr *tls_addr, uptr *tls_size) { +#ifdef SANITIZER_GO + *stk_addr = 0; + *stk_size = 0; + *tls_addr = 0; + *tls_size = 0; +#else + uptr stack_top, stack_bottom; + GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom); + *stk_addr = stack_bottom; + *stk_size = stack_top - stack_bottom; + *tls_addr = 0; + *tls_size = 0; +#endif +} + +void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, + uptr stack_top, uptr stack_bottom, bool fast) { + (void)fast; + (void)stack_top; + (void)stack_bottom; + stack->max_size = max_s; + void *tmp[kStackTraceMax]; + + // FIXME: CaptureStackBackTrace might be too slow for us. + // FIXME: Compare with StackWalk64. + // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc + uptr cs_ret = CaptureStackBackTrace(1, stack->max_size, tmp, 0); + uptr offset = 0; + // Skip the RTL frames by searching for the PC in the stacktrace. + // FIXME: this doesn't work well for the malloc/free stacks yet. + for (uptr i = 0; i < cs_ret; i++) { + if (pc != (uptr)tmp[i]) + continue; + offset = i; + break; + } + + stack->size = cs_ret - offset; + for (uptr i = 0; i < stack->size; i++) + stack->trace[i] = (uptr)tmp[i + offset]; +} + +void MaybeOpenReportFile() { + // Windows doesn't have native fork, and we don't support Cygwin or other + // environments that try to fake it, so the initial report_fd will always be + // correct. +} + +void RawWrite(const char *buffer) { + static const char *kRawWriteError = + "RawWrite can't output requested buffer!\n"; + uptr length = (uptr)internal_strlen(buffer); + if (length != internal_write(report_fd, buffer, length)) { + // stderr may be closed, but we may be able to print to the debugger + // instead. This is the case when launching a program from Visual Studio, + // and the following routine should write to its console. + OutputDebugStringA(buffer); + } +} + } // namespace __sanitizer #endif // _WIN32 |