Move the global safepoint to one page before static space
[sbcl.git] / src / runtime / win32-os.c
1 /*
2  * the Win32 incarnation of OS-dependent routines.  See also
3  * $(sbcl_arch)-win32-os.c
4  *
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.
10  */
11
12 /*
13  * This software is part of the SBCL system. See the README file for
14  * more information.
15  *
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.
21  */
22
23 /*
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
26  * yet.
27  */
28
29 #include <malloc.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/param.h>
33 #include <sys/file.h>
34 #include <io.h>
35 #include "sbcl.h"
36 #include "os.h"
37 #include "arch.h"
38 #include "globals.h"
39 #include "sbcl.h"
40 #include "interrupt.h"
41 #include "interr.h"
42 #include "lispregs.h"
43 #include "runtime.h"
44 #include "alloc.h"
45 #include "genesis/primitive-objects.h"
46 #include "dynbind.h"
47
48 #include <sys/types.h>
49 #include <sys/time.h>
50 #include <sys/stat.h>
51 #include <unistd.h>
52
53 #include <math.h>
54 #include <float.h>
55
56 #include <excpt.h>
57 #include <errno.h>
58
59 #include "validate.h"
60 #include "thread.h"
61 #include "cpputil.h"
62
63 #ifndef LISP_FEATURE_SB_THREAD
64 /* dummy definition to reduce ifdef clutter */
65 #define WITH_GC_AT_SAFEPOINTS_ONLY() if (0) ; else
66 #endif
67
68 os_vm_size_t os_vm_page_size;
69
70 #include "gc.h"
71 #include "gencgc-internal.h"
72 #include <winsock2.h>
73
74 #if 0
75 int linux_sparc_siginfo_bug = 0;
76 int linux_supports_futex=0;
77 #endif
78
79 #include <stdarg.h>
80 #include <string.h>
81
82 /* missing definitions for modern mingws */
83 #ifndef EH_UNWINDING
84 #define EH_UNWINDING 0x02
85 #endif
86 #ifndef EH_EXIT_UNWIND
87 #define EH_EXIT_UNWIND 0x04
88 #endif
89
90 /* Tired of writing arch_os_get_current_thread each time. */
91 #define this_thread (arch_os_get_current_thread())
92
93 /* wrappers for winapi calls that must be successful (like SBCL's
94  * (aver ...) form). */
95
96 /* win_aver function: basic building block for miscellaneous
97  * ..AVER.. macrology (below) */
98
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. */
103
104 static inline
105 intptr_t win_aver(intptr_t value, char* comment, char* file, int line,
106                   int justwarn)
107 {
108     if (!value) {
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"
115             " ... %s\n"
116             "     ===> returned #X%p, \n"
117             "     (in thread %p)"
118             " ... Win32 thinks:\n"
119             "     ===> code %u, message => %s\n"
120             " ... CRT thinks:\n"
121             "     ===> code %u, message => %s\n";
122
123         allocated =
124             FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|
125                            FORMAT_MESSAGE_FROM_SYSTEM,
126                            NULL,
127                            errorCode,
128                            MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
129                            (LPSTR)&errorMessage,
130                            1024u,
131                            NULL);
132
133         if (justwarn) {
134             fprintf(stderr, report_template,
135                     file, line,
136                     comment, value,
137                     this_thread,
138                     (unsigned)errorCode, errorMessage,
139                     posixerrno, posixstrerror);
140         } else {
141             lose(report_template,
142                     file, line,
143                     comment, value,
144                     this_thread,
145                     (unsigned)errorCode, errorMessage,
146                     posixerrno, posixstrerror);
147         }
148         if (allocated)
149             LocalFree(errorMessage);
150     }
151     return value;
152 }
153
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. */
157 static inline
158 intptr_t sys_aver(long value, char* comment, char* file, int line,
159               int justwarn)
160 {
161     win_aver((intptr_t)(value>=0),comment,file,line,justwarn);
162     return value;
163 }
164
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.
170  *
171  * Failed AVER() is normally fatal. Well, unless dyndebug_survive_aver
172  * flag is set. */
173
174 #define AVER(call)                                                      \
175     ({ __typeof__(call) __attribute__((unused)) me =                    \
176             (__typeof__(call))                                          \
177             win_aver((intptr_t)(call), #call, __FILE__, __LINE__, 0);      \
178         me;})
179
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. */
184
185 #define AVERLAX(call)                                                   \
186     ({ __typeof__(call) __attribute__((unused)) me =                    \
187             (__typeof__(call))                                          \
188             win_aver((intptr_t)(call), #call, __FILE__, __LINE__, 1);      \
189         me;})
190
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). */
194
195 #define CRT_AVER_NONNEGATIVE(call)                              \
196     ({ __typeof__(call) __attribute__((unused)) me =            \
197             (__typeof__(call))                                  \
198             sys_aver((call), #call, __FILE__, __LINE__, 0);     \
199         me;})
200
201 #define CRT_AVERLAX_NONNEGATIVE(call)                           \
202     ({ __typeof__(call) __attribute__((unused)) me =            \
203             (__typeof__(call))                                  \
204             sys_aver((call), #call, __FILE__, __LINE__, 1);     \
205         me;})
206
207 /* to be removed */
208 #define CRT_AVER(booly)                                         \
209     ({ __typeof__(booly) __attribute__((unused)) me = (booly);  \
210         sys_aver((booly)?0:-1, #booly, __FILE__, __LINE__, 0);  \
211         me;})
212
213 const char * t_nil_s(lispobj symbol);
214
215 /*
216  * The following signal-mask-related alien routines are called from Lisp:
217  */
218
219 /* As of win32, deferrables _do_ matter. gc_signal doesn't. */
220 unsigned long block_deferrables_and_return_mask()
221 {
222     sigset_t sset;
223     block_deferrable_signals(0, &sset);
224     return (unsigned long)sset;
225 }
226
227 #if defined(LISP_FEATURE_SB_THREAD)
228 void apply_sigmask(unsigned long sigmask)
229 {
230     sigset_t sset = (sigset_t)sigmask;
231     pthread_sigmask(SIG_SETMASK, &sset, 0);
232 }
233 #endif
234
235 /* The exception handling function looks like this: */
236 EXCEPTION_DISPOSITION handle_exception(EXCEPTION_RECORD *,
237                                        struct lisp_exception_frame *,
238                                        CONTEXT *,
239                                        void *);
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.
245  */
246
247
248 void *base_seh_frame;
249
250 static void *get_seh_frame(void)
251 {
252     void* retval;
253 #ifdef LISP_FEATURE_X86
254     asm volatile ("mov %%fs:0,%0": "=r" (retval));
255 #else
256     asm volatile ("mov %%gs:0,%0": "=r" (retval));
257 #endif
258     return retval;
259 }
260
261 static void set_seh_frame(void *frame)
262 {
263 #ifdef LISP_FEATURE_X86
264     asm volatile ("mov %0,%%fs:0": : "r" (frame));
265 #else
266     asm volatile ("mov %0,%%gs:0": : "r" (frame));
267 #endif
268 }
269
270 #if defined(LISP_FEATURE_SB_THREAD)
271
272 void alloc_gc_page()
273 {
274     AVER(VirtualAlloc(GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
275                       MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE));
276 }
277
278 /* Permit loads from GC_SAFEPOINT_PAGE_ADDR (NB page state change is
279  * "synchronized" with the memory region content/availability --
280  * e.g. you won't see other CPU flushing buffered writes after WP --
281  * but there is some window when other thread _seem_ to trap AFTER
282  * access is granted. You may think of it something like "OS enters
283  * SEH handler too slowly" -- what's important is there's no implicit
284  * synchronization between VirtualProtect caller and other thread's
285  * SEH handler, hence no ordering of events. VirtualProtect is
286  * implicitly synchronized with protected memory contents (only).
287  *
288  * The last fact may be potentially used with many benefits e.g. for
289  * foreign call speed, but we don't use it for now: almost the only
290  * fact relevant to the current signalling protocol is "sooner or
291  * later everyone will trap [everyone will stop trapping]".
292  *
293  * An interesting source on page-protection-based inter-thread
294  * communication is a well-known paper by Dave Dice, Hui Huang,
295  * Mingyao Yang: ``Asymmetric Dekker Synchronization''. Last time
296  * I checked it was available at
297  * http://home.comcast.net/~pjbishop/Dave/Asymmetric-Dekker-Synchronization.txt
298  */
299 void map_gc_page()
300 {
301     DWORD oldProt;
302     AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
303                         PAGE_READWRITE, &oldProt));
304 }
305
306 void unmap_gc_page()
307 {
308     DWORD oldProt;
309     AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
310                         PAGE_NOACCESS, &oldProt));
311 }
312
313 #endif
314
315 #if defined(LISP_FEATURE_SB_THREAD)
316 /* We want to get a slot in TIB that (1) is available at constant
317    offset, (2) is our private property, so libraries wouldn't legally
318    override it, (3) contains something predefined for threads created
319    out of our sight.
320
321    Low 64 TLS slots are adressable directly, starting with
322    FS:[#xE10]. When SBCL runtime is initialized, some of the low slots
323    may be already in use by its prerequisite DLLs, as DllMain()s and
324    TLS callbacks have been called already. But slot 63 is unlikely to
325    be reached at this point: one slot per DLL that needs it is the
326    common practice, and many system DLLs use predefined TIB-based
327    areas outside conventional TLS storage and don't need TLS slots.
328    With our current dependencies, even slot 2 is observed to be free
329    (as of WinXP and wine).
330
331    Now we'll call TlsAlloc() repeatedly until slot 63 is officially
332    assigned to us, then TlsFree() all other slots for normal use. TLS
333    slot 63, alias FS:[#.(+ #xE10 (* 4 63))], now belongs to us.
334
335    To summarize, let's list the assumptions we make:
336
337    - TIB, which is FS segment base, contains first 64 TLS slots at the
338    offset #xE10 (i.e. TIB layout compatibility);
339    - TLS slots are allocated from lower to higher ones;
340    - All libraries together with CRT startup have not requested 64
341    slots yet.
342
343    All these assumptions together don't seem to be less warranted than
344    the availability of TIB arbitrary data slot for our use. There are
345    some more reasons to prefer slot 63 over TIB arbitrary data: (1) if
346    our assumptions for slot 63 are violated, it will be detected at
347    startup instead of causing some system-specific unreproducible
348    problems afterwards, depending on OS and loaded foreign libraries;
349    (2) if getting slot 63 reliably with our current approach will
350    become impossible for some future Windows version, we can add TLS
351    callback directory to SBCL binary; main image TLS callback is
352    started before _any_ TLS slot is allocated by libraries, and
353    some C compiler vendors rely on this fact. */
354
355 void os_preinit()
356 {
357 #ifdef LISP_FEATURE_X86
358     DWORD slots[TLS_MINIMUM_AVAILABLE];
359     DWORD key;
360     int n_slots = 0, i;
361     for (i=0; i<TLS_MINIMUM_AVAILABLE; ++i) {
362         key = TlsAlloc();
363         if (key == OUR_TLS_INDEX) {
364             if (TlsGetValue(key)!=NULL)
365                 lose("TLS slot assertion failed: fresh slot value is not NULL");
366             TlsSetValue(OUR_TLS_INDEX, (void*)(intptr_t)0xFEEDBAC4);
367             if ((intptr_t)(void*)arch_os_get_current_thread()!=(intptr_t)0xFEEDBAC4)
368                 lose("TLS slot assertion failed: TIB layout change detected");
369             TlsSetValue(OUR_TLS_INDEX, NULL);
370             break;
371         }
372         slots[n_slots++]=key;
373     }
374     for (i=0; i<n_slots; ++i) {
375         TlsFree(slots[i]);
376     }
377     if (key!=OUR_TLS_INDEX) {
378         lose("TLS slot assertion failed: slot 63 is unavailable "
379              "(last TlsAlloc() returned %u)",key);
380     }
381 #endif
382 }
383 #endif  /* LISP_FEATURE_SB_THREAD */
384
385 int os_number_of_processors = 1;
386
387 BOOL WINAPI CancelIoEx(HANDLE handle, LPOVERLAPPED overlapped);
388 typeof(CancelIoEx) *ptr_CancelIoEx;
389 BOOL WINAPI CancelSynchronousIo(HANDLE threadHandle);
390 typeof(CancelSynchronousIo) *ptr_CancelSynchronousIo;
391
392 #define RESOLVE(hmodule,fn)                     \
393     do {                                        \
394         ptr_##fn = (typeof(ptr_##fn))           \
395             GetProcAddress(hmodule,#fn);        \
396     } while (0)
397
398 static void resolve_optional_imports()
399 {
400     HMODULE kernel32 = GetModuleHandleA("kernel32");
401     if (kernel32) {
402         RESOLVE(kernel32,CancelIoEx);
403         RESOLVE(kernel32,CancelSynchronousIo);
404     }
405 }
406
407 #undef RESOLVE
408
409 void os_init(char *argv[], char *envp[])
410 {
411     SYSTEM_INFO system_info;
412     GetSystemInfo(&system_info);
413     os_vm_page_size = system_info.dwPageSize > BACKEND_PAGE_BYTES?
414         system_info.dwPageSize : BACKEND_PAGE_BYTES;
415 #if defined(LISP_FEATURE_X86)
416     fast_bzero_pointer = fast_bzero_detect;
417 #endif
418     os_number_of_processors = system_info.dwNumberOfProcessors;
419
420     base_seh_frame = get_seh_frame();
421
422     resolve_optional_imports();
423 }
424
425 static inline boolean local_thread_stack_address_p(os_vm_address_t address)
426 {
427     return this_thread &&
428         (((((u64)address >= (u64)this_thread->os_address) &&
429            ((u64)address < ((u64)this_thread)-THREAD_CSP_PAGE_SIZE))||
430           (((u64)address >= (u64)this_thread->control_stack_start)&&
431            ((u64)address < (u64)this_thread->control_stack_end))));
432 }
433
434 /*
435  * So we have three fun scenarios here.
436  *
437  * First, we could be being called to reserve the memory areas
438  * during initialization (prior to loading the core file).
439  *
440  * Second, we could be being called by the GC to commit a page
441  * that has just been decommitted (for easy zero-fill).
442  *
443  * Third, we could be being called by create_thread_struct()
444  * in order to create the sundry and various stacks.
445  *
446  * The third case is easy to pick out because it passes an
447  * addr of 0.
448  *
449  * The second case is easy to pick out because it will be for
450  * a range of memory that is MEM_RESERVE rather than MEM_FREE.
451  *
452  * The second case is also an easy implement, because we leave
453  * the memory as reserved (since we do lazy commits).
454  */
455
456 os_vm_address_t
457 os_validate(os_vm_address_t addr, os_vm_size_t len)
458 {
459     MEMORY_BASIC_INFORMATION mem_info;
460
461     if (!addr) {
462         /* the simple case first */
463         return
464             AVERLAX(VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE));
465     }
466
467     if (!AVERLAX(VirtualQuery(addr, &mem_info, sizeof mem_info)))
468         return 0;
469
470     if ((mem_info.State == MEM_RESERVE) && (mem_info.RegionSize >=len)) {
471       /* It would be correct to return here. However, support for Wine
472        * is beneficial, and Wine has a strange behavior in this
473        * department. It reports all memory below KERNEL32.DLL as
474        * reserved, but disallows MEM_COMMIT.
475        *
476        * Let's work around it: reserve the region we need for a second
477        * time. The second reservation is documented to fail on normal NT
478        * family, but it will succeed on Wine if this region is
479        * actually free.
480        */
481       VirtualAlloc(addr, len, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
482       /* If it is wine, the second call has succeded, and now the region
483        * is really reserved. */
484       return addr;
485     }
486
487     if (mem_info.State == MEM_RESERVE) {
488         fprintf(stderr, "validation of reserved space too short.\n");
489         fflush(stderr);
490         /* Oddly, we do not treat this assertion as fatal; hence also the
491          * provision for MEM_RESERVE in the following code, I suppose: */
492     }
493
494     if (!AVERLAX(VirtualAlloc(addr, len, (mem_info.State == MEM_RESERVE)?
495                               MEM_COMMIT: MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
496         return 0;
497
498     return addr;
499 }
500
501 /*
502  * For os_invalidate(), we merely decommit the memory rather than
503  * freeing the address space. This loses when freeing per-thread
504  * data and related memory since it leaks address space.
505  *
506  * So far the original comment (author unknown).  It used to continue as
507  * follows:
508  *
509  *   It's not too lossy, however, since the two scenarios I'm aware of
510  *   are fd-stream buffers, which are pooled rather than torched, and
511  *   thread information, which I hope to pool (since windows creates
512  *   threads at its own whim, and we probably want to be able to have
513  *   them callback without funky magic on the part of the user, and
514  *   full-on thread allocation is fairly heavyweight).
515  *
516  * But: As it turns out, we are no longer content with decommitting
517  * without freeing, and have now grown a second function
518  * os_invalidate_free(), sort of a really_os_invalidate().
519  *
520  * As discussed on #lisp, this is not a satisfactory solution, and probably
521  * ought to be rectified in the following way:
522  *
523  *  - Any cases currently going through the non-freeing version of
524  *    os_invalidate() are ultimately meant for zero-filling applications.
525  *    Replace those use cases with an os_revalidate_bzero() or similarly
526  *    named function, which explicitly takes care of that aspect of
527  *    the semantics.
528  *
529  *  - The remaining uses of os_invalidate should actually free, and once
530  *    the above is implemented, we can rename os_invalidate_free back to
531  *    just os_invalidate().
532  *
533  * So far the new plan, as yet unimplemented. -- DFL
534  */
535
536 void
537 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
538 {
539     AVERLAX(VirtualFree(addr, len, MEM_DECOMMIT));
540 }
541
542 void
543 os_invalidate_free(os_vm_address_t addr, os_vm_size_t len)
544 {
545     AVERLAX(VirtualFree(addr, 0, MEM_RELEASE));
546 }
547
548 void
549 os_invalidate_free_by_any_address(os_vm_address_t addr, os_vm_size_t len)
550 {
551     MEMORY_BASIC_INFORMATION minfo;
552     AVERLAX(VirtualQuery(addr, &minfo, sizeof minfo));
553     AVERLAX(minfo.AllocationBase);
554     AVERLAX(VirtualFree(minfo.AllocationBase, 0, MEM_RELEASE));
555 }
556
557 #define maybe_open_osfhandle _open_osfhandle
558 #define maybe_get_osfhandle _get_osfhandle
559 #define FDTYPE int
560
561 /*
562  * os_map() is called to map a chunk of the core file into memory.
563  *
564  * Unfortunately, Windows semantics completely screws this up, so
565  * we just add backing store from the swapfile to where the chunk
566  * goes and read it up like a normal file. We could consider using
567  * a lazy read (demand page) setup, but that would mean keeping an
568  * open file pointer for the core indefinately (and be one more
569  * thing to maintain).
570  */
571
572 os_vm_address_t
573 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
574 {
575     os_vm_size_t count;
576
577     AVER(VirtualAlloc(addr, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE)||
578          VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT,
579                       PAGE_EXECUTE_READWRITE));
580
581     CRT_AVER_NONNEGATIVE(lseek(fd, offset, SEEK_SET));
582
583     count = read(fd, addr, len);
584     CRT_AVER( count == len );
585
586     return addr;
587 }
588
589 static DWORD os_protect_modes[8] = {
590     PAGE_NOACCESS,
591     PAGE_READONLY,
592     PAGE_READWRITE,
593     PAGE_READWRITE,
594     PAGE_EXECUTE,
595     PAGE_EXECUTE_READ,
596     PAGE_EXECUTE_READWRITE,
597     PAGE_EXECUTE_READWRITE,
598 };
599
600 void
601 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
602 {
603     DWORD old_prot;
604
605     DWORD new_prot = os_protect_modes[prot];
606     AVER(VirtualProtect(address, length, new_prot, &old_prot)||
607          (VirtualAlloc(address, length, MEM_COMMIT, new_prot) &&
608           VirtualProtect(address, length, new_prot, &old_prot)));
609     odxprint(misc,"Protecting %p + %p vmaccess %d "
610              "newprot %08x oldprot %08x",
611              address,length,prot,new_prot,old_prot);
612 }
613
614 /* FIXME: Now that FOO_END, rather than FOO_SIZE, is the fundamental
615  * description of a space, we could probably punt this and just do
616  * (FOO_START <= x && x < FOO_END) everywhere it's called. */
617 static boolean
618 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
619 {
620     char* beg = (char*)((uword_t)sbeg);
621     char* end = (char*)((uword_t)sbeg) + slen;
622     char* adr = (char*)a;
623     return (adr >= beg && adr < end);
624 }
625
626 boolean
627 is_linkage_table_addr(os_vm_address_t addr)
628 {
629     return in_range_p(addr, LINKAGE_TABLE_SPACE_START, LINKAGE_TABLE_SPACE_END);
630 }
631
632 static boolean is_some_thread_local_addr(os_vm_address_t addr);
633
634 boolean
635 is_valid_lisp_addr(os_vm_address_t addr)
636 {
637     if(in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE) ||
638        in_range_p(addr, STATIC_SPACE_START   , STATIC_SPACE_SIZE) ||
639        in_range_p(addr, DYNAMIC_SPACE_START  , dynamic_space_size) ||
640        is_some_thread_local_addr(addr))
641         return 1;
642     return 0;
643 }
644
645 /* test if an address is within thread-local space */
646 static boolean
647 is_thread_local_addr(struct thread* th, os_vm_address_t addr)
648 {
649     /* Assuming that this is correct, it would warrant further comment,
650      * I think.  Based on what our call site is doing, we have been
651      * tasked to check for the address of a lisp object; not merely any
652      * foreign address within the thread's area.  Indeed, this used to
653      * be a check for control and binding stack only, rather than the
654      * full thread "struct".  So shouldn't the THREAD_STRUCT_SIZE rather
655      * be (thread_control_stack_size+BINDING_STACK_SIZE) instead?  That
656      * would also do away with the LISP_FEATURE_SB_THREAD case.  Or does
657      * it simply not matter?  --DFL */
658     ptrdiff_t diff = ((char*)th->os_address)-(char*)addr;
659     return diff > (ptrdiff_t)0 && diff < (ptrdiff_t)THREAD_STRUCT_SIZE
660 #ifdef LISP_FEATURE_SB_THREAD
661         && addr != (os_vm_address_t) th->csp_around_foreign_call
662 #endif
663         ;
664 }
665
666 static boolean
667 is_some_thread_local_addr(os_vm_address_t addr)
668 {
669     boolean result = 0;
670 #ifdef LISP_FEATURE_SB_THREAD
671     struct thread *th;
672     pthread_mutex_lock(&all_threads_lock);
673     for_each_thread(th) {
674         if(is_thread_local_addr(th,addr)) {
675             result = 1;
676             break;
677         }
678     }
679     pthread_mutex_unlock(&all_threads_lock);
680 #endif
681     return result;
682 }
683
684
685 /* A tiny bit of interrupt.c state we want our paws on. */
686 extern boolean internal_errors_enabled;
687
688 extern void exception_handler_wrapper();
689
690 void
691 c_level_backtrace(const char* header, int depth)
692 {
693     void* frame;
694     int n = 0;
695     void** lastseh;
696
697     for (lastseh = get_seh_frame(); lastseh && (lastseh!=(void*)-1);
698          lastseh = *lastseh);
699
700     fprintf(stderr, "Backtrace: %s (thread %p)\n", header, this_thread);
701     for (frame = __builtin_frame_address(0); frame; frame=*(void**)frame)
702     {
703         if ((n++)>depth)
704             return;
705         fprintf(stderr, "[#%02d]: ebp = 0x%p, ret = 0x%p\n",n,
706                 frame, ((void**)frame)[1]);
707     }
708 }
709
710 #ifdef LISP_FEATURE_X86
711 #define voidreg(ctxptr,name) ((void*)((ctxptr)->E##name))
712 #else
713 #define voidreg(ctxptr,name) ((void*)((ctxptr)->R##name))
714 #endif
715
716
717 #if defined(LISP_FEATURE_X86)
718 static int
719 handle_single_step(os_context_t *ctx)
720 {
721     if (!single_stepping)
722         return -1;
723
724     /* We are doing a displaced instruction. At least function
725      * end breakpoints use this. */
726     WITH_GC_AT_SAFEPOINTS_ONLY () /* Todo: Is it really gc-unsafe? */
727         restore_breakpoint_from_single_step(ctx);
728
729     return 0;
730 }
731 #endif
732
733 #ifdef LISP_FEATURE_UD2_BREAKPOINTS
734 #define SBCL_EXCEPTION_BREAKPOINT EXCEPTION_ILLEGAL_INSTRUCTION
735 #define TRAP_CODE_WIDTH 2
736 #else
737 #define SBCL_EXCEPTION_BREAKPOINT EXCEPTION_BREAKPOINT
738 #define TRAP_CODE_WIDTH 1
739 #endif
740
741 static int
742 handle_breakpoint_trap(os_context_t *ctx, struct thread* self)
743 {
744 #ifdef LISP_FEATURE_UD2_BREAKPOINTS
745     if (((unsigned short *)((ctx->win32_context)->Eip))[0] != 0x0b0f)
746         return -1;
747 #endif
748
749     /* Unlike some other operating systems, Win32 leaves EIP
750      * pointing to the breakpoint instruction. */
751     (*os_context_pc_addr(ctx)) += TRAP_CODE_WIDTH;
752
753     /* Now EIP points just after the INT3 byte and aims at the
754      * 'kind' value (eg trap_Cerror). */
755     unsigned trap = *(unsigned char *)(*os_context_pc_addr(ctx));
756
757 #ifdef LISP_FEATURE_SB_THREAD
758     /* Before any other trap handler: gc_safepoint ensures that
759        inner alloc_sap for passing the context won't trap on
760        pseudo-atomic. */
761     if (trap == trap_PendingInterrupt) {
762         /* Done everything needed for this trap, except EIP
763            adjustment */
764         arch_skip_instruction(ctx);
765         thread_interrupted(ctx);
766         return 0;
767     }
768 #endif
769
770     /* This is just for info in case the monitor wants to print an
771      * approximation. */
772     access_control_stack_pointer(self) =
773         (lispobj *)*os_context_sp_addr(ctx);
774
775     WITH_GC_AT_SAFEPOINTS_ONLY() {
776 #if defined(LISP_FEATURE_SB_THREAD)
777         block_blockable_signals(0,&ctx->sigmask);
778 #endif
779         handle_trap(ctx, trap);
780 #if defined(LISP_FEATURE_SB_THREAD)
781         thread_sigmask(SIG_SETMASK,&ctx->sigmask,NULL);
782 #endif
783     }
784
785     /* Done, we're good to go! */
786     return 0;
787 }
788
789 static int
790 handle_access_violation(os_context_t *ctx,
791                         EXCEPTION_RECORD *exception_record,
792                         void *fault_address,
793                         struct thread* self)
794 {
795     CONTEXT *win32_context = ctx->win32_context;
796
797 #if defined(LISP_FEATURE_X86)
798     odxprint(pagefaults,
799              "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
800              "Addr %p Access %d\n",
801              self,
802              win32_context->Eip,
803              win32_context->Esp,
804              win32_context->Esi,
805              win32_context->Edi,
806              fault_address,
807              exception_record->ExceptionInformation[0]);
808 #else
809     odxprint(pagefaults,
810              "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
811              "Addr %p Access %d\n",
812              self,
813              win32_context->Rip,
814              win32_context->Rsp,
815              win32_context->Rsi,
816              win32_context->Rdi,
817              fault_address,
818              exception_record->ExceptionInformation[0]);
819 #endif
820
821     /* Stack: This case takes care of our various stack exhaustion
822      * protect pages (with the notable exception of the control stack!). */
823     if (self && local_thread_stack_address_p(fault_address)) {
824         if (handle_guard_page_triggered(ctx, fault_address))
825             return 0; /* gc safety? */
826         goto try_recommit;
827     }
828
829     /* Safepoint pages */
830 #ifdef LISP_FEATURE_SB_THREAD
831     if (fault_address == (void *) GC_SAFEPOINT_PAGE_ADDR) {
832         thread_in_lisp_raised(ctx);
833         return 0;
834     }
835
836     if ((((u64)fault_address) == ((u64)self->csp_around_foreign_call))){
837         thread_in_safety_transition(ctx);
838         return 0;
839     }
840 #endif
841
842     /* dynamic space */
843     page_index_t index = find_page_index(fault_address);
844     if (index != -1) {
845         /*
846          * Now, if the page is supposedly write-protected and this
847          * is a write, tell the gc that it's been hit.
848          */
849         if (page_table[index].write_protected) {
850             gencgc_handle_wp_violation(fault_address);
851         } else {
852             AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
853                               os_vm_page_size,
854                               MEM_COMMIT, PAGE_EXECUTE_READWRITE));
855         }
856         return 0;
857     }
858
859     if (fault_address == undefined_alien_address)
860         return -1;
861
862     /* linkage table or a "valid_lisp_addr" outside of dynamic space (?) */
863     if (is_linkage_table_addr(fault_address)
864         || is_valid_lisp_addr(fault_address))
865         goto try_recommit;
866
867     return -1;
868
869 try_recommit:
870     /* First use of a new page, lets get some memory for it. */
871
872 #if defined(LISP_FEATURE_X86)
873     AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
874                       os_vm_page_size,
875                       MEM_COMMIT, PAGE_EXECUTE_READWRITE)
876          ||(fprintf(stderr,"Unable to recommit addr %p eip 0x%08lx\n",
877                     fault_address, win32_context->Eip) &&
878             (c_level_backtrace("BT",5),
879              fake_foreign_function_call(ctx),
880              lose("Lispy backtrace"),
881              0)));
882 #else
883     AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
884                       os_vm_page_size,
885                       MEM_COMMIT, PAGE_EXECUTE_READWRITE)
886          ||(fprintf(stderr,"Unable to recommit addr %p eip 0x%p\n",
887                     fault_address, (void*)win32_context->Rip) &&
888             (c_level_backtrace("BT",5),
889              fake_foreign_function_call(ctx),
890              lose("Lispy backtrace"),
891              0)));
892 #endif
893
894     return 0;
895 }
896
897 static void
898 signal_internal_error_or_lose(os_context_t *ctx,
899                               EXCEPTION_RECORD *exception_record,
900                               void *fault_address)
901 {
902     /*
903      * If we fall through to here then we need to either forward
904      * the exception to the lisp-side exception handler if it's
905      * set up, or drop to LDB.
906      */
907
908     if (internal_errors_enabled) {
909         lispobj context_sap;
910         lispobj exception_record_sap;
911
912         asm("fnclex");
913         /* We're making the somewhat arbitrary decision that having
914          * internal errors enabled means that lisp has sufficient
915          * marbles to be able to handle exceptions, but exceptions
916          * aren't supposed to happen during cold init or reinit
917          * anyway. */
918
919 #if defined(LISP_FEATURE_SB_THREAD)
920         block_blockable_signals(0,&ctx->sigmask);
921 #endif
922         fake_foreign_function_call(ctx);
923
924         WITH_GC_AT_SAFEPOINTS_ONLY() {
925             /* Allocate the SAP objects while the "interrupts" are still
926              * disabled. */
927             context_sap = alloc_sap(ctx);
928             exception_record_sap = alloc_sap(exception_record);
929 #if defined(LISP_FEATURE_SB_THREAD)
930             thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
931 #endif
932
933             /* The exception system doesn't automatically clear pending
934              * exceptions, so we lose as soon as we execute any FP
935              * instruction unless we do this first. */
936             /* Call into lisp to handle things. */
937             funcall2(StaticSymbolFunction(HANDLE_WIN32_EXCEPTION),
938                      context_sap,
939                      exception_record_sap);
940         }
941         /* If Lisp doesn't nlx, we need to put things back. */
942         undo_fake_foreign_function_call(ctx);
943 #if defined(LISP_FEATURE_SB_THREAD)
944         thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
945 #endif
946         /* FIXME: HANDLE-WIN32-EXCEPTION should be allowed to decline */
947         return;
948     }
949
950     fprintf(stderr, "Exception Code: 0x%p.\n",
951             (void*)(intptr_t)exception_record->ExceptionCode);
952     fprintf(stderr, "Faulting IP: 0x%p.\n",
953             (void*)(intptr_t)exception_record->ExceptionAddress);
954     if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
955         MEMORY_BASIC_INFORMATION mem_info;
956
957         if (VirtualQuery(fault_address, &mem_info, sizeof mem_info)) {
958             fprintf(stderr, "page status: 0x%lx.\n", mem_info.State);
959         }
960
961         fprintf(stderr, "Was writing: %p, where: 0x%p.\n",
962                 (void*)exception_record->ExceptionInformation[0],
963                 fault_address);
964     }
965
966     fflush(stderr);
967
968     fake_foreign_function_call(ctx);
969     lose("Exception too early in cold init, cannot continue.");
970 }
971
972 /*
973  * A good explanation of the exception handling semantics is
974  *   http://win32assembly.online.fr/Exceptionhandling.html (possibly defunct)
975  * or:
976  *   http://www.microsoft.com/msj/0197/exception/exception.aspx
977  */
978
979 EXCEPTION_DISPOSITION
980 handle_exception(EXCEPTION_RECORD *exception_record,
981                  struct lisp_exception_frame *exception_frame,
982                  CONTEXT *win32_context,
983                  void *dispatcher_context)
984 {
985     if (!win32_context)
986         /* Not certain why this should be possible, but let's be safe... */
987         return ExceptionContinueSearch;
988
989     if (exception_record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) {
990         /* If we're being unwound, be graceful about it. */
991
992         /* Undo any dynamic bindings. */
993         unbind_to_here(exception_frame->bindstack_pointer,
994                        arch_os_get_current_thread());
995         return ExceptionContinueSearch;
996     }
997
998     DWORD lastError = GetLastError();
999     DWORD lastErrno = errno;
1000     DWORD code = exception_record->ExceptionCode;
1001     struct thread* self = arch_os_get_current_thread();
1002
1003     os_context_t context, *ctx = &context;
1004     context.win32_context = win32_context;
1005 #if defined(LISP_FEATURE_SB_THREAD)
1006     context.sigmask = self ? self->os_thread->blocked_signal_set : 0;
1007 #endif
1008
1009     /* For EXCEPTION_ACCESS_VIOLATION only. */
1010     void *fault_address = (void *)exception_record->ExceptionInformation[1];
1011
1012     odxprint(seh,
1013              "SEH: rec %p, ctxptr %p, rip %p, fault %p\n"
1014              "... code %p, rcx %p, fp-tags %p\n\n",
1015              exception_record,
1016              win32_context,
1017              voidreg(win32_context,ip),
1018              fault_address,
1019              (void*)(intptr_t)code,
1020              voidreg(win32_context,cx),
1021              win32_context->FloatSave.TagWord);
1022
1023     /* This function had become unwieldy.  Let's cut it down into
1024      * pieces based on the different exception codes.  Each exception
1025      * code handler gets the chance to decline by returning non-zero if it
1026      * isn't happy: */
1027
1028     int rc;
1029     switch (code) {
1030     case EXCEPTION_ACCESS_VIOLATION:
1031         rc = handle_access_violation(
1032             ctx, exception_record, fault_address, self);
1033         break;
1034
1035     case SBCL_EXCEPTION_BREAKPOINT:
1036         rc = handle_breakpoint_trap(ctx, self);
1037         break;
1038
1039 #if defined(LISP_FEATURE_X86)
1040     case EXCEPTION_SINGLE_STEP:
1041         rc = handle_single_step(ctx);
1042         break;
1043 #endif
1044
1045     default:
1046         rc = -1;
1047     }
1048
1049     if (rc)
1050         /* All else failed, drop through to the lisp-side exception handler. */
1051         signal_internal_error_or_lose(ctx, exception_record, fault_address);
1052
1053     errno = lastErrno;
1054     SetLastError(lastError);
1055     return ExceptionContinueExecution;
1056 }
1057
1058 void
1059 wos_install_interrupt_handlers(struct lisp_exception_frame *handler)
1060 {
1061 #ifdef LISP_FEATURE_X86
1062     handler->next_frame = get_seh_frame();
1063     handler->handler = (void*)exception_handler_wrapper;
1064     set_seh_frame(handler);
1065 #else
1066     static int once = 0;
1067     if (!once++)
1068         AddVectoredExceptionHandler(1,veh);
1069 #endif
1070 }
1071
1072 /*
1073  * The stubs below are replacements for the windows versions,
1074  * which can -fail- when used in our memory spaces because they
1075  * validate the memory spaces they are passed in a way that
1076  * denies our exception handler a chance to run.
1077  */
1078
1079 void *memmove(void *dest, const void *src, size_t n)
1080 {
1081     if (dest < src) {
1082         int i;
1083         for (i = 0; i < n; i++) *(((char *)dest)+i) = *(((char *)src)+i);
1084     } else {
1085         while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1086     }
1087     return dest;
1088 }
1089
1090 void *memcpy(void *dest, const void *src, size_t n)
1091 {
1092     while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1093     return dest;
1094 }
1095
1096 char *dirname(char *path)
1097 {
1098     static char buf[PATH_MAX + 1];
1099     size_t pathlen = strlen(path);
1100     int i;
1101
1102     if (pathlen >= sizeof(buf)) {
1103         lose("Pathname too long in dirname.\n");
1104         return NULL;
1105     }
1106
1107     strcpy(buf, path);
1108     for (i = pathlen; i >= 0; --i) {
1109         if (buf[i] == '/' || buf[i] == '\\') {
1110             buf[i] = '\0';
1111             break;
1112         }
1113     }
1114
1115     return buf;
1116 }
1117
1118 /* Unofficial but widely used property of console handles: they have
1119    #b11 in two minor bits, opposed to other handles, that are
1120    machine-word-aligned. Properly emulated even on wine.
1121
1122    Console handles are special in many aspects, e.g. they aren't NTDLL
1123    system handles: kernel32 redirects console operations to CSRSS
1124    requests. Using the hack below to distinguish console handles is
1125    justified, as it's the only method that won't hang during
1126    outstanding reads, won't try to lock NT kernel object (if there is
1127    one; console isn't), etc. */
1128 int
1129 console_handle_p(HANDLE handle)
1130 {
1131     return (handle != NULL)&&
1132         (handle != INVALID_HANDLE_VALUE)&&
1133         ((((int)(intptr_t)handle)&3)==3);
1134 }
1135
1136 /* Atomically mark current thread as (probably) doing synchronous I/O
1137  * on handle, if no cancellation is requested yet (and return TRUE),
1138  * otherwise clear thread's I/O cancellation flag and return false.
1139  */
1140 static
1141 boolean io_begin_interruptible(HANDLE handle)
1142 {
1143     /* No point in doing it unless OS supports cancellation from other
1144      * threads */
1145     if (!ptr_CancelIoEx)
1146         return 1;
1147
1148     if (!__sync_bool_compare_and_swap(&this_thread->synchronous_io_handle_and_flag,
1149                                       0, handle)) {
1150         ResetEvent(this_thread->private_events.events[0]);
1151         this_thread->synchronous_io_handle_and_flag = 0;
1152         return 0;
1153     }
1154     return 1;
1155 }
1156
1157 /* Unmark current thread as (probably) doing synchronous I/O; if an
1158  * I/O cancellation was requested, postpone it until next
1159  * io_begin_interruptible */
1160 static void
1161 io_end_interruptible(HANDLE handle)
1162 {
1163     if (!ptr_CancelIoEx)
1164         return;
1165     __sync_bool_compare_and_swap(&this_thread->synchronous_io_handle_and_flag,
1166                                  handle, 0);
1167 }
1168
1169 /* Documented limit for ReadConsole/WriteConsole is 64K bytes.
1170    Real limit observed on W2K-SP3 is somewhere in between 32KiB and 64Kib...
1171 */
1172 #define MAX_CONSOLE_TCHARS 16384
1173
1174 int
1175 win32_write_unicode_console(HANDLE handle, void * buf, int count)
1176 {
1177     DWORD written = 0;
1178     DWORD nchars;
1179     BOOL result;
1180     nchars = count>>1;
1181     if (nchars>MAX_CONSOLE_TCHARS) nchars = MAX_CONSOLE_TCHARS;
1182
1183     if (!io_begin_interruptible(handle)) {
1184         errno = EINTR;
1185         return -1;
1186     }
1187     result = WriteConsoleW(handle,buf,nchars,&written,NULL);
1188     io_end_interruptible(handle);
1189
1190     if (result) {
1191         if (!written) {
1192             errno = EINTR;
1193             return -1;
1194         } else {
1195             return 2*written;
1196         }
1197     } else {
1198         DWORD err = GetLastError();
1199         odxprint(io,"WriteConsole fails => %u\n", err);
1200         errno = (err==ERROR_OPERATION_ABORTED ? EINTR : EIO);
1201         return -1;
1202     }
1203 }
1204
1205 /*
1206  * (AK writes:)
1207  *
1208  * It may be unobvious, but (probably) the most straightforward way of
1209  * providing some sane CL:LISTEN semantics for line-mode console
1210  * channel requires _dedicated input thread_.
1211  *
1212  * LISTEN should return true iff the next (READ-CHAR) won't have to
1213  * wait. As our console may be shared with another process, entirely
1214  * out of our control, looking at the events in PeekConsoleEvent
1215  * result (and searching for #\Return) doesn't cut it.
1216  *
1217  * We decided that console input thread must do something smarter than
1218  * a bare loop of continuous ReadConsoleW(). On Unix, user experience
1219  * with the terminal is entirely unaffected by the fact that some
1220  * process does (or doesn't) call read(); the situation on MS Windows
1221  * is different.
1222  *
1223  * Echo output and line editing present on MS Windows while some
1224  * process is waiting in ReadConsole(); otherwise all input events are
1225  * buffered. If our thread were calling ReadConsole() all the time, it
1226  * would feel like Unix cooked mode.
1227  *
1228  * But we don't write a Unix emulator here, even if it sometimes feels
1229  * like that; therefore preserving this aspect of console I/O seems a
1230  * good thing to us.
1231  *
1232  * LISTEN itself becomes trivial with dedicated input thread, but the
1233  * goal stated above -- provide `native' user experience with blocked
1234  * console -- don't play well with this trivial implementation.
1235  *
1236  * What's currently implemented is a compromise, looking as something
1237  * in between Unix cooked mode and Win32 line mode.
1238  *
1239  * 1. As long as no console I/O function is called (incl. CL:LISTEN),
1240  * console looks `blocked': no echo, no line editing.
1241  *
1242  * 2. (READ-CHAR), (READ-SEQUENCE) and other functions doing real
1243  * input result in the ReadConsole request (in a dedicated thread);
1244  *
1245  * 3. Once ReadConsole is called, it is not cancelled in the
1246  * middle. In line mode, it returns when <Enter> key is hit (or
1247  * something like that happens). Therefore, if line editing and echo
1248  * output had a chance to happen, console won't look `blocked' until
1249  * the line is entered (even if line input was triggered by
1250  * (READ-CHAR)).
1251  *
1252  * 4. LISTEN may request ReadConsole too (if no other thread is
1253  * reading the console and no data are queued). It's the only case
1254  * when the console becomes `unblocked' without any actual input
1255  * requested by Lisp code.  LISTEN check if there is at least one
1256  * input event in PeekConsole queue; unless there is such an event,
1257  * ReadConsole is not triggered by LISTEN.
1258  *
1259  * 5. Console-reading Lisp thread now may be interrupted immediately;
1260  * ReadConsole call itself, however, continues until the line is
1261  * entered.
1262  */
1263
1264 struct {
1265     WCHAR buffer[MAX_CONSOLE_TCHARS];
1266     DWORD head, tail;
1267     pthread_mutex_t lock;
1268     pthread_cond_t cond_has_data;
1269     pthread_cond_t cond_has_client;
1270     pthread_t thread;
1271     boolean initialized;
1272     HANDLE handle;
1273     boolean in_progress;
1274 } ttyinput = {.lock = PTHREAD_MUTEX_INITIALIZER};
1275
1276 static void*
1277 tty_read_line_server()
1278 {
1279     pthread_mutex_lock(&ttyinput.lock);
1280     while (ttyinput.handle) {
1281         DWORD nchars;
1282         BOOL ok;
1283
1284         while (!ttyinput.in_progress)
1285             pthread_cond_wait(&ttyinput.cond_has_client,&ttyinput.lock);
1286
1287         pthread_mutex_unlock(&ttyinput.lock);
1288
1289         ok = ReadConsoleW(ttyinput.handle,
1290                           &ttyinput.buffer[ttyinput.tail],
1291                           MAX_CONSOLE_TCHARS-ttyinput.tail,
1292                           &nchars,NULL);
1293
1294         pthread_mutex_lock(&ttyinput.lock);
1295
1296         if (ok) {
1297             ttyinput.tail += nchars;
1298             pthread_cond_broadcast(&ttyinput.cond_has_data);
1299         }
1300         ttyinput.in_progress = 0;
1301     }
1302     pthread_mutex_unlock(&ttyinput.lock);
1303     return NULL;
1304 }
1305
1306 static boolean
1307 tty_maybe_initialize_unlocked(HANDLE handle)
1308 {
1309     if (!ttyinput.initialized) {
1310         if (!DuplicateHandle(GetCurrentProcess(),handle,
1311                              GetCurrentProcess(),&ttyinput.handle,
1312                              0,FALSE,DUPLICATE_SAME_ACCESS)) {
1313             return 0;
1314         }
1315         pthread_cond_init(&ttyinput.cond_has_data,NULL);
1316         pthread_cond_init(&ttyinput.cond_has_client,NULL);
1317         pthread_create(&ttyinput.thread,NULL,tty_read_line_server,NULL);
1318         ttyinput.initialized = 1;
1319     }
1320     return 1;
1321 }
1322
1323 boolean
1324 win32_tty_listen(HANDLE handle)
1325 {
1326     boolean result = 0;
1327     INPUT_RECORD ir;
1328     DWORD nevents;
1329     pthread_mutex_lock(&ttyinput.lock);
1330     if (!tty_maybe_initialize_unlocked(handle))
1331         result = 0;
1332
1333     if (ttyinput.in_progress) {
1334         result = 0;
1335     } else {
1336         if (ttyinput.head != ttyinput.tail) {
1337             result = 1;
1338         } else {
1339             if (PeekConsoleInput(ttyinput.handle,&ir,1,&nevents) && nevents) {
1340                 ttyinput.in_progress = 1;
1341                 pthread_cond_broadcast(&ttyinput.cond_has_client);
1342             }
1343         }
1344     }
1345     pthread_mutex_unlock(&ttyinput.lock);
1346     return result;
1347 }
1348
1349 static int
1350 tty_read_line_client(HANDLE handle, void* buf, int count)
1351 {
1352     int result = 0;
1353     int nchars = count / sizeof(WCHAR);
1354     sigset_t pendset;
1355
1356     if (!nchars)
1357         return 0;
1358     if (nchars>MAX_CONSOLE_TCHARS)
1359         nchars=MAX_CONSOLE_TCHARS;
1360
1361     count = nchars*sizeof(WCHAR);
1362
1363     pthread_mutex_lock(&ttyinput.lock);
1364
1365     if (!tty_maybe_initialize_unlocked(handle)) {
1366         result = -1;
1367         errno = EIO;
1368         goto unlock;
1369     }
1370
1371     while (!result) {
1372         while (ttyinput.head == ttyinput.tail) {
1373             if (!io_begin_interruptible(ttyinput.handle)) {
1374                 ttyinput.in_progress = 0;
1375                 result = -1;
1376                 errno = EINTR;
1377                 goto unlock;
1378             } else {
1379                 if (!ttyinput.in_progress) {
1380                     /* We are to wait */
1381                     ttyinput.in_progress=1;
1382                     /* wake console reader */
1383                     pthread_cond_broadcast(&ttyinput.cond_has_client);
1384                 }
1385                 pthread_cond_wait(&ttyinput.cond_has_data, &ttyinput.lock);
1386                 io_end_interruptible(ttyinput.handle);
1387             }
1388         }
1389         result = sizeof(WCHAR)*(ttyinput.tail-ttyinput.head);
1390         if (result > count) {
1391             result = count;
1392         }
1393         if (result) {
1394             if (result > 0) {
1395                 DWORD nch,offset = 0;
1396                 LPWSTR ubuf = buf;
1397
1398                 memcpy(buf,&ttyinput.buffer[ttyinput.head],count);
1399                 ttyinput.head += (result / sizeof(WCHAR));
1400                 if (ttyinput.head == ttyinput.tail)
1401                     ttyinput.head = ttyinput.tail = 0;
1402
1403                 for (nch=0;nch<result/sizeof(WCHAR);++nch) {
1404                     if (ubuf[nch]==13) {
1405                         ++offset;
1406                     } else {
1407                         ubuf[nch-offset]=ubuf[nch];
1408                     }
1409                 }
1410                 result-=offset*sizeof(WCHAR);
1411
1412             }
1413         } else {
1414             result = -1;
1415             ttyinput.head = ttyinput.tail = 0;
1416             errno = EIO;
1417         }
1418     }
1419 unlock:
1420     pthread_mutex_unlock(&ttyinput.lock);
1421     return result;
1422 }
1423
1424 int
1425 win32_read_unicode_console(HANDLE handle, void* buf, int count)
1426 {
1427
1428     int result;
1429     result = tty_read_line_client(handle,buf,count);
1430     return result;
1431 }
1432
1433 boolean
1434 win32_maybe_interrupt_io(void* thread)
1435 {
1436     struct thread *th = thread;
1437     boolean done = 0;
1438     /* Kludge. (?)
1439      *
1440      * ICBW about all of this.  But it seems to me that this procedure is
1441      * a race condition.  In theory.  One that is hard produce (I can't
1442      * come up with a test case that exploits it), and might only be a bug
1443      * if users are doing weird things with I/O, possibly from FFI.  But a
1444      * race is a race, so shouldn't this function and io_end_interruptible
1445      * cooperate more?
1446      *
1447      * Here's my thinking:
1448      *
1449      * A.. <interruptee thread>
1450      *     ... stuffs its handle into its structure.
1451      * B.. <interrupter thread>
1452      *     ... calls us to wake the thread, finds the handle.
1453      *     But just before we actually call CancelSynchronousIo/CancelIoEx,
1454      *     something weird happens in the scheduler and the system is
1455      *     so extremely busy that the interrupter doesn't get scheduled
1456      *     for a while, giving the interruptee lots of time to continue.
1457      * A.. Didn't actually have to block, calls io_end_interruptible (in
1458      *     which the handle flag already invalid, but it doesn't care
1459      *     about that and still continues).
1460      *     ... Proceeds to do unrelated I/O, e.g. goes into FFI code
1461      *     (possible, because the CSP page hasn't been armed yet), which
1462      *     does I/O from a C library, completely unrelated to SBCL's
1463      *     routines.
1464      * B.. The scheduler gives us time for the interrupter again.
1465      *     We call CancelSynchronousIo/CancelIoEx.
1466      * A.. Interruptee gets an expected error in unrelated I/O during FFI.
1467      *     Interruptee's C code is unhappy and dies.
1468      *
1469      * Note that CancelSynchronousIo and CancelIoEx have a rather different
1470      * effect here.  In the normal (CancelIoEx) case, we only ever kill
1471      * I/O on the file handle in question.  I think we could ask users
1472      * to please not both use Lisp streams (unix-read/write) _and_ FFI code
1473      * on the same file handle in quick succession.
1474      *
1475      * CancelSynchronousIo seems more dangerous though.  Here we interrupt
1476      * I/O on any other handle, even ones we're not actually responsible for,
1477      * because this functions deals with the thread handle, not the file
1478      * handle.
1479      *
1480      * Options:
1481      *  - Use mutexes.  Somewhere, somehow.  Presumably one mutex per
1482      *    target thread, acquired around win32_maybe_interrupt_io and
1483      *    io_end_interruptible.  (That's one mutex use per I/O
1484      *    operation, but I can't imagine that compared to our FFI overhead
1485      *    that's much of a problem.)
1486      *  - In io_end_interruptible, detect that the flag has been
1487      *    invalidated, and in that case, do something clever (what?) to
1488      *    wait for the imminent gc_stop_the_world, which implicitly tells
1489      *    us that win32_maybe_interrupt_io must have exited.  Except if
1490      *    some _third_ thread is also beginning to call interrupt-thread
1491      *    and wake_thread at the same time...?
1492      *  - Revert the whole CancelSynchronousIo business after all.
1493      *  - I'm wrong and everything is OK already.
1494      */
1495     if (ptr_CancelIoEx) {
1496         HANDLE h = (HANDLE)
1497             InterlockedExchangePointer((volatile LPVOID *)
1498                                        &th->synchronous_io_handle_and_flag,
1499                                        (LPVOID)INVALID_HANDLE_VALUE);
1500         if (h && (h!=INVALID_HANDLE_VALUE)) {
1501             if (console_handle_p(h)) {
1502                 pthread_mutex_lock(&ttyinput.lock);
1503                 pthread_cond_broadcast(&ttyinput.cond_has_data);
1504                 pthread_mutex_unlock(&ttyinput.lock);
1505             }
1506             if (ptr_CancelSynchronousIo) {
1507                 pthread_mutex_lock(&th->os_thread->fiber_lock);
1508                 done = ptr_CancelSynchronousIo(th->os_thread->fiber_group->handle);
1509                 pthread_mutex_unlock(&th->os_thread->fiber_lock);
1510             }
1511             return (!!done)|(!!ptr_CancelIoEx(h,NULL));
1512         }
1513     }
1514     return 0;
1515 }
1516
1517 static const LARGE_INTEGER zero_large_offset = {.QuadPart = 0LL};
1518
1519 int
1520 win32_unix_write(FDTYPE fd, void * buf, int count)
1521 {
1522     HANDLE handle;
1523     DWORD written_bytes;
1524     OVERLAPPED overlapped;
1525     struct thread * self = arch_os_get_current_thread();
1526     BOOL waitInGOR;
1527     LARGE_INTEGER file_position;
1528     BOOL seekable;
1529     BOOL ok;
1530
1531     handle =(HANDLE)maybe_get_osfhandle(fd);
1532     if (console_handle_p(handle))
1533         return win32_write_unicode_console(handle,buf,count);
1534
1535     overlapped.hEvent = self->private_events.events[0];
1536     seekable = SetFilePointerEx(handle,
1537                                 zero_large_offset,
1538                                 &file_position,
1539                                 FILE_CURRENT);
1540     if (seekable) {
1541         overlapped.Offset = file_position.LowPart;
1542         overlapped.OffsetHigh = file_position.HighPart;
1543     } else {
1544         overlapped.Offset = 0;
1545         overlapped.OffsetHigh = 0;
1546     }
1547     if (!io_begin_interruptible(handle)) {
1548         errno = EINTR;
1549         return -1;
1550     }
1551     ok = WriteFile(handle, buf, count, &written_bytes, &overlapped);
1552     io_end_interruptible(handle);
1553
1554     if (ok) {
1555         goto done_something;
1556     } else {
1557         DWORD errorCode = GetLastError();
1558         if (errorCode==ERROR_OPERATION_ABORTED) {
1559             GetOverlappedResult(handle,&overlapped,&written_bytes,FALSE);
1560             errno = EINTR;
1561             return -1;
1562         }
1563         if (errorCode!=ERROR_IO_PENDING) {
1564             errno = EIO;
1565             return -1;
1566         } else {
1567             if(WaitForMultipleObjects(2,self->private_events.events,
1568                                       FALSE,INFINITE) != WAIT_OBJECT_0) {
1569                 CancelIo(handle);
1570                 waitInGOR = TRUE;
1571             } else {
1572                 waitInGOR = FALSE;
1573             }
1574             if (!GetOverlappedResult(handle,&overlapped,&written_bytes,waitInGOR)) {
1575                 if (GetLastError()==ERROR_OPERATION_ABORTED) {
1576                     errno = EINTR;
1577                 } else {
1578                     errno = EIO;
1579                 }
1580                 return -1;
1581             } else {
1582                 goto done_something;
1583             }
1584         }
1585     }
1586   done_something:
1587     if (seekable) {
1588         file_position.QuadPart += written_bytes;
1589         SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
1590     }
1591     return written_bytes;
1592 }
1593
1594 int
1595 win32_unix_read(FDTYPE fd, void * buf, int count)
1596 {
1597     HANDLE handle;
1598     OVERLAPPED overlapped = {.Internal=0};
1599     DWORD read_bytes = 0;
1600     struct thread * self = arch_os_get_current_thread();
1601     DWORD errorCode = 0;
1602     BOOL waitInGOR = FALSE;
1603     BOOL ok = FALSE;
1604     LARGE_INTEGER file_position;
1605     BOOL seekable;
1606
1607     handle = (HANDLE)maybe_get_osfhandle(fd);
1608
1609     if (console_handle_p(handle))
1610         return win32_read_unicode_console(handle,buf,count);
1611
1612     overlapped.hEvent = self->private_events.events[0];
1613     /* If it has a position, we won't try overlapped */
1614     seekable = SetFilePointerEx(handle,
1615                                 zero_large_offset,
1616                                 &file_position,
1617                                 FILE_CURRENT);
1618     if (seekable) {
1619         overlapped.Offset = file_position.LowPart;
1620         overlapped.OffsetHigh = file_position.HighPart;
1621     } else {
1622         overlapped.Offset = 0;
1623         overlapped.OffsetHigh = 0;
1624     }
1625     if (!io_begin_interruptible(handle)) {
1626         errno = EINTR;
1627         return -1;
1628     }
1629     ok = ReadFile(handle,buf,count,&read_bytes, &overlapped);
1630     io_end_interruptible(handle);
1631     if (ok) {
1632         /* immediately */
1633         goto done_something;
1634     } else {
1635         errorCode = GetLastError();
1636         if (errorCode == ERROR_HANDLE_EOF ||
1637             errorCode == ERROR_BROKEN_PIPE ||
1638             errorCode == ERROR_NETNAME_DELETED) {
1639             read_bytes = 0;
1640             goto done_something;
1641         }
1642         if (errorCode==ERROR_OPERATION_ABORTED) {
1643             GetOverlappedResult(handle,&overlapped,&read_bytes,FALSE);
1644             errno = EINTR;
1645             return -1;
1646         }
1647         if (errorCode!=ERROR_IO_PENDING) {
1648             /* is it some _real_ error? */
1649             errno = EIO;
1650             return -1;
1651         } else {
1652             int ret;
1653             if( (ret = WaitForMultipleObjects(2,self->private_events.events,
1654                                               FALSE,INFINITE)) != WAIT_OBJECT_0) {
1655                 CancelIo(handle);
1656                 waitInGOR = TRUE;
1657                 /* Waiting for IO only */
1658             } else {
1659                 waitInGOR = FALSE;
1660             }
1661             ok = GetOverlappedResult(handle,&overlapped,&read_bytes,waitInGOR);
1662             if (!ok) {
1663                 errorCode = GetLastError();
1664                 if (errorCode == ERROR_HANDLE_EOF ||
1665                     errorCode == ERROR_BROKEN_PIPE ||
1666                     errorCode == ERROR_NETNAME_DELETED) {
1667                     read_bytes = 0;
1668                     goto done_something;
1669                 } else {
1670                     if (errorCode == ERROR_OPERATION_ABORTED)
1671                         errno = EINTR;      /* that's it. */
1672                     else
1673                         errno = EIO;        /* something unspecific */
1674                     return -1;
1675                 }
1676             } else
1677                 goto done_something;
1678         }
1679     }
1680   done_something:
1681     if (seekable) {
1682         file_position.QuadPart += read_bytes;
1683         SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
1684     }
1685     return read_bytes;
1686 }
1687
1688 /* This is a manually-maintained version of ldso_stubs.S. */
1689
1690 void __stdcall RtlUnwind(void *, void *, void *, void *); /* I don't have winternl.h */
1691
1692 void scratch(void)
1693 {
1694     LARGE_INTEGER la = {{0}};
1695     closesocket(0);
1696     CloseHandle(0);
1697     shutdown(0, 0);
1698     SetHandleInformation(0, 0, 0);
1699     GetHandleInformation(0, 0);
1700     getsockopt(0, 0, 0, 0, 0);
1701     FlushConsoleInputBuffer(0);
1702     FormatMessageA(0, 0, 0, 0, 0, 0, 0);
1703     FreeLibrary(0);
1704     GetACP();
1705     GetConsoleCP();
1706     GetConsoleOutputCP();
1707     GetCurrentProcess();
1708     GetExitCodeProcess(0, 0);
1709     GetLastError();
1710     GetOEMCP();
1711     GetProcAddress(0, 0);
1712     GetProcessTimes(0, 0, 0, 0, 0);
1713     GetSystemTimeAsFileTime(0);
1714     LoadLibrary(0);
1715     LocalFree(0);
1716     PeekConsoleInput(0, 0, 0, 0);
1717     PeekNamedPipe(0, 0, 0, 0, 0, 0);
1718     ReadFile(0, 0, 0, 0, 0);
1719     Sleep(0);
1720     WriteFile(0, 0, 0, 0, 0);
1721     _get_osfhandle(0);
1722     _open_osfhandle(0, 0);
1723     _rmdir(0);
1724     _pipe(0,0,0);
1725     access(0,0);
1726     close(0);
1727     dup(0);
1728     isatty(0);
1729     strerror(42);
1730     write(0, 0, 0);
1731     RtlUnwind(0, 0, 0, 0);
1732     MapViewOfFile(0,0,0,0,0);
1733     UnmapViewOfFile(0);
1734     FlushViewOfFile(0,0);
1735     SetFilePointerEx(0, la, 0, 0);
1736     DuplicateHandle(0, 0, 0, 0, 0, 0, 0);
1737     #ifndef LISP_FEATURE_SB_UNICODE
1738       CreateDirectoryA(0,0);
1739       CreateFileMappingA(0,0,0,0,0,0);
1740       CreateFileA(0,0,0,0,0,0,0);
1741       GetComputerNameA(0, 0);
1742       GetCurrentDirectoryA(0,0);
1743       GetEnvironmentVariableA(0, 0, 0);
1744       GetFileAttributesA(0);
1745       GetVersionExA(0);
1746       MoveFileA(0,0);
1747       SHGetFolderPathA(0, 0, 0, 0, 0);
1748       SetCurrentDirectoryA(0);
1749       SetEnvironmentVariableA(0, 0);
1750     #else
1751       CreateDirectoryW(0,0);
1752       CreateFileMappingW(0,0,0,0,0,0);
1753       CreateFileW(0,0,0,0,0,0,0);
1754       FormatMessageW(0, 0, 0, 0, 0, 0, 0);
1755       GetComputerNameW(0, 0);
1756       GetCurrentDirectoryW(0,0);
1757       GetEnvironmentVariableW(0, 0, 0);
1758       GetFileAttributesW(0);
1759       GetVersionExW(0);
1760       MoveFileW(0,0);
1761       SHGetFolderPathW(0, 0, 0, 0, 0);
1762       SetCurrentDirectoryW(0);
1763       SetEnvironmentVariableW(0, 0);
1764     #endif
1765     _exit(0);
1766 }
1767
1768 char *
1769 os_get_runtime_executable_path(int external)
1770 {
1771     char path[MAX_PATH + 1];
1772     DWORD bufsize = sizeof(path);
1773     DWORD size;
1774
1775     if ((size = GetModuleFileNameA(NULL, path, bufsize)) == 0)
1776         return NULL;
1777     else if (size == bufsize && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1778         return NULL;
1779
1780     return copied_string(path);
1781 }
1782
1783 #ifdef LISP_FEATURE_SB_THREAD
1784
1785 int
1786 win32_wait_object_or_signal(HANDLE waitFor)
1787 {
1788     struct thread * self = arch_os_get_current_thread();
1789     HANDLE handles[2];
1790     handles[0] = waitFor;
1791     handles[1] = self->private_events.events[1];
1792     return
1793         WaitForMultipleObjects(2,handles, FALSE,INFINITE);
1794 }
1795
1796 /*
1797  * Portability glue for win32 waitable timers.
1798  *
1799  * One may ask: Why is there a wrapper in C when the calls are so
1800  * obvious that Lisp could do them directly (as it did on Windows)?
1801  *
1802  * But the answer is that on POSIX platforms, we now emulate the win32
1803  * calls and hide that emulation behind this os_* abstraction.
1804  */
1805 HANDLE
1806 os_create_wtimer()
1807 {
1808     return CreateWaitableTimer(0, 0, 0);
1809 }
1810
1811 int
1812 os_wait_for_wtimer(HANDLE handle)
1813 {
1814     return win32_wait_object_or_signal(handle);
1815 }
1816
1817 void
1818 os_close_wtimer(HANDLE handle)
1819 {
1820     CloseHandle(handle);
1821 }
1822
1823 void
1824 os_set_wtimer(HANDLE handle, int sec, int nsec)
1825 {
1826     /* in units of 100ns, i.e. 0.1us. Negative for relative semantics. */
1827     long long dueTime
1828         = -(((long long) sec) * 10000000
1829             + ((long long) nsec + 99) / 100);
1830     SetWaitableTimer(handle, (LARGE_INTEGER*) &dueTime, 0, 0, 0, 0);
1831 }
1832
1833 void
1834 os_cancel_wtimer(HANDLE handle)
1835 {
1836     CancelWaitableTimer(handle);
1837 }
1838 #endif
1839
1840 /* EOF */