(relax_segment): Count the number of frags being processed and use this to

compute a maximum limit on the number of iterations that will be allowed when
attempting to relax the segment.
This commit is contained in:
Nick Clifton 2005-08-18 09:26:16 +00:00
parent 48733062ff
commit 4111faa579
2 changed files with 36 additions and 6 deletions

View File

@ -1,3 +1,10 @@
2005-08-18 Nick Clifton <nickc@redhat.com>
* write.c (relax_segment): Count the number of frags being
processed and use this to compute a maximum limit on the number of
iterations that will be allowed when attempting to relax the
segment.
2005-08-17 Danny Smith <dannysmith@users.sourceforge.net>
* config/obj-coff.c (obj_coff_weak): Set auxiliary record

View File

@ -1721,8 +1721,9 @@ relax_align (register relax_addressT address, /* Address now. */
int
relax_segment (struct frag *segment_frag_root, segT segment)
{
register struct frag *fragP;
register relax_addressT address;
unsigned long frag_count;
struct frag *fragP;
relax_addressT address;
int ret;
/* In case md_estimate_size_before_relax() wants to make fixSs. */
@ -1731,7 +1732,9 @@ relax_segment (struct frag *segment_frag_root, segT segment)
/* For each frag in segment: count and store (a 1st guess of)
fr_address. */
address = 0;
for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
for (frag_count = 0, fragP = segment_frag_root;
fragP;
fragP = fragP->fr_next, frag_count ++)
{
fragP->relax_marker = 0;
fragP->fr_address = address;
@ -1807,6 +1810,7 @@ relax_segment (struct frag *segment_frag_root, segT segment)
/* Do relax(). */
{
unsigned long max_iterations;
offsetT stretch; /* May be any size, 0 or negative. */
/* Cumulative number of addresses we have relaxed this pass.
We may have relaxed more than one address. */
@ -1815,6 +1819,20 @@ relax_segment (struct frag *segment_frag_root, segT segment)
grew, and another shrank. If a branch instruction doesn't fit anymore,
we could be scrod. */
/* We want to prevent going into an infinite loop where one frag grows
depending upon the location of a symbol which is in turn moved by
the growing frag. eg:
foo = .
.org foo+16
foo = .
So we dictate that this algorithm can be at most O2. */
max_iterations = frag_count * frag_count;
/* Check for overflow. */
if (max_iterations < frag_count)
max_iterations = frag_count;
do
{
stretch = 0;
@ -2033,10 +2051,15 @@ relax_segment (struct frag *segment_frag_root, segT segment)
stretch += growth;
stretched = 1;
}
} /* For each frag in the segment. */
}
}
while (stretched); /* Until nothing further to relax. */
} /* do_relax */
/* Until nothing further to relax. */
while (stretched && -- max_iterations);
if (stretched)
as_fatal (_("Infinite loop encountered whilst attempting to compute the addresses of symbols in section %s"),
segment_name (segment));
}
ret = 0;
for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)