* 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> 2005-12-07 H.J. Lu <hongjiu.lu@intel.com>
* elf.c (assign_section_numbers): Remove extra code in the last * 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. (scan_unit_for_symbols): New locals nested_funcs, nested_funcs_size.
Delete code setting funcinfo nesting_level field. Add code to set Delete code setting funcinfo nesting_level field. Add code to set
funcinfo caller_func field. funcinfo caller_func field.
2005-09-20 James E. Wilson <wilson@specifix.com> 2005-09-20 James E. Wilson <wilson@specifix.com>
* dwarf2.c (find_abstract_instance_name): Don't early exit when name * dwarf2.c (find_abstract_instance_name): Don't early exit when name
@ -628,7 +638,7 @@
local symbols and move it to local symbols and move it to
(msp430_elf_relax_adjust_locals): New function - walk over the (msp430_elf_relax_adjust_locals): New function - walk over the
sections in the bfd and adjust relocations as necessary. sections in the bfd and adjust relocations as necessary.
2005-08-31 DJ Delorie <dj@redhat.com> 2005-08-31 DJ Delorie <dj@redhat.com>
* elf32-i386.c (elf_i386_check_relocs): Don't cast a unary & * 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. */ /* Do not complain on overflow. */
complain_overflow_dont, complain_overflow_dont,
/* Complain if the bitfield overflows, whether it is considered /* Complain if the value overflows when considered as a signed
as signed or unsigned. */ 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_overflow_bitfield,
/* Complain if the value overflows when considered as signed /* Complain if the value overflows when considered as a signed
number. */ number. */
complain_overflow_signed, complain_overflow_signed,

View File

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

View File

@ -255,11 +255,12 @@ CODE_FRAGMENT
. {* Do not complain on overflow. *} . {* Do not complain on overflow. *}
. complain_overflow_dont, . complain_overflow_dont,
. .
. {* Complain if the bitfield overflows, whether it is considered . {* Complain if the value overflows when considered as a signed
. as signed or unsigned. *} . 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_overflow_bitfield,
. .
. {* Complain if the value overflows when considered as signed . {* Complain if the value overflows when considered as a signed
. number. *} . number. *}
. complain_overflow_signed, . complain_overflow_signed,
. .
@ -496,14 +497,14 @@ bfd_check_overflow (enum complain_overflow how,
bfd_vma fieldmask, addrmask, signmask, ss, a; bfd_vma fieldmask, addrmask, signmask, ss, a;
bfd_reloc_status_type flag = bfd_reloc_ok; bfd_reloc_status_type flag = bfd_reloc_ok;
a = relocation;
/* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not, /* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not,
we'll be permissive: extra bits in the field mask will we'll be permissive: extra bits in the field mask will
automatically extend the address mask for purposes of the automatically extend the address mask for purposes of the
overflow check. */ overflow check. */
fieldmask = N_ONES (bitsize); fieldmask = N_ONES (bitsize);
signmask = ~fieldmask;
addrmask = N_ONES (addrsize) | fieldmask; addrmask = N_ONES (addrsize) | fieldmask;
a = (relocation & addrmask) >> rightshift;;
switch (how) switch (how)
{ {
@ -513,19 +514,8 @@ bfd_check_overflow (enum complain_overflow how,
case complain_overflow_signed: case complain_overflow_signed:
/* If any sign bits are set, all sign bits must be set. That /* If any sign bits are set, all sign bits must be set. That
is, A must be a valid negative address after shifting. */ is, A must be a valid negative address after shifting. */
a = (a & addrmask) >> rightshift;
signmask = ~ (fieldmask >> 1); signmask = ~ (fieldmask >> 1);
ss = a & signmask; /* Fall thru */
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;
case complain_overflow_bitfield: case complain_overflow_bitfield:
/* Bitfields are sometimes signed, sometimes unsigned. We /* 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 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 if the value has some, but not all, bits set outside the
field. */ field. */
a >>= rightshift; ss = a & signmask;
ss = a & ~ fieldmask; if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
if (ss != 0 && ss != (((bfd_vma) -1 >> rightshift) & ~ fieldmask)) 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; flag = bfd_reloc_overflow;
break; break;
@ -1437,19 +1432,26 @@ _bfd_relocate_contents (reloc_howto_type *howto,
the size of an address. For bitfields, all the bits matter. the size of an address. For bitfields, all the bits matter.
See also bfd_check_overflow. */ See also bfd_check_overflow. */
fieldmask = N_ONES (howto->bitsize); fieldmask = N_ONES (howto->bitsize);
signmask = ~fieldmask;
addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask; addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
a = relocation; a = (relocation & addrmask) >> rightshift;
b = x & howto->src_mask; b = (x & howto->src_mask & addrmask) >> bitpos;
switch (howto->complain_on_overflow) switch (howto->complain_on_overflow)
{ {
case complain_overflow_signed: case complain_overflow_signed:
a = (a & addrmask) >> rightshift;
/* If any sign bits are set, all sign bits must be set. /* If any sign bits are set, all sign bits must be set.
That is, A must be a valid negative address after That is, A must be a valid negative address after
shifting. */ 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; ss = a & signmask;
if (ss != 0 && ss != ((addrmask >> rightshift) & signmask)) if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
flag = bfd_reloc_overflow; 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 SRC_MASK has more bits than BITSIZE, we can get into
trouble; we would need to verify that B is in range, as trouble; we would need to verify that B is in range, as
we do for A above. */ 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. */ /* Set all the bits above the sign bit. */
b = (b ^ signmask) - signmask; b = (b ^ ss) - ss;
b = (b & addrmask) >> bitpos;
/* Now we can do the addition. */ /* Now we can do the addition. */
sum = a + b; sum = a + b;
@ -1477,11 +1478,14 @@ _bfd_relocate_contents (reloc_howto_type *howto,
positive inputs. The test below looks only at the sign positive inputs. The test below looks only at the sign
bits, and it really just bits, and it really just
SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM) 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; break;
case complain_overflow_unsigned: 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 separate test, we can check for this by or-ing in the
operands when testing for the sum overflowing its final operands when testing for the sum overflowing its final
field. */ field. */
a = (a & addrmask) >> rightshift;
b = (b & addrmask) >> bitpos;
sum = (a + b) & addrmask; sum = (a + b) & addrmask;
if ((a | b | sum) & ~ fieldmask) if ((a | b | sum) & signmask)
flag = bfd_reloc_overflow; 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; break;
default: default:
@ -4625,7 +4594,7 @@ bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
} }
static reloc_howto_type bfd_howto_32 = 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 INTERNAL_FUNCTION