xref: /openbsd-src/gnu/usr.bin/gcc/gcc/config/i386/winnt.c (revision c87b03e512fc05ed6e0222f6fb0ae86264b1d05b)
1*c87b03e5Sespie /* Subroutines for insn-output.c for Windows NT.
2*c87b03e5Sespie    Contributed by Douglas Rupp (drupp@cs.washington.edu)
3*c87b03e5Sespie    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4*c87b03e5Sespie    Free Software Foundation, Inc.
5*c87b03e5Sespie 
6*c87b03e5Sespie This file is part of GCC.
7*c87b03e5Sespie 
8*c87b03e5Sespie GCC is free software; you can redistribute it and/or modify it under
9*c87b03e5Sespie the terms of the GNU General Public License as published by the Free
10*c87b03e5Sespie Software Foundation; either version 2, or (at your option) any later
11*c87b03e5Sespie version.
12*c87b03e5Sespie 
13*c87b03e5Sespie GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*c87b03e5Sespie WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*c87b03e5Sespie FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*c87b03e5Sespie for more details.
17*c87b03e5Sespie 
18*c87b03e5Sespie You should have received a copy of the GNU General Public License
19*c87b03e5Sespie along with GCC; see the file COPYING.  If not, write to the Free
20*c87b03e5Sespie Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21*c87b03e5Sespie 02111-1307, USA.  */
22*c87b03e5Sespie 
23*c87b03e5Sespie #include "config.h"
24*c87b03e5Sespie #include "system.h"
25*c87b03e5Sespie #include "rtl.h"
26*c87b03e5Sespie #include "regs.h"
27*c87b03e5Sespie #include "hard-reg-set.h"
28*c87b03e5Sespie #include "output.h"
29*c87b03e5Sespie #include "tree.h"
30*c87b03e5Sespie #include "flags.h"
31*c87b03e5Sespie #include "tm_p.h"
32*c87b03e5Sespie #include "toplev.h"
33*c87b03e5Sespie #include "hashtab.h"
34*c87b03e5Sespie #include "ggc.h"
35*c87b03e5Sespie 
36*c87b03e5Sespie /* i386/PE specific attribute support.
37*c87b03e5Sespie 
38*c87b03e5Sespie    i386/PE has two new attributes:
39*c87b03e5Sespie    dllexport - for exporting a function/variable that will live in a dll
40*c87b03e5Sespie    dllimport - for importing a function/variable from a dll
41*c87b03e5Sespie 
42*c87b03e5Sespie    Microsoft allows multiple declspecs in one __declspec, separating
43*c87b03e5Sespie    them with spaces.  We do NOT support this.  Instead, use __declspec
44*c87b03e5Sespie    multiple times.
45*c87b03e5Sespie */
46*c87b03e5Sespie 
47*c87b03e5Sespie static tree associated_type PARAMS ((tree));
48*c87b03e5Sespie const char * gen_stdcall_suffix PARAMS ((tree));
49*c87b03e5Sespie int i386_pe_dllexport_p PARAMS ((tree));
50*c87b03e5Sespie int i386_pe_dllimport_p PARAMS ((tree));
51*c87b03e5Sespie void i386_pe_mark_dllexport PARAMS ((tree));
52*c87b03e5Sespie void i386_pe_mark_dllimport PARAMS ((tree));
53*c87b03e5Sespie 
54*c87b03e5Sespie /* Handle a "dllimport" or "dllexport" attribute;
55*c87b03e5Sespie    arguments as in struct attribute_spec.handler.  */
56*c87b03e5Sespie tree
ix86_handle_dll_attribute(pnode,name,args,flags,no_add_attrs)57*c87b03e5Sespie ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
58*c87b03e5Sespie      tree * pnode;
59*c87b03e5Sespie      tree name;
60*c87b03e5Sespie      tree args;
61*c87b03e5Sespie      int flags;
62*c87b03e5Sespie      bool *no_add_attrs;
63*c87b03e5Sespie {
64*c87b03e5Sespie   tree node = *pnode;
65*c87b03e5Sespie 
66*c87b03e5Sespie   /* These attributes may apply to structure and union types being created,
67*c87b03e5Sespie      but otherwise should pass to the declaration involved.  */
68*c87b03e5Sespie   if (!DECL_P (node))
69*c87b03e5Sespie     {
70*c87b03e5Sespie       if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
71*c87b03e5Sespie 		   | (int) ATTR_FLAG_ARRAY_NEXT))
72*c87b03e5Sespie 	{
73*c87b03e5Sespie 	  *no_add_attrs = true;
74*c87b03e5Sespie 	  return tree_cons (name, args, NULL_TREE);
75*c87b03e5Sespie 	}
76*c87b03e5Sespie       if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
77*c87b03e5Sespie 	{
78*c87b03e5Sespie 	  warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
79*c87b03e5Sespie 	  *no_add_attrs = true;
80*c87b03e5Sespie 	}
81*c87b03e5Sespie 
82*c87b03e5Sespie       return NULL_TREE;
83*c87b03e5Sespie     }
84*c87b03e5Sespie 
85*c87b03e5Sespie   /* Report error on dllimport ambiguities seen now before they cause
86*c87b03e5Sespie      any damage.  */
87*c87b03e5Sespie   else if (is_attribute_p ("dllimport", name))
88*c87b03e5Sespie     {
89*c87b03e5Sespie       /* Like MS, treat definition of dllimported variables and
90*c87b03e5Sespie 	 non-inlined functions on declaration as syntax errors.
91*c87b03e5Sespie 	 We allow the attribute for function definitions if declared
92*c87b03e5Sespie 	 inline, but just ignore it in i386_pe_dllimport_p.  */
93*c87b03e5Sespie       if (TREE_CODE (node) == FUNCTION_DECL  && DECL_INITIAL (node)
94*c87b03e5Sespie           && !DECL_INLINE (node))
95*c87b03e5Sespie 	{
96*c87b03e5Sespie 	  error_with_decl (node, "function `%s' definition is marked dllimport.");
97*c87b03e5Sespie 	  *no_add_attrs = true;
98*c87b03e5Sespie 	}
99*c87b03e5Sespie 
100*c87b03e5Sespie       else if (TREE_CODE (node) == VAR_DECL)
101*c87b03e5Sespie 	{
102*c87b03e5Sespie 	  if (DECL_INITIAL (node))
103*c87b03e5Sespie 	    {
104*c87b03e5Sespie 	      error_with_decl (node,"variable `%s' definition is marked dllimport.");
105*c87b03e5Sespie 	      *no_add_attrs = true;
106*c87b03e5Sespie 	    }
107*c87b03e5Sespie 
108*c87b03e5Sespie 	  /* `extern' needn't be specified with dllimport.
109*c87b03e5Sespie 	     Specify `extern' now and hope for the best.  Sigh.  */
110*c87b03e5Sespie 	  DECL_EXTERNAL (node) = 1;
111*c87b03e5Sespie 	  /* Also, implicitly give dllimport'd variables declared within
112*c87b03e5Sespie 	     a function global scope, unless declared static.  */
113*c87b03e5Sespie 	  if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
114*c87b03e5Sespie   	    TREE_PUBLIC (node) = 1;
115*c87b03e5Sespie 	}
116*c87b03e5Sespie     }
117*c87b03e5Sespie 
118*c87b03e5Sespie   /*  Report error if symbol is not accessible at global scope. */
119*c87b03e5Sespie   if (!TREE_PUBLIC (node)
120*c87b03e5Sespie       && (TREE_CODE (node) == VAR_DECL
121*c87b03e5Sespie 	  || TREE_CODE (node) == FUNCTION_DECL))
122*c87b03e5Sespie     {
123*c87b03e5Sespie       error_with_decl (node, "external linkage required for symbol '%s' because of '%s' attribute.",
124*c87b03e5Sespie 		       IDENTIFIER_POINTER (name));
125*c87b03e5Sespie       *no_add_attrs = true;
126*c87b03e5Sespie     }
127*c87b03e5Sespie 
128*c87b03e5Sespie   return NULL_TREE;
129*c87b03e5Sespie }
130*c87b03e5Sespie 
131*c87b03e5Sespie /* Handle a "shared" attribute;
132*c87b03e5Sespie    arguments as in struct attribute_spec.handler.  */
133*c87b03e5Sespie tree
ix86_handle_shared_attribute(node,name,args,flags,no_add_attrs)134*c87b03e5Sespie ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
135*c87b03e5Sespie      tree *node;
136*c87b03e5Sespie      tree name;
137*c87b03e5Sespie      tree args ATTRIBUTE_UNUSED;
138*c87b03e5Sespie      int flags ATTRIBUTE_UNUSED;
139*c87b03e5Sespie      bool *no_add_attrs;
140*c87b03e5Sespie {
141*c87b03e5Sespie   if (TREE_CODE (*node) != VAR_DECL)
142*c87b03e5Sespie     {
143*c87b03e5Sespie       warning ("`%s' attribute only applies to variables",
144*c87b03e5Sespie 	       IDENTIFIER_POINTER (name));
145*c87b03e5Sespie       *no_add_attrs = true;
146*c87b03e5Sespie     }
147*c87b03e5Sespie 
148*c87b03e5Sespie   return NULL_TREE;
149*c87b03e5Sespie }
150*c87b03e5Sespie 
151*c87b03e5Sespie /* Return the type that we should use to determine if DECL is
152*c87b03e5Sespie    imported or exported.  */
153*c87b03e5Sespie 
154*c87b03e5Sespie static tree
associated_type(decl)155*c87b03e5Sespie associated_type (decl)
156*c87b03e5Sespie      tree decl;
157*c87b03e5Sespie {
158*c87b03e5Sespie   tree t = NULL_TREE;
159*c87b03e5Sespie 
160*c87b03e5Sespie   /* In the C++ frontend, DECL_CONTEXT for a method doesn't actually refer
161*c87b03e5Sespie      to the containing class.  So we look at the 'this' arg.  */
162*c87b03e5Sespie   if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
163*c87b03e5Sespie     {
164*c87b03e5Sespie       /* Artificial methods are not affected by the import/export status of
165*c87b03e5Sespie 	 their class unless they are virtual.  */
166*c87b03e5Sespie       if (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))
167*c87b03e5Sespie 	t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
168*c87b03e5Sespie     }
169*c87b03e5Sespie   else if (DECL_CONTEXT (decl)
170*c87b03e5Sespie 	   && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
171*c87b03e5Sespie     t = DECL_CONTEXT (decl);
172*c87b03e5Sespie 
173*c87b03e5Sespie   return t;
174*c87b03e5Sespie }
175*c87b03e5Sespie 
176*c87b03e5Sespie /* Return nonzero if DECL is a dllexport'd object.  */
177*c87b03e5Sespie 
178*c87b03e5Sespie int
i386_pe_dllexport_p(decl)179*c87b03e5Sespie i386_pe_dllexport_p (decl)
180*c87b03e5Sespie      tree decl;
181*c87b03e5Sespie {
182*c87b03e5Sespie   tree exp;
183*c87b03e5Sespie 
184*c87b03e5Sespie   if (TREE_CODE (decl) != VAR_DECL
185*c87b03e5Sespie       && TREE_CODE (decl) != FUNCTION_DECL)
186*c87b03e5Sespie     return 0;
187*c87b03e5Sespie   exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
188*c87b03e5Sespie   if (exp)
189*c87b03e5Sespie     return 1;
190*c87b03e5Sespie 
191*c87b03e5Sespie   /* Class members get the dllexport status of their class.  */
192*c87b03e5Sespie   if (associated_type (decl))
193*c87b03e5Sespie     {
194*c87b03e5Sespie       exp = lookup_attribute ("dllexport",
195*c87b03e5Sespie 			      TYPE_ATTRIBUTES (associated_type (decl)));
196*c87b03e5Sespie       if (exp)
197*c87b03e5Sespie 	return 1;
198*c87b03e5Sespie     }
199*c87b03e5Sespie 
200*c87b03e5Sespie   return 0;
201*c87b03e5Sespie }
202*c87b03e5Sespie 
203*c87b03e5Sespie /* Return nonzero if DECL is a dllimport'd object.  */
204*c87b03e5Sespie 
205*c87b03e5Sespie int
i386_pe_dllimport_p(decl)206*c87b03e5Sespie i386_pe_dllimport_p (decl)
207*c87b03e5Sespie      tree decl;
208*c87b03e5Sespie {
209*c87b03e5Sespie   tree imp;
210*c87b03e5Sespie   int context_imp = 0;
211*c87b03e5Sespie 
212*c87b03e5Sespie   if (TREE_CODE (decl) == FUNCTION_DECL
213*c87b03e5Sespie       && TARGET_NOP_FUN_DLLIMPORT)
214*c87b03e5Sespie     return 0;
215*c87b03e5Sespie 
216*c87b03e5Sespie   if (TREE_CODE (decl) != VAR_DECL
217*c87b03e5Sespie       && TREE_CODE (decl) != FUNCTION_DECL)
218*c87b03e5Sespie     return 0;
219*c87b03e5Sespie 
220*c87b03e5Sespie   imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
221*c87b03e5Sespie 
222*c87b03e5Sespie   /* Class members get the dllimport status of their class.  */
223*c87b03e5Sespie   if (!imp && associated_type (decl))
224*c87b03e5Sespie     {
225*c87b03e5Sespie       imp = lookup_attribute ("dllimport",
226*c87b03e5Sespie 			      TYPE_ATTRIBUTES (associated_type (decl)));
227*c87b03e5Sespie       if (imp)
228*c87b03e5Sespie 	context_imp = 1;
229*c87b03e5Sespie     }
230*c87b03e5Sespie 
231*c87b03e5Sespie   if (imp)
232*c87b03e5Sespie     {
233*c87b03e5Sespie       /* Don't mark defined functions as dllimport.  If the definition
234*c87b03e5Sespie 	 itself was marked with dllimport, than ix86_handle_dll_attribute
235*c87b03e5Sespie 	 reports an error. This handles the case when the definition
236*c87b03e5Sespie 	 overrides an earlier declaration.  */
237*c87b03e5Sespie       if (TREE_CODE (decl) ==  FUNCTION_DECL && DECL_INITIAL (decl)
238*c87b03e5Sespie 	  && !DECL_INLINE (decl))
239*c87b03e5Sespie 	{
240*c87b03e5Sespie 	   /* Don't warn about artificial methods.  */
241*c87b03e5Sespie 	  if (!DECL_ARTIFICIAL (decl))
242*c87b03e5Sespie 	    warning_with_decl (decl,"function '%s' is defined after prior declaration as dllimport: attribute ignored.");
243*c87b03e5Sespie 	  return 0;
244*c87b03e5Sespie 	}
245*c87b03e5Sespie 
246*c87b03e5Sespie       /* We ignore the dllimport attribute for inline member functions.
247*c87b03e5Sespie 	 This differs from MSVC behaviour which treats it like GNUC
248*c87b03e5Sespie      	 'extern inline' extension.   */
249*c87b03e5Sespie       else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
250*c87b03e5Sespie         {
251*c87b03e5Sespie 	  if (extra_warnings)
252*c87b03e5Sespie 	    warning_with_decl (decl, "inline function '%s' is declared as dllimport: attribute ignored.");
253*c87b03e5Sespie 	  return 0;
254*c87b03e5Sespie 	}
255*c87b03e5Sespie 
256*c87b03e5Sespie       /*  Don't allow definitions of static data members in dllimport class,
257*c87b03e5Sespie 	  Just ignore attribute for vtable data.  */
258*c87b03e5Sespie       else if (TREE_CODE (decl) == VAR_DECL
259*c87b03e5Sespie 	       && TREE_STATIC (decl) && TREE_PUBLIC (decl)
260*c87b03e5Sespie 	       && !DECL_EXTERNAL (decl) && context_imp)
261*c87b03e5Sespie 	{
262*c87b03e5Sespie 	  if (!DECL_VIRTUAL_P (decl))
263*c87b03e5Sespie 	      error_with_decl (decl, "definition of static data member '%s' of dllimport'd class.");
264*c87b03e5Sespie            return 0;
265*c87b03e5Sespie 	}
266*c87b03e5Sespie 
267*c87b03e5Sespie       /* Since we can't treat a pointer to a dllimport'd symbol as a
268*c87b03e5Sespie 	 constant address, we turn off the attribute on C++ virtual
269*c87b03e5Sespie 	 methods to allow creation of vtables using thunks. */
270*c87b03e5Sespie       else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
271*c87b03e5Sespie 	       && (DECL_VIRTUAL_P (decl)))
272*c87b03e5Sespie            return 0;
273*c87b03e5Sespie 
274*c87b03e5Sespie       return 1;
275*c87b03e5Sespie     }
276*c87b03e5Sespie 
277*c87b03e5Sespie   return 0;
278*c87b03e5Sespie }
279*c87b03e5Sespie 
280*c87b03e5Sespie /* Return nonzero if SYMBOL is marked as being dllexport'd.  */
281*c87b03e5Sespie 
282*c87b03e5Sespie int
i386_pe_dllexport_name_p(symbol)283*c87b03e5Sespie i386_pe_dllexport_name_p (symbol)
284*c87b03e5Sespie      const char *symbol;
285*c87b03e5Sespie {
286*c87b03e5Sespie   return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
287*c87b03e5Sespie          && symbol[1] == 'e' && symbol[2] == '.';
288*c87b03e5Sespie }
289*c87b03e5Sespie 
290*c87b03e5Sespie /* Return nonzero if SYMBOL is marked as being dllimport'd.  */
291*c87b03e5Sespie 
292*c87b03e5Sespie int
i386_pe_dllimport_name_p(symbol)293*c87b03e5Sespie i386_pe_dllimport_name_p (symbol)
294*c87b03e5Sespie      const char *symbol;
295*c87b03e5Sespie {
296*c87b03e5Sespie   return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
297*c87b03e5Sespie          && symbol[1] == 'i' && symbol[2] == '.';
298*c87b03e5Sespie }
299*c87b03e5Sespie 
300*c87b03e5Sespie /* Mark a DECL as being dllexport'd.
301*c87b03e5Sespie    Note that we override the previous setting (eg: dllimport).  */
302*c87b03e5Sespie 
303*c87b03e5Sespie void
i386_pe_mark_dllexport(decl)304*c87b03e5Sespie i386_pe_mark_dllexport (decl)
305*c87b03e5Sespie      tree decl;
306*c87b03e5Sespie {
307*c87b03e5Sespie   const char *oldname;
308*c87b03e5Sespie   char  *newname;
309*c87b03e5Sespie   rtx rtlname;
310*c87b03e5Sespie   tree idp;
311*c87b03e5Sespie 
312*c87b03e5Sespie   rtlname = XEXP (DECL_RTL (decl), 0);
313*c87b03e5Sespie   if (GET_CODE (rtlname) == SYMBOL_REF)
314*c87b03e5Sespie     oldname = XSTR (rtlname, 0);
315*c87b03e5Sespie   else if (GET_CODE (rtlname) == MEM
316*c87b03e5Sespie 	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
317*c87b03e5Sespie     oldname = XSTR (XEXP (rtlname, 0), 0);
318*c87b03e5Sespie   else
319*c87b03e5Sespie     abort ();
320*c87b03e5Sespie   if (i386_pe_dllimport_name_p (oldname))
321*c87b03e5Sespie     {
322*c87b03e5Sespie       warning_with_decl (decl,"inconsistent dll linkage for '%s': dllexport assumed.");
323*c87b03e5Sespie      /* Remove DLL_IMPORT_PREFIX.  */
324*c87b03e5Sespie       oldname += 9;
325*c87b03e5Sespie       DECL_NON_ADDR_CONST_P (decl) = 0;
326*c87b03e5Sespie     }
327*c87b03e5Sespie   else if (i386_pe_dllexport_name_p (oldname))
328*c87b03e5Sespie     return; /* already done */
329*c87b03e5Sespie 
330*c87b03e5Sespie   newname = alloca (strlen (oldname) + 4);
331*c87b03e5Sespie   sprintf (newname, "%ce.%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
332*c87b03e5Sespie 
333*c87b03e5Sespie   /* We pass newname through get_identifier to ensure it has a unique
334*c87b03e5Sespie      address.  RTL processing can sometimes peek inside the symbol ref
335*c87b03e5Sespie      and compare the string's addresses to see if two symbols are
336*c87b03e5Sespie      identical.  */
337*c87b03e5Sespie   idp = get_identifier (newname);
338*c87b03e5Sespie 
339*c87b03e5Sespie   XEXP (DECL_RTL (decl), 0) =
340*c87b03e5Sespie     gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
341*c87b03e5Sespie }
342*c87b03e5Sespie 
343*c87b03e5Sespie /* Mark a DECL as being dllimport'd.  */
344*c87b03e5Sespie 
345*c87b03e5Sespie void
i386_pe_mark_dllimport(decl)346*c87b03e5Sespie i386_pe_mark_dllimport (decl)
347*c87b03e5Sespie      tree decl;
348*c87b03e5Sespie {
349*c87b03e5Sespie   const char *oldname;
350*c87b03e5Sespie   char  *newname;
351*c87b03e5Sespie   tree idp;
352*c87b03e5Sespie   rtx rtlname, newrtl;
353*c87b03e5Sespie 
354*c87b03e5Sespie   rtlname = XEXP (DECL_RTL (decl), 0);
355*c87b03e5Sespie   if (GET_CODE (rtlname) == SYMBOL_REF)
356*c87b03e5Sespie     oldname = XSTR (rtlname, 0);
357*c87b03e5Sespie   else if (GET_CODE (rtlname) == MEM
358*c87b03e5Sespie 	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
359*c87b03e5Sespie     oldname = XSTR (XEXP (rtlname, 0), 0);
360*c87b03e5Sespie   else
361*c87b03e5Sespie     abort ();
362*c87b03e5Sespie   if (i386_pe_dllexport_name_p (oldname))
363*c87b03e5Sespie     {
364*c87b03e5Sespie       error ("`%s' declared as both exported to and imported from a DLL",
365*c87b03e5Sespie              IDENTIFIER_POINTER (DECL_NAME (decl)));
366*c87b03e5Sespie       return;
367*c87b03e5Sespie     }
368*c87b03e5Sespie   else if (i386_pe_dllimport_name_p (oldname))
369*c87b03e5Sespie     {
370*c87b03e5Sespie       /* Already done, but do a sanity check to prevent assembler errors. */
371*c87b03e5Sespie       if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
372*c87b03e5Sespie 	{
373*c87b03e5Sespie 	  error_with_decl (decl, "failure in redeclaration of '%s': dllimport'd symbol lacks external linkage.");
374*c87b03e5Sespie 	  abort();
375*c87b03e5Sespie 	}
376*c87b03e5Sespie     return;
377*c87b03e5Sespie     }
378*c87b03e5Sespie 
379*c87b03e5Sespie   newname = alloca (strlen (oldname) + 11);
380*c87b03e5Sespie   sprintf (newname, "%ci._imp__%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
381*c87b03e5Sespie 
382*c87b03e5Sespie   /* We pass newname through get_identifier to ensure it has a unique
383*c87b03e5Sespie      address.  RTL processing can sometimes peek inside the symbol ref
384*c87b03e5Sespie      and compare the string's addresses to see if two symbols are
385*c87b03e5Sespie      identical.  */
386*c87b03e5Sespie   idp = get_identifier (newname);
387*c87b03e5Sespie 
388*c87b03e5Sespie   newrtl = gen_rtx (MEM, Pmode,
389*c87b03e5Sespie 		    gen_rtx (SYMBOL_REF, Pmode,
390*c87b03e5Sespie 			     IDENTIFIER_POINTER (idp)));
391*c87b03e5Sespie   XEXP (DECL_RTL (decl), 0) = newrtl;
392*c87b03e5Sespie 
393*c87b03e5Sespie   /* Can't treat a pointer to this as a constant address */
394*c87b03e5Sespie   DECL_NON_ADDR_CONST_P (decl) = 1;
395*c87b03e5Sespie }
396*c87b03e5Sespie 
397*c87b03e5Sespie /* Return string which is the former assembler name modified with a
398*c87b03e5Sespie    suffix consisting of an atsign (@) followed by the number of bytes of
399*c87b03e5Sespie    arguments */
400*c87b03e5Sespie 
401*c87b03e5Sespie const char *
gen_stdcall_suffix(decl)402*c87b03e5Sespie gen_stdcall_suffix (decl)
403*c87b03e5Sespie   tree decl;
404*c87b03e5Sespie {
405*c87b03e5Sespie   int total = 0;
406*c87b03e5Sespie   /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
407*c87b03e5Sespie      of DECL_ASSEMBLER_NAME.  */
408*c87b03e5Sespie   const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
409*c87b03e5Sespie   char *newsym;
410*c87b03e5Sespie 
411*c87b03e5Sespie   if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
412*c87b03e5Sespie     if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
413*c87b03e5Sespie         == void_type_node)
414*c87b03e5Sespie       {
415*c87b03e5Sespie 	tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
416*c87b03e5Sespie 
417*c87b03e5Sespie 	while (TREE_VALUE (formal_type) != void_type_node)
418*c87b03e5Sespie 	  {
419*c87b03e5Sespie 	    int parm_size
420*c87b03e5Sespie 	      = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
421*c87b03e5Sespie 	    /* Must round up to include padding.  This is done the same
422*c87b03e5Sespie 	       way as in store_one_arg.  */
423*c87b03e5Sespie 	    parm_size = ((parm_size + PARM_BOUNDARY - 1)
424*c87b03e5Sespie 			 / PARM_BOUNDARY * PARM_BOUNDARY);
425*c87b03e5Sespie 	    total += parm_size;
426*c87b03e5Sespie 	    formal_type = TREE_CHAIN (formal_type);
427*c87b03e5Sespie 	  }
428*c87b03e5Sespie       }
429*c87b03e5Sespie 
430*c87b03e5Sespie   newsym = xmalloc (strlen (asmname) + 10);
431*c87b03e5Sespie   sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
432*c87b03e5Sespie   return IDENTIFIER_POINTER (get_identifier (newsym));
433*c87b03e5Sespie }
434*c87b03e5Sespie 
435*c87b03e5Sespie void
i386_pe_encode_section_info(decl,first)436*c87b03e5Sespie i386_pe_encode_section_info (decl, first)
437*c87b03e5Sespie      tree decl;
438*c87b03e5Sespie      int first ATTRIBUTE_UNUSED;
439*c87b03e5Sespie {
440*c87b03e5Sespie   /* This bit is copied from i386.h.  */
441*c87b03e5Sespie   if (optimize > 0 && TREE_CONSTANT (decl)
442*c87b03e5Sespie       && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
443*c87b03e5Sespie     {
444*c87b03e5Sespie       rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
445*c87b03e5Sespie                  ? TREE_CST_RTL (decl) : DECL_RTL (decl));
446*c87b03e5Sespie       SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
447*c87b03e5Sespie     }
448*c87b03e5Sespie 
449*c87b03e5Sespie   if (TREE_CODE (decl) == FUNCTION_DECL)
450*c87b03e5Sespie     if (lookup_attribute ("stdcall",
451*c87b03e5Sespie 			  TYPE_ATTRIBUTES (TREE_TYPE (decl))))
452*c87b03e5Sespie       XEXP (DECL_RTL (decl), 0) =
453*c87b03e5Sespie 	gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
454*c87b03e5Sespie 
455*c87b03e5Sespie   /* Mark the decl so we can tell from the rtl whether the object is
456*c87b03e5Sespie      dllexport'd or dllimport'd.  This also handles dllexport/dllimport
457*c87b03e5Sespie      override semantics.  */
458*c87b03e5Sespie 
459*c87b03e5Sespie   if (i386_pe_dllexport_p (decl))
460*c87b03e5Sespie     i386_pe_mark_dllexport (decl);
461*c87b03e5Sespie   else if (i386_pe_dllimport_p (decl))
462*c87b03e5Sespie     i386_pe_mark_dllimport (decl);
463*c87b03e5Sespie   /* It might be that DECL has already been marked as dllimport, but a
464*c87b03e5Sespie      subsequent definition nullified that.  The attribute is gone but
465*c87b03e5Sespie      DECL_RTL still has (DLL_IMPORT_EXPORT_PREFIX)i._imp__foo.  We need
466*c87b03e5Sespie      to remove that. Ditto for the DECL_NON_ADDR_CONST_P flag.  */
467*c87b03e5Sespie   else if ((TREE_CODE (decl) == FUNCTION_DECL
468*c87b03e5Sespie 	    || TREE_CODE (decl) == VAR_DECL)
469*c87b03e5Sespie 	   && DECL_RTL (decl) != NULL_RTX
470*c87b03e5Sespie 	   && GET_CODE (DECL_RTL (decl)) == MEM
471*c87b03e5Sespie 	   && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
472*c87b03e5Sespie 	   && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
473*c87b03e5Sespie 	   && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
474*c87b03e5Sespie     {
475*c87b03e5Sespie       const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
476*c87b03e5Sespie       tree idp = get_identifier (oldname + 9);
477*c87b03e5Sespie       rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
478*c87b03e5Sespie 
479*c87b03e5Sespie       warning_with_decl (decl, "'%s' %s after being referenced with dllimport linkage.",
480*c87b03e5Sespie 	         	 (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
481*c87b03e5Sespie 			 ? "defined locally" : "redeclared without dllimport attribute");
482*c87b03e5Sespie 
483*c87b03e5Sespie       XEXP (DECL_RTL (decl), 0) = newrtl;
484*c87b03e5Sespie 
485*c87b03e5Sespie       DECL_NON_ADDR_CONST_P (decl) = 0;
486*c87b03e5Sespie 
487*c87b03e5Sespie       /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
488*c87b03e5Sespie 	 We leave these alone for now.  */
489*c87b03e5Sespie     }
490*c87b03e5Sespie }
491*c87b03e5Sespie 
492*c87b03e5Sespie /* Strip only the leading encoding, leaving the stdcall suffix.  */
493*c87b03e5Sespie 
494*c87b03e5Sespie const char *
i386_pe_strip_name_encoding(str)495*c87b03e5Sespie i386_pe_strip_name_encoding (str)
496*c87b03e5Sespie      const char *str;
497*c87b03e5Sespie {
498*c87b03e5Sespie   if (*str == DLL_IMPORT_EXPORT_PREFIX)
499*c87b03e5Sespie     str += 3;
500*c87b03e5Sespie   if (*str == '*')
501*c87b03e5Sespie     str += 1;
502*c87b03e5Sespie   return str;
503*c87b03e5Sespie }
504*c87b03e5Sespie 
505*c87b03e5Sespie /* Also strip the stdcall suffix.  */
506*c87b03e5Sespie 
507*c87b03e5Sespie const char *
i386_pe_strip_name_encoding_full(str)508*c87b03e5Sespie i386_pe_strip_name_encoding_full (str)
509*c87b03e5Sespie      const char *str;
510*c87b03e5Sespie {
511*c87b03e5Sespie   const char *p;
512*c87b03e5Sespie   const char *name = i386_pe_strip_name_encoding (str);
513*c87b03e5Sespie 
514*c87b03e5Sespie   p = strchr (name, '@');
515*c87b03e5Sespie   if (p)
516*c87b03e5Sespie     return ggc_alloc_string (name, p - name);
517*c87b03e5Sespie 
518*c87b03e5Sespie   return name;
519*c87b03e5Sespie }
520*c87b03e5Sespie 
521*c87b03e5Sespie void
i386_pe_unique_section(decl,reloc)522*c87b03e5Sespie i386_pe_unique_section (decl, reloc)
523*c87b03e5Sespie      tree decl;
524*c87b03e5Sespie      int reloc;
525*c87b03e5Sespie {
526*c87b03e5Sespie   int len;
527*c87b03e5Sespie   const char *name, *prefix;
528*c87b03e5Sespie   char *string;
529*c87b03e5Sespie 
530*c87b03e5Sespie   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
531*c87b03e5Sespie   name = i386_pe_strip_name_encoding_full (name);
532*c87b03e5Sespie 
533*c87b03e5Sespie   /* The object is put in, for example, section .text$foo.
534*c87b03e5Sespie      The linker will then ultimately place them in .text
535*c87b03e5Sespie      (everything from the $ on is stripped). Don't put
536*c87b03e5Sespie      read-only data in .rdata section to avoid a PE linker
537*c87b03e5Sespie      bug when .rdata$* grouped sections are used in code
538*c87b03e5Sespie      without a .rdata section.  */
539*c87b03e5Sespie   if (TREE_CODE (decl) == FUNCTION_DECL)
540*c87b03e5Sespie     prefix = ".text$";
541*c87b03e5Sespie   else if (decl_readonly_section (decl, reloc))
542*c87b03e5Sespie     prefix = ".rdata$";
543*c87b03e5Sespie   else
544*c87b03e5Sespie     prefix = ".data$";
545*c87b03e5Sespie   len = strlen (name) + strlen (prefix);
546*c87b03e5Sespie   string = alloca (len + 1);
547*c87b03e5Sespie   sprintf (string, "%s%s", prefix, name);
548*c87b03e5Sespie 
549*c87b03e5Sespie   DECL_SECTION_NAME (decl) = build_string (len, string);
550*c87b03e5Sespie }
551*c87b03e5Sespie 
552*c87b03e5Sespie /* Select a set of attributes for section NAME based on the properties
553*c87b03e5Sespie    of DECL and whether or not RELOC indicates that DECL's initializer
554*c87b03e5Sespie    might contain runtime relocations.
555*c87b03e5Sespie 
556*c87b03e5Sespie    We make the section read-only and executable for a function decl,
557*c87b03e5Sespie    read-only for a const data decl, and writable for a non-const data decl.
558*c87b03e5Sespie 
559*c87b03e5Sespie    If the section has already been defined, to not allow it to have
560*c87b03e5Sespie    different attributes, as (1) this is ambiguous since we're not seeing
561*c87b03e5Sespie    all the declarations up front and (2) some assemblers (e.g. SVR4)
562*c87b03e5Sespie    do not recoginize section redefinitions.  */
563*c87b03e5Sespie /* ??? This differs from the "standard" PE implementation in that we
564*c87b03e5Sespie    handle the SHARED variable attribute.  Should this be done for all
565*c87b03e5Sespie    PE targets?  */
566*c87b03e5Sespie 
567*c87b03e5Sespie #define SECTION_PE_SHARED	SECTION_MACH_DEP
568*c87b03e5Sespie 
569*c87b03e5Sespie unsigned int
i386_pe_section_type_flags(decl,name,reloc)570*c87b03e5Sespie i386_pe_section_type_flags (decl, name, reloc)
571*c87b03e5Sespie      tree decl;
572*c87b03e5Sespie      const char *name;
573*c87b03e5Sespie      int reloc;
574*c87b03e5Sespie {
575*c87b03e5Sespie   static htab_t htab;
576*c87b03e5Sespie   unsigned int flags;
577*c87b03e5Sespie   unsigned int **slot;
578*c87b03e5Sespie 
579*c87b03e5Sespie   /* The names we put in the hashtable will always be the unique
580*c87b03e5Sespie      versions gived to us by the stringtable, so we can just use
581*c87b03e5Sespie      their addresses as the keys.  */
582*c87b03e5Sespie   if (!htab)
583*c87b03e5Sespie     htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
584*c87b03e5Sespie 
585*c87b03e5Sespie   if (decl && TREE_CODE (decl) == FUNCTION_DECL)
586*c87b03e5Sespie     flags = SECTION_CODE;
587*c87b03e5Sespie   else if (decl && decl_readonly_section (decl, reloc))
588*c87b03e5Sespie     flags = 0;
589*c87b03e5Sespie   else
590*c87b03e5Sespie     {
591*c87b03e5Sespie       flags = SECTION_WRITE;
592*c87b03e5Sespie 
593*c87b03e5Sespie       if (decl && TREE_CODE (decl) == VAR_DECL
594*c87b03e5Sespie 	  && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
595*c87b03e5Sespie 	flags |= SECTION_PE_SHARED;
596*c87b03e5Sespie     }
597*c87b03e5Sespie 
598*c87b03e5Sespie   if (decl && DECL_ONE_ONLY (decl))
599*c87b03e5Sespie     flags |= SECTION_LINKONCE;
600*c87b03e5Sespie 
601*c87b03e5Sespie   /* See if we already have an entry for this section.  */
602*c87b03e5Sespie   slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
603*c87b03e5Sespie   if (!*slot)
604*c87b03e5Sespie     {
605*c87b03e5Sespie       *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
606*c87b03e5Sespie       **slot = flags;
607*c87b03e5Sespie     }
608*c87b03e5Sespie   else
609*c87b03e5Sespie     {
610*c87b03e5Sespie       if (decl && **slot != flags)
611*c87b03e5Sespie 	error_with_decl (decl, "%s causes a section type conflict");
612*c87b03e5Sespie     }
613*c87b03e5Sespie 
614*c87b03e5Sespie   return flags;
615*c87b03e5Sespie }
616*c87b03e5Sespie 
617*c87b03e5Sespie void
i386_pe_asm_named_section(name,flags)618*c87b03e5Sespie i386_pe_asm_named_section (name, flags)
619*c87b03e5Sespie      const char *name;
620*c87b03e5Sespie      unsigned int flags;
621*c87b03e5Sespie {
622*c87b03e5Sespie   char flagchars[8], *f = flagchars;
623*c87b03e5Sespie 
624*c87b03e5Sespie   if (flags & SECTION_CODE)
625*c87b03e5Sespie     *f++ = 'x';
626*c87b03e5Sespie   if (flags & SECTION_WRITE)
627*c87b03e5Sespie     *f++ = 'w';
628*c87b03e5Sespie   if (flags & SECTION_PE_SHARED)
629*c87b03e5Sespie     *f++ = 's';
630*c87b03e5Sespie   *f = '\0';
631*c87b03e5Sespie 
632*c87b03e5Sespie   fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
633*c87b03e5Sespie 
634*c87b03e5Sespie   if (flags & SECTION_LINKONCE)
635*c87b03e5Sespie     {
636*c87b03e5Sespie       /* Functions may have been compiled at various levels of
637*c87b03e5Sespie          optimization so we can't use `same_size' here.
638*c87b03e5Sespie          Instead, have the linker pick one.  */
639*c87b03e5Sespie       fprintf (asm_out_file, "\t.linkonce %s\n",
640*c87b03e5Sespie 	       (flags & SECTION_CODE ? "discard" : "same_size"));
641*c87b03e5Sespie     }
642*c87b03e5Sespie }
643*c87b03e5Sespie 
644*c87b03e5Sespie /* The Microsoft linker requires that every function be marked as
645*c87b03e5Sespie    DT_FCN.  When using gas on cygwin, we must emit appropriate .type
646*c87b03e5Sespie    directives.  */
647*c87b03e5Sespie 
648*c87b03e5Sespie #include "gsyms.h"
649*c87b03e5Sespie 
650*c87b03e5Sespie /* Mark a function appropriately.  This should only be called for
651*c87b03e5Sespie    functions for which we are not emitting COFF debugging information.
652*c87b03e5Sespie    FILE is the assembler output file, NAME is the name of the
653*c87b03e5Sespie    function, and PUBLIC is nonzero if the function is globally
654*c87b03e5Sespie    visible.  */
655*c87b03e5Sespie 
656*c87b03e5Sespie void
i386_pe_declare_function_type(file,name,public)657*c87b03e5Sespie i386_pe_declare_function_type (file, name, public)
658*c87b03e5Sespie      FILE *file;
659*c87b03e5Sespie      const char *name;
660*c87b03e5Sespie      int public;
661*c87b03e5Sespie {
662*c87b03e5Sespie   fprintf (file, "\t.def\t");
663*c87b03e5Sespie   assemble_name (file, name);
664*c87b03e5Sespie   fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
665*c87b03e5Sespie 	   public ? (int) C_EXT : (int) C_STAT,
666*c87b03e5Sespie 	   (int) DT_FCN << N_BTSHFT);
667*c87b03e5Sespie }
668*c87b03e5Sespie 
669*c87b03e5Sespie /* Keep a list of external functions.  */
670*c87b03e5Sespie 
671*c87b03e5Sespie struct extern_list
672*c87b03e5Sespie {
673*c87b03e5Sespie   struct extern_list *next;
674*c87b03e5Sespie   const char *name;
675*c87b03e5Sespie };
676*c87b03e5Sespie 
677*c87b03e5Sespie static struct extern_list *extern_head;
678*c87b03e5Sespie 
679*c87b03e5Sespie /* Assemble an external function reference.  We need to keep a list of
680*c87b03e5Sespie    these, so that we can output the function types at the end of the
681*c87b03e5Sespie    assembly.  We can't output the types now, because we might see a
682*c87b03e5Sespie    definition of the function later on and emit debugging information
683*c87b03e5Sespie    for it then.  */
684*c87b03e5Sespie 
685*c87b03e5Sespie void
i386_pe_record_external_function(name)686*c87b03e5Sespie i386_pe_record_external_function (name)
687*c87b03e5Sespie      const char *name;
688*c87b03e5Sespie {
689*c87b03e5Sespie   struct extern_list *p;
690*c87b03e5Sespie 
691*c87b03e5Sespie   p = (struct extern_list *) xmalloc (sizeof *p);
692*c87b03e5Sespie   p->next = extern_head;
693*c87b03e5Sespie   p->name = name;
694*c87b03e5Sespie   extern_head = p;
695*c87b03e5Sespie }
696*c87b03e5Sespie 
697*c87b03e5Sespie /* Keep a list of exported symbols.  */
698*c87b03e5Sespie 
699*c87b03e5Sespie struct export_list
700*c87b03e5Sespie {
701*c87b03e5Sespie   struct export_list *next;
702*c87b03e5Sespie   const char *name;
703*c87b03e5Sespie   int is_data;		/* used to type tag exported symbols.  */
704*c87b03e5Sespie };
705*c87b03e5Sespie 
706*c87b03e5Sespie static struct export_list *export_head;
707*c87b03e5Sespie 
708*c87b03e5Sespie /* Assemble an export symbol entry.  We need to keep a list of
709*c87b03e5Sespie    these, so that we can output the export list at the end of the
710*c87b03e5Sespie    assembly.  We used to output these export symbols in each function,
711*c87b03e5Sespie    but that causes problems with GNU ld when the sections are
712*c87b03e5Sespie    linkonce.  */
713*c87b03e5Sespie 
714*c87b03e5Sespie void
i386_pe_record_exported_symbol(name,is_data)715*c87b03e5Sespie i386_pe_record_exported_symbol (name, is_data)
716*c87b03e5Sespie      const char *name;
717*c87b03e5Sespie      int is_data;
718*c87b03e5Sespie {
719*c87b03e5Sespie   struct export_list *p;
720*c87b03e5Sespie 
721*c87b03e5Sespie   p = (struct export_list *) xmalloc (sizeof *p);
722*c87b03e5Sespie   p->next = export_head;
723*c87b03e5Sespie   p->name = name;
724*c87b03e5Sespie   p->is_data = is_data;
725*c87b03e5Sespie   export_head = p;
726*c87b03e5Sespie }
727*c87b03e5Sespie 
728*c87b03e5Sespie /* This is called at the end of assembly.  For each external function
729*c87b03e5Sespie    which has not been defined, we output a declaration now.  We also
730*c87b03e5Sespie    output the .drectve section.  */
731*c87b03e5Sespie 
732*c87b03e5Sespie void
i386_pe_asm_file_end(file)733*c87b03e5Sespie i386_pe_asm_file_end (file)
734*c87b03e5Sespie      FILE *file;
735*c87b03e5Sespie {
736*c87b03e5Sespie   struct extern_list *p;
737*c87b03e5Sespie 
738*c87b03e5Sespie   ix86_asm_file_end (file);
739*c87b03e5Sespie 
740*c87b03e5Sespie   for (p = extern_head; p != NULL; p = p->next)
741*c87b03e5Sespie     {
742*c87b03e5Sespie       tree decl;
743*c87b03e5Sespie 
744*c87b03e5Sespie       decl = get_identifier (p->name);
745*c87b03e5Sespie 
746*c87b03e5Sespie       /* Positively ensure only one declaration for any given symbol.  */
747*c87b03e5Sespie       if (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl))
748*c87b03e5Sespie 	{
749*c87b03e5Sespie 	  TREE_ASM_WRITTEN (decl) = 1;
750*c87b03e5Sespie 	  i386_pe_declare_function_type (file, p->name, TREE_PUBLIC (decl));
751*c87b03e5Sespie 	}
752*c87b03e5Sespie     }
753*c87b03e5Sespie 
754*c87b03e5Sespie   if (export_head)
755*c87b03e5Sespie     {
756*c87b03e5Sespie       struct export_list *q;
757*c87b03e5Sespie       drectve_section ();
758*c87b03e5Sespie       for (q = export_head; q != NULL; q = q->next)
759*c87b03e5Sespie 	{
760*c87b03e5Sespie 	  fprintf (file, "\t.ascii \" -export:%s%s\"\n",
761*c87b03e5Sespie 		   i386_pe_strip_name_encoding (q->name),
762*c87b03e5Sespie 		   (q->is_data) ? ",data" : "");
763*c87b03e5Sespie 	}
764*c87b03e5Sespie     }
765*c87b03e5Sespie }
766