sb-bsd-sockets: More robust inet-socket-bind test on Windows.
[sbcl.git] / src / runtime / x86-64-win32-os.c
1 /*
2  * The x86 Win32 incarnation of arch-dependent OS-dependent routines.
3  * See also "win32-os.c".
4  */
5
6 /*
7  * This software is part of the SBCL system. See the README file for
8  * more information.
9  *
10  * This software is derived from the CMU CL system, which was
11  * written at Carnegie Mellon University and released into the
12  * public domain. The software is in the public domain and is
13  * provided with absolutely no warranty. See the COPYING and CREDITS
14  * files for more information.
15  */
16
17 #include <stdio.h>
18 #include <stddef.h>
19 #include <sys/param.h>
20 #include <sys/file.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 #include <errno.h>
24
25 #include "os.h"
26 #include "arch.h"
27 #include "globals.h"
28 #include "interrupt.h"
29 #include "interr.h"
30 #include "lispregs.h"
31 #include "sbcl.h"
32
33 #include <sys/types.h>
34 #include "runtime.h"
35 #include <sys/time.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38 #include "thread.h"             /* dynamic_values_bytes */
39 #include "cpputil.h"
40
41 #include "validate.h"
42 size_t os_vm_page_size;
43
44 int arch_os_thread_init(struct thread *thread)
45 {
46     {
47         void *top_exception_frame;
48         void *cur_stack_end;
49         void *cur_stack_start;
50         MEMORY_BASIC_INFORMATION stack_memory;
51
52         asm volatile ("mov %%gs:0,%0": "=r" (top_exception_frame));
53         asm volatile ("mov %%gs:8,%0": "=r" (cur_stack_end));
54
55         /* Can't pull stack start from fs:4 or fs:8 or whatever,
56          * because that's only what currently has memory behind
57          * it from being used, so do a quick VirtualQuery() and
58          * grab the AllocationBase. -AB 2006/11/25
59          */
60
61         if (!VirtualQuery(&stack_memory, &stack_memory, sizeof(stack_memory))) {
62             fprintf(stderr, "VirtualQuery: 0x%lx.\n", GetLastError());
63             lose("Could not query stack memory information.");
64         }
65
66         cur_stack_start = stack_memory.AllocationBase
67             /* OS provides its own guard page at the stack start,
68                and we have ours. Do you really want to see how they interact? */
69             + os_vm_page_size;
70
71         /* We use top_exception_frame rather than cur_stack_end to
72          * elide the last few (boring) stack entries at the bottom of
73          * the backtrace.
74          */
75         thread->control_stack_start = cur_stack_start;
76         thread->control_stack_end = cur_stack_end;
77
78 #ifndef LISP_FEATURE_SB_THREAD
79         /*
80          * Theoretically, threaded SBCL binds directly against
81          * the thread structure for these values. We don't do
82          * threads yet, but we'll probably do the same. We do
83          * need to reset these, though, because they were
84          * initialized based on the wrong stack space.
85          */
86         SetSymbolValue(CONTROL_STACK_START,(lispobj)thread->control_stack_start,thread);
87         SetSymbolValue(CONTROL_STACK_END,(lispobj)thread->control_stack_end,thread);
88 #endif
89     }
90
91 #ifdef LISP_FEATURE_SB_THREAD
92     pthread_setspecific(specials,thread);
93 #endif
94     return 1;
95 }
96
97 /* free any arch/os-specific resources used by thread, which is now
98  * defunct.  Not called on live threads
99  */
100
101 int arch_os_thread_cleanup(struct thread *thread) {
102     return 0;
103 }
104
105 #if defined(LISP_FEATURE_SB_THREAD)
106 sigset_t *os_context_sigmask_addr(os_context_t *context)
107 {
108   return &context->sigmask;
109 }
110 #endif
111
112 os_context_register_t *
113 os_context_register_addr(os_context_t *context, int offset)
114 {
115     static const size_t offsets[16] = {
116         offsetof(CONTEXT,Rax),
117         offsetof(CONTEXT,Rcx),
118         offsetof(CONTEXT,Rdx),
119         offsetof(CONTEXT,Rbx),
120         offsetof(CONTEXT,Rsp),
121         offsetof(CONTEXT,Rbp),
122         offsetof(CONTEXT,Rsi),
123         offsetof(CONTEXT,Rdi),
124         offsetof(CONTEXT,R8),
125         offsetof(CONTEXT,R9),
126         offsetof(CONTEXT,R10),
127         offsetof(CONTEXT,R11),
128         offsetof(CONTEXT,R12),
129         offsetof(CONTEXT,R13),
130         offsetof(CONTEXT,R14),
131         offsetof(CONTEXT,R15),
132     };
133     return
134         (offset >= 0 && offset < 32) ?
135         ((void*)(context->win32_context)) + offsets[offset>>1]  : 0;
136 }
137
138 os_context_register_t *
139 os_context_pc_addr(os_context_t *context)
140 {
141     return (void*)&context->win32_context->Rip; /*  REG_EIP */
142 }
143
144 os_context_register_t *
145 os_context_sp_addr(os_context_t *context)
146 {
147     return (void*)&context->win32_context->Rsp; /* REG_UESP */
148 }
149
150 os_context_register_t *
151 os_context_fp_addr(os_context_t *context)
152 {
153     return (void*)&context->win32_context->Rbp; /* REG_EBP */
154 }
155
156 unsigned long
157 os_context_fp_control(os_context_t *context)
158 {
159     return ((((context->win32_context->FloatSave.ControlWord) & 0xffff) ^ 0x3f) |
160             (((context->win32_context->FloatSave.StatusWord) & 0xffff) << 16));
161 }
162
163 void
164 os_restore_fp_control(os_context_t *context)
165 {
166     asm ("fldcw %0" : : "m" (context->win32_context->FloatSave.ControlWord));
167 }
168
169 void
170 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
171 {
172 }