OSDN Git Service

34d3f427d237824e03f181fcc101df62c413dd39
[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
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     return false;
328
329   return true;
330 }
331
332 /* Also strip the fastcall prefix and stdcall suffix.  */
333
334 const char *
335 i386_pe_strip_name_encoding_full (const char *str)
336 {
337   const char *p;
338   const char *name = default_strip_name_encoding (str);
339
340   /* Strip leading '@' on fastcall symbols.  */
341   if (*name == '@')
342     name++;
343
344   /* Strip trailing "@n".  */
345   p = strchr (name, '@');
346   if (p)
347     return ggc_alloc_string (name, p - name);
348
349   return name;
350 }
351
352 void
353 i386_pe_unique_section (tree decl, int reloc)
354 {
355   int len;
356   const char *name, *prefix;
357   char *string;
358
359   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
360   name = i386_pe_strip_name_encoding_full (name);
361
362   /* The object is put in, for example, section .text$foo.
363      The linker will then ultimately place them in .text
364      (everything from the $ on is stripped). Don't put
365      read-only data in .rdata section to avoid a PE linker
366      bug when .rdata$* grouped sections are used in code
367      without a .rdata section.  */
368   if (TREE_CODE (decl) == FUNCTION_DECL)
369     prefix = ".text$";
370   else if (decl_readonly_section (decl, reloc))
371     prefix = ".rdata$";
372   else
373     prefix = ".data$";
374   len = strlen (name) + strlen (prefix);
375   string = XALLOCAVEC (char, len + 1);
376   sprintf (string, "%s%s", prefix, name);
377
378   DECL_SECTION_NAME (decl) = build_string (len, string);
379 }
380
381 /* Select a set of attributes for section NAME based on the properties
382    of DECL and whether or not RELOC indicates that DECL's initializer
383    might contain runtime relocations.
384
385    We make the section read-only and executable for a function decl,
386    read-only for a const data decl, and writable for a non-const data decl.
387
388    If the section has already been defined, to not allow it to have
389    different attributes, as (1) this is ambiguous since we're not seeing
390    all the declarations up front and (2) some assemblers (e.g. SVR4)
391    do not recognize section redefinitions.  */
392 /* ??? This differs from the "standard" PE implementation in that we
393    handle the SHARED variable attribute.  Should this be done for all
394    PE targets?  */
395
396 #define SECTION_PE_SHARED       SECTION_MACH_DEP
397
398 unsigned int
399 i386_pe_section_type_flags (tree decl, const char *name, int reloc)
400 {
401   static htab_t htab;
402   unsigned int flags;
403   unsigned int **slot;
404
405   /* The names we put in the hashtable will always be the unique
406      versions given to us by the stringtable, so we can just use
407      their addresses as the keys.  */
408   if (!htab)
409     htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
410
411   if (decl && TREE_CODE (decl) == FUNCTION_DECL)
412     flags = SECTION_CODE;
413   else if (decl && decl_readonly_section (decl, reloc))
414     flags = 0;
415   else if (current_function_decl
416            && cfun
417            && crtl->subsections.unlikely_text_section_name
418            && strcmp (name, crtl->subsections.unlikely_text_section_name) == 0)
419     flags = SECTION_CODE;
420   else if (!decl
421            && (!current_function_decl || !cfun)
422            && strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
423     flags = SECTION_CODE;
424   else
425     {
426       flags = SECTION_WRITE;
427
428       if (decl && TREE_CODE (decl) == VAR_DECL
429           && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
430         flags |= SECTION_PE_SHARED;
431     }
432
433   if (decl && DECL_ONE_ONLY (decl))
434     flags |= SECTION_LINKONCE;
435
436   /* See if we already have an entry for this section.  */
437   slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
438   if (!*slot)
439     {
440       *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
441       **slot = flags;
442     }
443   else
444     {
445       if (decl && **slot != flags)
446         error ("%q+D causes a section type conflict", decl);
447     }
448
449   return flags;
450 }
451
452 void
453 i386_pe_asm_named_section (const char *name, unsigned int flags, 
454                            tree decl)
455 {
456   char flagchars[8], *f = flagchars;
457
458   if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
459     /* readonly data */
460     {
461       *f++ ='d';  /* This is necessary for older versions of gas.  */
462       *f++ ='r';
463     }
464   else  
465     {
466       if (flags & SECTION_CODE)
467         *f++ = 'x';
468       if (flags & SECTION_WRITE)
469         *f++ = 'w';
470       if (flags & SECTION_PE_SHARED)
471         *f++ = 's';
472     }
473
474   /* LTO sections need 1-byte alignment to avoid confusing the
475      zlib decompression algorithm with trailing zero pad bytes.  */
476   if (strncmp (name, LTO_SECTION_NAME_PREFIX,
477                         strlen (LTO_SECTION_NAME_PREFIX)) == 0)
478     *f++ = '0';
479
480   *f = '\0';
481
482   fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
483
484   if (flags & SECTION_LINKONCE)
485     {
486       /* Functions may have been compiled at various levels of
487          optimization so we can't use `same_size' here.
488          Instead, have the linker pick one, without warning.
489          If 'selectany' attribute has been specified,  MS compiler
490          sets 'discard' characteristic, rather than telling linker
491          to warn of size or content mismatch, so do the same.  */ 
492       bool discard = (flags & SECTION_CODE)
493                       || lookup_attribute ("selectany",
494                                            DECL_ATTRIBUTES (decl));      
495       fprintf (asm_out_file, "\t.linkonce %s\n",
496                (discard  ? "discard" : "same_size"));
497     }
498 }
499
500 /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker.  */
501
502 void
503 i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
504                                         const char *name, HOST_WIDE_INT size,
505                                         HOST_WIDE_INT align ATTRIBUTE_UNUSED)
506 {
507   HOST_WIDE_INT rounded;
508
509   /* Compute as in assemble_noswitch_variable, since we don't have
510      support for aligned common on older binutils.  We must also
511      avoid emitting a common symbol of size zero, as this is the
512      overloaded representation that indicates an undefined external
513      symbol in the PE object file format.  */
514   rounded = size ? size : 1;
515   rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
516   rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
517              * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
518   
519   i386_pe_maybe_record_exported_symbol (decl, name, 1);
520
521   fprintf (stream, "\t.comm\t");
522   assemble_name (stream, name);
523   if (use_pe_aligned_common)
524     fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
525            size ? size : (HOST_WIDE_INT) 1,
526            exact_log2 (align) - exact_log2 (CHAR_BIT));
527   else
528     fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
529            " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
530 }
531 \f
532 /* The Microsoft linker requires that every function be marked as
533    DT_FCN.  When using gas on cygwin, we must emit appropriate .type
534    directives.  */
535
536 #include "gsyms.h"
537
538 /* Mark a function appropriately.  This should only be called for
539    functions for which we are not emitting COFF debugging information.
540    FILE is the assembler output file, NAME is the name of the
541    function, and PUB is nonzero if the function is globally
542    visible.  */
543
544 void
545 i386_pe_declare_function_type (FILE *file, const char *name, int pub)
546 {
547   fprintf (file, "\t.def\t");
548   assemble_name (file, name);
549   fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
550            pub ? (int) C_EXT : (int) C_STAT,
551            (int) DT_FCN << N_BTSHFT);
552 }
553
554 /* Keep a list of external functions.  */
555
556 struct GTY(()) extern_list
557 {
558   struct extern_list *next;
559   tree decl;
560   const char *name;
561 };
562
563 static GTY(()) struct extern_list *extern_head;
564
565 /* Assemble an external function reference.  We need to keep a list of
566    these, so that we can output the function types at the end of the
567    assembly.  We can't output the types now, because we might see a
568    definition of the function later on and emit debugging information
569    for it then.  */
570
571 void
572 i386_pe_record_external_function (tree decl, const char *name)
573 {
574   struct extern_list *p;
575
576   p = (struct extern_list *) ggc_alloc (sizeof *p);
577   p->next = extern_head;
578   p->decl = decl;
579   p->name = name;
580   extern_head = p;
581 }
582
583 /* Keep a list of exported symbols.  */
584
585 struct GTY(()) export_list
586 {
587   struct export_list *next;
588   const char *name;
589   int is_data;          /* used to type tag exported symbols.  */
590 };
591
592 static GTY(()) struct export_list *export_head;
593
594 /* Assemble an export symbol entry.  We need to keep a list of
595    these, so that we can output the export list at the end of the
596    assembly.  We used to output these export symbols in each function,
597    but that causes problems with GNU ld when the sections are
598    linkonce.  Beware, DECL may be NULL if compile_file() is emitting
599    the LTO marker.  */
600
601 void
602 i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
603 {
604   rtx symbol;
605   struct export_list *p;
606
607   if (!decl)
608     return;
609
610   symbol = XEXP (DECL_RTL (decl), 0);
611   gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
612   if (!SYMBOL_REF_DLLEXPORT_P (symbol))
613     return;
614
615   gcc_assert (TREE_PUBLIC (decl));
616
617   p = (struct export_list *) ggc_alloc (sizeof *p);
618   p->next = export_head;
619   p->name = name;
620   p->is_data = is_data;
621   export_head = p;
622 }
623
624 #ifdef CXX_WRAP_SPEC_LIST
625
626 /*  Hash table equality helper function.  */
627
628 static int
629 wrapper_strcmp (const void *x, const void *y)
630 {
631   return !strcmp ((const char *) x, (const char *) y);
632 }
633
634 /* Search for a function named TARGET in the list of library wrappers
635    we are using, returning a pointer to it if found or NULL if not.
636    This function might be called on quite a few symbols, and we only
637    have the list of names of wrapped functions available to us as a
638    spec string, so first time round we lazily initialise a hash table
639    to make things quicker.  */
640
641 static const char *
642 i386_find_on_wrapper_list (const char *target)
643 {
644   static char first_time = 1;
645   static htab_t wrappers;
646
647   if (first_time)
648     {
649       /* Beware that this is not a complicated parser, it assumes
650          that any sequence of non-whitespace beginning with an
651          underscore is one of the wrapped symbols.  For now that's
652          adequate to distinguish symbols from spec substitutions
653          and command-line options.  */
654       static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
655       char *bufptr;
656       /* Breaks up the char array into separated strings
657          strings and enter them into the hash table.  */
658       wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
659         0, xcalloc, free);
660       for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
661         {
662           char *found = NULL;
663           if (ISSPACE (*bufptr))
664             continue;
665           if (*bufptr == '_')
666             found = bufptr;
667           while (*bufptr && !ISSPACE (*bufptr))
668             ++bufptr;
669           if (*bufptr)
670             *bufptr = 0;
671           if (found)
672             *htab_find_slot (wrappers, found, INSERT) = found;
673         }
674       first_time = 0;
675     }
676
677   return (const char *) htab_find (wrappers, target);
678 }
679
680 #endif /* CXX_WRAP_SPEC_LIST */
681
682 /* This is called at the end of assembly.  For each external function
683    which has not been defined, we output a declaration now.  We also
684    output the .drectve section.  */
685
686 void
687 i386_pe_file_end (void)
688 {
689   struct extern_list *p;
690
691   for (p = extern_head; p != NULL; p = p->next)
692     {
693       tree decl;
694
695       decl = p->decl;
696
697       /* Positively ensure only one declaration for any given symbol.  */
698       if (! TREE_ASM_WRITTEN (decl)
699           && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
700         {
701 #ifdef CXX_WRAP_SPEC_LIST
702           /* To ensure the DLL that provides the corresponding real
703              functions is still loaded at runtime, we must reference
704              the real function so that an (unused) import is created.  */
705           const char *realsym = i386_find_on_wrapper_list (p->name);
706           if (realsym)
707             i386_pe_declare_function_type (asm_out_file,
708                 concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
709 #endif /* CXX_WRAP_SPEC_LIST */
710           TREE_ASM_WRITTEN (decl) = 1;
711           i386_pe_declare_function_type (asm_out_file, p->name,
712                                          TREE_PUBLIC (decl));
713         }
714     }
715
716   if (export_head)
717     {
718       struct export_list *q;
719       drectve_section ();
720       for (q = export_head; q != NULL; q = q->next)
721         {
722           fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
723                    default_strip_name_encoding (q->name),
724                    (q->is_data ? ",data" : ""));
725         }
726     }
727 }
728
729 #include "gt-winnt.h"