[GDBserver] Multi-process + multi-arch
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-arm-low.c
index 8ddd90af3a9bbef21de1151c848baa2ef1ee1209..a6b745de0a253893416a5ada2afdfb7ceaa98414 100644 (file)
 
 /* Defined in auto-generated files.  */
 void init_registers_arm (void);
+extern const struct target_desc *tdesc_arm;
+
 void init_registers_arm_with_iwmmxt (void);
+extern const struct target_desc *tdesc_arm_with_iwmmxt;
+
 void init_registers_arm_with_vfpv2 (void);
+extern const struct target_desc *tdesc_arm_with_vfpv2;
+
 void init_registers_arm_with_vfpv3 (void);
+extern const struct target_desc *tdesc_arm_with_vfpv3;
+
 void init_registers_arm_with_neon (void);
+extern const struct target_desc *tdesc_arm_with_neon;
 
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 22
@@ -212,7 +221,7 @@ arm_fill_vfpregset (struct regcache *regcache, void *buf)
   else
     num = 16;
 
-  base = find_regno ("d0");
+  base = find_regno (regcache->tdesc, "d0");
   for (i = 0; i < num; i++)
     collect_register (regcache, base + i, (char *) buf + i * 8);
 
@@ -232,7 +241,7 @@ arm_store_vfpregset (struct regcache *regcache, const void *buf)
   else
     num = 16;
 
-  base = find_regno ("d0");
+  base = find_regno (regcache->tdesc, "d0");
   for (i = 0; i < num; i++)
     supply_register (regcache, base + i, (char *) buf + i * 8);
 
@@ -768,8 +777,8 @@ arm_get_hwcap (unsigned long *valp)
   return 0;
 }
 
-static void
-arm_arch_setup (void)
+static const struct target_desc *
+arm_read_description (void)
 {
   int pid = lwpid_of (get_thread_lwp (current_inferior));
 
@@ -778,29 +787,24 @@ arm_arch_setup (void)
 
   arm_hwcap = 0;
   if (arm_get_hwcap (&arm_hwcap) == 0)
-    {
-      init_registers_arm ();
-      return;
-    }
+    return tdesc_arm;
 
   if (arm_hwcap & HWCAP_IWMMXT)
-    {
-      init_registers_arm_with_iwmmxt ();
-      return;
-    }
+    return tdesc_arm_with_iwmmxt;
 
   if (arm_hwcap & HWCAP_VFP)
     {
+      const struct target_desc *result;
       char *buf;
 
       /* NEON implies either no VFP, or VFPv3-D32.  We only support
         it with VFP.  */
       if (arm_hwcap & HWCAP_NEON)
-       init_registers_arm_with_neon ();
+       result = tdesc_arm_with_neon;
       else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
-       init_registers_arm_with_vfpv3 ();
+       result = tdesc_arm_with_vfpv3;
       else
-       init_registers_arm_with_vfpv2 ();
+       result = tdesc_arm_with_vfpv2;
 
       /* Now make sure that the kernel supports reading these
         registers.  Support was added in 2.6.30.  */
@@ -810,19 +814,25 @@ arm_arch_setup (void)
          && errno == EIO)
        {
          arm_hwcap = 0;
-         init_registers_arm ();
+         result = tdesc_arm;
        }
       free (buf);
 
-      return;
+      return result;
     }
 
   /* The default configuration uses legacy FPA registers, probably
      simulated.  */
-  init_registers_arm ();
+  return tdesc_arm;
 }
 
-struct regset_info target_regsets[] = {
+static void
+arm_arch_setup (void)
+{
+  current_process ()->tdesc = arm_read_description ();
+}
+
+static struct regset_info arm_regsets[] = {
   { PTRACE_GETREGS, PTRACE_SETREGS, 0, 18 * 4,
     GENERAL_REGS,
     arm_fill_gregset, arm_store_gregset },
@@ -835,11 +845,35 @@ struct regset_info target_regsets[] = {
   { 0, 0, 0, -1, -1, NULL, NULL }
 };
 
+static struct regsets_info arm_regsets_info =
+  {
+    arm_regsets, /* regsets */
+    0, /* num_regsets */
+    NULL, /* disabled_regsets */
+  };
+
+static struct usrregs_info arm_usrregs_info =
+  {
+    arm_num_regs,
+    arm_regmap,
+  };
+
+static struct regs_info regs_info =
+  {
+    NULL, /* regset_bitmap */
+    &arm_usrregs_info,
+    &arm_regsets_info
+  };
+
+static const struct regs_info *
+arm_regs_info (void)
+{
+  return &regs_info;
+}
+
 struct linux_target_ops the_low_target = {
   arm_arch_setup,
-  arm_num_regs,
-  arm_regmap,
-  NULL,
+  arm_regs_info,
   arm_cannot_fetch_register,
   arm_cannot_store_register,
   NULL, /* fetch_register */
@@ -871,3 +905,16 @@ struct linux_target_ops the_low_target = {
   arm_new_thread,
   arm_prepare_to_resume,
 };
+
+void
+initialize_low_arch (void)
+{
+  /* Initialize the Linux target descriptions.  */
+  init_registers_arm ();
+  init_registers_arm_with_iwmmxt ();
+  init_registers_arm_with_vfpv2 ();
+  init_registers_arm_with_vfpv3 ();
+  init_registers_arm_with_neon ();
+
+  initialize_regsets_info (&arm_regsets_info);
+}
This page took 0.027437 seconds and 4 git commands to generate.