2000-09-09 Philip Blundell <philb@gnu.org>
[deliverable/binutils-gdb.git] / gas / ehopt.c
index cb900e0db2cee4960a5942bc04f3926013294551..a0a5f62f4d7abe18b070764bc911a75e05a1ccd5 100644 (file)
@@ -108,8 +108,16 @@ eh_frame_code_alignment ()
   current_seg = now_seg;
   current_subseg = now_subseg;
   subseg_new (".eh_frame", 0);
+#if defined (BFD_ASSEMBLER) || defined (MANY_SEGMENTS)
   f = seg_info (now_seg)->frchainP->frch_root;
+#else
+  f = frchain_now->frch_root;
+#endif
+#ifdef BFD_ASSEMBLER
   fix = seg_info (now_seg)->frchainP->fix_root;
+#else
+  fix = *seg_fix_rootP;
+#endif
   subseg_set (current_seg, current_subseg);
 
   /* Look through the frags of the section to find the code alignment.  */
@@ -167,7 +175,7 @@ eh_frame_code_alignment ()
        }
       while (offset < f->fr_fix && f->fr_literal[offset] != '\0')
        {
-         if (iaug < (sizeof augmentation) - 1)
+         if ((size_t) iaug < (sizeof augmentation) - 1)
            {
              augmentation[iaug] = f->fr_literal[offset];
              ++iaug;
@@ -253,17 +261,52 @@ check_eh_frame (exp, pnbytes)
      expressionS *exp;
      unsigned int *pnbytes;
 {
+  static int saw_size;
+  static symbolS *size_end_sym;
   static int saw_advance_loc4;
   static fragS *loc4_frag;
   static int loc4_fix;
 
+  if (saw_size
+      && S_IS_DEFINED (size_end_sym))
+    {
+      /* We have come to the end of the CIE or FDE.  See below where
+         we set saw_size.  We must check this first because we may now
+         be looking at the next size.  */
+      saw_size = 0;
+      saw_advance_loc4 = 0;
+    }
+
   if (flag_traditional_format)
     {
       /* Don't optimize.  */
     }
   else if (strcmp (segment_name (now_seg), ".eh_frame") != 0)
-    saw_advance_loc4 = 0;
-  else if (*pnbytes == 1
+    {
+      saw_size = 0;
+      saw_advance_loc4 = 0;
+    }
+  else if (! saw_size
+          && *pnbytes == 4)
+    {
+      /* This might be the size of the CIE or FDE.  We want to know
+         the size so that we don't accidentally optimize across an FDE
+         boundary.  We recognize the size in one of two forms: a
+         symbol which will later be defined as a difference, or a
+         subtraction of two symbols.  Either way, we can tell when we
+         are at the end of the FDE because the symbol becomes defined
+         (in the case of a subtraction, the end symbol, from which the
+         start symbol is being subtracted).  Other ways of describing
+         the size will not be optimized.  */
+      if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
+         && ! S_IS_DEFINED (exp->X_add_symbol))
+       {
+         saw_size = 1;
+         size_end_sym = exp->X_add_symbol;
+       }
+    }
+  else if (saw_size
+          && *pnbytes == 1
           && exp->X_op == O_constant
           && exp->X_add_number == DW_CFA_advance_loc4)
     {
This page took 0.023491 seconds and 4 git commands to generate.