/* MI Command Set - disassemble commands.
   Copyright (C) 2000-2024 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions (a Red Hat company).

   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 "arch-utils.h"
#include "target.h"
#include "value.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
#include "ui-out.h"
#include "disasm.h"

/* The arguments to be passed on the command line and parsed here are
   either:

   START-ADDRESS: address to start the disassembly at.
   END-ADDRESS: address to end the disassembly at.

   or:

   FILENAME: The name of the file where we want disassemble from.
   LINE: The line around which we want to disassemble. It will
   disassemble the function that contains that line.
   HOW_MANY: Number of disassembly lines to display. With source, it
   is the number of disassembly lines only, not counting the source
   lines.  

   always required:

   MODE: 0 -- disassembly.
	 1 -- disassembly and source (with deprecated source-centric view).
	 2 -- disassembly and opcodes.
	 3 -- disassembly, source-centric and opcodes.
	 4 -- disassembly, and source (with pc-centric view).
	 5 -- disassembly, source (pc-centric) and opcodes.  */

void
mi_cmd_disassemble (const char *command, const char *const *argv, int argc)
{
  struct gdbarch *gdbarch = get_current_arch ();
  struct ui_out *uiout = current_uiout;
  CORE_ADDR start;

  int mode;
  gdb_disassembly_flags disasm_flags;
  struct symtab *s;

  /* Which options have we processed ... */
  bool file_seen = false;
  bool line_seen = false;
  bool num_seen = false;
  bool start_seen = false;
  bool end_seen = false;
  bool addr_seen = false;
  bool opcodes_seen = false;
  bool source_seen = false;

  /* ... and their corresponding value. */
  const char *file_string = NULL;
  int line_num = -1;
  int how_many = -1;
  CORE_ADDR low = 0;
  CORE_ADDR high = 0;
  CORE_ADDR addr = 0;

  /* Flags to handle the --opcodes option.  */
  enum opcodes_mode
  {
    OPCODES_DEFAULT, OPCODES_NONE, OPCODES_DISPLAY, OPCODES_BYTES
  };
  enum opcodes_mode opcodes_mode = OPCODES_DEFAULT;

  /* Handle the -source option.  */
  bool show_source = false;

  /* Options processing stuff.  */
  int oind = 0;
  const char *oarg;
  enum opt
  {
    FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT, ADDR_OPT, OPCODES_OPT,
    SHOW_SRC_OPT
  };
  static const struct mi_opt opts[] =
    {
      {"f", FILE_OPT, 1},
      {"l", LINE_OPT, 1},
      {"n", NUM_OPT, 1},
      {"s", START_OPT, 1},
      {"e", END_OPT, 1},
      {"a", ADDR_OPT, 1},
      {"-opcodes", OPCODES_OPT, 1},
      {"-source", SHOW_SRC_OPT, 0},
      { 0, 0, 0 }
    };

  /* Get the options with their arguments. Keep track of what we
     encountered.  */
  while (1)
    {
      int opt = mi_getopt ("-data-disassemble", argc, argv, opts,
			   &oind, &oarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case FILE_OPT:
	  file_string = oarg;
	  file_seen = true;
	  break;
	case LINE_OPT:
	  line_num = atoi (oarg);
	  line_seen = true;
	  break;
	case NUM_OPT:
	  how_many = atoi (oarg);
	  num_seen = true;
	  break;
	case START_OPT:
	  low = parse_and_eval_address (oarg);
	  start_seen = true;
	  break;
	case END_OPT:
	  high = parse_and_eval_address (oarg);
	  end_seen = true;
	  break;
	case ADDR_OPT:
	  addr = parse_and_eval_address (oarg);
	  addr_seen = true;
	  break;
	case OPCODES_OPT:
	  opcodes_seen = true;
	  if (strcmp (oarg, "none") == 0)
	    opcodes_mode = OPCODES_NONE;
	  else if (strcmp (oarg, "display") == 0)
	    opcodes_mode = OPCODES_DISPLAY;
	  else if (strcmp (oarg, "bytes") == 0)
	    opcodes_mode = OPCODES_BYTES;
	  else
	    error (_("-data-disassemble: unknown value for -opcodes argument"));
	  break;
	case SHOW_SRC_OPT:
	  source_seen = true;
	  show_source = true;
	  break;
	}
    }
  argv += oind;
  argc -= oind;

  /* Allow only filename + linenum (with how_many which is not
     required) OR start_addr + end_addr OR addr.  */

  if (!(
	  ( line_seen &&  file_seen &&              !start_seen && !end_seen
								&& !addr_seen)

       || (!line_seen && !file_seen && !num_seen &&  start_seen &&  end_seen
								&& !addr_seen)

       || (!line_seen && !file_seen && !num_seen && !start_seen && !end_seen
								&&  addr_seen))
      || argc > 1)
    error (_("-data-disassemble: Usage: "
	     "( -f filename -l linenum [-n howmany] |"
	     " -s startaddr -e endaddr | -a addr ) "
	     "[ --opcodes mode ] [ --source ] [ [--] mode ]."));

  if (argc == 1)
    {
      mode = atoi (argv[0]);
      if (mode < 0 || mode > 5)
	error (_("-data-disassemble: Mode argument must be in the range 0-5."));
    }
  else
    mode = 0;

  if (mode != 0 && (source_seen || opcodes_seen))
    error (_("-data-disassemble: --opcodes and --source can only be used with mode 0"));

  /* Convert the mode into a set of disassembly flags.  */

  disasm_flags = 0;  /* Initialize here for -Wall.  */
  switch (mode)
    {
    case 0:
      break;
    case 1:
      disasm_flags |= DISASSEMBLY_SOURCE_DEPRECATED;
      break;
    case 2:
      disasm_flags |= DISASSEMBLY_RAW_BYTES;
      break;
    case 3:
      disasm_flags |= DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_RAW_BYTES;
      break;
    case 4:
      disasm_flags |= DISASSEMBLY_SOURCE;
      break;
    case 5:
      disasm_flags |= DISASSEMBLY_SOURCE | DISASSEMBLY_RAW_BYTES;
      break;
    default:
      gdb_assert_not_reached ("bad disassembly mode");
    }

  /* Now handle the (optional) --opcodes argument.  This partially
     overrides the mode value.  */
  if (opcodes_mode != OPCODES_DEFAULT)
    {
      /* Remove any existing flags related to opcodes display.  */
      disasm_flags &= ~(DISASSEMBLY_RAW_BYTES | DISASSEMBLY_RAW_INSN);

      /* Add back any required flags.  */
      if (opcodes_mode == OPCODES_DISPLAY)
	disasm_flags |= DISASSEMBLY_RAW_INSN;
      else if (opcodes_mode == OPCODES_BYTES)
	disasm_flags |= DISASSEMBLY_RAW_BYTES;
    }

  /* Handle the optional --source argument.  */
  if (show_source)
    {
      disasm_flags &= ~DISASSEMBLY_SOURCE_DEPRECATED;
      disasm_flags |= DISASSEMBLY_SOURCE;
    }

  /* We must get the function beginning and end where line_num is
     contained.  */

  if (line_seen && file_seen)
    {
      s = lookup_symtab (file_string);
      if (s == NULL)
	error (_("-data-disassemble: Invalid filename."));
      if (!find_line_pc (s, line_num, &start))
	error (_("-data-disassemble: Invalid line number"));
      if (find_pc_partial_function (start, NULL, &low, &high) == 0)
	error (_("-data-disassemble: "
		 "No function contains specified address"));
    }
  else if (addr_seen)
    {
      if (find_pc_partial_function (addr, NULL, &low, &high) == 0)
	error (_("-data-disassemble: "
		 "No function contains specified address"));
    }

  gdb_disassembly (gdbarch, uiout,
		   disasm_flags,
		   how_many, low, high);
}
