GDBserver
win32-i386-low.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-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 "win32-low.h"
20 #include "x86-low.h"
21 
22 #ifndef CONTEXT_EXTENDED_REGISTERS
23 #define CONTEXT_EXTENDED_REGISTERS 0
24 #endif
25 
26 #define FCS_REGNUM 27
27 #define FOP_REGNUM 31
28 
29 #define FLAG_TRACE_BIT 0x100
30 
31 #ifdef __x86_64__
32 /* Defined in auto-generated file reg-amd64.c. */
33 void init_registers_amd64 (void);
34 extern const struct target_desc *tdesc_amd64;
35 #else
36 /* Defined in auto-generated file reg-i386.c. */
37 void init_registers_i386 (void);
38 extern const struct target_desc *tdesc_i386;
39 #endif
40 
42 
43 static int
45  void *pid_p)
46 {
47  struct thread_info *thr = (struct thread_info *) entry;
49  int pid = *(int *) pid_p;
50 
51  /* Only update the threads of this process. */
52  if (pid_of (thr) == pid)
53  {
54  /* The actual update is done later just before resuming the lwp,
55  we just mark that the registers need updating. */
57  }
58 
59  return 0;
60 }
61 
62 /* Update the inferior's debug register REGNUM from STATE. */
63 
64 static void
66 {
67  /* Only update the threads of this process. */
68  int pid = pid_of (current_thread);
69 
70  gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
71 
73 }
74 
75 /* Update the inferior's DR7 debug control register from STATE. */
76 
77 static void
78 x86_dr_low_set_control (unsigned long control)
79 {
80  /* Only update the threads of this process. */
81  int pid = pid_of (current_thread);
82 
84 }
85 
86 /* Return the current value of a DR register of the current thread's
87  context. */
88 
89 static DWORD64
91 {
93 
95 
96 #define RET_DR(DR) \
97  case DR: \
98  return th->context.Dr ## DR
99 
100  switch (dr)
101  {
102  RET_DR (0);
103  RET_DR (1);
104  RET_DR (2);
105  RET_DR (3);
106  RET_DR (6);
107  RET_DR (7);
108  }
109 
110 #undef RET_DR
111 
112  gdb_assert_not_reached ("unhandled dr");
113 }
114 
115 static CORE_ADDR
117 {
118  gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
119 
120  return win32_get_current_dr (regnum - DR_FIRSTADDR);
121 }
122 
123 static unsigned long
125 {
126  return win32_get_current_dr (7);
127 }
128 
129 /* Get the value of the DR6 debug status register from the inferior
130  and record it in STATE. */
131 
132 static unsigned long
134 {
135  return win32_get_current_dr (6);
136 }
137 
138 /* Low-level function vector. */
139 struct x86_dr_low_type x86_dr_low =
140  {
146  sizeof (void *),
147  };
148 
149 /* Breakpoint/watchpoint support. */
150 
151 static int
153 {
154  switch (z_type)
155  {
156  case Z_PACKET_WRITE_WP:
157  case Z_PACKET_ACCESS_WP:
158  return 1;
159  default:
160  return 0;
161  }
162 }
163 
164 static int
166  int size, struct raw_breakpoint *bp)
167 {
168  switch (type)
169  {
172  {
173  enum target_hw_bp_type hw_type
175 
177  hw_type, addr, size);
178  }
179  default:
180  /* Unsupported. */
181  return 1;
182  }
183 }
184 
185 static int
187  int size, struct raw_breakpoint *bp)
188 {
189  switch (type)
190  {
193  {
194  enum target_hw_bp_type hw_type
196 
198  hw_type, addr, size);
199  }
200  default:
201  /* Unsupported. */
202  return 1;
203  }
204 }
205 
206 static int
208 {
210 }
211 
212 static CORE_ADDR
214 {
215  CORE_ADDR addr;
217  return addr;
218  return 0;
219 }
220 
221 static void
223 {
225 }
226 
227 static void
229 {
230  /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
231  the system doesn't support extended registers. */
232  static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS;
233 
234  again:
235  th->context.ContextFlags = (CONTEXT_FULL
237  | CONTEXT_DEBUG_REGISTERS
238  | extended_registers);
239 
240  if (!GetThreadContext (th->h, &th->context))
241  {
242  DWORD e = GetLastError ();
243 
244  if (extended_registers && e == ERROR_INVALID_PARAMETER)
245  {
246  extended_registers = 0;
247  goto again;
248  }
249 
250  error ("GetThreadContext failure %ld\n", (long) e);
251  }
252 }
253 
254 static void
256 {
257  if (th->debug_registers_changed)
258  {
259  struct x86_debug_reg_state *dr = &debug_reg_state;
260 
262 
263  th->context.Dr0 = dr->dr_mirror[0];
264  th->context.Dr1 = dr->dr_mirror[1];
265  th->context.Dr2 = dr->dr_mirror[2];
266  th->context.Dr3 = dr->dr_mirror[3];
267  /* th->context.Dr6 = dr->dr_status_mirror;
268  FIXME: should we set dr6 also ?? */
269  th->context.Dr7 = dr->dr_control_mirror;
270 
271  th->debug_registers_changed = 0;
272  }
273 }
274 
275 static void
277 {
278  th->debug_registers_changed = 1;
279 }
280 
281 static void
283 {
284  th->context.EFlags |= FLAG_TRACE_BIT;
285 }
286 
287 #ifndef __x86_64__
288 
289 /* An array of offset mappings into a Win32 Context structure.
290  This is a one-to-one mapping which is indexed by gdb's register
291  numbers. It retrieves an offset into the context structure where
292  the 4 byte register is located.
293  An offset value of -1 indicates that Win32 does not provide this
294  register in it's CONTEXT structure. In this case regptr will return
295  a pointer into a dummy register. */
296 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
297 static const int mappings[] = {
298  context_offset (Eax),
299  context_offset (Ecx),
300  context_offset (Edx),
301  context_offset (Ebx),
302  context_offset (Esp),
303  context_offset (Ebp),
304  context_offset (Esi),
305  context_offset (Edi),
306  context_offset (Eip),
307  context_offset (EFlags),
308  context_offset (SegCs),
309  context_offset (SegSs),
310  context_offset (SegDs),
311  context_offset (SegEs),
312  context_offset (SegFs),
313  context_offset (SegGs),
314  context_offset (FloatSave.RegisterArea[0 * 10]),
315  context_offset (FloatSave.RegisterArea[1 * 10]),
316  context_offset (FloatSave.RegisterArea[2 * 10]),
317  context_offset (FloatSave.RegisterArea[3 * 10]),
318  context_offset (FloatSave.RegisterArea[4 * 10]),
319  context_offset (FloatSave.RegisterArea[5 * 10]),
320  context_offset (FloatSave.RegisterArea[6 * 10]),
321  context_offset (FloatSave.RegisterArea[7 * 10]),
322  context_offset (FloatSave.ControlWord),
323  context_offset (FloatSave.StatusWord),
324  context_offset (FloatSave.TagWord),
325  context_offset (FloatSave.ErrorSelector),
326  context_offset (FloatSave.ErrorOffset),
327  context_offset (FloatSave.DataSelector),
328  context_offset (FloatSave.DataOffset),
329  context_offset (FloatSave.ErrorSelector),
330  /* XMM0-7 */
331  context_offset (ExtendedRegisters[10 * 16]),
332  context_offset (ExtendedRegisters[11 * 16]),
333  context_offset (ExtendedRegisters[12 * 16]),
334  context_offset (ExtendedRegisters[13 * 16]),
335  context_offset (ExtendedRegisters[14 * 16]),
336  context_offset (ExtendedRegisters[15 * 16]),
337  context_offset (ExtendedRegisters[16 * 16]),
338  context_offset (ExtendedRegisters[17 * 16]),
339  /* MXCSR */
340  context_offset (ExtendedRegisters[24])
341 };
342 #undef context_offset
343 
344 #else /* __x86_64__ */
345 
346 #define context_offset(x) (offsetof (CONTEXT, x))
347 static const int mappings[] =
348 {
349  context_offset (Rax),
350  context_offset (Rbx),
351  context_offset (Rcx),
352  context_offset (Rdx),
353  context_offset (Rsi),
354  context_offset (Rdi),
355  context_offset (Rbp),
356  context_offset (Rsp),
357  context_offset (R8),
358  context_offset (R9),
359  context_offset (R10),
360  context_offset (R11),
361  context_offset (R12),
362  context_offset (R13),
363  context_offset (R14),
364  context_offset (R15),
365  context_offset (Rip),
366  context_offset (EFlags),
367  context_offset (SegCs),
368  context_offset (SegSs),
369  context_offset (SegDs),
370  context_offset (SegEs),
371  context_offset (SegFs),
372  context_offset (SegGs),
373  context_offset (FloatSave.FloatRegisters[0]),
374  context_offset (FloatSave.FloatRegisters[1]),
375  context_offset (FloatSave.FloatRegisters[2]),
376  context_offset (FloatSave.FloatRegisters[3]),
377  context_offset (FloatSave.FloatRegisters[4]),
378  context_offset (FloatSave.FloatRegisters[5]),
379  context_offset (FloatSave.FloatRegisters[6]),
380  context_offset (FloatSave.FloatRegisters[7]),
381  context_offset (FloatSave.ControlWord),
382  context_offset (FloatSave.StatusWord),
383  context_offset (FloatSave.TagWord),
384  context_offset (FloatSave.ErrorSelector),
385  context_offset (FloatSave.ErrorOffset),
386  context_offset (FloatSave.DataSelector),
387  context_offset (FloatSave.DataOffset),
388  context_offset (FloatSave.ErrorSelector)
389  /* XMM0-7 */ ,
390  context_offset (Xmm0),
391  context_offset (Xmm1),
392  context_offset (Xmm2),
393  context_offset (Xmm3),
394  context_offset (Xmm4),
395  context_offset (Xmm5),
396  context_offset (Xmm6),
397  context_offset (Xmm7),
398  context_offset (Xmm8),
399  context_offset (Xmm9),
400  context_offset (Xmm10),
401  context_offset (Xmm11),
402  context_offset (Xmm12),
403  context_offset (Xmm13),
404  context_offset (Xmm14),
405  context_offset (Xmm15),
406  /* MXCSR */
407  context_offset (FloatSave.MxCsr)
408 };
409 #undef context_offset
410 
411 #endif /* __x86_64__ */
412 
413 /* Fetch register from gdbserver regcache data. */
414 static void
416  win32_thread_info *th, int r)
417 {
418  char *context_offset = (char *) &th->context + mappings[r];
419 
420  long l;
421  if (r == FCS_REGNUM)
422  {
423  l = *((long *) context_offset) & 0xffff;
424  supply_register (regcache, r, (char *) &l);
425  }
426  else if (r == FOP_REGNUM)
427  {
428  l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
429  supply_register (regcache, r, (char *) &l);
430  }
431  else
432  supply_register (regcache, r, context_offset);
433 }
434 
435 /* Store a new register value into the thread context of TH. */
436 static void
438  win32_thread_info *th, int r)
439 {
440  char *context_offset = (char *) &th->context + mappings[r];
441  collect_register (regcache, r, context_offset);
442 }
443 
444 static const unsigned char i386_win32_breakpoint = 0xcc;
445 #define i386_win32_breakpoint_len 1
446 
447 static void
449 {
450 #ifdef __x86_64__
451  init_registers_amd64 ();
452  win32_tdesc = tdesc_amd64;
453 #else
456 #endif
457 }
458 
459 struct win32_target_ops the_low_target = {
461  sizeof (mappings) / sizeof (mappings[0]),
476 };
enum target_hw_bp_type raw_bkpt_type_to_target_hw_bp_type(enum raw_bkpt_type raw_type)
Definition: mem-break.c:195
struct thread_info * current_thread
Definition: inferiors.c:28
void collect_register(struct regcache *regcache, int n, void *buf)
Definition: regcache.c:414
#define FCS_REGNUM
static void i386_prepare_to_resume(win32_thread_info *th)
bfd_vma CORE_ADDR
Definition: common-types.h:41
static int i386_supports_z_point_type(char z_type)
unsigned dr_control_mirror
Definition: x86-dregs.h:85
int x86_dr_remove_watchpoint(struct x86_debug_reg_state *state, enum target_hw_bp_type type, CORE_ADDR addr, int len)
Definition: x86-dregs.c:516
static void i386_get_thread_context(win32_thread_info *th)
regnum
int x86_dr_stopped_data_address(struct x86_debug_reg_state *state, CORE_ADDR *addr_p)
Definition: x86-dregs.c:571
static CORE_ADDR x86_dr_low_get_addr(int regnum)
void init_registers_i386(void)
static unsigned long x86_dr_low_get_control(void)
void win32_require_context(win32_thread_info *th)
Definition: win32-low.c:169
#define DR_FIRSTADDR
Definition: x86-dregs.h:69
#define FOP_REGNUM
static int update_debug_registers_callback(struct inferior_list_entry *entry, void *pid_p)
void * inferior_target_data(struct thread_info *inferior)
Definition: inferiors.c:222
int x86_dr_insert_watchpoint(struct x86_debug_reg_state *state, enum target_hw_bp_type type, CORE_ADDR addr, int len)
Definition: x86-dregs.c:474
#define context_offset(x)
static CORE_ADDR x86_stopped_data_address(void)
raw_bkpt_type
Definition: mem-break.h:40
CORE_ADDR dr_mirror[DR_NADDR]
Definition: x86-dregs.h:84
#define CONTEXT_EXTENDED_REGISTERS
static struct x86_debug_reg_state debug_reg_state
HMODULE DWORD
Definition: win32-low.c:1097
#define gdb_assert_not_reached(message)
Definition: gdb_assert.h:56
#define gdb_assert(expr)
Definition: gdb_assert.h:33
static int x86_stopped_by_watchpoint(void)
static unsigned long x86_dr_low_get_status(void)
static int i386_insert_point(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
struct inferior_list all_threads
Definition: inferiors.c:26
int x86_dr_stopped_by_watchpoint(struct x86_debug_reg_state *state)
Definition: x86-dregs.c:651
#define FLAG_TRACE_BIT
void x86_low_init_dregs(struct x86_debug_reg_state *state)
Definition: x86-low.c:27
static void i386_thread_added(win32_thread_info *th)
#define CONTEXT_FLOATING_POINT
Definition: win32-arm-low.c:22
#define i386_win32_breakpoint_len
int debug_registers_changed
Definition: win32-low.h:53
const struct target_desc * tdesc_i386
static const int mappings[]
#define pid_of(inf)
Definition: inferiors.h:76
static void i386_arch_setup(void)
const struct target_desc * win32_tdesc
Definition: win32-low.c:93
static void i386_single_step(win32_thread_info *th)
#define Z_PACKET_ACCESS_WP
Definition: mem-break.h:36
static void x86_dr_low_set_control(unsigned long control)
target_hw_bp_type
Definition: break-common.h:22
CONTEXT context
Definition: win32-low.h:49
static void x86_dr_low_set_addr(int regnum, CORE_ADDR addr)
Definition: inferiors.h:29
static void i386_initial_stuff(void)
static const unsigned char i386_win32_breakpoint
void supply_register(struct regcache *regcache, int n, const void *buf)
Definition: regcache.c:330
void error(const char *fmt,...)
Definition: errors.c:38
static int i386_remove_point(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
#define RET_DR(DR)
#define DR_LASTADDR
Definition: x86-dregs.h:70
#define Z_PACKET_WRITE_WP
Definition: mem-break.h:34
struct inferior_list_entry * find_inferior(struct inferior_list *list, int(*func)(struct inferior_list_entry *, void *), void *arg)
Definition: inferiors.c:188
static void i386_fetch_inferior_register(struct regcache *regcache, win32_thread_info *th, int r)
static void i386_store_inferior_register(struct regcache *regcache, win32_thread_info *th, int r)
static DWORD64 win32_get_current_dr(int dr)