]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Dynamically create tdesc in GDBserver
authorYao Qi <yao.qi@linaro.org>
Tue, 6 Jun 2017 22:05:32 +0000 (23:05 +0100)
committerYao Qi <yao.qi@linaro.org>
Tue, 20 Jun 2017 10:34:13 +0000 (11:34 +0100)
In this patch, GDBserver starts to use gdb/features/*.c feature files
by including them, so that GDBserver can create target descriptions
from features dynamically, like GDB does.  Adjust these feature .c
files for GDBserver.

These feature .c files calls some target description APIs only defined
GDB, so this patch also adds them in GDBserver.

TODO: complete ChangeLog.

gdb:

2017-06-06  Yao Qi  <yao.qi@linaro.org>

* features/i386/32bit-avx.c: Re-generated.
* features/i386/32bit-avx512.c: Re-generated.
* features/i386/32bit-core.c: Re-generated.
* features/i386/32bit-linux.c: Re-generated.
* features/i386/32bit-mpx.c: Re-generated.
* features/i386/32bit-pkeys.c: Re-generated.
* features/i386/32bit-sse.c: Re-generated.

gdb/gdbserver:

2017-06-06  Yao Qi  <yao.qi@linaro.org>

* linux-x86-tdesc.c: Include ../features/i386/32bit-*.c.
(initialize_low_tdesc): Don't use tdesc_i386_XXX_linux.
(i386_get_ipa_tdesc): Create target descriptions.
* tdesc.c (init_target_desc):
(current_target_desc):
(tdesc_create_feature): +
(tdesc_create_flags): +
(tdesc_add_flag): +
(tdesc_named_type): +
(tdesc_create_reg): +
(tdesc_create_vector): +
(tdesc_add_bitfield): +
(tdesc_add_field): +
(tdesc_set_struct_size): +
* tdesc.h (target_desc::target_desc): New.
(target_desc::~target_desc): New.
* regformats/regdat.sh: Generate code to call
tdesc_create_reg.
* target-descriptions.c (print_c_feature::visit): Print
code for GDB.

12 files changed:
gdb/features/i386/32bit-avx.c
gdb/features/i386/32bit-avx512.c
gdb/features/i386/32bit-core.c
gdb/features/i386/32bit-linux.c
gdb/features/i386/32bit-mpx.c
gdb/features/i386/32bit-pkeys.c
gdb/features/i386/32bit-sse.c
gdb/gdbserver/linux-x86-tdesc.c
gdb/gdbserver/tdesc.c
gdb/gdbserver/tdesc.h
gdb/regformats/regdat.sh
gdb/target-descriptions.c

index 53a939b50b835a1b42fe4e47026ead2311975188..bae025dbd83558f17068e2d4ff7d92ab31d2da94 100644 (file)
@@ -1,9 +1,13 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-avx.xml.tmp */
 
+#ifdef GDBSERVER
+#include "tdesc.h"
+#else
 #include "defs.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#endif
 
 static int
 create_feature_i386_32bit_avx (struct target_desc *result, long regnum)
index 9bbf3925a8297f3ca74c1a1d14c51bdf565aa904..ca15f8b43cf218901beabe21d641a4bdca54609e 100644 (file)
@@ -1,9 +1,13 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-avx512.xml.tmp */
 
+#ifdef GDBSERVER
+#include "tdesc.h"
+#else
 #include "defs.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#endif
 
 static int
 create_feature_i386_32bit_avx512 (struct target_desc *result, long regnum)
index c5f0fca6ffa94b44dc4909e4a5f256c6a98b4f94..8db91ab8f548a9f9878df935f3f5edf56e4ebc8d 100644 (file)
@@ -1,9 +1,13 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-core.xml.tmp */
 
+#ifdef GDBSERVER
+#include "tdesc.h"
+#else
 #include "defs.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#endif
 
 static int
 create_feature_i386_32bit_core (struct target_desc *result, long regnum)
index ff90d40605a88617b453dcf7a5971954d19366b0..7535c55182cb1b58ccd420285caa221f542be0e5 100644 (file)
@@ -1,9 +1,13 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-linux.xml.tmp */
 
+#ifdef GDBSERVER
+#include "tdesc.h"
+#else
 #include "defs.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#endif
 
 static int
 create_feature_i386_32bit_linux (struct target_desc *result, long regnum)
