xref: /dflybsd-src/contrib/gdb-7/gdb/mi/mi-cmd-disas.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* MI Command Set - disassemble commands.
2*ef5ccd6cSJohn Marino    Copyright (C) 2000-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert    Contributed by Cygnus Solutions (a Red Hat company).
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "arch-utils.h"
225796c8dcSSimon Schubert #include "target.h"
235796c8dcSSimon Schubert #include "value.h"
245796c8dcSSimon Schubert #include "mi-cmds.h"
255796c8dcSSimon Schubert #include "mi-getopt.h"
265796c8dcSSimon Schubert #include "gdb_string.h"
275796c8dcSSimon Schubert #include "ui-out.h"
285796c8dcSSimon Schubert #include "disasm.h"
295796c8dcSSimon Schubert 
30*ef5ccd6cSJohn Marino /* The arguments to be passed on the command line and parsed here are
315796c8dcSSimon Schubert    either:
325796c8dcSSimon Schubert 
335796c8dcSSimon Schubert    START-ADDRESS: address to start the disassembly at.
345796c8dcSSimon Schubert    END-ADDRESS: address to end the disassembly at.
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert    or:
375796c8dcSSimon Schubert 
385796c8dcSSimon Schubert    FILENAME: The name of the file where we want disassemble from.
395796c8dcSSimon Schubert    LINE: The line around which we want to disassemble. It will
405796c8dcSSimon Schubert    disassemble the function that contins that line.
41c50c785cSJohn Marino    HOW_MANY: Number of disassembly lines to display. With source, it
425796c8dcSSimon Schubert    is the number of disassembly lines only, not counting the source
435796c8dcSSimon Schubert    lines.
445796c8dcSSimon Schubert 
455796c8dcSSimon Schubert    always required:
465796c8dcSSimon Schubert 
47c50c785cSJohn Marino    MODE: 0 -- disassembly.
48c50c785cSJohn Marino          1 -- disassembly and source.
49c50c785cSJohn Marino          2 -- disassembly and opcodes.
50c50c785cSJohn Marino          3 -- disassembly, source and opcodes.
51c50c785cSJohn Marino */
52*ef5ccd6cSJohn Marino 
535796c8dcSSimon Schubert void
mi_cmd_disassemble(char * command,char ** argv,int argc)545796c8dcSSimon Schubert mi_cmd_disassemble (char *command, char **argv, int argc)
555796c8dcSSimon Schubert {
565796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_current_arch ();
57a45ae5f8SJohn Marino   struct ui_out *uiout = current_uiout;
585796c8dcSSimon Schubert   CORE_ADDR start;
595796c8dcSSimon Schubert 
60c50c785cSJohn Marino   int mode, disasm_flags;
615796c8dcSSimon Schubert   struct symtab *s;
625796c8dcSSimon Schubert 
635796c8dcSSimon Schubert   /* Which options have we processed ... */
645796c8dcSSimon Schubert   int file_seen = 0;
655796c8dcSSimon Schubert   int line_seen = 0;
665796c8dcSSimon Schubert   int num_seen = 0;
675796c8dcSSimon Schubert   int start_seen = 0;
685796c8dcSSimon Schubert   int end_seen = 0;
695796c8dcSSimon Schubert 
705796c8dcSSimon Schubert   /* ... and their corresponding value. */
715796c8dcSSimon Schubert   char *file_string = NULL;
725796c8dcSSimon Schubert   int line_num = -1;
735796c8dcSSimon Schubert   int how_many = -1;
745796c8dcSSimon Schubert   CORE_ADDR low = 0;
755796c8dcSSimon Schubert   CORE_ADDR high = 0;
76c50c785cSJohn Marino   struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
775796c8dcSSimon Schubert 
785796c8dcSSimon Schubert   /* Options processing stuff.  */
79*ef5ccd6cSJohn Marino   int oind = 0;
80*ef5ccd6cSJohn Marino   char *oarg;
815796c8dcSSimon Schubert   enum opt
825796c8dcSSimon Schubert   {
835796c8dcSSimon Schubert     FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
845796c8dcSSimon Schubert   };
85*ef5ccd6cSJohn Marino   static const struct mi_opt opts[] =
86*ef5ccd6cSJohn Marino     {
875796c8dcSSimon Schubert       {"f", FILE_OPT, 1},
885796c8dcSSimon Schubert       {"l", LINE_OPT, 1},
895796c8dcSSimon Schubert       {"n", NUM_OPT, 1},
905796c8dcSSimon Schubert       {"s", START_OPT, 1},
915796c8dcSSimon Schubert       {"e", END_OPT, 1},
925796c8dcSSimon Schubert       { 0, 0, 0 }
935796c8dcSSimon Schubert     };
945796c8dcSSimon Schubert 
955796c8dcSSimon Schubert   /* Get the options with their arguments. Keep track of what we
965796c8dcSSimon Schubert      encountered.  */
975796c8dcSSimon Schubert   while (1)
985796c8dcSSimon Schubert     {
99c50c785cSJohn Marino       int opt = mi_getopt ("-data-disassemble", argc, argv, opts,
100*ef5ccd6cSJohn Marino 			   &oind, &oarg);
1015796c8dcSSimon Schubert       if (opt < 0)
1025796c8dcSSimon Schubert 	break;
1035796c8dcSSimon Schubert       switch ((enum opt) opt)
1045796c8dcSSimon Schubert 	{
1055796c8dcSSimon Schubert 	case FILE_OPT:
106*ef5ccd6cSJohn Marino 	  file_string = xstrdup (oarg);
1075796c8dcSSimon Schubert 	  file_seen = 1;
108c50c785cSJohn Marino 	  make_cleanup (xfree, file_string);
1095796c8dcSSimon Schubert 	  break;
1105796c8dcSSimon Schubert 	case LINE_OPT:
111*ef5ccd6cSJohn Marino 	  line_num = atoi (oarg);
1125796c8dcSSimon Schubert 	  line_seen = 1;
1135796c8dcSSimon Schubert 	  break;
1145796c8dcSSimon Schubert 	case NUM_OPT:
115*ef5ccd6cSJohn Marino 	  how_many = atoi (oarg);
1165796c8dcSSimon Schubert 	  num_seen = 1;
1175796c8dcSSimon Schubert 	  break;
1185796c8dcSSimon Schubert 	case START_OPT:
119*ef5ccd6cSJohn Marino 	  low = parse_and_eval_address (oarg);
1205796c8dcSSimon Schubert 	  start_seen = 1;
1215796c8dcSSimon Schubert 	  break;
1225796c8dcSSimon Schubert 	case END_OPT:
123*ef5ccd6cSJohn Marino 	  high = parse_and_eval_address (oarg);
1245796c8dcSSimon Schubert 	  end_seen = 1;
1255796c8dcSSimon Schubert 	  break;
1265796c8dcSSimon Schubert 	}
1275796c8dcSSimon Schubert     }
128*ef5ccd6cSJohn Marino   argv += oind;
129*ef5ccd6cSJohn Marino   argc -= oind;
1305796c8dcSSimon Schubert 
1315796c8dcSSimon Schubert   /* Allow only filename + linenum (with how_many which is not
132*ef5ccd6cSJohn Marino      required) OR start_addr + end_addr.  */
1335796c8dcSSimon Schubert 
1345796c8dcSSimon Schubert   if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
1355796c8dcSSimon Schubert 	|| (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
1365796c8dcSSimon Schubert 	|| (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
137c50c785cSJohn Marino     error (_("-data-disassemble: Usage: ( [-f filename -l linenum [-n "
138c50c785cSJohn Marino 	     "howmany]] | [-s startaddr -e endaddr]) [--] mode."));
1395796c8dcSSimon Schubert 
1405796c8dcSSimon Schubert   if (argc != 1)
141c50c785cSJohn Marino     error (_("-data-disassemble: Usage: [-f filename -l linenum "
142c50c785cSJohn Marino 	     "[-n howmany]] [-s startaddr -e endaddr] [--] mode."));
1435796c8dcSSimon Schubert 
144c50c785cSJohn Marino   mode = atoi (argv[0]);
145c50c785cSJohn Marino   if (mode < 0 || mode > 3)
146c50c785cSJohn Marino     error (_("-data-disassemble: Mode argument must be 0, 1, 2, or 3."));
1475796c8dcSSimon Schubert 
148*ef5ccd6cSJohn Marino   /* Convert the mode into a set of disassembly flags.  */
149c50c785cSJohn Marino 
150c50c785cSJohn Marino   disasm_flags = 0;
151c50c785cSJohn Marino   if (mode & 0x1)
152c50c785cSJohn Marino     disasm_flags |= DISASSEMBLY_SOURCE;
153c50c785cSJohn Marino   if (mode & 0x2)
154c50c785cSJohn Marino     disasm_flags |= DISASSEMBLY_RAW_INSN;
1555796c8dcSSimon Schubert 
1565796c8dcSSimon Schubert   /* We must get the function beginning and end where line_num is
1575796c8dcSSimon Schubert      contained.  */
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert   if (line_seen && file_seen)
1605796c8dcSSimon Schubert     {
1615796c8dcSSimon Schubert       s = lookup_symtab (file_string);
1625796c8dcSSimon Schubert       if (s == NULL)
163c50c785cSJohn Marino 	error (_("-data-disassemble: Invalid filename."));
1645796c8dcSSimon Schubert       if (!find_line_pc (s, line_num, &start))
165c50c785cSJohn Marino 	error (_("-data-disassemble: Invalid line number"));
1665796c8dcSSimon Schubert       if (find_pc_partial_function (start, NULL, &low, &high) == 0)
167c50c785cSJohn Marino 	error (_("-data-disassemble: "
168c50c785cSJohn Marino 		 "No function contains specified address"));
1695796c8dcSSimon Schubert     }
1705796c8dcSSimon Schubert 
1715796c8dcSSimon Schubert   gdb_disassembly (gdbarch, uiout,
1725796c8dcSSimon Schubert   		   file_string,
173c50c785cSJohn Marino   		   disasm_flags,
1745796c8dcSSimon Schubert 		   how_many, low, high);
175c50c785cSJohn Marino 
176c50c785cSJohn Marino   do_cleanups (cleanups);
1775796c8dcSSimon Schubert }
178