GDBserver
lynx-i386-low.c
Go to the documentation of this file.
1 /* Copyright (C) 2010-2015 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 
23 /* The following two typedefs are defined in a .h file which is not
24  in the standard include path (/sys/include/family/x86/ucontext.h),
25  so we just duplicate them here. */
26 
27 /* General register context */
28 typedef struct usr_econtext {
29 
30  uint32_t uec_fault;
31  uint32_t uec_es;
32  uint32_t uec_ds;
33  uint32_t uec_edi;
34  uint32_t uec_esi;
35  uint32_t uec_ebp;
36  uint32_t uec_temp;
37  uint32_t uec_ebx;
38  uint32_t uec_edx;
39  uint32_t uec_ecx;
40  uint32_t uec_eax;
41  uint32_t uec_inum;
42  uint32_t uec_ecode;
43  uint32_t uec_eip;
44  uint32_t uec_cs;
45  uint32_t uec_eflags;
46  uint32_t uec_esp;
47  uint32_t uec_ss;
48  uint32_t uec_fs;
49  uint32_t uec_gs;
51 
52 /* Floating point and SIMD register context */
53 typedef struct usr_fcontext {
54  uint16_t ufc_control;
55  uint16_t ufc_status;
56  uint16_t ufc_tag;
57  uint16_t ufc_opcode;
58  uint8_t *ufc_inst_off;
59  uint32_t ufc_inst_sel;
60  uint8_t *ufc_data_off;
61  uint32_t ufc_data_sel;
62  uint32_t usse_mxcsr;
63  uint32_t usse_mxcsr_mask;
64  struct ufp387_real {
65  uint16_t umant4;
66  uint16_t umant3;
67  uint16_t umant2;
68  uint16_t umant1;
69  uint16_t us_and_e;
70  uint16_t ureserved_1;
71  uint16_t ureserved_2;
72  uint16_t ureserved_3;
73  } ufc_reg[8];
74  struct uxmm_register {
75  uint16_t uchunk_1;
76  uint16_t uchunk_2;
77  uint16_t uchunk_3;
78  uint16_t uchunk_4;
79  uint16_t uchunk_5;
80  uint16_t uchunk_6;
81  uint16_t uchunk_7;
82  uint16_t uchunk_8;
83  } uxmm_reg[8];
84  char ureserved[16][14];
86 
87 /* The index of various registers inside the regcache. */
88 
90 {
119 };
120 
121 /* Defined in auto-generated file i386.c. */
122 extern void init_registers_i386 (void);
123 extern const struct target_desc *tdesc_i386;
124 
125 /* The fill_function for the general-purpose register set. */
126 
127 static void
129 {
130 #define lynx_i386_collect_gp(regnum, fld) \
131  collect_register (regcache, regnum, \
132  buf + offsetof (usr_econtext_t, uec_##fld))
133 
150 }
151 
152 /* The store_function for the general-purpose register set. */
153 
154 static void
155 lynx_i386_store_gregset (struct regcache *regcache, const char *buf)
156 {
157 #define lynx_i386_supply_gp(regnum, fld) \
158  supply_register (regcache, regnum, \
159  buf + offsetof (usr_econtext_t, uec_##fld))
160 
177 }
178 
179 /* Extract the first 16 bits of register REGNUM in the REGCACHE,
180  and store these 2 bytes at DEST.
181 
182  This is useful to collect certain 16bit registers which are known
183  by GDBserver as 32bit registers (such as the Control Register
184  for instance). */
185 
186 static void
187 collect_16bit_register (struct regcache *regcache, int regnum, char *dest)
188 {
189  gdb_byte word[4];
190 
191  collect_register (regcache, regnum, word);
192  memcpy (dest, word, 2);
193 }
194 
195 /* The fill_function for the floating-point register set. */
196 
197 static void
199 {
200  int i;
201 
202  /* Collect %st0 .. %st7. */
203  for (i = 0; i < 8; i++)
204  collect_register (regcache, I386_ST0_REGNUM + i,
205  buf + offsetof (usr_fcontext_t, ufc_reg)
206  + i * sizeof (struct ufp387_real));
207 
208  /* Collect the other FPU registers. */
210  buf + offsetof (usr_fcontext_t, ufc_control));
212  buf + offsetof (usr_fcontext_t, ufc_status));
214  buf + offsetof (usr_fcontext_t, ufc_tag));
216  buf + offsetof (usr_fcontext_t, ufc_inst_sel));
218  buf + offsetof (usr_fcontext_t, ufc_inst_off));
220  buf + offsetof (usr_fcontext_t, ufc_data_sel));
222  buf + offsetof (usr_fcontext_t, ufc_data_off));
224  buf + offsetof (usr_fcontext_t, ufc_opcode));
225 
226  /* Collect the XMM registers. */
227  for (i = 0; i < 8; i++)
228  collect_register (regcache, I386_XMM0_REGNUM + i,
229  buf + offsetof (usr_fcontext_t, uxmm_reg)
230  + i * sizeof (struct uxmm_register));
232  buf + offsetof (usr_fcontext_t, usse_mxcsr));
233 }
234 
235 /* This is the supply counterpart for collect_16bit_register:
236  It extracts a 2byte value from BUF, and uses that value to
237  set REGNUM's value in the regcache.
238 
239  This is useful to supply the value of certain 16bit registers
240  which are known by GDBserver as 32bit registers (such as the Control
241  Register for instance). */
242 
243 static void
244 supply_16bit_register (struct regcache *regcache, int regnum, const char *buf)
245 {
246  gdb_byte word[4];
247 
248  memcpy (word, buf, 2);
249  memset (word + 2, 0, 2);
250  supply_register (regcache, regnum, word);
251 }
252 
253 /* The store_function for the floating-point register set. */
254 
255 static void
256 lynx_i386_store_fpregset (struct regcache *regcache, const char *buf)
257 {
258  int i;
259 
260  /* Store the %st0 .. %st7 registers. */
261  for (i = 0; i < 8; i++)
262  supply_register (regcache, I386_ST0_REGNUM + i,
263  buf + offsetof (usr_fcontext_t, ufc_reg)
264  + i * sizeof (struct ufp387_real));
265 
266  /* Store the other FPU registers. */
268  buf + offsetof (usr_fcontext_t, ufc_control));
270  buf + offsetof (usr_fcontext_t, ufc_status));
272  buf + offsetof (usr_fcontext_t, ufc_tag));
274  buf + offsetof (usr_fcontext_t, ufc_inst_sel));
276  buf + offsetof (usr_fcontext_t, ufc_inst_off));
278  buf + offsetof (usr_fcontext_t, ufc_data_sel));
280  buf + offsetof (usr_fcontext_t, ufc_data_off));
282  buf + offsetof (usr_fcontext_t, ufc_opcode));
283 
284  /* Store the XMM registers. */
285  for (i = 0; i < 8; i++)
286  supply_register (regcache, I386_XMM0_REGNUM + i,
287  buf + offsetof (usr_fcontext_t, uxmm_reg)
288  + i * sizeof (struct uxmm_register));
290  buf + offsetof (usr_fcontext_t, usse_mxcsr));
291 }
292 
293 /* Implements the lynx_target_ops.arch_setup routine. */
294 
295 static void
297 {
300 }
301 
302 /* Description of all the x86-lynx register sets. */
303 
304 struct lynx_regset_info lynx_target_regsets[] = {
305  /* General Purpose Registers. */
306  {PTRACE_GETREGS, PTRACE_SETREGS, sizeof(usr_econtext_t),
308  /* Floating Point Registers. */
309  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof(usr_fcontext_t),
311  /* End of list marker. */
312  {0, 0, -1, NULL, NULL }
313 };
314 
315 /* The lynx_target_ops vector for x86-lynx. */
316 
317 struct lynx_target_ops the_low_target = {
319 };
uint32_t uec_edi
Definition: lynx-i386-low.c:33
void collect_register(struct regcache *regcache, int n, void *buf)
Definition: regcache.c:414
uint16_t ufc_opcode
Definition: lynx-i386-low.c:57
const struct target_desc * tdesc_i386
uint32_t usse_mxcsr_mask
Definition: lynx-i386-low.c:63
uint16_t ufc_tag
Definition: lynx-i386-low.c:56
uint32_t uec_cs
Definition: lynx-i386-low.c:44
uint32_t uec_esi
Definition: lynx-i386-low.c:34
uint32_t uec_eflags
Definition: lynx-i386-low.c:45
uint32_t usse_mxcsr
Definition: lynx-i386-low.c:62
#define lynx_i386_supply_gp(regnum, fld)
uint32_t ufc_data_sel
Definition: lynx-i386-low.c:61
uint32_t uec_ebx
Definition: lynx-i386-low.c:37
uint8_t * ufc_data_off
Definition: lynx-i386-low.c:60
uint32_t uec_fs
Definition: lynx-i386-low.c:48
uint32_t uec_fault
Definition: lynx-i386-low.c:30
uint32_t ufc_inst_sel
Definition: lynx-i386-low.c:59
uint32_t uec_edx
Definition: lynx-i386-low.c:38
#define lynx_i386_collect_gp(regnum, fld)
regnum
uint8_t * ufc_inst_off
Definition: lynx-i386-low.c:58
lynx_i386_gdb_regnum
Definition: lynx-i386-low.c:89
static void lynx_i386_store_fpregset(struct regcache *regcache, const char *buf)
uint32_t uec_gs
Definition: lynx-i386-low.c:49
uint32_t uec_ebp
Definition: lynx-i386-low.c:35
static void lynx_i386_arch_setup(void)
void init_registers_i386(void)
static void lynx_i386_fill_gregset(struct regcache *regcache, char *buf)
char ureserved[16][14]
Definition: lynx-i386-low.c:84
const struct target_desc * lynx_tdesc
Definition: lynx-low.c:34
uint32_t uec_ds
Definition: lynx-i386-low.c:32
uint32_t uec_ecode
Definition: lynx-i386-low.c:42
uint32_t uec_temp
Definition: lynx-i386-low.c:36
uint32_t uec_es
Definition: lynx-i386-low.c:31
uint16_t ufc_control
Definition: lynx-i386-low.c:54
uint32_t uec_ss
Definition: lynx-i386-low.c:47
uint32_t uec_inum
Definition: lynx-i386-low.c:41
struct usr_fcontext::ufp387_real ufc_reg[8]
struct usr_fcontext usr_fcontext_t
uint32_t uec_esp
Definition: lynx-i386-low.c:46
bfd_byte gdb_byte
Definition: common-types.h:38
uint32_t uec_ecx
Definition: lynx-i386-low.c:39
struct usr_fcontext::uxmm_register uxmm_reg[8]
static void supply_16bit_register(struct regcache *regcache, int regnum, const char *buf)
uint16_t ufc_status
Definition: lynx-i386-low.c:55
uint32_t uec_eip
Definition: lynx-i386-low.c:43
static void lynx_i386_store_gregset(struct regcache *regcache, const char *buf)
uint32_t uec_eax
Definition: lynx-i386-low.c:40
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:330
static void lynx_i386_fill_fpregset(struct regcache *regcache, char *buf)