PR debug/9963
[official-gcc.git] / gcc / config / i386 / winnt.c
blobcecc97b5c5eaf0ea757875f622df6ec375f6a5d3
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
4 Free Software Foundation, Inc.
6 This file is part of GCC.
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 2, or (at your option) any later
11 version.
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.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "output.h"
31 #include "tree.h"
32 #include "flags.h"
33 #include "tm_p.h"
34 #include "toplev.h"
35 #include "hashtab.h"
36 #include "ggc.h"
38 /* i386/PE specific attribute support.
40 i386/PE has two new attributes:
41 dllexport - for exporting a function/variable that will live in a dll
42 dllimport - for importing a function/variable from a dll
44 Microsoft allows multiple declspecs in one __declspec, separating
45 them with spaces. We do NOT support this. Instead, use __declspec
46 multiple times.
49 static tree associated_type (tree);
50 static tree gen_stdcall_or_fastcall_suffix (tree, bool);
51 static int i386_pe_dllexport_p (tree);
52 static int i386_pe_dllimport_p (tree);
53 static void i386_pe_mark_dllexport (tree);
54 static void i386_pe_mark_dllimport (tree);
56 /* This is we how mark internal identifiers with dllimport or dllexport
57 attributes. */
58 #ifndef DLL_IMPORT_PREFIX
59 #define DLL_IMPORT_PREFIX "#i."
60 #endif
61 #ifndef DLL_EXPORT_PREFIX
62 #define DLL_EXPORT_PREFIX "#e."
63 #endif
65 /* Handle a "shared" attribute;
66 arguments as in struct attribute_spec.handler. */
67 tree
68 ix86_handle_shared_attribute (tree *node, tree name,
69 tree args ATTRIBUTE_UNUSED,
70 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
72 if (TREE_CODE (*node) != VAR_DECL)
74 warning ("%qs attribute only applies to variables",
75 IDENTIFIER_POINTER (name));
76 *no_add_attrs = true;
79 return NULL_TREE;
82 /* Handle a "selectany" attribute;
83 arguments as in struct attribute_spec.handler. */
84 tree
85 ix86_handle_selectany_attribute (tree *node, tree name,
86 tree args ATTRIBUTE_UNUSED,
87 int flags ATTRIBUTE_UNUSED,
88 bool *no_add_attrs)
90 /* The attribute applies only to objects that are initialized and have
91 external linkage, */
92 if (TREE_CODE (*node) == VAR_DECL && TREE_PUBLIC (*node)
93 && (DECL_INITIAL (*node)
94 /* If an object is initialized with a ctor, the static
95 initialization and destruction code for it is present in
96 each unit defining the object. The code that calls the
97 ctor is protected by a link-once guard variable, so that
98 the object still has link-once semantics, */
99 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (*node))))
100 make_decl_one_only (*node);
101 else
103 error ("%qs attribute applies only to initialized variables"
104 " with external linkage", IDENTIFIER_POINTER (name));
105 *no_add_attrs = true;
108 return NULL_TREE;
112 /* Return the type that we should use to determine if DECL is
113 imported or exported. */
115 static tree
116 associated_type (tree decl)
118 tree t = NULL_TREE;
120 /* In the C++ frontend, DECL_CONTEXT for a method doesn't actually refer
121 to the containing class. So we look at the 'this' arg. */
122 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
124 /* Artificial methods are not affected by the import/export status
125 of their class unless they are COMDAT. Implicit copy ctor's and
126 dtor's are not affected by class status but virtual and
127 non-virtual thunks are. */
128 if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl))
129 t = TYPE_MAIN_VARIANT
130 (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
132 else if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
133 t = DECL_CONTEXT (decl);
135 return t;
138 /* Return nonzero if DECL is a dllexport'd object. */
140 static int
141 i386_pe_dllexport_p (tree decl)
143 tree exp;
145 if (TREE_CODE (decl) != VAR_DECL
146 && TREE_CODE (decl) != FUNCTION_DECL)
147 return 0;
148 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
149 if (exp)
150 return 1;
152 /* Class members get the dllexport status of their class. */
153 if (associated_type (decl))
155 exp = lookup_attribute ("dllexport",
156 TYPE_ATTRIBUTES (associated_type (decl)));
157 if (exp)
158 return 1;
161 return 0;
164 /* Return nonzero if DECL is a dllimport'd object. */
166 static int
167 i386_pe_dllimport_p (tree decl)
169 tree imp;
170 int context_imp = 0;
172 if (TREE_CODE (decl) == FUNCTION_DECL
173 && TARGET_NOP_FUN_DLLIMPORT)
174 return 0;
176 if (TREE_CODE (decl) != VAR_DECL
177 && TREE_CODE (decl) != FUNCTION_DECL)
178 return 0;
180 imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
182 /* Class members get the dllimport status of their class. */
183 if (!imp && associated_type (decl))
185 imp = lookup_attribute ("dllimport",
186 TYPE_ATTRIBUTES (associated_type (decl)));
187 if (imp)
188 context_imp = 1;
191 if (imp)
193 /* Don't mark defined functions as dllimport. If the definition
194 itself was marked with dllimport, than ix86_handle_dll_attribute
195 reports an error. This handles the case when the definition
196 overrides an earlier declaration. */
197 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)
198 && !DECL_INLINE (decl))
200 /* Don't warn about artificial methods. */
201 if (!DECL_ARTIFICIAL (decl))
202 warning ("%Jfunction '%D' is defined after prior declaration "
203 "as dllimport: attribute ignored", decl, decl);
204 return 0;
207 /* We ignore the dllimport attribute for inline member functions.
208 This differs from MSVC behavior which treats it like GNUC
209 'extern inline' extension. */
210 else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
212 if (extra_warnings)
213 warning ("%Jinline function '%D' is declared as dllimport: "
214 "attribute ignored.", decl, decl);
215 return 0;
218 /* Don't allow definitions of static data members in dllimport class,
219 Just ignore attribute for vtable data. */
220 else if (TREE_CODE (decl) == VAR_DECL
221 && TREE_STATIC (decl) && TREE_PUBLIC (decl)
222 && !DECL_EXTERNAL (decl) && context_imp)
224 if (!DECL_VIRTUAL_P (decl))
225 error ("%Jdefinition of static data member '%D' of "
226 "dllimport'd class.", decl, decl);
227 return 0;
230 /* Since we can't treat a pointer to a dllimport'd symbol as a
231 constant address, we turn off the attribute on C++ virtual
232 methods to allow creation of vtables using thunks. Don't mark
233 artificial methods either (in associated_type, only COMDAT
234 artificial method get import status from class context). */
235 else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
236 && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
237 return 0;
239 return 1;
242 return 0;
245 /* Return nonzero if SYMBOL is marked as being dllexport'd. */
248 i386_pe_dllexport_name_p (const char *symbol)
250 return (strncmp (DLL_EXPORT_PREFIX, symbol,
251 strlen (DLL_EXPORT_PREFIX)) == 0);
254 /* Return nonzero if SYMBOL is marked as being dllimport'd. */
257 i386_pe_dllimport_name_p (const char *symbol)
259 return (strncmp (DLL_IMPORT_PREFIX, symbol,
260 strlen (DLL_IMPORT_PREFIX)) == 0);
263 /* Mark a DECL as being dllexport'd.
264 Note that we override the previous setting (e.g.: dllimport). */
266 static void
267 i386_pe_mark_dllexport (tree decl)
269 const char *oldname;
270 char *newname;
271 rtx rtlname;
272 rtx symref;
273 tree idp;
275 rtlname = XEXP (DECL_RTL (decl), 0);
276 if (GET_CODE (rtlname) == SYMBOL_REF)
277 oldname = XSTR (rtlname, 0);
278 else if (GET_CODE (rtlname) == MEM
279 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
280 oldname = XSTR (XEXP (rtlname, 0), 0);
281 else
282 abort ();
283 if (i386_pe_dllimport_name_p (oldname))
285 warning ("%Jinconsistent dll linkage for '%D', dllexport assumed.",
286 decl, decl);
287 /* Remove DLL_IMPORT_PREFIX. */
288 oldname += strlen (DLL_IMPORT_PREFIX);
289 DECL_NON_ADDR_CONST_P (decl) = 0;
291 else if (i386_pe_dllexport_name_p (oldname))
292 return; /* already done */
294 newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
295 sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
297 /* We pass newname through get_identifier to ensure it has a unique
298 address. RTL processing can sometimes peek inside the symbol ref
299 and compare the string's addresses to see if two symbols are
300 identical. */
301 idp = get_identifier (newname);
303 symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
304 SYMBOL_REF_DECL (symref) = decl;
305 XEXP (DECL_RTL (decl), 0) = symref;
308 /* Mark a DECL as being dllimport'd. */
310 static void
311 i386_pe_mark_dllimport (tree decl)
313 const char *oldname;
314 char *newname;
315 tree idp;
316 rtx rtlname, newrtl;
317 rtx symref;
319 rtlname = XEXP (DECL_RTL (decl), 0);
320 if (GET_CODE (rtlname) == SYMBOL_REF)
321 oldname = XSTR (rtlname, 0);
322 else if (GET_CODE (rtlname) == MEM
323 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
324 oldname = XSTR (XEXP (rtlname, 0), 0);
325 else
326 abort ();
327 if (i386_pe_dllexport_name_p (oldname))
329 error ("%qs declared as both exported to and imported from a DLL",
330 IDENTIFIER_POINTER (DECL_NAME (decl)));
331 return;
333 else if (i386_pe_dllimport_name_p (oldname))
335 /* Already done, but do a sanity check to prevent assembler errors. */
336 if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
338 error ("%Jfailure in redeclaration of '%D': dllimport'd "
339 "symbol lacks external linkage.", decl, decl);
340 abort();
342 return;
345 newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
346 sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
348 /* We pass newname through get_identifier to ensure it has a unique
349 address. RTL processing can sometimes peek inside the symbol ref
350 and compare the string's addresses to see if two symbols are
351 identical. */
352 idp = get_identifier (newname);
354 symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
355 SYMBOL_REF_DECL (symref) = decl;
356 newrtl = gen_rtx_MEM (Pmode,symref);
357 XEXP (DECL_RTL (decl), 0) = newrtl;
359 /* Can't treat a pointer to this as a constant address */
360 DECL_NON_ADDR_CONST_P (decl) = 1;
363 /* Return string which is the former assembler name modified with a
364 suffix consisting of an atsign (@) followed by the number of bytes of
365 arguments. If FASTCALL is true, also add the FASTCALL_PREFIX. */
367 static tree
368 gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
370 int total = 0;
371 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
372 of DECL_ASSEMBLER_NAME. */
373 const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
374 char *newsym;
375 char *p;
376 tree formal_type;
378 /* Do not change the identifier if a verbatim asmspec or already done. */
379 if (*asmname == '*' || strchr (asmname, '@'))
380 return DECL_ASSEMBLER_NAME (decl);
382 formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
383 if (formal_type != NULL_TREE)
385 /* These attributes are ignored for variadic functions in
386 i386.c:ix86_return_pops_args. For compatibility with MS
387 compiler do not add @0 suffix here. */
388 if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
389 return DECL_ASSEMBLER_NAME (decl);
391 /* Quit if we hit an incomplete type. Error is reported
392 by convert_arguments in c-typeck.c or cp/typeck.c. */
393 while (TREE_VALUE (formal_type) != void_type_node
394 && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
396 int parm_size
397 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
398 /* Must round up to include padding. This is done the same
399 way as in store_one_arg. */
400 parm_size = ((parm_size + PARM_BOUNDARY - 1)
401 / PARM_BOUNDARY * PARM_BOUNDARY);
402 total += parm_size;
403 formal_type = TREE_CHAIN (formal_type);\
407 /* Assume max of 8 base 10 digits in the suffix. */
408 newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
409 p = newsym;
410 if (fastcall)
411 *p++ = FASTCALL_PREFIX;
412 sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
413 return get_identifier (newsym);
416 void
417 i386_pe_encode_section_info (tree decl, rtx rtl, int first)
419 default_encode_section_info (decl, rtl, first);
421 if (first && TREE_CODE (decl) == FUNCTION_DECL)
423 tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
424 tree newid = NULL_TREE;
426 if (lookup_attribute ("stdcall", type_attributes))
427 newid = gen_stdcall_or_fastcall_suffix (decl, false);
428 else if (lookup_attribute ("fastcall", type_attributes))
429 newid = gen_stdcall_or_fastcall_suffix (decl, true);
430 if (newid != NULL_TREE)
432 rtx rtlname = XEXP (rtl, 0);
433 if (GET_CODE (rtlname) == MEM)
434 rtlname = XEXP (rtlname, 0);
435 XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
436 /* These attributes must be present on first declaration,
437 change_decl_assembler_name will warn if they are added
438 later and the decl has been referenced, but duplicate_decls
439 should catch the mismatch before this is called. */
440 change_decl_assembler_name (decl, newid);
444 /* Mark the decl so we can tell from the rtl whether the object is
445 dllexport'd or dllimport'd. This also handles dllexport/dllimport
446 override semantics. */
448 if (i386_pe_dllexport_p (decl))
449 i386_pe_mark_dllexport (decl);
450 else if (i386_pe_dllimport_p (decl))
451 i386_pe_mark_dllimport (decl);
452 /* It might be that DECL has already been marked as dllimport, but a
453 subsequent definition nullified that. The attribute is gone but
454 DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
455 that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
456 else if ((TREE_CODE (decl) == FUNCTION_DECL
457 || TREE_CODE (decl) == VAR_DECL)
458 && DECL_RTL (decl) != NULL_RTX
459 && GET_CODE (DECL_RTL (decl)) == MEM
460 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
461 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
462 && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
464 const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
466 /* Remove DLL_IMPORT_PREFIX. */
467 tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
468 rtx symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
469 SYMBOL_REF_DECL (symref) = decl;
470 XEXP (DECL_RTL (decl), 0) = symref;
471 DECL_NON_ADDR_CONST_P (decl) = 0;
473 /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
474 We leave these alone for now. */
476 if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
477 warning ("%J'%D' defined locally after being "
478 "referenced with dllimport linkage", decl, decl);
479 else
480 warning ("%J'%D' redeclared without dllimport attribute "
481 "after being referenced with dllimport linkage", decl, decl);
485 /* Strip only the leading encoding, leaving the stdcall suffix and fastcall
486 prefix if it exists. */
488 const char *
489 i386_pe_strip_name_encoding (const char *str)
491 if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
492 == 0)
493 str += strlen (DLL_IMPORT_PREFIX);
494 else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
495 == 0)
496 str += strlen (DLL_EXPORT_PREFIX);
497 if (*str == '*')
498 str += 1;
499 return str;
502 /* Also strip the fastcall prefix and stdcall suffix. */
504 const char *
505 i386_pe_strip_name_encoding_full (const char *str)
507 const char *p;
508 const char *name = i386_pe_strip_name_encoding (str);
510 /* Strip leading '@' on fastcall symbols. */
511 if (*name == '@')
512 name++;
514 /* Strip trailing "@n". */
515 p = strchr (name, '@');
516 if (p)
517 return ggc_alloc_string (name, p - name);
519 return name;
522 /* Output a reference to a label. Fastcall symbols are prefixed with @,
523 whereas symbols for functions using other calling conventions don't
524 have a prefix (unless they are marked dllimport or dllexport). */
526 void i386_pe_output_labelref (FILE *stream, const char *name)
528 if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
529 == 0)
530 /* A dll import */
532 if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
533 /* A dllimport fastcall symbol. */
535 fprintf (stream, "__imp_%s",
536 i386_pe_strip_name_encoding (name));
538 else
539 /* A dllimport non-fastcall symbol. */
541 fprintf (stream, "__imp__%s",
542 i386_pe_strip_name_encoding (name));
545 else if ((name[0] == FASTCALL_PREFIX)
546 || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
547 == 0
548 && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX))
549 /* A fastcall symbol. */
551 fprintf (stream, "%s",
552 i386_pe_strip_name_encoding (name));
554 else
555 /* Everything else. */
557 fprintf (stream, "%s%s", USER_LABEL_PREFIX,
558 i386_pe_strip_name_encoding (name));
562 void
563 i386_pe_unique_section (tree decl, int reloc)
565 int len;
566 const char *name, *prefix;
567 char *string;
569 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
570 name = i386_pe_strip_name_encoding_full (name);
572 /* The object is put in, for example, section .text$foo.
573 The linker will then ultimately place them in .text
574 (everything from the $ on is stripped). Don't put
575 read-only data in .rdata section to avoid a PE linker
576 bug when .rdata$* grouped sections are used in code
577 without a .rdata section. */
578 if (TREE_CODE (decl) == FUNCTION_DECL)
579 prefix = ".text$";
580 else if (decl_readonly_section (decl, reloc))
581 prefix = ".rdata$";
582 else
583 prefix = ".data$";
584 len = strlen (name) + strlen (prefix);
585 string = alloca (len + 1);
586 sprintf (string, "%s%s", prefix, name);
588 DECL_SECTION_NAME (decl) = build_string (len, string);
591 /* Select a set of attributes for section NAME based on the properties
592 of DECL and whether or not RELOC indicates that DECL's initializer
593 might contain runtime relocations.
595 We make the section read-only and executable for a function decl,
596 read-only for a const data decl, and writable for a non-const data decl.
598 If the section has already been defined, to not allow it to have
599 different attributes, as (1) this is ambiguous since we're not seeing
600 all the declarations up front and (2) some assemblers (e.g. SVR4)
601 do not recognize section redefinitions. */
602 /* ??? This differs from the "standard" PE implementation in that we
603 handle the SHARED variable attribute. Should this be done for all
604 PE targets? */
606 #define SECTION_PE_SHARED SECTION_MACH_DEP
608 unsigned int
609 i386_pe_section_type_flags (tree decl, const char *name, int reloc)
611 static htab_t htab;
612 unsigned int flags;
613 unsigned int **slot;
615 /* The names we put in the hashtable will always be the unique
616 versions given to us by the stringtable, so we can just use
617 their addresses as the keys. */
618 if (!htab)
619 htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
621 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
622 flags = SECTION_CODE;
623 else if (decl && decl_readonly_section (decl, reloc))
624 flags = 0;
625 else
627 flags = SECTION_WRITE;
629 if (decl && TREE_CODE (decl) == VAR_DECL
630 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
631 flags |= SECTION_PE_SHARED;
634 if (decl && DECL_ONE_ONLY (decl))
635 flags |= SECTION_LINKONCE;
637 /* See if we already have an entry for this section. */
638 slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
639 if (!*slot)
641 *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
642 **slot = flags;
644 else
646 if (decl && **slot != flags)
647 error ("%J'%D' causes a section type conflict", decl, decl);
650 return flags;
653 void
654 i386_pe_asm_named_section (const char *name, unsigned int flags,
655 tree decl)
657 char flagchars[8], *f = flagchars;
659 if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
660 /* readonly data */
662 *f++ ='d'; /* This is necessary for older versions of gas. */
663 *f++ ='r';
665 else
667 if (flags & SECTION_CODE)
668 *f++ = 'x';
669 if (flags & SECTION_WRITE)
670 *f++ = 'w';
671 if (flags & SECTION_PE_SHARED)
672 *f++ = 's';
675 *f = '\0';
677 fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
679 if (flags & SECTION_LINKONCE)
681 /* Functions may have been compiled at various levels of
682 optimization so we can't use `same_size' here.
683 Instead, have the linker pick one, without warning.
684 If 'selectany' attribute has been specified, MS compiler
685 sets 'discard' characteristic, rather than telling linker
686 to warn of size or content mismatch, so do the same. */
687 bool discard = (flags & SECTION_CODE)
688 || lookup_attribute ("selectany",
689 DECL_ATTRIBUTES (decl));
690 fprintf (asm_out_file, "\t.linkonce %s\n",
691 (discard ? "discard" : "same_size"));
695 /* The Microsoft linker requires that every function be marked as
696 DT_FCN. When using gas on cygwin, we must emit appropriate .type
697 directives. */
699 #include "gsyms.h"
701 /* Mark a function appropriately. This should only be called for
702 functions for which we are not emitting COFF debugging information.
703 FILE is the assembler output file, NAME is the name of the
704 function, and PUBLIC is nonzero if the function is globally
705 visible. */
707 void
708 i386_pe_declare_function_type (FILE *file, const char *name, int public)
710 fprintf (file, "\t.def\t");
711 assemble_name (file, name);
712 fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
713 public ? (int) C_EXT : (int) C_STAT,
714 (int) DT_FCN << N_BTSHFT);
717 /* Keep a list of external functions. */
719 struct extern_list GTY(())
721 struct extern_list *next;
722 tree decl;
723 const char *name;
726 static GTY(()) struct extern_list *extern_head;
728 /* Assemble an external function reference. We need to keep a list of
729 these, so that we can output the function types at the end of the
730 assembly. We can't output the types now, because we might see a
731 definition of the function later on and emit debugging information
732 for it then. */
734 void
735 i386_pe_record_external_function (tree decl, const char *name)
737 struct extern_list *p;
739 p = (struct extern_list *) ggc_alloc (sizeof *p);
740 p->next = extern_head;
741 p->decl = decl;
742 p->name = name;
743 extern_head = p;
746 /* Keep a list of exported symbols. */
748 struct export_list GTY(())
750 struct export_list *next;
751 const char *name;
752 int is_data; /* used to type tag exported symbols. */
755 static GTY(()) struct export_list *export_head;
757 /* Assemble an export symbol entry. We need to keep a list of
758 these, so that we can output the export list at the end of the
759 assembly. We used to output these export symbols in each function,
760 but that causes problems with GNU ld when the sections are
761 linkonce. */
763 void
764 i386_pe_record_exported_symbol (const char *name, int is_data)
766 struct export_list *p;
768 p = (struct export_list *) ggc_alloc (sizeof *p);
769 p->next = export_head;
770 p->name = name;
771 p->is_data = is_data;
772 export_head = p;
775 /* This is called at the end of assembly. For each external function
776 which has not been defined, we output a declaration now. We also
777 output the .drectve section. */
779 void
780 i386_pe_file_end (void)
782 struct extern_list *p;
784 ix86_file_end ();
786 for (p = extern_head; p != NULL; p = p->next)
788 tree decl;
790 decl = p->decl;
792 /* Positively ensure only one declaration for any given symbol. */
793 if (! TREE_ASM_WRITTEN (decl)
794 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
796 TREE_ASM_WRITTEN (decl) = 1;
797 i386_pe_declare_function_type (asm_out_file, p->name,
798 TREE_PUBLIC (decl));
802 if (export_head)
804 struct export_list *q;
805 drectve_section ();
806 for (q = export_head; q != NULL; q = q->next)
808 fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
809 i386_pe_strip_name_encoding (q->name),
810 (q->is_data) ? ",data" : "");
815 #include "gt-winnt.h"