Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Prefer check size of void* against write 4 or 8
[simgrid.git] / src / xbt / win32_ucontext.c
1 /*\r
2  *      win32-ucontext: Unix ucontext_t operations on Windows platforms\r
3  *      Copyright(C) 2007 Panagiotis E. Hadjidoukas\r
4  *\r
5  *      Contact Email: phadjido@cs.uoi.gr, xdoukas@ceid.upatras.gr\r
6  *\r
7  *      win32-ucontext is free software; you can redistribute it and/or\r
8  *      modify it under the terms of the GNU Lesser General Public\r
9  *      License as published by the Free Software Foundation; either\r
10  *      version 2 of the License, or (at your option) any later version.\r
11  *\r
12  *      win32-ucontext is distributed in the hope that it will be useful,\r
13  *      but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
15  *      Lesser General Public License for more details.\r
16  *\r
17  *      You should have received a copy of the GNU Lesser General Public\r
18  *      License along with SimGrid in the file LICENSE-LGPL-2.1;\r
19  *      if not, write to the Free Software Foundation, Inc.,\r
20  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\r
21  */  \r
22     \r
23 #include "win32_ucontext.h"\r
24 \r
25 int getcontext(ucontext_t * ucp) \r
26 {\r
27   int ret;\r
28   \r
29       /* Retrieve the full machine context */ \r
30       ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;\r
31   ret = GetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);\r
32   return (ret == 0) ? -1 : 0;\r
33 }\r
34 \r
35 int setcontext(const ucontext_t * ucp) \r
36 {\r
37   int ret;\r
38   \r
39       /* Restore the full machine context (already set) */ \r
40       ret = SetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);\r
41   return (ret == 0) ? -1 : 0;\r
42 }\r
43 \r
44 int makecontext(ucontext_t * ucp, void (*func) (), int argc, ...) \r
45 {\r
46   int i;\r
47   va_list ap;\r
48   char *sp;\r
49 \r
50    /* Stack grows down */\r
51       sp = (char *) (size_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size;\r
52   \r
53       /* Reserve stack space for the arguments (maximum possible: argc*(8 bytes per argument)) */ \r
54       sp -= argc * sizeof(void*);\r
55   if (sp < (char *) ucp->uc_stack.ss_sp) {\r
56     \r
57         /* errno = ENOMEM; */ \r
58         return -1;\r
59   }\r
60   \r
61       /* Set the instruction and the stack pointer */\r
62   #ifdef I_X86_\r
63   ucp->uc_mcontext.Eip = (DWORD) func;\r
64   ucp->uc_mcontext.Esp = (DWORD) sp - sizeof(void*);\r
65   #endif\r
66   #ifdef _IA64_\r
67   #  error "_IA64_"\r
68   #endif\r
69   #ifdef _AMD64_\r
70   ucp->uc_mcontext.Rip = (DWORD64) func;\r
71   ucp->uc_mcontext.Rsp = (DWORD64) sp - sizeof(void*);\r
72   #endif\r
73 \r
74       /* Save/Restore the full machine context */ \r
75       ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;\r
76   \r
77       /* Copy the arguments */ \r
78       va_start(ap, argc);\r
79   for (i = 0; i < argc; i++) {\r
80     memcpy(sp, ap, sizeof(void*));\r
81     ap += sizeof(void*);\r
82     sp += sizeof(void*);\r
83   }\r
84   va_end(ap);\r
85   return 0;\r
86 }\r
87 \r
88 int swapcontext(ucontext_t * oucp, const ucontext_t * ucp) \r
89 {\r
90   int ret;\r
91   if ((oucp == NULL) || (ucp == NULL)) {\r
92     \r
93         /*errno = EINVAL; */ \r
94         return -1;\r
95   }\r
96   ret = getcontext(oucp);\r
97   if (ret == 0) {\r
98     ret = setcontext(ucp);\r
99   }\r
100   return ret;\r
101 }\r
102 \r