index 50b627e93d7cc074a2cad48129e73560287a162d..9f1ae673a8a1890d8182f8aff609dd48df2aada4 100644 (file)
@@ -1,9 +1,13 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-mpx.xml.tmp */
 
+#ifdef GDBSERVER
+#include "tdesc.h"
+#else
 #include "defs.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#endif
 
 static int
 create_feature_i386_32bit_mpx (struct target_desc *result, long regnum)
index afb4958749ad74e4541f876ea70f5ad4cfc79cc2..86035abe1878668b77a6bb750551b6e7f67c5aa1 100644 (file)
@@ -1,9 +1,13 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-pkeys.xml.tmp */
 
+#ifdef GDBSERVER
+#include "tdesc.h"
+#else
 #include "defs.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#endif
 
 static int
 create_feature_i386_32bit_pkeys (struct target_desc *result, long regnum)
index 08c3948beb15d5a4bf6650213009b6d889684751..876c04df4bd2151470a6ae81a429120c74d5905b 100644 (file)
@@ -1,9 +1,13 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-sse.xml.tmp */
 
+#ifdef GDBSERVER
+#include "tdesc.h"
+#else
 #include "defs.h"
 #include "osabi.h"
 #include "target-descriptions.h"
+#endif
 
 static int
 create_feature_i386_32bit_sse (struct target_desc *result, long regnum)
index e294a987cab3cb726153d56a0b6a343edf98ddd0..f247a3cd5d07cf78b072ba1405e025739583cc28 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "server.h"
+#include "tdesc.h"
 #include "linux-x86-tdesc.h"
 
+#include "../features/i386/32bit-core.c"
+#include "../features/i386/32bit-linux.c"
+#include "../features/i386/32bit-sse.c"
+#include "../features/i386/32bit-avx.c"
+#include "../features/i386/32bit-avx512.c"
+#include "../features/i386/32bit-mpx.c"
+#include "../features/i386/32bit-pkeys.c"
+
 #if defined __i386__ || !defined IN_PROCESS_AGENT
 /* Defined in auto-generated file i386-linux.c.  */
 void init_registers_i386_linux (void);
@@ -63,15 +72,6 @@ initialize_low_tdesc ()
   init_registers_i386_avx_mpx_linux ();
   init_registers_i386_avx_avx512_linux ();
   init_registers_i386_avx_mpx_avx512_pku_linux ();
-
-  i386_tdescs[X86_TDESC_MMX] = tdesc_i386_mmx_linux;
-  i386_tdescs[X86_TDESC_SSE] = tdesc_i386_linux;
-  i386_tdescs[X86_TDESC_AVX] = tdesc_i386_avx_linux;
-  i386_tdescs[X86_TDESC_MPX] = tdesc_i386_mpx_linux;
-  i386_tdescs[X86_TDESC_AVX_MPX] = tdesc_i386_avx_mpx_linux;
-  i386_tdescs[X86_TDESC_AVX_AVX512] = tdesc_i386_avx_avx512_linux;
-  i386_tdescs[X86_TDESC_AVX_MPX_AVX512_PKU]
-    = tdesc_i386_avx_mpx_avx512_pku_linux;
 #endif
 }
 
@@ -82,7 +82,73 @@ i386_get_ipa_tdesc (int idx)
     internal_error (__FILE__, __LINE__,
                    "unknown ipa tdesc index: %d", idx);
 
