Fork of Keith's WSL Patch Queue for my Win64 work
Revision | 0e5d279d52ab9a24b3a9afed5f2b6949781defed (tree) |
---|---|
Time | 2019-04-03 07:00:03 |
Author | Keith Marshall <keith@user...> |
Commiter | Keith Marshall |
Add two Win64-specific MinGW Runtime patches.
@@ -0,0 +1,182 @@ | ||
1 | +# HG changeset patch | |
2 | +# Parent 66b461070c4b063621a1af46c9fbf17323ce536a | |
3 | +Make CPU features initialization code x86-64 compliant. | |
4 | + | |
5 | +* cpu_features.sx (CPUID_FLAG) [__x86_64__]: Omit check. | |
6 | +(CFI_OFFSET_BASE): New C preprocessor macro; use it with... | |
7 | +(.cfi_def_cfa, .cfi_def_cfa_offset, .cfi_offset): ...these, to... | |
8 | +[__x86_64__]: ...compute 64-bit offsets, as required, otherwise... | |
9 | +[!__x86_64__]: ...equivalent of existing hard-coded 32-bit offsets. | |
10 | +(FXSAVE_BUF_ALIGN) [__x86_64__]: Specify it as a 64-bit mask value. | |
11 | +(FXSAVE_BUF_ALIGN) [!__x86_64__]: Retain existing 32-bit definition. | |
12 | +(__cpu_features_init): Use x86-64 register names for "rsp", "rbp", and | |
13 | +"rbx", where appropriate; map them, using C preprocessor defines... | |
14 | +[!__x86_64__]: ...to "esp", "ebp", and "ebx" respectively. | |
15 | + | |
16 | +diff --git a/mingwrt/cpu_features.sx b/mingwrt/cpu_features.sx | |
17 | +--- a/mingwrt/cpu_features.sx | |
18 | ++++ b/mingwrt/cpu_features.sx | |
19 | +@@ -40,12 +40,37 @@ | |
20 | + #define RH_FLAG(BITNUM) (1 << ((BITNUM) - 8)) | |
21 | + | |
22 | + #define CPUID_FLAG RX_FLAG(21) /* EFLAGS bit 21 */ | |
23 | + | |
24 | + #define FXSAVE_BUFSIZ 512 | |
25 | ++#define FXTEST_BITS 0x0013C0DE | |
26 | ++ | |
27 | ++#if __x86_64__ | |
28 | ++/* For 64-bit CPUs, we need a 64-bit mask for 16-byte stack alignment, | |
29 | ++ * and .cfi_offset computations must be based on an 8-byte increment, | |
30 | ++ * (3-bit shift), per register push operation... | |
31 | ++ */ | |
32 | ++#define FXSAVE_BUF_ALIGN 0xFFFFFFFFFFFFFFF0 | |
33 | ++#define CFI_OFFSET_BASE(COUNT) ((COUNT) << 3) | |
34 | ++ | |
35 | ++#else /* !__x86_64__ */ | |
36 | ++/* ...whereas, for 32-bit CPUs, we need only a 32-bit mask for 16-byte | |
37 | ++ * stack alignment, and .cfi_offset computations are based on a 4-byte | |
38 | ++ * increment, (2-bit shift), per register push. | |
39 | ++ */ | |
40 | + #define FXSAVE_BUF_ALIGN 0xFFFFFFF0 | |
41 | +-#define FXTEST_BITS 0x0013C0DE | |
42 | ++#define CFI_OFFSET_BASE(COUNT) ((COUNT) << 2) | |
43 | ++ | |
44 | ++/* Additionally, we've adopted the convention of using 64-bit register | |
45 | ++ * names, where appropriate; since these registers don't exist on 32-bit | |
46 | ++ * x86 CPUs, we must map them to corresponding 32-bit register names. | |
47 | ++ */ | |
48 | ++#define rbp ebp | |
49 | ++#define rbx ebx | |
50 | ++#define rsp esp | |
51 | ++ | |
52 | ++#endif /* !__x86_64__ */ | |
53 | + | |
54 | + /* FIXME: is this optimization really worthwhile here? It breaks, | |
55 | + * with older GAS versions, (such as that commonly deployed in the | |
56 | + * GCC-3.4.5 era, and earlier)! | |
57 | + * | |
58 | +@@ -70,11 +95,15 @@ | |
59 | + .def ___cpu_features_init; .scl 2; .type 32; .endef | |
60 | + | |
61 | + ___cpu_features_init: | |
62 | + | |
63 | + .cfi_startproc | |
64 | +-/* Initialization requires use of the CPUID instruction; to check if it is | |
65 | ++/* Initialization requires use of the CPUID instruction; we may safely assume | |
66 | ++ * that it is always available, on 64-bit CPUs, but... | |
67 | ++ */ | |
68 | ++#if !__x86_64__ | |
69 | ++/* ...in the case of 32-bit CPUs, we cannot be sure; thus, to check if it is | |
70 | + * supported by the host CPU, we try to toggle the CPUID flag bit within the | |
71 | + * EFLAGS register, (ultimately leaving it unchanged). | |
72 | + */ | |
73 | + pushf /* save original flags state */ | |
74 | + pushf /* duplicate them in both... */ | |
75 | +@@ -95,18 +124,20 @@ | |
76 | + */ | |
77 | + xor eax, edx /* isolate CPUID_FLAG state */ | |
78 | + test eax, CPUID_FLAG /* did it change? */ | |
79 | + je 90f /* no: quit immediately */ | |
80 | + | |
81 | ++#endif /* !__x86_64__ */ | |
82 | ++ | |
83 | + /* If we're still here, then we may safely interrogate the CPU, using | |
84 | + * the CPUID instruction, to identify various CPU features which may, or | |
85 | + * may not, be supported, but first... | |
86 | + */ | |
87 | +- push ebx /* ...we MUST preserve this! */ | |
88 | ++ push rbx /* ...we MUST preserve this! */ | |
89 | + | |
90 | +-.cfi_def_cfa_offset 8 | |
91 | +-.cfi_offset ebx, -8 | |
92 | ++.cfi_def_cfa_offset CFI_OFFSET_BASE(2) | |
93 | ++.cfi_offset ebx, -CFI_OFFSET_BASE(2) | |
94 | + | |
95 | + /* First, we must perform a level zero CPUID enquiry, to determine the | |
96 | + * maximum level of interrogation which is supported. | |
97 | + */ | |
98 | + xor eax, eax /* zero request level code */ | |
99 | +@@ -168,48 +199,48 @@ 15: | |
100 | + /* We must create a local stack frame, with the stack pointer aligned to a | |
101 | + * sixteen byte boundary, in which to allocate an FXSAVE buffer; (failure to | |
102 | + * align this correctly will raise an unhandled exception, and GCC cannot be | |
103 | + * trusted to get this right in C language code). | |
104 | + */ | |
105 | +- push ebp | |
106 | +- mov ebp, esp | |
107 | ++ push rbp | |
108 | ++ mov rbp, rsp | |
109 | + | |
110 | +-.cfi_def_cfa ebp, 12 | |
111 | +-.cfi_offset ebp, -12 | |
112 | ++.cfi_def_cfa rbp, CFI_OFFSET_BASE(3) | |
113 | ++.cfi_offset rbp, -CFI_OFFSET_BASE(3) | |
114 | + | |
115 | +- sub esp, FXSAVE_BUFSIZ | |
116 | +- and esp, FXSAVE_BUF_ALIGN | |
117 | ++ sub rsp, FXSAVE_BUFSIZ | |
118 | ++ and rsp, FXSAVE_BUF_ALIGN | |
119 | + | |
120 | + /* Save the FPU state, and immediately attempt to restore it with some of | |
121 | + * the SSE specific control flags inverted. | |
122 | + */ | |
123 | +- fxsave [esp] | |
124 | +- mov ebx, DWORD PTR 200[esp] | |
125 | +- xor DWORD PTR 200[esp], FXTEST_BITS | |
126 | +- fxrstor [esp] | |
127 | ++ fxsave [rsp] | |
128 | ++ mov ebx, DWORD PTR 200[rsp] | |
129 | ++ xor DWORD PTR 200[rsp], FXTEST_BITS | |
130 | ++ fxrstor [rsp] | |
131 | + | |
132 | + /* Return the FXSAVE buffer to its original state, then overwrite it with | |
133 | + * the state just restored. | |
134 | + */ | |
135 | +- mov DWORD PTR 200[esp], ebx | |
136 | +- fxsave [esp] | |
137 | ++ mov DWORD PTR 200[rsp], ebx | |
138 | ++ fxsave [rsp] | |
139 | + | |
140 | + /* Explicitly restore the original FPU state, while noting (in EBX) the | |
141 | + * state of those SSE control flags, as retrieved from the FPU itself, | |
142 | + * after the attempt to change them. | |
143 | + */ | |
144 | +- xchg DWORD PTR 200[esp], ebx | |
145 | +- fxrstor [esp] | |
146 | ++ xchg DWORD PTR 200[rsp], ebx | |
147 | ++ fxrstor [rsp] | |
148 | + | |
149 | + /* Check if the operating system actually allowed the requested change of | |
150 | + * the SSE control flags, then discard the local stack frame. | |
151 | + */ | |
152 | +- xor ebx, DWORD PTR 200[esp] | |
153 | ++ xor ebx, DWORD PTR 200[rsp] | |
154 | + leave | |
155 | + | |
156 | +-.cfi_restore ebp | |
157 | +-.cfi_def_cfa esp, 8 | |
158 | ++.cfi_restore rbp | |
159 | ++.cfi_def_cfa rsp, CFI_OFFSET_BASE(2) | |
160 | + | |
161 | + cmp ebx, FXTEST_BITS /* SSE flags were changed? */ | |
162 | + jne 20f /* no: skip SSE detection */ | |
163 | + | |
164 | + /* If we're still here, then the operating system should support SSE; | |
165 | +@@ -268,14 +299,14 @@ 30: chk CPUID_CAP(3DNOWP) | |
166 | + */ | |
167 | + or DWORD PTR ___cpu_features, eax | |
168 | + | |
169 | + /* ...we restore the preserved state of the EBX register... | |
170 | + */ | |
171 | +-80: pop ebx | |
172 | ++80: pop rbx | |
173 | + | |
174 | +-.cfi_restore ebx | |
175 | +-.cfi_def_cfa_offset 4 | |
176 | ++.cfi_restore rbx | |
177 | ++.cfi_def_cfa_offset CFI_OFFSET_BASE(1) | |
178 | + | |
179 | + /* ...and return to the C runtime initialization procedure. | |
180 | + */ | |
181 | + 90: ret | |
182 | + |
@@ -1,3 +1,5 @@ | ||
1 | +win64-time-typedef.patch #+win64 | |
2 | +cpu-features-x86-64.patch #+win64 | |
1 | 3 | alloca-testing.patch #+void #-void |
2 | 4 | winerror-winsock2-update.patch #+void #-void |
3 | 5 | winnls-self-contained.patch #+self-contained |
@@ -0,0 +1,85 @@ | ||
1 | +# HG changeset patch | |
2 | +# Parent 14380a28681bc457a304fdab734113a16a40a0ba | |
3 | +Correct time_t definition for Win64. | |
4 | + | |
5 | +* include/sys/types.h [_WIN64] (time_t): Map it to __time64_t. | |
6 | +[_WIN64 && _USE_32BIT_TIME_T]: Emit misuse warning. | |
7 | + | |
8 | +diff --git a/mingwrt/include/sys/types.h b/mingwrt/include/sys/types.h | |
9 | +--- a/mingwrt/include/sys/types.h | |
10 | ++++ b/mingwrt/include/sys/types.h | |
11 | +@@ -5,11 +5,11 @@ | |
12 | + * | |
13 | + * $Id$ | |
14 | + * | |
15 | + * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> | |
16 | + * Copyright (C) 1997-1999, 2001, 2003, 2004, 2008, 2011, 2014-2016, | |
17 | +- * MinGW.org Project. | |
18 | ++ * 2018, MinGW.org Project. | |
19 | + * | |
20 | + * | |
21 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
22 | + * copy of this software and associated documentation files (the "Software"), | |
23 | + * to deal in the Software without restriction, including without limitation | |
24 | +@@ -131,27 +131,52 @@ | |
25 | + #endif | |
26 | + #undef __need_ssize_t | |
27 | + | |
28 | + #if ! defined __have_typedef_time_t \ | |
29 | + && ( defined _SYS_TYPES_H || defined __need_time_t ) | |
30 | +- /* Current versions of MSVC define time_t ambiguously, in terms of | |
31 | +- * one of the following unambiguous internal types: | |
32 | ++ /* FIXME: Is the following correct for linking with UCRTBASE.DLL? | |
33 | ++ * | |
34 | ++ * Current versions of MSVC define time_t, (ambiguously in 32-bit | |
35 | ++ * versions), in terms of one or other of the following unambiguous | |
36 | ++ * internal types: | |
37 | + */ | |
38 | + typedef __int32 __time32_t; /* unambiguous 32-bit time_t */ | |
39 | + typedef __int64 __time64_t; /* unambiguous 64-bit time_t */ | |
40 | + | |
41 | +-# if __MSVCRT_VERSION__ < __MSVCR80_DLL || defined _USE_32BIT_TIME_T | |
42 | +- /* From MSVCR80.DLL onwards, Microsoft have royally messed up the | |
43 | +- * definition of time_t; maintain POSIX consistency, (as MSVCRT.DLL | |
44 | +- * itself does), unless the user is explicitly using one of these | |
45 | +- * brain damaged DLL variants, and has not elected to retain the | |
46 | +- * 32-bit time_t representation. | |
47 | ++# if defined _WIN64 | |
48 | ++ /* According to MSDN, there is no ambiguity on the Win64 platform; | |
49 | ++ * time_t is always represented as a 64-bit data type... | |
50 | ++ */ | |
51 | ++ typedef __time64_t time_t; | |
52 | ++ | |
53 | ++# ifdef _USE_32BIT_TIME_T | |
54 | ++ /* ...and this feature test, which MSDN documents as necessary | |
55 | ++ * to retain legacy 32-bit time_t on Win32, is unsupported... | |
56 | ++ */ | |
57 | ++# warning "_WIN64 does not support the _USE_32BIT_TIME_T feature." | |
58 | ++# undef _USE_32BIT_TIME_T | |
59 | ++# endif | |
60 | ++ /* ...whereas, on the 32-bit platform, time_t may be represented as | |
61 | ++ * either a 32-bit or a 64-bit data type. According to current MSDN | |
62 | ++ * documentation, this ambiguity is resolved by the _USE_32BIT_TIME_T | |
63 | ++ * feature test macro; if defined, time_t is represented as a 32-bit | |
64 | ++ * data type, otherwise it becomes 64-bit. However, this is untrue | |
65 | ++ * for MSVCRT.DLL, and for any non-free legacy MSVCRxx.DLL which | |
66 | ++ * predates MSVCR80.DLL; thus... | |
67 | ++ */ | |
68 | ++# elif defined _USE_32BIT_TIME_T || __MSVCRT_VERSION__ < __MSVCR80_DLL | |
69 | ++ /* ...we resolve the ambiguity in favour of 32-bit time_t for all | |
70 | ++ * applications which specify _USE_32_BIT_TIME_T, and for all which | |
71 | ++ * fail to specify a linking preference for a non-free MSVCRxx.DLL | |
72 | ++ * from MSVCR80.DLL onwards... | |
73 | + */ | |
74 | + typedef __time32_t time_t; | |
75 | + | |
76 | + # else | |
77 | +- /* Microsoft's brain damaged default, from MSVCR80.DLL onwards. | |
78 | ++ /* ...we adopt the 64-bit default, which is applicable when linking | |
79 | ++ * with non-free MSVCRxx.DLL from MSVCR80.DLL onwards, provided that | |
80 | ++ * the _USE_32BIT_TIME_T feature has not been selected. | |
81 | + */ | |
82 | + typedef __time64_t time_t; | |
83 | + # endif | |
84 | + # if __GCC__ < 4 | |
85 | + /* Assume any compiler which is not GCC-4.x or newer may require |