public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v4 1/5] NEWS entry about aarch64-linux record/replay support
  2015-02-03  1:17 [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
  2015-02-03  1:17 ` [PATCH v4 4/5] Support for recording aarch64 advanced SIMD instructions Omair Javaid
@ 2015-02-03  1:17 ` Omair Javaid
  2015-02-03  3:38   ` Eli Zaretskii
  2015-02-03  1:17 ` [PATCH v4 3/5] Support for recording syscall on aarch64-linux Omair Javaid
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Omair Javaid @ 2015-02-03  1:17 UTC (permalink / raw)
  To: gdb-patches

gdb:

2015-02-02  Omair Javaid  <omair.javaid@linaro.org>

	* NEWS: Add a note on process record-replay support on aarch64*-linux*
	targets.
---
 gdb/NEWS | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index f19577a..468a14c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 7.9
 
+* Support for process record-replay and reverse debugging on aarch64*-linux*
+  targets has been added.  GDB now supports recording of A64 instruction set
+  including advance SIMD instructions.
+
 * The "info source" command now displays the producer string if it was
   present in the debug info.  This typically includes the compiler version
   and may include things like its command line arguments.
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 2/5] Implements aarch64 process record and reverse debugging support
  2015-02-03  1:17 [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
                   ` (2 preceding siblings ...)
  2015-02-03  1:17 ` [PATCH v4 3/5] Support for recording syscall on aarch64-linux Omair Javaid
@ 2015-02-03  1:17 ` Omair Javaid
  2015-02-19 12:35   ` Yao Qi
  2015-02-03  1:17 ` [PATCH v4 5/5] Enables gdb.reverse testsuite for aarch64*-linux targets Omair Javaid
  2015-02-03  1:32 ` [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
  5 siblings, 1 reply; 12+ messages in thread
From: Omair Javaid @ 2015-02-03  1:17 UTC (permalink / raw)
  To: gdb-patches

2015-02-02  Omair Javaid  <omair.javaid@linaro.org>

	* aarch64-linux-tdep.c (aarch64_linux_init_abi): Install AArch64
	process record handler.
	* aarch64-tdep.c (record.h): Include.
	(record-full.h): Include.
	(submask): New macro.
	(bit): New macro.
	(bits): New macro.
	(REG_ALLOC): New macro.
	(MEM_ALLOC): New macro.
	(struct aarch64_mem_r): Define.
	(aarch64_record_result): New enum.
	(struct insn_decode_record): Define.
	(insn_decode_record): New typedef.
	(aarch64_record_data_proc_reg): Add record handler for data processing
	register insns.
	(aarch64_record_data_proc_imm): Add record handler for data processing
	immediate insns.
	(aarch64_record_branch_except_sys): Add record handler for branch,
	exception and system insns.
	(aarch64_record_load_store): Add record handler for load/store insns.
	(aarch64_record_decode_insn_handler): Add record insn decoding function.
	(deallocate_reg_mem): Add memory cleanup function for record data.
	(aarch64_process_record): Add gdbarch handler for AArch64 process
	record.
	* aarch64-tdep.h (aarch64_process_record): New extern declaration.
---
 gdb/aarch64-linux-tdep.c |   3 +
 gdb/aarch64-tdep.c       | 578 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb/aarch64-tdep.h       |   3 +
 3 files changed, 584 insertions(+)

diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 1e1ca36..10a53d4 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -385,6 +385,9 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_stap_is_single_operand (gdbarch, aarch64_stap_is_single_operand);
   set_gdbarch_stap_parse_special_token (gdbarch,
 					aarch64_stap_parse_special_token);
+
+  /* Reversible debugging, process record.  */
+  set_gdbarch_process_record (gdbarch, aarch64_process_record);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 472ce70..ab9e83f 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -50,6 +50,9 @@
 
 #include "vec.h"
 
+#include "record.h"
+#include "record-full.h"
+
 #include "features/aarch64.c"
 
 /* Pseudo register base numbers.  */
@@ -2804,3 +2807,578 @@ When on, AArch64 specific debugging is enabled."),
 			    show_aarch64_debug,
 			    &setdebuglist, &showdebuglist);
 }
+
+/* AArch64 process record-replay related structures, defines etc.  */
+
+#define submask(x) ((1L << ((x) + 1)) - 1)
+#define bit(obj,st) (((obj) >> (st)) & 1)
+#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
+
+#define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \
+        do  \
+          { \
+            unsigned int reg_len = LENGTH; \
+            if (reg_len) \
+              { \
+                REGS = XNEWVEC (uint32_t, reg_len); \
+                memcpy(&REGS[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \
+              } \
+          } \
+        while (0)
+
+#define MEM_ALLOC(MEMS, LENGTH, RECORD_BUF) \
+        do  \
+          { \
+            unsigned int mem_len = LENGTH; \
+            if (mem_len) \
+            { \
+              MEMS =  XNEWVEC (struct aarch64_mem_r, mem_len);  \
+              memcpy(&MEMS->len, &RECORD_BUF[0], \
+                     sizeof(struct aarch64_mem_r) * LENGTH); \
+            } \
+          } \
+          while (0)
+
+/* AArch64 memory record structure.  */
+struct aarch64_mem_r
+{
+  uint64_t len;    /* Record length.  */
+  uint64_t addr;   /* Memory address.  */
+};
+
+enum aarch64_record_result
+{
+  AARCH64_RECORD_SUCCESS,
+  AARCH64_RECORD_FAILURE,
+  AARCH64_RECORD_UNSUPPORTED
+};
+
+/* AArch64 instruction record contains opcode of current insn and execution
+   state (before entry to decode_insn()), contains list of to-be-modified
+   registers and memory blocks (on return from decode_insn()).  */
+
+typedef struct insn_decode_record_t
+{
+  struct gdbarch *gdbarch;
+  struct regcache *regcache;
+  CORE_ADDR this_addr;
+  uint32_t aarch64_insn;
+  uint32_t mem_rec_count;
+  uint32_t reg_rec_count;
+  uint32_t *aarch64_regs;
+  struct aarch64_mem_r *aarch64_mems;
+} insn_decode_record;
+
+/* Record handler for data processing - register instructions.  */
+static unsigned int
+aarch64_record_data_proc_reg (insn_decode_record *aarch64_insn_r)
+{
+  uint8_t reg_rd, insn_bits24_27, insn_bits21_23, setflags;
+  uint32_t record_buf[4];
+
+  reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
+  insn_bits21_23 = bits (aarch64_insn_r->aarch64_insn, 21, 23);
+
+  if (!bit (aarch64_insn_r->aarch64_insn, 28))
+    {
+      /* Logical (shifted register).  */
+      if (insn_bits24_27 == 0x0a)
+        setflags = (bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03);
+      /* Add/subtract.  */
+      else if (insn_bits24_27 == 0x0b)
+        setflags = bit (aarch64_insn_r->aarch64_insn, 29);
+      else
+        return AARCH64_RECORD_UNSUPPORTED;
+
+      record_buf[0] = reg_rd;
+      aarch64_insn_r->reg_rec_count = 1;
+      if (setflags)
+        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
+    }
+  else
+    {
+      if (insn_bits24_27 == 0x0b)
+        {
+          /* Data-processing (3 source).  */
+          record_buf[0] = reg_rd;
+          aarch64_insn_r->reg_rec_count = 1;
+        }
+      else if (insn_bits24_27 == 0x0a)
+        {
+          if (insn_bits21_23 == 0x00)
+            {
+              /* Add/subtract (with carry).  */
+              record_buf[0] = reg_rd;
+              aarch64_insn_r->reg_rec_count = 1;
+              if (bit (aarch64_insn_r->aarch64_insn, 29))
+                {
+                  record_buf[1] = AARCH64_CPSR_REGNUM;
+                  aarch64_insn_r->reg_rec_count = 2;
+                }
+            }
+          else if (insn_bits21_23 == 0x02)
+            {
+              /* Conditional compare (register) / Conditional compare (immediate).  */
+              record_buf[0] = AARCH64_CPSR_REGNUM;
+              aarch64_insn_r->reg_rec_count = 1;
+            }
+          else if (insn_bits21_23 == 0x04 || insn_bits21_23 == 0x06)
+            {
+              /* CConditional select.  */
+              /* Data-processing (2 source).  */
+              /* Data-processing (1 source).  */
+              record_buf[0] = reg_rd;
+              aarch64_insn_r->reg_rec_count = 1;
+            }
+          else
+            return AARCH64_RECORD_UNSUPPORTED;
+        }
+    }
+
+  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+            record_buf);
+  return AARCH64_RECORD_SUCCESS;
+}
+
+/* Record handler for data processing - immediate instructions.  */
+static unsigned int
+aarch64_record_data_proc_imm (insn_decode_record *aarch64_insn_r)
+{
+  uint8_t reg_rd, insn_bit28, insn_bit23, insn_bits24_27, setflags;
+  uint32_t record_buf[4];
+
+  reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+  insn_bit28 = bit (aarch64_insn_r->aarch64_insn, 28);
+  insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23);
+  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
+
+  /* PC rel addressing / Move wide immediate / BitField / Extract.  */
+  if (insn_bits24_27 == 0x00 || insn_bits24_27 == 0x03 ||
+     (insn_bits24_27 == 0x02 && insn_bit23))
+    {
+      record_buf[0] = reg_rd;
+      aarch64_insn_r->reg_rec_count = 1;
+    }
+  else if (insn_bits24_27 == 0x01)
+    {
+      /* Add/Subtract (immediate).  */
+      setflags = bit (aarch64_insn_r->aarch64_insn, 29);
+      record_buf[0] = reg_rd;
+      aarch64_insn_r->reg_rec_count = 1;
+      if (setflags)
+        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
+    }
+  else if (insn_bits24_27 == 0x02 && !insn_bit23)
+    {
+      /* Logical (immediate).  */
+      setflags = bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03;
+      record_buf[0] = reg_rd;
+      aarch64_insn_r->reg_rec_count = 1;
+      if (setflags)
+        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
+    }
+  else
+    return AARCH64_RECORD_UNSUPPORTED;
+
+  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+            record_buf);
+  return AARCH64_RECORD_SUCCESS;
+}
+
+/* Record handler for branch, exception generation and system instructions.  */
+static unsigned int
+aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (aarch64_insn_r->gdbarch);
+  uint8_t insn_bits24_27, insn_bits28_31, insn_bits22_23;
+  uint32_t record_buf[4];
+
+  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
+  insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
+  insn_bits22_23 = bits (aarch64_insn_r->aarch64_insn, 22, 23);
+
+  if (insn_bits28_31 == 0x0d)
+    {
+      /* Exception generation instructions. */
+      if (insn_bits24_27 == 0x04)
+        return AARCH64_RECORD_UNSUPPORTED;
+      /* System instructions. */
+      else if (insn_bits24_27 == 0x05 && insn_bits22_23 == 0x00)
+        {
+          record_buf[0] = AARCH64_CPSR_REGNUM;
+          record_buf[1] = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+          aarch64_insn_r->reg_rec_count = 2;
+        }
+      else if((insn_bits24_27 & 0x0e) == 0x06)
+        {
+          record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
+          if (bits (aarch64_insn_r->aarch64_insn, 21, 22) == 0x01)
+            record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM;
+        }
+      else
+        return AARCH64_RECORD_UNSUPPORTED;
+    }
+  else if ((insn_bits28_31 & 0x07) == 0x01 && (insn_bits24_27 & 0x0c) == 0x04)
+    {
+      record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
+      if (bit (aarch64_insn_r->aarch64_insn, 31))
+        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM;
+    }
+  else
+    /* All other types of branch instructions. */
+    record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
+
+  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+            record_buf);
+  return AARCH64_RECORD_SUCCESS;
+}
+
+/* Record handler for load and store instructions.  */
+static unsigned int
+aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
+{
+  uint8_t insn_bits24_27, insn_bits28_29, insn_bits10_11;
+  uint8_t insn_bit23, insn_bit21;
+  uint8_t opc, size_bits, ld_flag, vector_flag;
+  uint32_t reg_rn, reg_rt, reg_rt2;
+  uint64_t datasize, offset;
+  uint32_t record_buf[8];
+  uint64_t record_buf_mem[8];
+  CORE_ADDR address;
+
+  insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
+  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
+  insn_bits28_29 = bits (aarch64_insn_r->aarch64_insn, 28, 29);
+  insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
+  insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23);
+  ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
+  vector_flag = bit (aarch64_insn_r->aarch64_insn, 26);
+  reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+  reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
+  reg_rt2 = bits (aarch64_insn_r->aarch64_insn, 10, 14);
+  size_bits = bits (aarch64_insn_r->aarch64_insn, 30, 31);
+
+  /* Load/store exclusive instructions decoding.  */
+  if (insn_bits24_27 == 0x08 && insn_bits28_29 == 0x00)
+    {
+      if (ld_flag)
+        {
+          record_buf[0] = reg_rt;
+          aarch64_insn_r->reg_rec_count = 1;
+          if (insn_bit21)
+            {
+              record_buf[1] = reg_rt2;
+              aarch64_insn_r->reg_rec_count = 2;
+            }
+        }
+      else
+        {
+          if (insn_bit21)
+            datasize = (8 << size_bits) * 2;
+          else
+            datasize = (8 << size_bits);
+          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
+                                      &address);
+          record_buf_mem[0] = datasize / 8;
+          record_buf_mem[1] = address;
+          aarch64_insn_r->mem_rec_count = 1;
+          if (!insn_bit23)
+            {
+              /* Save register rs.  */
+              record_buf[0] = bits (aarch64_insn_r->aarch64_insn, 16, 20);
+              aarch64_insn_r->reg_rec_count = 1;
+            }
+        }
+    }
+  /* Load register (literal) instructions decoding.  */
+  else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x01)
+    {
+      if (vector_flag)
+        record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
+      else
+        record_buf[0] = reg_rt;
+      aarch64_insn_r->reg_rec_count = 1;
+    }
+  /* All types of load/store pair instructions decoding.  */
+  else if ((insn_bits24_27 & 0x0a) == 0x08 && insn_bits28_29 == 0x02)
+    {
+      if (ld_flag)
+        {
+          if (vector_flag)
+            {
+              record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
+              record_buf[1] = reg_rt2 + AARCH64_V0_REGNUM;
+            }
+          else
+            {
+              record_buf[0] = reg_rt;
+              record_buf[1] = reg_rt2;
+            }
+          aarch64_insn_r->reg_rec_count = 2;
+        }
+      else
+        {
+          uint16_t imm7_off;
+          imm7_off = bits (aarch64_insn_r->aarch64_insn, 15, 21);
+          if (!vector_flag)
+            size_bits = size_bits >> 1;
+          datasize = 8 << (2 + size_bits);
+          offset = (imm7_off & 0x40) ? (~imm7_off & 0x007f) + 1 : imm7_off;
+          offset = offset << (2 + size_bits);
+          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
+                                      &address);
+          if (!((insn_bits24_27 & 0x0b) == 0x08 && insn_bit23))
+            {
+              if (imm7_off & 0x40)
+                address = address - offset;
+              else
+                address = address + offset;
+            }
+
+          record_buf_mem[0] = datasize / 8;
+          record_buf_mem[1] = address;
+          record_buf_mem[2] = datasize / 8;
+          record_buf_mem[3] = address + (datasize / 8);
+          aarch64_insn_r->mem_rec_count = 2;
+        }
+      if (bit (aarch64_insn_r->aarch64_insn, 23))
+        record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn;
+    }
+  /* Load/store register (unsigned immediate) instructions.  */
+  else if ((insn_bits24_27 & 0x0b) == 0x09 && insn_bits28_29 == 0x03)
+    {
+      opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
+      if (!(opc >> 1))
+        if (opc & 0x01)
+          ld_flag = 0x01;
+        else
+          ld_flag = 0x0;
+      else
+        if (size_bits != 0x03)
+          ld_flag = 0x01;
+        else
+          return AARCH64_RECORD_UNSUPPORTED;
+
+      if (!ld_flag)
+        {
+          offset = bits (aarch64_insn_r->aarch64_insn, 10, 21);
+          datasize = 8 << size_bits;
+          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
+                                      &address);
+          offset = offset << size_bits;
+          address = address + offset;
+
+          record_buf_mem[0] = datasize >> 3;
+          record_buf_mem[1] = address;
+          aarch64_insn_r->mem_rec_count = 1;
+        }
+      else
+        {
+          if (vector_flag)
+            record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
+          else
+            record_buf[0] = reg_rt;
+          aarch64_insn_r->reg_rec_count = 1;
+        }
+    }
+  /* Load/store register (register offset) instructions.  */
+  else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03 &&
+            insn_bits10_11 == 0x02 && insn_bit21)
+    {
+      opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
+      if (!(opc >> 1))
+        if (opc & 0x01)
+          ld_flag = 0x01;
+        else
+          ld_flag = 0x0;
+      else
+        if (size_bits != 0x03)
+          ld_flag = 0x01;
+        else
+          return AARCH64_RECORD_UNSUPPORTED;
+
+      if (!ld_flag)
+        {
+          uint64_t reg_rm_val;
+          regcache_raw_read_unsigned (aarch64_insn_r->regcache,
+                     bits (aarch64_insn_r->aarch64_insn, 16, 20), &reg_rm_val);
+          if (bit (aarch64_insn_r->aarch64_insn, 12))
+            offset = reg_rm_val << size_bits;
+          else
+            offset = reg_rm_val;
+          datasize = 8 << size_bits;
+          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
+                                      &address);
+          address = address + offset;
+          record_buf_mem[0] = datasize >> 3;
+          record_buf_mem[1] = address;
+          aarch64_insn_r->mem_rec_count = 1;
+        }
+      else
+        {
+          if (vector_flag)
+            record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
+          else
+            record_buf[0] = reg_rt;
+          aarch64_insn_r->reg_rec_count = 1;
+        }
+    }
+  /* Load/store register (immediate) instructions.  */
+  else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03 &&
+          !insn_bit21)
+    {
+      opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
+      if (!(opc >> 1))
+        if (opc & 0x01)
+          ld_flag = 0x01;
+        else
+          ld_flag = 0x0;
+      else
+        if (size_bits != 0x03)
+          ld_flag = 0x01;
+        else
+          return AARCH64_RECORD_UNSUPPORTED;
+
+      if (!ld_flag)
+        {
+          uint16_t imm9_off;
+          imm9_off = bits (aarch64_insn_r->aarch64_insn, 12, 20);
+          offset = (imm9_off & 0x0100) ? (((~imm9_off) & 0x01ff) + 1) : imm9_off;
+          datasize = 8 << size_bits;
+          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
+                                      &address);
+          if (insn_bits10_11 != 0x01)
+            {
+              if (imm9_off & 0x0100)
+                address = address - offset;
+              else
+                address = address + offset;
+            }
+          record_buf_mem[0] = datasize >> 3;
+          record_buf_mem[1] = address;
+          aarch64_insn_r->mem_rec_count = 1;
+        }
+      else
+        {
+          if (vector_flag)
+            record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
+          else
+            record_buf[0] = reg_rt;
+          aarch64_insn_r->reg_rec_count = 1;
+        }
+      if (insn_bits10_11 == 0x01 || insn_bits10_11 == 0x03)
+        record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn;
+    }
+  /* Advanced SIMD load/store instructions.  */
+  else
+    return AARCH64_RECORD_UNSUPPORTED;
+
+  MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
+             record_buf_mem);
+  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+             record_buf);
+  return AARCH64_RECORD_SUCCESS;
+}
+/* Decodes insns type and invokes its record handler.  */
+
+static unsigned int
+aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
+{
+  uint32_t ins_bit25, ins_bit26, ins_bit27, ins_bit28;
+
+  ins_bit25 = bit (aarch64_insn_r->aarch64_insn, 25);
+  ins_bit26 = bit (aarch64_insn_r->aarch64_insn, 26);
+  ins_bit27 = bit (aarch64_insn_r->aarch64_insn, 27);
+  ins_bit28 = bit (aarch64_insn_r->aarch64_insn, 28);
+
+  /* Data processing - immediate instructions.  */
+  if (!ins_bit26 && !ins_bit27 && ins_bit28)
+    return aarch64_record_data_proc_imm (aarch64_insn_r);
+
+  /* Branch, exception generation and system instructions.  */
+  if (ins_bit26 && !ins_bit27 && ins_bit28)
+    return aarch64_record_branch_except_sys (aarch64_insn_r);
+
+  /* Load and store instructions.  */
+  if (!ins_bit25 && ins_bit27)
+    return aarch64_record_load_store (aarch64_insn_r);
+
+  /* Data processing - register instructions.  */
+  if (ins_bit25 && !ins_bit26 && ins_bit27)
+    return aarch64_record_data_proc_reg (aarch64_insn_r);
+
+  /* Data processing - SIMD and floating point instructions.  */
+  if (ins_bit25 && ins_bit26 && ins_bit27)
+    return AARCH64_RECORD_UNSUPPORTED;
+
+  return AARCH64_RECORD_UNSUPPORTED;
+}
+
+/* Cleans up local record registers and memory allocations.  */
+
+static void
+deallocate_reg_mem (insn_decode_record *record)
+{
+  xfree (record->aarch64_regs);
+  xfree (record->aarch64_mems);
+}
+
+/* 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.  */
+
+int
+aarch64_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
+                        CORE_ADDR insn_addr)
+{
+  uint32_t rec_no = 0;
+  uint8_t insn_size = 4;
+  uint32_t ret = 0;
+  ULONGEST t_bit = 0, insn_id = 0;
+  gdb_byte buf[insn_size];
+  insn_decode_record aarch64_record;
+
+  memset (&buf[0], 0, insn_size);
+  memset (&aarch64_record, 0, sizeof (insn_decode_record));
+  target_read_memory (insn_addr, &buf[0], insn_size);
+  aarch64_record.aarch64_insn = (uint32_t) extract_unsigned_integer (&buf[0],
+                                insn_size, gdbarch_byte_order (gdbarch));
+  aarch64_record.regcache = regcache;
+  aarch64_record.this_addr = insn_addr;
+  aarch64_record.gdbarch = gdbarch;
+
+  ret = aarch64_record_decode_insn_handler (&aarch64_record);
+  if (ret == AARCH64_RECORD_UNSUPPORTED)
+    {
+      printf_unfiltered (_("Process record does not support instruction "
+                        "0x%0x at address %s.\n"),aarch64_record.aarch64_insn,
+                        paddress (gdbarch, insn_addr));
+      ret = -1;
+    }
+
+  if (0 == ret)
+    {
+      /* Record registers.  */
+      record_full_arch_list_add_reg (aarch64_record.regcache, AARCH64_PC_REGNUM);
+      if (aarch64_record.aarch64_regs)
+        for (rec_no = 0; rec_no < aarch64_record.reg_rec_count; rec_no++)
+          if (record_full_arch_list_add_reg (aarch64_record.regcache,
+             aarch64_record.aarch64_regs[rec_no]))
+            ret = -1;
+
+      /* Record memories.  */
+      if (aarch64_record.aarch64_mems)
+        for (rec_no = 0; rec_no < aarch64_record.mem_rec_count; rec_no++)
+          if (record_full_arch_list_add_mem
+             ((CORE_ADDR)aarch64_record.aarch64_mems[rec_no].addr,
+             aarch64_record.aarch64_mems[rec_no].len))
+            ret = -1;
+
+      if (record_full_arch_list_add_end ())
+        ret = -1;
+    }
+
+  deallocate_reg_mem (&aarch64_record);
+  return ret;
+}
diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
index 6a7794d..6f27ec8 100644
--- a/gdb/aarch64-tdep.h
+++ b/gdb/aarch64-tdep.h
@@ -90,4 +90,7 @@ struct gdbarch_tdep
   struct type *vnb_type;
 };
 
