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