From 8b39b1e7ab20609ced6a224cae440f19e6ae02c1 Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Mon, 4 Apr 2022 15:48:19 +0100 Subject: 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. --- gdb/arc-tdep.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'gdb/arc-tdep.c') diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c index 3edfd46..2f96e24 100644 --- a/gdb/arc-tdep.c +++ b/gdb/arc-tdep.c @@ -1306,24 +1306,6 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn, return false; } -/* See arc-tdep.h. */ - -struct disassemble_info -arc_disassemble_info (struct gdbarch *gdbarch) -{ - struct disassemble_info di; - init_disassemble_info_for_no_printing (&di); - di.arch = gdbarch_bfd_arch_info (gdbarch)->arch; - di.mach = gdbarch_bfd_arch_info (gdbarch)->mach; - di.endian = gdbarch_byte_order (gdbarch); - di.read_memory_func = [](bfd_vma memaddr, gdb_byte *myaddr, - unsigned int len, struct disassemble_info *info) - { - return target_read_code (memaddr, myaddr, len); - }; - return di; -} - /* Analyze the prologue and update the corresponding frame cache for the frame unwinder for unwinding frames that doesn't have debug info. In such situation GDB attempts to parse instructions in the prologue to understand @@ -1394,9 +1376,10 @@ arc_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR entrypoint, while (current_prologue_end < limit_pc) { struct arc_instruction insn; - struct disassemble_info di = arc_disassemble_info (gdbarch); - arc_insn_decode (current_prologue_end, &di, arc_delayed_print_insn, - &insn); + + struct gdb_non_printing_memory_disassembler dis (gdbarch); + arc_insn_decode (current_prologue_end, dis.disasm_info (), + arc_delayed_print_insn, &insn); if (arc_debug) arc_insn_dump (insn); @@ -2460,8 +2443,8 @@ dump_arc_instruction_command (const char *args, int from_tty) CORE_ADDR address = value_as_address (val); struct arc_instruction insn; - struct disassemble_info di = arc_disassemble_info (target_gdbarch ()); - arc_insn_decode (address, &di, arc_delayed_print_insn, &insn); + struct gdb_non_printing_memory_disassembler dis (target_gdbarch ()); + arc_insn_decode (address, dis.disasm_info (), arc_delayed_print_insn, &insn); arc_insn_dump (insn); } -- cgit v1.1