From 1e2b521d987a34898ca959a33972be8912511ba0 Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Thu, 23 Mar 2017 14:11:04 +0000 Subject: [PATCH] Handle PRFM in AArch64 process record This patch fixes the bug of handling PRFM instruction. PRFM is documented in a table with other load and store instructions, but it doesn't do any load or store. This patch also adds a unit test to PRFM instruction. gdb: 2017-03-23 Yao Qi * aarch64-tdep.c (aarch64_process_record_test): Declare. (_initialize_aarch64_tdep): Register it. (aarch64_record_load_store): Handle PRFM instruction. (aarch64_process_record_test): New function. --- gdb/ChangeLog | 7 ++++++ gdb/aarch64-tdep.c | 60 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cd863de6d76..9cfc5aacfc9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2017-03-23 Yao Qi + + * aarch64-tdep.c (aarch64_process_record_test): Declare. + (_initialize_aarch64_tdep): Register it. + (aarch64_record_load_store): Handle PRFM instruction. + (aarch64_process_record_test): New function. + 2017-03-23 Yao Qi * aarch64-tdep.c (aarch64_record_load_store): Fix code diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 486dac3cf72..f340d57df2a 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3038,6 +3038,11 @@ aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) paddress (gdbarch, tdep->lowest_pc)); } +namespace selftests +{ +static void aarch64_process_record_test (void); +} + /* Suppress warning from -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_aarch64_tdep; @@ -3060,6 +3065,7 @@ When on, AArch64 specific debugging is enabled."), #if GDB_SELF_TEST register_self_test (selftests::aarch64_analyze_prologue_test); + register_self_test (selftests::aarch64_process_record_test); #endif } @@ -3617,10 +3623,23 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r) } else { - if (size_bits != 0x03) - ld_flag = 0x01; + if (size_bits == 0x3 && vector_flag == 0x0 && opc == 0x2) + { + /* PRFM (immediate) */ + return AARCH64_RECORD_SUCCESS; + } + else if (size_bits == 0x2 && vector_flag == 0x0 && opc == 0x2) + { + /* LDRSW (immediate) */ + ld_flag = 0x1; + } else - return AARCH64_RECORD_UNKNOWN; + { + if (opc & 0x01) + ld_flag = 0x01; + else + ld_flag = 0x0; + } } if (record_debug) @@ -3949,6 +3968,41 @@ deallocate_reg_mem (insn_decode_record *record) xfree (record->aarch64_mems); } +#if GDB_SELF_TEST +namespace selftests { + +static void +aarch64_process_record_test (void) +{ + struct gdbarch_info info; + uint32_t ret; + + gdbarch_info_init (&info); + info.bfd_arch_info = bfd_scan_arch ("aarch64"); + + struct gdbarch *gdbarch = gdbarch_find_by_info (info); + SELF_CHECK (gdbarch != NULL); + + insn_decode_record aarch64_record; + + memset (&aarch64_record, 0, sizeof (insn_decode_record)); + aarch64_record.regcache = NULL; + aarch64_record.this_addr = 0; + aarch64_record.gdbarch = gdbarch; + + /* 20 00 80 f9 prfm pldl1keep, [x1] */ + aarch64_record.aarch64_insn = 0xf9800020; + ret = aarch64_record_decode_insn_handler (&aarch64_record); + SELF_CHECK (ret == AARCH64_RECORD_SUCCESS); + SELF_CHECK (aarch64_record.reg_rec_count == 0); + SELF_CHECK (aarch64_record.mem_rec_count == 0); + + deallocate_reg_mem (&aarch64_record); +} + +} // namespace selftests +#endif /* GDB_SELF_TEST */ + /* Parse the current instruction and record the values of the registers and memory that will be changed in current instruction to record_arch_list return -1 if something is wrong. */ -- 2.30.2