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