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   2005, 2006  Free Software Foundation, Inc.
5
6This file is part of GCC.
7
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
10Software Foundation; either version 2, or (at your option) any later
11version.
12
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.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING.  If not, write to the Free
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA.  */
22
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"
37
38/* i386/PE specific attribute support.
39
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
43
44   Microsoft allows multiple declspecs in one __declspec, separating
45   them with spaces.  We do NOT support this.  Instead, use __declspec
46   multiple times.
47*/
48
49static tree associated_type (tree);
50static tree gen_stdcall_or_fastcall_suffix (tree, bool);
51static bool i386_pe_dllexport_p (tree);
52static bool i386_pe_dllimport_p (tree);
53static void i386_pe_mark_dllexport (tree);
54static void i386_pe_mark_dllimport (tree);
55
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
64
65/* Handle a "shared" attribute;
66   arguments as in struct attribute_spec.handler.  */
67tree
68ix86_handle_shared_attribute (tree *node, tree name,
69			      tree args ATTRIBUTE_UNUSED,
70			      int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
71{
72  if (TREE_CODE (*node) != VAR_DECL)
73    {
74      warning (OPT_Wattributes, "%qs attribute only applies to variables",
75	       IDENTIFIER_POINTER (name));
76      *no_add_attrs = true;
77    }
78
79  return NULL_TREE;
80}
81
82/* Handle a "selectany" attribute;
83   arguments as in struct attribute_spec.handler.  */
84tree
85ix86_handle_selectany_attribute (tree *node, tree name,
86			         tree args ATTRIBUTE_UNUSED,
87			         int flags ATTRIBUTE_UNUSED,
88				 bool *no_add_attrs)
89{
90  /* The attribute applies only to objects that are initialized and have
91     external linkage.  However, we may not know about initialization
92     until the language frontend has processed the decl. We'll check for
93     initialization later in encode_section_info.  */
94  if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
95    {
96      error ("%qs attribute applies only to initialized variables"
97       	     " with external linkage",  IDENTIFIER_POINTER (name));
98      *no_add_attrs = true;
99    }
100
101  return NULL_TREE;
102}
103
104
105/* Return the type that we should use to determine if DECL is
106   imported or exported.  */
107
108static tree
109associated_type (tree decl)
110{
111  return  (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
112            ?  DECL_CONTEXT (decl) : NULL_TREE;
113}
114
115
116/* Return true if DECL is a dllexport'd object.  */
117
118static bool
119i386_pe_dllexport_p (tree decl)
120{
121  if (TREE_CODE (decl) != VAR_DECL
122       && TREE_CODE (decl) != FUNCTION_DECL)
123    return false;
124
125  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
126    return true;
127
128  /* Also mark class members of exported classes with dllexport.  */
129  if (associated_type (decl)
130      && lookup_attribute ("dllexport",
131			    TYPE_ATTRIBUTES (associated_type (decl))))
132    return i386_pe_type_dllexport_p (decl);
133
134  return false;
135}
136
137static bool
138i386_pe_dllimport_p (tree decl)
139{
140  if (TREE_CODE (decl) != VAR_DECL
141       && TREE_CODE (decl) != FUNCTION_DECL)
142    return false;
143
144  /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag.
145     We may need to override an earlier decision.  */
146  if (DECL_DLLIMPORT_P (decl)
147      && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)))
148    {
149       /* Make a final check to see if this is a definition before we generate
150          RTL for an indirect reference.  */
151       if (!DECL_EXTERNAL (decl))
152	{
153	  error ("%q+D: definition is marked as dllimport", decl);
154	  DECL_DLLIMPORT_P (decl) = 0;
155          return false;
156        }
157      return true;
158    }
159  /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
160     by  targetm.cxx.adjust_class_at_definition.  Check again to emit
161     warnings if the class attribute has been overridden by an
162     out-of-class definition.  */
163  else if (associated_type (decl)
164           && lookup_attribute ("dllimport",
165				TYPE_ATTRIBUTES (associated_type (decl))))
166    return i386_pe_type_dllimport_p (decl);
167
168  return false;
169}
170
171/* Handle the -mno-fun-dllimport target switch.  */
172bool
173i386_pe_valid_dllimport_attribute_p (tree decl)
174{
175   if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
176     return false;
177   return true;
178}
179
180/* Return nonzero if SYMBOL is marked as being dllexport'd.  */
181
182int
183i386_pe_dllexport_name_p (const char *symbol)
184{
185  return (strncmp (DLL_EXPORT_PREFIX, symbol,
186		   strlen (DLL_EXPORT_PREFIX)) == 0);
187}
188
189/* Return nonzero if SYMBOL is marked as being dllimport'd.  */
190
191int
192i386_pe_dllimport_name_p (const char *symbol)
193{
194  return (strncmp (DLL_IMPORT_PREFIX, symbol,
195		   strlen (DLL_IMPORT_PREFIX)) == 0);
196}
197
198/* Mark a DECL as being dllexport'd.
199   Note that we override the previous setting (e.g.: dllimport).  */
200
201static void
202i386_pe_mark_dllexport (tree decl)
203{
204  const char *oldname;
205  char  *newname;
206  rtx rtlname;
207  rtx symref;
208  tree idp;
209
210  rtlname = XEXP (DECL_RTL (decl), 0);
211  if (GET_CODE (rtlname) == MEM)
212    rtlname = XEXP (rtlname, 0);
213  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
214  oldname = XSTR (rtlname, 0);
215  if (i386_pe_dllimport_name_p (oldname))
216    {
217      warning (0, "inconsistent dll linkage for %q+D, dllexport assumed",
218	       decl);
219     /* Remove DLL_IMPORT_PREFIX.  */
220      oldname += strlen (DLL_IMPORT_PREFIX);
221    }
222  else if (i386_pe_dllexport_name_p (oldname))
223    return;  /*  already done  */
224
225  newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
226  sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
227
228  /* We pass newname through get_identifier to ensure it has a unique
229     address.  RTL processing can sometimes peek inside the symbol ref
230     and compare the string's addresses to see if two symbols are
231     identical.  */
232  idp = get_identifier (newname);
233
234  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
235  SET_SYMBOL_REF_DECL (symref, decl);
236  XEXP (DECL_RTL (decl), 0) = symref;
237}
238
239/* Mark a DECL as being dllimport'd.  */
240
241static void
242i386_pe_mark_dllimport (tree decl)
243{
244  const char *oldname;
245  char  *newname;
246  tree idp;
247  rtx rtlname, newrtl;
248  rtx symref;
249
250  rtlname = XEXP (DECL_RTL (decl), 0);
251  if (GET_CODE (rtlname) == MEM)
252    rtlname = XEXP (rtlname, 0);
253  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
254  oldname = XSTR (rtlname, 0);
255  if (i386_pe_dllexport_name_p (oldname))
256    {
257      error ("%qs declared as both exported to and imported from a DLL",
258             IDENTIFIER_POINTER (DECL_NAME (decl)));
259      return;
260    }
261  else if (i386_pe_dllimport_name_p (oldname))
262    {
263      /* Already done, but do a sanity check to prevent assembler
264	 errors.  */
265      gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
266		  && DECL_DLLIMPORT_P (decl));
267      return;
268    }
269
270  newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
271  sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
272
273  /* We pass newname through get_identifier to ensure it has a unique
274     address.  RTL processing can sometimes peek inside the symbol ref
275     and compare the string's addresses to see if two symbols are
276     identical.  */
277  idp = get_identifier (newname);
278
279  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
280  SET_SYMBOL_REF_DECL (symref, decl);
281  newrtl = gen_rtx_MEM (Pmode,symref);
282  XEXP (DECL_RTL (decl), 0) = newrtl;
283
284  DECL_DLLIMPORT_P (decl) = 1;
285}
286
287/* Return string which is the former assembler name modified with a
288   suffix consisting of an atsign (@) followed by the number of bytes of
289   arguments.  If FASTCALL is true, also add the FASTCALL_PREFIX.  */
290
291static tree
292gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
293{
294  int total = 0;
295  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
296     of DECL_ASSEMBLER_NAME.  */
297   const char *asmname =  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
298  char *newsym;
299  char *p;
300  tree formal_type;
301
302  /* Do not change the identifier if a verbatim asmspec or already done. */
303  if (*asmname == '*' || strchr (asmname, '@'))
304    return DECL_ASSEMBLER_NAME (decl);
305
306  formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
307  if (formal_type != NULL_TREE)
308    {
309      /* These attributes are ignored for variadic functions in
310	 i386.c:ix86_return_pops_args. For compatibility with MS
311         compiler do not add @0 suffix here.  */
312      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
313        return DECL_ASSEMBLER_NAME (decl);
314
315      /* Quit if we hit an incomplete type.  Error is reported
316         by convert_arguments in c-typeck.c or cp/typeck.c.  */
317      while (TREE_VALUE (formal_type) != void_type_node
318	     && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
319	{
320	  int parm_size
321	    = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
322	    /* Must round up to include padding.  This is done the same
323	       way as in store_one_arg.  */
324	  parm_size = ((parm_size + PARM_BOUNDARY - 1)
325		       / PARM_BOUNDARY * PARM_BOUNDARY);
326	  total += parm_size;
327	  formal_type = TREE_CHAIN (formal_type);\
328	}
329     }
330
331  /* Assume max of 8 base 10 digits in the suffix.  */
332  newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
333  p = newsym;
334  if (fastcall)
335    *p++ = FASTCALL_PREFIX;
336  sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
337  return get_identifier (newsym);
338}
339
340void
341i386_pe_encode_section_info (tree decl, rtx rtl, int first)
342{
343  default_encode_section_info (decl, rtl, first);
344
345  if (first && TREE_CODE (decl) == FUNCTION_DECL)
346    {
347      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
348      tree newid = NULL_TREE;
349
350      if (lookup_attribute ("stdcall", type_attributes))
351	newid = gen_stdcall_or_fastcall_suffix (decl, false);
352      else if (lookup_attribute ("fastcall", type_attributes))
353	newid = gen_stdcall_or_fastcall_suffix (decl, true);
354      if (newid != NULL_TREE)
355	{
356	  rtx rtlname = XEXP (rtl, 0);
357	  if (GET_CODE (rtlname) == MEM)
358	    rtlname = XEXP (rtlname, 0);
359	  XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
360	  /* These attributes must be present on first declaration,
361	     change_decl_assembler_name will warn if they are added
362	     later and the decl has been referenced, but duplicate_decls
363	     should catch the mismatch before this is called.  */
364	  change_decl_assembler_name (decl, newid);
365	}
366    }
367
368  else if (TREE_CODE (decl) == VAR_DECL
369           && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
370    {
371      if (DECL_INITIAL (decl)
372 	  /* If an object is initialized with a ctor, the static
373	     initialization and destruction code for it is present in
374	     each unit defining the object.  The code that calls the
375	     ctor is protected by a link-once guard variable, so that
376	     the object still has link-once semantics,  */
377    	   || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
378	make_decl_one_only (decl);
379      else
380	error ("%q+D:'selectany' attribute applies only to initialized objects",
381	       decl);
382    }
383
384  /* Mark the decl so we can tell from the rtl whether the object is
385     dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
386     handles dllexport/dllimport override semantics.  */
387
388  if (i386_pe_dllexport_p (decl))
389    i386_pe_mark_dllexport (decl);
390  else if (i386_pe_dllimport_p (decl))
391    i386_pe_mark_dllimport (decl);
392  /* It might be that DECL has been declared as dllimport, but a
393     subsequent definition nullified that.  Assert that
394     tree.c: merge_dllimport_decl_attributes has removed the attribute
395     before the RTL name was marked with the DLL_IMPORT_PREFIX.  */
396  else
397    gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL
398	    	   || TREE_CODE (decl) == VAR_DECL)
399		  && rtl != NULL_RTX
400		  && GET_CODE (rtl) == MEM
401		  && GET_CODE (XEXP (rtl, 0)) == MEM
402		  && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF
403		  && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0))));
404}
405
406/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
407   prefix if it exists.  */
408
409const char *
410i386_pe_strip_name_encoding (const char *str)
411{
412  if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
413      == 0)
414    str += strlen (DLL_IMPORT_PREFIX);
415  else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
416	   == 0)
417    str += strlen (DLL_EXPORT_PREFIX);
418  if (*str == '*')
419    str += 1;
420  return str;
421}
422
423/* Also strip the fastcall prefix and stdcall suffix.  */
424
425const char *
426i386_pe_strip_name_encoding_full (const char *str)
427{
428  const char *p;
429  const char *name = i386_pe_strip_name_encoding (str);
430
431  /* Strip leading '@' on fastcall symbols.  */
432  if (*name == '@')
433    name++;
434
435  /* Strip trailing "@n".  */
436  p = strchr (name, '@');
437  if (p)
438    return ggc_alloc_string (name, p - name);
439
440  return name;
441}
442
443/* Output a reference to a label. Fastcall symbols are prefixed with @,
444   whereas symbols for functions using other calling conventions don't
445   have a prefix (unless they are marked dllimport or dllexport).  */
446
447void i386_pe_output_labelref (FILE *stream, const char *name)
448{
449  if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
450      == 0)
451    /* A dll import */
452    {
453      if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
454      /* A dllimport fastcall symbol.  */
455        {
456          fprintf (stream, "__imp_%s",
457                   i386_pe_strip_name_encoding (name));
458        }
459      else
460      /* A dllimport non-fastcall symbol.  */
461        {
462          fprintf (stream, "__imp__%s",
463                   i386_pe_strip_name_encoding (name));
464        }
465    }
466  else if ((name[0] == FASTCALL_PREFIX)
467           || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
468	       == 0
469	       && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX))
470    /* A fastcall symbol.  */
471    {
472      fprintf (stream, "%s",
473               i386_pe_strip_name_encoding (name));
474    }
475  else
476    /* Everything else.  */
477    {
478      fprintf (stream, "%s%s", USER_LABEL_PREFIX,
479               i386_pe_strip_name_encoding (name));
480    }
481}
482
483void
484i386_pe_unique_section (tree decl, int reloc)
485{
486  int len;
487  const char *name, *prefix;
488  char *string;
489
490  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
491  name = i386_pe_strip_name_encoding_full (name);
492
493  /* The object is put in, for example, section .text$foo.
494     The linker will then ultimately place them in .text
495     (everything from the $ on is stripped). Don't put
496     read-only data in .rdata section to avoid a PE linker
497     bug when .rdata$* grouped sections are used in code
498     without a .rdata section.  */
499  if (TREE_CODE (decl) == FUNCTION_DECL)
500    prefix = ".text$";
501  else if (decl_readonly_section (decl, reloc))
502    prefix = ".rdata$";
503  else
504    prefix = ".data$";
505  len = strlen (name) + strlen (prefix);
506  string = alloca (len + 1);
507  sprintf (string, "%s%s", prefix, name);
508
509  DECL_SECTION_NAME (decl) = build_string (len, string);
510}
511
512/* Select a set of attributes for section NAME based on the properties
513   of DECL and whether or not RELOC indicates that DECL's initializer
514   might contain runtime relocations.
515
516   We make the section read-only and executable for a function decl,
517   read-only for a const data decl, and writable for a non-const data decl.
518
519   If the section has already been defined, to not allow it to have
520   different attributes, as (1) this is ambiguous since we're not seeing
521   all the declarations up front and (2) some assemblers (e.g. SVR4)
522   do not recognize section redefinitions.  */
523/* ??? This differs from the "standard" PE implementation in that we
524   handle the SHARED variable attribute.  Should this be done for all
525   PE targets?  */
526
527#define SECTION_PE_SHARED	SECTION_MACH_DEP
528
529unsigned int
530i386_pe_section_type_flags (tree decl, const char *name, int reloc)
531{
532  static htab_t htab;
533  unsigned int flags;
534  unsigned int **slot;
535
536  /* The names we put in the hashtable will always be the unique
537     versions given to us by the stringtable, so we can just use
538     their addresses as the keys.  */
539  if (!htab)
540    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
541
542  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
543    flags = SECTION_CODE;
544  else if (decl && decl_readonly_section (decl, reloc))
545    flags = 0;
546  else
547    {
548      flags = SECTION_WRITE;
549
550      if (decl && TREE_CODE (decl) == VAR_DECL
551	  && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
552	flags |= SECTION_PE_SHARED;
553    }
554
555  if (decl && DECL_ONE_ONLY (decl))
556    flags |= SECTION_LINKONCE;
557
558  /* See if we already have an entry for this section.  */
559  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
560  if (!*slot)
561    {
562      *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
563      **slot = flags;
564    }
565  else
566    {
567      if (decl && **slot != flags)
568	error ("%q+D causes a section type conflict", decl);
569    }
570
571  return flags;
572}
573
574void
575i386_pe_asm_named_section (const char *name, unsigned int flags,
576			   tree decl)
577{
578  char flagchars[8], *f = flagchars;
579
580  if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
581    /* readonly data */
582    {
583      *f++ ='d';  /* This is necessary for older versions of gas.  */
584      *f++ ='r';
585    }
586  else
587    {
588      if (flags & SECTION_CODE)
589        *f++ = 'x';
590      if (flags & SECTION_WRITE)
591        *f++ = 'w';
592      if (flags & SECTION_PE_SHARED)
593        *f++ = 's';
594    }
595
596  *f = '\0';
597
598  fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
599
600  if (flags & SECTION_LINKONCE)
601    {
602      /* Functions may have been compiled at various levels of
603	 optimization so we can't use `same_size' here.
604	 Instead, have the linker pick one, without warning.
605	 If 'selectany' attribute has been specified,  MS compiler
606	 sets 'discard' characteristic, rather than telling linker
607	 to warn of size or content mismatch, so do the same.  */
608      bool discard = (flags & SECTION_CODE)
609		      || lookup_attribute ("selectany",
610					   DECL_ATTRIBUTES (decl));
611      fprintf (asm_out_file, "\t.linkonce %s\n",
612	       (discard  ? "discard" : "same_size"));
613    }
614}
615
616/* The Microsoft linker requires that every function be marked as
617   DT_FCN.  When using gas on cygwin, we must emit appropriate .type
618   directives.  */
619
620#include "gsyms.h"
621
622/* Mark a function appropriately.  This should only be called for
623   functions for which we are not emitting COFF debugging information.
624   FILE is the assembler output file, NAME is the name of the
625   function, and PUBLIC is nonzero if the function is globally
626   visible.  */
627
628void
629i386_pe_declare_function_type (FILE *file, const char *name, int public)
630{
631  fprintf (file, "\t.def\t");
632  assemble_name (file, name);
633  fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
634	   public ? (int) C_EXT : (int) C_STAT,
635	   (int) DT_FCN << N_BTSHFT);
636}
637
638/* Keep a list of external functions.  */
639
640struct extern_list GTY(())
641{
642  struct extern_list *next;
643  tree decl;
644  const char *name;
645};
646
647static GTY(()) struct extern_list *extern_head;
648
649/* Assemble an external function reference.  We need to keep a list of
650   these, so that we can output the function types at the end of the
651   assembly.  We can't output the types now, because we might see a
652   definition of the function later on and emit debugging information
653   for it then.  */
654
655void
656i386_pe_record_external_function (tree decl, const char *name)
657{
658  struct extern_list *p;
659
660  p = (struct extern_list *) ggc_alloc (sizeof *p);
661  p->next = extern_head;
662  p->decl = decl;
663  p->name = name;
664  extern_head = p;
665}
666
667/* Keep a list of exported symbols.  */
668
669struct export_list GTY(())
670{
671  struct export_list *next;
672  const char *name;
673  int is_data;		/* used to type tag exported symbols.  */
674};
675
676static GTY(()) struct export_list *export_head;
677
678/* Assemble an export symbol entry.  We need to keep a list of
679   these, so that we can output the export list at the end of the
680   assembly.  We used to output these export symbols in each function,
681   but that causes problems with GNU ld when the sections are
682   linkonce.  */
683
684void
685i386_pe_record_exported_symbol (const char *name, int is_data)
686{
687  struct export_list *p;
688
689  p = (struct export_list *) ggc_alloc (sizeof *p);
690  p->next = export_head;
691  p->name = name;
692  p->is_data = is_data;
693  export_head = p;
694}
695
696/* This is called at the end of assembly.  For each external function
697   which has not been defined, we output a declaration now.  We also
698   output the .drectve section.  */
699
700void
701i386_pe_file_end (void)
702{
703  struct extern_list *p;
704
705  ix86_file_end ();
706
707  for (p = extern_head; p != NULL; p = p->next)
708    {
709      tree decl;
710
711      decl = p->decl;
712
713      /* Positively ensure only one declaration for any given symbol.  */
714      if (! TREE_ASM_WRITTEN (decl)
715	  && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
716	{
717	  TREE_ASM_WRITTEN (decl) = 1;
718	  i386_pe_declare_function_type (asm_out_file, p->name,
719					 TREE_PUBLIC (decl));
720	}
721    }
722
723  if (export_head)
724    {
725      struct export_list *q;
726      drectve_section ();
727      for (q = export_head; q != NULL; q = q->next)
728	{
729	  fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
730		   i386_pe_strip_name_encoding (q->name),
731		   (q->is_data) ? ",data" : "");
732	}
733    }
734}
735
736#include "gt-winnt.h"
737