* reloc.c (enum complain_overflow): New enumeration with the
authorIan Lance Taylor <ian@airs.com>
Thu, 22 Jul 1993 18:03:51 +0000 (18:03 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 22 Jul 1993 18:03:51 +0000 (18:03 +0000)
various flavours of overflow checking.
(srtuct reloc_howto_struct): Changed complain_on_overflow field
from boolean to emum complain_overflow.  Removed obsolete absolute
field.
(HOWTO): Removed absolute argument.
(bfd_perform_relocation): Do overflow checking on all types of
fields.
* bfd-in2.h: Updated accordingly.
* all targets: Updated initialization of reloc howto tables.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/coff-a29k.c
bfd/reloc.c

index a6880d6..3395c41 100644 (file)
@@ -1,3 +1,16 @@
+Thu Jul 22 13:34:57 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * reloc.c (enum complain_overflow): New enumeration with the
+       various flavours of overflow checking.
+       (srtuct reloc_howto_struct): Changed complain_on_overflow field
+       from boolean to emum complain_overflow.  Removed obsolete absolute
+       field.
+       (HOWTO): Removed absolute argument.
+       (bfd_perform_relocation): Do overflow checking on all types of
+       fields.
+       * bfd-in2.h: Updated accordingly.
+       * all targets: Updated initialization of reloc howto tables.
+
 Wed Jul 21 20:34:34 1993  Ken Raeburn  (raeburn@cambridge.cygnus.com)
 
        * opncls.c (bfd_create): Don't use C++ keyword "template" as a C
index 276e051..720c595 100644 (file)
@@ -955,6 +955,23 @@ typedef struct reloc_cache_entry
   CONST struct reloc_howto_struct *howto;
 
 } arelent;
