+ std::string disassembler_options_holder;
+
+ gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr,
+ &disassembler_options_holder);
+
+ int result = gdbarch_print_insn (gdbarch, addr, &di);
+ disassemble_free_target (&di);
+ return result;
+}
+
+char *
+get_disassembler_options (struct gdbarch *gdbarch)
+{
+ char **disassembler_options = gdbarch_disassembler_options (gdbarch);
+ if (disassembler_options == NULL)
+ return NULL;
+ return *disassembler_options;
+}
+
+void
+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;
+
+ /* Allow all architectures, even ones that do not support 'set disassembler',
+ to reset their disassembler options to NULL. */
+ if (options == NULL)
+ {
+ if (disassembler_options != NULL)
+ {
+ free (*disassembler_options);
+ *disassembler_options = NULL;
+ }
+ return;
+ }
+
+ valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
+ if (valid_options_and_args == NULL)
+ {
+ fprintf_filtered (gdb_stderr, _("\
+'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 (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)
+ {
+ fprintf_filtered (gdb_stderr,
+ _("Invalid disassembler option value: '%s'.\n"),
+ opt);
+ return;
+ }
+ }
+
+ free (*disassembler_options);
+ *disassembler_options = xstrdup (options);
+}
+
+static void
+set_disassembler_options_sfunc (const char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_disassembler_options (prospective_options);
+}
+
+static void
+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);
+ if (options == NULL)
+ options = "";
+
+ fprintf_filtered (file, _("The current disassembler options are '%s'\n\n"),
+ options);
+
+ valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
+
+ if (valid_options_and_args == NULL)
+ {
+ fputs_filtered (_("There are no disassembler options available "
+ "for this architecture.\n"),
+ file);
+ return;
+ }
+
+ valid_options = &valid_options_and_args->options;
+
+ fprintf_filtered (file, _("\
+The following disassembler options are supported for use with the\n\
+'set disassembler-options OPTION [,OPTION]...' command:\n"));
+
+ if (valid_options->description != NULL)
+ {
+ size_t i, max_len = 0;
+
+ fprintf_filtered (file, "\n");