1 /* Subroutines for insn-output.c for Windows NT.
2 Contributed by Douglas Rupp (drupp@cs.washington.edu)
3 Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "hard-reg-set.h"
31 /* i386/PE specific attribute support.
33 i386/PE has two new attributes:
34 dllexport - for exporting a function/variable that will live in a dll
35 dllimport - for importing a function/variable from a dll
37 Microsoft allows multiple declspecs in one __declspec, separating
38 them with spaces. We do NOT support this. Instead, use __declspec
42 /* Return nonzero if ATTR is a valid attribute for DECL.
43 ATTRIBUTES are any existing attributes and ARGS are the arguments
44 supplied with ATTR. */
47 i386_pe_valid_decl_attribute_p (decl, attributes, attr, args)
53 if (args == NULL_TREE)
55 if (is_attribute_p ("dllexport", attr))
57 if (is_attribute_p ("dllimport", attr))
61 return i386_valid_decl_attribute_p (decl, attributes, attr, args);
64 /* Return nonzero if ATTR is a valid attribute for TYPE.
65 ATTRIBUTES are any existing attributes and ARGS are the arguments
66 supplied with ATTR. */
69 i386_pe_valid_type_attribute_p (type, attributes, attr, args)
76 && (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE))
78 if (is_attribute_p ("dllexport", attr))
80 if (is_attribute_p ("dllimport", attr))
84 return i386_valid_type_attribute_p (type, attributes, attr, args);
87 /* Merge attributes in decls OLD and NEW.
89 This handles the following situation:
91 __declspec (dllimport) int foo;
94 The second instance of `foo' nullifies the dllimport. */
97 i386_pe_merge_decl_attributes (old, new)
101 int delete_dllimport_p;
103 old = DECL_MACHINE_ATTRIBUTES (old);
104 new = DECL_MACHINE_ATTRIBUTES (new);
106 /* What we need to do here is remove from `old' dllimport if it doesn't
107 appear in `new'. dllimport behaves like extern: if a declaration is
108 marked dllimport and a definition appears later, then the object
109 is not dllimport'd. */
111 if (lookup_attribute ("dllimport", old) != NULL_TREE
112 && lookup_attribute ("dllimport", new) == NULL_TREE)
113 delete_dllimport_p = 1;
115 delete_dllimport_p = 0;
117 a = merge_attributes (old, new);
119 if (delete_dllimport_p)
123 /* Scan the list for dllimport and delete it. */
124 for (prev = NULL_TREE, t = a; t; prev = t, t = TREE_CHAIN (t))
126 if (is_attribute_p ("dllimport", TREE_PURPOSE (t)))
128 if (prev == NULL_TREE)
131 TREE_CHAIN (prev) = TREE_CHAIN (t);
140 /* Return the type that we should use to determine if DECL is
141 imported or exported. */
144 associated_type (decl)
149 /* In the C++ frontend, DECL_CONTEXT for a method doesn't actually refer
150 to the containing class. So we look at the 'this' arg. */
151 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
153 /* Artificial methods are not affected by the import/export status of
154 their class unless they are virtual. */
155 if (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))
156 t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
158 else if (DECL_CONTEXT (decl)
159 && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
160 t = DECL_CONTEXT (decl);
165 /* Return non-zero if DECL is a dllexport'd object. */
168 i386_pe_dllexport_p (decl)
173 if (TREE_CODE (decl) != VAR_DECL
174 && TREE_CODE (decl) != FUNCTION_DECL)
176 exp = lookup_attribute ("dllexport", DECL_MACHINE_ATTRIBUTES (decl));
180 /* Class members get the dllexport status of their class. */
181 if (associated_type (decl))
183 exp = lookup_attribute ("dllexport",
184 TYPE_ATTRIBUTES (associated_type (decl)));
192 /* Return non-zero if DECL is a dllimport'd object. */
195 i386_pe_dllimport_p (decl)
200 if (TREE_CODE (decl) == FUNCTION_DECL
201 && TARGET_NOP_FUN_DLLIMPORT)
204 if (TREE_CODE (decl) != VAR_DECL
205 && TREE_CODE (decl) != FUNCTION_DECL)
207 imp = lookup_attribute ("dllimport", DECL_MACHINE_ATTRIBUTES (decl));
211 /* Class members get the dllimport status of their class. */
212 if (associated_type (decl))
214 imp = lookup_attribute ("dllimport",
215 TYPE_ATTRIBUTES (associated_type (decl)));
223 /* Return non-zero if SYMBOL is marked as being dllexport'd. */
226 i386_pe_dllexport_name_p (symbol)
229 return symbol[0] == '@' && symbol[1] == 'e' && symbol[2] == '.';
232 /* Return non-zero if SYMBOL is marked as being dllimport'd. */
235 i386_pe_dllimport_name_p (symbol)
238 return symbol[0] == '@' && symbol[1] == 'i' && symbol[2] == '.';
241 /* Mark a DECL as being dllexport'd.
242 Note that we override the previous setting (eg: dllimport). */
245 i386_pe_mark_dllexport (decl)
248 char *oldname, *newname;
252 rtlname = XEXP (DECL_RTL (decl), 0);
253 if (GET_CODE (rtlname) == SYMBOL_REF)
254 oldname = XSTR (rtlname, 0);
255 else if (GET_CODE (rtlname) == MEM
256 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
257 oldname = XSTR (XEXP (rtlname, 0), 0);
260 if (i386_pe_dllimport_name_p (oldname))
262 else if (i386_pe_dllexport_name_p (oldname))
263 return; /* already done */
265 newname = alloca (strlen (oldname) + 4);
266 sprintf (newname, "@e.%s", oldname);
268 /* We pass newname through get_identifier to ensure it has a unique
269 address. RTL processing can sometimes peek inside the symbol ref
270 and compare the string's addresses to see if two symbols are
272 idp = get_identifier (newname);
274 XEXP (DECL_RTL (decl), 0) =
275 gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
278 /* Mark a DECL as being dllimport'd. */
281 i386_pe_mark_dllimport (decl)
284 char *oldname, *newname;
288 rtlname = XEXP (DECL_RTL (decl), 0);
289 if (GET_CODE (rtlname) == SYMBOL_REF)
290 oldname = XSTR (rtlname, 0);
291 else if (GET_CODE (rtlname) == MEM
292 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
293 oldname = XSTR (XEXP (rtlname, 0), 0);
296 if (i386_pe_dllexport_name_p (oldname))
298 error ("`%s' declared as both exported to and imported from a DLL.",
299 IDENTIFIER_POINTER (DECL_NAME (decl)));
302 else if (i386_pe_dllimport_name_p (oldname))
304 /* Already done, but force correct linkage since the redeclaration
305 might have omitted explicit extern. Sigh. */
306 if (TREE_CODE (decl) == VAR_DECL
307 /* ??? Is this test for vtables needed? */
308 && !DECL_VIRTUAL_P (decl))
310 DECL_EXTERNAL (decl) = 1;
311 TREE_PUBLIC (decl) = 1;
316 /* ??? One can well ask why we're making these checks here,
317 and that would be a good question. */
319 /* Imported variables can't be initialized. Note that C++ classes
320 are marked initial, so we need to check. */
321 if (TREE_CODE (decl) == VAR_DECL
322 && !DECL_VIRTUAL_P (decl)
323 && (DECL_INITIAL (decl)
324 && ! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
326 error_with_decl (decl, "initialized variable `%s' is marked dllimport");
329 /* Nor can they be static. */
330 if (TREE_CODE (decl) == VAR_DECL
331 /* ??? Is this test for vtables needed? */
332 && !DECL_VIRTUAL_P (decl)
335 error_with_decl (decl, "static variable `%s' is marked dllimport");
339 /* `extern' needn't be specified with dllimport.
340 Specify `extern' now and hope for the best. Sigh. */
341 if (TREE_CODE (decl) == VAR_DECL
342 /* ??? Is this test for vtables needed? */
343 && !DECL_VIRTUAL_P (decl))
345 DECL_EXTERNAL (decl) = 1;
346 TREE_PUBLIC (decl) = 1;
349 newname = alloca (strlen (oldname) + 11);
350 sprintf (newname, "@i._imp__%s", oldname);
352 /* We pass newname through get_identifier to ensure it has a unique
353 address. RTL processing can sometimes peek inside the symbol ref
354 and compare the string's addresses to see if two symbols are
356 idp = get_identifier (newname);
358 newrtl = gen_rtx (MEM, Pmode,
359 gen_rtx (SYMBOL_REF, Pmode,
360 IDENTIFIER_POINTER (idp)));
361 XEXP (DECL_RTL (decl), 0) = newrtl;
363 /* Can't treat a pointer to this as a constant address */
364 DECL_NON_ADDR_CONST_P (decl) = 1;
367 /* Return string which is the former assembler name modified with a
368 suffix consisting of an atsign (@) followed by the number of bytes of
372 gen_stdcall_suffix (decl)
376 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
377 of DECL_ASSEMBLER_NAME. */
378 char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
381 if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
382 if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
385 tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
387 while (TREE_VALUE (formal_type) != void_type_node)
390 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
391 /* Must round up to include padding. This is done the same
392 way as in store_one_arg. */
393 parm_size = ((parm_size + PARM_BOUNDARY - 1)
394 / PARM_BOUNDARY * PARM_BOUNDARY);
396 formal_type = TREE_CHAIN (formal_type);
400 newsym = xmalloc (strlen (asmname) + 10);
401 sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
402 return IDENTIFIER_POINTER (get_identifier (newsym));
405 /* Cover function to implement ENCODE_SECTION_INFO. */
408 i386_pe_encode_section_info (decl)
411 /* This bit is copied from i386.h. */
412 if (optimize > 0 && TREE_CONSTANT (decl)
413 && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
415 rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
416 ? TREE_CST_RTL (decl) : DECL_RTL (decl));
417 SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
420 if (TREE_CODE (decl) == FUNCTION_DECL)
421 if (lookup_attribute ("stdcall",
422 TYPE_ATTRIBUTES (TREE_TYPE (decl))))
423 XEXP (DECL_RTL (decl), 0) =
424 gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
426 /* Mark the decl so we can tell from the rtl whether the object is
427 dllexport'd or dllimport'd. */
429 if (i386_pe_dllexport_p (decl))
430 i386_pe_mark_dllexport (decl);
431 else if (i386_pe_dllimport_p (decl))
432 i386_pe_mark_dllimport (decl);
433 /* It might be that DECL has already been marked as dllimport, but a
434 subsequent definition nullified that. The attribute is gone but
435 DECL_RTL still has @i._imp__foo. We need to remove that. Ditto
436 for the DECL_NON_ADDR_CONST_P flag. */
437 else if ((TREE_CODE (decl) == FUNCTION_DECL
438 || TREE_CODE (decl) == VAR_DECL)
439 && DECL_RTL (decl) != NULL_RTX
440 && GET_CODE (DECL_RTL (decl)) == MEM
441 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
442 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
443 && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
445 char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
446 tree idp = get_identifier (oldname + 9);
447 rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
449 XEXP (DECL_RTL (decl), 0) = newrtl;
451 DECL_NON_ADDR_CONST_P (decl) = 0;
453 /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
454 We leave these alone for now. */
458 /* Cover function for UNIQUE_SECTION. */
461 i386_pe_unique_section (decl, reloc)
466 char *name,*string,*prefix;
468 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
469 /* Strip off any encoding in fnname. */
470 STRIP_NAME_ENCODING (name, name);
472 /* The object is put in, for example, section .text$foo.
473 The linker will then ultimately place them in .text
474 (everything from the $ on is stripped). Don't put
475 read-only data in .rdata section to avoid a PE linker
476 bug when .rdata$* grouped sections are used in code
477 without a .rdata section. */
478 if (TREE_CODE (decl) == FUNCTION_DECL)
480 else if (DECL_READONLY_SECTION (decl, reloc))
481 #ifdef READONLY_DATA_SECTION
488 len = strlen (name) + strlen (prefix);
489 string = alloca (len + 1);
490 sprintf (string, "%s%s", prefix, name);
492 DECL_SECTION_NAME (decl) = build_string (len, string);
495 /* The Microsoft linker requires that every function be marked as
496 DT_FCN. When using gas on cygwin, we must emit appropriate .type
501 /* Mark a function appropriately. This should only be called for
502 functions for which we are not emitting COFF debugging information.
503 FILE is the assembler output file, NAME is the name of the
504 function, and PUBLIC is non-zero if the function is globally
508 i386_pe_declare_function_type (file, name, public)
513 fprintf (file, "\t.def\t");
514 assemble_name (file, name);
515 fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
516 public ? (int) C_EXT : (int) C_STAT,
517 (int) DT_FCN << N_BTSHFT);
520 /* Keep a list of external functions. */
524 struct extern_list *next;
528 static struct extern_list *extern_head;
530 /* Assemble an external function reference. We need to keep a list of
531 these, so that we can output the function types at the end of the
532 assembly. We can't output the types now, because we might see a
533 definition of the function later on and emit debugging information
537 i386_pe_record_external_function (name)
540 struct extern_list *p;
542 p = (struct extern_list *) permalloc (sizeof *p);
543 p->next = extern_head;
548 /* This is called at the end of assembly. For each external function
549 which has not been defined, we output a declaration now. */
552 i386_pe_asm_file_end (file)
555 struct extern_list *p;
557 for (p = extern_head; p != NULL; p = p->next)
561 decl = get_identifier (p->name);
563 /* Positively ensure only one declaration for any given symbol. */
564 if (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl))
566 TREE_ASM_WRITTEN (decl) = 1;
567 i386_pe_declare_function_type (file, p->name, TREE_PUBLIC (decl));