mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
(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:
parent
48733062ff
commit
4111faa579
@ -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
|
||||
|
35
gas/write.c
35
gas/write.c
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user