* reloc.c (enum complain_overflow): Correct comments.

(bfd_check_overflow): Combine complain_overflow_bitfield and
	complain_overflow_signed code.
	(_bfd_relocate_contents): Likewise.
	(bfd_howto_32): Use complain_overflow_dont.
	* elf32-d10v.c (elf_d10v_howto_table): Revert 2002-06-17 change.
	* bfd-in2.h: Regenerate.
This commit is contained in:
Alan Modra 2005-12-08 11:05:36 +00:00
parent 3950dc3f51
commit a7985d7382
4 changed files with 61 additions and 81 deletions

View File

@ -1,3 +1,13 @@
2005-12-08 Alan Modra <amodra@bigpond.net.au>
* reloc.c (enum complain_overflow): Correct comments.
(bfd_check_overflow): Combine complain_overflow_bitfield and
complain_overflow_signed code.
(_bfd_relocate_contents): Likewise.
(bfd_howto_32): Use complain_overflow_dont.
* elf32-d10v.c (elf_d10v_howto_table): Revert 2002-06-17 change.
* bfd-in2.h: Regenerate.
2005-12-07 H.J. Lu <hongjiu.lu@intel.com>
* elf.c (assign_section_numbers): Remove extra code in the last
@ -559,7 +569,7 @@
(scan_unit_for_symbols): New locals nested_funcs, nested_funcs_size.
Delete code setting funcinfo nesting_level field. Add code to set
funcinfo caller_func field.
2005-09-20 James E. Wilson <wilson@specifix.com>
* dwarf2.c (find_abstract_instance_name): Don't early exit when name
@ -628,7 +638,7 @@
local symbols and move it to
(msp430_elf_relax_adjust_locals): New function - walk over the
sections in the bfd and adjust relocations as necessary.
2005-08-31 DJ Delorie <dj@redhat.com>
* elf32-i386.c (elf_i386_check_relocs): Don't cast a unary &

View File

@ -2073,11 +2073,12 @@ 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 if the value overflows when considered as a signed
number one bit larger than the field. ie. A bitfield of N bits
is allowed to represent -2**n to 2**n-1. */
complain_overflow_bitfield,
/* Complain if the value overflows when considered as signed
/* Complain if the value overflows when considered as a signed
number. */
complain_overflow_signed,

View File

