diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-02-10 07:45:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-02-10 07:45:43 +0000 |
commit | 476c4db3dc56bee43df384704c75ccc71cfa7a1d (patch) | |
tree | 5d0dcec3cc12fc53532fc84029892b98711a2596 /lib/sanitizer_common/sanitizer_win.cc | |
parent | ca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (diff) | |
download | src-476c4db3dc56bee43df384704c75ccc71cfa7a1d.tar.gz src-476c4db3dc56bee43df384704c75ccc71cfa7a1d.zip |
Import compiler-rt trunk r228651.vendor/compiler-rt/compiler-rt-r228651
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=278497
svn path=/vendor/compiler-rt/compiler-rt-r228651/; revision=278498; tag=vendor/compiler-rt/compiler-rt-r228651
Diffstat (limited to 'lib/sanitizer_common/sanitizer_win.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_win.cc | 110 |
1 files changed, 100 insertions, 10 deletions
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index 3e9014199651..edd4bd11b369 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -20,6 +20,7 @@ #include <windows.h> #include <dbghelp.h> #include <io.h> +#include <psapi.h> #include <stdlib.h> #include "sanitizer_common.h" @@ -122,18 +123,34 @@ void *MmapNoReserveOrDie(uptr size, const char *mem_type) { } void *Mprotect(uptr fixed_addr, uptr size) { - return VirtualAlloc((LPVOID)fixed_addr, size, - MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); + void *res = VirtualAlloc((LPVOID)fixed_addr, size, + MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); + if (res == 0) + Report("WARNING: %s failed to " + "mprotect %p (%zd) bytes at %p (error code: %d)\n", + SanitizerToolName, size, size, fixed_addr, GetLastError()); + return res; } void FlushUnneededShadowMemory(uptr addr, uptr size) { // This is almost useless on 32-bits. - // FIXME: add madvice-analog when we move to 64-bits. + // FIXME: add madvise-analog when we move to 64-bits. +} + +void NoHugePagesInRegion(uptr addr, uptr size) { + // FIXME: probably similar to FlushUnneededShadowMemory. +} + +void DontDumpShadowMemory(uptr addr, uptr length) { + // This is almost useless on 32-bits. + // FIXME: add madvise-analog when we move to 64-bits. } bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { - // FIXME: shall we do anything here on Windows? - return true; + MEMORY_BASIC_INFORMATION mbi; + CHECK(VirtualQuery((void *)range_start, &mbi, sizeof(mbi))); + return mbi.Protect == PAGE_NOACCESS && + (uptr)mbi.BaseAddress + mbi.RegionSize >= range_end; } void *MapFileToMemory(const char *file_name, uptr *buff_size) { @@ -187,8 +204,77 @@ u32 GetUid() { UNIMPLEMENTED(); } +namespace { +struct ModuleInfo { + HMODULE handle; + uptr base_address; + uptr end_address; +}; + +int CompareModulesBase(const void *pl, const void *pr) { + const ModuleInfo &l = *(ModuleInfo *)pl, &r = *(ModuleInfo *)pr; + if (l.base_address < r.base_address) + return -1; + return l.base_address > r.base_address; +} +} // namespace + void DumpProcessMap() { - UNIMPLEMENTED(); + Report("Dumping process modules:\n"); + HANDLE cur_process = GetCurrentProcess(); + + // Query the list of modules. Start by assuming there are no more than 256 + // modules and retry if that's not sufficient. + ModuleInfo *modules; + size_t num_modules; + { + HMODULE *hmodules = 0; + uptr modules_buffer_size = sizeof(HMODULE) * 256; + DWORD bytes_required; + while (!hmodules) { + hmodules = (HMODULE *)MmapOrDie(modules_buffer_size, __FUNCTION__); + CHECK(EnumProcessModules(cur_process, hmodules, modules_buffer_size, + &bytes_required)); + if (bytes_required > modules_buffer_size) { + // Either there turned out to be more than 256 hmodules, or new hmodules + // could have loaded since the last try. Retry. + UnmapOrDie(hmodules, modules_buffer_size); + hmodules = 0; + modules_buffer_size = bytes_required; + } + } + + num_modules = bytes_required / sizeof(HMODULE); + modules = + (ModuleInfo *)MmapOrDie(num_modules * sizeof(ModuleInfo), __FUNCTION__); + for (size_t i = 0; i < num_modules; ++i) { + modules[i].handle = hmodules[i]; + MODULEINFO mi; + if (!GetModuleInformation(cur_process, hmodules[i], &mi, sizeof(mi))) + continue; + modules[i].base_address = (uptr)mi.lpBaseOfDll; + modules[i].end_address = (uptr)mi.lpBaseOfDll + mi.SizeOfImage; + } + UnmapOrDie(hmodules, modules_buffer_size); + } + + qsort(modules, num_modules, sizeof(ModuleInfo), CompareModulesBase); + + for (size_t i = 0; i < num_modules; ++i) { + const ModuleInfo &mi = modules[i]; + char module_name[MAX_PATH]; + bool got_module_name = GetModuleFileNameEx( + cur_process, mi.handle, module_name, sizeof(module_name)); + if (mi.end_address != 0) { + Printf("\t%p-%p %s\n", mi.base_address, mi.end_address, + got_module_name ? module_name : "[no name]"); + } else if (got_module_name) { + Printf("\t??\?-??? %s\n", module_name); + } else { + Printf("\t???\n"); + } + } + UnmapOrDie(modules, num_modules * sizeof(ModuleInfo)); } void DisableCoreDumperIfNecessary() { @@ -238,8 +324,9 @@ u64 NanoTime() { } void Abort() { - abort(); - internal__exit(-1); // abort is not NORETURN on Windows. + if (::IsDebuggerPresent()) + __debugbreak(); + internal__exit(3); } uptr GetListOfModules(LoadedModule *modules, uptr max_modules, @@ -379,6 +466,9 @@ uptr GetRSS() { return 0; } +void *internal_start_thread(void (*func)(void *arg), void *arg) { return 0; } +void internal_join_thread(void *th) { } + // ---------------------- BlockingMutex ---------------- {{{1 const uptr LOCK_UNINITIALIZED = 0; const uptr LOCK_READY = (uptr)-1; @@ -448,7 +538,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, } #if !SANITIZER_GO -void BufferedStackTrace::SlowUnwindStack(uptr pc, uptr max_depth) { +void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { CHECK_GE(max_depth, 2); // FIXME: CaptureStackBackTrace might be too slow for us. // FIXME: Compare with StackWalk64. @@ -464,7 +554,7 @@ void BufferedStackTrace::SlowUnwindStack(uptr pc, uptr max_depth) { } void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, - uptr max_depth) { + u32 max_depth) { CONTEXT ctx = *(CONTEXT *)context; STACKFRAME64 stack_frame; memset(&stack_frame, 0, sizeof(stack_frame)); |