-  return i386_tdescs[idx];
+  struct target_desc **tdesc = (struct target_desc **) &i386_tdescs[idx];
+
+  if (*tdesc == NULL)
+    {
+      *tdesc = new target_desc ();
+      long regnum = 0;
+
+      regnum = create_feature_i386_32bit_core (*tdesc, regnum);
+
+      if (idx != X86_TDESC_MMX)
+       regnum = create_feature_i386_32bit_sse (*tdesc, regnum);
+
+      regnum = create_feature_i386_32bit_linux (*tdesc, regnum);
+
+      if (idx == X86_TDESC_AVX || idx == X86_TDESC_AVX_MPX
+         || idx == X86_TDESC_AVX_AVX512
+         || idx == X86_TDESC_AVX_MPX_AVX512_PKU)
+       regnum = create_feature_i386_32bit_avx (*tdesc, regnum);
+
+      if (idx == X86_TDESC_MPX || idx == X86_TDESC_AVX_MPX
+         || idx == X86_TDESC_AVX_MPX_AVX512_PKU)
+       regnum = create_feature_i386_32bit_mpx (*tdesc, regnum);
+
+      if (idx == X86_TDESC_AVX_AVX512
+         || idx == X86_TDESC_AVX_MPX_AVX512_PKU)
+       regnum = create_feature_i386_32bit_avx512 (*tdesc, regnum);
+
+      if (idx == X86_TDESC_AVX_MPX_AVX512_PKU)
+       regnum = create_feature_i386_32bit_pkeys (*tdesc, regnum);
+
+      init_target_desc (*tdesc);
+
+#ifndef IN_PROCESS_AGENT
+      static const char *expedite_regs_i386[] = { "ebp", "esp", "eip", NULL };
+      (*tdesc)->expedite_regs = expedite_regs_i386;
+
+      switch (idx)
+       {
+       case X86_TDESC_MMX:
+         (*tdesc)->xmltarget = "i386-mmx-linux.xml";
+         break;
+       case X86_TDESC_SSE:
+         (*tdesc)->xmltarget = "i386-linux.xml";
+         break;
+       case X86_TDESC_AVX:
+         (*tdesc)->xmltarget = "i386-avx-linux.xml";
+         break;
+       case X86_TDESC_MPX:
+         (*tdesc)->xmltarget = "i386-mpx-linux.xml";
+         break;
+       case X86_TDESC_AVX_MPX:
+         (*tdesc)->xmltarget = "i386-avx-mpx-linux.xml";
+         break;
+       case X86_TDESC_AVX_AVX512:
+         (*tdesc)->xmltarget = "i386-avx-avx512-linux.xml";
+         break;
+       case X86_TDESC_AVX_MPX_AVX512_PKU:
+         (*tdesc)->xmltarget = "i386-avx-mpx-avx512-pku-linux.xml";
+         break;
+       default:
+         internal_error (__FILE__, __LINE__,
+                         "unknown ipa tdesc index: %d", idx);
+       }
+
+#endif
+    }
+  return *tdesc;;
 }
 
 #ifdef IN_PROCESS_AGENT
index 1b1882e865fe91aa067c2d7fbe86f0ed130cce18..686c76a46963d1c1f73132ed57458efc3dd03a1d 100644 (file)
@@ -41,7 +41,7 @@ init_target_desc (struct target_desc *tdesc)
 
 #ifndef IN_PROCESS_AGENT
 
-static const struct target_desc default_description = { NULL, 0, NULL, NULL };
+static const struct target_desc default_description {};
 
 void
 copy_target_description (struct target_desc *dest,
@@ -61,5 +61,79 @@ current_target_desc (void)
 
   return current_process ()->tdesc;
 }
-
 #endif
+
+struct tdesc_type
+{};
+
+struct tdesc_feature *
+tdesc_create_feature (struct target_desc *tdesc, const char *name)
+{
+  return tdesc;
+}
+
+struct tdesc_type *
+tdesc_create_flags (struct tdesc_feature *feature, const char *name,
+                   int size)
+{
+  return NULL;
+}
+
+void
+tdesc_add_flag (struct tdesc_type *type, int start,
+               const char *flag_name)
+{}
+
+struct tdesc_type *
+tdesc_named_type (const struct tdesc_feature *feature, const char *id)
+{
+  return NULL;
+}
+
+void
+tdesc_create_reg (struct tdesc_feature *feature, const char *name,
+                 int regnum, int save_restore, const char *group,
+                 int bitsize, const char *type)
+{
+  struct target_desc *tdesc = (struct target_desc *) feature;
+
+  while (VEC_length (tdesc_reg_p, tdesc->reg_defs) < regnum)
+    {
+      struct reg *reg = XCNEW (struct reg);
+
+      reg->name = "";
+      reg->size = 0;
+      VEC_safe_push (tdesc_reg_p, tdesc->reg_defs, reg);
+    }
+
+  gdb_assert (regnum == 0
+             || regnum == VEC_length (tdesc_reg_p, tdesc->reg_defs));
+
+  struct reg *reg = XCNEW (struct reg);
+
+  reg->name = name;
+  reg->size = bitsize;
+  VEC_safe_push (tdesc_reg_p, tdesc->reg_defs, reg);
+}
+
+struct tdesc_type *
+tdesc_create_vector (struct tdesc_feature *feature, const char *name,
+                    struct tdesc_type *field_type, int count)
+{
+  return NULL;
+}
+
+void
+tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
+                   int start, int end)
+{}
+
+void
+tdesc_add_field (struct tdesc_type *type, const char *field_name,
+                struct tdesc_type *field_type)
+{}
+
+void
+tdesc_set_struct_size (struct tdesc_type *type, int size)
+{
+}
index 424a2fd626bc08903d7cc56669690853440a497e..2d4cbfaa04d0630d104ccaf525deb2d880642106 100644 (file)
@@ -38,13 +38,28 @@ struct target_desc
 #ifndef IN_PROCESS_AGENT
   /* An array of register names.  These are the "expedite" registers:
      registers whose values are sent along with stop replies.  */