+enum complain_overflow
+{
+        /* Do not complain on overflow. */
+  complain_overflow_dont,
+
+        /* Complain if the bitfield overflows, whether it is considered
+          as signed or unsigned. */
+  complain_overflow_bitfield,
+
+        /* Complain if the value overflows when considered as signed
+          number. */
+  complain_overflow_signed,
+
+        /* Complain if the value overflows when considered as an
+          unsigned number. */
+  complain_overflow_unsigned
+};
 
 typedef CONST struct reloc_howto_struct 
 { 
@@ -975,7 +992,8 @@ typedef CONST struct reloc_howto_struct
            result is to be subtracted from the data.  */
   int size;
 
-        /*  Now obsolete?  But m68k-coff still uses it... */
+        /*  The number of bits in the item to be relocated.  This is used
+           when doing overflow checking.  */
   unsigned int bitsize;
 
         /*  Notes that the relocation is relative to the location in the
@@ -984,14 +1002,13 @@ typedef CONST struct reloc_howto_struct
            being relocated. */
   boolean pc_relative;
 
+        /*  The bit position of the reloc value in the destination.
+           The relocated value is left shifted by this amount. */
   unsigned int bitpos;
 
-        /*  Now obsolete */
-  boolean absolute;
-
-        /* Causes the relocation routine to return an error if overflow
-          is detected when relocating. */
-  boolean complain_on_overflow;
+        /* What type of overflow error should be checked for when
+          relocating. */
+  enum complain_overflow complain_on_overflow;
 
         /* If this field is non null, then the supplied function is
           called rather than the normal function. This allows really
@@ -1036,9 +1053,9 @@ typedef CONST struct reloc_howto_struct
   boolean pcrel_offset;
 
 } reloc_howto_type;
-#define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-  {(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
-#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,false,false,FUNCTION, NAME,false,0,0,IN)
+#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+  {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
+#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
 
 #define HOWTO_PREPARE(relocation, symbol)      \
   {                                            \
index e60fd40..01a2679 100644 (file)
@@ -226,24 +226,21 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
 */
 
 /*FIXME: I'm not real sure about this table */
-#define NA     0       /* Obsolete fields, via the documentation */
-#define NAB false
 static reloc_howto_type howto_table[] = 
 {
-  {R_ABS,     0, 3, NA, false, NA, NAB, true,a29k_reloc,"ABS",     true, 0xffffffff,0xffffffff, false},
+  {R_ABS,     0, 3, 32, false, 0, complain_overflow_bitfield,a29k_reloc,"ABS",     true, 0xffffffff,0xffffffff, false},
   {1},  {2},  {3},   {4},  {5},  {6},  {7},  {8},  {9}, {10},
   {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20},
   {21}, {22}, {23},
-  {R_IREL,    0, 3, NA, true,  NA, NAB, true,a29k_reloc,"IREL",    true, 0xffffffff,0xffffffff, false},
-  {R_IABS,    0, 3, NA, false, NA, NAB, true,a29k_reloc,"IABS",    true, 0xffffffff,0xffffffff, false},
-  {R_ILOHALF, 0, 3, NA, true,  NA, NAB, true,a29k_reloc,"ILOHALF", true, 0x0000ffff,0x0000ffff, false},
-  {R_IHIHALF, 0, 3, NA, true,  NA, NAB, true,a29k_reloc,"IHIHALF", true, 0xffff0000,0xffff0000, false},
-  {R_IHCONST, 0, 3, NA, true,  NA, NAB, true,a29k_reloc,"IHCONST", true, 0xffff0000,0xffff0000, false},
-  {R_BYTE,    0, 0, NA, false, NA, NAB, true,a29k_reloc,"BYTE",    true, 0x000000ff,0x000000ff, false},
-  {R_HWORD,   0, 1, NA, false, NA, NAB, true,a29k_reloc,"HWORD",   true, 0x0000ffff,0x0000ffff, false},
-  {R_WORD,    0, 2, NA, false, NA, NAB, true,a29k_reloc,"WORD",    true, 0xffffffff,0xffffffff, false},
+  {R_IREL,    0, 3, 32, true,  0, complain_overflow_signed,a29k_reloc,"IREL",    true, 0xffffffff,0xffffffff, false},
+  {R_IABS,    0, 3, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"IABS",    true, 0xffffffff,0xffffffff, false},
+  {R_ILOHALF, 0, 3, 16, true,  0, complain_overflow_signed, a29k_reloc,"ILOHALF", true, 0x0000ffff,0x0000ffff, false},
+  {R_IHIHALF, 0, 3, 16, true,  16, complain_overflow_signed, a29k_reloc,"IHIHALF", true, 0xffff0000,0xffff0000, false},
+  {R_IHCONST, 0, 3, 16, true,  0, complain_overflow_signed, a29k_reloc,"IHCONST", true, 0xffff0000,0xffff0000, false},
+  {R_BYTE,    0, 0, 8, false, 0, complain_overflow_bitfield, a29k_reloc,"BYTE",    true, 0x000000ff,0x000000ff, false},
+  {R_HWORD,   0, 1, 16, false, 0, complain_overflow_bitfield, a29k_reloc,"HWORD",   true, 0x0000ffff,0x0000ffff, false},
+  {R_WORD,    0, 2, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"WORD",    true, 0xffffffff,0xffffffff, false},
 };
-#undef NA
 
 #define BADMAG(x) A29KBADMAG(x)
 
index bfa7c85..890cb6f 100644 (file)
@@ -242,6 +242,34 @@ DESCRIPTION
         
 */
 
+/*
+SUBSUBSECTION
+       <<enum complain_overflow>>
+
+       Indicates what sort of overflow checking should be done when
+       performing a relocation.
+
+CODE_FRAGMENT
+.
+.enum complain_overflow
+.{
+.      {* Do not complain on overflow. *}
+.  complain_overflow_dont,
+.
+.      {* Complain if the bitfield overflows, whether it is considered
+.         as signed or unsigned. *}
+.  complain_overflow_bitfield,
+.
+.      {* Complain if the value overflows when considered as signed
+.         number. *}
+.  complain_overflow_signed,
+.
+.      {* Complain if the value overflows when considered as an
+.         unsigned number. *}
+.  complain_overflow_unsigned
+.};
+
+*/
 
 /*
 SUBSUBSECTION 
@@ -272,7 +300,8 @@ CODE_FRAGMENT
 .          result is to be subtracted from the data.  *}
 .  int size;
 .
-.       {*  Now obsolete?  But m68k-coff still uses it... *}
+.       {*  The number of bits in the item to be relocated.  This is used
+.          when doing overflow checking.  *}
 .  unsigned int bitsize;
 .
 .       {*  Notes that the relocation is relative to the location in the
@@ -281,14 +310,13 @@ CODE_FRAGMENT
 .           being relocated. *}
 .  boolean pc_relative;
 .
+.      {*  The bit position of the reloc value in the destination.
+.          The relocated value is left shifted by this amount. *}
 .  unsigned int bitpos;
 .
-.       {*  Now obsolete *}
-.  boolean absolute;
-.
-.       {* Causes the relocation routine to return an error if overflow
-.          is detected when relocating. *}
-.  boolean complain_on_overflow;
+.      {* What type of overflow error should be checked for when
+.         relocating. *}
+.  enum complain_overflow complain_on_overflow;
 .
 .       {* If this field is non null, then the supplied function is
 .          called rather than the normal function. This allows really
@@ -344,15 +372,15 @@ DESCRIPTION
        The HOWTO define is horrible and will go away.
 
 
-.#define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
-.  {(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
+.#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+.  {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
 
 DESCRIPTION
        And will be replaced with the totally magic way. But for the
        moment, we are compatible, so do it this way..
 
 
-.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,false,false,FUNCTION, NAME,false,0,0,IN)
+.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
 .
 DESCRIPTION
        Helper routine to turn a symbol into a relocation value.
@@ -548,18 +576,50 @@ DEFUN(bfd_perform_relocation,(abfd,
     }
 
 
-  if (howto->complain_on_overflow && howto->pc_relative)
+  /* FIXME: This overflow checking is incomplete, because the value
+     might have overflowed before we get here.  For a correct check we
+     need to compute the value in a size larger than bitsize, but we
+     can't reasonably do that for a reloc the same size as a host
+     machine word.  */
+  switch (howto->complain_on_overflow)
     {
-      /* We can detect overflow safely here */
+    case complain_overflow_dont:
+      break;
+    case complain_overflow_signed:
+      {
+       /* Assumes two's complement.  */
+       bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+       bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
 
-      bfd_signed_vma reloc_max = (1 << (howto->bitsize - 1))-1;
-      bfd_signed_vma reloc_min = ~(reloc_max);
+       if ((bfd_signed_vma) relocation > reloc_signed_max
+           || (bfd_signed_vma) relocation < reloc_signed_min)
+         flag = bfd_reloc_overflow;
+      }
+      break;
+    case complain_overflow_unsigned:
+      {
+       /* Assumes two's complement.  This expression avoids overflow
+          if howto->bitsize is the number of bits in bfd_vma.  */
+       bfd_vma reloc_unsigned_max =
+         (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
 
-      if ((bfd_signed_vma) relocation > reloc_max
-         || (bfd_signed_vma) relocation < reloc_min)
-       {
+       if ((bfd_vma) relocation > reloc_unsigned_max)
          flag = bfd_reloc_overflow;
-       }
+      }
+      break;
+    case complain_overflow_bitfield:
+      {
+       /* Assumes two's complement.  This expression avoids overflow
+          if howto->bitsize is the number of bits in bfd_vma.  */
+       bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+       if (((bfd_vma) relocation &~ reloc_bits) != 0
+           && ((bfd_vma) relocation &~ reloc_bits) != (-1 &~ reloc_bits))
+         flag = bfd_reloc_overflow;
+      }
+      break;
+    default:
+      abort ();
     }
   
   /* 
@@ -905,7 +965,7 @@ DEFUN(bfd_reloc_type_lookup,(abfd, code),
 }
 
 static reloc_howto_type bfd_howto_32 =
- HOWTO(0, 00,2,32,false,0,false,true,0,"VRT32", false,0xffffffff,0xffffffff,true);
+ HOWTO(0, 00,2,32,false,0,complain_overflow_bitfield,0,"VRT32", false,0xffffffff,0xffffffff,true);
 
 
 /*