explicit structure sharing in typed accessor function definitions
[sbcl.git] / src / runtime / win32-os.c
blob9c45a04313ced61c4f0ac211db32a951571a0632
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 pthread_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 if (trap == trap_PendingInterrupt) {
1130 /* Done everything needed for this trap, except EIP
1131 adjustment */
1132 arch_skip_instruction(ctx);
1133 thread_interrupted(ctx);
1134 return 0;
1136 #endif
1138 /* This is just for info in case the monitor wants to print an
1139 * approximation. */
1140 access_control_stack_pointer(self) =
1141 (lispobj *)*os_context_sp_addr(ctx);
1143 WITH_GC_AT_SAFEPOINTS_ONLY() {
1144 #if defined(LISP_FEATURE_SB_THREAD)
1145 block_blockable_signals(0,&ctx->sigmask);
1146 #endif
1147 handle_trap(ctx, trap);
1148 #if defined(LISP_FEATURE_SB_THREAD)
1149 thread_sigmask(SIG_SETMASK,&ctx->sigmask,NULL);
1150 #endif
1153 /* Done, we're good to go! */
1154 return 0;
1157 static int
1158 handle_access_violation(os_context_t *ctx,
1159 EXCEPTION_RECORD *exception_record,
1160 void *fault_address,
1161 struct thread* self)
1163 CONTEXT *win32_context = ctx->win32_context;
1165 #if defined(LISP_FEATURE_X86)
1166 odxprint(pagefaults,
1167 "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
1168 "Addr %p Access %d\n",
1169 self,
1170 win32_context->Eip,
1171 win32_context->Esp,
1172 win32_context->Esi,
1173 win32_context->Edi,
1174 fault_address,
1175 exception_record->ExceptionInformation[0]);
1176 #else
1177 odxprint(pagefaults,
1178 "SEGV. ThSap %p, Eip %p, Esp %p, Esi %p, Edi %p, "
1179 "Addr %p Access %d\n",
1180 self,
1181 win32_context->Rip,
1182 win32_context->Rsp,
1183 win32_context->Rsi,
1184 win32_context->Rdi,
1185 fault_address,
1186 exception_record->ExceptionInformation[0]);
1187 #endif
1189 /* Stack: This case takes care of our various stack exhaustion
1190 * protect pages (with the notable exception of the control stack!). */
1191 if (self && local_thread_stack_address_p(fault_address)) {
1192 if (handle_guard_page_triggered(ctx, fault_address))
1193 return 0; /* gc safety? */
1194 goto try_recommit;
1197 /* Safepoint pages */
1198 #ifdef LISP_FEATURE_SB_THREAD
1199 if (fault_address == (void *) GC_SAFEPOINT_PAGE_ADDR) {
1200 thread_in_lisp_raised(ctx);
1201 return 0;
1204 if ((((u64)fault_address) == ((u64)self->csp_around_foreign_call))){
1205 thread_in_safety_transition(ctx);
1206 return 0;
1208 #endif
1210 /* dynamic space */
1211 page_index_t index = find_page_index(fault_address);
1212 if (index != -1) {
1214 * Now, if the page is supposedly write-protected and this
1215 * is a write, tell the gc that it's been hit.
1217 if (page_table[index].write_protected) {
1218 gencgc_handle_wp_violation(fault_address);
1219 } else {
1220 AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
1221 os_vm_page_size,
1222 MEM_COMMIT, PAGE_EXECUTE_READWRITE));
1224 return 0;
1227 if (fault_address == undefined_alien_address)
1228 return -1;
1230 /* linkage table or a "valid_lisp_addr" outside of dynamic space (?) */
1231 if (is_linkage_table_addr(fault_address)
1232 || is_valid_lisp_addr(fault_address))
1233 goto try_recommit;
1235 return -1;
1237 try_recommit:
1238 /* First use of a new page, lets get some memory for it. */
1240 #if defined(LISP_FEATURE_X86)
1241 AVER(VirtualAlloc(PTR_ALIGN_DOWN(fault_address,os_vm_page_size),
1242 os_vm_page_size,
1243 MEM_COMMIT, PAGE_EXECUTE_READWRITE)
1244 ||(fprintf(stderr,"Unable to recommit addr %p eip 0x%08lx\n",
1245 fault_address, win32_context->Eip) &&
1246 (c_level_backtrace("BT",5),
1247 fake_foreign_function_call(ctx),
1248 lose("Lispy backtrace"),
1249 0)));
1250 #else
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 %p\n",
1255 fault_address, (void*)win32_context->Rip) &&
1256 (c_level_backtrace("BT",5),
1257 fake_foreign_function_call(ctx),
1258 lose("Lispy backtrace"),
1259 0)));
1260 #endif
1262 return 0;
1265 static void
1266 signal_internal_error_or_lose(os_context_t *ctx,
1267 EXCEPTION_RECORD *exception_record,
1268 void *fault_address)
1271 * If we fall through to here then we need to either forward
1272 * the exception to the lisp-side exception handler if it's
1273 * set up, or drop to LDB.
1276 if (internal_errors_enabled) {
1277 lispobj context_sap;
1278 lispobj exception_record_sap;
1280 asm("fnclex");
1281 /* We're making the somewhat arbitrary decision that having
1282 * internal errors enabled means that lisp has sufficient
1283 * marbles to be able to handle exceptions, but exceptions
1284 * aren't supposed to happen during cold init or reinit
1285 * anyway. */
1287 #if defined(LISP_FEATURE_SB_THREAD)
1288 block_blockable_signals(0,&ctx->sigmask);
1289 #endif
1290 fake_foreign_function_call(ctx);
1292 WITH_GC_AT_SAFEPOINTS_ONLY() {
1293 /* Allocate the SAP objects while the "interrupts" are still
1294 * disabled. */
1295 context_sap = alloc_sap(ctx);
1296 exception_record_sap = alloc_sap(exception_record);
1297 #if defined(LISP_FEATURE_SB_THREAD)
1298 thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
1299 #endif
1301 /* The exception system doesn't automatically clear pending
1302 * exceptions, so we lose as soon as we execute any FP
1303 * instruction unless we do this first. */
1304 /* Call into lisp to handle things. */
1305 funcall2(StaticSymbolFunction(HANDLE_WIN32_EXCEPTION),
1306 context_sap,
1307 exception_record_sap);
1309 /* If Lisp doesn't nlx, we need to put things back. */
1310 undo_fake_foreign_function_call(ctx);
1311 #if defined(LISP_FEATURE_SB_THREAD)
1312 thread_sigmask(SIG_SETMASK, &ctx->sigmask, NULL);
1313 #endif
1314 /* FIXME: HANDLE-WIN32-EXCEPTION should be allowed to decline */
1315 return;
1318 fprintf(stderr, "Exception Code: %p.\n",
1319 (void*)(intptr_t)exception_record->ExceptionCode);
1320 fprintf(stderr, "Faulting IP: %p.\n",
1321 (void*)(intptr_t)exception_record->ExceptionAddress);
1322 if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
1323 MEMORY_BASIC_INFORMATION mem_info;
1325 if (VirtualQuery(fault_address, &mem_info, sizeof mem_info)) {
1326 fprintf(stderr, "page status: 0x%lx.\n", mem_info.State);
1329 fprintf(stderr, "Was writing: %p, where: %p.\n",
1330 (void*)exception_record->ExceptionInformation[0],
1331 fault_address);
1334 fflush(stderr);
1336 fake_foreign_function_call(ctx);
1337 lose("Exception too early in cold init, cannot continue.");
1341 * A good explanation of the exception handling semantics is
1342 * http://win32assembly.online.fr/Exceptionhandling.html (possibly defunct)
1343 * or:
1344 * http://www.microsoft.com/msj/0197/exception/exception.aspx
1347 EXCEPTION_DISPOSITION
1348 handle_exception(EXCEPTION_RECORD *exception_record,
1349 struct lisp_exception_frame *exception_frame,
1350 CONTEXT *win32_context,
1351 void *dispatcher_context)
1353 if (!win32_context)
1354 /* Not certain why this should be possible, but let's be safe... */
1355 return ExceptionContinueSearch;
1357 if (exception_record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) {
1358 /* If we're being unwound, be graceful about it. */
1360 /* Undo any dynamic bindings. */
1361 unbind_to_here(exception_frame->bindstack_pointer,
1362 arch_os_get_current_thread());
1363 return ExceptionContinueSearch;
1366 DWORD lastError = GetLastError();
1367 DWORD lastErrno = errno;
1368 DWORD code = exception_record->ExceptionCode;
1369 struct thread* self = arch_os_get_current_thread();
1371 os_context_t context, *ctx = &context;
1372 context.win32_context = win32_context;
1373 #if defined(LISP_FEATURE_SB_THREAD)
1374 context.sigmask = self ? self->os_thread->blocked_signal_set : 0;
1375 #endif
1377 os_context_register_t oldbp = NULL;
1378 if (self) {
1379 oldbp = self ? self->carried_base_pointer : 0;
1380 self->carried_base_pointer
1381 = (os_context_register_t) voidreg(win32_context, bp);
1384 /* For EXCEPTION_ACCESS_VIOLATION only. */
1385 void *fault_address = (void *)exception_record->ExceptionInformation[1];
1387 odxprint(seh,
1388 "SEH: rec %p, ctxptr %p, rip %p, fault %p\n"
1389 "... code %p, rcx %p, fp-tags %p\n\n",
1390 exception_record,
1391 win32_context,
1392 voidreg(win32_context,ip),
1393 fault_address,
1394 (void*)(intptr_t)code,
1395 voidreg(win32_context,cx),
1396 win32_context->FloatSave.TagWord);
1398 /* This function had become unwieldy. Let's cut it down into
1399 * pieces based on the different exception codes. Each exception
1400 * code handler gets the chance to decline by returning non-zero if it
1401 * isn't happy: */
1403 int rc;
1404 switch (code) {
1405 case EXCEPTION_ACCESS_VIOLATION:
1406 rc = handle_access_violation(
1407 ctx, exception_record, fault_address, self);
1408 break;
1410 case SBCL_EXCEPTION_BREAKPOINT:
1411 rc = handle_breakpoint_trap(ctx, self);
1412 break;
1414 case EXCEPTION_SINGLE_STEP:
1415 rc = handle_single_step(ctx);
1416 break;
1418 default:
1419 rc = -1;
1422 if (rc)
1423 /* All else failed, drop through to the lisp-side exception handler. */
1424 signal_internal_error_or_lose(ctx, exception_record, fault_address);
1426 if (self)
1427 self->carried_base_pointer = oldbp;
1429 errno = lastErrno;
1430 SetLastError(lastError);
1431 return ExceptionContinueExecution;
1434 #ifdef LISP_FEATURE_X86_64
1436 #define RESTORING_ERRNO() \
1437 int sbcl__lastErrno = errno; \
1438 RUN_BODY_ONCE(restoring_errno, errno = sbcl__lastErrno)
1440 LONG
1441 veh(EXCEPTION_POINTERS *ep)
1443 EXCEPTION_DISPOSITION disp;
1445 RESTORING_ERRNO() {
1446 if (!pthread_self())
1447 return EXCEPTION_CONTINUE_SEARCH;
1450 disp = handle_exception(ep->ExceptionRecord,0,ep->ContextRecord,0);
1452 switch (disp)
1454 case ExceptionContinueExecution:
1455 return EXCEPTION_CONTINUE_EXECUTION;
1456 case ExceptionContinueSearch:
1457 return EXCEPTION_CONTINUE_SEARCH;
1458 default:
1459 fprintf(stderr,"Exception handler is mad\n");
1460 ExitProcess(0);
1463 #endif
1465 os_context_register_t
1466 carry_frame_pointer(os_context_register_t default_value)
1468 struct thread* self = arch_os_get_current_thread();
1469 os_context_register_t bp = self->carried_base_pointer;
1470 return bp ? bp : default_value;
1473 void
1474 wos_install_interrupt_handlers(struct lisp_exception_frame *handler)
1476 #ifdef LISP_FEATURE_X86
1477 handler->next_frame = get_seh_frame();
1478 handler->handler = (void*)exception_handler_wrapper;
1479 set_seh_frame(handler);
1480 #else
1481 static int once = 0;
1482 if (!once++)
1483 AddVectoredExceptionHandler(1,veh);
1484 #endif
1488 * The stubs below are replacements for the windows versions,
1489 * which can -fail- when used in our memory spaces because they
1490 * validate the memory spaces they are passed in a way that
1491 * denies our exception handler a chance to run.
1494 void *memmove(void *dest, const void *src, size_t n)
1496 if (dest < src) {
1497 int i;
1498 for (i = 0; i < n; i++) *(((char *)dest)+i) = *(((char *)src)+i);
1499 } else {
1500 while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1502 return dest;
1505 void *memcpy(void *dest, const void *src, size_t n)
1507 while (n--) *(((char *)dest)+n) = *(((char *)src)+n);
1508 return dest;
1511 char *dirname(char *path)
1513 static char buf[PATH_MAX + 1];
1514 size_t pathlen = strlen(path);
1515 int i;
1517 if (pathlen >= sizeof(buf)) {
1518 lose("Pathname too long in dirname.\n");
1519 return NULL;
1522 strcpy(buf, path);
1523 for (i = pathlen; i >= 0; --i) {
1524 if (buf[i] == '/' || buf[i] == '\\') {
1525 buf[i] = '\0';
1526 break;
1530 return buf;
1533 // 0 - not a socket or other error, 1 - has input, 2 - has no input
1535 socket_input_available(HANDLE socket)
1537 unsigned long count = 0, count_size = 0;
1538 int wsaErrno = GetLastError();
1539 int err = WSAIoctl((SOCKET)socket, FIONREAD, NULL, 0,
1540 &count, sizeof(count), &count_size, NULL, NULL);
1542 int ret;
1544 if (err == 0) {
1545 ret = (count > 0) ? 1 : 2;
1546 } else
1547 ret = 0;
1548 SetLastError(wsaErrno);
1549 return ret;
1552 /* Unofficial but widely used property of console handles: they have
1553 #b11 in two minor bits, opposed to other handles, that are
1554 machine-word-aligned. Properly emulated even on wine.
1556 Console handles are special in many aspects, e.g. they aren't NTDLL
1557 system handles: kernel32 redirects console operations to CSRSS
1558 requests. Using the hack below to distinguish console handles is
1559 justified, as it's the only method that won't hang during
1560 outstanding reads, won't try to lock NT kernel object (if there is
1561 one; console isn't), etc. */
1563 console_handle_p(HANDLE handle)
1565 return (handle != NULL)&&
1566 (handle != INVALID_HANDLE_VALUE)&&
1567 ((((int)(intptr_t)handle)&3)==3);
1570 /* Atomically mark current thread as (probably) doing synchronous I/O
1571 * on handle, if no cancellation is requested yet (and return TRUE),
1572 * otherwise clear thread's I/O cancellation flag and return false.
1574 static
1575 boolean io_begin_interruptible(HANDLE handle)
1577 /* No point in doing it unless OS supports cancellation from other
1578 * threads */
1579 if (!ptr_CancelIoEx)
1580 return 1;
1582 if (!__sync_bool_compare_and_swap(&this_thread->synchronous_io_handle_and_flag,
1583 0, handle)) {
1584 ResetEvent(this_thread->private_events.events[0]);
1585 this_thread->synchronous_io_handle_and_flag = 0;
1586 return 0;
1588 return 1;
1591 static pthread_mutex_t interrupt_io_lock = PTHREAD_MUTEX_INITIALIZER;
1593 /* Unmark current thread as (probably) doing synchronous I/O; if an
1594 * I/O cancellation was requested, postpone it until next
1595 * io_begin_interruptible */
1596 static void
1597 io_end_interruptible(HANDLE handle)
1599 if (!ptr_CancelIoEx)
1600 return;
1601 pthread_mutex_lock(&interrupt_io_lock);
1602 __sync_bool_compare_and_swap(&this_thread->synchronous_io_handle_and_flag,
1603 handle, 0);
1604 pthread_mutex_unlock(&interrupt_io_lock);
1607 /* Documented limit for ReadConsole/WriteConsole is 64K bytes.
1608 Real limit observed on W2K-SP3 is somewhere in between 32KiB and 64Kib...
1610 #define MAX_CONSOLE_TCHARS 16384
1613 win32_write_unicode_console(HANDLE handle, void * buf, int count)
1615 DWORD written = 0;
1616 DWORD nchars;
1617 BOOL result;
1618 nchars = count>>1;
1619 if (nchars>MAX_CONSOLE_TCHARS) nchars = MAX_CONSOLE_TCHARS;
1621 if (!io_begin_interruptible(handle)) {
1622 errno = EINTR;
1623 return -1;
1625 result = WriteConsoleW(handle,buf,nchars,&written,NULL);
1626 io_end_interruptible(handle);
1628 if (result) {
1629 if (!written) {
1630 errno = EINTR;
1631 return -1;
1632 } else {
1633 return 2*written;
1635 } else {
1636 DWORD err = GetLastError();
1637 odxprint(io,"WriteConsole fails => %u\n", err);
1638 errno = (err==ERROR_OPERATION_ABORTED ? EINTR : EIO);
1639 return -1;
1644 * (AK writes:)
1646 * It may be unobvious, but (probably) the most straightforward way of
1647 * providing some sane CL:LISTEN semantics for line-mode console
1648 * channel requires _dedicated input thread_.
1650 * LISTEN should return true iff the next (READ-CHAR) won't have to
1651 * wait. As our console may be shared with another process, entirely
1652 * out of our control, looking at the events in PeekConsoleEvent
1653 * result (and searching for #\Return) doesn't cut it.
1655 * We decided that console input thread must do something smarter than
1656 * a bare loop of continuous ReadConsoleW(). On Unix, user experience
1657 * with the terminal is entirely unaffected by the fact that some
1658 * process does (or doesn't) call read(); the situation on MS Windows
1659 * is different.
1661 * Echo output and line editing present on MS Windows while some
1662 * process is waiting in ReadConsole(); otherwise all input events are
1663 * buffered. If our thread were calling ReadConsole() all the time, it
1664 * would feel like Unix cooked mode.
1666 * But we don't write a Unix emulator here, even if it sometimes feels
1667 * like that; therefore preserving this aspect of console I/O seems a
1668 * good thing to us.
1670 * LISTEN itself becomes trivial with dedicated input thread, but the
1671 * goal stated above -- provide `native' user experience with blocked
1672 * console -- don't play well with this trivial implementation.
1674 * What's currently implemented is a compromise, looking as something
1675 * in between Unix cooked mode and Win32 line mode.
1677 * 1. As long as no console I/O function is called (incl. CL:LISTEN),
1678 * console looks `blocked': no echo, no line editing.
1680 * 2. (READ-CHAR), (READ-SEQUENCE) and other functions doing real
1681 * input result in the ReadConsole request (in a dedicated thread);
1683 * 3. Once ReadConsole is called, it is not cancelled in the
1684 * middle. In line mode, it returns when <Enter> key is hit (or
1685 * something like that happens). Therefore, if line editing and echo
1686 * output had a chance to happen, console won't look `blocked' until
1687 * the line is entered (even if line input was triggered by
1688 * (READ-CHAR)).
1690 * 4. LISTEN may request ReadConsole too (if no other thread is
1691 * reading the console and no data are queued). It's the only case
1692 * when the console becomes `unblocked' without any actual input
1693 * requested by Lisp code. LISTEN check if there is at least one
1694 * input event in PeekConsole queue; unless there is such an event,
1695 * ReadConsole is not triggered by LISTEN.
1697 * 5. Console-reading Lisp thread now may be interrupted immediately;
1698 * ReadConsole call itself, however, continues until the line is
1699 * entered.
1702 struct {
1703 WCHAR buffer[MAX_CONSOLE_TCHARS];
1704 DWORD head, tail;
1705 pthread_mutex_t lock;
1706 pthread_cond_t cond_has_data;
1707 pthread_cond_t cond_has_client;
1708 pthread_t thread;
1709 boolean initialized;
1710 HANDLE handle;
1711 boolean in_progress;
1712 } ttyinput = {.lock = PTHREAD_MUTEX_INITIALIZER};
1714 static void*
1715 tty_read_line_server()
1717 pthread_mutex_lock(&ttyinput.lock);
1718 while (ttyinput.handle) {
1719 DWORD nchars;
1720 BOOL ok;
1722 while (!ttyinput.in_progress)
1723 pthread_cond_wait(&ttyinput.cond_has_client,&ttyinput.lock);
1725 pthread_mutex_unlock(&ttyinput.lock);
1727 ok = ReadConsoleW(ttyinput.handle,
1728 &ttyinput.buffer[ttyinput.tail],
1729 MAX_CONSOLE_TCHARS-ttyinput.tail,
1730 &nchars,NULL);
1732 pthread_mutex_lock(&ttyinput.lock);
1734 if (ok) {
1735 ttyinput.tail += nchars;
1736 pthread_cond_broadcast(&ttyinput.cond_has_data);
1738 ttyinput.in_progress = 0;
1740 pthread_mutex_unlock(&ttyinput.lock);
1741 return NULL;
1744 static boolean
1745 tty_maybe_initialize_unlocked(HANDLE handle)
1747 if (!ttyinput.initialized) {
1748 if (!DuplicateHandle(GetCurrentProcess(),handle,
1749 GetCurrentProcess(),&ttyinput.handle,
1750 0,FALSE,DUPLICATE_SAME_ACCESS)) {
1751 return 0;
1753 pthread_cond_init(&ttyinput.cond_has_data,NULL);
1754 pthread_cond_init(&ttyinput.cond_has_client,NULL);
1755 pthread_create(&ttyinput.thread,NULL,tty_read_line_server,NULL);
1756 ttyinput.initialized = 1;
1758 return 1;
1761 boolean
1762 win32_tty_listen(HANDLE handle)
1764 boolean result = 0;
1765 INPUT_RECORD ir;
1766 DWORD nevents;
1767 pthread_mutex_lock(&ttyinput.lock);
1768 if (!tty_maybe_initialize_unlocked(handle))
1769 result = 0;
1771 if (ttyinput.in_progress) {
1772 result = 0;
1773 } else {
1774 if (ttyinput.head != ttyinput.tail) {
1775 result = 1;
1776 } else {
1777 if (PeekConsoleInput(ttyinput.handle,&ir,1,&nevents) && nevents) {
1778 ttyinput.in_progress = 1;
1779 pthread_cond_broadcast(&ttyinput.cond_has_client);
1783 pthread_mutex_unlock(&ttyinput.lock);
1784 return result;
1787 static int
1788 tty_read_line_client(HANDLE handle, void* buf, int count)
1790 int result = 0;
1791 int nchars = count / sizeof(WCHAR);
1792 sigset_t pendset;
1794 if (!nchars)
1795 return 0;
1796 if (nchars>MAX_CONSOLE_TCHARS)
1797 nchars=MAX_CONSOLE_TCHARS;
1799 count = nchars*sizeof(WCHAR);
1801 pthread_mutex_lock(&ttyinput.lock);
1803 if (!tty_maybe_initialize_unlocked(handle)) {
1804 result = -1;
1805 errno = EIO;
1806 goto unlock;
1809 while (!result) {
1810 while (ttyinput.head == ttyinput.tail) {
1811 if (!io_begin_interruptible(ttyinput.handle)) {
1812 ttyinput.in_progress = 0;
1813 result = -1;
1814 errno = EINTR;
1815 goto unlock;
1816 } else {
1817 if (!ttyinput.in_progress) {
1818 /* We are to wait */
1819 ttyinput.in_progress=1;
1820 /* wake console reader */
1821 pthread_cond_broadcast(&ttyinput.cond_has_client);
1823 pthread_cond_wait(&ttyinput.cond_has_data, &ttyinput.lock);
1824 io_end_interruptible(ttyinput.handle);
1827 result = sizeof(WCHAR)*(ttyinput.tail-ttyinput.head);
1828 if (result > count) {
1829 result = count;
1831 if (result) {
1832 if (result > 0) {
1833 DWORD nch,offset = 0;
1834 LPWSTR ubuf = buf;
1836 memcpy(buf,&ttyinput.buffer[ttyinput.head],count);
1837 ttyinput.head += (result / sizeof(WCHAR));
1838 if (ttyinput.head == ttyinput.tail)
1839 ttyinput.head = ttyinput.tail = 0;
1841 for (nch=0;nch<result/sizeof(WCHAR);++nch) {
1842 if (ubuf[nch]==13) {
1843 ++offset;
1844 } else {
1845 ubuf[nch-offset]=ubuf[nch];
1848 result-=offset*sizeof(WCHAR);
1851 } else {
1852 result = -1;
1853 ttyinput.head = ttyinput.tail = 0;
1854 errno = EIO;
1857 unlock:
1858 pthread_mutex_unlock(&ttyinput.lock);
1859 return result;
1863 win32_read_unicode_console(HANDLE handle, void* buf, int count)
1866 int result;
1867 result = tty_read_line_client(handle,buf,count);
1868 return result;
1871 boolean
1872 win32_maybe_interrupt_io(void* thread)
1874 struct thread *th = thread;
1875 boolean done = 0;
1876 if (ptr_CancelIoEx) {
1877 pthread_mutex_lock(&interrupt_io_lock);
1878 HANDLE h = (HANDLE)
1879 InterlockedExchangePointer((volatile LPVOID *)
1880 &th->synchronous_io_handle_and_flag,
1881 (LPVOID)INVALID_HANDLE_VALUE);
1882 if (h && (h!=INVALID_HANDLE_VALUE)) {
1883 if (console_handle_p(h)) {
1884 pthread_mutex_lock(&ttyinput.lock);
1885 pthread_cond_broadcast(&ttyinput.cond_has_data);
1886 pthread_mutex_unlock(&ttyinput.lock);
1888 if (ptr_CancelSynchronousIo) {
1889 pthread_mutex_lock(&th->os_thread->fiber_lock);
1890 done = !!ptr_CancelSynchronousIo(th->os_thread->fiber_group->handle);
1891 pthread_mutex_unlock(&th->os_thread->fiber_lock);
1893 done |= !!ptr_CancelIoEx(h,NULL);
1895 pthread_mutex_unlock(&interrupt_io_lock);
1897 return done;
1900 static const LARGE_INTEGER zero_large_offset = {.QuadPart = 0LL};
1903 win32_unix_write(HANDLE handle, void * buf, int count)
1905 DWORD written_bytes;
1906 OVERLAPPED overlapped;
1907 struct thread * self = arch_os_get_current_thread();
1908 BOOL waitInGOR;
1909 LARGE_INTEGER file_position;
1910 BOOL seekable;
1911 BOOL ok;
1913 if (console_handle_p(handle))
1914 return win32_write_unicode_console(handle,buf,count);
1916 overlapped.hEvent = self->private_events.events[0];
1917 seekable = SetFilePointerEx(handle,
1918 zero_large_offset,
1919 &file_position,
1920 FILE_CURRENT);
1921 if (seekable) {
1922 overlapped.Offset = file_position.LowPart;
1923 overlapped.OffsetHigh = file_position.HighPart;
1924 } else {
1925 overlapped.Offset = 0;
1926 overlapped.OffsetHigh = 0;
1928 if (!io_begin_interruptible(handle)) {
1929 errno = EINTR;
1930 return -1;
1932 ok = WriteFile(handle, buf, count, &written_bytes, &overlapped);
1933 io_end_interruptible(handle);
1935 if (ok) {
1936 goto done_something;
1937 } else {
1938 DWORD errorCode = GetLastError();
1939 if (errorCode==ERROR_OPERATION_ABORTED) {
1940 GetOverlappedResult(handle,&overlapped,&written_bytes,FALSE);
1941 errno = EINTR;
1942 return -1;
1944 if (errorCode!=ERROR_IO_PENDING) {
1945 errno = EIO;
1946 return -1;
1947 } else {
1948 if(WaitForMultipleObjects(2,self->private_events.events,
1949 FALSE,INFINITE) != WAIT_OBJECT_0) {
1950 CancelIo(handle);
1951 waitInGOR = TRUE;
1952 } else {
1953 waitInGOR = FALSE;
1955 if (!GetOverlappedResult(handle,&overlapped,&written_bytes,waitInGOR)) {
1956 if (GetLastError()==ERROR_OPERATION_ABORTED) {
1957 errno = EINTR;
1958 } else {
1959 errno = EIO;
1961 return -1;
1962 } else {
1963 goto done_something;
1967 done_something:
1968 if (seekable) {
1969 file_position.QuadPart += written_bytes;
1970 SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
1972 return written_bytes;
1976 win32_unix_read(HANDLE handle, void * buf, int count)
1978 OVERLAPPED overlapped = {.Internal=0};
1979 DWORD read_bytes = 0;
1980 struct thread * self = arch_os_get_current_thread();
1981 DWORD errorCode = 0;
1982 BOOL waitInGOR = FALSE;
1983 BOOL ok = FALSE;
1984 LARGE_INTEGER file_position;
1985 BOOL seekable;
1987 if (console_handle_p(handle))
1988 return win32_read_unicode_console(handle,buf,count);
1990 overlapped.hEvent = self->private_events.events[0];
1991 /* If it has a position, we won't try overlapped */
1992 seekable = SetFilePointerEx(handle,
1993 zero_large_offset,
1994 &file_position,
1995 FILE_CURRENT);
1996 if (seekable) {
1997 overlapped.Offset = file_position.LowPart;
1998 overlapped.OffsetHigh = file_position.HighPart;
1999 } else {
2000 overlapped.Offset = 0;
2001 overlapped.OffsetHigh = 0;
2003 if (!io_begin_interruptible(handle)) {
2004 errno = EINTR;
2005 return -1;
2007 ok = ReadFile(handle,buf,count,&read_bytes, &overlapped);
2008 io_end_interruptible(handle);
2009 if (ok) {
2010 /* immediately */
2011 goto done_something;
2012 } else {
2013 errorCode = GetLastError();
2014 if (errorCode == ERROR_HANDLE_EOF ||
2015 errorCode == ERROR_BROKEN_PIPE ||
2016 errorCode == ERROR_NETNAME_DELETED) {
2017 read_bytes = 0;
2018 goto done_something;
2020 if (errorCode==ERROR_OPERATION_ABORTED) {
2021 GetOverlappedResult(handle,&overlapped,&read_bytes,FALSE);
2022 errno = EINTR;
2023 return -1;
2025 if (errorCode!=ERROR_IO_PENDING) {
2026 /* is it some _real_ error? */
2027 errno = EIO;
2028 return -1;
2029 } else {
2030 int ret;
2031 if( (ret = WaitForMultipleObjects(2,self->private_events.events,
2032 FALSE,INFINITE)) != WAIT_OBJECT_0) {
2033 CancelIo(handle);
2034 waitInGOR = TRUE;
2035 /* Waiting for IO only */
2036 } else {
2037 waitInGOR = FALSE;
2039 ok = GetOverlappedResult(handle,&overlapped,&read_bytes,waitInGOR);
2040 if (!ok) {
2041 errorCode = GetLastError();
2042 if (errorCode == ERROR_HANDLE_EOF ||
2043 errorCode == ERROR_BROKEN_PIPE ||
2044 errorCode == ERROR_NETNAME_DELETED) {
2045 read_bytes = 0;
2046 goto done_something;
2047 } else {
2048 if (errorCode == ERROR_OPERATION_ABORTED)
2049 errno = EINTR; /* that's it. */
2050 else
2051 errno = EIO; /* something unspecific */
2052 return -1;
2054 } else
2055 goto done_something;
2058 done_something:
2059 if (seekable) {
2060 file_position.QuadPart += read_bytes;
2061 SetFilePointerEx(handle,file_position,NULL,FILE_BEGIN);
2063 return read_bytes;
2066 /* We used to have a scratch() function listing all symbols needed by
2067 * Lisp. Much rejoicing commenced upon its removal. However, I would
2068 * like cold init to fail aggressively when encountering unused symbols.
2069 * That poses a problem, however, since our C code no longer includes
2070 * any references to symbols in ws2_32.dll, and hence the linker
2071 * completely ignores our request to reference it (--no-as-needed does
2072 * not work). Warm init would later load the DLLs explicitly, but then
2073 * it's too late for an early sanity check. In the unfortunate spirit
2074 * of scratch(), continue to reference some required DLLs explicitly by
2075 * means of one scratch symbol per DLL.
2077 void scratch(void)
2079 /* a function from ws2_32.dll */
2080 shutdown(0, 0);
2082 /* a function from shell32.dll */
2083 SHGetFolderPathA(0, 0, 0, 0, 0);
2085 /* from advapi32.dll */
2086 CryptGenRandom(0, 0, 0);
2089 char *
2090 os_get_runtime_executable_path(int external)
2092 char path[MAX_PATH + 1];
2093 DWORD bufsize = sizeof(path);
2094 DWORD size;
2096 if ((size = GetModuleFileNameA(NULL, path, bufsize)) == 0)
2097 return NULL;
2098 else if (size == bufsize && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2099 return NULL;
2101 return copied_string(path);
2104 #ifdef LISP_FEATURE_SB_THREAD
2107 win32_wait_object_or_signal(HANDLE waitFor)
2109 struct thread * self = arch_os_get_current_thread();
2110 HANDLE handles[2];
2111 handles[0] = waitFor;
2112 handles[1] = self->private_events.events[1];
2113 return
2114 WaitForMultipleObjects(2,handles, FALSE,INFINITE);
2118 * Portability glue for win32 waitable timers.
2120 * One may ask: Why is there a wrapper in C when the calls are so
2121 * obvious that Lisp could do them directly (as it did on Windows)?
2123 * But the answer is that on POSIX platforms, we now emulate the win32
2124 * calls and hide that emulation behind this os_* abstraction.
2126 HANDLE
2127 os_create_wtimer()
2129 return CreateWaitableTimer(0, 0, 0);
2133 os_wait_for_wtimer(HANDLE handle)
2135 return win32_wait_object_or_signal(handle);
2138 void
2139 os_close_wtimer(HANDLE handle)
2141 CloseHandle(handle);
2144 void
2145 os_set_wtimer(HANDLE handle, int sec, int nsec)
2147 /* in units of 100ns, i.e. 0.1us. Negative for relative semantics. */
2148 long long dueTime
2149 = -(((long long) sec) * 10000000
2150 + ((long long) nsec + 99) / 100);
2151 SetWaitableTimer(handle, (LARGE_INTEGER*) &dueTime, 0, 0, 0, 0);
2154 void
2155 os_cancel_wtimer(HANDLE handle)
2157 CancelWaitableTimer(handle);
2159 #endif
2161 /* EOF */