This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

bfin, h8300, mmix, sh, stormy lax in fixup size


This patch reinstates a check on fixups that Ian removed in 1996 when
SH support was added.  I believe the reason Ian did this was for
SH_COUNT type fixups which reference some locataion unrelated to the
current frag.  Unfortunately, killing the check entirely has allowed
later ports to be imprecise in setting the fixup size, and opens up
the possibility that some are writing past the end of a frag.  I
suppose I should have audited every place that called fix_new* in
these targets and corrected the size param, but I'm lazy.  Instead
I've allowed them to continue current practice by making the fixup
size check forgiving.  Hopefully the target maintainers will be
spurred by "This target is buggy" to fix the problem.  ;-)

	* write.c (TC_FX_SIZE_SLACK): Define.
	(write_relocs): Reinstate check for fixup within frag.
	* config/tc-bfin.h (TC_FX_SIZE_SLACK): Define.
	* config/tc-h8300.h (TC_FX_SIZE_SLACK): Define.
	* config/tc-mmix.h (TC_FX_SIZE_SLACK): Define.
	* config/tc-sh.h (TC_FX_SIZE_SLACK): Define.
	* config/tc-xstormy16.h (TC_FX_SIZE_SLACK): Define.

Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.108
diff -u -p -r1.108 write.c
--- gas/write.c	17 Feb 2007 07:25:49 -0000	1.108
+++ gas/write.c	17 Feb 2007 07:26:35 -0000
@@ -97,6 +97,16 @@
 #define TC_FAKE_LABEL(NAME) (strcmp ((NAME), FAKE_LABEL_NAME) == 0)
 #endif
 
+/* Positive values of TC_FX_SIZE_SLACK allow a target to define
+   fixups that far past the end of a frag.  Having such fixups
+   is of course most most likely a bug in setting fx_size correctly.
+   A negative value disables the fixup check entirely, which is
+   appropriate for something like the Renesas / SuperH SH_COUNT
+   reloc.  */
+#ifndef TC_FX_SIZE_SLACK
+#define TC_FX_SIZE_SLACK(FIX) 0
+#endif
+
 /* Used to control final evaluation of expressions.  */
 int finalize_syms = 0;
 
