/* Function to ensure that the source and/or disassemly windows reflect the input address. */ void tui_update_source_windows_with_line (struct symtab *s, int line) { struct gdbarch *gdbarch; CORE_ADDR pc; struct tui_line_or_address l; if (!s) return; gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s)); switch (tui_current_layout ()) { case DISASSEM_COMMAND: case DISASSEM_DATA_COMMAND: find_line_pc (s, line, &pc); tui_update_source_windows_with_addr (gdbarch, pc); break; default: l.loa = LOA_LINE; l.u.line_no = line; tui_show_symtab_source (gdbarch, s, l, FALSE); if (tui_current_layout () == SRC_DISASSEM_COMMAND) { find_line_pc (s, line, &pc); tui_show_disassem (gdbarch, pc); } break; } return; }
/* Function to ensure that the source and/or disassemly windows reflect the input address. */ void tui_update_source_windows_with_line (struct symtab *s, int line) { CORE_ADDR pc; struct tui_line_or_address l; switch (tui_current_layout ()) { case DISASSEM_COMMAND: case DISASSEM_DATA_COMMAND: find_line_pc (s, line, &pc); tui_update_source_windows_with_addr (pc); break; default: l.loa = LOA_LINE; l.u.line_no = line; tui_show_symtab_source (s, l, FALSE); if (tui_current_layout () == SRC_DISASSEM_COMMAND) { find_line_pc (s, line, &pc); tui_show_disassem (pc); } break; } return; }
static void extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) { enum tui_layout_type cur_layout = tui_current_layout (); struct gdbarch *gdbarch = get_current_arch (); CORE_ADDR addr; CORE_ADDR pc; struct symtab_and_line cursal = get_current_source_symtab_and_line (); switch (cur_layout) { case SRC_COMMAND: case SRC_DATA_COMMAND: gdbarch = TUI_SRC_WIN->detail.source_info.gdbarch; find_line_pc (cursal.symtab, TUI_SRC_WIN->detail.source_info.start_line_or_addr.u.line_no, &pc); addr = pc; break; case DISASSEM_COMMAND: case SRC_DISASSEM_COMMAND: case DISASSEM_DATA_COMMAND: gdbarch = TUI_DISASM_WIN->detail.source_info.gdbarch; addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr; break; default: addr = 0; break; } *gdbarch_p = gdbarch; *addr_p = addr; }
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; }
/* 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); }
/* 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; }