2 * The x86 Win32 incarnation of arch-dependent OS-dependent routines.
3 * See also "win32-os.c".
7 * This software is part of the SBCL system. See the README file for
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.
19 #include <sys/param.h>
21 #include <sys/types.h>
28 #include "interrupt.h"
31 #include "genesis/sbcl.h"
33 #include <sys/types.h>
38 #include "thread.h" /* dynamic_values_bytes */
39 #include "align.h" /* PTR_ALIGN... */
43 int arch_os_thread_init(struct thread
*thread
)
46 void *top_exception_frame
;
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
;
67 /* We use top_exception_frame rather than cur_stack_end to
68 * elide the last few (boring) stack entries at the bottom of
71 thread
->control_stack_start
= cur_stack_start
;
72 thread
->control_stack_end
= top_exception_frame
;
75 TlsSetValue(OUR_TLS_INDEX
,thread
);
77 extern void win32_set_stack_guarantee(void);
78 win32_set_stack_guarantee();
83 /* free any arch/os-specific resources used by thread, which is now
84 * defunct. Not called on live threads
87 int arch_os_thread_cleanup(struct thread
*thread
) {
91 sigset_t
*os_context_sigmask_addr(os_context_t
*context
)
93 return &context
->sigmask
;
96 os_context_register_t
*
97 os_context_register_addr(os_context_t
*context
, int offset
)
99 static const size_t offsets
[8] = {
100 offsetof(CONTEXT
,Eax
),
101 offsetof(CONTEXT
,Ecx
),
102 offsetof(CONTEXT
,Edx
),
103 offsetof(CONTEXT
,Ebx
),
104 offsetof(CONTEXT
,Esp
),
105 offsetof(CONTEXT
,Ebp
),
106 offsetof(CONTEXT
,Esi
),
107 offsetof(CONTEXT
,Edi
),
110 (offset
>= 0 && offset
< 16) ?
111 ((void*)(context
->win32_context
)) + offsets
[offset
>>1] : 0;
114 os_context_register_t
*
115 os_context_sp_addr(os_context_t
*context
)
117 return (void*)&context
->win32_context
->Esp
; /* REG_UESP */
120 os_context_register_t
*
121 os_context_fp_addr(os_context_t
*context
)
123 return (void*)&context
->win32_context
->Ebp
; /* REG_EBP */
127 os_context_fp_control(os_context_t
*context
)
129 return ((((context
->win32_context
->FloatSave
.ControlWord
) & 0xffff) ^ 0x3f) |
130 (((context
->win32_context
->FloatSave
.StatusWord
) & 0xffff) << 16));
134 os_restore_fp_control(os_context_t
*context
)
136 asm ("fldcw %0" : : "m" (context
->win32_context
->FloatSave
.ControlWord
));
139 os_context_register_t
*
140 os_context_float_register_addr(os_context_t
*context
, int offset
)
142 return (os_context_register_t
*)&context
->win32_context
->FloatSave
.RegisterArea
[offset
];
145 os_flush_icache(os_vm_address_t address
, os_vm_size_t length
)
150 * The stubs below are replacements for the windows versions,
151 * which can -fail- when used in our memory spaces because they
152 * validate the memory spaces they are passed in a way that
153 * denies our exception handler a chance to run.
156 void *memmove(void *dest
, const void *src
, size_t n
)
160 for (i
= 0; i
< n
; i
++) *(((char *)dest
)+i
) = *(((char *)src
)+i
);
162 while (n
--) *(((char *)dest
)+n
) = *(((char *)src
)+n
);
167 void *memcpy(void *dest
, const void *src
, size_t n
)
169 while (n
--) *(((char *)dest
)+n
) = *(((char *)src
)+n
);