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: PR gas/4029: relax_segment can't stabilize .gcc_except_table


The problem is with rs_leb128 processing. When size needed for
the new value is 0x3fff is 2 and the old size is 3, growth is -1. Then
the next time the new value becomes 0x4000 and its size becomes 3. That
is an infinite loop.

This patch breaks the infinite loop by growing the size by 1 instead
of shrinking it by 1 when there are 3 growths after 3 shrinks.


H.J.
----
2007-02-19  H.J. Lu  <hongjiu.lu@intel.com>

	PR gas/4029
	* frags.h (frag): Add growths and shrinks.

	* write.c (relax_segment): Break infinite loop for rs_leb128.

--- gas/frags.h.relax	2006-04-18 02:58:26.000000000 -0700
+++ gas/frags.h	2007-02-18 18:51:23.000000000 -0800
@@ -77,6 +77,11 @@ struct frag {
   unsigned int has_code:1;
   unsigned int insn_addr:6;
 
+  /* Remember previous growths/shrinks to avoid infinite loop during
+     relaxation.  */
+  unsigned int growths: 2;
+  unsigned int shrinks: 2;
+
   /* What state is my tail in? */
   relax_stateT fr_type;
   relax_substateT fr_subtype;
--- gas/write.c.relax	2007-02-17 16:02:34.000000000 -0800
+++ gas/write.c	2007-02-18 18:49:43.000000000 -0800
@@ -2258,7 +2258,26 @@ relax_segment (struct frag *segment_frag
 		  value = resolve_symbol_value (fragP->fr_symbol);
 		  size = sizeof_leb128 (value, fragP->fr_subtype);
 		  growth = size - fragP->fr_offset;
-		  fragP->fr_offset = size;
+		  if (growth == -1
+		      && fragP->growths == 0x3
+		      && fragP->shrinks == 0x3)
+		    {
+		      /* There are 3 growths after 3 shrinks. To break
+			 infinite loop, we grow the size by 1 instead of
+			 shrink it by 1.  */
+		      growth = 1;
+		    }
+		  else
+		    {
+		      fragP->fr_offset = size;
+		      if (growth == -1 && fragP->shrinks != 0x3)
+			fragP->shrinks++;
+		      /* Start counting growth after the first shrink.  */
+		      if (fragP->shrinks
+			  && growth == 1
+			  && fragP->growths != 3)
+			fragP->growths++;
+		    }
 		}
 		break;
 


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