Keep track of prologue counts across .label_state/.copy_state directives
authorNick Clifton <nickc@redhat.com>
Fri, 22 Feb 2002 11:56:21 +0000 (11:56 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 22 Feb 2002 11:56:21 +0000 (11:56 +0000)
gas/ChangeLog
gas/config/tc-ia64.c

index 3d53b2a532d8ff63b6ebc0533cac540431733d63..102b41f54df9eadb056e46959005b7dc9baa7051 100644 (file)
@@ -1,3 +1,21 @@
+2002-02-20  David Mosberger  <davidm@hpl.hp.com>
+
+       * config/tc-ia64.c (dot_restore): Issue error message of epilogue
+       count exceeds prologue count.
+       (md_show_usage): Describe -mconstant-gp and -mauto-pic.
+       (unwind.label_prologue_count): New member.
+
+       Based on a patch by Hans Boehm <hboehm@hpl.hp.com>:
+
+       (get_saved_prologue_count): New function.
+       (save_prologue_count): New function.
+       (free_saved_prologue_count): New function.
+       (dot_label_state): Record state label by calling save_prologue_count().
+       (dot_copy_state): Restore prologue count by calling
+       get_saved_prologue_count().
+       (generate_unwind_image): Free up list of saved prologue
+       counts by calling free_saved_prologue_counts().
+
 2002-02-22  Nick Clifton  <nickc@cambridge.redhat.com>
 
        * config/tc-tic54x.c: Add missing prototypes and remove ANSI style
index 701752f47eb4d89129ec8c0d015ff4f15e12d1c4..88905b87ed0a273dd34b97a9b9a851fd66f695fc 100644 (file)
@@ -623,6 +623,15 @@ typedef struct unw_rec_list {
 
 #define SLOT_NUM_NOT_SET        (unsigned)-1
 
+/* Linked list of saved prologue counts.  A very poor
+   implementation of a map from label numbers to prologue counts.  */
+typedef struct label_prologue_count
+{
+  struct label_prologue_count *next;
+  unsigned long label_number;
+  unsigned int prologue_count;
+} label_prologue_count;
+
 static struct
 {
   unsigned long next_slot_number;
@@ -649,6 +658,8 @@ static struct
   int prologue;
   int prologue_mask;
   unsigned int prologue_count; /* number of .prologues seen so far */
+  /* Prologue counts at previous .label_state directives.  */
+  struct label_prologue_count * saved_prologue_counts;
 } unwind;
 
 typedef void (*vbyte_func) PARAMS ((int, char *, char *));
@@ -862,6 +873,9 @@ static int output_unw_records PARAMS ((unw_rec_list *, void **));
 static int convert_expr_to_ab_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
 static int convert_expr_to_xy_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
 static int generate_unwind_image PARAMS ((const char *));
+static unsigned int get_saved_prologue_count PARAMS ((unsigned long));
+static void save_prologue_count PARAMS ((unsigned long, unsigned int));
+static void free_saved_prologue_counts PARAMS ((void));
 
 /* Build the unwind section name by appending the (possibly stripped)
    text section NAME to the unwind PREFIX.  The resulting string
@@ -3156,6 +3170,14 @@ dot_restore (dummy)
     }
   else
     ecount = unwind.prologue_count - 1;
+
+  if (ecount >= unwind.prologue_count)
+    {
+      as_bad ("Epilogue count of %lu exceeds number of nested prologues (%u)",
+             ecount + 1, unwind.prologue_count);
+      return;
+    }
+
   add_unwind_entry (output_epilogue (ecount));
 
   if (ecount < unwind.prologue_count)
@@ -3228,7 +3250,7 @@ generate_unwind_image (text_name)
   size = output_unw_records (unwind.list, (void **) &unw_rec);
   if (size % md.pointer_size != 0)
     as_bad ("Unwind record is not a multiple of %d bytes.", md.pointer_size);
-                      
+
   /* If there are unwind records, switch sections, and output the info.  */
   if (size != 0)
     {
@@ -3288,6 +3310,7 @@ generate_unwind_image (text_name)
     }
 
   free_list_records (unwind.list);
+  free_saved_prologue_counts ();
   unwind.list = unwind.tail = unwind.current_entry = NULL;
 
   return size;
@@ -3714,6 +3737,61 @@ dot_spillmem_p (psprel)
     add_unwind_entry (output_spill_sprel_p (ab, reg, e3.X_add_number, qp));
 }
 
+static unsigned int
+get_saved_prologue_count (lbl)
+     unsigned long lbl;
+{
+  label_prologue_count *lpc = unwind.saved_prologue_counts;
+
+  while (lpc != NULL && lpc->label_number != lbl)
+    lpc = lpc->next;
+
+  if (lpc != NULL)
+    return lpc->prologue_count;
+
+  as_bad ("Missing .label_state %ld", lbl);
+  return 1;
+}
+
+static void
+save_prologue_count (lbl, count)
+     unsigned long lbl;
+     unsigned int count;
+{
+  label_prologue_count *lpc = unwind.saved_prologue_counts;
+
+  while (lpc != NULL && lpc->label_number != lbl)
+    lpc = lpc->next;
+
+  if (lpc != NULL)
+    lpc->prologue_count = count;
+  else
+    {
+      label_prologue_count * new_lpc = xmalloc (sizeof (* new_lpc));
+
+      new_lpc->next = unwind.saved_prologue_counts;
+      new_lpc->label_number = lbl;
+      new_lpc->prologue_count = count;
+      unwind.saved_prologue_counts = new_lpc;
+    }
+}
+
+static void
+free_saved_prologue_counts ()
+{
+  label_prologue_count * lpc = unwind.saved_prologue_counts;
+  label_prologue_count * next;
+
+  while (lpc != NULL)
+    {
+      next = lpc->next;
+      free (lpc);
+      lpc = next;
+    }
+
+  unwind.saved_prologue_counts = NULL;
+}
+
 static void
 dot_label_state (dummy)
      int dummy ATTRIBUTE_UNUSED;
@@ -3727,6 +3805,7 @@ dot_label_state (dummy)
       return;
     }
   add_unwind_entry (output_label_state (e.X_add_number));
+  save_prologue_count (e.X_add_number, unwind.prologue_count);
 }
 
 static void
@@ -3742,6 +3821,7 @@ dot_copy_state (dummy)
       return;
     }
   add_unwind_entry (output_copy_state (e.X_add_number));
+  unwind.prologue_count = get_saved_prologue_count (e.X_add_number);
 }
 
 static void
@@ -6336,6 +6416,11 @@ md_show_usage (stream)
 {
   fputs (_("\
 IA-64 options:\n\
+  --mconstant-gp         mark output file as using the constant-GP model\n\
+                         (sets ELF header flag EF_IA_64_CONS_GP)\n\
+  --mauto-pic            mark output file as using the constant-GP model\n\
+                         without function descriptors (sets ELF header flag\n\
+                         EF_IA_64_NOFUNCDESC_CONS_GP)\n\
   -milp32|-milp64|-mlp64|-mp64 select data model (default -mlp64)\n\
   -mle | -mbe            select little- or big-endian byte order (default -mle)\n\
   -x | -xexplicit        turn on dependency violation checking (default)\n\