[08/21] Disassembler fix.

Message ID 20250402121759.1962001-9-jovan.dmitrovic@htecgroup.com
State New
Headers
Series Integrate MIPS-Specific Support |

Commit Message

Jovan Dmitrovic April 2, 2025, 12:18 p.m. UTC
  From: Simon Dardis <simon.dardis@imgtec.com>

Mask off lowest bit when disassembling compressed code.
It fixes a bug in the MIPS disassembler by ensuring that the
disassembler for compressed instructions (MIPS16 and microMIPS)
does not start disassembling from odd addresses. These instructions
require at least 2-byte alignment. The fix adjusts the disassembly
logic by masking off the least significant bit of the input memory
address. MIPS16 and microMIPS instructions must be aligned to at
least 2 bytes. By removing the least significant bit, correct
alignment is ensured during disassembly. The disassembler always
aligns the memory address before continuing, ensuring accuracy when
disassembling MIPS16 and microMIPS instructions.

Cherry-picked e497794
from https://github.com/MIPS/binutils-gdb

Signed-off-by: Simon Dardis <simon.dardis@imgtec.com>
Signed-off-by: Faraz Shahbazker <fshahbazker@wavecomp.com>
Signed-off-by: Milica Matic <milica.matic@htecgroup.com>

opcodes/
	* mips-dis.c (print_insn_mips16, print_insn_micromips): Don't
	disassemble from odd addresses.
---
 opcodes/mips-dis.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
  

Patch

diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 612f694f442..80c447e854d 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -2278,7 +2278,7 @@  enum match_kind
 /* Disassemble mips16 instructions.  */
 
 static int
-print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
+print_insn_mips16 (bfd_vma memaddr_base, struct disassemble_info *info)
 {
   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   int status;
@@ -2292,6 +2292,10 @@  print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
   unsigned int first;
   unsigned int full;
 
+  /* Some users of bfd may supply an address with the MIPS16 flag set,
+     e.g. objdump.  MIPS16 instructions must be at least 2 byte aligned.  */
+  bfd_vma memaddr = memaddr_base & ~1;
+
   info->bytes_per_chunk = 2;
   info->display_endian = info->endian;
   info->insn_info_valid = 1;
@@ -2506,7 +2510,7 @@  print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
 /* Disassemble microMIPS instructions.  */
 
 static int
-print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+print_insn_micromips (bfd_vma memaddr_base, struct disassemble_info *info)
 {
   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   const struct mips_opcode *op, *opend;
@@ -2517,6 +2521,10 @@  print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
   int status;
   unsigned int insn;
 
+  /* Some users of bfd may supply an address with the micromips flag set,
+     e.g. objdump.  microMIPS instructions must be at least 2 byte aligned.  */
+  bfd_vma memaddr = memaddr_base & ~1;
+
   info->bytes_per_chunk = 2;
   info->display_endian = info->endian;
   info->insn_info_valid = 1;