diff options
author | Andrew Burgess <aburgess@redhat.com> | 2022-04-04 15:48:19 +0100 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2022-06-15 09:44:55 +0100 |
commit | 8b39b1e7ab20609ced6a224cae440f19e6ae02c1 (patch) | |
tree | 015e347bb39704d9424f3068c1ea372146d90b48 /gdb/arc-tdep.c | |
parent | 15e15b2d9cd3b1db68f99cd3b047352142ddfd1c (diff) | |
download | gdb-8b39b1e7ab20609ced6a224cae440f19e6ae02c1.zip gdb-8b39b1e7ab20609ced6a224cae440f19e6ae02c1.tar.gz gdb-8b39b1e7ab20609ced6a224cae440f19e6ae02c1.tar.bz2 |
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.
Diffstat (limited to 'gdb/arc-tdep.c')
-rw-r--r-- | gdb/arc-tdep.c | 29 |
1 files changed, 6 insertions, 23 deletions
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); } |