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