bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: infinate loop in as with .org pseudo


From: Nick Clifton
Subject: Re: infinate loop in as with .org pseudo
Date: Wed, 17 Aug 2005 18:59:14 +0100
User-agent: Mozilla Thunderbird 1.0 (X11/20041206)

Hi Dan,

Given this as input (three lines):

 foo = .
 .org foo+16
 foo = .

GNU as (with no special command-line options) apparently goes into an
infinate loop.

Not surprising really since that is a pathological piece of code. Still infinite loops are bad things, so please could you try out the attached patch and let me know if it works for you.

Cheers
  Nick



Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.93
diff -c -3 -p -r1.93 write.c
*** gas/write.c 11 Aug 2005 01:25:20 -0000      1.93
--- gas/write.c 17 Aug 2005 17:50:01 -0000
*************** relax_segment (struct frag *segment_frag
*** 1731,1737 ****
    /* For each frag in segment: count and store  (a 1st guess of)
       fr_address.  */
    address = 0;
!   for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
      {
        fragP->relax_marker = 0;
        fragP->fr_address = address;
--- 1732,1740 ----
    /* For each frag in segment: count and store  (a 1st guess of)
       fr_address.  */
    address = 0;
!   for (frag_count = 0, fragP = segment_frag_root;
!        fragP;
!        fragP = fragP->fr_next, frag_count ++)
      {
        fragP->relax_marker = 0;
        fragP->fr_address = address;
*************** relax_segment (struct frag *segment_frag
*** 1807,1812 ****
--- 1810,1816 ----
  
    /* Do relax().  */
    {
+     unsigned long max_iterations;
      offsetT stretch;  /* May be any size, 0 or negative.  */
      /* Cumulative number of addresses we have relaxed this pass.
         We may have relaxed more than one address.  */
*************** relax_segment (struct frag *segment_frag
*** 1815,1820 ****
--- 1819,1838 ----
         grew, and another shrank.  If a branch instruction doesn't fit anymore,
         we could be scrod.  */
  
+     /* We want to prevent going into an infinite loop where one frag grows
+        depending upon the location of a symbol which is in turn moved by#
+        the growing frag.  eg:
+ 
+          foo = .
+          .org foo+16
+          foo = .
+ 
+       So we dictate that this algorithm can be at most O2.  */
+     max_iterations = frag_count * frag_count;
+     /* Check for overflow.  */
+     if (max_iterations < frag_count)
+       max_iterations = frag_count;
+ 
      do
        {
        stretch = 0;
*************** relax_segment (struct frag *segment_frag
*** 2035,2042 ****
              }
          }                     /* For each frag in the segment.  */
        }
!     while (stretched);                /* Until nothing further to relax.  */
!   }                           /* do_relax  */
  
    ret = 0;
    for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
--- 2053,2063 ----
              }
          }                     /* For each frag in the segment.  */
        }
!     while (stretched && -- max_iterations);           /* Until nothing 
further to relax.  */
! 
!     if (stretched)
!       as_fatal (_("Infinite loop encountered whilst attempting to compute the 
size of section %s"), segment_name (segment));
!   }
  
    ret = 0;
    for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]