2 * the Win32 incarnation of OS-dependent routines. See also
3 * $(sbcl_arch)-win32-os.c
5 * This file (along with os.h) exports an OS-independent interface to
6 * the operating system VM facilities. Surprise surprise, this
7 * interface looks a lot like the Mach interface (but simpler in some
8 * places). For some operating systems, a subset of these functions
9 * will have to be emulated.
13 * This software is part of the SBCL system. See the README file for
16 * This software is derived from the CMU CL system, which was
17 * written at Carnegie Mellon University and released into the
18 * public domain. The software is in the public domain and is
19 * provided with absolutely no warranty. See the COPYING and CREDITS
20 * files for more information.
24 * This file was copied from the Linux version of the same, and
25 * likely still has some linuxisms in it have haven't been elimiated
32 #include <sys/param.h>
40 #include "interrupt.h"
45 #include "genesis/primitive-objects.h"
48 #include <sys/types.h>
63 #ifndef LISP_FEATURE_SB_THREAD
64 /* dummy definition to reduce ifdef clutter */
65 #define WITH_GC_AT_SAFEPOINTS_ONLY() if (0) ; else
68 os_vm_size_t os_vm_page_size;
71 #include "gencgc-internal.h"
75 int linux_sparc_siginfo_bug = 0;
76 int linux_supports_futex=0;
82 /* missing definitions for modern mingws */
84 #define EH_UNWINDING 0x02
86 #ifndef EH_EXIT_UNWIND
87 #define EH_EXIT_UNWIND 0x04
90 /* Tired of writing arch_os_get_current_thread each time. */
91 #define this_thread (arch_os_get_current_thread())
93 /* wrappers for winapi calls that must be successful (like SBCL's
94 * (aver ...) form). */
96 /* win_aver function: basic building block for miscellaneous
97 * ..AVER.. macrology (below) */
99 /* To do: These routines used to be "customizable" with dyndebug_init()
100 * and variables like dyndebug_survive_aver, dyndebug_skip_averlax based
101 * on environment variables. Those features got lost on the way, but
102 * ought to be reintroduced. */
105 intptr_t win_aver(intptr_t value, char* comment, char* file, int line,
109 LPSTR errorMessage = "<FormatMessage failed>";
110 DWORD errorCode = GetLastError(), allocated=0;
111 int posixerrno = errno;
112 const char* posixstrerror = strerror(errno);
113 char* report_template =
114 "Expression unexpectedly false: %s:%d\n"
116 " ===> returned #X%p, \n"
118 " ... Win32 thinks:\n"
119 " ===> code %u, message => %s\n"
121 " ===> code %u, message => %s\n";
124 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|
125 FORMAT_MESSAGE_FROM_SYSTEM,
128 MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
129 (LPSTR)&errorMessage,
134 fprintf(stderr, report_template,
138 (unsigned)errorCode, errorMessage,
139 posixerrno, posixstrerror);
141 lose(report_template,
145 (unsigned)errorCode, errorMessage,
146 posixerrno, posixstrerror);
149 LocalFree(errorMessage);
154 /* sys_aver function: really tiny adaptor of win_aver for
155 * "POSIX-parody" CRT results ("lowio" and similar stuff):
156 * negative number means something... negative. */
158 intptr_t sys_aver(long value, char* comment, char* file, int line,
161 win_aver((intptr_t)(value>=0),comment,file,line,justwarn);
165 /* Check for (call) result being boolean true. (call) may be arbitrary
166 * expression now; massive attack of gccisms ensures transparent type
167 * conversion back and forth, so the type of AVER(expression) is the
168 * type of expression. Value is the same _if_ it can be losslessly
169 * converted to (void*) and back.
171 * Failed AVER() is normally fatal. Well, unless dyndebug_survive_aver
175 ({ __typeof__(call) __attribute__((unused)) me = \
177 win_aver((intptr_t)(call), #call, __FILE__, __LINE__, 0); \
180 /* AVERLAX(call): do the same check as AVER did, but be mild on
181 * failure: print an annoying unrequested message to stderr, and
182 * continue. With dyndebug_skip_averlax flag, AVERLAX stop even to
183 * check and complain. */
185 #define AVERLAX(call) \
186 ({ __typeof__(call) __attribute__((unused)) me = \
188 win_aver((intptr_t)(call), #call, __FILE__, __LINE__, 1); \
191 /* Now, when failed AVER... prints both errno and GetLastError(), two
192 * variants of "POSIX/lowio" style checks below are almost useless
193 * (they build on sys_aver like the two above do on win_aver). */
195 #define CRT_AVER_NONNEGATIVE(call) \
196 ({ __typeof__(call) __attribute__((unused)) me = \
198 sys_aver((call), #call, __FILE__, __LINE__, 0); \
201 #define CRT_AVERLAX_NONNEGATIVE(call) \
202 ({ __typeof__(call) __attribute__((unused)) me = \
204 sys_aver((call), #call, __FILE__, __LINE__, 1); \
208 #define CRT_AVER(booly) \
209 ({ __typeof__(booly) __attribute__((unused)) me = (booly); \
210 sys_aver((booly)?0:-1, #booly, __FILE__, __LINE__, 0); \
213 const char * t_nil_s(lispobj symbol);
216 * The following signal-mask-related alien routines are called from Lisp:
219 /* As of win32, deferrables _do_ matter. gc_signal doesn't. */
220 unsigned long block_deferrables_and_return_mask()
223 block_deferrable_signals(0, &sset);
224 return (unsigned long)sset;
227 #if defined(LISP_FEATURE_SB_THREAD)
228 void apply_sigmask(unsigned long sigmask)
230 sigset_t sset = (sigset_t)sigmask;
231 pthread_sigmask(SIG_SETMASK, &sset, 0);
235 /* The exception handling function looks like this: */
236 EXCEPTION_DISPOSITION handle_exception(EXCEPTION_RECORD *,
237 struct lisp_exception_frame *,
240 /* handle_exception is defined further in this file, but since SBCL
241 * 1.0.1.24, it doesn't get registered as SEH handler directly anymore,
242 * not even by wos_install_interrupt_handlers. Instead, x86-assem.S
243 * provides exception_handler_wrapper; we install it here, and each
244 * exception frame on nested funcall()s also points to it.
248 void *base_seh_frame;
250 static void *get_seh_frame(void)
253 #ifdef LISP_FEATURE_X86
254 asm volatile ("mov %%fs:0,%0": "=r" (retval));
256 asm volatile ("mov %%gs:0,%0": "=r" (retval));
261 static void set_seh_frame(void *frame)
263 #ifdef LISP_FEATURE_X86
264 asm volatile ("mov %0,%%fs:0": : "r" (frame));
266 asm volatile ("mov %0,%%gs:0": : "r" (frame));
270 #if defined(LISP_FEATURE_SB_THREAD)
272 /* Permit loads from GC_SAFEPOINT_PAGE_ADDR (NB page state change is
273 * "synchronized" with the memory region content/availability --
274 * e.g. you won't see other CPU flushing buffered writes after WP --
275 * but there is some window when other thread _seem_ to trap AFTER
276 * access is granted. You may think of it something like "OS enters
277 * SEH handler too slowly" -- what's important is there's no implicit
278 * synchronization between VirtualProtect caller and other thread's
279 * SEH handler, hence no ordering of events. VirtualProtect is
280 * implicitly synchronized with protected memory contents (only).
282 * The last fact may be potentially used with many benefits e.g. for
283 * foreign call speed, but we don't use it for now: almost the only
284 * fact relevant to the current signalling protocol is "sooner or
285 * later everyone will trap [everyone will stop trapping]".
287 * An interesting source on page-protection-based inter-thread
288 * communication is a well-known paper by Dave Dice, Hui Huang,
289 * Mingyao Yang: ``Asymmetric Dekker Synchronization''. Last time
290 * I checked it was available at
291 * http://home.comcast.net/~pjbishop/Dave/Asymmetric-Dekker-Synchronization.txt
296 AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
297 PAGE_READWRITE, &oldProt));
303 AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
304 PAGE_NOACCESS, &oldProt));
309 #if defined(LISP_FEATURE_SB_THREAD)
310 /* We want to get a slot in TIB that (1) is available at constant
311 offset, (2) is our private property, so libraries wouldn't legally
312 override it, (3) contains something predefined for threads created
315 Low 64 TLS slots are adressable directly, starting with
316 FS:[#xE10]. When SBCL runtime is initialized, some of the low slots
317 may be already in use by its prerequisite DLLs, as DllMain()s and
318 TLS callbacks have been called already. But slot 63 is unlikely to
319 be reached at this point: one slot per DLL that needs it is the
320 common practice, and many system DLLs use predefined TIB-based
321 areas outside conventional TLS storage and don't need TLS slots.
322 With our current dependencies, even slot 2 is observed to be free
323 (as of WinXP and wine).
325 Now we'll call TlsAlloc() repeatedly until slot 63 is officially
326 assigned to us, then TlsFree() all other slots for normal use. TLS
327 slot 63, alias FS:[#.(+ #xE10 (* 4 63))], now belongs to us.
329 To summarize, let's list the assumptions we make:
331 - TIB, which is FS segment base, contains first 64 TLS slots at the
332 offset #xE10 (i.e. TIB layout compatibility);
333 - TLS slots are allocated from lower to higher ones;
334 - All libraries together with CRT startup have not requested 64
337 All these assumptions together don't seem to be less warranted than
338 the availability of TIB arbitrary data slot for our use. There are
339 some more reasons to prefer slot 63 over TIB arbitrary data: (1) if
340 our assumptions for slot 63 are violated, it will be detected at
341 startup instead of causing some system-specific unreproducible
342 problems afterwards, depending on OS and loaded foreign libraries;
343 (2) if getting slot 63 reliably with our current approach will
344 become impossible for some future Windows version, we can add TLS
345 callback directory to SBCL binary; main image TLS callback is
346 started before _any_ TLS slot is allocated by libraries, and
347 some C compiler vendors rely on this fact. */
351 #ifdef LISP_FEATURE_X86
352 DWORD slots[TLS_MINIMUM_AVAILABLE];
355 for (i=0; i<TLS_MINIMUM_AVAILABLE; ++i) {
357 if (key == OUR_TLS_INDEX) {
358 if (TlsGetValue(key)!=NULL)
359 lose("TLS slot assertion failed: fresh slot value is not NULL");
360 TlsSetValue(OUR_TLS_INDEX, (void*)(intptr_t)0xFEEDBAC4);
361 if ((intptr_t)(void*)arch_os_get_current_thread()!=(intptr_t)0xFEEDBAC4)
362 lose("TLS slot assertion failed: TIB layout change detected");
363 TlsSetValue(OUR_TLS_INDEX, NULL);
366 slots[n_slots++]=key;
368 for (i=0; i<n_slots; ++i) {
371 if (key!=OUR_TLS_INDEX) {
372 lose("TLS slot assertion failed: slot 63 is unavailable "
373 "(last TlsAlloc() returned %u)",key);
377 #endif /* LISP_FEATURE_SB_THREAD */
379 int os_number_of_processors = 1;
381 void os_init(char *argv[], char *envp[])
383 SYSTEM_INFO system_info;
384 GetSystemInfo(&system_info);
385 os_vm_page_size = system_info.dwPageSize > BACKEND_PAGE_BYTES?
386 system_info.dwPageSize : BACKEND_PAGE_BYTES;
387 #if defined(LISP_FEATURE_X86)
388 fast_bzero_pointer = fast_bzero_detect;
390 os_number_of_processors = system_info.dwNumberOfProcessors;
392 base_seh_frame = get_seh_frame();
395 static inline boolean local_thread_stack_address_p(os_vm_address_t address)
397 return this_thread &&
398 (((((u64)address >= (u64)this_thread->os_address) &&
399 ((u64)address < ((u64)this_thread)-THREAD_CSP_PAGE_SIZE))||
400 (((u64)address >= (u64)this_thread->control_stack_start)&&
401 ((u64)address < (u64)this_thread->control_stack_end))));
405 * So we have three fun scenarios here.
407 * First, we could be being called to reserve the memory areas
408 * during initialization (prior to loading the core file).
410 * Second, we could be being called by the GC to commit a page
411 * that has just been decommitted (for easy zero-fill).
413 * Third, we could be being called by create_thread_struct()
414 * in order to create the sundry and various stacks.
416 * The third case is easy to pick out because it passes an
419 * The second case is easy to pick out because it will be for
420 * a range of memory that is MEM_RESERVE rather than MEM_FREE.
422 * The second case is also an easy implement, because we leave
423 * the memory as reserved (since we do lazy commits).
427 os_validate(os_vm_address_t addr, os_vm_size_t len)
429 MEMORY_BASIC_INFORMATION mem_info;
432 /* the simple case first */
434 AVERLAX(VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE));
437 if (!AVERLAX(VirtualQuery(addr, &mem_info, sizeof mem_info)))
440 if ((mem_info.State == MEM_RESERVE) && (mem_info.RegionSize >=len)) {
441 /* It would be correct to return here. However, support for Wine
442 * is beneficial, and Wine has a strange behavior in this
443 * department. It reports all memory below KERNEL32.DLL as
444 * reserved, but disallows MEM_COMMIT.
446 * Let's work around it: reserve the region we need for a second
447 * time. The second reservation is documented to fail on normal NT
448 * family, but it will succeed on Wine if this region is
451 VirtualAlloc(addr, len, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
452 /* If it is wine, the second call has succeded, and now the region
453 * is really reserved. */
457 if (mem_info.State == MEM_RESERVE) {
458 fprintf(stderr, "validation of reserved space too short.\n");
460 /* Oddly, we do not treat this assertion as fatal; hence also the
461 * provision for MEM_RESERVE in the following code, I suppose: */
464 if (!AVERLAX(VirtualAlloc(addr, len, (mem_info.State == MEM_RESERVE)?
465 MEM_COMMIT: MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
472 * For os_invalidate(), we merely decommit the memory rather than
473 * freeing the address space. This loses when freeing per-thread
474 * data and related memory since it leaks address space.
476 * So far the original comment (author unknown). It used to continue as
479 * It's not too lossy, however, since the two scenarios I'm aware of
480 * are fd-stream buffers, which are pooled rather than torched, and
481 * thread information, which I hope to pool (since windows creates
482 * threads at its own whim, and we probably want to be able to have
483 * them callback without funky magic on the part of the user, and
484 * full-on thread allocation is fairly heavyweight).
486 * But: As it turns out, we are no longer content with decommitting
487 * without freeing, and have now grown a second function
488 * os_invalidate_free(), sort of a really_os_invalidate().
490 * As discussed on #lisp, this is not a satisfactory solution, and probably
491 * ought to be rectified in the following way:
493 * - Any cases currently going through the non-freeing version of
494 * os_invalidate() are ultimately meant for zero-filling applications.
495 * Replace those use cases with an os_revalidate_bzero() or similarly
496 * named function, which explicitly takes care of that aspect of
499 * - The remaining uses of os_invalidate should actually free, and once
500 * the above is implemented, we can rename os_invalidate_free back to
501 * just os_invalidate().
503 * So far the new plan, as yet unimplemented. -- DFL
507 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
509 AVERLAX(VirtualFree(addr, len, MEM_DECOMMIT));
513 os_invalidate_free(os_vm_address_t addr, os_vm_size_t len)
515 AVERLAX(VirtualFree(addr, 0, MEM_RELEASE));
519 os_invalidate_free_by_any_address(os_vm_address_t addr, os_vm_size_t len)
521 MEMORY_BASIC_INFORMATION minfo;
522 AVERLAX(VirtualQuery(addr, &minfo, sizeof minfo));
523 AVERLAX(minfo.AllocationBase);
524 AVERLAX(VirtualFree(minfo.AllocationBase, 0, MEM_RELEASE));
527 #define maybe_open_osfhandle _open_osfhandle
528 #define maybe_get_osfhandle _get_osfhandle
532 * os_map() is called to map a chunk of the core file into memory.
534 * Unfortunately, Windows semantics completely screws this up, so
535 * we just add backing store from the swapfile to where the chunk
536 * goes and read it up like a normal file. We could consider using
537 * a lazy read (demand page) setup, but that would mean keeping an
538 * open file pointer for the core indefinately (and be one more
539 * thing to maintain).
543 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
547 AVER(VirtualAlloc(addr, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE)||
548 VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT,
549 PAGE_EXECUTE_READWRITE));
551 CRT_AVER_NONNEGATIVE(lseek(fd, offset, SEEK_SET));
553 count = read(fd, addr, len);
554 CRT_AVER( count == len );
559 static DWORD os_protect_modes[8] = {
566 PAGE_EXECUTE_READWRITE,
567 PAGE_EXECUTE_READWRITE,
571 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
575 DWORD new_prot = os_protect_modes[prot];
576 AVER(VirtualProtect(address, length, new_prot, &old_prot)||
577 (VirtualAlloc(address, length, MEM_COMMIT, new_prot) &&
578 VirtualProtect(address, length, new_prot, &old_prot)));
579 odxprint(misc,"Protecting %p + %p vmaccess %d "
580 "newprot %08x oldprot %08x",
581 address,length,prot,new_prot,old_prot);
584 /* FIXME: Now that FOO_END, rather than FOO_SIZE, is the fundamental
585 * description of a space, we could probably punt this and just do
586 * (FOO_START <= x && x < FOO_END) everywhere it's called. */
588 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
590 char* beg = (char*)((uword_t)sbeg);
591 char* end = (char*)((uword_t)sbeg) + slen;
592 char* adr = (char*)a;
593 return (adr >= beg && adr < end);
597 is_linkage_table_addr(os_vm_address_t addr)
599 return in_range_p(addr, LINKAGE_TABLE_SPACE_START, LINKAGE_TABLE_SPACE_END);
602 static boolean is_some_thread_local_addr(os_vm_address_t addr);
605 is_valid_lisp_addr(os_vm_address_t addr)
607 if(in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE) ||
608 in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE) ||
609 in_range_p(addr, DYNAMIC_SPACE_START , dynamic_space_size) ||
610 is_some_thread_local_addr(addr))
615 /* test if an address is within thread-local space */
617 is_thread_local_addr(struct thread* th, os_vm_address_t addr)
619 /* Assuming that this is correct, it would warrant further comment,
620 * I think. Based on what our call site is doing, we have been
621 * tasked to check for the address of a lisp object; not merely any
622 * foreign address within the thread's area. Indeed, this used to
623 * be a check for control and binding stack only, rather than the
624 * full thread "struct". So shouldn't the THREAD_STRUCT_SIZE rather
625 * be (thread_control_stack_size+BINDING_STACK_SIZE) instead? That
626 * would also do away with the LISP_FEATURE_SB_THREAD case. Or does
627 * it simply not matter? --DFL */
628 ptrdiff_t diff = ((char*)th->os_address)-(char*)addr;
629 return diff > (ptrdiff_t)0 && diff < (ptrdiff_t)THREAD_STRUCT_SIZE
630 #ifdef LISP_FEATURE_SB_THREAD
631 && addr != (os_vm_address_t) th->csp_around_foreign_call
637 is_some_thread_local_addr(os_vm_address_t addr)
640 #ifdef LISP_FEATURE_SB_THREAD
642 pthread_mutex_lock(&all_threads_lock);
643 for_each_thread(th) {
644 if(is_thread_local_addr(th,addr)) {
649 pthread_mutex_unlock(&all_threads_lock);
655 /* A tiny bit of interrupt.c state we want our paws on. */
656 extern boolean internal_errors_enabled;
658 extern void exception_handler_wrapper();
661 c_level_backtrace(const char* header, int depth)
667 for (lastseh = get_seh_frame(); lastseh && (lastseh!=(void*)-1);
670 fprintf(stderr, "Backtrace: %s (thread %p)\n", header, this_thread);
671 for (frame = __builtin_frame_address(0); frame; frame=*(void**)frame)
675 fprintf(stderr, "[#%02d]: ebp = 0x%p, ret = 0x%p\n",n,
676 frame, ((void**)frame)[1]);
680 #ifdef LISP_FEATURE_X86
681 #define voidreg(ctxptr,name) ((void*)((ctxptr)->E##name))
683 #define voidreg(ctxptr,name) ((void*)((ctxptr)->R##name))
687 #if defined(LISP_FEATURE_X86)
689 handle_single_step(os_context_t *ctx)
691 if (!single_stepping)
694 /* We are doing a displaced instruction. At least function
695 * end breakpoints use this. */
696 WITH_GC_AT_SAFEPOINTS_ONLY () /* Todo: Is it really gc-unsafe? */
697 restore_breakpoint_from_single_step(ctx);
703 #ifdef LISP_FEATURE_UD2_BREAKPOINTS
704 #define SBCL_EXCEPTION_BREAKPOINT EXCEPTION_ILLEGAL_INSTRUCTION
705 #define TRAP_CODE_WIDTH 2
707 #define SBCL_EXCEPTION_BREAKPOINT EXCEPTION_BREAKPOINT
708 #define TRAP_CODE_WIDTH 1
712 handle_breakpoint_trap(os_context_t *ctx, struct thread* self)
714 #ifdef LISP_FEATURE_UD2_BREAKPOINTS
715 if (((unsigned short *)((ctx->win32_context)->Eip))[0] != 0x0b0f)
719 /* Unlike some other operating systems, Win32 leaves EIP
720 * pointing to the breakpoint instruction. */
721 (*os_context_pc_addr(ctx)) += TRAP_CODE_WIDTH;
723 /* Now EIP points just after the INT3 byte and aims at the
724 * 'kind' value (eg trap_Cerror). */
725 unsigned trap = *(unsigned char *)(*os_context_pc_addr(ctx));
727 #ifdef LISP_FEATURE_SB_THREAD
728 /* Before any other trap handler: gc_safepoint ensures that
729 inner alloc_sap for passing the context won't trap on
731 if (trap == trap_PendingInterrupt) {
732 /* Done everything needed for this trap, except EIP
734 arch_skip_instruction(ctx);
735 thread_interrupted(ctx);
740 /* This is just for info in case the monitor wants to print an
742 access_control_stack_pointer(self) =
743 (lispobj *)*os_context_sp_addr(ctx);
745 WITH_GC_AT_SAFEPOINTS_ONLY() {
746 #if defined(LISP_FEATURE_SB_THREAD)
747 block_blockable_signals(0,&ctx->sigmask);
749 handle_trap(ctx, trap);
750 #if defined(LISP_FEATURE_SB_THREAD)
751 thread_sigmask(SIG_SETMASK,&ctx->sigmask,NULL);
755 /* Done, we're good to go! */
760 handle_access_violation(os_context_t *ctx,
761 EXCEPTION_RECORD *exception_record,
765 CONTEXT *win32_context = ctx->win32_context;
767 #if defined(LISP_FEATURE_X86)
769 "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
770 "Addr %p Access %d\n",
777 exception_record->ExceptionInformation[0]);
780 "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
781 "Addr %p Access %d\n",
788 exception_record->ExceptionInformation[0]);
791 /* Stack: This case takes care of our various stack exhaustion
792 * protect pages (with the notable exception of the control stack!). */
793 if (self && local_thread_stack_address_p(fault_address)) {
794 if (handle_guard_page_triggered(ctx, fault_address))
795 return 0; /* gc safety? */
799 /* Safepoint pages */
800 #ifdef LISP_FEATURE_SB_THREAD
801 if (fault_address == (void *) GC_SAFEPOINT_PAGE_ADDR) {
802 thread_in_lisp_raised(ctx);
806 if ((((u64)fault_address) == ((u64)self->csp_around_foreign_call))){
807 thread_in_safety_transition(ctx);
813 page_index_t index = find_page_index(fault_address);
816 * Now, if the page is supposedly write-protected and this
817 * is a write, tell the gc that it's been hit.
819 if (page_table[index].write_protected) {
820 gencgc_handle_wp_violation(fault_address);
822 AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
824 MEM_COMMIT, PAGE_EXECUTE_READWRITE));
829 if (fault_address == undefined_alien_address)
832 /* linkage table or a "valid_lisp_addr" outside of dynamic space (?) */
833 if (is_linkage_table_addr(fault_address)
834 || is_valid_lisp_addr(fault_address))
840 /* First use of a new page, lets get some memory for it. */
842 #if defined(LISP_FEATURE_X86)
843 AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
845 MEM_COMMIT, PAGE_EXECUTE_READWRITE)
846 ||(fprintf(stderr,"Unable to recommit addr %p eip 0x%08lx\n",
847 fault_address, win32_context->Eip) &&
848 (c_level_backtrace("BT",5),
849 fake_foreign_function_call(ctx),
850 lose("Lispy backtrace"),
853 AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
855 MEM_COMMIT, PAGE_EXECUTE_READWRITE)
856 ||(fprintf(stderr,"Unable to recommit addr %p eip 0x%p\n",
857 fault_address, (void*)win32_context->Rip) &&
858 (c_level_backtrace("BT",5),
859 fake_foreign_function_call(ctx),
860 lose("Lispy backtrace"),
868 signal_internal_error_or_lose(os_context_t *ctx,
869 EXCEPTION_RECORD *exception_record,
873 * If we fall through to here then we need to either forward
874 * the exception to the lisp-side exception handler if it's
875 * set up, or drop to LDB.
878 if (internal_errors_enabled) {
880 lispobj exception_record_sap;
883 /* We're making the somewhat arbitrary decision that having
884 * internal errors enabled means that lisp has sufficient
885 * marbles to be able to handle exceptions, but exceptions
886 * aren't supposed to happen during cold init or reinit
889 #if defined(LISP_FEATURE_SB_THREAD)
890 block_blockable_signals(0,&ctx->sigmask);
892 fake_foreign_function_call(ctx);
894 WITH_GC_AT_SAFEPOINTS_ONLY() {
895 /* Allocate the SAP objects while the "interrupts" are still
897 context_sap = alloc_sap(ctx);
898 exception_record_sap = alloc_sap(exception_record);
899 #if defined(LISP_FEATURE_SB_THREAD)
900 thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
903 /* The exception system doesn't automatically clear pending
904 * exceptions, so we lose as soon as we execute any FP
905 * instruction unless we do this first. */
906 /* Call into lisp to handle things. */
907 funcall2(StaticSymbolFunction(HANDLE_WIN32_EXCEPTION),
909 exception_record_sap);
911 /* If Lisp doesn't nlx, we need to put things back. */
912 undo_fake_foreign_function_call(ctx);
913 #if defined(LISP_FEATURE_SB_THREAD)
914 thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
916 /* FIXME: HANDLE-WIN32-EXCEPTION should be allowed to decline */
920 fprintf(stderr, "Exception Code: 0x%p.\n",
921 (void*)(intptr_t)exception_record->ExceptionCode);
922 fprintf(stderr, "Faulting IP: 0x%p.\n",
923 (void*)(intptr_t)exception_record->ExceptionAddress);
924 if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
925 MEMORY_BASIC_INFORMATION mem_info;
927 if (VirtualQuery(fault_address, &mem_info, sizeof mem_info)) {
928 fprintf(stderr, "page status: 0x%lx.\n", mem_info.State);
931 fprintf(stderr, "Was writing: %p, where: 0x%p.\n",
932 (void*)exception_record->ExceptionInformation[0],
938 fake_foreign_function_call(ctx);
939 lose("Exception too early in cold init, cannot continue.");
943 * A good explanation of the exception handling semantics is
944 * http://win32assembly.online.fr/Exceptionhandling.html (possibly defunct)
946 * http://www.microsoft.com/msj/0197/exception/exception.aspx
949 EXCEPTION_DISPOSITION
950 handle_exception(EXCEPTION_RECORD *exception_record,
951 struct lisp_exception_frame *exception_frame,
952 CONTEXT *win32_context,
953 void *dispatcher_context)
956 /* Not certain why this should be possible, but let's be safe... */
957 return ExceptionContinueSearch;
959 if (exception_record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) {
960 /* If we're being unwound, be graceful about it. */
962 /* Undo any dynamic bindings. */
963 unbind_to_here(exception_frame->bindstack_pointer,
964 arch_os_get_current_thread());
965 return ExceptionContinueSearch;
968 DWORD lastError = GetLastError();
969 DWORD lastErrno = errno;
970 DWORD code = exception_record->ExceptionCode;
971 struct thread* self = arch_os_get_current_thread();
973 os_context_t context, *ctx = &context;
974 context.win32_context = win32_context;
975 #if defined(LISP_FEATURE_SB_THREAD)
976 context.sigmask = self ? self->os_thread->blocked_signal_set : 0;
979 /* For EXCEPTION_ACCESS_VIOLATION only. */
980 void *fault_address = (void *)exception_record->ExceptionInformation[1];
983 "SEH: rec %p, ctxptr %p, rip %p, fault %p\n"
984 "... code %p, rcx %p, fp-tags %p\n\n",
987 voidreg(win32_context,ip),
989 (void*)(intptr_t)code,
990 voidreg(win32_context,cx),
991 win32_context->FloatSave.TagWord);
993 /* This function had become unwieldy. Let's cut it down into
994 * pieces based on the different exception codes. Each exception
995 * code handler gets the chance to decline by returning non-zero if it
1000 case EXCEPTION_ACCESS_VIOLATION:
1001 rc = handle_access_violation(
1002 ctx, exception_record, fault_address, self);
1005 case SBCL_EXCEPTION_BREAKPOINT:
1006 rc = handle_breakpoint_trap(ctx, self);
1009 #if defined(LISP_FEATURE_X86)
1010 case EXCEPTION_SINGLE_STEP:
1011 rc = handle_single_step(ctx);
1020 /* All else failed, drop through to the lisp-side exception handler. */
1021 signal_internal_error_or_lose(ctx, exception_record, fault_address);
1024 SetLastError(lastError);
1025 return ExceptionContinueExecution;
1029 wos_install_interrupt_handlers(struct lisp_exception_frame *handler)
1031 #ifdef LISP_FEATURE_X86
1032 handler->next_frame = get_seh_frame();
1033 handler->handler = (void*)exception_handler_wrapper;
1034 set_seh_frame(handler);
1036 static int once = 0;
1038 AddVectoredExceptionHandler(1,veh);
1043 * The stubs below are replacements for the windows versions,
1044 * which can -fail- when used in our memory spaces because they
1045 * validate the memory spaces they are passed in a way that
1046 * denies our exception handler a chance to run.
1049 void *memmove(void *dest, const void *src, size_t n)
1053 for (i = 0; i < n; i++) *(((char *)dest)+i) = *(((char *)src)+i);
1055 while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1060 void *memcpy(void *dest, const void *src, size_t n)
1062 while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1066 char *dirname(char *path)
1068 static char buf[PATH_MAX + 1];
1069 size_t pathlen = strlen(path);
1072 if (pathlen >= sizeof(buf)) {
1073 lose("Pathname too long in dirname.\n");
1078 for (i = pathlen; i >= 0; --i) {
1079 if (buf[i] == '/' || buf[i] == '\\') {
1088 /* Unofficial but widely used property of console handles: they have
1089 #b11 in two minor bits, opposed to other handles, that are
1090 machine-word-aligned. Properly emulated even on wine.
1092 Console handles are special in many aspects, e.g. they aren't NTDLL
1093 system handles: kernel32 redirects console operations to CSRSS
1094 requests. Using the hack below to distinguish console handles is
1095 justified, as it's the only method that won't hang during
1096 outstanding reads, won't try to lock NT kernel object (if there is
1097 one; console isn't), etc. */
1099 console_handle_p(HANDLE handle)
1101 return (handle != NULL)&&
1102 (handle != INVALID_HANDLE_VALUE)&&
1103 ((((int)(intptr_t)handle)&3)==3);
1106 static const LARGE_INTEGER zero_large_offset = {.QuadPart = 0LL};
1109 win32_unix_write(FDTYPE fd, void * buf, int count)
1112 DWORD written_bytes;
1113 OVERLAPPED overlapped;
1114 struct thread * self = arch_os_get_current_thread();
1116 LARGE_INTEGER file_position;
1120 handle =(HANDLE)maybe_get_osfhandle(fd);
1121 if (console_handle_p(handle))
1122 return write(fd, buf, count);
1124 overlapped.hEvent = self->private_events.events[0];
1125 seekable = SetFilePointerEx(handle,
1130 overlapped.Offset = file_position.LowPart;
1131 overlapped.OffsetHigh = file_position.HighPart;
1133 overlapped.Offset = 0;
1134 overlapped.OffsetHigh = 0;
1136 ok = WriteFile(handle, buf, count, &written_bytes, &overlapped);
1139 goto done_something;
1141 if (GetLastError()!=ERROR_IO_PENDING) {
1145 if(WaitForMultipleObjects(2,self->private_events.events,
1146 FALSE,INFINITE) != WAIT_OBJECT_0) {
1152 if (!GetOverlappedResult(handle,&overlapped,&written_bytes,waitInGOR)) {
1153 if (GetLastError()==ERROR_OPERATION_ABORTED) {
1160 goto done_something;
1166 file_position.QuadPart += written_bytes;
1167 SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
1169 return written_bytes;
1173 win32_unix_read(FDTYPE fd, void * buf, int count)
1176 OVERLAPPED overlapped = {.Internal=0};
1177 DWORD read_bytes = 0;
1178 struct thread * self = arch_os_get_current_thread();
1179 DWORD errorCode = 0;
1180 BOOL waitInGOR = FALSE;
1182 LARGE_INTEGER file_position;
1185 handle = (HANDLE)maybe_get_osfhandle(fd);
1187 if (console_handle_p(handle)) {
1188 /* 1. Console is a singleton.
1189 2. The only way to cancel console handle I/O is to close it.
1191 if (console_handle_p(handle))
1192 return read(fd, buf, count);
1194 overlapped.hEvent = self->private_events.events[0];
1195 /* If it has a position, we won't try overlapped */
1196 seekable = SetFilePointerEx(handle,
1201 overlapped.Offset = file_position.LowPart;
1202 overlapped.OffsetHigh = file_position.HighPart;
1204 overlapped.Offset = 0;
1205 overlapped.OffsetHigh = 0;
1207 ok = ReadFile(handle,buf,count,&read_bytes, &overlapped);
1210 goto done_something;
1212 errorCode = GetLastError();
1213 if (errorCode == ERROR_HANDLE_EOF ||
1214 errorCode == ERROR_BROKEN_PIPE ||
1215 errorCode == ERROR_NETNAME_DELETED) {
1217 goto done_something;
1219 if (errorCode!=ERROR_IO_PENDING) {
1220 /* is it some _real_ error? */
1225 if( (ret = WaitForMultipleObjects(2,self->private_events.events,
1226 FALSE,INFINITE)) != WAIT_OBJECT_0) {
1229 /* Waiting for IO only */
1233 ok = GetOverlappedResult(handle,&overlapped,&read_bytes,waitInGOR);
1235 errorCode = GetLastError();
1236 if (errorCode == ERROR_HANDLE_EOF ||
1237 errorCode == ERROR_BROKEN_PIPE ||
1238 errorCode == ERROR_NETNAME_DELETED) {
1240 goto done_something;
1242 if (errorCode == ERROR_OPERATION_ABORTED)
1243 errno = EINTR; /* that's it. */
1245 errno = EIO; /* something unspecific */
1249 goto done_something;
1254 file_position.QuadPart += read_bytes;
1255 SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
1260 /* This is a manually-maintained version of ldso_stubs.S. */
1262 void __stdcall RtlUnwind(void *, void *, void *, void *); /* I don't have winternl.h */
1266 LARGE_INTEGER la = {{0}};
1270 SetHandleInformation(0, 0, 0);
1271 GetHandleInformation(0, 0);
1272 getsockopt(0, 0, 0, 0, 0);
1273 FlushConsoleInputBuffer(0);
1274 FormatMessageA(0, 0, 0, 0, 0, 0, 0);
1278 GetConsoleOutputCP();
1279 GetCurrentProcess();
1280 GetExitCodeProcess(0, 0);
1283 GetProcAddress(0, 0);
1284 GetProcessTimes(0, 0, 0, 0, 0);
1285 GetSystemTimeAsFileTime(0);
1288 PeekConsoleInput(0, 0, 0, 0);
1289 PeekNamedPipe(0, 0, 0, 0, 0, 0);
1290 ReadFile(0, 0, 0, 0, 0);
1292 WriteFile(0, 0, 0, 0, 0);
1294 _open_osfhandle(0, 0);
1303 RtlUnwind(0, 0, 0, 0);
1304 MapViewOfFile(0,0,0,0,0);
1306 FlushViewOfFile(0,0);
1307 SetFilePointerEx(0, la, 0, 0);
1308 DuplicateHandle(0, 0, 0, 0, 0, 0, 0);
1309 #ifndef LISP_FEATURE_SB_UNICODE
1310 CreateDirectoryA(0,0);
1311 CreateFileMappingA(0,0,0,0,0,0);
1312 CreateFileA(0,0,0,0,0,0,0);
1313 GetComputerNameA(0, 0);
1314 GetCurrentDirectoryA(0,0);
1315 GetEnvironmentVariableA(0, 0, 0);
1316 GetFileAttributesA(0);
1319 SHGetFolderPathA(0, 0, 0, 0, 0);
1320 SetCurrentDirectoryA(0);
1321 SetEnvironmentVariableA(0, 0);
1323 CreateDirectoryW(0,0);
1324 CreateFileMappingW(0,0,0,0,0,0);
1325 CreateFileW(0,0,0,0,0,0,0);
1326 FormatMessageW(0, 0, 0, 0, 0, 0, 0);
1327 GetComputerNameW(0, 0);
1328 GetCurrentDirectoryW(0,0);
1329 GetEnvironmentVariableW(0, 0, 0);
1330 GetFileAttributesW(0);
1333 SHGetFolderPathW(0, 0, 0, 0, 0);
1334 SetCurrentDirectoryW(0);
1335 SetEnvironmentVariableW(0, 0);
1341 os_get_runtime_executable_path(int external)
1343 char path[MAX_PATH + 1];
1344 DWORD bufsize = sizeof(path);
1347 if ((size = GetModuleFileNameA(NULL, path, bufsize)) == 0)
1349 else if (size == bufsize && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1352 return copied_string(path);
1355 #ifdef LISP_FEATURE_SB_THREAD
1358 win32_wait_object_or_signal(HANDLE waitFor)
1360 struct thread * self = arch_os_get_current_thread();
1362 handles[0] = waitFor;
1363 handles[1] = self->private_events.events[1];
1365 WaitForMultipleObjects(2,handles, FALSE,INFINITE);
1369 * Portability glue for win32 waitable timers.
1371 * One may ask: Why is there a wrapper in C when the calls are so
1372 * obvious that Lisp could do them directly (as it did on Windows)?
1374 * But the answer is that on POSIX platforms, we now emulate the win32
1375 * calls and hide that emulation behind this os_* abstraction.
1380 return CreateWaitableTimer(0, 0, 0);
1384 os_wait_for_wtimer(HANDLE handle)
1386 return win32_wait_object_or_signal(handle);
1390 os_close_wtimer(HANDLE handle)
1392 CloseHandle(handle);
1396 os_set_wtimer(HANDLE handle, int sec, int nsec)
1398 /* in units of 100ns, i.e. 0.1us. Negative for relative semantics. */
1400 = -(((long long) sec) * 10000000
1401 + ((long long) nsec + 99) / 100);
1402 SetWaitableTimer(handle, (LARGE_INTEGER*) &dueTime, 0, 0, 0, 0);
1406 os_cancel_wtimer(HANDLE handle)
1408 CancelWaitableTimer(handle);