* expr.c, write.c: Ultrix native 4.2 cc requires assert condition
authorIan Lance Taylor <ian@airs.com>
Fri, 12 Mar 1993 20:01:28 +0000 (20:01 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 12 Mar 1993 20:01:28 +0000 (20:01 +0000)
to be on a single line.

gas/ChangeLog
gas/expr.c
gas/write.c

index c6a64e915f7895bb86705977e7a5544933b7bd51..fd3ff162101af3c3f19c855e53988ec60627b63f 100644 (file)
@@ -1,3 +1,8 @@
+Fri Mar 12 12:00:07 1993  Ian Lance Taylor  (ian@cygnus.com)
+
+       * expr.c, write.c: Ultrix native 4.2 cc requires assert condition
+       to be on a single line.
+
 Thu Mar 11 17:56:22 1993  Ken Raeburn  (raeburn@cambridge.cygnus.com)
 
        * Makefile.in (config.h): Create file, writing out definitions of
index bfcb8e658f5ec2129425c8999fc6fbdec2b00188..bc083748ccd11e9366b3099a3d076460c48c73a5 100644 (file)
@@ -1,5 +1,5 @@
 /* expr.c -operands, expressions-
-   Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 
 #include "obstack.h"
 
-#if __STDC__ == 1
-static void clean_up_expression (expressionS * expressionP);
-#else /* __STDC__ */
-static void clean_up_expression ();    /* Internal. */
-#endif /* not __STDC__ */
-extern const char EXP_CHARS[]; /* JF hide MD floating pt stuff all the same place */
-extern const char FLT_CHARS[];
+static void clean_up_expression PARAMS ((expressionS * expressionP));
+extern const char EXP_CHARS[], FLT_CHARS[];
 
 /*
  * Build any floating-point literal here.
  * Also build any bignum literal here.
  */
 
-/* LITTLENUM_TYPE      generic_buffer [6]; *//* JF this is a hack */
 /* Seems atof_machine can backscan through generic_bignum and hit whatever
    happens to be loaded before it in memory.  And its way too complicated
    for me to fix right.  Thus a hack.  JF:  Just make generic_bignum bigger,
    and never write into the early words, thus they'll always be zero.
-   I hate Dean's floating-point code.  Bleh.
-   */
+   I hate Dean's floating-point code.  Bleh.  */
 LITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
 FLONUM_TYPE generic_floating_point_number =
 {
@@ -85,7 +78,7 @@ floating_constant (expressionP)
          as_bad ("bad floating-point constant: unknown error code=%d.", error_code);
        }
     }
-  expressionP->X_seg = SEG_BIG;
+  expressionP->X_seg = big_section;
   /* input_line_pointer->just after constant, */
   /* which may point to whitespace. */
   expressionP->X_add_number = -1;
@@ -108,7 +101,7 @@ integer_constant (radix, expressionP)
   register symbolS *symbolP;   /* points to symbol */
 
   int small;                   /* true if fits in 32 bits. */
-  extern char hex_value[];     /* in hex_value.c */
+  extern const char hex_value[]; /* in hex_value.c */
 
   /* may be bignum, or may fit in 32 bits. */
   /*
@@ -248,7 +241,7 @@ integer_constant (radix, expressionP)
            else
              {                 /* either not seen or not defined. */
                as_bad ("backw. ref to unknown label \"%d:\", 0 assumed.", number);
-               expressionP->X_seg = SEG_ABSOLUTE;
+               expressionP->X_seg = absolute_section;
              }
 
            expressionP->X_add_number = 0;
@@ -271,10 +264,10 @@ integer_constant (radix, expressionP)
 #ifndef many_segments
            /* since "know" puts its arg into a "string", we
               can't have newlines in the argument.  */
-           know (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN || S_GET_SEGMENT (symbolP) == SEG_TEXT || S_GET_SEGMENT (symbolP) == SEG_DATA);
+           know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
 #endif
            expressionP->X_add_symbol = symbolP;
-           expressionP->X_seg = SEG_UNKNOWN;
+           expressionP->X_seg = undefined_section;
            expressionP->X_subtract_symbol = NULL;
            expressionP->X_add_number = 0;
 
