aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_windows.h
blob: 75020ef03e31332f3c6b02fa07cb9ef374829d5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

// This file is shared between executor and csource package.

#include <direct.h> // for _chdir
#include <io.h> // for mktemp
#include <windows.h>

#if SYZ_EXECUTOR || SYZ_HANDLE_SEGV
static void install_segv_handler()
{
}

#define NONFAILING(...) \
	([&]() { __try { __VA_ARGS__; } __except (EXCEPTION_EXECUTE_HANDLER) { return false; } return true; }())
#endif

#if SYZ_EXECUTOR || SYZ_THREADED || SYZ_REPEAT && SYZ_EXECUTOR_USES_FORK_SERVER
static uint64 current_time_ms()
{
	return GetTickCount64();
}
#endif

#if SYZ_EXECUTOR || SYZ_THREADED || SYZ_REPEAT && SYZ_EXECUTOR_USES_FORK_SERVER
static void sleep_ms(uint64 ms)
{
	Sleep(ms);
}
#endif

#if SYZ_EXECUTOR || SYZ_THREADED
static void thread_start(void* (*fn)(void*), void* arg)
{
	HANDLE th = CreateThread(NULL, 128 << 10, (LPTHREAD_START_ROUTINE)fn, arg, 0, NULL);
	if (th == NULL)
		exitf("CreateThread failed");
}

struct event_t {
	CRITICAL_SECTION cs;
	CONDITION_VARIABLE cv;
	int state;
};

static void event_init(event_t* ev)
{
	InitializeCriticalSection(&ev->cs);
	InitializeConditionVariable(&ev->cv);
	ev->state = 0;
}

static void event_reset(event_t* ev)
{
	ev->state = 0;
}

static void event_set(event_t* ev)
{
	EnterCriticalSection(&ev->cs);
	if (ev->state)
		exitf("event already set");
	ev->state = 1;
	LeaveCriticalSection(&ev->cs);
	WakeAllConditionVariable(&ev->cv);
}

static void event_wait(event_t* ev)
{
	EnterCriticalSection(&ev->cs);
	while (!ev->state)
		SleepConditionVariableCS(&ev->cv, &ev->cs, INFINITE);
	LeaveCriticalSection(&ev->cs);
}

static int event_isset(event_t* ev)
{
	EnterCriticalSection(&ev->cs);
	int res = ev->state;
	LeaveCriticalSection(&ev->cs);
	return res;
}

static int event_timedwait(event_t* ev, uint64 timeout_ms)
{
	EnterCriticalSection(&ev->cs);
	uint64 start = current_time_ms();
	for (;;) {
		if (ev->state)
			break;
		uint64 now = current_time_ms();
		if (now - start > timeout_ms)
			break;
		SleepConditionVariableCS(&ev->cv, &ev->cs, timeout_ms - (now - start));
	}
	int res = ev->state;
	LeaveCriticalSection(&ev->cs);
	return res;
}
#endif

#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
static void loop();
static int do_sandbox_none(void)
{
	loop();
	return 0;
}
#endif

static void use_temporary_dir(void)
{
	char tmpdir_template[] = "./syzkaller.XXXXXX";
	char* tmpdir = mktemp(tmpdir_template);

	CreateDirectory(tmpdir, NULL);
	_chdir(tmpdir);
}