]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/winnt.c
cfgloop.c (verify_loop_structure): Use %' in diagnostics.
[thirdparty/gcc.git] / gcc / config / i386 / winnt.c
CommitLineData
30c71308
RK
1/* Subroutines for insn-output.c for Windows NT.
2 Contributed by Douglas Rupp (drupp@cs.washington.edu)
4e2bb0a4 3 Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
6d217c32 4 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
30c71308 5
6b6cb52e 6This file is part of GCC.
30c71308 7
6b6cb52e
DS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
2f83c7d6 10Software Foundation; either version 3, or (at your option) any later
6b6cb52e 11version.
30c71308 12
6b6cb52e
DS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
30c71308
RK
17
18You should have received a copy of the GNU General Public License
2f83c7d6
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
40dcd88b 21
30c71308 22#include "config.h"
293bcdc9 23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
30c71308
RK
26#include "rtl.h"
27#include "regs.h"
28#include "hard-reg-set.h"
29#include "output.h"
30#include "tree.h"
31#include "flags.h"
79f96374 32#include "tm_p.h"
718f9c0f 33#include "diagnostic-core.h"
79f96374 34#include "toplev.h"
7c262518 35#include "hashtab.h"
bfb139b4 36#include "langhooks.h"
772c5265 37#include "ggc.h"
da489f73 38#include "target.h"
f81c9774 39#include "except.h"
3bec79c5 40#include "lto-streamer.h"
30c71308 41
27da1b4d
MK
42/* i386/PE specific attribute support.
43
44 i386/PE has two new attributes:
45 dllexport - for exporting a function/variable that will live in a dll
46 dllimport - for importing a function/variable from a dll
47
48 Microsoft allows multiple declspecs in one __declspec, separating
49 them with spaces. We do NOT support this. Instead, use __declspec
50 multiple times.
51*/
52
91d231cb
JM
53/* Handle a "shared" attribute;
54 arguments as in struct attribute_spec.handler. */
55tree
9c808aad
AJ
56ix86_handle_shared_attribute (tree *node, tree name,
57 tree args ATTRIBUTE_UNUSED,
58 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
ac478ac0 59{
91d231cb 60 if (TREE_CODE (*node) != VAR_DECL)
ac478ac0 61 {
29d08eba
JM
62 warning (OPT_Wattributes, "%qE attribute only applies to variables",
63 name);
91d231cb 64 *no_add_attrs = true;
ac478ac0
JM
65 }
66
91d231cb 67 return NULL_TREE;
ac478ac0 68}
a20f6f00
DS
69
70/* Handle a "selectany" attribute;
71 arguments as in struct attribute_spec.handler. */
72tree
73ix86_handle_selectany_attribute (tree *node, tree name,
74 tree args ATTRIBUTE_UNUSED,
75 int flags ATTRIBUTE_UNUSED,
76 bool *no_add_attrs)
77{
78 /* The attribute applies only to objects that are initialized and have
4e2bb0a4
DS
79 external linkage. However, we may not know about initialization
80 until the language frontend has processed the decl. We'll check for
5234b8f5 81 initialization later in encode_section_info. */
4e2bb0a4 82 if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
a20f6f00 83 {
29d08eba
JM
84 error ("%qE attribute applies only to initialized variables"
85 " with external linkage", name);
a20f6f00
DS
86 *no_add_attrs = true;
87 }
88
89 return NULL_TREE;
90}
91
27da1b4d 92\f
ac478ac0
JM
93/* Return the type that we should use to determine if DECL is
94 imported or exported. */
27da1b4d 95
ac478ac0 96static tree
9c808aad 97associated_type (tree decl)
27da1b4d 98{
da489f73
RH
99 return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
100 ? DECL_CONTEXT (decl) : NULL_TREE);
27da1b4d
MK
101}
102
da489f73 103/* Return true if DECL should be a dllexport'd object. */
43d9ad1d
DS
104
105static bool
da489f73 106i386_pe_determine_dllexport_p (tree decl)
27da1b4d 107{
da489f73 108 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
43d9ad1d 109 return false;
27da1b4d 110
b20231fe
DS
111 /* Don't export local clones of dllexports. */
112 if (!TREE_PUBLIC (decl))
113 return false;
114
43d9ad1d
DS
115 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
116 return true;
27da1b4d 117
43d9ad1d
DS
118 return false;
119}
120
da489f73
RH
121/* Return true if DECL should be a dllimport'd object. */
122
43d9ad1d 123static bool
da489f73 124i386_pe_determine_dllimport_p (tree decl)
27da1b4d 125{
da489f73
RH
126 tree assoc;
127
128 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
43d9ad1d
DS
129 return false;
130
da489f73
RH
131 if (DECL_DLLIMPORT_P (decl))
132 return true;
133
43d9ad1d
DS
134 /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
135 by targetm.cxx.adjust_class_at_definition. Check again to emit
09a6b8a4
DS
136 error message if the class attribute has been overridden by an
137 out-of-class definition of static data. */
da489f73 138 assoc = associated_type (decl);
09a6b8a4
DS
139 if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))
140 && TREE_CODE (decl) == VAR_DECL
141 && TREE_STATIC (decl) && TREE_PUBLIC (decl)
142 && !DECL_EXTERNAL (decl)
143 /* vtable's are linkonce constants, so defining a vtable is not
144 an error as long as we don't try to import it too. */
145 && !DECL_VIRTUAL_P (decl))
146 error ("definition of static data member %q+D of "
d8a07487 147 "dllimport%'d class", decl);
43d9ad1d
DS
148
149 return false;
150}
27da1b4d 151
43d9ad1d 152/* Handle the -mno-fun-dllimport target switch. */
da489f73 153
43d9ad1d 154bool
3101faab 155i386_pe_valid_dllimport_attribute_p (const_tree decl)
43d9ad1d
DS
156{
157 if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
158 return false;
159 return true;
27da1b4d
MK
160}
161
5234b8f5
DS
162/* Return string which is the function name, identified by ID, modified
163 with a suffix consisting of an atsign (@) followed by the number of
164 bytes of arguments. If ID is NULL use the DECL_NAME as base. If
165 FASTCALL is true, also add the FASTCALL_PREFIX.
da489f73 166 Return NULL if no change required. */
30c71308 167
23d34220 168static tree
5234b8f5 169gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
30c71308 170{
da489f73 171 HOST_WIDE_INT total = 0;
5234b8f5 172 const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
da489f73 173 char *new_str, *p;
04e1d06b
MM
174 tree type = TREE_TYPE (decl);
175 tree arg;
176 function_args_iterator args_iter;
30c71308 177
5234b8f5 178 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
23d34220 179
04e1d06b
MM
180 if (prototype_p (type))
181 {
182 /* This attribute is ignored for variadic functions. */
183 if (stdarg_p (type))
184 return NULL_TREE;
185
186 /* Quit if we hit an incomplete type. Error is reported
187 by convert_arguments in c-typeck.c or cp/typeck.c. */
188 FOREACH_FUNCTION_ARGS(type, arg, args_iter)
189 {
190 HOST_WIDE_INT parm_size;
191 HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
192
193 if (! COMPLETE_TYPE_P (arg))
194 break;
195
196 parm_size = int_size_in_bytes (arg);
197 if (parm_size < 0)
198 break;
199
200 /* Must round up to include padding. This is done the same
201 way as in store_one_arg. */
202 parm_size = ((parm_size + parm_boundary_bytes - 1)
203 / parm_boundary_bytes * parm_boundary_bytes);
204 total += parm_size;
205 }
da489f73 206 }
9c808aad 207 /* Assume max of 8 base 10 digits in the suffix. */
5ead67f6 208 p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1);
23d34220
DS
209 if (fastcall)
210 *p++ = FASTCALL_PREFIX;
5234b8f5 211 sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total);
da489f73
RH
212
213 return get_identifier (new_str);
30c71308 214}
0ea6b275 215
5234b8f5
DS
216/* Maybe decorate and get a new identifier for the DECL of a stdcall or
217 fastcall function. The original identifier is supplied in ID. */
218
219static tree
220i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id)
221{
222 tree new_id = NULL_TREE;
223
224 if (TREE_CODE (decl) == FUNCTION_DECL)
225 {
226 tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
227 if (lookup_attribute ("stdcall", type_attributes))
228 new_id = gen_stdcall_or_fastcall_suffix (decl, id, false);
229 else if (lookup_attribute ("fastcall", type_attributes))
230 new_id = gen_stdcall_or_fastcall_suffix (decl, id, true);
231 }
232
233 return new_id;
234}
235
236/* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
237 in the language-independent default hook
238 langhooks,c:lhd_set_decl_assembler_name ()
239 and in cp/mangle,c:mangle_decl (). */
240tree
241i386_pe_mangle_decl_assembler_name (tree decl, tree id)
242{
243 tree new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, id);
244
245 return (new_id ? new_id : id);
246}
247
27da1b4d 248void
9c808aad 249i386_pe_encode_section_info (tree decl, rtx rtl, int first)
27da1b4d 250{
da489f73
RH
251 rtx symbol;
252 int flags;
253
254 /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above. */
c6a2438a 255 default_encode_section_info (decl, rtl, first);
27da1b4d 256
da489f73
RH
257 /* Careful not to prod global register variables. */
258 if (!MEM_P (rtl))
259 return;
260
261 symbol = XEXP (rtl, 0);
262 gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
263
264 switch (TREE_CODE (decl))
e91f04de 265 {
da489f73 266 case FUNCTION_DECL:
bfb139b4
DS
267 /* FIXME: Imported stdcall names are not modified by the Ada frontend.
268 Check and decorate the RTL name now. */
269 if (strcmp (lang_hooks.name, "GNU Ada") == 0)
23d34220 270 {
bfb139b4
DS
271 tree new_id;
272 tree old_id = DECL_ASSEMBLER_NAME (decl);
273 const char* asm_str = IDENTIFIER_POINTER (old_id);
274 /* Do not change the identifier if a verbatim asmspec
5234b8f5 275 or if stdcall suffix already added. */
bfb139b4
DS
276 if (!(*asm_str == '*' || strchr (asm_str, '@'))
277 && (new_id = i386_pe_maybe_mangle_decl_assembler_name (decl,
278 old_id)))
279 XSTR (symbol, 0) = IDENTIFIER_POINTER (new_id);
23d34220 280 }
da489f73 281 break;
27da1b4d 282
da489f73
RH
283 case VAR_DECL:
284 if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
285 {
286 if (DECL_INITIAL (decl)
287 /* If an object is initialized with a ctor, the static
288 initialization and destruction code for it is present in
289 each unit defining the object. The code that calls the
290 ctor is protected by a link-once guard variable, so that
291 the object still has link-once semantics, */
292 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
daa0eeb8 293 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
da489f73
RH
294 else
295 error ("%q+D:'selectany' attribute applies only to "
296 "initialized objects", decl);
297 }
298 break;
299
300 default:
301 return;
4e2bb0a4
DS
302 }
303
27da1b4d 304 /* Mark the decl so we can tell from the rtl whether the object is
43d9ad1d
DS
305 dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes
306 handles dllexport/dllimport override semantics. */
da489f73
RH
307 flags = (SYMBOL_REF_FLAGS (symbol) &
308 ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));
309 if (i386_pe_determine_dllexport_p (decl))
310 flags |= SYMBOL_FLAG_DLLEXPORT;
311 else if (i386_pe_determine_dllimport_p (decl))
09a6b8a4
DS
312 flags |= SYMBOL_FLAG_DLLIMPORT;
313
da489f73 314 SYMBOL_REF_FLAGS (symbol) = flags;
27da1b4d
MK
315}
316
da489f73 317bool
3101faab 318i386_pe_binds_local_p (const_tree exp)
772c5265 319{
da489f73
RH
320 /* PE does not do dynamic binding. Indeed, the only kind of
321 non-local reference comes from a dllimport'd symbol. */
322 if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
323 && DECL_DLLIMPORT_P (exp))
324 return false;
325
2dfccd83
DK
326 /* Or a weak one, now that they are supported. */
327 if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
328 && DECL_WEAK (exp))
037de943 329 return false;
2dfccd83 330
da489f73 331 return true;
772c5265
RH
332}
333
b1f123c7 334/* Also strip the fastcall prefix and stdcall suffix. */
772c5265
RH
335
336const char *
9c808aad 337i386_pe_strip_name_encoding_full (const char *str)
772c5265
RH
338{
339 const char *p;
da489f73 340 const char *name = default_strip_name_encoding (str);
9c808aad 341
b1f123c7
DS
342 /* Strip leading '@' on fastcall symbols. */
343 if (*name == '@')
344 name++;
345
346 /* Strip trailing "@n". */
772c5265
RH
347 p = strchr (name, '@');
348 if (p)
12df9508
DS
349 return ggc_alloc_string (name, p - name);
350
772c5265
RH
351 return name;
352}
353
516dd80f 354void
9c808aad 355i386_pe_unique_section (tree decl, int reloc)
b64deb96
JM
356{
357 int len;
79f96374
DB
358 const char *name, *prefix;
359 char *string;
b64deb96
JM
360
361 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
772c5265 362 name = i386_pe_strip_name_encoding_full (name);
b64deb96
JM
363
364 /* The object is put in, for example, section .text$foo.
365 The linker will then ultimately place them in .text
81023100 366 (everything from the $ on is stripped). Don't put
9c808aad 367 read-only data in .rdata section to avoid a PE linker
81023100
MK
368 bug when .rdata$* grouped sections are used in code
369 without a .rdata section. */
b64deb96
JM
370 if (TREE_CODE (decl) == FUNCTION_DECL)
371 prefix = ".text$";
4e4d733e 372 else if (decl_readonly_section (decl, reloc))
b64deb96
JM
373 prefix = ".rdata$";
374 else
375 prefix = ".data$";
376 len = strlen (name) + strlen (prefix);
5ead67f6 377 string = XALLOCAVEC (char, len + 1);
b64deb96
JM
378 sprintf (string, "%s%s", prefix, name);
379
516dd80f 380 DECL_SECTION_NAME (decl) = build_string (len, string);
b64deb96 381}
7c262518
RH
382
383/* Select a set of attributes for section NAME based on the properties
384 of DECL and whether or not RELOC indicates that DECL's initializer
385 might contain runtime relocations.
386
387 We make the section read-only and executable for a function decl,
388 read-only for a const data decl, and writable for a non-const data decl.
389
390 If the section has already been defined, to not allow it to have
391 different attributes, as (1) this is ambiguous since we're not seeing
392 all the declarations up front and (2) some assemblers (e.g. SVR4)
d1f87653 393 do not recognize section redefinitions. */
7c262518
RH
394/* ??? This differs from the "standard" PE implementation in that we
395 handle the SHARED variable attribute. Should this be done for all
396 PE targets? */
397
398#define SECTION_PE_SHARED SECTION_MACH_DEP
399
400unsigned int
9c808aad 401i386_pe_section_type_flags (tree decl, const char *name, int reloc)
7c262518
RH
402{
403 static htab_t htab;
404 unsigned int flags;
405 unsigned int **slot;
406
407 /* The names we put in the hashtable will always be the unique
1ae58c30 408 versions given to us by the stringtable, so we can just use
7c262518
RH
409 their addresses as the keys. */
410 if (!htab)
411 htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
412
413 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
414 flags = SECTION_CODE;
4e4d733e 415 else if (decl && decl_readonly_section (decl, reloc))
7c262518 416 flags = 0;
40f39798
ZM
417 else if (current_function_decl
418 && cfun
419 && crtl->subsections.unlikely_text_section_name
420 && strcmp (name, crtl->subsections.unlikely_text_section_name) == 0)
421 flags = SECTION_CODE;
422 else if (!decl
423 && (!current_function_decl || !cfun)
424 && strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
425 flags = SECTION_CODE;
7c262518
RH
426 else
427 {
428 flags = SECTION_WRITE;
429
430 if (decl && TREE_CODE (decl) == VAR_DECL
91d231cb 431 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
7c262518
RH
432 flags |= SECTION_PE_SHARED;
433 }
434
435 if (decl && DECL_ONE_ONLY (decl))
436 flags |= SECTION_LINKONCE;
437
438 /* See if we already have an entry for this section. */
439 slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
440 if (!*slot)
441 {
442 *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
443 **slot = flags;
444 }
445 else
446 {
447 if (decl && **slot != flags)
dee15844 448 error ("%q+D causes a section type conflict", decl);
7c262518
RH
449 }
450
451 return flags;
452}
453
454void
c18a5b6c 455i386_pe_asm_named_section (const char *name, unsigned int flags,
a20f6f00 456 tree decl)
7c262518
RH
457{
458 char flagchars[8], *f = flagchars;
459
7f27395d
DS
460 if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
461 /* readonly data */
462 {
463 *f++ ='d'; /* This is necessary for older versions of gas. */
464 *f++ ='r';
465 }
466 else
1e8a5248
DS
467 {
468 if (flags & SECTION_CODE)
469 *f++ = 'x';
470 if (flags & SECTION_WRITE)
471 *f++ = 'w';
472 if (flags & SECTION_PE_SHARED)
473 *f++ = 's';
474 }
7f27395d 475
3bec79c5
DK
476 /* LTO sections need 1-byte alignment to avoid confusing the
477 zlib decompression algorithm with trailing zero pad bytes. */
478 if (strncmp (name, LTO_SECTION_NAME_PREFIX,
479 strlen (LTO_SECTION_NAME_PREFIX)) == 0)
480 *f++ = '0';
481
7c262518
RH
482 *f = '\0';
483
484 fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
485
486 if (flags & SECTION_LINKONCE)
487 {
488 /* Functions may have been compiled at various levels of
a20f6f00
DS
489 optimization so we can't use `same_size' here.
490 Instead, have the linker pick one, without warning.
315682fb 491 If 'selectany' attribute has been specified, MS compiler
a20f6f00
DS
492 sets 'discard' characteristic, rather than telling linker
493 to warn of size or content mismatch, so do the same. */
494 bool discard = (flags & SECTION_CODE)
495 || lookup_attribute ("selectany",
496 DECL_ATTRIBUTES (decl));
7c262518 497 fprintf (asm_out_file, "\t.linkonce %s\n",
a20f6f00 498 (discard ? "discard" : "same_size"));
7c262518
RH
499 }
500}
da489f73 501
3bec79c5
DK
502/* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */
503
da489f73
RH
504void
505i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
506 const char *name, HOST_WIDE_INT size,
507 HOST_WIDE_INT align ATTRIBUTE_UNUSED)
508{
509 HOST_WIDE_INT rounded;
510
233215fe
DK
511 /* Compute as in assemble_noswitch_variable, since we don't have
512 support for aligned common on older binutils. We must also
513 avoid emitting a common symbol of size zero, as this is the
514 overloaded representation that indicates an undefined external
515 symbol in the PE object file format. */
da489f73
RH
516 rounded = size ? size : 1;
517 rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
518 rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
519 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
520
521 i386_pe_maybe_record_exported_symbol (decl, name, 1);
522
ecb8c3cc 523 fprintf (stream, "\t.comm\t");
da489f73 524 assemble_name (stream, name);
233215fe
DK
525 if (use_pe_aligned_common)
526 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
527 size ? size : (HOST_WIDE_INT) 1,
528 exact_log2 (align) - exact_log2 (CHAR_BIT));
529 else
530 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
531 " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
da489f73 532}
9fa1246d
JL
533\f
534/* The Microsoft linker requires that every function be marked as
cae21ae8 535 DT_FCN. When using gas on cygwin, we must emit appropriate .type
9fa1246d
JL
536 directives. */
537
538#include "gsyms.h"
539
540/* Mark a function appropriately. This should only be called for
541 functions for which we are not emitting COFF debugging information.
542 FILE is the assembler output file, NAME is the name of the
0a2aaacc 543 function, and PUB is nonzero if the function is globally
9fa1246d
JL
544 visible. */
545
546void
0a2aaacc 547i386_pe_declare_function_type (FILE *file, const char *name, int pub)
9fa1246d
JL
548{
549 fprintf (file, "\t.def\t");
550 assemble_name (file, name);
551 fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
0a2aaacc 552 pub ? (int) C_EXT : (int) C_STAT,
9fa1246d
JL
553 (int) DT_FCN << N_BTSHFT);
554}
555
556/* Keep a list of external functions. */
557
d1b38208 558struct GTY(()) extern_list
9fa1246d
JL
559{
560 struct extern_list *next;
3ce9c824 561 tree decl;
79f96374 562 const char *name;
9fa1246d
JL
563};
564
90aa6719 565static GTY(()) struct extern_list *extern_head;
9fa1246d
JL
566
567/* Assemble an external function reference. We need to keep a list of
568 these, so that we can output the function types at the end of the
569 assembly. We can't output the types now, because we might see a
570 definition of the function later on and emit debugging information
571 for it then. */
572
573void
3ce9c824 574i386_pe_record_external_function (tree decl, const char *name)
9fa1246d
JL
575{
576 struct extern_list *p;
577
a9429e29 578 p = ggc_alloc_extern_list ();
9fa1246d 579 p->next = extern_head;
3ce9c824 580 p->decl = decl;
9fa1246d
JL
581 p->name = name;
582 extern_head = p;
583}
584
8e260ba4
MK
585/* Keep a list of exported symbols. */
586
d1b38208 587struct GTY(()) export_list
8e260ba4
MK
588{
589 struct export_list *next;
79f96374 590 const char *name;
892a2d68 591 int is_data; /* used to type tag exported symbols. */
8e260ba4
MK
592};
593
90aa6719 594static GTY(()) struct export_list *export_head;
e43f9c10
MK
595
596/* Assemble an export symbol entry. We need to keep a list of
597 these, so that we can output the export list at the end of the
598 assembly. We used to output these export symbols in each function,
9c808aad 599 but that causes problems with GNU ld when the sections are
3bec79c5
DK
600 linkonce. Beware, DECL may be NULL if compile_file() is emitting
601 the LTO marker. */
e43f9c10
MK
602
603void
da489f73 604i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
e43f9c10 605{
da489f73 606 rtx symbol;
8e260ba4 607 struct export_list *p;
e43f9c10 608
3bec79c5
DK
609 if (!decl)
610 return;
611
da489f73
RH
612 symbol = XEXP (DECL_RTL (decl), 0);
613 gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
614 if (!SYMBOL_REF_DLLEXPORT_P (symbol))
615 return;
616
b20231fe
DS
617 gcc_assert (TREE_PUBLIC (decl));
618
a9429e29 619 p = ggc_alloc_export_list ();
8e260ba4 620 p->next = export_head;
e43f9c10 621 p->name = name;
8e260ba4
MK
622 p->is_data = is_data;
623 export_head = p;
e43f9c10
MK
624}
625
f7e413e2
DK
626#ifdef CXX_WRAP_SPEC_LIST
627
628/* Hash table equality helper function. */
629
630static int
631wrapper_strcmp (const void *x, const void *y)
632{
633 return !strcmp ((const char *) x, (const char *) y);
634}
635
636/* Search for a function named TARGET in the list of library wrappers
637 we are using, returning a pointer to it if found or NULL if not.
638 This function might be called on quite a few symbols, and we only
639 have the list of names of wrapped functions available to us as a
640 spec string, so first time round we lazily initialise a hash table
641 to make things quicker. */
642
643static const char *
644i386_find_on_wrapper_list (const char *target)
645{
646 static char first_time = 1;
647 static htab_t wrappers;
648
649 if (first_time)
650 {
651 /* Beware that this is not a complicated parser, it assumes
652 that any sequence of non-whitespace beginning with an
653 underscore is one of the wrapped symbols. For now that's
654 adequate to distinguish symbols from spec substitutions
655 and command-line options. */
656 static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
657 char *bufptr;
658 /* Breaks up the char array into separated strings
659 strings and enter them into the hash table. */
660 wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
661 0, xcalloc, free);
662 for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
663 {
664 char *found = NULL;
665 if (ISSPACE (*bufptr))
666 continue;
667 if (*bufptr == '_')
668 found = bufptr;
669 while (*bufptr && !ISSPACE (*bufptr))
670 ++bufptr;
671 if (*bufptr)
672 *bufptr = 0;
673 if (found)
674 *htab_find_slot (wrappers, found, INSERT) = found;
675 }
676 first_time = 0;
677 }
678
679 return (const char *) htab_find (wrappers, target);
680}
681
682#endif /* CXX_WRAP_SPEC_LIST */
683
9fa1246d 684/* This is called at the end of assembly. For each external function
e43f9c10
MK
685 which has not been defined, we output a declaration now. We also
686 output the .drectve section. */
9fa1246d
JL
687
688void
9c808aad 689i386_pe_file_end (void)
9fa1246d
JL
690{
691 struct extern_list *p;
692
693 for (p = extern_head; p != NULL; p = p->next)
694 {
695 tree decl;
696
3ce9c824 697 decl = p->decl;
9fa1246d
JL
698
699 /* Positively ensure only one declaration for any given symbol. */
3ce9c824
ILT
700 if (! TREE_ASM_WRITTEN (decl)
701 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
9fa1246d 702 {
f7e413e2
DK
703#ifdef CXX_WRAP_SPEC_LIST
704 /* To ensure the DLL that provides the corresponding real
705 functions is still loaded at runtime, we must reference
706 the real function so that an (unused) import is created. */
707 const char *realsym = i386_find_on_wrapper_list (p->name);
708 if (realsym)
709 i386_pe_declare_function_type (asm_out_file,
710 concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
711#endif /* CXX_WRAP_SPEC_LIST */
9fa1246d 712 TREE_ASM_WRITTEN (decl) = 1;
a5fe455b 713 i386_pe_declare_function_type (asm_out_file, p->name,
9c808aad 714 TREE_PUBLIC (decl));
9fa1246d
JL
715 }
716 }
e43f9c10 717
8e260ba4 718 if (export_head)
e43f9c10 719 {
8e260ba4
MK
720 struct export_list *q;
721 drectve_section ();
722 for (q = export_head; q != NULL; q = q->next)
723 {
23b488ad 724 fprintf (asm_out_file, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
4b07e9f7 725 default_strip_name_encoding (q->name),
da489f73 726 (q->is_data ? ",data" : ""));
8e260ba4 727 }
e43f9c10 728 }
9fa1246d 729}
90aa6719 730
f81c9774
RH
731\f
732/* x64 Structured Exception Handling unwind info. */
733
734struct seh_frame_state
735{
736 /* SEH records saves relative to the "current" stack pointer, whether
737 or not there's a frame pointer in place. This tracks the current
738 stack pointer offset from the CFA. */
739 HOST_WIDE_INT sp_offset;
740
741 /* The CFA is located at CFA_REG + CFA_OFFSET. */
742 HOST_WIDE_INT cfa_offset;
743 rtx cfa_reg;
744};
745
746/* Set up data structures beginning output for SEH. */
747
748void
749i386_pe_seh_init (FILE *f)
750{
751 struct seh_frame_state *seh;
752
753 if (!TARGET_SEH)
754 return;
755 if (cfun->is_thunk)
756 return;
757
758 /* We cannot support DRAP with SEH. We turned off support for it by
759 re-defining MAX_STACK_ALIGNMENT when SEH is enabled. */
760 gcc_assert (!stack_realign_drap);
761
762 seh = XCNEW (struct seh_frame_state);
763 cfun->machine->seh = seh;
764
765 seh->sp_offset = INCOMING_FRAME_SP_OFFSET;
766 seh->cfa_offset = INCOMING_FRAME_SP_OFFSET;
767 seh->cfa_reg = stack_pointer_rtx;
768
769 fputs ("\t.seh_proc\t", f);
770 assemble_name (f, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun->decl)));
771 fputc ('\n', f);
772}
773
774void
775i386_pe_seh_end_prologue (FILE *f)
776{
777 struct seh_frame_state *seh;
778
779 if (!TARGET_SEH)
780 return;
781 if (cfun->is_thunk)
782 return;
783 seh = cfun->machine->seh;
784
785 /* Emit an assembler directive to set up the frame pointer. Always do
786 this last. The documentation talks about doing this "before" any
787 other code that uses offsets, but (experimentally) that's after we
788 emit the codes in reverse order (handled by the assembler). */
789 if (seh->cfa_reg != stack_pointer_rtx)
790 {
791 HOST_WIDE_INT offset = seh->sp_offset - seh->cfa_offset;
792
793 gcc_assert ((offset & 15) == 0);
794 gcc_assert (IN_RANGE (offset, 0, 240));
795
796 fputs ("\t.seh_setframe\t", f);
797 print_reg (seh->cfa_reg, 0, f);
798 fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
799 }
800
801 XDELETE (seh);
802 cfun->machine->seh = NULL;
803
804 fputs ("\t.seh_endprologue\n", f);
805}
806
807static void
808i386_pe_seh_fini (FILE *f)
809{
810 if (!TARGET_SEH)
811 return;
812 if (cfun->is_thunk)
813 return;
814 fputs ("\t.seh_endproc\n", f);
815}
816
817/* Emit an assembler directive to save REG via a PUSH. */
818
819static void
820seh_emit_push (FILE *f, struct seh_frame_state *seh, rtx reg)
821{
822 unsigned int regno = REGNO (reg);
823
824 gcc_checking_assert (GENERAL_REGNO_P (regno));
825
826 seh->sp_offset += UNITS_PER_WORD;
827 if (seh->cfa_reg == stack_pointer_rtx)
828 seh->cfa_offset += UNITS_PER_WORD;
829
830 fputs ("\t.seh_pushreg\t", f);
831 print_reg (reg, 0, f);
832 fputc ('\n', f);
833}
834
835/* Emit an assembler directive to save REG at CFA - CFA_OFFSET. */
836
837static void
838seh_emit_save (FILE *f, struct seh_frame_state *seh,
839 rtx reg, HOST_WIDE_INT cfa_offset)
840{
841 unsigned int regno = REGNO (reg);
842 HOST_WIDE_INT offset;
843
844 /* Negative save offsets are of course not supported, since that
845 would be a store below the stack pointer and thus clobberable. */
846 gcc_assert (seh->sp_offset >= cfa_offset);
847 offset = seh->sp_offset - cfa_offset;
848
849 fputs ((SSE_REGNO_P (regno) ? "\t.seh_savexmm\t"
850 : GENERAL_REGNO_P (regno) ? "\t.seh_savereg\t"
851 : (gcc_unreachable (), "")), f);
852 print_reg (reg, 0, f);
853 fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
854}
855
856/* Emit an assembler directive to adjust RSP by OFFSET. */
857
858static void
859seh_emit_stackalloc (FILE *f, struct seh_frame_state *seh,
860 HOST_WIDE_INT offset)
861{
862 /* We're only concerned with prologue stack allocations, which all
863 are subtractions from the stack pointer. */
864 gcc_assert (offset < 0);
865 offset = -offset;
866
867 if (seh->cfa_reg == stack_pointer_rtx)
868 seh->cfa_offset += offset;
869 seh->sp_offset += offset;
870
871 fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset);
872}
873
874/* Process REG_CFA_ADJUST_CFA for SEH. */
875
876static void
877seh_cfa_adjust_cfa (FILE *f, struct seh_frame_state *seh, rtx pat)
878{
879 rtx dest, src;
880 HOST_WIDE_INT reg_offset = 0;
881 unsigned int dest_regno;
882
883 dest = SET_DEST (pat);
884 src = SET_SRC (pat);
885
886 if (GET_CODE (src) == PLUS)
887 {
888 reg_offset = INTVAL (XEXP (src, 1));
889 src = XEXP (src, 0);
890 }
891 else if (GET_CODE (src) == MINUS)
892 {
893 reg_offset = -INTVAL (XEXP (src, 1));
894 src = XEXP (src, 0);
895 }
896 gcc_assert (src == stack_pointer_rtx);
897 gcc_assert (seh->cfa_reg == stack_pointer_rtx);
898 dest_regno = REGNO (dest);
899
900 if (dest_regno == STACK_POINTER_REGNUM)
901 seh_emit_stackalloc (f, seh, reg_offset);
902 else if (dest_regno == HARD_FRAME_POINTER_REGNUM)
903 {
904 seh->cfa_reg = dest;
905 seh->cfa_offset -= reg_offset;
906 }
907 else
908 gcc_unreachable ();
909}
910
911/* Process REG_CFA_OFFSET for SEH. */
912
913static void
914seh_cfa_offset (FILE *f, struct seh_frame_state *seh, rtx pat)
915{
916 rtx dest, src;
917 HOST_WIDE_INT reg_offset;
918
919 dest = SET_DEST (pat);
920 src = SET_SRC (pat);
921
922 gcc_assert (MEM_P (dest));
923 dest = XEXP (dest, 0);
924 if (REG_P (dest))
925 reg_offset = 0;
926 else
927 {
928 gcc_assert (GET_CODE (dest) == PLUS);
929 reg_offset = INTVAL (XEXP (dest, 1));
930 dest = XEXP (dest, 0);
931 }
932 gcc_assert (dest == seh->cfa_reg);
933
934 seh_emit_save (f, seh, src, seh->cfa_offset - reg_offset);
935}
936
937/* Process a FRAME_RELATED_EXPR for SEH. */
938
939static void
940seh_frame_related_expr (FILE *f, struct seh_frame_state *seh, rtx pat)
941{
942 rtx dest, src;
943 HOST_WIDE_INT addend;
944
945 /* See the full loop in dwarf2out_frame_debug_expr. */
946 if (GET_CODE (pat) == PARALLEL || GET_CODE (pat) == SEQUENCE)
947 {
948 int i, n = XVECLEN (pat, 0), pass, npass;
949
950 npass = (GET_CODE (pat) == PARALLEL ? 2 : 1);
951 for (pass = 0; pass < npass; ++pass)
952 for (i = 0; i < n; ++i)
953 {
954 rtx ele = XVECEXP (pat, 0, i);
955
956 if (GET_CODE (ele) != SET)
957 continue;
958 dest = SET_DEST (ele);
959
960 /* Process each member of the PARALLEL independently. The first
961 member is always processed; others only if they are marked. */
962 if (i == 0 || RTX_FRAME_RELATED_P (ele))
963 {
964 /* Evaluate all register saves in the first pass and all
965 register updates in the second pass. */
966 if ((MEM_P (dest) ^ pass) || npass == 1)
967 seh_frame_related_expr (f, seh, ele);
968 }
969 }
970 return;
971 }
972
973 dest = SET_DEST (pat);
974 src = SET_SRC (pat);
975
976 switch (GET_CODE (dest))
977 {
978 case REG:
979 switch (GET_CODE (src))
980 {
981 case REG:
982 /* REG = REG: This should be establishing a frame pointer. */
983 gcc_assert (src == stack_pointer_rtx);
984 gcc_assert (dest == hard_frame_pointer_rtx);
985 seh_cfa_adjust_cfa (f, seh, pat);
986 break;
987
988 case PLUS:
989 addend = INTVAL (XEXP (src, 1));
990 src = XEXP (src, 0);
991 if (dest == hard_frame_pointer_rtx)
992 seh_cfa_adjust_cfa (f, seh, pat);
993 else if (dest == stack_pointer_rtx)
994 {
995 gcc_assert (src == stack_pointer_rtx);
996 seh_emit_stackalloc (f, seh, addend);
997 }
998 else
999 gcc_unreachable ();
1000 break;
1001
1002 default:
1003 gcc_unreachable ();
1004 }
1005 break;
1006
1007 case MEM:
1008 /* A save of some kind. */
1009 dest = XEXP (dest, 0);
1010 if (GET_CODE (dest) == PRE_DEC)
1011 {
1012 gcc_checking_assert (GET_MODE (src) == Pmode);
1013 gcc_checking_assert (REG_P (src));
1014 seh_emit_push (f, seh, src);
1015 }
1016 else
1017 seh_cfa_offset (f, seh, pat);
1018 break;
1019
1020 default:
1021 gcc_unreachable ();
1022 }
1023}
1024
1025/* This function looks at a single insn and emits any SEH directives
1026 required for unwind of this insn. */
1027
1028void
1029i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx insn)
1030{
1031 rtx note, pat;
1032 bool handled_one = false;
1033 struct seh_frame_state *seh;
1034
1035 if (!TARGET_SEH)
1036 return;
1037
1038 /* We free the SEH data once done with the prologue. Ignore those
1039 RTX_FRAME_RELATED_P insns that are associated with the epilogue. */
1040 seh = cfun->machine->seh;
1041 if (seh == NULL)
1042 return;
1043
1044 if (NOTE_P (insn) || !RTX_FRAME_RELATED_P (insn))
1045 return;
1046
1047 for (note = REG_NOTES (insn); note ; note = XEXP (note, 1))
1048 {
1049 pat = XEXP (note, 0);
1050 switch (REG_NOTE_KIND (note))
1051 {
1052 case REG_FRAME_RELATED_EXPR:
1053 goto found;
1054
1055 case REG_CFA_DEF_CFA:
1056 case REG_CFA_EXPRESSION:
1057 /* Only emitted with DRAP, which we disable. */
1058 gcc_unreachable ();
1059 break;
1060
1061 case REG_CFA_REGISTER:
1062 /* Only emitted in epilogues, which we skip. */
1063 gcc_unreachable ();
1064
1065 case REG_CFA_ADJUST_CFA:
1066 if (pat == NULL)
1067 {
1068 pat = PATTERN (insn);
1069 if (GET_CODE (pat) == PARALLEL)
1070 pat = XVECEXP (pat, 0, 0);
1071 }
1072 seh_cfa_adjust_cfa (asm_out_file, seh, pat);
1073 handled_one = true;
1074 break;
1075
1076 case REG_CFA_OFFSET:
1077 if (pat == NULL)
1078 pat = single_set (insn);
1079 seh_cfa_offset (asm_out_file, seh, pat);
1080 handled_one = true;
1081 break;
1082
1083 default:
1084 break;
1085 }
1086 }
1087 if (handled_one)
1088 return;
1089 pat = PATTERN (insn);
1090 found:
1091 seh_frame_related_expr (asm_out_file, seh, pat);
1092}
1093\f
1094void
1095i386_pe_start_function (FILE *f, const char *name, tree decl)
1096{
1097 i386_pe_maybe_record_exported_symbol (decl, name, 0);
1098 if (write_symbols != SDB_DEBUG)
1099 i386_pe_declare_function_type (f, name, TREE_PUBLIC (decl));
1100 ASM_OUTPUT_FUNCTION_LABEL (f, name, decl);
1101}
1102
1103void
1104i386_pe_end_function (FILE *f, const char *name ATTRIBUTE_UNUSED,
1105 tree decl ATTRIBUTE_UNUSED)
1106{
1107 i386_pe_seh_fini (f);
1108}
1109\f
1110
90aa6719 1111#include "gt-winnt.h"