aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog37
-rw-r--r--gdb/NEWS3
-rw-r--r--gdb/arm-tdep.c3
-rw-r--r--gdb/disasm.c127
-rw-r--r--gdb/disasm.h5
-rw-r--r--gdb/doc/ChangeLog6
-rw-r--r--gdb/doc/gdb.texinfo2
-rw-r--r--gdb/gdbarch.c28
-rw-r--r--gdb/gdbarch.h7
-rwxr-xr-xgdb/gdbarch.sh3
-rw-r--r--gdb/mips-tdep.c60
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.arch/mips-disassembler-options.exp58
-rw-r--r--gdb/testsuite/gdb.arch/mips-disassembler-options.s30
14 files changed, 316 insertions, 59 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0f601bd..7bb4100 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,40 @@
+2018-07-02 Maciej W. Rozycki <macro@mips.com>
+ Simon Marchi <simon.marchi@polymtl.ca>
+
+ 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 <sebastian.huber@embedded-brains.de>
* riscv-tdep.c (riscv_register_aliases): Swap "fp" and "s0" entries.
diff --git a/gdb/NEWS b/gdb/NEWS
index 839466e..ab7632c 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 3ea0e79..fdfb360 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 6983903..11793df 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 <option>[,<option>...]' command:\n"));
@@ -965,10 +1026,15 @@ The following disassembler options are supported for use with the\n\
{
size_t i, max_len = 0;
+ fprintf_filtered (file, "\n");
+
/* Compute the length of the longest option name. */
for (i = 0; valid_options->name[i] != NULL; i++)
{
size_t len = strlen (valid_options->name[i]);
+
+ if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
+ len += strlen (valid_options->arg[i]->name);
if (max_len < len)
max_len = len;
}
@@ -976,10 +1042,17 @@ The following disassembler options are supported for use with the\n\
for (i = 0, max_len++; valid_options->name[i] != NULL; i++)
{
fprintf_filtered (file, " %s", valid_options->name[i]);
+ if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
+ fprintf_filtered (file, "%s", valid_options->arg[i]->name);
if (valid_options->description[i] != NULL)
- fprintf_filtered (file, "%*c %s",
- (int)(max_len - strlen (valid_options->name[i])), ' ',
- valid_options->description[i]);
+ {
+ size_t len = strlen (valid_options->name[i]);
+
+ if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
+ len += strlen (valid_options->arg[i]->name);
+ fprintf_filtered (file, "%*c %s", (int) (max_len - len), ' ',
+ valid_options->description[i]);
+ }
fprintf_filtered (file, "\n");
}
}
@@ -990,12 +1063,33 @@ The following disassembler options are supported for use with the\n\
for (i = 0; valid_options->name[i] != NULL; i++)
{
fprintf_filtered (file, "%s", valid_options->name[i]);
+ if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
+ fprintf_filtered (file, "%s", valid_options->arg[i]->name);
if (valid_options->name[i + 1] != NULL)
fprintf_filtered (file, ", ");
wrap_here (" ");
}
fprintf_filtered (file, "\n");
}
+
+ valid_args = valid_options_and_args->args;
+ if (valid_args != NULL)
+ {
+ size_t i, j;
+
+ for (i = 0; valid_args[i].name != NULL; i++)
+ {
+ fprintf_filtered (file, _("\n\
+ For the options above, the following values are supported for \"%s\":\n "),
+ valid_args[i].name);
+ for (j = 0; valid_args[i].values[j] != NULL; j++)
+ {
+ fprintf_filtered (file, " %s", valid_args[i].values[j]);
+ wrap_here (" ");
+ }
+ fprintf_filtered (file, "\n");
+ }
+ }
}
/* A completion function for "set disassembler". */
@@ -1006,10 +1100,13 @@ disassembler_options_completer (struct cmd_list_element *ignore,
const char *text, const char *word)
{
struct gdbarch *gdbarch = get_current_arch ();
- const disasm_options_t *opts = gdbarch_valid_disassembler_options (gdbarch);
+ const disasm_options_and_args_t *opts_and_args
+ = gdbarch_valid_disassembler_options (gdbarch);
- if (opts != NULL)
+ if (opts_and_args != NULL)
{
+ const disasm_options_t *opts = &opts_and_args->options;
+
/* Only attempt to complete on the last option text. */
const char *separator = strrchr (text, ',');
if (separator != NULL)
diff --git a/gdb/disasm.h b/gdb/disasm.h
index 6aa046a..d71f113 100644
--- a/gdb/disasm.h
+++ b/gdb/disasm.h
@@ -66,6 +66,11 @@ private:
/* Stores data required for disassembling instructions in
opcodes. */
struct disassemble_info m_di;
+
+ /* If we own the string in `m_di.disassembler_options', we do so
+ using this field. */
+ std::string m_disassembler_options_holder;
+
CORE_ADDR m_err_memaddr;
static int dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 6954398..fbdab9b 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-02 Maciej W. Rozycki <macro@mips.com>
+
+ PR tdep/8282
+ * gdb.texinfo (Source and Machine Code): Document `set
+ disassembler-options' support for the MIPS target.
+
2018-06-28 Petr Tesarik <ptesarik@suse.cz>
* gdb.texinfo (Files): Document "add-symbol-file -o offset".
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7fb6ac5..91ec219 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -8759,7 +8759,7 @@ The default value is the empty string.
If it is necessary to specify more than one disassembler option, then
multiple options can be placed together into a comma separated list.
-Currently this command is only supported on targets ARM, PowerPC
+Currently this command is only supported on targets ARM, MIPS, PowerPC
and S/390.
@kindex show disassembler-options
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 0c8d8ee..e2abf26 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -350,8 +350,9 @@ struct gdbarch
gdbarch_gcc_target_options_ftype *gcc_target_options;
gdbarch_gnu_triplet_regexp_ftype *gnu_triplet_regexp;
gdbarch_addressable_memory_unit_size_ftype *addressable_memory_unit_size;
+ const char * disassembler_options_implicit;
char ** disassembler_options;
- const disasm_options_t * valid_disassembler_options;
+ const disasm_options_and_args_t * valid_disassembler_options;
gdbarch_type_align_ftype *type_align;
};
@@ -707,6 +708,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of gcc_target_options, invalid_p == 0 */
/* Skip verify of gnu_triplet_regexp, invalid_p == 0 */
/* Skip verify of addressable_memory_unit_size, invalid_p == 0 */
+ /* Skip verify of disassembler_options_implicit, invalid_p == 0 */
/* Skip verify of disassembler_options, invalid_p == 0 */
/* Skip verify of valid_disassembler_options, invalid_p == 0 */
/* Skip verify of type_align, invalid_p == 0 */
@@ -902,6 +904,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: disassembler_options = %s\n",
pstring_ptr (gdbarch->disassembler_options));
fprintf_unfiltered (file,
+ "gdbarch_dump: disassembler_options_implicit = %s\n",
+ pstring (gdbarch->disassembler_options_implicit));
+ fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_displaced_step_copy_insn_p() = %d\n",
gdbarch_displaced_step_copy_insn_p (gdbarch));
fprintf_unfiltered (file,
@@ -5044,6 +5049,23 @@ set_gdbarch_addressable_memory_unit_size (struct gdbarch *gdbarch,
gdbarch->addressable_memory_unit_size = addressable_memory_unit_size;
}
+const char *
+gdbarch_disassembler_options_implicit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of disassembler_options_implicit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_disassembler_options_implicit called\n");
+ return gdbarch->disassembler_options_implicit;
+}
+
+void
+set_gdbarch_disassembler_options_implicit (struct gdbarch *gdbarch,
+ const char * disassembler_options_implicit)
+{
+ gdbarch->disassembler_options_implicit = disassembler_options_implicit;
+}
+
char **
gdbarch_disassembler_options (struct gdbarch *gdbarch)
{
@@ -5061,7 +5083,7 @@ set_gdbarch_disassembler_options (struct gdbarch *gdbarch,
gdbarch->disassembler_options = disassembler_options;
}
-const disasm_options_t *
+const disasm_options_and_args_t *
gdbarch_valid_disassembler_options (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
@@ -5073,7 +5095,7 @@ gdbarch_valid_disassembler_options (struct gdbarch *gdbarch)
void
set_gdbarch_valid_disassembler_options (struct gdbarch *gdbarch,
- const disasm_options_t * valid_disassembler_options)
+ const disasm_options_and_args_t * valid_disassembler_options)
{
gdbarch->valid_disassembler_options = valid_disassembler_options;
}
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index d13672bd..0df1fd1 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1549,11 +1549,14 @@ extern void set_gdbarch_addressable_memory_unit_size (struct gdbarch *gdbarch, g
/* Functions for allowing a target to modify its disassembler options. */
+extern const char * gdbarch_disassembler_options_implicit (struct gdbarch *gdbarch);
+extern void set_gdbarch_disassembler_options_implicit (struct gdbarch *gdbarch, const char * disassembler_options_implicit);
+
extern char ** gdbarch_disassembler_options (struct gdbarch *gdbarch);
extern void set_gdbarch_disassembler_options (struct gdbarch *gdbarch, char ** disassembler_options);
-extern const disasm_options_t * gdbarch_valid_disassembler_options (struct gdbarch *gdbarch);
-extern void set_gdbarch_valid_disassembler_options (struct gdbarch *gdbarch, const disasm_options_t * valid_disassembler_options);
+extern const disasm_options_and_args_t * gdbarch_valid_disassembler_options (struct gdbarch *gdbarch);
+extern void set_gdbarch_valid_disassembler_options (struct gdbarch *gdbarch, const disasm_options_and_args_t * valid_disassembler_options);
/* Type alignment. */
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index c85444d..4473943 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1157,8 +1157,9 @@ m;const char *;gnu_triplet_regexp;void;;;default_gnu_triplet_regexp;;0
m;int;addressable_memory_unit_size;void;;;default_addressable_memory_unit_size;;0
# Functions for allowing a target to modify its disassembler options.
+v;const char *;disassembler_options_implicit;;;0;0;;0;pstring (gdbarch->disassembler_options_implicit)
v;char **;disassembler_options;;;0;0;;0;pstring_ptr (gdbarch->disassembler_options)
-v;const disasm_options_t *;valid_disassembler_options;;;0;0;;0;host_address_to_string (gdbarch->valid_disassembler_options)
+v;const disasm_options_and_args_t *;valid_disassembler_options;;;0;0;;0;host_address_to_string (gdbarch->valid_disassembler_options)
# Type alignment.
m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 32b2d40..36fae02 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -214,6 +214,18 @@ static unsigned int mips_debug = 0;
struct target_desc *mips_tdesc_gp32;
struct target_desc *mips_tdesc_gp64;
+/* The current set of options to be passed to the disassembler. */
+static char *mips_disassembler_options;
+
+/* Implicit disassembler options for individual ABIs. These tell
+ libopcodes to use general-purpose register names corresponding
+ to the ABI we have selected, perhaps via a `set mips abi ...'
+ override, rather than ones inferred from the ABI set in the ELF
+ headers of the binary file selected for debugging. */
+static const char mips_disassembler_options_o32[] = "gpr-names=32";
+static const char mips_disassembler_options_n32[] = "gpr-names=n32";
+static const char mips_disassembler_options_n64[] = "gpr-names=64";
+
const struct mips_regnum *
mips_regnum (struct gdbarch *gdbarch)
{
@@ -6990,40 +7002,9 @@ gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info)
memaddr &= (info->mach == bfd_mach_mips16
|| info->mach == bfd_mach_mips_micromips) ? ~1 : ~3;
- /* Set the disassembler options. */
- if (!info->disassembler_options)
- /* This string is not recognized explicitly by the disassembler,
- but it tells the disassembler to not try to guess the ABI from
- the bfd elf headers, such that, if the user overrides the ABI
- of a program linked as NewABI, the disassembly will follow the
- register naming conventions specified by the user. */
- info->disassembler_options = "gpr-names=32";
-
return default_print_insn (memaddr, info);
}
-static int
-gdb_print_insn_mips_n32 (bfd_vma memaddr, struct disassemble_info *info)
-{
- /* Set up the disassembler info, so that we get the right
- register names from libopcodes. */
- info->disassembler_options = "gpr-names=n32";
- info->flavour = bfd_target_elf_flavour;
-
- return gdb_print_insn_mips (memaddr, info);
-}
-
-static int
-gdb_print_insn_mips_n64 (bfd_vma memaddr, struct disassemble_info *info)
-{
- /* Set up the disassembler info, so that we get the right
- register names from libopcodes. */
- info->disassembler_options = "gpr-names=64";
- info->flavour = bfd_target_elf_flavour;
-
- return gdb_print_insn_mips (memaddr, info);
-}
-
/* Implement the breakpoint_kind_from_pc gdbarch method. */
static int
@@ -8727,12 +8708,19 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info);
- if (mips_abi == MIPS_ABI_N32)
- set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips_n32);
- else if (mips_abi == MIPS_ABI_N64)
- set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips_n64);
+ set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips);
+ if (mips_abi == MIPS_ABI_N64)
+ set_gdbarch_disassembler_options_implicit
+ (gdbarch, (const char *) mips_disassembler_options_n64);
+ else if (mips_abi == MIPS_ABI_N32)
+ set_gdbarch_disassembler_options_implicit
+ (gdbarch, (const char *) mips_disassembler_options_n32);
else
- set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips);
+ set_gdbarch_disassembler_options_implicit
+ (gdbarch, (const char *) mips_disassembler_options_o32);
+ set_gdbarch_disassembler_options (gdbarch, &mips_disassembler_options);
+ set_gdbarch_valid_disassembler_options (gdbarch,
+ disassembler_options_mips ());
/* FIXME: cagney/2003-08-29: The macros target_have_steppable_watchpoint,
HAVE_NONSTEPPABLE_WATCHPOINT, and target_have_continuable_watchpoint
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 93c849c..e802927 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-02 Maciej W. Rozycki <macro@mips.com>
+
+ PR tdep/8282
+ * gdb.arch/mips-disassembler-options.exp: New test.
+ * gdb.arch/mips-disassembler-options.s: New test source.
+
2018-06-29 Pedro Alves <palves@redhat.com>
* gdb.threads/names.exp: Adjust expected "info threads" output.
diff --git a/gdb/testsuite/gdb.arch/mips-disassembler-options.exp b/gdb/testsuite/gdb.arch/mips-disassembler-options.exp
new file mode 100644
index 0000000..8db3026
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/mips-disassembler-options.exp
@@ -0,0 +1,58 @@
+# Copyright 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test MIPS disassembler options.
+
+if { ![istarget "mips*-*-*"] } then {
+ verbose "Skipping MIPS disassembler option tests."
+ return
+}
+
+standard_testfile .s
+set objfile [standard_output_file ${testfile}.o]
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {}] \
+ != "" } {
+ return
+}
+
+clean_restart ${objfile}
+
+proc mips_disassemble_test { func insn mesg } {
+ gdb_test "disassemble $func" \
+ "Dump of assembler code for function\
+ $func:\r\n\[^:\]+:\t$insn\r\nEnd of assembler dump\." \
+ $mesg
+}
+
+# Verify defaults.
+mips_disassemble_test foo "move\tv0,v1" "disassemble default"
+
+# Verify option overrides.
+gdb_test "set disassembler-options gpr-names=numeric"
+mips_disassemble_test foo "move\t\\\$2,\\\$3" "disassemble numeric, gpr-names"
+# Check multiple options too.
+gdb_test "set disassembler-options msa,reg-names=numeric,reg-names=r3000"
+mips_disassemble_test foo "move\t\\\$2,\\\$3" "disassemble numeric, reg-names"
+
+# Verify ABI overrides.
+mips_disassemble_test bar "move\t\\\$2,\\\$8" "disassemble ABI, numeric"
+gdb_test "set disassembler-options"
+gdb_test "set mips abi o32"
+mips_disassemble_test bar "move\tv0,t0" "disassemble ABI, o32"
+gdb_test "set mips abi n32"
+mips_disassemble_test bar "move\tv0,a4" "disassemble ABI, n32"
+gdb_test "set mips abi n64"
+mips_disassemble_test bar "move\tv0,a4" "disassemble ABI, n64"
diff --git a/gdb/testsuite/gdb.arch/mips-disassembler-options.s b/gdb/testsuite/gdb.arch/mips-disassembler-options.s
new file mode 100644
index 0000000..6bf48cc
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/mips-disassembler-options.s
@@ -0,0 +1,30 @@
+# This test is part of GDB, the GNU debugger.
+#
+# Copyright 2018 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Note: this is meant to be buildable as MIPS16 or microMIPS code too.
+
+ .globl foo
+ .ent foo
+foo:
+ move $2, $3
+ .end foo
+
+ .globl bar
+ .ent bar
+bar:
+ move $2, $8
+ .end bar