Handle .space directive with non-constant operand:
authorKen Raeburn <raeburn@cygnus>
Sat, 31 Dec 1994 00:08:40 +0000 (00:08 +0000)
committerKen Raeburn <raeburn@cygnus>
Sat, 31 Dec 1994 00:08:40 +0000 (00:08 +0000)
* read.c (s_space): Rewrite to handle general expressions.  Generate rs_space
frags for non-constant values.
* write.c (cvt_frag_to_fill): Treat rs_align_code and rs_space like rs_align
and rs_org.  Verify that fr_offset is non-negative, and force frag type to
rs_fill only after assertion checks.
(relax_segment): Treat rs_align_code like rs_align.  Treat rs_space like rs_org
in the first switch; in the second, force the operand to a constant, and use it
for the growth size.

gas/ChangeLog
gas/read.c
gas/write.c

index a70423925470dd28e7caff406f0d7ea5333fe6b2..80a4a12a5b403491298a6616d7033fdda6146b81 100644 (file)
@@ -9,6 +9,28 @@ Fri Dec 30 18:21:41 1994  Ken Raeburn  <raeburn@cujo.cygnus.com>
        everything it includes.  Delete those files from per-file
        dependencies.
 
+       * as.h (relax_substateT): Now defined to be unsigned int.
+       (relax_stateT): Separate typedef from enum definition.
+       (enum _relax_state): Reordered for better punctuation.  Added new
+       values rs_align_code and rs_space.
+       (lineno, struct lineno_struct): Unused, deleted.
+
+       * as.h: No longer include assert.h.
+       (as_assert): Declare.
+       (assert): New definition, calls as_assert longer needed.
+       (__PRETTY_FUNCTION__): Provide default for older versions of gcc.
+       * messages.c (as_assert): New function.
+       * gdbinit.in: Put a breakpoint there.
+
+       * read.c (s_space): Rewrite to handle general expressions.
+       Generate rs_space frags for non-constant values.
+       * write.c (cvt_frag_to_fill): Treat rs_align_code and rs_space
+       like rs_align and rs_org.  Verify that fr_offset is non-negative,
+       and force frag type to rs_fill only after assertion checks.
+       (relax_segment): Treat rs_align_code like rs_align.  Treat
+       rs_space like rs_org in the first switch; in the second, force the
+       operand to a constant, and use it for the growth size.
+
 Wed Dec 28 20:57:37 1994  Jeff Law  (law@snake.cs.utah.edu)
 
        * config/tc-hppa.c (pa_subspace): For sections with the ZERO
index 3bedd149e7ca6cebe16090886b2e49c888fb4125..2b20177d3f16b8446d41386dc8b090c76d58adfa 100644 (file)
@@ -1425,38 +1425,54 @@ void
 s_space (mult)
      int mult;
 {
-  long temp_repeat;
-  register long temp_fill;
-  register char *p;
+  expressionS exp;
+  long temp_repeat, temp_fill;
+  char *p = 0;
 
   /* Just like .fill, but temp_size = 1 */
-  if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
+  expression (&exp);
+  if (exp.X_op == O_constant
+      /* for testing purposes */
+      && 0)
     {
-      temp_fill = get_absolute_expression ();
+      long repeat;
+
+      repeat = exp.X_add_number;
+      if (mult)
+       repeat *= mult;
+      if (repeat <= 0)
+       {
+         as_warn (".space repeat count is %s, ignored",
+                  repeat ? "negative" : "zero");
+         ignore_rest_of_line ();
+         return;
+       }
+
+      if (!need_pass_2)
+       p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
+                     temp_repeat, (char *) 0);
     }
   else
     {
-      input_line_pointer--;    /* Backup over what was not a ','. */
-      temp_fill = 0;
+      if (!need_pass_2)
+       p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
+                     make_expr_symbol (&exp), 0L, (char *) 0);
     }
-  if (mult)
+  if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
     {
-      temp_repeat *= mult;
+      temp_fill = get_absolute_expression ();
     }
