X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fdisasm.c;h=c6edc92930d66db7c77068679fda81aa5456ae53;hb=0d02e70b197c786f26175b9a73f94e01d14abdab;hp=d989a8b7f508f7a534e6d4bd0148de8ddc57982c;hpb=d55e5aa6b29906346c51ad00e6a9b112590aa294;p=binutils-gdb.git
diff --git a/gdb/disasm.c b/gdb/disasm.c
index d989a8b7f50..c6edc92930d 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -1,6 +1,6 @@
/* Disassemble support for GDB.
- Copyright (C) 2000-2019 Free Software Foundation, Inc.
+ Copyright (C) 2000-2022 Free Software Foundation, Inc.
This file is part of GDB.
@@ -18,23 +18,20 @@
along with this program. If not, see . */
#include "defs.h"
-
-/* Standard C++ includes. */
-#include
-
-/* Local non-gdb includes. */
#include "arch-utils.h"
-#include "common/gdb_optional.h"
-#include "dis-asm.h"
+#include "target.h"
+#include "value.h"
+#include "ui-out.h"
#include "disasm.h"
-#include "gdbcmd.h"
#include "gdbcore.h"
-#include "safe-ctype.h"
+#include "gdbcmd.h"
+#include "dis-asm.h"
#include "source.h"
-#include "target.h"
-#include "ui-out.h"
+#include "safe-ctype.h"
+#include
+#include "gdbsupport/gdb_optional.h"
#include "valprint.h"
-#include "value.h"
+#include "cli/cli-style.h"
/* Disassemble functions.
FIXME: We should get rid of all the duplicate code in gdb that does
@@ -42,7 +39,7 @@
/* This variable is used to hold the prospective disassembler_options value
which is set by the "set disassembler_options" command. */
-static char *prospective_options = NULL;
+static std::string prospective_options;
/* This structure is used to store line number information for the
deprecated /m option.
@@ -135,9 +132,9 @@ line_has_code_p (htab_t table, struct symtab *symtab, int line)
/* Wrapper of target_read_code. */
int
-gdb_disassembler::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
- unsigned int len,
- struct disassemble_info *info)
+gdb_disassembler_memory_reader::dis_asm_read_memory
+ (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
+ struct disassemble_info *info)
{
return target_read_code (memaddr, myaddr, len);
}
@@ -151,7 +148,7 @@ gdb_disassembler::dis_asm_memory_error (int err, bfd_vma memaddr,
gdb_disassembler *self
= static_cast(info->application_data);
- self->m_err_memaddr = memaddr;
+ self->m_err_memaddr.emplace (memaddr);
}
/* Wrapper of print_address. */
@@ -166,28 +163,58 @@ gdb_disassembler::dis_asm_print_address (bfd_vma addr,
print_address (self->arch (), addr, self->stream ());
}
-static int
-compare_lines (const void *mle1p, const void *mle2p)
+/* Format disassembler output to STREAM. */
+
+int
+gdb_printing_disassembler::fprintf_func (void *stream,
+ const char *format, ...)
{
- struct deprecated_dis_line_entry *mle1, *mle2;
- int val;
+ va_list args;
- mle1 = (struct deprecated_dis_line_entry *) mle1p;
- mle2 = (struct deprecated_dis_line_entry *) mle2p;
+ va_start (args, format);
+ gdb_vprintf ((struct ui_file *) stream, format, args);
+ va_end (args);
+ /* Something non -ve. */
+ return 0;
+}
+
+/* See disasm.h. */
+
+int
+gdb_printing_disassembler::fprintf_styled_func (void *stream,
+ enum disassembler_style style,
+ const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ gdb_vprintf ((struct ui_file *) stream, format, args);
+ va_end (args);
+ /* Something non -ve. */
+ return 0;
+}
+
+static bool
+line_is_less_than (const deprecated_dis_line_entry &mle1,
+ const deprecated_dis_line_entry &mle2)
+{
+ bool val;
/* End of sequence markers have a line number of 0 but don't want to
be sorted to the head of the list, instead sort by PC. */
- if (mle1->line == 0 || mle2->line == 0)
+ if (mle1.line == 0 || mle2.line == 0)
{
- val = mle1->start_pc - mle2->start_pc;
- if (val == 0)
- val = mle1->line - mle2->line;
+ if (mle1.start_pc != mle2.start_pc)
+ val = mle1.start_pc < mle2.start_pc;
+ else
+ val = mle1.line < mle2.line;
}
else
{
- val = mle1->line - mle2->line;
- if (val == 0)
- val = mle1->start_pc - mle2->start_pc;
+ if (mle1.line != mle2.line)
+ val = mle1.line < mle2.line;
+ else
+ val = mle1.start_pc < mle2.start_pc;
}
return val;
}
@@ -195,8 +222,7 @@ compare_lines (const void *mle1p, const void *mle2p)
/* See disasm.h. */
int
-gdb_pretty_print_disassembler::pretty_print_insn (struct ui_out *uiout,
- const struct disasm_insn *insn,
+gdb_pretty_print_disassembler::pretty_print_insn (const struct disasm_insn *insn,
gdb_disassembly_flags flags)
{
/* parts of the symbolic representation of the address */
@@ -208,57 +234,93 @@ gdb_pretty_print_disassembler::pretty_print_insn (struct ui_out *uiout,
struct gdbarch *gdbarch = arch ();
{
- ui_out_emit_tuple tuple_emitter (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (m_uiout, NULL);
pc = insn->addr;
if (insn->number != 0)
{
- uiout->field_fmt ("insn-number", "%u", insn->number);
- uiout->text ("\t");
+ m_uiout->field_unsigned ("insn-number", insn->number);
+ m_uiout->text ("\t");
}
if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
{
if (insn->is_speculative)
{
- uiout->field_string ("is-speculative", "?");
+ m_uiout->field_string ("is-speculative", "?");
/* The speculative execution indication overwrites the first
character of the PC prefix.
We assume a PC prefix length of 3 characters. */
if ((flags & DISASSEMBLY_OMIT_PC) == 0)
- uiout->text (pc_prefix (pc) + 1);
+ m_uiout->text (pc_prefix (pc) + 1);
else
- uiout->text (" ");
+ m_uiout->text (" ");
}
else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
- uiout->text (pc_prefix (pc));
+ m_uiout->text (pc_prefix (pc));
else
- uiout->text (" ");
+ m_uiout->text (" ");
}
else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
- uiout->text (pc_prefix (pc));
- uiout->field_core_addr ("address", gdbarch, pc);
+ m_uiout->text (pc_prefix (pc));
+ m_uiout->field_core_addr ("address", gdbarch, pc);
std::string name, filename;
- if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
- &line, &unmapped))
+ bool omit_fname = ((flags & DISASSEMBLY_OMIT_FNAME) != 0);
+ if (!build_address_symbolic (gdbarch, pc, false, omit_fname, &name,
+ &offset, &filename, &line, &unmapped))
{
/* We don't care now about line, filename and unmapped. But we might in
the future. */
- uiout->text (" <");
- if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
- uiout->field_string ("func-name", name.c_str (),
- ui_out_style_kind::FUNCTION);
- uiout->text ("+");
- uiout->field_int ("offset", offset);
- uiout->text (">:\t");
+ m_uiout->text (" <");
+ if (!omit_fname)
+ m_uiout->field_string ("func-name", name,
+ function_name_style.style ());
+ /* For negative offsets, avoid displaying them as +-N; the sign of
+ the offset takes the place of the "+" here. */
+ if (offset >= 0)
+ m_uiout->text ("+");
+ m_uiout->field_signed ("offset", offset);
+ m_uiout->text (">:\t");
}
else
- uiout->text (":\t");
+ m_uiout->text (":\t");
+ /* Clear the buffer into which we will disassemble the instruction. */
m_insn_stb.clear ();
+ /* A helper function to write the M_INSN_STB buffer, followed by a
+ newline. This can be called in a couple of situations. */
+ auto write_out_insn_buffer = [&] ()
+ {
+ m_uiout->field_stream ("inst", m_insn_stb);
+ m_uiout->text ("\n");
+ };
+
+ try
+ {
+ /* Now we can disassemble the instruction. If the disassembler
+ returns a negative value this indicates an error and is handled
+ within the print_insn call, resulting in an exception being
+ thrown. Returning zero makes no sense, as this indicates we
+ disassembled something successfully, but it was something of no
+ size? */
+ size = m_di.print_insn (pc);
+ gdb_assert (size > 0);
+ }
+ catch (const gdb_exception &ex)
+ {
+ /* An exception was thrown while disassembling the instruction.
+ However, the disassembler might still have written something
+ out, so ensure that we flush the instruction buffer before
+ rethrowing the exception. We can't perform this write from an
+ object destructor as the write itself might throw an exception
+ if the pager kicks in, and the user selects quit. */
+ write_out_insn_buffer ();
+ throw ex;
+ }
+
if (flags & DISASSEMBLY_RAW_INSN)
{
CORE_ADDR end_pc;
@@ -269,7 +331,6 @@ gdb_pretty_print_disassembler::pretty_print_insn (struct ui_out *uiout,
write them out in a single go for the MI. */
m_opcode_stb.clear ();
- size = m_di.print_insn (pc);
end_pc = pc + size;
for (;pc < end_pc; ++pc)
@@ -279,15 +340,13 @@ gdb_pretty_print_disassembler::pretty_print_insn (struct ui_out *uiout,
spacer = " ";
}
- uiout->field_stream ("opcodes", m_opcode_stb);
- uiout->text ("\t");
+ m_uiout->field_stream ("opcodes", m_opcode_stb);
+ m_uiout->text ("\t");
}
- else
- size = m_di.print_insn (pc);
- uiout->field_stream ("inst", m_insn_stb);
+ /* Disassembly was a success, write out the instruction buffer. */
+ write_out_insn_buffer ();
}
- uiout->text ("\n");
return size;
}
@@ -303,13 +362,13 @@ dump_insns (struct gdbarch *gdbarch,
memset (&insn, 0, sizeof (insn));
insn.addr = low;
- gdb_pretty_print_disassembler disasm (gdbarch);
+ gdb_pretty_print_disassembler disasm (gdbarch, uiout);
while (insn.addr < high && (how_many < 0 || num_displayed < how_many))
{
int size;
- size = disasm.pretty_print_insn (uiout, &insn, flags);
+ size = disasm.pretty_print_insn (&insn, flags);
if (size <= 0)
break;
@@ -351,10 +410,10 @@ do_mixed_source_and_assembly_deprecated
int num_displayed = 0;
print_source_lines_flags psl_flags = 0;
- gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
+ gdb_assert (symtab != nullptr && symtab->linetable () != nullptr);
- nlines = SYMTAB_LINETABLE (symtab)->nitems;
- le = SYMTAB_LINETABLE (symtab)->item;
+ nlines = symtab->linetable ()->nitems;
+ le = symtab->linetable ()->item;
if (flags & DISASSEMBLY_FILENAME)
psl_flags |= PRINT_SOURCE_LINES_FILENAME;
@@ -404,8 +463,7 @@ do_mixed_source_and_assembly_deprecated
/* Now, sort mle by line #s (and, then by addresses within lines). */
if (out_of_order)
- qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
- compare_lines);
+ std::sort (mle, mle + newlines, line_is_less_than);
/* Now, for each line entry, emit the specified lines (unless
they have been emitted before), followed by the assembly code
@@ -462,7 +520,7 @@ do_mixed_source_and_assembly_deprecated
how_many, flags, NULL);
/* When we've reached the end of the mle array, or we've seen the last
- assembly range for this source line, close out the list/tuple. */
+ assembly range for this source line, close out the list/tuple. */
if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
{
inner_list_emitter.reset ();
@@ -494,7 +552,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch,
struct symtab *last_symtab;
int last_line;
- gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
+ gdb_assert (main_symtab != NULL && main_symtab->linetable () != NULL);
/* First pass: collect the list of all source files and lines.
We do this so that we can only print lines containing code once.
@@ -512,8 +570,8 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch,
line after the opening brace. We still want to print this opening brace.
first_le is used to implement this. */
- nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
- le = SYMTAB_LINETABLE (main_symtab)->item;
+ nlines = main_symtab->linetable ()->nitems;
+ le = main_symtab->linetable ()->item;
first_le = NULL;
/* Skip all the preceding functions. */
@@ -713,21 +771,6 @@ do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
dump_insns (gdbarch, uiout, low, high, how_many, flags, NULL);
}
-/* Initialize the disassemble info struct ready for the specified
- stream. */
-
-static int ATTRIBUTE_PRINTF (2, 3)
-fprintf_disasm (void *stream, const char *format, ...)
-{
- va_list args;
-
- va_start (args, format);
- vfprintf_filtered ((struct ui_file *) stream, format, args);
- va_end (args);
- /* Something non -ve. */
- return 0;
-}
-
/* Combine implicit and user disassembler options and return them
in a newly-created string. */
@@ -755,23 +798,41 @@ get_all_disassembler_options (struct gdbarch *gdbarch)
gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
struct ui_file *file,
- di_read_memory_ftype read_memory_func)
- : m_gdbarch (gdbarch),
- m_err_memaddr (0)
+ read_memory_ftype func)
+ : gdb_printing_disassembler (gdbarch, &m_buffer, func,
+ dis_asm_memory_error, dis_asm_print_address),
+ m_buffer (!use_ext_lang_colorization_p && disassembler_styling
+ && file->can_emit_style_escape ()),
+ m_dest (file)
+{ /* Nothing. */ }
+
+/* See disasm.h. */
+
+gdb_disassemble_info::gdb_disassemble_info
+ (struct gdbarch *gdbarch, struct ui_file *stream,
+ read_memory_ftype read_memory_func, memory_error_ftype memory_error_func,
+ print_address_ftype print_address_func, fprintf_ftype fprintf_func,
+ fprintf_styled_ftype fprintf_styled_func)
+ : m_gdbarch (gdbarch)
{
- init_disassemble_info (&m_di, file, fprintf_disasm);
+ gdb_assert (fprintf_func != nullptr);
+ gdb_assert (fprintf_styled_func != nullptr);
+ init_disassemble_info (&m_di, stream, fprintf_func,
+ fprintf_styled_func);
m_di.flavour = bfd_target_unknown_flavour;
- m_di.memory_error_func = dis_asm_memory_error;
- m_di.print_address_func = dis_asm_print_address;
- /* NOTE: cagney/2003-04-28: The original code, from the old Insight
- disassembler had a local optomization here. By default it would
- access the executable file, instead of the target memory (there
- was a growing list of exceptions though). Unfortunately, the
- heuristic was flawed. Commands like "disassemble &variable"
- didn't work as they relied on the access going to the target.
- Further, it has been supperseeded by trust-read-only-sections
- (although that should be superseeded by target_trust..._p()). */
- m_di.read_memory_func = read_memory_func;
+
+ /* The memory_error_func, print_address_func, and read_memory_func are
+ all initialized to a default (non-nullptr) value by the call to
+ init_disassemble_info above. If the user is overriding these fields
+ (by passing non-nullptr values) then do that now, otherwise, leave
+ these fields as the defaults. */
+ if (memory_error_func != nullptr)
+ m_di.memory_error_func = memory_error_func;
+ if (print_address_func != nullptr)
+ m_di.print_address_func = print_address_func;
+ if (read_memory_func != nullptr)
+ m_di.read_memory_func = read_memory_func;
+
m_di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
m_di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
m_di.endian = gdbarch_byte_order (gdbarch);
@@ -783,16 +844,102 @@ gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
disassemble_init_for_target (&m_di);
}
+/* See disasm.h. */
+
+gdb_disassemble_info::~gdb_disassemble_info ()
+{
+ disassemble_free_target (&m_di);
+}
+
+/* Wrapper around calling gdbarch_print_insn. This function takes care of
+ first calling the extension language hooks for print_insn, and, if none
+ of the extension languages can print this instruction, calls
+ gdbarch_print_insn to do the work.
+
+ GDBARCH is the architecture to disassemble in, VMA is the address of the
+ instruction being disassembled, and INFO is the libopcodes disassembler
+ related information. */
+
+static int
+gdb_print_insn_1 (struct gdbarch *gdbarch, CORE_ADDR vma,
+ struct disassemble_info *info)
+{
+ /* Call into the extension languages to do the disassembly. */
+ gdb::optional length = ext_lang_print_insn (gdbarch, vma, info);
+ if (length.has_value ())
+ return *length;
+
+ /* No extension language wanted to do the disassembly, so do it
+ manually. */
+ return gdbarch_print_insn (gdbarch, vma, info);
+}
+
+/* See disasm.h. */
+
+bool gdb_disassembler::use_ext_lang_colorization_p = true;
+
+/* See disasm.h. */
+
int
gdb_disassembler::print_insn (CORE_ADDR memaddr,
int *branch_delay_insns)
{
- m_err_memaddr = 0;
+ m_err_memaddr.reset ();
+ m_buffer.clear ();
+
+ int length = gdb_print_insn_1 (arch (), memaddr, &m_di);
+
+ /* If we have successfully disassembled an instruction, styling is on, we
+ think that the extension language might be able to perform styling for
+ us, and the destination can support styling, then lets call into the
+ extension languages in order to style this output. */
+ if (length > 0 && disassembler_styling
+ && use_ext_lang_colorization_p
+ && m_dest->can_emit_style_escape ())
+ {
+ gdb::optional ext_contents;
+ ext_contents = ext_lang_colorize_disasm (m_buffer.string (), arch ());
+ if (ext_contents.has_value ())
+ m_buffer = std::move (*ext_contents);
+ else
+ {
+ /* The extension language failed to add styling to the
+ disassembly output. Set the static flag so that next time we
+ disassemble we don't even bother attempting to use the
+ extension language for styling. */
+ use_ext_lang_colorization_p = false;
+
+ /* The instruction we just disassembled, and the extension
+ languages failed to style, might have otherwise had some
+ minimal styling applied by GDB. To regain that styling we
+ need to recreate m_buffer, but this time with styling support.
+
+ To do this we perform an in-place new, but this time turn on
+ the styling support, then we can re-disassembly the
+ instruction, and gain any minimal styling GDB might add. */
+ gdb_static_assert ((std::is_same::value));
+ gdb_assert (!m_buffer.term_out ());
+ m_buffer.~string_file ();
+ new (&m_buffer) string_file (true);
+ length = gdb_print_insn_1 (arch (), memaddr, &m_di);
+ gdb_assert (length > 0);
+ }
+ }
- int length = gdbarch_print_insn (arch (), memaddr, &m_di);
+ /* Push any disassemble output to the real destination stream. We do
+ this even if the disassembler reported failure (-1) as the
+ disassembler may have printed something to its output stream. */
+ m_di.fprintf_func (m_dest, "%s", m_buffer.c_str ());
+ /* If the disassembler failed then report an appropriate error. */
if (length < 0)
- memory_error (TARGET_XFER_E_IO, m_err_memaddr);
+ {
+ if (m_err_memaddr.has_value ())
+ memory_error (TARGET_XFER_E_IO, *m_err_memaddr);
+ else
+ error (_("unknown disassembler error (error = %d)"), length);
+ }
if (branch_delay_insns != NULL)
{
@@ -815,8 +962,8 @@ gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
/* Assume symtab is valid for whole PC range. */
symtab = find_pc_line_symtab (low);
- if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
- nlines = SYMTAB_LINETABLE (symtab)->nitems;
+ if (symtab != NULL && symtab->linetable () != NULL)
+ nlines = symtab->linetable ()->nitems;
if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
|| nlines <= 0)
@@ -856,47 +1003,47 @@ gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
return gdb_print_insn (gdbarch, addr, &null_stream, NULL);
}
-/* fprintf-function for gdb_buffered_insn_length. This function is a
- nop, we don't want to print anything, we just want to compute the
- length of the insn. */
+/* See disasm.h. */
-static int ATTRIBUTE_PRINTF (2, 3)
-gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
+int
+gdb_non_printing_disassembler::null_fprintf_func (void *stream,
+ const char *format, ...)
{
return 0;
}
-/* Initialize a struct disassemble_info for gdb_buffered_insn_length.
- Upon return, *DISASSEMBLER_OPTIONS_HOLDER owns the string pointed
- to by DI.DISASSEMBLER_OPTIONS. */
+/* See disasm.h. */
-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,
- std::string *disassembler_options_holder)
+int
+gdb_non_printing_disassembler::null_fprintf_styled_func
+ (void *stream, enum disassembler_style style, const char *format, ...)
{
- init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
-
- /* init_disassemble_info installs buffer_read_memory, etc.
- so we don't need to do that here.
- The cast is necessary until disassemble_info is const-ified. */
- di->buffer = (gdb_byte *) insn;
- di->buffer_length = max_len;
- di->buffer_vma = addr;
-
- di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
- di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
- di->endian = gdbarch_byte_order (gdbarch);
- di->endian_code = gdbarch_byte_order_for_code (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);
+ return 0;
}
+/* A non-printing disassemble_info management class. The disassemble_info
+ setup by this class will not print anything to the output stream (there
+ is no output stream), and the instruction to be disassembled will be
+ read from a buffer passed to the constructor. */
+
+struct gdb_non_printing_buffer_disassembler
+ : public gdb_non_printing_disassembler
+{
+ /* Constructor. GDBARCH is the architecture to disassemble for, BUFFER
+ contains the instruction to disassemble, and INSN_ADDRESS is the
+ address (in target memory) of the instruction to disassemble. */
+ gdb_non_printing_buffer_disassembler (struct gdbarch *gdbarch,
+ gdb::array_view buffer,
+ CORE_ADDR insn_address)
+ : gdb_non_printing_disassembler (gdbarch, nullptr)
+ {
+ /* The cast is necessary until disassemble_info is const-ified. */
+ m_di.buffer = (gdb_byte *) buffer.data ();
+ m_di.buffer_length = buffer.size ();
+ m_di.buffer_vma = insn_address;
+ }
+};
+
/* Return the length in bytes of INSN. MAX_LEN is the size of the
buffer containing INSN. */
@@ -904,13 +1051,11 @@ int
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,
- &disassembler_options_holder);
-
- return gdbarch_print_insn (gdbarch, addr, &di);
+ gdb::array_view buffer
+ = gdb::make_array_view (insn, max_len);
+ gdb_non_printing_buffer_disassembler dis (gdbarch, buffer, addr);
+ int result = gdb_print_insn_1 (gdbarch, addr, dis.disasm_info ());
+ return result;
}
char *
@@ -923,13 +1068,16 @@ get_disassembler_options (struct gdbarch *gdbarch)
}
void
-set_disassembler_options (char *prospective_options)
+set_disassembler_options (const 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);
+ gdb::unique_xmalloc_ptr prospective_options_local
+ = make_unique_xstrdup (prospective_options);
+ char *options = remove_whitespace_and_extra_commas
+ (prospective_options_local.get ());
const char *opt;
/* Allow all architectures, even ones that do not support 'set disassembler',
@@ -947,7 +1095,7 @@ set_disassembler_options (char *prospective_options)
valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
if (valid_options_and_args == NULL)
{
- fprintf_filtered (gdb_stdlog, _("\
+ gdb_printf (gdb_stderr, _("\
'set disassembler-options ...' is not supported on this architecture.\n"));
return;
}
@@ -983,9 +1131,9 @@ set_disassembler_options (char *prospective_options)
break;
if (valid_options->name[i] == NULL)
{
- fprintf_filtered (gdb_stdlog,
- _("Invalid disassembler option value: '%s'.\n"),
- opt);
+ gdb_printf (gdb_stderr,
+ _("Invalid disassembler option value: '%s'.\n"),
+ opt);
return;
}
}
@@ -998,7 +1146,7 @@ static void
set_disassembler_options_sfunc (const char *args, int from_tty,
struct cmd_list_element *c)
{
- set_disassembler_options (prospective_options);
+ set_disassembler_options (prospective_options.c_str ());
}
static void
@@ -1014,22 +1162,22 @@ show_disassembler_options_sfunc (struct ui_file *file, int from_tty,
if (options == NULL)
options = "";
- fprintf_filtered (file, _("The current disassembler options are '%s'\n\n"),
- options);
+ gdb_printf (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);
+ gdb_puts (_("There are no disassembler options available "
+ "for this architecture.\n"),
+ file);
return;
}
valid_options = &valid_options_and_args->options;
- fprintf_filtered (file, _("\
+ gdb_printf (file, _("\
The following disassembler options are supported for use with the\n\
'set disassembler-options OPTION [,OPTION]...' command:\n"));
@@ -1037,7 +1185,7 @@ The following disassembler options are supported for use with the\n\
{
size_t i, max_len = 0;
- fprintf_filtered (file, "\n");
+ gdb_printf (file, "\n");
/* Compute the length of the longest option name. */
for (i = 0; valid_options->name[i] != NULL; i++)
@@ -1052,35 +1200,35 @@ 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]);
+ gdb_printf (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);
+ gdb_printf (file, "%s", valid_options->arg[i]->name);
if (valid_options->description[i] != NULL)
{
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]);
+ gdb_printf (file, "%*c %s", (int) (max_len - len), ' ',
+ valid_options->description[i]);
}
- fprintf_filtered (file, "\n");
+ gdb_printf (file, "\n");
}
}
else
{
size_t i;
- fprintf_filtered (file, " ");
+ gdb_printf (file, " ");
for (i = 0; valid_options->name[i] != NULL; i++)
{
- fprintf_filtered (file, "%s", valid_options->name[i]);
+ gdb_printf (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);
+ gdb_printf (file, "%s", valid_options->arg[i]->name);
if (valid_options->name[i + 1] != NULL)
- fprintf_filtered (file, ", ");
- wrap_here (" ");
+ gdb_printf (file, ", ");
+ file->wrap_here (2);
}
- fprintf_filtered (file, "\n");
+ gdb_printf (file, "\n");
}
valid_args = valid_options_and_args->args;
@@ -1090,15 +1238,15 @@ The following disassembler options are supported for use with the\n\
for (i = 0; valid_args[i].name != NULL; i++)
{
- fprintf_filtered (file, _("\n\
+ gdb_printf (file, _("\n\
For the options above, the following values are supported for \"%s\":\n "),
- valid_args[i].name);
+ 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 (" ");
+ gdb_printf (file, " %s", valid_args[i].values[j]);
+ file->wrap_here (3);
}
- fprintf_filtered (file, "\n");
+ gdb_printf (file, "\n");
}
}
}
@@ -1130,20 +1278,20 @@ disassembler_options_completer (struct cmd_list_element *ignore,
/* Initialization code. */
+void _initialize_disasm ();
void
-_initialize_disasm (void)
+_initialize_disasm ()
{
- struct cmd_list_element *cmd;
-
/* Add the command that controls the disassembler options. */
- cmd = add_setshow_string_noescape_cmd ("disassembler-options", no_class,
- &prospective_options, _("\
+ set_show_commands set_show_disas_opts
+ = add_setshow_string_noescape_cmd ("disassembler-options", no_class,
+ &prospective_options, _("\
Set the disassembler options.\n\
Usage: set disassembler-options OPTION [,OPTION]...\n\n\
-See: 'show disassembler-options' for valid option values.\n"), _("\
+See: 'show disassembler-options' for valid option values."), _("\
Show the disassembler options."), NULL,
set_disassembler_options_sfunc,
show_disassembler_options_sfunc,
&setlist, &showlist);
- set_cmd_completer (cmd, disassembler_options_completer);
+ set_cmd_completer (set_show_disas_opts.set, disassembler_options_completer);
}