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:
parent
fce9773608
commit
5ce032bdfc
@ -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
|
||||
|
@ -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 ++;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user