[GDBserver] Centralize tdesc for i386-linux
authorYao Qi <yao.qi@linaro.org>
Tue, 5 Sep 2017 08:54:53 +0000 (09:54 +0100)
committerYao Qi <yao.qi@linaro.org>
Tue, 5 Sep 2017 08:54:53 +0000 (09:54 +0100)
tdesc_i386_XXX_linux is used in many places in linux-x86-low.c and this
patch adds a new function i386_linux_read_description to return the right
tdesc according to xcr0.  i386_linux_read_description is quite similar to
the counterpart in GDB, and the following patch will share the duplicated
code, so this patch adds arch/tdesc.h includes the declarations of various
tdesc apis which are used by the shared code.  The generated c feature
files can include arch/tdesc.h only.

gdb/gdbserver:

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

* configure.srv (srv_tgtobj): Append linux-x86-tdesc.o.
(ipa_obj): Likewise.
* linux-i386-ipa.c: Include common/x86-xstate.h
(get_ipa_tdesc): Call i386_linux_read_description.
(initialize_low_tracepoint): Don't call  init_registers_XXX
functions, call initialize_low_tdesc instead.
* linux-x86-low.c (x86_linux_read_description): Call
i386_linux_read_description.
(initialize_low_arch): Don't call init_registers_i386_XXX
functions, call initialize_low_tdesc.
* linux-x86-tdesc.c: New file.
* linux-x86-tdesc.h (x86_linux_tdesc): New X86_TDESC_LAST.
(i386_get_ipa_tdesc_idx): Declare.
(i386_get_ipa_tdesc): Declare.
(initialize_low_tdesc): Declare.

gdb:

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

* arch/tdesc.h: New file.
* regformats/regdat.sh: Generate code using tdesc_create_reg.
* target-descriptions.c: Update comments.
* target-descriptions.h: Include "arch/tdesc.h".  Remove the
declarations.
* 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.

21 files changed:
gdb/ChangeLog
gdb/arch/tdesc.h [new file with mode: 0644]
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/ChangeLog
gdb/gdbserver/configure.srv
gdb/gdbserver/linux-i386-ipa.c
gdb/gdbserver/linux-x86-low.c
gdb/gdbserver/linux-x86-tdesc.c [new file with mode: 0644]
gdb/gdbserver/linux-x86-tdesc.h
gdb/gdbserver/tdesc.c
gdb/gdbserver/tdesc.h
gdb/i386-linux-tdep.c
gdb/regformats/regdat.sh
gdb/target-descriptions.c
gdb/target-descriptions.h

index 729a74f04a381bf139ba4a444db8ae92551e6faf..cebd4f563e3d5d7af0a8ec9af48cc57cbb25c164 100644 (file)
@@ -1,3 +1,18 @@
+2017-09-05  Yao Qi  <yao.qi@linaro.org>
+
+       * arch/tdesc.h: New file.
+       * regformats/regdat.sh: Generate code using tdesc_create_reg.
+       * target-descriptions.c: Update comments.
+       * target-descriptions.h: Include "arch/tdesc.h".  Remove the
+       declarations.
+       * 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.
+
 2017-09-05  Yao Qi  <yao.qi@linaro.org>
 
        * regformats/regdat.sh: Update generated code.
diff --git a/gdb/arch/tdesc.h b/gdb/arch/tdesc.h
new file mode 100644 (file)
index 0000000..872df68
--- /dev/null
@@ -0,0 +1,80 @@
+/* Copyright (C) 2006-2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef ARCH_TDESC_H
+#define ARCH_TDESC_H 1
+
+struct tdesc_feature;
+struct tdesc_type;
+struct tdesc_reg;
+struct target_desc;
+
+/* Return the type associated with ID in the context of FEATURE, or
+   NULL if none.  */
+struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
+                                    const char *id);
+
+/* Return the created feature named NAME in target description TDESC.  */
+struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
+                                           const char *name);
+
+/* Return the created vector tdesc_type named NAME in FEATURE.  */
+struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature,
+                                       const char *name,
+                                       struct tdesc_type *field_type,
+                                       int count);
+
+/* Return the created struct tdesc_type named NAME in FEATURE.  */
+struct tdesc_type *tdesc_create_struct (struct tdesc_feature *feature,
+                                       const char *name);
+
+/* Return the created union tdesc_type named NAME in FEATURE.  */
+struct tdesc_type *tdesc_create_union (struct tdesc_feature *feature,
+                                      const char *name);
+
+/* Return the created flags tdesc_type named NAME in FEATURE.  */
+struct tdesc_type *tdesc_create_flags (struct tdesc_feature *feature,
+                                      const char *name,
+                                      int size);
+
+/* Add a new field to TYPE.  FIELD_NAME is its name, and FIELD_TYPE is
+   its type.  */
+void tdesc_add_field (struct tdesc_type *type, const char *field_name,
+                     struct tdesc_type *field_type);
+
+/* Set the total length of TYPE.  Structs which contain bitfields may
+   omit the reserved bits, so the end of the last field may not
+   suffice.  */
+void tdesc_set_struct_size (struct tdesc_type *type, int size);
+
+/* Add a new untyped bitfield to TYPE.
+   Untyped bitfields become either uint32 or uint64 depending on the size
+   of the underlying type.  */
+void tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
+                        int start, int end);
+
+/* A flag is just a typed(bool) single-bit bitfield.
+   This function is kept to minimize changes in generated files.  */
+void tdesc_add_flag (struct tdesc_type *type, int start,
+                    const char *flag_name);
+
+/* Create a register in feature FEATURE.  */
+void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
+                      int regnum, int save_restore, const char *group,
+                      int bitsize, const char *type);
+
+#endif /* ARCH_TDESC_H */
index 0e7151586584791dadc248bb5492d9a56356b8b7..3a98936a0c7a9715cb2d83feacde0cc6f675d8ac 100644 (file)
@@ -1,7 +1,7 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-avx.xml */
 
