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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user