This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Fix checking bignum values that are being inserted into byte sized containers.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5f2b6bc955535ebfc280a04c22c937cfedb83916

commit 5f2b6bc955535ebfc280a04c22c937cfedb83916
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Mar 16 11:33:55 2016 +0000

    Fix checking bignum values that are being inserted into byte sized containers.
    
    	* read.c (emit_expr_with_reloc): Add code check a bignum with
    	nbytes == 1.
    	* config/rx/rx-parse.y (rx_intop): Accept bignum values for sizes
    	other than 32-bits.
    	* testsuite/gas/elf/bignum.s: New test source file.
    	* testsuite/gas/elf/bignum.d: New test driver file.
    	* testsuite/gas/elf/elf.exp: Run the new test.

Diff:
---
 gas/ChangeLog                   | 10 ++++++++++
 gas/config/rx-parse.y           | 11 ++++++++---
 gas/read.c                      | 21 ++++++++++++++++++++-
 gas/testsuite/gas/elf/bignums.d | 14 ++++++++++++++
 gas/testsuite/gas/elf/bignums.s | 23 +++++++++++++++++++++++
 gas/testsuite/gas/elf/elf.exp   |  9 +++++----
 6 files changed, 80 insertions(+), 8 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index d67d752..0f1c13b 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,13 @@
+2016-03-16  Nick Clifton  <nickc@redhat.com>
+
+	* read.c (emit_expr_with_reloc): Add code check a bignum with
+	nbytes == 1.
+	* config/rx/rx-parse.y (rx_intop): Accept bignum values for sizes
+	other than 32-bits.
+	* testsuite/gas/elf/bignum.s: New test source file.
+	* testsuite/gas/elf/bignum.d: New test driver file.
+	* testsuite/gas/elf/elf.exp: Run the new test.
+
 2016-03-15  Ulrich Drepper  <drepper@gmail.com>
 
 	* doc/c-i386.texi (Register Naming): Update to details of the
diff --git a/gas/config/rx-parse.y b/gas/config/rx-parse.y
index 3bd37d0..c0e3217 100644
--- a/gas/config/rx-parse.y
+++ b/gas/config/rx-parse.y
@@ -1494,9 +1494,14 @@ rx_intop (expressionS exp, int nbits, int opbits)
   long v;
   long mask, msb;
 
-  if (exp.X_op == O_big && nbits == 32)
-      return 1;
-  if (exp.X_op != O_constant)
+  if (exp.X_op == O_big)
+    {
+      if (nbits == 32)
+	return 1;
+      if (exp.X_add_number == -1)
+	return 0;
+    }
+  else if (exp.X_op != O_constant)
     return 0;
   v = exp.X_add_number;
 
diff --git a/gas/read.c b/gas/read.c
index 8f5dfff..ea6d9f6 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -4411,7 +4411,8 @@ emit_expr_with_reloc (expressionS *exp,
       if ((get & mask) != 0
 	  && ((get & mask) != mask
 	      || (get & hibit) == 0))
-	{		/* Leading bits contain both 0s & 1s.  */
+	{
+	  /* Leading bits contain both 0s & 1s.  */
 #if defined (BFD64) && BFD_HOST_64BIT_LONG_LONG
 #ifndef __MSVCRT__
 	  as_warn (_("value 0x%llx truncated to 0x%llx"),
@@ -4437,16 +4438,34 @@ emit_expr_with_reloc (expressionS *exp,
       if (nbytes < size)
 	{
 	  int i = nbytes / CHARS_PER_LITTLENUM;
+
 	  if (i != 0)
 	    {
 	      LITTLENUM_TYPE sign = 0;
 	      if ((generic_bignum[--i]
 		   & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0)
 		sign = ~(LITTLENUM_TYPE) 0;
+
 	      while (++i < exp->X_add_number)
 		if (generic_bignum[i] != sign)
 		  break;
 	    }
+	  else if (nbytes == 1)
+	    {
+	      /* We have nbytes == 1 and CHARS_PER_LITTLENUM == 2 (probably).
+		 Check that bits 8.. of generic_bignum[0] match bit 7
+		 and that they match all of generic_bignum[1..exp->X_add_number].  */
+	      LITTLENUM_TYPE sign = (generic_bignum[0] & (1 << 7)) ? -1 : 0;
+	      LITTLENUM_TYPE himask = LITTLENUM_MASK & ~ 0xFF;
+
+	      if ((generic_bignum[0] & himask) == (sign & himask))
+		{
+		  while (++i < exp->X_add_number)
+		    if (generic_bignum[i] != sign)
+		      break;
+		}
+	    }
+
 	  if (i < exp->X_add_number)
 	    as_warn (_("bignum truncated to %d bytes"), nbytes);
 	  size = nbytes;
diff --git a/gas/testsuite/gas/elf/bignums.d b/gas/testsuite/gas/elf/bignums.d
new file mode 100644
index 0000000..799ef3c
--- /dev/null
+++ b/gas/testsuite/gas/elf/bignums.d
@@ -0,0 +1,14 @@
+#readelf: -x .data
+#name: bignum byte values
+#not-target: rx-*
+# The RX target sometimes calls its data section D_1.
+# 
+# Test that 8-bit and 16-bit constants can be specified via bignums.
+# 
+# Note - we should really apply this test to all targets, not just
+# ELF based ones, but we need a tool that can dump the data section
+# in a fixed format and readelf fits the bill.
+
+Hex dump of section .*:
+  0x00000000 9800(7698|9876) 9800(7698|9876) 9800.*
+#pass
diff --git a/gas/testsuite/gas/elf/bignums.s b/gas/testsuite/gas/elf/bignums.s
new file mode 100644
index 0000000..91de585
--- /dev/null
+++ b/gas/testsuite/gas/elf/bignums.s
@@ -0,0 +1,23 @@
+	.data
+
+	# On a 64-bit host the two values below will be read into a simple
+	# 64-bit field in the expressionS structure and the type will be set
+	# to O_constant.  On a 32-bit host however they will read into the
+	# generic_bignum array and the type set to O_bignum.  Either way they
+	# should both evaluate without errors.
+	#
+	# Note - some targets place .hword values on a 16-bit boundary, so we
+	# declare a second, zero, .byte value in order to make the data
+	# consistent across all targets.
+
+	.byte  0xffffffffffffff98, 0
+	.hword 0xffffffffffff9876
+
+	# Check that on 64-bit hosts real bignum values also work.
+
+	.byte  0xffffffffffffffffffffffffffffff98, 0
+	.hword 0xffffffffffffffffffffffffffff9876
+
+	# Also check a ridiculously long bignum value.
+
+	.byte  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff98, 0
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index fb5619d..bde875b 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -226,9 +226,10 @@ if { [is_elf_format] } then {
 
     run_dump_test "strtab"
 
-load_lib gas-dg.exp
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/err-*.s $srcdir/$subdir/warn-*.s]] "" ""
-dg-finish
+    run_dump_test "bignums"
     
+    load_lib gas-dg.exp
+    dg-init
+    dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/err-*.s $srcdir/$subdir/warn-*.s]] "" ""
+    dg-finish
 }


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