diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0f601bdbf07..7bb41008327 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,40 @@ +2018-07-02 Maciej W. Rozycki + Simon Marchi + + PR tdep/8282 + * disasm.h (gdb_disassembler): Add + `m_disassembler_options_holder'. member + * disasm.c (get_all_disassembler_options): New function. + (gdb_disassembler::gdb_disassembler): Use it. + (gdb_buffered_insn_length_init_dis): Likewise. + (gdb_buffered_insn_length): Adjust accordingly. + (set_disassembler_options): Handle options with arguments. + (show_disassembler_options_sfunc): Likewise. Add a leading new + line if showing options with descriptions. + (disassembler_options_completer): Adapt to using the + `disasm_options_and_args_t' structure. + * mips-tdep.c (mips_disassembler_options): New variable. + (mips_disassembler_options_o32): Likewise. + (mips_disassembler_options_n32): Likewise. + (mips_disassembler_options_n64): Likewise. + (gdb_print_insn_mips): Don't set `disassembler_options'. + (gdb_print_insn_mips_n32, gdb_print_insn_mips_n64): Remove + functions. + (mips_gdbarch_init): Always set `gdbarch_print_insn' to + `gdb_print_insn_mips'. Set `gdbarch_disassembler_options', + `gdbarch_disassembler_options_implicit' and + `gdbarch_valid_disassembler_options'. + * arm-tdep.c (_initialize_arm_tdep): Adapt to using the + `disasm_options_and_args_t' structure. + * gdbarch.sh (disassembler_options_implicit): New `gdbarch' + method. + (valid_disassembler_options): Switch from `disasm_options_t' to + the `disasm_options_and_args_t' structure. + * NEWS: Document `set disassembler-options' support for the MIPS + target. + * gdbarch.h: Regenerate. + * gdbarch.c: Regenerate. + 2018-07-02 Sebastian Huber * riscv-tdep.c (riscv_register_aliases): Swap "fp" and "s0" entries. diff --git a/gdb/NEWS b/gdb/NEWS index 839466e7e06..ab7632c817e 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,9 @@ *** Changes since GDB 8.1 +* The 'set disassembler-options' command now supports specifying options + for the MIPS target. + * The 'symbol-file' command now accepts an '-o' option to add a relative offset to all sections. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 3ea0e79b739..fdfb360f5cc 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9572,7 +9572,8 @@ _initialize_arm_tdep (void) arm_disassembler_options = xstrdup ("reg-names-std"); - const disasm_options_t *disasm_options = disassembler_options_arm (); + const disasm_options_t *disasm_options + = &disassembler_options_arm ()->options; int num_disassembly_styles = 0; for (i = 0; disasm_options->name[i] != NULL; i++) if (CONST_STRNEQ (disasm_options->name[i], "reg-names-")) diff --git a/gdb/disasm.c b/gdb/disasm.c index 6983903fd6f..11793df67c0 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -722,6 +722,31 @@ fprintf_disasm (void *stream, const char *format, ...) return 0; } +/* Combine implicit and user disassembler options and return them + in a newly-created string. */ + +static std::string +get_all_disassembler_options (struct gdbarch *gdbarch) +{ + const char *implicit = gdbarch_disassembler_options_implicit (gdbarch); + const char *options = get_disassembler_options (gdbarch); + const char *comma = ","; + + if (implicit == nullptr) + { + implicit = ""; + comma = ""; + } + + if (options == nullptr) + { + options = ""; + comma = ""; + } + + return string_printf ("%s%s%s", implicit, comma, options); +} + gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch, struct ui_file *file, di_read_memory_ftype read_memory_func) @@ -746,7 +771,9 @@ gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch, m_di.endian = gdbarch_byte_order (gdbarch); m_di.endian_code = gdbarch_byte_order_for_code (gdbarch); m_di.application_data = this; - m_di.disassembler_options = get_disassembler_options (gdbarch); + m_disassembler_options_holder = get_all_disassembler_options (gdbarch); + if (!m_disassembler_options_holder.empty ()) + m_di.disassembler_options = m_disassembler_options_holder.c_str (); disassemble_init_for_target (&m_di); } @@ -833,13 +860,16 @@ gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...) return 0; } -/* Initialize a struct disassemble_info for gdb_buffered_insn_length. */ +/* Initialize a struct disassemble_info for gdb_buffered_insn_length. + Upon return, *DISASSEMBLER_OPTIONS_HOLDER owns the string pointed + to by DI.DISASSEMBLER_OPTIONS. */ static void gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch, struct disassemble_info *di, const gdb_byte *insn, int max_len, - CORE_ADDR addr) + CORE_ADDR addr, + std::string *disassembler_options_holder) { init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf); @@ -855,7 +885,9 @@ gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch, di->endian = gdbarch_byte_order (gdbarch); di->endian_code = gdbarch_byte_order_for_code (gdbarch); - di->disassembler_options = get_disassembler_options (gdbarch); + *disassembler_options_holder = get_all_disassembler_options (gdbarch); + if (!disassembler_options_holder->empty ()) + di->disassembler_options = disassembler_options_holder->c_str (); disassemble_init_for_target (di); } @@ -867,8 +899,10 @@ gdb_buffered_insn_length (struct gdbarch *gdbarch, const gdb_byte *insn, int max_len, CORE_ADDR addr) { struct disassemble_info di; + std::string disassembler_options_holder; - gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr); + gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr, + &disassembler_options_holder); return gdbarch_print_insn (gdbarch, addr, &di); } @@ -887,6 +921,7 @@ set_disassembler_options (char *prospective_options) { struct gdbarch *gdbarch = get_current_arch (); char **disassembler_options = gdbarch_disassembler_options (gdbarch); + const disasm_options_and_args_t *valid_options_and_args; const disasm_options_t *valid_options; char *options = remove_whitespace_and_extra_commas (prospective_options); const char *opt; @@ -903,20 +938,42 @@ set_disassembler_options (char *prospective_options) return; } - valid_options = gdbarch_valid_disassembler_options (gdbarch); - if (valid_options == NULL) + valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch); + if (valid_options_and_args == NULL) { fprintf_filtered (gdb_stdlog, _("\ 'set disassembler-options ...' is not supported on this architecture.\n")); return; } + valid_options = &valid_options_and_args->options; + /* Verify we have valid disassembler options. */ FOR_EACH_DISASSEMBLER_OPTION (opt, options) { size_t i; for (i = 0; valid_options->name[i] != NULL; i++) - if (disassembler_options_cmp (opt, valid_options->name[i]) == 0) + if (valid_options->arg != NULL && valid_options->arg[i] != NULL) + { + size_t len = strlen (valid_options->name[i]); + bool found = false; + const char *arg; + size_t j; + + if (memcmp (opt, valid_options->name[i], len) != 0) + continue; + arg = opt + len; + for (j = 0; valid_options->arg[i]->values[j] != NULL; j++) + if (disassembler_options_cmp + (arg, valid_options->arg[i]->values[j]) == 0) + { + found = true; + break; + } + if (found) + break; + } + else if (disassembler_options_cmp (opt, valid_options->name[i]) == 0) break; if (valid_options->name[i] == NULL) { @@ -943,6 +1000,8 @@ show_disassembler_options_sfunc (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { struct gdbarch *gdbarch = get_current_arch (); + const disasm_options_and_args_t *valid_options_and_args; + const disasm_option_arg_t *valid_args; const disasm_options_t *valid_options; const char *options = get_disassembler_options (gdbarch); @@ -952,11 +1011,13 @@ show_disassembler_options_sfunc (struct ui_file *file, int from_tty, fprintf_filtered (file, _("The current disassembler options are '%s'\n"), options); - valid_options = gdbarch_valid_disassembler_options (gdbarch); + valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch); - if (valid_options == NULL) + if (valid_options_and_args == NULL) return; + valid_options = &valid_options_and_args->options; + fprintf_filtered (file, _("\n\ The following disassembler options are supported for use with the\n\ 'set disassembler-options