+extern int aarch64_process_record (struct gdbarch *gdbarch,
+                               struct regcache *regcache, CORE_ADDR addr);
+
 #endif /* aarch64-tdep.h */
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 3/5] Support for recording syscall on aarch64-linux
  2015-02-03  1:17 [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
  2015-02-03  1:17 ` [PATCH v4 4/5] Support for recording aarch64 advanced SIMD instructions Omair Javaid
  2015-02-03  1:17 ` [PATCH v4 1/5] NEWS entry about aarch64-linux record/replay support Omair Javaid
@ 2015-02-03  1:17 ` Omair Javaid
  2015-02-19 16:55   ` Yao Qi
  2015-02-03  1:17 ` [PATCH v4 2/5] Implements aarch64 process record and reverse debugging support Omair Javaid
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Omair Javaid @ 2015-02-03  1:17 UTC (permalink / raw)
  To: gdb-patches

gdb:

2015-02-02  Omair Javaid  <omair.javaid@linaro.org>

	* aarch64-linux-tdep.c (linux-record): Include.
	(record-full.h): Include.
	(struct linux_record_tdep aarch64_linux_record_tdep): Declare.
	(aarch64_canonicalize_syscall): New function to translate syscall
	numbers from aarch64 to canonical.
	(aarch64_all_but_pc_registers_record): New function.
	(aarch64_linux_syscall_record): New function.
	(aarch64_linux_init_abi): Update to handle syscall recording.
	* aarch64-linux-tdep.h (aarch64_syscall): New enum.
	* aarch64-tdep.c (aarch64_record_branch_except_sys): Add code to
	handle recording of syscalls.
	* aarch64-tdep.h
	(struct gdbarch_tdep) <aarch64_syscall_record>: Defined.
	* linux-record.h (struct linux_record_tdep): Add two more syscall
	argument fields.
        * configure.tgt: Add linux-record.o to gdb_target_obs.
---
 gdb/aarch64-linux-tdep.c | 914 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb/aarch64-linux-tdep.h | 266 ++++++++++++++
 gdb/aarch64-tdep.c       |  15 +-
 gdb/aarch64-tdep.h       |   3 +
 gdb/configure.tgt        |   2 +-
 gdb/linux-record.h       |   2 +
 6 files changed, 1200 insertions(+), 2 deletions(-)

diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 10a53d4..597beab 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -41,6 +41,9 @@
 #include "user-regs.h"
 #include <ctype.h>
 
+#include "record-full.h"
+#include "linux-record.h"
+
 /* Signal frame handling.
 
       +------------+  ^
@@ -341,6 +344,753 @@ aarch64_stap_parse_special_token (struct gdbarch *gdbarch,
   return 1;
 }
 
+/* AArch64 process record-replay constructs: syscall, signal etc.  */
+
+struct linux_record_tdep aarch64_linux_record_tdep;
+
+/* aarch64_canonicalize_syscall maps syscall ids from the native AArch64
+   linux set of syscall ids into a canonical set of syscall ids used by
+   process record.  */
+
+static enum gdb_syscall
+aarch64_canonicalize_syscall (enum aarch64_syscall syscall_number)
+{
+  switch (syscall_number) {
+  case aarch64_sys_read:
+    return gdb_sys_read;
+
+  case aarch64_sys_write:
+    return gdb_sys_write;
+
+  case aarch64_sys_open:
+    return gdb_sys_open;
+
+  case aarch64_sys_close:
+    return gdb_sys_close;
+
+  case aarch64_sys_lseek:
+    return gdb_sys_lseek;
+
+  case aarch64_sys_mprotect:
+    return gdb_sys_mprotect;
+
+  case aarch64_sys_munmap:
+    return gdb_sys_munmap;
+
+  case aarch64_sys_brk:
+    return gdb_sys_brk;
+
+  case aarch64_sys_rt_sigaction:
+    return gdb_sys_rt_sigaction;
+
+  case aarch64_sys_rt_sigprocmask:
+    return gdb_sys_rt_sigprocmask;
+
+  case aarch64_sys_rt_sigreturn:
+    return gdb_sys_rt_sigreturn;
+
+  case aarch64_sys_ioctl:
+    return gdb_sys_ioctl;
+
+  case aarch64_sys_pread64:
+    return gdb_sys_pread64;
+
+  case aarch64_sys_pwrite64:
+    return gdb_sys_pwrite64;
+
+  case aarch64_sys_readv:
+    return gdb_sys_readv;
+
+  case aarch64_sys_writev:
+    return gdb_sys_writev;
+
+  case aarch64_sys_sched_yield:
+    return gdb_sys_sched_yield;
+
+  case aarch64_sys_mremap:
+    return gdb_sys_mremap;
+
+  case aarch64_sys_msync:
+    return gdb_sys_msync;
+
+  case aarch64_sys_mincore:
+    return gdb_sys_mincore;
+
+  case aarch64_sys_madvise:
+    return gdb_sys_madvise;
+
+  case aarch64_sys_shmget:
+    return gdb_sys_shmget;
+
+  case aarch64_sys_shmat:
+    return gdb_sys_shmat;
+
+  case aarch64_sys_shmctl:
+    return gdb_sys_shmctl;
+
+  case aarch64_sys_dup:
+    return gdb_sys_dup;
+
+  case aarch64_sys_nanosleep:
+    return gdb_sys_nanosleep;
+
+  case aarch64_sys_getitimer:
+    return gdb_sys_getitimer;
+
+  case aarch64_sys_setitimer:
+    return gdb_sys_setitimer;
+
+  case aarch64_sys_getpid:
+    return gdb_sys_getpid;
+
+  case aarch64_sys_sendfile:
+    return gdb_sys_sendfile;
+
+  case aarch64_sys_socket:
+    return gdb_sys_socket;
+
+  case aarch64_sys_connect:
+    return gdb_sys_connect;
+
+  case aarch64_sys_accept:
+    return gdb_sys_accept;
+
+  case aarch64_sys_sendto:
+    return gdb_sys_sendto;
+
+  case aarch64_sys_recvfrom:
+    return gdb_sys_recvfrom;
+
+  case aarch64_sys_sendmsg:
+    return gdb_sys_sendmsg;
+
+  case aarch64_sys_recvmsg:
+    return gdb_sys_recvmsg;
+
+  case aarch64_sys_shutdown:
+    return gdb_sys_shutdown;
+
+  case aarch64_sys_bind:
+    return gdb_sys_bind;
+
+  case aarch64_sys_listen:
+    return gdb_sys_listen;
+
+  case aarch64_sys_getsockname:
+    return gdb_sys_getsockname;
+
+  case aarch64_sys_getpeername:
+    return gdb_sys_getpeername;
+
+  case aarch64_sys_socketpair:
+    return gdb_sys_socketpair;
+
+  case aarch64_sys_setsockopt:
+    return gdb_sys_setsockopt;
+
+  case aarch64_sys_getsockopt:
+    return gdb_sys_getsockopt;
+
+  case aarch64_sys_clone:
+    return gdb_sys_clone;
+
+  case aarch64_sys_execve:
+    return gdb_sys_execve;
+
+  case aarch64_sys_exit:
+    return gdb_sys_exit;
+
+  case aarch64_sys_wait4:
+    return gdb_sys_wait4;
+
+  case aarch64_sys_kill:
+    return gdb_sys_kill;
+
+  case aarch64_sys_uname:
+    return gdb_sys_uname;
+
+  case aarch64_sys_semget:
+    return gdb_sys_semget;
+
+  case aarch64_sys_semop:
+    return gdb_sys_semop;
+
+  case aarch64_sys_semctl:
+    return gdb_sys_semctl;
+
+  case aarch64_sys_shmdt:
+    return gdb_sys_shmdt;
+
+  case aarch64_sys_msgget:
+    return gdb_sys_msgget;
+
+  case aarch64_sys_msgsnd:
+    return gdb_sys_msgsnd;
+
+  case aarch64_sys_msgrcv:
+    return gdb_sys_msgrcv;
+
+  case aarch64_sys_msgctl:
+    return gdb_sys_msgctl;
+
+  case aarch64_sys_fcntl:
+    return gdb_sys_fcntl;
+
+  case aarch64_sys_flock:
+    return gdb_sys_flock;
+
+  case aarch64_sys_fsync:
+    return gdb_sys_fsync;
+
+  case aarch64_sys_fdatasync:
+    return gdb_sys_fdatasync;
+
+  case aarch64_sys_truncate:
+    return gdb_sys_truncate;
+
+  case aarch64_sys_ftruncate:
+    return gdb_sys_ftruncate;
+
+  case aarch64_sys_getcwd:
+    return gdb_sys_getcwd;
+
+  case aarch64_sys_chdir:
+    return gdb_sys_chdir;
+
+  case aarch64_sys_fchdir:
+    return gdb_sys_fchdir;
+
+  case aarch64_sys_rename:
+    return gdb_sys_rename;
+
+  case aarch64_sys_mkdir:
+    return gdb_sys_mkdir;
+
+  case aarch64_sys_link:
+    return gdb_sys_link;
+
+  case aarch64_sys_unlink:
+    return gdb_sys_unlink;
+
+  case aarch64_sys_symlink:
+    return gdb_sys_symlink;
+
+  case aarch64_sys_readlink:
+    return gdb_sys_readlink;
+
+  case aarch64_sys_fchmodat:
+    return gdb_sys_fchmodat;
+
+  case aarch64_sys_fchmod:
+    return gdb_sys_fchmod;
+
+  case aarch64_sys_fchownat:
+    return gdb_sys_fchownat;
+
+  case aarch64_sys_fchown:
+    return gdb_sys_fchown;
+
+  case aarch64_sys_umask:
+    return gdb_sys_umask;
+
+  case aarch64_sys_gettimeofday:
+    return gdb_sys_gettimeofday;
+
+  case aarch64_sys_getrlimit:
+    return gdb_sys_getrlimit;
+
+  case aarch64_sys_getrusage:
+    return gdb_sys_getrusage;
+
+  case aarch64_sys_sysinfo:
+    return gdb_sys_sysinfo;
+
+  case aarch64_sys_ptrace:
+    return gdb_sys_ptrace;
+
+  case aarch64_sys_getuid:
+    return gdb_sys_getuid;
+
+  case aarch64_sys_syslog:
+    return gdb_sys_syslog;
+
+  case aarch64_sys_getgid:
+    return gdb_sys_getgid;
+
+  case aarch64_sys_setuid:
+    return gdb_sys_setuid;
+
+  case aarch64_sys_setgid:
+    return gdb_sys_setgid;
+
+  case aarch64_sys_geteuid:
+    return gdb_sys_geteuid;
+
+  case aarch64_sys_getegid:
+    return gdb_sys_getegid;
+
+  case aarch64_sys_setpgid:
+    return gdb_sys_setpgid;
+
+  case aarch64_sys_getppid:
+    return gdb_sys_getppid;
+
+  case aarch64_sys_setsid:
+    return gdb_sys_setsid;
+
+  case aarch64_sys_setreuid:
+    return gdb_sys_setreuid;
+
+  case aarch64_sys_setregid:
+    return gdb_sys_setregid;
+
+  case aarch64_sys_getgroups:
+    return gdb_sys_getgroups;
+
+  case aarch64_sys_setgroups:
+    return gdb_sys_setgroups;
+
+  case aarch64_sys_setresuid:
+    return gdb_sys_setresuid;
+
+  case aarch64_sys_getresuid:
+    return gdb_sys_getresuid;
+
+  case aarch64_sys_setresgid:
+    return gdb_sys_setresgid;
+
+  case aarch64_sys_getresgid:
+    return gdb_sys_getresgid;
+
+  case aarch64_sys_getpgid:
+    return gdb_sys_getpgid;
+
+  case aarch64_sys_setfsuid:
+    return gdb_sys_setfsuid;
+
+  case aarch64_sys_setfsgid:
+    return gdb_sys_setfsgid;
+
+  case aarch64_sys_getsid:
+    return gdb_sys_getsid;
+
+  case aarch64_sys_capget:
+    return gdb_sys_capget;
+
+  case aarch64_sys_capset:
+    return gdb_sys_capset;
+
+  case aarch64_sys_rt_sigpending:
+    return gdb_sys_rt_sigpending;
+
+  case aarch64_sys_rt_sigtimedwait:
+    return gdb_sys_rt_sigtimedwait;
+
+  case aarch64_sys_rt_sigqueueinfo:
+    return gdb_sys_rt_sigqueueinfo;
+
+  case aarch64_sys_rt_sigsuspend:
+    return gdb_sys_rt_sigsuspend;
+
+  case aarch64_sys_sigaltstack:
+    return gdb_sys_sigaltstack;
+
+  case aarch64_sys_mknod:
+    return gdb_sys_mknod;
+
+  case aarch64_sys_personality:
+    return gdb_sys_personality;
+
+  case aarch64_sys_statfs:
+    return gdb_sys_statfs;
+
+  case aarch64_sys_fstat:
+    return gdb_sys_fstat;
+
+  case aarch64_sys_fstatfs:
+    return gdb_sys_fstatfs;
+
+  case aarch64_sys_getpriority:
+    return gdb_sys_getpriority;
+
+  case aarch64_sys_setpriority:
+    return gdb_sys_setpriority;
+
+  case aarch64_sys_sched_setparam:
+    return gdb_sys_sched_setparam;
+
+  case aarch64_sys_sched_getparam:
+    return gdb_sys_sched_getparam;
+
+  case aarch64_sys_sched_setscheduler:
+    return gdb_sys_sched_setscheduler;
+
+  case aarch64_sys_sched_getscheduler:
+    return gdb_sys_sched_getscheduler;
+
+  case aarch64_sys_sched_get_priority_max:
+    return gdb_sys_sched_get_priority_max;
+
+  case aarch64_sys_sched_get_priority_min:
+    return gdb_sys_sched_get_priority_min;
+
+  case aarch64_sys_sched_rr_get_interval:
+    return gdb_sys_sched_rr_get_interval;
+
+  case aarch64_sys_mlock:
+    return gdb_sys_mlock;
+
+  case aarch64_sys_munlock:
+    return gdb_sys_munlock;
+
+  case aarch64_sys_mlockall:
+    return gdb_sys_mlockall;
+
+  case aarch64_sys_munlockall:
+    return gdb_sys_munlockall;
+
+  case aarch64_sys_vhangup:
+    return gdb_sys_vhangup;
+
+  case aarch64_sys_prctl:
+    return gdb_sys_prctl;
+
+  case aarch64_sys_adjtimex:
+    return gdb_sys_adjtimex;
+
+  case aarch64_sys_setrlimit:
+    return gdb_sys_setrlimit;
+
+  case aarch64_sys_chroot:
+    return gdb_sys_chroot;
+
+  case aarch64_sys_sync:
+    return gdb_sys_sync;
+
+  case aarch64_sys_acct:
+    return gdb_sys_acct;
+
+  case aarch64_sys_settimeofday:
+    return gdb_sys_settimeofday;
+
+  case aarch64_sys_mount:
+    return gdb_sys_mount;
+
+  case aarch64_sys_swapon:
+    return gdb_sys_swapon;
+
+  case aarch64_sys_swapoff:
+    return gdb_sys_swapoff;
+
+  case aarch64_sys_reboot:
+    return gdb_sys_reboot;
+
+  case aarch64_sys_sethostname:
+    return gdb_sys_sethostname;
+
+  case aarch64_sys_setdomainname:
+    return gdb_sys_setdomainname;
+
+  case aarch64_sys_init_module:
+    return gdb_sys_init_module;
+
+  case aarch64_sys_delete_module:
+    return gdb_sys_delete_module;
+
+  case aarch64_sys_quotactl:
+    return gdb_sys_quotactl;
+
+  case aarch64_sys_nfsservctl:
+    return gdb_sys_nfsservctl;
+
+  case aarch64_sys_gettid:
+    return gdb_sys_gettid;
+
+  case aarch64_sys_readahead:
+    return gdb_sys_readahead;
+
+  case aarch64_sys_setxattr:
+    return gdb_sys_setxattr;
+
+  case aarch64_sys_lsetxattr:
+    return gdb_sys_lsetxattr;
+
+  case aarch64_sys_fsetxattr:
+    return gdb_sys_fsetxattr;
+
+  case aarch64_sys_getxattr:
+    return gdb_sys_getxattr;
+
+  case aarch64_sys_lgetxattr:
+    return gdb_sys_lgetxattr;
+
+  case aarch64_sys_fgetxattr:
+    return gdb_sys_fgetxattr;
+
+  case aarch64_sys_listxattr:
+    return gdb_sys_listxattr;
+
+  case aarch64_sys_llistxattr:
+    return gdb_sys_llistxattr;
+
+  case aarch64_sys_flistxattr:
+    return gdb_sys_flistxattr;
+
+  case aarch64_sys_removexattr:
+    return gdb_sys_removexattr;
+
+  case aarch64_sys_lremovexattr:
+    return gdb_sys_lremovexattr;
+
+  case aarch64_sys_fremovexattr:
+    return gdb_sys_fremovexattr;
+
+  case aarch64_sys_tkill:
+    return gdb_sys_tkill;
+
+  case aarch64_sys_times:
+    return gdb_sys_times;
+
+  case aarch64_sys_futex:
+    return gdb_sys_futex;
+
+  case aarch64_sys_sched_setaffinity:
+    return gdb_sys_sched_setaffinity;
+
+  case aarch64_sys_sched_getaffinity:
+    return gdb_sys_sched_getaffinity;
+
+  case aarch64_sys_io_setup:
+    return gdb_sys_io_setup;
+
+  case aarch64_sys_io_destroy:
+    return gdb_sys_io_destroy;
+
+  case aarch64_sys_io_getevents:
+    return gdb_sys_io_getevents;
+
+  case aarch64_sys_io_submit:
+    return gdb_sys_io_submit;
+
+  case aarch64_sys_io_cancel:
+    return gdb_sys_io_cancel;
+
+  case aarch64_sys_lookup_dcookie:
+    return gdb_sys_lookup_dcookie;
+
+  case aarch64_sys_epoll_create1:
+    return gdb_sys_epoll_create;
+
+  case aarch64_sys_remap_file_pages:
+    return gdb_sys_remap_file_pages;
+
+  case aarch64_sys_getdents64:
+    return gdb_sys_getdents64;
+
+  case aarch64_sys_set_tid_address:
+    return gdb_sys_set_tid_address;
+
+  case aarch64_sys_semtimedop:
+    return gdb_sys_semtimedop;
+
+  case aarch64_sys_fadvise64:
+    return gdb_sys_fadvise64;
+
+  case aarch64_sys_timer_create:
+    return gdb_sys_timer_create;
+
+  case aarch64_sys_timer_settime:
+    return gdb_sys_timer_settime;
+
+  case aarch64_sys_timer_gettime:
+    return gdb_sys_timer_gettime;
+
+  case aarch64_sys_timer_getoverrun:
+    return gdb_sys_timer_getoverrun;
+
+  case aarch64_sys_timer_delete:
+    return gdb_sys_timer_delete;
+
+  case aarch64_sys_clock_settime:
+    return gdb_sys_clock_settime;
+
+  case aarch64_sys_clock_gettime:
+    return gdb_sys_clock_gettime;
+
+  case aarch64_sys_clock_getres:
+    return gdb_sys_clock_getres;
+
+  case aarch64_sys_clock_nanosleep:
+    return gdb_sys_clock_nanosleep;
+
+  case aarch64_sys_exit_group:
+    return gdb_sys_exit_group;
+
+  case aarch64_sys_epoll_pwait:
+    return gdb_sys_epoll_pwait;
+
+  case aarch64_sys_epoll_ctl:
+    return gdb_sys_epoll_ctl;
+
+  case aarch64_sys_tgkill:
+    return gdb_sys_tgkill;
+
+  case aarch64_sys_mbind:
+    return gdb_sys_mbind;
+
+  case aarch64_sys_set_mempolicy:
+    return gdb_sys_set_mempolicy;
+
+  case aarch64_sys_get_mempolicy:
+    return gdb_sys_get_mempolicy;
+
+  case aarch64_sys_mq_open:
+    return gdb_sys_mq_open;
+
+  case aarch64_sys_mq_unlink:
+    return gdb_sys_mq_unlink;
+
+  case aarch64_sys_mq_timedsend:
+    return gdb_sys_mq_timedsend;
+
+  case aarch64_sys_mq_timedreceive:
+    return gdb_sys_mq_timedreceive;
+
+  case aarch64_sys_mq_notify:
+    return gdb_sys_mq_notify;
+
+  case aarch64_sys_mq_getsetattr:
+    return gdb_sys_mq_getsetattr;
+
+  case aarch64_sys_kexec_load:
+    return gdb_sys_kexec_load;
+
+  case aarch64_sys_waitid:
+    return gdb_sys_waitid;
+
+  case aarch64_sys_add_key:
+    return gdb_sys_add_key;
+
+  case aarch64_sys_request_key:
+    return gdb_sys_request_key;
+
+  case aarch64_sys_keyctl:
+    return gdb_sys_keyctl;
+
+  case aarch64_sys_ioprio_set:
+    return gdb_sys_ioprio_set;
+
+  case aarch64_sys_ioprio_get:
+    return gdb_sys_ioprio_get;
+
+  case aarch64_sys_inotify_add_watch:
+    return gdb_sys_inotify_add_watch;
+
+  case aarch64_sys_inotify_rm_watch:
+    return gdb_sys_inotify_rm_watch;
+
+  case aarch64_sys_migrate_pages:
+    return gdb_sys_migrate_pages;
+
+  case aarch64_sys_pselect6:
+    return gdb_sys_pselect6;
+
+  case aarch64_sys_ppoll:
+    return gdb_sys_ppoll;
+
+  case aarch64_sys_unshare:
+    return gdb_sys_unshare;
+
+  case aarch64_sys_set_robust_list:
+    return gdb_sys_set_robust_list;
+
+  case aarch64_sys_get_robust_list:
+    return gdb_sys_get_robust_list;
+
+  case aarch64_sys_splice:
+    return gdb_sys_splice;
+
+  case aarch64_sys_tee:
+    return gdb_sys_tee;
+
+  case aarch64_sys_sync_file_range:
+    return gdb_sys_sync_file_range;
+
+  case aarch64_sys_vmsplice:
+    return gdb_sys_vmsplice;
+
+  case aarch64_sys_move_pages:
+    return gdb_sys_move_pages;
+
+  case aarch64_sys_mmap:
+    return gdb_sys_mmap2;
+
+  default:
+    return -1;
+  }
+}
+
+/* Record all registers but PC register for process-record.  */
+
+static int
+aarch64_all_but_pc_registers_record (struct regcache *regcache)
+{
+  int i;
+
+  for (i = 0; i < AARCH64_PC_REGNUM; i++)
+    if (record_full_arch_list_add_reg (regcache, AARCH64_X0_REGNUM + i))
+      return -1;
+
+  if (record_full_arch_list_add_reg (regcache, AARCH64_CPSR_REGNUM))
+    return -1;
+
+  return 0;
+}
+
+/* Handler for arm system call instruction recording.  */
+
+static int
+aarch64_linux_syscall_record (struct regcache *regcache, unsigned long svc_number)
+{
+  int ret = 0;
+  enum gdb_syscall syscall_gdb;
+
+  syscall_gdb = aarch64_canonicalize_syscall (svc_number);
+
+  if (syscall_gdb < 0)
+    {
+      printf_unfiltered (_("Process record and replay target doesn't "
+                           "support syscall number %s\n"),
+                           plongest (svc_number));
+      return -1;
+    }
+
+  if (syscall_gdb == gdb_sys_sigreturn
+      || syscall_gdb == gdb_sys_rt_sigreturn)
+   {
+     if (aarch64_all_but_pc_registers_record (regcache))
+       return -1;
+     return 0;
+   }
+
+  ret = record_linux_system_call (syscall_gdb, regcache,
+                                  &aarch64_linux_record_tdep);
+  if (ret != 0)
+    return ret;
+
+  /* Record the return value of the system call.  */
+  if (record_full_arch_list_add_reg (regcache, AARCH64_X0_REGNUM))
+    return -1;
+  /* Record LR.  */
+  if (record_full_arch_list_add_reg (regcache, AARCH64_LR_REGNUM))
+    return -1;
+  /* Record CPSR.  */
+  if (record_full_arch_list_add_reg (regcache, AARCH64_CPSR_REGNUM))
+    return -1;
+
+  return 0;
+}
+
 static void
 aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -388,6 +1138,170 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Reversible debugging, process record.  */
   set_gdbarch_process_record (gdbarch, aarch64_process_record);
+  /* Syscall record.  */
+  tdep->aarch64_syscall_record = aarch64_linux_syscall_record;
+
+  /* Initialize the aarch64_linux_record_tdep.  */
+  /* These values are the size of the type that will be used in a system
+     call.  They are obtained from Linux Kernel source.  */
+  aarch64_linux_record_tdep.size_pointer
+    = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+  aarch64_linux_record_tdep.size__old_kernel_stat = 32;
+  aarch64_linux_record_tdep.size_tms = 32;
+  aarch64_linux_record_tdep.size_loff_t = 8;
+  aarch64_linux_record_tdep.size_flock = 32;
+  aarch64_linux_record_tdep.size_oldold_utsname = 45;
+  aarch64_linux_record_tdep.size_ustat = 32;
+  aarch64_linux_record_tdep.size_old_sigaction = 152;
+  aarch64_linux_record_tdep.size_old_sigset_t = 128;
+  aarch64_linux_record_tdep.size_rlimit = 16;
+  aarch64_linux_record_tdep.size_rusage = 144;
+  aarch64_linux_record_tdep.size_timeval = 16;
+  aarch64_linux_record_tdep.size_timezone = 8;
+  aarch64_linux_record_tdep.size_old_gid_t = 2;
+  aarch64_linux_record_tdep.size_old_uid_t = 2;
+  aarch64_linux_record_tdep.size_fd_set = 128;
+  aarch64_linux_record_tdep.size_dirent = 280;
+  aarch64_linux_record_tdep.size_dirent64 = 280;
+  aarch64_linux_record_tdep.size_statfs = 120;
+  aarch64_linux_record_tdep.size_statfs64 = 120;
+  aarch64_linux_record_tdep.size_sockaddr = 16;
+  aarch64_linux_record_tdep.size_int
+    = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
+  aarch64_linux_record_tdep.size_long
+    = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  aarch64_linux_record_tdep.size_ulong
+    = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  aarch64_linux_record_tdep.size_msghdr = 56;
+  aarch64_linux_record_tdep.size_itimerval = 32;
+  aarch64_linux_record_tdep.size_stat = 144;
+  aarch64_linux_record_tdep.size_old_utsname = 325;
+  aarch64_linux_record_tdep.size_sysinfo = 112;
+  aarch64_linux_record_tdep.size_msqid_ds = 120;
+  aarch64_linux_record_tdep.size_shmid_ds = 112;
+  aarch64_linux_record_tdep.size_new_utsname = 390;
+  aarch64_linux_record_tdep.size_timex = 208;
+  aarch64_linux_record_tdep.size_mem_dqinfo = 24;
+  aarch64_linux_record_tdep.size_if_dqblk = 72;
+  aarch64_linux_record_tdep.size_fs_quota_stat = 80;
+  aarch64_linux_record_tdep.size_timespec = 16;
+  aarch64_linux_record_tdep.size_pollfd = 8;
+  aarch64_linux_record_tdep.size_NFS_FHSIZE = 32;
+  aarch64_linux_record_tdep.size_knfsd_fh = 132;
+  aarch64_linux_record_tdep.size_TASK_COMM_LEN = 16;
+  aarch64_linux_record_tdep.size_sigaction = 152;
+  aarch64_linux_record_tdep.size_sigset_t = 128;
+  aarch64_linux_record_tdep.size_siginfo_t = 128;
+  aarch64_linux_record_tdep.size_cap_user_data_t = 8;
+  aarch64_linux_record_tdep.size_stack_t = 24;
+  aarch64_linux_record_tdep.size_off_t = 8;
+  aarch64_linux_record_tdep.size_stat64 = 144;
+  aarch64_linux_record_tdep.size_gid_t = 4;
+  aarch64_linux_record_tdep.size_uid_t = 4;
+  aarch64_linux_record_tdep.size_PAGE_SIZE = 4096;
+  aarch64_linux_record_tdep.size_flock64 = 32;
+  aarch64_linux_record_tdep.size_user_desc = 16;
+  aarch64_linux_record_tdep.size_io_event = 32;
+  aarch64_linux_record_tdep.size_iocb = 64;
+  aarch64_linux_record_tdep.size_epoll_event = 12;
+  aarch64_linux_record_tdep.size_itimerspec = 32;
+  aarch64_linux_record_tdep.size_mq_attr = 64;
+  aarch64_linux_record_tdep.size_siginfo = 128;
+  aarch64_linux_record_tdep.size_termios = 60;
+  aarch64_linux_record_tdep.size_termios2 = 44;
+  aarch64_linux_record_tdep.size_pid_t = 4;
+  aarch64_linux_record_tdep.size_winsize = 8;
+  aarch64_linux_record_tdep.size_serial_struct = 72;
+  aarch64_linux_record_tdep.size_serial_icounter_struct = 80;
+  aarch64_linux_record_tdep.size_hayes_esp_config = 12;
+  aarch64_linux_record_tdep.size_size_t = 8;
+  aarch64_linux_record_tdep.size_iovec = 16;
+
+  /* These values are the second argument of system call "sys_ioctl".
+     They are obtained from Linux Kernel source.  */
+  aarch64_linux_record_tdep.ioctl_TCGETS = 0x5401;
+  aarch64_linux_record_tdep.ioctl_TCSETS = 0x5402;
+  aarch64_linux_record_tdep.ioctl_TCSETSW = 0x5403;
+  aarch64_linux_record_tdep.ioctl_TCSETSF = 0x5404;
+  aarch64_linux_record_tdep.ioctl_TCGETA = 0x5405;
+  aarch64_linux_record_tdep.ioctl_TCSETA = 0x5406;
+  aarch64_linux_record_tdep.ioctl_TCSETAW = 0x5407;
+  aarch64_linux_record_tdep.ioctl_TCSETAF = 0x5408;
+  aarch64_linux_record_tdep.ioctl_TCSBRK = 0x5409;
+  aarch64_linux_record_tdep.ioctl_TCXONC = 0x540a;
+  aarch64_linux_record_tdep.ioctl_TCFLSH = 0x540b;
+  aarch64_linux_record_tdep.ioctl_TIOCEXCL = 0x540c;
+  aarch64_linux_record_tdep.ioctl_TIOCNXCL = 0x540d;
+  aarch64_linux_record_tdep.ioctl_TIOCSCTTY = 0x540e;
+  aarch64_linux_record_tdep.ioctl_TIOCGPGRP = 0x540f;
+  aarch64_linux_record_tdep.ioctl_TIOCSPGRP = 0x5410;
+  aarch64_linux_record_tdep.ioctl_TIOCOUTQ = 0x5411;
+  aarch64_linux_record_tdep.ioctl_TIOCSTI = 0x5412;
+  aarch64_linux_record_tdep.ioctl_TIOCGWINSZ = 0x5413;
+  aarch64_linux_record_tdep.ioctl_TIOCSWINSZ = 0x5414;
+  aarch64_linux_record_tdep.ioctl_TIOCMGET = 0x5415;
+  aarch64_linux_record_tdep.ioctl_TIOCMBIS = 0x5416;
+  aarch64_linux_record_tdep.ioctl_TIOCMBIC = 0x5417;
+  aarch64_linux_record_tdep.ioctl_TIOCMSET = 0x5418;
+  aarch64_linux_record_tdep.ioctl_TIOCGSOFTCAR = 0x5419;
+  aarch64_linux_record_tdep.ioctl_TIOCSSOFTCAR = 0x541a;
+  aarch64_linux_record_tdep.ioctl_FIONREAD = 0x541b;
+  aarch64_linux_record_tdep.ioctl_TIOCINQ = 0x541b;
+  aarch64_linux_record_tdep.ioctl_TIOCLINUX = 0x541c;
+  aarch64_linux_record_tdep.ioctl_TIOCCONS = 0x541d;
+  aarch64_linux_record_tdep.ioctl_TIOCGSERIAL = 0x541e;
+  aarch64_linux_record_tdep.ioctl_TIOCSSERIAL = 0x541f;
+  aarch64_linux_record_tdep.ioctl_TIOCPKT = 0x5420;
+  aarch64_linux_record_tdep.ioctl_FIONBIO = 0x5421;
+  aarch64_linux_record_tdep.ioctl_TIOCNOTTY = 0x5422;
+  aarch64_linux_record_tdep.ioctl_TIOCSETD = 0x5423;
+  aarch64_linux_record_tdep.ioctl_TIOCGETD = 0x5424;
+  aarch64_linux_record_tdep.ioctl_TCSBRKP = 0x5425;
+  aarch64_linux_record_tdep.ioctl_TIOCTTYGSTRUCT = 0x5426;
+  aarch64_linux_record_tdep.ioctl_TIOCSBRK = 0x5427;
+  aarch64_linux_record_tdep.ioctl_TIOCCBRK = 0x5428;
+  aarch64_linux_record_tdep.ioctl_TIOCGSID = 0x5429;
+  aarch64_linux_record_tdep.ioctl_TCGETS2 = 0x802c542a;
+  aarch64_linux_record_tdep.ioctl_TCSETS2 = 0x402c542b;
+  aarch64_linux_record_tdep.ioctl_TCSETSW2 = 0x402c542c;
+  aarch64_linux_record_tdep.ioctl_TCSETSF2 = 0x402c542d;
+  aarch64_linux_record_tdep.ioctl_TIOCGPTN = 0x80045430;
+  aarch64_linux_record_tdep.ioctl_TIOCSPTLCK = 0x40045431;
+  aarch64_linux_record_tdep.ioctl_FIONCLEX = 0x5450;
+  aarch64_linux_record_tdep.ioctl_FIOCLEX = 0x5451;
+  aarch64_linux_record_tdep.ioctl_FIOASYNC = 0x5452;
+  aarch64_linux_record_tdep.ioctl_TIOCSERCONFIG = 0x5453;
+  aarch64_linux_record_tdep.ioctl_TIOCSERGWILD = 0x5454;
+  aarch64_linux_record_tdep.ioctl_TIOCSERSWILD = 0x5455;
+  aarch64_linux_record_tdep.ioctl_TIOCGLCKTRMIOS = 0x5456;
+  aarch64_linux_record_tdep.ioctl_TIOCSLCKTRMIOS = 0x5457;
+  aarch64_linux_record_tdep.ioctl_TIOCSERGSTRUCT = 0x5458;
+  aarch64_linux_record_tdep.ioctl_TIOCSERGETLSR = 0x5459;
+  aarch64_linux_record_tdep.ioctl_TIOCSERGETMULTI = 0x545a;
+  aarch64_linux_record_tdep.ioctl_TIOCSERSETMULTI = 0x545b;
+  aarch64_linux_record_tdep.ioctl_TIOCMIWAIT = 0x545c;
+  aarch64_linux_record_tdep.ioctl_TIOCGICOUNT = 0x545d;
+  aarch64_linux_record_tdep.ioctl_TIOCGHAYESESP = 0x545e;
+  aarch64_linux_record_tdep.ioctl_TIOCSHAYESESP = 0x545f;
+  aarch64_linux_record_tdep.ioctl_FIOQSIZE = 0x5460;
+
+  /* These values are the second argument of system call "sys_fcntl"
+     and "sys_fcntl64".  They are obtained from Linux Kernel source.  */
+  aarch64_linux_record_tdep.fcntl_F_GETLK = 5;
+  aarch64_linux_record_tdep.fcntl_F_GETLK64 = 12;
+  aarch64_linux_record_tdep.fcntl_F_SETLK64 = 13;
+  aarch64_linux_record_tdep.fcntl_F_SETLKW64 = 14;
+
+  /* The AArch64 syscall calling convention: reg x0-x7 for arguments,
+     reg x8 for syscall number and return value in reg x0.  */
+  aarch64_linux_record_tdep.arg1 = AARCH64_X0_REGNUM + 0;
+  aarch64_linux_record_tdep.arg2 = AARCH64_X0_REGNUM + 1;
+  aarch64_linux_record_tdep.arg3 = AARCH64_X0_REGNUM + 2;
+  aarch64_linux_record_tdep.arg4 = AARCH64_X0_REGNUM + 3;
+  aarch64_linux_record_tdep.arg5 = AARCH64_X0_REGNUM + 4;
+  aarch64_linux_record_tdep.arg6 = AARCH64_X0_REGNUM + 5;
+  aarch64_linux_record_tdep.arg7 = AARCH64_X0_REGNUM + 6;
+  aarch64_linux_record_tdep.arg8 = AARCH64_X0_REGNUM + 7;
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
index 9d09ae6..4475f2e 100644
--- a/gdb/aarch64-linux-tdep.h
+++ b/gdb/aarch64-linux-tdep.h
@@ -32,3 +32,269 @@
 
 extern const struct regset aarch64_linux_gregset;
 extern const struct regset aarch64_linux_fpregset;
+
+/* Enum that defines the AArch64 linux specific syscall identifiers used for
+   process record/replay.  */
+
+enum aarch64_syscall {
+  aarch64_sys_io_setup = 0,
+  aarch64_sys_io_destroy = 1,
+  aarch64_sys_io_submit = 2,
+  aarch64_sys_io_cancel = 3,
+  aarch64_sys_io_getevents = 4,
+  aarch64_sys_setxattr = 5,
+  aarch64_sys_lsetxattr = 6,
+  aarch64_sys_fsetxattr = 7,
+  aarch64_sys_getxattr = 8,
+  aarch64_sys_lgetxattr = 9,
+  aarch64_sys_fgetxattr = 10,
+  aarch64_sys_listxattr = 11,
+  aarch64_sys_llistxattr = 12,
+  aarch64_sys_flistxattr = 13,
+  aarch64_sys_removexattr = 14,
+  aarch64_sys_lremovexattr = 15,
+  aarch64_sys_fremovexattr = 16,
+  aarch64_sys_getcwd = 17,
+  aarch64_sys_lookup_dcookie = 18,
+  aarch64_sys_eventfd2 = 19,
+  aarch64_sys_epoll_create1 = 20,
+  aarch64_sys_epoll_ctl = 21,
+  aarch64_sys_epoll_pwait = 22,
+  aarch64_sys_dup = 23,
+  aarch64_sys_dup3 = 24,
+  aarch64_sys_fcntl = 25,
+  aarch64_sys_inotify_init1 = 26,
+  aarch64_sys_inotify_add_watch = 27,
+  aarch64_sys_inotify_rm_watch = 28,
+  aarch64_sys_ioctl = 29,
+  aarch64_sys_ioprio_set = 30,
+  aarch64_sys_ioprio_get = 31,
+  aarch64_sys_flock = 32,
+  aarch64_sys_mknod = 33,
+  aarch64_sys_mkdir = 34,
+  aarch64_sys_unlink = 35,
+  aarch64_sys_symlink = 36,
+  aarch64_sys_link = 37,
+  aarch64_sys_rename = 38,
+  aarch64_sys_umount2 = 39,
+  aarch64_sys_mount = 40,
+  aarch64_sys_pivot_root = 41,
+  aarch64_sys_nfsservctl = 42,
+  aarch64_sys_statfs = 43,
+  aarch64_sys_fstatfs = 44,
+  aarch64_sys_truncate = 45,
+  aarch64_sys_ftruncate = 46,
+  aarch64_sys_fallocate = 47,
+  aarch64_sys_faccess = 48,
+  aarch64_sys_chdir = 49,
+  aarch64_sys_fchdir = 50,
+  aarch64_sys_chroot = 51,
+  aarch64_sys_fchmod = 52,
+  aarch64_sys_fchmodat = 53,
+  aarch64_sys_fchownat = 54,
+  aarch64_sys_fchown = 55,
+  aarch64_sys_open = 56,
+  aarch64_sys_close = 57,
+  aarch64_sys_vhangup = 58,
+  aarch64_sys_pipe2 = 59,
+  aarch64_sys_quotactl = 60,
+  aarch64_sys_getdents64 = 61,
+  aarch64_sys_lseek = 62,
+  aarch64_sys_read = 63,
+  aarch64_sys_write = 64,
+  aarch64_sys_readv = 65,
+  aarch64_sys_writev = 66,
+  aarch64_sys_pread64 = 67,
+  aarch64_sys_pwrite64 = 68,
+  aarch64_sys_preadv = 69,
+  aarch64_sys_pwritev = 70,
+  aarch64_sys_sendfile = 71,
+  aarch64_sys_pselect6 = 72,
+  aarch64_sys_ppoll = 73,
+  aarch64_sys_signalfd4 = 74,
+  aarch64_sys_vmsplice = 75,
+  aarch64_sys_splice = 76,
+  aarch64_sys_tee = 77,
+  aarch64_sys_readlink = 78,
+  aarch64_sys_fstatat = 79,
+  aarch64_sys_fstat = 80,
+  aarch64_sys_sync = 81,
+  aarch64_sys_fsync = 82,
+  aarch64_sys_fdatasync = 83,
+  aarch64_sys_sync_file_range2 = 84,
+  aarch64_sys_sync_file_range = 84,
+  aarch64_sys_timerfd_create = 85,
+  aarch64_sys_timerfd_settime = 86,
+  aarch64_sys_timerfd_gettime = 87,
+  aarch64_sys_utimensat = 88,
+  aarch64_sys_acct = 89,
+  aarch64_sys_capget = 90,
+  aarch64_sys_capset = 91,
+  aarch64_sys_personality = 92,
+  aarch64_sys_exit = 93,
+  aarch64_sys_exit_group = 94,
+  aarch64_sys_waitid = 95,
+  aarch64_sys_set_tid_address = 96,
+  aarch64_sys_unshare = 97,
+  aarch64_sys_futex = 98,
+  aarch64_sys_set_robust_list = 99,
+  aarch64_sys_get_robust_list = 100,
+  aarch64_sys_nanosleep = 101,
+  aarch64_sys_getitimer = 102,
+  aarch64_sys_setitimer = 103,
+  aarch64_sys_kexec_load = 104,
+  aarch64_sys_init_module = 105,
+  aarch64_sys_delete_module = 106,
+  aarch64_sys_timer_create = 107,
+  aarch64_sys_timer_gettime = 108,
+  aarch64_sys_timer_getoverrun = 109,
+  aarch64_sys_timer_settime = 110,
+  aarch64_sys_timer_delete = 111,
+  aarch64_sys_clock_settime = 112,
+  aarch64_sys_clock_gettime = 113,
+  aarch64_sys_clock_getres = 114,
+  aarch64_sys_clock_nanosleep = 115,
+  aarch64_sys_syslog = 116,
+  aarch64_sys_ptrace = 117,
+  aarch64_sys_sched_setparam = 118,
+  aarch64_sys_sched_setscheduler = 119,
+  aarch64_sys_sched_getscheduler = 120,
+  aarch64_sys_sched_getparam = 121,
+  aarch64_sys_sched_setaffinity = 122,
+  aarch64_sys_sched_getaffinity = 123,
+  aarch64_sys_sched_yield = 124,
+  aarch64_sys_sched_get_priority_max = 125,
+  aarch64_sys_sched_get_priority_min = 126,
+  aarch64_sys_sched_rr_get_interval = 127,
+  aarch64_sys_kill = 129,
+  aarch64_sys_tkill = 130,
+  aarch64_sys_tgkill = 131,
+  aarch64_sys_sigaltstack = 132,
+  aarch64_sys_rt_sigsuspend = 133,
+  aarch64_sys_rt_sigaction = 134,
+  aarch64_sys_rt_sigprocmask = 135,
+  aarch64_sys_rt_sigpending = 136,
+  aarch64_sys_rt_sigtimedwait = 137,
+  aarch64_sys_rt_sigqueueinfo = 138,
+  aarch64_sys_rt_sigreturn = 139,
+  aarch64_sys_setpriority = 140,
+  aarch64_sys_getpriority = 141,
+  aarch64_sys_reboot = 142,
+  aarch64_sys_setregid = 143,
+  aarch64_sys_setgid = 144,
+  aarch64_sys_setreuid = 145,
+  aarch64_sys_setuid = 146,
+  aarch64_sys_setresuid = 147,
+  aarch64_sys_getresuid = 148,
+  aarch64_sys_setresgid = 149,
+  aarch64_sys_getresgid = 150,
+  aarch64_sys_setfsuid = 151,
+  aarch64_sys_setfsgid = 152,
+  aarch64_sys_times = 153,
+  aarch64_sys_setpgid = 154,
+  aarch64_sys_getpgid = 155,
+  aarch64_sys_getsid = 156,
+  aarch64_sys_setsid = 157,
+  aarch64_sys_getgroups = 158,
+  aarch64_sys_setgroups = 159,
+  aarch64_sys_uname = 160,
+  aarch64_sys_sethostname = 161,
+  aarch64_sys_setdomainname = 162,
+  aarch64_sys_getrlimit = 163,
+  aarch64_sys_setrlimit = 164,
+  aarch64_sys_getrusage = 165,
+  aarch64_sys_umask = 166,
+  aarch64_sys_prctl = 167,
+  aarch64_sys_getcpu = 168,
+  aarch64_sys_gettimeofday = 169,
+  aarch64_sys_settimeofday = 170,
+  aarch64_sys_adjtimex = 171,
+  aarch64_sys_getpid = 172,
+  aarch64_sys_getppid = 173,
+  aarch64_sys_getuid = 174,
+  aarch64_sys_geteuid = 175,
+  aarch64_sys_getgid = 176,
+  aarch64_sys_getegid = 177,
+  aarch64_sys_gettid = 178,
+  aarch64_sys_sysinfo = 179,
+  aarch64_sys_mq_open = 180,
+  aarch64_sys_mq_unlink = 181,
+  aarch64_sys_mq_timedsend = 182,
+  aarch64_sys_mq_timedreceive = 183,
+  aarch64_sys_mq_notify = 184,
+  aarch64_sys_mq_getsetattr = 185,
+  aarch64_sys_msgget = 186,
+  aarch64_sys_msgctl = 187,
+  aarch64_sys_msgrcv = 188,
+  aarch64_sys_msgsnd = 189,
+  aarch64_sys_semget = 190,
+  aarch64_sys_semctl = 191,
+  aarch64_sys_semtimedop = 192,
+  aarch64_sys_semop = 193,
+  aarch64_sys_shmget = 194,
+  aarch64_sys_shmctl = 195,
+  aarch64_sys_shmat = 196,
+  aarch64_sys_shmdt = 197,
+  aarch64_sys_socket = 198,
+  aarch64_sys_socketpair = 199,
+  aarch64_sys_bind = 200,
+  aarch64_sys_listen = 201,
+  aarch64_sys_accept = 202,
+  aarch64_sys_connect = 203,
+  aarch64_sys_getsockname = 204,
+  aarch64_sys_getpeername = 205,
+  aarch64_sys_sendto = 206,
+  aarch64_sys_recvfrom = 207,
+  aarch64_sys_setsockopt = 208,
+  aarch64_sys_getsockopt = 209,
+  aarch64_sys_shutdown = 210,
+  aarch64_sys_sendmsg = 211,
+  aarch64_sys_recvmsg = 212,
+  aarch64_sys_readahead = 213,
+  aarch64_sys_brk = 214,
+  aarch64_sys_munmap = 215,
+  aarch64_sys_mremap = 216,
+  aarch64_sys_add_key = 217,
+  aarch64_sys_request_key = 218,
+  aarch64_sys_keyctl = 219,
+  aarch64_sys_clone = 220,
+  aarch64_sys_execve = 221,
+  aarch64_sys_mmap = 222,
+  aarch64_sys_fadvise64 = 223,
+  aarch64_sys_swapon = 224,
+  aarch64_sys_swapoff = 225,
+  aarch64_sys_mprotect = 226,
+  aarch64_sys_msync = 227,
+  aarch64_sys_mlock = 228,
+  aarch64_sys_munlock = 229,
+  aarch64_sys_mlockall = 230,
+  aarch64_sys_munlockall = 231,
+  aarch64_sys_mincore = 232,
+  aarch64_sys_madvise = 233,
+  aarch64_sys_remap_file_pages = 234,
+  aarch64_sys_mbind = 235,
+  aarch64_sys_get_mempolicy = 236,
+  aarch64_sys_set_mempolicy = 237,
+  aarch64_sys_migrate_pages = 238,
+  aarch64_sys_move_pages = 239,
+  aarch64_sys_rt_tgsigqueueinfo = 240,
+  aarch64_sys_perf_event_open = 241,
+  aarch64_sys_accept4 = 242,
+  aarch64_sys_recvmmsg = 243,
+  aarch64_sys_wait4 = 260,
+  aarch64_sys_prlimit64 = 261,
+  aarch64_sys_fanotify_init = 262,
+  aarch64_sys_fanotify_mark = 263,
+  aarch64_sys_name_to_handle_at = 264,
+  aarch64_sys_open_by_handle_at = 265,
+  aarch64_sys_clock_adjtime = 266,
+  aarch64_sys_syncfs = 267,
+  aarch64_sys_setns = 268,
+  aarch64_sys_sendmmsg = 269,
+  aarch64_sys_process_vm_readv = 270,
+  aarch64_sys_process_vm_writev = 271,
+  aarch64_sys_kcmp = 272,
+  aarch64_sys_finit_module = 273,
+  aarch64_sys_sched_setattr = 274,
+  aarch64_sys_sched_getattr = 275,
+};
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index ab9e83f..faa650a 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -3002,7 +3002,20 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
     {
       /* Exception generation instructions. */
       if (insn_bits24_27 == 0x04)
-        return AARCH64_RECORD_UNSUPPORTED;
+        {
+          if (!bits (aarch64_insn_r->aarch64_insn, 2, 4) &&
+              !bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
+               bits (aarch64_insn_r->aarch64_insn, 0, 1) == 0x01)
+            {
+              ULONGEST svc_number;
+              regcache_raw_read_unsigned (aarch64_insn_r->regcache, 8,
+                                          &svc_number);
+              return tdep->aarch64_syscall_record (aarch64_insn_r->regcache,
+                                                   svc_number);
+            }
+          else
+            return AARCH64_RECORD_UNSUPPORTED;
+        }
       /* System instructions. */
       else if (insn_bits24_27 == 0x05 && insn_bits22_23 == 0x00)
         {
diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
index 6f27ec8..63051f9 100644
--- a/gdb/aarch64-tdep.h
+++ b/gdb/aarch64-tdep.h
@@ -88,6 +88,9 @@ struct gdbarch_tdep
   struct type *vns_type;
   struct type *vnh_type;
   struct type *vnb_type;
+
+  /* syscall record.  */
+  int (*aarch64_syscall_record) (struct regcache *regcache, unsigned long svc_number);
 };
 
 extern int aarch64_process_record (struct gdbarch *gdbarch,
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 7fdd34e..d018cf9 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -43,7 +43,7 @@ aarch64*-*-linux*)
 	# Target: AArch64 linux
 	gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o \
 			glibc-tdep.o linux-tdep.o solib-svr4.o \
-			symfile-mem.o"
+			symfile-mem.o linux-record.o"
 	build_gdbserver=yes
 	;;
 
diff --git a/gdb/linux-record.h b/gdb/linux-record.h
index ab39cb9..34dad52 100644
--- a/gdb/linux-record.h
+++ b/gdb/linux-record.h
@@ -174,6 +174,8 @@ struct linux_record_tdep
   int arg4;
   int arg5;
   int arg6;
+  int arg7;
+  int arg8;
 };
 
 /* Enum that defines the gdb-canonical set of Linux syscall identifiers.
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 4/5] Support for recording aarch64 advanced SIMD instructions
  2015-02-03  1:17 [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
@ 2015-02-03  1:17 ` Omair Javaid
  2015-02-20  9:53   ` Yao Qi
  2015-02-03  1:17 ` [PATCH v4 1/5] NEWS entry about aarch64-linux record/replay support Omair Javaid
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Omair Javaid @ 2015-02-03  1:17 UTC (permalink / raw)
  To: gdb-patches

gdb:

2015-02-02  Omair Javaid  <omair.javaid@linaro.org>

	* aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
	for data processing SIMD and floating point insns.
	(aarch64_record_asimd_load_store): Add handler to record ASIMD load
	store insns.
	(aarch64_record_load_store): Install record handler
	aarch64_record_asimd_load_store.
	(aarch64_record_decode_insn_handler): Install record handler
	aarch64_record_data_proc_simd_fp.
---
 gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 226 insertions(+), 2 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index faa650a..d2ec2c1 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -3047,6 +3047,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
   return AARCH64_RECORD_SUCCESS;
 }
 
