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