run-program: support I/O redirection to binary streams on win32.
[sbcl.git] / src / runtime / x86-win32-os.c
blob5fc49f9ae3105d5ddec6c264ad108cd575c61e4e
1 /*
2 * The x86 Win32 incarnation of arch-dependent OS-dependent routines.
3 * See also "win32-os.c".
4 */
6 /*
7 * This software is part of the SBCL system. See the README file for
8 * more information.
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.
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>
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"
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" /* PTR_ALIGN... */
41 #include "validate.h"
43 int arch_os_thread_init(struct thread *thread)
46 void *top_exception_frame;
47 void *cur_stack_end;
48 void *cur_stack_start;
49 MEMORY_BASIC_INFORMATION stack_memory;
51 asm volatile ("movl %%fs:0,%0": "=r" (top_exception_frame));
52 asm volatile ("movl %%fs:4,%0": "=r" (cur_stack_end));
54 /* Can't pull stack start from fs:4 or fs:8 or whatever,
55 * because that's only what currently has memory behind
56 * it from being used, so do a quick VirtualQuery() and
57 * grab the AllocationBase. -AB 2006/11/25
60 if (!VirtualQuery(&stack_memory, &stack_memory, sizeof(stack_memory))) {
61 fprintf(stderr, "VirtualQuery: 0x%lx.\n", GetLastError());
62 lose("Could not query stack memory information.");
65 cur_stack_start = stack_memory.AllocationBase
66 /* Kludge: Elide SBCL's guard page from the range. (The
67 * real solution is to not establish SBCL's guard page in
68 * the first place. The trick will be to find a good time
69 * at which to re-enable the Windows guard page when
70 * returning from it though.) */
71 + os_vm_page_size;
73 /* We use top_exception_frame rather than cur_stack_end to
74 * elide the last few (boring) stack entries at the bottom of
75 * the backtrace.
77 thread->control_stack_start = cur_stack_start;
78 thread->control_stack_end = top_exception_frame;
80 #ifndef LISP_FEATURE_SB_THREAD
82 * Theoretically, threaded SBCL binds directly against
83 * the thread structure for these values. We don't do
84 * threads yet, but we'll probably do the same. We do
85 * need to reset these, though, because they were
86 * initialized based on the wrong stack space.
88 SetSymbolValue(CONTROL_STACK_START,(lispobj)thread->control_stack_start,thread);
89 SetSymbolValue(CONTROL_STACK_END,(lispobj)thread->control_stack_end,thread);
90 #endif
93 #ifdef LISP_FEATURE_SB_THREAD
94 TlsSetValue(OUR_TLS_INDEX,thread);
95 #endif
96 return 1;
99 /* free any arch/os-specific resources used by thread, which is now
100 * defunct. Not called on live threads
103 int arch_os_thread_cleanup(struct thread *thread) {
104 return 0;
107 #if defined(LISP_FEATURE_SB_THREAD)
108 sigset_t *os_context_sigmask_addr(os_context_t *context)
110 return &context->sigmask;
112 #endif
114 os_context_register_t *
115 os_context_register_addr(os_context_t *context, int offset)
117 static const size_t offsets[8] = {
118 offsetof(CONTEXT,Eax),
119 offsetof(CONTEXT,Ecx),
120 offsetof(CONTEXT,Edx),
121 offsetof(CONTEXT,Ebx),
122 offsetof(CONTEXT,Esp),
123 offsetof(CONTEXT,Ebp),
124 offsetof(CONTEXT,Esi),
125 offsetof(CONTEXT,Edi),
127 return
128 (offset >= 0 && offset < 16) ?
129 ((void*)(context->win32_context)) + offsets[offset>>1] : 0;
132 os_context_register_t *
133 os_context_pc_addr(os_context_t *context)
135 return (void*)&context->win32_context->Eip; /* REG_EIP */
138 os_context_register_t *
139 os_context_sp_addr(os_context_t *context)
141 return (void*)&context->win32_context->Esp; /* REG_UESP */
144 os_context_register_t *
145 os_context_fp_addr(os_context_t *context)
147 return (void*)&context->win32_context->Ebp; /* REG_EBP */
150 unsigned long
151 os_context_fp_control(os_context_t *context)
153 return ((((context->win32_context->FloatSave.ControlWord) & 0xffff) ^ 0x3f) |
154 (((context->win32_context->FloatSave.StatusWord) & 0xffff) << 16));
157 void
158 os_restore_fp_control(os_context_t *context)
160 asm ("fldcw %0" : : "m" (context->win32_context->FloatSave.ControlWord));
163 os_context_register_t *
164 os_context_float_register_addr(os_context_t *context, int offset)
166 return (os_context_register_t*)&context->win32_context->FloatSave.RegisterArea[offset];
168 void
169 os_flush_icache(os_vm_address_t address, os_vm_size_t length)