diff options
author | Nick Clifton <nickc@redhat.com> | 2019-04-19 10:39:47 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2019-04-19 10:39:47 +0100 |
commit | 5ce032bdfc60a8f44f6307b2297384c852100f95 (patch) | |
tree | caba4efd415ea2d34cef2332481458b8b8f377db /gas/config/tc-rx.c | |
parent | fce9773608d45757dfb26ef7783f37d432ae9a88 (diff) | |
download | fsf-binutils-gdb-5ce032bdfc60a8f44f6307b2297384c852100f95.zip fsf-binutils-gdb-5ce032bdfc60a8f44f6307b2297384c852100f95.tar.gz fsf-binutils-gdb-5ce032bdfc60a8f44f6307b2297384c852100f95.tar.bz2 |
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.
Diffstat (limited to 'gas/config/tc-rx.c')
-rw-r--r-- | gas/config/tc-rx.c | 19 |
1 files changed, 13 insertions, 6 deletions
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 ++; } |