summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2017-09-05 09:54:53 +0100
committerYao Qi <yao.qi@linaro.org>2017-09-05 09:54:53 +0100
commitf49ff00066929bf7c38f9c89ad640561bbb331f6 (patch)
treeb410bbcba3cb5b90d02547b31e4f9efd0c0a7a8f
parent2b68ef2f11daef3ab3c6941ebf53dfcd0fb79fbf (diff)
downloadbinutils-gdb-f49ff00066929bf7c38f9c89ad640561bbb331f6.tar.gz
[GDBserver] Centralize tdesc for i386-linux
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.
-rw-r--r--gdb/ChangeLog15
-rw-r--r--gdb/arch/tdesc.h80
-rw-r--r--gdb/features/i386/32bit-avx.c2
-rw-r--r--gdb/features/i386/32bit-avx512.c2
-rw-r--r--gdb/features/i386/32bit-core.c2
-rw-r--r--gdb/features/i386/32bit-linux.c2
-rw-r--r--gdb/features/i386/32bit-mpx.c2
-rw-r--r--gdb/features/i386/32bit-pkeys.c2
-rw-r--r--gdb/features/i386/32bit-sse.c2
-rw-r--r--gdb/gdbserver/ChangeLog18
-rw-r--r--gdb/gdbserver/configure.srv6
-rw-r--r--gdb/gdbserver/linux-i386-ipa.c39
-rw-r--r--gdb/gdbserver/linux-x86-low.c59
-rw-r--r--gdb/gdbserver/linux-x86-tdesc.c177
-rw-r--r--gdb/gdbserver/linux-x86-tdesc.h31
-rw-r--r--gdb/gdbserver/tdesc.c110
-rw-r--r--gdb/gdbserver/tdesc.h29
-rw-r--r--gdb/i386-linux-tdep.c1
-rwxr-xr-xgdb/regformats/regdat.sh10
-rw-r--r--gdb/target-descriptions.c32
-rw-r--r--gdb/target-descriptions.h36
21 files changed, 491 insertions, 166 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 729a74f04a3..cebd4f563e3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,20 @@
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.
2017-09-05 Yao Qi <yao.qi@linaro.org>
diff --git a/gdb/arch/tdesc.h b/gdb/arch/tdesc.h
new file mode 100644
index 00000000000..872df68bb4d
--- /dev/null
+++ b/gdb/arch/tdesc.h
@@ -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 */
diff --git a/gdb/features/i386/32bit-avx.c b/gdb/features/i386/32bit-avx.c
index 0e715158658..3a98936a0c7 100644
--- a/gdb/features/i386/32bit-avx.c
+++ b/gdb/features/i386/32bit-avx.c
@@ -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)
diff --git a/gdb/features/i386/32bit-avx512.c b/gdb/features/i386/32bit-avx512.c
index 034f557094d..b13e1d33081 100644
--- a/gdb/features/i386/32bit-avx512.c
+++ b/gdb/features/i386/32bit-avx512.c
@@ -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)
diff --git a/gdb/features/i386/32bit-core.c b/gdb/features/i386/32bit-core.c
index b43de4da82f..ea6db935c06 100644
--- a/gdb/features/i386/32bit-core.c
+++ b/gdb/features/i386/32bit-core.c
@@ -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)
diff --git a/gdb/features/i386/32bit-linux.c b/gdb/features/i386/32bit-linux.c
index 1b50882c6c8..1ba932d795a 100644
--- a/gdb/features/i386/32bit-linux.c
+++ b/gdb/features/i386/32bit-linux.c
@@ -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)
diff --git a/gdb/features/i386/32bit-mpx.c b/gdb/features/i386/32bit-mpx.c
index 6ed3b2ea202..f7d2ef052c5 100644
--- a/gdb/features/i386/32bit-mpx.c
+++ b/gdb/features/i386/32bit-mpx.c
@@ -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)
diff --git a/gdb/features/i386/32bit-pkeys.c b/gdb/features/i386/32bit-pkeys.c
index 24a40aa381e..89f1a5b3e06 100644
--- a/gdb/features/i386/32bit-pkeys.c
+++ b/gdb/features/i386/32bit-pkeys.c
@@ -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)
diff --git a/gdb/features/i386/32bit-sse.c b/gdb/features/i386/32bit-sse.c
index c0684fbdcce..98f4cd061c0 100644
--- a/gdb/features/i386/32bit-sse.c
+++ b/gdb/features/i386/32bit-sse.c
@@ -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)
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index b6febf24eb5..66e9f5379b8 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,23 @@
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
instead of 0.
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 789a16b867b..1a270120be0 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -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"
diff --git a/gdb/gdbserver/linux-i386-ipa.c b/gdb/gdbserver/linux-i386-ipa.c
index e9ac78b06a5..54608da15da 100644
--- a/gdb/gdbserver/linux-i386-ipa.c
+++ b/gdb/gdbserver/linux-i386-ipa.c
@@ -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 ();
}
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 5c56a5d7eaf..24b76a71f49 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -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
index 00000000000..0d0be83d4a1
--- /dev/null
+++ b/gdb/gdbserver/linux-x86-tdesc.c
@@ -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
diff --git a/gdb/gdbserver/linux-x86-tdesc.h b/gdb/gdbserver/linux-x86-tdesc.h
index bbe4078e1b1..03bd1f16cf2 100644
--- a/gdb/gdbserver/linux-x86-tdesc.h
+++ b/gdb/gdbserver/linux-x86-tdesc.h
@@ -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 ();
diff --git a/gdb/gdbserver/tdesc.c b/gdb/gdbserver/tdesc.c
index 1b1882e865f..4504c9bbc03 100644
--- a/gdb/gdbserver/tdesc.c
+++ b/gdb/gdbserver/tdesc.c
@@ -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)
+{
+}
diff --git a/gdb/gdbserver/tdesc.h b/gdb/gdbserver/tdesc.h
index 424a2fd626b..50d0364faeb 100644
--- a/gdb/gdbserver/tdesc.h
+++ b/gdb/gdbserver/tdesc.h
@@ -19,14 +19,20 @@
#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
};
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index dd21b7057f1..792706caec3 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -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. */
diff --git a/gdb/regformats/regdat.sh b/gdb/regformats/regdat.sh
index 236cd9347be..66449cc60e2 100755
--- a/gdb/regformats/regdat.sh
+++ b/gdb/regformats/regdat.sh
@@ -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
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index bee8e004f4b..f0ced664085 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -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,
}
+/* 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");
}
diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h
index 591da150559..c4f9b92e456 100644
--- a/gdb/target-descriptions.h
+++ b/gdb/target-descriptions.h
@@ -21,14 +21,10 @@
#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 {