aboutsummaryrefslogtreecommitdiff
path: root/gdb/aarch64-tdep.c
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2017-03-23 14:11:04 +0000
committerYao Qi <yao.qi@linaro.org>2017-03-23 14:11:04 +0000
commit1e2b521d987a34898ca959a33972be8912511ba0 (patch)
tree8f0c276b9fcd904e4b06cc9b3124450f2d51c8b9 /gdb/aarch64-tdep.c
parent338771252e913f82df8a445cb3e748a791b1cba8 (diff)
downloadgdb-1e2b521d987a34898ca959a33972be8912511ba0.zip
gdb-1e2b521d987a34898ca959a33972be8912511ba0.tar.gz
gdb-1e2b521d987a34898ca959a33972be8912511ba0.tar.bz2
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 <yao.qi@linaro.org> * 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.
Diffstat (limited to 'gdb/aarch64-tdep.c')
-rw-r--r--gdb/aarch64-tdep.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 486dac3..f340d57 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. */