Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/i386/host-mingw32.c @ 56:3c8a44c06a95
Added tag gcc-4.4.5 for changeset 77e2b8dfacca
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:41:23 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
rev | line source |
---|---|
0 | 1 /* mingw32 host-specific hook definitions. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2 Copyright (C) 2004, 2007, 2009 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 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
23 #include "hosthooks.h" | |
24 #include "hosthooks-def.h" | |
25 #include "toplev.h" | |
26 #include "diagnostic.h" | |
27 | |
28 | |
29 #define WIN32_LEAN_AND_MEAN /* Not so important if we have windows.h.gch. */ | |
30 #include <windows.h> | |
31 | |
32 static void * mingw32_gt_pch_get_address (size_t, int); | |
33 static int mingw32_gt_pch_use_address (void *, size_t, int, size_t); | |
34 static size_t mingw32_gt_pch_alloc_granularity (void); | |
35 | |
36 #undef HOST_HOOKS_GT_PCH_GET_ADDRESS | |
37 #define HOST_HOOKS_GT_PCH_GET_ADDRESS mingw32_gt_pch_get_address | |
38 #undef HOST_HOOKS_GT_PCH_USE_ADDRESS | |
39 #define HOST_HOOKS_GT_PCH_USE_ADDRESS mingw32_gt_pch_use_address | |
40 #undef HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY | |
41 #define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY mingw32_gt_pch_alloc_granularity | |
42 | |
43 static inline void w32_error(const char*, const char*, int, const char*); | |
44 | |
45 /* FIXME: Is this big enough? */ | |
46 static const size_t pch_VA_max_size = 128 * 1024 * 1024; | |
47 | |
48 /* Granularity for reserving address space. */ | |
49 static const size_t va_granularity = 0x10000; | |
50 | |
51 /* Print out the GetLastError() translation. */ | |
52 static inline void | |
53 w32_error (const char* function, const char* file, int line, | |
54 const char* my_msg) | |
55 { | |
56 LPSTR w32_msgbuf; | |
57 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | |
58 | FORMAT_MESSAGE_FROM_SYSTEM | |
59 | FORMAT_MESSAGE_IGNORE_INSERTS | |
60 | FORMAT_MESSAGE_MAX_WIDTH_MASK, | |
61 NULL, GetLastError(), | |
62 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
63 (LPSTR) &w32_msgbuf, 0, NULL); | |
64 fprintf(stderr, "internal error in %s, at %s:%d: %s: %s\n", | |
65 function, trim_filename (file), line, my_msg, w32_msgbuf); | |
66 LocalFree ((HLOCAL)w32_msgbuf); | |
67 } | |
68 | |
69 /* Granularity for reserving address space. */ | |
70 static size_t mingw32_gt_pch_alloc_granularity (void) | |
71 { | |
72 return va_granularity; | |
73 } | |
74 | |
75 /* Identify an address that's likely to be free in a subsequent invocation | |
76 of the compiler. The area should be able to hold SIZE bytes. FD is an | |
77 open file descriptor if the host would like to probe with mmap. */ | |
78 | |
79 static void * | |
80 mingw32_gt_pch_get_address (size_t size, int fd ATTRIBUTE_UNUSED) | |
81 { | |
82 void* res; | |
83 size = (size + va_granularity - 1) & ~(va_granularity - 1); | |
84 if (size > pch_VA_max_size) | |
85 return NULL; | |
86 | |
87 /* FIXME: We let system determine base by setting first arg to NULL. | |
88 Allocating at top of available address space avoids unnecessary | |
89 fragmentation of "ordinary" (malloc's) address space but may not | |
90 be safe with delayed load of system dll's. Preferred addresses | |
91 for NT system dlls is in 0x70000000 to 0x78000000 range. | |
92 If we allocate at bottom we need to reserve the address as early | |
93 as possible and at the same point in each invocation. */ | |
94 | |
95 res = VirtualAlloc (NULL, pch_VA_max_size, | |
96 MEM_RESERVE | MEM_TOP_DOWN, | |
97 PAGE_NOACCESS); | |
98 if (!res) | |
99 w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc"); | |
100 else | |
101 /* We do not need the address space for now, so free it. */ | |
102 VirtualFree (res, 0, MEM_RELEASE); | |
103 | |
104 return res; | |
105 } | |
106 | |
107 /* ADDR is an address returned by gt_pch_get_address. Attempt to allocate | |
108 SIZE bytes at the same address and load it with the data from FD at | |
109 OFFSET. Return -1 if we couldn't allocate memory at ADDR, return 0 | |
110 if the memory is allocated but the data not loaded, return 1 if done. */ | |
111 | |
112 static int | |
113 mingw32_gt_pch_use_address (void *addr, size_t size, int fd, | |
114 size_t offset) | |
115 { | |
116 void * mmap_addr; | |
117 HANDLE mmap_handle; | |
118 | |
119 /* Apparently, MS Vista puts unnamed file mapping objects into Global | |
120 namespace when running an application in a Terminal Server | |
121 session. This causes failure since, by default, applications | |
122 don't get SeCreateGlobalPrivilege. We don't need global | |
123 memory sharing so explicitly put object into Local namespace. | |
124 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
125 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
|
126 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
|
127 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
|
128 |
0 | 129 #define OBJECT_NAME_FMT "Local\\MinGWGCCPCH-" |
130 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
131 char* object_name = NULL; |
0 | 132 /* However, the documentation for CreateFileMapping says that on NT4 |
133 and earlier, backslashes are invalid in object name. So, we need | |
134 to check if we are on Windows2000 or higher. */ | |
135 OSVERSIONINFO 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
|
136 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
|
137 |
0 | 138 if (size == 0) |
139 return 0; | |
140 | |
141 /* Offset must be also be a multiple of allocation granularity for | |
142 this to work. We can't change the offset. */ | |
143 if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size) | |
144 return -1; | |
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 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
147 /* 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
|
148 uniquely-named local object if running > 4. */ |
0 | 149 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
|
150 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
|
151 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
152 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
|
153 + 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
|
154 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
|
155 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
|
156 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
|
157 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
158 |
0 | 159 mmap_handle = CreateFileMappingA ((HANDLE) _get_osfhandle (fd), NULL, |
160 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
|
161 object_name); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
162 |
0 | 163 if (mmap_handle == NULL) |
164 { | |
165 w32_error (__FUNCTION__, __FILE__, __LINE__, "CreateFileMapping"); | |
166 return -1; | |
167 } | |
168 mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset, | |
169 size, addr); | |
170 if (mmap_addr != addr) | |
171 { | |
172 w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx"); | |
173 CloseHandle(mmap_handle); | |
174 return -1; | |
175 } | |
176 | |
177 return 1; | |
178 } | |
179 | |
180 const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; |