This is the mail archive of the binutils-cvs@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]

[binutils-gdb] RX Assembler: Ensure that the internal limit on the number of relaxation iterations is not larger th


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5ce032bdfc60a8f44f6307b2297384c852100f95

commit 5ce032bdfc60a8f44f6307b2297384c852100f95
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Apr 19 10:39:47 2019 +0100

    RX Assembler: Ensure that the internal limit on the number of relaxation iterations is not larger that the external limit.
    
    	PR 24464
    	* config/tc-rx.h (md_relax_frag): Pass the max_iterations variable
    	to the relaxation function.
    	* config/tc-rx.c (rx_relax_frag): Add new parameter - the maximum
    	number of iterations.  Make sure that our internal iteration limit
    	does not exceed this external iteration limit.

Diff:
---
 gas/ChangeLog      |  9 +++++++++
 gas/config/tc-rx.c | 19 +++++++++++++------
 gas/config/tc-rx.h | 11 +++++++++--
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 5488ef2..d49ec4d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,12 @@
+2019-04-19  Nick Clifton  <nickc@redhat.com>
+
+	PR 24464
+	* config/tc-rx.h (md_relax_frag): Pass the max_iterations variable
+	to the relaxation function.
+	* config/tc-rx.c (rx_relax_frag): Add new parameter - the maximum
+	number of iterations.  Make sure that our internal iteration limit
+	does not exceed this external iteration limit.
+
 2019-04-18  Matthew Fortune  <matthew.fortune@mips.com>
 
 	* config/tc-mips.c (match_non_zero_reg_operand): Update
diff --git a/gas/config/tc-rx.c b/gas/config/tc-rx.c
index 8688837..6b19f2f 100644
--- a/gas/config/tc-rx.c
+++ b/gas/config/tc-rx.c
@@ -740,8 +740,8 @@ typedef struct rx_bytesT
   int n_relax;
   int link_relax;
   fixS *link_relax_fixP;
-  char times_grown;
-  char times_shrank;
+  unsigned long times_grown;
+  unsigned long times_shrank;
 } rx_bytesT;
 
 static rx_bytesT rx_bytes;
@@ -1558,7 +1558,7 @@ rx_next_opcode (fragS *fragP)
    fr_subtype to calculate the difference.  */
 
 int
-rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
+rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch, unsigned long max_iterations)
 {
   addressT addr0, sym_addr;
   addressT mypc;
@@ -1755,9 +1755,16 @@ rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
   /* 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;
+      /* Make sure that our iteration limit is no bigger than the one being
+	 used inside write.c:relax_segment().  Otherwise we can end up
+	 iterating for too long, and triggering a fatal error there.  See
+	 PR 24464 for more details.  */
+      unsigned long limit = max_iterations > 10 ? 10 : max_iterations;
+
+      if (fragP->tc_frag_data->times_shrank > limit
+	  && fragP->tc_frag_data->times_grown > limit)
+	newsize = oldsize;
+
       if (fragP->tc_frag_data->times_shrank < 20)
        fragP->tc_frag_data->times_shrank ++;
     }
diff --git a/gas/config/tc-rx.h b/gas/config/tc-rx.h
index 09c50f9..69302e5 100644
--- a/gas/config/tc-rx.h
+++ b/gas/config/tc-rx.h
@@ -54,8 +54,15 @@ extern int target_big_endian;
 #define md_end rx_md_end
 extern void rx_md_end (void);
 
-#define md_relax_frag rx_relax_frag
-extern int rx_relax_frag (segT, fragS *, long);
+/* Note - the definition of MD_RELAX_FRAG here includes a reference to the
+   MAX_ITERATIONS variable which is defined locally in write.c:relax_segment()
+   but which is not normally passed to target specific relaxing code.  This
+   reference is needed however as the number of iterations of the RX relaxing
+   code needs to be constrained by the maximum number of iterations allowed
+   by relax_segment().  See PR 24464 for more details.  */
+#define md_relax_frag(SEG, FRAGP, STRETCH) \
+  rx_relax_frag ((SEG), (FRAGP), (STRETCH), max_iterations)
+extern int rx_relax_frag (segT, fragS *, long, unsigned long);
 
 #define TC_FRAG_TYPE struct rx_bytesT *
 #define TC_FRAG_INIT(fragp, max_bytes) rx_frag_init (fragp)


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