+/* Record handler for advanced SIMD load and store instructions.  */
+static unsigned int
+aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
+{
+  CORE_ADDR address;
+  uint64_t addr_offset = 0;
+  uint32_t record_buf[24];
+  uint64_t record_buf_mem[24];
+  uint32_t reg_rn, reg_rt, reg_rm;
+  uint32_t reg_index = 0, mem_index = 0;
+  uint8_t eindex, rindex, sindex, reg_tt, replicate;
+  uint8_t elements, esize, rpt, selem, single, scale;
+  uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;
+
+  reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+  reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
+  reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
+
+  wback = bit (aarch64_insn_r->aarch64_insn, 23);
+  single = bit (aarch64_insn_r->aarch64_insn, 24);
+  ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
+  size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
+  opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
+  regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
+
+  if (single)
+    {
+      scale = opcode_bits >> 2;
+      selem = ((opcode_bits & 0x02) |
+              bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
+      replicate = 0;
+      switch (scale)
+        {
+        case 2:
+          if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
+            scale = 3;
+          break;
+        case 3:
+          scale = size_bits;
+          replicate = 1;
+          break;
+        default:
+          break;
+        }
+      esize = 8 << scale;
+      if (replicate)
+        for (sindex = 0; sindex < selem; sindex++)
+          {
+            record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
+            reg_rt = (reg_rt + 1) % 32;
+          }
+      else
+        {
+          for (sindex = 0; sindex < selem; sindex++)
+            if (ld_flag)
+              record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
+            else
+              {
+                record_buf_mem[mem_index++] = esize / 8;
+                record_buf_mem[mem_index++] = address + addr_offset;
+              }
+            addr_offset = addr_offset + (esize / 8);
+            reg_rt = (reg_rt + 1) % 32;
+        }
+    }
+  else
+    {
+      esize = 8 << size_bits;
+      if (bit (aarch64_insn_r->aarch64_insn, 30))
+        elements = 128 / esize;
+      else
+        elements = 64 / esize;
+
+      switch (opcode_bits)
+        {
+        case 0:
+          rpt = 1;
+          selem = 4;
+          break;
+        case 2:
+          rpt = 4;
+          selem = 1;
+          break;
+        case 4:
+          rpt = 1;
+          selem = 3;
+          break;
+        case 6:
+          rpt = 3;
+          selem = 1;
+          break;
+        case 7:
+          rpt = 1;
+          selem = 1;
+          break;
+        case 8:
+          rpt = 1;
+          selem = 2;
+          break;
+        case 10:
+          rpt = 2;
+          selem = 1;
+          break;
+        default:
+          return AARCH64_RECORD_UNSUPPORTED;
+          break;
+        }
+      for (rindex = 0; rindex < rpt; rindex++)
+        for (eindex = 0; eindex < elements; eindex++)
+          {
+            reg_tt = (reg_rt + rindex) % 32;
+            for (sindex = 0; sindex < selem; sindex++)
+              {
+                if (ld_flag)
+                  record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
+                else
+                  {
+                    record_buf_mem[mem_index++] = esize / 8;
+                    record_buf_mem[mem_index++] = address + addr_offset;
+                  }
+                addr_offset = addr_offset + (esize / 8);
+                reg_tt = (reg_tt + 1) % 32;
+              }
+          }
+    }
+
+  if (wback)
+    record_buf[reg_index++] = reg_rn;
+
+  aarch64_insn_r->reg_rec_count = reg_index;
+  aarch64_insn_r->mem_rec_count = mem_index / 2;
+  MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
+             record_buf_mem);
+  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+             record_buf);
+  return AARCH64_RECORD_SUCCESS;
+}
+
 /* Record handler for load and store instructions.  */
 static unsigned int
 aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
