This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] avoid infinite loops with .align/relax on RX


With enough small .aligns and with relaxation enabled, gas would get
caught in a loop of "grow this, now this can shrink, but then the
other one reaches, so shrink it, now you have to grow this other one
back..."

A simple "timeout" on this waffling back and forth, with a fallback to
"grow only", prevents this looping.  Applied.


	* config/tc-rx.c (rx_bytesT): Add grown/shrank counters for
	relaxation.
	(rx_relax_frag): Prevent infinite loops of grow/shrink/grow/etc.

Index: config/tc-rx.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-rx.c,v
retrieving revision 1.2
diff -p -U3 -r1.2  config/tc-rx.c
--- config/tc-rx.c	14 Dec 2009 10:59:37 -0000	1.2
+++ config/tc-rx.c	2 Jul 2010 19:59:27 -0000
@@ -624,6 +624,8 @@ typedef struct rx_bytesT
   int n_relax;
   int link_relax;
   fixS *link_relax_fixP;
+  char times_grown;
+  char times_shrank;
 } rx_bytesT;
 
 static rx_bytesT rx_bytes;
@@ -1485,6 +1487,21 @@ rx_relax_frag (segT segment ATTRIBUTE_UN
 	break;
       }
 
+  /* This prevents infinite loops in align-heavy sources.  */
+  if (newsize < oldsize)
+    {
+      if (fragP->tc_frag_data->times_shrank > 10
+         && fragP->tc_frag_data->times_grown > 10)
+       newsize = oldsize;
+      if (fragP->tc_frag_data->times_shrank < 20)
+       fragP->tc_frag_data->times_shrank ++;
+    }
+  else if (newsize > oldsize)
+    {
+      if (fragP->tc_frag_data->times_grown < 20)
+       fragP->tc_frag_data->times_grown ++;
+    }
+
   fragP->fr_subtype = newsize;
   tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
   return newsize - oldsize;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]