aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2005-12-08 11:05:36 +0000
committerAlan Modra <amodra@gmail.com>2005-12-08 11:05:36 +0000
commita7985d7382642610f87799e271e3854079eba6b2 (patch)
tree04d12b0edad4524aa7e49174df28bf32e14670d5
parent3950dc3f514d6a60c003565e610c925bc7cf4abf (diff)
downloadgdb-a7985d7382642610f87799e271e3854079eba6b2.zip
gdb-a7985d7382642610f87799e271e3854079eba6b2.tar.gz
gdb-a7985d7382642610f87799e271e3854079eba6b2.tar.bz2
* 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.
-rw-r--r--bfd/ChangeLog14
-rw-r--r--bfd/bfd-in2.h7
-rw-r--r--bfd/elf32-d10v.c12
-rw-r--r--bfd/reloc.c109
4 files changed, 61 insertions, 81 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f76458a..1db9170 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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 &
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index fc02ecf..39c15bd 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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,
diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c
index a0e506a..293b141 100644
--- a/bfd/elf32-d10v.c
+++ b/bfd/elf32-d10v.c
@@ -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. */
diff --git a/bfd/reloc.c b/bfd/reloc.c
index d964f16..d5277c0 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -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)
- 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))
+ if ((a | b | sum) & 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