aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2004-10-07 15:18:11 +0000
committerNick Clifton <nickc@redhat.com>2004-10-07 15:18:11 +0000
commit289040ca3e3329ab71a74971802228a071aee04d (patch)
treeadd7fc212b27df7a92ca3d8277dab93caf30b063
parent89658e5257dd9b4dd7dd1e77f46e2ecc491c89fd (diff)
downloadbinutils-289040ca3e3329ab71a74971802228a071aee04d.zip
binutils-289040ca3e3329ab71a74971802228a071aee04d.tar.gz
binutils-289040ca3e3329ab71a74971802228a071aee04d.tar.bz2
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.
-rw-r--r--gas/ChangeLog3
-rw-r--r--gas/dw2gencfi.c49
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/cfi/cfi-common-4.d20
-rw-r--r--gas/testsuite/gas/cfi/cfi-common-4.s9
-rw-r--r--gas/testsuite/gas/cfi/cfi.exp1
6 files changed, 65 insertions, 22 deletions
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 <Tomer.Levi@nsc.com>
* 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 <mludvig@suse.cz>
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 <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>
* 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"