-#include "target-descriptions.h"
+#include "arch/tdesc.h"
 
 static int
 create_feature_i386_32bit_avx (struct target_desc *result, long regnum)
index 034f557094dbf1f16552d3e77062f7a3c47c0ab5..b13e1d330810aa46736a39780635a3a5afa45bac 100644 (file)
@@ -1,7 +1,7 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-avx512.xml */
 
-#include "target-descriptions.h"
+#include "arch/tdesc.h"
 
 static int
 create_feature_i386_32bit_avx512 (struct target_desc *result, long regnum)
index b43de4da82fb3f8238d1d7acfb3e5ffc1bb433ba..ea6db935c0611e97838ce729e65cb382eb29a776 100644 (file)
@@ -1,7 +1,7 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-core.xml */
 
-#include "target-descriptions.h"
+#include "arch/tdesc.h"
 
 static int
 create_feature_i386_32bit_core (struct target_desc *result, long regnum)
index 1b50882c6c8bda6f8f0a4a92e805665b42884112..1ba932d795af393ebfa2860b29acdd069177ca19 100644 (file)
@@ -1,7 +1,7 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-linux.xml */
 
-#include "target-descriptions.h"
+#include "arch/tdesc.h"
 
 static int
 create_feature_i386_32bit_linux (struct target_desc *result, long regnum)
index 6ed3b2ea202d85dc10f08f4c2ceae3bb397e5db4..f7d2ef052c5aa16c8c717b167ee10b1457294b10 100644 (file)
@@ -1,7 +1,7 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-mpx.xml */
 
-#include "target-descriptions.h"
+#include "arch/tdesc.h"
 
 static int
 create_feature_i386_32bit_mpx (struct target_desc *result, long regnum)
index 24a40aa381e369f3d005219e7002109c74a577d2..89f1a5b3e0612ac5ad17cac7d78cd626d5ea9f3d 100644 (file)
@@ -1,7 +1,7 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-pkeys.xml */
 
-#include "target-descriptions.h"
+#include "arch/tdesc.h"
 
 static int
 create_feature_i386_32bit_pkeys (struct target_desc *result, long regnum)
index c0684fbdccee4c7d3d1bc8d0a5a637f448d67485..98f4cd061c0f01e32f4745fd6a4688782f429afd 100644 (file)
@@ -1,7 +1,7 @@
 /* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
   Original: 32bit-sse.xml */
 
-#include "target-descriptions.h"
+#include "arch/tdesc.h"
 
 static int
 create_feature_i386_32bit_sse (struct target_desc *result, long regnum)
index b6febf24eb56105b0db263fe099cf742bef0bc57..66e9f5379b80acfcd18fc74e47596e5ac5b2eda4 100644 (file)
@@ -1,3 +1,21 @@
+2017-09-05  Yao Qi  <yao.qi@linaro.org>
+
+       * configure.srv (srv_tgtobj): Append linux-x86-tdesc.o.
+       (ipa_obj): Likewise.
+       * linux-i386-ipa.c: Include common/x86-xstate.h
+       (get_ipa_tdesc): Call i386_linux_read_description.
+       (initialize_low_tracepoint): Don't call  init_registers_XXX
+       functions, call initialize_low_tdesc instead.
+       * linux-x86-low.c (x86_linux_read_description): Call
+       i386_linux_read_description.
+       (initialize_low_arch): Don't call init_registers_i386_XXX
+       functions, call initialize_low_tdesc.
+       * linux-x86-tdesc.c: New file.
+       * linux-x86-tdesc.h (x86_linux_tdesc): New X86_TDESC_LAST.
+       (i386_get_ipa_tdesc_idx): Declare.
+       (i386_get_ipa_tdesc): Declare.
+       (initialize_low_tdesc): Declare.
+
 2017-09-05  Yao Qi  <yao.qi@linaro.org>
 
        * linux-x86-low.c (x86_get_ipa_tdesc_idx): Use X86_TDESC_MMX
