This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[committed, nios2] fix incorrect disassembly of signed fields
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: <binutils at sourceware dot org>
- Date: Sun, 23 Sep 2018 13:54:34 -0600
- Subject: [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;