server: Specify the user APC to call only once the system APC has executed.
[wine] / server / context_x86_64.c
1 /*
2  * x86-64 register context support
3  *
4  * Copyright (C) 1999, 2005 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #ifdef __x86_64__
24
25 #include <assert.h>
26 #include <errno.h>
27 #include <stdarg.h>
28 #include <unistd.h>
29
30 #define NONAMELESSUNION
31 #include "windef.h"
32 #include "winbase.h"
33
34 #include "file.h"
35 #include "thread.h"
36 #include "request.h"
37
38 /* copy a context structure according to the flags */
39 void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
40 {
41     flags &= ~CONTEXT_AMD64;  /* get rid of CPU id */
42     if (flags & CONTEXT_CONTROL)
43     {
44         to->Rbp    = from->Rbp;
45         to->Rip    = from->Rip;
46         to->Rsp    = from->Rsp;
47         to->SegCs  = from->SegCs;
48         to->SegSs  = from->SegSs;
49         to->EFlags = from->EFlags;
50         to->MxCsr  = from->MxCsr;
51     }
52     if (flags & CONTEXT_INTEGER)
53     {
54         to->Rax = from->Rax;
55         to->Rcx = from->Rcx;
56         to->Rdx = from->Rdx;
57         to->Rbx = from->Rbx;
58         to->Rsi = from->Rsi;
59         to->Rdi = from->Rdi;
60         to->R8  = from->R8;
61         to->R9  = from->R9;
62         to->R10 = from->R10;
63         to->R11 = from->R11;
64         to->R12 = from->R12;
65         to->R13 = from->R13;
66         to->R14 = from->R14;
67         to->R15 = from->R15;
68     }
69     if (flags & CONTEXT_SEGMENTS)
70     {
71         to->SegDs = from->SegDs;
72         to->SegEs = from->SegEs;
73         to->SegFs = from->SegFs;
74         to->SegGs = from->SegGs;
75     }
76     if (flags & CONTEXT_FLOATING_POINT)
77     {
78         to->u.FltSave = from->u.FltSave;
79     }
80     /* we don't bother copying the debug registers, since they */
81     /* always need to be accessed by ptrace anyway */
82     to->ContextFlags |= flags & ~CONTEXT_DEBUG_REGISTERS;
83 }
84
85 /* retrieve the current instruction pointer of a context */
86 void *get_context_ip( const CONTEXT *context )
87 {
88     return (void *)context->Rip;
89 }
90
91 /* return the context flag that contains the CPU id */
92 unsigned int get_context_cpu_flag(void)
93 {
94     return CONTEXT_AMD64;
95 }
96
97 /* return only the context flags that correspond to system regs */
98 /* (system regs are the ones we can't access on the client side) */
99 unsigned int get_context_system_regs( unsigned int flags )
100 {
101     return flags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64);
102 }
103
104 #endif  /* __x86_64__ */