a242f7258af194ac04ab09011100168ca0a70d83
[external/binutils.git] / gdb / gdbserver / win32-i386-low.c
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
37 static struct x86_debug_reg_state debug_reg_state;
38
39 static void
40 update_debug_registers (thread_info *thread)
41 {
42   win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
43
44   /* The actual update is done later just before resuming the lwp,
45      we just mark that the registers need updating.  */
46   th->debug_registers_changed = 1;
47 }
48
49 /* Update the inferior's debug register REGNUM from STATE.  */
50
51 static void
52 x86_dr_low_set_addr (int regnum, CORE_ADDR addr)
53 {
54   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
55
56   /* Only update the threads of this process.  */
57   for_each_thread (current_thread->id.pid (), update_debug_registers);
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.  */
66   for_each_thread (current_thread->id.pid (), update_debug_registers);
67 }
68
69 /* Return the current value of a DR register of the current thread's
70    context.  */
71
72 static DWORD64
73 win32_get_current_dr (int dr)
74 {
75   win32_thread_info *th
76     = (win32_thread_info *) thread_target_data (current_thread);
77
78   win32_require_context (th);
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
100 x86_dr_low_get_addr (int regnum)
101 {
102   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
103
104   return win32_get_current_dr (regnum - DR_FIRSTADDR);
105 }
106
107 static unsigned long
108 x86_dr_low_get_control (void)
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
117 x86_dr_low_get_status (void)
118 {
119   return win32_get_current_dr (6);
120 }
121
122 /* Low-level function vector.  */
123 struct x86_dr_low_type x86_dr_low =
124   {
125     x86_dr_low_set_control,
126     x86_dr_low_set_addr,
127     x86_dr_low_get_addr,
128     x86_dr_low_get_status,
129     x86_dr_low_get_control,
130     sizeof (void *),
131   };
132
133 /* Breakpoint/watchpoint support.  */
134
135 static int
136 i386_supports_z_point_type (char z_type)
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
149 i386_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
150                    int size, struct raw_breakpoint *bp)
151 {
152   switch (type)
153     {
154     case raw_bkpt_type_write_wp:
155     case raw_bkpt_type_access_wp:
156       {
157         enum target_hw_bp_type hw_type
158           = raw_bkpt_type_to_target_hw_bp_type (type);
159
160         return x86_dr_insert_watchpoint (&debug_reg_state,
161                                          hw_type, addr, size);
162       }
163     default:
164       /* Unsupported.  */
165       return 1;
166     }
167 }
168
169 static int
170 i386_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
171                    int size, struct raw_breakpoint *bp)
172 {
173   switch (type)
174     {
175     case raw_bkpt_type_write_wp:
176     case raw_bkpt_type_access_wp:
177       {
178         enum target_hw_bp_type hw_type
179           = raw_bkpt_type_to_target_hw_bp_type (type);
180
181         return x86_dr_remove_watchpoint (&debug_reg_state,
182                                          hw_type, addr, size);
183       }
184     default:
185       /* Unsupported.  */
186       return 1;
187     }
188 }
189
190 static int
191 x86_stopped_by_watchpoint (void)
192 {
193   return x86_dr_stopped_by_watchpoint (&debug_reg_state);
194 }
195
196 static CORE_ADDR
197 x86_stopped_data_address (void)
198 {
199   CORE_ADDR addr;
200   if (x86_dr_stopped_data_address (&debug_reg_state, &addr))
201     return addr;
202   return 0;
203 }
204
205 static void
206 i386_initial_stuff (void)
207 {
208   x86_low_init_dregs (&debug_reg_state);
209 }
210
211 static void
212 i386_get_thread_context (win32_thread_info *th)
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
220                               | CONTEXT_FLOATING_POINT
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
239 i386_prepare_to_resume (win32_thread_info *th)
240 {
241   if (th->debug_registers_changed)
242     {
243       struct x86_debug_reg_state *dr = &debug_reg_state;
244
245       win32_require_context (th);
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
260 i386_thread_added (win32_thread_info *th)
261 {
262   th->debug_registers_changed = 1;
263 }
264
265 static void
266 i386_single_step (win32_thread_info *th)
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
399 i386_fetch_inferior_register (struct regcache *regcache,
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
416     supply_register (regcache, r, context_offset);
417 }
418
419 /* Store a new register value into the thread context of TH.  */
420 static void
421 i386_store_inferior_register (struct regcache *regcache,
422                               win32_thread_info *th, int r)
423 {
424   char *context_offset = (char *) &th->context + mappings[r];
425   collect_register (regcache, r, context_offset);
426 }
427
428 static const unsigned char i386_win32_breakpoint = 0xcc;
429 #define i386_win32_breakpoint_len 1
430
431 static void
432 i386_arch_setup (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
448 struct win32_target_ops the_low_target = {
449   i386_arch_setup,
450   sizeof (mappings) / sizeof (mappings[0]),
451   i386_initial_stuff,
452   i386_get_thread_context,
453   i386_prepare_to_resume,
454   i386_thread_added,
455   i386_fetch_inferior_register,
456   i386_store_inferior_register,
457   i386_single_step,
458   &i386_win32_breakpoint,
459   i386_win32_breakpoint_len,
460   i386_supports_z_point_type,
461   i386_insert_point,
462   i386_remove_point,
463   x86_stopped_by_watchpoint,
464   x86_stopped_data_address
465 };