mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 10:34:21 +08:00
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:
@ -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>
|
2019-04-18 Matthew Fortune <matthew.fortune@mips.com>
|
||||||
|
|
||||||
* config/tc-mips.c (match_non_zero_reg_operand): Update
|
* config/tc-mips.c (match_non_zero_reg_operand): Update
|
||||||
|
@ -740,8 +740,8 @@ typedef struct rx_bytesT
|
|||||||
int n_relax;
|
int n_relax;
|
||||||
int link_relax;
|
int link_relax;
|
||||||
fixS *link_relax_fixP;
|
fixS *link_relax_fixP;
|
||||||
char times_grown;
|
unsigned long times_grown;
|
||||||
char times_shrank;
|
unsigned long times_shrank;
|
||||||
} rx_bytesT;
|
} rx_bytesT;
|
||||||
|
|
||||||
static rx_bytesT rx_bytes;
|
static rx_bytesT rx_bytes;
|
||||||
@ -1558,7 +1558,7 @@ rx_next_opcode (fragS *fragP)
|
|||||||
fr_subtype to calculate the difference. */
|
fr_subtype to calculate the difference. */
|
||||||
|
|
||||||
int
|
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 addr0, sym_addr;
|
||||||
addressT mypc;
|
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. */
|
/* This prevents infinite loops in align-heavy sources. */
|
||||||
if (newsize < oldsize)
|
if (newsize < oldsize)
|
||||||
{
|
{
|
||||||
if (fragP->tc_frag_data->times_shrank > 10
|
/* Make sure that our iteration limit is no bigger than the one being
|
||||||
&& fragP->tc_frag_data->times_grown > 10)
|
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;
|
newsize = oldsize;
|
||||||
|
|
||||||
if (fragP->tc_frag_data->times_shrank < 20)
|
if (fragP->tc_frag_data->times_shrank < 20)
|
||||||
fragP->tc_frag_data->times_shrank ++;
|
fragP->tc_frag_data->times_shrank ++;
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,15 @@ extern int target_big_endian;
|
|||||||
#define md_end rx_md_end
|
#define md_end rx_md_end
|
||||||
extern void rx_md_end (void);
|
extern void rx_md_end (void);
|
||||||
|
|
||||||
#define md_relax_frag rx_relax_frag
|
/* Note - the definition of MD_RELAX_FRAG here includes a reference to the
|
||||||
extern int rx_relax_frag (segT, fragS *, long);
|
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_TYPE struct rx_bytesT *
|
||||||
#define TC_FRAG_INIT(fragp, max_bytes) rx_frag_init (fragp)
|
#define TC_FRAG_INIT(fragp, max_bytes) rx_frag_init (fragp)
|
||||||
|
Reference in New Issue
Block a user