bfd:
[deliverable/binutils-gdb.git] / gas / dw2gencfi.c
index dfe24af77ea6290ae957f8c7952abd2baaf4d8e5..974cdfb8bb6256dc8535c26c36f30ca82ab6e4b8 100644 (file)
@@ -1,5 +1,5 @@
 /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
-   Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michal Ludvig <mludvig@suse.cz>
 
 # define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
 #endif
 
+/* ??? Share this with dwarf2cfg.c.  */
+#ifndef TC_DWARF2_EMIT_OFFSET
+#define TC_DWARF2_EMIT_OFFSET  generic_dwarf2_emit_offset
+
+/* Create an offset to .dwarf2_*.  */
+
+static void
+generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
+{
+  expressionS exp;
+
+  exp.X_op = O_symbol;
+  exp.X_add_symbol = symbol;
+  exp.X_add_number = 0;
+  emit_expr (&exp, size);
+}
+#endif
+
 struct cfi_escape_data {
   struct cfi_escape_data *next;
   expressionS exp;
@@ -1303,9 +1321,9 @@ output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
       if (cie->lsda_encoding != DW_EH_PE_omit)
        out_one ('L');
       out_one ('R');
-      if (cie->signal_frame)
-       out_one ('S');
     }
+  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.  */
@@ -1319,29 +1337,31 @@ output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
       if (cie->per_encoding != DW_EH_PE_omit)
        augmentation_size += 1 + encoding_size (cie->per_encoding);
       out_uleb128 (augmentation_size);         /* Augmentation size.  */
-    }
-  if (cie->per_encoding != DW_EH_PE_omit)
-    {
-      offsetT size = encoding_size (cie->per_encoding);
-      out_one (cie->per_encoding);
-      exp = cie->personality;
-      if ((cie->per_encoding & 0x70) == DW_EH_PE_pcrel)
+
+      if (cie->per_encoding != DW_EH_PE_omit)
        {
+         offsetT size = encoding_size (cie->per_encoding);
+         out_one (cie->per_encoding);
+         exp = cie->personality;
+         if ((cie->per_encoding & 0x70) == DW_EH_PE_pcrel)
+           {
 #if CFI_DIFF_EXPR_OK
-         exp.X_op = O_subtract;
-         exp.X_op_symbol = symbol_temp_new_now ();
-         emit_expr (&exp, size);
+             exp.X_op = O_subtract;
+             exp.X_op_symbol = symbol_temp_new_now ();
+             emit_expr (&exp, size);
 #elif defined (tc_cfi_emit_pcrel_expr)
-         tc_cfi_emit_pcrel_expr (&exp, size);
+             tc_cfi_emit_pcrel_expr (&exp, size);
 #else
-         abort ();
+             abort ();
 #endif
+           }
+         else
+           emit_expr (&exp, size);
        }
-      else
-       emit_expr (&exp, size);
+
+      if (cie->lsda_encoding != DW_EH_PE_omit)
+       out_one (cie->lsda_encoding);
     }
-  if (cie->lsda_encoding != DW_EH_PE_omit)
-    out_one (cie->lsda_encoding);
 
   switch (DWARF2_FDE_RELOC_SIZE)
     {
@@ -1403,19 +1423,21 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie,
 
   if (eh_frame)
     {
+      exp.X_op = O_subtract;
       exp.X_add_symbol = after_size_address;
       exp.X_op_symbol = cie->start_address;
+      exp.X_add_number = 0;
+      emit_expr (&exp, offset_size);           /* CIE offset.  */
     }
   else
     {
-      exp.X_op = O_symbol;
-      exp.X_add_symbol = cie->start_address;
-      exp.X_op_symbol = NULL;
+      TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
     }
-  emit_expr (&exp, offset_size);               /* CIE offset.  */
 
   if (eh_frame)
     {
+      exp.X_op = O_subtract;
+      exp.X_add_number = 0;
 #if CFI_DIFF_EXPR_OK
       exp.X_add_symbol = fde->start_address;
       exp.X_op_symbol = symbol_temp_new_now ();
@@ -1423,7 +1445,6 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie,
 #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, DWARF2_FDE_RELOC_SIZE);     /* Code offset.  */
 #else
@@ -1434,7 +1455,9 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie,
     }
   else
     {
+      exp.X_op = O_symbol;
       exp.X_add_symbol = fde->start_address;
+      exp.X_add_number = 0;
       addr_size = DWARF2_ADDR_SIZE (stdoutput);
       emit_expr (&exp, addr_size);
     }
@@ -1442,6 +1465,7 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie,
   exp.X_op = O_subtract;
   exp.X_add_symbol = fde->end_address;
   exp.X_op_symbol = fde->start_address;                /* Code length.  */
+  exp.X_add_number = 0;
   emit_expr (&exp, addr_size);
 
   augmentation_size = encoding_size (fde->lsda_encoding);
@@ -1716,7 +1740,6 @@ cfi_finish (void)
       for (fde = all_fde_data; fde ; fde = fde->next)
        {
          struct cfi_insn_data *first;
-         struct cie_entry *cie;
 
          if (fde->end_address == NULL)
            {
This page took 0.024726 seconds and 4 git commands to generate.