]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/linux-x86-tdesc.c
Dynamically composite xml in reply to GDB
[thirdparty/binutils-gdb.git] / gdb / gdbserver / linux-x86-tdesc.c
CommitLineData
f49ff000
YQ
1/* GNU/Linux/x86-64 specific target description, for the remote server
2 for GDB.
3 Copyright (C) 2017 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "server.h"
21#include "tdesc.h"
22#include "linux-x86-tdesc.h"
23#include "x86-xstate.h"
f49ff000
YQ
24
25#if defined __i386__ || !defined IN_PROCESS_AGENT
26#include "../features/i386/32bit-core.c"
27#include "../features/i386/32bit-linux.c"
28#include "../features/i386/32bit-sse.c"
29#include "../features/i386/32bit-avx.c"
30#include "../features/i386/32bit-avx512.c"
31#include "../features/i386/32bit-mpx.c"
32#include "../features/i386/32bit-pkeys.c"
33
34/* Defined in auto-generated file i386-linux.c. */
35void init_registers_i386_linux (void);
36extern const struct target_desc *tdesc_i386_linux;
37
38/* Defined in auto-generated file i386-mmx-linux.c. */
39void init_registers_i386_mmx_linux (void);
40extern const struct target_desc *tdesc_i386_mmx_linux;
41
42/* Defined in auto-generated file i386-avx-linux.c. */
43void init_registers_i386_avx_linux (void);
44extern const struct target_desc *tdesc_i386_avx_linux;
45
46/* Defined in auto-generated file i386-avx-mpx-linux.c. */
47void init_registers_i386_avx_mpx_linux (void);
48extern const struct target_desc *tdesc_i386_avx_mpx_linux;
49
50/* Defined in auto-generated file i386-avx-avx512-linux.c. */
51void init_registers_i386_avx_avx512_linux (void);
52extern const struct target_desc *tdesc_i386_avx_avx512_linux;
53
54/* Defined in auto-generated file i386-avx-mpx-avx512-linux.c. */
55void init_registers_i386_avx_mpx_avx512_pku_linux (void);
56extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux;
57
58/* Defined in auto-generated file i386-mpx-linux.c. */
59void init_registers_i386_mpx_linux (void);
60extern const struct target_desc *tdesc_i386_mpx_linux;
61#endif
62
63static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
64
0a188386
YQ
65#if defined GDB_SELF_TEST && !defined IN_PROCESS_AGENT
66#include "selftest.h"
67
68namespace selftests {
69namespace tdesc {
70static void
71i386_tdesc_test ()
72{
73 struct
74 {
75 unsigned int mask;
76 const target_desc *tdesc;
77 } tdesc_tests[] = {
78 { X86_XSTATE_X87, tdesc_i386_mmx_linux },
79 { X86_XSTATE_SSE_MASK, tdesc_i386_linux },
80 { X86_XSTATE_AVX_MASK, tdesc_i386_avx_linux },
81 { X86_XSTATE_MPX_MASK, tdesc_i386_mpx_linux },
82 { X86_XSTATE_AVX_MPX_MASK, tdesc_i386_avx_mpx_linux },
83 { X86_XSTATE_AVX_AVX512_MASK, tdesc_i386_avx_avx512_linux },
84 { X86_XSTATE_AVX_MPX_AVX512_PKU_MASK, tdesc_i386_avx_mpx_avx512_pku_linux }
85 };
86
87 for (auto &elem : tdesc_tests)
88 {
89 const target_desc *tdesc = i386_linux_read_description (elem.mask);
90
91 SELF_CHECK (*tdesc == *elem.tdesc);
92 }
93}
94}
95} // namespace selftests
96#endif /* GDB_SELF_TEST */
97
f49ff000
YQ
98void
99initialize_low_tdesc ()
100{
101#if defined __i386__ || !defined IN_PROCESS_AGENT
102 init_registers_i386_linux ();
103 init_registers_i386_mmx_linux ();
104 init_registers_i386_avx_linux ();
105 init_registers_i386_mpx_linux ();
106 init_registers_i386_avx_mpx_linux ();
107 init_registers_i386_avx_avx512_linux ();
108 init_registers_i386_avx_mpx_avx512_pku_linux ();
0a188386
YQ
109
110#if GDB_SELF_TEST && !defined IN_PROCESS_AGENT
111 selftests::register_test (selftests::tdesc::i386_tdesc_test);
112#endif
f49ff000
YQ
113#endif
114}
115
116#if defined __i386__ || !defined IN_PROCESS_AGENT
117
118/* Return the target description according to XCR0. */
119
120const struct target_desc *
121i386_linux_read_description (uint64_t xcr0)
122{
123 struct target_desc **tdesc = NULL;
124
125 if (xcr0 & X86_XSTATE_PKRU)
126 tdesc = &i386_tdescs[X86_TDESC_AVX_MPX_AVX512_PKU];
127 else if (xcr0 & X86_XSTATE_AVX512)
128 tdesc = &i386_tdescs[X86_TDESC_AVX_AVX512];
129 else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
130 tdesc = &i386_tdescs[X86_TDESC_AVX_MPX];
131 else if (xcr0 & X86_XSTATE_MPX)
132 tdesc = &i386_tdescs[X86_TDESC_MPX];
133 else if (xcr0 & X86_XSTATE_AVX)
134 tdesc = &i386_tdescs[X86_TDESC_AVX];
135 else if (xcr0 & X86_XSTATE_SSE)
136 tdesc = &i386_tdescs[X86_TDESC_SSE];
137 else if (xcr0 & X86_XSTATE_X87)
138 tdesc = &i386_tdescs[X86_TDESC_MMX];
139
140 if (tdesc == NULL)
141 return NULL;
142
143 if (*tdesc == NULL)
144 {
145 *tdesc = new target_desc ();
146
0abe8a89
YQ
147#ifndef IN_PROCESS_AGENT
148 set_tdesc_architecture (*tdesc, "i386");
149 set_tdesc_osabi (*tdesc, "GNU/Linux");
150#endif
151
f49ff000
YQ
152 long regnum = 0;
153
154 if (xcr0 & X86_XSTATE_X87)
155 regnum = create_feature_i386_32bit_core (*tdesc, regnum);
156
157 if (xcr0 & X86_XSTATE_SSE)
158 regnum = create_feature_i386_32bit_sse (*tdesc, regnum);
159
160 regnum = create_feature_i386_32bit_linux (*tdesc, regnum);
161
162 if (xcr0 & X86_XSTATE_AVX)
163 regnum = create_feature_i386_32bit_avx (*tdesc, regnum);
164
165 if (xcr0 & X86_XSTATE_MPX)
166 regnum = create_feature_i386_32bit_mpx (*tdesc, regnum);
167
168 if (xcr0 & X86_XSTATE_AVX512)
169 regnum = create_feature_i386_32bit_avx512 (*tdesc, regnum);
170
171 if (xcr0 & X86_XSTATE_PKRU)
172 regnum = create_feature_i386_32bit_pkeys (*tdesc, regnum);
173
174 init_target_desc (*tdesc);
175
176#ifndef IN_PROCESS_AGENT
177 static const char *expedite_regs_i386[] = { "ebp", "esp", "eip", NULL };
178 (*tdesc)->expedite_regs = expedite_regs_i386;
f49ff000
YQ
179#endif
180 }
181
182 return *tdesc;;
183}
184#endif
185
186#ifndef IN_PROCESS_AGENT
187int
188i386_get_ipa_tdesc_idx (const struct target_desc *tdesc)
189{
190 for (int i = 0; i < X86_TDESC_LAST; i++)
191 {
192 if (tdesc == i386_tdescs[i])
193 return i;
194 }
195
196 /* If none tdesc is found, return the one with minimum features. */
197 return X86_TDESC_MMX;
198}
199
200#endif