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