* 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:
parent
3950dc3f51
commit
a7985d7382
@ -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 &
|
||||||
|
@ -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,
|
||||||
|
|
||||||
|
@ -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. */
|
||||||
|
109
bfd/reloc.c
109
bfd/reloc.c
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user