GDBserver
lynx-i386-low.c
Go to the documentation of this file.
1 /* Copyright (C) 2010-2018 Free Software Foundation, Inc.
2 
3  This file is part of GDB.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "server.h"
19 #include "lynx-low.h"
20 #include <limits.h>
21 #include <sys/ptrace.h>
22 #include "x86-xstate.h"
23 #include "arch/i386.h"
24 
25 /* The following two typedefs are defined in a .h file which is not
26  in the standard include path (/sys/include/family/x86/ucontext.h),
27  so we just duplicate them here. */
28 
29 /* General register context */
30 typedef struct usr_econtext {
31 
32  uint32_t uec_fault;
33  uint32_t uec_es;
34  uint32_t uec_ds;
35  uint32_t uec_edi;
36  uint32_t uec_esi;
37  uint32_t uec_ebp;
38  uint32_t uec_temp;
39  uint32_t uec_ebx;
40  uint32_t uec_edx;
41  uint32_t uec_ecx;
42  uint32_t uec_eax;
43  uint32_t uec_inum;
44  uint32_t uec_ecode;
45  uint32_t uec_eip;
46  uint32_t uec_cs;
47  uint32_t uec_eflags;
48  uint32_t uec_esp;
49  uint32_t uec_ss;
50  uint32_t uec_fs;
51  uint32_t uec_gs;
53 
54 /* Floating point and SIMD register context */
55 typedef struct usr_fcontext {
56  uint16_t ufc_control;
57  uint16_t ufc_status;
58  uint16_t ufc_tag;
59  uint16_t ufc_opcode;
60  uint8_t *ufc_inst_off;
61  uint32_t ufc_inst_sel;
62  uint8_t *ufc_data_off;
63  uint32_t ufc_data_sel;
64  uint32_t usse_mxcsr;
65  uint32_t usse_mxcsr_mask;
66  struct ufp387_real {
67  uint16_t umant4;
68  uint16_t umant3;
69  uint16_t umant2;
70  uint16_t umant1;
71  uint16_t us_and_e;
72  uint16_t ureserved_1;
73  uint16_t ureserved_2;
74  uint16_t ureserved_3;
75  } ufc_reg[8];
76  struct uxmm_register {
77  uint16_t uchunk_1;
78  uint16_t uchunk_2;
79  uint16_t uchunk_3;
80  uint16_t uchunk_4;
81  uint16_t uchunk_5;
82  uint16_t uchunk_6;
83  uint16_t uchunk_7;
84  uint16_t uchunk_8;
85  } uxmm_reg[8];
86  char ureserved[16][14];
88 
89 /* The index of various registers inside the regcache. */
90 
92 {
121 };
122 
123 /* The fill_function for the general-purpose register set. */
124 
125 static void
127 {
128 #define lynx_i386_collect_gp(regnum, fld) \
129  collect_register (regcache, regnum, \
130  buf + offsetof (usr_econtext_t, uec_##fld))
131 
148 }
149 
150 /* The store_function for the general-purpose register set. */
151 
152 static void
153 lynx_i386_store_gregset (struct regcache *regcache, const char *buf)
154 {
155 #define lynx_i386_supply_gp(regnum, fld) \
156  supply_register (regcache, regnum, \
157  buf + offsetof (usr_econtext_t, uec_##fld))
158 
175 }
176 
177 /* Extract the first 16 bits of register REGNUM in the REGCACHE,
178  and store these 2 bytes at DEST.
179 
180  This is useful to collect certain 16bit registers which are known
181  by GDBserver as 32bit registers (such as the Control Register
182  for instance). */
183 
184 static void
185 collect_16bit_register (struct regcache *regcache, int regnum, char *dest)
186 {
187  gdb_byte word[4];
188 
190  memcpy (dest, word, 2);
191 }
192 
193 /* The fill_function for the floating-point register set. */
194 
195 static void
197 {
198  int i;
199 
200  /* Collect %st0 .. %st7. */
201  for (i = 0; i < 8; i++)
203  buf + offsetof (usr_fcontext_t, ufc_reg)
204  + i * sizeof (struct ufp387_real));
205 
206  /* Collect the other FPU registers. */
208  buf + offsetof (usr_fcontext_t, ufc_control));
210  buf + offsetof (usr_fcontext_t, ufc_status));
212  buf + offsetof (usr_fcontext_t, ufc_tag));
214  buf + offsetof (usr_fcontext_t, ufc_inst_sel));
216  buf + offsetof (usr_fcontext_t, ufc_inst_off));
218  buf + offsetof (usr_fcontext_t, ufc_data_sel));
220  buf + offsetof (usr_fcontext_t, ufc_data_off));
222  buf + offsetof (usr_fcontext_t, ufc_opcode));
223 
224  /* Collect the XMM registers. */
225  for (i = 0; i < 8; i++)
227  buf + offsetof (usr_fcontext_t, uxmm_reg)
228  + i * sizeof (struct uxmm_register));
230  buf + offsetof (usr_fcontext_t, usse_mxcsr));
231 }
232 
233 /* This is the supply counterpart for collect_16bit_register:
234  It extracts a 2byte value from BUF, and uses that value to
235  set REGNUM's value in the regcache.
236 
237  This is useful to supply the value of certain 16bit registers
238  which are known by GDBserver as 32bit registers (such as the Control
239  Register for instance). */
240 
241 static void
242 supply_16bit_register (struct regcache *regcache, int regnum, const char *buf)
243 {
244  gdb_byte word[4];
245 
246  memcpy (word, buf, 2);
247  memset (word + 2, 0, 2);
249 }
250 
251 /* The store_function for the floating-point register set. */
252 
253 static void
254 lynx_i386_store_fpregset (struct regcache *regcache, const char *buf)
255 {
256  int i;
257 
258  /* Store the %st0 .. %st7 registers. */
259  for (i = 0; i < 8; i++)
261  buf + offsetof (usr_fcontext_t, ufc_reg)
262  + i * sizeof (struct ufp387_real));
263 
264  /* Store the other FPU registers. */
266  buf + offsetof (usr_fcontext_t, ufc_control));
268  buf + offsetof (usr_fcontext_t, ufc_status));
270  buf + offsetof (usr_fcontext_t, ufc_tag));
272  buf + offsetof (usr_fcontext_t, ufc_inst_sel));
274  buf + offsetof (usr_fcontext_t, ufc_inst_off));
276  buf + offsetof (usr_fcontext_t, ufc_data_sel));
278  buf + offsetof (usr_fcontext_t, ufc_data_off));
280  buf + offsetof (usr_fcontext_t, ufc_opcode));
281 
282  /* Store the XMM registers. */
283  for (i = 0; i < 8; i++)
285  buf + offsetof (usr_fcontext_t, uxmm_reg)
286  + i * sizeof (struct uxmm_register));
288  buf + offsetof (usr_fcontext_t, usse_mxcsr));
289 }
290 
291 /* Implements the lynx_target_ops.arch_setup routine. */
292 
293 static void
295 {
296  struct target_desc *tdesc
297  = i386_create_target_description (X86_XSTATE_SSE_MASK, false);
298 
299  init_target_desc (tdesc);
300 
301  lynx_tdesc = tdesc;
302 }
303 
304 /* Description of all the x86-lynx register sets. */
305 
307  /* General Purpose Registers. */
308  {PTRACE_GETREGS, PTRACE_SETREGS, sizeof(usr_econtext_t),
310  /* Floating Point Registers. */
311  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof(usr_fcontext_t),
313  /* End of list marker. */
314  {0, 0, -1, NULL, NULL }
315 };
316 
317 /* The lynx_target_ops vector for x86-lynx. */
318 
321 };
uint32_t uec_edi
Definition: lynx-i386-low.c:35
void collect_register(struct regcache *regcache, int n, void *buf)
Definition: regcache.c:402
uint16_t ufc_opcode
Definition: lynx-i386-low.c:59
uint32_t usse_mxcsr_mask
Definition: lynx-i386-low.c:65
uint16_t ufc_tag
Definition: lynx-i386-low.c:58
uint32_t uec_cs
Definition: lynx-i386-low.c:46
#define X86_XSTATE_SSE_MASK
Definition: x86-xstate.h:42
uint32_t uec_esi
Definition: lynx-i386-low.c:36
uint32_t uec_eflags
Definition: lynx-i386-low.c:47
uint32_t usse_mxcsr
Definition: lynx-i386-low.c:64
#define lynx_i386_supply_gp(regnum, fld)
uint32_t ufc_data_sel
Definition: lynx-i386-low.c:63
uint32_t uec_ebx
Definition: lynx-i386-low.c:39
void * memset(T *s, int c, size_t n)=delete
uint8_t * ufc_data_off
Definition: lynx-i386-low.c:62
uint32_t uec_fs
Definition: lynx-i386-low.c:50
uint32_t uec_fault
Definition: lynx-i386-low.c:32
uint32_t ufc_inst_sel
Definition: lynx-i386-low.c:61
uint32_t uec_edx
Definition: lynx-i386-low.c:40
#define lynx_i386_collect_gp(regnum, fld)
regnum
uint8_t * ufc_inst_off
Definition: lynx-i386-low.c:60
lynx_i386_gdb_regnum
Definition: lynx-i386-low.c:91
static void lynx_i386_store_fpregset(struct regcache *regcache, const char *buf)
uint32_t uec_gs
Definition: lynx-i386-low.c:51
uint32_t uec_ebp
Definition: lynx-i386-low.c:37
static void lynx_i386_arch_setup(void)
static void lynx_i386_fill_gregset(struct regcache *regcache, char *buf)
char ureserved[16][14]
Definition: lynx-i386-low.c:86
const struct target_desc * lynx_tdesc
Definition: lynx-low.c:36
uint32_t uec_ds
Definition: lynx-i386-low.c:34
uint32_t uec_ecode
Definition: lynx-i386-low.c:44
uint32_t uec_temp
Definition: lynx-i386-low.c:38
uint32_t uec_es
Definition: lynx-i386-low.c:33
uint16_t ufc_control
Definition: lynx-i386-low.c:56
uint32_t uec_ss
Definition: lynx-i386-low.c:49
uint32_t uec_inum
Definition: lynx-i386-low.c:43
struct usr_fcontext::ufp387_real ufc_reg[8]
struct usr_fcontext usr_fcontext_t
void init_target_desc(struct target_desc *tdesc)
Definition: tdesc.c:23
uint32_t uec_esp
Definition: lynx-i386-low.c:48
bfd_byte gdb_byte
Definition: common-types.h:38
uint32_t uec_ecx
Definition: lynx-i386-low.c:41
struct usr_fcontext::uxmm_register uxmm_reg[8]
static void supply_16bit_register(struct regcache *regcache, int regnum, const char *buf)
struct lynx_regset_info lynx_target_regsets[]
uint16_t ufc_status
Definition: lynx-i386-low.c:57
uint32_t uec_eip
Definition: lynx-i386-low.c:45
static void lynx_i386_store_gregset(struct regcache *regcache, const char *buf)
uint32_t uec_eax
Definition: lynx-i386-low.c:42
static void collect_16bit_register(struct regcache *regcache, int regnum, char *dest)
struct usr_econtext usr_econtext_t
void supply_register(struct regcache *regcache, int n, const void *buf)
Definition: regcache.c:318
struct lynx_target_ops the_low_target
static void lynx_i386_fill_fpregset(struct regcache *regcache, char *buf)