From: Yao Qi Date: Tue, 5 Sep 2017 08:54:53 +0000 (+0100) Subject: [GDBserver] Centralize tdesc for i386-linux X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f49ff00066929bf7c38f9c89ad640561bbb331f6;p=binutils-gdb.git [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 * 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 * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 729a74f04a3..cebd4f563e3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2017-09-05 Yao Qi + + * 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 * regformats/regdat.sh: Update generated code. 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 . */ + +#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,3 +1,21 @@ +2017-09-05 Yao Qi + + * 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 * linux-x86-low.c (x86_get_ipa_tdesc_idx): Use X86_TDESC_MMX 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 #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 . */ + +#include "server.h" +#include "tdesc.h" +#include "linux-x86-tdesc.h" +#include "x86-xstate.h" +#include + +#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 {