88 lines
3.3 KiB
Diff
88 lines
3.3 KiB
Diff
|
From 5ce032bdfc60a8f44f6307b2297384c852100f95 Mon Sep 17 00:00:00 2001
|
||
|
From: Nick Clifton <nickc@redhat.com>
|
||
|
Date: Fri, 19 Apr 2019 10:39:47 +0100
|
||
|
Subject: [PATCH] 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.
|
||
|
---
|
||
|
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/config/tc-rx.c b/gas/config/tc-rx.c
|
||
|
index 8688837b31..6b19f2f397 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 09c50f9471..69302e565b 100644
|
||
|
--- a/gas/config/tc-rx.h
|
||
|
+++ b/gas/config/tc-rx.h
|
||
|
@@ -54,8 +54,15 @@
|
||
|
#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 rx_frag_init
|
||
|
--
|
||
|
2.21.0
|
||
|
|