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

   Copyright (C) 2017-2018 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"

#if GDB_SELF_TEST
#include "selftest.h"
#include "selftest-arch.h"

namespace selftests {

/* Test disassembly of one instruction.  */

static void
print_one_insn_test (struct gdbarch *gdbarch)
{
  size_t len = 0;
  const gdb_byte *insn = NULL;

  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:
    case bfd_arch_mep:
    case bfd_arch_mips:
    case bfd_arch_tic6x:
    case bfd_arch_xtensa:
      return;
    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_arc:
      /* PR 21003 */
      if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
	return;
      /* fall through */
    case bfd_arch_nios2:
    case bfd_arch_score:
      /* nios2 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;
    default:
      {
	/* Test disassemble breakpoint instruction.  */
	CORE_ADDR pc = 0;
	int kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
	int bplen;

	insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
	len = bplen;

	break;
      }
    }
  SELF_CHECK (len > 0);

  /* 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, set verbose to true.  */
  static const bool verbose = false;

  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,
			  (verbose ? gdb_stdout : &null_stream),
			  gdb_disassembler_test::read_memory),
	m_insn (insn), m_len (len)
    {
    }

    int
    print_insn (CORE_ADDR memaddr)
    {
      if (verbose)
	{
	  fprintf_unfiltered (stream (), "%s ",
			      gdbarch_bfd_arch_info (arch ())->arch_name);
	}

      int len = gdb_disassembler::print_insn (memaddr);

      if (verbose)
	fprintf_unfiltered (stream (), "\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)
    {
      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 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)
    {
      /* Always return an error.  */
      return -1;
    }
  };

  gdb_disassembler_test di (gdbarch);
  bool saw_memory_error = false;

  TRY
    {
      di.print_insn (0);
    }
  CATCH (ex, RETURN_MASK_ERROR)
    {
      if (ex.error == MEMORY_ERROR)
	saw_memory_error = true;
    }
  END_CATCH

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

} // namespace selftests
#endif /* GDB_SELF_TEST */

void
_initialize_disasm_selftests (void)
{
#if GDB_SELF_TEST
  selftests::register_test_foreach_arch ("print_one_insn",
					 selftests::print_one_insn_test);
  selftests::register_test_foreach_arch ("memory_error",
					 selftests::memory_error_test);
#endif
}
