* elf64-hppa.c (elf64_hppa_grok_prstatus): New function.
[deliverable/binutils-gdb.git] / gas / dw2gencfi.c
index d54e23346e3de10be3b9c7a867922cbe63da6b34..bfa5d5cf45a6f74d0815a0d80810b41bed0b284c 100644 (file)
@@ -1,5 +1,5 @@
 /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
-   Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    Contributed by Michal Ludvig <mludvig@suse.cz>
 
    This file is part of GAS, the GNU Assembler.
@@ -88,6 +88,7 @@ struct fde_entry
   struct cfi_insn_data *data;
   struct cfi_insn_data **last;
   unsigned int return_column;
+  unsigned int signal_frame;
 };
 
 struct cie_entry
@@ -95,6 +96,7 @@ struct cie_entry
   struct cie_entry *next;
   symbolS *start_address;
   unsigned int return_column;
+  unsigned int signal_frame;
   struct cfi_insn_data *first, *last;
 };
 
@@ -354,6 +356,7 @@ static void dot_cfi_endproc (int);
 #define CFI_return_column      0x101
 #define CFI_rel_offset         0x102
 #define CFI_escape             0x103
+#define CFI_signal_frame       0x104
 
 const pseudo_typeS cfi_pseudo_table[] =
   {
@@ -374,6 +377,7 @@ const pseudo_typeS cfi_pseudo_table[] =
     { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
     { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
     { "cfi_escape", dot_cfi_escape, 0 },
+    { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
     { NULL, NULL, 0 }
   };
 
@@ -415,7 +419,7 @@ cfi_parse_reg (void)
     }
 #endif
 
-  expression (&exp);
+  expression_and_evaluate (&exp);
   switch (exp.X_op)
     {
     case O_register:
@@ -447,6 +451,7 @@ dot_cfi (int arg)
   if (!cur_fde_data)
     {
       as_bad (_("CFI instruction used without previous .cfi_startproc"));
+      ignore_rest_of_line ();
       return;
     }
 
@@ -501,13 +506,27 @@ dot_cfi (int arg)
       break;
 
     case DW_CFA_restore:
-      reg1 = cfi_parse_reg ();
-      cfi_add_CFA_restore (reg1);
+      for (;;)
+       {
+         reg1 = cfi_parse_reg ();
+         cfi_add_CFA_restore (reg1);
+         SKIP_WHITESPACE ();
+         if (*input_line_pointer != ',')
+           break;
+         ++input_line_pointer;
+       }
       break;
 
     case DW_CFA_undefined:
-      reg1 = cfi_parse_reg ();
-      cfi_add_CFA_undefined (reg1);
+      for (;;)
+       {
+         reg1 = cfi_parse_reg ();
+         cfi_add_CFA_undefined (reg1);
+         SKIP_WHITESPACE ();
+         if (*input_line_pointer != ',')
+           break;
+         ++input_line_pointer;
+       }
       break;
 
     case DW_CFA_same_value:
@@ -532,6 +551,10 @@ dot_cfi (int arg)
       cfi_add_CFA_insn (DW_CFA_GNU_window_save);
       break;
 
+    case CFI_signal_frame:
+      cur_fde_data->signal_frame = 1;
+      break;
+
     default:
       abort ();
     }
@@ -548,6 +571,7 @@ dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
   if (!cur_fde_data)
     {
       as_bad (_("CFI instruction used without previous .cfi_startproc"));
+      ignore_rest_of_line ();
       return;
     }
 
@@ -570,6 +594,9 @@ dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
   insn = alloc_cfi_insn_data ();
   insn->insn = CFI_escape;
   insn->u.esc = head;
+
+  --input_line_pointer;
+  demand_empty_rest_of_line ();
 }
 
 static void
@@ -580,6 +607,7 @@ dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
   if (cur_fde_data)
     {
       as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
+      ignore_rest_of_line ();
       return;
     }
 
@@ -614,10 +642,13 @@ dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
   if (! cur_fde_data)
     {
       as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
+      ignore_rest_of_line ();
       return;
     }
 
   cfi_end_fde (symbol_temp_new_now ());
+
+  demand_empty_rest_of_line ();
 }
 
 \f
@@ -841,6 +872,8 @@ output_cie (struct cie_entry *cie)
   out_one (DW_CIE_VERSION);                    /* Version.  */
   out_one ('z');                               /* Augmentation.  */
   out_one ('R');
+  if (cie->signal_frame)
+    out_one ('S');
   out_one (0);
   out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH);   /* Code alignment.  */
   out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT);     /* Data alignment.  */
@@ -921,7 +954,8 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst)
 
   for (cie = cie_root; cie; cie = cie->next)
     {
-      if (cie->return_column != fde->return_column)
+      if (cie->return_column != fde->return_column
+         || cie->signal_frame != fde->signal_frame)
        continue;
       for (i = cie->first, j = fde->data;
           i != cie->last && j != NULL;
@@ -994,6 +1028,7 @@ select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst)
   cie->next = cie_root;
   cie_root = cie;
   cie->return_column = fde->return_column;
+  cie->signal_frame = fde->signal_frame;
   cie->first = fde->data;
 
   for (i = cie->first; i ; i = i->next)
This page took 0.025175 seconds and 4 git commands to generate.