aboutsummaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_win.cc
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-02-10 07:45:43 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-02-10 07:45:43 +0000
commit476c4db3dc56bee43df384704c75ccc71cfa7a1d (patch)
tree5d0dcec3cc12fc53532fc84029892b98711a2596 /lib/sanitizer_common/sanitizer_win.cc
parentca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (diff)
downloadsrc-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.cc110
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));