1 /* Copyright (C) 2007-2021 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 "gdbsupport/x86-xstate.h"
22 #ifdef __x86_64__
23 #include "arch/amd64.h"
24 #endif
25 #include "arch/i386.h"
26 #include "tdesc.h"
27 #include "x86-tdesc.h"
28 
29 using namespace windows_nat;
30 
31 #ifndef CONTEXT_EXTENDED_REGISTERS
32 #define CONTEXT_EXTENDED_REGISTERS 0
33 #endif
34 
35 #define FCS_REGNUM 27
36 #define FOP_REGNUM 31
37 
38 #define FLAG_TRACE_BIT 0x100
39 
40 static struct x86_debug_reg_state debug_reg_state;
41 
42 static void
update_debug_registers(thread_info * thread)43 update_debug_registers (thread_info *thread)
44 {
45   windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
46 
47   /* The actual update is done later just before resuming the lwp,
48      we just mark that the registers need updating.  */
49   th->debug_registers_changed = true;
50 }
51 
52 /* Update the inferior's debug register REGNUM from STATE.  */
53 
54 static void
x86_dr_low_set_addr(int regnum,CORE_ADDR addr)55 x86_dr_low_set_addr (int regnum, CORE_ADDR addr)
56 {
57   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
58 
59   /* Only update the threads of this process.  */
60   for_each_thread (current_thread->id.pid (), update_debug_registers);
61 }
62 
63 /* Update the inferior's DR7 debug control register from STATE.  */
64 
65 static void
x86_dr_low_set_control(unsigned long control)66 x86_dr_low_set_control (unsigned long control)
67 {
68   /* Only update the threads of this process.  */
69   for_each_thread (current_thread->id.pid (), update_debug_registers);
70 }
71 
72 /* Return the current value of a DR register of the current thread's
73    context.  */
74 
75 static DWORD64
win32_get_current_dr(int dr)76 win32_get_current_dr (int dr)
77 {
78   windows_thread_info *th
79     = (windows_thread_info *) thread_target_data (current_thread);
80 
81   win32_require_context (th);
82 
83 #ifdef __x86_64__
84 #define RET_DR(DR)				\
85   case DR:					\
86     return th->wow64_context.Dr ## DR
87 
88   if (wow64_process)
89     {
90       switch (dr)
91 	{
92 	  RET_DR (0);
93 	  RET_DR (1);
94 	  RET_DR (2);
95 	  RET_DR (3);
96 	  RET_DR (6);
97 	  RET_DR (7);
98 	}
99     }
100   else
101 #undef RET_DR
102 #endif
103 #define RET_DR(DR)				\
104   case DR:					\
105     return th->context.Dr ## DR
106 
107     {
108       switch (dr)
109 	{
110 	  RET_DR (0);
111 	  RET_DR (1);
112 	  RET_DR (2);
113 	  RET_DR (3);
114 	  RET_DR (6);
115 	  RET_DR (7);
116 	}
117     }
118 
119 #undef RET_DR
120 
121   gdb_assert_not_reached ("unhandled dr");
122 }
123 
124 static CORE_ADDR
x86_dr_low_get_addr(int regnum)125 x86_dr_low_get_addr (int regnum)
126 {
127   gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
128 
129   return win32_get_current_dr (regnum - DR_FIRSTADDR);
130 }
131 
132 static unsigned long
x86_dr_low_get_control(void)133 x86_dr_low_get_control (void)
134 {
135   return win32_get_current_dr (7);
136 }
137 
138 /* Get the value of the DR6 debug status register from the inferior
139    and record it in STATE.  */
140 
141 static unsigned long
x86_dr_low_get_status(void)142 x86_dr_low_get_status (void)
143 {
144   return win32_get_current_dr (6);
145 }
146 
147 /* Low-level function vector.  */
148 struct x86_dr_low_type x86_dr_low =
149   {
150     x86_dr_low_set_control,
151     x86_dr_low_set_addr,
152     x86_dr_low_get_addr,
153     x86_dr_low_get_status,
154     x86_dr_low_get_control,
155     sizeof (void *),
156   };
157 
158 /* Breakpoint/watchpoint support.  */
159 
160 static int
i386_supports_z_point_type(char z_type)161 i386_supports_z_point_type (char z_type)
162 {
163   switch (z_type)
164     {
165     case Z_PACKET_HW_BP:
166     case Z_PACKET_WRITE_WP:
167     case Z_PACKET_ACCESS_WP:
168       return 1;
169     default:
170       return 0;
171     }
172 }
173 
174 static int
i386_insert_point(enum raw_bkpt_type type,CORE_ADDR addr,int size,struct raw_breakpoint * bp)175 i386_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
176 		   int size, struct raw_breakpoint *bp)
177 {
178   switch (type)
179     {
180     case raw_bkpt_type_hw:
181     case raw_bkpt_type_write_wp:
182     case raw_bkpt_type_access_wp:
183       {
184 	enum target_hw_bp_type hw_type
185 	  = raw_bkpt_type_to_target_hw_bp_type (type);
186 
187 	return x86_dr_insert_watchpoint (&debug_reg_state,
188 					 hw_type, addr, size);
189       }
190     default:
191       /* Unsupported.  */
192       return 1;
193     }
194 }
195 
196 static int
i386_remove_point(enum raw_bkpt_type type,CORE_ADDR addr,int size,struct raw_breakpoint * bp)197 i386_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
198 		   int size, struct raw_breakpoint *bp)
199 {
200   switch (type)
201     {
202     case raw_bkpt_type_hw:
203     case raw_bkpt_type_write_wp:
204     case raw_bkpt_type_access_wp:
205       {
206 	enum target_hw_bp_type hw_type
207 	  = raw_bkpt_type_to_target_hw_bp_type (type);
208 
209 	return x86_dr_remove_watchpoint (&debug_reg_state,
210 					 hw_type, addr, size);
211       }
212     default:
213       /* Unsupported.  */
214       return 1;
215     }
216 }
217 
218 static int
x86_stopped_by_watchpoint(void)219 x86_stopped_by_watchpoint (void)
220 {
221   return x86_dr_stopped_by_watchpoint (&debug_reg_state);
222 }
223 
224 static CORE_ADDR
x86_stopped_data_address(void)225 x86_stopped_data_address (void)
226 {
227   CORE_ADDR addr;
228   if (x86_dr_stopped_data_address (&debug_reg_state, &addr))
229     return addr;
230   return 0;
231 }
232 
233 static void
i386_initial_stuff(void)234 i386_initial_stuff (void)
235 {
236   x86_low_init_dregs (&debug_reg_state);
237 }
238 
239 static void
i386_get_thread_context(windows_thread_info * th)240 i386_get_thread_context (windows_thread_info *th)
241 {
242   /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
243      the system doesn't support extended registers.  */
244   static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS;
245 
246  again:
247 #ifdef __x86_64__
248   if (wow64_process)
249     th->wow64_context.ContextFlags = (CONTEXT_FULL
250 				      | CONTEXT_FLOATING_POINT
251 				      | CONTEXT_DEBUG_REGISTERS
252 				      | extended_registers);
253   else
254 #endif
255     th->context.ContextFlags = (CONTEXT_FULL
256 				| CONTEXT_FLOATING_POINT
257 				| CONTEXT_DEBUG_REGISTERS
258 				| extended_registers);
259 
260   BOOL ret;
261 #ifdef __x86_64__
262   if (wow64_process)
263     ret = Wow64GetThreadContext (th->h, &th->wow64_context);
264   else
265 #endif
266     ret = GetThreadContext (th->h, &th->context);
267   if (!ret)
268     {
269       DWORD e = GetLastError ();
270 
271       if (extended_registers && e == ERROR_INVALID_PARAMETER)
272 	{
273 	  extended_registers = 0;
274 	  goto again;
275 	}
276 
277       error ("GetThreadContext failure %ld\n", (long) e);
278     }
279 }
280 
281 static void
i386_prepare_to_resume(windows_thread_info * th)282 i386_prepare_to_resume (windows_thread_info *th)
283 {
284   if (th->debug_registers_changed)
285     {
286       struct x86_debug_reg_state *dr = &debug_reg_state;
287 
288       win32_require_context (th);
289 
290 #ifdef __x86_64__
291       if (wow64_process)
292 	{
293 	  th->wow64_context.Dr0 = dr->dr_mirror[0];
294 	  th->wow64_context.Dr1 = dr->dr_mirror[1];
295 	  th->wow64_context.Dr2 = dr->dr_mirror[2];
296 	  th->wow64_context.Dr3 = dr->dr_mirror[3];
297 	  /* th->wow64_context.Dr6 = dr->dr_status_mirror;
298 	     FIXME: should we set dr6 also ?? */
299 	  th->wow64_context.Dr7 = dr->dr_control_mirror;
300 	}
301       else
302 #endif
303 	{
304 	  th->context.Dr0 = dr->dr_mirror[0];
305 	  th->context.Dr1 = dr->dr_mirror[1];
306 	  th->context.Dr2 = dr->dr_mirror[2];
307 	  th->context.Dr3 = dr->dr_mirror[3];
308 	  /* th->context.Dr6 = dr->dr_status_mirror;
309 	     FIXME: should we set dr6 also ?? */
310 	  th->context.Dr7 = dr->dr_control_mirror;
311 	}
312 
313       th->debug_registers_changed = false;
314     }
315 }
316 
317 static void
i386_thread_added(windows_thread_info * th)318 i386_thread_added (windows_thread_info *th)
319 {
320   th->debug_registers_changed = true;
321 }
322 
323 static void
i386_single_step(windows_thread_info * th)324 i386_single_step (windows_thread_info *th)
325 {
326 #ifdef __x86_64__
327   if (wow64_process)
328     th->wow64_context.EFlags |= FLAG_TRACE_BIT;
329   else
330 #endif
331     th->context.EFlags |= FLAG_TRACE_BIT;
332 }
333 
334 /* An array of offset mappings into a Win32 Context structure.
335    This is a one-to-one mapping which is indexed by gdb's register
336    numbers.  It retrieves an offset into the context structure where
337    the 4 byte register is located.
338    An offset value of -1 indicates that Win32 does not provide this
339    register in it's CONTEXT structure.  In this case regptr will return
340    a pointer into a dummy register.  */
341 #ifdef __x86_64__
342 #define context_offset(x) (offsetof (WOW64_CONTEXT, x))
343 #else
344 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
345 #endif
346 static const int i386_mappings[] = {
347   context_offset (Eax),
348   context_offset (Ecx),
349   context_offset (Edx),
350   context_offset (Ebx),
351   context_offset (Esp),
352   context_offset (Ebp),
353   context_offset (Esi),
354   context_offset (Edi),
355   context_offset (Eip),
356   context_offset (EFlags),
357   context_offset (SegCs),
358   context_offset (SegSs),
359   context_offset (SegDs),
360   context_offset (SegEs),
361   context_offset (SegFs),
362   context_offset (SegGs),
363   context_offset (FloatSave.RegisterArea[0 * 10]),
364   context_offset (FloatSave.RegisterArea[1 * 10]),
365   context_offset (FloatSave.RegisterArea[2 * 10]),
366   context_offset (FloatSave.RegisterArea[3 * 10]),
367   context_offset (FloatSave.RegisterArea[4 * 10]),
368   context_offset (FloatSave.RegisterArea[5 * 10]),
369   context_offset (FloatSave.RegisterArea[6 * 10]),
370   context_offset (FloatSave.RegisterArea[7 * 10]),
371   context_offset (FloatSave.ControlWord),
372   context_offset (FloatSave.StatusWord),
373   context_offset (FloatSave.TagWord),
374   context_offset (FloatSave.ErrorSelector),
375   context_offset (FloatSave.ErrorOffset),
376   context_offset (FloatSave.DataSelector),
377   context_offset (FloatSave.DataOffset),
378   context_offset (FloatSave.ErrorSelector),
379   /* XMM0-7 */
380   context_offset (ExtendedRegisters[10 * 16]),
381   context_offset (ExtendedRegisters[11 * 16]),
382   context_offset (ExtendedRegisters[12 * 16]),
383   context_offset (ExtendedRegisters[13 * 16]),
384   context_offset (ExtendedRegisters[14 * 16]),
385   context_offset (ExtendedRegisters[15 * 16]),
386   context_offset (ExtendedRegisters[16 * 16]),
387   context_offset (ExtendedRegisters[17 * 16]),
388   /* MXCSR */
389   context_offset (ExtendedRegisters[24])
390 };
391 #undef context_offset
392 
393 #ifdef __x86_64__
394 
395 #define context_offset(x) (offsetof (CONTEXT, x))
396 static const int amd64_mappings[] =
397 {
398   context_offset (Rax),
399   context_offset (Rbx),
400   context_offset (Rcx),
401   context_offset (Rdx),
402   context_offset (Rsi),
403   context_offset (Rdi),
404   context_offset (Rbp),
405   context_offset (Rsp),
406   context_offset (R8),
407   context_offset (R9),
408   context_offset (R10),
409   context_offset (R11),
410   context_offset (R12),
411   context_offset (R13),
412   context_offset (R14),
413   context_offset (R15),
414   context_offset (Rip),
415   context_offset (EFlags),
416   context_offset (SegCs),
417   context_offset (SegSs),
418   context_offset (SegDs),
419   context_offset (SegEs),
420   context_offset (SegFs),
421   context_offset (SegGs),
422   context_offset (FloatSave.FloatRegisters[0]),
423   context_offset (FloatSave.FloatRegisters[1]),
424   context_offset (FloatSave.FloatRegisters[2]),
425   context_offset (FloatSave.FloatRegisters[3]),
426   context_offset (FloatSave.FloatRegisters[4]),
427   context_offset (FloatSave.FloatRegisters[5]),
428   context_offset (FloatSave.FloatRegisters[6]),
429   context_offset (FloatSave.FloatRegisters[7]),
430   context_offset (FloatSave.ControlWord),
431   context_offset (FloatSave.StatusWord),
432   context_offset (FloatSave.TagWord),
433   context_offset (FloatSave.ErrorSelector),
434   context_offset (FloatSave.ErrorOffset),
435   context_offset (FloatSave.DataSelector),
436   context_offset (FloatSave.DataOffset),
437   context_offset (FloatSave.ErrorSelector)
438   /* XMM0-7 */ ,
439   context_offset (Xmm0),
440   context_offset (Xmm1),
441   context_offset (Xmm2),
442   context_offset (Xmm3),
443   context_offset (Xmm4),
444   context_offset (Xmm5),
445   context_offset (Xmm6),
446   context_offset (Xmm7),
447   context_offset (Xmm8),
448   context_offset (Xmm9),
449   context_offset (Xmm10),
450   context_offset (Xmm11),
451   context_offset (Xmm12),
452   context_offset (Xmm13),
453   context_offset (Xmm14),
454   context_offset (Xmm15),
455   /* MXCSR */
456   context_offset (FloatSave.MxCsr)
457 };
458 #undef context_offset
459 
460 #endif /* __x86_64__ */
461 
462 /* Fetch register from gdbserver regcache data.  */
463 static void
i386_fetch_inferior_register(struct regcache * regcache,windows_thread_info * th,int r)464 i386_fetch_inferior_register (struct regcache *regcache,
465 			      windows_thread_info *th, int r)
466 {
467   const int *mappings;
468 #ifdef __x86_64__
469   if (!wow64_process)
470     mappings = amd64_mappings;
471   else
472 #endif
473     mappings = i386_mappings;
474 
475   char *context_offset;
476 #ifdef __x86_64__
477   if (wow64_process)
478     context_offset = (char *) &th->wow64_context + mappings[r];
479   else
480 #endif
481     context_offset = (char *) &th->context + mappings[r];
482 
483   long l;
484   if (r == FCS_REGNUM)
485     {
486       l = *((long *) context_offset) & 0xffff;
487       supply_register (regcache, r, (char *) &l);
488     }
489   else if (r == FOP_REGNUM)
490     {
491       l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
492       supply_register (regcache, r, (char *) &l);
493     }
494   else
495     supply_register (regcache, r, context_offset);
496 }
497 
498 /* Store a new register value into the thread context of TH.  */
499 static void
i386_store_inferior_register(struct regcache * regcache,windows_thread_info * th,int r)500 i386_store_inferior_register (struct regcache *regcache,
501 			      windows_thread_info *th, int r)
502 {
503   const int *mappings;
504 #ifdef __x86_64__
505   if (!wow64_process)
506     mappings = amd64_mappings;
507   else
508 #endif
509     mappings = i386_mappings;
510 
511   char *context_offset;
512 #ifdef __x86_64__
513   if (wow64_process)
514     context_offset = (char *) &th->wow64_context + mappings[r];
515   else
516 #endif
517     context_offset = (char *) &th->context + mappings[r];
518 
519   collect_register (regcache, r, context_offset);
520 }
521 
522 static const unsigned char i386_win32_breakpoint = 0xcc;
523 #define i386_win32_breakpoint_len 1
524 
525 static void
i386_arch_setup(void)526 i386_arch_setup (void)
527 {
528   struct target_desc *tdesc;
529 
530 #ifdef __x86_64__
531   tdesc = amd64_create_target_description (X86_XSTATE_SSE_MASK, false,
532 					   false, false);
533   init_target_desc (tdesc, amd64_expedite_regs);
534   win32_tdesc = tdesc;
535 #endif
536 
537   tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false);
538   init_target_desc (tdesc, i386_expedite_regs);
539 #ifdef __x86_64__
540   wow64_win32_tdesc = tdesc;
541 #else
542   win32_tdesc = tdesc;
543 #endif
544 }
545 
546 /* Implement win32_target_ops "num_regs" method.  */
547 
548 static int
i386_win32_num_regs(void)549 i386_win32_num_regs (void)
550 {
551   int num_regs;
552 #ifdef __x86_64__
553   if (!wow64_process)
554     num_regs = sizeof (amd64_mappings) / sizeof (amd64_mappings[0]);
555   else
556 #endif
557     num_regs = sizeof (i386_mappings) / sizeof (i386_mappings[0]);
558   return num_regs;
559 }
560 
561 /* Implement win32_target_ops "get_pc" method.  */
562 
563 static CORE_ADDR
i386_win32_get_pc(struct regcache * regcache)564 i386_win32_get_pc (struct regcache *regcache)
565 {
566   bool use_64bit = register_size (regcache->tdesc, 0) == 8;
567 
568   if (use_64bit)
569     {
570       uint64_t pc;
571 
572       collect_register_by_name (regcache, "rip", &pc);
573       return (CORE_ADDR) pc;
574     }
575   else
576     {
577       uint32_t pc;
578 
579       collect_register_by_name (regcache, "eip", &pc);
580       return (CORE_ADDR) pc;
581     }
582 }
583 
584 /* Implement win32_target_ops "set_pc" method.  */
585 
586 static void
i386_win32_set_pc(struct regcache * regcache,CORE_ADDR pc)587 i386_win32_set_pc (struct regcache *regcache, CORE_ADDR pc)
588 {
589   bool use_64bit = register_size (regcache->tdesc, 0) == 8;
590 
591   if (use_64bit)
592     {
593       uint64_t newpc = pc;
594 
595       supply_register_by_name (regcache, "rip", &newpc);
596     }
597   else
598     {
599       uint32_t newpc = pc;
600 
601       supply_register_by_name (regcache, "eip", &newpc);
602     }
603 }
604 
605 struct win32_target_ops the_low_target = {
606   i386_arch_setup,
607   i386_win32_num_regs,
608   i386_initial_stuff,
609   i386_get_thread_context,
610   i386_prepare_to_resume,
611   i386_thread_added,
612   i386_fetch_inferior_register,
613   i386_store_inferior_register,
614   i386_single_step,
615   &i386_win32_breakpoint,
616   i386_win32_breakpoint_len,
617   1,
618   i386_win32_get_pc,
619   i386_win32_set_pc,
620   i386_supports_z_point_type,
621   i386_insert_point,
622   i386_remove_point,
623   x86_stopped_by_watchpoint,
624   x86_stopped_data_address
625 };
626