index 789a16b867bf98577da6c40a739fddd05b10ce19..1a270120be044cf78280cd2fffa8ab7b104072ab 100644 (file)
@@ -123,13 +123,14 @@ case "${target}" in
                            srv_tgtobj="amd64-linux-siginfo.o"
                        fi
                        srv_tgtobj="${srv_tgtobj} $srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
+                       srv_tgtobj="${srv_tgtobj} linux-x86-tdesc.o"
                        srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
                        srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
                        srv_linux_usrregs=yes
                        srv_linux_regsets=yes
                        srv_linux_thread_db=yes
                        srv_linux_btrace=yes
-                       ipa_obj="${ipa_i386_linux_regobj} linux-i386-ipa.o"
+                       ipa_obj="${ipa_i386_linux_regobj} linux-i386-ipa.o linux-x86-tdesc-ipa.o"
                        ;;
   i[34567]86-*-lynxos*)        srv_regobj="i386.o"
                        srv_tgtobj="lynx-low.o lynx-i386-low.o fork-child.o fork-inferior.o"
@@ -357,6 +358,7 @@ case "${target}" in
                        ;;
   x86_64-*-linux*)     srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
                        srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
+                       srv_tgtobj="${srv_tgtobj} linux-x86-tdesc.o"
                        srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
                        srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
                        srv_tgtobj="${srv_tgtobj} amd64-linux-siginfo.o"
@@ -370,7 +372,7 @@ case "${target}" in
                        else
                            ipa_obj="${ipa_amd64_linux_regobj}"
                        fi
-                       ipa_obj="${ipa_obj} linux-amd64-ipa.o"
+                       ipa_obj="${ipa_obj} linux-amd64-ipa.o linux-x86-tdesc-ipa.o"
                        ;;
   x86_64-*-mingw*)     srv_regobj="$srv_amd64_regobj"
                        srv_tgtobj="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
index e9ac78b06a5e11c5c0ae2739502f21fb55429a3d..54608da15da9a8ce49b7ebffab623e92ca6a4cfc 100644 (file)
@@ -22,6 +22,7 @@
 #include <sys/mman.h>
 #include "tracepoint.h"
 #include "linux-x86-tdesc.h"
+#include "common/x86-xstate.h"
 
 /* GDB register numbers.  */
 
