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]

[committed, nios2] fix incorrect disassembly of signed fields


I recently spotted some failures in the gas testsuite when running nios2 tests on x86_64-w64-mingw32 host for the first time, which turned out to be a disassembler bug rather than an assembler bug. This host has a 32-bit long type and 64-bit bfd_vma type, and some sloppy type conversions from int to unsigned long and then to bfd_vma in the disassembler were causing the extension of signed instruction fields from 32 to 64 bits to happen as an unsigned conversion. This particularly affected printing of branch target addresses -- in some cases it was printing the wrong symbol, even.

I've checked in the attached patch to clean this up. I'm now explicitly using signed temporaries of the appropriate type (long or bfd_signed_vma) instead of unsigned long for the intermediate value, and I changed the casts on the bit field extraction to int32_t to make the size as well as the signedness more obvious.

-Sandra
commit 6031ac352c05c5c9f44e24fa1c5a8222a7a7d02d
Author: Sandra Loosemore <sandra@codesourcery.com>
Date:   Sun Sep 23 12:31:23 2018 -0700

    Fix incorrect extraction of signed constants in nios2 disassembler.
    
    2018-09-23  Sandra Loosemore  <sandra@codesourcery.com>
    
    	opcodes/
    	* nios2-dis.c (nios2_print_insn_arg): Make sure signed conversions
    	are used when extracting signed fields and converting them to
    	potentially 64-bit types.

diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 9f32531..9b68285 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-23  Sandra Loosemore  <sandra@codesourcery.com>
+
+	* nios2-dis.c (nios2_print_insn_arg): Make sure signed conversions
+	are used when extracting signed fields and converting them to
+	potentially 64-bit types.
+
 2018-09-21  Simon Marchi  <simon.marchi@ericsson.com>
 
 	* Makefile.am: Remove NO_WMISSING_FIELD_INITIALIZERS.
diff --git a/opcodes/nios2-dis.c b/opcodes/nios2-dis.c
index 257e5bb..51027b5 100644
--- a/opcodes/nios2-dis.c
+++ b/opcodes/nios2-dis.c
@@ -275,6 +275,8 @@ nios2_print_insn_arg (const char *argptr,
 		      const struct nios2_opcode *op)
 {
   unsigned long i = 0;
+  long s = 0;
+  bfd_signed_vma o = 0;
   struct nios2_reg *reg_base;
 
   switch (*argptr)
@@ -552,15 +554,15 @@ nios2_print_insn_arg (const char *argptr,
       switch (op->format)
 	{
 	case iw_i_type:
-	  i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
+	  s = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
 	  break;
 	case iw_F2I16_type:
-	  i = (signed) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16;
+	  s = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16;
 	  break;
 	default:
 	  bad_opcode (op);
 	}
-      (*info->fprintf_func) (info->stream, "%ld", i);
+      (*info->fprintf_func) (info->stream, "%ld", s);
       break;
 
     case 'I':
@@ -568,15 +570,15 @@ nios2_print_insn_arg (const char *argptr,
       switch (op->format)
 	{
 	case iw_F2X4I12_type:
-	  i = (signed) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20;
+	  s = (int32_t) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20;
 	  break;
 	case iw_F1X4I12_type:
-	  i = (signed) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20;
+	  s = (int32_t) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20;
 	  break;
 	default:
 	  bad_opcode (op);
 	}
-      (*info->fprintf_func) (info->stream, "%ld", i);
+      (*info->fprintf_func) (info->stream, "%ld", s);
       break;
 
     case 'u':
@@ -671,15 +673,15 @@ nios2_print_insn_arg (const char *argptr,
       switch (op->format)
 	{
 	case iw_i_type:
-	  i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
+	  o = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
 	  break;
 	case iw_F2I16_type:
-	  i = (signed) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16;
+	  o = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16;
 	  break;
 	default:
 	  bad_opcode (op);
 	}
-      address = address + 4 + i;
+      address = address + 4 + o;
       (*info->print_address_func) (address, info);
       break;
 
@@ -688,12 +690,12 @@ nios2_print_insn_arg (const char *argptr,
       switch (op->format)
 	{
 	case iw_I10_type:
-	  i = (signed) (GET_IW_I10_IMM10 (opcode) << 22) >> 21;
+	  o = (int32_t) (GET_IW_I10_IMM10 (opcode) << 22) >> 21;
 	  break;
 	default:
 	  bad_opcode (op);
 	}
-      address = address + 2 + i;
+      address = address + 2 + o;
       (*info->print_address_func) (address, info);
       break;
 
@@ -702,12 +704,12 @@ nios2_print_insn_arg (const char *argptr,
       switch (op->format)
 	{
 	case iw_T1I7_type:
-	  i = (signed) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24;
+	  o = (int32_t) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24;
 	  break;
 	default:
 	  bad_opcode (op);
 	}
-      address = address + 2 + i;
+      address = address + 2 + o;
       (*info->print_address_func) (address, info);
       break;
 

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