PR25125, relaxation chooses wrong branch size

Message ID 20191025125107.GA3433@bubble.grove.modra.org
State New
Headers show
Series
  • PR25125, relaxation chooses wrong branch size
Related show

Commit Message

Alan Modra Oct. 25, 2019, 12:51 p.m.
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.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/gas/write.c b/gas/write.c
index 9b5ae6ff32..8f7786eb36 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