aboutsummaryrefslogtreecommitdiff
path: root/gdb/arc-linux-tdep.c
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2022-04-04 15:48:19 +0100
committerAndrew Burgess <aburgess@redhat.com>2022-06-15 09:44:55 +0100
commit8b39b1e7ab20609ced6a224cae440f19e6ae02c1 (patch)
tree015e347bb39704d9424f3068c1ea372146d90b48 /gdb/arc-linux-tdep.c
parent15e15b2d9cd3b1db68f99cd3b047352142ddfd1c (diff)
downloadbinutils-8b39b1e7ab20609ced6a224cae440f19e6ae02c1.zip
binutils-8b39b1e7ab20609ced6a224cae440f19e6ae02c1.tar.gz
binutils-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-linux-tdep.c')
-rw-r--r--gdb/arc-linux-tdep.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/gdb/arc-linux-tdep.c b/gdb/arc-linux-tdep.c
index 13595f2..04ca38f 100644
--- a/gdb/arc-linux-tdep.c
+++ b/gdb/arc-linux-tdep.c
@@ -356,7 +356,7 @@ arc_linux_sw_breakpoint_from_kind (struct gdbarch *gdbarch,
*/
static std::vector<CORE_ADDR>
-handle_atomic_sequence (arc_instruction insn, disassemble_info &di)
+handle_atomic_sequence (arc_instruction insn, disassemble_info *di)
{
const int atomic_seq_len = 24; /* Instruction sequence length. */
std::vector<CORE_ADDR> next_pcs;
@@ -374,7 +374,7 @@ handle_atomic_sequence (arc_instruction insn, disassemble_info &di)
for (int insn_count = 0; insn_count < atomic_seq_len; ++insn_count)
{
arc_insn_decode (arc_insn_get_linear_next_pc (insn),
- &di, arc_delayed_print_insn, &insn);
+ di, arc_delayed_print_insn, &insn);
if (insn.insn_class == BRCC)
{
@@ -412,15 +412,15 @@ arc_linux_software_single_step (struct regcache *regcache)
{
struct gdbarch *gdbarch = regcache->arch ();
arc_gdbarch_tdep *tdep = (arc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
- struct disassemble_info di = arc_disassemble_info (gdbarch);
+ struct gdb_non_printing_memory_disassembler dis (gdbarch);
/* Read current instruction. */
struct arc_instruction curr_insn;
- arc_insn_decode (regcache_read_pc (regcache), &di, arc_delayed_print_insn,
- &curr_insn);
+ arc_insn_decode (regcache_read_pc (regcache), dis.disasm_info (),
+ arc_delayed_print_insn, &curr_insn);
if (curr_insn.insn_class == LLOCK)
- return handle_atomic_sequence (curr_insn, di);
+ return handle_atomic_sequence (curr_insn, dis.disasm_info ());
CORE_ADDR next_pc = arc_insn_get_linear_next_pc (curr_insn);
std::vector<CORE_ADDR> next_pcs;
@@ -431,7 +431,8 @@ arc_linux_software_single_step (struct regcache *regcache)
if (curr_insn.has_delay_slot)
{
struct arc_instruction next_insn;
- arc_insn_decode (next_pc, &di, arc_delayed_print_insn, &next_insn);
+ arc_insn_decode (next_pc, dis.disasm_info (), arc_delayed_print_insn,
+ &next_insn);
next_pcs.push_back (arc_insn_get_linear_next_pc (next_insn));
}
else