LoongArch: Fix disassembly on big-endian hosts

Message ID 20261001161725.3812551-2-jremus@linux.ibm.com
State New
Headers
Series LoongArch: Fix disassembly on big-endian hosts |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Jens Remus Oct. 1, 2026, 4:17 p.m. UTC
  The LoongArch disassembler read a 4-byte instruction word directly into
insn_t (= uint32_t).  On a big-endian host this yields a byte-swapped
instruction, causing every decode to fail.

Fix this by reading into a bfd_byte buffer and then extracting the value
with bfd_getl32(), which always interprets the bytes in little-endian
order regardless of host endianness.

This resolves all binutils, gas, and ld test failures observed in a
cross-build for loongarch64-linux-gnu on s390 64-bit (s390x).

opcodes/
	* loongarch-dis.c (print_insn_loongarch): Read instruction word
	into a byte buffer and use bfd_getl32 to convert to host order.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
 opcodes/loongarch-dis.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
  

Patch

diff --git a/opcodes/loongarch-dis.c b/opcodes/loongarch-dis.c
index bdfc6a467e43..181efdfb8f46 100644
--- a/opcodes/loongarch-dis.c
+++ b/opcodes/loongarch-dis.c
@@ -404,6 +404,7 @@  disassemble_one (insn_t insn, struct disassemble_info *info)
 int
 print_insn_loongarch (bfd_vma memaddr, struct disassemble_info *info)
 {
+  bfd_byte buffer[4];
   insn_t insn;
   int status;
 
@@ -420,13 +421,15 @@  print_insn_loongarch (bfd_vma memaddr, struct disassemble_info *info)
   info->insn_info_valid = 1;
   info->target = memaddr;
 
-  if ((status = info->read_memory_func (memaddr, (bfd_byte *) &insn,
-					sizeof (insn), info)) != 0)
+  if ((status = info->read_memory_func (memaddr, buffer, sizeof (buffer),
+					info)) != 0)
     {
       info->memory_error_func (status, memaddr, info);
       return -1; /* loongarch_insn_length (0); */
     }
 
+  insn = bfd_getl32 (buffer);
+
   disassemble_one (insn, info);
 
   return loongarch_insn_length (insn);