static void
btrace_insn_history (struct ui_out *uiout,
		     const struct btrace_insn_iterator *begin,
		     const struct btrace_insn_iterator *end, int flags)
{
  struct gdbarch *gdbarch;
  struct btrace_insn_iterator it;

  DEBUG ("itrace (0x%x): [%u; %u)", flags, btrace_insn_number (begin),
	 btrace_insn_number (end));

  gdbarch = target_gdbarch ();

  for (it = *begin; btrace_insn_cmp (&it, end) != 0; btrace_insn_next (&it, 1))
    {
      const struct btrace_insn *insn;

      insn = btrace_insn_get (&it);

      /* Print the instruction index.  */
      ui_out_field_uint (uiout, "index", btrace_insn_number (&it));
      ui_out_text (uiout, "\t");

      /* Disassembly with '/m' flag may not produce the expected result.
	 See PR gdb/11833.  */
      gdb_disassembly (gdbarch, uiout, NULL, flags, 1, insn->pc, insn->pc + 1);
    }
}
Exemple #2
0
static void
btrace_insn_history (struct btrace_thread_info *btinfo, struct ui_out *uiout,
		     unsigned int begin, unsigned int end, int flags)
{
  struct gdbarch *gdbarch;
  struct btrace_inst *inst;
  unsigned int idx;

  DEBUG ("itrace (0x%x): [%u; %u[", flags, begin, end);

  gdbarch = target_gdbarch ();

  for (idx = begin; VEC_iterate (btrace_inst_s, btinfo->itrace, idx, inst)
	 && idx < end; ++idx)
    {
      /* Print the instruction index.  */
      ui_out_field_uint (uiout, "index", idx);
      ui_out_text (uiout, "\t");

      /* Disassembly with '/m' flag may not produce the expected result.
	 See PR gdb/11833.  */
      gdb_disassembly (gdbarch, uiout, NULL, flags, 1, inst->pc, inst->pc + 1);
    }
}
enum mi_cmd_result
mi_cmd_disassemble (char *command, char **argv, int argc)
{
  int mixed_source_and_assembly;
  struct symtab *s;

  /* Which options have we processed ... */
  int file_seen = 0;
  int line_seen = 0;
  int start_seen = 0;
  int end_seen = 0;
  int num_seen = 0;
  int prev_seen = 0;
  int peeklimit_seen = 0;

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

  /* Options processing stuff. */
  int optind = 0;
  char *optarg;
  enum opt
  {
    FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT, PREV_OPT, PEEKLIMIT_OPT
  };
  static struct mi_opt opts[] = {
    { "f", FILE_OPT, 1 },
    { "l", LINE_OPT, 1 },
    { "n", NUM_OPT, 1 },
    { "s", START_OPT, 1 },
    { "e", END_OPT, 1 },
    { "p", PREV_OPT, 1 },
    { "P", PEEKLIMIT_OPT, 1 },
    { NULL, 0, 0 }
  };

  /* Get the options with their arguments. Keep track of what we
     encountered. */
  while (1)
    {
      int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts,
			   &optind, &optarg);
      if (opt < 0)
	break;
      switch ((enum opt)opt)
	{
	case FILE_OPT:
	  file_string = xstrdup(optarg);
	  file_seen = 1;
	  break;
	case LINE_OPT:
	  line_num = atoi(optarg);
	  line_seen = 1;
	  break;
	case NUM_OPT:
	  how_many = atoi(optarg);
	  num_seen = 1;
	  break;
	case START_OPT:
	  start = parse_and_eval_address(optarg);
	  start_seen = 1;
	  break;
	case END_OPT:
	  high = parse_and_eval_address(optarg);
	  end_seen = 1;
	  break;
	case PREV_OPT:
	  prev = atoi(optarg);
	  prev_seen = 1;
	  break;
	case PEEKLIMIT_OPT:
	  peeklimit = atoi(optarg);
	  peeklimit_seen = 1;
	  break;
	default:
	  break;
	}
    }
  argv += optind;
  argc -= optind;

  if (argc < 1)
    mi_cmd_disassemble_usage ("Must specify mixed mode argument.");
  if (argc > 1)
    mi_cmd_disassemble_usage ("Extra arguments present.");

  if ((argv[0][0] == '\0') || (argv[0][1] != '\0'))
    mi_cmd_disassemble_usage ("Mixed mode argument must be 0 or 1.");
  if ((argv[0][0] != '0') && (argv[0][0] != '1'))
    mi_cmd_disassemble_usage ("Mixed mode argument must be 0 or 1.");
  mixed_source_and_assembly = (argv[0][0] == '1');

  if (start_seen && line_seen)
    mi_cmd_disassemble_usage ("May not specify both a line number and a start address.");

  if ((line_seen && !file_seen) || (file_seen && !line_seen))
    mi_cmd_disassemble_usage ("File and line number must be specified together.");

  if (line_seen && file_seen)
    {
      s = lookup_symtab (file_string);
      if (s == NULL)
	error ("mi_cmd_disassemble: Invalid filename.");
      if (! find_line_pc (s, line_num, &start))
	error ("mi_cmd_disassemble: Invalid line number.");
    }
  else if (! start_seen)
    mi_cmd_disassemble_usage ("No starting point specified.");

  if (end_seen)
    {
      if (num_seen || prev_seen)
	mi_cmd_disassemble_usage ("May not specify both an ending address and -n or -p.");

      gdb_disassembly (uiout, start, high, mixed_source_and_assembly, how_many);
      return MI_CMD_DONE;
    }

  if (find_pc_partial_function_no_inlined (start, NULL, &low, &high) == 0)
    error ("mi_cmd_disassemble: No function contains the specified address.");

  if (! num_seen)
    {
      /* If only the start address is given, disassemble the entire
	 function around the start address.  */

      gdb_disassembly(uiout, low, high, mixed_source_and_assembly, how_many);
      return MI_CMD_DONE;
    }

  /* And finally, now we know start_seen, !line_seen, !file_seen, !end_seen, and num_seen. */

  if (prev_seen)
    {
      CORE_ADDR tmp;
      int ret;

      if (peeklimit_seen >= 1)
        ret = find_pc_offset(start, &tmp, -prev, 1, peeklimit);
      else
        ret = find_pc_offset(start, &tmp, -prev, 1, -1);
      if ((ret != -1) && (tmp != INVALID_ADDRESS))
	start = tmp;
    }

  gdb_disassembly(uiout, start, high, mixed_source_and_assembly, how_many);
  return MI_CMD_DONE;
}
Exemple #4
0
/* 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 contins 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.
         2 -- disassembly and opcodes.
         3 -- disassembly, source and opcodes.
*/
void
mi_cmd_disassemble (char *command, char **argv, int argc)
{
  struct gdbarch *gdbarch = get_current_arch ();
  struct ui_out *uiout = current_uiout;
  CORE_ADDR start;

  int mode, disasm_flags;
  struct symtab *s;

  /* Which options have we processed ... */
  int file_seen = 0;
  int line_seen = 0;
  int num_seen = 0;
  int start_seen = 0;
  int end_seen = 0;

  /* ... and their corresponding value. */
  char *file_string = NULL;
  int line_num = -1;
  int how_many = -1;
  CORE_ADDR low = 0;
  CORE_ADDR high = 0;
  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);

  /* Options processing stuff. */
  int oind = 0;
  char *oarg;
  enum opt
  {
    FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_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},
    { 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 = xstrdup (oarg);
	  file_seen = 1;
	  make_cleanup (xfree, file_string);
	  break;
	case LINE_OPT:
	  line_num = atoi (oarg);
	  line_seen = 1;
	  break;
	case NUM_OPT:
	  how_many = atoi (oarg);
	  num_seen = 1;
	  break;
	case START_OPT:
	  low = parse_and_eval_address (oarg);
	  start_seen = 1;
	  break;
	case END_OPT:
	  high = parse_and_eval_address (oarg);
	  end_seen = 1;
	  break;
	}
    }
  argv += oind;
  argc -= oind;

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

  if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
	|| (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
	|| (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
    error (_("-data-disassemble: Usage: ( [-f filename -l linenum [-n "
	     "howmany]] | [-s startaddr -e endaddr]) [--] mode."));

  if (argc != 1)
    error (_("-data-disassemble: Usage: [-f filename -l linenum "
	     "[-n howmany]] [-s startaddr -e endaddr] [--] mode."));

  mode = atoi (argv[0]);
  if (mode < 0 || mode > 3)
    error (_("-data-disassemble: Mode argument must be 0, 1, 2, or 3."));

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

  disasm_flags = 0;
  if (mode & 0x1)
    disasm_flags |= DISASSEMBLY_SOURCE;
  if (mode & 0x2)
    disasm_flags |= DISASSEMBLY_RAW_INSN;

  /* 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"));
    }

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

  do_cleanups (cleanups);
}
Exemple #5
0
/* 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 contins that line.
   HOW_MANY: Number of disassembly lines to display. In mixed mode, it
   is the number of disassembly lines only, not counting the source
   lines.  

   always required:

   MODE: 0 or 1 for disassembly only, or mixed source and disassembly,
   respectively. */
enum mi_cmd_result
mi_cmd_disassemble (char *command, char **argv, int argc)
{
  enum mi_cmd_result retval;
  CORE_ADDR start;

  int mixed_source_and_assembly;
  struct symtab *s;

  /* Which options have we processed ... */
  int file_seen = 0;
  int line_seen = 0;
  int num_seen = 0;
  int start_seen = 0;
  int end_seen = 0;

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

  /* Options processing stuff. */
  int optind = 0;
  char *optarg;
  enum opt
  {
    FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
  };
  static struct mi_opt opts[] = {
    {"f", FILE_OPT, 1},
    {"l", LINE_OPT, 1},
    {"n", NUM_OPT, 1},
    {"s", START_OPT, 1},
    {"e", END_OPT, 1},
    0
  };

  /* Get the options with their arguments. Keep track of what we
     encountered. */
  while (1)
    {
      int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts,
			   &optind, &optarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case FILE_OPT:
	  file_string = xstrdup (optarg);
	  file_seen = 1;
	  break;
	case LINE_OPT:
	  line_num = atoi (optarg);
	  line_seen = 1;
	  break;
	case NUM_OPT:
	  how_many = atoi (optarg);
	  num_seen = 1;
	  break;
	case START_OPT:
	  low = parse_and_eval_address (optarg);
	  start_seen = 1;
	  break;
	case END_OPT:
	  high = parse_and_eval_address (optarg);
	  end_seen = 1;
	  break;
	}
    }
  argv += optind;
  argc -= optind;

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

  if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
	|| (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
	|| (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
    error
      ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode.");

  if (argc != 1)
    error
      ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode.");

  mixed_source_and_assembly = atoi (argv[0]);
  if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1))
    error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1.");


  /* 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 ("mi_cmd_disassemble: Invalid filename.");
      if (!find_line_pc (s, line_num, &start))
	error ("mi_cmd_disassemble: Invalid line number");
      if (find_pc_partial_function (start, NULL, &low, &high) == 0)
	error ("mi_cmd_disassemble: No function contains specified address");
    }

  gdb_disassembly (uiout,
  		   file_string,
		   line_num,
		   mixed_source_and_assembly, how_many, low, high);

  return MI_CMD_DONE;
}