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.
This commit is contained in:
Nick Clifton 2019-04-19 10:39:47 +01:00
parent fce9773608
commit 5ce032bdfc
3 changed files with 31 additions and 8 deletions

View File

@ -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

View File

@ -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 ++;
}

View File

@ -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)