Warning: That file was not part of the compilation database. It may have many parsing errors.

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

Warning: That file was not part of the compilation database. It may have many parsing errors.