@@ -3285,7 +3423,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
     }
   /* Advanced SIMD load/store instructions.  */
   else
-    return AARCH64_RECORD_UNSUPPORTED;
+    return aarch64_record_asimd_load_store (aarch64_insn_r);
 
   MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
              record_buf_mem);
@@ -3293,6 +3431,92 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
              record_buf);
   return AARCH64_RECORD_SUCCESS;
 }
+
+/* Record handler for data processing SIMD and floating point instructions.  */
+
+static unsigned int
+aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
+{
+  uint8_t insn_bit21, opcode, rmode, reg_rd;
+  uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
+  uint8_t insn_bits11_14;
+  uint32_t record_buf[2];
+
+  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
+  insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
+  insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
+  insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
+  insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
+  opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
+  rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
+  reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+  insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
+
+  if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
+    {
+      /* Floating point - fixed point conversion instructions.  */
+      if (!insn_bit21)
+        if ((opcode >> 1) == 0x0 && rmode == 0x03)
+          record_buf[0] = reg_rd;
+        else
+          record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+      /* Floating point - conditional compare instructions.  */
+      else if (insn_bits10_11 == 0x01)
+        record_buf[0] = AARCH64_CPSR_REGNUM;
+      /* Floating point - data processing (2-source) and
+         conditional select instructions.  */
+      else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
+        record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+      else if (insn_bits10_11 == 0x00)
+        {
+          /* Floating point - immediate instructions.  */
+          if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
+            record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+          /* Floating point - compare instructions.  */
+          else if ((insn_bits12_15 & 0x03) == 0x02)
+            record_buf[0] = AARCH64_CPSR_REGNUM;
+          /* Floating point - integer conversions instructions.  */
+          if (insn_bits12_15 == 0x00)
+            {
+              /* Convert float to integer instruction.  */
+              if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
+                record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
+              /* Convert integer to float instruction.  */
+              else if ((opcode >> 1) == 0x01 && !rmode)
+                record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+              /* Move float to integer instruction.  */
+              else if ((opcode >> 1) == 0x03)
+                {
+                  if (!(opcode & 0x01))
+                    record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
+                  else
+                    record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+                }
+            }
+        }
+    }
+  else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
+    {
+      /* Advanced SIMD copy instructions.  */
+      if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
+          !bit (aarch64_insn_r->aarch64_insn, 15) &&
+          bit (aarch64_insn_r->aarch64_insn, 10))
+        if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
+          record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
+        else
+          record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+      else
+        record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+    }
+  /* All remaining floating point or advanced SIMD instructions.  */
+  else
+    record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+
+  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+             record_buf);
+  return AARCH64_RECORD_SUCCESS;
+}
+
 /* Decodes insns type and invokes its record handler.  */
 
 static unsigned int
