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