/* Self tests for disassembler for GDB, the GNU debugger.

   Copyright (C) 2017-2023 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "disasm.h"
#include "gdbsupport/selftest.h"
#include "selftest-arch.h"
#include "gdbarch.h"

namespace selftests
{

/* Return a pointer to a buffer containing an instruction that can be
   disassembled for architecture GDBARCH.  *LEN will be set to the length
   of the returned buffer.

   If there's no known instruction to disassemble for GDBARCH (because we
   haven't figured on out, not because no instructions exist) then nullptr
   is returned, and *LEN is set to 0.  */

static const gdb_byte *
get_test_insn (struct gdbarch *gdbarch, size_t *len)
{
  *len = 0;
  const gdb_byte *insn = nullptr;

  switch (gdbarch_bfd_arch_info (gdbarch)->arch)
    {
    case bfd_arch_bfin:
      /* M3.L = 0xe117 */
      static const gdb_byte bfin_insn[] = { 0x17, 0xe1, 0xff, 0xff };

      insn = bfin_insn;
      *len = sizeof (bfin_insn);
      break;
    case bfd_arch_arm:
      /* mov     r0, #0 */
      static const gdb_byte arm_insn[] = { 0x0, 0x0, 0xa0, 0xe3 };

      insn = arm_insn;
      *len = sizeof (arm_insn);
      break;
    case bfd_arch_ia64:
      /* We get:
	 internal-error: gdbarch_sw_breakpoint_from_kind:
	 Assertion `gdbarch->sw_breakpoint_from_kind != NULL' failed.  */
      return insn;
    case bfd_arch_mep:
      /* Disassembles as '*unknown*' insn, then len self-check fails.  */
      return insn;
    case bfd_arch_mips:
      if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mips16)
	/* Disassembles insn, but len self-check fails.  */
	return insn;
      goto generic_case;
    case bfd_arch_tic6x:
      /* Disassembles as '<undefined instruction 0x56454314>' insn, but len
	 self-check passes, so let's allow it.  */
      goto generic_case;
    case bfd_arch_xtensa:
      /* Disassembles insn, but len self-check fails.  */
      return insn;
    case bfd_arch_or1k:
      /* Disassembles as '*unknown*' insn, but len self-check passes, so let's
	 allow it.  */
      goto generic_case;
    case bfd_arch_s390:
      /* nopr %r7 */
      static const gdb_byte s390_insn[] = { 0x07, 0x07 };

      insn = s390_insn;
      *len = sizeof (s390_insn);
      break;
    case bfd_arch_xstormy16:
      /* nop */
      static const gdb_byte xstormy16_insn[] = { 0x0, 0x0 };

      insn = xstormy16_insn;
      *len = sizeof (xstormy16_insn);
      break;
    case bfd_arch_nios2:
    case bfd_arch_score:
    case bfd_arch_riscv:
      /* nios2, riscv, and score need to know the current instruction
	 to select breakpoint instruction.  Give the breakpoint
	 instruction kind explicitly.  */
      {
	int bplen;
	insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen);
	*len = bplen;
      }
      break;
    case bfd_arch_arc:
      /* PR 21003 */
      if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
	return insn;
      goto generic_case;
    case bfd_arch_z80:
      {
	int bplen;
	insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 0x0008, &bplen);
	*len = bplen;
      }
      break;
    case bfd_arch_i386:
      {
	const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
	/* The disassembly tests will fail on x86-linux because
	   opcodes rejects an attempt to disassemble for an arch with
	   a 64-bit address size when bfd_vma is 32-bit.  */
	if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
	  return insn;
      }
      /* fall through */
    default:
    generic_case:
      {
	/* Test disassemble breakpoint instruction.  */
	CORE_ADDR pc = 0;
	int kind;
	int bplen;

	struct gdbarch_info info;
	info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);

	enum gdb_osabi it;
	bool found = false;
	for (it = GDB_OSABI_UNKNOWN; it != GDB_OSABI_INVALID;
	     it = static_cast<enum gdb_osabi> (static_cast<int> (it) + 1))
	  {
	    if (it == GDB_OSABI_UNKNOWN)
	      continue;

	    info.osabi = it;

	    if (it != GDB_OSABI_NONE)
	      {
		if (!has_gdb_osabi_handler (info))
		  /* Unsupported.  Skip to prevent warnings like:
		     A handler for the OS ABI <x> is not built into this
		     configuration of GDB.  Attempting to continue with the
		     default <y> settings.  */
		  continue;
	      }

	    gdbarch = gdbarch_find_by_info (info);
	    SELF_CHECK (gdbarch != NULL);

	    try
	      {
		kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
		insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
	      }
	    catch (...)
	      {
		continue;
	      }
	    found = true;
	    break;
	  }

	/* Assert that we have found an instruction to disassemble.  */
	SELF_CHECK (found);

	*len = bplen;
	break;
      }
    }
  SELF_CHECK (*len > 0);

  return insn;
}