@@ -3323,7 +3547,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
 
   /* Data processing - SIMD and floating point instructions.  */
   if (ins_bit25 && ins_bit26 && ins_bit27)
-    return AARCH64_RECORD_UNSUPPORTED;
+    return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
 
   return AARCH64_RECORD_UNSUPPORTED;
 }
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux
@ 2015-02-03  1:17 Omair Javaid
  2015-02-03  1:17 ` [PATCH v4 4/5] Support for recording aarch64 advanced SIMD instructions Omair Javaid
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Omair Javaid @ 2015-02-03  1:17 UTC (permalink / raw)
  To: gdb-patches

This is another attempt to get these aarch64 record replay patches approved.

These have been lingering since mid last year and I ll be very thankful if some of our maintainers can help me get them committed.

I have added a couple of bug fixes which has improved the testsuite failure rate.

Here are the fresh results from gdb.reverse testsuite ran on aarch64 hardware:
Remote & Native:

Patch#1  NEWS entry about aarch64-linux record/replay support
has been previously posted and approved here:
https://sourceware.org/ml/gdb-patches/2014-06/msg00185.html
https://sourceware.org/ml/gdb-patches/2014-09/msg00611.html

Patch#2  Implements aarch64 process record and reverse debugging support
has been discussed and updated in several iteration. Previous versions and
discussions can be found here:
https://sourceware.org/ml/gdb-patches/2014-10/msg00540.html
https://sourceware.org/ml/gdb-patches/2014-08/msg00662.html


Patch#3  Support for recording syscall on aarch64-linux
has been previously discussed and improved in this version too.
Previous discussions can be found here:
https://sourceware.org/ml/gdb-patches/2014-10/msg00541.html

Patch#4  Support for recording aarch64 advanced SIMD instructions
has also been previously posted and discussed here:
https://sourceware.org/ml/gdb-patches/2014-10/msg00345.html

Patch#5  Enables gdb.reverse testsuite for aarch64*-linux targets
is a pretty trivial patch to enable gdb testsuite. Its previously posted and discussed here:
https://sourceware.org/ml/gdb-patches/2014-06/msg00242.html

Omair Javaid (5):
  NEWS entry about aarch64-linux record/replay support
  Implements aarch64 process record and reverse debugging support
  Support for recording syscall on aarch64-linux
  Support for recording aarch64 advanced SIMD instructions
  Enables gdb.reverse testsuite for aarch64*-linux targets

 gdb/NEWS                  |   4 +
 gdb/aarch64-linux-tdep.c  | 917 ++++++++++++++++++++++++++++++++++++++++++++++
 gdb/aarch64-linux-tdep.h  | 266 ++++++++++++++
 gdb/aarch64-tdep.c        | 815 ++++++++++++++++++++++++++++++++++++++++
 gdb/aarch64-tdep.h        |   6 +
 gdb/configure.tgt         |   2 +-
 gdb/linux-record.h        |   2 +
 gdb/testsuite/lib/gdb.exp |   2 +
 8 files changed, 2013 insertions(+), 1 deletion(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 5/5] Enables gdb.reverse testsuite for aarch64*-linux targets
  2015-02-03  1:17 [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
                   ` (3 preceding siblings ...)
  2015-02-03  1:17 ` [PATCH v4 2/5] Implements aarch64 process record and reverse debugging support Omair Javaid
@ 2015-02-03  1:17 ` Omair Javaid
  2015-02-20  9:57   ` Yao Qi
  2015-02-03  1:32 ` [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
  5 siblings, 1 reply; 12+ messages in thread
From: Omair Javaid @ 2015-02-03  1:17 UTC (permalink / raw)
  To: gdb-patches

gdb/testsuite:

2015-02-02  Omair Javaid  <omair.javaid@linaro.org>

	* lib/gdb.exp (supports_process_record): Return true for aarch64*-linux*.
	(supports_reverse): Likewise.
---
 gdb/testsuite/lib/gdb.exp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index a6f200f..2d33bce 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -1910,6 +1910,7 @@ proc supports_process_record {} {
 
     if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
          || [istarget "i\[34567\]86-*-linux*"]
+         || [istarget "aarch64*-*-linux*"]
          || [istarget "powerpc*-*-linux*"] } {
 	return 1
     }
@@ -1927,6 +1928,7 @@ proc supports_reverse {} {
 
     if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
          || [istarget "i\[34567\]86-*-linux*"]
+         || [istarget "aarch64*-*-linux*"]
          || [istarget "powerpc*-*-linux*"] } {
 	return 1
     }
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux
  2015-02-03  1:17 [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
                   ` (4 preceding siblings ...)
  2015-02-03  1:17 ` [PATCH v4 5/5] Enables gdb.reverse testsuite for aarch64*-linux targets Omair Javaid
@ 2015-02-03  1:32 ` Omair Javaid
  5 siblings, 0 replies; 12+ messages in thread
From: Omair Javaid @ 2015-02-03  1:32 UTC (permalink / raw)
  To: gdb-patches

On 3 February 2015 at 06:16, Omair Javaid <omair.javaid@linaro.org> wrote:
> This is another attempt to get these aarch64 record replay patches approved.
>
> These have been lingering since mid last year and I ll be very thankful if some of our maintainers can help me get them committed.
>
> I have added a couple of bug fixes which has improved the testsuite failure rate.
>
> Here are the fresh results from gdb.reverse testsuite ran on aarch64 hardware:
> Remote & Native:

# of expected passes 2319
# of unexpected failures 7

Forgot to add results in my previous email.

>
> Patch#1  NEWS entry about aarch64-linux record/replay support
> has been previously posted and approved here:
> https://sourceware.org/ml/gdb-patches/2014-06/msg00185.html
> https://sourceware.org/ml/gdb-patches/2014-09/msg00611.html
>
> Patch#2  Implements aarch64 process record and reverse debugging support
> has been discussed and updated in several iteration. Previous versions and
> discussions can be found here:
> https://sourceware.org/ml/gdb-patches/2014-10/msg00540.html
> https://sourceware.org/ml/gdb-patches/2014-08/msg00662.html
>
>
> Patch#3  Support for recording syscall on aarch64-linux
> has been previously discussed and improved in this version too.
> Previous discussions can be found here:
> https://sourceware.org/ml/gdb-patches/2014-10/msg00541.html
>
> Patch#4  Support for recording aarch64 advanced SIMD instructions
> has also been previously posted and discussed here:
> https://sourceware.org/ml/gdb-patches/2014-10/msg00345.html
>
> Patch#5  Enables gdb.reverse testsuite for aarch64*-linux targets
> is a pretty trivial patch to enable gdb testsuite. Its previously posted and discussed here:
> https://sourceware.org/ml/gdb-patches/2014-06/msg00242.html
>
> Omair Javaid (5):
>   NEWS entry about aarch64-linux record/replay support
>   Implements aarch64 process record and reverse debugging support
>   Support for recording syscall on aarch64-linux
>   Support for recording aarch64 advanced SIMD instructions
>   Enables gdb.reverse testsuite for aarch64*-linux targets
>
>  gdb/NEWS                  |   4 +
>  gdb/aarch64-linux-tdep.c  | 917 ++++++++++++++++++++++++++++++++++++++++++++++
>  gdb/aarch64-linux-tdep.h  | 266 ++++++++++++++
>  gdb/aarch64-tdep.c        | 815 ++++++++++++++++++++++++++++++++++++++++
>  gdb/aarch64-tdep.h        |   6 +
>  gdb/configure.tgt         |   2 +-
>  gdb/linux-record.h        |   2 +
>  gdb/testsuite/lib/gdb.exp |   2 +
>  8 files changed, 2013 insertions(+), 1 deletion(-)
>
> --
> 1.9.1
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 1/5] NEWS entry about aarch64-linux record/replay support
  2015-02-03  1:17 ` [PATCH v4 1/5] NEWS entry about aarch64-linux record/replay support Omair Javaid
@ 2015-02-03  3:38   ` Eli Zaretskii
  0 siblings, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2015-02-03  3:38 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

> From: Omair Javaid <omair.javaid@linaro.org>
> Date: Tue,  3 Feb 2015 06:16:52 +0500
> 
> gdb:
> 
> 2015-02-02  Omair Javaid  <omair.javaid@linaro.org>
> 
> 	* NEWS: Add a note on process record-replay support on aarch64*-linux*
> 	targets.
> ---
>  gdb/NEWS | 4 ++++
>  1 file changed, 4 insertions(+)

OK, thanks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 2/5] Implements aarch64 process record and reverse debugging support
  2015-02-03  1:17 ` [PATCH v4 2/5] Implements aarch64 process record and reverse debugging support Omair Javaid
@ 2015-02-19 12:35   ` Yao Qi
  0 siblings, 0 replies; 12+ messages in thread
From: Yao Qi @ 2015-02-19 12:35 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

Omair Javaid <omair.javaid@linaro.org> writes:

Hi Omair,
Thanks for your patience to submit and update your patches
continuously.  I finally have a chance to review this series...

> 2015-02-02  Omair Javaid  <omair.javaid@linaro.org>
>
> 	* aarch64-linux-tdep.c (aarch64_linux_init_abi): Install AArch64
> 	process record handler.
> 	* aarch64-tdep.c (record.h): Include.
> 	(record-full.h): Include.
> 	(submask): New macro.
> 	(bit): New macro.
> 	(bits): New macro.
> 	(REG_ALLOC): New macro.
> 	(MEM_ALLOC): New macro.
> 	(struct aarch64_mem_r): Define.
> 	(aarch64_record_result): New enum.
> 	(struct insn_decode_record): Define.
> 	(insn_decode_record): New typedef.
> 	(aarch64_record_data_proc_reg): Add record handler for data processing
> 	register insns.

"New function" should be fine here, some instances below.

> 	(aarch64_record_data_proc_imm): Add record handler for data processing
> 	immediate insns.
> 	(aarch64_record_branch_except_sys): Add record handler for branch,
> 	exception and system insns.
> 	(aarch64_record_load_store): Add record handler for load/store insns.
> 	(aarch64_record_decode_insn_handler): Add record insn decoding function.
> 	(deallocate_reg_mem): Add memory cleanup function for record
> 	data.
> 	(aarch64_process_record): Add gdbarch handler for AArch64 process
> 	record.
> 	* aarch64-tdep.h (aarch64_process_record): New extern declaration.


> +
> +/* AArch64 instruction record contains opcode of current insn and execution
> +   state (before entry to decode_insn()), contains list of to-be-modified
> +   registers and memory blocks (on return from decode_insn()).  */

These comments are good, but please move them into each field below.

> +
> +typedef struct insn_decode_record_t
> +{
> +  struct gdbarch *gdbarch;
> +  struct regcache *regcache;
> +  CORE_ADDR this_addr;
> +  uint32_t aarch64_insn;
> +  uint32_t mem_rec_count;
> +  uint32_t reg_rec_count;
> +  uint32_t *aarch64_regs;
> +  struct aarch64_mem_r *aarch64_mems;
> +} insn_decode_record;
> +
> +/* Record handler for data processing - register instructions.  */

A blank line is needed between the function definition and comment, here
and somewhere else.

> +static unsigned int
> +aarch64_record_data_proc_reg (insn_decode_record *aarch64_insn_r)
> +{
> +  uint8_t reg_rd, insn_bits24_27, insn_bits21_23, setflags;
> +  uint32_t record_buf[4];
> +
> +  reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> +  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
> +  insn_bits21_23 = bits (aarch64_insn_r->aarch64_insn, 21, 23);
> +
> +  if (!bit (aarch64_insn_r->aarch64_insn, 28))
> +    {

Please move local setflags here, as it is only used inside this block.

> +      /* Logical (shifted register).  */
> +      if (insn_bits24_27 == 0x0a)
> +        setflags = (bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03);
> +      /* Add/subtract.  */
> +      else if (insn_bits24_27 == 0x0b)
> +        setflags = bit (aarch64_insn_r->aarch64_insn, 29);
> +      else
> +        return AARCH64_RECORD_UNSUPPORTED;

According to the manual I have, there isn't such instruction encoding
goes to the "return AARCH64_RECORD_UNSUPPORTED" path.  What is the
definition of AARCH64_RECORD_UNSUPPORTED?  Its literal meaning to me
is that there are some instructions encoding available, but GDB doesn't
support them in process record.  For the instructions will appear in
future, probably we can return AARCH64_RECORD_UNKNOWN or
AARCH64_RECORD_UNALLOCATED.  In this way, we can easily do statistics
which instructions are not supported.  What do you think?

> +
> +      record_buf[0] = reg_rd;
> +      aarch64_insn_r->reg_rec_count = 1;
> +      if (setflags)
> +        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
> +    }
> +  else
> +    {
> +      if (insn_bits24_27 == 0x0b)
> +        {
> +          /* Data-processing (3 source).  */
> +          record_buf[0] = reg_rd;
> +          aarch64_insn_r->reg_rec_count = 1;
> +        }
> +      else if (insn_bits24_27 == 0x0a)
> +        {
> +          if (insn_bits21_23 == 0x00)
> +            {
> +              /* Add/subtract (with carry).  */
> +              record_buf[0] = reg_rd;
> +              aarch64_insn_r->reg_rec_count = 1;
> +              if (bit (aarch64_insn_r->aarch64_insn, 29))
> +                {
> +                  record_buf[1] = AARCH64_CPSR_REGNUM;
> +                  aarch64_insn_r->reg_rec_count = 2;
> +                }
> +            }
> +          else if (insn_bits21_23 == 0x02)
> +            {
> +              /* Conditional compare (register) / Conditional compare (immediate).  */

This line is too long.

> +              record_buf[0] = AARCH64_CPSR_REGNUM;
> +              aarch64_insn_r->reg_rec_count = 1;
> +            }
> +          else if (insn_bits21_23 == 0x04 || insn_bits21_23 == 0x06)
> +            {
> +              /* CConditional select.  */
> +              /* Data-processing (2 source).  */
> +              /* Data-processing (1 source).  */
> +              record_buf[0] = reg_rd;
> +              aarch64_insn_r->reg_rec_count = 1;
> +            }
> +          else
> +            return AARCH64_RECORD_UNSUPPORTED;
> +        }
> +    }
> +
> +  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> +            record_buf);
> +  return AARCH64_RECORD_SUCCESS;
> +}
> +
> +/* Record handler for data processing - immediate instructions.  */
> +static unsigned int
> +aarch64_record_data_proc_imm (insn_decode_record *aarch64_insn_r)
> +{
> +  uint8_t reg_rd, insn_bit28, insn_bit23, insn_bits24_27, setflags;
> +  uint32_t record_buf[4];
> +
> +  reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> +  insn_bit28 = bit (aarch64_insn_r->aarch64_insn, 28);
> +  insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23);
> +  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
> +
> +  /* PC rel addressing / Move wide immediate / BitField / Extract.  */

Let's split the comments into pieces and associate each to the condition below,

> +  if (insn_bits24_27 == 0x00 || insn_bits24_27 == 0x03 ||

Move "||" to the next line.

> +     (insn_bits24_27 == 0x02 && insn_bit23))


something like:

    if (insn_bits24_27 == 0x00 /* PC rel addressing */
        || insn_bits24_27 == 0x03 /* Bitfield and Extract */
        || (insn_bits24_27 == 0x02 && insn_bit23)) /* Move wide (immediate) */

It's clear to read code and manual together in this way, IMO.

> +    {
> +      record_buf[0] = reg_rd;
> +      aarch64_insn_r->reg_rec_count = 1;
> +    }
> +  else if (insn_bits24_27 == 0x01)
> +    {
> +      /* Add/Subtract (immediate).  */
> +      setflags = bit (aarch64_insn_r->aarch64_insn, 29);
> +      record_buf[0] = reg_rd;
> +      aarch64_insn_r->reg_rec_count = 1;
> +      if (setflags)
> +        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
> +    }
> +  else if (insn_bits24_27 == 0x02 && !insn_bit23)
> +    {
> +      /* Logical (immediate).  */
> +      setflags = bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03;
> +      record_buf[0] = reg_rd;
> +      aarch64_insn_r->reg_rec_count = 1;
> +      if (setflags)
> +        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM;
> +    }
> +  else
> +    return AARCH64_RECORD_UNSUPPORTED;
> +
> +  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> +            record_buf);
> +  return AARCH64_RECORD_SUCCESS;
> +}
> +
> +/* Record handler for branch, exception generation and system instructions.  */
> +static unsigned int
> +aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
> +{
> +  struct gdbarch_tdep *tdep = gdbarch_tdep (aarch64_insn_r->gdbarch);

tdep isn't used.

> +  uint8_t insn_bits24_27, insn_bits28_31, insn_bits22_23;
> +  uint32_t record_buf[4];
> +
> +  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
> +  insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
> +  insn_bits22_23 = bits (aarch64_insn_r->aarch64_insn, 22, 23);
> +
> +  if (insn_bits28_31 == 0x0d)
> +    {
> +      /* Exception generation instructions. */
> +      if (insn_bits24_27 == 0x04)
> +        return AARCH64_RECORD_UNSUPPORTED;
> +      /* System instructions. */
> +      else if (insn_bits24_27 == 0x05 && insn_bits22_23 == 0x00)
> +        {
> +          record_buf[0] = AARCH64_CPSR_REGNUM;
> +          record_buf[1] = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> +          aarch64_insn_r->reg_rec_count = 2;

Some system instructions change Rt, such as "MSR (register)", but some
don't, such as ISB and DMB.  We should handle them differently.

> +        }
> +      else if((insn_bits24_27 & 0x0e) == 0x06)
> +        {

Add /* Unconditional branch (register) */

> +          record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
> +          if (bits (aarch64_insn_r->aarch64_insn, 21, 22) == 0x01)
> +            record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM;
> +        }
> +      else
> +        return AARCH64_RECORD_UNSUPPORTED;

return AARCH64_RECORD_UNKNOWN?

> +    }
> +  else if ((insn_bits28_31 & 0x07) == 0x01 && (insn_bits24_27 & 0x0c) == 0x04)
> +    {

/* Unconditional branch (immediate) */

> +      record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
> +      if (bit (aarch64_insn_r->aarch64_insn, 31))
> +        record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM;
> +    }
> +  else
> +    /* All other types of branch instructions. */

Let us mention these branch instructions explicitly, like:

      /* Compare & branch (immediate), Test & branch (immediate) and
         Conditional branch (immediate) */

> +    record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM;
> +
> +  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> +            record_buf);
> +  return AARCH64_RECORD_SUCCESS;
> +}
> +
> +/* Record handler for load and store instructions.  */
> +static unsigned int
> +aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
> +{
> +  uint8_t insn_bits24_27, insn_bits28_29, insn_bits10_11;
> +  uint8_t insn_bit23, insn_bit21;
> +  uint8_t opc, size_bits, ld_flag, vector_flag;
> +  uint32_t reg_rn, reg_rt, reg_rt2;
> +  uint64_t datasize, offset;
> +  uint32_t record_buf[8];
> +  uint64_t record_buf_mem[8];
> +  CORE_ADDR address;
> +
> +  insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
> +  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
> +  insn_bits28_29 = bits (aarch64_insn_r->aarch64_insn, 28, 29);
> +  insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
> +  insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23);
> +  ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
> +  vector_flag = bit (aarch64_insn_r->aarch64_insn, 26);
> +  reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> +  reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
> +  reg_rt2 = bits (aarch64_insn_r->aarch64_insn, 10, 14);
> +  size_bits = bits (aarch64_insn_r->aarch64_insn, 30, 31);
> +
> +  /* Load/store exclusive instructions decoding.  */

The comment should consistent in style, better to be

    /* Load/store exclusive */

> +  if (insn_bits24_27 == 0x08 && insn_bits28_29 == 0x00)
> +    {
> +      if (ld_flag)
> +        {
> +          record_buf[0] = reg_rt;
> +          aarch64_insn_r->reg_rec_count = 1;
> +          if (insn_bit21)
> +            {
> +              record_buf[1] = reg_rt2;
> +              aarch64_insn_r->reg_rec_count = 2;
> +            }
> +        }
> +      else
> +        {
> +          if (insn_bit21)
> +            datasize = (8 << size_bits) * 2;
> +          else
> +            datasize = (8 << size_bits);
> +          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
> +                                      &address);
> +          record_buf_mem[0] = datasize / 8;
> +          record_buf_mem[1] = address;
> +          aarch64_insn_r->mem_rec_count = 1;
> +          if (!insn_bit23)
> +            {
> +              /* Save register rs.  */
> +              record_buf[0] = bits (aarch64_insn_r->aarch64_insn, 16, 20);
> +              aarch64_insn_r->reg_rec_count = 1;
> +            }
> +        }
> +    }
> +  /* Load register (literal) instructions decoding.  */
> +  else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x01)
> +    {
> +      if (vector_flag)
> +        record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
> +      else
> +        record_buf[0] = reg_rt;
> +      aarch64_insn_r->reg_rec_count = 1;
> +    }
> +  /* All types of load/store pair instructions decoding.  */
> +  else if ((insn_bits24_27 & 0x0a) == 0x08 && insn_bits28_29 == 0x02)
> +    {
> +      if (ld_flag)
> +        {
> +          if (vector_flag)
> +            {
> +              record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
> +              record_buf[1] = reg_rt2 + AARCH64_V0_REGNUM;
> +            }
> +          else
> +            {
> +              record_buf[0] = reg_rt;
> +              record_buf[1] = reg_rt2;
> +            }
> +          aarch64_insn_r->reg_rec_count = 2;
> +        }
> +      else
> +        {
> +          uint16_t imm7_off;
> +          imm7_off = bits (aarch64_insn_r->aarch64_insn, 15, 21);
> +          if (!vector_flag)
> +            size_bits = size_bits >> 1;
> +          datasize = 8 << (2 + size_bits);
> +          offset = (imm7_off & 0x40) ? (~imm7_off & 0x007f) + 1 : imm7_off;
> +          offset = offset << (2 + size_bits);
> +          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
> +                                      &address);
> +          if (!((insn_bits24_27 & 0x0b) == 0x08 && insn_bit23))
> +            {
> +              if (imm7_off & 0x40)
> +                address = address - offset;
> +              else
> +                address = address + offset;
> +            }
> +
> +          record_buf_mem[0] = datasize / 8;
> +          record_buf_mem[1] = address;
> +          record_buf_mem[2] = datasize / 8;
> +          record_buf_mem[3] = address + (datasize / 8);
> +          aarch64_insn_r->mem_rec_count = 2;
> +        }
> +      if (bit (aarch64_insn_r->aarch64_insn, 23))
> +        record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn;
> +    }
> +  /* Load/store register (unsigned immediate) instructions.  */
> +  else if ((insn_bits24_27 & 0x0b) == 0x09 && insn_bits28_29 == 0x03)
> +    {
> +      opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
> +      if (!(opc >> 1))
> +        if (opc & 0x01)
> +          ld_flag = 0x01;
> +        else
> +          ld_flag = 0x0;
> +      else
> +        if (size_bits != 0x03)
> +          ld_flag = 0x01;
> +        else
> +          return AARCH64_RECORD_UNSUPPORTED;
> +
> +      if (!ld_flag)
> +        {
> +          offset = bits (aarch64_insn_r->aarch64_insn, 10, 21);
> +          datasize = 8 << size_bits;
> +          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
> +                                      &address);
> +          offset = offset << size_bits;
> +          address = address + offset;
> +
> +          record_buf_mem[0] = datasize >> 3;
> +          record_buf_mem[1] = address;
> +          aarch64_insn_r->mem_rec_count = 1;
> +        }
> +      else
> +        {
> +          if (vector_flag)
> +            record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
> +          else
> +            record_buf[0] = reg_rt;
> +          aarch64_insn_r->reg_rec_count = 1;
> +        }
> +    }
> +  /* Load/store register (register offset) instructions.  */
> +  else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03 &&
> +            insn_bits10_11 == 0x02 && insn_bit21)
> +    {
> +      opc = bits (aarch64_insn_r->aarch64_insn, 22, 23);
> +      if (!(opc >> 1))
> +        if (opc & 0x01)
> +          ld_flag = 0x01;
> +        else
> +          ld_flag = 0x0;
> +      else
> +        if (size_bits != 0x03)
> +          ld_flag = 0x01;
> +        else
> +          return AARCH64_RECORD_UNSUPPORTED;
> +
> +      if (!ld_flag)
> +        {
> +          uint64_t reg_rm_val;
> +          regcache_raw_read_unsigned (aarch64_insn_r->regcache,
> +                     bits (aarch64_insn_r->aarch64_insn, 16, 20), &reg_rm_val);
> +          if (bit (aarch64_insn_r->aarch64_insn, 12))
> +            offset = reg_rm_val << size_bits;
> +          else
> +            offset = reg_rm_val;
> +          datasize = 8 << size_bits;
> +          regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn,
> +                                      &address);
> +          address = address + offset;
> +          record_buf_mem[0] = datasize >> 3;
> +          record_buf_mem[1] = address;
> +          aarch64_insn_r->mem_rec_count = 1;
> +        }
> +      else
> +        {
> +          if (vector_flag)
> +            record_buf[0] = reg_rt + AARCH64_V0_REGNUM;
> +          else
> +            record_buf[0] = reg_rt;
> +          aarch64_insn_r->reg_rec_count = 1;
> +        }
> +    }
> +  /* Load/store register (immediate) instructions.  */

To be clear, Load/store register (unprivileged) instruction goes into
this path too.  Please update the comment to reflect this.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 3/5] Support for recording syscall on aarch64-linux
  2015-02-03  1:17 ` [PATCH v4 3/5] Support for recording syscall on aarch64-linux Omair Javaid
@ 2015-02-19 16:55   ` Yao Qi
  0 siblings, 0 replies; 12+ messages in thread
From: Yao Qi @ 2015-02-19 16:55 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

Omair Javaid <omair.javaid@linaro.org> writes:

> 	* aarch64-linux-tdep.c (linux-record): Include.

s/linux-record/linux-record.h/

> 	(record-full.h): Include.
> 	(struct linux_record_tdep aarch64_linux_record_tdep): Declare.
> 	(aarch64_canonicalize_syscall): New function to translate syscall
> 	numbers from aarch64 to canonical.

"New function" only should be fine.

> 	(aarch64_all_but_pc_registers_record): New function.
> 	(aarch64_linux_syscall_record): New function.
> 	(aarch64_linux_init_abi): Update to handle syscall recording.
> 	* aarch64-linux-tdep.h (aarch64_syscall): New enum.
> 	* aarch64-tdep.c (aarch64_record_branch_except_sys): Add code to
> 	handle recording of syscalls.
> 	* aarch64-tdep.h
> 	(struct gdbarch_tdep) <aarch64_syscall_record>: Defined.
> 	* linux-record.h (struct linux_record_tdep): Add two more syscall
> 	argument fields.

	* linux-record.h (struct linux_record_tdep) <arg7, arg8>: New fields.

> +/* aarch64_canonicalize_syscall maps syscall ids from the native AArch64
> +   linux set of syscall ids into a canonical set of syscall ids used by
> +   process record.  */
> +
> +static enum gdb_syscall
> +aarch64_canonicalize_syscall (enum aarch64_syscall syscall_number)
> +{
> +  switch (syscall_number) {
> +  case aarch64_sys_read:
> +    return gdb_sys_read;
> +

Can we add a macro which does such replacement,

   SYSCALL_MAP (read) -> case aarch64_sys_read: return gdb_sys_read;

so that this function should be shorter.

> +
> +  case aarch64_sys_mmap:
> +    return gdb_sys_mmap2;
> +
> +  default:
> +    return -1;
> +  }
> +}
> +
> +/* Record all registers but PC register for process-record.  */
> +
> +static int
> +aarch64_all_but_pc_registers_record (struct regcache *regcache)
> +{
> +  int i;
> +
> +  for (i = 0; i < AARCH64_PC_REGNUM; i++)
> +    if (record_full_arch_list_add_reg (regcache, AARCH64_X0_REGNUM + i))
> +      return -1;

Nit, better that "i" starts from AARCH64_X0_REGNUM, like,

  for (i = AARCH64_X0_REGNUM; i < AARCH64_PC_REGNUM; i++)
     if (record_full_arch_list_add_reg (regcache, i))
        return -1;
> +
> +  /* The AArch64 syscall calling convention: reg x0-x7 for arguments,
> +     reg x8 for syscall number and return value in reg x0.  */
> +  aarch64_linux_record_tdep.arg1 = AARCH64_X0_REGNUM + 0;
> +  aarch64_linux_record_tdep.arg2 = AARCH64_X0_REGNUM + 1;
> +  aarch64_linux_record_tdep.arg3 = AARCH64_X0_REGNUM + 2;
> +  aarch64_linux_record_tdep.arg4 = AARCH64_X0_REGNUM + 3;
> +  aarch64_linux_record_tdep.arg5 = AARCH64_X0_REGNUM + 4;
> +  aarch64_linux_record_tdep.arg6 = AARCH64_X0_REGNUM + 5;
> +  aarch64_linux_record_tdep.arg7 = AARCH64_X0_REGNUM + 6;
> +  aarch64_linux_record_tdep.arg8 = AARCH64_X0_REGNUM + 7;

x7 is not used for arguments in linux syscall.  At least, that is what I
am told from glibc source sysdeps/unix/sysv/linux/aarch64/sysdep.h:

/* Linux takes system call args in registers:
        syscall number  x8
        arg 1           x0
        arg 2           x1
        arg 3           x2
        arg 4           x3
        arg 5           x4
        arg 6           x5
        arg 7           x6

>  }
>  
>  /* Provide a prototype to silence -Wmissing-prototypes.  */
> diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
> index 9d09ae6..4475f2e 100644
> --- a/gdb/aarch64-linux-tdep.h
> +++ b/gdb/aarch64-linux-tdep.h
> @@ -32,3 +32,269 @@
>  
>  extern const struct regset aarch64_linux_gregset;
>  extern const struct regset aarch64_linux_fpregset;
> +
> +/* Enum that defines the AArch64 linux specific syscall identifiers used for
> +   process record/replay.  */
> +
> +enum aarch64_syscall {
....
> +};

Why don't define this enum in aarch64-linux-tdep.c?

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 4/5] Support for recording aarch64 advanced SIMD instructions
  2015-02-03  1:17 ` [PATCH v4 4/5] Support for recording aarch64 advanced SIMD instructions Omair Javaid
@ 2015-02-20  9:53   ` Yao Qi
  0 siblings, 0 replies; 12+ messages in thread
From: Yao Qi @ 2015-02-20  9:53 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

Omair Javaid <omair.javaid@linaro.org> writes:

Hi Omair,
you need some descriptions about your patch rather than just a changelog
here.

> gdb:
>
> 2015-02-02  Omair Javaid  <omair.javaid@linaro.org>
>
> 	* aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
> 	for data processing SIMD and floating point insns.

"New function" should be fine.

> 	(aarch64_record_asimd_load_store): Add handler to record ASIMD load
> 	store insns.

Likewise.

> 	(aarch64_record_load_store): Install record handler
> 	aarch64_record_asimd_load_store.
> 	(aarch64_record_decode_insn_handler): Install record handler
> 	aarch64_record_data_proc_simd_fp.
> ---
>  gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 226 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index faa650a..d2ec2c1 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -3047,6 +3047,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
>    return AARCH64_RECORD_SUCCESS;
>  }
>  
> +/* Record handler for advanced SIMD load and store instructions.  */

A blank line is needed here.

> +static unsigned int
> +aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
> +{
> +  CORE_ADDR address;
> +  uint64_t addr_offset = 0;
> +  uint32_t record_buf[24];
> +  uint64_t record_buf_mem[24];
> +  uint32_t reg_rn, reg_rt, reg_rm;
> +  uint32_t reg_index = 0, mem_index = 0;
> +  uint8_t eindex, rindex, sindex, reg_tt, replicate;
> +  uint8_t elements, esize, rpt, selem, single, scale;
> +  uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;

There are so many local variables defined.  Please define them in the
block in which they are used.

> +
> +  reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> +  reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
> +  reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
> +
> +  wback = bit (aarch64_insn_r->aarch64_insn, 23);
> +  single = bit (aarch64_insn_r->aarch64_insn, 24);
> +  ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
> +  size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
> +  opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
> +  regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
> +
> +  if (single)

Nit: since 'single' is only used once, better to use
'bit (aarch64_insn_r->aarch64_insn, 24)', however this is just my
personal preference.

> +    {

Add a comment here like /* Load/store single structure */

> +      scale = opcode_bits >> 2;

scale and replicate can be defined here.

> +      selem = ((opcode_bits & 0x02) |
> +              bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
> +      replicate = 0;
> +      switch (scale)
> +        {
> +        case 2:
> +          if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
> +            scale = 3;
> +          break;
> +        case 3:
> +          scale = size_bits;
> +          replicate = 1;
> +          break;
> +        default:
> +          break;
> +        }

Sorry, I don't understand this piece of code.  Could you elaborate?
This block is supposed to handle "Advanced SIMD load/store single
structure" and "Advanced SIMD load/store single structure
(post-indexed)", right?


> +      esize = 8 << scale;
> +      if (replicate)
> +        for (sindex = 0; sindex < selem; sindex++)
> +          {
> +            record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
> +            reg_rt = (reg_rt + 1) % 32;
> +          }
> +      else
> +        {
> +          for (sindex = 0; sindex < selem; sindex++)
> +            if (ld_flag)
> +              record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
> +            else
> +              {
> +                record_buf_mem[mem_index++] = esize / 8;
> +                record_buf_mem[mem_index++] = address + addr_offset;
> +              }
> +            addr_offset = addr_offset + (esize / 8);
> +            reg_rt = (reg_rt + 1) % 32;
> +        }
> +    }
> +  else
> +    {

local variables elements and rpt can be defined here, with comments.

> +      esize = 8 << size_bits;
> +      if (bit (aarch64_insn_r->aarch64_insn, 30))
> +        elements = 128 / esize;
> +      else
> +        elements = 64 / esize;
> +
> +      switch (opcode_bits)
> +        {
> +        case 0:

Is it "ST4 (multiple structures)" instruction?  If it is, add comments
for each case about what instructions it is to handle.

> +          rpt = 1;
> +          selem = 4;
> +          break;
> +        case 2:
> +          rpt = 4;
> +          selem = 1;
> +          break;
> +        case 4:
> +          rpt = 1;
> +          selem = 3;
> +          break;
> +        case 6:
> +          rpt = 3;
> +          selem = 1;
> +          break;
> +        case 7:
> +          rpt = 1;
> +          selem = 1;
> +          break;
> +        case 8:
> +          rpt = 1;
> +          selem = 2;
> +          break;
> +        case 10:
> +          rpt = 2;
> +          selem = 1;
> +          break;
> +        default:
> +          return AARCH64_RECORD_UNSUPPORTED;
> +          break;
> +        }
> +      for (rindex = 0; rindex < rpt; rindex++)
> +        for (eindex = 0; eindex < elements; eindex++)
> +          {
> +            reg_tt = (reg_rt + rindex) % 32;
> +            for (sindex = 0; sindex < selem; sindex++)
> +              {
> +                if (ld_flag)

The whole "else" branch is about "Advanced SIMD load/store multiple
structures" and "Advanced SIMD load/store multiple structures
(post-indexed)" instructions, IIUC.  How can ld_flag (bit 22) be true?
It is always zero as far as I can tell from the manual.

> +
> +/* Record handler for data processing SIMD and floating point instructions.  */
> +
> +static unsigned int
> +aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
> +{
> +  uint8_t insn_bit21, opcode, rmode, reg_rd;
> +  uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
> +  uint8_t insn_bits11_14;
> +  uint32_t record_buf[2];
> +
> +  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
> +  insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
> +  insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
> +  insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
> +  insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
> +  opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
> +  rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
> +  reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> +  insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
> +
> +  if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
> +    {
> +      /* Floating point - fixed point conversion instructions.  */
> +      if (!insn_bit21)

brace is needed here...

> +        if ((opcode >> 1) == 0x0 && rmode == 0x03)
> +          record_buf[0] = reg_rd;
> +        else
> +          record_buf[0] = reg_rd + AARCH64_V0_REGNUM;

... and here.

> +      /* Floating point - conditional compare instructions.  */
> +      else if (insn_bits10_11 == 0x01)
> +        record_buf[0] = AARCH64_CPSR_REGNUM;
> +      /* Floating point - data processing (2-source) and
> +         conditional select instructions.  */
> +      else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
> +        record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +      else if (insn_bits10_11 == 0x00)
> +        {
> +          /* Floating point - immediate instructions.  */
> +          if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
> +            record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +          /* Floating point - compare instructions.  */
> +          else if ((insn_bits12_15 & 0x03) == 0x02)
> +            record_buf[0] = AARCH64_CPSR_REGNUM;
> +          /* Floating point - integer conversions instructions.  */
> +          if (insn_bits12_15 == 0x00)
> +            {
> +              /* Convert float to integer instruction.  */
> +              if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
> +                record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> +              /* Convert integer to float instruction.  */
> +              else if ((opcode >> 1) == 0x01 && !rmode)
> +                record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +              /* Move float to integer instruction.  */
> +              else if ((opcode >> 1) == 0x03)
> +                {
> +                  if (!(opcode & 0x01))
> +                    record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> +                  else
> +                    record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +                }
> +            }
> +        }
> +    }
> +  else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)

s/0x0E/0x0e/

> +    {
> +      /* Advanced SIMD copy instructions.  */
> +      if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&

Move && to the next line.

> +          !bit (aarch64_insn_r->aarch64_insn, 15) &&
> +          bit (aarch64_insn_r->aarch64_insn, 10))

brace here

> +        if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
> +          record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> +        else
> +          record_buf[0] = reg_rd + AARCH64_V0_REGNUM;

and here.

> +      else
> +        record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +    }
> +  /* All remaining floating point or advanced SIMD instructions.  */
> +  else
> +    record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +
> +  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> +             record_buf);
> +  return AARCH64_RECORD_SUCCESS;
> +}
> +

Last but not least, we need test case for these Advanced SIMD
instructions, as compiler may not generate these instructions for
gdb.reverse/*.c files.  x86 has already had some tests, so aarch64
should have some too.  As a start, we don't need to cover all Advanced
SIMD instructions in one go.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 5/5] Enables gdb.reverse testsuite for aarch64*-linux targets
  2015-02-03  1:17 ` [PATCH v4 5/5] Enables gdb.reverse testsuite for aarch64*-linux targets Omair Javaid
@ 2015-02-20  9:57   ` Yao Qi
  0 siblings, 0 replies; 12+ messages in thread
From: Yao Qi @ 2015-02-20  9:57 UTC (permalink / raw)
  To: Omair Javaid; +Cc: gdb-patches

Omair Javaid <omair.javaid@linaro.org> writes:

> gdb/testsuite:
>
> 2015-02-02  Omair Javaid  <omair.javaid@linaro.org>
>
> 	* lib/gdb.exp (supports_process_record): Return true for aarch64*-linux*.
> 	(supports_reverse): Likewise.

This is good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-02-20  9:57 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-03  1:17 [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid
2015-02-03  1:17 ` [PATCH v4 4/5] Support for recording aarch64 advanced SIMD instructions Omair Javaid
2015-02-20  9:53   ` Yao Qi
2015-02-03  1:17 ` [PATCH v4 1/5] NEWS entry about aarch64-linux record/replay support Omair Javaid
2015-02-03  3:38   ` Eli Zaretskii
2015-02-03  1:17 ` [PATCH v4 3/5] Support for recording syscall on aarch64-linux Omair Javaid
2015-02-19 16:55   ` Yao Qi
2015-02-03  1:17 ` [PATCH v4 2/5] Implements aarch64 process record and reverse debugging support Omair Javaid
2015-02-19 12:35   ` Yao Qi
2015-02-03  1:17 ` [PATCH v4 5/5] Enables gdb.reverse testsuite for aarch64*-linux targets Omair Javaid
2015-02-20  9:57   ` Yao Qi
2015-02-03  1:32 ` [PATCH v4 0/5] Process record and reverse debugging support on aarch64-linux Omair Javaid

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).