@@ -317,7 +310,7 @@ integer_constant (radix, expressionP)
        default:
          {
            expressionP->X_add_number = number;
-           expressionP->X_seg = SEG_ABSOLUTE;
+           expressionP->X_seg = absolute_section;
            input_line_pointer--;       /* restore following character. */
            break;
          }                     /* really just a number */
@@ -329,7 +322,7 @@ integer_constant (radix, expressionP)
   else
     {                          /* not a small number */
       expressionP->X_add_number = number;
-      expressionP->X_seg = SEG_BIG;
+      expressionP->X_seg = big_section;
       input_line_pointer--;    /*->char following number. */
     }                          /* if (small) */
 }                              /* integer_constant() */
@@ -414,7 +407,7 @@ operand (expressionP)
              /* The string was only zero */
              expressionP->X_add_symbol = 0;
              expressionP->X_add_number = 0;
-             expressionP->X_seg = SEG_ABSOLUTE;
+             expressionP->X_seg = absolute_section;
            }
 
          break;
@@ -479,6 +472,7 @@ operand (expressionP)
 
          input_line_pointer++;
          floating_constant (expressionP);
+         expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);
          break;
 
 #ifdef LOCAL_LABELS_DOLLAR
@@ -509,18 +503,17 @@ operand (expressionP)
         permitted for a single quote. The next character, parity errors and
         all, is taken as the value of the operand. VERY KINKY.  */
       expressionP->X_add_number = *input_line_pointer++;
-      expressionP->X_seg = SEG_ABSOLUTE;
+      expressionP->X_seg = absolute_section;
       break;
 
     case '~':
     case '-':
     case '+':
-
       {
        /* unary operator: hope for SEG_ABSOLUTE */
-       switch (operand (expressionP))
+       segT opseg = operand (expressionP);
+       if (opseg == absolute_section)
          {
-         case SEG_ABSOLUTE:
            /* input_line_pointer -> char after operand */
            if (c == '-')
              {
@@ -532,29 +525,26 @@ operand (expressionP)
              {
                expressionP->X_add_number = ~expressionP->X_add_number;
              }
-           break;
-
-         case SEG_TEXT:
-         case SEG_DATA:
-         case SEG_BSS:
-         case SEG_PASS1:
-         case SEG_UNKNOWN:
+         }
+       else if (opseg == text_section
+                || opseg == data_section
+                || opseg == bss_section
+                || opseg == pass1_section
+                || opseg == undefined_section)
+         {
            if (c == '-')
-             {                 /* JF I hope this hack works */
+             {
                expressionP->X_subtract_symbol = expressionP->X_add_symbol;
                expressionP->X_add_symbol = 0;
-               expressionP->X_seg = SEG_DIFFERENCE;
-               break;
+               expressionP->X_seg = diff_section;
              }
-         default:              /* unary on non-absolute is unsuported */
-           as_warn ("Unary operator %c ignored because bad operand follows", c);
-           break;
-           /* Expression undisturbed from operand(). */
+           else
+             as_warn ("Unary operator %c ignored because bad operand follows",
+                      c);
          }
+       else
+         as_warn ("Unary operator %c ignored because bad operand follows", c);
       }
-
-
-
       break;
 
     case '.':
@@ -589,9 +579,10 @@ operand (expressionP)
        }
     case ',':
     case '\n':
+    case '\0':
     eol:
       /* can't imagine any other kind of operand */
-      expressionP->X_seg = SEG_ABSENT;
+      expressionP->X_seg = absent_section;
       input_line_pointer--;
       md_operand (expressionP);
       break;
@@ -612,14 +603,11 @@ operand (expressionP)
          /* If we have an absolute symbol or a reg, then we know its value
             now.  */
          expressionP->X_seg = S_GET_SEGMENT (symbolP);
-         switch (expressionP->X_seg)
+         if (expressionP->X_seg == absolute_section
+             || expressionP->X_seg == reg_section)
+           expressionP->X_add_number = S_GET_VALUE (symbolP);
+         else
            {
-           case SEG_ABSOLUTE:
-           case SEG_REGISTER:
-             expressionP->X_add_number = S_GET_VALUE (symbolP);
-             break;
-
-           default:
              expressionP->X_add_number = 0;
              expressionP->X_add_symbol = symbolP;
            }
@@ -630,18 +618,10 @@ operand (expressionP)
        {
          as_bad ("Bad expression");
          expressionP->X_add_number = 0;
-         expressionP->X_seg = SEG_ABSOLUTE;
-
+         expressionP->X_seg = absolute_section;
        }
-
     }
 
