]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/winnt.c
utils.c (init_gnat_to_gnu): Use typed GC allocation.
[thirdparty/gcc.git] / gcc / config / i386 / winnt.c
CommitLineData
30c71308
RK
1/* Subroutines for insn-output.c for Windows NT.
2 Contributed by Douglas Rupp (drupp@cs.washington.edu)
4e2bb0a4 3 Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
6d217c32 4 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
30c71308 5
6b6cb52e 6This file is part of GCC.
30c71308 7
6b6cb52e
DS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
2f83c7d6 10Software Foundation; either version 3, or (at your option) any later
6b6cb52e 11version.
30c71308 12
6b6cb52e
DS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
30c71308
RK
17
18You should have received a copy of the GNU General Public License
2f83c7d6
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
40dcd88b 21
30c71308 22#include "config.h"
293bcdc9 23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
30c71308
RK
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"
79f96374
DB
32#include "tm_p.h"
33#include "toplev.h"
7c262518 34#include "hashtab.h"
bfb139b4 35#include "langhooks.h"
772c5265 36#include "ggc.h"
da489f73 37#include "target.h"
3bec79c5 38#include "lto-streamer.h"
30c71308 39
27da1b4d
MK
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
91d231cb
JM
51/* Handle a "shared" attribute;
52 arguments as in struct attribute_spec.handler. */
53tree
9c808aad
AJ
54ix86_handle_shared_attribute (tree *node, tree name,
55 tree args ATTRIBUTE_UNUSED,
56 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
ac478ac0 57{
91d231cb 58 if (TREE_CODE (*node) != VAR_DECL)
ac478ac0 59 {
29d08eba
JM
60 warning (OPT_Wattributes, "%qE attribute only applies to variables",
61 name);
91d231cb 62 *no_add_attrs = true;
ac478ac0
JM
63 }
64
91d231cb 65 return NULL_TREE;
ac478ac0 66}
a20f6f00
DS
67
68/* Handle a "selectany" attribute;
69 arguments as in struct attribute_spec.handler. */
70tree
71ix86_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
4e2bb0a4
DS
77 external linkage. However, we may not know about initialization
78 until the language frontend has processed the decl. We'll check for
5234b8f5 79 initialization later in encode_section_info. */
4e2bb0a4 80 if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
a20f6f00 81 {
29d08eba
JM
82 error ("%qE attribute applies only to initialized variables"
83 " with external linkage", name);
a20f6f00
DS
84 *no_add_attrs = true;
85 }
86
87 return NULL_TREE;
88}
89
27da1b4d 90\f
ac478ac0
JM
91/* Return the type that we should use to determine if DECL is
92 imported or exported. */
27da1b4d 93
ac478ac0 94static tree
9c808aad 95associated_type (tree decl)
27da1b4d 96{
da489f73
RH
97 return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
98 ? DECL_CONTEXT (decl) : NULL_TREE);
27da1b4d
MK
99}
100
da489f73 101/* Return true if DECL should be a dllexport'd object. */
43d9ad1d
DS
102
103static bool
da489f73 104i386_pe_determine_dllexport_p (tree decl)
27da1b4d 105{
da489f73 106 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
43d9ad1d 107 return false;
27da1b4d 108
b20231fe
DS
109 /* Don't export local clones of dllexports. */
110 if (!TREE_PUBLIC (decl))
111 return false;
112
43d9ad1d
DS
113 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
114 return true;
27da1b4d 115
43d9ad1d
DS
116 return false;
117}
118
da489f73
RH
119/* Return true if DECL should be a dllimport'd object. */
120
43d9ad1d 121static bool
da489f73 122i386_pe_determine_dllimport_p (tree decl)
27da1b4d 123{
da489f73
RH
124 tree assoc;
125
126 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
43d9ad1d
DS
127 return false;
128
da489f73
RH
129 if (DECL_DLLIMPORT_P (decl))
130 return true;
131
43d9ad1d
DS
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
09a6b8a4
DS
134 error message if the class attribute has been overridden by an
135 out-of-class definition of static data. */
da489f73 136 assoc = associated_type (decl);
09a6b8a4
DS
137 if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))
138 && TREE_CODE (decl) == VAR_DECL
139 && TREE_STATIC (decl) && TREE_PUBLIC (decl)
140 && !DECL_EXTERNAL (decl)
141 /* vtable's are linkonce constants, so defining a vtable is not
142 an error as long as we don't try to import it too. */
143 && !DECL_VIRTUAL_P (decl))
144 error ("definition of static data member %q+D of "
145 "dllimport'd class", decl);
43d9ad1d
DS
146
147 return false;
148}
27da1b4d 149
43d9ad1d 150/* Handle the -mno-fun-dllimport target switch. */
da489f73 151
43d9ad1d 152bool
3101faab 153i386_pe_valid_dllimport_attribute_p (const_tree decl)
43d9ad1d
DS
154{
155 if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
156 return false;
157 return true;
27da1b4d
MK
158}
159
5234b8f5
DS
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.
da489f73 164 Return NULL if no change required. */
30c71308 165
23d34220 166static tree
5234b8f5 167gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
30c71308 168{
da489f73 169 HOST_WIDE_INT total = 0;
5234b8f5 170 const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
da489f73 171 char *new_str, *p;
04e1d06b
MM
172 tree type = TREE_TYPE (decl);
173 tree arg;
174 function_args_iterator args_iter;
30c71308 175
5234b8f5 176 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
23d34220 177
04e1d06b
MM
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 }
da489f73 204 }
9c808aad 205 /* Assume max of 8 base 10 digits in the suffix. */
5ead67f6 206 p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1);
23d34220
DS
207 if (fastcall)
208 *p++ = FASTCALL_PREFIX;
5234b8f5 209 sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total);
da489f73
RH
210
211 return get_identifier (new_str);
30c71308 212}
0ea6b275 213
5234b8f5
DS
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
217static tree
218i386_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 (). */
238tree
239i386_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
27da1b4d 246void
9c808aad 247i386_pe_encode_section_info (tree decl, rtx rtl, int first)
27da1b4d 248{
da489f73
RH
249 rtx symbol;
250 int flags;
251
252 /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above. */
c6a2438a 253 default_encode_section_info (decl, rtl, first);
27da1b4d 254
da489f73
RH
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))
e91f04de 263 {
da489f73 264 case FUNCTION_DECL:
bfb139b4
DS
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)
23d34220 268 {
bfb139b4
DS
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
5234b8f5 273 or if stdcall suffix already added. */
bfb139b4
DS
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);
23d34220 278 }
da489f73 279 break;
27da1b4d 280
da489f73
RH
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)))
daa0eeb8 291 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
da489f73
RH
292 else
293 error ("%q+D:'selectany' attribute applies only to "
294 "initialized objects", decl);
295 }
296 break;
297
298 default:
299 return;
4e2bb0a4
DS
300 }
301
27da1b4d 302 /* Mark the decl so we can tell from the rtl whether the object is
43d9ad1d
DS
303 dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes
304 handles dllexport/dllimport override semantics. */
da489f73
RH
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))
09a6b8a4
DS
310 flags |= SYMBOL_FLAG_DLLIMPORT;
311
da489f73 312 SYMBOL_REF_FLAGS (symbol) = flags;
27da1b4d
MK
313}
314
da489f73 315bool
3101faab 316i386_pe_binds_local_p (const_tree exp)
772c5265 317{
da489f73
RH
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
2dfccd83
DK
324 /* Or a weak one, now that they are supported. */
325 if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
326 && DECL_WEAK (exp))
e97580ce
DK
327 /* But x64 gets confused and attempts to use unsupported GOTPCREL
328 relocations if we tell it the truth, so we still return true in
329 that case until the deeper problem can be fixed. */
330 return (TARGET_64BIT && DEFAULT_ABI == MS_ABI);
2dfccd83 331
da489f73 332 return true;
772c5265
RH
333}
334
b1f123c7 335/* Also strip the fastcall prefix and stdcall suffix. */
772c5265
RH
336
337const char *
9c808aad 338i386_pe_strip_name_encoding_full (const char *str)
772c5265
RH
339{
340 const char *p;
da489f73 341 const char *name = default_strip_name_encoding (str);
9c808aad 342
b1f123c7
DS
343 /* Strip leading '@' on fastcall symbols. */
344 if (*name == '@')
345 name++;
346
347 /* Strip trailing "@n". */
772c5265
RH
348 p = strchr (name, '@');
349 if (p)
12df9508
DS
350 return ggc_alloc_string (name, p - name);
351
772c5265
RH
352 return name;
353}
354
516dd80f 355void
9c808aad 356i386_pe_unique_section (tree decl, int reloc)
b64deb96
JM
357{
358 int len;
79f96374
DB
359 const char *name, *prefix;
360 char *string;
b64deb96
JM
361
362 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
772c5265 363 name = i386_pe_strip_name_encoding_full (name);
b64deb96
JM
364
365 /* The object is put in, for example, section .text$foo.
366 The linker will then ultimately place them in .text
81023100 367 (everything from the $ on is stripped). Don't put
9c808aad 368 read-only data in .rdata section to avoid a PE linker
81023100
MK
369 bug when .rdata$* grouped sections are used in code
370 without a .rdata section. */
b64deb96
JM
371 if (TREE_CODE (decl) == FUNCTION_DECL)
372 prefix = ".text$";
4e4d733e 373 else if (decl_readonly_section (decl, reloc))
b64deb96
JM
374 prefix = ".rdata$";
375 else
376 prefix = ".data$";
377 len = strlen (name) + strlen (prefix);
5ead67f6 378 string = XALLOCAVEC (char, len + 1);
b64deb96
JM
379 sprintf (string, "%s%s", prefix, name);
380
516dd80f 381 DECL_SECTION_NAME (decl) = build_string (len, string);
b64deb96 382}
7c262518
RH
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)
d1f87653 394 do not recognize section redefinitions. */
7c262518
RH
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
401unsigned int
9c808aad 402i386_pe_section_type_flags (tree decl, const char *name, int reloc)
7c262518
RH
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
1ae58c30 409 versions given to us by the stringtable, so we can just use
7c262518
RH
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;
4e4d733e 416 else if (decl && decl_readonly_section (decl, reloc))
7c262518 417 flags = 0;
40f39798
ZM
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;
7c262518
RH
427 else
428 {
429 flags = SECTION_WRITE;
430
431 if (decl && TREE_CODE (decl) == VAR_DECL
91d231cb 432 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
7c262518
RH
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)
dee15844 449 error ("%q+D causes a section type conflict", decl);
7c262518
RH
450 }
451
452 return flags;
453}
454
455void
c18a5b6c 456i386_pe_asm_named_section (const char *name, unsigned int flags,
a20f6f00 457 tree decl)
7c262518
RH
458{
459 char flagchars[8], *f = flagchars;
460
7f27395d
DS
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
1e8a5248
DS
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 }
7f27395d 476
3bec79c5
DK
477 /* LTO sections need 1-byte alignment to avoid confusing the
478 zlib decompression algorithm with trailing zero pad bytes. */
479 if (strncmp (name, LTO_SECTION_NAME_PREFIX,
480 strlen (LTO_SECTION_NAME_PREFIX)) == 0)
481 *f++ = '0';
482
7c262518
RH
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
a20f6f00
DS
490 optimization so we can't use `same_size' here.
491 Instead, have the linker pick one, without warning.
315682fb 492 If 'selectany' attribute has been specified, MS compiler
a20f6f00
DS
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));
7c262518 498 fprintf (asm_out_file, "\t.linkonce %s\n",
a20f6f00 499 (discard ? "discard" : "same_size"));
7c262518
RH
500 }
501}
da489f73 502
3bec79c5
DK
503/* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */
504
da489f73
RH
505void
506i386_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
233215fe
DK
512 /* Compute as in assemble_noswitch_variable, since we don't have
513 support for aligned common on older binutils. We must also
514 avoid emitting a common symbol of size zero, as this is the
515 overloaded representation that indicates an undefined external
516 symbol in the PE object file format. */
da489f73
RH
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
ecb8c3cc 524 fprintf (stream, "\t.comm\t");
da489f73 525 assemble_name (stream, name);
233215fe
DK
526 if (use_pe_aligned_common)
527 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
528 size ? size : (HOST_WIDE_INT) 1,
529 exact_log2 (align) - exact_log2 (CHAR_BIT));
530 else
531 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
532 " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
da489f73 533}
9fa1246d
JL
534\f
535/* The Microsoft linker requires that every function be marked as
cae21ae8 536 DT_FCN. When using gas on cygwin, we must emit appropriate .type
9fa1246d
JL
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
0a2aaacc 544 function, and PUB is nonzero if the function is globally
9fa1246d
JL
545 visible. */
546
547void
0a2aaacc 548i386_pe_declare_function_type (FILE *file, const char *name, int pub)
9fa1246d
JL
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",
0a2aaacc 553 pub ? (int) C_EXT : (int) C_STAT,
9fa1246d
JL
554 (int) DT_FCN << N_BTSHFT);
555}
556
557/* Keep a list of external functions. */
558
d1b38208 559struct GTY(()) extern_list
9fa1246d
JL
560{
561 struct extern_list *next;
3ce9c824 562 tree decl;
79f96374 563 const char *name;
9fa1246d
JL
564};
565
90aa6719 566static GTY(()) struct extern_list *extern_head;
9fa1246d
JL
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
574void
3ce9c824 575i386_pe_record_external_function (tree decl, const char *name)
9fa1246d
JL
576{
577 struct extern_list *p;
578
a9429e29 579 p = ggc_alloc_extern_list ();
9fa1246d 580 p->next = extern_head;
3ce9c824 581 p->decl = decl;
9fa1246d
JL
582 p->name = name;
583 extern_head = p;
584}
585
8e260ba4
MK
586/* Keep a list of exported symbols. */
587
d1b38208 588struct GTY(()) export_list
8e260ba4
MK
589{
590 struct export_list *next;
79f96374 591 const char *name;
892a2d68 592 int is_data; /* used to type tag exported symbols. */
8e260ba4
MK
593};
594
90aa6719 595static GTY(()) struct export_list *export_head;
e43f9c10
MK
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,
9c808aad 600 but that causes problems with GNU ld when the sections are
3bec79c5
DK
601 linkonce. Beware, DECL may be NULL if compile_file() is emitting
602 the LTO marker. */
e43f9c10
MK
603
604void
da489f73 605i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
e43f9c10 606{
da489f73 607 rtx symbol;
8e260ba4 608 struct export_list *p;
e43f9c10 609
3bec79c5
DK
610 if (!decl)
611 return;
612
da489f73
RH
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
b20231fe
DS
618 gcc_assert (TREE_PUBLIC (decl));
619
a9429e29 620 p = ggc_alloc_export_list ();
8e260ba4 621 p->next = export_head;
e43f9c10 622 p->name = name;
8e260ba4
MK
623 p->is_data = is_data;
624 export_head = p;
e43f9c10
MK
625}
626
f7e413e2
DK
627#ifdef CXX_WRAP_SPEC_LIST
628
629/* Hash table equality helper function. */
630
631static int
632wrapper_strcmp (const void *x, const void *y)
633{
634 return !strcmp ((const char *) x, (const char *) y);
635}
636
637/* Search for a function named TARGET in the list of library wrappers
638 we are using, returning a pointer to it if found or NULL if not.
639 This function might be called on quite a few symbols, and we only
640 have the list of names of wrapped functions available to us as a
641 spec string, so first time round we lazily initialise a hash table
642 to make things quicker. */
643
644static const char *
645i386_find_on_wrapper_list (const char *target)
646{
647 static char first_time = 1;
648 static htab_t wrappers;
649
650 if (first_time)
651 {
652 /* Beware that this is not a complicated parser, it assumes
653 that any sequence of non-whitespace beginning with an
654 underscore is one of the wrapped symbols. For now that's
655 adequate to distinguish symbols from spec substitutions
656 and command-line options. */
657 static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
658 char *bufptr;
659 /* Breaks up the char array into separated strings
660 strings and enter them into the hash table. */
661 wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
662 0, xcalloc, free);
663 for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
664 {
665 char *found = NULL;
666 if (ISSPACE (*bufptr))
667 continue;
668 if (*bufptr == '_')
669 found = bufptr;
670 while (*bufptr && !ISSPACE (*bufptr))
671 ++bufptr;
672 if (*bufptr)
673 *bufptr = 0;
674 if (found)
675 *htab_find_slot (wrappers, found, INSERT) = found;
676 }
677 first_time = 0;
678 }
679
680 return (const char *) htab_find (wrappers, target);
681}
682
683#endif /* CXX_WRAP_SPEC_LIST */
684
9fa1246d 685/* This is called at the end of assembly. For each external function
e43f9c10
MK
686 which has not been defined, we output a declaration now. We also
687 output the .drectve section. */
9fa1246d
JL
688
689void
9c808aad 690i386_pe_file_end (void)
9fa1246d
JL
691{
692 struct extern_list *p;
693
694 for (p = extern_head; p != NULL; p = p->next)
695 {
696 tree decl;
697
3ce9c824 698 decl = p->decl;
9fa1246d
JL
699
700 /* Positively ensure only one declaration for any given symbol. */
3ce9c824
ILT
701 if (! TREE_ASM_WRITTEN (decl)
702 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
9fa1246d 703 {
f7e413e2
DK
704#ifdef CXX_WRAP_SPEC_LIST
705 /* To ensure the DLL that provides the corresponding real
706 functions is still loaded at runtime, we must reference
707 the real function so that an (unused) import is created. */
708 const char *realsym = i386_find_on_wrapper_list (p->name);
709 if (realsym)
710 i386_pe_declare_function_type (asm_out_file,
711 concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
712#endif /* CXX_WRAP_SPEC_LIST */
9fa1246d 713 TREE_ASM_WRITTEN (decl) = 1;
a5fe455b 714 i386_pe_declare_function_type (asm_out_file, p->name,
9c808aad 715 TREE_PUBLIC (decl));
9fa1246d
JL
716 }
717 }
e43f9c10 718
8e260ba4 719 if (export_head)
e43f9c10 720 {
8e260ba4
MK
721 struct export_list *q;
722 drectve_section ();
723 for (q = export_head; q != NULL; q = q->next)
724 {
a5fe455b 725 fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
4b07e9f7 726 default_strip_name_encoding (q->name),
da489f73 727 (q->is_data ? ",data" : ""));
8e260ba4 728 }
e43f9c10 729 }
9fa1246d 730}
90aa6719
DS
731
732#include "gt-winnt.h"