@@ -250,27 +251,24 @@ initialize_fast_tracepoint_trampoline_buffer (void)
 const struct target_desc *
 get_ipa_tdesc (int idx)
 {
-  switch (idx)
+  if (idx >= X86_TDESC_LAST)
     {
-    case X86_TDESC_MMX:
-      return tdesc_i386_mmx_linux;
-    case X86_TDESC_SSE:
-      return tdesc_i386_linux;
-    case X86_TDESC_AVX:
-      return tdesc_i386_avx_linux;
-    case X86_TDESC_MPX:
-      return tdesc_i386_mpx_linux;
-    case X86_TDESC_AVX_MPX:
-      return tdesc_i386_avx_mpx_linux;
-    case X86_TDESC_AVX_AVX512:
-      return tdesc_i386_avx_avx512_linux;
-    case X86_TDESC_AVX_MPX_AVX512_PKU:
-      return tdesc_i386_avx_mpx_avx512_pku_linux;
-    default:
       internal_error (__FILE__, __LINE__,
                      "unknown ipa tdesc index: %d", idx);
-      return tdesc_i386_linux;
     }
+
+  /* Map the tdesc index to xcr0 mask.  */
+  uint64_t idx2mask[X86_TDESC_LAST] = {
+    X86_XSTATE_X87_MASK,
+    X86_XSTATE_SSE_MASK,
+    X86_XSTATE_AVX_MASK,
+    X86_XSTATE_MPX_MASK,
+    X86_XSTATE_AVX_MPX_MASK,
+    X86_XSTATE_AVX_AVX512_MASK,
+    X86_XSTATE_AVX_MPX_AVX512_PKU_MASK,
+  };
+
+  return i386_linux_read_description (idx2mask[idx]);
 }
 
 /* Allocate buffer for the jump pads.  On i386, we can reach an arbitrary
@@ -291,12 +289,7 @@ alloc_jump_pad_buffer (size_t size)
 void
 initialize_low_tracepoint (void)
 {
-  init_registers_i386_mmx_linux ();
-  init_registers_i386_linux ();
-  init_registers_i386_avx_linux ();
-  init_registers_i386_mpx_linux ();
-  init_registers_i386_avx_avx512_linux ();
-  init_registers_i386_avx_mpx_avx512_pku_linux ();
+  initialize_low_tdesc ();
 
   initialize_fast_tracepoint_trampoline_buffer ();
 }
index 5c56a5d7eafa2c6a35727b1c06b78910aa04db42..24b76a71f490277a4e20d2b9f05936c9e00420be 100644 (file)
@@ -757,7 +757,7 @@ x86_linux_read_description (void)
        {
          have_ptrace_getfpxregs = 0;
          have_ptrace_getregset = 0;
-         return tdesc_i386_mmx_linux;
+         return i386_linux_read_description (X86_XSTATE_X87);
        }
       else
        have_ptrace_getfpxregs = 1;
@@ -873,31 +873,15 @@ x86_linux_read_description (void)
     }
   else
     {
-      if (xcr0_features)
-       {
-         switch (xcr0 & X86_XSTATE_ALL_MASK)
-           {
-           case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK:
-             return tdesc_i386_avx_mpx_avx512_pku_linux;
-
-           case (X86_XSTATE_AVX_AVX512_MASK):
-             return tdesc_i386_avx_avx512_linux;
+      const target_desc *tdesc = NULL;
 
-           case (X86_XSTATE_MPX_MASK):
-             return tdesc_i386_mpx_linux;
-
-           case (X86_XSTATE_AVX_MPX_MASK):
-             return tdesc_i386_avx_mpx_linux;
+      if (xcr0_features)
+         tdesc = i386_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK);
 
-           case (X86_XSTATE_AVX_MASK):
-             return tdesc_i386_avx_linux;
+      if (tdesc == NULL)
+       tdesc = i386_linux_read_description (X86_XSTATE_SSE);
 
-           default:
-             return tdesc_i386_linux;
-           }
-       }
-      else
-       return tdesc_i386_linux;
+      return tdesc;
     }
 
   gdb_assert_not_reached ("failed to return tdesc");
@@ -2912,23 +2896,10 @@ x86_get_ipa_tdesc_idx (void)
     return X86_TDESC_AVX_AVX512;
 #endif
 
-  if (tdesc == tdesc_i386_mmx_linux)
-    return X86_TDESC_MMX;
-  if (tdesc == tdesc_i386_linux || tdesc == tdesc_i386_linux_no_xml)
+  if (tdesc == tdesc_i386_linux_no_xml)
     return X86_TDESC_SSE;
-  if (tdesc == tdesc_i386_avx_linux)
-    return X86_TDESC_AVX;
-  if (tdesc == tdesc_i386_mpx_linux)
-    return X86_TDESC_MPX;
-  if (tdesc == tdesc_i386_avx_mpx_linux)
-    return X86_TDESC_AVX_MPX;
-  if (tdesc == tdesc_i386_avx_mpx_avx512_pku_linux)
-    return X86_TDESC_AVX_MPX_AVX512_PKU;
-  if (tdesc == tdesc_i386_avx_avx512_linux)
-    return X86_TDESC_AVX_AVX512;
 
-  /* If none tdesc is found, return the one with minimum features.  */
-  return X86_TDESC_MMX;
+  return i386_get_ipa_tdesc_idx (tdesc);
 }
 
 /* This is initialized assuming an amd64 target.
@@ -2997,16 +2968,12 @@ initialize_low_arch (void)
   copy_target_description (tdesc_amd64_linux_no_xml, tdesc_amd64_linux);
   tdesc_amd64_linux_no_xml->xmltarget = xmltarget_amd64_linux_no_xml;
 #endif
-  init_registers_i386_linux ();
-  init_registers_i386_mmx_linux ();
-  init_registers_i386_avx_linux ();
-  init_registers_i386_mpx_linux ();
-  init_registers_i386_avx_mpx_linux ();
-  init_registers_i386_avx_avx512_linux ();
-  init_registers_i386_avx_mpx_avx512_pku_linux ();
+
+  initialize_low_tdesc ();
 
   tdesc_i386_linux_no_xml = XNEW (struct target_desc);
-  copy_target_description (tdesc_i386_linux_no_xml, tdesc_i386_linux);
+  copy_target_description (tdesc_i386_linux_no_xml,
+                          i386_linux_read_description (X86_XSTATE_SSE_MASK));
   tdesc_i386_linux_no_xml->xmltarget = xmltarget_i386_linux_no_xml;
 
   initialize_regsets_info (&x86_regsets_info);
diff --git a/gdb/gdbserver/linux-x86-tdesc.c b/gdb/gdbserver/linux-x86-tdesc.c
new file mode 100644 (file)
index 0000000..0d0be83
--- /dev/null
@@ -0,0 +1,177 @@
+/* GNU/Linux/x86-64 specific target description, for the remote server
+   for GDB.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "server.h"
+#include "tdesc.h"
+#include "linux-x86-tdesc.h"
+#include "x86-xstate.h"
+#include <inttypes.h>
+
+#if defined __i386__ || !defined IN_PROCESS_AGENT
+#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"
+
+/* Defined in auto-generated file i386-linux.c.  */
+void init_registers_i386_linux (void);
+extern const struct target_desc *tdesc_i386_linux;
+
+/* Defined in auto-generated file i386-mmx-linux.c.  */
+void init_registers_i386_mmx_linux (void);
+extern const struct target_desc *tdesc_i386_mmx_linux;
+
+/* Defined in auto-generated file i386-avx-linux.c.  */
+void init_registers_i386_avx_linux (void);
+extern const struct target_desc *tdesc_i386_avx_linux;
+
+/* Defined in auto-generated file i386-avx-mpx-linux.c.  */
+void init_registers_i386_avx_mpx_linux (void);
+extern const struct target_desc *tdesc_i386_avx_mpx_linux;
+
+/* Defined in auto-generated file i386-avx-avx512-linux.c.  */
+void init_registers_i386_avx_avx512_linux (void);
+extern const struct target_desc *tdesc_i386_avx_avx512_linux;
+
+/* Defined in auto-generated file i386-avx-mpx-avx512-linux.c.  */
+void init_registers_i386_avx_mpx_avx512_pku_linux (void);
+extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux;
+
+/* Defined in auto-generated file i386-mpx-linux.c.  */
+void init_registers_i386_mpx_linux (void);
+extern const struct target_desc *tdesc_i386_mpx_linux;
+#endif
+
+static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
+
+void
+initialize_low_tdesc ()
+{
+#if defined __i386__ || !defined IN_PROCESS_AGENT
+  init_registers_i386_linux ();
+  init_registers_i386_mmx_linux ();
+  init_registers_i386_avx_linux ();
+  init_registers_i386_mpx_linux ();
+  init_registers_i386_avx_mpx_linux ();
+  init_registers_i386_avx_avx512_linux ();
+  init_registers_i386_avx_mpx_avx512_pku_linux ();
+#endif
+}
+
+#if defined __i386__ || !defined IN_PROCESS_AGENT
+
+/* Return the target description according to XCR0.  */
+
+const struct target_desc *
+i386_linux_read_description (uint64_t xcr0)
+{
+  struct target_desc **tdesc = NULL;
+
+  if (xcr0 & X86_XSTATE_PKRU)
+     tdesc = &i386_tdescs[X86_TDESC_AVX_MPX_AVX512_PKU];
+  else if (xcr0 & X86_XSTATE_AVX512)
+    tdesc = &i386_tdescs[X86_TDESC_AVX_AVX512];
+  else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
+    tdesc = &i386_tdescs[X86_TDESC_AVX_MPX];
+  else if (xcr0 & X86_XSTATE_MPX)
+    tdesc = &i386_tdescs[X86_TDESC_MPX];
+  else if (xcr0 & X86_XSTATE_AVX)
+    tdesc = &i386_tdescs[X86_TDESC_AVX];
+  else if (xcr0 & X86_XSTATE_SSE)
+    tdesc = &i386_tdescs[X86_TDESC_SSE];
+  else if (xcr0 & X86_XSTATE_X87)
+    tdesc = &i386_tdescs[X86_TDESC_MMX];
+
+  if (tdesc == NULL)
+    return NULL;
+
+  if (*tdesc == NULL)
+    {
+      *tdesc = new target_desc ();
+
+      long regnum = 0;
+
+      if (xcr0 & X86_XSTATE_X87)
+       regnum = create_feature_i386_32bit_core (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_SSE)
+       regnum = create_feature_i386_32bit_sse (*tdesc, regnum);
+
+      regnum = create_feature_i386_32bit_linux (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_AVX)
+       regnum = create_feature_i386_32bit_avx (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_MPX)
+       regnum = create_feature_i386_32bit_mpx (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_AVX512)
+       regnum = create_feature_i386_32bit_avx512 (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_PKRU)
+       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;
+
+      if (xcr0 & X86_XSTATE_PKRU)
+       (*tdesc)->xmltarget = "i386-avx-mpx-avx512-pku-linux.xml";
+      else if (xcr0 & X86_XSTATE_AVX512)
+       (*tdesc)->xmltarget = "i386-avx-avx512-linux.xml";
+      else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
+       (*tdesc)->xmltarget = "i386-avx-mpx-linux.xml";
+      else if (xcr0 & X86_XSTATE_MPX)
+       (*tdesc)->xmltarget = "i386-mpx-linux.xml";
+      else if (xcr0 & X86_XSTATE_AVX)
+       (*tdesc)->xmltarget = "i386-avx-linux.xml";
+      else if (xcr0 & X86_XSTATE_SSE)
+       (*tdesc)->xmltarget = "i386-linux.xml";
+      else if (xcr0 & X86_XSTATE_X87)
+       (*tdesc)->xmltarget = "i386-mmx-linux.xml";
+      else
+       internal_error (__FILE__, __LINE__,
+                       "unknown xcr0: %" PRIu64, xcr0);
+#endif
+    }
+
+  return *tdesc;;
+}
+#endif
+
+#ifndef IN_PROCESS_AGENT
+int
+i386_get_ipa_tdesc_idx (const struct target_desc *tdesc)
+{
+  for (int i = 0; i < X86_TDESC_LAST; i++)
+    {
+      if (tdesc == i386_tdescs[i])
+       return i;
+    }
+
+  /* If none tdesc is found, return the one with minimum features.  */
+  return X86_TDESC_MMX;
+}
+
+#endif
index bbe4078e1b159deeb67de74395a3accb16ede517..03bd1f16cf2d521a5b8e0861764dce511ff71a61 100644 (file)
@@ -30,6 +30,7 @@ enum x86_linux_tdesc {
   X86_TDESC_AVX_MPX = 4,
   X86_TDESC_AVX_AVX512 = 5,
   X86_TDESC_AVX_MPX_AVX512_PKU = 6,
+  X86_TDESC_LAST = 7,
 };
 
 #ifdef __x86_64__
