When separating CIE out from FDE, treat a DW_CFA_remember_state as we do a
authorNick Clifton <nickc@redhat.com>
Thu, 7 Oct 2004 15:18:11 +0000 (15:18 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 7 Oct 2004 15:18:11 +0000 (15:18 +0000)
DW_CFA_advance_loc.  Test to make sure that this feature continues to work.

gas/ChangeLog
gas/dw2gencfi.c
gas/testsuite/ChangeLog
gas/testsuite/gas/cfi/cfi-common-4.d [new file with mode: 0644]
gas/testsuite/gas/cfi/cfi-common-4.s [new file with mode: 0644]
gas/testsuite/gas/cfi/cfi.exp

index dd7e73b..889cc59 100644 (file)
@@ -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
index 3937329..3bfd14f 100644 (file)
@@ -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
 
    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"));
 }
 
 \f
@@ -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;
 
index 565dc1b..23ff4d9 100644 (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>
 
        * 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 (file)
index 0000000..14ab086
--- /dev/null
@@ -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 (file)
index 0000000..1851529
--- /dev/null
@@ -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
index f32a047..a1dc006 100644 (file)
@@ -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"