From: Nick Clifton Date: Thu, 7 Oct 2004 15:18:11 +0000 (+0000) Subject: When separating CIE out from FDE, treat a DW_CFA_remember_state as we do a X-Git-Tag: gdb_6_3-20041019-branchpoint~140 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=289040ca3e3329ab71a74971802228a071aee04d;p=platform%2Fupstream%2Fbinutils.git When separating CIE out from FDE, treat a DW_CFA_remember_state as we do a DW_CFA_advance_loc. Test to make sure that this feature continues to work. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index dd7e73b..889cc59 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -3,6 +3,9 @@ * macro.c (macro_expand_body): When ELF, use .LL rather than LL as prefix for symbol names generated from the LOCAL macro directive. + * dw2gencfi.c (select_cie_for_fde): When separating CIE out from + FDE, treat a DW_CFA_remember_state as we do a DW_CFA_advance_loc. + 2004-10-07 Tomer Levi * config/tc-crx.c (preprocess_reglist): Handle Co-processor diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index 3937329..3bfd14f 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -1,5 +1,5 @@ /* dw2gencfi.c - Support for generating Dwarf2 CFI information. - Copyright 2003 Free Software Foundation, Inc. + Copyright 2003, 2004 Free Software Foundation, Inc. Contributed by Michal Ludvig This file is part of GAS, the GNU Assembler. @@ -25,7 +25,7 @@ /* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field of the CIE. Default to 1 if not otherwise specified. */ -#ifndef DWARF2_LINE_MIN_INSN_LENGTH +#ifndef DWARF2_LINE_MIN_INSN_LENGTH # define DWARF2_LINE_MIN_INSN_LENGTH 1 #endif @@ -33,10 +33,10 @@ provide the following definitions. Otherwise provide them to allow compilation to continue. */ #ifndef TARGET_USE_CFIPOP -# ifndef DWARF2_DEFAULT_RETURN_COLUMN +# ifndef DWARF2_DEFAULT_RETURN_COLUMN # define DWARF2_DEFAULT_RETURN_COLUMN 0 # endif -# ifndef DWARF2_CIE_DATA_ALIGNMENT +# ifndef DWARF2_CIE_DATA_ALIGNMENT # define DWARF2_CIE_DATA_ALIGNMENT 1 # endif #endif @@ -341,6 +341,8 @@ cfi_add_CFA_restore_state (void) cfa_save_stack = p->next; free (p); } + else + as_bad (_("CFI state restore without previous remember")); } @@ -836,20 +838,20 @@ output_cie (struct cie_entry *cie) exp.X_op_symbol = after_size_address; exp.X_add_number = 0; - emit_expr (&exp, 4); /* Length */ + emit_expr (&exp, 4); /* Length. */ symbol_set_value_now (after_size_address); - out_four (0); /* CIE id */ - out_one (DW_CIE_VERSION); /* Version */ - out_one ('z'); /* Augmentation */ + out_four (0); /* CIE id. */ + out_one (DW_CIE_VERSION); /* Version. */ + out_one ('z'); /* Augmentation. */ out_one ('R'); out_one (0); - out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment */ - out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment */ + out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */ + out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */ if (DW_CIE_VERSION == 1) /* Return column. */ out_one (cie->return_column); else out_uleb128 (cie->return_column); - out_uleb128 (1); /* Augmentation size */ + out_uleb128 (1); /* Augmentation size. */ #if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4); #else @@ -878,34 +880,34 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie, exp.X_add_symbol = end_address; exp.X_op_symbol = after_size_address; exp.X_add_number = 0; - emit_expr (&exp, 4); /* Length */ + emit_expr (&exp, 4); /* Length. */ symbol_set_value_now (after_size_address); exp.X_add_symbol = after_size_address; exp.X_op_symbol = cie->start_address; - emit_expr (&exp, 4); /* CIE offset */ + emit_expr (&exp, 4); /* CIE offset. */ #ifdef DIFF_EXPR_OK exp.X_add_symbol = fde->start_address; exp.X_op_symbol = symbol_temp_new_now (); - emit_expr (&exp, 4); /* Code offset */ + emit_expr (&exp, 4); /* Code offset. */ #else exp.X_op = O_symbol; exp.X_add_symbol = fde->start_address; exp.X_op_symbol = NULL; #ifdef tc_cfi_emit_pcrel_expr - tc_cfi_emit_pcrel_expr (&exp, 4); /* Code offset */ + tc_cfi_emit_pcrel_expr (&exp, 4); /* Code offset. */ #else - emit_expr (&exp, 4); /* Code offset */ + emit_expr (&exp, 4); /* Code offset. */ #endif exp.X_op = O_subtract; #endif exp.X_add_symbol = fde->end_address; - exp.X_op_symbol = fde->start_address; /* Code length */ + exp.X_op_symbol = fde->start_address; /* Code length. */ emit_expr (&exp, 4); - out_uleb128 (0); /* Augmentation size */ + out_uleb128 (0); /* Augmentation size. */ for (; first; first = first->next) output_cfi_insn (first); @@ -933,8 +935,9 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst) switch (i->insn) { case DW_CFA_advance_loc: - /* We reached the first advance in the FDE, but did not - reach the end of the CIE list. */ + case DW_CFA_remember_state: + /* We reached the first advance/remember in the FDE, + but did not reach the end of the CIE list. */ goto fail; case DW_CFA_offset: @@ -975,11 +978,12 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst) } /* Success if we reached the end of the CIE list, and we've either - run out of FDE entries or we've encountered an advance or - escape. */ + run out of FDE entries or we've encountered an advance, + remember, or escape. */ if (i == cie->last && (!j || j->insn == DW_CFA_advance_loc + || j->insn == DW_CFA_remember_state || j->insn == CFI_escape)) { *pfirst = j; @@ -997,6 +1001,7 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst) for (i = cie->first; i ; i = i->next) if (i->insn == DW_CFA_advance_loc + || i->insn == DW_CFA_remember_state || i->insn == CFI_escape) break; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 565dc1b..23ff4d9 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-10-07 Jan Beulich + + * gas/cfi/cfi-common-4.[ds]: New. + * gas/cfi/cfi.exp: Run new test. + 2004-10-07 Tomer Levi * gas/crx/cop_insn.s: New file. diff --git a/gas/testsuite/gas/cfi/cfi-common-4.d b/gas/testsuite/gas/cfi/cfi-common-4.d new file mode 100644 index 0000000..14ab086 --- /dev/null +++ b/gas/testsuite/gas/cfi/cfi-common-4.d @@ -0,0 +1,20 @@ +#readelf: -wf +#name: CFI common 4 +The section .eh_frame contains: + +00000000 00000010 00000000 CIE + Version: 1 + Augmentation: "zR" + Code alignment factor: .* + Data alignment factor: .* + Return address column: .* + Augmentation data: 1b +#... +00000014 00000010 00000018 FDE cie=00000000 pc=.* + DW_CFA_remember_state + DW_CFA_restore_state +#... +00000028 00000010 0000002c FDE cie=00000000 pc=.* + DW_CFA_remember_state + DW_CFA_restore_state +#pass diff --git a/gas/testsuite/gas/cfi/cfi-common-4.s b/gas/testsuite/gas/cfi/cfi-common-4.s new file mode 100644 index 0000000..1851529 --- /dev/null +++ b/gas/testsuite/gas/cfi/cfi-common-4.s @@ -0,0 +1,9 @@ + .cfi_startproc simple + .cfi_remember_state + .cfi_restore_state + .cfi_endproc + + .cfi_startproc simple + .cfi_remember_state + .cfi_restore_state + .cfi_endproc diff --git a/gas/testsuite/gas/cfi/cfi.exp b/gas/testsuite/gas/cfi/cfi.exp index f32a047..a1dc006 100644 --- a/gas/testsuite/gas/cfi/cfi.exp +++ b/gas/testsuite/gas/cfi/cfi.exp @@ -64,3 +64,4 @@ run_list_test "cfi-diag-1" "" run_dump_test "cfi-common-1" run_dump_test "cfi-common-2" run_dump_test "cfi-common-3" +run_dump_test "cfi-common-4"