[GDBserver] Centralize tdesc for i386-linux
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-x86-tdesc.c
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. */
36 void init_registers_i386_linux (void);
37 extern const struct target_desc *tdesc_i386_linux;
38
39 /* Defined in auto-generated file i386-mmx-linux.c. */
40 void init_registers_i386_mmx_linux (void);
41 extern const struct target_desc *tdesc_i386_mmx_linux;
42
43 /* Defined in auto-generated file i386-avx-linux.c. */
44 void init_registers_i386_avx_linux (void);
45 extern const struct target_desc *tdesc_i386_avx_linux;
46
47 /* Defined in auto-generated file i386-avx-mpx-linux.c. */
48 void init_registers_i386_avx_mpx_linux (void);
49 extern const struct target_desc *tdesc_i386_avx_mpx_linux;
50
51 /* Defined in auto-generated file i386-avx-avx512-linux.c. */
52 void init_registers_i386_avx_avx512_linux (void);
53 extern const struct target_desc *tdesc_i386_avx_avx512_linux;
54
55 /* Defined in auto-generated file i386-avx-mpx-avx512-linux.c. */
56 void init_registers_i386_avx_mpx_avx512_pku_linux (void);
57 extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux;
58
59 /* Defined in auto-generated file i386-mpx-linux.c. */
60 void init_registers_i386_mpx_linux (void);
61 extern const struct target_desc *tdesc_i386_mpx_linux;
62 #endif
63
64 static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
65
66 void
67 initialize_low_tdesc ()
68 {
69 #if defined __i386__ || !defined IN_PROCESS_AGENT
70 init_registers_i386_linux ();
71 init_registers_i386_mmx_linux ();
72 init_registers_i386_avx_linux ();
73 init_registers_i386_mpx_linux ();
74 init_registers_i386_avx_mpx_linux ();
75 init_registers_i386_avx_avx512_linux ();
76 init_registers_i386_avx_mpx_avx512_pku_linux ();
77 #endif
78 }
79
80 #if defined __i386__ || !defined IN_PROCESS_AGENT
81
82 /* Return the target description according to XCR0. */
83
84 const struct target_desc *
85 i386_linux_read_description (uint64_t xcr0)
86 {
87 struct target_desc **tdesc = NULL;
88
89 if (xcr0 & X86_XSTATE_PKRU)
90 tdesc = &i386_tdescs[X86_TDESC_AVX_MPX_AVX512_PKU];
91 else if (xcr0 & X86_XSTATE_AVX512)
92 tdesc = &i386_tdescs[X86_TDESC_AVX_AVX512];
93 else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
94 tdesc = &i386_tdescs[X86_TDESC_AVX_MPX];
95 else if (xcr0 & X86_XSTATE_MPX)
96 tdesc = &i386_tdescs[X86_TDESC_MPX];
97 else if (xcr0 & X86_XSTATE_AVX)
98 tdesc = &i386_tdescs[X86_TDESC_AVX];
99 else if (xcr0 & X86_XSTATE_SSE)
100 tdesc = &i386_tdescs[X86_TDESC_SSE];
101 else if (xcr0 & X86_XSTATE_X87)
102 tdesc = &i386_tdescs[X86_TDESC_MMX];
103
104 if (tdesc == NULL)
105 return NULL;
106
107 if (*tdesc == NULL)
108 {
109 *tdesc = new target_desc ();
110
111 long regnum = 0;
112
113 if (xcr0 & X86_XSTATE_X87)
114 regnum = create_feature_i386_32bit_core (*tdesc, regnum);
115
116 if (xcr0 & X86_XSTATE_SSE)
117 regnum = create_feature_i386_32bit_sse (*tdesc, regnum);
118
119 regnum = create_feature_i386_32bit_linux (*tdesc, regnum);
120
121 if (xcr0 & X86_XSTATE_AVX)
122 regnum = create_feature_i386_32bit_avx (*tdesc, regnum);
123
124 if (xcr0 & X86_XSTATE_MPX)
125 regnum = create_feature_i386_32bit_mpx (*tdesc, regnum);
126
127 if (xcr0 & X86_XSTATE_AVX512)
128 regnum = create_feature_i386_32bit_avx512 (*tdesc, regnum);
129
130 if (xcr0 & X86_XSTATE_PKRU)
131 regnum = create_feature_i386_32bit_pkeys (*tdesc, regnum);
132
133 init_target_desc (*tdesc);
134
135 #ifndef IN_PROCESS_AGENT
136 static const char *expedite_regs_i386[] = { "ebp", "esp", "eip", NULL };
137 (*tdesc)->expedite_regs = expedite_regs_i386;
138
139 if (xcr0 & X86_XSTATE_PKRU)
140 (*tdesc)->xmltarget = "i386-avx-mpx-avx512-pku-linux.xml";
141 else if (xcr0 & X86_XSTATE_AVX512)
142 (*tdesc)->xmltarget = "i386-avx-avx512-linux.xml";
143 else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
144 (*tdesc)->xmltarget = "i386-avx-mpx-linux.xml";
145 else if (xcr0 & X86_XSTATE_MPX)
146 (*tdesc)->xmltarget = "i386-mpx-linux.xml";
147 else if (xcr0 & X86_XSTATE_AVX)
148 (*tdesc)->xmltarget = "i386-avx-linux.xml";
149 else if (xcr0 & X86_XSTATE_SSE)
150 (*tdesc)->xmltarget = "i386-linux.xml";
151 else if (xcr0 & X86_XSTATE_X87)
152 (*tdesc)->xmltarget = "i386-mmx-linux.xml";
153 else
154 internal_error (__FILE__, __LINE__,
155 "unknown xcr0: %" PRIu64, xcr0);
156 #endif
157 }
158
159 return *tdesc;;
160 }
161 #endif
162
163 #ifndef IN_PROCESS_AGENT
164 int
165 i386_get_ipa_tdesc_idx (const struct target_desc *tdesc)
166 {
167 for (int i = 0; i < X86_TDESC_LAST; i++)
168 {
169 if (tdesc == i386_tdescs[i])
170 return i;
171 }
172
173 /* If none tdesc is found, return the one with minimum features. */
174 return X86_TDESC_MMX;
175 }
176
177 #endif
This page took 0.035049 seconds and 4 git commands to generate.