aboutsummaryrefslogtreecommitdiff
path: root/gas/write.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-10-25 19:46:24 +1030
committerAlan Modra <amodra@gmail.com>2019-10-25 23:19:24 +1030
commit37a5888387413a4b787468eff710eefebe134201 (patch)
tree85003343520c718155045d0ea00437ef7b502930 /gas/write.c
parent158da0d12a7c9bb01c6d9b8d3da609a1e2561916 (diff)
downloadbinutils-37a5888387413a4b787468eff710eefebe134201.zip
binutils-37a5888387413a4b787468eff710eefebe134201.tar.gz
binutils-37a5888387413a4b787468eff710eefebe134201.tar.bz2
PR25125, relaxation chooses wrong branch size
The patch I made for PR12049 didn't test for a "negative" branch properly. "if (target < address)" ought to have been "if (target < address + fragP->fr_fix)". Rather than making that change, this patch adds fragP->fr_fix into address earlier. The patch also avoids running into a bad interaction with the m68k md_prepare_relax_scan by returning zero growth immediately, since the adjusted target expression would result in a zero "aim". PR gas/25125 PR gas/12049 * write.c (relax_frag): Correct calculation of delta for positive branches where "stretch" would make the branch negative. Return zero immediately in that case. Correct TC_PCREL_ADJUST comment.
Diffstat (limited to 'gas/write.c')
-rw-r--r--gas/write.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/gas/write.c b/gas/write.c
index 9b5ae6f..8f7786e 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -2497,7 +2497,7 @@ relax_frag (segT segment, fragS *fragP, long stretch)
const relax_typeS *table;
target = fragP->fr_offset;
- address = fragP->fr_address;
+ address = fragP->fr_address + fragP->fr_fix;
table = TC_GENERIC_RELAX_TABLE;
this_state = fragP->fr_subtype;
start_type = this_type = table + this_state;
@@ -2537,13 +2537,13 @@ relax_frag (segT segment, fragS *fragP, long stretch)
negative. Don't allow this in case the negative reach is
large enough to require a larger branch instruction. */
else if (target < address)
- target = fragP->fr_next->fr_address + stretch;
+ return 0;
}
}
- aim = target - address - fragP->fr_fix;
+ aim = target - address;
#ifdef TC_PCREL_ADJUST
- /* Currently only the ns32k family needs this. */
+ /* Currently only the ns32k and arc needs this. */
aim += TC_PCREL_ADJUST (fragP);
#endif