@@ -77,31 +78,9 @@ extern const struct target_desc *tdesc_x32_avx_avx512_linux;
 #endif
 
 #if defined __i386__ || !defined IN_PROCESS_AGENT
-/* Defined in auto-generated file i386-linux.c.  */
-void init_registers_i386_linux (void);
-extern const struct target_desc *tdesc_i386_linux;
-
-/* Defined in auto-generated file i386-mmx-linux.c.  */
-void init_registers_i386_mmx_linux (void);
-extern const struct target_desc *tdesc_i386_mmx_linux;
-
-/* Defined in auto-generated file i386-avx-linux.c.  */
-void init_registers_i386_avx_linux (void);
-extern const struct target_desc *tdesc_i386_avx_linux;
-
-/* Defined in auto-generated file i386-avx-mpx-linux.c.  */
-void init_registers_i386_avx_mpx_linux (void);
-extern const struct target_desc *tdesc_i386_avx_mpx_linux;
-
-/* Defined in auto-generated file i386-avx-avx512-linux.c.  */
-void init_registers_i386_avx_avx512_linux (void);
-extern const struct target_desc *tdesc_i386_avx_avx512_linux;
+int i386_get_ipa_tdesc_idx (const struct target_desc *tdesc);
+#endif
 
-/* Defined in auto-generated file i386-avx-mpx-avx512-linux.c.  */
-void init_registers_i386_avx_mpx_avx512_pku_linux (void);
-extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux;
+const struct target_desc *i386_linux_read_description (uint64_t xcr0);
 
