* 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.
This commit is contained in:
Ian Lance Taylor 1993-07-22 18:03:51 +00:00
parent c2ac84cbbc
commit 66a277abe2
4 changed files with 129 additions and 42 deletions

View 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

View 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) \
{ \

View 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)

View 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_max
|| (bfd_signed_vma) relocation < reloc_min)
{
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_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);
/*