* po/bfd.pot: Updated by the Translation project.
[platform/upstream/binutils.git] / gas / dw2gencfi.c
1 /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
2    Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
3    Free Software Foundation, Inc.
4    Contributed by Michal Ludvig <mludvig@suse.cz>
5
6    This file is part of GAS, the GNU Assembler.
7
8    GAS is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3, or (at your option)
11    any later version.
12
13    GAS is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to the Free
20    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22
23 #include "as.h"
24 #include "dw2gencfi.h"
25 #include "subsegs.h"
26
27 #ifdef TARGET_USE_CFIPOP
28
29 /* By default, use difference expressions if DIFF_EXPR_OK is defined.  */
30 #ifndef CFI_DIFF_EXPR_OK
31 # ifdef DIFF_EXPR_OK
32 #  define CFI_DIFF_EXPR_OK 1
33 # else
34 #  define CFI_DIFF_EXPR_OK 0
35 # endif
36 #endif
37
38 /* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
39    of the CIE.  Default to 1 if not otherwise specified.  */
40 #ifndef  DWARF2_LINE_MIN_INSN_LENGTH
41 # define DWARF2_LINE_MIN_INSN_LENGTH 1
42 #endif
43
44 /* By default, use 32-bit relocations from .eh_frame into .text.  */
45 #ifndef DWARF2_FDE_RELOC_SIZE
46 # define DWARF2_FDE_RELOC_SIZE 4
47 #endif
48
49 /* By default, use a read-only .eh_frame section.  */
50 #ifndef DWARF2_EH_FRAME_READ_ONLY
51 # define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
52 #endif
53
54 #ifndef EH_FRAME_ALIGNMENT
55 # define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
56 #endif
57
58 #ifndef tc_cfi_frame_initial_instructions
59 # define tc_cfi_frame_initial_instructions() ((void)0)
60 #endif
61
62 #ifndef DWARF2_ADDR_SIZE
63 # define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
64 #endif
65
66 struct cfi_escape_data {
67   struct cfi_escape_data *next;
68   expressionS exp;
69 };
70
71 struct cfi_insn_data
72 {
73   struct cfi_insn_data *next;
74   int insn;
75   union {
76     struct {
77       unsigned reg;
78       offsetT offset;
79     } ri;
80
81     struct {
82       unsigned reg1;
83       unsigned reg2;
84     } rr;
85
86     unsigned r;
87     offsetT i;
88
89     struct {
90       symbolS *lab1;
91       symbolS *lab2;
92     } ll;
93
94     struct cfi_escape_data *esc;
95
96     struct {
97       unsigned reg, encoding;
98       expressionS exp;
99     } ea;
100   } u;
101 };
102
103 struct fde_entry
104 {
105   struct fde_entry *next;
106   symbolS *start_address;
107   symbolS *end_address;
108   struct cfi_insn_data *data;
109   struct cfi_insn_data **last;
110   unsigned char per_encoding;
111   unsigned char lsda_encoding;
112   expressionS personality;
113   expressionS lsda;
114   unsigned int return_column;
115   unsigned int signal_frame;
116 };
117
118 struct cie_entry
119 {
120   struct cie_entry *next;
121   symbolS *start_address;
122   unsigned int return_column;
123   unsigned int signal_frame;
124   unsigned char per_encoding;
125   unsigned char lsda_encoding;
126   expressionS personality;
127   struct cfi_insn_data *first, *last;
128 };
129
130
131 /* List of FDE entries.  */
132 static struct fde_entry *all_fde_data;
133 static struct fde_entry **last_fde_data = &all_fde_data;
134
135 /* List of CIEs so that they could be reused.  */
136 static struct cie_entry *cie_root;
137
138 /* Stack of old CFI data, for save/restore.  */
139 struct cfa_save_data
140 {
141   struct cfa_save_data *next;
142   offsetT cfa_offset;
143 };
144
145 /* Current open FDE entry.  */
146 struct frch_cfi_data
147 {
148   struct fde_entry *cur_fde_data;
149   symbolS *last_address;
150   offsetT cur_cfa_offset;
151   struct cfa_save_data *cfa_save_stack;
152 };
153 \f
154 /* Construct a new FDE structure and add it to the end of the fde list.  */
155
156 static struct fde_entry *
157 alloc_fde_entry (void)
158 {
159   struct fde_entry *fde = (struct fde_entry *)
160       xcalloc (1, sizeof (struct fde_entry));
161
162   frchain_now->frch_cfi_data = (struct frch_cfi_data *)
163       xcalloc (1, sizeof (struct frch_cfi_data));
164   frchain_now->frch_cfi_data->cur_fde_data = fde;
165   *last_fde_data = fde;
166   last_fde_data = &fde->next;
167
168   fde->last = &fde->data;
169   fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
170   fde->per_encoding = DW_EH_PE_omit;
171   fde->lsda_encoding = DW_EH_PE_omit;
172
173   return fde;
174 }
175
176 /* The following functions are available for a backend to construct its
177    own unwind information, usually from legacy unwind directives.  */
178
179 /* Construct a new INSN structure and add it to the end of the insn list
180    for the currently active FDE.  */
181
182 static struct cfi_insn_data *
183 alloc_cfi_insn_data (void)
184 {
185   struct cfi_insn_data *insn = (struct cfi_insn_data *)
186       xcalloc (1, sizeof (struct cfi_insn_data));
187   struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
188
189   *cur_fde_data->last = insn;
190   cur_fde_data->last = &insn->next;
191
192   return insn;
193 }
194
195 /* Construct a new FDE structure that begins at LABEL.  */
196
197 void 
198 cfi_new_fde (symbolS *label)
199 {
200   struct fde_entry *fde = alloc_fde_entry ();
201   fde->start_address = label;
202   frchain_now->frch_cfi_data->last_address = label;
203 }
204
205 /* End the currently open FDE.  */
206
207 void 
208 cfi_end_fde (symbolS *label)
209 {
210   frchain_now->frch_cfi_data->cur_fde_data->end_address = label;
211   free (frchain_now->frch_cfi_data);
212   frchain_now->frch_cfi_data = NULL;
213 }
214
215 /* Set the return column for the current FDE.  */
216
217 void
218 cfi_set_return_column (unsigned regno)
219 {
220   frchain_now->frch_cfi_data->cur_fde_data->return_column = regno;
221 }
222
223 /* Universal functions to store new instructions.  */
224
225 static void
226 cfi_add_CFA_insn(int insn)
227 {
228   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
229
230   insn_ptr->insn = insn;
231 }
232
233 static void
234 cfi_add_CFA_insn_reg (int insn, unsigned regno)
235 {
236   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
237
238   insn_ptr->insn = insn;
239   insn_ptr->u.r = regno;
240 }
241
242 static void
243 cfi_add_CFA_insn_offset (int insn, offsetT offset)
244 {
245   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
246
247   insn_ptr->insn = insn;
248   insn_ptr->u.i = offset;
249 }
250
251 static void
252 cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
253 {
254   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
255
256   insn_ptr->insn = insn;
257   insn_ptr->u.rr.reg1 = reg1;
258   insn_ptr->u.rr.reg2 = reg2;
259 }
260
261 static void
262 cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
263 {
264   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
265
266   insn_ptr->insn = insn;
267   insn_ptr->u.ri.reg = regno;
268   insn_ptr->u.ri.offset = offset;
269 }
270
271 /* Add a CFI insn to advance the PC from the last address to LABEL.  */
272
273 void
274 cfi_add_advance_loc (symbolS *label)
275 {
276   struct cfi_insn_data *insn = alloc_cfi_insn_data ();
277
278   insn->insn = DW_CFA_advance_loc;
279   insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address;
280   insn->u.ll.lab2 = label;
281
282   frchain_now->frch_cfi_data->last_address = label;
283 }
284
285 /* Add a DW_CFA_offset record to the CFI data.  */
286
287 void
288 cfi_add_CFA_offset (unsigned regno, offsetT offset)
289 {
290   unsigned int abs_data_align;
291
292   gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
293   cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
294
295   abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
296                     ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
297   if (offset % abs_data_align)
298     as_bad (_("register save offset not a multiple of %u"), abs_data_align);
299 }
300
301 /* Add a DW_CFA_def_cfa record to the CFI data.  */
302
303 void
304 cfi_add_CFA_def_cfa (unsigned regno, offsetT offset)
305 {
306   cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
307   frchain_now->frch_cfi_data->cur_cfa_offset = offset;
308 }
309
310 /* Add a DW_CFA_register record to the CFI data.  */
311
312 void
313 cfi_add_CFA_register (unsigned reg1, unsigned reg2)
314 {
315   cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
316 }
317
318 /* Add a DW_CFA_def_cfa_register record to the CFI data.  */
319
320 void
321 cfi_add_CFA_def_cfa_register (unsigned regno)
322 {
323   cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
324 }
325
326 /* Add a DW_CFA_def_cfa_offset record to the CFI data.  */
327
328 void
329 cfi_add_CFA_def_cfa_offset (offsetT offset)
330 {
331   cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
332   frchain_now->frch_cfi_data->cur_cfa_offset = offset;
333 }
334
335 void
336 cfi_add_CFA_restore (unsigned regno)
337 {
338   cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
339 }
340
341 void
342 cfi_add_CFA_undefined (unsigned regno)
343 {
344   cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
345 }
346
347 void
348 cfi_add_CFA_same_value (unsigned regno)
349 {
350   cfi_add_CFA_insn_reg (DW_CFA_same_value, regno);
351 }
352
353 void
354 cfi_add_CFA_remember_state (void)
355 {
356   struct cfa_save_data *p;
357
358   cfi_add_CFA_insn (DW_CFA_remember_state);
359
360   p = (struct cfa_save_data *) xmalloc (sizeof (*p));
361   p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
362   p->next = frchain_now->frch_cfi_data->cfa_save_stack;
363   frchain_now->frch_cfi_data->cfa_save_stack = p;
364 }
365
366 void
367 cfi_add_CFA_restore_state (void)
368 {
369   struct cfa_save_data *p;
370
371   cfi_add_CFA_insn (DW_CFA_restore_state);
372
373   p = frchain_now->frch_cfi_data->cfa_save_stack;
374   if (p)
375     {
376       frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset;
377       frchain_now->frch_cfi_data->cfa_save_stack = p->next;
378       free (p);
379     }
380   else
381     as_bad (_("CFI state restore without previous remember"));
382 }
383
384 \f
385 /* Parse CFI assembler directives.  */
386
387 static void dot_cfi (int);
388 static void dot_cfi_escape (int);
389 static void dot_cfi_startproc (int);
390 static void dot_cfi_endproc (int);
391 static void dot_cfi_personality (int);
392 static void dot_cfi_lsda (int);
393 static void dot_cfi_val_encoded_addr (int);
394
395 /* Fake CFI type; outside the byte range of any real CFI insn.  */
396 #define CFI_adjust_cfa_offset   0x100
397 #define CFI_return_column       0x101
398 #define CFI_rel_offset          0x102
399 #define CFI_escape              0x103
400 #define CFI_signal_frame        0x104
401 #define CFI_val_encoded_addr    0x105
402
403 const pseudo_typeS cfi_pseudo_table[] =
404   {
405     { "cfi_startproc", dot_cfi_startproc, 0 },
406     { "cfi_endproc", dot_cfi_endproc, 0 },
407     { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
408     { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
409     { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset },
410     { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
411     { "cfi_offset", dot_cfi, DW_CFA_offset },
412     { "cfi_rel_offset", dot_cfi, CFI_rel_offset },
413     { "cfi_register", dot_cfi, DW_CFA_register },
414     { "cfi_return_column", dot_cfi, CFI_return_column },
415     { "cfi_restore", dot_cfi, DW_CFA_restore },
416     { "cfi_undefined", dot_cfi, DW_CFA_undefined },
417     { "cfi_same_value", dot_cfi, DW_CFA_same_value },
418     { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
419     { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
420     { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
421     { "cfi_escape", dot_cfi_escape, 0 },
422     { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
423     { "cfi_personality", dot_cfi_personality, 0 },
424     { "cfi_lsda", dot_cfi_lsda, 0 },
425     { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
426     { NULL, NULL, 0 }
427   };
428
429 static void
430 cfi_parse_separator (void)
431 {
432   SKIP_WHITESPACE ();
433   if (*input_line_pointer == ',')
434     input_line_pointer++;
435   else
436     as_bad (_("missing separator"));
437 }
438
439 #ifndef tc_parse_to_dw2regnum
440 static void
441 tc_parse_to_dw2regnum(expressionS *exp)
442 {
443 # ifdef tc_regname_to_dw2regnum
444   SKIP_WHITESPACE ();
445   if (is_name_beginner (*input_line_pointer)
446       || (*input_line_pointer == '%'
447           && is_name_beginner (*++input_line_pointer)))
448     {
449       char *name, c;
450
451       name = input_line_pointer;
452       c = get_symbol_end ();
453
454       exp->X_op = O_constant;
455       exp->X_add_number = tc_regname_to_dw2regnum (name);
456
457       *input_line_pointer = c;
458     }
459   else
460 # endif
461     expression_and_evaluate (exp);
462 }
463 #endif
464
465 static unsigned
466 cfi_parse_reg (void)
467 {
468   int regno;
469   expressionS exp;
470
471   tc_parse_to_dw2regnum (&exp);
472   switch (exp.X_op)
473     {
474     case O_register:
475     case O_constant:
476       regno = exp.X_add_number;
477       break;
478
479     default:
480       regno = -1;
481       break;
482     }
483
484   if (regno < 0)
485     {
486       as_bad (_("bad register expression"));
487       regno = 0;
488     }
489
490   return regno;
491 }
492
493 static offsetT
494 cfi_parse_const (void)
495 {
496   return get_absolute_expression ();
497 }
498
499 static void
500 dot_cfi (int arg)
501 {
502   offsetT offset;
503   unsigned reg1, reg2;
504
505   if (frchain_now->frch_cfi_data == NULL)
506     {
507       as_bad (_("CFI instruction used without previous .cfi_startproc"));
508       ignore_rest_of_line ();
509       return;
510     }
511
512   /* If the last address was not at the current PC, advance to current.  */
513   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
514       || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
515          != frag_now_fix ())
516     cfi_add_advance_loc (symbol_temp_new_now ());
517
518   switch (arg)
519     {
520     case DW_CFA_offset:
521       reg1 = cfi_parse_reg ();
522       cfi_parse_separator ();
523       offset = cfi_parse_const ();
524       cfi_add_CFA_offset (reg1, offset);
525       break;
526
527     case CFI_rel_offset:
528       reg1 = cfi_parse_reg ();
529       cfi_parse_separator ();
530       offset = cfi_parse_const ();
531       cfi_add_CFA_offset (reg1,
532                           offset - frchain_now->frch_cfi_data->cur_cfa_offset);
533       break;
534
535     case DW_CFA_def_cfa:
536       reg1 = cfi_parse_reg ();
537       cfi_parse_separator ();
538       offset = cfi_parse_const ();
539       cfi_add_CFA_def_cfa (reg1, offset);
540       break;
541
542     case DW_CFA_register:
543       reg1 = cfi_parse_reg ();
544       cfi_parse_separator ();
545       reg2 = cfi_parse_reg ();
546       cfi_add_CFA_register (reg1, reg2);
547       break;
548
549     case DW_CFA_def_cfa_register:
550       reg1 = cfi_parse_reg ();
551       cfi_add_CFA_def_cfa_register (reg1);
552       break;
553
554     case DW_CFA_def_cfa_offset:
555       offset = cfi_parse_const ();
556       cfi_add_CFA_def_cfa_offset (offset);
557       break;
558
559     case CFI_adjust_cfa_offset:
560       offset = cfi_parse_const ();
561       cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
562                                   + offset);
563       break;
564
565     case DW_CFA_restore:
566       for (;;)
567         {
568           reg1 = cfi_parse_reg ();
569           cfi_add_CFA_restore (reg1);
570           SKIP_WHITESPACE ();
571           if (*input_line_pointer != ',')
572             break;
573           ++input_line_pointer;
574         }
575       break;
576
577     case DW_CFA_undefined:
578       for (;;)
579         {
580           reg1 = cfi_parse_reg ();
581           cfi_add_CFA_undefined (reg1);
582           SKIP_WHITESPACE ();
583           if (*input_line_pointer != ',')
584             break;
585           ++input_line_pointer;
586         }
587       break;
588
589     case DW_CFA_same_value:
590       reg1 = cfi_parse_reg ();
591       cfi_add_CFA_same_value (reg1);
592       break;
593
594     case CFI_return_column:
595       reg1 = cfi_parse_reg ();
596       cfi_set_return_column (reg1);
597       break;
598
599     case DW_CFA_remember_state:
600       cfi_add_CFA_remember_state ();
601       break;
602
603     case DW_CFA_restore_state:
604       cfi_add_CFA_restore_state ();
605       break;
606
607     case DW_CFA_GNU_window_save:
608       cfi_add_CFA_insn (DW_CFA_GNU_window_save);
609       break;
610
611     case CFI_signal_frame:
612       frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
613       break;
614
615     default:
616       abort ();
617     }
618
619   demand_empty_rest_of_line ();
620 }
621
622 static void
623 dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
624 {
625   struct cfi_escape_data *head, **tail, *e;
626   struct cfi_insn_data *insn;
627
628   if (frchain_now->frch_cfi_data == NULL)
629     {
630       as_bad (_("CFI instruction used without previous .cfi_startproc"));
631       ignore_rest_of_line ();
632       return;
633     }
634
635   /* If the last address was not at the current PC, advance to current.  */
636   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
637       || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
638          != frag_now_fix ())
639     cfi_add_advance_loc (symbol_temp_new_now ());
640
641   tail = &head;
642   do
643     {
644       e = (struct cfi_escape_data *) xmalloc (sizeof (*e));
645       do_parse_cons_expression (&e->exp, 1);
646       *tail = e;
647       tail = &e->next;
648     }
649   while (*input_line_pointer++ == ',');
650   *tail = NULL;
651
652   insn = alloc_cfi_insn_data ();
653   insn->insn = CFI_escape;
654   insn->u.esc = head;
655
656   --input_line_pointer;
657   demand_empty_rest_of_line ();
658 }
659
660 static void
661 dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
662 {
663   struct fde_entry *fde;
664   offsetT encoding;
665
666   if (frchain_now->frch_cfi_data == NULL)
667     {
668       as_bad (_("CFI instruction used without previous .cfi_startproc"));
669       ignore_rest_of_line ();
670       return;
671     }
672
673   fde = frchain_now->frch_cfi_data->cur_fde_data;
674   encoding = cfi_parse_const ();
675   if (encoding == DW_EH_PE_omit)
676     {
677       demand_empty_rest_of_line ();
678       fde->per_encoding = encoding;
679       return;
680     }
681
682   if ((encoding & 0xff) != encoding
683       || ((encoding & 0x70) != 0
684 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
685           && (encoding & 0x70) != DW_EH_PE_pcrel
686 #endif
687           )
688          /* leb128 can be handled, but does something actually need it?  */
689       || (encoding & 7) == DW_EH_PE_uleb128
690       || (encoding & 7) > DW_EH_PE_udata8)
691     {
692       as_bad (_("invalid or unsupported encoding in .cfi_personality"));
693       ignore_rest_of_line ();
694       return;
695     }
696
697   if (*input_line_pointer++ != ',')
698     {
699       as_bad (_(".cfi_personality requires encoding and symbol arguments"));
700       ignore_rest_of_line ();
701       return;
702     }
703
704   expression_and_evaluate (&fde->personality);
705   switch (fde->personality.X_op)
706     {
707     case O_symbol:
708       break;
709     case O_constant:
710       if ((encoding & 0x70) == DW_EH_PE_pcrel)
711         encoding = DW_EH_PE_omit;
712       break;
713     default:
714       encoding = DW_EH_PE_omit;
715       break;
716     }
717
718   fde->per_encoding = encoding;
719
720   if (encoding == DW_EH_PE_omit)
721     {
722       as_bad (_("wrong second argument to .cfi_personality"));
723       ignore_rest_of_line ();
724       return;
725     }
726
727   demand_empty_rest_of_line ();
728 }
729
730 static void
731 dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
732 {
733   struct fde_entry *fde;
734   offsetT encoding;
735
736   if (frchain_now->frch_cfi_data == NULL)
737     {
738       as_bad (_("CFI instruction used without previous .cfi_startproc"));
739       ignore_rest_of_line ();
740       return;
741     }
742
743   fde = frchain_now->frch_cfi_data->cur_fde_data;
744   encoding = cfi_parse_const ();
745   if (encoding == DW_EH_PE_omit)
746     {
747       demand_empty_rest_of_line ();
748       fde->lsda_encoding = encoding;
749       return;
750     }
751
752   if ((encoding & 0xff) != encoding
753       || ((encoding & 0x70) != 0
754 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
755           && (encoding & 0x70) != DW_EH_PE_pcrel
756 #endif
757           )
758          /* leb128 can be handled, but does something actually need it?  */
759       || (encoding & 7) == DW_EH_PE_uleb128
760       || (encoding & 7) > DW_EH_PE_udata8)
761     {
762       as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
763       ignore_rest_of_line ();
764       return;
765     }
766
767   if (*input_line_pointer++ != ',')
768     {
769       as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
770       ignore_rest_of_line ();
771       return;
772     }
773
774   fde->lsda_encoding = encoding;
775
776   expression_and_evaluate (&fde->lsda);
777   switch (fde->lsda.X_op)
778     {
779     case O_symbol:
780       break;
781     case O_constant:
782       if ((encoding & 0x70) == DW_EH_PE_pcrel)
783         encoding = DW_EH_PE_omit;
784       break;
785     default:
786       encoding = DW_EH_PE_omit;
787       break;
788     }
789
790   fde->lsda_encoding = encoding;
791
792   if (encoding == DW_EH_PE_omit)
793     {
794       as_bad (_("wrong second argument to .cfi_lsda"));
795       ignore_rest_of_line ();
796       return;
797     }
798
799   demand_empty_rest_of_line ();
800 }
801
802 static void
803 dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
804 {
805   struct cfi_insn_data *insn_ptr;
806   offsetT encoding;
807
808   if (frchain_now->frch_cfi_data == NULL)
809     {
810       as_bad (_("CFI instruction used without previous .cfi_startproc"));
811       ignore_rest_of_line ();
812       return;
813     }
814
815   /* If the last address was not at the current PC, advance to current.  */
816   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
817       || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
818          != frag_now_fix ())
819     cfi_add_advance_loc (symbol_temp_new_now ());
820
821   insn_ptr = alloc_cfi_insn_data ();
822   insn_ptr->insn = CFI_val_encoded_addr;
823   
824   insn_ptr->u.ea.reg = cfi_parse_reg ();
825
826   cfi_parse_separator ();
827   encoding = cfi_parse_const ();
828   if ((encoding & 0xff) != encoding
829       || ((encoding & 0x70) != 0
830 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
831           && (encoding & 0x70) != DW_EH_PE_pcrel
832 #endif
833           )
834          /* leb128 can be handled, but does something actually need it?  */
835       || (encoding & 7) == DW_EH_PE_uleb128
836       || (encoding & 7) > DW_EH_PE_udata8)
837     {
838       as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
839       encoding = DW_EH_PE_omit;
840     }
841
842   cfi_parse_separator ();
843   expression_and_evaluate (&insn_ptr->u.ea.exp);
844   switch (insn_ptr->u.ea.exp.X_op)
845     {
846     case O_symbol:
847       break;
848     case O_constant:
849       if ((encoding & 0x70) != DW_EH_PE_pcrel)
850         break;
851     default:
852       encoding = DW_EH_PE_omit;
853       break;
854     }
855
856   insn_ptr->u.ea.encoding = encoding;
857   if (encoding == DW_EH_PE_omit)
858     {
859       as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
860       ignore_rest_of_line ();
861       return;
862     }
863
864   demand_empty_rest_of_line ();
865 }
866
867 static void
868 dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
869 {
870   int simple = 0;
871
872   if (frchain_now->frch_cfi_data != NULL)
873     {
874       as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
875       ignore_rest_of_line ();
876       return;
877     }
878
879   cfi_new_fde (symbol_temp_new_now ());
880
881   SKIP_WHITESPACE ();
882   if (is_name_beginner (*input_line_pointer))
883     {
884       char *name, c;
885
886       name = input_line_pointer;
887       c = get_symbol_end ();
888
889       if (strcmp (name, "simple") == 0)
890         {
891           simple = 1;
892           *input_line_pointer = c;
893         }
894       else
895         input_line_pointer = name;
896     }
897   demand_empty_rest_of_line ();
898
899   frchain_now->frch_cfi_data->cur_cfa_offset = 0;
900   if (!simple)
901     tc_cfi_frame_initial_instructions ();
902 }
903
904 static void
905 dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
906 {
907   if (frchain_now->frch_cfi_data == NULL)
908     {
909       as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
910       ignore_rest_of_line ();
911       return;
912     }
913
914   cfi_end_fde (symbol_temp_new_now ());
915
916   demand_empty_rest_of_line ();
917 }
918
919 \f
920 /* Emit a single byte into the current segment.  */
921
922 static inline void
923 out_one (int byte)
924 {
925   FRAG_APPEND_1_CHAR (byte);
926 }
927
928 /* Emit a two-byte word into the current segment.  */
929
930 static inline void
931 out_two (int data)
932 {
933   md_number_to_chars (frag_more (2), data, 2);
934 }
935
936 /* Emit a four byte word into the current segment.  */
937
938 static inline void
939 out_four (int data)
940 {
941   md_number_to_chars (frag_more (4), data, 4);
942 }
943
944 /* Emit an unsigned "little-endian base 128" number.  */
945
946 static void
947 out_uleb128 (addressT value)
948 {
949   output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
950 }
951
952 /* Emit an unsigned "little-endian base 128" number.  */
953
954 static void
955 out_sleb128 (offsetT value)
956 {
957   output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
958 }
959
960 static void
961 output_cfi_insn (struct cfi_insn_data *insn)
962 {
963   offsetT offset;
964   unsigned int regno;
965
966   switch (insn->insn)
967     {
968     case DW_CFA_advance_loc:
969       {
970         symbolS *from = insn->u.ll.lab1;
971         symbolS *to = insn->u.ll.lab2;
972
973         if (symbol_get_frag (to) == symbol_get_frag (from))
974           {
975             addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
976             addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
977
978             if (scaled <= 0x3F)
979               out_one (DW_CFA_advance_loc + scaled);
980             else if (scaled <= 0xFF)
981               {
982                 out_one (DW_CFA_advance_loc1);
983                 out_one (scaled);
984               }
985             else if (scaled <= 0xFFFF)
986               {
987                 out_one (DW_CFA_advance_loc2);
988                 out_two (scaled);
989               }
990             else
991               {
992                 out_one (DW_CFA_advance_loc4);
993                 out_four (scaled);
994               }
995           }
996         else
997           {
998             expressionS exp;
999
1000             exp.X_op = O_subtract;
1001             exp.X_add_symbol = to;
1002             exp.X_op_symbol = from;
1003             exp.X_add_number = 0;
1004
1005             /* The code in ehopt.c expects that one byte of the encoding
1006                is already allocated to the frag.  This comes from the way
1007                that it scans the .eh_frame section looking first for the
1008                .byte DW_CFA_advance_loc4.  */
1009             *frag_more (1) = DW_CFA_advance_loc4;
1010
1011             frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1012                       make_expr_symbol (&exp), frag_now_fix () - 1,
1013                       (char *) frag_now);
1014           }
1015       }
1016       break;
1017
1018     case DW_CFA_def_cfa:
1019       offset = insn->u.ri.offset;
1020       if (offset < 0)
1021         {
1022           out_one (DW_CFA_def_cfa_sf);
1023           out_uleb128 (insn->u.ri.reg);
1024           out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1025         }
1026       else
1027         {
1028           out_one (DW_CFA_def_cfa);
1029           out_uleb128 (insn->u.ri.reg);
1030           out_uleb128 (offset);
1031         }
1032       break;
1033
1034     case DW_CFA_def_cfa_register:
1035     case DW_CFA_undefined:
1036     case DW_CFA_same_value:
1037       out_one (insn->insn);
1038       out_uleb128 (insn->u.r);
1039       break;
1040
1041     case DW_CFA_def_cfa_offset:
1042       offset = insn->u.i;
1043       if (offset < 0)
1044         {
1045           out_one (DW_CFA_def_cfa_offset_sf);
1046           out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1047         }
1048       else
1049         {
1050           out_one (DW_CFA_def_cfa_offset);
1051           out_uleb128 (offset);
1052         }
1053       break;
1054
1055     case DW_CFA_restore:
1056       regno = insn->u.r;
1057       if (regno <= 0x3F)
1058         {
1059           out_one (DW_CFA_restore + regno);
1060         }
1061       else
1062         {
1063           out_one (DW_CFA_restore_extended);
1064           out_uleb128 (regno);
1065         }
1066       break;
1067
1068     case DW_CFA_offset:
1069       regno = insn->u.ri.reg;
1070       offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1071       if (offset < 0)
1072         {
1073           out_one (DW_CFA_offset_extended_sf);
1074           out_uleb128 (regno);
1075           out_sleb128 (offset);
1076         }
1077       else if (regno <= 0x3F)
1078         {
1079           out_one (DW_CFA_offset + regno);
1080           out_uleb128 (offset);
1081         }
1082       else
1083         {
1084           out_one (DW_CFA_offset_extended);
1085           out_uleb128 (regno);
1086           out_uleb128 (offset);
1087         }
1088       break;
1089
1090     case DW_CFA_register:
1091       out_one (DW_CFA_register);
1092       out_uleb128 (insn->u.rr.reg1);
1093       out_uleb128 (insn->u.rr.reg2);
1094       break;
1095
1096     case DW_CFA_remember_state:
1097     case DW_CFA_restore_state:
1098       out_one (insn->insn);
1099       break;
1100
1101     case DW_CFA_GNU_window_save:
1102       out_one (DW_CFA_GNU_window_save);
1103       break;
1104
1105     case CFI_escape:
1106       {
1107         struct cfi_escape_data *e;
1108         for (e = insn->u.esc; e ; e = e->next)
1109           emit_expr (&e->exp, 1);
1110         break;
1111       }
1112
1113     case CFI_val_encoded_addr:
1114       {
1115         unsigned encoding = insn->u.ea.encoding;
1116         offsetT encoding_size;
1117
1118         if (encoding == DW_EH_PE_omit)
1119           break;
1120         out_one (DW_CFA_val_expression);
1121         out_uleb128 (insn->u.ea.reg);
1122
1123         switch (encoding & 0x7)
1124           {
1125           case DW_EH_PE_absptr:
1126             encoding_size = DWARF2_ADDR_SIZE (stdoutput);
1127             break;
1128           case DW_EH_PE_udata2:
1129             encoding_size = 2;
1130             break;
1131           case DW_EH_PE_udata4:
1132             encoding_size = 4;
1133             break;
1134           case DW_EH_PE_udata8:
1135             encoding_size = 8;
1136             break;
1137           default:
1138             abort ();
1139           }
1140
1141         /* If the user has requested absolute encoding,
1142            then use the smaller DW_OP_addr encoding.  */
1143         if (insn->u.ea.encoding == DW_EH_PE_absptr)
1144           {
1145             out_uleb128 (1 + encoding_size);
1146             out_one (DW_OP_addr);
1147           }
1148         else
1149           {
1150             out_uleb128 (1 + 1 + encoding_size);
1151             out_one (DW_OP_GNU_encoded_addr);
1152             out_one (encoding);
1153
1154             if ((encoding & 0x70) == DW_EH_PE_pcrel)
1155               {
1156 #if CFI_DIFF_EXPR_OK
1157                 insn->u.ea.exp.X_op = O_subtract;
1158                 insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1159 #elif defined (tc_cfi_emit_pcrel_expr)
1160                 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, encoding_size);
1161                 break;
1162 #else
1163                 abort ();
1164 #endif
1165               }
1166           }
1167         emit_expr (&insn->u.ea.exp, encoding_size);
1168       }
1169       break;
1170       
1171     default:
1172       abort ();
1173     }
1174 }
1175
1176 static offsetT
1177 encoding_size (unsigned char encoding)
1178 {
1179   if (encoding == DW_EH_PE_omit)
1180     return 0;
1181   switch (encoding & 0x7)
1182     {
1183     case 0:
1184       return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
1185     case DW_EH_PE_udata2:
1186       return 2;
1187     case DW_EH_PE_udata4:
1188       return 4;
1189     case DW_EH_PE_udata8:
1190       return 8;
1191     default:
1192       abort ();
1193     }
1194 }
1195
1196 static void
1197 output_cie (struct cie_entry *cie)
1198 {
1199   symbolS *after_size_address, *end_address;
1200   expressionS exp;
1201   struct cfi_insn_data *i;
1202   offsetT augmentation_size;
1203   int enc;
1204
1205   cie->start_address = symbol_temp_new_now ();
1206   after_size_address = symbol_temp_make ();
1207   end_address = symbol_temp_make ();
1208
1209   exp.X_op = O_subtract;
1210   exp.X_add_symbol = end_address;
1211   exp.X_op_symbol = after_size_address;
1212   exp.X_add_number = 0;
1213
1214   emit_expr (&exp, 4);                          /* Length.  */
1215   symbol_set_value_now (after_size_address);
1216   out_four (0);                                 /* CIE id.  */
1217   out_one (DW_CIE_VERSION);                     /* Version.  */
1218   out_one ('z');                                /* Augmentation.  */
1219   if (cie->per_encoding != DW_EH_PE_omit)
1220     out_one ('P');
1221   if (cie->lsda_encoding != DW_EH_PE_omit)
1222     out_one ('L');
1223   out_one ('R');
1224   if (cie->signal_frame)
1225     out_one ('S');
1226   out_one (0);
1227   out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH);    /* Code alignment.  */
1228   out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT);      /* Data alignment.  */
1229   if (DW_CIE_VERSION == 1)                      /* Return column.  */
1230     out_one (cie->return_column);
1231   else
1232     out_uleb128 (cie->return_column);
1233   augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1234   if (cie->per_encoding != DW_EH_PE_omit)
1235     augmentation_size += 1 + encoding_size (cie->per_encoding);
1236   out_uleb128 (augmentation_size);              /* Augmentation size.  */
1237   if (cie->per_encoding != DW_EH_PE_omit)
1238     {
1239       offsetT size = encoding_size (cie->per_encoding);
1240       out_one (cie->per_encoding);
1241       exp = cie->personality;
1242       if ((cie->per_encoding & 0x70) == DW_EH_PE_pcrel)
1243         {
1244 #if CFI_DIFF_EXPR_OK
1245           exp.X_op = O_subtract;
1246           exp.X_op_symbol = symbol_temp_new_now ();
1247           emit_expr (&exp, size);
1248 #elif defined (tc_cfi_emit_pcrel_expr)
1249           tc_cfi_emit_pcrel_expr (&exp, size);
1250 #else
1251           abort ();
1252 #endif
1253         }
1254       else
1255         emit_expr (&exp, size);
1256     }
1257   if (cie->lsda_encoding != DW_EH_PE_omit)
1258     out_one (cie->lsda_encoding);
1259
1260   switch (DWARF2_FDE_RELOC_SIZE)
1261     {
1262     case 2:
1263       enc = DW_EH_PE_sdata2;
1264       break;
1265     case 4:
1266       enc = DW_EH_PE_sdata4;
1267       break;
1268     case 8:
1269       enc = DW_EH_PE_sdata8;
1270       break;
1271     default:
1272       abort ();
1273     }
1274 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1275   enc |= DW_EH_PE_pcrel;
1276 #endif
1277   out_one (enc);
1278
1279   if (cie->first)
1280     for (i = cie->first; i != cie->last; i = i->next)
1281       output_cfi_insn (i);
1282
1283   frag_align (2, DW_CFA_nop, 0);
1284   symbol_set_value_now (end_address);
1285 }
1286
1287 static void
1288 output_fde (struct fde_entry *fde, struct cie_entry *cie,
1289             struct cfi_insn_data *first, int align)
1290 {
1291   symbolS *after_size_address, *end_address;
1292   expressionS exp;
1293   offsetT augmentation_size;
1294
1295   after_size_address = symbol_temp_make ();
1296   end_address = symbol_temp_make ();
1297
1298   exp.X_op = O_subtract;
1299   exp.X_add_symbol = end_address;
1300   exp.X_op_symbol = after_size_address;
1301   exp.X_add_number = 0;
1302   emit_expr (&exp, 4);                          /* Length.  */
1303   symbol_set_value_now (after_size_address);
1304
1305   exp.X_add_symbol = after_size_address;
1306   exp.X_op_symbol = cie->start_address;
1307   emit_expr (&exp, 4);                          /* CIE offset.  */
1308
1309 #if CFI_DIFF_EXPR_OK
1310   exp.X_add_symbol = fde->start_address;
1311   exp.X_op_symbol = symbol_temp_new_now ();
1312   emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);      /* Code offset.  */
1313 #else
1314   exp.X_op = O_symbol;
1315   exp.X_add_symbol = fde->start_address;
1316   exp.X_op_symbol = NULL;
1317 #ifdef tc_cfi_emit_pcrel_expr
1318   tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE);  /* Code offset.  */
1319 #else
1320   emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);      /* Code offset.  */
1321 #endif
1322   exp.X_op = O_subtract;
1323 #endif
1324
1325   exp.X_add_symbol = fde->end_address;
1326   exp.X_op_symbol = fde->start_address;         /* Code length.  */
1327   emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);
1328
1329   augmentation_size = encoding_size (fde->lsda_encoding);
1330   out_uleb128 (augmentation_size);              /* Augmentation size.  */
1331
1332   if (fde->lsda_encoding != DW_EH_PE_omit)
1333     {
1334       exp = fde->lsda;
1335       if ((fde->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
1336         {
1337 #if CFI_DIFF_EXPR_OK
1338           exp.X_op = O_subtract;
1339           exp.X_op_symbol = symbol_temp_new_now ();
1340           emit_expr (&exp, augmentation_size);
1341 #elif defined (tc_cfi_emit_pcrel_expr)
1342           tc_cfi_emit_pcrel_expr (&exp, augmentation_size);
1343 #else
1344           abort ();
1345 #endif
1346         }
1347       else
1348         emit_expr (&exp, augmentation_size);
1349     }
1350
1351   for (; first; first = first->next)
1352     output_cfi_insn (first);
1353
1354   frag_align (align, DW_CFA_nop, 0);
1355   symbol_set_value_now (end_address);
1356 }
1357
1358 static struct cie_entry *
1359 select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst)
1360 {
1361   struct cfi_insn_data *i, *j;
1362   struct cie_entry *cie;
1363
1364   for (cie = cie_root; cie; cie = cie->next)
1365     {
1366       if (cie->return_column != fde->return_column
1367           || cie->signal_frame != fde->signal_frame
1368           || cie->per_encoding != fde->per_encoding
1369           || cie->lsda_encoding != fde->lsda_encoding)
1370         continue;
1371       if (cie->per_encoding != DW_EH_PE_omit)
1372         {
1373           if (cie->personality.X_op != fde->personality.X_op
1374               || cie->personality.X_add_number
1375                  != fde->personality.X_add_number)
1376             continue;
1377           switch (cie->personality.X_op)
1378             {
1379             case O_constant:
1380               if (cie->personality.X_unsigned != fde->personality.X_unsigned)
1381                 continue;
1382               break;
1383             case O_symbol:
1384               if (cie->personality.X_add_symbol
1385                   != fde->personality.X_add_symbol)
1386                 continue;
1387               break;
1388             default:
1389               abort ();
1390             }
1391         }
1392       for (i = cie->first, j = fde->data;
1393            i != cie->last && j != NULL;
1394            i = i->next, j = j->next)
1395         {
1396           if (i->insn != j->insn)
1397             goto fail;
1398           switch (i->insn)
1399             {
1400             case DW_CFA_advance_loc:
1401             case DW_CFA_remember_state:
1402               /* We reached the first advance/remember in the FDE,
1403                  but did not reach the end of the CIE list.  */
1404               goto fail;
1405
1406             case DW_CFA_offset:
1407             case DW_CFA_def_cfa:
1408               if (i->u.ri.reg != j->u.ri.reg)
1409                 goto fail;
1410               if (i->u.ri.offset != j->u.ri.offset)
1411                 goto fail;
1412               break;
1413
1414             case DW_CFA_register:
1415               if (i->u.rr.reg1 != j->u.rr.reg1)
1416                 goto fail;
1417               if (i->u.rr.reg2 != j->u.rr.reg2)
1418                 goto fail;
1419               break;
1420
1421             case DW_CFA_def_cfa_register:
1422             case DW_CFA_restore:
1423             case DW_CFA_undefined:
1424             case DW_CFA_same_value:
1425               if (i->u.r != j->u.r)
1426                 goto fail;
1427               break;
1428
1429             case DW_CFA_def_cfa_offset:
1430               if (i->u.i != j->u.i)
1431                 goto fail;
1432               break;
1433
1434             case CFI_escape:
1435             case CFI_val_encoded_addr:
1436               /* Don't bother matching these for now.  */
1437               goto fail;
1438
1439             default:
1440               abort ();
1441             }
1442         }
1443
1444       /* Success if we reached the end of the CIE list, and we've either
1445          run out of FDE entries or we've encountered an advance,
1446          remember, or escape.  */
1447       if (i == cie->last
1448           && (!j
1449               || j->insn == DW_CFA_advance_loc
1450               || j->insn == DW_CFA_remember_state
1451               || j->insn == CFI_escape
1452               || j->insn == CFI_val_encoded_addr))
1453         {
1454           *pfirst = j;
1455           return cie;
1456         }
1457
1458     fail:;
1459     }
1460
1461   cie = (struct cie_entry *) xmalloc (sizeof (struct cie_entry));
1462   cie->next = cie_root;
1463   cie_root = cie;
1464   cie->return_column = fde->return_column;
1465   cie->signal_frame = fde->signal_frame;
1466   cie->per_encoding = fde->per_encoding;
1467   cie->lsda_encoding = fde->lsda_encoding;
1468   cie->personality = fde->personality;
1469   cie->first = fde->data;
1470
1471   for (i = cie->first; i ; i = i->next)
1472     if (i->insn == DW_CFA_advance_loc
1473         || i->insn == DW_CFA_remember_state
1474         || i->insn == CFI_escape
1475         || i->insn == CFI_val_encoded_addr)
1476       break;
1477
1478   cie->last = i;
1479   *pfirst = i;
1480    
1481   output_cie (cie);
1482
1483   return cie;
1484 }
1485
1486 void
1487 cfi_finish (void)
1488 {
1489   segT cfi_seg;
1490   struct fde_entry *fde;
1491   int save_flag_traditional_format;
1492
1493   if (all_fde_data == 0)
1494     return;
1495
1496   /* Open .eh_frame section.  */
1497   cfi_seg = subseg_new (".eh_frame", 0);
1498   bfd_set_section_flags (stdoutput, cfi_seg,
1499                          SEC_ALLOC | SEC_LOAD | SEC_DATA
1500                          | DWARF2_EH_FRAME_READ_ONLY);
1501   subseg_set (cfi_seg, 0);
1502   record_alignment (cfi_seg, EH_FRAME_ALIGNMENT);
1503
1504 #ifdef md_fix_up_eh_frame
1505   md_fix_up_eh_frame (cfi_seg);
1506 #endif
1507
1508   /* Make sure check_eh_frame doesn't do anything with our output.  */
1509   save_flag_traditional_format = flag_traditional_format;
1510   flag_traditional_format = 1;
1511
1512   for (fde = all_fde_data; fde ; fde = fde->next)
1513     {
1514       struct cfi_insn_data *first;
1515       struct cie_entry *cie;
1516
1517       if (fde->end_address == NULL)
1518         {
1519           as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
1520           fde->end_address = fde->start_address;
1521         }
1522
1523       cie = select_cie_for_fde (fde, &first);
1524       output_fde (fde, cie, first, fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
1525     }
1526
1527   flag_traditional_format = save_flag_traditional_format;
1528 }
1529
1530 #else /* TARGET_USE_CFIPOP */
1531 void
1532 cfi_finish (void)
1533 {
1534 }
1535 #endif /* TARGET_USE_CFIPOP */