-/* Defined in auto-generated file i386-mpx-linux.c.  */
-void init_registers_i386_mpx_linux (void);
-extern const struct target_desc *tdesc_i386_mpx_linux;
-#endif
+void initialize_low_tdesc ();
index 1b1882e865fe91aa067c2d7fbe86f0ed130cce18..4504c9bbc03ada2de3c6ad6f1706c9685d6deb44 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,111 @@ current_target_desc (void)
 
   return current_process ()->tdesc;
 }
-
 #endif
+
+struct tdesc_type
+{};
+
+/* See arch/tdesc.h.  */
+
+struct tdesc_feature *
+tdesc_create_feature (struct target_desc *tdesc, const char *name)
+{
+  return tdesc;
+}
+
+/* See arch/tdesc.h.  */
+
+struct tdesc_type *
+tdesc_create_flags (struct tdesc_feature *feature, const char *name,
+                   int size)
+{
+  return NULL;
+}
+
+/* See arch/tdesc.h.  */
+
+void
+tdesc_add_flag (struct tdesc_type *type, int start,
+               const char *flag_name)
+{}
+
+/* See arch/tdesc.h.  */
+
+struct tdesc_type *
+tdesc_named_type (const struct tdesc_feature *feature, const char *id)
+{
+  return NULL;
+}
+
+/* See arch/tdesc.h.  */
+
+struct tdesc_type *
+tdesc_create_union (struct tdesc_feature *feature, const char *id)
+{
+  return NULL;
+}
+
+/* See arch/tdesc.h.  */
+
+struct tdesc_type *
+tdesc_create_struct (struct tdesc_feature *feature, const char *id)
+{
+  return NULL;
+}
+
+/* See arch/tdesc.h.  */
+
+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);
+}
+
+/* See arch/tdesc.h.  */
+
+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)
+{}
+
+/* See arch/tdesc.h.  */
+
+void
+tdesc_add_field (struct tdesc_type *type, const char *field_name,
+                struct tdesc_type *field_type)
+{}
+
+/* See arch/tdesc.h.  */
+
+void
+tdesc_set_struct_size (struct tdesc_type *type, int size)
+{
+}
index 424a2fd626bc08903d7cc56669690853440a497e..50d0364faeb1638346537cfaa34831cc64b785cd 100644 (file)
 #ifndef TDESC_H
 #define TDESC_H
 
