[PATCH v3 13/13] IA64 Linux: Define regset structures.

Andreas Arnez <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <[email protected]>
gdb/
	* ia64-linux-tdep.c: Include "regset.h".
	(ia64_linux_gregmap, ia64_linux_fpregmap): New register maps.
	(IA64_LINUX_GREGS_SIZE, IA64_LINUX_FPREGS_SIZE): New macros.
	(ia64_linux_supply_fpregset): New function.
	(ia64_linux_gregset, ia64_linux_fpregset): New regsets.
	(ia64_linux_regset_from_core_section): New function.
	(ia64_linux_init_abi): Set regset_from_core_section gdbarch
	method.
---
 gdb/ia64-linux-tdep.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c
index 128924e..3bdf2a1 100644
--- a/gdb/ia64-linux-tdep.c
+++ b/gdb/ia64-linux-tdep.c
@@ -26,6 +26,7 @@
 #include "solib-svr4.h"
 #include "symtab.h"
 #include "linux-tdep.h"
+#include "regset.h"
 
 #include <ctype.h>
 
@@ -131,6 +132,91 @@ ia64_linux_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
 	  || isdigit (*s));  /* Literal number.  */
 }
 
+/* Core file support. */
+
+static const struct regcache_map_entry ia64_linux_gregmap[] =
+  {
+    { 32, IA64_GR0_REGNUM, 8 },	/* r0 ... r31 */
+    { 1, REGCACHE_MAP_SKIP, 8 }, /* FIXME: NAT collection bits? */
+    { 1, IA64_PR_REGNUM, 8 },
+    { 8, IA64_BR0_REGNUM, 8 },	/* b0 ... b7 */
+    { 1, IA64_IP_REGNUM, 8 },
+    { 1, IA64_CFM_REGNUM, 8 },
+    { 1, IA64_PSR_REGNUM, 8 },
+    { 1, IA64_RSC_REGNUM, 8 },
+    { 1, IA64_BSP_REGNUM, 8 },
+    { 1, IA64_BSPSTORE_REGNUM, 8 },
+    { 1, IA64_RNAT_REGNUM, 8 },
+    { 1, IA64_CCV_REGNUM, 8 },
+    { 1, IA64_UNAT_REGNUM, 8 },
+    { 1, IA64_FPSR_REGNUM, 8 },
+    { 1, IA64_PFS_REGNUM, 8 },
+    { 1, IA64_LC_REGNUM, 8 },
+    { 1, IA64_EC_REGNUM, 8 },
+    { 0 }
+  };
+
+/* Size of 'gregset_t', as defined by the Linux kernel.  Note that
+   this is more than actually mapped in the regmap above.  */
+
+#define IA64_LINUX_GREGS_SIZE (128 * 8)
+
+static const struct regcache_map_entry ia64_linux_fpregmap[] =
+  {
+    { 128, IA64_FR0_REGNUM, 16 }, /* f0 ... f127 */
+    { 0 }
+  };
+
+#define IA64_LINUX_FPREGS_SIZE (128 * 16)
+
+static void
+ia64_linux_supply_fpregset (const struct regset *regset,
+			    struct regcache *regcache,
+			    int regnum, const void *regs, size_t len)
+{
+  const gdb_byte f_zero[16] = { 0 };
+  const gdb_byte f_one[16] =
+    { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 };
+
+  regcache_supply_regset (regset, regcache, regnum, regs, len);
+
+  /* Kernel generated cores have fr1==0 instead of 1.0.  Older GDBs
+     did the same.  So ignore whatever might be recorded in fpregset_t
+     for fr0/fr1 and always supply their expected values.  */
+  if (regnum == -1 || regnum == IA64_FR0_REGNUM)
+    regcache_raw_supply (regcache, IA64_FR0_REGNUM, f_zero);
+  if (regnum == -1 || regnum == IA64_FR1_REGNUM)
+    regcache_raw_supply (regcache, IA64_FR1_REGNUM, f_one);
+}
+
+static const struct regset ia64_linux_gregset =
+  {
+    ia64_linux_gregmap,
+    regcache_supply_regset, regcache_collect_regset
+  };
+
+static const struct regset ia64_linux_fpregset =
+  {
+    ia64_linux_fpregmap,
+    ia64_linux_supply_fpregset, regcache_collect_regset
+  };
+
+static const struct regset *
+ia64_linux_regset_from_core_section (struct gdbarch *gdbarch,
+				     const char *sect_name,
+				     size_t sect_size)
+{
+  if (strcmp (sect_name, ".reg") == 0
+      && sect_size >= IA64_LINUX_GREGS_SIZE)
+    return &ia64_linux_gregset;
+
+  if (strcmp (sect_name, ".reg2") == 0
+      && sect_size >= IA64_LINUX_FPREGS_SIZE)
+    return &ia64_linux_fpregset;
+
+  return NULL;
+}
+
 static void
 ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -161,6 +247,10 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                              svr4_fetch_objfile_link_map);
 
+  /* Core file support. */
+  set_gdbarch_regset_from_core_section (gdbarch,
+					ia64_linux_regset_from_core_section);
+
   /* SystemTap related.  */
   set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
   set_gdbarch_stap_register_indirection_prefixes (gdbarch,
-- 
1.8.4.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.