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