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 
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 2, 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 COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-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 
49 static tree associated_type (tree);
50 static tree gen_stdcall_or_fastcall_suffix (tree, bool);
51 static bool i386_pe_dllexport_p (tree);
52 static bool i386_pe_dllimport_p (tree);
53 static void i386_pe_mark_dllexport (tree);
54 static 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.  */
67 tree
ix86_handle_shared_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)68 ix86_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.  */
84 tree
ix86_handle_selectany_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)85 ix86_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 
108 static tree
associated_type(tree decl)109 associated_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 
118 static bool
i386_pe_dllexport_p(tree decl)119 i386_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 
137 static bool
i386_pe_dllimport_p(tree decl)138 i386_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.  */
172 bool
i386_pe_valid_dllimport_attribute_p(tree decl)173 i386_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 
182 int
i386_pe_dllexport_name_p(const char * symbol)183 i386_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 
191 int
i386_pe_dllimport_name_p(const char * symbol)192 i386_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 
201 static void
i386_pe_mark_dllexport(tree decl)202 i386_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 
241 static void
i386_pe_mark_dllimport(tree decl)242 i386_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 
291 static tree
gen_stdcall_or_fastcall_suffix(tree decl,bool fastcall)292 gen_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 
340 void
i386_pe_encode_section_info(tree decl,rtx rtl,int first)341 i386_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 
409 const char *
i386_pe_strip_name_encoding(const char * str)410 i386_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 
425 const char *
i386_pe_strip_name_encoding_full(const char * str)426 i386_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 
i386_pe_output_labelref(FILE * stream,const char * name)447 void 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 
483 void
i386_pe_unique_section(tree decl,int reloc)484 i386_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 
529 unsigned int
i386_pe_section_type_flags(tree decl,const char * name,int reloc)530 i386_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 
574 void
i386_pe_asm_named_section(const char * name,unsigned int flags,tree decl)575 i386_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 
628 void
i386_pe_declare_function_type(FILE * file,const char * name,int public)629 i386_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 
640 struct extern_list GTY(())
641 {
642   struct extern_list *next;
643   tree decl;
644   const char *name;
645 };
646 
647 static 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 
655 void
i386_pe_record_external_function(tree decl,const char * name)656 i386_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 
669 struct 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 
676 static 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 
684 void
i386_pe_record_exported_symbol(const char * name,int is_data)685 i386_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 
700 void
i386_pe_file_end(void)701 i386_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