-  if (temp_repeat <= 0)
+  else
     {
-      as_warn ("Repeat < 0, .space ignored");
-      ignore_rest_of_line ();
-      return;
+      input_line_pointer--;    /* Backup over what was not a ','. */
+      temp_fill = 0;
     }
-  if (!need_pass_2)
+  if (p)
     {
-      p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
-                   temp_repeat, (char *) 0);
       *p = temp_fill;
     }
   demand_empty_rest_of_line ();
-}                              /* s_space() */
+}
 
 void
 s_text (ignore)
@@ -1969,7 +1985,7 @@ parse_bitfield_cons (exp, nbytes)
             widths, positions, and masks which most
             of our current object formats don't
             support.
-            
+
             In the specific case where a symbol
             *is* defined in this assembly, we
             *could* build fixups and track it, but
@@ -2481,7 +2497,7 @@ get_absolute_expression ()
   if (exp.X_op != O_constant)
     {
       if (exp.X_op != O_absent)
-       as_bad ("bad absolute expression; zero assumed");
+       as_bad ("bad or irreducible absolute expression; zero assumed");
       exp.X_add_number = 0;
     }
   return exp.X_add_number;
index b362670255bc194ba2a5602a4e9a659b666eb750..7cdf2c2008e38a88d1753edcce4fc9ae4843fc46 100644 (file)
@@ -419,15 +419,18 @@ cvt_frag_to_fill (headers, fragP)
   switch (fragP->fr_type)
     {
     case rs_align:
+    case rs_align_code:
     case rs_org:
+    case rs_space:
 #ifdef HANDLE_ALIGN
       HANDLE_ALIGN (fragP);
 #endif
-      fragP->fr_type = rs_fill;
       know (fragP->fr_next != NULL);
       fragP->fr_offset = (fragP->fr_next->fr_address
                          - fragP->fr_address
                          - fragP->fr_fix) / fragP->fr_var;
+      assert (fragP->fr_offset >= 0);
+      fragP->fr_type = rs_fill;
       break;
 
     case rs_fill:
@@ -625,8 +628,8 @@ adjust_reloc_syms (abfd, sec, xxx)
           md_estimate_size_before_relax in tc-mips.c uses this test
           as well, so if you change this code you should look at that
           code.  */
-       if (symsec == &bfd_und_section
-           || symsec == &bfd_abs_section
+       if (bfd_is_und_section (symsec)
+           || bfd_is_abs_section (symsec)
            || bfd_is_com_section (symsec))
          {
            fixp->fx_addsy->sy_used_in_reloc = 1;
@@ -1731,6 +1734,7 @@ relax_segment (segment_frag_root, segment)
          break;
 
        case rs_align:
+       case rs_align_code:
          {
            int offset = relax_align (address, (int) fragP->fr_offset);
            if (offset % fragP->fr_var != 0)
@@ -1744,6 +1748,7 @@ relax_segment (segment_frag_root, segment)
          break;
 
        case rs_org:
+       case rs_space:
          /* Assume .org is nugatory. It will grow with 1st relax.  */
          break;
 
@@ -1859,6 +1864,7 @@ relax_segment (segment_frag_root, segment)
                }               /* case rs_broken_word */
 #endif
              case rs_align:
+             case rs_align_code:
                growth = (relax_align ((relax_addressT) (address
                                                         + fragP->fr_fix),
                                       (int) offset)
@@ -1895,6 +1901,23 @@ relax_segment (segment_frag_root, segment)
                growth -= stretch;      /* This is an absolute growth factor */
                break;
 
+             case rs_space:
+               if (symbolP)
+                 {
+                   growth = S_GET_VALUE (symbolP);
+                   if (symbolP->sy_frag != &zero_address_frag)
+                     as_bad (".space specifies non-absolute value");
+                   fragP->fr_symbol = 0;
+                   if (growth < 0)
+                     {
+                       as_warn (".space or .fill with negative value, ignored");
+                       growth = 0;
+                     }
+                 }
+               else
+                 growth = 0;
+               break;
+
              case rs_machine_dependent:
 #ifdef md_relax_frag
                growth = md_relax_frag (fragP, stretch);