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