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.
+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
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
{
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
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
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) \
{ \
*/
/*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)
*/
+/*
+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
. 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
. 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
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.
}
- 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 ();
}
/*
}
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);
/*