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