-
-
-
-
-
-
   /*
    * It is more 'efficient' to clean up the expressionS when they are created.
    * Doing it here saves lines of code.
@@ -670,32 +650,30 @@ static void
 clean_up_expression (expressionP)
      register expressionS *expressionP;
 {
-  switch (expressionP->X_seg)
+  segT s = expressionP->X_seg;
+  if (s == absent_section
+      || s == pass1_section)
     {
-    case SEG_ABSENT:
-    case SEG_PASS1:
       expressionP->X_add_symbol = NULL;
       expressionP->X_subtract_symbol = NULL;
       expressionP->X_add_number = 0;
-      break;
-
-    case SEG_BIG:
-    case SEG_ABSOLUTE:
+    }
+  else if (s == big_section
+          || s == absolute_section)
+    {
       expressionP->X_subtract_symbol = NULL;
       expressionP->X_add_symbol = NULL;
-      break;
-
-    case SEG_UNKNOWN:
-      expressionP->X_subtract_symbol = NULL;
-      break;
-
-    case SEG_DIFFERENCE:
+    }
+  else if (s == undefined_section)
+    expressionP->X_subtract_symbol = NULL;
+  else if (s == diff_section)
+    {
       /*
-        * It does not hurt to 'cancel' NULL==NULL
-        * when comparing symbols for 'eq'ness.
-        * It is faster to re-cancel them to NULL
-        * than to check for this special case.
-        */
+       * It does not hurt to 'cancel' NULL==NULL
+       * when comparing symbols for 'eq'ness.
+       * It is faster to re-cancel them to NULL
+       * than to check for this special case.
+       */
       if (expressionP->X_subtract_symbol == expressionP->X_add_symbol
          || (expressionP->X_subtract_symbol
              && expressionP->X_add_symbol
@@ -704,16 +682,16 @@ clean_up_expression (expressionP)
        {
          expressionP->X_subtract_symbol = NULL;
          expressionP->X_add_symbol = NULL;
-         expressionP->X_seg = SEG_ABSOLUTE;
+         expressionP->X_seg = absolute_section;
        }
-      break;
-
-    case SEG_REGISTER:
+    }
+  else if (s == reg_section)
+    {
       expressionP->X_add_symbol = NULL;
       expressionP->X_subtract_symbol = NULL;
-      break;
-
-    default:
+    }
+  else
+    {
       if (SEG_NORMAL (expressionP->X_seg))
        {
          expressionP->X_subtract_symbol = NULL;
@@ -722,9 +700,8 @@ clean_up_expression (expressionP)
        {
          BAD_CASE (expressionP->X_seg);
        }
-      break;
     }
-}                              /* clean_up_expression() */
+}
 \f
 /*
  *                     expr_part ()
@@ -744,8 +721,16 @@ expr_part (symbol_1_PP, symbol_2_P)
 {
   segT return_value;
 #ifndef MANY_SEGMENTS
-  know ((*symbol_1_PP) == NULL || (S_GET_SEGMENT (*symbol_1_PP) == SEG_TEXT) || (S_GET_SEGMENT (*symbol_1_PP) == SEG_DATA) || (S_GET_SEGMENT (*symbol_1_PP) == SEG_BSS) || (!S_IS_DEFINED (*symbol_1_PP)));
-  know (symbol_2_P == NULL || (S_GET_SEGMENT (symbol_2_P) == SEG_TEXT) || (S_GET_SEGMENT (symbol_2_P) == SEG_DATA) || (S_GET_SEGMENT (symbol_2_P) == SEG_BSS) || (!S_IS_DEFINED (symbol_2_P)));
+  assert ((*symbol_1_PP) == NULL \
+         || (S_GET_SEGMENT (*symbol_1_PP) == text_section) \
+         || (S_GET_SEGMENT (*symbol_1_PP) == data_section) \
+         || (S_GET_SEGMENT (*symbol_1_PP) == bss_section) \
+         || (!S_IS_DEFINED (*symbol_1_PP)));
+  assert (symbol_2_P == NULL \
+         || (S_GET_SEGMENT (symbol_2_P) == text_section) \
+         || (S_GET_SEGMENT (symbol_2_P) == data_section) \
+         || (S_GET_SEGMENT (symbol_2_P) == bss_section) \
+         || (!S_IS_DEFINED (symbol_2_P)));
 #endif
   if (*symbol_1_PP)
     {
@@ -753,13 +738,13 @@ expr_part (symbol_1_PP, symbol_2_P)
        {
          if (symbol_2_P)
            {
-             return_value = SEG_PASS1;
+             return_value = pass1_section;
              *symbol_1_PP = NULL;
            }
          else
            {
              know (!S_IS_DEFINED (*symbol_1_PP));
-             return_value = SEG_UNKNOWN;
+             return_value = undefined_section;
            }
        }
       else
@@ -769,7 +754,7 @@ expr_part (symbol_1_PP, symbol_2_P)
              if (!S_IS_DEFINED (symbol_2_P))
                {
                  *symbol_1_PP = NULL;
-                 return_value = SEG_PASS1;
+                 return_value = pass1_section;
                }
              else
                {
@@ -777,7 +762,7 @@ expr_part (symbol_1_PP, symbol_2_P)
                  as_bad ("Expression too complex, 2 symbolS forgotten: \"%s\" \"%s\"",
                        S_GET_NAME (*symbol_1_PP), S_GET_NAME (symbol_2_P));
                  *symbol_1_PP = NULL;
-                 return_value = SEG_ABSOLUTE;
+                 return_value = absolute_section;
                }
            }
          else
@@ -796,15 +781,21 @@ expr_part (symbol_1_PP, symbol_2_P)
       else
        {
          *symbol_1_PP = NULL;
-         return_value = SEG_ABSOLUTE;
+         return_value = absolute_section;
        }
     }
 #ifndef MANY_SEGMENTS
-  know (return_value == SEG_ABSOLUTE || return_value == SEG_TEXT || return_value == SEG_DATA || return_value == SEG_BSS || return_value == SEG_UNKNOWN || return_value == SEG_PASS1);
+  assert (return_value == absolute_section \
+         || return_value == text_section \
+         || return_value == data_section \
+         || return_value == bss_section \
+         || return_value == undefined_section \
+         || return_value == pass1_section);
 #endif
-  know ((*symbol_1_PP) == NULL || (S_GET_SEGMENT (*symbol_1_PP) == return_value));
+  know ((*symbol_1_PP) == NULL
+       || (S_GET_SEGMENT (*symbol_1_PP) == return_value));
   return (return_value);
-}                              /* expr_part() */
+}
 \f
 /* Expression parser. */
 
