[binutils-gdb] ubsan: csky: left shift cannot be represented in type 'int'

Alan Modra amodra@sourceware.org
Wed Dec 11 01:13:00 GMT 2019


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

commit d93bba9e0d6c7bd3a570688612a3dd0a5eb0193a
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Dec 10 23:37:03 2019 +1030

    ubsan: csky: left shift cannot be represented in type 'int'
    
    In the following buf is an unsigned char array, so elements are
    promoted to int before arithmetic operations.
    
      if (dis_info.info->endian == BFD_ENDIAN_BIG)
        while (n--)
          val |= buf[n] << (n*8);
      else
        for (i = 0; i < n; i++)
          val |= buf[i] << (i*8);
    
    	* csky-dis.c (csky_chars_to_number): Rewrite.  Avoid signed
    	overflow when collecting bytes of a number.

Diff:
---
 opcodes/ChangeLog  | 5 +++++
 opcodes/csky-dis.c | 8 ++++----
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 6b76f15..5cd7361 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,10 @@
 2019-12-11  Alan Modra  <amodra@gmail.com>
 
+	* csky-dis.c (csky_chars_to_number): Rewrite.  Avoid signed
+	overflow when collecting bytes of a number.
+
+2019-12-11  Alan Modra  <amodra@gmail.com>
+
 	* cris-dis.c (print_with_operands): Avoid signed integer
 	overflow when collecting bytes of a 32-bit integer.
 
diff --git a/opcodes/csky-dis.c b/opcodes/csky-dis.c
index ffdb596..af830f3 100644
--- a/opcodes/csky-dis.c
+++ b/opcodes/csky-dis.c
@@ -140,11 +140,11 @@ csky_chars_to_number (unsigned char * buf, int n)
   unsigned int val = 0;
 
   if (dis_info.info->endian == BFD_ENDIAN_BIG)
-    while (n--)
-      val |= buf[n] << (n*8);
-  else
     for (i = 0; i < n; i++)
-      val |= buf[i] << (i*8);
+      val = val << 8 | (buf[i] & 0xff);
+  else
+    for (i = n - 1; i >= 0; i--)
+      val = val << 8 | (buf[i] & 0xff);
   return val;
 }



More information about the Binutils-cvs mailing list