+#include "arch/tdesc.h"
+
 struct reg;
 
 typedef struct reg *tdesc_reg_p;
 DEF_VEC_P(tdesc_reg_p);
 
-/* A target description.  */
+struct tdesc_feature
+{};
+
+/* A target description.  Inherit from tdesc_feature so that target_desc
+   can be used as tdesc_feature.  */
 
-struct target_desc
+struct target_desc : tdesc_feature
 {
   /* A vector of elements of register definitions that
      describe the inferior's register set.  */
@@ -38,13 +44,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
 };
 
index dd21b7057f12238c7d0e81f178e1ff07ea7a2cfa..792706caec34bdee9ac29a27d558e5b9b493de93 100644 (file)
@@ -53,6 +53,7 @@
 #include "features/i386/32bit-mpx.c"
 #include "features/i386/32bit-avx512.c"
 #include "features/i386/32bit-pkeys.c"
+#include "target-descriptions.h"
 
 /* Return non-zero, when the register is in the corresponding register
    group.  Put the LINUX_ORIG_EAX register in the system group.  */
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 bee8e004f4b04354383e7c09e71647a44b4acd7c..f0ced6640856340d6053338cf9eff8f3aa0e6c22 100644 (file)
@@ -846,8 +846,7 @@ tdesc_predefined_type (enum tdesc_type_kind kind)
   gdb_assert_not_reached ("bad predefined tdesc type");
 }
 
-/* Return the type associated with ID in the context of FEATURE, or
-   NULL if none.  */
+/* See arch/tdesc.h.  */
 
 struct tdesc_type *
 tdesc_named_type (const struct tdesc_feature *feature, const char *id)
@@ -1566,6 +1565,8 @@ tdesc_use_registers (struct gdbarch *gdbarch,
 }
 \f
 
