forked from Imagelibrary/binutils-gdb
gdb: refactor the non-printing disassemblers
This commit started from an observation I made while working on some other disassembler patches, that is, that the function gdb_buffered_insn_length, is broken ... sort of. I noticed that the gdb_buffered_insn_length function doesn't set up the application data field if the disassemble_info structure. Further, I noticed that some architectures, for example, ARM, require that the application_data field be set, see gdb_print_insn_arm in arm-tdep.c. And so, if we ever use gdb_buffered_insn_length for ARM, then GDB will likely crash. Which is why I said only "sort of" broken. Right now we don't use gdb_buffered_insn_length with ARM, so maybe it isn't broken yet? Anyway to prove to myself that there was a problem here I extended the disassembler self tests in disasm-selftests.c to include a test of gdb_buffered_insn_length. As I run the test for all architectures, I do indeed see GDB crash for ARM. To fix this we need gdb_buffered_insn_length to create a disassembler that inherits from gdb_disassemble_info, but we also need this new disassembler to not print anything. And so, I introduce a new gdb_non_printing_disassembler class, this is a disassembler that doesn't print anything to the output stream. I then observed that both ARC and S12Z also create non-printing disassemblers, but these are slightly different. While the disassembler in gdb_non_printing_disassembler reads the instruction from a buffer, the ARC and S12Z disassemblers read from target memory using target_read_code. And so, I further split gdb_non_printing_disassembler into two sub-classes, gdb_non_printing_memory_disassembler and gdb_non_printing_buffer_disassembler. The new selftests now pass, but otherwise, there should be no user visible changes after this commit.
This commit is contained in:
56
gdb/disasm.h
56
gdb/disasm.h
@@ -136,6 +136,56 @@ protected:
|
||||
ATTRIBUTE_PRINTF(3,4);
|
||||
};
|
||||
|
||||
/* A basic disassembler that doesn't actually print anything. */
|
||||
|
||||
struct gdb_non_printing_disassembler : public gdb_disassemble_info
|
||||
{
|
||||
gdb_non_printing_disassembler (struct gdbarch *gdbarch,
|
||||
read_memory_ftype read_memory_func)
|
||||
: gdb_disassemble_info (gdbarch, nullptr /* stream */,
|
||||
read_memory_func,
|
||||
nullptr /* memory_error_func */,
|
||||
nullptr /* print_address_func */,
|
||||
null_fprintf_func,
|
||||
null_fprintf_styled_func)
|
||||
{ /* Nothing. */ }
|
||||
|
||||
private:
|
||||
|
||||
/* Callback used as the disassemble_info's fprintf_func callback, this
|
||||
doesn't write anything to STREAM, but just returns 0. */
|
||||
static int null_fprintf_func (void *stream, const char *format, ...)
|
||||
ATTRIBUTE_PRINTF(2,3);
|
||||
|
||||
/* Callback used as the disassemble_info's fprintf_styled_func callback,
|
||||
, this doesn't write anything to STREAM, but just returns 0. */
|
||||
static int null_fprintf_styled_func (void *stream,
|
||||
enum disassembler_style style,
|
||||
const char *format, ...)
|
||||
ATTRIBUTE_PRINTF(3,4);
|
||||
};
|
||||
|
||||
/* 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 target memory. */
|
||||
|
||||
struct gdb_non_printing_memory_disassembler
|
||||
: public gdb_non_printing_disassembler
|
||||
{
|
||||
/* Constructor. GDBARCH is the architecture to disassemble for. */
|
||||
gdb_non_printing_memory_disassembler (struct gdbarch *gdbarch)
|
||||
:gdb_non_printing_disassembler (gdbarch, dis_asm_read_memory)
|
||||
{ /* Nothing. */ }
|
||||
|
||||
private:
|
||||
|
||||
/* Implements the read_memory_func disassemble_info callback. */
|
||||
static int dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
|
||||
unsigned int len,
|
||||
struct disassemble_info *info);
|
||||
};
|
||||
|
||||
/* A dissassembler class that provides 'print_insn', a method for
|
||||
disassembling a single instruction to the output stream. */
|
||||
|
||||
@@ -278,10 +328,4 @@ extern char *get_disassembler_options (struct gdbarch *gdbarch);
|
||||
|
||||
extern void set_disassembler_options (const char *options);
|
||||
|
||||
/* Setup DINFO with its output function and output stream setup so that
|
||||
nothing is printed while disassembling. */
|
||||
|
||||
extern void init_disassemble_info_for_no_printing
|
||||
(struct disassemble_info *dinfo);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user