@ -50,10 +50,10 @@ static reloc_howto_type elf_d10v_howto_table[] =
HOWTO (R_D10V_10_PCREL_R, /* Type. */
2, /* Rightshift. */
2, /* Size (0 = byte, 1 = short, 2 = long). */
7, /* Bitsize. */
8, /* Bitsize. */
TRUE, /* PC_relative. */
0, /* Bitpos. */
complain_overflow_bitfield, /* Complain_on_overflow. */
complain_overflow_signed, /* Complain_on_overflow. */
bfd_elf_generic_reloc, /* Special_function. */
"R_D10V_10_PCREL_R", /* Name. */
FALSE, /* Partial_inplace. */
@ -65,10 +65,10 @@ static reloc_howto_type elf_d10v_howto_table[] =
HOWTO (R_D10V_10_PCREL_L, /* Type. */
2, /* Rightshift. */
2, /* Size (0 = byte, 1 = short, 2 = long). */
7, /* Bitsize. */
8, /* Bitsize. */
TRUE, /* PC_relative. */
15, /* Bitpos. */
complain_overflow_bitfield, /* Complain_on_overflow. */
complain_overflow_signed, /* Complain_on_overflow. */
bfd_elf_generic_reloc, /* Special_function. */
"R_D10V_10_PCREL_L", /* Name. */
FALSE, /* Partial_inplace. */
@ -110,10 +110,10 @@ static reloc_howto_type elf_d10v_howto_table[] =
HOWTO (R_D10V_18_PCREL, /* Type. */
2, /* Rightshift. */
2, /* Size (0 = byte, 1 = short, 2 = long). */
15, /* Bitsize. */
16, /* Bitsize. */
TRUE, /* PC_relative. */
0, /* Bitpos. */
complain_overflow_bitfield, /* Complain_on_overflow. */
complain_overflow_signed, /* Complain_on_overflow. */
bfd_elf_generic_reloc, /* Special_function. */
"R_D10V_18_PCREL", /* Name. */
FALSE, /* Partial_inplace. */

View File

@ -255,11 +255,12 @@ CODE_FRAGMENT
. {* Do not complain on overflow. *}
. complain_overflow_dont,
.
. {* Complain if the bitfield overflows, whether it is considered
. as signed or unsigned. *}
. {* Complain if the value overflows when considered as a signed
. number one bit larger than the field. ie. A bitfield of N bits
. is allowed to represent -2**n to 2**n-1. *}
. complain_overflow_bitfield,
.
. {* Complain if the value overflows when considered as signed
. {* Complain if the value overflows when considered as a signed
. number. *}
. complain_overflow_signed,
.
@ -496,14 +497,14 @@ bfd_check_overflow (enum complain_overflow how,
bfd_vma fieldmask, addrmask, signmask, ss, a;
bfd_reloc_status_type flag = bfd_reloc_ok;
a = relocation;
/* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not,
we'll be permissive: extra bits in the field mask will
automatically extend the address mask for purposes of the
overflow check. */
fieldmask = N_ONES (bitsize);
signmask = ~fieldmask;
addrmask = N_ONES (addrsize) | fieldmask;
a = (relocation & addrmask) >> rightshift;;
switch (how)
{
@ -513,19 +514,8 @@ bfd_check_overflow (enum complain_overflow how,
case complain_overflow_signed:
/* If any sign bits are set, all sign bits must be set. That
is, A must be a valid negative address after shifting. */
a = (a & addrmask) >> rightshift;
signmask = ~ (fieldmask >> 1);
ss = a & signmask;
if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
flag = bfd_reloc_overflow;
break;
case complain_overflow_unsigned:
/* We have an overflow if the address does not fit in the field. */
a = (a & addrmask) >> rightshift;
if ((a & ~ fieldmask) != 0)
flag = bfd_reloc_overflow;
break;
/* Fall thru */
case complain_overflow_bitfield:
/* Bitfields are sometimes signed, sometimes unsigned. We
@ -533,9 +523,14 @@ bfd_check_overflow (enum complain_overflow how,
of n bits is allowed to store -2**n to 2**n-1. Thus overflow
if the value has some, but not all, bits set outside the
field. */
a >>= rightshift;
ss = a & ~ fieldmask;
if (ss != 0 && ss != (((bfd_vma) -1 >> rightshift) & ~ fieldmask))
ss = a & signmask;
if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
flag = bfd_reloc_overflow;
break;
case complain_overflow_unsigned:
/* We have an overflow if the address does not fit in the field. */
if ((a & signmask) != 0)
flag = bfd_reloc_overflow;
break;
@ -1437,19 +1432,26 @@ _bfd_relocate_contents (reloc_howto_type *howto,
the size of an address. For bitfields, all the bits matter.
See also bfd_check_overflow. */
fieldmask = N_ONES (howto->bitsize);
signmask = ~fieldmask;
addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
a = relocation;
b = x & howto->src_mask;
a = (relocation & addrmask) >> rightshift;
b = (x & howto->src_mask & addrmask) >> bitpos;
switch (howto->complain_on_overflow)
{
case complain_overflow_signed:
a = (a & addrmask) >> rightshift;
/* If any sign bits are set, all sign bits must be set.
That is, A must be a valid negative address after
shifting. */
signmask = ~ (fieldmask >> 1);
signmask = ~(fieldmask >> 1);
/* Fall thru */
case complain_overflow_bitfield:
/* Much like the signed check, but for a field one bit
wider. We allow a bitfield to represent numbers in the
range -2**n to 2**n-1, where n is the number of bits in the
field. Note that when bfd_vma is 32 bits, a 32-bit reloc
can't overflow, which is exactly what we want. */
ss = a & signmask;
if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
flag = bfd_reloc_overflow;
@ -1460,12 +1462,11 @@ _bfd_relocate_contents (reloc_howto_type *howto,
SRC_MASK has more bits than BITSIZE, we can get into
trouble; we would need to verify that B is in range, as
we do for A above. */
signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
ss = ((~howto->src_mask) >> 1) & howto->src_mask;
ss >>= bitpos;
/* Set all the bits above the sign bit. */
b = (b ^ signmask) - signmask;
b = (b & addrmask) >> bitpos;
b = (b ^ ss) - ss;
/* Now we can do the addition. */
sum = a + b;
@ -1477,11 +1478,14 @@ _bfd_relocate_contents (reloc_howto_type *howto,
positive inputs. The test below looks only at the sign
bits, and it really just
SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
*/
signmask = (fieldmask >> 1) + 1;
if (((~ (a ^ b)) & (a ^ sum)) & signmask)
flag = bfd_reloc_overflow;
We mask with addrmask here to explicitly allow an address
wrap-around. The Linux kernel relies on it, and it is
the only way to write assembler code which can run when
loaded at a location 0x80000000 away from the location at
which it is linked. */
if (((~(a ^ b)) & (a ^ sum)) & signmask & addrmask)
flag = bfd_reloc_overflow;
break;
case complain_overflow_unsigned:
@ -1496,44 +1500,9 @@ _bfd_relocate_contents (reloc_howto_type *howto,
separate test, we can check for this by or-ing in the
operands when testing for the sum overflowing its final
field. */
a = (a & addrmask) >> rightshift;
b = (b & addrmask) >> bitpos;
sum = (a + b) & addrmask;
if ((a | b | sum) & ~ fieldmask)
if ((a | b | sum) & signmask)
flag = bfd_reloc_overflow;
break;
case complain_overflow_bitfield:
/* Much like the signed check, but for a field one bit
wider, and no trimming inputs with addrmask. We allow a
bitfield to represent numbers in the range -2**n to
2**n-1, where n is the number of bits in the field.
Note that when bfd_vma is 32 bits, a 32-bit reloc can't
overflow, which is exactly what we want. */
a >>= rightshift;
signmask = ~ fieldmask;
ss = a & signmask;
if (ss != 0 && ss != (((bfd_vma) -1 >> rightshift) & signmask))
flag = bfd_reloc_overflow;
signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
b = (b ^ signmask) - signmask;
b >>= bitpos;
sum = a + b;
/* We mask with addrmask here to explicitly allow an address
wrap-around. The Linux kernel relies on it, and it is
the only way to write assembler code which can run when
loaded at a location 0x80000000 away from the location at
which it is linked. */
signmask = fieldmask + 1;
if (((~ (a ^ b)) & (a ^ sum)) & signmask & addrmask)
flag = bfd_reloc_overflow;
break;
default:
@ -4625,7 +4594,7 @@ bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
}
static reloc_howto_type bfd_howto_32 =
HOWTO (0, 00, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "VRT32", FALSE, 0xffffffff, 0xffffffff, TRUE);
HOWTO (0, 00, 2, 32, FALSE, 0, complain_overflow_dont, 0, "VRT32", FALSE, 0xffffffff, 0xffffffff, TRUE);
/*
INTERNAL_FUNCTION