-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathucontext_w.cpp
More file actions
101 lines (85 loc) · 2.78 KB
/
ucontext_w.cpp
File metadata and controls
101 lines (85 loc) · 2.78 KB
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
/*
* win32/64-ucontext: Unix ucontext_t operations on Windows platforms
* Copyright(C) 2007-2014 Panagiotis E. Hadjidoukas
*
* Contact Email: phadjido@gmail.com, xdoukas@ceid.upatras.gr
*
* win32/64-ucontext is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* win32/64-ucontext is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with win32/64-ucontext in the file COPYING.LIB;
* if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "ucontext_w.h"
#include <stdarg.h>
#include <stdio.h>
int getcontext(ucontext_t *ucp) noexcept
{
int ret;
/* Retrieve the full machine context */
ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;
ret = GetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);
return (ret == 0) ? -1: 0;
}
static int setcontext(const ucontext_t *ucp) noexcept
{
int ret;
/* Restore the full machine context (already set) */
ret = SetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);
return (ret == 0) ? -1: 0;
}
int makecontext(ucontext_t *ucp, void (*func)(), int argc, ...) noexcept
{
int i;
va_list ap;
char *sp;
/* Stack grows down */
sp = (char *) (size_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size;
/* Reserve stack space for the arguments (maximum possible: argc*(8 bytes per argument)) */
sp -= argc * 8;
if ( sp < (char *)ucp->uc_stack.ss_sp) {
/* errno = ENOMEM;*/
return -1;
}
/* Set the instruction and the stack pointer */
#if defined(_X86_)
ucp->uc_mcontext.Eip = (unsigned long long) func;
ucp->uc_mcontext.Esp = (unsigned long long) (sp - 4);
#else
ucp->uc_mcontext.Rip = (unsigned long long) func;
ucp->uc_mcontext.Rsp = (unsigned long long) (sp - 40);
#endif
/* Save/Restore the full machine context */
ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;
/* Copy the arguments */
va_start(ap, argc);
for (i = 0; i<argc; i++) {
memcpy(sp, ap, 8);
ap += 8;
sp += 8;
}
va_end(ap);
return 0;
}
int swapcontext(ucontext_t *oucp, const ucontext_t *ucp) noexcept
{
int ret;
if ((oucp == NULL) || (ucp == NULL)) {
/*errno = EINVAL;*/
return -1;
}
ret = getcontext(oucp);
if (ret == 0) {
ret = setcontext(ucp);
}
return ret;
}