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.
This commit is contained in:
Nick Clifton 2004-10-07 15:18:11 +00:00
parent 89658e5257
commit 289040ca3e
6 changed files with 65 additions and 22 deletions

View file

@ -3,6 +3,9 @@
* macro.c (macro_expand_body): When ELF, use .LL rather than LL as * macro.c (macro_expand_body): When ELF, use .LL rather than LL as
prefix for symbol names generated from the LOCAL macro directive. 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 <Tomer.Levi@nsc.com> 2004-10-07 Tomer Levi <Tomer.Levi@nsc.com>
* config/tc-crx.c (preprocess_reglist): Handle Co-processor * config/tc-crx.c (preprocess_reglist): Handle Co-processor

View file

@ -1,5 +1,5 @@
/* dw2gencfi.c - Support for generating Dwarf2 CFI information. /* 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 <mludvig@suse.cz> Contributed by Michal Ludvig <mludvig@suse.cz>
This file is part of GAS, the GNU Assembler. 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 /* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
of the CIE. Default to 1 if not otherwise specified. */ 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 # define DWARF2_LINE_MIN_INSN_LENGTH 1
#endif #endif
@ -33,10 +33,10 @@
provide the following definitions. Otherwise provide them to provide the following definitions. Otherwise provide them to
allow compilation to continue. */ allow compilation to continue. */
#ifndef TARGET_USE_CFIPOP #ifndef TARGET_USE_CFIPOP
# ifndef DWARF2_DEFAULT_RETURN_COLUMN # ifndef DWARF2_DEFAULT_RETURN_COLUMN
# define DWARF2_DEFAULT_RETURN_COLUMN 0 # define DWARF2_DEFAULT_RETURN_COLUMN 0
# endif # endif
# ifndef DWARF2_CIE_DATA_ALIGNMENT # ifndef DWARF2_CIE_DATA_ALIGNMENT
# define DWARF2_CIE_DATA_ALIGNMENT 1 # define DWARF2_CIE_DATA_ALIGNMENT 1
# endif # endif
#endif #endif
@ -341,6 +341,8 @@ cfi_add_CFA_restore_state (void)
cfa_save_stack = p->next; cfa_save_stack = p->next;
free (p); 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_op_symbol = after_size_address;
exp.X_add_number = 0; exp.X_add_number = 0;
emit_expr (&exp, 4); /* Length */ emit_expr (&exp, 4); /* Length. */
symbol_set_value_now (after_size_address); symbol_set_value_now (after_size_address);
out_four (0); /* CIE id */ out_four (0); /* CIE id. */
out_one (DW_CIE_VERSION); /* Version */ out_one (DW_CIE_VERSION); /* Version. */
out_one ('z'); /* Augmentation */ out_one ('z'); /* Augmentation. */
out_one ('R'); out_one ('R');
out_one (0); out_one (0);
out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment */ out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment */ out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
if (DW_CIE_VERSION == 1) /* Return column. */ if (DW_CIE_VERSION == 1) /* Return column. */
out_one (cie->return_column); out_one (cie->return_column);
else else
out_uleb128 (cie->return_column); 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 #if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4); out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4);
#else #else
@ -878,34 +880,34 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie,
exp.X_add_symbol = end_address; exp.X_add_symbol = end_address;
exp.X_op_symbol = after_size_address; exp.X_op_symbol = after_size_address;
exp.X_add_number = 0; exp.X_add_number = 0;
emit_expr (&exp, 4); /* Length */ emit_expr (&exp, 4); /* Length. */
symbol_set_value_now (after_size_address); symbol_set_value_now (after_size_address);
exp.X_add_symbol = after_size_address; exp.X_add_symbol = after_size_address;
exp.X_op_symbol = cie->start_address; exp.X_op_symbol = cie->start_address;
emit_expr (&exp, 4); /* CIE offset */ emit_expr (&exp, 4); /* CIE offset. */
#ifdef DIFF_EXPR_OK #ifdef DIFF_EXPR_OK
exp.X_add_symbol = fde->start_address; exp.X_add_symbol = fde->start_address;
exp.X_op_symbol = symbol_temp_new_now (); exp.X_op_symbol = symbol_temp_new_now ();
emit_expr (&exp, 4); /* Code offset */ emit_expr (&exp, 4); /* Code offset. */
#else #else
exp.X_op = O_symbol; exp.X_op = O_symbol;
exp.X_add_symbol = fde->start_address; exp.X_add_symbol = fde->start_address;
exp.X_op_symbol = NULL; exp.X_op_symbol = NULL;
#ifdef tc_cfi_emit_pcrel_expr #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 #else
emit_expr (&exp, 4); /* Code offset */ emit_expr (&exp, 4); /* Code offset. */
#endif #endif
exp.X_op = O_subtract; exp.X_op = O_subtract;
#endif #endif
exp.X_add_symbol = fde->end_address; 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); emit_expr (&exp, 4);
out_uleb128 (0); /* Augmentation size */ out_uleb128 (0); /* Augmentation size. */
for (; first; first = first->next) for (; first; first = first->next)
output_cfi_insn (first); output_cfi_insn (first);
@ -933,8 +935,9 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst)
switch (i->insn) switch (i->insn)
{ {
case DW_CFA_advance_loc: case DW_CFA_advance_loc:
/* We reached the first advance in the FDE, but did not case DW_CFA_remember_state:
reach the end of the CIE list. */ /* We reached the first advance/remember in the FDE,
but did not reach the end of the CIE list. */
goto fail; goto fail;
case DW_CFA_offset: 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 /* 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 run out of FDE entries or we've encountered an advance,
escape. */ remember, or escape. */
if (i == cie->last if (i == cie->last
&& (!j && (!j
|| j->insn == DW_CFA_advance_loc || j->insn == DW_CFA_advance_loc
|| j->insn == DW_CFA_remember_state
|| j->insn == CFI_escape)) || j->insn == CFI_escape))
{ {
*pfirst = j; *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) for (i = cie->first; i ; i = i->next)
if (i->insn == DW_CFA_advance_loc if (i->insn == DW_CFA_advance_loc
|| i->insn == DW_CFA_remember_state
|| i->insn == CFI_escape) || i->insn == CFI_escape)
break; break;

View file

@ -1,3 +1,8 @@
2004-10-07 Jan Beulich <jbeulich@novell.com>
* gas/cfi/cfi-common-4.[ds]: New.
* gas/cfi/cfi.exp: Run new test.
2004-10-07 Tomer Levi <Tomer.Levi@nsc.com> 2004-10-07 Tomer Levi <Tomer.Levi@nsc.com>
* gas/crx/cop_insn.s: New file. * gas/crx/cop_insn.s: New file.

View file

@ -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

View file

@ -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

View file

@ -64,3 +64,4 @@ run_list_test "cfi-diag-1" ""
run_dump_test "cfi-common-1" run_dump_test "cfi-common-1"
run_dump_test "cfi-common-2" run_dump_test "cfi-common-2"
run_dump_test "cfi-common-3" run_dump_test "cfi-common-3"
run_dump_test "cfi-common-4"