From f878857138ee05b6c8fb872d2fd0befc52d57b4b Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 7 Oct 2004 15:18:11 +0000 Subject: 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. --- gas/dw2gencfi.c | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'gas/dw2gencfi.c') diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index 3937329e40..3bfd14f46a 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; -- cgit v1.2.1