Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/i386/host-mingw32.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 /* mingw32 host-specific hook definitions. |
131 | 2 Copyright (C) 2004-2018 Free Software Foundation, Inc. |
0 | 3 |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published | |
8 by the Free Software Foundation; either version 3, or (at your | |
9 option) any later version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
14 License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
131 | 20 #define IN_TARGET_CODE 1 |
21 | |
0 | 22 #include "config.h" |
23 #include "system.h" | |
24 #include "coretypes.h" | |
111 | 25 #include "diagnostic.h" |
0 | 26 #include "hosthooks.h" |
27 #include "hosthooks-def.h" | |
28 | |
29 | |
30 #define WIN32_LEAN_AND_MEAN /* Not so important if we have windows.h.gch. */ | |
31 #include <windows.h> | |
111 | 32 #include <stdlib.h> |
0 | 33 |
34 static void * mingw32_gt_pch_get_address (size_t, int); | |
35 static int mingw32_gt_pch_use_address (void *, size_t, int, size_t); | |
36 static size_t mingw32_gt_pch_alloc_granularity (void); | |
37 | |
38 #undef HOST_HOOKS_GT_PCH_GET_ADDRESS | |
39 #define HOST_HOOKS_GT_PCH_GET_ADDRESS mingw32_gt_pch_get_address | |
40 #undef HOST_HOOKS_GT_PCH_USE_ADDRESS | |
41 #define HOST_HOOKS_GT_PCH_USE_ADDRESS mingw32_gt_pch_use_address | |
42 #undef HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY | |
43 #define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY mingw32_gt_pch_alloc_granularity | |
44 | |
45 static inline void w32_error(const char*, const char*, int, const char*); | |
46 | |
47 /* FIXME: Is this big enough? */ | |
48 static const size_t pch_VA_max_size = 128 * 1024 * 1024; | |
49 | |
50 /* Granularity for reserving address space. */ | |
111 | 51 static size_t va_granularity = 0x10000; |
0 | 52 |
53 /* Print out the GetLastError() translation. */ | |
54 static inline void | |
55 w32_error (const char* function, const char* file, int line, | |
56 const char* my_msg) | |
57 { | |
58 LPSTR w32_msgbuf; | |
59 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | |
60 | FORMAT_MESSAGE_FROM_SYSTEM | |
61 | FORMAT_MESSAGE_IGNORE_INSERTS | |
62 | FORMAT_MESSAGE_MAX_WIDTH_MASK, | |
63 NULL, GetLastError(), | |
64 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
65 (LPSTR) &w32_msgbuf, 0, NULL); | |
66 fprintf(stderr, "internal error in %s, at %s:%d: %s: %s\n", | |
67 function, trim_filename (file), line, my_msg, w32_msgbuf); | |
68 LocalFree ((HLOCAL)w32_msgbuf); | |
69 } | |
70 | |
71 /* Granularity for reserving address space. */ | |
111 | 72 static size_t |
73 mingw32_gt_pch_alloc_granularity (void) | |
0 | 74 { |
111 | 75 SYSTEM_INFO si; |
76 | |
77 GetSystemInfo (&si); | |
78 va_granularity = (size_t) si.dwAllocationGranularity; | |
79 | |
0 | 80 return va_granularity; |
81 } | |
82 | |
83 /* Identify an address that's likely to be free in a subsequent invocation | |
84 of the compiler. The area should be able to hold SIZE bytes. FD is an | |
85 open file descriptor if the host would like to probe with mmap. */ | |
86 | |
87 static void * | |
111 | 88 mingw32_gt_pch_get_address (size_t size, int) |
0 | 89 { |
90 void* res; | |
91 size = (size + va_granularity - 1) & ~(va_granularity - 1); | |
92 if (size > pch_VA_max_size) | |
93 return NULL; | |
94 | |
95 /* FIXME: We let system determine base by setting first arg to NULL. | |
96 Allocating at top of available address space avoids unnecessary | |
97 fragmentation of "ordinary" (malloc's) address space but may not | |
98 be safe with delayed load of system dll's. Preferred addresses | |
99 for NT system dlls is in 0x70000000 to 0x78000000 range. | |
100 If we allocate at bottom we need to reserve the address as early | |
101 as possible and at the same point in each invocation. */ | |
102 | |
103 res = VirtualAlloc (NULL, pch_VA_max_size, | |
104 MEM_RESERVE | MEM_TOP_DOWN, | |
105 PAGE_NOACCESS); | |
106 if (!res) | |
107 w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc"); | |
108 else | |
109 /* We do not need the address space for now, so free it. */ | |
110 VirtualFree (res, 0, MEM_RELEASE); | |
111 | |
112 return res; | |
113 } | |
114 | |
115 /* ADDR is an address returned by gt_pch_get_address. Attempt to allocate | |
116 SIZE bytes at the same address and load it with the data from FD at | |
117 OFFSET. Return -1 if we couldn't allocate memory at ADDR, return 0 | |
118 if the memory is allocated but the data not loaded, return 1 if done. */ | |
119 | |
120 static int | |
121 mingw32_gt_pch_use_address (void *addr, size_t size, int fd, | |
122 size_t offset) | |
123 { | |
124 void * mmap_addr; | |
125 HANDLE mmap_handle; | |
111 | 126 |
0 | 127 /* Apparently, MS Vista puts unnamed file mapping objects into Global |
128 namespace when running an application in a Terminal Server | |
129 session. This causes failure since, by default, applications | |
130 don't get SeCreateGlobalPrivilege. We don't need global | |
131 memory sharing so explicitly put object into Local namespace. | |
132 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
133 If multiple concurrent GCC processes are using PCH functionality, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
134 MapViewOfFileEx returns "Access Denied" error. So we ensure the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
135 session-wide mapping name is unique by appending process ID. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
136 |
0 | 137 #define OBJECT_NAME_FMT "Local\\MinGWGCCPCH-" |
138 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
139 char* object_name = NULL; |
0 | 140 /* However, the documentation for CreateFileMapping says that on NT4 |
141 and earlier, backslashes are invalid in object name. So, we need | |
142 to check if we are on Windows2000 or higher. */ | |
143 OSVERSIONINFO version_info; | |
111 | 144 int r; |
145 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
146 version_info.dwOSVersionInfoSize = sizeof (version_info); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
147 |
0 | 148 if (size == 0) |
149 return 0; | |
150 | |
151 /* Offset must be also be a multiple of allocation granularity for | |
152 this to work. We can't change the offset. */ | |
153 if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size) | |
154 return -1; | |
155 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
156 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
157 /* Determine the version of Windows we are running on and use a |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
158 uniquely-named local object if running > 4. */ |
0 | 159 GetVersionEx (&version_info); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
160 if (version_info.dwMajorVersion > 4) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
161 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
162 char local_object_name [sizeof (OBJECT_NAME_FMT) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
163 + sizeof (DWORD) * 2]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
164 snprintf (local_object_name, sizeof (local_object_name), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
165 OBJECT_NAME_FMT "%lx", GetCurrentProcessId()); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
166 object_name = local_object_name; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
167 } |
0 | 168 mmap_handle = CreateFileMappingA ((HANDLE) _get_osfhandle (fd), NULL, |
169 PAGE_WRITECOPY | SEC_COMMIT, 0, 0, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
170 object_name); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
171 |
0 | 172 if (mmap_handle == NULL) |
173 { | |
174 w32_error (__FUNCTION__, __FILE__, __LINE__, "CreateFileMapping"); | |
175 return -1; | |
176 } | |
111 | 177 |
178 /* Retry five times, as here might occure a race with multiple gcc's | |
179 instances at same time. */ | |
180 for (r = 0; r < 5; r++) | |
181 { | |
182 mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset, | |
183 size, addr); | |
184 if (mmap_addr == addr) | |
185 break; | |
186 if (r != 4) | |
187 Sleep (500); | |
188 } | |
189 | |
0 | 190 if (mmap_addr != addr) |
191 { | |
192 w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx"); | |
193 CloseHandle(mmap_handle); | |
194 return -1; | |
195 } | |
196 | |
197 return 1; | |
198 } | |
199 | |
200 const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; |