GDBserver
linux-x86-tdesc.c
Go to the documentation of this file.
1 /* GNU/Linux/x86-64 specific target description, for the remote server
2  for GDB.
3  Copyright (C) 2017-2018 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 "arch/i386.h"
24 #include "common/x86-xstate.h"
25 #ifdef __x86_64__
26 #include "arch/amd64.h"
27 #endif
28 
29 /* Return the right x86_linux_tdesc index for a given XCR0. Return
30  X86_TDESC_LAST if can't find a match. */
31 
32 static enum x86_linux_tdesc
33 xcr0_to_tdesc_idx (uint64_t xcr0, bool is_x32)
34 {
35  if (xcr0 & X86_XSTATE_PKRU)
36  {
37  if (is_x32)
38  {
39  /* No x32 MPX and PKU, fall back to avx_avx512. */
40  return X86_TDESC_AVX_AVX512;
41  }
42  else
44  }
45  else if (xcr0 & X86_XSTATE_AVX512)
46  return X86_TDESC_AVX_AVX512;
48  {
49  if (is_x32) /* No MPX on x32. */
50  return X86_TDESC_AVX;
51  else
52  return X86_TDESC_AVX_MPX;
53  }
54  else if (xcr0 & X86_XSTATE_MPX)
55  {
56  if (is_x32) /* No MPX on x32. */
57  return X86_TDESC_AVX;
58  else
59  return X86_TDESC_MPX;
60  }
61  else if (xcr0 & X86_XSTATE_AVX)
62  return X86_TDESC_AVX;
63  else if (xcr0 & X86_XSTATE_SSE)
64  return X86_TDESC_SSE;
65  else if (xcr0 & X86_XSTATE_X87)
66  return X86_TDESC_MMX;
67  else
68  return X86_TDESC_LAST;
69 }
70 
71 static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
72 
73 #if defined __i386__ || !defined IN_PROCESS_AGENT
74 
75 /* Return the target description according to XCR0. */
76 
77 const struct target_desc *
79 {
80  enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, false);
81 
82  if (idx == X86_TDESC_LAST)
83  return NULL;
84 
85  struct target_desc **tdesc = &i386_tdescs[idx];
86 
87  if (*tdesc == NULL)
88  {
89  *tdesc = i386_create_target_description (xcr0, true);
90 
91  init_target_desc (*tdesc);
92 
93 #ifndef IN_PROCESS_AGENT
94  static const char *expedite_regs_i386[] = { "ebp", "esp", "eip", NULL };
95  (*tdesc)->expedite_regs = expedite_regs_i386;
96 #endif
97  }
98 
99  return *tdesc;;
100 }
101 #endif
102 
103 #ifdef __x86_64__
104 
105 static target_desc *amd64_tdescs[X86_TDESC_LAST] = { };
106 static target_desc *x32_tdescs[X86_TDESC_LAST] = { };
107 
108 const struct target_desc *
109 amd64_linux_read_description (uint64_t xcr0, bool is_x32)
110 {
111  enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, is_x32);
112 
113  if (idx == X86_TDESC_LAST)
114  return NULL;
115 
116  struct target_desc **tdesc = NULL;
117 
118  if (is_x32)
119  tdesc = &x32_tdescs[idx];
120  else
121  tdesc = &amd64_tdescs[idx];
122 
123  if (*tdesc == NULL)
124  {
125  *tdesc = amd64_create_target_description (xcr0, is_x32, true);
126 
127  init_target_desc (*tdesc);
128 
129 #ifndef IN_PROCESS_AGENT
130  static const char *expedite_regs_amd64[] = { "rbp", "rsp", "rip", NULL };
131  (*tdesc)->expedite_regs = expedite_regs_amd64;
132 #endif
133  }
134  return *tdesc;
135 }
136 
137 #endif
138 
139 #ifndef IN_PROCESS_AGENT
140 
141 int
142 i386_get_ipa_tdesc_idx (const struct target_desc *tdesc)
143 {
144  for (int i = 0; i < X86_TDESC_LAST; i++)
145  {
146  if (tdesc == i386_tdescs[i])
147  return i;
148  }
149 
150  /* If none tdesc is found, return the one with minimum features. */
151  return X86_TDESC_MMX;
152 }
153 
154 #if defined __x86_64__
155 int
156 amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc)
157 {
158  for (int i = 0; i < X86_TDESC_LAST; i++)
159  {
160  if (tdesc == amd64_tdescs[i])
161  return i;
162  }
163  for (int i = 0; i < X86_TDESC_LAST; i++)
164  {
165  if (tdesc == x32_tdescs[i])
166  return i;
167  }
168 
169  return X86_TDESC_SSE;
170 }
171 
172 #endif
173 #endif
const struct target_desc * i386_linux_read_description(uint64_t xcr0)
static struct target_desc * i386_tdescs[X86_TDESC_LAST]
#define X86_XSTATE_PKRU
Definition: x86-xstate.h:38
static enum x86_linux_tdesc xcr0_to_tdesc_idx(uint64_t xcr0, bool is_x32)
#define X86_XSTATE_SSE
Definition: x86-xstate.h:25
void init_target_desc(struct target_desc *tdesc)
Definition: tdesc.c:23
#define X86_XSTATE_AVX512
Definition: x86-xstate.h:35
int i386_get_ipa_tdesc_idx(const struct target_desc *tdesc)
x86_linux_tdesc
#define X86_XSTATE_MPX
Definition: x86-xstate.h:29
#define X86_XSTATE_X87
Definition: x86-xstate.h:24
#define X86_XSTATE_AVX_MPX_MASK
Definition: x86-xstate.h:45
#define X86_XSTATE_AVX
Definition: x86-xstate.h:26