198944Sobrien/* MI Command Set - disassemble commands. 298944Sobrien Copyright 2000, 2001, 2002 Free Software Foundation, Inc. 398944Sobrien Contributed by Cygnus Solutions (a Red Hat company). 498944Sobrien 598944Sobrien This file is part of GDB. 698944Sobrien 798944Sobrien This program is free software; you can redistribute it and/or modify 898944Sobrien it under the terms of the GNU General Public License as published by 998944Sobrien the Free Software Foundation; either version 2 of the License, or 1098944Sobrien (at your option) any later version. 1198944Sobrien 1298944Sobrien This program is distributed in the hope that it will be useful, 1398944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1498944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598944Sobrien GNU General Public License for more details. 1698944Sobrien 1798944Sobrien You should have received a copy of the GNU General Public License 1898944Sobrien along with this program; if not, write to the Free Software 1998944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2098944Sobrien Boston, MA 02111-1307, USA. */ 2198944Sobrien 2298944Sobrien#include "defs.h" 2398944Sobrien#include "target.h" 2498944Sobrien#include "value.h" 2598944Sobrien#include "mi-cmds.h" 2698944Sobrien#include "mi-getopt.h" 27130803Smarcel#include "gdb_string.h" 2898944Sobrien#include "ui-out.h" 29130803Smarcel#include "disasm.h" 3098944Sobrien 3198944Sobrien/* The arguments to be passed on the command line and parsed here are: 3298944Sobrien 3398944Sobrien either: 3498944Sobrien 3598944Sobrien START-ADDRESS: address to start the disassembly at. 3698944Sobrien END-ADDRESS: address to end the disassembly at. 3798944Sobrien 3898944Sobrien or: 3998944Sobrien 4098944Sobrien FILENAME: The name of the file where we want disassemble from. 4198944Sobrien LINE: The line around which we want to disassemble. It will 4298944Sobrien disassemble the function that contins that line. 4398944Sobrien HOW_MANY: Number of disassembly lines to display. In mixed mode, it 4498944Sobrien is the number of disassembly lines only, not counting the source 4598944Sobrien lines. 4698944Sobrien 4798944Sobrien always required: 4898944Sobrien 4998944Sobrien MODE: 0 or 1 for disassembly only, or mixed source and disassembly, 5098944Sobrien respectively. */ 5198944Sobrienenum mi_cmd_result 5298944Sobrienmi_cmd_disassemble (char *command, char **argv, int argc) 5398944Sobrien{ 54130803Smarcel enum mi_cmd_result retval; 5598944Sobrien CORE_ADDR start; 5698944Sobrien 5798944Sobrien int mixed_source_and_assembly; 5898944Sobrien struct symtab *s; 5998944Sobrien 6098944Sobrien /* Which options have we processed ... */ 6198944Sobrien int file_seen = 0; 6298944Sobrien int line_seen = 0; 6398944Sobrien int num_seen = 0; 6498944Sobrien int start_seen = 0; 6598944Sobrien int end_seen = 0; 6698944Sobrien 6798944Sobrien /* ... and their corresponding value. */ 6898944Sobrien char *file_string = NULL; 6998944Sobrien int line_num = -1; 7098944Sobrien int how_many = -1; 7198944Sobrien CORE_ADDR low = 0; 7298944Sobrien CORE_ADDR high = 0; 7398944Sobrien 7498944Sobrien /* Options processing stuff. */ 7598944Sobrien int optind = 0; 7698944Sobrien char *optarg; 7798944Sobrien enum opt 7898944Sobrien { 79130803Smarcel FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT 80130803Smarcel }; 81130803Smarcel static struct mi_opt opts[] = { 8298944Sobrien {"f", FILE_OPT, 1}, 8398944Sobrien {"l", LINE_OPT, 1}, 8498944Sobrien {"n", NUM_OPT, 1}, 8598944Sobrien {"s", START_OPT, 1}, 8698944Sobrien {"e", END_OPT, 1}, 8798944Sobrien 0 8898944Sobrien }; 8998944Sobrien 9098944Sobrien /* Get the options with their arguments. Keep track of what we 9198944Sobrien encountered. */ 9298944Sobrien while (1) 9398944Sobrien { 9498944Sobrien int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts, 9598944Sobrien &optind, &optarg); 9698944Sobrien if (opt < 0) 9798944Sobrien break; 9898944Sobrien switch ((enum opt) opt) 9998944Sobrien { 10098944Sobrien case FILE_OPT: 10198944Sobrien file_string = xstrdup (optarg); 10298944Sobrien file_seen = 1; 10398944Sobrien break; 10498944Sobrien case LINE_OPT: 10598944Sobrien line_num = atoi (optarg); 10698944Sobrien line_seen = 1; 10798944Sobrien break; 10898944Sobrien case NUM_OPT: 10998944Sobrien how_many = atoi (optarg); 11098944Sobrien num_seen = 1; 11198944Sobrien break; 11298944Sobrien case START_OPT: 11398944Sobrien low = parse_and_eval_address (optarg); 11498944Sobrien start_seen = 1; 11598944Sobrien break; 11698944Sobrien case END_OPT: 11798944Sobrien high = parse_and_eval_address (optarg); 11898944Sobrien end_seen = 1; 11998944Sobrien break; 12098944Sobrien } 12198944Sobrien } 12298944Sobrien argv += optind; 12398944Sobrien argc -= optind; 12498944Sobrien 12598944Sobrien /* Allow only filename + linenum (with how_many which is not 12698944Sobrien required) OR start_addr + and_addr */ 12798944Sobrien 12898944Sobrien if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen) 12998944Sobrien || (line_seen && file_seen && !num_seen && !start_seen && !end_seen) 130130803Smarcel || (!line_seen && !file_seen && !num_seen && start_seen && end_seen))) 131130803Smarcel error 132130803Smarcel ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode."); 13398944Sobrien 13498944Sobrien if (argc != 1) 135130803Smarcel error 136130803Smarcel ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode."); 13798944Sobrien 13898944Sobrien mixed_source_and_assembly = atoi (argv[0]); 13998944Sobrien if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1)) 14098944Sobrien error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1."); 14198944Sobrien 142130803Smarcel 14398944Sobrien /* We must get the function beginning and end where line_num is 14498944Sobrien contained. */ 14598944Sobrien 14698944Sobrien if (line_seen && file_seen) 14798944Sobrien { 14898944Sobrien s = lookup_symtab (file_string); 14998944Sobrien if (s == NULL) 15098944Sobrien error ("mi_cmd_disassemble: Invalid filename."); 15198944Sobrien if (!find_line_pc (s, line_num, &start)) 15298944Sobrien error ("mi_cmd_disassemble: Invalid line number"); 15398944Sobrien if (find_pc_partial_function (start, NULL, &low, &high) == 0) 15498944Sobrien error ("mi_cmd_disassemble: No function contains specified address"); 15598944Sobrien } 15698944Sobrien 157130803Smarcel gdb_disassembly (uiout, 158130803Smarcel file_string, 159130803Smarcel line_num, 160130803Smarcel mixed_source_and_assembly, how_many, low, high); 16198944Sobrien 16298944Sobrien return MI_CMD_DONE; 16398944Sobrien} 164