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>
5 This file is part of GAS, the GNU Assembler.
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)
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.
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
23 #include "dw2gencfi.h"
26 #ifdef TARGET_USE_CFIPOP
28 /* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
29 of the CIE. Default to 1 if not otherwise specified. */
30 #ifndef DWARF2_LINE_MIN_INSN_LENGTH
31 # define DWARF2_LINE_MIN_INSN_LENGTH 1
34 #ifndef EH_FRAME_ALIGNMENT
35 # define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
38 #ifndef tc_cfi_frame_initial_instructions
39 # define tc_cfi_frame_initial_instructions() ((void)0)
45 struct cfi_insn_data
*next
;
66 struct cfi_escape_data
{
67 struct cfi_escape_data
*next
;
75 struct fde_entry
*next
;
76 symbolS
*start_address
;
78 struct cfi_insn_data
*data
;
79 struct cfi_insn_data
**last
;
80 unsigned char per_encoding
;
81 unsigned char lsda_encoding
;
82 expressionS personality
;
84 unsigned int return_column
;
85 unsigned int signal_frame
;
90 struct cie_entry
*next
;
91 symbolS
*start_address
;
92 unsigned int return_column
;
93 unsigned int signal_frame
;
94 unsigned char per_encoding
;
95 unsigned char lsda_encoding
;
96 expressionS personality
;
97 struct cfi_insn_data
*first
, *last
;
101 /* List of FDE entries. */
102 static struct fde_entry
*all_fde_data
;
103 static struct fde_entry
**last_fde_data
= &all_fde_data
;
105 /* List of CIEs so that they could be reused. */
106 static struct cie_entry
*cie_root
;
108 /* Stack of old CFI data, for save/restore. */
111 struct cfa_save_data
*next
;
115 /* Current open FDE entry. */
118 struct fde_entry
*cur_fde_data
;
119 symbolS
*last_address
;
120 offsetT cur_cfa_offset
;
121 struct cfa_save_data
*cfa_save_stack
;
124 /* Construct a new FDE structure and add it to the end of the fde list. */
126 static struct fde_entry
*
127 alloc_fde_entry (void)
129 struct fde_entry
*fde
= xcalloc (1, sizeof (struct fde_entry
));
131 frchain_now
->frch_cfi_data
= xcalloc (1, sizeof (struct frch_cfi_data
));
132 frchain_now
->frch_cfi_data
->cur_fde_data
= fde
;
133 *last_fde_data
= fde
;
134 last_fde_data
= &fde
->next
;
136 fde
->last
= &fde
->data
;
137 fde
->return_column
= DWARF2_DEFAULT_RETURN_COLUMN
;
138 fde
->per_encoding
= DW_EH_PE_omit
;
139 fde
->lsda_encoding
= DW_EH_PE_omit
;
144 /* The following functions are available for a backend to construct its
145 own unwind information, usually from legacy unwind directives. */
147 /* Construct a new INSN structure and add it to the end of the insn list
148 for the currently active FDE. */
150 static struct cfi_insn_data
*
151 alloc_cfi_insn_data (void)
153 struct cfi_insn_data
*insn
= xcalloc (1, sizeof (struct cfi_insn_data
));
154 struct fde_entry
*cur_fde_data
= frchain_now
->frch_cfi_data
->cur_fde_data
;
156 *cur_fde_data
->last
= insn
;
157 cur_fde_data
->last
= &insn
->next
;
162 /* Construct a new FDE structure that begins at LABEL. */
165 cfi_new_fde (symbolS
*label
)
167 struct fde_entry
*fde
= alloc_fde_entry ();
168 fde
->start_address
= label
;
169 frchain_now
->frch_cfi_data
->last_address
= label
;
172 /* End the currently open FDE. */
175 cfi_end_fde (symbolS
*label
)
177 frchain_now
->frch_cfi_data
->cur_fde_data
->end_address
= label
;
178 free (frchain_now
->frch_cfi_data
);
179 frchain_now
->frch_cfi_data
= NULL
;
182 /* Set the return column for the current FDE. */
185 cfi_set_return_column (unsigned regno
)
187 frchain_now
->frch_cfi_data
->cur_fde_data
->return_column
= regno
;
190 /* Universal functions to store new instructions. */
193 cfi_add_CFA_insn(int insn
)
195 struct cfi_insn_data
*insn_ptr
= alloc_cfi_insn_data ();
197 insn_ptr
->insn
= insn
;
201 cfi_add_CFA_insn_reg (int insn
, unsigned regno
)
203 struct cfi_insn_data
*insn_ptr
= alloc_cfi_insn_data ();
205 insn_ptr
->insn
= insn
;
206 insn_ptr
->u
.r
= regno
;
210 cfi_add_CFA_insn_offset (int insn
, offsetT offset
)
212 struct cfi_insn_data
*insn_ptr
= alloc_cfi_insn_data ();
214 insn_ptr
->insn
= insn
;
215 insn_ptr
->u
.i
= offset
;
219 cfi_add_CFA_insn_reg_reg (int insn
, unsigned reg1
, unsigned reg2
)
221 struct cfi_insn_data
*insn_ptr
= alloc_cfi_insn_data ();
223 insn_ptr
->insn
= insn
;
224 insn_ptr
->u
.rr
.reg1
= reg1
;
225 insn_ptr
->u
.rr
.reg2
= reg2
;
229 cfi_add_CFA_insn_reg_offset (int insn
, unsigned regno
, offsetT offset
)
231 struct cfi_insn_data
*insn_ptr
= alloc_cfi_insn_data ();
233 insn_ptr
->insn
= insn
;
234 insn_ptr
->u
.ri
.reg
= regno
;
235 insn_ptr
->u
.ri
.offset
= offset
;
238 /* Add a CFI insn to advance the PC from the last address to LABEL. */
241 cfi_add_advance_loc (symbolS
*label
)
243 struct cfi_insn_data
*insn
= alloc_cfi_insn_data ();
245 insn
->insn
= DW_CFA_advance_loc
;
246 insn
->u
.ll
.lab1
= frchain_now
->frch_cfi_data
->last_address
;
247 insn
->u
.ll
.lab2
= label
;
249 frchain_now
->frch_cfi_data
->last_address
= label
;
252 /* Add a DW_CFA_offset record to the CFI data. */
255 cfi_add_CFA_offset (unsigned regno
, offsetT offset
)
257 unsigned int abs_data_align
;
259 assert (DWARF2_CIE_DATA_ALIGNMENT
!= 0);
260 cfi_add_CFA_insn_reg_offset (DW_CFA_offset
, regno
, offset
);
262 abs_data_align
= (DWARF2_CIE_DATA_ALIGNMENT
< 0
263 ? -DWARF2_CIE_DATA_ALIGNMENT
: DWARF2_CIE_DATA_ALIGNMENT
);
264 if (offset
% abs_data_align
)
265 as_bad (_("register save offset not a multiple of %u"), abs_data_align
);
268 /* Add a DW_CFA_def_cfa record to the CFI data. */
271 cfi_add_CFA_def_cfa (unsigned regno
, offsetT offset
)
273 cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa
, regno
, offset
);
274 frchain_now
->frch_cfi_data
->cur_cfa_offset
= offset
;
277 /* Add a DW_CFA_register record to the CFI data. */
280 cfi_add_CFA_register (unsigned reg1
, unsigned reg2
)
282 cfi_add_CFA_insn_reg_reg (DW_CFA_register
, reg1
, reg2
);
285 /* Add a DW_CFA_def_cfa_register record to the CFI data. */
288 cfi_add_CFA_def_cfa_register (unsigned regno
)
290 cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register
, regno
);
293 /* Add a DW_CFA_def_cfa_offset record to the CFI data. */
296 cfi_add_CFA_def_cfa_offset (offsetT offset
)
298 cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset
, offset
);
299 frchain_now
->frch_cfi_data
->cur_cfa_offset
= offset
;
303 cfi_add_CFA_restore (unsigned regno
)
305 cfi_add_CFA_insn_reg (DW_CFA_restore
, regno
);
309 cfi_add_CFA_undefined (unsigned regno
)
311 cfi_add_CFA_insn_reg (DW_CFA_undefined
, regno
);
315 cfi_add_CFA_same_value (unsigned regno
)
317 cfi_add_CFA_insn_reg (DW_CFA_same_value
, regno
);
321 cfi_add_CFA_remember_state (void)
323 struct cfa_save_data
*p
;
325 cfi_add_CFA_insn (DW_CFA_remember_state
);
327 p
= xmalloc (sizeof (*p
));
328 p
->cfa_offset
= frchain_now
->frch_cfi_data
->cur_cfa_offset
;
329 p
->next
= frchain_now
->frch_cfi_data
->cfa_save_stack
;
330 frchain_now
->frch_cfi_data
->cfa_save_stack
= p
;
334 cfi_add_CFA_restore_state (void)
336 struct cfa_save_data
*p
;
338 cfi_add_CFA_insn (DW_CFA_restore_state
);
340 p
= frchain_now
->frch_cfi_data
->cfa_save_stack
;
343 frchain_now
->frch_cfi_data
->cur_cfa_offset
= p
->cfa_offset
;
344 frchain_now
->frch_cfi_data
->cfa_save_stack
= p
->next
;
348 as_bad (_("CFI state restore without previous remember"));
352 /* Parse CFI assembler directives. */
354 static void dot_cfi (int);
355 static void dot_cfi_escape (int);
356 static void dot_cfi_startproc (int);
357 static void dot_cfi_endproc (int);
358 static void dot_cfi_personality (int);
359 static void dot_cfi_lsda (int);
361 /* Fake CFI type; outside the byte range of any real CFI insn. */
362 #define CFI_adjust_cfa_offset 0x100
363 #define CFI_return_column 0x101
364 #define CFI_rel_offset 0x102
365 #define CFI_escape 0x103
366 #define CFI_signal_frame 0x104
368 const pseudo_typeS cfi_pseudo_table
[] =
370 { "cfi_startproc", dot_cfi_startproc
, 0 },
371 { "cfi_endproc", dot_cfi_endproc
, 0 },
372 { "cfi_def_cfa", dot_cfi
, DW_CFA_def_cfa
},
373 { "cfi_def_cfa_register", dot_cfi
, DW_CFA_def_cfa_register
},
374 { "cfi_def_cfa_offset", dot_cfi
, DW_CFA_def_cfa_offset
},
375 { "cfi_adjust_cfa_offset", dot_cfi
, CFI_adjust_cfa_offset
},
376 { "cfi_offset", dot_cfi
, DW_CFA_offset
},
377 { "cfi_rel_offset", dot_cfi
, CFI_rel_offset
},
378 { "cfi_register", dot_cfi
, DW_CFA_register
},
379 { "cfi_return_column", dot_cfi
, CFI_return_column
},
380 { "cfi_restore", dot_cfi
, DW_CFA_restore
},
381 { "cfi_undefined", dot_cfi
, DW_CFA_undefined
},
382 { "cfi_same_value", dot_cfi
, DW_CFA_same_value
},
383 { "cfi_remember_state", dot_cfi
, DW_CFA_remember_state
},
384 { "cfi_restore_state", dot_cfi
, DW_CFA_restore_state
},
385 { "cfi_window_save", dot_cfi
, DW_CFA_GNU_window_save
},
386 { "cfi_escape", dot_cfi_escape
, 0 },
387 { "cfi_signal_frame", dot_cfi
, CFI_signal_frame
},
388 { "cfi_personality", dot_cfi_personality
, 0 },
389 { "cfi_lsda", dot_cfi_lsda
, 0 },
394 cfi_parse_separator (void)
397 if (*input_line_pointer
== ',')
398 input_line_pointer
++;
400 as_bad (_("missing separator"));
409 #ifdef tc_regname_to_dw2regnum
411 if (is_name_beginner (*input_line_pointer
)
412 || (*input_line_pointer
== '%'
413 && is_name_beginner (*++input_line_pointer
)))
417 name
= input_line_pointer
;
418 c
= get_symbol_end ();
420 if ((regno
= tc_regname_to_dw2regnum (name
)) < 0)
422 as_bad (_("bad register expression"));
426 *input_line_pointer
= c
;
431 expression_and_evaluate (&exp
);
436 regno
= exp
.X_add_number
;
440 as_bad (_("bad register expression"));
449 cfi_parse_const (void)
451 return get_absolute_expression ();
460 if (frchain_now
->frch_cfi_data
== NULL
)
462 as_bad (_("CFI instruction used without previous .cfi_startproc"));
463 ignore_rest_of_line ();
467 /* If the last address was not at the current PC, advance to current. */
468 if (symbol_get_frag (frchain_now
->frch_cfi_data
->last_address
) != frag_now
469 || S_GET_VALUE (frchain_now
->frch_cfi_data
->last_address
)
471 cfi_add_advance_loc (symbol_temp_new_now ());
476 reg1
= cfi_parse_reg ();
477 cfi_parse_separator ();
478 offset
= cfi_parse_const ();
479 cfi_add_CFA_offset (reg1
, offset
);
483 reg1
= cfi_parse_reg ();
484 cfi_parse_separator ();
485 offset
= cfi_parse_const ();
486 cfi_add_CFA_offset (reg1
,
487 offset
- frchain_now
->frch_cfi_data
->cur_cfa_offset
);
491 reg1
= cfi_parse_reg ();
492 cfi_parse_separator ();
493 offset
= cfi_parse_const ();
494 cfi_add_CFA_def_cfa (reg1
, offset
);
497 case DW_CFA_register
:
498 reg1
= cfi_parse_reg ();
499 cfi_parse_separator ();
500 reg2
= cfi_parse_reg ();
501 cfi_add_CFA_register (reg1
, reg2
);
504 case DW_CFA_def_cfa_register
:
505 reg1
= cfi_parse_reg ();
506 cfi_add_CFA_def_cfa_register (reg1
);
509 case DW_CFA_def_cfa_offset
:
510 offset
= cfi_parse_const ();
511 cfi_add_CFA_def_cfa_offset (offset
);
514 case CFI_adjust_cfa_offset
:
515 offset
= cfi_parse_const ();
516 cfi_add_CFA_def_cfa_offset (frchain_now
->frch_cfi_data
->cur_cfa_offset
523 reg1
= cfi_parse_reg ();
524 cfi_add_CFA_restore (reg1
);
526 if (*input_line_pointer
!= ',')
528 ++input_line_pointer
;
532 case DW_CFA_undefined
:
535 reg1
= cfi_parse_reg ();
536 cfi_add_CFA_undefined (reg1
);
538 if (*input_line_pointer
!= ',')
540 ++input_line_pointer
;
544 case DW_CFA_same_value
:
545 reg1
= cfi_parse_reg ();
546 cfi_add_CFA_same_value (reg1
);
549 case CFI_return_column
:
550 reg1
= cfi_parse_reg ();
551 cfi_set_return_column (reg1
);
554 case DW_CFA_remember_state
:
555 cfi_add_CFA_remember_state ();
558 case DW_CFA_restore_state
:
559 cfi_add_CFA_restore_state ();
562 case DW_CFA_GNU_window_save
:
563 cfi_add_CFA_insn (DW_CFA_GNU_window_save
);
566 case CFI_signal_frame
:
567 frchain_now
->frch_cfi_data
->cur_fde_data
->signal_frame
= 1;
574 demand_empty_rest_of_line ();
578 dot_cfi_escape (int ignored ATTRIBUTE_UNUSED
)
580 struct cfi_escape_data
*head
, **tail
, *e
;
581 struct cfi_insn_data
*insn
;
583 if (frchain_now
->frch_cfi_data
== NULL
)
585 as_bad (_("CFI instruction used without previous .cfi_startproc"));
586 ignore_rest_of_line ();
590 /* If the last address was not at the current PC, advance to current. */
591 if (symbol_get_frag (frchain_now
->frch_cfi_data
->last_address
) != frag_now
592 || S_GET_VALUE (frchain_now
->frch_cfi_data
->last_address
)
594 cfi_add_advance_loc (symbol_temp_new_now ());
599 e
= xmalloc (sizeof (*e
));
600 do_parse_cons_expression (&e
->exp
, 1);
604 while (*input_line_pointer
++ == ',');
607 insn
= alloc_cfi_insn_data ();
608 insn
->insn
= CFI_escape
;
611 --input_line_pointer
;
612 demand_empty_rest_of_line ();
616 dot_cfi_personality (int ignored ATTRIBUTE_UNUSED
)
618 struct fde_entry
*fde
;
621 if (frchain_now
->frch_cfi_data
== NULL
)
623 as_bad (_("CFI instruction used without previous .cfi_startproc"));
624 ignore_rest_of_line ();
628 fde
= frchain_now
->frch_cfi_data
->cur_fde_data
;
629 encoding
= get_absolute_expression ();
630 if (encoding
== DW_EH_PE_omit
)
632 demand_empty_rest_of_line ();
633 fde
->per_encoding
= encoding
;
637 if ((encoding
& 0xff) != encoding
638 || ((encoding
& 0x70) != 0
639 #if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
640 && (encoding
& 0x70) != DW_EH_PE_pcrel
643 /* leb128 can be handled, but does something actually need it? */
644 || (encoding
& 7) == DW_EH_PE_uleb128
645 || (encoding
& 7) > DW_EH_PE_udata8
)
647 as_bad (_("invalid or unsupported encoding in .cfi_personality"));
648 ignore_rest_of_line ();
652 if (*input_line_pointer
++ != ',')
654 as_bad (_(".cfi_personality requires encoding and symbol arguments"));
655 ignore_rest_of_line ();
659 expression_and_evaluate (&fde
->personality
);
660 switch (fde
->personality
.X_op
)
665 if ((encoding
& 0x70) == DW_EH_PE_pcrel
)
666 encoding
= DW_EH_PE_omit
;
669 encoding
= DW_EH_PE_omit
;
673 fde
->per_encoding
= encoding
;
675 if (encoding
== DW_EH_PE_omit
)
677 as_bad (_("wrong second argument to .cfi_personality"));
678 ignore_rest_of_line ();
682 demand_empty_rest_of_line ();
686 dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED
)
688 struct fde_entry
*fde
;
691 if (frchain_now
->frch_cfi_data
== NULL
)
693 as_bad (_("CFI instruction used without previous .cfi_startproc"));
694 ignore_rest_of_line ();
698 fde
= frchain_now
->frch_cfi_data
->cur_fde_data
;
699 encoding
= get_absolute_expression ();
700 if (encoding
== DW_EH_PE_omit
)
702 demand_empty_rest_of_line ();
703 fde
->lsda_encoding
= encoding
;
707 if ((encoding
& 0xff) != encoding
708 || ((encoding
& 0x70) != 0
709 #if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
710 && (encoding
& 0x70) != DW_EH_PE_pcrel
713 /* leb128 can be handled, but does something actually need it? */
714 || (encoding
& 7) == DW_EH_PE_uleb128
715 || (encoding
& 7) > DW_EH_PE_udata8
)
717 as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
718 ignore_rest_of_line ();
722 if (*input_line_pointer
++ != ',')
724 as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
725 ignore_rest_of_line ();
729 fde
->lsda_encoding
= encoding
;
731 expression_and_evaluate (&fde
->lsda
);
732 switch (fde
->lsda
.X_op
)
737 if ((encoding
& 0x70) == DW_EH_PE_pcrel
)
738 encoding
= DW_EH_PE_omit
;
741 encoding
= DW_EH_PE_omit
;
745 fde
->lsda_encoding
= encoding
;
747 if (encoding
== DW_EH_PE_omit
)
749 as_bad (_("wrong second argument to .cfi_lsda"));
750 ignore_rest_of_line ();
754 demand_empty_rest_of_line ();
758 dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED
)
762 if (frchain_now
->frch_cfi_data
!= NULL
)
764 as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
765 ignore_rest_of_line ();
769 cfi_new_fde (symbol_temp_new_now ());
772 if (is_name_beginner (*input_line_pointer
))
776 name
= input_line_pointer
;
777 c
= get_symbol_end ();
779 if (strcmp (name
, "simple") == 0)
782 *input_line_pointer
= c
;
785 input_line_pointer
= name
;
787 demand_empty_rest_of_line ();
789 frchain_now
->frch_cfi_data
->cur_cfa_offset
= 0;
791 tc_cfi_frame_initial_instructions ();
795 dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED
)
797 if (frchain_now
->frch_cfi_data
== NULL
)
799 as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
800 ignore_rest_of_line ();
804 cfi_end_fde (symbol_temp_new_now ());
806 demand_empty_rest_of_line ();
810 /* Emit a single byte into the current segment. */
815 FRAG_APPEND_1_CHAR (byte
);
818 /* Emit a two-byte word into the current segment. */
823 md_number_to_chars (frag_more (2), data
, 2);
826 /* Emit a four byte word into the current segment. */
831 md_number_to_chars (frag_more (4), data
, 4);
834 /* Emit an unsigned "little-endian base 128" number. */
837 out_uleb128 (addressT value
)
839 output_leb128 (frag_more (sizeof_leb128 (value
, 0)), value
, 0);
842 /* Emit an unsigned "little-endian base 128" number. */
845 out_sleb128 (offsetT value
)
847 output_leb128 (frag_more (sizeof_leb128 (value
, 1)), value
, 1);
851 output_cfi_insn (struct cfi_insn_data
*insn
)
858 case DW_CFA_advance_loc
:
860 symbolS
*from
= insn
->u
.ll
.lab1
;
861 symbolS
*to
= insn
->u
.ll
.lab2
;
863 if (symbol_get_frag (to
) == symbol_get_frag (from
))
865 addressT delta
= S_GET_VALUE (to
) - S_GET_VALUE (from
);
866 addressT scaled
= delta
/ DWARF2_LINE_MIN_INSN_LENGTH
;
869 out_one (DW_CFA_advance_loc
+ scaled
);
870 else if (delta
<= 0xFF)
872 out_one (DW_CFA_advance_loc1
);
875 else if (delta
<= 0xFFFF)
877 out_one (DW_CFA_advance_loc2
);
882 out_one (DW_CFA_advance_loc4
);
890 exp
.X_op
= O_subtract
;
891 exp
.X_add_symbol
= to
;
892 exp
.X_op_symbol
= from
;
893 exp
.X_add_number
= 0;
895 /* The code in ehopt.c expects that one byte of the encoding
896 is already allocated to the frag. This comes from the way
897 that it scans the .eh_frame section looking first for the
898 .byte DW_CFA_advance_loc4. */
901 frag_var (rs_cfa
, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH
<< 3,
902 make_expr_symbol (&exp
), frag_now_fix () - 1,
909 offset
= insn
->u
.ri
.offset
;
912 out_one (DW_CFA_def_cfa_sf
);
913 out_uleb128 (insn
->u
.ri
.reg
);
914 out_sleb128 (offset
/ DWARF2_CIE_DATA_ALIGNMENT
);
918 out_one (DW_CFA_def_cfa
);
919 out_uleb128 (insn
->u
.ri
.reg
);
920 out_uleb128 (offset
);
924 case DW_CFA_def_cfa_register
:
925 case DW_CFA_undefined
:
926 case DW_CFA_same_value
:
927 out_one (insn
->insn
);
928 out_uleb128 (insn
->u
.r
);
931 case DW_CFA_def_cfa_offset
:
935 out_one (DW_CFA_def_cfa_offset_sf
);
936 out_sleb128 (offset
/ DWARF2_CIE_DATA_ALIGNMENT
);
940 out_one (DW_CFA_def_cfa_offset
);
941 out_uleb128 (offset
);
949 out_one (DW_CFA_restore
+ regno
);
953 out_one (DW_CFA_restore_extended
);
959 regno
= insn
->u
.ri
.reg
;
960 offset
= insn
->u
.ri
.offset
/ DWARF2_CIE_DATA_ALIGNMENT
;
963 out_one (DW_CFA_offset_extended_sf
);
965 out_sleb128 (offset
);
967 else if (regno
<= 0x3F)
969 out_one (DW_CFA_offset
+ regno
);
970 out_uleb128 (offset
);
974 out_one (DW_CFA_offset_extended
);
976 out_uleb128 (offset
);
980 case DW_CFA_register
:
981 out_one (DW_CFA_register
);
982 out_uleb128 (insn
->u
.rr
.reg1
);
983 out_uleb128 (insn
->u
.rr
.reg2
);
986 case DW_CFA_remember_state
:
987 case DW_CFA_restore_state
:
988 out_one (insn
->insn
);
991 case DW_CFA_GNU_window_save
:
992 out_one (DW_CFA_GNU_window_save
);
997 struct cfi_escape_data
*e
;
998 for (e
= insn
->u
.esc
; e
; e
= e
->next
)
999 emit_expr (&e
->exp
, 1);
1009 encoding_size (unsigned char encoding
)
1011 if (encoding
== DW_EH_PE_omit
)
1013 switch (encoding
& 0x7)
1016 return bfd_get_arch_size (stdoutput
) == 64 ? 8 : 4;
1017 case DW_EH_PE_udata2
:
1019 case DW_EH_PE_udata4
:
1021 case DW_EH_PE_udata8
:
1029 output_cie (struct cie_entry
*cie
)
1031 symbolS
*after_size_address
, *end_address
;
1033 struct cfi_insn_data
*i
;
1034 offsetT augmentation_size
;
1036 cie
->start_address
= symbol_temp_new_now ();
1037 after_size_address
= symbol_temp_make ();
1038 end_address
= symbol_temp_make ();
1040 exp
.X_op
= O_subtract
;
1041 exp
.X_add_symbol
= end_address
;
1042 exp
.X_op_symbol
= after_size_address
;
1043 exp
.X_add_number
= 0;
1045 emit_expr (&exp
, 4); /* Length. */
1046 symbol_set_value_now (after_size_address
);
1047 out_four (0); /* CIE id. */
1048 out_one (DW_CIE_VERSION
); /* Version. */
1049 out_one ('z'); /* Augmentation. */
1050 if (cie
->per_encoding
!= DW_EH_PE_omit
)
1052 if (cie
->lsda_encoding
!= DW_EH_PE_omit
)
1055 if (cie
->signal_frame
)
1058 out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH
); /* Code alignment. */
1059 out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT
); /* Data alignment. */
1060 if (DW_CIE_VERSION
== 1) /* Return column. */
1061 out_one (cie
->return_column
);
1063 out_uleb128 (cie
->return_column
);
1064 augmentation_size
= 1 + (cie
->lsda_encoding
!= DW_EH_PE_omit
);
1065 if (cie
->per_encoding
!= DW_EH_PE_omit
)
1066 augmentation_size
+= 1 + encoding_size (cie
->per_encoding
);
1067 out_uleb128 (augmentation_size
); /* Augmentation size. */
1068 if (cie
->per_encoding
!= DW_EH_PE_omit
)
1070 offsetT size
= encoding_size (cie
->per_encoding
);
1071 out_one (cie
->per_encoding
);
1072 exp
= cie
->personality
;
1073 if ((cie
->per_encoding
& 0x70) == DW_EH_PE_pcrel
)
1076 exp
.X_op
= O_subtract
;
1077 exp
.X_op_symbol
= symbol_temp_new_now ();
1078 emit_expr (&exp
, size
);
1079 #elif defined (tc_cfi_emit_pcrel_expr)
1080 tc_cfi_emit_pcrel_expr (&exp
, size
);
1086 emit_expr (&exp
, size
);
1088 if (cie
->lsda_encoding
!= DW_EH_PE_omit
)
1089 out_one (cie
->lsda_encoding
);
1090 #if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1091 out_one (DW_EH_PE_pcrel
| DW_EH_PE_sdata4
);
1093 out_one (DW_EH_PE_sdata4
);
1097 for (i
= cie
->first
; i
!= cie
->last
; i
= i
->next
)
1098 output_cfi_insn (i
);
1100 frag_align (2, DW_CFA_nop
, 0);
1101 symbol_set_value_now (end_address
);
1105 output_fde (struct fde_entry
*fde
, struct cie_entry
*cie
,
1106 struct cfi_insn_data
*first
, int align
)
1108 symbolS
*after_size_address
, *end_address
;
1110 offsetT augmentation_size
;
1112 after_size_address
= symbol_temp_make ();
1113 end_address
= symbol_temp_make ();
1115 exp
.X_op
= O_subtract
;
1116 exp
.X_add_symbol
= end_address
;
1117 exp
.X_op_symbol
= after_size_address
;
1118 exp
.X_add_number
= 0;
1119 emit_expr (&exp
, 4); /* Length. */
1120 symbol_set_value_now (after_size_address
);
1122 exp
.X_add_symbol
= after_size_address
;
1123 exp
.X_op_symbol
= cie
->start_address
;
1124 emit_expr (&exp
, 4); /* CIE offset. */
1127 exp
.X_add_symbol
= fde
->start_address
;
1128 exp
.X_op_symbol
= symbol_temp_new_now ();
1129 emit_expr (&exp
, 4); /* Code offset. */
1131 exp
.X_op
= O_symbol
;
1132 exp
.X_add_symbol
= fde
->start_address
;
1133 exp
.X_op_symbol
= NULL
;
1134 #ifdef tc_cfi_emit_pcrel_expr
1135 tc_cfi_emit_pcrel_expr (&exp
, 4); /* Code offset. */
1137 emit_expr (&exp
, 4); /* Code offset. */
1139 exp
.X_op
= O_subtract
;
1142 exp
.X_add_symbol
= fde
->end_address
;
1143 exp
.X_op_symbol
= fde
->start_address
; /* Code length. */
1144 emit_expr (&exp
, 4);
1146 augmentation_size
= encoding_size (fde
->lsda_encoding
);
1147 out_uleb128 (augmentation_size
); /* Augmentation size. */
1149 if (fde
->lsda_encoding
!= DW_EH_PE_omit
)
1152 if ((fde
->lsda_encoding
& 0x70) == DW_EH_PE_pcrel
)
1155 exp
.X_op
= O_subtract
;
1156 exp
.X_op_symbol
= symbol_temp_new_now ();
1157 emit_expr (&exp
, augmentation_size
);
1158 #elif defined (tc_cfi_emit_pcrel_expr)
1159 tc_cfi_emit_pcrel_expr (&exp
, augmentation_size
);
1165 emit_expr (&exp
, augmentation_size
);
1168 for (; first
; first
= first
->next
)
1169 output_cfi_insn (first
);
1171 frag_align (align
, DW_CFA_nop
, 0);
1172 symbol_set_value_now (end_address
);
1175 static struct cie_entry
*
1176 select_cie_for_fde (struct fde_entry
*fde
, struct cfi_insn_data
**pfirst
)
1178 struct cfi_insn_data
*i
, *j
;
1179 struct cie_entry
*cie
;
1181 for (cie
= cie_root
; cie
; cie
= cie
->next
)
1183 if (cie
->return_column
!= fde
->return_column
1184 || cie
->signal_frame
!= fde
->signal_frame
1185 || cie
->per_encoding
!= fde
->per_encoding
1186 || cie
->lsda_encoding
!= fde
->lsda_encoding
)
1188 if (cie
->per_encoding
!= DW_EH_PE_omit
)
1190 if (cie
->personality
.X_op
!= fde
->personality
.X_op
1191 || cie
->personality
.X_add_number
1192 != fde
->personality
.X_add_number
)
1194 switch (cie
->personality
.X_op
)
1197 if (cie
->personality
.X_unsigned
!= fde
->personality
.X_unsigned
)
1201 if (cie
->personality
.X_add_symbol
1202 != fde
->personality
.X_add_symbol
)
1209 for (i
= cie
->first
, j
= fde
->data
;
1210 i
!= cie
->last
&& j
!= NULL
;
1211 i
= i
->next
, j
= j
->next
)
1213 if (i
->insn
!= j
->insn
)
1217 case DW_CFA_advance_loc
:
1218 case DW_CFA_remember_state
:
1219 /* We reached the first advance/remember in the FDE,
1220 but did not reach the end of the CIE list. */
1224 case DW_CFA_def_cfa
:
1225 if (i
->u
.ri
.reg
!= j
->u
.ri
.reg
)
1227 if (i
->u
.ri
.offset
!= j
->u
.ri
.offset
)
1231 case DW_CFA_register
:
1232 if (i
->u
.rr
.reg1
!= j
->u
.rr
.reg1
)
1234 if (i
->u
.rr
.reg2
!= j
->u
.rr
.reg2
)
1238 case DW_CFA_def_cfa_register
:
1239 case DW_CFA_restore
:
1240 case DW_CFA_undefined
:
1241 case DW_CFA_same_value
:
1242 if (i
->u
.r
!= j
->u
.r
)
1246 case DW_CFA_def_cfa_offset
:
1247 if (i
->u
.i
!= j
->u
.i
)
1252 /* Don't bother matching these for now. */
1260 /* Success if we reached the end of the CIE list, and we've either
1261 run out of FDE entries or we've encountered an advance,
1262 remember, or escape. */
1265 || j
->insn
== DW_CFA_advance_loc
1266 || j
->insn
== DW_CFA_remember_state
1267 || j
->insn
== CFI_escape
))
1276 cie
= xmalloc (sizeof (struct cie_entry
));
1277 cie
->next
= cie_root
;
1279 cie
->return_column
= fde
->return_column
;
1280 cie
->signal_frame
= fde
->signal_frame
;
1281 cie
->per_encoding
= fde
->per_encoding
;
1282 cie
->lsda_encoding
= fde
->lsda_encoding
;
1283 cie
->personality
= fde
->personality
;
1284 cie
->first
= fde
->data
;
1286 for (i
= cie
->first
; i
; i
= i
->next
)
1287 if (i
->insn
== DW_CFA_advance_loc
1288 || i
->insn
== DW_CFA_remember_state
1289 || i
->insn
== CFI_escape
)
1304 struct fde_entry
*fde
;
1305 int save_flag_traditional_format
;
1307 if (all_fde_data
== 0)
1310 /* Open .eh_frame section. */
1311 cfi_seg
= subseg_new (".eh_frame", 0);
1312 bfd_set_section_flags (stdoutput
, cfi_seg
,
1313 SEC_ALLOC
| SEC_LOAD
| SEC_DATA
| SEC_READONLY
);
1314 subseg_set (cfi_seg
, 0);
1315 record_alignment (cfi_seg
, EH_FRAME_ALIGNMENT
);
1317 /* Make sure check_eh_frame doesn't do anything with our output. */
1318 save_flag_traditional_format
= flag_traditional_format
;
1319 flag_traditional_format
= 1;
1321 for (fde
= all_fde_data
; fde
; fde
= fde
->next
)
1323 struct cfi_insn_data
*first
;
1324 struct cie_entry
*cie
;
1326 if (fde
->end_address
== NULL
)
1328 as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
1329 fde
->end_address
= fde
->start_address
;
1332 cie
= select_cie_for_fde (fde
, &first
);
1333 output_fde (fde
, cie
, first
, fde
->next
== NULL
? EH_FRAME_ALIGNMENT
: 2);
1336 flag_traditional_format
= save_flag_traditional_format
;
1339 #else /* TARGET_USE_CFIPOP */
1344 #endif /* TARGET_USE_CFIPOP */