OSDN Git Service

d2828f04ecdcab399f40506de9242c37e4237ea8
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / winnt.c
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, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
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 #undef IN_GCC_FRONTEND
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"
38 #include "lto-streamer.h"
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     {
60       warning (OPT_Wattributes, "%qE attribute only applies to variables",
61                name);
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     {   
82       error ("%qE attribute applies only to initialized variables"
83              " with external linkage", name);
84       *no_add_attrs = true;
85     }
86
87   return NULL_TREE;
88 }
89
90 \f
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 {
106   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
107     return false;
108
109   /* Don't export local clones of dllexports.  */
110   if (!TREE_PUBLIC (decl))
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
134      error message if the class attribute has been overridden by an
135      out-of-class definition of static data.  */
136   assoc = associated_type (decl);
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);
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)))
291             make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
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))
310     flags |= SYMBOL_FLAG_DLLIMPORT;
311  
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
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))
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);
331
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
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
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
503 /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker.  */
504
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
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.  */
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);
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);
533 }
534 \f
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
559 struct GTY(()) extern_list
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
588 struct GTY(()) export_list
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
601    linkonce.  Beware, DECL may be NULL if compile_file() is emitting
602    the LTO marker.  */
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
610   if (!decl)
611     return;
612
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
618   gcc_assert (TREE_PUBLIC (decl));
619
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
627 #ifdef CXX_WRAP_SPEC_LIST
628
629 /*  Hash table equality helper function.  */
630
631 static int
632 wrapper_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
644 static const char *
645 i386_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
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         {
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 */
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"