@@ -913,13 +904,13 @@ expr (rank, resultP)
        {
          input_line_pointer++;
        }                       /*->after operator. */
-      if (SEG_ABSENT == expr (op_rank[(int) op_left], &right))
+      if (absent_section == expr (op_rank[(int) op_left], &right))
        {
          as_warn ("Missing operand value assumed absolute 0.");
          resultP->X_add_number = 0;
          resultP->X_subtract_symbol = NULL;
          resultP->X_add_symbol = NULL;
-         resultP->X_seg = SEG_ABSOLUTE;
+         resultP->X_seg = absolute_section;
        }
       know (*input_line_pointer != ' ');
       c_right = *input_line_pointer;
@@ -933,26 +924,26 @@ expr (rank, resultP)
       /* left-hand quantity in resultP */
       /* right-hand quantity in right. */
       /* operator in op_left. */
-      if (resultP->X_seg == SEG_PASS1 || right.X_seg == SEG_PASS1)
+      if (resultP->X_seg == pass1_section || right.X_seg == pass1_section)
        {
-         resultP->X_seg = SEG_PASS1;
+         resultP->X_seg = pass1_section;
        }
       else
        {
-         if (resultP->X_seg == SEG_BIG)
+         if (resultP->X_seg == big_section)
            {
              as_warn ("Left operand of %c is a %s.  Integer 0 assumed.",
                    c_left, resultP->X_add_number > 0 ? "bignum" : "float");
-             resultP->X_seg = SEG_ABSOLUTE;
+             resultP->X_seg = absolute_section;
              resultP->X_add_symbol = 0;
              resultP->X_subtract_symbol = 0;
              resultP->X_add_number = 0;
            }
-         if (right.X_seg == SEG_BIG)
+         if (right.X_seg == big_section)
            {
              as_warn ("Right operand of %c is a %s.  Integer 0 assumed.",
                       c_left, right.X_add_number > 0 ? "bignum" : "float");
-             right.X_seg = SEG_ABSOLUTE;
+             right.X_seg = absolute_section;
              right.X_add_symbol = 0;
              right.X_subtract_symbol = 0;
              right.X_add_number = 0;
@@ -974,7 +965,7 @@ expr (rank, resultP)
              right.X_subtract_symbol = symbolP;
              if (symbolP)
                {
-                 right.X_seg = SEG_DIFFERENCE;
+                 right.X_seg = diff_section;
                }
              op_left = O_add;
            }
@@ -985,63 +976,63 @@ expr (rank, resultP)
              segT seg2;
 #ifndef MANY_SEGMENTS
 
-             know (resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg == SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1 || resultP->X_seg == SEG_REGISTER);
+             know (resultP->X_seg == data_section || resultP->X_seg == text_section || resultP->X_seg == bss_section || resultP->X_seg == undefined_section || resultP->X_seg == diff_section || resultP->X_seg == absolute_section || resultP->X_seg == pass1_section || resultP->X_seg == reg_section);
 
-             know (right.X_seg == SEG_DATA || right.X_seg == SEG_TEXT || right.X_seg == SEG_BSS || right.X_seg == SEG_UNKNOWN || right.X_seg == SEG_DIFFERENCE || right.X_seg == SEG_ABSOLUTE || right.X_seg == SEG_PASS1);
+             know (right.X_seg == data_section || right.X_seg == text_section || right.X_seg == bss_section || right.X_seg == undefined_section || right.X_seg == diff_section || right.X_seg == absolute_section || right.X_seg == pass1_section);
 #endif
              clean_up_expression (&right);
              clean_up_expression (resultP);
 
              seg1 = expr_part (&resultP->X_add_symbol, right.X_add_symbol);
              seg2 = expr_part (&resultP->X_subtract_symbol, right.X_subtract_symbol);
-             if (seg1 == SEG_PASS1 || seg2 == SEG_PASS1)
+             if (seg1 == pass1_section || seg2 == pass1_section)
                {
                  need_pass_2 = 1;
-                 resultP->X_seg = SEG_PASS1;
+                 resultP->X_seg = pass1_section;
                }
-             else if (seg2 == SEG_ABSOLUTE)
+             else if (seg2 == absolute_section)
                resultP->X_seg = seg1;
-             else if (seg1 != SEG_UNKNOWN
-                      && seg1 != SEG_ABSOLUTE
-                      && seg2 != SEG_UNKNOWN
+             else if (seg1 != undefined_section
+                      && seg1 != absolute_section
+                      && seg2 != undefined_section
                       && seg1 != seg2)
                {
-                 know (seg2 != SEG_ABSOLUTE);
+                 know (seg2 != absolute_section);
                  know (resultP->X_subtract_symbol);
 #ifndef MANY_SEGMENTS
-                 know (seg1 == SEG_TEXT || seg1 == SEG_DATA || seg1 == SEG_BSS);
-                 know (seg2 == SEG_TEXT || seg2 == SEG_DATA || seg2 == SEG_BSS);
+                 know (seg1 == text_section || seg1 == data_section || seg1 == bss_section);
+                 know (seg2 == text_section || seg2 == data_section || seg2 == bss_section);
 #endif
                  know (resultP->X_add_symbol);
                  know (resultP->X_subtract_symbol);
                  as_bad ("Expression too complex: forgetting %s - %s",
                          S_GET_NAME (resultP->X_add_symbol),
                          S_GET_NAME (resultP->X_subtract_symbol));
-                 resultP->X_seg = SEG_ABSOLUTE;
+                 resultP->X_seg = absolute_section;
                  /* Clean_up_expression() will do the rest. */
                }
              else
-               resultP->X_seg = SEG_DIFFERENCE;
+               resultP->X_seg = diff_section;
 
              resultP->X_add_number += right.X_add_number;
              clean_up_expression (resultP);
            }
          else
            {                   /* Not +. */
-             if (resultP->X_seg == SEG_UNKNOWN || right.X_seg == SEG_UNKNOWN)
+             if (resultP->X_seg == undefined_section || right.X_seg == undefined_section)
                {
-                 resultP->X_seg = SEG_PASS1;
+                 resultP->X_seg = pass1_section;
                  need_pass_2 = 1;
                }
              else
                {
                  resultP->X_subtract_symbol = NULL;
                  resultP->X_add_symbol = NULL;
-                 /* Will be SEG_ABSOLUTE. */
-                 if (resultP->X_seg != SEG_ABSOLUTE || right.X_seg != SEG_ABSOLUTE)
+                 /* Will be absolute_section. */
+                 if (resultP->X_seg != absolute_section || right.X_seg != absolute_section)
                    {
                      as_bad ("Relocation error. Absolute 0 assumed.");
-                     resultP->X_seg = SEG_ABSOLUTE;
+                     resultP->X_seg = absolute_section;
                      resultP->X_add_number = 0;
                    }
                  else
index 4e207f9bd57f09d1dc535ca38db90b2de6d23f01..0c550b991740a313b73b418506f1bea74483296e 100644 (file)
@@ -214,7 +214,13 @@ chain_frchains_together (abfd, section, xxx)
      segT section;
      char *xxx;                        /* unused */
 {
-  chain_frchains_together_1 (section, seg_info (section)->frchainP);
+  segment_info_type *info;
+
+  /* BFD may have introduced its own sections without using
+     subseg_new, so it is possible that seg_info is NULL.  */
+  info = seg_info (section);
+  if (info != (segment_info_type *) NULL)
+    chain_frchains_together_1 (section, info->frchainP);
 }
 
 #endif
@@ -277,8 +283,8 @@ cvt_frag_to_fill (x, fragP)
       md_convert_frag (headers, fragP);
 #endif
 
-      assert (fragP->fr_next == NULL
-             || (fragP->fr_next->fr_address - fragP->fr_address
+      assert (fragP->fr_next == NULL \
+             || (fragP->fr_next->fr_address - fragP->fr_address \
                  == fragP->fr_fix));
 
       /*
@@ -557,9 +563,9 @@ write_object_file ()
      @@ Is this really necessary??  */
 #ifndef SUB_SEGMENT_ALIGN
 #ifdef BFD_ASSEMBLER
-#define SUB_SEGMENT_ALIGN (0)
+#define SUB_SEGMENT_ALIGN(SEG) (0)
 #else
-#define SUB_SEGMENT_ALIGN (2)
+#define SUB_SEGMENT_ALIGN(SEG) (2)
 #endif
 #endif
   for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
@@ -569,7 +575,7 @@ write_object_file ()
 #else
       subseg_new (frchainP->frch_seg, frchainP->frch_subseg);
 #endif
-      frag_align (SUB_SEGMENT_ALIGN, NOP_OPCODE);
+      frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE);
       /* frag_align will have left a new frag.
         Use this last frag for an empty ".fill".
 
@@ -1003,9 +1009,6 @@ write_object_file ()
                         text_frag_root, data_frag_root);
 #endif /* VMS */
 #else /* BFD_ASSEMBLER */
-#ifdef obj_frob_file
-  obj_frob_file ();
-#endif
 
   /* Set up symbol table, and write it out.  */
   if (symbol_rootP)
@@ -1105,6 +1108,10 @@ write_object_file ()
        }
     }
 
+#ifdef obj_frob_file
+  obj_frob_file ();
+#endif
+
   /* Now that all the sizes are known, and contents correct, we can
      start writing the file.  */
   bfd_map_over_sections (stdoutput, write_contents, (char *) 0);