gas: Fix mmix fixups and TC_FX_SIZE_SLACK, PR25331

Message ID alpine.BSF.2.20.16.2006282341540.74942@arjuna.pair.com
State New
Headers show
Series
  • gas: Fix mmix fixups and TC_FX_SIZE_SLACK, PR25331
Related show

Commit Message

Hans-Peter Nilsson June 29, 2020, 3:42 a.m.
Finally; sorry for the delay.  There were a few false starts, where I
    misinterpreted the error-messages and the comment that Alan added:
    it's not the fix size that's too large (and the frag too small), it's
    stating the wrong size of what will be "fixed up" - that of the actual
    target value, not the size of the field that needs to be adjusted.
    Comments added for clarity.

    Test-suite committed separately.

    gas:
    	PR gas/25331
    	* config/tc-mmix.c (md_assemble) <fixup for
    	BFD_RELOC_MMIX_BASE_PLUS_OFFSET>: This fixup affects 1 byte, not 8.
    	Also, set its fx_no_overflow.
    	(md_convert_frag) <case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO)>:
    	Similarly this fixup affects 4 bytes, not 8 and needs its
    	fx_no_overflow set.
    	* config/tc-mmix.h (TC_FX_SIZE_SLACK): Don't define.


brgds, H-P

Patch

diff --git a/gas/config/tc-mmix.c b/gas/config/tc-mmix.c
index a7728fa..f97953f 100644
--- a/gas/config/tc-mmix.c
+++ b/gas/config/tc-mmix.c
@@ -1332,6 +1332,7 @@  md_assemble (char *str)
       if (n_operands == 2)
 	{
 	  symbolS *sym;
+	  fixS *tmpfixP;

 	  /* The last operand is immediate whenever we see just two
 	     operands.  */
@@ -1380,8 +1381,13 @@  md_assemble (char *str)
 	  /* Now we know it can be a "base address plus offset".  Add
 	     proper fixup types so we can handle this later, when we've
 	     parsed everything.  */
-	  fix_new (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
-		   8, sym, 0, 0, BFD_RELOC_MMIX_BASE_PLUS_OFFSET);
+	  tmpfixP
+	    = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
+		       1, sym, 0, 0, BFD_RELOC_MMIX_BASE_PLUS_OFFSET);
+	  /* This is a non-trivial fixup: the ->fx_offset will not
+	     reflect the stored value, so the generic overflow test
+	     doesn't apply. */
+	  tmpfixP->fx_no_overflow = 1;
 	  break;
 	}

@@ -2332,11 +2338,18 @@  md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
     case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO):
       /* Setting the unknown bits to 0 seems the most appropriate.  */
       mmix_set_geta_branch_offset (opcodep, 0);
-      tmpfixP = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 8,
+      tmpfixP = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
 			 fragP->fr_symbol, fragP->fr_offset, 1,
 			 BFD_RELOC_MMIX_PUSHJ_STUBBABLE);
       COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
       var_part_size = 0;
+
+      /* This is a non-trivial fixup; we'll be calling a generated
+	 stub, whose address fits into the fixup.  The actual target,
+	 as reflected by the fixup value, is further away than fits
+	 into the fixup, so the generic overflow test doesn't
+	 apply. */
+      tmpfixP->fx_no_overflow = 1;
       break;

     case ENCODE_RELAX (STATE_GETA, STATE_ZERO):
diff --git a/gas/config/tc-mmix.h b/gas/config/tc-mmix.h
index d9e8599..f7a54c1 100644
--- a/gas/config/tc-mmix.h
+++ b/gas/config/tc-mmix.h
@@ -226,8 +226,5 @@  extern void mmix_md_do_align (int, char *, int, int);
    explicitly say one byte.  */
 #define DWARF2_LINE_MIN_INSN_LENGTH 1

-/* This target is buggy, and sets fix size too large.  */
-#define TC_FX_SIZE_SLACK(FIX) 6
-
 /* MMIX has global register symbols.  */
 #define TC_GLOBAL_REGISTER_SYMBOL_OK