Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/i386/winnt.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
rev | line source |
---|---|
0 | 1 /* Subroutines for insn-output.c for Windows NT. |
2 Contributed by Douglas Rupp (drupp@cs.washington.edu) | |
3 Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
4 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
0 | 5 |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #include "config.h" | |
23 #include "system.h" | |
24 #include "coretypes.h" | |
25 #include "tm.h" | |
26 #include "rtl.h" | |
27 #include "regs.h" | |
28 #include "hard-reg-set.h" | |
29 #include "output.h" | |
30 #include "tree.h" | |
31 #include "flags.h" | |
32 #include "tm_p.h" | |
33 #include "toplev.h" | |
34 #include "hashtab.h" | |
35 #include "langhooks.h" | |
36 #include "ggc.h" | |
37 #include "target.h" | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
38 #include "lto-streamer.h" |
0 | 39 |
40 /* i386/PE specific attribute support. | |
41 | |
42 i386/PE has two new attributes: | |
43 dllexport - for exporting a function/variable that will live in a dll | |
44 dllimport - for importing a function/variable from a dll | |
45 | |
46 Microsoft allows multiple declspecs in one __declspec, separating | |
47 them with spaces. We do NOT support this. Instead, use __declspec | |
48 multiple times. | |
49 */ | |
50 | |
51 /* Handle a "shared" attribute; | |
52 arguments as in struct attribute_spec.handler. */ | |
53 tree | |
54 ix86_handle_shared_attribute (tree *node, tree name, | |
55 tree args ATTRIBUTE_UNUSED, | |
56 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) | |
57 { | |
58 if (TREE_CODE (*node) != VAR_DECL) | |
59 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
60 warning (OPT_Wattributes, "%qE attribute only applies to variables", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
61 name); |
0 | 62 *no_add_attrs = true; |
63 } | |
64 | |
65 return NULL_TREE; | |
66 } | |
67 | |
68 /* Handle a "selectany" attribute; | |
69 arguments as in struct attribute_spec.handler. */ | |
70 tree | |
71 ix86_handle_selectany_attribute (tree *node, tree name, | |
72 tree args ATTRIBUTE_UNUSED, | |
73 int flags ATTRIBUTE_UNUSED, | |
74 bool *no_add_attrs) | |
75 { | |
76 /* The attribute applies only to objects that are initialized and have | |
77 external linkage. However, we may not know about initialization | |
78 until the language frontend has processed the decl. We'll check for | |
79 initialization later in encode_section_info. */ | |
80 if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node)) | |
81 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
82 error ("%qE attribute applies only to initialized variables" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
83 " with external linkage", name); |
0 | 84 *no_add_attrs = true; |
85 } | |
86 | |
87 return NULL_TREE; | |
88 } | |
89 | |
90 | |
91 /* Return the type that we should use to determine if DECL is | |
92 imported or exported. */ | |
93 | |
94 static tree | |
95 associated_type (tree decl) | |
96 { | |
97 return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)) | |
98 ? DECL_CONTEXT (decl) : NULL_TREE); | |
99 } | |
100 | |
101 /* Return true if DECL should be a dllexport'd object. */ | |
102 | |
103 static bool | |
104 i386_pe_determine_dllexport_p (tree decl) | |
105 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
106 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
107 return false; |
0 | 108 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
109 /* Don't export local clones of dllexports. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
110 if (!TREE_PUBLIC (decl)) |
0 | 111 return false; |
112 | |
113 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) | |
114 return true; | |
115 | |
116 return false; | |
117 } | |
118 | |
119 /* Return true if DECL should be a dllimport'd object. */ | |
120 | |
121 static bool | |
122 i386_pe_determine_dllimport_p (tree decl) | |
123 { | |
124 tree assoc; | |
125 | |
126 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) | |
127 return false; | |
128 | |
129 if (DECL_DLLIMPORT_P (decl)) | |
130 return true; | |
131 | |
132 /* The DECL_DLLIMPORT_P flag was set for decls in the class definition | |
133 by targetm.cxx.adjust_class_at_definition. Check again to emit | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
134 error message if the class attribute has been overridden by an |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
135 out-of-class definition of static data. */ |
0 | 136 assoc = associated_type (decl); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
137 if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
138 && TREE_CODE (decl) == VAR_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
139 && TREE_STATIC (decl) && TREE_PUBLIC (decl) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
140 && !DECL_EXTERNAL (decl) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
141 /* vtable's are linkonce constants, so defining a vtable is not |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
142 an error as long as we don't try to import it too. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
143 && !DECL_VIRTUAL_P (decl)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
144 error ("definition of static data member %q+D of " |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
145 "dllimport'd class", decl); |
0 | 146 |
147 return false; | |
148 } | |
149 | |
150 /* Handle the -mno-fun-dllimport target switch. */ | |
151 | |
152 bool | |
153 i386_pe_valid_dllimport_attribute_p (const_tree decl) | |
154 { | |
155 if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL) | |
156 return false; | |
157 return true; | |
158 } | |
159 | |
160 /* Return string which is the function name, identified by ID, modified | |
161 with a suffix consisting of an atsign (@) followed by the number of | |
162 bytes of arguments. If ID is NULL use the DECL_NAME as base. If | |
163 FASTCALL is true, also add the FASTCALL_PREFIX. | |
164 Return NULL if no change required. */ | |
165 | |
166 static tree | |
167 gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall) | |
168 { | |
169 HOST_WIDE_INT total = 0; | |
170 const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl)); | |
171 char *new_str, *p; | |
172 tree type = TREE_TYPE (decl); | |
173 tree arg; | |
174 function_args_iterator args_iter; | |
175 | |
176 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); | |
177 | |
178 if (prototype_p (type)) | |
179 { | |
180 /* This attribute is ignored for variadic functions. */ | |
181 if (stdarg_p (type)) | |
182 return NULL_TREE; | |
183 | |
184 /* Quit if we hit an incomplete type. Error is reported | |
185 by convert_arguments in c-typeck.c or cp/typeck.c. */ | |
186 FOREACH_FUNCTION_ARGS(type, arg, args_iter) | |
187 { | |
188 HOST_WIDE_INT parm_size; | |
189 HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT; | |
190 | |
191 if (! COMPLETE_TYPE_P (arg)) | |
192 break; | |
193 | |
194 parm_size = int_size_in_bytes (arg); | |
195 if (parm_size < 0) | |
196 break; | |
197 | |
198 /* Must round up to include padding. This is done the same | |
199 way as in store_one_arg. */ | |
200 parm_size = ((parm_size + parm_boundary_bytes - 1) | |
201 / parm_boundary_bytes * parm_boundary_bytes); | |
202 total += parm_size; | |
203 } | |
204 } | |
205 /* Assume max of 8 base 10 digits in the suffix. */ | |
206 p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1); | |
207 if (fastcall) | |
208 *p++ = FASTCALL_PREFIX; | |
209 sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total); | |
210 | |
211 return get_identifier (new_str); | |
212 } | |
213 | |
214 /* Maybe decorate and get a new identifier for the DECL of a stdcall or | |
215 fastcall function. The original identifier is supplied in ID. */ | |
216 | |
217 static tree | |
218 i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id) | |
219 { | |
220 tree new_id = NULL_TREE; | |
221 | |
222 if (TREE_CODE (decl) == FUNCTION_DECL) | |
223 { | |
224 tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); | |
225 if (lookup_attribute ("stdcall", type_attributes)) | |
226 new_id = gen_stdcall_or_fastcall_suffix (decl, id, false); | |
227 else if (lookup_attribute ("fastcall", type_attributes)) | |
228 new_id = gen_stdcall_or_fastcall_suffix (decl, id, true); | |
229 } | |
230 | |
231 return new_id; | |
232 } | |
233 | |
234 /* This is used as a target hook to modify the DECL_ASSEMBLER_NAME | |
235 in the language-independent default hook | |
236 langhooks,c:lhd_set_decl_assembler_name () | |
237 and in cp/mangle,c:mangle_decl (). */ | |
238 tree | |
239 i386_pe_mangle_decl_assembler_name (tree decl, tree id) | |
240 { | |
241 tree new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, id); | |
242 | |
243 return (new_id ? new_id : id); | |
244 } | |
245 | |
246 void | |
247 i386_pe_encode_section_info (tree decl, rtx rtl, int first) | |
248 { | |
249 rtx symbol; | |
250 int flags; | |
251 | |
252 /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above. */ | |
253 default_encode_section_info (decl, rtl, first); | |
254 | |
255 /* Careful not to prod global register variables. */ | |
256 if (!MEM_P (rtl)) | |
257 return; | |
258 | |
259 symbol = XEXP (rtl, 0); | |
260 gcc_assert (GET_CODE (symbol) == SYMBOL_REF); | |
261 | |
262 switch (TREE_CODE (decl)) | |
263 { | |
264 case FUNCTION_DECL: | |
265 /* FIXME: Imported stdcall names are not modified by the Ada frontend. | |
266 Check and decorate the RTL name now. */ | |
267 if (strcmp (lang_hooks.name, "GNU Ada") == 0) | |
268 { | |
269 tree new_id; | |
270 tree old_id = DECL_ASSEMBLER_NAME (decl); | |
271 const char* asm_str = IDENTIFIER_POINTER (old_id); | |
272 /* Do not change the identifier if a verbatim asmspec | |
273 or if stdcall suffix already added. */ | |
274 if (!(*asm_str == '*' || strchr (asm_str, '@')) | |
275 && (new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, | |
276 old_id))) | |
277 XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id); | |
278 } | |
279 break; | |
280 | |
281 case VAR_DECL: | |
282 if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl))) | |
283 { | |
284 if (DECL_INITIAL (decl) | |
285 /* If an object is initialized with a ctor, the static | |
286 initialization and destruction code for it is present in | |
287 each unit defining the object. The code that calls the | |
288 ctor is protected by a link-once guard variable, so that | |
289 the object still has link-once semantics, */ | |
290 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
291 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); |
0 | 292 else |
293 error ("%q+D:'selectany' attribute applies only to " | |
294 "initialized objects", decl); | |
295 } | |
296 break; | |
297 | |
298 default: | |
299 return; | |
300 } | |
301 | |
302 /* Mark the decl so we can tell from the rtl whether the object is | |
303 dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes | |
304 handles dllexport/dllimport override semantics. */ | |
305 flags = (SYMBOL_REF_FLAGS (symbol) & | |
306 ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT)); | |
307 if (i386_pe_determine_dllexport_p (decl)) | |
308 flags |= SYMBOL_FLAG_DLLEXPORT; | |
309 else if (i386_pe_determine_dllimport_p (decl)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
310 flags |= SYMBOL_FLAG_DLLIMPORT; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
311 |
0 | 312 SYMBOL_REF_FLAGS (symbol) = flags; |
313 } | |
314 | |
315 bool | |
316 i386_pe_binds_local_p (const_tree exp) | |
317 { | |
318 /* PE does not do dynamic binding. Indeed, the only kind of | |
319 non-local reference comes from a dllimport'd symbol. */ | |
320 if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL) | |
321 && DECL_DLLIMPORT_P (exp)) | |
322 return false; | |
323 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
324 /* Or a weak one, now that they are supported. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
325 if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
326 && DECL_WEAK (exp)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
327 /* But x64 gets confused and attempts to use unsupported GOTPCREL |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
328 relocations if we tell it the truth, so we still return true in |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
329 that case until the deeper problem can be fixed. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
330 return (TARGET_64BIT && DEFAULT_ABI == MS_ABI); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
331 |
0 | 332 return true; |
333 } | |
334 | |
335 /* Also strip the fastcall prefix and stdcall suffix. */ | |
336 | |
337 const char * | |
338 i386_pe_strip_name_encoding_full (const char *str) | |
339 { | |
340 const char *p; | |
341 const char *name = default_strip_name_encoding (str); | |
342 | |
343 /* Strip leading '@' on fastcall symbols. */ | |
344 if (*name == '@') | |
345 name++; | |
346 | |
347 /* Strip trailing "@n". */ | |
348 p = strchr (name, '@'); | |
349 if (p) | |
350 return ggc_alloc_string (name, p - name); | |
351 | |
352 return name; | |
353 } | |
354 | |
355 void | |
356 i386_pe_unique_section (tree decl, int reloc) | |
357 { | |
358 int len; | |
359 const char *name, *prefix; | |
360 char *string; | |
361 | |
362 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
363 name = i386_pe_strip_name_encoding_full (name); | |
364 | |
365 /* The object is put in, for example, section .text$foo. | |
366 The linker will then ultimately place them in .text | |
367 (everything from the $ on is stripped). Don't put | |
368 read-only data in .rdata section to avoid a PE linker | |
369 bug when .rdata$* grouped sections are used in code | |
370 without a .rdata section. */ | |
371 if (TREE_CODE (decl) == FUNCTION_DECL) | |
372 prefix = ".text$"; | |
373 else if (decl_readonly_section (decl, reloc)) | |
374 prefix = ".rdata$"; | |
375 else | |
376 prefix = ".data$"; | |
377 len = strlen (name) + strlen (prefix); | |
378 string = XALLOCAVEC (char, len + 1); | |
379 sprintf (string, "%s%s", prefix, name); | |
380 | |
381 DECL_SECTION_NAME (decl) = build_string (len, string); | |
382 } | |
383 | |
384 /* Select a set of attributes for section NAME based on the properties | |
385 of DECL and whether or not RELOC indicates that DECL's initializer | |
386 might contain runtime relocations. | |
387 | |
388 We make the section read-only and executable for a function decl, | |
389 read-only for a const data decl, and writable for a non-const data decl. | |
390 | |
391 If the section has already been defined, to not allow it to have | |
392 different attributes, as (1) this is ambiguous since we're not seeing | |
393 all the declarations up front and (2) some assemblers (e.g. SVR4) | |
394 do not recognize section redefinitions. */ | |
395 /* ??? This differs from the "standard" PE implementation in that we | |
396 handle the SHARED variable attribute. Should this be done for all | |
397 PE targets? */ | |
398 | |
399 #define SECTION_PE_SHARED SECTION_MACH_DEP | |
400 | |
401 unsigned int | |
402 i386_pe_section_type_flags (tree decl, const char *name, int reloc) | |
403 { | |
404 static htab_t htab; | |
405 unsigned int flags; | |
406 unsigned int **slot; | |
407 | |
408 /* The names we put in the hashtable will always be the unique | |
409 versions given to us by the stringtable, so we can just use | |
410 their addresses as the keys. */ | |
411 if (!htab) | |
412 htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL); | |
413 | |
414 if (decl && TREE_CODE (decl) == FUNCTION_DECL) | |
415 flags = SECTION_CODE; | |
416 else if (decl && decl_readonly_section (decl, reloc)) | |
417 flags = 0; | |
418 else if (current_function_decl | |
419 && cfun | |
420 && crtl->subsections.unlikely_text_section_name | |
421 && strcmp (name, crtl->subsections.unlikely_text_section_name) == 0) | |
422 flags = SECTION_CODE; | |
423 else if (!decl | |
424 && (!current_function_decl || !cfun) | |
425 && strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0) | |
426 flags = SECTION_CODE; | |
427 else | |
428 { | |
429 flags = SECTION_WRITE; | |
430 | |
431 if (decl && TREE_CODE (decl) == VAR_DECL | |
432 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl))) | |
433 flags |= SECTION_PE_SHARED; | |
434 } | |
435 | |
436 if (decl && DECL_ONE_ONLY (decl)) | |
437 flags |= SECTION_LINKONCE; | |
438 | |
439 /* See if we already have an entry for this section. */ | |
440 slot = (unsigned int **) htab_find_slot (htab, name, INSERT); | |
441 if (!*slot) | |
442 { | |
443 *slot = (unsigned int *) xmalloc (sizeof (unsigned int)); | |
444 **slot = flags; | |
445 } | |
446 else | |
447 { | |
448 if (decl && **slot != flags) | |
449 error ("%q+D causes a section type conflict", decl); | |
450 } | |
451 | |
452 return flags; | |
453 } | |
454 | |
455 void | |
456 i386_pe_asm_named_section (const char *name, unsigned int flags, | |
457 tree decl) | |
458 { | |
459 char flagchars[8], *f = flagchars; | |
460 | |
461 if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0) | |
462 /* readonly data */ | |
463 { | |
464 *f++ ='d'; /* This is necessary for older versions of gas. */ | |
465 *f++ ='r'; | |
466 } | |
467 else | |
468 { | |
469 if (flags & SECTION_CODE) | |
470 *f++ = 'x'; | |
471 if (flags & SECTION_WRITE) | |
472 *f++ = 'w'; | |
473 if (flags & SECTION_PE_SHARED) | |
474 *f++ = 's'; | |
475 } | |
476 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
477 /* LTO sections need 1-byte alignment to avoid confusing the |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
478 zlib decompression algorithm with trailing zero pad bytes. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
479 if (strncmp (name, LTO_SECTION_NAME_PREFIX, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
480 strlen (LTO_SECTION_NAME_PREFIX)) == 0) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
481 *f++ = '0'; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
482 |
0 | 483 *f = '\0'; |
484 | |
485 fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars); | |
486 | |
487 if (flags & SECTION_LINKONCE) | |
488 { | |
489 /* Functions may have been compiled at various levels of | |
490 optimization so we can't use `same_size' here. | |
491 Instead, have the linker pick one, without warning. | |
492 If 'selectany' attribute has been specified, MS compiler | |
493 sets 'discard' characteristic, rather than telling linker | |
494 to warn of size or content mismatch, so do the same. */ | |
495 bool discard = (flags & SECTION_CODE) | |
496 || lookup_attribute ("selectany", | |
497 DECL_ATTRIBUTES (decl)); | |
498 fprintf (asm_out_file, "\t.linkonce %s\n", | |
499 (discard ? "discard" : "same_size")); | |
500 } | |
501 } | |
502 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
503 /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
504 |
0 | 505 void |
506 i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl, | |
507 const char *name, HOST_WIDE_INT size, | |
508 HOST_WIDE_INT align ATTRIBUTE_UNUSED) | |
509 { | |
510 HOST_WIDE_INT rounded; | |
511 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
512 /* Compute as in assemble_noswitch_variable, since we don't have |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
513 support for aligned common on older binutils. We must also |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
514 avoid emitting a common symbol of size zero, as this is the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
515 overloaded representation that indicates an undefined external |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
516 symbol in the PE object file format. */ |
0 | 517 rounded = size ? size : 1; |
518 rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1; | |
519 rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT) | |
520 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); | |
521 | |
522 i386_pe_maybe_record_exported_symbol (decl, name, 1); | |
523 | |
524 fprintf (stream, "\t.comm\t"); | |
525 assemble_name (stream, name); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
526 if (use_pe_aligned_common) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
527 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
528 size ? size : (HOST_WIDE_INT) 1, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
529 exact_log2 (align) - exact_log2 (CHAR_BIT)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
530 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
531 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
532 " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size); |
0 | 533 } |
534 | |
535 /* The Microsoft linker requires that every function be marked as | |
536 DT_FCN. When using gas on cygwin, we must emit appropriate .type | |
537 directives. */ | |
538 | |
539 #include "gsyms.h" | |
540 | |
541 /* Mark a function appropriately. This should only be called for | |
542 functions for which we are not emitting COFF debugging information. | |
543 FILE is the assembler output file, NAME is the name of the | |
544 function, and PUB is nonzero if the function is globally | |
545 visible. */ | |
546 | |
547 void | |
548 i386_pe_declare_function_type (FILE *file, const char *name, int pub) | |
549 { | |
550 fprintf (file, "\t.def\t"); | |
551 assemble_name (file, name); | |
552 fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n", | |
553 pub ? (int) C_EXT : (int) C_STAT, | |
554 (int) DT_FCN << N_BTSHFT); | |
555 } | |
556 | |
557 /* Keep a list of external functions. */ | |
558 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
559 struct GTY(()) extern_list |
0 | 560 { |
561 struct extern_list *next; | |
562 tree decl; | |
563 const char *name; | |
564 }; | |
565 | |
566 static GTY(()) struct extern_list *extern_head; | |
567 | |
568 /* Assemble an external function reference. We need to keep a list of | |
569 these, so that we can output the function types at the end of the | |
570 assembly. We can't output the types now, because we might see a | |
571 definition of the function later on and emit debugging information | |
572 for it then. */ | |
573 | |
574 void | |
575 i386_pe_record_external_function (tree decl, const char *name) | |
576 { | |
577 struct extern_list *p; | |
578 | |
579 p = (struct extern_list *) ggc_alloc (sizeof *p); | |
580 p->next = extern_head; | |
581 p->decl = decl; | |
582 p->name = name; | |
583 extern_head = p; | |
584 } | |
585 | |
586 /* Keep a list of exported symbols. */ | |
587 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
588 struct GTY(()) export_list |
0 | 589 { |
590 struct export_list *next; | |
591 const char *name; | |
592 int is_data; /* used to type tag exported symbols. */ | |
593 }; | |
594 | |
595 static GTY(()) struct export_list *export_head; | |
596 | |
597 /* Assemble an export symbol entry. We need to keep a list of | |
598 these, so that we can output the export list at the end of the | |
599 assembly. We used to output these export symbols in each function, | |
600 but that causes problems with GNU ld when the sections are | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
601 linkonce. Beware, DECL may be NULL if compile_file() is emitting |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
602 the LTO marker. */ |
0 | 603 |
604 void | |
605 i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data) | |
606 { | |
607 rtx symbol; | |
608 struct export_list *p; | |
609 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
610 if (!decl) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
611 return; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
612 |
0 | 613 symbol = XEXP (DECL_RTL (decl), 0); |
614 gcc_assert (GET_CODE (symbol) == SYMBOL_REF); | |
615 if (!SYMBOL_REF_DLLEXPORT_P (symbol)) | |
616 return; | |
617 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
618 gcc_assert (TREE_PUBLIC (decl)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
619 |
0 | 620 p = (struct export_list *) ggc_alloc (sizeof *p); |
621 p->next = export_head; | |
622 p->name = name; | |
623 p->is_data = is_data; | |
624 export_head = p; | |
625 } | |
626 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
627 #ifdef CXX_WRAP_SPEC_LIST |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
628 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
629 /* Hash table equality helper function. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
630 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
631 static int |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
632 wrapper_strcmp (const void *x, const void *y) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
633 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
634 return !strcmp ((const char *) x, (const char *) y); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
635 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
636 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
637 /* Search for a function named TARGET in the list of library wrappers |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
638 we are using, returning a pointer to it if found or NULL if not. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
639 This function might be called on quite a few symbols, and we only |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
640 have the list of names of wrapped functions available to us as a |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
641 spec string, so first time round we lazily initialise a hash table |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
642 to make things quicker. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
643 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
644 static const char * |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
645 i386_find_on_wrapper_list (const char *target) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
646 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
647 static char first_time = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
648 static htab_t wrappers; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
649 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
650 if (first_time) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
651 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
652 /* Beware that this is not a complicated parser, it assumes |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
653 that any sequence of non-whitespace beginning with an |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
654 underscore is one of the wrapped symbols. For now that's |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
655 adequate to distinguish symbols from spec substitutions |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
656 and command-line options. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
657 static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
658 char *bufptr; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
659 /* Breaks up the char array into separated strings |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
660 strings and enter them into the hash table. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
661 wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
662 0, xcalloc, free); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
663 for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
664 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
665 char *found = NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
666 if (ISSPACE (*bufptr)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
667 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
668 if (*bufptr == '_') |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
669 found = bufptr; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
670 while (*bufptr && !ISSPACE (*bufptr)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
671 ++bufptr; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
672 if (*bufptr) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
673 *bufptr = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
674 if (found) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
675 *htab_find_slot (wrappers, found, INSERT) = found; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
676 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
677 first_time = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
678 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
679 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
680 return (const char *) htab_find (wrappers, target); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
681 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
682 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
683 #endif /* CXX_WRAP_SPEC_LIST */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
684 |
0 | 685 /* This is called at the end of assembly. For each external function |
686 which has not been defined, we output a declaration now. We also | |
687 output the .drectve section. */ | |
688 | |
689 void | |
690 i386_pe_file_end (void) | |
691 { | |
692 struct extern_list *p; | |
693 | |
694 for (p = extern_head; p != NULL; p = p->next) | |
695 { | |
696 tree decl; | |
697 | |
698 decl = p->decl; | |
699 | |
700 /* Positively ensure only one declaration for any given symbol. */ | |
701 if (! TREE_ASM_WRITTEN (decl) | |
702 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) | |
703 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
704 #ifdef CXX_WRAP_SPEC_LIST |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
705 /* To ensure the DLL that provides the corresponding real |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
706 functions is still loaded at runtime, we must reference |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
707 the real function so that an (unused) import is created. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
708 const char *realsym = i386_find_on_wrapper_list (p->name); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
709 if (realsym) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
710 i386_pe_declare_function_type (asm_out_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
711 concat ("__real_", realsym, NULL), TREE_PUBLIC (decl)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
712 #endif /* CXX_WRAP_SPEC_LIST */ |
0 | 713 TREE_ASM_WRITTEN (decl) = 1; |
714 i386_pe_declare_function_type (asm_out_file, p->name, | |
715 TREE_PUBLIC (decl)); | |
716 } | |
717 } | |
718 | |
719 if (export_head) | |
720 { | |
721 struct export_list *q; | |
722 drectve_section (); | |
723 for (q = export_head; q != NULL; q = q->next) | |
724 { | |
725 fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n", | |
726 default_strip_name_encoding (q->name), | |
727 (q->is_data ? ",data" : "")); | |
728 } | |
729 } | |
730 } | |
731 | |
732 #include "gt-winnt.h" |