+/* See arch/tdesc.h.  */
+
 void
 tdesc_create_reg (struct tdesc_feature *feature, const char *name,
                  int regnum, int save_restore, const char *group,
@@ -1577,6 +1578,8 @@ tdesc_create_reg (struct tdesc_feature *feature, const char *name,
   VEC_safe_push (tdesc_reg_p, feature->registers, reg);
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_vector (struct tdesc_feature *feature, const char *name,
                     struct tdesc_type *field_type, int count)
@@ -1590,6 +1593,8 @@ tdesc_create_vector (struct tdesc_feature *feature, const char *name,
   return type;
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_struct (struct tdesc_feature *feature, const char *name)
 {
@@ -1599,9 +1604,7 @@ tdesc_create_struct (struct tdesc_feature *feature, const char *name)
   return type;
 }
 
-/* Set the total length of TYPE.  Structs which contain bitfields may
-   omit the reserved bits, so the end of the last field may not
-   suffice.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_set_struct_size (struct tdesc_type *type, int size)
@@ -1611,6 +1614,8 @@ tdesc_set_struct_size (struct tdesc_type *type, int size)
   type->u.u.size = size;
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_union (struct tdesc_feature *feature, const char *name)
 {
@@ -1620,6 +1625,8 @@ tdesc_create_union (struct tdesc_feature *feature, const char *name)
   return type;
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_flags (struct tdesc_feature *feature, const char *name,
                    int size)
@@ -1648,7 +1655,7 @@ tdesc_create_enum (struct tdesc_feature *feature, const char *name,
   return type;
 }
 
-/* Add a new field to TYPE.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_add_field (struct tdesc_type *type, const char *field_name,
@@ -1669,8 +1676,6 @@ tdesc_add_field (struct tdesc_type *type, const char *field_name,
   VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
 }
 
-/* Add a new typed bitfield to TYPE.  */
-
 void
 tdesc_add_typed_bitfield (struct tdesc_type *type, const char *field_name,
                          int start, int end, struct tdesc_type *field_type)
@@ -1689,9 +1694,7 @@ tdesc_add_typed_bitfield (struct tdesc_type *type, const char *field_name,
   VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
 }
 
-/* Add a new untyped bitfield to TYPE.
-   Untyped bitfields become either uint32 or uint64 depending on the size
-   of the underlying type.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
@@ -1709,8 +1712,7 @@ tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
   tdesc_add_typed_bitfield (type, field_name, start, end, field_type);
 }
 
-/* A flag is just a typed(bool) single-bit bitfield.
-   This function is kept to minimize changes in generated files.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_add_flag (struct tdesc_type *type, int start,
@@ -1745,6 +1747,8 @@ tdesc_add_enum_value (struct tdesc_type *type, int value,
   VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_feature *
 tdesc_create_feature (struct target_desc *tdesc, const char *name)
 {
@@ -2175,7 +2179,7 @@ public:
     printf_unfiltered ("  Original: %s */\n\n",
                       lbasename (m_filename_after_features.c_str ()));
 
-    printf_unfiltered ("#include \"target-descriptions.h\"\n");
+    printf_unfiltered ("#include \"arch/tdesc.h\"\n");
     printf_unfiltered ("\n");
   }
 
index 591da1505596591f2715fce704032443ce859306..c4f9b92e456d5fcd23eba0e5d3d3a1ac394d8555 100644 (file)
 
 #ifndef TARGET_DESCRIPTIONS_H
 #define TARGET_DESCRIPTIONS_H 1
+#include "arch/tdesc.h"
 
-struct tdesc_feature;
 struct tdesc_arch_data;
-struct tdesc_type;
-struct tdesc_reg;
-struct target_desc;
 struct target_ops;
-struct target_desc;
 /* An inferior's target description info is stored in this opaque
    object.  There's one such object per inferior.  */
 struct target_desc_info;
@@ -182,12 +178,6 @@ const struct tdesc_feature *tdesc_find_feature (const struct target_desc *,
 
 const char *tdesc_feature_name (const struct tdesc_feature *feature);
 
-/* Return the type associated with ID in the context of FEATURE, or
-   NULL if none.  */
-
-struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
-                                    const char *id);
-
 /* Return the name of register REGNO, from the target description or
    from an architecture-provided pseudo_register_name method.  */
 
@@ -220,38 +210,14 @@ void set_tdesc_property (struct target_desc *,
                         const char *key, const char *value);
 void tdesc_add_compatible (struct target_desc *,
                           const struct bfd_arch_info *);
-
-struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
-                                           const char *name);
-struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature,
-                                       const char *name,
-                                       struct tdesc_type *field_type,
-                                       int count);
-struct tdesc_type *tdesc_create_struct (struct tdesc_feature *feature,
-                                       const char *name);
-void tdesc_set_struct_size (struct tdesc_type *type, int size);
-struct tdesc_type *tdesc_create_union (struct tdesc_feature *feature,
-                                      const char *name);
-struct tdesc_type *tdesc_create_flags (struct tdesc_feature *feature,
-                                      const char *name,
-                                      int size);
 struct tdesc_type *tdesc_create_enum (struct tdesc_feature *feature,
                                      const char *name,
                                      int size);
-void tdesc_add_field (struct tdesc_type *type, const char *field_name,
-                     struct tdesc_type *field_type);
 void tdesc_add_typed_bitfield (struct tdesc_type *type, const char *field_name,
                               int start, int end,
                               struct tdesc_type *field_type);
-void tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
-                        int start, int end);
-void tdesc_add_flag (struct tdesc_type *type, int start,
-                    const char *flag_name);
 void tdesc_add_enum_value (struct tdesc_type *type, int value,
                           const char *name);
-void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
-                      int regnum, int save_restore, const char *group,
-                      int bitsize, const char *type);
 
 #if GDB_SELF_TEST
 namespace selftests {