]>
gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/winnt.c
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"
33 /* i386/PE specific attribute support.
35 i386/PE has two new attributes:
36 dllexport - for exporting a function/variable that will live in a dll
37 dllimport - for importing a function/variable from a dll
39 Microsoft allows multiple declspecs in one __declspec, separating
40 them with spaces. We do NOT support this. Instead, use __declspec
44 static tree associated_type
PARAMS ((tree
));
45 const char * gen_stdcall_suffix
PARAMS ((tree
));
46 int i386_pe_dllexport_p
PARAMS ((tree
));
47 int i386_pe_dllimport_p
PARAMS ((tree
));
48 void i386_pe_mark_dllexport
PARAMS ((tree
));
49 void i386_pe_mark_dllimport
PARAMS ((tree
));
51 /* Return nonzero if ATTR is a valid attribute for DECL.
52 ATTRIBUTES are any existing attributes and ARGS are the arguments
53 supplied with ATTR. */
56 i386_pe_valid_decl_attribute_p (decl
, attributes
, attr
, args
)
62 if (args
== NULL_TREE
)
64 if (is_attribute_p ("dllexport", attr
))
66 if (is_attribute_p ("dllimport", attr
))
68 if (is_attribute_p ("shared", attr
))
69 return TREE_CODE (decl
) == VAR_DECL
;
72 return ix86_valid_decl_attribute_p (decl
, attributes
, attr
, args
);
75 /* Return nonzero if ATTR is a valid attribute for TYPE.
76 ATTRIBUTES are any existing attributes and ARGS are the arguments
77 supplied with ATTR. */
80 i386_pe_valid_type_attribute_p (type
, attributes
, attr
, args
)
87 && (TREE_CODE (type
) == RECORD_TYPE
|| TREE_CODE (type
) == UNION_TYPE
))
89 if (is_attribute_p ("dllexport", attr
))
91 if (is_attribute_p ("dllimport", attr
))
95 return ix86_valid_type_attribute_p (type
, attributes
, attr
, args
);
98 /* Merge attributes in decls OLD and NEW.
100 This handles the following situation:
102 __declspec (dllimport) int foo;
105 The second instance of `foo' nullifies the dllimport. */
108 i386_pe_merge_decl_attributes (old
, new)
112 int delete_dllimport_p
;
114 old
= DECL_MACHINE_ATTRIBUTES (old
);
115 new = DECL_MACHINE_ATTRIBUTES (new);
117 /* What we need to do here is remove from `old' dllimport if it doesn't
118 appear in `new'. dllimport behaves like extern: if a declaration is
119 marked dllimport and a definition appears later, then the object
120 is not dllimport'd. */
122 if (lookup_attribute ("dllimport", old
) != NULL_TREE
123 && lookup_attribute ("dllimport", new) == NULL_TREE
)
124 delete_dllimport_p
= 1;
126 delete_dllimport_p
= 0;
128 a
= merge_attributes (old
, new);
130 if (delete_dllimport_p
)
134 /* Scan the list for dllimport and delete it. */
135 for (prev
= NULL_TREE
, t
= a
; t
; prev
= t
, t
= TREE_CHAIN (t
))
137 if (is_attribute_p ("dllimport", TREE_PURPOSE (t
)))
139 if (prev
== NULL_TREE
)
142 TREE_CHAIN (prev
) = TREE_CHAIN (t
);
151 /* Return the type that we should use to determine if DECL is
152 imported or exported. */
155 associated_type (decl
)
160 /* In the C++ frontend, DECL_CONTEXT for a method doesn't actually refer
161 to the containing class. So we look at the 'this' arg. */
162 if (TREE_CODE (TREE_TYPE (decl
)) == METHOD_TYPE
)
164 /* Artificial methods are not affected by the import/export status of
165 their class unless they are virtual. */
166 if (! DECL_ARTIFICIAL (decl
) || DECL_VINDEX (decl
))
167 t
= TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl
))));
169 else if (DECL_CONTEXT (decl
)
170 && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl
))) == 't')
171 t
= DECL_CONTEXT (decl
);
176 /* Return non-zero if DECL is a dllexport'd object. */
179 i386_pe_dllexport_p (decl
)
184 if (TREE_CODE (decl
) != VAR_DECL
185 && TREE_CODE (decl
) != FUNCTION_DECL
)
187 exp
= lookup_attribute ("dllexport", DECL_MACHINE_ATTRIBUTES (decl
));
191 /* Class members get the dllexport status of their class. */
192 if (associated_type (decl
))
194 exp
= lookup_attribute ("dllexport",
195 TYPE_ATTRIBUTES (associated_type (decl
)));
203 /* Return non-zero if DECL is a dllimport'd object. */
206 i386_pe_dllimport_p (decl
)
211 if (TREE_CODE (decl
) == FUNCTION_DECL
212 && TARGET_NOP_FUN_DLLIMPORT
)
215 if (TREE_CODE (decl
) != VAR_DECL
216 && TREE_CODE (decl
) != FUNCTION_DECL
)
218 imp
= lookup_attribute ("dllimport", DECL_MACHINE_ATTRIBUTES (decl
));
222 /* Class members get the dllimport status of their class. */
223 if (associated_type (decl
))
225 imp
= lookup_attribute ("dllimport",
226 TYPE_ATTRIBUTES (associated_type (decl
)));
234 /* Return non-zero if SYMBOL is marked as being dllexport'd. */
237 i386_pe_dllexport_name_p (symbol
)
240 return symbol
[0] == '@' && symbol
[1] == 'e' && symbol
[2] == '.';
243 /* Return non-zero if SYMBOL is marked as being dllimport'd. */
246 i386_pe_dllimport_name_p (symbol
)
249 return symbol
[0] == '@' && symbol
[1] == 'i' && symbol
[2] == '.';
252 /* Mark a DECL as being dllexport'd.
253 Note that we override the previous setting (eg: dllimport). */
256 i386_pe_mark_dllexport (decl
)
264 rtlname
= XEXP (DECL_RTL (decl
), 0);
265 if (GET_CODE (rtlname
) == SYMBOL_REF
)
266 oldname
= XSTR (rtlname
, 0);
267 else if (GET_CODE (rtlname
) == MEM
268 && GET_CODE (XEXP (rtlname
, 0)) == SYMBOL_REF
)
269 oldname
= XSTR (XEXP (rtlname
, 0), 0);
272 if (i386_pe_dllimport_name_p (oldname
))
274 else if (i386_pe_dllexport_name_p (oldname
))
275 return; /* already done */
277 newname
= alloca (strlen (oldname
) + 4);
278 sprintf (newname
, "@e.%s", oldname
);
280 /* We pass newname through get_identifier to ensure it has a unique
281 address. RTL processing can sometimes peek inside the symbol ref
282 and compare the string's addresses to see if two symbols are
284 idp
= get_identifier (newname
);
286 XEXP (DECL_RTL (decl
), 0) =
287 gen_rtx (SYMBOL_REF
, Pmode
, IDENTIFIER_POINTER (idp
));
290 /* Mark a DECL as being dllimport'd. */
293 i386_pe_mark_dllimport (decl
)
301 rtlname
= XEXP (DECL_RTL (decl
), 0);
302 if (GET_CODE (rtlname
) == SYMBOL_REF
)
303 oldname
= XSTR (rtlname
, 0);
304 else if (GET_CODE (rtlname
) == MEM
305 && GET_CODE (XEXP (rtlname
, 0)) == SYMBOL_REF
)
306 oldname
= XSTR (XEXP (rtlname
, 0), 0);
309 if (i386_pe_dllexport_name_p (oldname
))
311 error ("`%s' declared as both exported to and imported from a DLL.",
312 IDENTIFIER_POINTER (DECL_NAME (decl
)));
315 else if (i386_pe_dllimport_name_p (oldname
))
317 /* Already done, but force correct linkage since the redeclaration
318 might have omitted explicit extern. Sigh. */
319 if (TREE_CODE (decl
) == VAR_DECL
320 /* ??? Is this test for vtables needed? */
321 && !DECL_VIRTUAL_P (decl
))
323 DECL_EXTERNAL (decl
) = 1;
324 TREE_PUBLIC (decl
) = 1;
329 /* ??? One can well ask why we're making these checks here,
330 and that would be a good question. */
332 /* Imported variables can't be initialized. Note that C++ classes
333 are marked initial, so we need to check. */
334 if (TREE_CODE (decl
) == VAR_DECL
335 && !DECL_VIRTUAL_P (decl
)
336 && (DECL_INITIAL (decl
)
337 && ! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
))))
339 error_with_decl (decl
, "initialized variable `%s' is marked dllimport");
342 /* Nor can they be static. */
343 if (TREE_CODE (decl
) == VAR_DECL
344 /* ??? Is this test for vtables needed? */
345 && !DECL_VIRTUAL_P (decl
)
348 error_with_decl (decl
, "static variable `%s' is marked dllimport");
352 /* `extern' needn't be specified with dllimport.
353 Specify `extern' now and hope for the best. Sigh. */
354 if (TREE_CODE (decl
) == VAR_DECL
355 /* ??? Is this test for vtables needed? */
356 && !DECL_VIRTUAL_P (decl
))
358 DECL_EXTERNAL (decl
) = 1;
359 TREE_PUBLIC (decl
) = 1;
362 newname
= alloca (strlen (oldname
) + 11);
363 sprintf (newname
, "@i._imp__%s", oldname
);
365 /* We pass newname through get_identifier to ensure it has a unique
366 address. RTL processing can sometimes peek inside the symbol ref
367 and compare the string's addresses to see if two symbols are
369 idp
= get_identifier (newname
);
371 newrtl
= gen_rtx (MEM
, Pmode
,
372 gen_rtx (SYMBOL_REF
, Pmode
,
373 IDENTIFIER_POINTER (idp
)));
374 XEXP (DECL_RTL (decl
), 0) = newrtl
;
376 /* Can't treat a pointer to this as a constant address */
377 DECL_NON_ADDR_CONST_P (decl
) = 1;
380 /* Return string which is the former assembler name modified with a
381 suffix consisting of an atsign (@) followed by the number of bytes of
385 gen_stdcall_suffix (decl
)
389 /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
390 of DECL_ASSEMBLER_NAME. */
391 const char *asmname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
394 if (TYPE_ARG_TYPES (TREE_TYPE (decl
)))
395 if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl
))))
398 tree formal_type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
400 while (TREE_VALUE (formal_type
) != void_type_node
)
403 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type
)));
404 /* Must round up to include padding. This is done the same
405 way as in store_one_arg. */
406 parm_size
= ((parm_size
+ PARM_BOUNDARY
- 1)
407 / PARM_BOUNDARY
* PARM_BOUNDARY
);
409 formal_type
= TREE_CHAIN (formal_type
);
413 newsym
= xmalloc (strlen (asmname
) + 10);
414 sprintf (newsym
, "%s@%d", asmname
, total
/BITS_PER_UNIT
);
415 return IDENTIFIER_POINTER (get_identifier (newsym
));
418 /* Cover function to implement ENCODE_SECTION_INFO. */
421 i386_pe_encode_section_info (decl
)
424 /* This bit is copied from i386.h. */
425 if (optimize
> 0 && TREE_CONSTANT (decl
)
426 && (!flag_writable_strings
|| TREE_CODE (decl
) != STRING_CST
))
428 rtx rtl
= (TREE_CODE_CLASS (TREE_CODE (decl
)) != 'd'
429 ? TREE_CST_RTL (decl
) : DECL_RTL (decl
));
430 SYMBOL_REF_FLAG (XEXP (rtl
, 0)) = 1;
433 if (TREE_CODE (decl
) == FUNCTION_DECL
)
434 if (lookup_attribute ("stdcall",
435 TYPE_ATTRIBUTES (TREE_TYPE (decl
))))
436 XEXP (DECL_RTL (decl
), 0) =
437 gen_rtx (SYMBOL_REF
, Pmode
, gen_stdcall_suffix (decl
));
439 /* Mark the decl so we can tell from the rtl whether the object is
440 dllexport'd or dllimport'd. */
442 if (i386_pe_dllexport_p (decl
))
443 i386_pe_mark_dllexport (decl
);
444 else if (i386_pe_dllimport_p (decl
))
445 i386_pe_mark_dllimport (decl
);
446 /* It might be that DECL has already been marked as dllimport, but a
447 subsequent definition nullified that. The attribute is gone but
448 DECL_RTL still has @i._imp__foo. We need to remove that. Ditto
449 for the DECL_NON_ADDR_CONST_P flag. */
450 else if ((TREE_CODE (decl
) == FUNCTION_DECL
451 || TREE_CODE (decl
) == VAR_DECL
)
452 && DECL_RTL (decl
) != NULL_RTX
453 && GET_CODE (DECL_RTL (decl
)) == MEM
454 && GET_CODE (XEXP (DECL_RTL (decl
), 0)) == MEM
455 && GET_CODE (XEXP (XEXP (DECL_RTL (decl
), 0), 0)) == SYMBOL_REF
456 && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl
), 0), 0), 0)))
458 const char *oldname
= XSTR (XEXP (XEXP (DECL_RTL (decl
), 0), 0), 0);
459 tree idp
= get_identifier (oldname
+ 9);
460 rtx newrtl
= gen_rtx (SYMBOL_REF
, Pmode
, IDENTIFIER_POINTER (idp
));
462 XEXP (DECL_RTL (decl
), 0) = newrtl
;
464 DECL_NON_ADDR_CONST_P (decl
) = 0;
466 /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
467 We leave these alone for now. */
471 /* Cover function for UNIQUE_SECTION. */
474 i386_pe_unique_section (decl
, reloc
)
479 const char *name
, *prefix
;
482 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
483 /* Strip off any encoding in fnname. */
484 STRIP_NAME_ENCODING (name
, name
);
486 /* The object is put in, for example, section .text$foo.
487 The linker will then ultimately place them in .text
488 (everything from the $ on is stripped). Don't put
489 read-only data in .rdata section to avoid a PE linker
490 bug when .rdata$* grouped sections are used in code
491 without a .rdata section. */
492 if (TREE_CODE (decl
) == FUNCTION_DECL
)
494 /* else if (DECL_INITIAL (decl) == 0
495 || DECL_INITIAL (decl) == error_mark_node)
497 else if (DECL_READONLY_SECTION (decl
, reloc
))
498 #ifdef READONLY_DATA_SECTION
505 len
= strlen (name
) + strlen (prefix
);
506 string
= alloca (len
+ 1);
507 sprintf (string
, "%s%s", prefix
, name
);
509 DECL_SECTION_NAME (decl
) = build_string (len
, string
);
512 /* The Microsoft linker requires that every function be marked as
513 DT_FCN. When using gas on cygwin, we must emit appropriate .type
518 /* Mark a function appropriately. This should only be called for
519 functions for which we are not emitting COFF debugging information.
520 FILE is the assembler output file, NAME is the name of the
521 function, and PUBLIC is non-zero if the function is globally
525 i386_pe_declare_function_type (file
, name
, public)
530 fprintf (file
, "\t.def\t");
531 assemble_name (file
, name
);
532 fprintf (file
, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
533 public ? (int) C_EXT
: (int) C_STAT
,
534 (int) DT_FCN
<< N_BTSHFT
);
537 /* Keep a list of external functions. */
541 struct extern_list
*next
;
545 static struct extern_list
*extern_head
;
547 /* Assemble an external function reference. We need to keep a list of
548 these, so that we can output the function types at the end of the
549 assembly. We can't output the types now, because we might see a
550 definition of the function later on and emit debugging information
554 i386_pe_record_external_function (name
)
557 struct extern_list
*p
;
559 p
= (struct extern_list
*) permalloc (sizeof *p
);
560 p
->next
= extern_head
;
565 /* Keep a list of exported symbols. */
569 struct export_list
*next
;
571 int is_data
; /* used to type tag exported symbols. */
574 static struct export_list
*export_head
;
576 /* Assemble an export symbol entry. We need to keep a list of
577 these, so that we can output the export list at the end of the
578 assembly. We used to output these export symbols in each function,
579 but that causes problems with GNU ld when the sections are
583 i386_pe_record_exported_symbol (name
, is_data
)
587 struct export_list
*p
;
589 p
= (struct export_list
*) permalloc (sizeof *p
);
590 p
->next
= export_head
;
592 p
->is_data
= is_data
;
596 /* This is called at the end of assembly. For each external function
597 which has not been defined, we output a declaration now. We also
598 output the .drectve section. */
601 i386_pe_asm_file_end (file
)
604 struct extern_list
*p
;
606 ix86_asm_file_end (file
);
608 for (p
= extern_head
; p
!= NULL
; p
= p
->next
)
612 decl
= get_identifier (p
->name
);
614 /* Positively ensure only one declaration for any given symbol. */
615 if (! TREE_ASM_WRITTEN (decl
) && TREE_SYMBOL_REFERENCED (decl
))
617 TREE_ASM_WRITTEN (decl
) = 1;
618 i386_pe_declare_function_type (file
, p
->name
, TREE_PUBLIC (decl
));
624 struct export_list
*q
;
626 for (q
= export_head
; q
!= NULL
; q
= q
->next
)
628 fprintf (file
, "\t.ascii \" -export:%s%s\"\n",
629 I386_PE_STRIP_ENCODING (q
->name
),
630 (q
->is_data
) ? ",data" : "");
This page took 0.065282 seconds and 5 git commands to generate.