/* MI Command Set - disassemble commands.
- Copyright (C) 2000, 2001, 2002, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2016 Free Software Foundation, Inc.
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "arch-utils.h"
#include "target.h"
#include "value.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
-#include "gdb_string.h"
#include "ui-out.h"
#include "disasm.h"
-/* The arguments to be passed on the command line and parsed here are:
-
+/* The arguments to be passed on the command line and parsed here are
either:
START-ADDRESS: address to start the disassembly at.
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
+ 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 or 1 for disassembly only, or mixed source and disassembly,
- respectively. */
+ 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 (char *command, char **argv, int argc)
{
+ struct gdbarch *gdbarch = get_current_arch ();
+ struct ui_out *uiout = current_uiout;
CORE_ADDR start;
- int mixed_source_and_assembly;
+ int mode, disasm_flags;
struct symtab *s;
/* Which options have we processed ... */
int how_many = -1;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
+ struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
- /* Options processing stuff. */
- int optind = 0;
- char *optarg;
+ /* Options processing stuff. */
+ int oind = 0;
+ char *oarg;
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, 0, 0 }
- };
+ 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. */
+ encountered. */
while (1)
{
- int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts,
- &optind, &optarg);
+ 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 (optarg);
+ file_string = xstrdup (oarg);
file_seen = 1;
+ make_cleanup (xfree, file_string);
break;
case LINE_OPT:
- line_num = atoi (optarg);
+ line_num = atoi (oarg);
line_seen = 1;
break;
case NUM_OPT:
- how_many = atoi (optarg);
+ how_many = atoi (oarg);
num_seen = 1;
break;
case START_OPT:
- low = parse_and_eval_address (optarg);
+ low = parse_and_eval_address (oarg);
start_seen = 1;
break;
case END_OPT:
- high = parse_and_eval_address (optarg);
+ high = parse_and_eval_address (oarg);
end_seen = 1;
break;
}
}
- argv += optind;
- argc -= optind;
+ argv += oind;
+ argc -= oind;
/* Allow only filename + linenum (with how_many which is not
- required) OR start_addr + and_addr */
+ required) OR start_addr + end_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.");
+ error (_("-data-disassemble: Usage: ( [-f filename -l linenum [-n "
+ "howmany]] | [-s startaddr -e endaddr]) [--] mode."));
if (argc != 1)
- error
- ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode.");
+ error (_("-data-disassemble: Usage: [-f filename -l linenum "
+ "[-n howmany]] [-s startaddr -e endaddr] [--] 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."));
+ mode = atoi (argv[0]);
+ if (mode < 0 || mode > 5)
+ error (_("-data-disassemble: Mode argument must be in the range 0-5."));
+ /* 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_INSN;
+ break;
+ case 3:
+ disasm_flags |= DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_RAW_INSN;
+ break;
+ case 4:
+ disasm_flags |= DISASSEMBLY_SOURCE;
+ break;
+ case 5:
+ disasm_flags |= DISASSEMBLY_SOURCE | DISASSEMBLY_RAW_INSN;
+ break;
+ default:
+ gdb_assert_not_reached ("bad disassembly mode");
+ }
/* We must get the function beginning and end where line_num is
- contained. */
+ contained. */
if (line_seen && file_seen)
{
s = lookup_symtab (file_string);
if (s == NULL)
- error (_("mi_cmd_disassemble: Invalid filename."));
+ error (_("-data-disassemble: Invalid filename."));
if (!find_line_pc (s, line_num, &start))
- error (_("mi_cmd_disassemble: Invalid line number"));
+ error (_("-data-disassemble: Invalid line number"));
if (find_pc_partial_function (start, NULL, &low, &high) == 0)
- error (_("mi_cmd_disassemble: No function contains specified address"));
+ error (_("-data-disassemble: "
+ "No function contains specified address"));
}
- gdb_disassembly (uiout,
+ gdb_disassembly (gdbarch, uiout,
file_string,
- line_num,
- mixed_source_and_assembly, how_many, low, high);
+ disasm_flags,
+ how_many, low, high);
+ do_cleanups (cleanups);
}