/* Test disassembly of one instruction.  */

static void
print_one_insn_test (struct gdbarch *gdbarch)
{
  size_t len;
  const gdb_byte *insn = get_test_insn (gdbarch, &len);

  if (insn == nullptr)
    return;

  /* Test gdb_disassembler for a given gdbarch by reading data from a
     pre-allocated buffer.  If you want to see the disassembled
     instruction printed to gdb_stdout, use maint selftest -verbose.  */

  class gdb_disassembler_test : public gdb_disassembler
  {
  public:

    explicit gdb_disassembler_test (struct gdbarch *gdbarch,
				    const gdb_byte *insn, size_t len)
      : gdb_disassembler (gdbarch,
			  (run_verbose () ? gdb_stdlog : &null_stream),
			  gdb_disassembler_test::read_memory),
	m_insn (insn),
	m_len (len)
    {
    }

    int print_insn (CORE_ADDR memaddr)
    {
      int len = gdb_disassembler::print_insn (memaddr);

      if (run_verbose ())
	debug_printf ("\n");

      return len;
    }

  private:

    /* A buffer contain one instruction.  */
    const gdb_byte *m_insn;

    /* Length of the buffer.  */
    size_t m_len;

    static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
			    unsigned int len,
			    struct disassemble_info *info) noexcept
    {
      gdb_disassembler_test *self
	= static_cast<gdb_disassembler_test *> (info->application_data);

      /* The disassembler in opcodes may read more data than one
	 instruction.  Supply infinite consecutive copies
	 of the same instruction.  */
      for (size_t i = 0; i < len; i++)
	myaddr[i] = self->m_insn[(memaddr + i) % self->m_len];

      return 0;
    }
  };

  gdb_disassembler_test di (gdbarch, insn, len);

  SELF_CHECK (di.print_insn (0) == len);
}

/* Test the gdb_buffered_insn_length function.  */

static void
buffered_insn_length_test (struct gdbarch *gdbarch)
{
  size_t buf_len;
  const gdb_byte *insn = get_test_insn (gdbarch, &buf_len);

  if (insn == nullptr)
    return;

  /* The tic6x architecture is VLIW.  Disassembling requires that the
     entire instruction bundle be available.  However, the buffer we got
     back from get_test_insn only contains a single instruction, which is
     just part of an instruction bundle.  As a result, the disassemble will
     fail.  To avoid this, skip tic6x tests now.  */
  if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_tic6x)
    return;

  CORE_ADDR insn_address = 0;
  int calculated_len
    = gdb_buffered_insn_length (gdbarch, insn, buf_len, insn_address);

  SELF_CHECK (calculated_len == buf_len);
}

/* Test disassembly on memory error.  */

static void
memory_error_test (struct gdbarch *gdbarch)
{
  class gdb_disassembler_test : public gdb_disassembler
  {
  public:

    gdb_disassembler_test (struct gdbarch *gdbarch)
      : gdb_disassembler (gdbarch, &null_stream,
			  gdb_disassembler_test::read_memory)
    {
    }

    static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
			    unsigned int len,
			    struct disassemble_info *info) noexcept
    {
      /* Always return an error.  */
      return -1;
    }
  };

  if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_i386)
    {
      const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
      /* This test will fail on x86-linux because opcodes rejects an
	 attempt to disassemble for an arch with a 64-bit address size
	 when bfd_vma is 32-bit.  */
      if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
	return;
    }

  gdb_disassembler_test di (gdbarch);
  bool saw_memory_error = false;

  try
    {
      di.print_insn (0);
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == MEMORY_ERROR)
	saw_memory_error = true;
    }

  /* Expect MEMORY_ERROR.  */
  SELF_CHECK (saw_memory_error);
}

} // namespace selftests

void _initialize_disasm_selftests ();

void
_initialize_disasm_selftests ()
{
  selftests::register_test_foreach_arch ("print_one_insn",
					 selftests::print_one_insn_test);
  selftests::register_test_foreach_arch ("memory_error",
					 selftests::memory_error_test);
  selftests::register_test_foreach_arch ("buffered_insn_length",
					 selftests::buffered_insn_length_test);
}
