This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]