[prev in list] [next in list] [prev in thread] [next in thread] 

List:       binutils-cvs
Subject:    [binutils-gdb] PR26502 UBSAN: tc-tic6x.c left shift of negative value
From:       Alan Modra via Binutils-cvs <binutils-cvs () sourceware ! org>
Date:       2020-08-31 11:00:28
Message-ID: 20200831110028.B8F8139540F2 () sourceware ! org
[Download RAW message or body]

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

commit 94f360ea2ffcee8a06cdda62df73b49c75e9a089
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Aug 31 17:16:21 2020 +0930

    PR26502 UBSAN: tc-tic6x.c left shift of negative value
    
            PR 26502
            * config/tc-tic6x.c (md_apply_fix): Use unsigned variables.

Diff:
---
 gas/ChangeLog         |  5 +++++
 gas/config/tc-tic6x.c | 42 +++++++++++++++++++++---------------------
 2 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 2265271dba7..1976c109895 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2020-08-31  Alan Modra  <amodra@gmail.com>
+
+	PR 26502
+	* config/tc-tic6x.c (md_apply_fix): Use unsigned variables.
+
 2020-08-31  Alan Modra  <amodra@gmail.com>
 
 	PR 26497
diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c
index 3295d958988..904d257ac7f 100644
--- a/gas/config/tc-tic6x.c
+++ b/gas/config/tc-tic6x.c
@@ -3775,7 +3775,7 @@ md_assemble (char *str)
 void
 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
-  offsetT value = *valP;
+  valueT value = *valP;
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
 
   value = SEXT (value);
@@ -3805,7 +3805,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_16:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  if (value < -0x8000 || value > 0xffff)
+	  if (value + 0x8000 > 0xffff + 0x8000)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("value too large for 2-byte field"));
 	  md_number_to_chars (buf, value, 2);
@@ -3815,7 +3815,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_8:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  if (value < -0x80 || value > 0xff)
+	  if (value + 0x80 > 0xff + 0x80)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("value too large for 1-byte field"));
 	  *buf = value;
@@ -3831,7 +3831,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_SBR_GOT_L16_W:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 	  int shift;
 
 	  switch (fixP->fx_r_type)
@@ -3851,7 +3851,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	    }
 
 	  MODIFY_VALUE (newval, value, shift, 7, 16);
-	  if ((value < -0x8000 || value > 0x7fff)
+	  if ((value + 0x8000 > 0x7fff + 0x8000)
 	      && (fixP->fx_r_type == BFD_RELOC_C6000_ABS_S16
 		  || fixP->fx_r_type == BFD_RELOC_C6000_SBR_S16))
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -3872,7 +3872,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_SBR_GOT_H16_W:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 	  int shift;
 
 	  switch (fixP->fx_r_type)
@@ -3903,7 +3903,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_PCR_L16:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 	  int shift = fixP->fx_r_type == BFD_RELOC_C6000_PCR_H16 ? 16 : 0;
 
 	  MODIFY_VALUE (newval, value, shift, 7, 16);
@@ -3915,10 +3915,10 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_SBR_U15_B:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 
 	  MODIFY_VALUE (newval, value, 0, 8, 15);
-	  if (value < 0 || value > 0x7fff)
+	  if (value > 0x7fff)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("immediate offset out of range"));
 
@@ -3929,7 +3929,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_SBR_U15_H:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 
 	  /* Constant ADDA operands, processed as constant when the
 	     instruction is parsed, are encoded as-is rather than
@@ -3945,7 +3945,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	  if (value & 1)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("immediate offset not 2-byte-aligned"));
-	  if (value < 0 || value > 0xfffe)
+	  if (value > 0xfffe)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("immediate offset out of range"));
 
@@ -3957,7 +3957,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_SBR_GOT_U15_W:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 
 	  /* Constant ADDA operands, processed as constant when the
 	     instruction is parsed, are encoded as-is rather than
@@ -3973,7 +3973,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	  if (value & 3)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("immediate offset not 4-byte-aligned"));
-	  if (value < 0 || value > 0x1fffc)
+	  if (value > 0x1fffc)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("immediate offset out of range"));
 
@@ -3994,14 +3994,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_PCR_S21:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 
 	  MODIFY_VALUE (newval, value, 2, 7, 21);
 
 	  if (value & 3)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset not 4-byte-aligned"));
-	  if (value < -0x400000 || value > 0x3ffffc)
+	  if (value + 0x400000 > 0x3ffffc + 0x400000)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset out of range"));
 
@@ -4012,14 +4012,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_PCR_S12:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 
 	  MODIFY_VALUE (newval, value, 2, 16, 12);
 
 	  if (value & 3)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset not 4-byte-aligned"));
-	  if (value < -0x2000 || value > 0x1ffc)
+	  if (value + 0x2000 > 0x1ffc + 0x2000)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset out of range"));
 
@@ -4030,14 +4030,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_PCR_S10:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 
 	  MODIFY_VALUE (newval, value, 2, 13, 10);
 
 	  if (value & 3)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset not 4-byte-aligned"));
-	  if (value < -0x800 || value > 0x7fc)
+	  if (value + 0x800 > 0x7fc + 0x800)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset out of range"));
 
@@ -4048,14 +4048,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_C6000_PCR_S7:
       if (fixP->fx_done || !seg->use_rela_p)
 	{
-	  offsetT newval = md_chars_to_number (buf, 4);
+	  valueT newval = md_chars_to_number (buf, 4);
 
 	  MODIFY_VALUE (newval, value, 2, 16, 7);
 
 	  if (value & 3)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset not 4-byte-aligned"));
-	  if (value < -0x100 || value > 0xfc)
+	  if (value + 0x100 > 0xfc + 0x100)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("PC-relative offset out of range"));
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic