118334Speter/* Subroutines for insn-output.c for Windows NT.
218334Speter   Contributed by Douglas Rupp (drupp@cs.washington.edu)
3169689Skan   Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4169689Skan   2005, 2006  Free Software Foundation, Inc.
518334Speter
6119256SkanThis file is part of GCC.
718334Speter
8119256SkanGCC is free software; you can redistribute it and/or modify it under
9119256Skanthe terms of the GNU General Public License as published by the Free
10119256SkanSoftware Foundation; either version 2, or (at your option) any later
11119256Skanversion.
1218334Speter
13119256SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
14119256SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
15119256SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16119256Skanfor more details.
1718334Speter
1818334SpeterYou should have received a copy of the GNU General Public License
19119256Skanalong with GCC; see the file COPYING.  If not, write to the Free
20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169689Skan02110-1301, USA.  */
2218334Speter
2318334Speter#include "config.h"
2450397Sobrien#include "system.h"
25132718Skan#include "coretypes.h"
26132718Skan#include "tm.h"
2718334Speter#include "rtl.h"
2818334Speter#include "regs.h"
2918334Speter#include "hard-reg-set.h"
3018334Speter#include "output.h"
3118334Speter#include "tree.h"
3218334Speter#include "flags.h"
3390075Sobrien#include "tm_p.h"
3490075Sobrien#include "toplev.h"
3590075Sobrien#include "hashtab.h"
36117395Skan#include "ggc.h"
3718334Speter
3850397Sobrien/* i386/PE specific attribute support.
3950397Sobrien
4050397Sobrien   i386/PE has two new attributes:
4150397Sobrien   dllexport - for exporting a function/variable that will live in a dll
4250397Sobrien   dllimport - for importing a function/variable from a dll
4350397Sobrien
4450397Sobrien   Microsoft allows multiple declspecs in one __declspec, separating
4550397Sobrien   them with spaces.  We do NOT support this.  Instead, use __declspec
4650397Sobrien   multiple times.
4750397Sobrien*/
4850397Sobrien
49132718Skanstatic tree associated_type (tree);
50169689Skanstatic tree gen_stdcall_or_fastcall_suffix (tree, bool);
51169689Skanstatic bool i386_pe_dllexport_p (tree);
52169689Skanstatic bool i386_pe_dllimport_p (tree);
53132718Skanstatic void i386_pe_mark_dllexport (tree);
54132718Skanstatic void i386_pe_mark_dllimport (tree);
5550397Sobrien
56132718Skan/* This is we how mark internal identifiers with dllimport or dllexport
57132718Skan   attributes.  */
58132718Skan#ifndef DLL_IMPORT_PREFIX
59132718Skan#define DLL_IMPORT_PREFIX "#i."
60132718Skan#endif
61132718Skan#ifndef DLL_EXPORT_PREFIX
62132718Skan#define DLL_EXPORT_PREFIX "#e."
63132718Skan#endif
64132718Skan
65169689Skan/* Handle a "shared" attribute;
6690075Sobrien   arguments as in struct attribute_spec.handler.  */
6790075Sobrientree
68169689Skanix86_handle_shared_attribute (tree *node, tree name,
69169689Skan			      tree args ATTRIBUTE_UNUSED,
70169689Skan			      int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
7150397Sobrien{
72169689Skan  if (TREE_CODE (*node) != VAR_DECL)
7350397Sobrien    {
74169689Skan      warning (OPT_Wattributes, "%qs attribute only applies to variables",
75169689Skan	       IDENTIFIER_POINTER (name));
76119256Skan      *no_add_attrs = true;
77119256Skan    }
78119256Skan
7990075Sobrien  return NULL_TREE;
8050397Sobrien}
8150397Sobrien
82169689Skan/* Handle a "selectany" attribute;
8390075Sobrien   arguments as in struct attribute_spec.handler.  */
8450397Sobrientree
85169689Skanix86_handle_selectany_attribute (tree *node, tree name,
86169689Skan			         tree args ATTRIBUTE_UNUSED,
87169689Skan			         int flags ATTRIBUTE_UNUSED,
88169689Skan				 bool *no_add_attrs)
8950397Sobrien{
90169689Skan  /* The attribute applies only to objects that are initialized and have
91169689Skan     external linkage.  However, we may not know about initialization
92169689Skan     until the language frontend has processed the decl. We'll check for
93169689Skan     initialization later in encode_section_info.  */
94169689Skan  if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
95169689Skan    {
96169689Skan      error ("%qs attribute applies only to initialized variables"
97169689Skan       	     " with external linkage",  IDENTIFIER_POINTER (name));
9890075Sobrien      *no_add_attrs = true;
9950397Sobrien    }
10050397Sobrien
10190075Sobrien  return NULL_TREE;
10250397Sobrien}
103169689Skan
10450397Sobrien
10550397Sobrien/* Return the type that we should use to determine if DECL is
10650397Sobrien   imported or exported.  */
10750397Sobrien
10850397Sobrienstatic tree
109132718Skanassociated_type (tree decl)
11050397Sobrien{
111169689Skan  return  (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
112169689Skan            ?  DECL_CONTEXT (decl) : NULL_TREE;
113169689Skan}
11450397Sobrien
11550397Sobrien
116169689Skan/* Return true if DECL is a dllexport'd object.  */
11750397Sobrien
118169689Skanstatic bool
119132718Skani386_pe_dllexport_p (tree decl)
12050397Sobrien{
12150397Sobrien  if (TREE_CODE (decl) != VAR_DECL
122169689Skan       && TREE_CODE (decl) != FUNCTION_DECL)
123169689Skan    return false;
12450397Sobrien
125169689Skan  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
126169689Skan    return true;
12750397Sobrien
128169689Skan  /* Also mark class members of exported classes with dllexport.  */
129169689Skan  if (associated_type (decl)
130169689Skan      && lookup_attribute ("dllexport",
131169689Skan			    TYPE_ATTRIBUTES (associated_type (decl))))
132169689Skan    return i386_pe_type_dllexport_p (decl);
133169689Skan
134169689Skan  return false;
13550397Sobrien}
13650397Sobrien
137169689Skanstatic bool
138132718Skani386_pe_dllimport_p (tree decl)
13950397Sobrien{
14050397Sobrien  if (TREE_CODE (decl) != VAR_DECL
141169689Skan       && TREE_CODE (decl) != FUNCTION_DECL)
142169689Skan    return false;
143119256Skan
144169689Skan  /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag.
145169689Skan     We may need to override an earlier decision.  */
146169689Skan  if (DECL_DLLIMPORT_P (decl)
147169689Skan      && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)))
14850397Sobrien    {
149169689Skan       /* Make a final check to see if this is a definition before we generate
150169689Skan          RTL for an indirect reference.  */
151169689Skan       if (!DECL_EXTERNAL (decl))
152119256Skan	{
153169689Skan	  error ("%q+D: definition is marked as dllimport", decl);
154169689Skan	  DECL_DLLIMPORT_P (decl) = 0;
155169689Skan          return false;
156169689Skan        }
157169689Skan      return true;
158119256Skan    }
159169689Skan  /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
160169689Skan     by  targetm.cxx.adjust_class_at_definition.  Check again to emit
161169689Skan     warnings if the class attribute has been overridden by an
162169689Skan     out-of-class definition.  */
163169689Skan  else if (associated_type (decl)
164169689Skan           && lookup_attribute ("dllimport",
165169689Skan				TYPE_ATTRIBUTES (associated_type (decl))))
166169689Skan    return i386_pe_type_dllimport_p (decl);
167119256Skan
168169689Skan  return false;
16950397Sobrien}
17050397Sobrien
171169689Skan/* Handle the -mno-fun-dllimport target switch.  */
172169689Skanbool
173169689Skani386_pe_valid_dllimport_attribute_p (tree decl)
174169689Skan{
175169689Skan   if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
176169689Skan     return false;
177169689Skan   return true;
178169689Skan}
179169689Skan
180117395Skan/* Return nonzero if SYMBOL is marked as being dllexport'd.  */
18150397Sobrien
18250397Sobrienint
183132718Skani386_pe_dllexport_name_p (const char *symbol)
18450397Sobrien{
185132718Skan  return (strncmp (DLL_EXPORT_PREFIX, symbol,
186132718Skan		   strlen (DLL_EXPORT_PREFIX)) == 0);
18750397Sobrien}
18850397Sobrien
189117395Skan/* Return nonzero if SYMBOL is marked as being dllimport'd.  */
19050397Sobrien
19150397Sobrienint
192132718Skani386_pe_dllimport_name_p (const char *symbol)
19350397Sobrien{
194132718Skan  return (strncmp (DLL_IMPORT_PREFIX, symbol,
195132718Skan		   strlen (DLL_IMPORT_PREFIX)) == 0);
19650397Sobrien}
19750397Sobrien
19850397Sobrien/* Mark a DECL as being dllexport'd.
199169689Skan   Note that we override the previous setting (e.g.: dllimport).  */
20050397Sobrien
201132718Skanstatic void
202132718Skani386_pe_mark_dllexport (tree decl)
20350397Sobrien{
20490075Sobrien  const char *oldname;
20590075Sobrien  char  *newname;
20650397Sobrien  rtx rtlname;
207169689Skan  rtx symref;
20850397Sobrien  tree idp;
20950397Sobrien
21050397Sobrien  rtlname = XEXP (DECL_RTL (decl), 0);
211169689Skan  if (GET_CODE (rtlname) == MEM)
212169689Skan    rtlname = XEXP (rtlname, 0);
213169689Skan  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
214169689Skan  oldname = XSTR (rtlname, 0);
21550397Sobrien  if (i386_pe_dllimport_name_p (oldname))
216119256Skan    {
217169689Skan      warning (0, "inconsistent dll linkage for %q+D, dllexport assumed",
218169689Skan	       decl);
219119256Skan     /* Remove DLL_IMPORT_PREFIX.  */
220132718Skan      oldname += strlen (DLL_IMPORT_PREFIX);
221119256Skan    }
22250397Sobrien  else if (i386_pe_dllexport_name_p (oldname))
223132718Skan    return;  /*  already done  */
22450397Sobrien
225132718Skan  newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
226132718Skan  sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
22750397Sobrien
22850397Sobrien  /* We pass newname through get_identifier to ensure it has a unique
22950397Sobrien     address.  RTL processing can sometimes peek inside the symbol ref
23050397Sobrien     and compare the string's addresses to see if two symbols are
23150397Sobrien     identical.  */
23250397Sobrien  idp = get_identifier (newname);
23350397Sobrien
234169689Skan  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
235169689Skan  SET_SYMBOL_REF_DECL (symref, decl);
236169689Skan  XEXP (DECL_RTL (decl), 0) = symref;
23750397Sobrien}
23850397Sobrien
23950397Sobrien/* Mark a DECL as being dllimport'd.  */
24050397Sobrien
241132718Skanstatic void
242132718Skani386_pe_mark_dllimport (tree decl)
24350397Sobrien{
24490075Sobrien  const char *oldname;
24590075Sobrien  char  *newname;
24650397Sobrien  tree idp;
24750397Sobrien  rtx rtlname, newrtl;
248169689Skan  rtx symref;
24950397Sobrien
25050397Sobrien  rtlname = XEXP (DECL_RTL (decl), 0);
251169689Skan  if (GET_CODE (rtlname) == MEM)
252169689Skan    rtlname = XEXP (rtlname, 0);
253169689Skan  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
254169689Skan  oldname = XSTR (rtlname, 0);
25550397Sobrien  if (i386_pe_dllexport_name_p (oldname))
25650397Sobrien    {
257169689Skan      error ("%qs declared as both exported to and imported from a DLL",
25850397Sobrien             IDENTIFIER_POINTER (DECL_NAME (decl)));
25950397Sobrien      return;
26050397Sobrien    }
26150397Sobrien  else if (i386_pe_dllimport_name_p (oldname))
26250397Sobrien    {
263169689Skan      /* Already done, but do a sanity check to prevent assembler
264169689Skan	 errors.  */
265169689Skan      gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
266169689Skan		  && DECL_DLLIMPORT_P (decl));
267132718Skan      return;
26850397Sobrien    }
26950397Sobrien
270132718Skan  newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
271132718Skan  sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
27250397Sobrien
27350397Sobrien  /* We pass newname through get_identifier to ensure it has a unique
27450397Sobrien     address.  RTL processing can sometimes peek inside the symbol ref
27550397Sobrien     and compare the string's addresses to see if two symbols are
27650397Sobrien     identical.  */
27750397Sobrien  idp = get_identifier (newname);
27850397Sobrien
279169689Skan  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
280169689Skan  SET_SYMBOL_REF_DECL (symref, decl);
281169689Skan  newrtl = gen_rtx_MEM (Pmode,symref);
28250397Sobrien  XEXP (DECL_RTL (decl), 0) = newrtl;
28350397Sobrien
284169689Skan  DECL_DLLIMPORT_P (decl) = 1;
28550397Sobrien}
28650397Sobrien
287132718Skan/* Return string which is the former assembler name modified with a
288132718Skan   suffix consisting of an atsign (@) followed by the number of bytes of
289169689Skan   arguments.  If FASTCALL is true, also add the FASTCALL_PREFIX.  */
29018334Speter
291169689Skanstatic tree
292169689Skangen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
29318334Speter{
29418334Speter  int total = 0;
29550397Sobrien  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
29650397Sobrien     of DECL_ASSEMBLER_NAME.  */
297169689Skan   const char *asmname =  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
29818334Speter  char *newsym;
299169689Skan  char *p;
300169689Skan  tree formal_type;
30118334Speter
302169689Skan  /* Do not change the identifier if a verbatim asmspec or already done. */
303169689Skan  if (*asmname == '*' || strchr (asmname, '@'))
304169689Skan    return DECL_ASSEMBLER_NAME (decl);
30518334Speter
306169689Skan  formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
307169689Skan  if (formal_type != NULL_TREE)
308169689Skan    {
309169689Skan      /* These attributes are ignored for variadic functions in
310169689Skan	 i386.c:ix86_return_pops_args. For compatibility with MS
311169689Skan         compiler do not add @0 suffix here.  */
312169689Skan      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
313169689Skan        return DECL_ASSEMBLER_NAME (decl);
314169689Skan
315169689Skan      /* Quit if we hit an incomplete type.  Error is reported
316169689Skan         by convert_arguments in c-typeck.c or cp/typeck.c.  */
317169689Skan      while (TREE_VALUE (formal_type) != void_type_node
318169689Skan	     && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
319169689Skan	{
320169689Skan	  int parm_size
321169689Skan	    = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
32250397Sobrien	    /* Must round up to include padding.  This is done the same
32350397Sobrien	       way as in store_one_arg.  */
324169689Skan	  parm_size = ((parm_size + PARM_BOUNDARY - 1)
325169689Skan		       / PARM_BOUNDARY * PARM_BOUNDARY);
326169689Skan	  total += parm_size;
327169689Skan	  formal_type = TREE_CHAIN (formal_type);\
328169689Skan	}
329169689Skan     }
33018334Speter
331132718Skan  /* Assume max of 8 base 10 digits in the suffix.  */
332169689Skan  newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
333169689Skan  p = newsym;
334169689Skan  if (fastcall)
335169689Skan    *p++ = FASTCALL_PREFIX;
336169689Skan  sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
337169689Skan  return get_identifier (newsym);
33818334Speter}
33918334Speter
34050397Sobrienvoid
341132718Skani386_pe_encode_section_info (tree decl, rtx rtl, int first)
34250397Sobrien{
343132718Skan  default_encode_section_info (decl, rtl, first);
344132718Skan
345169689Skan  if (first && TREE_CODE (decl) == FUNCTION_DECL)
34650397Sobrien    {
347169689Skan      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
348169689Skan      tree newid = NULL_TREE;
349169689Skan
350169689Skan      if (lookup_attribute ("stdcall", type_attributes))
351169689Skan	newid = gen_stdcall_or_fastcall_suffix (decl, false);
352169689Skan      else if (lookup_attribute ("fastcall", type_attributes))
353169689Skan	newid = gen_stdcall_or_fastcall_suffix (decl, true);
354169689Skan      if (newid != NULL_TREE)
355169689Skan	{
356169689Skan	  rtx rtlname = XEXP (rtl, 0);
357169689Skan	  if (GET_CODE (rtlname) == MEM)
358169689Skan	    rtlname = XEXP (rtlname, 0);
359169689Skan	  XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
360169689Skan	  /* These attributes must be present on first declaration,
361169689Skan	     change_decl_assembler_name will warn if they are added
362169689Skan	     later and the decl has been referenced, but duplicate_decls
363169689Skan	     should catch the mismatch before this is called.  */
364169689Skan	  change_decl_assembler_name (decl, newid);
365169689Skan	}
36650397Sobrien    }
36750397Sobrien
368169689Skan  else if (TREE_CODE (decl) == VAR_DECL
369169689Skan           && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
370169689Skan    {
371169689Skan      if (DECL_INITIAL (decl)
372169689Skan 	  /* If an object is initialized with a ctor, the static
373169689Skan	     initialization and destruction code for it is present in
374169689Skan	     each unit defining the object.  The code that calls the
375169689Skan	     ctor is protected by a link-once guard variable, so that
376169689Skan	     the object still has link-once semantics,  */
377169689Skan    	   || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
378169689Skan	make_decl_one_only (decl);
379169689Skan      else
380169689Skan	error ("%q+D:'selectany' attribute applies only to initialized objects",
381169689Skan	       decl);
382169689Skan    }
383169689Skan
38450397Sobrien  /* Mark the decl so we can tell from the rtl whether the object is
385169689Skan     dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
386169689Skan     handles dllexport/dllimport override semantics.  */
38750397Sobrien
38850397Sobrien  if (i386_pe_dllexport_p (decl))
38950397Sobrien    i386_pe_mark_dllexport (decl);
39050397Sobrien  else if (i386_pe_dllimport_p (decl))
39150397Sobrien    i386_pe_mark_dllimport (decl);
392169689Skan  /* It might be that DECL has been declared as dllimport, but a
393169689Skan     subsequent definition nullified that.  Assert that
394169689Skan     tree.c: merge_dllimport_decl_attributes has removed the attribute
395169689Skan     before the RTL name was marked with the DLL_IMPORT_PREFIX.  */
396169689Skan  else
397169689Skan    gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL
398169689Skan	    	   || TREE_CODE (decl) == VAR_DECL)
399169689Skan		  && rtl != NULL_RTX
400169689Skan		  && GET_CODE (rtl) == MEM
401169689Skan		  && GET_CODE (XEXP (rtl, 0)) == MEM
402169689Skan		  && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF
403169689Skan		  && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0))));
40450397Sobrien}
40550397Sobrien
406132718Skan/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
407132718Skan   prefix if it exists.  */
40850397Sobrien
409117395Skanconst char *
410132718Skani386_pe_strip_name_encoding (const char *str)
411117395Skan{
412132718Skan  if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
413132718Skan      == 0)
414132718Skan    str += strlen (DLL_IMPORT_PREFIX);
415132718Skan  else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
416132718Skan	   == 0)
417132718Skan    str += strlen (DLL_EXPORT_PREFIX);
418117395Skan  if (*str == '*')
419117395Skan    str += 1;
420117395Skan  return str;
421117395Skan}
422117395Skan
423169689Skan/* Also strip the fastcall prefix and stdcall suffix.  */
424117395Skan
425117395Skanconst char *
426132718Skani386_pe_strip_name_encoding_full (const char *str)
427117395Skan{
428117395Skan  const char *p;
429117395Skan  const char *name = i386_pe_strip_name_encoding (str);
430132718Skan
431169689Skan  /* Strip leading '@' on fastcall symbols.  */
432169689Skan  if (*name == '@')
433169689Skan    name++;
434169689Skan
435169689Skan  /* Strip trailing "@n".  */
436117395Skan  p = strchr (name, '@');
437117395Skan  if (p)
438117395Skan    return ggc_alloc_string (name, p - name);
439117395Skan
440117395Skan  return name;
441117395Skan}
442117395Skan
443132718Skan/* Output a reference to a label. Fastcall symbols are prefixed with @,
444132718Skan   whereas symbols for functions using other calling conventions don't
445132718Skan   have a prefix (unless they are marked dllimport or dllexport).  */
446132718Skan
447132718Skanvoid i386_pe_output_labelref (FILE *stream, const char *name)
448132718Skan{
449132718Skan  if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
450132718Skan      == 0)
451132718Skan    /* A dll import */
452132718Skan    {
453132718Skan      if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
454132718Skan      /* A dllimport fastcall symbol.  */
455132718Skan        {
456132718Skan          fprintf (stream, "__imp_%s",
457132718Skan                   i386_pe_strip_name_encoding (name));
458132718Skan        }
459132718Skan      else
460132718Skan      /* A dllimport non-fastcall symbol.  */
461132718Skan        {
462132718Skan          fprintf (stream, "__imp__%s",
463132718Skan                   i386_pe_strip_name_encoding (name));
464132718Skan        }
465132718Skan    }
466132718Skan  else if ((name[0] == FASTCALL_PREFIX)
467169689Skan           || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
468132718Skan	       == 0
469169689Skan	       && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX))
470132718Skan    /* A fastcall symbol.  */
471132718Skan    {
472132718Skan      fprintf (stream, "%s",
473132718Skan               i386_pe_strip_name_encoding (name));
474132718Skan    }
475132718Skan  else
476132718Skan    /* Everything else.  */
477132718Skan    {
478132718Skan      fprintf (stream, "%s%s", USER_LABEL_PREFIX,
479132718Skan               i386_pe_strip_name_encoding (name));
480132718Skan    }
481132718Skan}
482132718Skan
48350397Sobrienvoid
484132718Skani386_pe_unique_section (tree decl, int reloc)
48550397Sobrien{
48650397Sobrien  int len;
48790075Sobrien  const char *name, *prefix;
48890075Sobrien  char *string;
48950397Sobrien
49050397Sobrien  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
491117395Skan  name = i386_pe_strip_name_encoding_full (name);
49250397Sobrien
49350397Sobrien  /* The object is put in, for example, section .text$foo.
49450397Sobrien     The linker will then ultimately place them in .text
49550397Sobrien     (everything from the $ on is stripped). Don't put
496132718Skan     read-only data in .rdata section to avoid a PE linker
49750397Sobrien     bug when .rdata$* grouped sections are used in code
49850397Sobrien     without a .rdata section.  */
49950397Sobrien  if (TREE_CODE (decl) == FUNCTION_DECL)
50050397Sobrien    prefix = ".text$";
501117395Skan  else if (decl_readonly_section (decl, reloc))
50250397Sobrien    prefix = ".rdata$";
50350397Sobrien  else
50450397Sobrien    prefix = ".data$";
50550397Sobrien  len = strlen (name) + strlen (prefix);
50650397Sobrien  string = alloca (len + 1);
50750397Sobrien  sprintf (string, "%s%s", prefix, name);
50850397Sobrien
50950397Sobrien  DECL_SECTION_NAME (decl) = build_string (len, string);
51050397Sobrien}
51190075Sobrien
51290075Sobrien/* Select a set of attributes for section NAME based on the properties
51390075Sobrien   of DECL and whether or not RELOC indicates that DECL's initializer
51490075Sobrien   might contain runtime relocations.
51590075Sobrien
51690075Sobrien   We make the section read-only and executable for a function decl,
51790075Sobrien   read-only for a const data decl, and writable for a non-const data decl.
51890075Sobrien
51990075Sobrien   If the section has already been defined, to not allow it to have
52090075Sobrien   different attributes, as (1) this is ambiguous since we're not seeing
52190075Sobrien   all the declarations up front and (2) some assemblers (e.g. SVR4)
522132718Skan   do not recognize section redefinitions.  */
52390075Sobrien/* ??? This differs from the "standard" PE implementation in that we
52490075Sobrien   handle the SHARED variable attribute.  Should this be done for all
52590075Sobrien   PE targets?  */
52690075Sobrien
52790075Sobrien#define SECTION_PE_SHARED	SECTION_MACH_DEP
52890075Sobrien
52990075Sobrienunsigned int
530132718Skani386_pe_section_type_flags (tree decl, const char *name, int reloc)
53190075Sobrien{
53290075Sobrien  static htab_t htab;
53390075Sobrien  unsigned int flags;
53490075Sobrien  unsigned int **slot;
53590075Sobrien
53690075Sobrien  /* The names we put in the hashtable will always be the unique
537169689Skan     versions given to us by the stringtable, so we can just use
53890075Sobrien     their addresses as the keys.  */
53990075Sobrien  if (!htab)
54090075Sobrien    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
54190075Sobrien
54290075Sobrien  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
54390075Sobrien    flags = SECTION_CODE;
544117395Skan  else if (decl && decl_readonly_section (decl, reloc))
54590075Sobrien    flags = 0;
54690075Sobrien  else
54790075Sobrien    {
54890075Sobrien      flags = SECTION_WRITE;
54990075Sobrien
55090075Sobrien      if (decl && TREE_CODE (decl) == VAR_DECL
55190075Sobrien	  && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
55290075Sobrien	flags |= SECTION_PE_SHARED;
55390075Sobrien    }
55490075Sobrien
55590075Sobrien  if (decl && DECL_ONE_ONLY (decl))
55690075Sobrien    flags |= SECTION_LINKONCE;
55790075Sobrien
55890075Sobrien  /* See if we already have an entry for this section.  */
55990075Sobrien  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
56090075Sobrien  if (!*slot)
56190075Sobrien    {
56290075Sobrien      *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
56390075Sobrien      **slot = flags;
56490075Sobrien    }
56590075Sobrien  else
56690075Sobrien    {
56790075Sobrien      if (decl && **slot != flags)
568169689Skan	error ("%q+D causes a section type conflict", decl);
56990075Sobrien    }
57090075Sobrien
57190075Sobrien  return flags;
57290075Sobrien}
57390075Sobrien
57490075Sobrienvoid
575169689Skani386_pe_asm_named_section (const char *name, unsigned int flags,
576169689Skan			   tree decl)
57790075Sobrien{
57890075Sobrien  char flagchars[8], *f = flagchars;
57990075Sobrien
580132718Skan  if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
581132718Skan    /* readonly data */
582132718Skan    {
583132718Skan      *f++ ='d';  /* This is necessary for older versions of gas.  */
584132718Skan      *f++ ='r';
585132718Skan    }
586132718Skan  else
587132718Skan    {
588132718Skan      if (flags & SECTION_CODE)
589132718Skan        *f++ = 'x';
590132718Skan      if (flags & SECTION_WRITE)
591132718Skan        *f++ = 'w';
592132718Skan      if (flags & SECTION_PE_SHARED)
593132718Skan        *f++ = 's';
594132718Skan    }
595132718Skan
59690075Sobrien  *f = '\0';
59790075Sobrien
59890075Sobrien  fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
59990075Sobrien
60090075Sobrien  if (flags & SECTION_LINKONCE)
60190075Sobrien    {
60290075Sobrien      /* Functions may have been compiled at various levels of
603169689Skan	 optimization so we can't use `same_size' here.
604169689Skan	 Instead, have the linker pick one, without warning.
605169689Skan	 If 'selectany' attribute has been specified,  MS compiler
606169689Skan	 sets 'discard' characteristic, rather than telling linker
607169689Skan	 to warn of size or content mismatch, so do the same.  */
608169689Skan      bool discard = (flags & SECTION_CODE)
609169689Skan		      || lookup_attribute ("selectany",
610169689Skan					   DECL_ATTRIBUTES (decl));
61190075Sobrien      fprintf (asm_out_file, "\t.linkonce %s\n",
612169689Skan	       (discard  ? "discard" : "same_size"));
61390075Sobrien    }
61490075Sobrien}
61550397Sobrien
61650397Sobrien/* The Microsoft linker requires that every function be marked as
61752284Sobrien   DT_FCN.  When using gas on cygwin, we must emit appropriate .type
61850397Sobrien   directives.  */
61950397Sobrien
62050397Sobrien#include "gsyms.h"
62150397Sobrien
62250397Sobrien/* Mark a function appropriately.  This should only be called for
62350397Sobrien   functions for which we are not emitting COFF debugging information.
62450397Sobrien   FILE is the assembler output file, NAME is the name of the
625117395Skan   function, and PUBLIC is nonzero if the function is globally
62650397Sobrien   visible.  */
62750397Sobrien
62850397Sobrienvoid
629132718Skani386_pe_declare_function_type (FILE *file, const char *name, int public)
63050397Sobrien{
63150397Sobrien  fprintf (file, "\t.def\t");
63250397Sobrien  assemble_name (file, name);
63350397Sobrien  fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
63450397Sobrien	   public ? (int) C_EXT : (int) C_STAT,
63550397Sobrien	   (int) DT_FCN << N_BTSHFT);
63650397Sobrien}
63750397Sobrien
63850397Sobrien/* Keep a list of external functions.  */
63950397Sobrien
640169689Skanstruct extern_list GTY(())
64150397Sobrien{
64250397Sobrien  struct extern_list *next;
643169689Skan  tree decl;
64490075Sobrien  const char *name;
64550397Sobrien};
64650397Sobrien
647169689Skanstatic GTY(()) struct extern_list *extern_head;
64850397Sobrien
64950397Sobrien/* Assemble an external function reference.  We need to keep a list of
65050397Sobrien   these, so that we can output the function types at the end of the
65150397Sobrien   assembly.  We can't output the types now, because we might see a
65250397Sobrien   definition of the function later on and emit debugging information
65350397Sobrien   for it then.  */
65450397Sobrien
65550397Sobrienvoid
656169689Skani386_pe_record_external_function (tree decl, const char *name)
65750397Sobrien{
65850397Sobrien  struct extern_list *p;
65950397Sobrien
660169689Skan  p = (struct extern_list *) ggc_alloc (sizeof *p);
66150397Sobrien  p->next = extern_head;
662169689Skan  p->decl = decl;
66350397Sobrien  p->name = name;
66450397Sobrien  extern_head = p;
66550397Sobrien}
66650397Sobrien
66790075Sobrien/* Keep a list of exported symbols.  */
66852284Sobrien
669169689Skanstruct export_list GTY(())
67090075Sobrien{
67190075Sobrien  struct export_list *next;
67290075Sobrien  const char *name;
67390075Sobrien  int is_data;		/* used to type tag exported symbols.  */
67490075Sobrien};
67590075Sobrien
676169689Skanstatic GTY(()) struct export_list *export_head;
67790075Sobrien
67852284Sobrien/* Assemble an export symbol entry.  We need to keep a list of
67952284Sobrien   these, so that we can output the export list at the end of the
68052284Sobrien   assembly.  We used to output these export symbols in each function,
681132718Skan   but that causes problems with GNU ld when the sections are
68252284Sobrien   linkonce.  */
68352284Sobrien
68452284Sobrienvoid
685132718Skani386_pe_record_exported_symbol (const char *name, int is_data)
68652284Sobrien{
68790075Sobrien  struct export_list *p;
68852284Sobrien
689169689Skan  p = (struct export_list *) ggc_alloc (sizeof *p);
69090075Sobrien  p->next = export_head;
69152284Sobrien  p->name = name;
69290075Sobrien  p->is_data = is_data;
69390075Sobrien  export_head = p;
69452284Sobrien}
69552284Sobrien
69650397Sobrien/* This is called at the end of assembly.  For each external function
69752284Sobrien   which has not been defined, we output a declaration now.  We also
69852284Sobrien   output the .drectve section.  */
69950397Sobrien
70050397Sobrienvoid
701132718Skani386_pe_file_end (void)
70250397Sobrien{
70350397Sobrien  struct extern_list *p;
70450397Sobrien
705132718Skan  ix86_file_end ();
70690075Sobrien
70750397Sobrien  for (p = extern_head; p != NULL; p = p->next)
70850397Sobrien    {
70950397Sobrien      tree decl;
71050397Sobrien
711169689Skan      decl = p->decl;
71250397Sobrien
71350397Sobrien      /* Positively ensure only one declaration for any given symbol.  */
714169689Skan      if (! TREE_ASM_WRITTEN (decl)
715169689Skan	  && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
71650397Sobrien	{
71750397Sobrien	  TREE_ASM_WRITTEN (decl) = 1;
718132718Skan	  i386_pe_declare_function_type (asm_out_file, p->name,
719132718Skan					 TREE_PUBLIC (decl));
72050397Sobrien	}
72150397Sobrien    }
72252284Sobrien
72390075Sobrien  if (export_head)
72452284Sobrien    {
72590075Sobrien      struct export_list *q;
72690075Sobrien      drectve_section ();
72790075Sobrien      for (q = export_head; q != NULL; q = q->next)
72890075Sobrien	{
729132718Skan	  fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
730117395Skan		   i386_pe_strip_name_encoding (q->name),
73190075Sobrien		   (q->is_data) ? ",data" : "");
73290075Sobrien	}
73352284Sobrien    }
73450397Sobrien}
735169689Skan
736169689Skan#include "gt-winnt.h"
737