This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
reloc addrmask
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 22 Feb 2010 08:54:53 +1030
- Subject: reloc addrmask
This fixes some relocation corner cases I noticed a while ago. The
first use of addrmask in these functions is masking the relocation
value before any right shift has been applied. So, for example, it we
have a 62-bit field that is right shifted 2 bits, ie. the field takes
multiple of 4 values over the full 64-bit range, then simply or'ing in
fieldmask only extends addrmask to 62 bits.
Later uses are all after the value has been right shifted, but only in
one of those cases did we right shift addrmask.
* reloc.c (bfd_check_overflow): When forming addrmask, shift
fieldmask left by rightshift.
(_bfd_relocate_contents): Likewise. Use rightshift addrmask in all
overflow checks.
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.197
diff -u -p -r1.197 reloc.c
--- bfd/reloc.c 8 Feb 2010 20:28:43 -0000 1.197
+++ bfd/reloc.c 19 Feb 2010 03:37:11 -0000
@@ -1,6 +1,6 @@
/* BFD support for handling relocation entries.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -504,7 +504,7 @@ bfd_check_overflow (enum complain_overfl
overflow check. */
fieldmask = N_ONES (bitsize);
signmask = ~fieldmask;
- addrmask = N_ONES (addrsize) | fieldmask;
+ addrmask = N_ONES (addrsize) | (fieldmask << rightshift);
a = (relocation & addrmask) >> rightshift;;
switch (how)
@@ -1434,9 +1434,11 @@ _bfd_relocate_contents (reloc_howto_type
See also bfd_check_overflow. */
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 << rightshift));
a = (relocation & addrmask) >> rightshift;
b = (x & howto->src_mask & addrmask) >> bitpos;
+ addrmask >>= rightshift;
switch (howto->complain_on_overflow)
{
@@ -1454,7 +1456,7 @@ _bfd_relocate_contents (reloc_howto_type
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))
+ if (ss != 0 && ss != (addrmask & signmask))
flag = bfd_reloc_overflow;
/* We only need this next bit of code if the sign bit of B
--
Alan Modra
Australia Development Lab, IBM