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 #include <wincrypt.h>
74 
75 #if 0
76 int linux_sparc_siginfo_bug = 0;
77 int linux_supports_futex=0;
78 #endif
79 
80 #include <stdarg.h>
81 #include <string.h>
82 
83 /* missing definitions for modern mingws */
84 #ifndef EH_UNWINDING
85 #define EH_UNWINDING 0x02
86 #endif
87 #ifndef EH_EXIT_UNWIND
88 #define EH_EXIT_UNWIND 0x04
89 #endif
90 
91 /* Tired of writing arch_os_get_current_thread each time. */
92 #define this_thread (arch_os_get_current_thread())
93 
94 /* wrappers for winapi calls that must be successful (like SBCL's
95  * (aver ...) form). */
96 
97 /* win_aver function: basic building block for miscellaneous
98  * ..AVER.. macrology (below) */
99 
100 /* To do: These routines used to be "customizable" with dyndebug_init()
101  * and variables like dyndebug_survive_aver, dyndebug_skip_averlax based
102  * on environment variables.  Those features got lost on the way, but
103  * ought to be reintroduced. */
104 
105 static inline
win_aver(intptr_t value,char * comment,char * file,int line,int justwarn)106 intptr_t win_aver(intptr_t value, char* comment, char* file, int line,
107                   int justwarn)
108 {
109     if (!value) {
110         LPSTR errorMessage = "<FormatMessage failed>";
111         DWORD errorCode = GetLastError(), allocated=0;
112         int posixerrno = errno;
113         const char* posixstrerror = strerror(errno);
114         char* report_template =
115             "Expression unexpectedly false: %s:%d\n"
116             " ... %s\n"
117             "     ===> returned #X%p, \n"
118             "     (in thread %p)"
119             " ... Win32 thinks:\n"
120             "     ===> code %u, message => %s\n"
121             " ... CRT thinks:\n"
122             "     ===> code %u, message => %s\n";
123 
124         allocated =
125             FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|
126                            FORMAT_MESSAGE_FROM_SYSTEM,
127                            NULL,
128                            errorCode,
129                            MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
130                            (LPSTR)&errorMessage,
131                            1024u,
132                            NULL);
133 
134         if (justwarn) {
135             fprintf(stderr, report_template,
136                     file, line,
137                     comment, value,
138                     this_thread,
139                     (unsigned)errorCode, errorMessage,
140                     posixerrno, posixstrerror);
141         } else {
142             lose(report_template,
143                     file, line,
144                     comment, value,
145                     this_thread,
146                     (unsigned)errorCode, errorMessage,
147                     posixerrno, posixstrerror);
148         }
149         if (allocated)
150             LocalFree(errorMessage);
151     }
152     return value;
153 }
154 
155 /* sys_aver function: really tiny adaptor of win_aver for
156  * "POSIX-parody" CRT results ("lowio" and similar stuff):
157  * negative number means something... negative. */
158 static inline
sys_aver(long value,char * comment,char * file,int line,int justwarn)159 intptr_t sys_aver(long value, char* comment, char* file, int line,
160               int justwarn)
161 {
162     win_aver((intptr_t)(value>=0),comment,file,line,justwarn);
163     return value;
164 }
165 
166 /* Check for (call) result being boolean true. (call) may be arbitrary
167  * expression now; massive attack of gccisms ensures transparent type
168  * conversion back and forth, so the type of AVER(expression) is the
169  * type of expression. Value is the same _if_ it can be losslessly
170  * converted to (void*) and back.
171  *
172  * Failed AVER() is normally fatal. Well, unless dyndebug_survive_aver
173  * flag is set. */
174 
175 #define AVER(call)                                                      \
176     ({ __typeof__(call) __attribute__((unused)) me =                    \
177             (__typeof__(call))                                          \
178             win_aver((intptr_t)(call), #call, __FILE__, __LINE__, 0);      \
179         me;})
180 
181 /* AVERLAX(call): do the same check as AVER did, but be mild on
182  * failure: print an annoying unrequested message to stderr, and
183  * continue. With dyndebug_skip_averlax flag, AVERLAX stop even to
184  * check and complain. */
185 
186 #define AVERLAX(call)                                                   \
187     ({ __typeof__(call) __attribute__((unused)) me =                    \
188             (__typeof__(call))                                          \
189             win_aver((intptr_t)(call), #call, __FILE__, __LINE__, 1);      \
190         me;})
191 
192 /* Now, when failed AVER... prints both errno and GetLastError(), two
193  * variants of "POSIX/lowio" style checks below are almost useless
194  * (they build on sys_aver like the two above do on win_aver). */
195 
196 #define CRT_AVER_NONNEGATIVE(call)                              \
197     ({ __typeof__(call) __attribute__((unused)) me =            \
198             (__typeof__(call))                                  \
199             sys_aver((call), #call, __FILE__, __LINE__, 0);     \
200         me;})
201 
202 #define CRT_AVERLAX_NONNEGATIVE(call)                           \
203     ({ __typeof__(call) __attribute__((unused)) me =            \
204             (__typeof__(call))                                  \
205             sys_aver((call), #call, __FILE__, __LINE__, 1);     \
206         me;})
207 
208 /* to be removed */
209 #define CRT_AVER(booly)                                         \
210     ({ __typeof__(booly) __attribute__((unused)) me = (booly);  \
211         sys_aver((booly)?0:-1, #booly, __FILE__, __LINE__, 0);  \
212         me;})
213 
214 const char * t_nil_s(lispobj symbol);
215 
216 /*
217  * The following signal-mask-related alien routines are called from Lisp:
218  */
219 
220 /* As of win32, deferrables _do_ matter. gc_signal doesn't. */
block_deferrables_and_return_mask()221 unsigned long block_deferrables_and_return_mask()
222 {
223     sigset_t sset;
224     block_deferrable_signals(&sset);
225     return (unsigned long)sset;
226 }
227 
228 #if defined(LISP_FEATURE_SB_THREAD)
apply_sigmask(unsigned long sigmask)229 void apply_sigmask(unsigned long sigmask)
230 {
231     sigset_t sset = (sigset_t)sigmask;
232     thread_sigmask(SIG_SETMASK, &sset, 0);
233 }
234 #endif
235 
236 /* The exception handling function looks like this: */
237 EXCEPTION_DISPOSITION handle_exception(EXCEPTION_RECORD *,
238                                        struct lisp_exception_frame *,
239                                        CONTEXT *,
240                                        void *);
241 /* handle_exception is defined further in this file, but since SBCL
242  * 1.0.1.24, it doesn't get registered as SEH handler directly anymore,
243  * not even by wos_install_interrupt_handlers. Instead, x86-assem.S
244  * provides exception_handler_wrapper; we install it here, and each
245  * exception frame on nested funcall()s also points to it.
246  */
247 
248 
249 void *base_seh_frame;
250 
251 HMODULE runtime_module_handle = 0u;
252 
get_seh_frame(void)253 static void *get_seh_frame(void)
254 {
255     void* retval;
256 #ifdef LISP_FEATURE_X86
257     asm volatile ("mov %%fs:0,%0": "=r" (retval));
258 #else
259     asm volatile ("mov %%gs:0,%0": "=r" (retval));
260 #endif
261     return retval;
262 }
263 
set_seh_frame(void * frame)264 static void set_seh_frame(void *frame)
265 {
266 #ifdef LISP_FEATURE_X86
267     asm volatile ("mov %0,%%fs:0": : "r" (frame));
268 #else
269     asm volatile ("mov %0,%%gs:0": : "r" (frame));
270 #endif
271 }
272 
273 #if defined(LISP_FEATURE_SB_THREAD)
274 
alloc_gc_page()275 void alloc_gc_page()
276 {
277     AVER(VirtualAlloc(GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
278                       MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE));
279 }
280 
281 /* Permit loads from GC_SAFEPOINT_PAGE_ADDR (NB page state change is
282  * "synchronized" with the memory region content/availability --
283  * e.g. you won't see other CPU flushing buffered writes after WP --
284  * but there is some window when other thread _seem_ to trap AFTER
285  * access is granted. You may think of it something like "OS enters
286  * SEH handler too slowly" -- what's important is there's no implicit
287  * synchronization between VirtualProtect caller and other thread's
288  * SEH handler, hence no ordering of events. VirtualProtect is
289  * implicitly synchronized with protected memory contents (only).
290  *
291  * The last fact may be potentially used with many benefits e.g. for
292  * foreign call speed, but we don't use it for now: almost the only
293  * fact relevant to the current signalling protocol is "sooner or
294  * later everyone will trap [everyone will stop trapping]".
295  *
296  * An interesting source on page-protection-based inter-thread
297  * communication is a well-known paper by Dave Dice, Hui Huang,
298  * Mingyao Yang: ``Asymmetric Dekker Synchronization''. Last time
299  * I checked it was available at
300  * http://home.comcast.net/~pjbishop/Dave/Asymmetric-Dekker-Synchronization.txt
301  */
map_gc_page()302 void map_gc_page()
303 {
304     DWORD oldProt;
305     AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
306                         PAGE_READWRITE, &oldProt));
307 }
308 
unmap_gc_page()309 void unmap_gc_page()
310 {
311     DWORD oldProt;
312     AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
313                         PAGE_NOACCESS, &oldProt));
314 }
315 
316 #endif
317 
318 #if defined(LISP_FEATURE_SB_DYNAMIC_CORE)
319 /* This feature has already saved me more development time than it
320  * took to implement.  In its current state, ``dynamic RT<->core
321  * linking'' is a protocol of initialization of C runtime and Lisp
322  * core, populating SBCL linkage table with entries for runtime
323  * "foreign" symbols that were referenced in cross-compiled code.
324  *
325  * How it works: a sketch
326  *
327  * Last Genesis (resulting in cold-sbcl_core) binds foreign fixups in
328  * x-compiled lisp-objs to sequential addresses from the beginning of
329  * linkage-table space; that's how it ``resolves'' foreign references.
330  * Obviously, this process doesn't require pre-built runtime presence.
331  *
332  * When the runtime loads the core (cold-sbcl_core initially,
333  * sbcl_core later), runtime should do its part of the protocol by (1)
334  * traversing a list of ``runtime symbols'' prepared by Genesis and
335  * dumped as a static symbol value, (2) resolving each name from this
336  * list to an address (stubbing unresolved ones with
337  * undefined_alien_address or undefined_alien_function), (3) adding an
338  * entry for each symbol somewhere near the beginning of linkage table
339  * space (location is provided by the core).
340  *
341  * The implementation of the part described in the last paragraph
342  * follows. C side is currently more ``hackish'' and less clear than
343  * the Lisp code; OTOH, related Lisp changes are scattered, and some
344  * of them play part in complex interrelations -- beautiful but taking
345  * much time to understand --- but my subset of PE-i386 parser below
346  * is in one place (here) and doesn't have _any_ non-trivial coupling
347  * with the rest of the Runtime.
348  *
349  * What do we gain with this feature, after all?
350  *
351  * One things that I have to do rather frequently: recompile and
352  * replace runtime without rebuilding the core. Doubtlessly, slam.sh
353  * was a great time-saver here, but relinking ``cold'' core and bake a
354  * ``warm'' one takes, as it seems, more than 10x times of bare
355  * SBCL.EXE build time -- even if everything is recompiled, which is
356  * now unnecessary. Today, if I have a new idea for the runtime,
357  * getting from C-x C-s M-x ``compile'' to fully loaded SBCL
358  * installation takes 5-15 seconds.
359  *
360  * Another thing (that I'm not currently using, but obviously
361  * possible) is delivering software patches to remote system on
362  * customer site. As you are doing minor additions or corrections in
363  * Lisp code, it doesn't take much effort to prepare a tiny ``FASL
364  * bundle'' that rolls up your patch, redumps and -- presto -- 100MiB
365  * program is fixed by sending and loading a 50KiB thingie.
366  *
367  * However, until LISP_FEATURE_SB_DYNAMIC_CORE, if your bug were fixed
368  * by modifying two lines of _C_ sources, a customer described above
369  * had to be ready to receive and reinstall a new 100MiB
370  * executable. With the aid of code below, deploying such a fix
371  * requires only sending ~300KiB (when stripped) of SBCL.EXE.
372  *
373  * But there is more to it: as the common linkage-table is used for
374  * DLLs and core, its entries may be overridden almost without a look
375  * into SBCL internals. Therefore, ``patching'' C runtime _without_
376  * restarting target systems is also possible in many situations
377  * (it's not as trivial as loading FASLs into a running daemon, but
378  * easy enough to be a viable alternative if any downtime is highly
379  * undesirable).
380  *
381  * During my (rather limited) commercial Lisp development experience
382  * I've already been through a couple of situations where such
383  * ``deployment'' issues were important; from my _total_ programming
384  * experience I know -- _sometimes_ they are a two orders of magnitude
385  * more important than those I observed.
386  *
387  * The possibility of entire runtime ``hot-swapping'' in running
388  * process is not purely theoretical, as it could seem. There are 2-3
389  * problems whose solution is not obvious (call stack patching, for
390  * instance), but it's literally _nothing_ if compared with
391  * e.g. LISP_FEATURE_SB_AUTO_FPU_SWITCH.  By the way, one of the
392  * problems with ``hot-swapping'', that could become a major one in
393  * many other environments, is nonexistent in SBCL: we already have a
394  * ``global quiesce point'' that is generally required for this kind
395  * of worldwide revolution -- around collect_garbage.
396  *
397  * What's almost unnoticeable from the C side (where you are now, dear
398  * reader): using the same style for all linking is beautiful. I tried
399  * to leave old-style linking code in place for the sake of
400  * _non-linkage-table_ platforms (they probably don't have -ldl or its
401  * equivalent, like LL/GPA, at all) -- but i did it usually by moving
402  * the entire `old style' code under #!-sb-dynamic-core and
403  * refactoring the `new style' branch, instead of cutting the tail
404  * piecemeal and increasing #!+-ifdeffery amount & the world enthropy.
405  *
406  * If we look at the majority of the ``new style'' code units, it's a
407  * common thing to observe how #!+-ifdeffery _vanishes_ instead of
408  * multiplying: #!-sb-xc, #!+sb-xc-host and #!-sb-xc-host end up
409  * needing the same code. Runtime checks of static v. dynamic symbol
410  * disappear even faster. STDCALL mangling and leading underscores go
411  * out of scope (and GCed, hopefully) instead of surfacing here and
412  * there as a ``special case for core static symbols''. What I like
413  * the most about CL development in general is a frequency of solving
414  * problems and fixing bugs by simplifying code and dropping special
415  * cases.
416  *
417  * Last important thing about the following code: besides resolving
418  * symbols provided by the core itself, it detects runtime's own
419  * build-time prerequisite DLLs. Any symbol that is unresolved against
420  * the core is looked up in those DLLs (normally kernel32, msvcrt,
421  * ws2_32... I could forget something). This action (1) resembles
422  * implementation of foreign symbol lookup in SBCL itself, (2)
423  * emulates shared library d.l. facilities of OSes that use flat
424  * dynamic symbol namespace (or default to it). Anyone concerned with
425  * portability problems of this PE-i386 stuff below will be glad to
426  * hear that it could be ported to most modern Unices _by deletion_:
427  * raw dlsym() with null handle usually does the same thing that i'm
428  * trying to squeeze out of MS Windows by the brute force.
429  *
430  * My reason for _desiring_ flat symbol namespace, populated from
431  * link-time dependencies, is avoiding any kind of ``requested-by-Lisp
432  * symbol lists to be linked statically'', providing core v. runtime
433  * independence in both directions. Minimizing future maintenance
434  * effort is very important; I had gone for it consistently, starting
435  * by turning "CloseHandle@4" into a simple "CloseHandle", continuing
436  * by adding intermediate Genesis resulting in autogenerated symbol
437  * list (farewell, void scratch(); good riddance), going to take
438  * another great step for core/runtime independence... and _without_
439  * flat namespace emulation, the ghosts and spirits exiled at the
440  * first steps would come and take revenge: well, here are the symbols
441  * that are really in msvcrt.dll.. hmm, let's link statically against
442  * them, so the entry is pulled from the import library.. and those
443  * entry has mangled names that we have to map.. ENOUGH, I though
444  * here: fed up with stuff like that.
445  *
446  * Now here we are, without import libraries, without mangled symbols,
447  * and without nm-generated symbol tables. Every symbol exported by
448  * the runtime is added to SBCL.EXE export directory; every symbol
449  * requested by the core is looked up by GetProcAddress for SBCL.EXE,
450  * falling back to GetProcAddress for MSVCRT.dll, etc etc.. All ties
451  * between SBCL's foreign symbols with object file symbol tables,
452  * import libraries and other pre-linking symbol-resolving entities
453  * _having no representation in SBCL.EXE_ were teared.
454  *
455  * This simplistic approach proved to work well; there is only one
456  * problem introduced by it, and rather minor: in real MSVCRT.dll,
457  * what's used to be available as open() is now called _open();
458  * similar thing happened to many other `lowio' functions, though not
459  * every one, so it's not a kind of name mangling but rather someone's
460  * evil creative mind in action.
461  *
462  * When we look up any of those poor `uglified' functions in CRT
463  * reference on MSDN, we can see a notice resembling this one:
464  *
465  * `unixishname()' is obsolete and provided for backward
466  * compatibility; new standard-compliant function, `_unixishname()',
467  * should be used instead.  Sentences of that kind were there for
468  * several years, probably even for a decade or more (a propos,
469  * MSVCRT.dll, as the name to link against, predates year 2000, so
470  * it's actually possible). Reasoning behing it (what MS people had in
471  * mind) always seemed strange to me: if everyone uses open() and that
472  * `everyone' is important to you, why rename the function?  If no one
473  * uses open(), why provide or retain _open() at all? <kidding>After
474  * all, names like _open() are entirely non-informative and just plain
475  * ugly; compare that with CreateFileW() or InitCommonControlsEx(),
476  * the real examples of beauty and clarity.</kidding>
477  *
478  * Anyway, if the /standard/ name on Windows is _open() (I start to
479  * recall, vaguely, that it's because of _underscore names being
480  * `reserved to system' and all other ones `available for user', per
481  * ANSI/ISO C89) -- well, if the /standard/ name is _open, SBCL should
482  * use it when it uses MSVCRT and not some ``backward-compatible''
483  * stuff. Deciding this way, I added a hack to SBCL's syscall macros,
484  * so "[_]open" as a syscall name is interpreted as a request to link
485  * agains "_open" on win32 and "open" on every other system.
486  *
487  * Of course, this name-parsing trick lacks conceptual clarity; we're
488  * going to get rid of it eventually. */
489 
os_get_build_time_shared_libraries(u32 excl_maximum,void * opt_root,void ** opt_store_handles,const char * opt_store_names[])490 u32 os_get_build_time_shared_libraries(u32 excl_maximum,
491                                        void* opt_root,
492                                        void** opt_store_handles,
493                                        const char *opt_store_names[])
494 {
495     void* base = opt_root ? opt_root : (void*)runtime_module_handle;
496     /* base defaults to 0x400000 with GCC/mingw32. If you dereference
497      * that location, you'll see 'MZ' bytes */
498     void* base_magic_location =
499         base + ((IMAGE_DOS_HEADER*)base)->e_lfanew;
500 
501     /* dos header provided the offset from `base' to
502      * IMAGE_FILE_HEADER where PE-i386 really starts */
503 
504     void* check_duplicates[excl_maximum];
505 
506     if ((*(u32*)base_magic_location)!=0x4550) {
507         /* We don't need this DLL thingie _that_ much. If the world
508          * has changed to a degree where PE magic isn't found, let's
509          * silently return `no libraries detected'. */
510         return 0;
511     } else {
512         /* We traverse PE-i386 structures of SBCL.EXE in memory (not
513          * in the file). File and memory layout _surely_ differ in
514          * some places and _may_ differ in some other places, but
515          * fortunately, those places are irrelevant to the task at
516          * hand. */
517 
518         IMAGE_FILE_HEADER* image_file_header = (base_magic_location + 4);
519         IMAGE_OPTIONAL_HEADER* image_optional_header =
520             (void*)(image_file_header + 1);
521         IMAGE_DATA_DIRECTORY* image_import_direntry =
522             &image_optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
523         IMAGE_IMPORT_DESCRIPTOR* image_import_descriptor =
524             base + image_import_direntry->VirtualAddress;
525         u32 nlibrary, i,j;
526 
527         for (nlibrary=0u; nlibrary < excl_maximum
528                           && image_import_descriptor->FirstThunk;
529              ++image_import_descriptor)
530         {
531             HMODULE hmodule;
532             odxprint(runtime_link, "Now should know DLL: %s",
533                      (char*)(base + image_import_descriptor->Name));
534             /* Code using image thunk data to get its handle was here, with a
535              * number of platform-specific tricks (like using VirtualQuery for
536              * old OSes lacking GetModuleHandleEx).
537              *
538              * It's now replaced with requesting handle by name, which is
539              * theoretically unreliable (with SxS, multiple modules with same
540              * name are quite possible), but good enough to find the
541              * link-time dependencies of our executable or DLL. */
542 
543             hmodule = (HMODULE)
544                 GetModuleHandle(base + image_import_descriptor->Name);
545 
546             if (hmodule)
547             {
548                 /* We may encouncer some module more than once while
549                    traversing import descriptors (it's usually a
550                    result of non-trivial linking process, like doing
551                    ld -r on some groups of files before linking
552                    everything together.
553 
554                    Anyway: using a module handle more than once will
555                    do no harm, but it slows down the startup (even
556                    now, our startup time is not a pleasant topic to
557                    discuss when it comes to :sb-dynamic-core; there is
558                    an obvious direction to go for speed, though --
559                    instead of resolving symbols one-by-one, locate PE
560                    export directories -- they are sorted by symbol
561                    name -- and merge them, at one pass, with sorted
562                    list of required symbols (the best time to sort the
563                    latter list is during Genesis -- that's why I don't
564                    proceed with memory copying, qsort() and merge
565                    right here)). */
566 
567                 for (j=0; j<nlibrary; ++j)
568                 {
569                     if(check_duplicates[j] == hmodule)
570                         break;
571                 }
572                 if (j<nlibrary) continue; /* duplicate => skip it in
573                                            * outer loop */
574 
575                 check_duplicates[nlibrary] = hmodule;
576                 if (opt_store_handles) {
577                     opt_store_handles[nlibrary] = hmodule;
578                 }
579                 if (opt_store_names) {
580                     opt_store_names[nlibrary] = (const char *)
581                         (base + image_import_descriptor->Name);
582                 }
583                 odxprint(runtime_link, "DLL detection: %u, base %p: %s",
584                          nlibrary, hmodule,
585                          (char*)(base + image_import_descriptor->Name));
586                 ++ nlibrary;
587             }
588         }
589         return nlibrary;
590     }
591 }
592 
593 static u32 buildTimeImageCount = 0;
594 static void* buildTimeImages[16];
595 
596 /* Resolve symbols against the executable and its build-time dependencies */
os_dlsym_default(char * name)597 void* os_dlsym_default(char* name)
598 {
599     unsigned int i;
600     void* result = 0;
601     if (buildTimeImageCount == 0) {
602         buildTimeImageCount =
603             1 + os_get_build_time_shared_libraries(15u,
604             NULL, 1+(void**)buildTimeImages, NULL);
605     }
606     for (i = 0; i<buildTimeImageCount && (!result); ++i) {
607         result = GetProcAddress(buildTimeImages[i], name);
608     }
609     return result;
610 }
611 
612 #endif /* SB_DYNAMIC_CORE */
613 
614 #if defined(LISP_FEATURE_SB_THREAD)
615 /* We want to get a slot in TIB that (1) is available at constant
616    offset, (2) is our private property, so libraries wouldn't legally
617    override it, (3) contains something predefined for threads created
618    out of our sight.
619 
620    Low 64 TLS slots are adressable directly, starting with
621    FS:[#xE10]. When SBCL runtime is initialized, some of the low slots
622    may be already in use by its prerequisite DLLs, as DllMain()s and
623    TLS callbacks have been called already. But slot 63 is unlikely to
624    be reached at this point: one slot per DLL that needs it is the
625    common practice, and many system DLLs use predefined TIB-based
626    areas outside conventional TLS storage and don't need TLS slots.
627    With our current dependencies, even slot 2 is observed to be free
628    (as of WinXP and wine).
629 
630    Now we'll call TlsAlloc() repeatedly until slot 63 is officially
631    assigned to us, then TlsFree() all other slots for normal use. TLS
632    slot 63, alias FS:[#.(+ #xE10 (* 4 63))], now belongs to us.
633 
634    To summarize, let's list the assumptions we make:
635 
636    - TIB, which is FS segment base, contains first 64 TLS slots at the
637    offset #xE10 (i.e. TIB layout compatibility);
638    - TLS slots are allocated from lower to higher ones;
639    - All libraries together with CRT startup have not requested 64
640    slots yet.
641 
642    All these assumptions together don't seem to be less warranted than
643    the availability of TIB arbitrary data slot for our use. There are
644    some more reasons to prefer slot 63 over TIB arbitrary data: (1) if
645    our assumptions for slot 63 are violated, it will be detected at
646    startup instead of causing some system-specific unreproducible
647    problems afterwards, depending on OS and loaded foreign libraries;
648    (2) if getting slot 63 reliably with our current approach will
649    become impossible for some future Windows version, we can add TLS
650    callback directory to SBCL binary; main image TLS callback is
651    started before _any_ TLS slot is allocated by libraries, and
652    some C compiler vendors rely on this fact. */
653 
os_preinit()654 void os_preinit()
655 {
656 #ifdef LISP_FEATURE_X86
657     DWORD slots[TLS_MINIMUM_AVAILABLE];
658     DWORD key;
659     int n_slots = 0, i;
660     for (i=0; i<TLS_MINIMUM_AVAILABLE; ++i) {
661         key = TlsAlloc();
662         if (key == OUR_TLS_INDEX) {
663             if (TlsGetValue(key)!=NULL)
664                 lose("TLS slot assertion failed: fresh slot value is not NULL");
665             TlsSetValue(OUR_TLS_INDEX, (void*)(intptr_t)0xFEEDBAC4);
666             if ((intptr_t)(void*)arch_os_get_current_thread()!=(intptr_t)0xFEEDBAC4)
667                 lose("TLS slot assertion failed: TIB layout change detected");
668             TlsSetValue(OUR_TLS_INDEX, NULL);
669             break;
670         }
671         slots[n_slots++]=key;
672     }
673     for (i=0; i<n_slots; ++i) {
674         TlsFree(slots[i]);
675     }
676     if (key!=OUR_TLS_INDEX) {
677         lose("TLS slot assertion failed: slot 63 is unavailable "
678              "(last TlsAlloc() returned %u)",key);
679     }
680 #endif
681 }
682 #endif  /* LISP_FEATURE_SB_THREAD */
683 
684 
685 #ifdef LISP_FEATURE_X86_64
686 /* Windows has 32-bit 'longs', so printf...%lX (and other %l patterns) doesn't
687  * work well with address-sized values, like it's done all over the place in
688  * SBCL. And msvcrt uses I64, not LL, for printing long longs.
689  *
690  * I've already had enough search/replace with longs/words/intptr_t for today,
691  * so I prefer to solve this problem with a format string translator. */
692 
693 /* There is (will be) defines for printf and friends. */
694 
translating_vfprintf(FILE * stream,const char * fmt,va_list args)695 static int translating_vfprintf(FILE*stream, const char *fmt, va_list args)
696 {
697     char translated[1024];
698     int i=0, delta = 0;
699 
700     while (fmt[i-delta] && i<sizeof(translated)-1) {
701         if((fmt[i-delta]=='%')&&
702            (fmt[i-delta+1]=='l')) {
703             translated[i++]='%';
704             translated[i++]='I';
705             translated[i++]='6';
706             translated[i++]='4';
707             delta += 2;
708         } else {
709             translated[i]=fmt[i-delta];
710             ++i;
711         }
712     }
713     translated[i++]=0;
714     return vfprintf(stream,translated,args);
715 }
716 
printf(const char * fmt,...)717 int printf(const char*fmt,...)
718 {
719     va_list args;
720     va_start(args,fmt);
721     return translating_vfprintf(stdout,fmt,args);
722 }
fprintf(FILE * stream,const char * fmt,...)723 int fprintf(FILE*stream,const char*fmt,...)
724 {
725     va_list args;
726     va_start(args,fmt);
727     return translating_vfprintf(stream,fmt,args);
728 }
729 
730 #endif
731 
732 int os_number_of_processors = 1;
733 
734 BOOL WINAPI CancelIoEx(HANDLE handle, LPOVERLAPPED overlapped);
735 typeof(CancelIoEx) *ptr_CancelIoEx;
736 BOOL WINAPI CancelSynchronousIo(HANDLE threadHandle);
typeof(CancelSynchronousIo)737 typeof(CancelSynchronousIo) *ptr_CancelSynchronousIo;
738 
739 #define RESOLVE(hmodule,fn)                     \
740     do {                                        \
741         ptr_##fn = (typeof(ptr_##fn))           \
742             GetProcAddress(hmodule,#fn);        \
743     } while (0)
744 
745 static void resolve_optional_imports()
746 {
747     HMODULE kernel32 = GetModuleHandleA("kernel32");
748     if (kernel32) {
749         RESOLVE(kernel32,CancelIoEx);
750         RESOLVE(kernel32,CancelSynchronousIo);
751     }
752 }
753 
754 #undef RESOLVE
755 
win32_get_module_handle_by_address(os_vm_address_t addr)756 intptr_t win32_get_module_handle_by_address(os_vm_address_t addr)
757 {
758     HMODULE result = 0;
759     /* So apparently we could use VirtualQuery instead of
760      * GetModuleHandleEx if we wanted to support pre-XP, pre-2003
761      * versions of Windows (i.e. Windows 2000).  I've opted against such
762      * special-casing. :-).  --DFL */
763     return (intptr_t)(GetModuleHandleEx(
764                           GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
765                           GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
766                           (LPCSTR)addr, &result)
767                       ? result : 0);
768 }
769 
os_init(char * argv[],char * envp[])770 void os_init(char *argv[], char *envp[])
771 {
772     SYSTEM_INFO system_info;
773     GetSystemInfo(&system_info);
774     os_vm_page_size = system_info.dwPageSize > BACKEND_PAGE_BYTES?
775         system_info.dwPageSize : BACKEND_PAGE_BYTES;
776 #if defined(LISP_FEATURE_X86)
777     fast_bzero_pointer = fast_bzero_detect;
778 #endif
779     os_number_of_processors = system_info.dwNumberOfProcessors;
780 
781     base_seh_frame = get_seh_frame();
782 
783     resolve_optional_imports();
784     runtime_module_handle = (HMODULE)win32_get_module_handle_by_address(&runtime_module_handle);
785 }
786 
local_thread_stack_address_p(os_vm_address_t address)787 static inline boolean local_thread_stack_address_p(os_vm_address_t address)
788 {
789     return this_thread &&
790         (((((u64)address >= (u64)this_thread->os_address) &&
791            ((u64)address < ((u64)this_thread)-THREAD_CSP_PAGE_SIZE))||
792           (((u64)address >= (u64)this_thread->control_stack_start)&&
793            ((u64)address < (u64)this_thread->control_stack_end))));
794 }
795 
796 /*
797  * So we have three fun scenarios here.
798  *
799  * First, we could be being called to reserve the memory areas
800  * during initialization (prior to loading the core file).
801  *
802  * Second, we could be being called by the GC to commit a page
803  * that has just been decommitted (for easy zero-fill).
804  *
805  * Third, we could be being called by create_thread_struct()
806  * in order to create the sundry and various stacks.
807  *
808  * The third case is easy to pick out because it passes an
809  * addr of 0.
810  *
811  * The second case is easy to pick out because it will be for
812  * a range of memory that is MEM_RESERVE rather than MEM_FREE.
813  *
814  * The second case is also an easy implement, because we leave
815  * the memory as reserved (since we do lazy commits).
816  */
817 
818 os_vm_address_t
os_validate(os_vm_address_t addr,os_vm_size_t len)819 os_validate(os_vm_address_t addr, os_vm_size_t len)
820 {
821     MEMORY_BASIC_INFORMATION mem_info;
822 
823     if (!addr) {
824         /* the simple case first */
825         return
826             AVERLAX(VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE));
827     }
828 
829     if (!AVERLAX(VirtualQuery(addr, &mem_info, sizeof mem_info)))
830         return 0;
831 
832     if ((mem_info.State == MEM_RESERVE) && (mem_info.RegionSize >=len)) {
833       /* It would be correct to return here. However, support for Wine
834        * is beneficial, and Wine has a strange behavior in this
835        * department. It reports all memory below KERNEL32.DLL as
836        * reserved, but disallows MEM_COMMIT.
837        *
838        * Let's work around it: reserve the region we need for a second
839        * time. The second reservation is documented to fail on normal NT
840        * family, but it will succeed on Wine if this region is
841        * actually free.
842        */
843       VirtualAlloc(addr, len, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
844       /* If it is wine, the second call has succeded, and now the region
845        * is really reserved. */
846       return addr;
847     }
848 
849     if (mem_info.State == MEM_RESERVE) {
850         fprintf(stderr, "validation of reserved space too short.\n");
851         fflush(stderr);
852         /* Oddly, we do not treat this assertion as fatal; hence also the
853          * provision for MEM_RESERVE in the following code, I suppose: */
854     }
855 
856     if (!AVERLAX(VirtualAlloc(addr, len, (mem_info.State == MEM_RESERVE)?
857                               MEM_COMMIT: MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
858         return 0;
859 
860     return addr;
861 }
862 
863 /*
864  * For os_invalidate(), we merely decommit the memory rather than
865  * freeing the address space. This loses when freeing per-thread
866  * data and related memory since it leaks address space.
867  *
868  * So far the original comment (author unknown).  It used to continue as
869  * follows:
870  *
871  *   It's not too lossy, however, since the two scenarios I'm aware of
872  *   are fd-stream buffers, which are pooled rather than torched, and
873  *   thread information, which I hope to pool (since windows creates
874  *   threads at its own whim, and we probably want to be able to have
875  *   them callback without funky magic on the part of the user, and
876  *   full-on thread allocation is fairly heavyweight).
877  *
878  * But: As it turns out, we are no longer content with decommitting
879  * without freeing, and have now grown a second function
880  * os_invalidate_free(), sort of a really_os_invalidate().
881  *
882  * As discussed on #lisp, this is not a satisfactory solution, and probably
883  * ought to be rectified in the following way:
884  *
885  *  - Any cases currently going through the non-freeing version of
886  *    os_invalidate() are ultimately meant for zero-filling applications.
887  *    Replace those use cases with an os_revalidate_bzero() or similarly
888  *    named function, which explicitly takes care of that aspect of
889  *    the semantics.
890  *
891  *  - The remaining uses of os_invalidate should actually free, and once
892  *    the above is implemented, we can rename os_invalidate_free back to
893  *    just os_invalidate().
894  *
895  * So far the new plan, as yet unimplemented. -- DFL
896  */
897 
898 void
os_invalidate(os_vm_address_t addr,os_vm_size_t len)899 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
900 {
901     AVERLAX(VirtualFree(addr, len, MEM_DECOMMIT));
902 }
903 
904 void
os_invalidate_free(os_vm_address_t addr,os_vm_size_t len)905 os_invalidate_free(os_vm_address_t addr, os_vm_size_t len)
906 {
907     AVERLAX(VirtualFree(addr, 0, MEM_RELEASE));
908 }
909 
910 void
os_invalidate_free_by_any_address(os_vm_address_t addr,os_vm_size_t len)911 os_invalidate_free_by_any_address(os_vm_address_t addr, os_vm_size_t len)
912 {
913     MEMORY_BASIC_INFORMATION minfo;
914     AVERLAX(VirtualQuery(addr, &minfo, sizeof minfo));
915     AVERLAX(minfo.AllocationBase);
916     AVERLAX(VirtualFree(minfo.AllocationBase, 0, MEM_RELEASE));
917 }
918 
919 /* os_validate doesn't commit, i.e. doesn't actually "validate" in the
920  * sense that we could start using the space afterwards.  Usually it's
921  * os_map or Lisp code that will run into that, in which case we recommit
922  * elsewhere in this file.  For cases where C wants to write into newly
923  * os_validate()d memory, it needs to commit it explicitly first:
924  */
925 os_vm_address_t
os_validate_recommit(os_vm_address_t addr,os_vm_size_t len)926 os_validate_recommit(os_vm_address_t addr, os_vm_size_t len)
927 {
928     return
929         AVERLAX(VirtualAlloc(addr, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE));
930 }
931 
932 /*
933  * os_map() is called to map a chunk of the core file into memory.
934  *
935  * Unfortunately, Windows semantics completely screws this up, so
936  * we just add backing store from the swapfile to where the chunk
937  * goes and read it up like a normal file. We could consider using
938  * a lazy read (demand page) setup, but that would mean keeping an
939  * open file pointer for the core indefinately (and be one more
940  * thing to maintain).
941  */
942 
943 os_vm_address_t
os_map(int fd,int offset,os_vm_address_t addr,os_vm_size_t len)944 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
945 {
946     os_vm_size_t count;
947 
948     AVER(VirtualAlloc(addr, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE)||
949          VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT,
950                       PAGE_EXECUTE_READWRITE));
951 
952     CRT_AVER_NONNEGATIVE(lseek(fd, offset, SEEK_SET));
953 
954     count = read(fd, addr, len);
955     CRT_AVER( count == len );
956 
957     return addr;
958 }
959 
960 static DWORD os_protect_modes[8] = {
961     PAGE_NOACCESS,
962     PAGE_READONLY,
963     PAGE_READWRITE,
964     PAGE_READWRITE,
965     PAGE_EXECUTE,
966     PAGE_EXECUTE_READ,
967     PAGE_EXECUTE_READWRITE,
968     PAGE_EXECUTE_READWRITE,
969 };
970 
971 void
os_protect(os_vm_address_t address,os_vm_size_t length,os_vm_prot_t prot)972 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
973 {
974     DWORD old_prot;
975 
976     DWORD new_prot = os_protect_modes[prot];
977     AVER(VirtualProtect(address, length, new_prot, &old_prot)||
978          (VirtualAlloc(address, length, MEM_COMMIT, new_prot) &&
979           VirtualProtect(address, length, new_prot, &old_prot)));
980     odxprint(misc,"Protecting %p + %p vmaccess %d "
981              "newprot %08x oldprot %08x",
982              address,length,prot,new_prot,old_prot);
983 }
984 
985 /* FIXME: Now that FOO_END, rather than FOO_SIZE, is the fundamental
986  * description of a space, we could probably punt this and just do
987  * (FOO_START <= x && x < FOO_END) everywhere it's called. */
988 static boolean
in_range_p(os_vm_address_t a,lispobj sbeg,size_t slen)989 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
990 {
991     char* beg = (char*)((uword_t)sbeg);
992     char* end = (char*)((uword_t)sbeg) + slen;
993     char* adr = (char*)a;
994     return (adr >= beg && adr < end);
995 }
996 
997 boolean
is_linkage_table_addr(os_vm_address_t addr)998 is_linkage_table_addr(os_vm_address_t addr)
999 {
1000     return in_range_p(addr, LINKAGE_TABLE_SPACE_START, LINKAGE_TABLE_SPACE_SIZE);
1001 }
1002 
1003 static boolean is_some_thread_local_addr(os_vm_address_t addr);
1004 
1005 boolean
is_valid_lisp_addr(os_vm_address_t addr)1006 is_valid_lisp_addr(os_vm_address_t addr)
1007 {
1008     if(in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE) ||
1009        in_range_p(addr, STATIC_SPACE_START   , STATIC_SPACE_SIZE) ||
1010        in_range_p(addr, DYNAMIC_SPACE_START  , dynamic_space_size) ||
1011        is_some_thread_local_addr(addr))
1012         return 1;
1013     return 0;
1014 }
1015 
1016 /* test if an address is within thread-local space */
1017 static boolean
is_thread_local_addr(struct thread * th,os_vm_address_t addr)1018 is_thread_local_addr(struct thread* th, os_vm_address_t addr)
1019 {
1020     /* Assuming that this is correct, it would warrant further comment,
1021      * I think.  Based on what our call site is doing, we have been
1022      * tasked to check for the address of a lisp object; not merely any
1023      * foreign address within the thread's area.  Indeed, this used to
1024      * be a check for control and binding stack only, rather than the
1025      * full thread "struct".  So shouldn't the THREAD_STRUCT_SIZE rather
1026      * be (thread_control_stack_size+BINDING_STACK_SIZE) instead?  That
1027      * would also do away with the LISP_FEATURE_SB_THREAD case.  Or does
1028      * it simply not matter?  --DFL */
1029     ptrdiff_t diff = ((char*)th->os_address)-(char*)addr;
1030     return diff > (ptrdiff_t)0 && diff < (ptrdiff_t)THREAD_STRUCT_SIZE
1031 #ifdef LISP_FEATURE_SB_THREAD
1032         && addr != (os_vm_address_t) th->csp_around_foreign_call
1033 #endif
1034         ;
1035 }
1036 
1037 static boolean
is_some_thread_local_addr(os_vm_address_t addr)1038 is_some_thread_local_addr(os_vm_address_t addr)
1039 {
1040     boolean result = 0;
1041 #ifdef LISP_FEATURE_SB_THREAD
1042     struct thread *th;
1043     pthread_mutex_lock(&all_threads_lock);
1044     for_each_thread(th) {
1045         if(is_thread_local_addr(th,addr)) {
1046             result = 1;
1047             break;
1048         }
1049     }
1050     pthread_mutex_unlock(&all_threads_lock);
1051 #endif
1052     return result;
1053 }
1054 
1055 
1056 /* A tiny bit of interrupt.c state we want our paws on. */
1057 extern boolean internal_errors_enabled;
1058 
1059 extern void exception_handler_wrapper();
1060 
1061 void
c_level_backtrace(const char * header,int depth)1062 c_level_backtrace(const char* header, int depth)
1063 {
1064     void* frame;
1065     int n = 0;
1066     void** lastseh;
1067 
1068     for (lastseh = get_seh_frame(); lastseh && (lastseh!=(void*)-1);
1069          lastseh = *lastseh);
1070 
1071     fprintf(stderr, "Backtrace: %s (thread %p)\n", header, this_thread);
1072     for (frame = __builtin_frame_address(0); frame; frame=*(void**)frame)
1073     {
1074         if ((n++)>depth)
1075             return;
1076         fprintf(stderr, "[#%02d]: ebp = %p, ret = %p\n",n,
1077                 frame, ((void**)frame)[1]);
1078     }
1079 }
1080 
1081 #ifdef LISP_FEATURE_X86
1082 #define voidreg(ctxptr,name) ((void*)((ctxptr)->E##name))
1083 #else
1084 #define voidreg(ctxptr,name) ((void*)((ctxptr)->R##name))
1085 #endif
1086 
1087 
1088 static int
handle_single_step(os_context_t * ctx)1089 handle_single_step(os_context_t *ctx)
1090 {
1091     if (!single_stepping)
1092         return -1;
1093 
1094     /* We are doing a displaced instruction. At least function
1095      * end breakpoints use this. */
1096     restore_breakpoint_from_single_step(ctx);
1097 
1098     return 0;
1099 }
1100 
1101 #ifdef LISP_FEATURE_UD2_BREAKPOINTS
1102 #define SBCL_EXCEPTION_BREAKPOINT EXCEPTION_ILLEGAL_INSTRUCTION
1103 #define TRAP_CODE_WIDTH 2
1104 #else
1105 #define SBCL_EXCEPTION_BREAKPOINT EXCEPTION_BREAKPOINT
1106 #define TRAP_CODE_WIDTH 1
1107 #endif
1108 
1109 static int
handle_breakpoint_trap(os_context_t * ctx,struct thread * self)1110 handle_breakpoint_trap(os_context_t *ctx, struct thread* self)
1111 {
1112 #ifdef LISP_FEATURE_UD2_BREAKPOINTS
1113     if (((unsigned short *)*os_context_pc_addr(ctx))[0] != 0x0b0f)
1114         return -1;
1115 #endif
1116 
1117     /* Unlike some other operating systems, Win32 leaves EIP
1118      * pointing to the breakpoint instruction. */
1119     (*os_context_pc_addr(ctx)) += TRAP_CODE_WIDTH;
1120 
1121     /* Now EIP points just after the INT3 byte and aims at the
1122      * 'kind' value (eg trap_Cerror). */
1123     unsigned trap = *(unsigned char *)(*os_context_pc_addr(ctx));
1124 
1125 #ifdef LISP_FEATURE_SB_THREAD
1126     /* Before any other trap handler: gc_safepoint ensures that
1127        inner alloc_sap for passing the context won't trap on
1128        pseudo-atomic. */
1129     /* Now that there is no alloc_sap, I don't know what happens here. */
1130     if (trap == trap_PendingInterrupt) {
1131         /* Done everything needed for this trap, except EIP
1132            adjustment */
1133         arch_skip_instruction(ctx);
1134         thread_interrupted(ctx);
1135         return 0;
1136     }
1137 #endif
1138 
1139     /* This is just for info in case the monitor wants to print an
1140      * approximation. */
1141     access_control_stack_pointer(self) =
1142         (lispobj *)*os_context_sp_addr(ctx);
1143 
1144     WITH_GC_AT_SAFEPOINTS_ONLY() {
1145 #if defined(LISP_FEATURE_SB_THREAD)
1146         block_blockable_signals(&ctx->sigmask);
1147 #endif
1148         handle_trap(ctx, trap);
1149 #if defined(LISP_FEATURE_SB_THREAD)
1150         thread_sigmask(SIG_SETMASK,&ctx->sigmask,NULL);
1151 #endif
1152     }
1153 
1154     /* Done, we're good to go! */
1155     return 0;
1156 }
1157 
1158 static int
handle_access_violation(os_context_t * ctx,EXCEPTION_RECORD * exception_record,void * fault_address,struct thread * self)1159 handle_access_violation(os_context_t *ctx,
1160                         EXCEPTION_RECORD *exception_record,
1161                         void *fault_address,
1162                         struct thread* self)
1163 {
1164     CONTEXT *win32_context = ctx->win32_context;
1165 
1166 #if defined(LISP_FEATURE_X86)
1167     odxprint(pagefaults,
1168              "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
1169              "Addr %p Access %d\n",
1170              self,
1171              win32_context->Eip,
1172              win32_context->Esp,
1173              win32_context->Esi,
1174              win32_context->Edi,
1175              fault_address,
1176              exception_record->ExceptionInformation[0]);
1177 #else
1178     odxprint(pagefaults,
1179              "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
1180              "Addr %p Access %d\n",
1181              self,
1182              win32_context->Rip,
1183              win32_context->Rsp,
1184              win32_context->Rsi,
1185              win32_context->Rdi,
1186              fault_address,
1187              exception_record->ExceptionInformation[0]);
1188 #endif
1189 
1190     /* Stack: This case takes care of our various stack exhaustion
1191      * protect pages (with the notable exception of the control stack!). */
1192     if (self && local_thread_stack_address_p(fault_address)) {
1193         if (handle_guard_page_triggered(ctx, fault_address))
1194             return 0; /* gc safety? */
1195         goto try_recommit;
1196     }
1197 
1198     /* Safepoint pages */
1199 #ifdef LISP_FEATURE_SB_THREAD
1200     if (fault_address == (void *) GC_SAFEPOINT_PAGE_ADDR) {
1201         thread_in_lisp_raised(ctx);
1202         return 0;
1203     }
1204 
1205     if ((((u64)fault_address) == ((u64)self->csp_around_foreign_call))){
1206         thread_in_safety_transition(ctx);
1207         return 0;
1208     }
1209 #endif
1210 
1211     /* dynamic space */
1212     page_index_t index = find_page_index(fault_address);
1213     if (index != -1) {
1214         /*
1215          * Now, if the page is supposedly write-protected and this
1216          * is a write, tell the gc that it's been hit.
1217          */
1218         if (page_table[index].write_protected) {
1219             gencgc_handle_wp_violation(fault_address);
1220         } else {
1221             AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
1222                               os_vm_page_size,
1223                               MEM_COMMIT, PAGE_EXECUTE_READWRITE));
1224         }
1225         return 0;
1226     }
1227 
1228     if (fault_address == undefined_alien_address)
1229         return -1;
1230 
1231     /* linkage table or a "valid_lisp_addr" outside of dynamic space (?) */
1232     if (is_linkage_table_addr(fault_address)
1233         || is_valid_lisp_addr(fault_address))
1234         goto try_recommit;
1235 
1236     return -1;
1237 
1238 try_recommit:
1239     /* First use of a new page, lets get some memory for it. */
1240 
1241 #if defined(LISP_FEATURE_X86)
1242     AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
1243                       os_vm_page_size,
1244                       MEM_COMMIT, PAGE_EXECUTE_READWRITE)
1245          ||(fprintf(stderr,"Unable to recommit addr %p eip 0x%08lx\n",
1246                     fault_address, win32_context->Eip) &&
1247             (c_level_backtrace("BT",5),
1248              fake_foreign_function_call(ctx),
1249              lose("Lispy backtrace"),
1250              0)));
1251 #else
1252     AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
1253                       os_vm_page_size,
1254                       MEM_COMMIT, PAGE_EXECUTE_READWRITE)
1255          ||(fprintf(stderr,"Unable to recommit addr %p eip %p\n",
1256                     fault_address, (void*)win32_context->Rip) &&
1257             (c_level_backtrace("BT",5),
1258              fake_foreign_function_call(ctx),
1259              lose("Lispy backtrace"),
1260              0)));
1261 #endif
1262 
1263     return 0;
1264 }
1265 
1266 static void
signal_internal_error_or_lose(os_context_t * ctx,EXCEPTION_RECORD * exception_record,void * fault_address)1267 signal_internal_error_or_lose(os_context_t *ctx,
1268                               EXCEPTION_RECORD *exception_record,
1269                               void *fault_address)
1270 {
1271     /*
1272      * If we fall through to here then we need to either forward
1273      * the exception to the lisp-side exception handler if it's
1274      * set up, or drop to LDB.
1275      */
1276 
1277     if (internal_errors_enabled) {
1278 
1279         asm("fnclex");
1280         /* We're making the somewhat arbitrary decision that having
1281          * internal errors enabled means that lisp has sufficient
1282          * marbles to be able to handle exceptions, but exceptions
1283          * aren't supposed to happen during cold init or reinit
1284          * anyway. */
1285 
1286 #if defined(LISP_FEATURE_SB_THREAD)
1287         block_blockable_signals(&ctx->sigmask);
1288 #endif
1289         fake_foreign_function_call(ctx);
1290 
1291         WITH_GC_AT_SAFEPOINTS_ONLY() {
1292             DX_ALLOC_SAP(context_sap, ctx);
1293             DX_ALLOC_SAP(exception_record_sap, exception_record);
1294 
1295 #if defined(LISP_FEATURE_SB_THREAD)
1296             thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
1297 #endif
1298 
1299             /* The exception system doesn't automatically clear pending
1300              * exceptions, so we lose as soon as we execute any FP
1301              * instruction unless we do this first. */
1302             /* Call into lisp to handle things. */
1303             funcall2(StaticSymbolFunction(HANDLE_WIN32_EXCEPTION),
1304                      context_sap,
1305                      exception_record_sap);
1306         }
1307         /* If Lisp doesn't nlx, we need to put things back. */
1308         undo_fake_foreign_function_call(ctx);
1309 #if defined(LISP_FEATURE_SB_THREAD)
1310         thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
1311 #endif
1312         /* FIXME: HANDLE-WIN32-EXCEPTION should be allowed to decline */
1313         return;
1314     }
1315 
1316     fprintf(stderr, "Exception Code: %p.\n",
1317             (void*)(intptr_t)exception_record->ExceptionCode);
1318     fprintf(stderr, "Faulting IP: %p.\n",
1319             (void*)(intptr_t)exception_record->ExceptionAddress);
1320     if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
1321         MEMORY_BASIC_INFORMATION mem_info;
1322 
1323         if (VirtualQuery(fault_address, &mem_info, sizeof mem_info)) {
1324             fprintf(stderr, "page status: 0x%lx.\n", mem_info.State);
1325         }
1326 
1327         fprintf(stderr, "Was writing: %p, where: %p.\n",
1328                 (void*)exception_record->ExceptionInformation[0],
1329                 fault_address);
1330     }
1331 
1332     fflush(stderr);
1333 
1334     fake_foreign_function_call(ctx);
1335     lose("Exception too early in cold init, cannot continue.");
1336 }
1337 
1338 /*
1339  * A good explanation of the exception handling semantics is
1340  *   http://win32assembly.online.fr/Exceptionhandling.html (possibly defunct)
1341  * or:
1342  *   http://www.microsoft.com/msj/0197/exception/exception.aspx
1343  */
1344 
1345 EXCEPTION_DISPOSITION
handle_exception(EXCEPTION_RECORD * exception_record,struct lisp_exception_frame * exception_frame,CONTEXT * win32_context,void * dispatcher_context)1346 handle_exception(EXCEPTION_RECORD *exception_record,
1347                  struct lisp_exception_frame *exception_frame,
1348                  CONTEXT *win32_context,
1349                  void *dispatcher_context)
1350 {
1351     if (!win32_context)
1352         /* Not certain why this should be possible, but let's be safe... */
1353         return ExceptionContinueSearch;
1354 
1355     if (exception_record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) {
1356         /* If we're being unwound, be graceful about it. */
1357 
1358         /* Undo any dynamic bindings. */
1359         unbind_to_here(exception_frame->bindstack_pointer,
1360                        arch_os_get_current_thread());
1361         return ExceptionContinueSearch;
1362     }
1363 
1364     DWORD lastError = GetLastError();
1365     DWORD lastErrno = errno;
1366     DWORD code = exception_record->ExceptionCode;
1367     struct thread* self = arch_os_get_current_thread();
1368 
1369     os_context_t context, *ctx = &context;
1370     context.win32_context = win32_context;
1371 #if defined(LISP_FEATURE_SB_THREAD)
1372     context.sigmask = self ? self->os_thread->blocked_signal_set : 0;
1373 #endif
1374 
1375     os_context_register_t oldbp = NULL;
1376     if (self) {
1377         oldbp = self ? self->carried_base_pointer : 0;
1378         self->carried_base_pointer
1379             = (os_context_register_t) voidreg(win32_context, bp);
1380     }
1381 
1382     /* For EXCEPTION_ACCESS_VIOLATION only. */
1383     void *fault_address = (void *)exception_record->ExceptionInformation[1];
1384 
1385     odxprint(seh,
1386              "SEH: rec %p, ctxptr %p, rip %p, fault %p\n"
1387              "... code %p, rcx %p, fp-tags %p\n\n",
1388              exception_record,
1389              win32_context,
1390              voidreg(win32_context,ip),
1391              fault_address,
1392              (void*)(intptr_t)code,
1393              voidreg(win32_context,cx),
1394              win32_context->FloatSave.TagWord);
1395 
1396     /* This function had become unwieldy.  Let's cut it down into
1397      * pieces based on the different exception codes.  Each exception
1398      * code handler gets the chance to decline by returning non-zero if it
1399      * isn't happy: */
1400 
1401     int rc;
1402     switch (code) {
1403     case EXCEPTION_ACCESS_VIOLATION:
1404         rc = handle_access_violation(
1405             ctx, exception_record, fault_address, self);
1406         break;
1407 
1408     case SBCL_EXCEPTION_BREAKPOINT:
1409         rc = handle_breakpoint_trap(ctx, self);
1410         break;
1411 
1412     case EXCEPTION_SINGLE_STEP:
1413         rc = handle_single_step(ctx);
1414         break;
1415 
1416     default:
1417         rc = -1;
1418     }
1419 
1420     if (rc)
1421         /* All else failed, drop through to the lisp-side exception handler. */
1422         signal_internal_error_or_lose(ctx, exception_record, fault_address);
1423 
1424     if (self)
1425         self->carried_base_pointer = oldbp;
1426 
1427     errno = lastErrno;
1428     SetLastError(lastError);
1429     return ExceptionContinueExecution;
1430 }
1431 
1432 #ifdef LISP_FEATURE_X86_64
1433 
1434 #define RESTORING_ERRNO()                                       \
1435     int sbcl__lastErrno = errno;                                \
1436     RUN_BODY_ONCE(restoring_errno, errno = sbcl__lastErrno)
1437 
1438 LONG
veh(EXCEPTION_POINTERS * ep)1439 veh(EXCEPTION_POINTERS *ep)
1440 {
1441     EXCEPTION_DISPOSITION disp;
1442 
1443     RESTORING_ERRNO() {
1444         if (!pthread_self())
1445             return EXCEPTION_CONTINUE_SEARCH;
1446     }
1447 
1448     disp = handle_exception(ep->ExceptionRecord,0,ep->ContextRecord,0);
1449 
1450     switch (disp)
1451     {
1452     case ExceptionContinueExecution:
1453         return EXCEPTION_CONTINUE_EXECUTION;
1454     case ExceptionContinueSearch:
1455         return EXCEPTION_CONTINUE_SEARCH;
1456     default:
1457         fprintf(stderr,"Exception handler is mad\n");
1458         ExitProcess(0);
1459     }
1460 }
1461 #endif
1462 
1463 os_context_register_t
carry_frame_pointer(os_context_register_t default_value)1464 carry_frame_pointer(os_context_register_t default_value)
1465 {
1466     struct thread* self = arch_os_get_current_thread();
1467     os_context_register_t bp = self->carried_base_pointer;
1468     return bp ? bp : default_value;
1469 }
1470 
1471 void
wos_install_interrupt_handlers(struct lisp_exception_frame * handler)1472 wos_install_interrupt_handlers(struct lisp_exception_frame *handler)
1473 {
1474 #ifdef LISP_FEATURE_X86
1475     handler->next_frame = get_seh_frame();
1476     handler->handler = (void*)exception_handler_wrapper;
1477     set_seh_frame(handler);
1478 #else
1479     static int once = 0;
1480     if (!once++)
1481         AddVectoredExceptionHandler(1,veh);
1482 #endif
1483 }
1484 
1485 /*
1486  * The stubs below are replacements for the windows versions,
1487  * which can -fail- when used in our memory spaces because they
1488  * validate the memory spaces they are passed in a way that
1489  * denies our exception handler a chance to run.
1490  */
1491 
memmove(void * dest,const void * src,size_t n)1492 void *memmove(void *dest, const void *src, size_t n)
1493 {
1494     if (dest < src) {
1495         int i;
1496         for (i = 0; i < n; i++) *(((char *)dest)+i) = *(((char *)src)+i);
1497     } else {
1498         while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1499     }
1500     return dest;
1501 }
1502 
memcpy(void * dest,const void * src,size_t n)1503 void *memcpy(void *dest, const void *src, size_t n)
1504 {
1505     while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1506     return dest;
1507 }
1508 
dirname(char * path)1509 char *dirname(char *path)
1510 {
1511     static char buf[PATH_MAX + 1];
1512     size_t pathlen = strlen(path);
1513     int i;
1514 
1515     if (pathlen >= sizeof(buf)) {
1516         lose("Pathname too long in dirname.\n");
1517         return NULL;
1518     }
1519 
1520     strcpy(buf, path);
1521     for (i = pathlen; i >= 0; --i) {
1522         if (buf[i] == '/' || buf[i] == '\\') {
1523             buf[i] = '\0';
1524             break;
1525         }
1526     }
1527 
1528     return buf;
1529 }
1530 
1531 // 0 - not a socket or other error, 1 - has input, 2 - has no input
1532 int
socket_input_available(HANDLE socket)1533 socket_input_available(HANDLE socket)
1534 {
1535     unsigned long count = 0, count_size = 0;
1536     int wsaErrno = GetLastError();
1537     int err = WSAIoctl((SOCKET)socket, FIONREAD, NULL, 0,
1538                        &count, sizeof(count), &count_size, NULL, NULL);
1539 
1540     int ret;
1541 
1542     if (err == 0) {
1543         ret = (count > 0) ? 1 : 2;
1544     } else
1545         ret = 0;
1546     SetLastError(wsaErrno);
1547     return ret;
1548 }
1549 
1550 /* Unofficial but widely used property of console handles: they have
1551    #b11 in two minor bits, opposed to other handles, that are
1552    machine-word-aligned. Properly emulated even on wine.
1553 
1554    Console handles are special in many aspects, e.g. they aren't NTDLL
1555    system handles: kernel32 redirects console operations to CSRSS
1556    requests. Using the hack below to distinguish console handles is
1557    justified, as it's the only method that won't hang during
1558    outstanding reads, won't try to lock NT kernel object (if there is
1559    one; console isn't), etc. */
1560 int
console_handle_p(HANDLE handle)1561 console_handle_p(HANDLE handle)
1562 {
1563     return (handle != NULL)&&
1564         (handle != INVALID_HANDLE_VALUE)&&
1565         ((((int)(intptr_t)handle)&3)==3);
1566 }
1567 
1568 /* Atomically mark current thread as (probably) doing synchronous I/O
1569  * on handle, if no cancellation is requested yet (and return TRUE),
1570  * otherwise clear thread's I/O cancellation flag and return false.
1571  */
1572 static
io_begin_interruptible(HANDLE handle)1573 boolean io_begin_interruptible(HANDLE handle)
1574 {
1575     /* No point in doing it unless OS supports cancellation from other
1576      * threads */
1577     if (!ptr_CancelIoEx)
1578         return 1;
1579 
1580     if (!__sync_bool_compare_and_swap(&this_thread->synchronous_io_handle_and_flag,
1581                                       0, handle)) {
1582         ResetEvent(this_thread->private_events.events[0]);
1583         this_thread->synchronous_io_handle_and_flag = 0;
1584         return 0;
1585     }
1586     return 1;
1587 }
1588 
1589 static pthread_mutex_t interrupt_io_lock = PTHREAD_MUTEX_INITIALIZER;
1590 
1591 /* Unmark current thread as (probably) doing synchronous I/O; if an
1592  * I/O cancellation was requested, postpone it until next
1593  * io_begin_interruptible */
1594 static void
io_end_interruptible(HANDLE handle)1595 io_end_interruptible(HANDLE handle)
1596 {
1597     if (!ptr_CancelIoEx)
1598         return;
1599     pthread_mutex_lock(&interrupt_io_lock);
1600     __sync_bool_compare_and_swap(&this_thread->synchronous_io_handle_and_flag,
1601                                  handle, 0);
1602     pthread_mutex_unlock(&interrupt_io_lock);
1603 }
1604 
1605 /* Documented limit for ReadConsole/WriteConsole is 64K bytes.
1606    Real limit observed on W2K-SP3 is somewhere in between 32KiB and 64Kib...
1607 */
1608 #define MAX_CONSOLE_TCHARS 16384
1609 
1610 int
win32_write_unicode_console(HANDLE handle,void * buf,int count)1611 win32_write_unicode_console(HANDLE handle, void * buf, int count)
1612 {
1613     DWORD written = 0;
1614     DWORD nchars;
1615     BOOL result;
1616     nchars = count>>1;
1617     if (nchars>MAX_CONSOLE_TCHARS) nchars = MAX_CONSOLE_TCHARS;
1618 
1619     if (!io_begin_interruptible(handle)) {
1620         errno = EINTR;
1621         return -1;
1622     }
1623     result = WriteConsoleW(handle,buf,nchars,&written,NULL);
1624     io_end_interruptible(handle);
1625 
1626     if (result) {
1627         if (!written) {
1628             errno = EINTR;
1629             return -1;
1630         } else {
1631             return 2*written;
1632         }
1633     } else {
1634         DWORD err = GetLastError();
1635         odxprint(io,"WriteConsole fails => %u\n", err);
1636         errno = (err==ERROR_OPERATION_ABORTED ? EINTR : EIO);
1637         return -1;
1638     }
1639 }
1640 
1641 /*
1642  * (AK writes:)
1643  *
1644  * It may be unobvious, but (probably) the most straightforward way of
1645  * providing some sane CL:LISTEN semantics for line-mode console
1646  * channel requires _dedicated input thread_.
1647  *
1648  * LISTEN should return true iff the next (READ-CHAR) won't have to
1649  * wait. As our console may be shared with another process, entirely
1650  * out of our control, looking at the events in PeekConsoleEvent
1651  * result (and searching for #\Return) doesn't cut it.
1652  *
1653  * We decided that console input thread must do something smarter than
1654  * a bare loop of continuous ReadConsoleW(). On Unix, user experience
1655  * with the terminal is entirely unaffected by the fact that some
1656  * process does (or doesn't) call read(); the situation on MS Windows
1657  * is different.
1658  *
1659  * Echo output and line editing present on MS Windows while some
1660  * process is waiting in ReadConsole(); otherwise all input events are
1661  * buffered. If our thread were calling ReadConsole() all the time, it
1662  * would feel like Unix cooked mode.
1663  *
1664  * But we don't write a Unix emulator here, even if it sometimes feels
1665  * like that; therefore preserving this aspect of console I/O seems a
1666  * good thing to us.
1667  *
1668  * LISTEN itself becomes trivial with dedicated input thread, but the
1669  * goal stated above -- provide `native' user experience with blocked
1670  * console -- don't play well with this trivial implementation.
1671  *
1672  * What's currently implemented is a compromise, looking as something
1673  * in between Unix cooked mode and Win32 line mode.
1674  *
1675  * 1. As long as no console I/O function is called (incl. CL:LISTEN),
1676  * console looks `blocked': no echo, no line editing.
1677  *
1678  * 2. (READ-CHAR), (READ-SEQUENCE) and other functions doing real
1679  * input result in the ReadConsole request (in a dedicated thread);
1680  *
1681  * 3. Once ReadConsole is called, it is not cancelled in the
1682  * middle. In line mode, it returns when <Enter> key is hit (or
1683  * something like that happens). Therefore, if line editing and echo
1684  * output had a chance to happen, console won't look `blocked' until
1685  * the line is entered (even if line input was triggered by
1686  * (READ-CHAR)).
1687  *
1688  * 4. LISTEN may request ReadConsole too (if no other thread is
1689  * reading the console and no data are queued). It's the only case
1690  * when the console becomes `unblocked' without any actual input
1691  * requested by Lisp code.  LISTEN check if there is at least one
1692  * input event in PeekConsole queue; unless there is such an event,
1693  * ReadConsole is not triggered by LISTEN.
1694  *
1695  * 5. Console-reading Lisp thread now may be interrupted immediately;
1696  * ReadConsole call itself, however, continues until the line is
1697  * entered.
1698  */
1699 
1700 struct {
1701     WCHAR buffer[MAX_CONSOLE_TCHARS];
1702     DWORD head, tail;
1703     pthread_mutex_t lock;
1704     pthread_cond_t cond_has_data;
1705     pthread_cond_t cond_has_client;
1706     pthread_t thread;
1707     boolean initialized;
1708     HANDLE handle;
1709     boolean in_progress;
1710 } ttyinput = {.lock = PTHREAD_MUTEX_INITIALIZER};
1711 
1712 static void*
tty_read_line_server()1713 tty_read_line_server()
1714 {
1715     pthread_mutex_lock(&ttyinput.lock);
1716     while (ttyinput.handle) {
1717         DWORD nchars;
1718         BOOL ok;
1719 
1720         while (!ttyinput.in_progress)
1721             pthread_cond_wait(&ttyinput.cond_has_client,&ttyinput.lock);
1722 
1723         pthread_mutex_unlock(&ttyinput.lock);
1724 
1725         ok = ReadConsoleW(ttyinput.handle,
1726                           &ttyinput.buffer[ttyinput.tail],
1727                           MAX_CONSOLE_TCHARS-ttyinput.tail,
1728                           &nchars,NULL);
1729 
1730         pthread_mutex_lock(&ttyinput.lock);
1731 
1732         if (ok) {
1733             ttyinput.tail += nchars;
1734             pthread_cond_broadcast(&ttyinput.cond_has_data);
1735         }
1736         ttyinput.in_progress = 0;
1737     }
1738     pthread_mutex_unlock(&ttyinput.lock);
1739     return NULL;
1740 }
1741 
1742 static boolean
tty_maybe_initialize_unlocked(HANDLE handle)1743 tty_maybe_initialize_unlocked(HANDLE handle)
1744 {
1745     if (!ttyinput.initialized) {
1746         if (!DuplicateHandle(GetCurrentProcess(),handle,
1747                              GetCurrentProcess(),&ttyinput.handle,
1748                              0,FALSE,DUPLICATE_SAME_ACCESS)) {
1749             return 0;
1750         }
1751         pthread_cond_init(&ttyinput.cond_has_data,NULL);
1752         pthread_cond_init(&ttyinput.cond_has_client,NULL);
1753         pthread_create(&ttyinput.thread,NULL,tty_read_line_server,NULL);
1754         ttyinput.initialized = 1;
1755     }
1756     return 1;
1757 }
1758 
1759 boolean
win32_tty_listen(HANDLE handle)1760 win32_tty_listen(HANDLE handle)
1761 {
1762     boolean result = 0;
1763     INPUT_RECORD ir;
1764     DWORD nevents;
1765     pthread_mutex_lock(&ttyinput.lock);
1766     if (!tty_maybe_initialize_unlocked(handle))
1767         result = 0;
1768 
1769     if (ttyinput.in_progress) {
1770         result = 0;
1771     } else {
1772         if (ttyinput.head != ttyinput.tail) {
1773             result = 1;
1774         } else {
1775             if (PeekConsoleInput(ttyinput.handle,&ir,1,&nevents) && nevents) {
1776                 ttyinput.in_progress = 1;
1777                 pthread_cond_broadcast(&ttyinput.cond_has_client);
1778             }
1779         }
1780     }
1781     pthread_mutex_unlock(&ttyinput.lock);
1782     return result;
1783 }
1784 
1785 static int
tty_read_line_client(HANDLE handle,void * buf,int count)1786 tty_read_line_client(HANDLE handle, void* buf, int count)
1787 {
1788     int result = 0;
1789     int nchars = count / sizeof(WCHAR);
1790     sigset_t pendset;
1791 
1792     if (!nchars)
1793         return 0;
1794     if (nchars>MAX_CONSOLE_TCHARS)
1795         nchars=MAX_CONSOLE_TCHARS;
1796 
1797     count = nchars*sizeof(WCHAR);
1798 
1799     pthread_mutex_lock(&ttyinput.lock);
1800 
1801     if (!tty_maybe_initialize_unlocked(handle)) {
1802         result = -1;
1803         errno = EIO;
1804         goto unlock;
1805     }
1806 
1807     while (!result) {
1808         while (ttyinput.head == ttyinput.tail) {
1809             if (!io_begin_interruptible(ttyinput.handle)) {
1810                 ttyinput.in_progress = 0;
1811                 result = -1;
1812                 errno = EINTR;
1813                 goto unlock;
1814             } else {
1815                 if (!ttyinput.in_progress) {
1816                     /* We are to wait */
1817                     ttyinput.in_progress=1;
1818                     /* wake console reader */
1819                     pthread_cond_broadcast(&ttyinput.cond_has_client);
1820                 }
1821                 pthread_cond_wait(&ttyinput.cond_has_data, &ttyinput.lock);
1822                 io_end_interruptible(ttyinput.handle);
1823             }
1824         }
1825         result = sizeof(WCHAR)*(ttyinput.tail-ttyinput.head);
1826         if (result > count) {
1827             result = count;
1828         }
1829         if (result) {
1830             if (result > 0) {
1831                 DWORD nch,offset = 0;
1832                 LPWSTR ubuf = buf;
1833 
1834                 memcpy(buf,&ttyinput.buffer[ttyinput.head],count);
1835                 ttyinput.head += (result / sizeof(WCHAR));
1836                 if (ttyinput.head == ttyinput.tail)
1837                     ttyinput.head = ttyinput.tail = 0;
1838 
1839                 for (nch=0;nch<result/sizeof(WCHAR);++nch) {
1840                     if (ubuf[nch]==13) {
1841                         ++offset;
1842                     } else {
1843                         ubuf[nch-offset]=ubuf[nch];
1844                     }
1845                 }
1846                 result-=offset*sizeof(WCHAR);
1847 
1848             }
1849         } else {
1850             result = -1;
1851             ttyinput.head = ttyinput.tail = 0;
1852             errno = EIO;
1853         }
1854     }
1855 unlock:
1856     pthread_mutex_unlock(&ttyinput.lock);
1857     return result;
1858 }
1859 
1860 int
win32_read_unicode_console(HANDLE handle,void * buf,int count)1861 win32_read_unicode_console(HANDLE handle, void* buf, int count)
1862 {
1863 
1864     int result;
1865     result = tty_read_line_client(handle,buf,count);
1866     return result;
1867 }
1868 
1869 boolean
win32_maybe_interrupt_io(void * thread)1870 win32_maybe_interrupt_io(void* thread)
1871 {
1872     struct thread *th = thread;
1873     boolean done = 0;
1874     if (ptr_CancelIoEx) {
1875         pthread_mutex_lock(&interrupt_io_lock);
1876         HANDLE h = (HANDLE)
1877             InterlockedExchangePointer((volatile LPVOID *)
1878                                        &th->synchronous_io_handle_and_flag,
1879                                        (LPVOID)INVALID_HANDLE_VALUE);
1880         if (h && (h!=INVALID_HANDLE_VALUE)) {
1881             if (console_handle_p(h)) {
1882                 pthread_mutex_lock(&ttyinput.lock);
1883                 pthread_cond_broadcast(&ttyinput.cond_has_data);
1884                 pthread_mutex_unlock(&ttyinput.lock);
1885             }
1886             if (ptr_CancelSynchronousIo) {
1887                 pthread_mutex_lock(&th->os_thread->fiber_lock);
1888                 done = !!ptr_CancelSynchronousIo(th->os_thread->fiber_group->handle);
1889                 pthread_mutex_unlock(&th->os_thread->fiber_lock);
1890             }
1891             done |= !!ptr_CancelIoEx(h,NULL);
1892         }
1893         pthread_mutex_unlock(&interrupt_io_lock);
1894     }
1895     return done;
1896 }
1897 
1898 static const LARGE_INTEGER zero_large_offset = {.QuadPart = 0LL};
1899 
1900 int
win32_unix_write(HANDLE handle,void * buf,int count)1901 win32_unix_write(HANDLE handle, void * buf, int count)
1902 {
1903     DWORD written_bytes;
1904     OVERLAPPED overlapped;
1905     struct thread * self = arch_os_get_current_thread();
1906     BOOL waitInGOR;
1907     LARGE_INTEGER file_position;
1908     BOOL seekable;
1909     BOOL ok;
1910 
1911     if (console_handle_p(handle))
1912         return win32_write_unicode_console(handle,buf,count);
1913 
1914     overlapped.hEvent = self->private_events.events[0];
1915     seekable = SetFilePointerEx(handle,
1916                                 zero_large_offset,
1917                                 &file_position,
1918                                 FILE_CURRENT);
1919     if (seekable) {
1920         overlapped.Offset = file_position.LowPart;
1921         overlapped.OffsetHigh = file_position.HighPart;
1922     } else {
1923         overlapped.Offset = 0;
1924         overlapped.OffsetHigh = 0;
1925     }
1926     if (!io_begin_interruptible(handle)) {
1927         errno = EINTR;
1928         return -1;
1929     }
1930     ok = WriteFile(handle, buf, count, &written_bytes, &overlapped);
1931     io_end_interruptible(handle);
1932 
1933     if (ok) {
1934         goto done_something;
1935     } else {
1936         DWORD errorCode = GetLastError();
1937         if (errorCode==ERROR_OPERATION_ABORTED) {
1938             GetOverlappedResult(handle,&overlapped,&written_bytes,FALSE);
1939             errno = EINTR;
1940             return -1;
1941         }
1942         if (errorCode!=ERROR_IO_PENDING) {
1943             errno = EIO;
1944             return -1;
1945         } else {
1946             if(WaitForMultipleObjects(2,self->private_events.events,
1947                                       FALSE,INFINITE) != WAIT_OBJECT_0) {
1948                 CancelIo(handle);
1949                 waitInGOR = TRUE;
1950             } else {
1951                 waitInGOR = FALSE;
1952             }
1953             if (!GetOverlappedResult(handle,&overlapped,&written_bytes,waitInGOR)) {
1954                 if (GetLastError()==ERROR_OPERATION_ABORTED) {
1955                     errno = EINTR;
1956                 } else {
1957                     errno = EIO;
1958                 }
1959                 return -1;
1960             } else {
1961                 goto done_something;
1962             }
1963         }
1964     }
1965   done_something:
1966     if (seekable) {
1967         file_position.QuadPart += written_bytes;
1968         SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
1969     }
1970     return written_bytes;
1971 }
1972 
1973 int
win32_unix_read(HANDLE handle,void * buf,int count)1974 win32_unix_read(HANDLE handle, void * buf, int count)
1975 {
1976     OVERLAPPED overlapped = {.Internal=0};
1977     DWORD read_bytes = 0;
1978     struct thread * self = arch_os_get_current_thread();
1979     DWORD errorCode = 0;
1980     BOOL waitInGOR = FALSE;
1981     BOOL ok = FALSE;
1982     LARGE_INTEGER file_position;
1983     BOOL seekable;
1984 
1985     if (console_handle_p(handle))
1986         return win32_read_unicode_console(handle,buf,count);
1987 
1988     overlapped.hEvent = self->private_events.events[0];
1989     /* If it has a position, we won't try overlapped */
1990     seekable = SetFilePointerEx(handle,
1991                                 zero_large_offset,
1992                                 &file_position,
1993                                 FILE_CURRENT);
1994     if (seekable) {
1995         overlapped.Offset = file_position.LowPart;
1996         overlapped.OffsetHigh = file_position.HighPart;
1997     } else {
1998         overlapped.Offset = 0;
1999         overlapped.OffsetHigh = 0;
2000     }
2001     if (!io_begin_interruptible(handle)) {
2002         errno = EINTR;
2003         return -1;
2004     }
2005     ok = ReadFile(handle,buf,count,&read_bytes, &overlapped);
2006     io_end_interruptible(handle);
2007     if (ok) {
2008         /* immediately */
2009         goto done_something;
2010     } else {
2011         errorCode = GetLastError();
2012         if (errorCode == ERROR_HANDLE_EOF ||
2013             errorCode == ERROR_BROKEN_PIPE ||
2014             errorCode == ERROR_NETNAME_DELETED) {
2015             read_bytes = 0;
2016             goto done_something;
2017         }
2018         if (errorCode==ERROR_OPERATION_ABORTED) {
2019             GetOverlappedResult(handle,&overlapped,&read_bytes,FALSE);
2020             errno = EINTR;
2021             return -1;
2022         }
2023         if (errorCode!=ERROR_IO_PENDING) {
2024             /* is it some _real_ error? */
2025             errno = EIO;
2026             return -1;
2027         } else {
2028             int ret;
2029             if( (ret = WaitForMultipleObjects(2,self->private_events.events,
2030                                               FALSE,INFINITE)) != WAIT_OBJECT_0) {
2031                 CancelIo(handle);
2032                 waitInGOR = TRUE;
2033                 /* Waiting for IO only */
2034             } else {
2035                 waitInGOR = FALSE;
2036             }
2037             ok = GetOverlappedResult(handle,&overlapped,&read_bytes,waitInGOR);
2038             if (!ok) {
2039                 errorCode = GetLastError();
2040                 if (errorCode == ERROR_HANDLE_EOF ||
2041                     errorCode == ERROR_BROKEN_PIPE ||
2042                     errorCode == ERROR_NETNAME_DELETED) {
2043                     read_bytes = 0;
2044                     goto done_something;
2045                 } else {
2046                     if (errorCode == ERROR_OPERATION_ABORTED)
2047                         errno = EINTR;      /* that's it. */
2048                     else
2049                         errno = EIO;        /* something unspecific */
2050                     return -1;
2051                 }
2052             } else
2053                 goto done_something;
2054         }
2055     }
2056   done_something:
2057     if (seekable) {
2058         file_position.QuadPart += read_bytes;
2059         SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
2060     }
2061     return read_bytes;
2062 }
2063 
2064 /* We used to have a scratch() function listing all symbols needed by
2065  * Lisp.  Much rejoicing commenced upon its removal.  However, I would
2066  * like cold init to fail aggressively when encountering unused symbols.
2067  * That poses a problem, however, since our C code no longer includes
2068  * any references to symbols in ws2_32.dll, and hence the linker
2069  * completely ignores our request to reference it (--no-as-needed does
2070  * not work).  Warm init would later load the DLLs explicitly, but then
2071  * it's too late for an early sanity check.  In the unfortunate spirit
2072  * of scratch(), continue to reference some required DLLs explicitly by
2073  * means of one scratch symbol per DLL.
2074  */
scratch(void)2075 void scratch(void)
2076 {
2077     /* a function from ws2_32.dll */
2078     shutdown(0, 0);
2079 
2080     /* a function from shell32.dll */
2081     SHGetFolderPathA(0, 0, 0, 0, 0);
2082 
2083     /* from advapi32.dll */
2084     CryptGenRandom(0, 0, 0);
2085 }
2086 
2087 char *
os_get_runtime_executable_path(int external)2088 os_get_runtime_executable_path(int external)
2089 {
2090     char path[MAX_PATH + 1];
2091     DWORD bufsize = sizeof(path);
2092     DWORD size;
2093 
2094     if ((size = GetModuleFileNameA(NULL, path, bufsize)) == 0)
2095         return NULL;
2096     else if (size == bufsize && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2097         return NULL;
2098 
2099     return copied_string(path);
2100 }
2101 
2102 #ifdef LISP_FEATURE_SB_THREAD
2103 
2104 DWORD
win32_wait_object_or_signal(HANDLE waitFor)2105 win32_wait_object_or_signal(HANDLE waitFor)
2106 {
2107     struct thread *self = arch_os_get_current_thread();
2108     HANDLE handles[] = {waitFor, self->private_events.events[1]};
2109     return
2110         WaitForMultipleObjects(2,handles, FALSE,INFINITE);
2111 }
2112 
2113 DWORD
win32_wait_for_multiple_objects_or_signal(HANDLE * handles,DWORD count)2114 win32_wait_for_multiple_objects_or_signal(HANDLE *handles, DWORD count)
2115 {
2116     struct thread *self = arch_os_get_current_thread();
2117     handles[count] = self->private_events.events[1];
2118 
2119     return
2120         WaitForMultipleObjects(count + 1, handles, FALSE, INFINITE);
2121 }
2122 
2123 /*
2124  * Portability glue for win32 waitable timers.
2125  *
2126  * One may ask: Why is there a wrapper in C when the calls are so
2127  * obvious that Lisp could do them directly (as it did on Windows)?
2128  *
2129  * But the answer is that on POSIX platforms, we now emulate the win32
2130  * calls and hide that emulation behind this os_* abstraction.
2131  */
2132 HANDLE
os_create_wtimer()2133 os_create_wtimer()
2134 {
2135     return CreateWaitableTimer(0, 0, 0);
2136 }
2137 
2138 int
os_wait_for_wtimer(HANDLE handle)2139 os_wait_for_wtimer(HANDLE handle)
2140 {
2141     return win32_wait_object_or_signal(handle);
2142 }
2143 
2144 void
os_close_wtimer(HANDLE handle)2145 os_close_wtimer(HANDLE handle)
2146 {
2147     CloseHandle(handle);
2148 }
2149 
2150 void
os_set_wtimer(HANDLE handle,int sec,int nsec)2151 os_set_wtimer(HANDLE handle, int sec, int nsec)
2152 {
2153     /* in units of 100ns, i.e. 0.1us. Negative for relative semantics. */
2154     long long dueTime
2155         = -(((long long) sec) * 10000000
2156             + ((long long) nsec + 99) / 100);
2157     SetWaitableTimer(handle, (LARGE_INTEGER*) &dueTime, 0, 0, 0, 0);
2158 }
2159 
2160 void
os_cancel_wtimer(HANDLE handle)2161 os_cancel_wtimer(HANDLE handle)
2162 {
2163     CancelWaitableTimer(handle);
2164 }
2165 #endif
2166 
2167 /* EOF */
2168