Use flatteningization in package-data-list
[sbcl.git] / src / runtime / win32-os.c
blob8a5f6aaa05a707850cc61821fab90556abb3fc19
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 <winsock2.h>
73 #include <wincrypt.h>
75 #if 0
76 int linux_sparc_siginfo_bug = 0;
77 int linux_supports_futex=0;
78 #endif
80 #include <stdarg.h>
81 #include <string.h>
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
91 /* Tired of writing arch_os_get_current_thread each time. */
92 #define this_thread (arch_os_get_current_thread())
94 /* wrappers for winapi calls that must be successful (like SBCL's
95 * (aver ...) form). */
97 /* win_aver function: basic building block for miscellaneous
98 * ..AVER.. macrology (below) */
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. */
105 static inline
106 intptr_t win_aver(intptr_t value, char* comment, char* file, int line,
107 int justwarn)
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";
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);
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);
149 if (allocated)
150 LocalFree(errorMessage);
152 return value;
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
159 intptr_t sys_aver(long value, char* comment, char* file, int line,
160 int justwarn)
162 win_aver((intptr_t)(value>=0),comment,file,line,justwarn);
163 return value;
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.
172 * Failed AVER() is normally fatal. Well, unless dyndebug_survive_aver
173 * flag is set. */
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;})
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. */
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;})
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). */
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;})
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;})
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;})
214 const char * t_nil_s(lispobj symbol);
217 * The following signal-mask-related alien routines are called from Lisp:
220 /* As of win32, deferrables _do_ matter. gc_signal doesn't. */
221 unsigned long block_deferrables_and_return_mask()
223 sigset_t sset;
224 block_deferrable_signals(0, &sset);
225 return (unsigned long)sset;
228 #if defined(LISP_FEATURE_SB_THREAD)
229 void apply_sigmask(unsigned long sigmask)
231 sigset_t sset = (sigset_t)sigmask;
232 thread_sigmask(SIG_SETMASK, &sset, 0);
234 #endif
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.
249 void *base_seh_frame;
251 HMODULE runtime_module_handle = 0u;
253 static void *get_seh_frame(void)
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;
264 static void set_seh_frame(void *frame)
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
273 #if defined(LISP_FEATURE_SB_THREAD)
275 void alloc_gc_page()
277 AVER(VirtualAlloc(GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
278 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE));
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).
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]".
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
302 void map_gc_page()
304 DWORD oldProt;
305 AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
306 PAGE_READWRITE, &oldProt));
309 void unmap_gc_page()
311 DWORD oldProt;
312 AVER(VirtualProtect((void*) GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
313 PAGE_NOACCESS, &oldProt));
316 #endif
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.
325 * How it works: a sketch
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.
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).
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.
349 * What do we gain with this feature, after all?
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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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:
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>
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.
487 * Of course, this name-parsing trick lacks conceptual clarity; we're
488 * going to get rid of it eventually. */
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[])
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;
501 /* dos header provided the offset from `base' to
502 * IMAGE_FILE_HEADER where PE-i386 really starts */
504 void* check_duplicates[excl_maximum];
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. */
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;
527 for (nlibrary=0u; nlibrary < excl_maximum
528 && image_import_descriptor->FirstThunk;
529 ++image_import_descriptor)
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).
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. */
543 hmodule = (HMODULE)
544 GetModuleHandle(base + image_import_descriptor->Name);
546 if (hmodule)
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.
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)). */
567 for (j=0; j<nlibrary; ++j)
569 if(check_duplicates[j] == hmodule)
570 break;
572 if (j<nlibrary) continue; /* duplicate => skip it in
573 * outer loop */
575 check_duplicates[nlibrary] = hmodule;
576 if (opt_store_handles) {
577 opt_store_handles[nlibrary] = hmodule;
579 if (opt_store_names) {
580 opt_store_names[nlibrary] = (const char *)
581 (base + image_import_descriptor->Name);
583 odxprint(runtime_link, "DLL detection: %u, base %p: %s",
584 nlibrary, hmodule,
585 (char*)(base + image_import_descriptor->Name));
586 ++ nlibrary;
589 return nlibrary;
593 static u32 buildTimeImageCount = 0;
594 static void* buildTimeImages[16];
596 /* Resolve symbols against the executable and its build-time dependencies */
597 void* os_dlsym_default(char* name)
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);
606 for (i = 0; i<buildTimeImageCount && (!result); ++i) {
607 result = GetProcAddress(buildTimeImages[i], name);
609 return result;
612 #endif /* SB_DYNAMIC_CORE */
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.
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).
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.
634 To summarize, let's list the assumptions we make:
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.
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. */
654 void os_preinit()
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;
671 slots[n_slots++]=key;
673 for (i=0; i<n_slots; ++i) {
674 TlsFree(slots[i]);
676 if (key!=OUR_TLS_INDEX) {
677 lose("TLS slot assertion failed: slot 63 is unavailable "
678 "(last TlsAlloc() returned %u)",key);
680 #endif
682 #endif /* LISP_FEATURE_SB_THREAD */
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.
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. */
693 /* There is (will be) defines for printf and friends. */
695 static int translating_vfprintf(FILE*stream, const char *fmt, va_list args)
697 char translated[1024];
698 int i=0, delta = 0;
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;
713 translated[i++]=0;
714 return vfprintf(stream,translated,args);
717 int printf(const char*fmt,...)
719 va_list args;
720 va_start(args,fmt);
721 return translating_vfprintf(stdout,fmt,args);
723 int fprintf(FILE*stream,const char*fmt,...)
725 va_list args;
726 va_start(args,fmt);
727 return translating_vfprintf(stream,fmt,args);
730 #endif
732 int os_number_of_processors = 1;
734 BOOL WINAPI CancelIoEx(HANDLE handle, LPOVERLAPPED overlapped);
735 typeof(CancelIoEx) *ptr_CancelIoEx;
736 BOOL WINAPI CancelSynchronousIo(HANDLE threadHandle);
737 typeof(CancelSynchronousIo) *ptr_CancelSynchronousIo;
739 #define RESOLVE(hmodule,fn) \
740 do { \
741 ptr_##fn = (typeof(ptr_##fn)) \
742 GetProcAddress(hmodule,#fn); \
743 } while (0)
745 static void resolve_optional_imports()
747 HMODULE kernel32 = GetModuleHandleA("kernel32");
748 if (kernel32) {
749 RESOLVE(kernel32,CancelIoEx);
750 RESOLVE(kernel32,CancelSynchronousIo);
754 #undef RESOLVE
756 intptr_t win32_get_module_handle_by_address(os_vm_address_t addr)
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);
770 void os_init(char *argv[], char *envp[])
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;
781 base_seh_frame = get_seh_frame();
783 resolve_optional_imports();
784 runtime_module_handle = (HMODULE)win32_get_module_handle_by_address(&runtime_module_handle);
787 static inline boolean local_thread_stack_address_p(os_vm_address_t address)
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))));
797 * So we have three fun scenarios here.
799 * First, we could be being called to reserve the memory areas
800 * during initialization (prior to loading the core file).
802 * Second, we could be being called by the GC to commit a page
803 * that has just been decommitted (for easy zero-fill).
805 * Third, we could be being called by create_thread_struct()
806 * in order to create the sundry and various stacks.
808 * The third case is easy to pick out because it passes an
809 * addr of 0.
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.
814 * The second case is also an easy implement, because we leave
815 * the memory as reserved (since we do lazy commits).
818 os_vm_address_t
819 os_validate(os_vm_address_t addr, os_vm_size_t len)
821 MEMORY_BASIC_INFORMATION mem_info;
823 if (!addr) {
824 /* the simple case first */
825 return
826 AVERLAX(VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE));
829 if (!AVERLAX(VirtualQuery(addr, &mem_info, sizeof mem_info)))
830 return 0;
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.
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.
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;
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: */
856 if (!AVERLAX(VirtualAlloc(addr, len, (mem_info.State == MEM_RESERVE)?
857 MEM_COMMIT: MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
858 return 0;
860 return addr;
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.
868 * So far the original comment (author unknown). It used to continue as
869 * follows:
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).
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().
882 * As discussed on #lisp, this is not a satisfactory solution, and probably
883 * ought to be rectified in the following way:
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.
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().
895 * So far the new plan, as yet unimplemented. -- DFL
898 void
899 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
901 AVERLAX(VirtualFree(addr, len, MEM_DECOMMIT));
904 void
905 os_invalidate_free(os_vm_address_t addr, os_vm_size_t len)
907 AVERLAX(VirtualFree(addr, 0, MEM_RELEASE));
910 void
911 os_invalidate_free_by_any_address(os_vm_address_t addr, os_vm_size_t len)
913 MEMORY_BASIC_INFORMATION minfo;
914 AVERLAX(VirtualQuery(addr, &minfo, sizeof minfo));
915 AVERLAX(minfo.AllocationBase);
916 AVERLAX(VirtualFree(minfo.AllocationBase, 0, MEM_RELEASE));
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:
925 os_vm_address_t
926 os_validate_recommit(os_vm_address_t addr, os_vm_size_t len)
928 return
929 AVERLAX(VirtualAlloc(addr, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE));
933 * os_map() is called to map a chunk of the core file into memory.
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).
943 os_vm_address_t
944 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
946 os_vm_size_t count;
948 AVER(VirtualAlloc(addr, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE)||
949 VirtualAlloc(addr, len, MEM_RESERVE|MEM_COMMIT,
950 PAGE_EXECUTE_READWRITE));
952 CRT_AVER_NONNEGATIVE(lseek(fd, offset, SEEK_SET));
954 count = read(fd, addr, len);
955 CRT_AVER( count == len );
957 return addr;
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,
971 void
972 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
974 DWORD old_prot;
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);
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
989 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
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);
997 boolean
998 is_linkage_table_addr(os_vm_address_t addr)
1000 return in_range_p(addr, LINKAGE_TABLE_SPACE_START, LINKAGE_TABLE_SPACE_SIZE);
1003 static boolean is_some_thread_local_addr(os_vm_address_t addr);
1005 boolean
1006 is_valid_lisp_addr(os_vm_address_t addr)
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;
1016 /* test if an address is within thread-local space */
1017 static boolean
1018 is_thread_local_addr(struct thread* th, os_vm_address_t addr)
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
1037 static boolean
1038 is_some_thread_local_addr(os_vm_address_t addr)
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;
1050 pthread_mutex_unlock(&all_threads_lock);
1051 #endif
1052 return result;
1056 /* A tiny bit of interrupt.c state we want our paws on. */
1057 extern boolean internal_errors_enabled;
1059 extern void exception_handler_wrapper();
1061 void
1062 c_level_backtrace(const char* header, int depth)
1064 void* frame;
1065 int n = 0;
1066 void** lastseh;
1068 for (lastseh = get_seh_frame(); lastseh && (lastseh!=(void*)-1);
1069 lastseh = *lastseh);
1071 fprintf(stderr, "Backtrace: %s (thread %p)\n", header, this_thread);
1072 for (frame = __builtin_frame_address(0); frame; frame=*(void**)frame)
1074 if ((n++)>depth)
1075 return;
1076 fprintf(stderr, "[#%02d]: ebp = %p, ret = %p\n",n,
1077 frame, ((void**)frame)[1]);
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
1088 static int
1089 handle_single_step(os_context_t *ctx)
1091 if (!single_stepping)
1092 return -1;
1094 /* We are doing a displaced instruction. At least function
1095 * end breakpoints use this. */
1096 restore_breakpoint_from_single_step(ctx);
1098 return 0;
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
1109 static int
1110 handle_breakpoint_trap(os_context_t *ctx, struct thread* self)
1112 #ifdef LISP_FEATURE_UD2_BREAKPOINTS
1113 if (((unsigned short *)*os_context_pc_addr(ctx))[0] != 0x0b0f)
1114 return -1;
1115 #endif
1117 /* Unlike some other operating systems, Win32 leaves EIP
1118 * pointing to the breakpoint instruction. */
1119 (*os_context_pc_addr(ctx)) += TRAP_CODE_WIDTH;
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));
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;
1137 #endif
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);
1144 WITH_GC_AT_SAFEPOINTS_ONLY() {
1145 #if defined(LISP_FEATURE_SB_THREAD)
1146 block_blockable_signals(0,&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
1154 /* Done, we're good to go! */
1155 return 0;
1158 static int
1159 handle_access_violation(os_context_t *ctx,
1160 EXCEPTION_RECORD *exception_record,
1161 void *fault_address,
1162 struct thread* self)
1164 CONTEXT *win32_context = ctx->win32_context;
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
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;
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;
1205 if ((((u64)fault_address) == ((u64)self->csp_around_foreign_call))){
1206 thread_in_safety_transition(ctx);
1207 return 0;
1209 #endif
1211 /* dynamic space */
1212 page_index_t index = find_page_index(fault_address);
1213 if (index != -1) {
1215 * Now, if the page is supposedly write-protected and this
1216 * is a write, tell the gc that it's been hit.
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));
1225 return 0;
1228 if (fault_address == undefined_alien_address)
1229 return -1;
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;
1236 return -1;
1238 try_recommit:
1239 /* First use of a new page, lets get some memory for it. */
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
1263 return 0;
1266 static void
1267 signal_internal_error_or_lose(os_context_t *ctx,
1268 EXCEPTION_RECORD *exception_record,
1269 void *fault_address)
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.
1277 if (internal_errors_enabled) {
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. */
1286 #if defined(LISP_FEATURE_SB_THREAD)
1287 block_blockable_signals(0,&ctx->sigmask);
1288 #endif
1289 fake_foreign_function_call(ctx);
1291 WITH_GC_AT_SAFEPOINTS_ONLY() {
1292 DX_ALLOC_SAP(context_sap, ctx);
1293 DX_ALLOC_SAP(exception_record_sap, exception_record);
1295 #if defined(LISP_FEATURE_SB_THREAD)
1296 thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
1297 #endif
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);
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;
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;
1323 if (VirtualQuery(fault_address, &mem_info, sizeof mem_info)) {
1324 fprintf(stderr, "page status: 0x%lx.\n", mem_info.State);
1327 fprintf(stderr, "Was writing: %p, where: %p.\n",
1328 (void*)exception_record->ExceptionInformation[0],
1329 fault_address);
1332 fflush(stderr);
1334 fake_foreign_function_call(ctx);
1335 lose("Exception too early in cold init, cannot continue.");
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
1345 EXCEPTION_DISPOSITION
1346 handle_exception(EXCEPTION_RECORD *exception_record,
1347 struct lisp_exception_frame *exception_frame,
1348 CONTEXT *win32_context,
1349 void *dispatcher_context)
1351 if (!win32_context)
1352 /* Not certain why this should be possible, but let's be safe... */
1353 return ExceptionContinueSearch;
1355 if (exception_record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) {
1356 /* If we're being unwound, be graceful about it. */
1358 /* Undo any dynamic bindings. */
1359 unbind_to_here(exception_frame->bindstack_pointer,
1360 arch_os_get_current_thread());
1361 return ExceptionContinueSearch;
1364 DWORD lastError = GetLastError();
1365 DWORD lastErrno = errno;
1366 DWORD code = exception_record->ExceptionCode;
1367 struct thread* self = arch_os_get_current_thread();
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
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);
1382 /* For EXCEPTION_ACCESS_VIOLATION only. */
1383 void *fault_address = (void *)exception_record->ExceptionInformation[1];
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);
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: */
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;
1408 case SBCL_EXCEPTION_BREAKPOINT:
1409 rc = handle_breakpoint_trap(ctx, self);
1410 break;
1412 case EXCEPTION_SINGLE_STEP:
1413 rc = handle_single_step(ctx);
1414 break;
1416 default:
1417 rc = -1;
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);
1424 if (self)
1425 self->carried_base_pointer = oldbp;
1427 errno = lastErrno;
1428 SetLastError(lastError);
1429 return ExceptionContinueExecution;
1432 #ifdef LISP_FEATURE_X86_64
1434 #define RESTORING_ERRNO() \
1435 int sbcl__lastErrno = errno; \
1436 RUN_BODY_ONCE(restoring_errno, errno = sbcl__lastErrno)
1438 LONG
1439 veh(EXCEPTION_POINTERS *ep)
1441 EXCEPTION_DISPOSITION disp;
1443 RESTORING_ERRNO() {
1444 if (!pthread_self())
1445 return EXCEPTION_CONTINUE_SEARCH;
1448 disp = handle_exception(ep->ExceptionRecord,0,ep->ContextRecord,0);
1450 switch (disp)
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);
1461 #endif
1463 os_context_register_t
1464 carry_frame_pointer(os_context_register_t default_value)
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;
1471 void
1472 wos_install_interrupt_handlers(struct lisp_exception_frame *handler)
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
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.
1492 void *memmove(void *dest, const void *src, size_t n)
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);
1500 return dest;
1503 void *memcpy(void *dest, const void *src, size_t n)
1505 while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1506 return dest;
1509 char *dirname(char *path)
1511 static char buf[PATH_MAX + 1];
1512 size_t pathlen = strlen(path);
1513 int i;
1515 if (pathlen >= sizeof(buf)) {
1516 lose("Pathname too long in dirname.\n");
1517 return NULL;
1520 strcpy(buf, path);
1521 for (i = pathlen; i >= 0; --i) {
1522 if (buf[i] == '/' || buf[i] == '\\') {
1523 buf[i] = '\0';
1524 break;
1528 return buf;
1531 // 0 - not a socket or other error, 1 - has input, 2 - has no input
1533 socket_input_available(HANDLE socket)
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);
1540 int ret;
1542 if (err == 0) {
1543 ret = (count > 0) ? 1 : 2;
1544 } else
1545 ret = 0;
1546 SetLastError(wsaErrno);
1547 return ret;
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.
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. */
1561 console_handle_p(HANDLE handle)
1563 return (handle != NULL)&&
1564 (handle != INVALID_HANDLE_VALUE)&&
1565 ((((int)(intptr_t)handle)&3)==3);
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.
1572 static
1573 boolean io_begin_interruptible(HANDLE handle)
1575 /* No point in doing it unless OS supports cancellation from other
1576 * threads */
1577 if (!ptr_CancelIoEx)
1578 return 1;
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;
1586 return 1;
1589 static pthread_mutex_t interrupt_io_lock = PTHREAD_MUTEX_INITIALIZER;
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
1595 io_end_interruptible(HANDLE handle)
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);
1605 /* Documented limit for ReadConsole/WriteConsole is 64K bytes.
1606 Real limit observed on W2K-SP3 is somewhere in between 32KiB and 64Kib...
1608 #define MAX_CONSOLE_TCHARS 16384
1611 win32_write_unicode_console(HANDLE handle, void * buf, int count)
1613 DWORD written = 0;
1614 DWORD nchars;
1615 BOOL result;
1616 nchars = count>>1;
1617 if (nchars>MAX_CONSOLE_TCHARS) nchars = MAX_CONSOLE_TCHARS;
1619 if (!io_begin_interruptible(handle)) {
1620 errno = EINTR;
1621 return -1;
1623 result = WriteConsoleW(handle,buf,nchars,&written,NULL);
1624 io_end_interruptible(handle);
1626 if (result) {
1627 if (!written) {
1628 errno = EINTR;
1629 return -1;
1630 } else {
1631 return 2*written;
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;
1642 * (AK writes:)
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_.
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.
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.
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.
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.
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.
1672 * What's currently implemented is a compromise, looking as something
1673 * in between Unix cooked mode and Win32 line mode.
1675 * 1. As long as no console I/O function is called (incl. CL:LISTEN),
1676 * console looks `blocked': no echo, no line editing.
1678 * 2. (READ-CHAR), (READ-SEQUENCE) and other functions doing real
1679 * input result in the ReadConsole request (in a dedicated thread);
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)).
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.
1695 * 5. Console-reading Lisp thread now may be interrupted immediately;
1696 * ReadConsole call itself, however, continues until the line is
1697 * entered.
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};
1712 static void*
1713 tty_read_line_server()
1715 pthread_mutex_lock(&ttyinput.lock);
1716 while (ttyinput.handle) {
1717 DWORD nchars;
1718 BOOL ok;
1720 while (!ttyinput.in_progress)
1721 pthread_cond_wait(&ttyinput.cond_has_client,&ttyinput.lock);
1723 pthread_mutex_unlock(&ttyinput.lock);
1725 ok = ReadConsoleW(ttyinput.handle,
1726 &ttyinput.buffer[ttyinput.tail],
1727 MAX_CONSOLE_TCHARS-ttyinput.tail,
1728 &nchars,NULL);
1730 pthread_mutex_lock(&ttyinput.lock);
1732 if (ok) {
1733 ttyinput.tail += nchars;
1734 pthread_cond_broadcast(&ttyinput.cond_has_data);
1736 ttyinput.in_progress = 0;
1738 pthread_mutex_unlock(&ttyinput.lock);
1739 return NULL;
1742 static boolean
1743 tty_maybe_initialize_unlocked(HANDLE handle)
1745 if (!ttyinput.initialized) {
1746 if (!DuplicateHandle(GetCurrentProcess(),handle,
1747 GetCurrentProcess(),&ttyinput.handle,
1748 0,FALSE,DUPLICATE_SAME_ACCESS)) {
1749 return 0;
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;
1756 return 1;
1759 boolean
1760 win32_tty_listen(HANDLE handle)
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;
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);
1781 pthread_mutex_unlock(&ttyinput.lock);
1782 return result;
1785 static int
1786 tty_read_line_client(HANDLE handle, void* buf, int count)
1788 int result = 0;
1789 int nchars = count / sizeof(WCHAR);
1790 sigset_t pendset;
1792 if (!nchars)
1793 return 0;
1794 if (nchars>MAX_CONSOLE_TCHARS)
1795 nchars=MAX_CONSOLE_TCHARS;
1797 count = nchars*sizeof(WCHAR);
1799 pthread_mutex_lock(&ttyinput.lock);
1801 if (!tty_maybe_initialize_unlocked(handle)) {
1802 result = -1;
1803 errno = EIO;
1804 goto unlock;
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);
1821 pthread_cond_wait(&ttyinput.cond_has_data, &ttyinput.lock);
1822 io_end_interruptible(ttyinput.handle);
1825 result = sizeof(WCHAR)*(ttyinput.tail-ttyinput.head);
1826 if (result > count) {
1827 result = count;
1829 if (result) {
1830 if (result > 0) {
1831 DWORD nch,offset = 0;
1832 LPWSTR ubuf = buf;
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;
1839 for (nch=0;nch<result/sizeof(WCHAR);++nch) {
1840 if (ubuf[nch]==13) {
1841 ++offset;
1842 } else {
1843 ubuf[nch-offset]=ubuf[nch];
1846 result-=offset*sizeof(WCHAR);
1849 } else {
1850 result = -1;
1851 ttyinput.head = ttyinput.tail = 0;
1852 errno = EIO;
1855 unlock:
1856 pthread_mutex_unlock(&ttyinput.lock);
1857 return result;
1861 win32_read_unicode_console(HANDLE handle, void* buf, int count)
1864 int result;
1865 result = tty_read_line_client(handle,buf,count);
1866 return result;
1869 boolean
1870 win32_maybe_interrupt_io(void* thread)
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);
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);
1891 done |= !!ptr_CancelIoEx(h,NULL);
1893 pthread_mutex_unlock(&interrupt_io_lock);
1895 return done;
1898 static const LARGE_INTEGER zero_large_offset = {.QuadPart = 0LL};
1901 win32_unix_write(HANDLE handle, void * buf, int count)
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;
1911 if (console_handle_p(handle))
1912 return win32_write_unicode_console(handle,buf,count);
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;
1926 if (!io_begin_interruptible(handle)) {
1927 errno = EINTR;
1928 return -1;
1930 ok = WriteFile(handle, buf, count, &written_bytes, &overlapped);
1931 io_end_interruptible(handle);
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;
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;
1953 if (!GetOverlappedResult(handle,&overlapped,&written_bytes,waitInGOR)) {
1954 if (GetLastError()==ERROR_OPERATION_ABORTED) {
1955 errno = EINTR;
1956 } else {
1957 errno = EIO;
1959 return -1;
1960 } else {
1961 goto done_something;
1965 done_something:
1966 if (seekable) {
1967 file_position.QuadPart += written_bytes;
1968 SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
1970 return written_bytes;
1974 win32_unix_read(HANDLE handle, void * buf, int count)
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;
1985 if (console_handle_p(handle))
1986 return win32_read_unicode_console(handle,buf,count);
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;
2001 if (!io_begin_interruptible(handle)) {
2002 errno = EINTR;
2003 return -1;
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;
2018 if (errorCode==ERROR_OPERATION_ABORTED) {
2019 GetOverlappedResult(handle,&overlapped,&read_bytes,FALSE);
2020 errno = EINTR;
2021 return -1;
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;
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;
2052 } else
2053 goto done_something;
2056 done_something:
2057 if (seekable) {
2058 file_position.QuadPart += read_bytes;
2059 SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
2061 return read_bytes;
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.
2075 void scratch(void)
2077 /* a function from ws2_32.dll */
2078 shutdown(0, 0);
2080 /* a function from shell32.dll */
2081 SHGetFolderPathA(0, 0, 0, 0, 0);
2083 /* from advapi32.dll */
2084 CryptGenRandom(0, 0, 0);
2087 char *
2088 os_get_runtime_executable_path(int external)
2090 char path[MAX_PATH + 1];
2091 DWORD bufsize = sizeof(path);
2092 DWORD size;
2094 if ((size = GetModuleFileNameA(NULL, path, bufsize)) == 0)
2095 return NULL;
2096 else if (size == bufsize && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2097 return NULL;
2099 return copied_string(path);
2102 #ifdef LISP_FEATURE_SB_THREAD
2105 win32_wait_object_or_signal(HANDLE waitFor)
2107 struct thread * self = arch_os_get_current_thread();
2108 HANDLE handles[2];
2109 handles[0] = waitFor;
2110 handles[1] = self->private_events.events[1];
2111 return
2112 WaitForMultipleObjects(2,handles, FALSE,INFINITE);
2116 * Portability glue for win32 waitable timers.
2118 * One may ask: Why is there a wrapper in C when the calls are so
2119 * obvious that Lisp could do them directly (as it did on Windows)?
2121 * But the answer is that on POSIX platforms, we now emulate the win32
2122 * calls and hide that emulation behind this os_* abstraction.
2124 HANDLE
2125 os_create_wtimer()
2127 return CreateWaitableTimer(0, 0, 0);
2131 os_wait_for_wtimer(HANDLE handle)
2133 return win32_wait_object_or_signal(handle);
2136 void
2137 os_close_wtimer(HANDLE handle)
2139 CloseHandle(handle);
2142 void
2143 os_set_wtimer(HANDLE handle, int sec, int nsec)
2145 /* in units of 100ns, i.e. 0.1us. Negative for relative semantics. */
2146 long long dueTime
2147 = -(((long long) sec) * 10000000
2148 + ((long long) nsec + 99) / 100);
2149 SetWaitableTimer(handle, (LARGE_INTEGER*) &dueTime, 0, 0, 0, 0);
2152 void
2153 os_cancel_wtimer(HANDLE handle)
2155 CancelWaitableTimer(handle);
2157 #endif
2159 /* EOF */