@@ -1017,6 +1027,8 @@ write_relocs (bfd *abfd, asection *sec, 
     {
       arelent *reloc;
       bfd_reloc_status_type s;
+      int fx_size, slack;
+      offsetT loc;
 
       if (fixp->fx_done)
 	{
@@ -1031,12 +1043,15 @@ write_relocs (bfd *abfd, asection *sec, 
 	  continue;
 	}
 
-      /*
-	This test is triggered inappropriately for the SH:
-         if (fixp->fx_where + fixp->fx_size
-	     > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
-	     abort ();
-      */
+      fx_size = fixp->fx_size;
+      slack = TC_FX_SIZE_SLACK (fixp);
+      if (slack > 0)
+	fx_size = fx_size > slack ? fx_size - slack : 0;
+      loc = fixp->fx_where + fx_size;
+      if (slack >= 0
+	  && loc > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+	as_bad_where (fixp->fx_file, fixp->fx_line,
+		      _("internal error: fixup not contained within frag"));
 
       s = bfd_install_relocation (stdoutput, reloc,
 				  fixp->fx_frag->fr_literal,
@@ -1071,6 +1086,8 @@ write_relocs (bfd *abfd, asection *sec, 
       arelent **reloc;
       bfd_reloc_status_type s;
       int j;
+      int fx_size, slack;
+      offsetT loc;
 
       if (fixp->fx_done)
 	{
@@ -1085,10 +1102,17 @@ write_relocs (bfd *abfd, asection *sec, 
 	  relocs[i++] = reloc[j];
 	  assert (i <= n);
 	}
-      if (fixp->fx_where + fixp->fx_size
-	  > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+
+      fx_size = fixp->fx_size;
+      slack = TC_FX_SIZE_SLACK (fixp);
+      if (slack > 0)
+	fx_size = fx_size > slack ? fx_size - slack : 0;
+      loc = fixp->fx_where + fx_size;
+      if (slack >= 0
+	  && loc > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
 	as_bad_where (fixp->fx_file, fixp->fx_line,
 		      _("internal error: fixup not contained within frag"));
+
       for (j = 0; reloc[j]; j++)
 	{
 	  s = bfd_install_relocation (stdoutput, reloc[j],
Index: gas/config/tc-bfin.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-bfin.h,v
retrieving revision 1.3
diff -u -p -r1.3 tc-bfin.h
--- gas/config/tc-bfin.h	23 May 2006 04:56:56 -0000	1.3
+++ gas/config/tc-bfin.h	17 Feb 2007 03:44:11 -0000
@@ -75,4 +75,7 @@ extern long md_pcrel_from_section PARAMS
 /* Values passed to md_apply_fix3 don't include symbol values.  */
 #define MD_APPLY_SYM_VALUE(FIX) 0
 
+/* This target is buggy, and sets fix size too large.  */
+#define TC_FX_SIZE_SLACK(FIX) 2
+
 /* end of tc-bfin.h */
Index: gas/config/tc-h8300.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-h8300.h,v
retrieving revision 1.20
diff -u -p -r1.20 tc-h8300.h
--- gas/config/tc-h8300.h	18 Aug 2005 11:54:33 -0000	1.20
+++ gas/config/tc-h8300.h	17 Feb 2007 03:44:11 -0000
@@ -86,3 +86,6 @@ extern int Nmode;
 extern int SXmode;
 
 #define md_operand(x)
+
+/* This target is buggy, and sets fix size too large.  */
+#define TC_FX_SIZE_SLACK(FIX) 1
Index: gas/config/tc-mmix.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mmix.h,v
retrieving revision 1.10
diff -u -p -r1.10 tc-mmix.h
--- gas/config/tc-mmix.h	11 Oct 2005 11:16:16 -0000	1.10
+++ gas/config/tc-mmix.h	17 Feb 2007 03:44:11 -0000
@@ -221,3 +221,6 @@ extern void mmix_md_do_align (int, char 
    sequences sprinkled in, we can get unaligned DWARF2 offsets, so let's
    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
Index: gas/config/tc-sh.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-sh.h,v
retrieving revision 1.45
diff -u -p -r1.45 tc-sh.h
--- gas/config/tc-sh.h	1 Feb 2007 14:12:18 -0000	1.45
+++ gas/config/tc-sh.h	17 Feb 2007 03:44:12 -0000
@@ -81,6 +81,11 @@ extern int sh_force_relocation (struct f
 #define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC)
 extern long md_pcrel_from_section (struct fix *, segT);
 
+/* SH_COUNT relocs are allowed outside of frag.
+   The target is also buggy and sets fix size too large for other relocs.  */
+#define TC_FX_SIZE_SLACK(FIX) \
+  ((FIX)->fx_r_type == BFD_RELOC_SH_COUNT ? -1 : 2)
+
 #define IGNORE_NONSTANDARD_ESCAPES
 
 #define LISTING_HEADER \
Index: gas/config/tc-xstormy16.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xstormy16.h,v
retrieving revision 1.9
diff -u -p -r1.9 tc-xstormy16.h
--- gas/config/tc-xstormy16.h	11 Aug 2005 01:25:28 -0000	1.9
+++ gas/config/tc-xstormy16.h	17 Feb 2007 03:44:12 -0000
@@ -63,3 +63,6 @@ extern void xstormy16_cons_fix_new (frag
 
 /* Minimum instruction is two bytes.  */
 #define DWARF2_LINE_MIN_INSN_LENGTH 2
+
+/* This target is buggy, and sets fix size too large.  */
+#define TC_FX_SIZE_SLACK(FIX) 2

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]