Imported Upstream version 7.9
[platform/upstream/gdb.git] / gdb / aarch64-linux-tdep.c
index 30ed73f..1e1ca36 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GNU/Linux AArch64.
 
-   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+   Copyright (C) 2009-2015 Free Software Foundation, Inc.
    Contributed by ARM Ltd.
 
    This file is part of GDB.
 #include "user-regs.h"
 #include <ctype.h>
 
-/* The general-purpose regset consists of 31 X registers, plus SP, PC,
-   and PSTATE registers, as defined in the AArch64 port of the Linux
-   kernel.  */
-#define AARCH64_LINUX_SIZEOF_GREGSET  (34 * X_REGISTER_SIZE)
-
-/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
-   are 4 bytes wide each, and the whole structure is padded to 128 bit
-   alignment.  */
-#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
-
 /* Signal frame handling.
 
       +------------+  ^
@@ -190,89 +180,51 @@ static const struct tramp_frame aarch64_linux_rt_sigframe =
   aarch64_linux_sigframe_init
 };
 
-/* Fill GDB's register array with the general-purpose register values
-   in the buffer pointed by GREGS_BUF.  */
-
-void
-aarch64_linux_supply_gregset (struct regcache *regcache,
-                             const gdb_byte *gregs_buf)
-{
-  int regno;
-
-  for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
-    regcache_raw_supply (regcache, regno,
-                        gregs_buf + X_REGISTER_SIZE
-                        * (regno - AARCH64_X0_REGNUM));
-}
-
-/* The "supply_regset" function for the general-purpose register set.  */
+/* Register maps.  */
 
-static void
-supply_gregset_from_core (const struct regset *regset,
-                         struct regcache *regcache,
-                         int regnum, const void *regbuf, size_t len)
-{
-  aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
-}
-
-/* Fill GDB's register array with the floating-point register values
-   in the buffer pointed by FPREGS_BUF.  */
-
-void
-aarch64_linux_supply_fpregset (struct regcache *regcache,
-                              const gdb_byte *fpregs_buf)
-{
-  int regno;
-
-  for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
-    regcache_raw_supply (regcache, regno,
-                        fpregs_buf + V_REGISTER_SIZE
-                        * (regno - AARCH64_V0_REGNUM));
-
-  regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
-                      fpregs_buf + V_REGISTER_SIZE * 32);
-  regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
-                      fpregs_buf + V_REGISTER_SIZE * 32 + 4);
-}
-
-/* The "supply_regset" function for the floating-point register set.  */
+static const struct regcache_map_entry aarch64_linux_gregmap[] =
+  {
+    { 31, AARCH64_X0_REGNUM, 8 }, /* x0 ... x30 */
+    { 1, AARCH64_SP_REGNUM, 8 },
+    { 1, AARCH64_PC_REGNUM, 8 },
+    { 1, AARCH64_CPSR_REGNUM, 8 },
+    { 0 }
+  };
 
-static void
-supply_fpregset_from_core (const struct regset *regset,
-                          struct regcache *regcache,
-                          int regnum, const void *regbuf, size_t len)
-{
-  aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
-}
+static const struct regcache_map_entry aarch64_linux_fpregmap[] =
+  {
+    { 32, AARCH64_V0_REGNUM, 16 }, /* v0 ... v31 */
+    { 1, AARCH64_FPSR_REGNUM, 4 },
+    { 1, AARCH64_FPCR_REGNUM, 4 },
+    { 0 }
+  };
 
-/* Register set definitions. */
+/* Register set definitions.  */
 
-static const struct regset aarch64_linux_gregset =
+const struct regset aarch64_linux_gregset =
   {
-    NULL, supply_gregset_from_core, NULL
+    aarch64_linux_gregmap,
+    regcache_supply_regset, regcache_collect_regset
   };
 
-static const struct regset aarch64_linux_fpregset =
+const struct regset aarch64_linux_fpregset =
   {
-    NULL, supply_fpregset_from_core, NULL
+    aarch64_linux_fpregmap,
+    regcache_supply_regset, regcache_collect_regset
   };
 
 /* Implement the "regset_from_core_section" gdbarch method.  */
 
-static const struct regset *
-aarch64_linux_regset_from_core_section (struct gdbarch *gdbarch,
-                                       const char *sect_name,
-                                       size_t sect_size)
+static void
+aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
+                                           iterate_over_regset_sections_cb *cb,
+                                           void *cb_data,
+                                           const struct regcache *regcache)
 {
-  if (strcmp (sect_name, ".reg") == 0
-      && sect_size == AARCH64_LINUX_SIZEOF_GREGSET)
-    return &aarch64_linux_gregset;
-
-  if (strcmp (sect_name, ".reg2") == 0
-      && sect_size == AARCH64_LINUX_SIZEOF_FPREGSET)
-    return &aarch64_linux_fpregset;
-
-  return NULL;
+  cb (".reg", AARCH64_LINUX_SIZEOF_GREGSET, &aarch64_linux_gregset,
+      NULL, cb_data);
+  cb (".reg2", AARCH64_LINUX_SIZEOF_FPREGSET, &aarch64_linux_fpregset,
+      NULL, cb_data);
 }
 
 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
@@ -420,8 +372,8 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Enable longjmp.  */
   tdep->jb_pc = 11;
 
-  set_gdbarch_regset_from_core_section (gdbarch,
-                                       aarch64_linux_regset_from_core_section);
+  set_gdbarch_iterate_over_regset_sections
+    (gdbarch, aarch64_linux_iterate_over_regset_sections);
 
   /* SystemTap related.  */
   set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);