[GDBserver] unit test to i386_tdesc
[deliverable/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"
24#include <inttypes.h>
25
26#if defined __i386__ || !defined IN_PROCESS_AGENT
27#include "../features/i386/32bit-core.c"
28#include "../features/i386/32bit-linux.c"
29#include "../features/i386/32bit-sse.c"
30#include "../features/i386/32bit-avx.c"
31#include "../features/i386/32bit-avx512.c"
32#include "../features/i386/32bit-mpx.c"
33#include "../features/i386/32bit-pkeys.c"
34
35/* Defined in auto-generated file i386-linux.c. */
36void init_registers_i386_linux (void);
37extern const struct target_desc *tdesc_i386_linux;
38
39/* Defined in auto-generated file i386-mmx-linux.c. */
40void init_registers_i386_mmx_linux (void);
41extern const struct target_desc *tdesc_i386_mmx_linux;
42
43/* Defined in auto-generated file i386-avx-linux.c. */
44void init_registers_i386_avx_linux (void);
45extern const struct target_desc *tdesc_i386_avx_linux;
46
47/* Defined in auto-generated file i386-avx-mpx-linux.c. */
48void init_registers_i386_avx_mpx_linux (void);
49extern const struct target_desc *tdesc_i386_avx_mpx_linux;
50
51/* Defined in auto-generated file i386-avx-avx512-linux.c. */
52void init_registers_i386_avx_avx512_linux (void);
53extern const struct target_desc *tdesc_i386_avx_avx512_linux;
54
55/* Defined in auto-generated file i386-avx-mpx-avx512-linux.c. */
56void init_registers_i386_avx_mpx_avx512_pku_linux (void);
57extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux;
58
59/* Defined in auto-generated file i386-mpx-linux.c. */
60void init_registers_i386_mpx_linux (void);
61extern const struct target_desc *tdesc_i386_mpx_linux;
62#endif
63
64static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
65
0a188386
YQ
66#if defined GDB_SELF_TEST && !defined IN_PROCESS_AGENT
67#include "selftest.h"
68
69namespace selftests {
70namespace tdesc {
71static void
72i386_tdesc_test ()
73{
74 struct
75 {
76 unsigned int mask;
77 const target_desc *tdesc;
78 } tdesc_tests[] = {
79 { X86_XSTATE_X87, tdesc_i386_mmx_linux },
80 { X86_XSTATE_SSE_MASK, tdesc_i386_linux },
81 { X86_XSTATE_AVX_MASK, tdesc_i386_avx_linux },
82 { X86_XSTATE_MPX_MASK, tdesc_i386_mpx_linux },
83 { X86_XSTATE_AVX_MPX_MASK, tdesc_i386_avx_mpx_linux },
84 { X86_XSTATE_AVX_AVX512_MASK, tdesc_i386_avx_avx512_linux },
85 { X86_XSTATE_AVX_MPX_AVX512_PKU_MASK, tdesc_i386_avx_mpx_avx512_pku_linux }
86 };
87
88 for (auto &elem : tdesc_tests)
89 {
90 const target_desc *tdesc = i386_linux_read_description (elem.mask);
91
92 SELF_CHECK (*tdesc == *elem.tdesc);
93 }
94}
95}
96} // namespace selftests
97#endif /* GDB_SELF_TEST */
98
f49ff000
YQ
99void
100initialize_low_tdesc ()
101{
102#if defined __i386__ || !defined IN_PROCESS_AGENT
103 init_registers_i386_linux ();
104 init_registers_i386_mmx_linux ();
105 init_registers_i386_avx_linux ();
106 init_registers_i386_mpx_linux ();
107 init_registers_i386_avx_mpx_linux ();
108 init_registers_i386_avx_avx512_linux ();
109 init_registers_i386_avx_mpx_avx512_pku_linux ();
0a188386
YQ
110
111#if GDB_SELF_TEST && !defined IN_PROCESS_AGENT
112 selftests::register_test (selftests::tdesc::i386_tdesc_test);
113#endif
f49ff000
YQ
114#endif
115}
116
117#if defined __i386__ || !defined IN_PROCESS_AGENT
118
119/* Return the target description according to XCR0. */
120
121const struct target_desc *
122i386_linux_read_description (uint64_t xcr0)
123{
124 struct target_desc **tdesc = NULL;
125
126 if (xcr0 & X86_XSTATE_PKRU)
127 tdesc = &i386_tdescs[X86_TDESC_AVX_MPX_AVX512_PKU];
128 else if (xcr0 & X86_XSTATE_AVX512)
129 tdesc = &i386_tdescs[X86_TDESC_AVX_AVX512];
130 else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
131 tdesc = &i386_tdescs[X86_TDESC_AVX_MPX];
132 else if (xcr0 & X86_XSTATE_MPX)
133 tdesc = &i386_tdescs[X86_TDESC_MPX];
134 else if (xcr0 & X86_XSTATE_AVX)
135 tdesc = &i386_tdescs[X86_TDESC_AVX];
136 else if (xcr0 & X86_XSTATE_SSE)
137 tdesc = &i386_tdescs[X86_TDESC_SSE];
138 else if (xcr0 & X86_XSTATE_X87)
139 tdesc = &i386_tdescs[X86_TDESC_MMX];
140
141 if (tdesc == NULL)
142 return NULL;
143
144 if (*tdesc == NULL)
145 {
146 *tdesc = new target_desc ();
147
148 long regnum = 0;
149
150 if (xcr0 & X86_XSTATE_X87)
151 regnum = create_feature_i386_32bit_core (*tdesc, regnum);
152
153 if (xcr0 & X86_XSTATE_SSE)
154 regnum = create_feature_i386_32bit_sse (*tdesc, regnum);
155
156 regnum = create_feature_i386_32bit_linux (*tdesc, regnum);
157
158 if (xcr0 & X86_XSTATE_AVX)
159 regnum = create_feature_i386_32bit_avx (*tdesc, regnum);
160
161 if (xcr0 & X86_XSTATE_MPX)
162 regnum = create_feature_i386_32bit_mpx (*tdesc, regnum);
163
164 if (xcr0 & X86_XSTATE_AVX512)
165 regnum = create_feature_i386_32bit_avx512 (*tdesc, regnum);
166
167 if (xcr0 & X86_XSTATE_PKRU)
168 regnum = create_feature_i386_32bit_pkeys (*tdesc, regnum);
169
170 init_target_desc (*tdesc);
171
172#ifndef IN_PROCESS_AGENT
173 static const char *expedite_regs_i386[] = { "ebp", "esp", "eip", NULL };
174 (*tdesc)->expedite_regs = expedite_regs_i386;
175
176 if (xcr0 & X86_XSTATE_PKRU)
177 (*tdesc)->xmltarget = "i386-avx-mpx-avx512-pku-linux.xml";
178 else if (xcr0 & X86_XSTATE_AVX512)
179 (*tdesc)->xmltarget = "i386-avx-avx512-linux.xml";
180 else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
181 (*tdesc)->xmltarget = "i386-avx-mpx-linux.xml";
182 else if (xcr0 & X86_XSTATE_MPX)
183 (*tdesc)->xmltarget = "i386-mpx-linux.xml";
184 else if (xcr0 & X86_XSTATE_AVX)
185 (*tdesc)->xmltarget = "i386-avx-linux.xml";
186 else if (xcr0 & X86_XSTATE_SSE)
187 (*tdesc)->xmltarget = "i386-linux.xml";
188 else if (xcr0 & X86_XSTATE_X87)
189 (*tdesc)->xmltarget = "i386-mmx-linux.xml";
190 else
191 internal_error (__FILE__, __LINE__,
192 "unknown xcr0: %" PRIu64, xcr0);
193#endif
194 }
195
196 return *tdesc;;
197}
198#endif
199
200#ifndef IN_PROCESS_AGENT
201int
202i386_get_ipa_tdesc_idx (const struct target_desc *tdesc)
203{
204 for (int i = 0; i < X86_TDESC_LAST; i++)
205 {
206 if (tdesc == i386_tdescs[i])
207 return i;
208 }
209
210 /* If none tdesc is found, return the one with minimum features. */
211 return X86_TDESC_MMX;
212}
213
214#endif
This page took 0.031289 seconds and 4 git commands to generate.