* write.c (TC_FX_SIZE_SLACK): Define.
authorAlan Modra <amodra@gmail.com>
Sat, 17 Feb 2007 23:13:49 +0000 (23:13 +0000)
committerAlan Modra <amodra@gmail.com>
Sat, 17 Feb 2007 23:13:49 +0000 (23:13 +0000)
(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.

gas/ChangeLog
gas/config/tc-bfin.h
gas/config/tc-h8300.h
gas/config/tc-mmix.h
gas/config/tc-sh.h
gas/config/tc-xstormy16.h
gas/write.c

index a4ac8f9..e68439d 100644 (file)
@@ -1,3 +1,13 @@
+2007-02-18  Alan Modra  <amodra@bigpond.net.au>
+
+       * 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.
+
 2007-02-17  Mark Mitchell  <mark@codesourcery.com>
             Nathan Sidwell  <nathan@codesourcery.com>
             Vladimir Prus  <vladimir@codesourcery.com
index fb0c63c..e1f95a9 100644 (file)
@@ -75,4 +75,7 @@ extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
 /* 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 bfc8f72..7191181 100644 (file)
@@ -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 61bc881..b4ab0c7 100644 (file)
@@ -221,3 +221,6 @@ extern void mmix_md_do_align (int, char *, int, int);
    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 93fdd90..0ad914e 100644 (file)
@@ -81,6 +81,11 @@ extern int sh_force_relocation (struct fix *);
 #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 5425874..727a496 100644 (file)
@@ -63,3 +63,6 @@ extern void xstormy16_cons_fix_new (fragS *f, int, int, expressionS *);
 
 /* 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
index afce604..46549b8 100644 (file)
 #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, void *xxx ATTRIBUTE_UNUSED)
     {
       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, void *xxx ATTRIBUTE_UNUSED)
          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, void *xxx ATTRIBUTE_UNUSED)
       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, void *xxx ATTRIBUTE_UNUSED)
          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],