-  const char **expedite_regs;
+  const char **expedite_regs = NULL;
 
   /* Defines what to return when looking for the "target.xml" file in
      response to qXfer:features:read.  Its contents can either be
      verbatim XML code (prefixed with a '@') or else the name of the
      actual XML file to be used in place of "target.xml".  */
-  const char *xmltarget;
+  const char *xmltarget = NULL;
+
+public:
+  target_desc ()
+    : reg_defs (NULL), registers_size (0)
+  {}
+
+  ~target_desc ()
+  {
+    int i;
+    struct reg *reg;
+
+    for (i = 0; VEC_iterate (tdesc_reg_p, reg_defs, i, reg); i++)
+      xfree (reg);
+    VEC_free (tdesc_reg_p, reg_defs);
+  }
 #endif
 };
 
@@ -62,4 +77,43 @@ void init_target_desc (struct target_desc *tdesc);
 
 const struct target_desc *current_target_desc (void);
 
+#ifndef IN_PROCESS_AGENT
+#endif
+
+#define tdesc_feature target_desc
+
+struct tdesc_type;
+
+struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
+                                           const char *name);
+
+struct tdesc_type *tdesc_create_flags (struct tdesc_feature *feature,
+                                      const char *name, int size);
+
+void tdesc_add_flag (struct tdesc_type *type, int start,
+                    const char *flag_name);
+
+struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
+                                    const char *id);
+
+#define tdesc_create_union tdesc_named_type
+#define tdesc_create_struct tdesc_named_type
+
+void tdesc_add_field (struct tdesc_type *type, const char *field_name,
+                     struct tdesc_type *field_type);
+
+void tdesc_set_struct_size (struct tdesc_type *type, int size);
+
+void tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
+                        int start, int end);
+
+void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
+                      int regnum, int save_restore, const char *group,
+                      int bitsize, const char *type);
+
+struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature,
+                                       const char *name,
+                                       struct tdesc_type *field_type,
+                                       int count);
+
 #endif /* TDESC_H */
index 236cd9347bed63a8376bbbbf5ab1de2b21481858..66449cc60e2c3eb9a588bdf8c36ad5611632b6f4 100755 (executable)
@@ -131,7 +131,6 @@ do
     echo "{"
     echo "  static struct target_desc tdesc_${name}_s;"
     echo "  struct target_desc *result = &tdesc_${name}_s;"
-    echo "  memset (result, 0, sizeof (*result));"
 
     continue
   elif test "${type}" = "xmltarget"; then
@@ -150,12 +149,9 @@ do
     echo "$0: $1 does not specify \`\`name''." 1>&2
     exit 1
   else
-    echo "  {struct reg *reg = XCNEW (struct reg);"
-    echo "  reg->name = \"${entry}\";"
-    echo "  reg->offset = ${offset};"
-    echo "  reg->size = ${type};"
-    echo "  VEC_safe_push (tdesc_reg_p, result->reg_defs, reg);"
-    echo "  };"
+    echo "  tdesc_create_reg ((struct tdesc_feature *) result, \"${entry}\","
+    echo "  0, 0, NULL, ${type}, NULL);"
+
     offset=`expr ${offset} + ${type}`
     i=`expr $i + 1`
   fi
index 0b953795c0934ee66c8c9ee0226bdd0f05d8fed3..1795518c88bb81d261f8b9873b1678da61f34a35 100644 (file)
@@ -2163,9 +2163,13 @@ public:
 
   void visit (const target_desc *e) override
   {
+    printf_unfiltered ("#ifdef GDBSERVER\n");
+    printf_unfiltered ("#include \"tdesc.h\"\n");
+    printf_unfiltered ("#else\n");
     printf_unfiltered ("#include \"defs.h\"\n");
     printf_unfiltered ("#include \"osabi.h\"\n");
     printf_unfiltered ("#include \"target-descriptions.h\"\n");
+    printf_unfiltered ("#endif\n");
     printf_unfiltered ("\n");
   }